TensorFlow运作方式

要用到的代码都在Github上。当然,如果你本地装了TensorFlow,也可以用Everything直接搜索以下文件:

  • mnist.py
  • fully_connected_feed.py

    要开始训练,只需要:
    python fully_connected_feed.py

准备数据,下载数据;

设置输入与占位符大小

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

构建计算图

  • interence()-前向反馈网络的构建;
  • loss()-添加计算损失的OP;
  • training()-添加计算梯度的OP;
  1. interfence

每一层都有唯一的tf.name_space作用域:

with tf.name_scope('hidden1') as scope:

每一层的权重和偏差为:

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作用域下的权重变量名称是hidden1/weights

  1. loss

    计算预测值tensor(logits)与标签tensor(labels)的交叉熵,并将其第一维度下的交叉熵的平均值作为loss;

  2. training

    training()函数添加了通过梯度下降(gradient descent)将损失最小化所需的操作。它包括:

    • 获取损失Tensor,传递到tf.scalar_summary函数(它可向事件文件events files中写入总结报告的值);

    tf.scalar_summary(loss.op.name, loss)

    • 按照学习率应用梯度下降法;

    optimizer = tf.train.GradientDescentOptimizer(FLAGS.learning_rate)

    • 用全部变量global_step记录全局训练的次数,并用minimize()进行优化;

    global_step = tf.Variable(0, name='global_step', trainable=False)

    train_op = optimizer.minimize(loss, global_step=global_step)

训练模型

一般训练模型文件是另一个*.py文件。

  1. 计算图

    run_training函数的开始,应该将所有操作都与tf.Graph全局关联:

    with tf.Graph().as_default():

  2. 会话

    sess = tf.Session()
    init = tf.initialize_all_variables()
    sess.run(init)
  3. 训练循环

    for step in xrange(max_steps):
    sess.run(train_op)
  4. 提供变量(feed)

    assets_feed, labels_feed = data_set.next_batch(FLAGS.batch_size)
    feed_dict = {
    assets_placeholder: assets_feed,
    labels_placeholder: labels_feed,
    }
    sess.run(feed_dict=feed_dict)
  5. 获取运行状态

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

    并打印状态:

    if step % 100 == 0:
    print 'Step %d: loss = %.2f (%.3f sec)' % (step, loss_value, duration)
  6. 状态可视化

    summary_op = tf.merge_all_summaries() #所有的训练中的即时数据在图表构建阶段合并到该op
    summary_writer = tf.train.SummaryWriter(FLAGS.train_dir, # 实例化一个SummaryWriter用于写入Graph及即时数据值的事件文件
    graph_def=sess.graph_def)
    summary_str = sess.run(summary_op, feed_dict=feed_dict) #将summary_op的所有数据运行
    summary_writer.add_summary(summary_str, step) #写入事件文件

    训练文件夹下打开TensorBoard,可查看即时数据的迭代值随step的变化。

  7. 保存检查点(checkpoint)

    训练中会自动定期调用saver.save()方法,向训练文件夹中写入当前所有Variable的值的文件。

    saver = tf.train.Saver()
    saver.save(sess, FLAGS.train_dir, global_step=step)
    saver.restore(sess, FLAGS.train_dir) #用该方法重新载入模型的参数,继续训练

评估模型

每训练1000步,尝试使用训练集和验证集对模型评估:

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

构建评估计算图(Eval Graph),并输出

test_all_assets, test_all_labels = get_data(train=False) #获取验证集
eval_correct = mnist.evaluation(logits, labels_placeholder) #进行验证
eval_correct = tf.nn.in_top_k(logits, labels, 1) #

之后,我们可以创建一个循环,往其中添加feed_dict,并在调用sess.run()函数时传入eval_correct操作,目的就是用给定的数据集评估模型。

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

true_count变量会累加所有in_top_k操作判定为正确的预测之和。接下来,只需要将正确测试的总数,除以例子总数,就可以得出准确率了。

