反向传播算法及其推导过程

反向传播算法及其推导过程

在使用pytorch搭建神经网络时,一直对这几行代码不是很理解:

optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()

而这正是神经网络最重要的算法之一:BP算法,这次借助一个最简单的例子,手动推导一遍向后传播过程,以期对神经网络有更深刻的理解。

神经网络结构

这里使用一个三层网络结构,一层输入层,一层隐藏层,一层输出层,每层均包含两个神经元,其中隐含层和输出层都有偏置。
神经网络结构
为了让这个例子更加具体,给网络中的参数进行初始化如下:
参数初始化

前向传播

隐藏层

首先我们计算h1和h2的输入:
h1 和 h2的输入
之后将输入传递给激活函数(这里使用的是sigmoid激活函数),得到:
h1和h2的输出

输出层

将隐藏层的输出作为输入,对输出层的神经元重复上述过程。
输出层的输入和输出

误差计算

这里我们均方误差作为目标函数:
均方误差
分别计算 [公式] 和 [公式] 的误差:
o1和o2的误差
总误差为:
总误差

反向传播

输出层–>隐藏层

更新w5参数:
w5偏导
应用链式法则:

为了求出w5的梯度,我们要一层一层地算:
首先,计算总误差对O1(out)的梯度:

然后计算总误差对O1(in)的梯度:


这里对sigmoid的求导需要一些技巧:
求sigmoid的导数
最后计算对w5的梯度:
对w5的梯度
把所有梯度值相乘:
在这里插入图片描述
选用随机梯度下作为优化函数,学习率定为0.5,有:
w5最新值
同理我们可以求出w6,w7,w8的更新值:

再次应用上面的算法,对b2进行更新:
不更新

隐藏层–>输入层

对于 [公式] 的梯度,我们需要计算出:


而右式中第一项由两部分相加组成:
第一项
如果继续算下去的话,也并不难算,但是这时我们暂停一下,来考虑一下BP算法如何处理这种多项相加的导数计算。
BP算法的精华在于,它可以只用一次从上至下的遍历,即可算出指定参数的导数,它是如何做到的呢?
在每一层计算导数时,仅仅计算这一层相对于下一层的导数,并把计算得到的值传到下一层,当下一层收集到所有来自上游的导数后,把他们的值相加,乘上自己对自己下一层的导数并传递到下一层?
是不是懵了?不懵才怪,我们用一个例子来解释一下:
在这里插入图片描述
当我们在O1这一层时,我们计算两个导数值,即:
在这里插入图片描述
然后分别把他们放到隐藏层备用,同理,在计算o2时也把计算到的两个值传递到隐藏层。
而当我们在隐藏层中计算下一级导数时,就可以很方便的把两个值加起来,继续下一层的计算。
(这里可能还是表述的不是很清楚,可以参考知乎的一篇文章:https://www.zhihu.com/question/27239198/answer/89853077 写得非常好)

好了,我们继续计算第二层的导数,其中第一项:

第二项为:

两式相加,再加上对w1的求导:
对w1的梯度
同样,对w1进行更新:

用同样的方法更新w2,w3,w4,b1计算结果如下:

这样我们就完成了一次正向计算 + 一次反向传播

验证

这个时候,我们再进行一次正向的计算,看一看Etotal有没有减少,这里就不逐步分析了:
在这里插入图片描述
在这里插入图片描述

可以看到,更新后的Etotal为0.28390,比第一次的0.29837有明显的降低,可以验证我们的传播过程基本正确。

与代码联系

现在我们再来看这五行代码:

optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()

就很清楚他们都做了什么:

  1. 把梯度置为0,这一步对应我们上文中说到每次反向传播,都会在中间层记录上一层传下来的梯度之和,这一步就是每层的这个值清零,方便一次新的计算
  2. 带入inputs,得到output,这相当于我们刚刚带入i1,i2,求出O1(out),和O2(out),即为一次正向的传播
  3. loss的计算。相当于我们刚刚计算Etotal,事实上,如果指定loss=nn.MSELoss(),那这一步就是刚好对应我们的Etotal
  4. backward,这一步就是刚刚我们整个的反向传播过程,在每一层都算出对应一个梯度值
  5. optimizer.step(),更新参数,这一步就是我们取学习率为0.5并更新w的操作,把每个参数都进行了更新

以上即为反向传播的原理,计算和使用pytorch实现的代码,如有谬误,欢迎指正~

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MLP神经网络反向传播算法公式推导如下: 1. 前向传播 首先,对于一个输入样本,我们需要进行前向传播,计算出每个神经元的输出值。假设输入层有n个神经元,隐藏层有m个神经元,输出层有k个神经元,则有: 输入层到隐藏层的权重矩阵为W,隐藏层到输出层的权重矩阵为V,输入层的输出为x,隐藏层的输出为h,输出层的输出为y,则有: $$h = f(Wx)$$ $$y = g(Vh)$$ 其中,f和g分别为激活函数,通常为sigmoid函数或ReLU函数等。 2. 反向传播 接下来,我们需要计算误差并进行反向传播,更新权重矩阵。假设样本的真实标签为t,则输出层的误差为: $$\delta_k = (y_k - t_k)g'(net_k)$$ 其中,net_k为输出层神经元的加权输入,g'为激活函数的导数。 隐藏层的误差可以根据输出层的误差和权重矩阵V计算得到: $$\delta_j = g'(net_j)\sum_{k=1}^K \delta_k V_{kj}$$ 其中,net_j为隐藏层神经元的加权输入。 根据误差,我们可以更新输出层到隐藏层的权重矩阵V: $$\Delta V_{kj} = -\eta \delta_k h_j$$ 其中,$\eta$为学习率。 同样地,我们可以根据误差更新输入层到隐藏层的权重矩阵W: $$\Delta W_{ji} = -\eta \delta_j x_i$$ 3. 总结 综上所述,MLP神经网络反向传播算法包括以下步骤: 1. 前向传播,计算每个神经元的输出值。 2. 计算输出层的误差,然后根据误差更新输出层到隐藏层的权重矩阵V。 3. 计算隐藏层的误差,然后根据误差更新输入层到隐藏层的权重矩阵W。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值