附:课程链接
第五讲.全连接网络基础
5.1MNIST数据集
由于个人使用Win7系统,并未完全按照课程所讲,以下记录的也基本是我的结合课程做的Windows系统+PyCharm操作。且本人有python基础,故一些操作可能简略。并未完全按照网课。
记住编写代码时,除注释内容外,字符均使用英文格式。
本节目标:搭建神经网络,在MNIST数据集上训练模型,输出手写数字识别准确率。
一、NMIST数据集:
1.简介:MNIST共有7W张图片,其中6W张0-9手写数字图片和标签,用于训练神经网络,1W张0-9手写数字图片和标签,用于测试神经网络。每张图片大小为28*28像素。
【补充(据助教笔记):
】
图片中纯黑色像素值用0表示,纯白色用0-1之间浮点数表示,越接近于1颜色越白。
我们把每张图片的784个像素点(28*28 = 784)组成长度为784的一维数组,作为喂入神经网络的输入特征。如下图:
MNIST数据集还提供了每张图片对应的标签,以一个长度为10的一维数组给出,每个元素表示所出现数值的概率。比如上述数组对应的标签:
表示(从左往右数)0、1、2、3、4、5、6的6出现的概率是100%,其他数字出现的概率是0%。图片应该是阿拉伯数字6。
2.tensorflow官方提供了input_data模块,该模块使用read_data_sets()自动加载数据集,使用方法如下:
read_data_sets()函数中有两个参数,第一个参数表示数据集存放路径,第二个参数表示数据集的存取形式,当第二个参数为True时,表示以独热码形式存取数据集。
read_data_sets()函数运行时,会检查指定路径内是否已有数据集,若指定路径没有数据集,则自动下载,并将mnist数据集分为训练集train、验证集validation、测试集test三个子集存放。在终端显示如下内容:
我们的程序使用子集train训练模型参数,使用子集test测试模型准确率。
返回mnist数据集中训练集train、验证集validation、测试集test样本数:
在tensorflow中用以下函数返回子集样本数:
# 导入input_data用于自动下载和安装MNIST数据集
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("mnist_work/", one_hot=True)
#返回训练集train样本数
print('train data size:',mnist.train.num_examples)
#返回验证集validation样本数
print('validation data size:',mnist.validation.num_examples)
#返回测试集test样本数
print('test data size:',mnist.test.num_examples)
验证结果:
train data size: 55000
validation data size: 5000
test data size: 10000
使用train.labels函数返回mnist数据集标签,例如想要查看训练集中第0张图片的标签,则:
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("mnist_work/", one_hot=True)
print(mnist.train.labels[0])
运行结果:
[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]
使用train.images函数返回mnist数据集图片像素值,例如想要查看训练集中第0张图片像素值,则:
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("mnist_work/", one_hot=True)
print(mnist.train.images[0])
运行结果不便展示,直接上课程截图:
定义好每一轮一小撮输入的数据大小后,可以使用mnist.train.next_batch(BATCH_SIZE)从训练集中随机抽取BATCH_SIZE组数据和标签,分别赋值给xx和ys,可以打印出它们的形状:
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("mnist_work/", one_hot=True)
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) #200行数据,每个数据有784个像素点,是输入的特征
ys shape: (200, 10) #对应的200个标签,每个标签有10个元素,是输出的分类
二、记忆几个函数:
【有关以上函数的附:对于以上函数,可以观看文首所附课程链接,也可以看助教的笔记,但是助教的笔记有的我尝试了一下,与其与出入,有可能是python版本不同导致的(课程python2.x,我的python3.x,所以会有一定语法不同带来的错误),由于我时间比较紧张,写了几个发现问题比较大就干脆全删了。后期有时间我可能会在补发吧。】
三、模型的保存和加载
保存模型:
在反向传播过程中,一般会间隔一定轮数保存一次神经网络模型,并产生三个文件(保存当前图结构的.meta文件、保存当前参数名的.index文件、保存当前参数的.data文件),在tensorflow中语法如下表示:
sever = tf.train.Saver() #实例化saver对象
with tf.Session() as sess: #在with结构for循环中一定轮数时,保存模型到当前会话
for i in range(STEPS):
if i%轮数 == 0: #每循环一定轮数,用saver.save把当前会话的参数的信息保存到路径下,并在文件尾加上当前训练的轮数
saver.save(sess,os.path.join(MODEL_SAVE_PATH,
MODEL_NAME),global_step = global_step)
加载模型:
在tensorflow中语法如下表示:
with tf.Session() as sess: #在with结构中加载ckpt
ckpt = tf.train.get_checkpoint_state(存储路径)
if ckpt and ckpt.model_checkpoint_path: #如果ckpt和模型存在,则用saver.restore()把模型参数加载到当前会话中
saver.restore(sess,ckpt.model_checkpoint_path)
如果训练过程中使用过滑动平均,每个参数的滑动平均值也会被保存到模型中,我们使用模型识别图片时,更希望加载参数的滑动平均值,用以下三句话可以实例化可还原滑动平均值的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))
#y是喂入神经网络BATCH_SIZE数据后计算的结果,是BATCH_SIZE乘以10的二维数组,每一行表示一轮BATCH前向传播的结果
#tf.argmax()的第二个参数1,选取最大值的操作仅在第1个维度进行,也就是返回每一行最大值所对应的的列表索引号,会得到一个长度为BATCH的一维数组
#这个一维数组中的值就表示了每一轮样本推算出的数字识别结果
#tf.equal判断两个张量中每一维是否相等,如果相等返回true,否则返回false
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
#tf.cast会将一个布尔型的数值转换成实数型,然后计算平均值,这个平均值就是模型在这一组数据上的正确率。