# MNIST数据集:
在数据集中工含有七万张图片,其中55000为训练数据集,5000张为验证集,10000张为测试集。每张图片是一个 28*28像素点的手写数字,黑底白字,黑底用0表示,白字用0~1之间的浮点数表示,浮点数越接近于1颜色越白。每张图片的784(28*28=784)像素点,组成长度为784的一维数组,该数组就是我们要喂入神经网络的输入特征
举例:
一张数字手写体图片变成长度为 784 的一维数组[0.0.0.0.0.231 0.235 0.459 ……0.219 0.0.0.0.]输入神经网络。该图片对应的标签为[0.0.0.0.0.0.1.0. 0.0],每个数值表示每个数值出现的概率。标签中索引号为 6 的元素为 1,表示是数字6出现的概率为 100%,其它数值出现的概率为0,则该图片对应的识别结果是6
# 使用 input_data模块中的read_data_sets() 加载mnist数据集
from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets("./data/",one_hot=True)input_data模块使用函数read_data_sets()自动加载数据集,从上面的列子中我们可以看到,在 read_data_sets() 函数中存在两个参数,第一个参数表示数据集的存放路径,第二个参数表示数据集的存放形式。当第二个参数为 True 时,表示以独热码的形式存取数据集
当函数 read_data_sets() 运行时,会检查我们所写入的路径中是否已经存在数据集,如果指定的路径中不存在数据集,则会自动下载数据集,并将mnist数据集分为训练集train,验证集validation 和测试集 test 三个子集进行存放。
下面内容是自动下载后数据集存放的情况
Extracting ./data/train-images-idx3-ubyte.gz Extracting ./data/train-labels-idx1-ubyte.gz Extracting ./data/tl0k-images-idx3-ubyte.gz Extracting ./data/ tl0k-labels-idx1-ubyte.gz# 返回数据集中国训练集,验证集,测试集 test 的样本数
Tensorflow中返回样本数
1:返回训练集 train 样本数
print "train data sample size:",mnist.train.mun_examples2:返回验证集 validation 样本数
print "validation data sample size:",mnist.validation.mun_examples3:返回测试集 test 样本数
print "test data sample size:",mnist.test.mun_examples# 使用函数 train.labels 返回mnist数据集的标签
# 例如想输出第0张图片的标签 mnist.train.labels[0] 输出结果为:array([0.,0.,0.,0.,0.,0.,1.,0.,0.,0])# 使用函数 train.images 返回mnist 数据集图片像素值
# 例如,要输出第0张图片的784个像素点 mnist.train.images[0] 输出结果为: array([0. ,0. ,0. , 0. ,0. ,0. , 0. ,0. ,0. , … … …])# 使用函数 mnist.train.next_batch() 将数据输入神经网络
BATCH_SIZE = 200 xs,ys = mnist.train.next_batch(BATCH_SIZE) print "xs shape:" , xs.shape print "ys shape:" , ys.shape # 输出结果 xs.shape(200,784) xs.shape(200,10) # 分析 # mnist.train.next_batch()函数传入一个参数BATCH_SIZE,表示随即从训练集中抽取BATCH_SIZE个样本输入神经网络中,并将样本的 像数值 和 标签 分别赋给 xs 和 ys# 实现MNIST数据集手写数字的识别常用的函数
tf.get_collection("") # 该函数表示从 collection 集合中抽取全部变量生成一个列表
tf.add_n() # 该函数表示将参数列表中对应元素相加 x=tf.constant([[1,2],[1,2]]) y=tf.constant([[1,1],[1,2]]) z=tf.add(x,y) print z 输出结果:[[2,3],[2,4]]
tf.cast(x,dtype) # 函数表示将参数 x 转为指定类型 A = tf.convert_to_tensor(np.array([[1,1,2,4], [3,4,8,5]])) print A.dtype b = tf.cast(A, tf.float32) print b.dtype 结果输出: <dtype: 'int64'> <dtype: 'float32'> 可以看出,矩阵A由整数型变为了32为浮点数型
tf.equal() # 函数表示对比两个矩阵或向量元素,元素相等返回True,反之 A = [[1,3,4,5,6]] B = [[1,3,4,3,2]] with tf.Session( ) as sess: print(sess.run(tf.equal(A, B))) 输出结果:[[ True True True False False]] 在矩阵 A 和 B 中,第 1、2、3 个元素相等,第 4、5 个元素不等,故输出结果中, 第 1、2、3 个元素取值为 True,第 4、5 个元素取值为 False。
tf.reduce_mean(x,axis) # 该函数表示求矩阵张量或张量指定维度的平均值,该函数具有两个参数,如果不指定第二个参数,则在所有元素中取平均值;如果第二个参数指定为0,则在第一维度上取平均值,每一列求平均值;如果将第二个参数指定为1,则在第二维度上取平均值,即每一行求平均值 x = [[1., 1.] [2., 2.]] print tf.reduce_mean(x) # 不指定:结果为1.5 print tf.reduce_mean(x,0) # 参数指定为0:结果为[1.5,1.5] print tf.reduce_mean(x,1) # 参数指定为1:结果为[1.,2.]
tf.argmax(x,axis) # 该函数表示返回指定维度axis下,参数x中最大值对应的索引号。x表示的一个列表 tf.argmax([1,0,0],1) 其中axis的值为1,表示在参数x的第一维度取最大值对饮的索引号,其中列表中值最大的是1,返回0
os.path.join() # 函数表示将参数字符串按照路径命名规则拼接,也就是使用"/"进行拼接 import os os.path.join("/com/doaoao/","hello/world/","tensorflow") 输出结果为:"/com/doaoao/hello/world/tensorflow"
s.split() # 将字符串s按照指定的字符串进行拆分,并返回拆分列表 s = "/com/doaoao/hello/world/tensorflow" s.split("/") 拆分后返回的结果为:["com","doaoao","hello","world","tensorflow"]
tf.Graph().as_default() # 该函数表示将当前图设置成默认图,并返回一个上下文件管理器,该函数一般与 with 搭配使用,应用于将已经抵挡一号的神经网络在计算机图中复现 with tf.Graph().as_default as g: 表示将在Graph()内定义的节点加入到计算图g中# 神经网络模型的保存
在反向传播的过程中,一般会间隔一定的轮数保存一次神经网络模型,并产生三个文件(当前图结构的.meta文件,保存当前参数名的.index文件,保存当前参数.data文件)
在tensorflow中表示如下
saver = tf.train.Saver() with tf.Session() as sess: for i in range(STEPS): if i % 轮数 == 0: saver.save(sess, os.path.join(MODEL_SAVE_PATH,MODEL_NAME), global_step=global_step)利用 tf.train.Saver() 实例化saver对象,咋with结构中,每循环一定的轮数,利用saver.save()将当前会话的参数等信息保存到路径MODEL_SAVE_PATH/MODEL_NAME 中,并在文件尾部加上当前训练的轮数(global_step=global_step)
# 神经网络模型加载
在测试网络训练时,需要将训练练好的神经网络模型加载,在Tensorflow中表示如下
with tf.Session() as sess: ckpt = tf.train.get_checkpoint_state(存储路径) if ckpt and ckpt.model_checkpoint_path: saver.restore(sess, ckpt.model_checkpoint_path)在with中加载保存神经网络模型,在with结构中加载ckpt,如果ckpt和保存的模型在指定路径中存在,则用 saver.restore 将模型参数保存到当前的会话中
# 加载模型中参数的滑动平均
在保存模型时,若模型中采用滑动平均,则参数的滑动平均值会保存在相应的文件中,通过实例化 saver 对象,实现滑动平均值的加载,在Tensorflow中如下表示
ema = tf.train.ExponentialMovingAverage(滑动平均基数) ema_restore = ema.variables_to_restore() saver = tf.train.Saver(ema_restore)# 神经网络模型准确率的评估方法
在网络模型准确率评估时,一般通过计算机在一组数据上的识别准确率,评估神经网络的效果,在Tensorflow中如下表示
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
上述分析:
y表示神经网络喂入 BATCH_SIZE 数据后计算的结果,y是BATCH_SIZE乘以10的二维数组,每行表示一轮BATCH前向传播的结果,tf.argmax()的第二个参数1表示选取最大值得操作仅仅在第一个维度进行,也就是返回每一行最大值所对应得列表索引号,回得到一个长度为BATCH得一维数组,这个一维数组中的值就表示了每轮样本推算出的数字识别结果。tf.equal()判断两个张量中每一维是否相等,如果相等返回True,否则返回False。tf.cast()会将一个布尔型的数值转成实数型,然后计算平均值,这个平均值就是这个模型在这组数据上的准确率。
# 复习神经网络八股
神经网络八股包括:前向传播,反向传播,反向传播过程中用到的正则化,指数衰减学习率,活动平均方法的设置,测试模块
1:向前传播过程
# 前向传播过程完成神经网络的搭建 def forward(x, regularizer): w= b= y= return y def get_weight(shape, regularizer): def get_bias(shape):在前向传播的过程中,需要定义神经网络中的参数w和偏置b,定义由输入到输出的网络结构中,通过定义函数 get_wright() 实现对参数w的设置,包括参数w的形状和是否正则化的标致。通过定义函数get_bias() 实现对偏置b的设置
2:反向传播过程
def backward( mnist ): x = tf.placeholder(dtype, shape ) y_ = tf.placeholder(dtype, shape ) #定义前向传播函数 y = forward( ) global_step = loss = train_step = tf.train.GradientDescentOptimizer(learning_rate). minimize(loss, global_step=global_step) #实例化 saver 对象 saver = tf.train.Saver() with tf.Session() as sess: #初始化所有模型参数 tf.initialize_all_variables().run() #训练模型 for i in range(STEPS): sess.run(train_step, feed_dict={x: , y_: }) if i % 轮数 == 0: print saver.save()利用placeholder给输入 x 和 y_ 占位,要复现前向传播计算出y,定义global_step,定义loss
3:正则化,指数衰减学习率,滑动平均方法的设置
3.1正则化 regularzation
挡在前向传播过程中即 forward.py 文件中,设置正则化参数 regularzation 为1时,则表明在反向传播过程中优化模型参数时,需要在损失函数中加入正则化选项,结构如下所示
# 首先,需要在前向传播过程即 forward.py 文件中加入 if regularizer != None: tf.add_to_collection('losses',tf.contrib.layers.l2_regularizer(regularizer)(w)) # 其次,需要在反向传播过程即 backword.py 文件中加入 ce = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,labels=tf.argmax(y_, 1)) cem = tf.reduce_mean(ce) loss = cem + tf.add_n(tf.get_collection('losses')) # 其中,tf.nn.sparse_softmax_cross_entropy_with_logits()表示 softmax()函数与交叉熵一起使用。3.2 指数衰减学习率
在训练模型时,使用指数衰减学习率可以使模型在训练的前期快熟收敛接近较优解,又可以保证模型在训练后期不会有太大波动
# 运用指数衰减学习率,需要在反向传播过程即 backword.py 文件中加入: learning_rate = tf.train.exponential_decay( LEARNING_RATE_BASE, global_step, LEARNING_RATE_STEP, LEARNING_RATE_DECAY, staircase=True)3.3 滑动平均
在模型训练时引入滑动平均可以使模型再测试数据上表现得更加得健壮
# 需要在反向传播过程即 backword.py 文件中加入: ema = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step) ema_op = ema.apply(tf.trainable_variables()) with tf.control_dependencies([train_step, ema_op]): train_op = tf.no_op(name='train')测试过程:tesy.py
def test( mnist ): with tf.Graph( ).as_default( ) as g: #给 x y_占位 x = tf.placeholder(dtype,shape) y_ = tf.placeholder(dtype,shape) #前向传播得到预测结果 y y = mnist_forward.forward(x, None) #前向传播得到 y #实例化可还原滑动平均的 saver ema = tf.train.ExponentialMovingAverage(滑动衰减率) ema_restore = ema.variables_to_restore() saver = tf.train.Saver(ema_restore) #计算正确率 correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(y_,1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32)) while True: with tf.Session() as sess: #加载训练好的模型 ckpt = tf.train.get_checkpoint_state(存储路径) #如果已有 ckpt 模型则恢复 if ckpt and ckpt.model_checkpoint_path: #恢复会话 saver.restore(sess, ckpt.model_checkpoint_path) #恢复轮数 global_ste = ckpt.model_checkpoint_path.split ('/')[-1].split('-')[-1] #计算准确率 accuracy_score = sess.run(accuracy, feed_dict= {x:测试数据, y_:测试数据标签 }) # 打印提示 print("After %s training step(s), test accuracy= %g" % (global_step, accuracy_score)) #如果没有模型 else: print('No checkpoint file found') #模型不存在提示 return # 其次,制定 main()函数 def main(): #加载测试数据集 mnist = input_data.read_data_sets("./data/", one_hot=True) #调用定义好的测试函数 test() test(mnist) if __name__ == '__main__': main()## 实现手写字体识别任务
实现手写字体识别任务,并将其分为三个模块文件,分别是网络结构前向传播过程文件(mnist_forward.py),描述网络参数优化方法的反向传播过程文件(mnist_backward.py),验证模型准确率的测试过程文件(mnist_test.py)
1:前向传播过程文件 mnist_forward.py
# coding: utf-8 import tensorflow as tf INPUT_NODE = 784 OUTPUT_NODE = 10 LATER1_NODE = 500 def get_weight(shape,regularizer): w = tf.Variable(tf.truncated_normal(shape,stddev=0.1)) if regularizer != None: tf.add_to_collection('losses',tf.contrib.layers.l2_regularizer(regularizer)(w)) return w def get_bias(shape): b = tf.Variable(tf.zeros(shape)) return b def forward(x,regularizer): w1 = get_weight([INPUT_NODE,LATER1_NODE],regularizer) b1 = get_bias([LATER1_NODE]) y1 = tf.nn.relu(tf.matmul(x,w1) + b1) w2 = get_weight([LATER1_NODE,OUTPUT_NODE],regularizer) b2 = get_bias([OUTPUT_NODE]) y = tf.matmul(y1, w2) + b2 return y2:反向传播过程文件 mnist_backward.py
# coding: utf-8 import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data import mnist_forward import os BATCH_SIZE = 200 LEARING_RATE_BASE = 0.1 LEARING_RATE_DECAY = 0.99 REGULARIZER = 0.0001 STEPS = 50000 MOVING_AVRAGE_DECAY = 0.99 MODEL_SAVE_PATH = "./model" MODEL_NAME = "mnist_model" def backward(mnist): x = tf.placeholder(tf.float32,[None,mnist_forward.INPUT_NODE]) y_ = tf.placeholder(tf.float32,[None,mnist_forward.OUTPUT_NODE]) y = mnist_forward.forward(x,REGULARIZER) global_step = tf.Variable(0,trainable=False) ce = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,labels=tf.argmax(y_,1)) cem = tf.reduce_mean(ce) loss = cem + tf.add_n(tf.get_collection('losses')) learning_rate = tf.train.exponential_decay( LEARING_RATE_BASE, global_step, mnist.train.num_examples / BATCH_SIZE, LEARING_RATE_DECAY, staircase=True) train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=global_step) ema = tf.train.ExponentialMovingAverage(MOVING_AVRAGE_DECAY,global_step) ema_op = ema.apply(tf.trainable_variables()) with tf.control_dependencies([train_step, ema_op]): train_op = tf.no_op(name='train') saver = tf.train.Saver() with tf.Session() as sess: init_op = tf.global_variables_initializer() sess.run(init_op) for i in range(STEPS): xs,ys = mnist.train.next_batch(BATCH_SIZE) _,loss_value,step = sess.run([train_op,loss,global_step],feed_dict={x:xs,y_:ys}) if i % 1000 == 0: print("After %d training step(s), loss on training batch is %g ." %(step,loss_value)) saver.save(sess,os.path.join(MODEL_SAVE_PATH,MODEL_NAME),global_step=global_step) def main(): mnist = input_data.read_data_sets("./data/",one_hot=True) backward(mnist) if __name__ == '__main__': main()3:测试过程文件 mnist_test.py
# coding: utf-8 import time import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data import mnist_forward import mnist_backward TEST_INITERVAL_SECS = 5 def test(mnist): with tf.Graph().as_default() as g: x = tf.placeholder(tf.float32,[None,mnist_forward.INPUT_NODE]) y_ = tf.placeholder(tf.float32,[None,mnist_forward.OUTPUT_NODE]) y = mnist_forward.forward(x, None) ema = tf.train.ExponentialMovingAverage(mnist_backward.MOVING_AVRAGE_DECAY) ema_restore = ema.variables_to_restore() saver = tf.train.Saver(ema_restore) correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(y_,1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32)) while True: with tf.Session() as sess: ckpt = tf.train.get_checkpoint_state(mnist_backward.MODEL_SAVE_PATH) if ckpt and ckpt.model_checkpoint_path: saver.restore(sess, ckpt.model_checkpoint_path) global_ste = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1] accuracy_score = sess.run(accuracy, feed_dict={x:mnist.test.images, y_:mnist.test.label}) print("After %s training step(s), test accuracy=%g" % (global_step, accuracy_score)) else: print('No checkpoint file found') return def main(): mnist = input_data.read_data_sets("./data/", one_hot=True) test(mnist) if __name__ == '__main__': main()..
本笔记整理自:慕课Tensorflow笔记