简体   繁体   English

在张量流的急切执行训练期间修复部分变量

[英]Fix part of a variable during eager execution training in tensorflow

Is there a way to only update some of the variables during an eager execution update step?有没有办法在急切执行更新步骤中只更新一些变量? Consider this minimal working example:考虑这个最小的工作示例:

import tensorflow as tf
tf.enable_eager_execution()
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)

x = tf.Variable([1.0, 2.0])

def train(x):
    with tf.GradientTape() as tape:
        loss = x[0]**2 + x[1]**2 + 1/(x[0]+x[1])
        variables = [x]
        grads = tape.gradient(loss, variables)
        optimizer.apply_gradients(zip(grads, variables))

for _ in range(2000):
    train(x)
    print(x.numpy())

Which converges to [0.5, 0.5] .收敛到[0.5, 0.5] I'd like to fix the value of x[0] to it's initial value, while keeping everything else the way it is.我想将x[0]的值固定为其初始值,同时保持其他所有内容不变。 What I've tried so far:到目前为止我尝试过的:

  • Adding a x[0].assign(1.0) operation to the training step which grows the graph unnecessarily向训练步骤添加x[0].assign(1.0)操作,这会不必要地增长图
  • Changing variables = [x[:-1]] which gives ValueError: No gradients provided for any variable: ['tf.Tensor([1.], shape=(1,), dtype=float32)']更改variables = [x[:-1]]这给出了ValueError: No gradients provided for any variable: ['tf.Tensor([1.], shape=(1,), dtype=float32)']
  • Adding grads = [grads[0][1:]] which gives tensorflow.python.framework.errors_impl.InvalidArgumentError: var and delta do not have the same shape[2] [1] [Op:ResourceApplyGradientDescent]添加grads = [grads[0][1:]]这给tensorflow.python.framework.errors_impl.InvalidArgumentError: var and delta do not have the same shape[2] [1] [Op:ResourceApplyGradientDescent]
  • Doing both, which gives TypeError: 'NoneType' object is not subscriptable两者都做,这会导致TypeError: 'NoneType' object is not subscriptable

For this MWE I can easily use two separate variables, but I'm interested in the generic case where I only want to update a known slice of an array.对于这个 MWE,我可以轻松地使用两个单独的变量,但我对我只想更新数组的已知切片的一般情况感兴趣。

You can set the gradient of the index you don't want to update to 0. In the code snippet bellow, the mask tensor indicates which elements we want to update (values 1 ), and which elements we don't want to update (values 0 ).您可以将不想更新的索引的梯度设置为 0。在下面的代码片段中, mask张量指示我们要更新哪些元素(值为1 ),以及我们不想更新哪些元素(值0 )。

import tensorflow as tf
tf.enable_eager_execution()

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)

x = tf.Variable([1.0, 2.0])
mask = tf.constant([0.0, 1.0])

def train(x):
    with tf.GradientTape() as tape:
        loss = x[0]**2 + x[1]**2 + 1/(x[0]+x[1])
        variables = [x]

        grads = tape.gradient(loss, variables) * mask
        optimizer.apply_gradients(zip(grads, variables))

for _ in range(100):
    train(x)
    print(x.numpy())

Another possible solution for your problem can be to stop the gradient on operations that x[0] is dependent on.您的问题的另一种可能解决方案是停止x[0]所依赖的操作的梯度。 For example:例如:

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)

x = tf.Variable([1.0, 2.0])

def train(x):
    with tf.GradientTape() as tape:
        loss = tf.stop_gradient(x[0])**2 + x[1]**2 + 1/(tf.stop_gradient(x[0])+x[1])
        variables = [x]

        grads = tape.gradient(loss, variables)
        optimizer.apply_gradients(zip(grads, variables))

for _ in range(100):
    train(x)
    print(x.numpy())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM