搭建之前的基础与思考
构建模型的基本思想:
构建深度学习的过程:产生idea,将idea转化成code,最后进行experiment,之后根据结果修改idea,继续idea–>code–>experiment的循环,直到最终训练到表现不错的深度学习网络模型。
BP网络的搭建
BPNN v-0.1
目标:搭建一个有学习能力的BP神经网络。
目标完成情况:
●局限:只能计算固定大小的数据尺寸
●局限:只有一层,即为感知机或单层神经网络
有一定了解的可以直接看到代码,代码注释有思路。
idea
●神经元(单层感知机):接收n维列向量x(特征维度为n),输出y的估计。
多组输入x,可以按列堆叠形成矩阵。
●激活函数:Sigmoid、ReLU等
●损失函数:量化模型预测值与真实值的偏差,模型训练的目的是让Loss尽可能小。
例如:
成本函数就是所有训练样本损失函数的平均。
●反向传播时的复合求导
反向传播时只需要计算每一层的导数,最后乘积即可。
整体复盘以及数据流向图
code
根据面向对象编程思想,有两种实现思路,以神经元为最小类或以神经网络为最小类。
这里为了有更清晰的层次选择以神经元为最小类。
自己早数据,假设数据是学生的身高体重,根据此二者预测学生性别。
# Define dataset,已经经过预处理,保留特征
data = np.array([[-2, -1], # Alice[25, 6], # Bob[17, 4], # Charlie[-15, -6], # Diana
])
all_y_trues = np.array([1, # Alice0, # Bob0, # Charlie1, # Diana
])
代码:
import numpy as np# 激活函数与激活函数的求导
def sigmoid(x):return 1/(1 + np.exp(-x))
def d_sigomid(x):return sigmoid(x) * (1 - sigmoid(x))# 神经元
class Neuron:'''-神经元基本属性包括权重和偏置量-神经元方法前向计算和反向传递-神经元默认接收二维的输入'''#初始化,针对特定尺寸的数据集def __init__(self):self.weights = np.random.normal(size=(1, 2))self.bias = np.random.normal()#前向计算过程集成化,用于训练完成后一步输出预测值def feedforward(self, inputs):Z = np.dot(self.weights, inputs) + self.biasreturn sigmoid(Z)#训练函数def train_epoch(self, x_data, true_value):'''-迭代目的是更新权重参数和偏置参数,为了得到梯度需要知道导数为了计算导数需要知道前向计算过程中的一些值。训练时按照这个思路去计算需要的值,再更新权重就可以。'''#准备工作learn_rate = 0.1epochs = 100for epoch in range(epoch):for x, y_true in zip(x_data, ture_value):#前向计算z = np.dot(self.weight, inputs) + self.biasy = sigmoid(z)#损失函数采用平方差计算,求导较为容易#l = (y - true_value) ** 2 #只有需要查看效果的轮次才计算输出#一般只需要知道l关于y的导数即可,并不需要计算l的值#反向传播d_L_d_y = -2 * (y_true - y)d_y_d_z = d_sigmod(z)d_z_d_w1 = x1 d_z_d_w2 = x2 #实际计算可以合并很多步骤,这里分开写为了使过程更清晰dw1 = d_L_d_y * d_y_d_z * d_z_d_w1dw2 = d_L_d_y * d_y_d_z * d_z_d_w2db = d_L_d_y * d_y_d_z#体现了反向计算的复合过程#更新self.w[0] -= learn_rate * dw1self.w[1] -= learn_rate * dw2self.b -= learn_rate * dbif epoch % 10 == 0:if epoch % 10 == 0:y_preds = np.apply_along_axis(self.feedforward, 1, data)loss = ((y_preds - y_true) ** 2).mean()print("Epoch %d loss %.3f" % (epoch, loss))BPNN = Neuron()
BPNN.train(data, all_y_trues)
experiment
记录1
尝试调参,没有效果
尝试输出一些中间值,发现预测结果是没问题的,只是loss的计算有问题
预测值是二维的列,真实值是一维的行,np广播相减直接出来一个4*4的矩阵。做减法时加一个转置就OK
记录2
原因很明显,问题过于简单且没有噪音。
增加了一些数据并加入少量噪音。
能明显看到loss的下降过程,说明实验成功。
BPNN v-0.2向量化