对误差反向传播的理解和学习

    关于反向传播,我非常推荐下面的一个在线书籍,其给出了非常详实、生动且易于理解的反向传播算法以及相关公式的推导,公式不繁杂是一大特点,Neural Networks and Deep Learning。本文将对其讲解给以归纳和总结,其中有些个人的见解,通篇将使用下图所示神经网络。

一、符号假设

损失函数为 C

第 l 层的第 j 个神经元表示为 nr_j^l

l 层的第 j 个神经元的偏置为 b_j^l,输入层无偏置

l-1 层的第 k 个神经元与第 l 层的第 j 个神经元之间的的权重为 w^l_{jk}l\geqslant 1

l 层的第 j 个神经元的激活值为 a_j^l

l 层的第 j 个神经元的输入值为 z_j^l=\sum_{k=1}^{n_{l-1}}w_{jk}^l+b_j^l,其中 n_{l-1} 表示第 l-1 层的神经元数量

二、什么是误差

    BP算法的全称是误差反向传播算法 ,关键是什么是误差,再其次才是反向传播。 结合下图,来理解误差的概念。

    现在,如果 nr_1^1 的输入发生变化,C 的变化为

                                                                                         \frac{\partial C}{\partial z_1^1}\Delta z_1^1

    假设 \Delta z_1^1 的变化较小。如果偏导项较大,且与 \Delta z_1^1 的符号相反,损失就会降低;反之,如果偏导项接近于零,那么无论 \Delta z_1^1 变化多大,损失的变动都不会很明显。可以这样理解,误差越大,学习能力越强,反之学习能力越弱

    那么,我们认为 C 的变化量由 \frac{\partial C}{\partial z_1^1} 来决定。误差越大,C 下降的空间就越大;反之,C 下降的空间就越小。\frac{\partial C}{\partial z_1^1} 显然可以用来度量学习误差。

    误差通过向前传递,导致后面的神经元误差发生变化,最终 C 在众多误差变化下发生改变。

三、误差的计算

    对误差的相关公式推导详见上文在线文档,原理还是链式推导,这里不再给出详细证明。

    用 \delta _j^l 表示vnr_j^l 的误差。稍后会发现,对误差的计算将关系到对权重和偏置的偏导计算。假定损失函数为均方误差,那么输出层的误差为

                                                                            \delta^L=(\textbf{\textit{a}}^L-\textbf{y})\ \bigodot \ \sigma ^{'}\left (\textbf{\textit{z}}^L \right )

    其中,\textbf{\textit{a}}^L 是输出层的激活值向量, \textbf{\textit{y}} 是样本真实标签向量。单个神经元误差为

                                                                              \delta _j^L=\frac{\partial C}{\partial z_j^L}=\frac{\partial C}{\partial a_j^L} \sigma ^{'}\left ( z_j^L \right )

    误差反向传播体现在相邻层的学习误差存在依赖,表示如下

                                                                          \delta ^l=((\textbf{\textit{w}}^{l+1})^T\delta ^{l+1}) \ \bigodot \ \sigma^{'} (\textbf{\textit{z}}^l)

    为了更加直观的理解上式,不妨来看一下其非向量表达形式

                                                                          \delta_j ^l=(\delta ^{l+1}\sum_{k=1}^{N_{l+1}}\textbf{\textit{w}}_{jk}^{l+1})\ast \ \sigma^{'}(\textbf{\textit{z}}_j^l)

      第一项是第 l+1 层各个神经元的学习误差的加权,第二项是激活函数对 \textbf{\textit{z}}_j^l 的偏导,表示激活值的变化率。其表达的直观意义是什么那? 结合下图和自己的理解来浅谈一下。

      聚焦 nr_1^1,第二层每个神经元的误差和第一层每个神经元是存在关系的,如nr_1^2 的误差的 20% 由 nr_1^1 导致,50% 由 nr_2^1 所致, 30% 由 nr_3^1 所致,而这些值恰是连接 nr_1^2 的权重值。那么在反向计算误差时,很自然的第二层每个神经元会将对应的误差值成比例的推向前一层现在 nr_1^1 接收了第 二层各个神经元推过来的误差,同时误差被 \sigma^{'}(\textbf{\textit{z}}_j^l) 进行了制约。如果 \sigma^{'}(\textbf{\textit{z}}_j^l)  大于 1,误差会放大,学习能力被放大,反之,学习能力开始缩水,慢慢的会死掉。如何制约学习能力,也就是激活函数的选择,这是一个超参数的选择问题。

三、偏置和权重的导数

    通过链式求导能计算出 C 相对每个权重的导数

                                                                                             \frac{\partial C}{\partial w_{jk}^l}

    以及 C 相对每个偏置的导数

                                                                                               \frac{\partial C}{\partial b_{j}^l}

    但是,这样做的时间复杂度是相当高的,详见上文在线文档中的分析。实际上,通过借助误差的计算便可完成对权重和偏置的导数表达。关于偏置的导数,其表达如下

                                                                                          \frac{\partial C}{\partial b_{j}^l}=\delta _j^l

    很棒,我们得到 \delta _j^l 立马得到上式,链式推导如下

                                                             {\color{Blue} }\frac{\partial C}{\partial b_{j}^l}= \sum_{k}^{N_{l+1}}\frac{\partial C}{\partial a_k^{l+1}}\frac{\partial a_k^{l+1}}{\partial z_k^{l+1}}\frac{\partial z_k^{l+1}}{\partial a_j^{l}}\frac{\partial a_j^{l}}{\partial z_j^{l}}\frac{\partial z_j^l}{\partial b_j^l}

                                                                     =\frac{\partial z_j^l}{\partial b_j^l}\frac{\partial C}{\partial z_j^{l}}=\frac{\partial C}{\partial z_j^{l}}=\delta _j^l

     权重的导数也有类似的表示如下

                                                                                      \frac{\partial C}{\partial w_{jk}^l} = a_k^{l-1}\delta _j^l

      链式推导如下

                                                                                 \frac{\partial C}{\partial w_{jk}^l} = \frac{\partial C}{\partial a_j^l}\frac{\partial a_j^l}{\partial z_j^l}\frac{\partial z_j^l}{\partial w_{jk}^l}

                                                                                            = \frac{\partial C}{\partial a_j^l}\frac{\partial a_j^l}{\partial z_j^l}a_k^{l-1}

                                                                                            = \frac{\partial C}{\partial z_j^l}a_k^{l-1}

发布了94 篇原创文章 · 获赞 31 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/gaoxueyi551/article/details/104383691