我的微信公众号名称:深度学习与智能决策
微信公众号ID:MultiAgent1024
公众号介绍:主要研究强化学习、计算机视觉、深度学习、机器学习等相关内容,分享学习过程中的学习笔记和心得!期待您的关注,欢迎一起学习交流进步!

在这篇文档里面依旧是使用前馈神经网络(feed-forward neural network)来构建MNIST识别的神经网络,只不过神经网络的编写更加规范了。主要是对mnist.py 和fully_connected_feed.py 这两个文件代码的一个解释。这两个文件在tensorflow的官方github中都可以找到tensorflow/tensorflow/examples/tutorials/mnist/。在mnist.py里面主要编写的就是构建全连接神经网络-mnist的模型,在fully_connected_feed.py里面主要编写利用mnist数据集的训练代码。运行fully_connected_feed.py就可以开始训练我们的模型。

mnist.py

在开始之前我们需要导入一些模块:

import math
import tensorflow as tf

在mnist.py里面我们经过三阶段的模式函数操作:inference()loss(),和training(),就能够把图表构建完成了。

1.inference() —— 尽可能地构建好图表,满足促使神经网络向前反馈并做出预测的要求。

2.loss() —— 往inference图表中添加生成损失(loss)所需要的操作(ops)。

3.training() —— 往损失图表中添加计算并应用梯度(gradients)所需的操作。

inference():

inferfence()函数会尽可能地构建图表,返回包含了预测结果(out prediction)的Tensor。它以图片的占位符(image placeholder)作为输入,借助ReLu(Rectified Linear Units)激活函数,构建一对全连接层。

每一层都创建于一个唯一的tf.name_scope之下,创建于该作用域之下的所有元素都将带有其前缀。

with tf.name_scope('hidden1'):

接下来我们需要构建第一层的神经元了,我们知道第一层的神经元以图像作为输入,因此我们首先需要去给出图像的大小的参数:

IMAGE_SIZE = 28
IMAGE_PIXELS = IMAGE_SIZE * IMAGE_SIZE

我们有了这个参数之后,我们就可以构建输入层,也就是第一层的神经元的权重(weight)和偏置(bias)了,第一层的输出为隐藏层第一层的输入:

    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')

因此权重W的维度是:[IMAGE_PIXELS, hidden1_units],tf.truncated_normal初始函数将根据所得到的均值和标准差,生成一个随机分布。

定义好了权重和偏置之后,接下来就需要将其和输入图像连接起来并经过激活函数:

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

这样的话第一层神经元就构建好了,接下来我们以同样的方式构建第二层神经元:

  with tf.name_scope('hidden2'):weights = tf.Variable(tf.truncated_normal([hidden1_units, hidden2_units],stddev=1.0 / math.sqrt(float(hidden1_units))),name='weights')biases = tf.Variable(tf.zeros([hidden2_units]),name='biases')hidden2 = tf.nn.relu(tf.matmul(hidden1, weights) + biases)

最后我们希望输出是10个类别,因此我们需要定义一个参数去确定我们的输出是多少维度的:

NUM_CLASSES = 10

之后构建输出层(至于这里为啥没有经过激活函数我也不是很清楚,如果有知道的同学的话还希望可以留言告诉我一下,嘻嘻):

  with tf.name_scope('softmax_linear'):weights = tf.Variable(tf.truncated_normal([hidden2_units, NUM_CLASSES],stddev=1.0 / math.sqrt(float(hidden2_units))),name='weights')biases = tf.Variable(tf.zeros([NUM_CLASSES]),name='biases')logits = tf.matmul(hidden2, weights) + biases

整个inference函数的构建如下所示:

def inference(images, hidden1_units, hidden2_units):with tf.name_scope('hidden1'):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')hidden1 = tf.nn.relu(tf.matmul(images, weights) + biases)with tf.name_scope('hidden2'):weights = tf.Variable(tf.truncated_normal([hidden1_units, hidden2_units],stddev=1.0 / math.sqrt(float(hidden1_units))),name='weights')biases = tf.Variable(tf.zeros([hidden2_units]),name='biases')hidden2 = tf.nn.relu(tf.matmul(hidden1, weights) + biases)with tf.name_scope('softmax_linear'):weights = tf.Variable(tf.truncated_normal([hidden2_units, NUM_CLASSES],stddev=1.0 / math.sqrt(float(hidden2_units))),name='weights')biases = tf.Variable(tf.zeros([NUM_CLASSES]),name='biases')logits = tf.matmul(hidden2, weights) + biasesreturn logits

loss():

loss()函数通过添加所需的op来构建图:

首先,这个来自lables_placeholder是被编码成一个1-hot的向量。例如:如果一个标签是被定义为数字“3”,那么它的表示形式如下所示:

[0, 0, 0, 1, 0, 0, 0, 0, 0, 0]

loss()函数的编写如下:

def loss(logits, labels):labels = tf.to_int64(labels)return tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)

tf.to_int64将张量转换为 int64 类型;

使用tf.nn.sparse_softmax_cross_entropy_with_logits的交叉熵(cross-entropy)loss。

  • labels:形状为[d_0, d_1, ..., d_{r-1}]的Tensor(其中,r是labels和结果的秩),并且有dtype int32或int64。labels中的每个条目必须是[0, num_classes)中的索引。当此操作在CPU上运行时,其他值将引发异常,并返回NaNGPU上相应的loss和梯度行。
  • logits:形状为[d_0, d_1, ..., d_{r-1}, num_classes],并且是dtype float32或float64的未缩放的日志概率。

返回与logits具有相同类型的加权损失Tensor。

training():

training的代码如下图所示:

def training(loss, learning_rate):tf.summary.scalar('loss', loss)optimizer = tf.train.GradientDescentOptimizer(learning_rate)global_step = tf.Variable(0, name='global_step', trainable=False)train_op = optimizer.minimize(loss, global_step=global_step)return train_op

对于tf.summary.scalar()函数的理解:TensorBoard可以将训练过程中的各种绘制数据展示出来,包括标量(scallars),图片(images),音频(Audio),计算图(graph)分布,直方图(histograms)和嵌入式向量。

如果我们需要使用TensorBoard展示数据的话,我们需要在执行Tensorflow就计算图的过程中,将各种类型的数据汇总并记录到日志文件中。然后使用TensorBoard读取这些日志文件,解析数据并产生数据可视化的Web页面,让我们可以在浏览器中观察各种汇总数据。summary_op包括了summary.scalar、summary.histogram、summary.image等操作,这些操作的输出是各种summary protobuf,最后通过summary.writer写入到event文件中。

Tensorflow API中包含系列生成summary数据的API接口,这些函数将汇总信息存放在protobuf中,以字符串形式表达。具体的更加细致的用法可以参考博客。接下来的操作就跟之前的一样,使用梯度下降算法优化迭代更新,不同的是我们生成一个变量用于保存全局训练步骤(global training step)的数值。

之后还多了一个函数,如下所示:

def evaluation(logits, labels):correct = tf.nn.in_top_k(logits, labels, 1)return tf.reduce_sum(tf.cast(correct, tf.int32))

tf.nn.in_top_k组要是用于计算预测的结果和实际结果的是否相等,返回一个bool类型的张量,tf.nn.in_top_k(prediction, target, K):prediction就是表示你预测的结果,大小就是预测样本的数量乘以输出的维度,类型是tf.float32等。target就是实际样本类别的标签(是mnist标签对应的下标值,一个10维的标签代表一个值(这个十维的标签的最大值的下标),具体的解析参考博客),大小就是样本数量的个数。K表示每个样本的预测结果的前K个最大的数里面是否含有target中的值。一般都是取1。

tf.cast表示将数据转化为tf.int32格式。tf.reduce_sum表示为压缩求和。

fully_connected_feed.py

在开始训练之前我们需要先用tf.placeholder占位符帮手写体数据集占一个位置,这里我们的标签的维度是[batch_size, 1]:

def placeholder_inputs(batch_size):images_placeholder = tf.placeholder(tf.float32, shape=(batch_size,mnist.IMAGE_PIXELS))labels_placeholder = tf.placeholder(tf.int32, shape=(batch_size))return images_placeholder, labels_placeholder

run_training():

在开始训练之前,我们需要去读取数据:

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

read_data_sets函数是input_data.py源码中的函数,主要用于读取数据,它需要三个参数:

  • train_dir——文件夹的文件夹的位置
  • fake_data——是否使用假数据,默认为False
  • one_hot——是否把标签转为一维向量,默认为False,由于这里没有采用one-hot编码,那么这里的返回值就是图片数字的下标,也就是图片数字到底是几。是一个单纯的数字,而不是一个十维的向量([0, 0, 0, 1, 0, 0, 0, 0, 0, 0])。

run_training()这个函数的一开始,是一个Python语言中的with命令,这个命令表明所有已经构建的操作都要与默认的tf.Graph全局实例关联起来。

with tf.Graph().as_default():

tf.Graph实例是一系列可以作为整体执行的操作。TensorFlow的大部分场景只需要依赖默认图表一个实例即可。利用多个图表的更加复杂的使用场景也是可能的,但是超出了本教程的范围。

之后的话,我们需要调用之前写好的神经网络来对其进行训练,在训练之前需要调用之前写好的占位符函数placeholder_input()来给输入数据占个位置:

