初学tensorflow-CNN

使用CNN对MNIST分类。

1、导入功能包

import tensorflow.compat.v1 as tf
tf.disable_eager_execution()
from tensorflow.examples.tutorials.mnist import input_data

2、下载MNIST数据集

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

3、定义权重方法

def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial)
  • 此处使用的是truncated_normal()方法进行初始化权重,在CNN效果好。

4、定义偏置方法

def bias_variable(shape):
    initial = tf.constant(0.1, shape=shape)
    return tf.Variable(initial)


5、定义卷积层方法

def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
  • x代表输入image,结构为[simple个数(一般用-1),图片长,图片宽,图片通道]。w为权重,结构为[卷积核长,卷积核宽,卷积核通道(要与图片通道相等),卷积核个数]。strides为步长,[固定,x轴移动步数,Y轴移动步数,固定],pading为全0填充。参考下图可以加深卷积核的理解,重点是理解输出通道以及计算方式。
    卷积核

6、定义模型输入

xs = tf.placeholder(tf.float32, [None, 784])#/255. # 28x28
ys = tf.placeholder(tf.float32, [None, 10])
keep_prob = tf.placeholder(tf.float32)
x_image = tf.reshape(xs, [-1, 28, 28, 1])#转换维度[全部例子,图片长,图片宽,图片通道个数]
  • mnist数据集被拉成一串,为784列(2828),所以xs结构为[none,784]。keep_prob为dropout。将mnist数据集还原为2828结构,用作卷积神经网络的输入,x_image作用既如此。

7、定义模型卷积、池化层

W_conv1 = weight_variable([5,5, 1,32]) #[卷积核长,卷积核宽,输入图片通道个数,输出图片通道个数]
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) #28x28x32
h_pool1 = max_pool_2x2(h_conv1)#14*14*32
W_conv2 = weight_variable([5,5, 32,64]) #[卷积核长,卷积核宽,输入图片通道个数,输出图片通道个数]
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) #14x14x64
h_pool2 = max_pool_2x2(h_conv2)#7*7*64
  • 采用最大池化max_pool_22()方法,两层卷积池化后图片结构为77*64,不断卷积池化的过程就是将图片变小变厚的过程。

8、定义模型平坦层

h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])#-1代表全部例子
  • 平坦层后接全连接层,需要对池化后的数据在进行变形,将其拉成一串。结构为[所有的simple,将[7,7,14]结构转换为7714]。作为全连接网络的输入。

9、定义模型全连接层

W_fc1 = weight_variable([7*7*64, 1024])
b_fc1 = bias_variable([1024])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
prediction = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
  • 注意此处使用了dropout方法,通过每次训练过程,使部分神经元不激活,从而避免了过拟合现象。所谓过拟合,即在训练集损失很低,在测试集损失确很高。
  • 此处使用了两层隐层,激活函数使用softmax,因为要做分类。

10、模型编译

cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction),
                                          reduction_indices=[1])) 
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
  • 采用交叉熵方法计算损失。
  • 采用Adam优化器进行参数优化。

11、参数初始化

sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)

12、模型训练

for i in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys, keep_prob: 0.5})
  • 每次丢入模型100个数据进行训练,其结果并不会比全部数据丢入模型效果差。

13、定义模型评估方法

def compute_accuracy(v_xs, v_ys):
    global prediction            
    y_pre = sess.run(prediction, feed_dict={xs: v_xs, keep_prob: 1})
    correct_prediction = tf.equal(tf.argmax(y_pre,1), tf.argmax(v_ys,1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    result = sess.run(accuracy, feed_dict={xs: v_xs, ys: v_ys, keep_prob: 1})
    return result
  • 计算准确率。

print(compute_accuracy(
    mnist.test.images[:1000], mnist.test.labels[:1000]))

14、代码已上传本人github,其主要根据莫烦代码修改而成。

参考文献:

1、神经网络黑盒的简单解释(推荐)
2、莫烦tensorflow教程

打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2015-2021 高腾腾
  • Powered by Hexo Theme Ayer
  • PV: UV:

谢谢大爷

支付宝
微信