在机器学习中,给定一个最小化的损失函数,我们通常选择一些机器学习库来更新参数。例如,在tensorflow中,我们通常会做以下事情,首先记下损失函数,
self.loss = F(\theta, \eta)
self.optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
self.train_op = self.optimizer.minimize(
self.loss, global_step=tf.contrib.framework.get_global_step())
然后使用_, loss = sess.run([self.train_op, self.loss], feed_dict)
更新参数以最小化损失函数。
在这种情况下,我们不需要关心F(\ theta,\ eta)w.r.t \ theta和\ eta的渐变的确切形式。
我想知道如何使用特定形式的损失梯度w.r.t其参数来更新参数并最小化损失。也就是说,给定渐变形式,如何使用机器学习库写下要更新的内容。
Update1 @lejlot提供了一个惊人的答案(见下文),帮助这个基于首先通过Adam计算一些true_gradient
,然后将渐变修改为你想要的。但是,对我来说,我想知道是否有可能采取行动,直接对损失采用一种理想的梯度形式。这背后的原因是我不知道计算true_gradients
的形式,所以我不能添加一些东西。例如,我希望的渐变形式为f(\theta)
,但是如何从计算的true_gradients转到f(\theta)
是未知的,因为我们不知道计算的true_gradients
的形式。
答案 0 :(得分:2)
首先,值得注意的是梯度只有一个正确的“形式”,并且它由像TF这样的库使用自动微分自动计算。如果您对此渐变执行任何,则它不再是您正在考虑的损失函数的渐变。接下来它可能仍会导致收敛(有很多定理表明如果更新方向“足够相似”它仍然可以工作)但是值得理解的是,使用渐变通常会创建一些不是任何函数的适当梯度。如果将除梯度下降之外的任何东西应用为优化器,这是非常重要的 - 例如在你的代码中你有Adam,如果你提供的东西不是一个合适的梯度(因为它使用它来进行二阶估计,因此可以完全破坏)如果你搞乱了渐变,它们将完全错误,甚至可能导致分歧/随机行为。)
然而,如果你只是知道一个渐变(或者有一个好的数学理由相信你所做的不会破坏优化),你可以通过利用这个事实直接在TF中自己应用它.minimize内部调用两个函数:compute_gradients和apply_gradients。
所以(在伪代码中)它将在以下几行中出现:
self.optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
true_gradients = self.optimizer.compute_gradients(self.loss)
my_own_gradients = do_some_magical_stuff_with(true_gradients)
self.train_op = self.optimizer.apply_gradients(my_own_gradients)
就是这样!