HTML5技术

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

字号+ 作者:H5之家 来源:H5之家 2017-11-23 08:01 我要评论( )

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

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

 

 卷积神经网络的前向传播

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

 

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

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

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

 

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

\begin{equation}
\begin{aligned}
\ net_{o_{11}}&= conv (input,filter)\\
&= i_{11} \times h_{11} + i_{12} \times h_{12} +i_{21} \times h_{21} + i_{22} \times h_{22}\\
&=1 \times 1 + 0 \times (-1) +1 \times 1 + 1 \times (-1)=1
\end{aligned}
\end{equation}

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

\begin{equation}
\begin{aligned}
out_{o_{11}} &= activators(net_{o_{11}}) \\
&=max(0,net_{o_{11}}) = 1
\end{aligned}
\end{equation}

  其他神经元计算方式相同

 

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

  

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

\begin{equation}
\begin{aligned}
net_{m_{11}} &= max(o_{11},o_{12},o_{21},o_{23}) = 1\\
&out_{m_{11}} = net_{m_{11}} = 1
\end{aligned}
\end{equation}

 

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

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

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

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

 

 卷积神经网络的反向传播

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

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

  1.通过前向传播计算每一层的输入值$net_{i,j}$  (如卷积后的feature_map的第一个神经元的输入:$net_{i_{11}}$)

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

  3.计算每个神经元权重$w_{i,j}$ 的梯度,$\eta_{i,j} = \frac{\partial E}{\partial net_{i,j}} \cdot \frac{\partial net_{i,j}}{\partial w_{i,j}} = \delta_{i,j} \cdot out_{i,j}$

  4.更新权重 $w_{i,j} = w_{i,j}-\lambda \cdot \eta_{i,j}$(其中$\lambda$为学习率)

  卷积层的反向传播

  由前向传播可得:

\begin{equation}
\begin{aligned}
\ net_{o_{11}}&= conv (input,filter)\\
&= i_{11} \times h_{11} + i_{12} \times h_{12} +i_{21} \times h_{21} + i_{22} \times h_{22}\\
out_{o_{11}} &= activators(net_{o_{11}}) \\
&=max(0,net_{o_{11}})
\end{aligned}
\end{equation}

  所以上一层的输出也就是这一层的输入,即:$out_{i_{11}} = activators(net_{i_{11}}) = i_{11}$

  首先计算输入层的误差项$\delta_{11}$:

$$\delta_{11} = \frac{\partial E}{\partial net_{o_{11}}} =\frac{\partial E}{\partial i_{11}} \cdot \frac{\partial i_{11}}{\partial net_{i_{11}}}$$(注意这里是$net_{i_{11}}$,代表的是上一层的输入,不是$net_{o_{11}}$)

  先计算$\frac{\partial E}{\partial i_{11}} $

  此处我们并不清楚$\frac{\partial E}{\partial i_{11}}$怎么算,那可以先把input层通过卷积核做完卷积运算后的输出feature_map写出来:

 

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • Linux系列教程(二十二)——Linux的bash变量 - YSOcean

    Linux系列教程(二十二)——Linux的bash变量 - YSOcean

    2017-11-19 08:00

  • 极简版ASP.NET Core学习路径及教程 - 腾飞(Jesse)

    极简版ASP.NET Core学习路径及教程 - 腾飞(Jesse)

    2017-11-17 14:02

  • [深度学习]实现一个博弈型的AI,从五子棋开始(1) - xerwin

    [深度学习]实现一个博弈型的AI,从五子棋开始(1) - xerwin

    2017-11-15 12:01

  • JavaScprit30-5 学习笔记 - 喵20

    JavaScprit30-5 学习笔记 - 喵20

    2017-10-23 11:07

网友点评