原始的MNIST数据集包含以下4个文件:
分别是测试图像数据,测试图像的标签,训练图像数据,训练图像的标签。
训练图像一共有60000张,测试图像一共有10000张。
可以采用如下代码下载
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/",one_hot=True)
得到了mnist对象,查看其各个变量的shape:
#查看训练数据的大小
print(mnist.train.images.shape)
print(mnist.train.labels.shape)
#查看验证数据的大小
print( mnist.validation.images.shape)
print(mnist.validation.labels.shape)
#查看测试数据的大小
print(mnist.test.images.shape)
print(mnist.test.labels.shape)
得到如下结果:
可知:60000张训练图像又分为了55000张训练图片和5000张验证图片。
在原始的数据集中,每张图片都由28*28的矩阵表示,从而所有的训练图片既可以用(55000,784)表示
在Tensorflow中,使用两层卷积网络对其进行分类:
#coding:utf-8
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
#读入数据
mnist = input_data.read_data_sets("MNIST_data/",one_hot = True)
#x为训练图像的占位符,y_为训练图像标签的占位符
x=tf.placeholder(tf.float32,[None,784])
y_=tf.placeholder(tf.float32,[None,10])
#卷积:将单张图片从784维向量重新还原为28*28的矩阵图片
x_image = tf.reshape(x,[-1,28,28,1])
#卷积运算
def weight_variable(shape):
initial = tf.truncated_normal(shape,stddev=0.1)
return tf.Variable(initial)
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_2x2(x):
return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
#第一层卷积层
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)
h_pool1=max_pool_2x2(h_conv1)
#第二层卷积层
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)
h_pool2 = max_pool_2x2(h_conv2)
#全连接层,输出为1024维的向量
W_fc1 = weight_variable([7 * 7 * 64,1024])
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2,[-1,7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat,W_fc1)+b_fc1)
#使用Dropout,keep_prob是一个占位符,训练时为0.5,测试时为1
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)
#把1024维的向量转换为10维,对应10个类别
W_fc2 = weight_variable([1024,10])
b_fc2 = bias_variable([10])
y_conv = tf.matmul(h_fc1_drop,W_fc2)+b_fc2
#不采用先Softmax再计算交叉熵的方法
#而是用tf.nn.softmax_cross_entropy_with_logits直接计算
cross_entropy = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits(labels= y_,logits=y_conv)
)
# 同样定义train_step
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
#定义测试的准确率
correct_prediction = tf.equal(tf.argmax(y_conv,1),tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
#创建session,对变量初始化
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
#训练20000步
for i in range(20000):
batch = mnist.train.next_batch(50)
#每100步报告一次在验证集上的准确率
if i % 100 == 0:
train_accuracy = accuracy.eval(feed_dict={
x:batch[0],y_:batch[1],keep_prob:1.0
})
print("step %d,training accuracy %g" %(i,train_accuracy))
train_step.run(feed_dict={x:batch[0],y_:batch[1],keep_prob:0.5})
关于卷积后特征图的计算方式:
1.输入矩阵:4D,[样本数,图像高度,图像宽度,图像通道数]
2.输出矩阵:与输入矩阵的维度和顺序相同,只是后三个维度的尺寸会发生变化
3.权重矩阵: 4D,[卷积核高度,卷积核宽度,输入通道数,输出通道数(卷积核个数)]
权重矩阵的输入通道数和输入矩阵的图像通道数相同,输出矩阵的输出通道数与权重矩阵的输出通道数一致。输出矩阵的宽度与高度的求解公式可以用N=(W-F+2P)/S +1来求解
特别的Tensorflow中关于padding为SAME时,特征图的大小只与stride有关
池化后的通道数不会改变。