numpy实现神经网络-反向传播

    科技2022-07-10  170

    参考链接: https://www.jianshu.com/p/964345dddb70 https://www.cnblogs.com/jsfantasy/p/12177216.html 花了一天学习反向传播,记录一下,以便后面回顾。

    反向传播概念:前向传递输入信号直至输出产生误差,反向传播误差信息更新权重矩阵。类似于反馈系统,通过输出来影响网络各个层的权值和偏置。数学约定:

    按照图示数学符号网络的对网络进行描述,以便进行公示推到。下图展示了从输出层反向传播推导出第一层的权值,偏置也是类似的。

    激活函数采用sigmoid函数,函数的定义与求导如图。

    单个神经元推到后,我们要进行总结,以便编程使用。下图为总结的公式

    BP1: 面向输出层,C为损失函数,前面部分代表损失函数对输出层输出值的求导,后面部分代表输出层输入激活函数的求导,两者在进行对应元素相乘 BP2: 面向隐藏层,前面部分代表后一层的权值于后一层的后一层的误差的矩阵乘法,后面部分代表该层输入激活函数的求导,两者在进行对应元素相乘 BP3: 表示第L层偏置的导数等于第L层的误差 BP4: 表示第L层权值的导数等于前一层输出值与第L层的矩阵乘法 注意区分矩阵乘法与对应元素相乘的区别 仔细观察,你会发现BP1与BP2相结合就能发挥出最大功效,可以计算出任意层的误差,只要首先利用BP1公式计算出输出层误差,然后利用BP2层层传递,就无敌了,这也正是误差反向传播算法的缘由吧。同时对于权重w以及偏置b我们就可以通过BP3和BP4公式来计算了。

    梯度下降公式:

    关键代码赏析(反向传播部分):

    def backpropagation(self, X, y, learning_rate): # 反向传播算法实现 output = self.feed_forward(X)# 向前计算,得到最终输出值 for i in reversed(range(len(self._layers))): # 反向循环 layer = self._layers[i] if layer == self._layers[-1]: # 如果是输出层 layer.error = y - output # 这里直接用真实值减去预测值,没有求导 #对应公式BP1 layer.delta = layer.error * layer.apply_activation_derivative(output) else: # 如果是隐藏层 next_layer = self._layers[i + 1] layer.error = np.dot(next_layer.weights, next_layer.delta) #对应公式BP2 layer.delta = layer.error * layer.apply_activation_derivative(layer.activation_output) # 循环更新权值 for i in range(len(self._layers)): layer = self._layers[i] # o_i 为上一网络层的输出 o_i = np.atleast_2d(X if i == 0 else self._layers[i - 1].activation_output) # 梯度下降公式+BP4公式,delta 是公式中的负数,故这里用加号 layer.weights += layer.delta * o_i.T * learning_rate
    Processed: 0.011, SQL: 8