《TensorFlow实战Google深度学习框架》API整理(三)

目录

 

Ch5:MNIST数字识别问题

from tensorflow.examples.tutorials.mnist import input_data

tf.nn.relu()

tf.truncated_normal()

tf.argmax()

tf.nn.sparse_softmax_cross_entropy_with_logits()

tf.contrib.layers.l2_regularizer()

tf.control_dependencies()/tf.no_op()

tf.cast()

tf.train.Saver()

tf.train.import_meta_graph()

tf.assign()

其它

参考


Ch5:MNIST数字识别问题

from tensorflow.examples.tutorials.mnist import input_data

#将数据集提取为三个部分:mnist.trainmnist.testmnist.validation,每个部分包含有imageslabelstraintestvalidation中样本的数量分别为55000100005000

mnist = input_data.read_data_sets("../../datasets/MNIST_data/", one_hot=True)
batch_size = 100
xs, ys = mnist.train.next_batch(batch_size)    # 从train的集合中选取batch_size个训练数据。

tf.nn.relu()

线性整流函数(Rectified Linear Unit, ReLU),又称修正线性单元。等同于max(0,x),将输入小于0的值赋值为0,输入大于0的值不变。

import tensorflow as tf
 
a = tf.constant([-1.0, 2.0,-3.6])
with tf.Session() as sess:
    b = tf.nn.relu(a)
    print(sess.run(b))

#实际上是上一章调用ema的average接口,来获取当前时序数据的指数滑动平均值

avg_class.average(weights2)

tf.truncated_normal()

tf.truncated_normal(shape, mean, stddev) :shape表示生成张量的维度,mean是均值,stddev是标准差。这个函数产生正态分布,均值和标准差自己设定。这是一个截断的产生正态分布的函数,就是说产生正态分布的值如果与均值的差值大于两倍的标准差,那就重新生成。和一般的正态分布的产生随机数据比起来,这个函数产生的随机数与均值的差距不会超过两倍的标准差,但是一般的别的函数是可能的。

tf.argmax()

tf.argmax(vector, 1):返回的是vector中的最大值的索引号,如果vector是一个向量,那就返回一个值,如果是一个矩阵,那就返回一个向量,这个向量的每一个维度都是相对应矩阵行的最大值元素的索引号。

import tensorflow as tf
import numpy as np
 
A = [[1,3,4,5,6]]
B = [[1,3,4], [2,4,1]]
 
with tf.Session() as sess:
    print(sess.run(tf.argmax(A, 1)))
print(sess.run(tf.argmax(B, 1)))

输出:
[4]
[2 1]

tf.nn.sparse_softmax_cross_entropy_with_logits()

注意与tf.nn.sigmoid_cross_entropy_with_logits以及tf.nn.softmax_cross_entropy_with_logits的区别和联系。首先顾名思义,tf.nn.sparse_softmax_cross_entropy_with_logits和tf.nn.softmax_cross_entropy_with_logits都是将输入送到softmax层,再利用softmax层的输入和实际的标签数据,来计算交叉熵,交叉熵是分类问题中常见的损失函数。二者的区别主要在于二者使用的标签真值形式是不同的

  • sparse_softmax_cross_entropy_with_logits:

使用的是实数来表示类别,数据类型为int16,int32,或者 int64,标签大小范围为[0,num_classes-1],标签的维度为[batch_size]大小

  • softmax_cross_entropy_with_logits

使用的是one-hot二进制码来表示类别,数据类型为float16,float32,或者float64,维度为[batch_size, num_classes]。这里需要说明一下的时,标签数据类型并不是Bool型的。这是因为实际上在tensorflow中,softmax_cross_entropy_with_logits中的每一个类别是一个概率分布,tensorflow中对该模块的说明中明确指出了这一点,Each row labels[i] must be a valid probability distribution。很显然,one-hot的二进码也可以看是一个有效的概率分布。

import tensorflow as tf

sess = tf.InteractiveSession()
logits = tf.constant([[1.0, 2.0, 3.0], [1.0, 2.0, 3.0], [1.0, 2.0, 3.0]])
labels = tf.constant([[0.0, 0.0, 1.0], [0.0, 0.0, 1.0], [0.0, 0.0, 1.0]])
softmax = tf.nn.softmax(logits)
sparse_labels = tf.argmax(labels, 1)
cross_entropy = -tf.reduce_sum(labels * tf.log(softmax))
cross_entropy2 = tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=labels))
cross_entropy3 = tf.reduce_sum(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=sparse_labels))
print("sparse_labels                        : {}".format(sparse_labels.eval()))
print("cross entropy by tf                  : %.4f" % cross_entropy.eval())
print("cross entropy by softmax_cross       : %.4f" % cross_entropy2.eval())
print("cross entropy by sparse_softmax_cross: %.4f" % cross_entropy3.eval())

