CNN
CNN的基本结构包括两层,其一为特征提取层,每个神经元的输入与前一层的局部接受域相连,并提取该局部的特征。一旦该局部特征被提取后,它与其它特征间的位置关系也随之确定下来;其二是特征映射层,网络的每个计算层由多个特征映射组成,每个特征映射是一个平面,平面上所有神经元的权值相等。特征映射结构采用影响函数核小的sigmoid函数作为卷积网络的激活函数,使得特征映射具有位移不变性。此外,由于一个映射面上的神经元共享权值,因而减少了网络自由参数的个数。卷积神经网络中的每一个卷积层都紧跟着一个用来求局部平均与二次提取的计算层,这种特有的两次特征提取结构减小了特征分辨率。

问题

使用MNIST数据集进行训练,识别图片中的手写数字(0到9共10类)。

思路

使用一个简单的CNN网络结构如下,括号里边表示tensor经过本层后的输出shape:

输入层(28 * 28 * 1)
卷积层1(28 * 28 * 32)
pooling层1(14 * 14 * 32)
卷积层2(14 * 14 * 64)
pooling层2(7 * 7 * 64)
全连接层(1 * 1024)
softmax层(10)

函数说明

在撸代码前,先对几个会用到的主要函数中的主要参数进行说明。

1.矩阵变换
tf.truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)

随机产生一个形状为shape的服从截断正态分布(均值为mean,标准差为stddev)的tensor。
截断的方法根据官方API的定义为,如果单次随机生成的值偏离均值2倍标准差之外,就丢弃并重新随机生成一个新的数。

2.卷积层
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)

1)input
input是一个形状为[batch, in_height, in_width, in_channels]的tensor:
a)batch: 每次batch数据的数量。

c) in_channels: 输入通道数量。
如输入层的图片经过了二值化,则通道为1,如果输入层的图片是RGB彩色的,则通道为3;再如卷积层1有32个通道,则pooling层1的输入(卷积层1的输出)即为32通道。

2) filter
filter是一个形状为[filter_height, filter_width, in_channels, out_channels]的tensor:
a) filter_height, filter_width : 卷积核的高与宽。
如卷积层1中的卷积核,filter_height, filter_width都为28。
b) in_channels : 输入通道数量。
c) out_channels : 输出通道的数量。
如输入数据经过卷积层1后,通道数量从1变为32。

3) strides
strides是指滑动窗口(卷积核)的滑动规则,包含4个维度,分别对应input的4个维度,即每次在input tensor上滑动时的步长。其中batch和in_channels维度一般都设置为1,所以形状为[1, stride, stride, 1]。

4) padding

3.池化层
tf.nn.max_pool(value, ksize, strides, padding, data_format=’NHWC’, name=None)

1) value
以tf.nn.conv2d()函数的参数input理解即可。
2)ksize
滑动窗口(pool)的大小尺寸,这里注意这个大小尺寸并不仅仅指2维上的高和宽,ksize的每个维度同样对应input的各个维度(只是大小,不是滑动步长)。
同样的,batch和in_channels维度多设置为1。
如pooling层1的ksize即为[1, 2, 2, 1],即用一个2*2的窗口做pooling。
3)strides
同tf.nn.conv2d()函数的参数strides。
4)padding

4.dropout 防止过拟合
tf.nn.dropout(x, keep_prob, noise_shape=None, seed=None, name=None)

1)x 输入tensor。
2)keep_prob : x中每个元素的输出概率,输出为原值或0。