TensorFlow力学101笔记[4]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TensorFlow力学101笔记[4]相关的知识,希望对你有一定的参考价值。

TensorFlow力学101笔记[4]

本教程的目的是展示如何使用TensorFlow来训练和评估使用(经典)MNIST数据集的手写数字分类的简单前馈神经网络。

教程文件

本教程引用以下文件:

文件目的
mnist.py 构建完全连接的MNIST模型的代码。
fully_connected_feed.py 使用Feed字典对下载的数据集训练构建的MNIST模型的主要代码。

fully_connected_feed.py直接运行文件开始培训:

python fully_connected_feed.py

准备数据

MNIST是机器学习中的一个经典问题。问题是查看手写数字的灰度28x28像素图像,并确定图像表示的数字,从0到9的所有数字。

 

技术分享

下载

在该run_training()方法的顶部,该input_data.read_data_sets() 函数将确保正确的数据已下载到您的本地培训文件夹,然后解包该数据以返回DataSet 实例的字典

data_sets = input_data.read_data_sets(FLAGS.train_dir, FLAGS.fake_data)

注意:该fake_data标志用于单元测试,读取器可能会被忽略。

数据集目的
data_sets.train 55000张图片和标签,用于初级培训。
data_sets.validation 5000张图像和标签,用于训练准确性的迭代验证。
data_sets.test 10000张图像和标签,用于最终测试训练的精度。

输入和占位符

placeholder_inputs()函数创建两个tf.placeholder 操作,定义输入的形状,包括batch_size图形的其余部分,实际训练示例将被馈送到该操作中

images_placeholder = tf.placeholder(tf.float32, shape=(batch_size,
                                                       mnist.IMAGE_PIXELS))
labels_placeholder = tf.placeholder(tf.int32, shape=(batch_size))

 进一步下来,在训练循环中,将完整图像和标签数据集切片以适应batch_size每个步骤,与这些占位符操作相匹配,然后sess.run()使用feed_dict 参数传递到函数中

构建图

产生用于数据的占位符后,将图表从内置 mnist.py文件根据3级图案:inference()loss(),和training()

 

  1. inference() - 建立图表,直到运行网络前进来进行预测。
  2. loss() - 添加推理图,生成损失所需的操作。
  3. training() - 将损耗图表添加到计算和应用渐变所需的操作。

推理

inference()函数根据需要构建图形,以返回包含输出预测的张量。

它将图像占位符作为输入,并在其顶部构建一对具有ReLU激活的完全连接的层,之后是指定输出逻辑的十个节点线性层。

每个图层都创建在唯一的下面tf.name_scope ,作为在该范围内创建的项目的前缀。

 

with tf.name_scope(hidden1):

在定义的范围内,每个这些层要使用的权重和偏差被生成为tf.Variable 具有所需形状的实例:

weights = tf.Variable(
    tf.truncated_normal([IMAGE_PIXELS, hidden1_units],
                        stddev=1.0 / math.sqrt(float(IMAGE_PIXELS))),
    name=weights)
biases = tf.Variable(tf.zeros([hidden1_units]),
                     name=biases)

在 tf.truncated_normal初始化生成与给定的平均值和标准偏差的随机分布。

然后,偏置被初始化tf.zeros 以确保它们以所有零值开始,它们的形状只是它们连接到的层中的单元数量。

 

然后创建图形的三个主要操作 - 为隐藏层tf.nn.relu 包装两个操作tf.matmul和一个额外tf.matmul的逻辑操作,每个操作依次tf.Variable连接到每个输入占位符或上一个图层的输出张量。

hidden1 = tf.nn.relu(tf.matmul(images, weights) + biases)
hidden2 = tf.nn.relu(tf.matmul(hidden1, weights) + biases)
logits = tf.matmul(hidden2, weights) + biases

最后,logits返回包含输出张量。

loss

loss()功能通过添加所需的损失操作进一步构建图。

首先,将值labels_placeholder转换为64位整数。然后,tf.nn.sparse_softmax_cross_entropy_with_logits添加一个操作以自动生成1个热标签

labels = tf.to_int64(labels)
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(
    labels=labels, logits=logits, name=xentropy)