precision = float(true_count) / float(num_examples)
print ' Num examples: %d Num correct: %d Precision @ 1: %0.02f' % (
num_examples, true_count, precision)

卷积神经网络案例2:进阶的卷积网络

之前的MNIST数据集构建的卷积网络较为简单,现在不再使用简单的MNIST手写数据集,而使用CIFAR-10数据集(该数据集上,深度模型可表现更优越),它包括60000张32$\times$32的彩图,训练集50000张,测试集10000张。Labels共标注10类。

分别是飞机,汽车,鸟,猫,鹿,狗,青蛙,马,船,卡车。CIFAR-10非常通用,常用来论文中用于性能对比,还曾出现在Kaggle竞赛。

该神经网络在GTX1080单显卡(只是用3000个batch,每个batch包含128个样本)须要几十秒。

训练时的小Trick

  • 对图片进行翻转,随机剪切,随机亮度,随机对比度,高斯标准化等得到更多样本进行数据增强;(distorted_inputs函数in file cifar10_input.py)
  • 对权重进行L2正则化;(_variable_with_weight_decay in file cifar10_pruning.py)
  • 每个卷积-池化层后使用LRN层,增强泛化能力。

下面直接上代码:

# -*- coding: utf-8 -*-
# 载入常用库,NumPy的time,并载入TlensorFow Models中的自动下载、读取CIFAR-10数据的类。
import cifar10_pruning as cifar10
import cifar10_input
import tensorflow as tf
import numpy as np
import time ########输入数据########
# 训练论数、batch大小(3000个batch,每个batch包含128个样本)。
max_steps = 10000
batch_size = 128
# 下载CIFAR-10数据的默认路径
data_dir = '/tmp/cifar10_data/cifar-10-batches-bin' ########初始化权重########
# 定义初始化weight的函数,依然使用tf.truncated_normal截断的正态分布来初始化权重。
# 这里给weight加一个L2的loss,相当于做了一个L2的正则化处理。这个collection名为“losses”,会在后面计算总体loss时被用上
def variable_with_weight_loss(shape, stddev, wl):
var = tf.Variable(tf.truncated_normal(shape, stddev = stddev))
if wl is not None:
weight_loss = tf.multiply(tf.nn.l2_loss(var), wl, name = 'weight_loss')
tf.add_to_collection('losses', weight_loss)
return var ########数据处理########
# 把cifar10的数据解压到data_dir中,然后将下一行代码注释掉,取消运行
# (用到cifar-10.py)使用CIFAR-10下载数据集,并解压展开到其默认位置
cifar10.maybe_download_and_extract() # 使用cifar10_input类中的distorted_input函数产生训练需要使用的数据,返回的是已经封装好的tensor,每次执行都会生成一个batch_size的数量的样本。
assets_train, labels_train = cifar10_input.distorted_inputs(data_dir = data_dir, batch_size = batch_size) # 使用cifar10_input.inputs函数生成测试数据。需要裁剪图片正中间的24*24的区块,并进行数据标准化操作。
assets_test, labels_test = cifar10_input.inputs(eval_data = True, data_dir = data_dir, batch_size = batch_size) # 创建输入数据的placeholder。batche_size在之后定义网络结构时被用到了,所以数据尺寸的第一个值样本条数需要提前设定。
image_holder = tf.placeholder(tf.float32, [batch_size, 24, 24, 3])
label_holder = tf.placeholder(tf.int32, [batch_size]) ########设计网络结构########
# 第一个卷积层
# 创建卷积核并进行初始化,不对第一个卷积层的weight进行L2正则
weight1 = variable_with_weight_loss(shape = [5,5,3,64], stddev = 5e-2, wl = 0.0)
# 对输入数据进行卷积操作
kernel1 = tf.nn.conv2d(image_holder, weight1, [1,1,1,1], padding = 'SAME')
# 这层的bias全部初始化为0,再将卷积的结果加上bias
bias1 = tf.Variable(tf.constant(0.0, shape = [64]))
# 使用激活函数进行非线性化
conv1 = tf.nn.relu(tf.nn.bias_add(kernel1, bias1))
# 使用尺寸为3*3且步长为2*2的最大池化层处理数据,最大池化层的尺寸和步长不一致,增加数据的丰富性
pool1 = tf.nn.max_pool(conv1, ksize = [1,3,3,1], strides = [1,2,2,1], padding = 'SAME')
# 使用LRN对结果进行处理,对局部神经元的活动创建竞争环境,增强模型的泛化能力
norm1 = tf.nn.lrn(pool1, 4, bias = 1.0, alpha = 0.001/9.0, beta = 0.75) # 第二个卷积层(与上一层相似)
# 上一层的卷积核数量为64(即输出64个通道)。本层卷积核的第三维度输入通道数为64。
weight2 = variable_with_weight_loss(shape = [5,5,64,64], stddev = 5e-2, wl = 0.0)
kernel2 = tf.nn.conv2d(norm1, weight2, [1,1,1,1], padding = 'SAME')
# bias值全部初始化为0.1。
bias2 = tf.Variable(tf.constant(0.1, shape = [64]))
conv2 = tf.nn.relu(tf.nn.bias_add(kernel2, bias2))
# 与上一层不同,先进行LRN处理,在进行最大池化层。
norm2 = tf.nn.lrn(conv2, 4, bias = 1.0, alpha = 0.001/9.0, beta = 0.75)
pool2 = tf.nn.max_pool(norm2, ksize = [1,3,3,1], strides = [1,2,2,1], padding = 'SAME') # 全连接层
# 将上一层的输出结果进行flatten。tf.reshape函数将每个样本都变成一维向量。
reshape = tf.reshape(pool2, [batch_size, -1])
# 获取数据扁平化之后的长度。
dim = reshape.get_shape()[1].value
# 对全连接层的weight进行初始化,隐含节点数为384,正太分布的标准差0.04。设置非零的weight loss,这一程所有参数被L2正则约束。
weight3 = variable_with_weight_loss(shape = [dim, 384], stddev = 0.04, wl = 0.004)
# bias值初始化为0.1
bias3 = tf.Variable(tf.constant(0.1, shape = [384]))
# 使用激活函数进行非线性化
local3 = tf.nn.relu(tf.matmul(reshape, weight3) + bias3) # 全连接层(与上一层类似)
# 隐含层节点数下降一半只有192个,其他超参数保持不变
weight4 = variable_with_weight_loss(shape = [384,192], stddev = 0.04, wl = 0.004)
bias4 = tf.Variable(tf.constant(0.1, shape = [192]))
local4 = tf.nn.relu(tf.matmul(local3, weight4) + bias4) # 输出层(把Softmax的操作放在了loss部分)
# 创建weight,其正态分布标准差为上一层隐含节点的倒数,并且不计入L2的正则。
weight5 = variable_with_weight_loss(shape = [192,10], stddev = 1/192.0, wl = 0.0)
bias5 = tf.Variable(tf.constant(0.0, shape = [10]))
# Softmax放在下面的原因。我们不需要对inference的输出进行softmax处理就可以获得最终的分类结果。
# 直接比较inference输出的各类的数值大小即可。计算softmax主要是为了计算loss。因此softmax操作整合到后面合适。
# 模型Inference的输出结果
logits = tf.nn.relu(tf.matmul(local4, weight5) + bias5) ########计算CNN的loss########
# softmax和cross entropy loss的计算合在一起
# 得到最终的loss,其中包括cross entropy loss和后两个全连接层weight的L2 loss
def loss(logits, labels):
labels = tf.cast(labels, tf.int64)
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits = logits, labels = labels, name = 'cross_entropy_per_example')
cross_entropy_mean = tf.reduce_mean(cross_entropy, name = 'cross_entropy')
tf.add_to_collection('losses', cross_entropy_mean)
return tf.add_n(tf.get_collection('losses'), name = 'total_loss')
# loss函数中传入值,获得最终的loss
loss = loss(logits, label_holder) ########训练设置 ########
# 选择优化器,学习速率设为1e-3
train_op = tf.train.AdamOptimizer(1e-3).minimize(loss)
# 输出结果中top k的准确率,也就是输出分数最高的那一类的准确率
top_k_op = tf.nn.in_top_k(logits, label_holder, 1) # 创建默认的Session
sess = tf.InteractiveSession()
# 初始化全部模型参数
tf.global_variables_initializer().run()
# 启动图片数据增强的线程队列,一共使用16个线程进行加速。不启动无法开始后面的inference
tf.train.start_queue_runners() ########开始训练########
# 记录每个step花费的时间,每隔10个step计算并展示当前的loss、每秒能训练的样本数量,以及在一个batch花费的时间。
for step in range(max_steps):
start_time = time.time()
# 在每一个step的训练过程,先获得一个batch数据。再将这个batch数据传入train_op和loss的计算。
image_batch, label_batch = sess.run([assets_train, labels_train])
_, loss_value = sess.run([train_op, loss],
feed_dict = {image_holder: image_batch, label_holder: label_batch})
duration = time.time() - start_time
if step %10 ==0:
examples_per_sec = batch_size / duration
sec_per_batch = float(duration)
format_str = ('step %d,loss=%.2f (%.1f example/sec; %.3f sec/batch)')
print(format_str % (step, loss_value, examples_per_sec, sec_per_batch)) # 测试集评测准确率
# 测试集样本数
num_examples = 10000
import math
# 计算多少个batch能将全部样本评测完
num_iter = int(math.ceil(num_examples / batch_size))
true_count = 0
total_sample_count = num_iter * batch_size
step = 0
# 在每一个的step中使用Session的run方法获取test的batch
# 再执行top_k_op计算模型在这个batch的top 1上预测正确的样本数。
# 最后汇总所有预测正确的结果,求得全部测试样本中预测正确的数量。
while step < num_iter:
image_batch, label_batch = sess.run([assets_test,labels_test])
predictions = sess.run([top_k_op], feed_dict = {image_holder: image_batch, label_holder: label_batch})
true_count += np.sum(predictions)
step += 1
# 最后将准确率评测结果计算并打印出来。
precision = true_count / total_sample_count
# print('precision @ 1 = %.3f' % precision) print (' Num examples: %d Num correct: %d Precision @ 1: %0.02f ' % (
total_sample_count, true_count, precision))

