我一直在寻找用于处理梯度示例代码TensorFlow具有:只能用TensorFlow中梯度处理的代码示例来实现像优化器那样的梯度下降?
# Create an optimizer.
opt = GradientDescentOptimizer(learning_rate=0.1)
# Compute the gradients for a list of variables.
grads_and_vars = opt.compute_gradients(loss, <list of variables>)
# grads_and_vars is a list of tuples (gradient, variable). Do whatever you
# need to the 'gradient' part, for example cap them, etc.
capped_grads_and_vars = [(MyCapper(gv[0]), gv[1]) for gv in grads_and_vars]
# Ask the optimizer to apply the capped gradients.
opt.apply_gradients(capped_grads_and_vars)
然而,我注意到apply_gradients
函数从GradientDescentOptimizer
的。这是否意味着使用上面的示例代码,只能实现渐变规则(请注意,我们可以更改opt = GradientDescentOptimizer
或Adam
或任何其他优化器)?特别是,apply_gradients
是做什么的?我明确地检查了tf github page中的代码,但它是一堆与数学表达式无关的python,所以很难说出它在做什么以及它是如何从优化器转换为优化器的。例如,如果我想实现我自己的可能使用渐变的自定义优化器(或者可能不会,例如直接用一些规则更改权重,也许生物学上更合理的规则),那么使用上面的示例代码不可能实现?
我特别想要实现了在一个紧凑的域人为限制的梯度下降版本。特别是我想实现下面的等式:
w := (w - mu*grad + eps) mod B
in TensorFlow。我意识到,以下是正确的:
w := w mod B - mu*grad mod B + eps mod B
,所以我想我可能只是做实现它:
def Process_grads(g,mu_noise,stddev_noise,B):
return (g+tf.random_normal(tf.shape(g),mean=mu_noise,stddev=stddev_noise)) % B
,然后只是有:
processed_grads_and_vars = [(Process_grads(gv[0]), gv[1]) for gv in grads_and_vars]
# Ask the optimizer to apply the processed gradients.
opt.apply_gradients(processed_grads_and_vars)
然而,我意识到那还不够好,因为我实际上没有访问w
,所以我不能实现:
w mod B
至少不是我试过的方式。有没有办法做到这一点?即实际上直接改变更新规则?至少我尝试过的方式?
我知道它的一种哈克更新规则,但我的观点更多的是改变更新方程,而不是实际关注更新规则(所以如果它有点奇怪,不要挂上它)。
我想出了超级哈克解决方案:
def manual_update_GDL(arg,learning_rate,g,mu_noise,stddev_noise):
with tf.variable_scope(arg.mdl_scope_name,reuse=True):
W_var = tf.get_variable(name='W')
eps = tf.random_normal(tf.shape(g),mean=mu_noise,stddev=stddev_noise)
#
W_new = tf.mod(W_var - learning_rate*g + eps , 20)
sess.run(W_var.assign(W_new))
def manual_GDL(arg,loss,learning_rate,mu_noise,stddev_noise,compact,B):
# Compute the gradients for a list of variables.
grads_and_vars = opt.compute_gradients(loss)
# process gradients
processed_grads_and_vars = [(manual_update_GDL(arg,learning_rate,g,mu_noise,stddev_noise), v) for g,v in grads_and_vars]
不知道,如果它的工作原理,但这样的事情应该在一般的工作。这个想法是写下想要使用的公式(TensorFlow中的)作为学习率,然后使用会话手动更新权重。
不幸的是,这样的解决方案意味着我们必须照顾退火(手动衰减学习率似乎令人讨厌)。这个解决方案可能有很多其他问题,随时指出(如果可以的话,给出解决方案)。
对于这个非常简单的问题,我意识到一个可以做正常的优化更新规则,然后只取权重的MOD,并将它们重新分配给他们的价值:
sess.run(fetches=train_step)
if arg.compact:
# apply w := (w - mu*g + eps) mod B
W_val = W_var.eval()
W_new = tf.mod(W_var,arg.B).eval()
W_var.assign(W_new).eval()
但在这种情况是一个巧合,这种简单的解决方案存在(不幸的是,绕过了我的问题的整个观点)。
其实,这种解决方案会减慢代码很多。目前是我拥有的最好的。
作为参考,我已经看到了这个问题:How to create an optimizer in Tensorflow,但没有找到它直接回答我的问题。
如果你修改所有的梯度是'毕业= W - (W MOD乙 - 亩*毕业MOD B + EPS MOD B) ''和'tf.train.GradientDescentOptimizer'具有1.0的学习率?这应该将梯度应用为'w = = grad',即'w = w mod B-mu * grad mod B + eps mod B'。 –