Tensorflow实现CNN流程

引言

Tensorflow是Google开发的大规模分布式深度学习框架,其采用数据流图(定义一个静态图,新版增加了动态图)的形式来进行数值计算。本文使用Tensorflow基于CNN完成MNIST数据集的分类任务。

实现流程

2.1 导入相关包

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

2.2 获取数据

# 获取数据
# 会在当前目录下新建一个MNIST_data文件,如果已经存在,会自动调用。
mnist = input_data.read_data_sets("MNIST_data", one_hot=True)
X_train=mnist.train.images  # 训练数据
y_train=mnist.train.labels  # 训练标签
X_test=mnist.test.images    # 测试数据
y_test=mnist.test.labels    # 测试标签
print(X_train.shape, y_train.shape)

2.3 定义参数

# 定义参数
epoch = 20
batch_size = 200
batch_num = len(X_train) // batch_size
learning_rate = 0.001

2.4 定义占位符

# 定义占位符placeholder
x = tf.placeholder(tf.float32, [None, 784])    # 样本的形式
y = tf.placeholder(tf.float32, [None, 10])     # 标签的形式
keep_prob = tf.placeholder(tf.float32)         # dropout层

# 把输入数据reshape成CNN的输入格式
x_image = tf.reshape(x, [-1, 28, 28, 1])    # -1指样本数, 1指通道数

2.5 定义相关函数备用

# 取数据
def get_data(x, y, batch_size, batch_num):
    for i in range(batch_num):
        batch_x = x[i*batch_size:(i+1)*batch_size]
        batch_y = y[i*batch_size:(i+1)*batch_size]
        yield batch_x, batch_y

# 定义参数W
def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial)

# 定义参数b
def bias_variable(shape):
    initial = tf.constant(0.1, shape=shape)
    return tf.Variable(initial)

# 定义卷积网络
def conv2D(X, W):
    return tf.nn.conv2d(X, W, strides=[1,1,1,1], padding='SAME')

# 定义池化层
def max_pool(x):
    return tf.nn.max_pool(x, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')

2.6 定义CNN模型

# 第一层
with tf.name_scope("first"):
    # 参数
    conv1_W = weight_variable([5, 5, 1, 32]) # 卷积核长宽5,输入通道为1, 输出通道为32
    conv1_b = bias_variable([32])            # 跟W的输出通道对应
    # 卷积池化
    conv1_out = tf.nn.relu(conv2D(x_image, conv1_W) + conv1_b)
    maxpool_out = max_pool(conv1_out)
# 第二层
with tf.name_scope("second"):
    # 参数
    conv2_W = weight_variable([5, 5, 32, 64])
    conv2_b = bias_variable([64])
    # 卷积池化
    conv2_out = tf.nn.relu(conv2D(maxpool_out, conv2_W) + conv2_b)
    maxpool_out = max_pool(conv2_out)
# flatten层
with tf.name_scope("flatten1"):
    # 参数
    fc1_W = weight_variable([7*7*64, 1024])
    fc1_b = bias_variable([1024])
    # flatten
    fc1_input = tf.reshape(maxpool_out, [-1, 7*7*64])
    fc1_out = tf.nn.relu(tf.matmul(fc1_input, fc1_W) + fc1_b)
    # dropout
    fc1_drop = tf.nn.dropout(fc1_out, keep_prob)
# flatten层2
with tf.name_scope("flatten2"):
    # 参数
    fc2_W = weight_variable([1024, 10])
    fc2_b = bias_variable([10])
    # flatten
    fc2_out = tf.matmul(fc1_drop, fc2_W) + fc2_b

定义损失值和优化器和准确率

# 损失值
cross_entropy = tf.reduce_mean(
	# 模型中fc2_out并没使用softmax激活函数,因此使用下面的损失函数
    tf.nn.softmax_cross_entropy_with_logits_v2(
    labels = y, logits = fc2_out)
)
# 优化器
train_step = tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy)

# 准确率
y_pred = tf.nn.softmax(fc2_out)
pred_correct = tf.equal(tf.arg_max(y_pred, 1), tf.arg_max(y, 1))
accuracy = tf.reduce_mean(tf.cast(pred_correct, tf.float32))

训练并测试

# model
with tf.Session() as sess:
    init = tf.global_variables_initializer()
    sess.run(init)
    for epoch in range(epoch):
        loss = 0
        train_data = get_data(X_train, y_train, batch_size, batch_num)
        for data, label in train_data:
            _, loss_item = sess.run([train_step, cross_entropy], feed_dict = {x:data, y:label, keep_prob:1})
            loss = loss + loss_item
        acc = sess.run(accuracy, feed_dict={x:X_test, y:y_test, keep_prob:1})
        print("第{}个epoch的loss:{:0.3f},测试集准确率为:{:0.3f}".format(epoch, loss/batch_num, acc)) 

Tensorflow实现CNN流程_第1张图片

你可能感兴趣的:(图像,数据处理,自然语言处理,图像分类,tensorflow,深度学习,卷积神经网络)