当前最新版本的tutorial已经更新了版本,其中--max_steps可以按以下代码控制:

以下代码训练了5000*2步,至于为什么乘以2,不知道...待学习。

parser.add_argument(
'--max_steps',
type=int,
default=5000,
help='Number of batches to run.')

TensorFlow学习笔记11-开始用TensorFlow的更多相关文章

  1. Tensorflow学习笔记4:分布式Tensorflow

    简介 Tensorflow API提供了Cluster.Server以及Supervisor来支持模型的分布式训练. 关于Tensorflow的分布式训练介绍可以参考Distributed Tenso ...

  2. Tensorflow 学习笔记(一)TensorFlow入门

    一.计算模型----计算图 1.1 计算图的概念:TensorFlow就是通过图的形式绘制出张量节点的计算过程,例如下图执行了一个a+b的操作. 1.2 计算图的使用 TensorFlow程序一般分为 ...

  3. Tensorflow学习笔记2019.01.03

    tensorflow学习笔记: 3.2 Tensorflow中定义数据流图 张量知识矩阵的一个超集. 超集:如果一个集合S2中的每一个元素都在集合S1中,且集合S1中可能包含S2中没有的元素,则集合S ...

  4. Tensorflow学习笔记No.11

    图像定位 图像定位是指在图像中将我们需要识别的部分使用定位框进行定位标记,本次主要讲述如何使用tensorflow2.0实现简单的图像定位任务. 我所使用的定位方法是训练神经网络使它输出定位框的四个顶 ...

  5. 深度学习-tensorflow学习笔记(1)-MNIST手写字体识别预备知识

    深度学习-tensorflow学习笔记(1)-MNIST手写字体识别预备知识 在tf第一个例子的时候需要很多预备知识. tf基本知识 香农熵 交叉熵代价函数cross-entropy 卷积神经网络 s ...

  6. tensorflow学习笔记(4)-学习率

    tensorflow学习笔记(4)-学习率 首先学习率如下图 所以在实际运用中我们会使用指数衰减的学习率 在tf中有这样一个函数 tf.train.exponential_decay(learning ...

  7. tensorflow学习笔记(1)-基本语法和前向传播

    tensorflow学习笔记(1) (1)tf中的图 图中就是一个计算图,一个计算过程.                                       图中的constant是个常量 计 ...

  8. tensorflow学习笔记-bili莫烦

    bilibili莫烦tensorflow视频教程学习笔记 1.初次使用Tensorflow实现一元线性回归 # 屏蔽警告 import os os.environ[' import numpy as ...

  9. tensorflow学习笔记——使用TensorFlow操作MNIST数据(2)

    tensorflow学习笔记——使用TensorFlow操作MNIST数据(1) 一:神经网络知识点整理 1.1,多层:使用多层权重,例如多层全连接方式 以下定义了三个隐藏层的全连接方式的神经网络样例 ...

随机推荐

  1. mpg123 - 播放 MPEG 1.0/2.0 Layer-1, -2, -3 音频文件

    语法 mpg123 [ -tscvqy01m24 ][ -b size ][ -k num ][ -n num ][ -f factor ][ -r rate ][ -g gain ][ -a dev ...

  2. vue + nginx部署404

    记录: vue项目打包放到服务器,使用nginx反向代理的时候路由页面刷新报404,因为刷新时,不存在路径对应的文件或文件夹,需要在nginx配置中添加代码: index index.html; tr ...

  3. Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration

    https://www.cnblogs.com/EasonJim/p/7546136.html 错误如下: ERROR 31473 --- [ main] o.s.b.d.LoggingFailure ...

  4. ubuntu上的疑难杂症(不定期更新……)

    ubuntu系统英伟达显卡驱动怎么装 sudo apt-get purge nvidia* #如果之前安装过显卡驱动,就执行这一句来卸载 sudo apt-add-repository ppa:gra ...

  5. Ant Design -- 图片可拖拽效果,图片跟随鼠标移动

    Ant Design 图片可拖拽效果,图片跟随鼠标移动,需计算鼠标在图片中与图片左上角的X轴的距离和鼠标在图片中与图片左上角的Y轴的距离. constructor(props) { super(pro ...

  6. Web基础之http协议

    第6章 Web基础之http协议 第6章 Web基础之http协议一.http协议介绍 1.1)什么是超文本 1.2)什么是URL 1.3)什么是超文本传输协议二.访问网站分析三.页面请求信息解析(仅 ...

  7. PAT Advanced 1042 Shuffling Machine (20 分)(知识点:利用sstream进行转换int和string)

    Shuffling is a procedure used to randomize a deck of playing cards. Because standard shuffling techn ...

  8. Django【第17篇】:Django之信号

    django中的信号 Django中的信号及其用法 Django中提供了"信号调度",用于在框架执行操作时解耦. 一些动作发生的时候,系统会根据信号定义的函数执行相应的操作 Dja ...

  9. [CF1208D] Restore Permutation

    传送门 题意:有一个长为\(n\)的排列\(p\),设\(S_i=\sum_{j=1}^{i-1}p_j\cdot[p_j<p_i]\),给出\(S\),要求还原出\(p\).保证有解,\(n\ ...

  10. java -cp与java -jar的区别

    java -cp 和 -classpath 一样,是指定类运行所依赖其他类的路径,通常是类库,jar包之类,需要全路径到jar包,window上分号“;”格式:java -cp .;myClass.j ...