如何在Tensorflow中使用stop_gradient

Ale*_*Sax 42 tensorflow

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

我目前正在使用stop_gradientCBOW word2vec模型中的单词嵌入来生成损失函数的梯度.我想获得价值,而不是反向传播(因为我正在生成对抗性的例子).

目前,我正在使用代码:

lossGrad = gradients.gradients(loss, embed)[0]
real_grad = lossGrad.eval(feed_dict)
Run Code Online (Sandbox Code Playgroud)

但是当我运行它时,无论如何它都会进行反向传播!我做错了什么,同样重要的是,我该如何解决这个问题呢?

澄清:通过"反向传播"来澄清我的意思是"计算值并更新模型参数".

UPDATE

如果我在第一个训练步骤之后运行上面的两行,那么在100次训练步骤之后,我得到的损失与我不运行这两行时相同.我可能从根本上误解了关于Tensorflow的一些事情.

我已经尝试set_random_seed在图形声明的开头和每个训练步骤之前使用它们.多次运行之间的总损失是一致的,但不包括/排除这两条线之间.因此,如果不是导致差异的RNG,并且在训练步骤之间没有意外更新模型参数,您是否知道会导致这种行为的原因是什么?

Welp,这有点晚了,但这就是我解决它的方式.我只想优化一些但不是全部的变量.我认为防止优化某些变量的方法是使用stop_grad- 但我从来没有找到一种方法来实现这一点.也许有一种方法,但对我有用的是调整我optimizer只对一组变量进行优化.所以代替:

opt = tf.train.GradientDescentOptimizer(learning_rate=eta)
train_op = opt.minimize(loss)
Run Code Online (Sandbox Code Playgroud)

我用了:

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

这阻止opt了更新不在的变量var_list.希望它也适合你!

Abh*_*hra 51

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)
Run Code Online (Sandbox Code Playgroud)


mrr*_*rry 29

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

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