Tensorflow卷积神经网络(CNN)手写数字识别示例学习

目录

一、问题描述

二、数据描述

三、网络结构

1. 输入层

2. 卷积层

3. 池化层

4. 全连接层

5. 输出层

四、示例网络结构

五、程序解读

1.  加载MNIST数据集

2.  创建Session和占位符

3.  定义卷积层1的权重和偏置量

4.  卷积层1

5.  池化层1

6.  定义卷积层2的权重和偏置量

7.  卷积层2和池化层2

8.  全连接层

9.  输出层

六、参考资料

七、源码

一、问题描述

利用卷积神经网络将MNIST数据集的28×28像素的灰度手写数字图片识别为相应的数字。

二、数据描述

MNIST数据集是28×28像素的灰度手写数字图片,其中数字的范围从0到9

具体如下所示(参考自Tensorflow官方文档):

文件

内容

train-images-idx3-ubyte.gz

训练集图片,55000张训练图片, 5000张验证图片

train-labels-idx1-ubyte.gz

训练集图片对应的数字标签

t10k-images-idx3-ubyte.gz

测试集图片,10000张图片

t10k-labels-idx1-ubyte.gz

测试集图片对应的数字标签

《Tensorflow卷积神经网络(CNN)手写数字识别示例学习》

三、网络结构

卷积神经网络一般包含以下几层:

    输入层:用于将数据输入到神经网络中

    卷积层:使用卷积核提取特征

    激励层:对卷积操作的线性运算进行非线性映射

    池化层:卷积得到的特征图进行稀疏处理,减少数据量

    全连接层:在网络的末端进行重新拟合,恢复特征,减少特征的损失

    输出层:输出结果

1. 输入层

卷积神经网络中输入层的结构可以是多维的,例如MNIST数据集中是28×28像素的灰度图片,因此输入为28×28的的二维矩阵。

2. 卷积层

卷积层是使用卷积核提取特征,在卷积层中需要理解局部感受野和共享权值。

局部感受野:类似于一个滑动窗口,以窗口的范围去提取对应范围的神经元携带的特征。

共享权值:根据局部感受野提取特征,原始数据中的一部分神经元与卷积层中的一个神经元相连接,每一条线对应一个权重,而在卷积层中,对于同一个卷积核,权重是相同的。

《Tensorflow卷积神经网络(CNN)手写数字识别示例学习》

上图为卷积操作示意图(图片来源于网络,侵删),其中Image表示图片数据矩阵,游走的窗口为卷积核矩阵,x0、x1表示的是权重,一个N×N的图像经过M×M的卷积核卷积后将得到(N-M+1)×(N-M+1)的输出。

卷积后输出的矩阵数据成为特征映射图,一个卷积核输出一个特征映射图,卷积操作是一种线性计算,因此通常在卷积后进行一次非线性映射。

3. 池化层

池化层是将卷积得到的特征映射图进行稀疏处理,减少数据量,操作与卷积基本相似,不同的是卷积操作是一种线性计算,而池化的计算方法更多样化,一般有如下计算方式:

最大池化:取样池中的最大值作为池化结果

均值池化:取样池中的平均值作为池化结果

还有重叠池化、均方池化、归一化池化等方法。

4. 全连接层

在网络的末端对提取后的特征进行恢复,重新拟合,减少因为特征提取而造成的特征丢失。全连接层的神经元数需要根据经验和实验结果进行反复调参。

5. 输出层

输出层用于将最终的结果输出,针对不同的问题,输出层的结构也不相同,例如MNIST数据集识别问题中,输出层为有10个神经元的向量。

四、示例网络结构

示例模型包括输入层、两个卷积层、两个池化层、全连接层和输出层,其中卷积和池化操作的特征图输出大小计算公式为:

《Tensorflow卷积神经网络(CNN)手写数字识别示例学习》

ImageWidth:图片宽度

Padding:边缘补齐像素数

KernelSize:卷积核宽度

Stride:移动步长

具体模型结构如下所示:

《Tensorflow卷积神经网络(CNN)手写数字识别示例学习》

五、程序解读

