常用的api做个记录,防止遗忘
reshape
tf.reshape(tensor, shape, name=None)
函数的作用是将tensor变换为参数shape的形式。
其中shape为一个列表形式,特殊的一点是列表中可以存在-1。-1代表的含义是不用我们自己指定这一维的大小,函数会自动计算,但列表中只能存在一个-1。
# tensor 't' is [1, 2, 3, 4, 5, 6, 7, 8, 9]
# tensor 't' has shape [9]
reshape(t, [3, 3]) ==> [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
# tensor 't' is [[[1, 1], [2, 2]],
# [[3, 3], [4, 4]]]
# tensor 't' has shape [2, 2, 2]
reshape(t, [2, 4]) ==> [[1, 1, 2, 2],
[3, 3, 4, 4]]
# tensor 't' is [[[1, 1, 1],
# [2, 2, 2]],
# [[3, 3, 3],
# [4, 4, 4]],
# [[5, 5, 5],
# [6, 6, 6]]]
# tensor 't' has shape [3, 2, 3]
# pass '[-1]' to flatten 't'
reshape(t, [-1]) ==> [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6]
# -1 can also be used to infer the shape
# -1 is inferred to be 9:
reshape(t, [2, -1]) ==> [[1, 1, 1, 2, 2, 2, 3, 3, 3],
[4, 4, 4, 5, 5, 5, 6, 6, 6]]
# -1 is inferred to be 2:
reshape(t, [-1, 9]) ==> [[1, 1, 1, 2, 2, 2, 3, 3, 3],
[4, 4, 4, 5, 5, 5, 6, 6, 6]]
# -1 is inferred to be 3:
reshape(t, [ 2, -1, 3]) ==> [[[1, 1, 1],
[2, 2, 2],
[3, 3, 3]],
[[4, 4, 4],
[5, 5, 5],
[6, 6, 6]]]
# tensor 't' is [7]
# shape `[]` reshapes to a scalar
reshape(t, []) ==> 7
embedding_lookup
embedding_lookup函数的作用更像是一个搜索操作,即根据我们提供的索引,从对应的tensor中寻找对应位置的切片。
代码
# embedding
embedding = tf.constant(
[[0.21,0.41,0.51,0.11]],
[0.22,0.42,0.52,0.12],
[0.23,0.43,0.53,0.13],
[0.24,0.44,0.54,0.14]],dtype=tf.float32)
feature_batch = tf.constant([2,3,1,0])
get_embedding1 = tf.nn.embedding_lookup(embedding,feature_batch)
embedding层其实是一个全连接神经网络层,那么其过程等价于:
embedding = tf.constant(
[
[0.21,0.41,0.51,0.11],
[0.22,0.42,0.52,0.12],
[0.23,0.43,0.53,0.13],
[0.24,0.44,0.54,0.14]
],dtype=tf.float32)
feature_batch = tf.constant([2,3,1,0])
feature_batch_one_hot = tf.one_hot(feature_batch,depth=4)
get_embedding2 = tf.matmul(feature_batch_one_hot,embedding)
gather
embedding_lookup是特殊的gather
gather函数的原型为:
def gather(params, indices, validate_indices=None, name=None, axis=0):
当params是二维的tensor,轴axis=0时,跟我们讲的embedding_lookup函数等价:
embedding = tf.constant(
[
[0.21,0.41,0.51,0.11],
[0.22,0.42,0.52,0.12],
[0.23,0.43,0.53,0.13],
[0.24,0.44,0.54,0.14]
],dtype=tf.float32)
index_a = tf.Variable([2,3,1,0])
gather_a = tf.gather(embedding, index_a)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(gather_a))
结果:
但假设我们的axis不是0,是1呢,其过程如下:
embedding = tf.constant(
[
[0.21,0.41,0.51,0.11],
[0.22,0.42,0.52,0.12],
[0.23,0.43,0.53,0.13],
[0.24,0.44,0.54,0.14]
],dtype=tf.float32)
gather_a_axis1 = tf.gather(embedding,index_a,axis=1)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(gather_a_axis1))
结果:
slice
可以用于切片
原函数如下
def slice(input_, begin, size, name=None):
其中“input_”是你输入的tensor,就是被切的那个。
“begin”是每一个维度的起始位置。
“size”相当于问每个维度拿几个元素出来。
例子1
t = tf.constant([[[1, 1, 1], [2, 2, 2]],
[[3, 3, 3], [4, 4, 4]],
[[5, 5, 5], [6, 6, 6]]])
tf.slice(t, [1, 0, 0], [1, 1, 3])
结果:
[[[3, 3, 3]]]
解析:
第二个参数是维度 第三个参数是在相应维度上的取值
首先第一个数 由于t的size是【3 2 3】,所以【1 0 0 】1表示取3里面的第一维为起始 即[[3, 3, 3], [4, 4, 4]] ,[1 1 3]里面第一参数表示取一个 ,
第二个参数 分别是 0和1 0表示取[[3, 3, 3], [4, 4, 4]] 里面第一维 1表示取一个 结果为3 3 3
第三个参数 0和3 表示从0开始 取三个数 即结果
例子2
t = tf.constant([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]], [[5, 5, 5], [6, 6, 6]]])
tf.slice(t, [1, 0, 0], [1, 2, 3])
结果:
[[[3, 3, 3], [4, 4, 4]]]
transpose
转置操作 一维比较简单
# 'x' is [[1 2 3]
# [4 5 6]]
tf.transpose(x) ==> [[1 4]
[2 5]
[3 6]]
多维
重点来了:
tf.transpose的第二个参数perm=[0,1,2],0 1 2 分别代表着size中的三个数
import tensorflow as tf
#x = tf.constant([[1, 2 ,3],[4, 5, 6]])
x = [[[1,2,3,4],[5,6,7,8],[9,10,11,12]],
[[21,22,23,24],[25,26,27,28],[29,30,31,32]]]
# x的size 为 2X3X4 所以0 1 2 分别代表 2 3 4
#a=tf.constant(x)
a=tf.transpose(x, [0, 1, 2])
#结果应为 a 的size 2 X3 X4
b=tf.transpose(x, [0, 2, 1])
# b的size 2X4X3
c=tf.transpose(x, [1, 0, 2])
d=tf.transpose(x, [1, 2, 0])
e=tf.transpose(x, [2, 1, 0])
f=tf.transpose(x, [2, 0, 1])
with tf.Session() as sess:
print ('---------------')
print (sess.run(a))
print ('---------------')
print (sess.run(b))
print ('---------------')
print (sess.run(c))
print ('---------------')
print (sess.run(d))
print ('---------------')
print (sess.run(e))
print ('---------------')
print (sess.run(f))
print ('---------------')
结果:
---------------
[[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[[21 22 23 24]
[25 26 27 28]
[29 30 31 32]]]
---------------
[[[ 1 5 9]
[ 2 6 10]
[ 3 7 11]
[ 4 8 12]]
[[21 25 29]
[22 26 30]
[23 27 31]
[24 28 32]]]
---------------
[[[ 1 2 3 4]
[21 22 23 24]]
[[ 5 6 7 8]
[25 26 27 28]]
[[ 9 10 11 12]
[29 30 31 32]]]
---------------
[[[ 1 21]
[ 2 22]
[ 3 23]
[ 4 24]]
[[ 5 25]
[ 6 26]
[ 7 27]
[ 8 28]]
[[ 9 29]
[10 30]
[11 31]
[12 32]]]
---------------
[[[ 1 21]
[ 5 25]
[ 9 29]]
[[ 2 22]
[ 6 26]
[10 30]]
[[ 3 23]
[ 7 27]
[11 31]]
[[ 4 24]
[ 8 28]
[12 32]]]
---------------
[[[ 1 5 9]
[21 25 29]]
[[ 2 6 10]
[22 26 30]]
[[ 3 7 11]
[23 27 31]]
[[ 4 8 12]
[24 28 32]]]
concat
在不同的方向进行拼接 不会改变维度的数量 横向和纵向拼接
t1 = [[1, 2, 3],
[4, 5, 6]]
t2 = [[7, 8, 9],
[10, 11, 12]]
tf.concat([t1, t2], 0)
结果:
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]]
tf.concat([t1, t2], 1)
结果:
[[1, 2, 3, 7, 8, 9],
[4, 5, 6, 10, 11, 12]]
对于axis等于负数的情况
负数在数组索引里面表示倒数(countdown)。比如,对于列表ls = [1,2,3]而言,ls[-1] = 3,表示读取倒数第一个索引对应值。
axis=-1表示倒数第一个维度,对于三维矩阵拼接来说,axis=-1等价于axis=2。同理,axis=-2代表倒数第二个维度,对于三维矩阵拼接来说,axis=-2等价于axis=1。
一般在维度非常高的情况下,我们想在最’高’的维度进行拼接,一般就直接用countdown机制,直接axis=-1就搞定了。
squeeze
squeeze(
input,
axis=None,
name=None,
squeeze_dims=None
)
返回将原始input中所有维度为1的那些维都删掉的结果。
例子
t1 = tf.Variable([[[1,2,3,0,0],[4,5,6,0,0]]])
t2=tf.squeeze(t1)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
sess.run(t2)
print(t1.shape)
print(t2.shape)
print(t2.eval())
结果:
(1, 2, 5)
(2, 5)
[[1 2 3 0 0]
[4 5 6 0 0]]
tile
函数定义
tf.tile(
input,
multiples,
name=None
)
input是待扩展的张量,multiples是扩展方法。
假如input是一个3维的张量。那么mutiples就必须是一个1x3的1维张量。这个张量的三个值依次表示input的第1,第2,第3维数据扩展几倍。
例子如下:
import tensorflow as tf
a = tf.constant([[1, 2], [3, 4], [5, 6]], dtype=tf.float32)
a1 = tf.tile(a, [2, 3])
with tf.Session() as sess:
print(sess.run(a))
print(sess.run(tf.shape(a)))
print(sess.run(a1))
print(sess.run(tf.shape(a1)))
结果:
[[1. 2.]
[3. 4.]
[5. 6.]]
[3 2]
[[1. 2. 1. 2. 1. 2.]
[3. 4. 3. 4. 3. 4.]
[5. 6. 5. 6. 5. 6.]
[1. 2. 1. 2. 1. 2.]
[3. 4. 3. 4. 3. 4.]
[5. 6. 5. 6. 5. 6.]]
[6 6]
square
tf.square(a)是对a里的每一个元素求平方
reduce_sum、reduce_mean
tf.reduce_sum(
input_tensor,
axis=None,
keepdims=None,
name=None,
reduction_indices=None,
keep_dims=None)
input_tensor:待求和的tensor;
axis:指定的维,如果不指定,则计算所有元素的总和;
keepdims:是否保持原有张量的维度,设置为True,结果保持输入tensor的形状,设置为False,结果会降低维度,如果不传入这个参数,则系统默认为False;
name:操作的名称;
reduction_indices:在以前版本中用来指定轴,已弃用;
keep_dims:在以前版本中用来设置是否保持原张量的维度,已弃用;
例子:
import tensorflow as tf
x = [[1,2,3],
[1,2,3]]
xx = tf.cast(x,tf.float32)
mean_0 = tf.reduce_mean(xx, axis=1, keep_dims=False)
mean_1 = tf.reduce_mean(xx, axis=1, keep_dims=True)
sum_0 = tf.reduce_sum(xx, axis=1, keep_dims=False)
sum_1 = tf.reduce_sum(xx, axis=1, keep_dims=True)
with tf.Session() as sess:
print(sess.run(mean_0))
print(sess.run(mean_1))
print(sess.run(sum_0))
print(sess.run(sum_1))
# 结果
[2. 2.]
[[2.]
[2.]]
[6. 6.]
[[6.]
[6.]]
tf.multiply与tf.matmul
tf.multiply()两个矩阵中对应元素各自相乘
tf.matmul()将矩阵a乘以矩阵b,生成a * b。
tf.less()和tf.where()
tf.less 做比较 默认第一个小于第二个 否则为False
tf.where 一个参数时 返回true坐标 两个事 最替换 具体看例子
import tensorflow as tf
A=[[1,2,3]]
t=tf.shape(A)#t为A的shape,A为1行3列
i=[3,2]
r=tf.less(i,t)#i=[3,2] t=[1,3] ,将i的元素和t的元素逐一比较,如果同一位置i的元素的值小于t的元素的值则输出True,否则输出False
with tf.Session() as sess:
print(sess.run(t))
print(sess.run(r))
/*
[1 3]
[False True]
*/
A=[[1,2,3],
[4,5,6]]
t = tf.shape(A)
i=[[1,2,3],
[1,2,3]]
r = tf.less(i, A)#将i和A的元素逐一对比
with tf.Session() as sess:
print(sess.run(t))
print(A)
print(sess.run(r))
/*
[2 3]
[[1, 2, 3], [4, 5, 6]]
[[False False False]
[ True True True]]
*/
import numpy as np
a=np.array([[1,0,0],[0,1,1]])
a1=np.array([[3,2,3],[4,5,6]])
b=tf.equal(a,1)
with tf.Session() as sess:
print("#####")
print(sess.run(b))
print(sess.run(tf.where(b)))#当tf.where()只有一个参数时返回该输入参数中的Ture的位置
print(sess.run(tf.where(b,a,a1)))#当tf.where()有三个参数时返回值为将第一个参数中的False对应的第二个参数的位置的元素替换成第三个参数对应位置的值
/*
#####
[[ True False False]
[False True True]]
[[0 0]
[1 1]
[1 2]]
[[1 2 3]
[4 1 1]]
*/
tf.get_variable() VS tf.Variable()
- tf.Variable()
W = tf.Variable(<initial-value>, name=<optional-name>)
- 用于生成一个初始值为initial-value的变量。必须指定初始化值
- tf.get_variable()
W = tf.get_variable(name, shape=None, dtype=tf.float32, initializer=None,
regularizer=None, trainable=True, collections=None)
- 获取已存在的变量(要求不仅名字,而且初始化方法等各个参数都一样),如果不存在,就新建一个。
- 可以用各种初始化方法,不用明确指定值。
- tf.get_variable() 会检查当前命名空间下是否存在同样name的变量,可以方便共享变量。而tf.Variable 每次都会新建一个变量。需要注意的是tf.get_variable() 要配合reuse和tf.variable_scope() 使用。
sparse_softmax_cross_entropy(logits=logits, labels=labels) VS sparse_softmax_cross_entropy_with_logits
tf.losses.sparse_softmax_cross_entropy(logits=logits, labels=labels) 等价与
tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=labels) 加 tf.reduce_mean(方便加入mask 对一些补齐的数据损失进行消除)。
它们的参数维度:
logits: [batch_size, num_classes]
labels: [batch_size,]
import tensorflow as tf
import math
sess = tf.Session()
batch_size=1
num_classes=3
logits = tf.constant([3,1,-3], shape=[batch_size, num_classes], dtype=tf.float32)
labels = tf.constant([2], shape=[batch_size,], dtype=tf.int32)
softmax = tf.nn.softmax(logits)
print("\n--softmax:",softmax.eval())
log_soft = [-math.log(i) for i in softmax.eval()[0]]
print("--1:",log_soft[2])
print("--2:",tf.losses.sparse_softmax_cross_entropy(logits=logits, labels=labels).eval())
temp = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=labels)
print("--3:",tf.reduce_mean(temp).eval())
"""
--softmax: [[0.87887824 0.11894324 0.00217852]]
--1: 6.1291089069914575
--2: 6.129109
--3: 6.129109
"""
sign()函数
tf.sign(x, name=None)
返回符号
y= sign(x) =
- 1 if x<0;
- 0 if x==0;
- 1if x>0
tf.sequence_mask()
主要用于数据填充
- 函数定义
# 函数定义
sequence_mask(
lengths,
maxlen=None,
dtype=tf.bool,
name=None
)
# 返回数据
return mask类型数据
返回值默认是tf.bool类型 如果使用tf.float32 True编程1 False为0
- 两个例子
import tensorflow as tf
lenght = 4
mask_data = tf.sequence_mask(lengths=lenght)
# 输出结果,输出结果是长度为4的array,前四个True
array([ True, True, True, True])
# 定义maxlen时
mask_data = tf.sequence_mask(lengths=lenght,maxlen=6)
# 输出结果,输出结果是长度为6的array,前四个True
array([ True, True, True, True, False, False])
# 定义dtype时
mask_data = tf.sequence_mask(lengths=lenght,maxlen=6,dtype=tf.float32)
# 输出结果,输出结果是长度为6的array,前四个1.0
array([1., 1., 1., 1., 0., 0.], dtype=float32)
# 比如这个lenght就是记录了第一个句子2个单词,第二个句子2个单词,第三个句子4个单词
lenght = [2,2,4]
mask_data = tf.sequence_mask(lengths=lenght)
# 长度为max(lenght)
array([[ True, True, False, False],
[ True, True, False, False],
[ True, True, True, True]])
# 定义maxlen时
mask_data = tf.sequence_mask(lengths=lenght,maxlen=6)
# 长度为maxlen
array([[ True, True, False, False, False, False],
[ True, True, False, False, False, False],
[ True, True, True, True, False, False]])
# 定义dtype时
mask_data = tf.sequence_mask(lengths=lenght,maxlen=6,dtype=tf.float32)
# 长度为maxlen,数据格式为float32
array([[1., 1., 0., 0., 0., 0.],
[1., 1., 0., 0., 0., 0.],
[1., 1., 1., 1., 0., 0.]], dtype=float32)
tf.metrics.accuracy
计算准确率 预测对的除所有的
他会有两个返回值 常用语estimator中的eval方法
accuracy, update_op = tf.metrics.accuracy(labels=x, predictions=y)
- tf.metrics.accuracy返回两个值,accuracy为到上一个batch为止的准确度,update_op为更新本批次后的准确度。
- 官方文档
def accuracy(labels,
predictions,
weights=None,
metrics_collections=None,
updates_collections=None,
name=None):
# 想特别说一下 weights参数 可以结合tf.sequence_mask()使用
# 用来表示那些计算的时候可以不用加到计算里面来
- 实例
import numpy as np
import tensorflow as tf
x = tf.placeholder(tf.int32, [6])
y = tf.placeholder(tf.int32, [6])
weights = tf.sequence_mask(5, maxlen=6)
acc, acc_op = tf.metrics.accuracy(labels=x, predictions=y,weights=weights)
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
sess.run(tf.local_variables_initializer())
v = sess.run([acc, acc_op], feed_dict={x: [1, 2, 3, 4, 0,1],
y: [1, 2, 4, 4, 1,1]})
#虽然六个数 但只算5个(正确3)
print(v) #[0.0, 0.6]
v = sess.run([acc, acc_op], feed_dict={x: [1, 1, 1, 1, 0,1],
y: [0, 0, 0, 0, 1,1]})
#总的10个(正确3)
print(v) #[0.6, 0.3]
v = sess.run([acc, acc_op], feed_dict={x: [1, 1, 1, 1, 0,1],
y: [0, 0, 0, 0, 1,2]})
#总的15个(正确3)
print(v) #[0.3, 0.2]
tf.nn.conv2d 和 tf.nn.max_pool
bidirectional_dynamic_rnn
Tensorboard
学习率衰减(tf.train.exponential_decay)
tf.train.exponential_decay(
learning_rate,
global_step,
decay_steps,
decay_rate,
staircase=False,
name=None)
- learning_rate 为事先设定的初始学习率
- global_step是一个变量,可以用Tensor或者Python number来表示,表示当前训练到了多少步
- decay_steps 表示衰减速度
- decay_rate 为衰减系数
- staircase 如果是True,表示每经过decay_steps训练之后进行梯度计算,表现为离散;如果是False,表示每个step之后都进行梯度计算,表现为连续(实际上还是离散)
使用方式
global_step = tf.Variable(0, trainable=False)
initial_learning_rate = 0.001
learning_rate = tf.train.exponential_decay(initial_learning_rate,
global_step=global_step,
decay_steps=10,
decay_rate=0.5,
staircase=True)
opt = tf.train.AdamOptimizer(learning_rate=learning_rate)
self.train_op = opt.minimize(self.loss, var_list=tvars,global_step=global_step)
# global_step写在minimize里面可以自动的加 如果不写里面 需要每次sess.run一下才会增加
gfile
gfile API介绍
下面将分别介绍每一个gfile API!
-
tf.gfile.Copy(oldpath, newpath, overwrite=False)
拷贝源文件并创建目标文件,无返回,其形参说明如下:
oldpath:带路径名字的拷贝源文件;
newpath:带路径名字的拷贝目标文件;
overwrite:目标文件已经存在时是否要覆盖,默认为false,如果目标文件已经存在则会报错 -
tf.gfile.MkDir(dirname)
创建一个目录,dirname为目录名字,无返回。 -
tf.gfile.Remove(filename)
删除文件,filename即文件名,无返回。 -
tf.gfile.DeleteRecursively(dirname)
递归删除所有目录及其文件,dirname即目录名,无返回。 -
tf.gfile.Exists(filename)
判断目录或文件是否存在,filename可为目录路径或带文件名的路径,有该目录则返回True,否则False。 -
tf.gfile.Glob(filename)
查找匹配pattern的文件并以列表的形式返回,filename可以是一个具体的文件名,也可以是包含通配符的正则表达式。 -
tf.gfile.IsDirectory(dirname)
判断所给目录是否存在,如果存在则返回True,否则返回False,dirname是目录名。 -
tf.gfile.ListDirectory(dirname)
罗列dirname目录下的所有文件并以列表形式返回,dirname必须是目录名。 -
tf.gfile.MakeDirs(dirname)
以递归方式建立父目录及其子目录,如果目录已存在且是可覆盖则会创建成功,否则报错,无返回。 -
tf.gfile.Rename(oldname, newname, overwrite=False)
重命名或移动一个文件或目录,无返回,其形参说明如下:
oldname:旧目录或旧文件;
newname:新目录或新文件;
overwrite:默认为false,如果新目录或新文件已经存在则会报错,否则重命名或移动成功。 -
tf.gfile.Stat(filename)
返回目录的统计数据,该函数会返回FileStatistics数据结构,以dir(tf.gfile.Stat(filename))获取返回数据的属性如下: -
tf.gfile.Walk(top, in_order=True)
递归获取目录信息生成器,top是目录名,in_order默认为True指示顺序遍历目录,否则将无序遍历,每次生成返回如下格式信息(dirname, [subdirname, subdirname, …], [filename, filename, …])。 -
tf.gfile.GFile(filename, mode)
获取文本操作句柄,类似于python提供的文本操作open()函数,filename是要打开的文件名,mode是以何种方式去读写,将会返回一个文本操作句柄。
tf.gfile.Open()是该接口的同名,可任意使用其中一个! -
tf.gfile.FastGFile(filename, mode)
该函数与tf.gfile.GFile的差别仅仅在于“无阻塞”,即该函数会无阻赛以较快的方式获取文本操作句柄。
tf.argmax(vector, 1)
返回的是vector中的最大值的索引号,如果vector是一个向量,那就返回一个值,如果是一个矩阵,那就返回一个向量,这个向量的每一个维度都是相对应矩阵行的最大值元素的索引号
import tensorflow as tf
import numpy as np
B =[[[1,2,3],[2,1,1]],[[4,2,5],[2,8,1]]]
#[2,2,3]
with tf.Session() as sess:
print(sess.run(tf.argmax(B, -1)))
#结果
[[2 0]
[2 1]]
tf.assert_less_equal
tf.assert_less_equal()如果x>y就抛出异常
tf.assert_less_equal(
x,
y,
data=None,
summarize=None,
message=None,
name=None
)
import tensorflow as tf
x = 1.4
y = 1.2
sess = tf.Session()
with tf.control_dependencies([tf.assert_less_equal(x, y)]):
output = tf.reduce_sum(x)
print(sess.run(output))
tf.control_dependencies
其实从字面上看,control_dependencies 是控制依赖的意思,我们可以大致推测出来,这个函数应该使用来控制就算图节点之间的依赖的。其实正是如此,tf.control_dependencies()是用来控制计算流图的,给图中的某些节点指定计算的顺序。
tf.control_dependencies(self, control_inputs)
arguments:control_inputs: A list of `Operation` or `Tensor` objects
which must be executed or computed before running the operations
defined in the context. (注意这里control_inputs是list)
return: A context manager that specifies control dependencies
for all operations constructed within the context.
我们可以知道,该函数接受的参数control_inputs,是Operation或者Tensor构成的list。返回的是一个上下文管理器,该上下文管理器用来控制在该上下文中的操作的依赖。也就是说,上下文管理器下定义的操作是依赖control_inputs中的操作的,control_dependencies用来控制control_inputs中操作执行后,才执行上下文管理器中定义的操作。
- 例子1
如果我们想要确保获取更新后的参数,name我们可以这样组织我们的代码。
opt = tf.train.Optimizer().minize(loss)
with tf.control_dependencies([opt]): #先执行opt
updated_weight = tf.identity(weight) #再执行该操作
with tf.Session() as sess:
tf.global_variables_initializer().run()
sess.run(updated_weight, feed_dict={...}) # 这样每次得到的都是更新后的weight