『DeepLearning』tensorFlow搭建CNN-mnist上手

一直关注DL,从TensorFlow开源就开始尝试,在 [ 极客学院 Wiki ] 看教程。不过三天打鱼两天晒网,雄关漫道真如铁,而今迈步从头越,以期望能够相互讨论不断学习。

CNN

CNN(Convolutional Neural Networks) 卷积神经网络是一个多层的神经网络,每层由多个二维平面组成,而每个平面由多个独立神经元组成。简单讲就是把一个图片的数据传递给CNN,原图层是由RGB组成(是由像素点组成的平面矩阵),然后CNN把它的厚度加厚,长宽变小,每做一层都这样被拉长,最终放入全连接层学习,学习其类别标签,获得对新样本的预测能力。

原理这里就不啰嗦了,推荐看这个博客Deep Learning(深度学习)学习笔记整理系列之(一)

当然有视频教程:google 在 udacity 上的 CNN 教程, 个人感觉视频节奏太慢。

一些主要概念

局部感知&参数共享

局部感知:每个神经元其实没有必要对全局图像进行感知,只需要对局部进行感知,然后在更高层将局部的信息综合起来就得到了全局的信息。这样可以大大减小参数量。

图2

图2

在上右图中,假如每个神经元只和10×10个像素值相连,那么权值数据为1000000×100个参数,减少为原来的万分之一。而那10×10个像素值对应的10×10个参数,其实就相当于卷积操作。

经过上面操作之后仍然参数较多,就有了权值共享。在上面的局部连接中,每个神经元都对应100个参数,一共1000000个神经元,如果这1000000个神经元的100个参数都是相等的,那么参数数目就变为100了。

卷积核

下图是一个3×3的卷积核在5×5的图像上做卷积的过程。每个卷积都是一种特征提取方式,就像一个筛子,将图像中符合条件(激活值越大越符合条件)的部分筛选出来。

图3

图3

只有一个卷积核的时候,显然特征提取是不充分的,通过添加多卷积核,比如32个,学习得到32个特征

equal

滑动的步长-stride

上面卷积那张图片3从左到右,每次滑动的时候只移动一格,步长为1,如果它一次滑动n格,这就是步长n。

卷积的边界处理-padding

如图3所示,卷积后的矩阵只有3*3,比原来的图片要小了,因为边界没有了,所以要考虑这个边界的问题,网上说卷积的边界处理有两种方式:

  • 丢掉边界,也就是就按右边那个缩小的矩阵来。
  • 复制边界,也就是把左边的最外层原封不动地复制过去,长宽不变。

tensorflow中conv2d的”padding”参数可以设为两个值SAME,VALID;

SAME:edge_row = (kernel_row - 1) / 2;edge_cols = (kernel_cols - 1) / 2;

VALID:edge_row = edge_cols = 0;

edge_row就是边的行数,kernel_row就是卷积核的行数

Down-pooling

equal

池化很好立即,如上图,池化分为两种,一种是最大池化,在选中区域中找最大的值作为抽样后的值,另一种是平均值池化,把选中的区域中的平均值作为抽样后的值,这样做的,原因是为了后面全连接的时候减少连接数。

全连接

权重最多的地方,每一个输出都可以看成前一层的每一个结点乘以一个权重系数W,最后加上一个偏置值b得到。

img

由于全连接层参数冗余(仅全连接层参数就可占整个网络参数80%左右),近期一些性能优异的网络模型如ResNet和GoogLeNet等均用全局平均池化(global average pooling,GAP)取代FC来融合学到的深度特征,最后仍用softmax等损失函数作为网络目标函数来指导学习过程。

MNIST上手

MNIST是一个入门级的计算机视觉数据集,它包含各种手写数字图片,也包含每一张图片对应的标签,告诉我们这个是数字几。

这里就不赘述,参考MNIST机器学习入门

关于TensorFlow的安装,windows可以参考:win64安装TensorFlow,ubuntu直接pip install tensorflow。

整体结构