images_placeholder, labels_placeholder = placeholder_inputs(FLAGS.batch_size)

这样的话我们就假装我们有了输入的图片和其对应的标签(其实是没有的,我们需要之后再将其传进来,嘻嘻),接下来我们构建图的输出公式:

logits = mnist.inference(images_placeholder,FLAGS.hidden1,FLAGS.hidden2)

选择损失和训练参数:

    loss = mnist.loss(logits, labels_placeholder)train_op = mnist.training(loss, FLAGS.learning_rate)

评估模型结果指标:

eval_correct = mnist.evaluation(logits, labels_placeholder)

接下来我们把图运行过程中发生的事情(产生的数据记录下来):

summary = tf.summary.merge_all()

初始化变量:

init = tf.global_variables_initializer()

建立一个保存训练中间数据的存档点:

saver = tf.train.Saver()

建立会话:

sess = tf.Session()

创建一个记事本写入器(这里我也想吐槽一下,为什么不之前的创建记事本放在一起):

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

之后再初始化变量:

sess.run(init)

做完这些基本的操作之后我们就可以对其进行迭代训练了,但是在迭代训练之前我们得处理一下我们的输入数据,之前我们一直都是用tf.placeholder来假装我们有输入数据,现在我们需要将真实数据传入进来:

def fill_feed_dict(data_set, images_pl, labels_pl):images_feed, labels_feed = data_set.next_batch(FLAGS.batch_size,FLAGS.fake_data)feed_dict = {images_pl: images_feed,labels_pl: labels_feed}return feed_dict

fill_feed_dict函数输入是数据,图像placeholder的变量名称,和标签placeholder的变量名称,返回一个字典,即需要传入到会话图中的数据。再接着就可以对其进行迭代训练:

    for step in xrange(FLAGS.max_steps):start_time = time.time()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数组,而这些数组中包含了当前这步训练中对应Tensor的值。由于train_op并不会产生输出,其在返回的元祖中的对应元素就是None,所以会被抛弃。但是,如果模型在训练中出现偏差,loss Tensor的值可能会变成NaN,所以我们要获取它的值,并记录下来。我们也希望记录一下程序运行的时间:

duration = time.time() - start_time

如果进行顺利的话,我们每隔100步,打印一下步数,损失函数值,和程序运行的时间。

      if step % 100 == 0:print('Step %d: loss = %.2f (%.3f sec)' % (step, loss_value, duration))summary_str = sess.run(summary, feed_dict=feed_dict)summary_writer.add_summary(summary_str, step)summary_writer.flush()

在每次运行summary时,都会往事件文件中写入最新的即时数据,函数的输出会传入事件文件读写器(writer)的add_summary()函数。

我们也希望能够保存我们的训练模型:

      if (step + 1) % 1000 == 0 or (step + 1) == FLAGS.max_steps:checkpoint_file = os.path.join(FLAGS.log_dir, 'model.ckpt')saver.save(sess, checkpoint_file, global_step=step)

接下来我们定义一个评估模型的函数:

def do_eval(sess,eval_correct,images_placeholder,labels_placeholder,data_set):true_count = 0  # Counts the number of correct predictions.steps_per_epoch = data_set.num_examples // FLAGS.batch_sizenum_examples = steps_per_epoch * FLAGS.batch_sizefor 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)precision = float(true_count) / num_examplesprint('Num examples: %d  Num correct: %d  Precision @ 1: %0.04f' %(num_examples, true_count, precision))
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)

每隔一千个训练步骤,我们的代码会尝试使用训练数据集与测试数据集,对模型进行评估。do_eval函数会被调用三次,分别使用训练数据集、验证数据集合测试数据集。

总的代码文件目录如下:

总的代码文档链接:链接:https://pan.baidu.com/s/1TqOJSWeHbIV6kMJBwT1mYA  提取码:2h6h

https://github.com/18279406017/code-of-csdn/tree/master/Tensorflow/six

参考

http://www.tensorfly.cn/tfdoc/tutorials/mnist_tf.html

https://tensorflow.googlesource.com/tensorflow/+/master/tensorflow/g3doc/tutorials/mnist/tf/index.md

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/fully_connected_feed.py

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/mnist.py

