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

Python 如何在训练时冻结tensorflow变量中的特定节点?,python,tensorflow,deep-learning,Python,Tensorflow,Deep Learning,目前,我很难将变量中的一些元素设置为不可训练的。这意味着给定一个变量,如x x= tf.Variable(tf.zeros([2,2])) 我只希望训练x[0,0]和x[1,1],同时在训练时保持x[0,1]和x[1.0]不变 目前,tensorflow确实提供了通过使用trainable=False或tf.stop\u gradient()使任何变量不可训练的选项。但是,这些方法将使x中的所有元素都不可训练。我的问题是如何获得这种选择性?目前没有选择性缺乏更新;但是,您可以通过明确指定应更新

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

x= tf.Variable(tf.zeros([2,2]))
我只希望训练x[0,0]和x[1,1],同时在训练时保持x[0,1]和x[1.0]不变


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

目前没有选择性缺乏更新;但是,您可以通过明确指定应更新的变量来间接实现此效果。
.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或其他方法收集统计数据,这可能需要两个单独的优化器(最终每个优化器都会有单独的统计数据!)。然而,如果每个训练只有一组冻结变量,那么使用var_列表,一切都会变得简单

但是,没有办法解决变量子集的训练问题。Tensorflow始终将变量视为单个单位。您必须以不同的方式指定计算以实现此目的,一种方式是:

  • 创建一个二进制掩码M,其中包含1,您要在其中停止X上的更新
  • 创建不可训练的单独变量X',并将其赋值为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 = tf.Variable(tf.zeros([2, 2]))
mask = tf.constant([[1, 0], [0, 1]], dtype=x.dtype)
x = mask * x + tf.stop_gradient((1 - mask) * x)

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

您可以使用
tf.stop\u gradient
技巧来防止被屏蔽的
tf.Variable
元素训练。例如:

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 = tf.Variable(tf.zeros([2, 2]))
mask = tf.constant([[1, 0], [0, 1]], dtype=x.dtype)
x = mask * x + tf.stop_gradient((1 - mask) * x)

很抱歉,上面的方法不起作用。无论是否具有控件依赖项,x_冻结中的所有元素都会随着每次迭代而更新。如果xp可训练=False,则无法更新这些元素。失败的唯一方法是在图中的任何位置使用“x”(而不是用x_冻结替换对x的任何引用)。特别是,不能使用权重衰减或任何其他直接应用于所有可训练变量的正则化器等。