【TensorFlow】MNIST(使用CNN)

官方文档 —— MNIST进阶
代码已上传至 Github —— mnist_cnn.py

下载MNIST数据集


以下有两种下载方式,如果链接失效可以搜索网上的资源

下载之后将其放在 mnist/data/ 文件夹下,目录结构如下

mnist/
    mnist_cnn.py
    data/
        train-images-idx3-ubyte.gz
        train-labels-idx1-ubyte.gz
        t10k-images-idx3-ubyte.gz
        t10k-labels-idx1-ubyte.gz

mnist_cnn.py中用以下代码导入,注意要使用别名input_data,官网中漏了

import tensorflow.examples.tutorials.mnist.input_data as input_data
mnist = input_data.read_data_sets("data/", one_hot=True)

这时候运行mnist_cnn.py,代码的输出结果如下

$ python mnist_cnn.py

Extracting data/train-images-idx3-ubyte.gz
Extracting data/train-labels-idx1-ubyte.gz
Extracting data/t10k-images-idx3-ubyte.gz
Extracting data/t10k-labels-idx1-ubyte.gz

完整代码


初始化变量跟文档不一样,原因是官网的版本较落后。应该用global_variables_initializer()代替initialize_all_variables()

文档最后训练和评估模型一部分代码中accuracy.eval()train_step.run()有问题,解决方法如下

  • 将代码放在with sess.as_default():
  • 显式传递Session,比如run(session=sess)
  • 使用sess.run(accuracy,feed_dict=...)

需要解释的地方都在代码的注释中说明了

import tensorflow.examples.tutorials.mnist.input_data as input_data
import tensorflow as tf

# 导入数据集
mnist = input_data.read_data_sets("data/", one_hot=True)


# 权重初始化:使用标准差为0.1的正态分布
def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial)


# 偏置初始化:使用常量0.1
def bias_variable(shape):
    initial = tf.constant(0.1, shape=shape)
    return tf.Variable(initial)


# 卷积:使用1步长,0边距的模板,保证输出和输入是同一个大小
def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding="SAME")


# 池化:用简单传统的2x2大小的模板
def max_pool_2x2(x):
    return tf.nn.max_pool(
        x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")


# 第一层卷积
x = tf.placeholder(tf.float32, [None, 784])  # 使用占位符,用于指定任意数量的图片
W_conv1 = weight_variable([5, 5, 1,
                           32])  # 第1,2维是patch的大小,第3维是输入的通道数目,第4维是输出的通道数目
b_conv1 = bias_variable([32])  # 每一个输出通道都有一个对应的偏置量

x_image = tf.reshape(
    x, [-1, 28, 28, 1])  # 把x变成一个4d向量,第2、第3维对应图片的宽、高,第4维代表图片的颜色通道数

h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(
    h_conv1)  # 把x_image和权值向量进行卷积,加上偏置项,然后应用ReLU激活函数,最后进行max pooling

# 第二层卷积
W_conv2 = weight_variable([5, 5, 32, 64])  # 每个5x5的patch会得到64个特征
b_conv2 = bias_variable([64])

h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)

# 密集连接层
W_fc1 = weight_variable([7 * 7 * 64,
                         1024])  # 图片尺寸减小到7x7,加入一个有1024个神经元的全连接层,用于处理整个图片
b_fc1 = bias_variable([1024])

h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])  # 把池化层输出的张量reshape成一些向量
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

# Dropout
keep_prob = tf.placeholder("float")  # 用placeholder来代表一个神经元的输出在dropout中保持不变的概率
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

# 输出层
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])

y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)  # 添加一个softmax层

# 最小化交叉熵
y_ = tf.placeholder("float", [None, 10])  # 正确值
cross_entropy = -tf.reduce_sum(y_ * tf.log(y_conv))
train_step = tf.train.AdamOptimizer(1e-4).minimize(
    cross_entropy)  # 用ADAM优化器来做梯度最速下降

# 初始化变量
init = tf.global_variables_initializer()

# 启动图
sess = tf.Session()
sess.run(init)

# 训练和评估模型
correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

for step in range(1000):
    batch = mnist.train.next_batch(50)
    if step % 100 == 0:  # 每100次迭代输出一次日志
        train_accuracy = sess.run(
            accuracy, feed_dict={
                x: batch[0],
                y_: batch[1],
                keep_prob: 1.0
            })
        print("步骤 %d,训练准确度 %g" % (step, train_accuracy))
    sess.run(train_step, feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})

print("测试准确度 %g" % (sess.run(
    accuracy,
    feed_dict={
        x: mnist.test.images,
        y_: mnist.test.labels,
        keep_prob: 1.0
    })))

运行结果如下

$ python mnist_cnn.py

Extracting data/train-images-idx3-ubyte.gz
Extracting data/train-labels-idx1-ubyte.gz
Extracting data/t10k-images-idx3-ubyte.gz
Extracting data/t10k-labels-idx1-ubyte.gz

步骤 0,训练准确度 0.08
步骤 100,训练准确度 0.82
步骤 200,训练准确度 0.86
步骤 300,训练准确度 0.9
步骤 400,训练准确度 0.9
步骤 500,训练准确度 0.88
步骤 600,训练准确度 0.94
步骤 700,训练准确度 0.88
步骤 800,训练准确度 0.94
步骤 900,训练准确度 0.96

测试准确度 0.9624
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值