参考:

参考:tensorflow书

1、输入层

输入层是神经网络的输入,在图像处理的卷积神经网络中,它代表一张图片的像素矩阵,一般来说三维矩阵代表一张图片,三维矩阵的长和宽分别代表了图片的大小,三维矩阵的深度代表了图像的色彩通道。比如黑白图片的深度为1,在RGB色彩模式下,图像的深度为3(也可以称作RGB三个通道)。从输入层开始,卷积神经网络通过不同的神经网络结构将上一层的三维矩阵转化为下一层的三维矩阵,直到最后的全连接层。

2、卷积层

 卷积层中每个节点输入是上一层神经网络的小块,这个小块的大小通常根据实际需求来定,如3x3, 5x5等,卷积层通过将神经网络的每小块进行深入分析得到抽象程度更高的特征。一般来说,通过卷积层处理后的节点矩阵深度会增加。

经过卷积后图片的大小变化后结果如下:

(输入图片大小-卷积层大小+2*(填充0的圈数))/步长  +1

 其中,卷积层输出的深度=卷积核(filter)的个数(也可以称为卷积层数),其次卷积核的个数设定是一个经验值,是通过调参所得,对于不同的图像训练集,深度的设置会有所不同。以下图为例:

3d点云卷积神经网络源代码 三维卷积神经网络_卷积

上图左边的32x32x3为输入层,经过一个5x5x3的卷积核(filter)处理后,得到最右边的结果。

假若我们使用6个5x5x3的卷积核,那么就会得到6个分开的activation maps:

3d点云卷积神经网络源代码 三维卷积神经网络_池化_02

上图新得到28x28x6的图片,然后跟对应的激活函数,如下图所示。

3d点云卷积神经网络源代码 三维卷积神经网络_卷积_03

动态图展示如下图所示:

3d点云卷积神经网络源代码 三维卷积神经网络_卷积核_04

我们以通过过滤器将2x2x3的节点矩阵转化为1x1x5的单位节点矩阵为例。一个过滤器的前向传播过程和全连接层相似,它总共需要2x2x3x5+5=65个参数,其中+5为偏置项参数的个数。假设使用

3d点云卷积神经网络源代码 三维卷积神经网络_3d点云卷积神经网络源代码_05

来表示对于输出单位节点矩阵中的第i个节点,过滤器输入节点(x,y,z)的权重,使用3d点云卷积神经网络源代码 三维卷积神经网络_池化_06表示第i个输出节点对应的偏置项参数,那么单位矩阵中的第i个节点的取值g(i)为:

3d点云卷积神经网络源代码 三维卷积神经网络_池化_07

其中ax,y,z表示过滤器中节点(x,y,z)的取值,f为激活函数。计算过程如下图所示:

3d点云卷积神经网络源代码 三维卷积神经网络_3d点云卷积神经网络源代码_08

同样的,通过上图的计算方法,可以得到对应的g(1)到g(4)的值。

在卷积神经网络中,每一个卷积层中使用的过滤器中的参数都是一样的,这是卷积神经网络一个非常重要的性质,以mnist手写体数字识别为例,无论数字'1'出现在左上角还是右下角,图片的种类都是不变的,因为左上角和右下角使用的过滤器的参数相同,所以通过卷积层后无论数字在图像上的哪个位置,得到结果都是一样的。

影响矩阵输出大小的因素包括:1、是否使用全0填充.  2、步长的选择.     

共享每一个卷积层的过滤器参数可以大幅减少神经网络上的参数,举个例子,若输入层矩阵的维度是32x32x3,假设第一层卷积层使用尺寸为5x5,深度为16的滤波器,那么这个卷积层的参数个数为5x5x3x16+16=1216个,假若使用500个隐藏节点的全连接层将会有1.5百万个参数,相比之下,使用卷积层能大幅减少参数数量。