注意:tf.nn.softmax函数默认(dim=-1)是对张量最后一维的shape=(p,)向量进行softmax计算,得到一个概率向量。不同的是,tf.nn.sigmoid函数对一个张量的每一个标量元素求得一个概率。也就是说tf.nn.softmax默认针对1阶张量进行运算,可以通过指定dim来针对1阶以上的张量进行运算,但不能对0阶张量进行运算。而tf.nn.sigmoid是针对0阶张量,。

下面说说tf.nn.sigmoid_cross_entropy_with_logits:不同于softmax系列函数是张量中向量与向量间的运算。sigmoid_cross_entropy_with_logits函数则是张量中标量与标量间的运算。

z = 0.8
x = 1.3
cross_entropy4 = tf.nn.sigmoid_cross_entropy_with_logits(labels=z, logits=x)
# tf.nn.sigmoid_cross_entropy_with_logits的具体实现:
cross_entropy5 = - z * tf.log(tf.nn.sigmoid(x)) \
                 - (1-z) * tf.log(1-tf.nn.sigmoid(x))
sess = tf.InteractiveSession()
print(sess.run(cross_entropy4))
print(sess.run(cross_entropy5))

cross_entropy4 与cross_entropy5 的值是相等的。sigmoid_cross_entropy_with_logits的具体实现就是

如果sigmoid_cross_entropy_with_logits的labels和logits是相同shape的张量,输出结果则是与labels和logits有相同shape的张量。张量的每个元素都是labels和logits相对的值捉对按上述方法计算出来的交叉熵。

tf.contrib.layers.l2_regularizer()

创建一个L2正则化方法

tf.control_dependencies()/tf.no_op()

在有些机器学习程序中我们想要指定某些操作执行的依赖关系,这时我们可以使用tf.control_dependencies()来实现。control_dependencies(control_inputs)返回一个控制依赖的上下文管理器,使用with关键字可以让在这个上下文环境中的操作都在control_inputs 执行。

with g.control_dependencies([a, b, c]):
  # `d` and `e` will only run after `a`, `b`, and `c` have executed.
  d = ...
  e = ...

可以嵌套control_dependencies 使用

with g.control_dependencies([a, b]):
  # Ops constructed here run after `a` and `b`.
  with g.control_dependencies([c, d]):
# Ops constructed here run after `a`, `b`, `c`, and `d`.

可以传入None 来消除依赖:

with g.control_dependencies([a, b]):
  # Ops constructed here run after `a` and `b`.
  with g.control_dependencies(None):
    # Ops constructed here run normally, not waiting for either `a` or `b`.
    with g.control_dependencies([c, d]):
      # Ops constructed here run after `c` and `d`, also not waiting
      # for either `a` or `b`.

在训练模型时,我们每步训练可能要执行两种操作,op a,b这时我们就可以使用如下代码

with tf.control_dependencies([a, b]):
    c= tf.no_op(name='train') # tf.no_op;什么也不做
sess.run(c)
# 也可以将其替换为
c= tf.group([a, b])
sess.run(c)

tf.cast()

tf.cast()函数的作用是执行 tensorflow 中张量数据类型转换,比如读入的图片如果是int8类型的,一般在要在训练前把图像的数据格式转换为float32。

cast定义:

cast(x, dtype, name=None)

第一个参数 x:   待转换的数据(张量)

第二个参数 dtype: 目标数据类型

第三个参数 name: 可选参数,定义操作的名称

tf.train.Saver()

模型保存,先要创建一个Saver对象:如

saver = tf.train.Saver(max_to_keep=0)

这里的max_keep参数代表的是保存模型的个数,默认为5。

TensorFlow中的Saver对象是用于参数保存和恢复的。其实 创建 saver对象时使用的键值对就是表达了一种对应关系:

save时, 表示:variable的值应该保存到 checkpoint文件中的哪个 key

restore时,表示:checkpoint文件中key对应的值,应该restore到哪个variable

参数会保存到 checkpoint 文件中,通过键值对的形式在 checkpoint中存放着。如果 Saver 的构造函数中传的是 dict,那么在 save 的时候,checkpoint文件中存放的就是对应的 key-value。如下:

import tensorflow as tf
# Create some variables.
v1 = tf.Variable(1.0, name="v1")
v2 = tf.Variable(2.0, name="v2")

