MNIST数据集
MNIST是一个入门级的计算机视觉数据集。它包含各种手写数字图片,在TensorFlow的mnist这个demo就是是通过Softmax Regression模型来训练预测mnist数据集。
TensorFlow的Tutorial里提供了一份python源代码用于自动下载和安装MNIST数据集。
from tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_sets
mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)
下载后的数据集就存放在制定的data_dir下面。
每一个MNIST单元都有两部分组成,一张手写图片和一个对应的标签,可以把图片设为xs,标签设为ys,可以通过mnist.test.images,mnist.test.labels分别得到图片和标签。数据集中的图片其实讲图片的像素点放到了一个行向量中,每一个图片都是28*28=784个像素,则行向量有784维。,标签lable是10维的向量。如果label是1,那标签向量就为{0,1,0,0,0,0,0,0,0,0,0}。
SoftMax Regression分类器模型
Softmax模型可以用来给不同对象分配概率。不管多复杂的分类器模型,例如卷积神经网络,循环神经网络,一般最后一步都需要用Softmax来分配概率。
对于一个输入图片属于数字i的证据可以表示为:
其中 Wi表示权重,bi表示数字属于i类的偏置量,j代表给定图片x的像素索引用于像素求和。
对于任意样本x,evidence里的值[evidence1,evidence2,...,evidencen]是有正有负的。
原始的evidence数据无法用于预测,需要用softmax将evidence数据转换成概率分布。先代入指数函数变成成非负数,然后做归一化处理,这样evidence就是严格服从概率分布了。
如果用y来表示概率,就可上式就可表示为:
损失函数
损失函数可以使用对数损失表示,对数损失,也称为交叉熵损失,用于度量分类器的预测输出概率分布和真实分布的差异。
在二分类问题中,真实标签集合为:
y∈[0,1]
,而分类器预测到概率分布为:
P=Pr(y=1)
,那对于每一个样本的对数损失就是在给定真实样本标签的条件下,分类器的负对数似然函数:
在多元分类情况下例如:
真实类标签分布:
Y | class0 | class1 | class2 |
---|---|---|---|
y1 | 0 | 1 | 0 |
y2 | 1 | 0 | 0 |
y3 | 0 | 0 | 1 |
预测分类标签分布:
P | class0 | class1 | class2 |
---|---|---|---|
y1 | 0.2 | 0.7 | 0.1 |
y2 | 0.5 | 0.2 | 0.3 |
y3 | 0.3 | 0.3 | 0.4 |
整个样本集合上的分类器对数损失可以定义为:
使用TensorFlow构建SoftmaxRegression构建分类模型
inference:构建evidence前向推断模型
Y=W∗X+b
:
logits = tf.add(tf.matmul(X,W),b)
softmax: 将evidence转换成概率分布:
Y_pred = tf.nn.softmax(logits=logits)
loss : 构建损失函数:
Trainloss = tf.reduce_mean(-tf.reduce_sum(Y_true * tf.log(Y_pred),axis=1))
train: 将损失函数代入梯度优化节点,进行优化
evaluate:使用训练得到的模型权重用于评估测试样本。
代码
import os
import argparse
import sys
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data
#os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
FLAGS = None
def main(_):
mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)
with tf.Graph().as_default():
#input
with tf.name_scope('Input'):
X = tf.placeholder(tf.float32 , shape=[None,784],name="X")
Y_true = tf.placeholder(tf.float32 ,shape=[None,10], name="Y_true" )
with tf.name_scope('Inference'):
#模型参数变量
W = tf.Variable(tf.zeros([784,10]),name="Weight")
b = tf.Variable(tf.zeros([10]),name="Bias")
#inference :Y= X*W + b
logits = tf.add(tf.matmul(X,W),b)
#Softmax把logits 变成概率分布
with tf.name_scope('Softmax'):
Y_pred = tf.nn.softmax(logits=logits)
with tf.name_scope('Loss'):
#loss :
Trainloss = tf.reduce_mean(-tf.reduce_sum(Y_true * tf.log(Y_pred),axis=1))
with tf.name_scope('Train'):
#train:
optimizer = tf.train.GradientDescentOptimizer(learning_rate = 0.5)
TrainOp = optimizer.minimize(Trainloss)
with tf.name_scope('Evaluate'):
Y_P_max = tf.argmax(Y_pred,1)
Y_T_max = tf.argmax(Y_true,1)
correct_prediction = tf.equal(Y_P_max,Y_T_max)
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
InitOp = tf.global_variables_initializer()
writer = tf.summary.FileWriter(logdir='logs_2',graph=tf.get_default_graph())
writer.close()
with tf.Session() as sess:
sess.run(InitOp)
for step in range(1000):
batch_xs,batch_ys = mnist.train.next_batch(100)
_,train_loss = sess.run([TrainOp,Trainloss],feed_dict={X:batch_xs,Y_true:batch_ys})
print("train step:",step," train_loss:",train_loss)
ypm = sess.run(Y_P_max,feed_dict={X:mnist.test.images})
ytm = sess.run(Y_T_max,feed_dict={Y_true:mnist.test.labels})
for i in range(len(ypm)):
print ("P 序号:%s 值:%s" % (i + 1, ypm[i]))
print ("T 序号:%s 值:%s" % (i + 1, ytm[i]))
#print("max pre Y : ",ypm)
#print("max true Y: ",ytm)
accuracy_score = sess.run(accuracy,feed_dict={X:mnist.test.images,Y_true:mnist.test.labels})
print("accuracy_score:",accuracy_score)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--data_dir', type=str, default='D:/tensorflow/pys/test1/tmp/tensorflow/mnist/input_data',
help='Directory for storing input data')
FLAGS, unparsed = parser.parse_known_args()
tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)