filter_weight=tf.get_variable('weights',shape=[5,5,3,16],initializer=tf.truncated_normal_initializer(stddev=0.1))#卷积核的参数,分别对应[filter_height,filter_width,in_channels,out_channels],具体含义对应[卷积核高度,卷积核宽度,图像通道数,卷积核个数]
bias=tf.get_variable('biases',shape=[16],initializer=tf.constant_initializer(0.1))     
conv=tf.nn.conv2d(input,filter_weight,strides=[1,1,1,1],padding='SAME')     #函数的input为当前层的节点矩阵,分别对应:[batch,in_height,in_width,in_channels],具体含义是[训练时一个batch的图片数量,图片高度,图片宽度,图像通道数]。第二个参数为卷积层权重。第三个参数为不同维度的步长,第一维和最后维要求一定是1,因为卷积层步长只对矩阵的长和宽有效。最后个参数padding是填充的方法,其中SAME表示添加全0填充,VALID表示不添加
bias=tf.nn.bias_add(conv,biases)  #为矩阵不同位置上的节点都加上同样的偏置项
actived_conv=tf.nn.relu(bias)
###################
##或者
input = tf.Variable(tf.random_normal([1,5,5,5]))
filter = tf.Variable(tf.random_normal([3,3,5,1]))
op = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='VALID')  

#对于步长不为1的,则设置[1,stride,stride,1]
input = tf.Variable(tf.random_normal([10,5,5,5]))
filter = tf.Variable(tf.random_normal([3,3,5,7]))
op = tf.nn.conv2d(input, filter, strides=[1, 2, 2, 1], padding='SAME') #每张图都有7张的3x3的feature map,输出的shape就是[10,3,3,7]



 3、池化层

池化层不会改变三维矩阵的深度,但可以缩小矩阵的大小。池化操作可以认为是将一张分辨率较高的图片转化为分辨率较低的图片,通过池化层可以进一步缩小最后全连接层中节点的个数,从而达到减少整个神经网络中参数的目的。使用池化层即可以加快计算速度也能防止过拟合的作用。

一般来说池化层分两类:最大池化层(max pooling),这是被使用最多的池化层结构。以及使用平均值操作的池化层称为平均池化层(average pooling)。

和卷积层的过滤器类似,池化层的过滤器也需要人工设定过滤器的尺寸、是否使用全0填充,以及过滤器移动的步长等设置。卷积层和池化层中过滤器移动的方式是相似的,唯一区别在于卷积层使用的过滤器是横跨整个深度的,池化层使用的过滤器只影响一个深度上的节点。所以池化层的过滤器除了在长和宽两个维度移动之外,它还需要在深度这个维度移动。池化层过程以如下图为例:

3d点云卷积神经网络源代码 三维卷积神经网络_3d点云卷积神经网络源代码_09

如下代码实现了最大池化层的前向传播算法:



pool=tf.nn.max_pool(active_conv,ksize=[1,3,3,1],strides=[1,2,2,1],padding='SAME')  #active_conv为当前层节点矩阵,和tf.nn.conv2d函数的第一个参数一致,ksize提供过滤器的尺寸,过滤器的尺寸是一个长度为4的一维数组,这个数组第一个和最后个必须为1,意味着池化层的过滤器是不可以跨不同输入样例或者节点矩阵深度的。strides提供步长信息,padding决定是否全用0填充,实际应用中池化层过滤器尺寸一般为[1,2,2,1]或[1,3,3,1]。平均池化层的函数为:tf.nn.max_pool(...),参数和tf.nn.max_pool一致



 

4、全连接层

经过较多轮卷积层和池化层处理后,卷积神经网络最后层一般由1-2个全连接层得到最后的分类结果。经过几轮卷积层和池化层处理后,图像信息被抽象成信息含量更高的特征。我们可以将卷积层和池化层看成自动图像特征提取的过程,在特征提取完后,仍需要使用全连接层来完成分类任务。

5、softmax层

该层主要用于分类问题,将最后的输出结果转化为归一化的概率数据。