然后,它使用tf.reduce_mean 以平均跨批尺寸的交叉熵值(第一尺寸)作为总损耗。 

loss = tf.reduce_mean(cross_entropy, name=‘xentropy_mean‘)

并返回张量,然后将包含损耗值。

训练

training()函数将需要通过尽量减少损失的操作 梯度下降

 

首先,它需要损失张量从loss()功能和将它交给一个 tf.summary.scalar,用于生成摘要值到事件的运算与使用时的文件 tf.summary.FileWriter(见下文)。在这种情况下,它会在每次总结写出时间发出损失的快照值。

tf.summary.scalar(‘loss‘, loss)

接下来,我们实例化一个tf.train.GradientDescentOptimizer 负责应用与要求的学习率梯度。

optimizer = tf.train.GradientDescentOptimizer(learning_rate)

然后生成一个变量包含全球训练步骤计数器和tf.train.Optimizer.minimize OP既用于更新系统中的可训练的权重,并增加全球的一步。这op是,按照惯例,被称为train_op是什么必须由TensorFlow会议,以诱导训练一个完整的步骤(见下文)运行。

 
global_step = tf.Variable(0, name=‘global_step‘, trainable=False)
train_op = optimizer.minimize(loss, global_step=global_step)

训练模型

一旦图被建成,它可以被迭代训练和通过在用户代码控制的循环进行评价fully_connected_feed.py

 

该图

在顶部run_training()的功能是一个Python with的命令,指示所有内置OPS的要与默认的全局相关的tf.Graph 实例。

with tf.Graph().as_default():

tf.Graph是可以一起作为一个组来执行OPS的集合。大多数TensorFlow用途将只需要依靠单一的默认图形。 

有多个图形更复杂的应用也是可能的,但是超出了简单的教程的范围。

会话

一旦所有的构建制备已经完成,所有产生的必要的OPS,一个tf.Session 用于运行图形创建。

sess = tf.Session()

可替换地,Session可以生成到with用于作用域块: 

with tf.Session() as sess:

空参数会表明这个代码将附加到(或创建如果尚未创建),默认的本地会话。

创建会话后,立即在所有的tf.Variable 情况下,通过调用初始化tf.Session.run 自己的初始化运算。 

init = tf.global_variables_initializer()
sess.run(init)

tf.Session.run 方法将运行对应于作为参数传递运算(多个)的曲线图的完整子集。在这第一个电话时,init OP是tf.group 只包含了变量初始化。图中的其余部分都没有在这里运行; 这种情况发生在下面的训练循环。

 

铁路环线

初始化与会话变量后,训练就可以开始。

用户代码控制每个步骤的培养,并且可以做有用的训练是最简单的循环:

 
for step in xrange(FLAGS.max_steps):
    sess.run(train_op)

然而,该教程稍微更复杂的,因为它也必须切片了输入数据的每个步骤,以匹配先前生成的占位符。

 

饲料图表

对于每个步骤,该代码将生成的进料字典将包含所述一组在其上的步骤,由它们所表示的占位符OPS键训练示例。

fill_feed_dict()功能,给定的DataSet查询其下一 batch_size组图像和标签,和张量相匹配的占位符被填充包含下一图像和标签。

images_feed, labels_feed = data_set.next_batch(FLAGS.batch_size,
                                               FLAGS.fake_data)

Python字典对象然后与占位符作为键和代表馈送张量作为值生成的。

feed_dict = {
    images_placeholder: images_feed,
    labels_placeholder: labels_feed,
}

这是传递到sess.run()函数的feed_dict参数提供的培训这一步骤的输入例子。

 

检查状态

该代码指定了两个值,在其运行的调用来获取:[train_op, loss]

for step in xrange(FLAGS.max_steps):
    feed_dict = fill_feed_dict(data_sets.train,
                               images_placeholder,
                               labels_placeholder)
    _, loss_value = sess.run([train_op, loss],
                             feed_dict=feed_dict)

因为有两个值来获取,sess.run()返回两个项目的元组。每个Tensor在值的列表中获取对应于所返回的元组numpy的阵列,在这种训练步骤填充有张量的值。由于train_opOperation没有输出值,在返回的元组中的相应元件是None,因此,丢弃。然而,价值loss张量有可能成为NaN的,如果模型训练过程中发散,所以我们捕获记录这个值。

