“冻结”tensorflow中的一些变量/范围:停止梯度vs传递变量以最小化

2024-04-26 14:46:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试实现Adversarial NN,这需要在交替训练小批量期间“冻结”图形的一部分或另一部分。一、 有两个子网:G和D

G( Z ) ->  Xz
D( X ) ->  Y

其中G的损失函数依赖于D[G(Z)], D[X]

首先需要训练D中所有G参数固定的参数,然后训练G中所有G参数固定的参数。第一种情况下的损失函数在第二种情况下为负损失函数,更新必须应用于第一子网还是第二子网的参数。

我看到tensorflow有tf.stop_gradient函数。为了训练D(下游)子网,我可以使用此函数来阻止梯度流

 Z -> [ G ] -> tf.stop_gradient(Xz) -> [ D ] -> Y

tf.stop_gradient的注释非常简洁,没有内联示例(示例seq2seq.py太长,不太容易阅读),但看起来它必须在图形创建期间调用。这是否意味着,如果要以交替批处理方式阻止/取消阻止渐变流,则需要重新创建并重新初始化图形模型?

似乎也不能用tf.stop_gradient来阻止通过G(上游)网络的梯度,对吧?

作为替代方案,我看到可以将变量列表作为opt_op = opt.minimize(cost, <list of variables>)传递给优化器调用,如果可以获得每个子网范围内的所有变量,这将是一个简单的解决方案。对于tf.scope,可以得到一个<list of variables>


Tags: of函数图形示例参数tf情况list
3条回答

您可能需要考虑的另一个选项是,可以对变量设置trainable=False。这意味着它不会被训练修改。

tf.Variable(my_weights, trainable=False)

@mrry的回答是完全正确的,也许比我要建议的更一般。但我认为实现它的一个更简单的方法是直接将python引用传递给var_list

W = tf.Variable(...)
C = tf.Variable(...)
Y_est = tf.matmul(W,C)
loss = tf.reduce_sum((data-Y_est)**2)
optimizer = tf.train.AdamOptimizer(0.001)

# You can pass the python object directly
train_W = optimizer.minimize(loss, var_list=[W])
train_C = optimizer.minimize(loss, var_list=[C])

我这里有一个独立的示例:https://gist.github.com/ahwillia/8cedc710352eb919b684d8848bc2df3a

正如您在问题中提到的,实现这一点的最简单方法是使用对opt.minimize(cost, ...)的单独调用创建两个优化器操作。默认情况下,优化器将使用^{}中的所有变量。如果要将变量筛选到特定作用域,可以按如下所示对^{}使用可选的scope参数:

optimizer = tf.train.AdagradOptimzer(0.01)

first_train_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,
                                     "scope/prefix/for/first/vars")
first_train_op = optimizer.minimize(cost, var_list=first_train_vars)

second_train_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES,
                                      "scope/prefix/for/second/vars")                     
second_train_op = optimizer.minimize(cost, var_list=second_train_vars)

相关问题 更多 >