【深度学习系列】卷积神经网络详解(二)——自己手写一个卷积神经网络

上篇文章中我们讲解了卷积神经网络的基本原理,包括几个基本层的定义、运算规则等。本文主要写卷积神经网络如何进行一次完整的训练,包括前向传播和反向传播,并自己手写一个卷积神经网络。如果不了解基本原理的,可以先看看上篇文章:【深度学习系列】卷积神经网络CNN原理详解(一)——基本原理

公司主营业务:网站制作、成都网站制作、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。创新互联是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。创新互联推出麻章免费做网站回馈大家。


卷积神经网络的前向传播

首先我们来看一个最简单的卷积神经网络:

1. 输入层---->卷积层

以上一节的例子为例,输入是一个4*4 的image,经过两个2*2的卷积核进行卷积运算后,变成两个3*3的feature_map

   以卷积核filter1为例(stride = 1 ):

计算第一个卷积层神经元o11的输入: 

 neto11=conv(input,filter)=i11×h11+i12×h12+i21×h21+i22×h22=1×1+0×(−1)+1×1+1×(−1)=1(1)(1) neto11=conv(input,filter)=i11×h11+i12×h12+i21×h21+i22×h22=1×1+0×(−1)+1×1+1×(−1)=1

   神经元o11的输出:(此处使用Relu激活函数)

outo11=activators(neto11)=max(0,neto11)=1(2)(2)outo11=activators(neto11)=max(0,neto11)=1

其他神经元计算方式相同

2. 卷积层---->池化层

计算池化层m11 的输入(取窗口为 2 * 2),池化层没有激活函数  

netm11=max(o11,o12,o21,o22)=1outm11=netm11=1(3)(3)netm11=max(o11,o12,o21,o22)=1outm11=netm11=1

3. 池化层---->全连接层

池化层的输出到flatten层把所有元素“拍平”,然后到全连接层。

4.全连接层---->输出层

全连接层到输出层就是正常的神经元与神经元之间的邻接相连,通过softmax函数计算后输出到output,得到不同类别的概率值,输出概率值最大的即为该图片的类别。


 卷积神经网络的反向传播

传统的神经网络是全连接形式的,如果进行反向传播,只需要由下一层对前一层不断的求偏导,即求链式偏导就可以求出每一层的误差敏感项,然后求出权重和偏置项的梯度,即可更新权重。而卷积神经网络有两个特殊的层:卷积层和池化层。池化层输出时不需要经过激活函数,是一个滑动窗口的最大值,一个常数,那么它的偏导是1。池化层相当于对上层图片做了一个压缩,这个反向求误差敏感项时与传统的反向传播方式不同。从卷积后的feature_map反向传播到前一层时,由于前向传播时是通过卷积核做卷积运算得到的feature_map,所以反向传播与传统的也不一样,需要更新卷积核的参数。下面我们介绍一下池化层和卷积层是如何做反向传播的。

在介绍之前,首先回顾一下传统的反向传播方法:

1.通过前向传播计算每一层的输入值neti,jneti,j  (如卷积后的feature_map的第一个神经元的输入:neti11neti11)

2.反向传播计算每个神经元的误差项δi,jδi,j ,δi,j=∂E∂neti,jδi,j=∂E∂neti,j,其中E为损失函数计算得到的总体误差,可以用平方差,交叉熵等表示。

3.计算每个神经元权重wi,jwi,j 的梯度,ηi,j=∂E∂neti,j⋅∂neti,j∂wi,j=δi,j⋅outi,jηi,j=∂E∂neti,j⋅∂neti,j∂wi,j=δi,j⋅outi,j

4.更新权重 wi,j=wi,j−λ⋅ηi,jwi,j=wi,j−λ⋅ηi,j(其中λλ为学习率)

卷积层的反向传播

由前向传播可得:

 i11 neto11outo11=outi11=activators(neti11)=conv(input,filter)=i11×h11+i12×h12+i21×h21+i22×h22=activators(neto11)=max(0,neto11)(4)(4) i11=outi11=activators(neti11) neto11=conv(input,filter)=i11×h11+i12×h12+i21×h21+i22×h22outo11=activators(neto11)=max(0,neto11)

neti11neti11表示上一层的输入,outo11outo11表示上一层的输出

首先计算卷积的上一层的第一个元素i11i11的误差项δ11δ11:

δ11=∂E∂neti11=∂E∂i11⋅∂i11∂neti11δ11=∂E∂neti11=∂E∂i11⋅∂i11∂neti11 (注意这里是
neti11neti11,因为
i11=f(neti11)i11=f(neti11),f表示激活函数,不是
neto11neto11)

注:原来这里写的是计算输入层的误差项是不准确的,这里的i11i11表示的是卷积层的上一层即可。

先计算∂E∂i11∂E∂i11

此处我们并不清楚∂E∂i11∂E∂i11怎么算,那可以先把input层通过卷积核做完卷积运算后的输出feature_map写出来:

neto11=i11×h11+i12×h12+i21×h21+i22×h22neto12=i12×h11+i13×h12+i22×h21+i23×h22neto12=i13×h11+i14×h12+i23×h21+i24×h22neto21=i21×h11+i22×h12+i31×h21+i32×h22neto22=i22×h11+i23×h12+i32×h21+i33×h22neto23=i23×h11+i24×h12+i33×h21+i34×h22neto31=i31×h11+i32×h12+i41×h21+i42×h22neto32=i32×h11+i33×h12+i42×h21+i43×h22neto33=i33×h11+i34×h12+i43×h21+i44×h22(5)(5)neto11=i11×h11+i12×h12+i21×h21+i22×h22neto12=i12×h11+i13×h12+i22×h21+i23×h22neto12=i13×h11+i14×h12+i23×h21+i24×h22neto21=i21×h11+i22×h12+i31×h21+i32×h22neto22=i22×h11+i23×h12+i32×h21+i33×h22neto23=i23×h11+i24×h12+i33×h21+i34×h22neto31=i31×h11+i32×h12+i41×h21+i42×h22neto32=i32×h11+i33×h12+i42×h21+i43×h22neto33=i33×h11+i34×h12+i43×h21+i44×h22

