手写数字分类可以说是机器学习的“Hello world”了。先前在《Python深度学习》中有使用Keras实现手写数字分类,具体可以看看Keras实现手写数字分类 在本文中会使用两种方式实现手写数字分类,一种是Softmax Regression,第二种是多层感知机(即全连接网络) 神经网络的训练分四个步骤:1)定义算法公式;2)定义损失函数和选择优化器;3)训练步骤;4)对模型进行准确率评估
mnist是一个经典的手写测试集,包含6000万张训练图片和10000张测试图片,每张图片的大小为28*28。 对于图片数据的处理,将2828的图片展开成7841,对标签采用one_hot编码,即标签是一个10维的向量,对于标签0,即为[1,0,0,0,0,0,0,0,0,0]。
相比Keras,TensorFlow的使用没有那么直观,有以下几点需要说明 2.Session 为了能够实现一个计算流程就需要一个graph来表示这个流程,而为了能够执行这个图就需要一个会话(Session)来启动这个图,这个过程相当于graph是画好的一张图,然后我用一个Session来执行这个图。 Session的方法run(),这里详细的介绍一下run的使用方法。其作用是Runs operations and evaluates tensors in fetches,意思是执行一次Session,其中待执行的内容放在fetches中,这里的fetches目前暂时看成是一些待计算的内容。 常用的两种方式
#方法一 sess = tf.Session() sess.run(...) sess.close() # 方法二 with tf.Session() as sess: sess.run(...)2.常用函数
tf.reduce_mean() #计算平均值 tf.reduce_sum() #计算总和 tf.matmul() #计算矩阵乘法 tf.argmax() #计算一个张量中最大值的序号 tf.cast() #转换数据类型本文使用Softmax Regression算法(常用于多任务分类)实现模型。其原理是,将可以判定为某类的特征相加,然后将这些特征转化为判定是这类的概率。关于Softmax Regression算法可以参考SoftmaxRegression详解。
代码详解:
from tensorflow.examples.tutorials.mnist import input_data import tensorflow as tf mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) #载入数据 #tf.InteractiveSession()主要用于python这种交互场景下 #它和标准的Sessin的唯一区别就是它初始化自己是default的Session。 sess = tf.InteractiveSession() x = tf.placeholder(tf.float32, [None, 784])#创建输入数据存放的地方 w = tf.Variable(tf.zeros([784, 10])) #创建weights的Variable对象 b = tf.Variable(tf.zeros([10])) #创建bias的Variable对象 y = tf.nn.softmax(tf.matmul(x, w) + b) #实现y = Softmax(wx +b) y_ = tf.placeholder(tf.float32, [None, 10]) #真实的预测值存放的地方 #计算交叉熵 cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1])) train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy) #learning rate = 0.5 tf.global_variables_initializer().run() #使用TensorFlow的全局参数初始化器,并运行其run方法 #迭代训练1000次 for i in range(1000): batch_xs, batch_ys = mnist.train.next_batch(100) #每次随机地从训练集取100个样本 train_step.run({x:batch_xs, y_: batch_ys}) correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)) #验证预测值与真实值是否相等 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) #计算模型精度 print(accuracy.eval({x: mnist.test.images, y_:mnist.test.labels}))运行结果
本项目还可以使用多层感知机,即全连接层(在书的第4.4节),《Python深度学习》里面其实就是用的全连接网络(两层隐含层层),这里只用了一层。主要学一下怎么加全连接层。
代码详解
from tensorflow.examples.tutorials.mnist import input_data import tensorflow as tf mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) #调用数据 sess = tf.InteractiveSession() #创建Session in_units = 784 #输入节点数 h1_units = 300 #隐含层输出节点数 w1 = tf.Variable(tf.truncated_normal([in_units, h1_units], stddev = 0.1)) #初始化w1 b1 = tf.Variable(tf.zeros([h1_units])) #初始化b1 w2 = tf.Variable(tf.zeros([h1_units, 10])) #初始化w2 b2 = tf.Variable(tf.zeros([10])) #初始化b2 x = tf.placeholder(tf.float32, [None, in_units]) #定义输入x的placeholder keep_prob = tf.placeholder(tf.float32) #定义dropout的保留节点的比率 hidden = tf.nn.relu(tf.matmul(x, w1) + b1) #创建隐含层 hidden1_drop = tf.nn.dropout(hidden, keep_prob) #设置隐含层的dropout y = tf.nn.softmax(tf.matmul(hidden1_drop, w2) + b2) #输出层结果(预测值) y_ = tf.placeholder(tf.float32, [None, 10]) #真实值 cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1])) #交叉熵 train_step = tf.train.AdagradOptimizer(0.3).minimize(cross_entropy) #使用Adagrad优化器 tf.global_variables_initializer().run() #使用TensorFlow的全局参数初始化器,并运行其run方法 #迭代训练3000次 for i in range(3000): batch_xs, batch_ys = mnist.train.next_batch(100) #每次用100个样本训练 train_step.run({x : batch_xs, y_: batch_ys, keep_prob:0.75}) #训练模型,dropout的参数设为0.75 correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)) #验证预测值与真实值是否相等 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) #计算模型准确率 print(accuracy.eval({x : mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0})) #输出测试集准确率运行结果
TensorFlow实现手写数字分类 Session与InteractiveSession的区别
