【发布时间】:2015-11-16 03:10:01
【问题描述】:
我想知道如何在 tensorflow 中使用stop_gradient,文档对我来说不是很清楚。
我目前正在使用stop_gradient 来生成损失函数 w.r.t 的梯度。 CBOW word2vec 模型中的词嵌入。我只想获得价值,而不是进行反向传播(因为我正在生成对抗性示例)。
目前,我正在使用代码:
lossGrad = gradients.gradients(loss, embed)[0]
real_grad = lossGrad.eval(feed_dict)
但是当我运行它时,它无论如何都会进行反向传播!我做错了什么,同样重要的是,我该如何解决这个问题?
澄清:为了澄清“反向传播”,我的意思是“计算值和更新模型参数”。
更新
如果我在第一个训练步骤之后运行上面的两行代码,我在 100 个训练步骤之后得到的损失与我不运行这两行代码时不同。我可能从根本上误解了 Tensorflow。
我尝试在图形声明的开头和每个训练步骤之前都使用set_random_seed 进行设置。多次运行之间的总损失是一致的,但在包括/排除这两条线之间却不一致。因此,如果不是 RNG 导致了差异,也不是训练步骤之间模型参数的意外更新,您知道什么会导致这种行为吗?
解决方案
Welp,这有点晚了,但这是我解决它的方法。我只想优化一些但不是全部变量。我认为防止优化某些变量的方法是使用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 中的变量。希望它也对你有用!
【问题讨论】:
-
loss(因此是lossGrad)是否依赖于任何输入阅读器,或者是否所有示例都使用feed_dict传递? (feed_dict是否与lossGrad.eval(...)和训练步骤相同?)你的图中的随机诱导操作是什么? -
不,所有的例子都是通过
feed_dict传入的。feed_dict与训练步骤相同。随机诱导操作是变量embeddings和nce_weights的初始化。embed取决于embeddings,损失取决于embeddings和nce_weights。它可以在教程中的 word2vec 示例中重现。 -
我注意到 word2vec 示例使用了一个自定义阅读器操作 (
word2vec.skipgram),它是有状态的。您确定它没有执行多次(尽管输入了示例和标签),即在训练步骤中执行一次,在获取梯度时执行一次?另一种可能性:如果难以追踪副作用,您可以修改对session.run(train_op)的调用以在同一步骤中计算梯度。 -
我的错 - 我的意思是 word2vec_basic。 IIRC,这个不使用
word2vec.skipgram。修改对session.run(train_op)的调用(耶!)用于渐变w.r.t。美联储的输入,但如果我想使用新的输入。有没有办法解决这个问题? -
“反向传播”是指“计算值和更新模型参数”。 ==> backprop 只计算梯度。优化器用于更新参数。
标签: tensorflow