文中如有错误,或您有不同的看法,请评论中指出讨论,谢谢。
1.符号说明
假设网络一共有0 ~ N层,其中0为输入层,N为输出层,1 ~ N-1为隐藏层。每层网络都有 n L n_L nL个神经元,L代表第L层网络。
除了输入层以外,网络的每个神经元都有两个变量 a i ( L ) , b i ( L ) a^{(L)}_{i},b^{(L)}_{i} ai(L),bi(L),上下标分别表示第L层的第i个神经元, b i ( L ) b^{(L)}_{i} bi(L)是 a i ( L ) a^{(L)}_{i} ai(L)用激活函数 f ( x ) f(x) f(x)激活后的数值,即 b i ( L ) = f ( a i ( L ) ) b^{(L)}_{i}=f(a^{(L)}_{i}) bi(L)=f(ai(L))。
相邻的两层网络用权重 w i j ( L ) w^{(L)}_{ij} wij(L)连接,表示连接第L-1层第i个神经元和第L层第j个神经元的权重。
网络的输出为 b 1 ( N ) , . . . , b n N ( N ) b_1^{(N)},...,b_{n_N}^{(N)} b1(N),...,bnN(N),这些输出会作为输入到一个设置好的损失函数 E ( x ) E(x) E(x)中,然后得到网络输出与标准值的损失值。
为了方便之后写代码,所以要用矩阵/向量的方式来表示每层网络的变量。符号说明如下:
- A ( L ) = [ a 1 ( L ) , a 2 ( L ) , . . . , a n L ( L ) ] 1 × n L A^{(L)}=[a^{(L)}_1,a^{(L)}_2,...,a^{(L)}_{n_L}]_{1\times n_L} A(L)=[a1(L),a2(L),...,anL(L)]1×nL;
- B ( L ) = [ b 1 ( L ) , b 2 ( L ) , . . . , b n L ( L ) ] 1 × n L B^{(L)}=[b^{(L)}_1,b^{(L)}_2,...,b^{(L)}_{n_L}]_{1\times n_L} B(L)=[b1(L),b2(L),...,bnL(L)]1×nL;
- W ( L ) = [ w 11 ( L ) . . . w 1 n L ( L ) . . . . . . . . . w n L − 1 1 ( L ) . . . w n L − 1 n L ( L ) ] n L − 1 × n L W^{(L)}=\bigg[ \begin{matrix}w^{(L)}_{11} ... w^{(L)}_{1n_L}\\ .........\\ w^{(L)}_{n_{L-1}1} ... w^{(L)}_{n_{L-1}n_L}\end{matrix} \bigg]_{n_{L-1}\times n_{L}} W(L)=[w11(L)...w1nL(L).........wnL−11(L)...wnL−1nL(L)]nL−1×nL;
2.前向传播
前向传播的主要作用就是根据网络的输入量来计算各层网络所有神经元的节点值 A ( L ) , B ( L ) A^{(L)},B^{(L)} A(L),B(L),最终根据网络的输出 B ( N ) B^{(N)} B(N)和输入量对应的样本标签值 Y Y Y计算损失值 E ( Y − B ( N ) ) E(Y-B^{(N)}) E(Y−B(N))。
由于前向传播比较简单,所以就不仔细分析了,就直接用矩阵变量来表示过程。
1). 初始化所有的权重 W ( L ) , L = 1 , 2 , . . . , N W^{(L)},L=1,2,...,N W(L),L=1,2,...,N;
2). 网络的输入为 A ( 0 ) A^{(0)} A(0),激活函数设为 f ( x ) f(x) f(x),如果输入是矩阵,则表示对矩阵的每个元素执行 f ( x ) f(x) f(x)的映射;
3). 然后就按顺序开始计算:
A ( 0 ) × W ( 1 ) ⇒ A ( 1 ) = A ( 0 ) × W ( 1 ) ⇒ B ( 1 ) = f ( A ( 1 ) ) A^{(0)}\times W^{(1)}\Rightarrow A^{(1)}=A^{(0)}\times W^{(1)}\Rightarrow B^{(1)}=f(A^{(1)}) A(0)×W(1)⇒A(1)=A(0)×W(1)⇒B(1)=f(A(1)),
B ( 1 ) × W ( 2 ) ⇒ A ( 2 ) = B ( 1 ) × W ( 2 ) ⇒ B ( 2 ) = f ( A ( 2 ) ) B^{(1)}\times W^{(2)}\Rightarrow A^{(2)}=B^{(1)}\times W^{(2)}\Rightarrow B^{(2)}=f(A^{(2)}) B(1)×W(2)⇒A(2)=B(1)×W(2)⇒B(2)=f(A(2)),
…,
B ( N − 1 ) × W ( N ) ⇒ A ( N ) = B ( N − 1 ) × W ( N ) ⇒ B ( N ) = f ( A ( N ) ) B^{(N-1)}\times W^{(N)}\Rightarrow A^{(N)}=B^{(N-1)}\times W^{(N)}\Rightarrow B^{(N)}=f(A^{(N)}) B(N−1)×W(N)⇒A(N)=B(N−1)×W(N)⇒B(N)=f(A(N)),
4).最后根据损失函数计算损失值, E ( Y − B ( N ) ) E(Y-B^{(N)}) E(Y−B(N)),其中 Y Y Y是网络输入对应的标签(正确值)。
3.反向传播
反向传播顾名思义当然要从网络的反向开始,也就是损失函数。反向传播的主要目的是根据网络得到的损失值,计算损失值相对于网络每个权重的导数(梯度),然后每个权重都利用梯度下降法进行权重值的更新。从而开始下一轮的前向传播和反向传播,使损失值越来越小,而网络的预测值逐渐贴近真实值。
那么重点就落在如何计算每个权重的梯度呢?(主要是基于“链式求导法”)
1).先从第N-1层到第N层的权重 W ( N ) = { w i N − 1 i N ( N ) } W^{(N)}=\{w^{(N)}_{i_{N-1}i_N}\} W(N)={
wiN−1iN(N)}开始分析:
∂ E ∂ w i N − 1 i N ( N ) = ∂ E ∂ a i N ( N ) ∂ a i N ( N ) ∂ w i N − 1 i N ( N ) = ∂ E ∂ b i N ( N ) ∂ b i N