Tensorflow中使用图来表示计算任务,在会话(Session)中执行图,使用 tensor 表示数据.通过变量(Variable)维护状态,使用 feed 和 fetch 可以为任意的操作赋值或者从其中获取数据.

1.  加载MNIST数据集

mnist =input_data.read_data_sets("MNIST_data", one_hot=True)

命令会自动下载MNIST数据集,存放在”MNIST_data”目录下,也可以手动下载数据集后放入此目录下。执行read_data_sets()函数后将会返回一个DataSet实例,其中包含训练数据、验证数据和测试数据。

2.  创建Session和占位符

sess =tf.InteractiveSession()
x =tf.placeholder("float", shape=[None, 784])
y_ =tf.placeholder("float", shape=[None, 10])

x和y_都是tensor,其中x表示输入数据,由于是28×28像素的灰度图片,因此输入为784维的向量。y_表示模型输出,为0-9的数字,因此是10维的向量。

3.  定义卷积层1的权重和偏置量

w_conv1 = tf.Variable(tf.truncated_normal([5,5, 1, 32], stddev=0.1))
b_conv1 =tf.Variable(tf.constant(0.1, shape=[32]))

卷积操作的计算公式为:W × X + b

[5, 5, 1,32]表示卷积核的大小为5×5,输出为32,即共有32个卷积核,卷积操作会产生32个特征映射图。

其中w_conv1表示权重W,由正太分布截取得出。b_conv1表示偏置量,初始值均为0.1,由于卷积操作会输出32个特征图,因此偏置量的维度为32。

4.  卷积层1

x_image =tf.reshape(x, [-1,28,28,1])

将输入tensor x 调整成为28×28矩阵形式。

r_conv1 = tf.nn.conv2d(x_image,w_conv1, strides=[1, 1, 1, 1], padding='SAME') + b_conv1
h_conv1 = tf.nn.relu(r_conv1)

进行卷积操作W × X + b,得到线性变化的结果r_conv1,再利用Tensorflow的relu规则进行非线性映射,出的卷积的结果h_conv1。

5.  池化层1

h_pool1 = tf.nn.max_pool(h_conv1,ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

采用了最大池化方法,其中ksize表示取样池的大小,strides表示步长,padding表示边缘补齐方法,SAME方式会在图片边缘补0,补齐边缘像素为1,最终得出池化结果h_pool1。

6.  定义卷积层2的权重和偏置量

w_conv2 =tf.Variable(tf.truncated_normal([5, 5, 32, 64], stddev=0.1))
b_conv2 =tf.Variable(tf.constant(0.1, shape=[64]))

卷积层2的输入为32张特征映射图,有64个卷积核,最终将输出64个特征映射图。

7.  卷积层2和池化层2

r_conv2 = tf.nn.conv2d(h_pool1,w_conv2, strides=[1, 1, 1, 1], padding='SAME') + b_conv1
h_conv2 =tf.nn.relu(r_conv2)
h_pool2 = tf.nn.max_pool(h_conv2,ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

经过卷积层2和池化层2后,得到64张7×7的特征映射图。

8.  全连接层

W_fc1 =tf.Variable(tf.truncated_normal([7 * 7 * 64, 1024], stddev=0.1))
b_fc1 =tf.Variable(tf.constant(0.1, shape=[1024]))

全连接层设有1024个神经元,本层的神经元数需要根据经验和实验结果进行反复调参确定。

h_pool2_flat= tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 =tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

将第二层池化后的数据调整为7×7×64的向量,与全连接层的权重进行矩阵相乘,然后进行非线性映射得到1024维的向量。

9.  输出层

W_fc2 = tf.Variable(tf.truncated_normal([1024,10], stddev=0.1))
b_fc2 = tf.Variable(tf.constant(0.1,shape=[10]))
y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop,W_fc2) + b_fc2)

输出层为10维的向量,通过softmax函数输出。

六、参考资料

深度学习(四)卷积神经网络入门学习(1)

深度学习之卷积神经网络CNN及tensorflow代码实现示例

TensorFlow 官方文档

七、源码

Github地址:Tensorflow卷积神经网络(CNN)手写数字识别

点赞