主要参考 Yann LeCun 在 1998 年发表的论文 Gradient-Based Learning Applied to Document Recognition 中所提出的经典的 LeNet5网络
- 输入:28*28的图片,1通道。
- 第1次卷积:5x5,步长1x1,共32个卷积核。out:28x28x32。
- 第1次pooling:2x2核,out:14x14x32
- 第2次卷积:5x5,步长1x1,共64个卷积核。out:14x14x64。
- 第2次pooling:2x2核,out:7x7x64。
- 全连接层1:1024个神经元的全连接层,把池化层输出的张量reshape成一些向量,乘上权重矩阵,加上偏置,然后对其使用ReLU
- dropout:减少过拟合,用一个placeholder来代表一个神经元的输出在dropout中保持不变的概率。这样我们可以在训练过程中启用dropout,在测试过程中关闭dropout
- 全连接层+softmax层

数据准备

自动下载和安装这个数据集源代码:源代码

import input_data
from tensorflow.examples.tutorials.mnist import input_data
# 读取数据
mnist = input_data.read_data_sets("D:/data/minist/", one_hot=True)
# seesion初始化变量
sess = tf.InteractiveSession()
# 为输入图像和目标输出类别创建节点,来开始构建计算图。x和y是占位符
x = tf.placeholder("float", shape=[None, 784])  # 784=28x28
y_ = tf.placeholder("float", shape=[None, 10])

定义2维的 convolutional 图层

def conv2d(x, W):
    # stride [1, x_movement, y_movement, 1]
    # Must have strides[0] = strides[3] = 1
    # strides 就是跨多大步抽取信息
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

定义pooling

def max_pool_2x2(x):
    # stride [1, x_movement, y_movement, 1]
    # 用pooling对付跨步大丢失信息问题
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

第一层卷积+pooling

'''1. conv1 layer'''
#  把x_image的厚度1加厚变成了32
W_conv1 = weight_variable([5, 5, 1, 32])  # patch 5x5, in size 1, out size 32
b_conv1 = bias_variable([32])
x_image = tf.reshape(x, [-1, 28, 28, 1])  # 最后一个1表示数据是黑白的
# 构建第一个convolutional层,然后加一个非线性化的处理relu
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)  # output size 28x28x32
# 经过pooling后,长宽缩小为14x14
h_pool1 = max_pool_2x2(h_conv1)  # output size 14x14x32

第二层卷积+pooling

'''2. conv2 layer'''
# 把厚度32加厚变成了64
W_conv2 = weight_variable([5, 5, 32, 64])  # patch 5x5, in size 32, out size 64
b_conv2 = bias_variable([64])
# 构建第二个convolutional层
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)  # output size 14x14x64
# 经过pooling后,长宽缩小为7x7
h_pool2 = max_pool_2x2(h_conv2)  # output size 7x7x64

全连接层+pooling

# 变成1024
W_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])
# [n_samples, 7, 7, 64] ->> [n_samples, 7*7*64]
# 把pooling后的结果变平
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)

keep_prob = tf.placeholder("float")
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

softmax

# 最后一层,输入1024,输出size 10,用 softmax 计算概率进行分类的处理
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
# 向量化后的图片x和权重矩阵W相乘,加上偏置b,然后计算每个分类的softmax概率值。
y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)

定义损失函数

# 损失函数定义为交叉熵
cross_entropy = -tf.reduce_sum(y_ * tf.log(y_conv))
# 最梯度下降法让交叉熵下降,步长为0.01
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)  # 3333333333 test accuracy 0.9922
# train_step = tf.train.GradientDescentOptimizer(1e-3).minimize(cross_entropy)

定义评估模型

# 计算分类的准确率,tf.equal 来检测我们的预测是否真实标签匹配
correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))
# 计算出匹配结果correct_prediction的平均值为,如[1,0,1,1]为0.75
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
sess.run(tf.initialize_all_variables())

训练模型

for i in range(20000):
    batch = mnist.train.next_batch(50)
    if i % 100 == 0:
        train_accuracy = accuracy.eval(feed_dict={
            x: batch[0], y_: batch[1], keep_prob: 1.0})
        print("step %d, training accuracy %g" % (i, train_accuracy))
    train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})

# 输出最终模型在测试集上的准确率
print("test accuracy %g" % accuracy.eval(feed_dict={
    x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))

完整代码:mnist_main.py

下一篇:TensorFlow-CIFAR10 CNN代码分析

Reference

  1. http://deeplearning.stanford.edu/wiki/index.php/UFLDL%E6%95%99%E7%A8%8B
  2. http://wiki.jikexueyuan.com/project/tensorflow-zh/tutorials/mnist_pros.html
  3. http://blog.csdn.net/zouxy09/article/details/8781543
  4. https://www.zhihu.com/question/41037974/answer/150522307
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百川AI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值