这是一篇学习UFLDL反向传导算法的笔记,按自己的思路捋了一遍,有不对的地方请大家指点。
首先说明一下神经网络的符号:
1. nl 表示神经网络的层数。
2. sl 表示第 l 层神经元个数,不包含偏置单元。
3. z(l)i 表示第 l 层第 i 个神经元的输入; a(l)i 表示第 l 层第 i 个神经元的输出。
4. W(l)ij 表示第 l 层第 j 个神经元连接到第 l+1 层第 i 个神经元的权重,因此权值矩阵 W 的维数为 sl+1 x sl
第二层各神经元的计算方法如下:
a(2)1a(2)2a(2)3a(2)4=f(W(1)11x1+W(1)12x2+W(1)13x3+b(1)1)=f(W(1)21x1+W(1)22x2+W(1)23x3+b(1)2)=f(W(1)31x1+W(1)32x2+W(1)33x3+b(1)3)=f(W(1)41x1+W(1)42x2+W(1)43x3+b(1)4)
我们可以将其向量化表示:
z(2)a(2)=W(1)x+b(1)=f(z(2))
这里的矩阵
W 的具体形式为:
W4×3=⎡⎣⎢⎢⎢⎢⎢⎢W(1)11W(1)21W(1)31W(1)41W(1)12W(1)22W(1)32W(1)42W(1)13W(1)23W(1)33W(1)43⎤⎦⎥⎥⎥⎥⎥⎥
第
2 层的神经元个数为
4 ,第
1 层神经元的个数为
3 ,因此为
4×3 维的矩阵。
代价函数
对于单个样本我们将神经网络的代价函数定义为:
J(W,b;x,y)=12∥∥hW,b(x)−y∥∥2
对所有
K 个样本,神经网络的总的代价函数(这也是批量的由来)为:
J(W,b)=[1K∑k=1KJ(W,b;x(k),y(k))]+λ2∑l=1nl−1∑i=1sl∑j=1sl+1(W(l)ji)2=[1K∑k=1K(12∥∥hW,b(x(k))−y(k)∥∥2)]+λ2∑l=1nl−1∑i=1sl∑j=1sl+1(W(l)ji)2
使用批量梯度下降算法寻求神经网络的最优参数
我们使用批量梯度下降算法寻求神经网络的最优参数 W(l),bl 。
我们先来看对于 第 l+1 层第 i 个神经元来说,第 l 层第 j 个神经元的权值可按如下方式迭代更新:
W(l)ij=W(l)ij−α∂∂W(l)ijJ(W,b)=W(l)ij−α⎡⎣⎛⎝1K∑k=1K∂∂W(l)ijJ(W,b;x(k),y(k))⎞⎠+λW(l)ij⎤⎦
类似的,对于 第
l+1 层第
i 个神经元来说,第
l 层的偏置单元的权值可按如下方式迭代更新:
b(l)i=b(l)i−α∂∂b(l)iJ(W,b)=b(l)i−α⎡⎣1K∑k=1K∂∂b(l)iJ(W,b;x(k),y(k))⎤⎦
我们现在的目的是求出以下两个式子就可以对参数进行迭代了:
∂∂W(l)ijJ(W,b;x(k),y(k))∂∂b(l)iJ(W,b;x(k),y(k))
又我们知道第 l+1 层第 i 个神经元的输入 z(l+1)i 可以由以下式子计算:
z(l+1)i=∑j=1slW(l)ija(l)j+b(l)i
再进一步的对上面的式子进行变形:
∂∂W(l)ijJ(W,b;x(k),y(k))=∂J(W,b;x(k),y(k))∂z(l+1)i⋅∂z(l+1)i∂W(l)ij=∂J(W,b;x(k),y(k))∂z(l+1)i⋅a(l)j
同样的,对于 b(l)i 的偏导数:
∂∂b(l)iJ(W,b;x(k),y(k))=∂J(W,b;x(k),y(k))∂z(l+1)i⋅∂z(l+1)i∂b(l)i=∂J(W,b;x(k),y(k))∂z(l+1)i
残差的定义
接下来我们定义:
δ(l)i=∂∂z(l)iJ(W,b;x(k),y(k))
为第
k 个样本在第
l 层第
i 个神经元上产生的残差。再次回顾我们的参数更新公式:
对于
W(l)ij 我们有:
W(l)ij=W(l)ij−α∂∂W(l)ijJ(W,b)=W(l)ij−α⎡⎣⎛⎝1K∑k=1K∂∂W(l)ijJ(W,b;x(k),y(k))⎞⎠+λW(l)ij⎤⎦=W(l)ij−α⎡⎣⎛⎝1K∑k=1K∂J(W,b;x(k),y(k))∂z(l+1)i⋅a(l)j⎞⎠+λW(l)ij⎤⎦=W(l)ij−α[(1K∑k=1Kδ(l+1)i⋅a(l)j)+λW(l)ij]
类似的,对于 b(l)i 我们有:
b(l)i=b(l)i−α∂∂b(l)iJ(W,b)=b(l)i−α1K∑k=1K∂∂b(l)iJ(W,b;x(k),y(k))=b(l)i−α1K∑k=1K∂J(W,b;x(k),y(k))∂z(l+1)i=b(l)i−α1K∑k=1Kδ(l+1)i
现在的核心问题只剩下一个了,这个残差该如何求?
我们先计算最后一层第 i 个神经元上的残差,这里为了简单起见,不再指定为第 k 个样本。
δ(nl)i=∂∂z(nl)iJ(W,b;x,y)=∂∂z(nl)i12∥∥hW,b(x)−y∥∥2=∂∂z(nl)i12∑j=1snl(yj−a(nl)j)2=∂∂z(nl)i12∑j=1snl(yj−f(z(nl)j))2=−(yi−f(z(nl)i))f′(z(nl)i)
然后计算倒数第二层即第 nl−1 层第 i 个神经元的残差:
δ(nl−1)i=∂∂z(nl−1)iJ(W,b;x,y)=∂∂z(nl−1)i12∑j=1snl(yj−a(nl)j)2=12∑j=1snl∂∂z(nl−1)i(yj−f(z(nl)j))2=∑j=1snl−(yj−f(z(nl)j))∂∂z(nl−1)if(z(nl)j)=∑j=1snl−(yj−f(z(nl)j))f′(z(nl)j)∂z(nl)j∂z(nl−1)i=∑j=1snlδ(nl)j∂∂z(nl−1)i∑q=1snlW(nl−1)jqf(z(nl−1)q)=∑j=1snlW(nl−1)jiδ(nl)jf′(z(nl−1)i)
下面是残差传播的示意图:
从这里可以看出紧挨着的两层神经元之间的残差是有关系的,这也是反向传播的由来。更一般的,可以将上述关系表述为:
δ(l)i=∑j=1sl+1W(l)jiδ(l+1)jf′(z(l)i)
再再次回顾我们的参数更新公式:
W(l)ijb(l)i=W(l)ij−α[(1K∑k=1Kδ(l+1)i⋅a(l)j)+λW(l)ij]=b(l)i−α1K∑k=1Kδ(l+1)i
我们需要先计算输出层神经元的残差,然后一级一级的计算前一层的神经元的残差,利用这些残差就可以更新神经网络参数了。
向量化表示
这里我们尝试将上述结果表示成向量或矩阵的形式,比如我们希望能一次性更新某一层神经元的权值和偏置,而不是一个一个的更新。
δ(l+1)i 表示的是第 l+1 层第 i 个神经元的残差,那么整个第 l+1 层神经元的偏差是多少呢?
δ(l+1)i=∑j=1sl+2W(l+1)jiδ(l+2)jf′(z(l+1)i)
从而得到:
δ(l+1)=(W(l+1))Tδ(l+2)∙f′(z(l+1))
注:这里的
∙ 是指点乘,即对应元素相乘,
δ(l+1) 是一个
sl+1×1 维的列向量。
a(l)j 表示第 l 层第 j 个神经元的输出,因此整个第 l 层的神经元的输出可用 a(l) 表示,是一个 sl×1 维的列向量。
因此对于矩阵 W(l) 来说,我们记:
∇W(l)J(W,b;x,y)=δ(l+1)(a(l))T
我们将
ΔW(l) 初始化为
0 ,然后对所有
K 个样本将它们的
∇W(l)J(W,b;x,y) 累加到
ΔW(l) 中去:
ΔW(l):=ΔW(l)+∇W(l)J(W,b;x,y)
然后更新一次
W(l) :
W(l)=W(l)−α[(1KΔW(l))+λW(l)]
这里再强调一下:上式中的
ΔW(l) 是所有
K 个样本的
δ(l+1)(a(l))T
累加和,如果希望做随机梯度下降了或者是mini-batch,这里就不用把所有样本的残差加起来了。
类似的,令:
∇b(l)J(W,b;x,y)=δ(l+1)
我们将
Δb(l) 初始化为
0 , 然后对所有
K 个样本将它们的
∇b(l)J(W,b;x,y) 累加到
Δb(l) 中去
Δb(l):=Δb(l)+∇b(l)J(W,b;x,y)
于是有:
b(l)=b(l)−α[1KΔb(l)]
同样的,上式中的
Δb(l) 是所有
K 个样本的
δ(l+1)
累加和。
小结
上面的推导过程尝试把所有的步骤都写出来了,个人感觉比UFLDL上的教程更为详尽,只要你耐心看总能看得懂的。当然这篇文章有些细节并未作说明,比如惩罚因子的作用,为什么没有对偏置进行规则化,激活函数的选择等,这些都可以在UFLDL中找到答案,对应的链接在下面的参考中给出。
参考
[1] 神经网络
[2] 反向传导算法