参考文档:
Tensorflow中文社区:
http://www.tensorfly.cn/tfdoc/tutorials/mnist_beginners.html
MNIST
MNIST是一个入门级CV数据集,包含手写数字图片。其中60000张用来训练,10000张用来测试。
一个MINST数据单元包含一张手写数字图片(28*28)以及一个图片所对应的label;
将每张28*28的图片展开成向量,长度为784。那么mnist.train.images就是一个[60000,784]的张量;
mnist.train.labels是一个[60000,10]的矩阵。
构建简单softmax回归模型实现预测
代码
# -*- coding:utf-8 -*-
import tensorflow as tf
import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
x = tf.placeholder("float",[None,784]) #x是一个占位符,None表示张量的第一个维度可以是任意长度的
W = tf.Variable(tf.zeros([784,10])) #随意设置w和b的值,因为后续要学习
b = tf.Variable(tf.zeros([10]))
#W的维度是[784,10],因为我们想要用784维的图片向量乘以它以得到一个10维的证据值向量,每一位对应不同数字类。b的形状是[10],所以我们可以直接把它加到输出上面。
y = tf.nn.softmax(tf.matmul(x,W)+b) #预测值
y_ = tf.placeholder("float",[None,10]) #正确值
cross_entropy = -tf.reduce_sum(y_ * tf.log(y))
'''
首先,用 tf.log 计算 y 的每个元素的对数。
接下来,我们把 y_ 的每一个元素和 tf.log(y_) 的对应元素相乘。
最后,用 tf.reduce_sum 计算张量的所有元素的总和。
(注意,这里的交叉熵不仅仅用来衡量单一的一对预测和真实值,而是所有100幅图片的交叉熵的总和
'''
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
#要求TensorFlow用梯度下降算法(gradient descent algorithm)以0.01的学习速率最小化交叉熵
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
#开始训练模型,这里我们让模型循环训练1000次
for i in range(1000):
#该循环的每个步骤中,我们都会随机抓取训练数据中的100个批处理数据点,
# 然后我们用这些数据点作为参数替换之前的占位符来运行train_step
batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(train_step,feed_dict={x:batch_xs,y_:batch_ys})
#评估模型性能
'''
首先找出那些预测正确的标签。
tf.argmax 是一个非常有用的函数,它能给出某个tensor对象在某一维上的其数据最大值所在的索引值。
由于标签向量是由0,1组成,因此最大值1所在的索引位置就是类别标签,
比如tf.argmax(y,1)返回的是模型对于任一输入x预测到的标签值,
而 tf.argmax(y_,1) 代表正确的标签,可以用 tf.equal 来检测我们的预测是否真实标签匹配(索引位置一样表示匹配)。
'''
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
#返回一组布尔值。为了确定正确预测项的比例,可以把布尔值转换成浮点数,然后取平均值。
#例如,[True, False, True, True] 会变成 [1,0,1,1] ,取平均值后得到 0.75.
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
print sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels})
测试准确率:0.9133
构建一个多层卷积网络实现预测
实现代码
# -*- coding:utf-8 -*-
import tensorflow as tf
import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
sess = tf.InteractiveSession()
x = tf.placeholder("float",[None,784]) #x是一个占位符,None表示张量的第一个维度可以是任意长度的
#W的维度是[784,10],因为我们想要用784维的图片向量乘以它以得到一个10维的证据值向量,每一位对应不同数字类。b的形状是[10],所以我们可以直接把它加到输出上面。
y_ = tf.placeholder("float",[None,10]) #正确值
#创建权重生成函数
def weight_variable(shape):
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
#bias生成函数
def bias_variable(shape):
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)
#卷积使用1步长stride size,0边距padding size的模板
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
#池化利用max pooling
def max_pool_2x2(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1], padding='SAME')
#第一层:卷积 + max pooling
#卷积的权重张量形状是[5, 5, 1, 32],前两个维度是patch的大小,接着是输入的通道数目,最后是输出的通道数目
W_conv1 = weight_variable([5, 5, 1, 32])
b_conv1 = bias_variable([32])
x_image = tf.reshape(x, [-1,28,28,1])
#为了用这一层,把x变成一个4d向量,其第2、第3维对应图片的宽、高,最后一维代表图片的颜色通道数(因为是灰度图所以这里的通道数为1,如果是rgb彩色图,则为3)
#把x_image和权值向量进行卷积,加上偏置项,然后应用ReLU激活函数,最后进行max pooling。
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)
#第二层
#为了构建一个更深的网络,我们会把几个类似的层堆叠起来。第二层中,每个5x5的patch会得到64个特征
W_conv2 = wei