这是一篇学习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] 反向传导算法