Tensorflow入门学习(二)——识别MNIST数据集

1、Softmax回归

1.1 Softmax回归原理

Softmax回归是Logistic回归的推广,只是Softmax回归是一个多分类模型,而Logistic回归是二分类模型。
首先我们需要了解**什么是Softmax函数:**该函数就是实现将分类中对类别的预测转化为合理的概率值,实现将分类结果映射到(0,1)区间内。我们假设有一个数组V,Vi表示第i个元素,第i个元素的Softmax值表示如下:
在这里插入图片描述
假设有三个类别a、b、c,那么这三个类别分别对应的Softmax值用Softmax函数计算如下: e a e a + e b + e c \frac{e^a}{e^a+e^b+e^c} ea+eb+ecea e b e a + e b + e c \frac{e^b}{e^a+e^b+e^c} ea+eb+eceb e c e a + e b + e c \frac{e^c}{e^a+e^b+e^c} ea+eb+ecec

假设 x x x是单个样本的特征, W , b W, b W,b是Softmax模型的参数。在MNIST数据集中, x x x表示输入图片,是一个784维的向量, W W W是一个矩阵形状为(784,10), b b b是10维向量。Softmax模型首先是计算各个类别的Logit:
L o g i t = W T x + b Logit=W^Tx+b Logit=WTx+b
得到一个10维的向量,表示样本对各个类别的一个“打分”结果,然后用Softmax函数转为各个类别的概率值:
y = S o f t m a x ( L o g i t ) = S o f t m a x ( W x + b ) y=Softmax(Logit)=Softmax(W^x+b) y=Softmax(Logit)=Softmax(Wx+b)

1.2 Tensorflow中实现Softmax回归对MNIST数据集识别

在对Softmax回归原理之后,用Tensorflow实现对MNIST数据集的分类识别

import tensorflow  as tf
# 创建x,x是一个占位符(placeholder),代表待识别图片
x = tf.placeholder(tf.float32, [None, 784])
# W是softmax模型的参数, 将一个784维的输入转换为一个10维的输出
# 在Tensorflow中,变量的参数用tf.Variable表示
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
y = tf.nn.softmax(tf.matmul(x,W)+b)  #模型预测类别结果
y_ = tf.placeholder(tf.float32, [None, 10]) #实际标签
'''这里定义了一些占位符和变量( Variable )。在TensorFlow中,无论是占位符还是变量,它们实际上都是“ Tensor”。从TensorFlow 的名字中,就可以看出Tensor 在整个系统中处于核心地位。TensorFlow 中的Tensor 并不是具体的数值,它只是一些我们“希望” TensorFlow 系统计算的“节点’'''
'''y表示模型输出结果,y_表示实际标签,理论上两者越接近越好,这里用交叉熵损失函数表示两者的相似性,损失函数越小,越相似'''
## Tensorflow中交叉熵定义如下:
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y)))

## 用优化算法对模型参数进行优化
## 用梯度下降法
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

'''在优化前,必须要创建一个会话(Session),并在会话中对变量进行初始化操作
   会话可以看成对这些结点进行计算的上下文'''
#创建一个Session,只有在Session中才能运行优化步骤train_step
sess = tf.InteractiveSession()
#运行之前必须要初始化所有变量,分配内存
tf.global_variables_initializer().run()

##进行优化
for _ in range(1000):
    batch_xs,batch_ys = mnist.train.next_batch(100) #每次提取100个数据进行训练,共训练1000次
    sess.run(train_step,feed_dict={x:batch_xs,y_:batch_ys})

correct_predict = tf.equal(tf.argmax(y,1),tf.argmax(y_,1)) #tf.argmax(y,1),tf.argmax(y_,1)的功能是取出数组中最大值的下标
##由热独表示可知下标既为类别,得出模型下标和实际下标后通过tf.equal来比较两者是否相同
accuracy = tf.reduce_mean(tf.cast(correct_predict,tf.float32))
#用tf.cast(correct_prediction, tf. float32 )将比较值转换成float32 型的变量,此时True 会被转换成l , False 会被转接成0 。
#用tf.reduce_mea n 可以计算数组中的所高元素的平均值,相当于得到了模型的预测准确率
print(sess.run(accuracy,feed_dict={x:mnist.test.images,y_:mnist.test.labels}))

2、卷积网络分类

卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度学习(deep learning)的代表算法之一。
卷积网络结构如下包含输入层、隐层(卷积层、池化层)、全连接层、输出层。(网上关于卷积神经网络的教程一抓一大把,看一两个教程就懂差不多了)
利用Tensor flow建立两层卷积神经网络对MNIST数据集进行识别:

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

mnist = input_data.read_data_sets("MNIST_data/",one_hot=True)

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)

#卷积层之后是全连接层
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_prop是一个占位符,训练为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中的Logit

#采用tf.nn.softmax_cross_enropy_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)
    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})

#训练结束后报告在测试集上的准确率
print("test accuracy %g" % accuracy.eval(feed_dict={
    x:mnist.test.images,y_:mnist.test.labels,keep_prob:1.0
}))



用卷积神经网络识别准确率率远高于Softmax回归的识别准确率。

你可能感兴趣的:(Tensorflow)