首页 > 解决方案 > tf.stop_gradient 和 feed 变量之间的 Tensorflow 差异优化器?

问题描述

我正在尝试在自我监督学习中训练模型。流程图类似于以下内容: 在此处输入图像描述

让我们假设N1已经训练过,我们只想训练N2. 这是我目前的实现:

x_1 = tf.placeholder(tf.float32, [None, 128, 128, 1])
x_2 = tf.placeholder(tf.float32, [None, 128, 128, 1])

s_t1 = tf.stop_gradient(N1(x_1))  # treat s_t1 as a constant
s_t2_pred = N2(s_t1)) 
s_t2 = tf.stop_gradient(N1(x_2))  # treat s_t2 as a constant

loss = some_loss_function(s_t2, s_t2_pred)
train_op = tf.train.AdamOptimizer(lr).minimize(loss)

这样,我应该只优化N2. 让我感到困惑的是,如果我使用下面的代码,我会得到非常不同的结果(比上面的要好得多):

# treat everything as a variable:
s_t1 = N1(x_1)
s_t2_pred = N2(s_t1)
s_t2 = N1(x_2)

loss = some_loss_function(s_t2, s_t2_pred)
var_list = take_all_variables_in_N2()
train_op = tf.train.AdamOptimizer(lr).minimize(loss, var_list)

我想知道第一个实现有什么问题。究竟是什么行为tf.stop_gradient(文档有点差)?这与第二种方法有何不同?

从半监督学习的实际角度来看:两者有什么区别?哪一个是正确的方法?

谢谢 :)



我在下面的评论中添加了一个可能的解决方案。我仍然很乐意从更有经验的用户那里收到任何反馈,并就在 tensorflow 中构建自监督学习问题的最佳方法分享一些意见。

再见,G。

标签: tensorflowvariablesoptimizationgradient

解决方案


我找到了我的问题的可能解决方案,并将其发布在这里,以防有人发现它有用。

显然,tf.stop_gradients()只会阻止新梯度通过层反向传播,但是:如果我们有动量项(例如,使用 Adam 或 RMSProp 时),由于过去累积的一些梯度,这些层的变量仍然可以更新(包含在动量项中)。让我们看一下SGD + Momentum的简单案例;公式是:

w1 = w0 - a*grad(loss) - b*v0

其中w1w0是时间 0 和 1 的权重,a是 学习率v0是累积速度(过去梯度的函数)。使用tf.stop_gradients()相当于将第二项乘以零。那么,更新规则变为:

w1 = w0 - b*v0

例如,我们仍然有一个可以更新权重的动量组件。

解决此问题的方法是将要更新的变量显式传递给优化器。例如:

var_list = take_all_variables_in_N2()
train_op = tf.train.AdamOptimizer(lr).minimize(loss, var_list)

参考:

[1] http://ruder.io/optimizing-gradient-descent/

[2]在 TensorFlow 中使用 stop_gradient 和 AdamOptimizer


推荐阅读