Tensorflow是Google开发的大规模分布式深度学习框架,其采用数据流图(定义一个静态图,新版增加了动态图)的形式来进行数值计算。本文使用Tensorflow基于CNN完成MNIST数据集的分类任务。
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
# 获取数据
# 会在当前目录下新建一个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)
# 定义参数
epoch = 20
batch_size = 200
batch_num = len(X_train) // batch_size
learning_rate = 0.001
# 定义占位符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指通道数
# 取数据
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')
# 第一层
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))