假设训练运行没有NaN的罚款,训练回路还打印一个简单的状态文本每100步,让用户知道的训练状态。

if step % 100 == 0:
    print(‘Step %d: loss = %.2f (%.3f sec)‘ % (step, loss_value, duration))

可视化状态

为了发射由所使用的事件文件TensorBoard,所有的摘要(在这种情况下,只有一个)被收集到在图形建筑物相单张量。

summary = tf.summary.merge_all()

然后创建会话后,一个tf.summary.FileWriter 可以被实例事件写入文件,其中包含两个图形本身及摘要的值。

summary_writer = tf.summary.FileWriter(FLAGS.train_dir, sess.graph)

最后,事件文件将被新的汇总值在每次更新时间 summary评估,并通过笔者的输出add_summary() 功能。

 
summary_str = sess.run(summary, feed_dict=feed_dict)
summary_writer.add_summary(summary_str, step)

当事件写入文件,TensorBoard可以对抗训练文件夹中运行,从摘要中显示的值。

 技术分享

 

保存检查点

为了发射出可用于以后恢复了进一步的培训或评估模型的检查点文件,我们实例化一个 tf.train.Saver

saver = tf.train.Saver()

在训练循环,该tf.train.Saver.save 方法将定期被要求写检查点文件到培训目录中的所有训练的变量的当前值。

saver.save(sess, FLAGS.train_dir, global_step=step)

在未来的某个点后,训练可能会通过使用恢复 tf.train.Saver.restore 方法来重新加载模型参数。

saver.restore(sess, FLAGS.train_dir)

评估模型

 每千步,代码会试图评估对双方的训练和测试数据集模型。do_eval()功能被称为三次,对于培训,验证和测试数据集。

 
print(‘Training Data Eval:‘)
do_eval(sess,
        eval_correct,
        images_placeholder,
        labels_placeholder,
        data_sets.train)
print(‘Validation Data Eval:‘)
do_eval(sess,
        eval_correct,
        images_placeholder,
        labels_placeholder,
        data_sets.validation)
print(‘Test Data Eval:‘)
do_eval(sess,
        eval_correct,
        images_placeholder,
        labels_placeholder,
        data_sets.test)

需要注意的是更为复杂的使用通常会封存data_sets.test 只显著金额超参数整定后进行检查。对于一个简单的小问题MNIST的缘故,但是,我们评估对所有的数据。

 

构建评估和演示图

在进入训练循环之前,评估和演示OP应该已经通过调用内置evaluation()的功能mnist.py与同logits /标签参数的loss()功能。

 
eval_correct = mnist.evaluation(logits, labels_placeholder)

evaluation()功能简单地生成一个tf.nn.in_top_k 运算,可以自动得分每个模型输出正确的,如果真标签可在K最可能的预测中找到。在这种情况下,我们的K值设置为1只考虑一个预测如果正确的话它是真正的标签。

 
eval_correct = tf.nn.in_top_k(logits, labels, 1)

EVAL输出

然后可以创建用于填充一个循环feed_dict,并呼吁sess.run() 对eval_correct运来评估在给定数据集模型。

 
for step in xrange(steps_per_epoch):
    feed_dict = fill_feed_dict(data_set,
                               images_placeholder,
                               labels_placeholder)
    true_count += sess.run(eval_correct, feed_dict=feed_dict)

true_count变量只是积累的所有的预测的 in_top_kOP已经确定是正确的。从那里,精度可以从简单地通过实施例的总数量除以来计算。

 
precision = true_count / num_examples
print(‘  Num examples: %d  Num correct: %d  Precision @ 1: %0.04f‘ %
      (num_examples, true_count, precision))











以上是关于TensorFlow力学101笔记[4]的主要内容,如果未能解决你的问题,请参考以下文章

TensorFlow.js:那两个张量相等吗?

Tensorflow学习笔记(对MNIST经典例程的)的代码注释与理解

Tensorflow 无法识别 cudart64_101.dll

tensorflow 应用fizzbuzz

tensorflow笔记:多层CNN代码分析

tensorflow笔记:多层LSTM代码分析