[英]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:到目前为止我尝试过的:
x[0].assign(1.0)
operation to the training step which grows the graph unnecessarilyx[0].assign(1.0)
操作,这会不必要地增长图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)']
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]
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.