🐋反向传播算法(BP)
2021-11-15
| 2023-8-6
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
 

DNN反向传播算法要解决的问题

什么时候需要这个反向传播算法?
回到监督学习的一般问题,假设有 个训练样本: ,其中 为输入向量,特征维度为 ,而 为输出向量,特征维度为 。我们需要利用这 个样本训练出一个模型,当有一个新的测试样本 来到时, 可以预测 向量的输出。
如果采用DNN的模型,即输入层有 个神经元,输出层有 个神经元,再加上一些含有若干神经元的隐藏层。此时我们需要找到合适的所有隐藏层和输出层对应的线性系数矩阵,偏倚向量 ,让所有的训练样本输入计算出的输出尽可能的等于或很接近样本输出。怎么找到合适的参数呢?
这里就很容易联想到可以用一个合适的损失函数来度量训练样本的输出损失,接着对这个损失函数进行优化求最小化的极值,对应的一系列线性系数矩阵,偏倚向量即为最终结果。在DNN中,损失函数优化极值求解的过程最常见的一般是通过梯度下降法来一步步迭代完成的,当然也可以是其他的迭代方法比如牛顿法与拟牛顿法。
对DNN的损失函数用梯度下降法进行迭代优化求极小值的过程即为反向传播算法。
 

DNN反向传播算法的基本思路

在进行DNN反向传播算法前,需要选择一个损失函数,来度量训练样本计算出的输出和真实的训练样本输出之间的损失。
训练样本计算出的输出是怎么得来的?
这个输出是随机选择一系列,用前向传播算法计算出来的。即通过一系列的计算:
计算到输出层第层( 是最后一层, 是中间某一层)对应的即为前向传播算法计算出来的输出。
 
DNN可选择的损失函数有不少,这里使用最常见的均方差来度量损失。即对于每个样本,期望最小化下式:
其中, 为特征维度为的向量,而 范数。
 
损失函数有了,现在开始用梯度下降法迭代求解每一层的
首先是输出层第层。注意到输出层的满足下式:
这样对于输出层的参数,我们的损失函数变为:
这样求解 的梯度就简单了:
符号 代表Hadamard积,对于两个维度相同的向量 ,则:
Hadamard一般用于链式求导中联合激活函数的导数部分,这部分是一个向量。和之前的梯度向量之间是同维度的,需要通过hadamard运算。
在求解输出层的 的时候,有中间依赖部分 ,因此可以把公共的部分即对 先算出来,记为:
现在把输出层的梯度算出来了,那么如何计算上一层 层的梯度,上上层 层的梯度呢?这里需要一步步的递推,注意到对于第 层的未激活输出 ,它的梯度可以表示为:
如果我们可以依次计算出第 层的 ,则该层的 很容易计算?为什么呢?根据前向传播算法,有:
所以根据上式可以很方便的计算出第层的 的梯度如下:
那么现在问题的关键就是要求出 了。这里用数学归纳法,第 层的 上面我们已经求出, 假设第 层的 已经求出来了,那么如何求出第 层的 呢?
可见,用归纳法递推 的关键在于求解
的关系其实很容易找出:
这样很容易求出:
将上式带入上面 关系式我们得到:
现在得到了 的递推关系式,只要求出了某一层的 ,求解 的对应梯度就很简单的。
 

DNN反向传播算法过程

总结下DNN反向传播算法的过程
由于梯度下降法有批量(Batch),小批量(mini-Batch),随机三个变种,为了简化描述,这里以最基本的批量梯度下降法为例来描述反向传播算法。
 
输入: 总层数 ,以及各隐藏层与输出层的神经元个数,激活函数,损失函数,迭代步长 ,最大迭代次数MAX与停止迭代阈值 ,输入的 个训练样本
输出:各隐藏层与输出层的线性关系系数矩阵 和偏倚向量
 
1) 初始化各隐藏层与输出层的线性关系系数矩阵 和偏倚向量 的值为一个随机值
2)for iter to 1 to MAX:
for i =1 to m:
将DNN输入 设置为
for =2 to L,进行前向传播算法计算
通过损失函数计算输出层的
for = L-1 to 2, 进行反向传播算法计算
for = 2 to L,更新第 层的 :
如果所有 的变化值都小于停止迭代阈值 ,则跳出迭代循环到步骤3
3) 输出各隐藏层与输出层的线性关系系数矩阵 和偏倚向量
 
注:可以不加这个 ,毕竟步长是常数,而也是常数,两个常数相乘还是一个常数,那么可以只用一个常数在那里即可
 
 
注意:
反向传播重复利用前向传播中存储的中间值,以避免重复计算。 带来的影响之一是需要保留中间值,直到反向传播完成。 这也是训练比单纯的预测需要更多的内存(显存)的原因之一。 此外,这些中间值的大小与网络层的数量和批量的大小大致成正比。 因此,使用更大的批量来训练更深层次的网络更容易导致内存不足(out of memory)错误
 
  • PyTorch
  • 激活函数损失函数和激活函数的选择
    目录