如何在Tensorflow中使用stop_gradient
tensorflow
6
0

我想知道如何在stop_gradient中使用stop_gradient ,并且文档对我来说不清楚。

我目前正在使用stop_gradient来生成CBOW word2vec模型中词嵌入的损失函数的梯度。我只想获取值,而不要进行反向传播(因为我正在生成对抗性示例)。

目前,我正在使用代码:

lossGrad = gradients.gradients(loss, embed)[0]
real_grad = lossGrad.eval(feed_dict)

但是当我运行它时,它仍然会进行反向传播!我在做什么错,同样重要的是,我该如何解决呢?

澄清:为了通过“反向传播”进行澄清,我的意思是“计算值并更新模型参数”。

更新

如果在第一步训练之后我在上面的两条线跑了,经过100次训练后我得到了与不跑那两条线时不同的损失。从根本上来说,我可能对Tensorflow有误解。

我尝试在图声明的开始和每个训练步骤之前使用set_random_seed设置。多次运行之间的总损失是一致的,但包括/排除这两行之间的损失却不一致。因此,如果不是由RNG引起差异,也不是在训练步骤之间未预料到的模型参数更新,您是否知道会导致这种行为的原因?

抱歉,有些晚了,但是这是我解决的方法。我只想优化某些而非全部变量。我认为防止优化某些变量的方法是使用stop_grad但我从未找到一种使该工作有效的方法。也许有办法,但是对我有用的是将optimizer调整为仅对变量列表进行优化。所以代替:

opt = tf.train.GradientDescentOptimizer(learning_rate=eta)
train_op = opt.minimize(loss)

我用了:

opt = tf.train.GradientDescentOptimizer(learning_rate=eta)
train_op = opt.minimize(loss, var_list=[variables to optimize over])

这样可以防止opt更新不在var_list的变量。希望它也对您有用!

参考资料:
Stack Overflow
收藏
评论
共 2 个回答
高赞 时间 活跃

tf.stop_gradient提供了一种在反向传播期间不针对某些变量计算梯度的方法。

例如,在下面的代码中,我们有三个变量w1,w2,w3和输入x。损耗为平方((x1.dot(w1)-x.dot(w2 * w3))))。我们希望将w1的损耗减至最小,但希望保持w2和w3固定。为了实现这一点,我们可以只放置tf.stop_gradient(tf.matmul(x,w2 * w3))。

在下图中,我从初始值绘制了w1,w2和w3作为训练迭代函数的方式。可以看出,在w1变化之前,w2和w3保持固定,直到等于w2 * w3。

显示w1仅学习而w2和w3不学习的图像:

显示w1仅学习而w2和w3不学习的图像

import tensorflow as tf
import numpy as np

w1 = tf.get_variable("w1", shape=[5, 1], initializer=tf.truncated_normal_initializer())
w2 = tf.get_variable("w2", shape=[5, 1], initializer=tf.truncated_normal_initializer())
w3 = tf.get_variable("w3", shape=[5, 1], initializer=tf.truncated_normal_initializer())
x = tf.placeholder(tf.float32, shape=[None, 5], name="x")


a1 = tf.matmul(x, w1)
a2 = tf.matmul(x, w2*w3)
a2 = tf.stop_gradient(a2)
loss = tf.reduce_mean(tf.square(a1 - a2))
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
gradients = optimizer.compute_gradients(loss)
train_op = optimizer.apply_gradients(gradients)
收藏
评论

tf.gradients(loss, embed)计算张量loss相对于张量embed的偏导数。 TensorFlow通过反向传播计算此偏导数,因此评估tf.gradients(...)执行反向传播是预期的行为。但是,评估该张量不会执行任何变量更新,因为表达式不包含任何赋值操作

tf.stop_gradient()是一个操作,在向前方向上充当标识函数,但阻止累积的梯度在向后方向tf.stop_gradient()过该运算符。它不会完全阻止反向传播,而是可以防止单个张量对为表达式计算的梯度做出贡献。该操作文档提供了有关该操作以及何时使用的更多详细信息。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号