saver = tf.train.Saver({"variable_1":v1, "variable_2": v2})
# Use the saver object normally after that.
with tf.Session() as sess:
    tf.global_variables_initializer().run()
saver.save(sess, 'test-ckpt/model-2')

我们利用官方提供的工具来查看一下checkpoint中保存了什么

from tensorflow.python.tools.inspect_checkpoint import print_tensors_in_checkpoint_file

print_tensors_in_checkpoint_file("test-ckpt/model-2", None, True)
# 输出:
#tensor_name:  variable_1
#1.0
#tensor_name:  variable_2
#2.0

如果构建saver对象的时候,我们传入的是 list, 那么将会用对应 Variable 的 variable.op.name 作为 key。

import tensorflow as tf
# Create some variables.
v1 = tf.Variable(1.0, name="v1")
v2 = tf.Variable(2.0, name="v2")

saver = tf.train.Saver([v1, v2])
# Use the saver object normally after that.
with tf.Session() as sess:
    tf.global_variables_initializer().run()
saver.save(sess, 'test-ckpt/model-2')
我们再使用官方工具打印出 checkpoint 中的数据,得到

tensor_name:  v1
1.0
tensor_name:  v2
2.0

如果我们现在想将 checkpoint 中v2的值restore到v1 中,v1的值restore到v2中,我们该怎么做?

这时,我们只能采用基于 dict 的 saver

import tensorflow as tf
# Create some variables.
v1 = tf.Variable(1.0, name="v1")
v2 = tf.Variable(2.0, name="v2")

saver = tf.train.Saver({"variable_1":v1, "variable_2": v2})
# Use the saver object normally after that.
with tf.Session() as sess:
    tf.global_variables_initializer().run()
saver.save(sess, 'test-ckpt/model-2')

restore的代码和save的代码有所不同

import tensorflow as tf
# Create some variables.
v1 = tf.Variable(1.0, name="v1")
v2 = tf.Variable(2.0, name="v2")
#restore的时候,variable_1对应到v2,variable_2对应到v1,就可以实现目的了。
saver = tf.train.Saver({"variable_1":v2, "variable_2": v1})
# Use the saver object normally after that.
with tf.Session() as sess:
    tf.global_variables_initializer().run()
    saver.restore(sess, 'test-ckpt/model-2')
    print(sess.run(v1), sess.run(v2))
# 输出的结果是 2.0 1.0,如我们所期望的那样

回顾总结:

save时, 表示:variable的值应该保存到 checkpoint文件中的哪个 key下;restore时,表示:checkpoint文件中key对应的值,应该restore到哪个variable。

tf.train.import_meta_graph()

import_meta_graph将定义在.meta的网络导入到当前图中。所以,这会替你创造图/网络,但我们仍然需要导入在这张图上训练好的参数。一般来说加载完成模型之后,会需要手动加载参数,所以会和saver.restore()api联合使用。

with tf.Session() as sess:
  new_saver = tf.train.import_meta_graph('my_test_model-1000.meta')
  new_saver.restore(sess, tf.train.latest_checkpoint('./'))

tf.assign()

tf.assign(A, new_number): 这个函数的功能主要是把A的值变为new_number

直接在保存模型时保存时序数据的ema值

v = tf.Variable(0, dtype = tf.float32, name="v")
ema = tf.train.ExponentialMovingAverage(0.99)
print(ema.variables_to_restore())

saver = tf.train.Saver(ema.variables_to_restore())
with tf.Session() as sess:
saver.restore(sess, "Saved_model/model2.ckpt")

其它

tf.get_default_graph().as_graph_def():得到当前图的计算节点信息

graph_util.convert_variables_to_constants():将相关节点的values固定

tf.gfile.GFile(): # 保存模型

graph_def.ParseFromString(f.read())通过得到模型中的图和变量数据

tf.import_graph_def()加载目前的图

gfile.FastGFile()

tf.gfile.FastGFile(path,decodestyle)

函数功能:实现对图片的读取。

函数参数:(1)path:图片所在路径 (2)decodestyle:图片的解码方式。(‘r’:UTF-8编码; ‘rb’:非UTF-8编码)

saver.export_meta_graph():详见https://zhuanlan.zhihu.com/p/31308381

tf.train.NewCheckpointReader() 用于创建一个reader对象,进而导出持久化模型的所有变量

reader = tf.train.NewCheckpointReader("/home/penglu/Desktop/lp/model.ckpt")
variables = reader.get_variable_to_shape_map() 
for ele in variables:
	print(ele)

reader.get_tensor(key) 用于查看ckpt模型文件中的变量

参考

Saver(保存与加载模型)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值