tf.assign
这个函数很简单,但其实它是有return的,返回值和赋值相同,而且返回值是深度拷贝。这一点极其重要,在后面会反复出现
global_step = tf.Variable(0, name='global_step', trainable=False)
print("id_global",id(global_step))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print("global_step",sess.run(global_step))
print("id_global",id(global_step))
aaa = tf.assign(global_step,1)
print("id_aaa",id(aaa))
print("aaa",sess.run(aaa))
print("global_step",sess.run(global_step))
id_global 2245964104816
global_step 0
id_global 2245964104816
id_aaa 2245964371112
aaa 1
global_step 1
tf.group
把若干两个操作组合成为一个操作,在graph中表现为多个节点被组合成了一个节点。经常用于初始化操作:
tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
tf.identity
赋值操作 y = tf.identity(x), 把x 赋给 y。为什么需要这个命令呢,如果直接用y=x不行吗,下面来看一个例子
import tensorflow as tf
x = tf.Variable(0.0)
#返回一个op,表示给变量x加1的操作
x_plus_1 = tf.assign_add(x, 1)
#control_dependencies的意义是,在执行with包含的内容(在这里就是 y = x)前
#先执行control_dependencies中的内容(在这里就是 x_plus_1)
with tf.control_dependencies([x_plus_1]):
y = x
init = tf.initialize_all_variables()
print(id(x))
print(id(y))
with tf.Session() as session:
init.run()
for i in range(5):
print(session.run(y))
print(session.run(x))
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
这段代码的目的是让tensor x每次自增1 然后赋值给y,但是很明显并没有成功。不仅y没有被自增,连x自增都没有执行。为什么不行呢?因为在tensorflow 中,y= x 不算一个操作,因此不会再计算图中留下一个节点,所以即使用了control_dependency,x_plus_1 = tf.assign_add(x, 1)节点也根本不会执行。因为他和要被执行的y没有依赖关系,他们之间也没有tensor从x_plus_1流入到y中。
这时就需要用y = tf.identity(x),在
with tf.control_dependencies([x_plus_1]):
语句中,只有他后面跟着一个节点(即tensorflow的操作),那么依赖节点 x_plus_1 和 后面的节点才会有tensor流。这也是tensorflow的意义,永远都要记住一点:普通的python运算不是节点,tensorflow的命令操作才是节点,tensor只能从节点流向节点,节点代表的是tensorflow的操作。
global steps
global steps 是tensorflow优化器中的参数,例如
global_step = tf.Variable(0, name='global_step', trainable=False)
optimizer = tf.train.AdadeltaOptimizer(0.01)
optimizer.minimize(loss, global_step=global_step)
在优化器内部,始终都有一个计数器,来记录迭代次数。只不过这个计数器,没有通过retun返回,这里通过
optimizer.minimize(loss, global_step=global_step)
把定义的global_step变量和优化器内部的计数器指向同一个内存,就可以得到迭代步数了。
tf.control_dependencies
即依赖操作,后面的操作会依赖 tf.control_dependencies执行完以后再操作,举一个简单的例子
import tensorflow as tf
a_1 = tf.Variable(1)
b_1 = tf.Variable(2)
update_op = tf.assign(a_1, 10)
add = tf.add(a_1, b_1)
a_2 = tf.Variable(1)
b_2 = tf.Variable(2)
update_op = tf.assign(a_2, 10)
with tf.control_dependencies([update_op]):
add_with_dependencies = tf.add(a_2, b_2)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
ans_1, ans_2 = sess.run([add, add_with_dependencies])
print("Add: ", ans_1)
print("Add_with_dependency: ", ans_2)
输出:
Add: 3
Add_with_dependency: 12
可以看到,由于assign函数有返回值,所以在第一个例子中,由于update_op没有被run,所以没有执行。在第二个例子中,add操作等在了assign操作之后在执行。
tf.get_collection()、tf.add_to_collection()和tf.GraphKeys
如果觉得几个张量属于同一类,那么可以把这些张量放到一个map中,这些张量组成一个list,例如
import tensorflow as tf;
import numpy as np;
import matplotlib.pyplot as plt;
v1 = tf.get_variable(name='v1', shape=[1], initializer=tf.constant_initializer(0))
tf.add_to_collection('loss', v1)
v2 = tf.get_variable(name='v2', shape=[1], initializer=tf.constant_initializer(2))
tf.add_to_collection('loss', v2)
with tf.Session() as sess:
sess.run(tf.initialize_all_variables())
print tf.get_collection('loss')
print sess.run(tf.add_n(tf.get_collection('loss')))
所以collection本质上就是map,每次添加一个collection,都会想map中添加一个键值对,键自定义,value就是张量list
在很多命令中,tensorflow会自动给一些操作添加collection。这些collection的key都添加在tf.GraphKeys中,这些key包括:
ACTIVATIONS = 'activations'
ASSET_FILEPATHS = 'asset_filepaths'
BIASES = 'biases'
CONCATENATED_VARIABLES = 'concatenated_variables'
COND_CONTEXT = 'cond_context'
EVAL_STEP = 'eval_step'
GLOBAL_STEP = 'global_step'
GLOBAL_VARIABLES = 'variables'
INIT_OP = 'init_op'
LOCAL_INIT_OP = 'local_init_op'
LOCAL_RESOURCES = 'local_resources'
LOCAL_VARIABLES = 'local_variables'
LOSSES = 'losses'
METRIC_VARIABLES = 'metric_variables'
MODEL_VARIABLES = 'model_variables'
MOVING_AVERAGE_VARIABLES = 'moving_average_variables'
QUEUE_RUNNERS = 'queue_runners'
READY_FOR_LOCAL_INIT_OP = 'ready_for_local_init_op'
READY_OP = 'ready_op'
REGULARIZATION_LOSSES = 'regularization_losses'
RESOURCES = 'resources'
SAVEABLE_OBJECTS = 'saveable_objects'
SAVERS = 'savers'
SUMMARIES = 'summaries'
SUMMARY_OP = 'summary_op'
TABLE_INITIALIZERS = 'table_initializer'
TRAINABLE_RESOURCE_VARIABLES = 'trainable_resource_variables'
TRAINABLE_VARIABLES = 'trainable_variables'
TRAIN_OP = 'train_op'
UPDATE_OPS = 'update_ops'
VARIABLES = 'variables'
WEIGHTS = 'weights'
WHILE_CONTEXT = 'while_context'
如果我想拿出所有的正则项loss,则需要
tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
在tensorflow 1 中,如果使用了tf.layers.batch_normalization 命令 ,则必须在定义最小化loss的节点前定义依赖
with tf.control_dependencies(tf.get_collection(tf.GraphKeys.UPDATE_OPS)):
train_op = optimizer.minimize(total_mean_loss, global_step=global_step)
具体的内容可以看转载的一篇文章https://blog.youkuaiyun.com/kangshuangzhu/article/details/108308751
不过现在tf.layers.batch_normalization 已经废弃不用,推荐使用tf.keras.layers.BatchNormalization
这2个函数的用法有一个区别:
tf.layers.batch_normalization(input,training=True)
tf.layers.BatchNormalization()(input,training=True)
获取所有variable(每个op中可训练的张量)的name:
1 2 |
|
获取所有tensor(每个op的输出张量)的name:
1 2 |
|
获取所有op及其输入输出的name:
1 2 3 |
|