然后依次对输入元素ii,jii,j求偏导

i11i11的偏导:

∂E∂i11=∂E∂neto11⋅∂neto11∂i11=δ11⋅h11(6)(6)∂E∂i11=∂E∂neto11⋅∂neto11∂i11=δ11⋅h11

i12i12的偏导:

∂E∂i12=∂E∂neto11⋅∂neto11∂i12+∂E∂neto12⋅∂neto12∂i12=δ11⋅h12+δ12⋅h11(7)(7)∂E∂i12=∂E∂neto11⋅∂neto11∂i12+∂E∂neto12⋅∂neto12∂i12=δ11⋅h12+δ12⋅h11

i13i13的偏导:

∂E∂i13=∂E∂neto12⋅∂neto12∂i13+∂E∂neto13⋅∂neto13∂i13=δ12⋅h12+δ13⋅h11(8)(8)∂E∂i13=∂E∂neto12⋅∂neto12∂i13+∂E∂neto13⋅∂neto13∂i13=δ12⋅h12+δ13⋅h11

i21i21的偏导:

∂E∂i21=∂E∂neto11⋅∂neto11∂i21+∂E∂neto21⋅∂neto21∂i21=δ11⋅h21+δ21⋅h11(9)(9)∂E∂i21=∂E∂neto11⋅∂neto11∂i21+∂E∂neto21⋅∂neto21∂i21=δ11⋅h21+δ21⋅h11

i22i22的偏导:

∂E∂i22=∂E∂neto11⋅∂neto11∂i22+∂E∂neto12⋅∂neto12∂i22+∂E∂neto21⋅∂neto21∂i22+∂E∂neto22⋅∂neto22∂i22=δ11⋅h22+δ12⋅h21+δ21⋅h12+δ22⋅h11(10)(10)∂E∂i22=∂E∂neto11⋅∂neto11∂i22+∂E∂neto12⋅∂neto12∂i22+∂E∂neto21⋅∂neto21∂i22+∂E∂neto22⋅∂neto22∂i22=δ11⋅h22+δ12⋅h21+δ21⋅h12+δ22⋅h11

观察一下上面几个式子的规律,归纳一下,可以得到如下表达式:

⎡⎣⎢⎢⎢⎢⎢⎢000000δ11δ21δ3100δ12δ22δ3200δ13δ23δ33000000⎤⎦⎥⎥⎥⎥⎥⎥⋅[h22h12h21h11]=⎡⎣⎢⎢⎢⎢⎢⎢⎢∂E∂i11∂E∂i21∂E∂i31∂E∂i41∂E∂i12∂E∂i22∂E∂i32∂E∂i42∂E∂i13∂E∂i23∂E∂i33∂E∂i43∂E∂i14∂E∂i24∂E∂i34∂E∂i44⎤⎦⎥⎥⎥⎥⎥⎥⎥(11)(11)[000000δ11δ12δ1300δ21δ22δ2300δ31δ32δ33000000]⋅[h22h21h12h11]=[∂E∂i11∂E∂i12∂E∂i13∂E∂i14∂E∂i21∂E∂i22∂E∂i23∂E∂i24∂E∂i31∂E∂i32∂E∂i33∂E∂i34∂E∂i41∂E∂i42∂E∂i43∂E∂i44]

图中的卷积核进行了180°翻转,与这一层的误差敏感项矩阵deltai,j)deltai,j)周围补零后的矩阵做卷积运算后,就可以得到∂E∂i11∂E∂i11,即

∂E∂ii,j=∑m⋅∑nhm,nδi+m,j+n∂E∂ii,j=∑m⋅∑nhm,nδi+m,j+n

第一项求完后,我们来求第二项∂i11∂neti11∂i11∂neti11

∵i11∴∂i11∂neti11∴δ11=outi11=activators(neti11)=f′(neti11)=∂E∂neto11=∂E∂i11⋅∂i11∂neti11=∑m⋅∑nhm,nδi+m,j+n⋅f′(neti11)(12)(12)∵i11=outi11=activators(neti11)∴∂i11∂neti11=f′(neti11)∴δ11=∂E∂neto11=∂E∂i11⋅∂i11∂neti11=∑m⋅∑nhm,nδi+m,j+n⋅f′(neti11)

此时我们的误差敏感矩阵就求完了,得到误差敏感矩阵后,即可求权重的梯度。

由于上面已经写出了卷积层的输入neto11neto11与权重hi,jhi,j之间的表达式,所以可以直接求出:

∂E∂h11=∂E∂neto11⋅∂neto11∂h11+...+∂E∂neto33⋅∂neto33∂h11=δ11⋅h11+...+δ33⋅h11(13)(13)∂E∂h11=∂E∂neto11⋅∂neto11∂h11+...+∂E∂neto33⋅∂neto33∂h11=δ11⋅h11+...+δ33⋅h11

推论出权重的梯度

∂E∂hi,j=∑m∑nδm,noutoi+m,j+n(14)(14)∂E∂hi,j=∑m∑nδm,noutoi+m,j+n

偏置项的梯度

∂E∂b=∂E∂neto11∂neto11∂wb+∂E∂neto12 网页标题:【深度学习系列】卷积神经网络详解(二)——自己手写一个卷积神经网络
文章路径:http://www.shufengxianlan.com/qtweb/news49/394699.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联