如何在训练时冻结tensorflow变量中的特定节点?

时间:2017-11-19 19:16:23

标签: python tensorflow deep-learning

目前我无法将变量中的一些元素作为不可训练的元素。这意味着给定一个变量,如x,

x= tf.Variable(tf.zeros([2,2]))

我希望只训练x [0,0]和x [1,1]同时保持x [0,1] ans x [1.0]在训练时固定。

目前,tensorflow确实提供了使用trainable=Falsetf.stop_gradient()使任何变量不可训练的选项。但是,这些方法会使x中的所有元素都不可训练。我的问题是如何获得这种选择性?

2 个答案:

答案 0 :(得分:4)

现在没有选择性缺乏更新;但是,您可以通过指定更新的明确变量来间接实现此效果。 .minimize和所有渐变函数都接受您要优化的变量列表 - 只需创建一个列表省略其中一些,例如

v1 = tf.Variable( ... ) # we want to freeze it in one op 
v2 = tf.Variable( ... ) # we want to freeze it in another op
v3 = tf.Variable( ... ) # we always want to train this one
loss = ...
optimizer = tf.train.GradientDescentOptimizer(0.1)

op1 = optimizer.minimize(loss, 
      var_list=[v for v in tf.get_collection(tf.TRAINABLE_VARIABLES) if v != v1])

op2 = optimizer.minimize(loss, 
      var_list=[v for v in tf.get_collection(tf.TRAINABLE_VARIABLES) if v != v2])

现在你可以随时打电话给他们。变量子集。请注意,如果您使用Adam或其他一些方法收集统计信息,则可能需要2个单独的优化器(并且每个优化器最终会有单独的统计信息!)。但是,如果每次训练只有一组冻结变量 - 使用var_list,一切都会很简单。

然而,没有办法来修复变量子集的训练。 Tensorflow始终将变量视为一个单元。您必须以不同的方式指定计算才能实现此目的,一种方法是:

  • 创建一个带有1的二进制掩码M,您希望通过X
  • 停止更新
  • 创建单独的变量X',这是不可训练的,并且tf.assign to it值X
  • 输出X'* M +(1-M)* X

例如:

x = tf.Variable( ... )
xp= tf.Variable( ..., trainable=False)
m = tf.Constant( ... ) # mask
cp= tf.Assign(x, xp)
with tf.control_dependencies([cp]):
  x_frozen = m*xp + (1-m)*x

你只需使用x_frozen而不是x。请注意,我们需要控制依赖,因为tf.assign可以异步执行,在这里我们要确保它始终具有最新的x值。

答案 1 :(得分:0)

您可以使用with open('./plots') as f: documents=[] for x in f: documents.append(x.split('<EOS>')) for i, document in enumerate(documents): print('documents[{}]: {!r}'.format(i, document)) 技巧来阻止受掩盖的tf.stop_gradient元素的训练。例如:

tf.Variable