输入通过前向传播由输入层传播到输出层;梯度通过后向传播由输出层传播到输入层。
求解:
可见若我们能够求解出,就 ok 啦,下面就看如何求解
结合(4)和 (5)
若我们能够求解出,就可算出对 的偏微分。
而要求解 就得有 ,这是一个很好的递归公式,要求该层对 z 的偏微分,就得知道后续所有层对z的偏微分,直至输出层,时间复杂度O(n^2)。换种思路,我们可以从最后一层往前求解,则这种求解走一遍,所有的都可以求解,时间复杂度O(n)。图示如下:
N个样本的损失函数,其中代表单个样本损失函数:
求解梯度,以 weight 为例, bias 同理:
可见,我们只要求解单个样本上的梯度,再对所有样本梯度求和,就可以了。
下面以输入层、所有隐藏层、输出层均为2维为例,仅考虑单个样本的 weight 的梯度。
整个梯度求解 分为两步
- 前向传播:
- 后向传播:
前向传播比较好求解 ,因为 z 和 w 的式子很简单 :
看 的前面接的是啥(上一个神经元的输出值 or 输入层)就是啥,我们在前向传播的时候会计算出每个神经元的输出值,所以这边很容易就能拿到上一个神经元的输出值,如下图,激活函数取 sigmoid ( )函数。
后向传播 比较复杂。
有如下公式, z 先经过激活函数输出 a , a 再通过后续的神经元影响 C 。
,
a 对 z 的偏导很好求, ,因为在前向传播过程中所有神经元的输出已经计算出来了,即 z 已经固定下来了,所以 是一个可以求解的数值。
那么就剩下 , 是通过 和 对 C 产生影响。
,因为 ,所以 ,故 。
。若我们能够知道 和 就可以求解了。我们要知道当前层的梯度,就先得知道他后面一层的梯度,这可以看作一个递归问题,递归结束的条件就是在输出层求解时,我们只要知道 激活函数 和 损失函数就可以求了,而这俩函数是固定的。下面我们看输出层。
输出层是很好求的, 只要知道激活函数是啥就可以求解, 只要知道损失函数就可以求解:
只要输出层求出来了,它前面的一层也就可以求出来了,依次下去可以理解为递归求解。但是递归的复杂度比较高,求解当前层梯度,需要从当前层一直求解到输出层,可以发现很多层的梯度都被求解了不止一次,复杂度很高。若是我们换个方式来看待,直接从输出层开始往前求解,也可以理解成将递归求解转换为动态规划求解,从后往前求解也是后向传播的由来。这个思路可以由下图表示,我们将输入是 和 ,它们的权重分别为 和 ,再乘上激活函数带来的梯度 ,这个梯度对后向传播来说是一个常数,因为前向传播的时候就固定了,就得到输出 。所以梯度求解可以看作是梯度经过一个类似的神经网络从后往前传播。
参考
https://speech.ee.ntu.edu.tw/~tlkagk/courses/ML_2016/Lecture/BP.pdf