神经网络(手写数字1-10识别)
变量
数据中给出的标签y为1-10之间的数字, 但是为了带入分类算法, 将yy转为R1×10R1×10的向量表示1-10之间的数据, 如[0 0 0 0 1 0 0 0 0 0], 则表示5等等
KK:y(i)y(i)的长度, 这里是10
mm: 样本的数量
nn: 特征的数量, 包括偏移+1的特征
假设激活函数为sigmoid函数, 即11+e(−x)11+e(−x)
公式
损失函数
cost(hΘ(x(i))−y(i))cost(hΘ(x(i))−y(i))为
cost(hΘ(x(i))−y(i))=∑k=1Ky(i)klog(hΘ(y(i)k))+(1−y(i)k)log(1−hΘ(y(i)k))cost(hΘ(x(i))−y(i))=∑k=1Kyk(i)log(hΘ(yk(i)))+(1−yk(i))log(1−hΘ(yk(i)))
损失函数JJ为
J(Θ)=1m∑i=1mcost(hΘ(x(i))−y(i))+λ2m∑lL−1∑i=1sl∑j=1sl+1ΘljiJ(Θ)=1m∑i=1mcost(hΘ(x(i))−y(i))+λ2m∑lL−1∑i=1sl∑j=1sl+1Θjil
上面式子展开为
J(Θ)=1m∑i=1m∑k=1Ky(i)klog(hΘ(y(i)k))+(1−y(i)k)log(1−hΘ(y(i)k))+λ2m∑lL−1∑i=1sl∑j=1sl+1ΘljiJ(Θ)=1m∑i=1m∑k=1Kyk(i)log(hΘ(yk(i)))+(1−yk(i))log(1−hΘ(yk(i)))+λ2m∑lL−1∑i=1sl∑j=1sl+1Θjil
正向传播与反向传播
为什么使用正向传播与反向传播
有了正向传播, 计算出输出层的结果, 就可以带入我们上面的公式计算出J
有了正向传播再加上反向传播, 就可以更快的计算出每一个权重的梯度, 而不是向传统方法一样一个一个的给权重求导数
可以会误解的
在反向传播中, 第一步就是hΘ(x)−yhΘ(x)−y, 对于这个式子可能会有人认为这个就是J, 其实不是, 它与J一点关系都没有, 它仅仅是为了反向传播中计算出各个计算节点的误差值而产生的
神经网络示意图
在字母右上角的数字表示第几层
权重矩阵的维度计算
ll: 表示当前层
slsl: 表示当前层有几个节点, 不包括+1偏移节点
sl+1×(sl+1)sl+1×(sl+1)
比如Θ(1)Θ(1)就是l=1l=1时,size(Θ(1))=3×4size(Θ(1))=3×4
a1a1表示一个输入样本, 也就是输入层,a(1)1,a(1)2,a(1)3a1(1),a2(1),a3(1)表示3个特征, 其中+1在第1层表示为a(1)0a0(1), 在第2层表示为a(2)0a0(2)
a(2)a(2)表示隐藏层
a(3)a(3)表示输出层, 可以理解为hΘ(x(i))hΘ(x(i))
Θ(1)Θ(1)表示输入层到隐藏层的权重矩阵
Θ(2)Θ(2)表示隐藏层到输出层的权重矩阵
现在不考虑bias节点, 输入层有3个节点, 隐藏层有3个节点, 输出层有3个节点, 这里只有输入层没有激活函数, 也就是没有运算的功能, 仅仅是担任提供数据的功能, 我们常说一个神经网络是2层, 3层之类的, 是根据该神经网络的计算层的个数判断的, 我们这里的神经网络就是一个2层神经网络
根据当前神经网络列出正向传播公式(对于单个样本)
在这之前, 先随机初始化权重矩阵(第1层与第2层的权重矩阵), 如果初始化, 见下文
a(1)=x(i)a(1)=x(i)
a(2)1=g(Θ10a(1)0+Θ11a(1)1+Θ12a(1)2+Θ13a(1)3)a1(2)=g(Θ10a0(1)+Θ11a1(1)+Θ12a2(1)+Θ13a3(1)), 其中g()g()为sigmoid函数, 括号里面的Θ10a(1)0+Θ11a(1)1+Θ12a(1)2+Θ13a(1)3Θ10a0(1)+Θ11a1(1)+Θ12a2(1)+Θ13a3(1)式子因为太长, 一般使z(2)1=Θ10a(1)0+Θ11a(1)1+Θ12a(1)2+Θ13a(1)3z1(2)=Θ10a0(1)+Θ11a1(1)+Θ12a2(1)+Θ13a3(1), 从而,a(2)1=g(z(2)1)a1(2)=g(z1(2))
同理,a(2)2=g(Θ20a(1)0+Θ21a(1)1+Θ22a(1)2+Θ23a(1)3)a2(2)=g(Θ20a0(1)+Θ21a1(1)+Θ22a2(1)+Θ23a3(1)), 所以,z(2)2=Θ20a(1)0+Θ21a(1)1+Θ22a(1)2+Θ23a(1)3z2(2)=Θ20a0(1)+Θ21a1(1)+Θ22a2(1)+Θ23a3(1), 从而得到,a(2)2=g(z(2)2)a2(2)=g(z2(2))
a(2)3=g(z(2)2)a3(2)=g(z2(2))
到了第2层也是如此
最后计算得出
a(3)1=g(z(3)1)a1(3)=g(z1(3))
a(3)2=g(z(3)2)a2(3)=g(z2(3))
a(3)3=g(z(3)3)a3(3)=g(z3(3))
到此单样本正向传播结束
上面的式子, 由于是在一个样本中一个特征一个特征的计算, 所以有一点繁琐, 但是只要理解了每一个特征的计算方法, 那么转为矩阵运算或者向量运算是非常方便的, 接下来就将上面的式子转为向量式
a(1)=x(i)a(1)=x(i)
z(2)=Θ(1)a(1)z(2)=Θ(1)a(1)
a(2)=g(z(2))a(2)=g(z(2))
z(3)=Θ(2)a(2)z(3)=Θ(2)a(2)
a(3)=g(z(3))a(3)=g(z(3))
到此单样本的正向传播结束
上面已经完成了正向传播, 现在进行反向传播
对于单个样本, 列出向量表达式
最后得到的Δ(2)Δ(2)和Δ(3)Δ(3)就是Θ(1)Θ(1)矩阵和Θ(2)Θ(2)矩阵的梯度矩阵
注意: 在使用BP求梯度的时候, 一般是一个矩阵一个矩阵的权重去求的, 而传统的梯度是由一个一个的权重去求的, 或者直接通过权重向量去求
delta(3)=hΘ(a(3))−y(i)delta(3)=hΘ(a(3))−y(i), 这里的y是已经从1-10的数字转为向量表示的向量
delta(2)=(Θ(2))Tdelta(3).∗g(z(2))delta(2)=(Θ(2))Tdelta(3).∗g(z(2))
Δ(2)=δ(2)(a(1))TΔ(2)=δ(2)(a(1))T,Δ(3)=δ(3)(a(2))TΔ(3)=δ(3)(a(2))T
现在已经计算完了对于单个样本来说每一个计算节点的误差值
对于剩下的m−1m−1个样本, 记录每一个迭代的δ(2)δ(2)和δ(3)δ(3)的值, 在乘以对应的a(x)a(x), 将结果分别累加到Δ(2)Δ(2)和Δ(2)Δ(2)
接着1mΔ(2)+λmΘ1mΔ(2)+λmΘ, 注意偏移的权重不能正则化
随机初始化矩阵
公式
ϵ=0.12ϵ=0.12
W=rand(inputSize,outputSize+1)×2ϵ−ϵW=rand(inputSize,outputSize+1)×2ϵ−ϵ
为什么这里是inputSize和(outputSize + 1)在上文提到的公式中提到了
梯度检验
虽然BP可以快速计算出权重的导数, 但是它复杂, 论准确率, 还是传统求梯度的方法更好, 但就是太慢了, 所以通过使用梯度检验的方式检验我们实现的BP是否正确
我们不那训练集, 而是自己常见简单固定的数据, 并且神经网络要简单, 否则速度很慢
因为J比较复杂, 所以我们根据梯度的定义去求导
gradOfθ1=J(θ1+ϵ,θ2,...)−J(θ1−ϵ,θ2,...)2ϵgradOfθ1=J(θ1+ϵ,θ2,...)−J(θ1−ϵ,θ2,...)2ϵ
一次对所有的θθ求导, 将他们以一个向量的方式导出
小技巧
在将一个向量式子转为一个矩阵式子的时, 可以列出他们的维度, 根据维度判断怎样在矩阵式子中是成立的
作者:Andrew_Chan