TensorFlow 2.0 中的最小化未按预期进行

minimization does not proceed as expected in TensorFlow 2.0

这几天一直在学习tensorflow 2.0。我写了一个非常简单的测试模型。具体来说,我想最小化函数 x1^2-2x1+1,它在 x1 = 1 时达到最优。我没有只创建一个变量 x1,而是创建了任何其他变量 x2 = 2x1 + 1 看看它是否有效,如果我未来不同变量之间有复杂的关系。 这是我的代码:

import tensorflow as tf

opt = tf.keras.optimizers.SGD(learning_rate=0.1)

var1 = tf.Variable(tf.random.normal([1]))
var2 = tf.add(tf.multiply(-2, var1), 1)

loss = lambda: var1 * var1 + var2

for i in range(1000):
    opt.minimize(loss, var_list=[var1])
    print('var1: {}, var2: {}'.format(var1.numpy(), var2.numpy()))

变量var1很快收敛到0,而var2保持不变。那么,我的代码哪里出了问题?

问题是您在编写代码时就好像在图形模式下一样 (TF 1.x)。当你写这行时:

var2 = tf.add(tf.multiply(-2, var1), 1)

var2会被赋值(初始随机值var1乘二加一),之后就不再变化了。与图形模式不同,其中 var2 表示符号计算 -2 * var1 + 1,在急切模式中,它只是在评估代码行时计算的值。这意味着你的损失函数实际上只是计算 var1 的平方加上一些常数,所以当 var1 等于零时总是达到最小值。

在 TF 2.x 中,您必须在每次训练迭代时计算损失,而不是像在 TF 1.x 中那样在训练循环之前用符号表示一次。因此,对于 var1.

的每个新值,var2 的计算必须在 loss 函数内完成
import tensorflow as tf

opt = tf.keras.optimizers.SGD(learning_rate=0.1)
var1 = tf.Variable(tf.random.normal([1]))
def loss():
    var2 = tf.add(tf.multiply(-2, var1), 1)
    return var1 * var1 + var2

for i in range(1000):
    opt.minimize(loss, var_list=[var1])
    print('var1: {}'.format(var1.numpy()))
    # ...
    # var1: [0.9999999]