卷积神经网络CNN理解

虽然在机器学习和深度学习这块投入了不少精力,可是近一段时间在看论文的过程中,对一些细节方面和算法深层次的原因方面总感觉有些不得其意,所以回过头来,将基础部分查漏补缺。

首先,我们解释一下为什么卷积神经网络要比传统的神经网络要好。图像是由一个个像素点组成的,以灰色28*28大小的图像为例,如果使用全连接的网络结构,网络中的神经元与相邻层上的每个神经元均连接,如下图所示,那么输入层就会有28*28=784个神经元,假若隐含层采用15个神经元,大约会需要784*15=11760个权重,加上输出层的10个神经元,整个三层神经网络总共需要784*15*10=117600个权重(除去偏置项),参数是如此巨大,计算复杂,使得调参变得很困难,所以不建议使用传统神经网络。而CNN采用了局部连接,权值共享和下采样三种方法减少参数量。

卷积神经网络(CNN)是一种多层的监督学习神经网路,包括卷积层(Conv)、池化层(Pooling),全连接层(FC),其中卷积层和池化层是实现卷积网络特征提取功能的核心模块。通常情况下,CNN的常见架构模式为:

INPUT-->[[Conv]*N-->Pool?]*M-->[FC]*K

也就是N个卷积层叠加,然后可选叠加一个Pooling层,重复这个子结构M次,最后叠加K个全连接层。

卷积神经网络包含了一个由卷积层和池化层构成的特征提取器,在卷积层中,一个神经元只与部分邻层神经元相连【局部连接】。在CNN中的卷积层中包含多个feature map, 每个feature map 由一些矩形排列的神经元组成(例如某个feature map的大小为m*n,那么该map共有m*n个神经元),同一个feature map的神经元通共享权值(卷积核)【权值共享】。共享权值带来的直接好处就是减少网络各层之间的连接,同时降低过拟合的风险。子采样也是池化,通常有均值子采样(mean pooling)和最大值子采样(max pooling)两种形式,通过池化来降低卷积层输出的特征向量【池化】。卷积和池化大大简化了模型复杂度,减少了模型的参数。

卷积运算

对于一个尺寸大小为N*N的feature map,如果步幅大小为S,filter的尺寸大小为F*F,Zero Padding的数量是P,那么经过卷积运算得到M*M大小的feature map,其中。为了更好的描述卷积计算过程,我们假设输入map为X,filter为W,输出的map为A,用表示X中第i行第j列的元素,用表示W中第m行第n列的权重,用表示filter的偏置项,用表示A中第p行第q列中的元素,f为激活函数,则计算卷积的公式为。举一个小例子,设有一个5*5的feature map,使用一个3*3的filter进行卷积,步幅为S=1,无Zero Padding,那么就得到一个3*3的feature map, 下面的动图很好的展示了计算过程。

前面讲的是深度为1的卷积层的计算方法,如果深度大于1,卷积的运算应该是什么样的?我也一直都很纠结这个问题,其实只要把上面的公式进行扩展一下即可。,其中D是深度。每个卷积层有多个filter,每个filter和原始图像进行卷积后,就可以得到一个feature map,卷积后的feature map的深度和卷积层的filter的个数是相同的。下面的动图展示了包含两个filter的卷积层的计算。输入map为7*7*3,步幅S=2, 在输入元素的周围补了一圈0,P=1,经过两个3*3*3filter的卷积,得到了3*3*2的输出map,输出map的深度是和卷积核的个数是一致的。

Tensorflow代码实现

tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)

函数作用:对输入数据进行二维卷积操作

参数说明:

  • input:输入,A 4-D tensor,shape为[batch_size, input_height, input_width, input_channels],数据类型必须为float32或者float64
  • filter: 卷积核,A 4-D tensor,shape为[filter_height, filter_width, input_channels, output_channels], 和input有相同的数据类型
  • strides: 步长,一个长度为4的一维列表,每一位对应input中每一位对应的移动步长,在使用中,由于input的第一维和第四维不参与卷积运算,所以strides一般为[1, X, X, 1]
  • padding: 填充方式,一个字符串,取值‘SAME’或者‘VALID’. 当padding = ‘SAME’时,tensorflow会自动对原图像进行补零操作,从而使得输入和输出的图像大小一致;当padding = ‘VALID’时, 采用不填充的方式,会根据计算公式缩小原图像的大小,计算公式为(W-F+2P)/S+1, W是图像大小,F为卷积核大小,P是填充数量,S是步长。
  • use_cudnn_on_gpu=None : 可选布尔值,默认为True

池化

池化层的主要目的是通过降采样的方式,在不影响图像质量的情况下,压缩图片,减少参数。子采样有两种形式,一种是均值子采样,即是对一个区域里的元素求平均值;另一种就是最大值采样,即是在一个区域中寻找最大值,如下图所示。

# 平均池化
tf.nn.avg_pool(value, ksize, strides, padding, name=None)
# 最大化池化
tf.nn.max_pool(value, ksize, strides, padding, name=None)

函数作用:对输入进行池化操作

参数说明:

  • value:池化输入,A 4-D tensor,shape为[batch_size, input_height, input_width, input_channels],数据类型为float32,float64,qint8,quint8,qint32
  • ksize:池化窗口大小,A 4-D tensor,一般为[1, X, X, 1]
  • strides:步长,一般为[1, X, X, 1],同上述卷积运算的strides
  • padding:填充,一个字符串取值‘SAME’或者‘VALID’,同上述卷积运算的padding

对于卷积网络的架构,可以参考我的另一篇博客,点这里,介绍了最常用的一些CNN网络架构,在这里就不在赘述。

猜你喜欢

转载自blog.csdn.net/weixin_42111770/article/details/80808412