1、概述
新版的tensorflow的layer模块提供了更为简单的api,是我们能够非常快速的创建卷积神经网络。卷积神经网络被广泛的应用在计算机视觉的技术当中。现在要用卷积神经网络来进行手写数字的识别。
可以使用minist数据集来进行本次卷积神经网络的训练。这个数据集包含6万张训练样本和1万张测试样本的图片。
2、数据下载与数据结构分析
可以使用下面命令下载数据
# mnist数据集
import tensorflow as tf
mnist = tf.contrib.learn.datasets.load_dataset("mnist")
输出结果如下图所示:
将手写图片的数据取出,分为训练集与验证集
import numpy as np
train_data = mnist.train.images
print(train_data.shape)
train_labels = np.asarray(mnist.train.labels, dtype=np.int32)
print(train_labels.shape)
eval_data = mnist.test.images
print(eval_data.shape)
eval_labels = np.asarray(mnist.test.labels, dtype=np.int32)
print(eval_labels.shape)
输出结果如下图所示
下面观察一下图片的分布:
# 正式生成分布数据
import matplotlib.pyplot as plt
plotdata=pd.DataFrame({'clsname':train_labels,'clsdata': 1})
plotdata=clsdata['clsdata'].groupby(clsdata['clsname']).size()
x = plotdata.index.tolist()
y = plotdata.values.tolist()
plt.bar(x,y)
plt.show()
输出效果如下图所示:
预览图片:
#展示训练,随机从训练图片中抽取一个图片进行展示
cur_index = np.random.randint(mnist.train.num_examples,size=1)
cur_image = train_data[cur_index,:]
cur_image = np.reshape(cur_image,(28,28))
print("这是第",cur_index,"张图片","这张图片所对应的数字是",train_labels[cur_index])
plt.matshow(cur_image,cmap=plt.get_cmap('gray'))
plt.show()
输出效果如下图所示
3、整体网络结构
整个网络包括输入层,两层卷积池化层一个全链接层和一个输出层,基本结构描述如下
- 输入层
卷积神经网络的输入数据需要是一个四维的数据,所以需要对维度进行转化,将其转化为[*,28,28,1]维度
2、第一层卷积
第一层卷积使用32个5*5像素的过滤器进行卷积。使用relu函数进行激活。
3、第一层池化
使用2*2的过滤器以步长为2 进行max池化
4、第二层卷积
第一层卷积使用64个5*5像素的过滤器进行卷积。使用relu函数进行激活。
5、第二层池化
与第一层池化一样,使用2*2的过滤器以步长为2 进行max池化
6、全链接层
包含1024个神经元,并使用0.4的drop率进行处理,防止过拟合。
7、输出层
包含10个神经元采取one-hot形式,代表9个数字
4、整体实现
- 读取并处理数据
# mnist数据集
import tensorflow as tf
import numpy as np
import pandas as pd
# Load training and eval data
mnist = tf.contrib.learn.datasets.load_dataset("mnist")
train_data = mnist.train.images # Returns np.array
train_labels = np.asarray(mnist.train.labels, dtype=np.int32)
eval_data = mnist.test.images # Returns np.array
eval_labels = np.asarray(mnist.test.labels, dtype=np.int32)
定义数据处理函数以方便,数据进入模型
train_input_fn = tf.estimator.inputs.numpy_input_fn(
x={"x": train_data},
y=train_labels,
batch_size=100,
num_epochs=None,
shuffle=True)
2、定义模型
采用之前设定的结构定义模型,定义模型代码如下:
mnist_classifier = tf.estimator.Estimator(
model_fn=cnn_model_fn, model_dir="model")
模型函数代码如下:
def cnn_model_fn(features, labels, mode):
# 对输入函数进行维度转换
input_layer = tf.reshape(features["x"], [-1, 28, 28, 1])
# 第一层卷积层
conv1 = tf.layers.conv2d(
inputs=input_layer,
filters=32,
kernel_size=[5, 5],
padding="same",
activation=tf.nn.relu)
# 第一层池化层
pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)
# 第二层卷积层
conv2 = tf.layers.conv2d(
inputs=pool1,
filters=64,
kernel_size=[5, 5],
padding="same",
activation=tf.nn.relu)
# 第二层池化层
pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)
# 将数据拉平
pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 64])
# 第一层全连接层
dense = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu)
# 防止过拟合进行dropout操作
dropout = tf.layers.dropout(
inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)
# 输出层
logits = tf.layers.dense(inputs=dropout, units=10)
# 如果是预测模式
predictions = {
# Generate predictions (for PREDICT and EVAL mode)
"classes": tf.argmax(input=logits, axis=1),
# Add `softmax_tensor` to the graph. It is used for PREDICT and by the
# `logging_hook`.
"probabilities": tf.nn.softmax(logits, name="softmax_tensor")
}
if mode == tf.estimator.ModeKeys.PREDICT:
return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)
# 如果是训练模式
# 计算代价函数
loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
if mode == tf.estimator.ModeKeys.TRAIN:
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
train_op = optimizer.minimize(
loss=loss,
global_step=tf.train.get_global_step())
return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)
# 如果是评估模式
eval_metric_ops = {
"accuracy": tf.metrics.accuracy(
labels=labels, predictions=predictions["classes"])}
return tf.estimator.EstimatorSpec(
mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)
为了看到训练效果,设置一下日志输出方式
tensors_to_log = {"probabilities": "softmax_tensor"}
logging_hook = tf.train.LoggingTensorHook(
tensors=tensors_to_log, every_n_iter=50)
进行训练
mnist_classifier.train(
input_fn=train_input_fn,
steps=20000,
hooks=[logging_hook])