Tensorflow官方文档学习理解 (六)-TensorFlow运作方式入门相关推荐

  1. tensorflow学习笔记十7:tensorflow官方文档学习 How to Retrain Inception's Final Layer for New Categories

    现代物体识别模型有数以百万计的参数,可能需要数周才能完全训练.学习迁移是一个捷径,很多这样的工作,以充分的训练模式的一组类ImageNet技术,并从现有的权重进行新课.在这个例子中,我们将从头再训练最 ...

  2. 每天一小时python官方文档学习(六)————循环和条件控制的进阶用法

    学习完数据结构之后,我们就能够对之前在第二天中讲过的流程控制工具,添加更多的用法了,这里主要介绍的是for循环语句和if与while条件判断语句. 5.6. 循环的技巧 我们学过的遍历序列for i ...

  3. TensorFlow官方文档中的sub 和mul中的函数已经在API中改名了

    照着tensorflow 官方文档学习tensorflow时,出现问题: 第一,执行程序 #进入一个交互式Tensorflow会话 import tensorflow as tf sess = tf. ...

  4. TensorFlow 官方文档中文版发布啦(持续维护)

    TensorFlow 是 Google 研发的第二代人工智能学习系统,是 Google 为了帮助全球开发者们更加方便和高效地开发机器学习 (Machine Learning)和人工智能 (AI) 应用 ...

  5. tensorflow官方文档_开源分享:最好的TensorFlow入门教程

    如果一门技术的学习曲线过于陡峭,那么我们在入门时的场景往往是,一鼓作气,没入门,再而衰,三而竭.演绎一出从入门到放弃的败走麦城. 今天发现一个入门TensorFlow的宝藏,迫不及待的分享给大家.这个 ...

  6. TensorFlow 官方文档中文版发布啦(持续维护) 1

    TensorFlow 是 Google 研发的第二代人工智能学习系统,是 Google 为了帮助全球开发者们更加方便和高效地开发机器学习 (Machine Learning)和人工智能 (AI) 应用 ...

  7. 嫌官方文档太烂?TensorFlow 开源工具书,助你快速上手开发!

    公众号关注 "GitHubDaily" 设为 "星标",每天带你逛 GitHub! 转自机器之心 「官方文档排布凌乱.搜索难用.API 丑陋不堪--」这是很多人 ...

  8. TensorFlow 官方文档中文版

    TensorFlow 官方文档中文版: http://wiki.jikexueyuan.com/project/tensorflow-zh/ w3cschool https://www.w3cscho ...

  9. Spring Boot 官方文档学习(一)入门及使用

    Spring Boot 官方文档学习(一)入门及使用 个人说明:本文内容都是从为知笔记上复制过来的,样式难免走样,以后再修改吧.另外,本文可以看作官方文档的选择性的翻译(大部分),以及个人使用经验及问 ...

  10. HarmonyOS(一) 快速开始学习鸿蒙开发,官方文档学习路线解析

    系列文章目录 HarmonyOS(一):快速开始学习鸿蒙开发,官方文档学习路线解析 HarmonyOS(二):应用开发环境搭建准备 HarmonyOS(三):创建你的第一个HelloWorld应用 文 ...

最新文章

  1. 咨询业或将危害电力信息化进程?
  2. Java学习笔记32
  3. Spring IoC 源码系列(四)bean创建流程与循环依赖问题分析
  4. linux下反删除软件,浅谈Linux文件系统反删除方法(二)
  5. ble 连接成功后找不到服务_闷声发大财的BLE芯片龙头
  6. 1个报表工具,5大体系,60种可视化图表,靠这些打动领导就够了
  7. 蚁群算法路径规划_环境感知与规划专题(十)——基于采样的路径规划算法(二)...
  8. 变异数分析_人工智能系统中分析变异的祸害
  9. Vista暴力破解器只是一个玩笑 谁说破解谁撒谎
  10. 算法笔记练习 题解合集
  11. java jbutton方法_java-如何设置JButton的大小?
  12. 这么连接计算机网络,详细教您手机怎么连接电脑上网
  13. 06 Redis中BigKey、HotKey的发现与处理
  14. Titan数据库简介
  15. FULL JOIN 数据库全连接查询SQL
  16. 旧瓶新酒之ngx_lua fail2ban实现主动诱捕
  17. python画图入门例子
  18. Revit获取族预览图
  19. linux系统拷贝文件到桌面,centos拷贝文件夹命令
  20. JDK 12 ,JDK 13 , JDK 14 新特性 详解

热门文章

  1. LINUX文件处理命令
  2. ESXi配置vCenter服务器
  3. 路由器获取路由后加表原则
  4. 基于天地图标点html教程,天地图WEB API入门指导
  5. Cobbler详解(四)——CentOS7系统导入
  6. Linux firewall防火墙详解(二)——firewall配置
  7. runC爆严重漏洞影响Kubernetes、Docker,阿里云修复runC漏洞的公告
  8. Android冷启动优化解析
  9. linux-centos使用 wget命令获取jdk
  10. 《TensorFlow技术解析与实战》——1.1 什么是人工智能