使用输入之一最小化 Tensorflow 回归模型的输出

问题描述

我已经使用 this 指南训练了一个 TF 回归模型。该模型有 9 个输入和 1 个输出

我现在要做的是在一个应用程序中使用它,其目标是在给定其他输入值的情况下,通过调整一个输入值来最小化输出值。

例如,让我们表示输入值 x1,x2,...,x9输出y。给定 x2,x3,x9 的值,最小化输出 x1y 的值是多少?

我以前没有使用过这样的 TF 回归模型,我应该怎么做?

解决方法

我可以给你一个关于如何用张量流解决优化问题的粗略例子。

让我们假设您有一个特定的函数,并且想要根据一些基本事实 y 优化该函数的输入。让我们调用该函数 my_funct。 (在您的情况下,它将是一个冻结的神经网络)。在我的示例中,我将采用一个简单的函数,例如 sum :

@tf.function
def my_funct(inp):
    return tf.reduce_sum(inp)

现在,让我们定义一个输入和一个基本事实。在那个优化问题中,我的基本事实是输入的总和 + 1。所以在优化结束时,我的变量 x1 应该等于 x1 +1

inp = tf.random.normal((9,))
y_true = tf.reduce_sum(inp) + 1

现在,您需要在 x1 中编码要优化的值(在您的示例中为 tf.Variable)。这是 TensorFlow 跟踪需要优化的状态的方式。在我们的例子中,x1 是我们输入的第一个值。

x1 = tf.Variable(inp[0])

让我们自己开始优化。我们需要:

  • 一个成本函数,它会告诉我们离目标还有多远
  • 一种优化器,一种可以修改程序状态的算法,从而降低成本函数。

在这种情况下,我将使用梯度下降优化器和均方误差作为目标函数,但还有很多其他可能更适合您的问题。

opt = tf.optimizers.SGD()
cost = tf.losses.mse

然后,我们可以使用 TensorFlow 自行编写优化。为此,我们需要计算我们的成本函数相对于我们的状态的梯度,我们将提供给优化器,以便它可以在正确的方向上修改状态,以最小化我们的成本。

可以这样做:

STEPS = 200
for _ in range(STEPS):
    with tf.GradientTape() as tape:
        tape.watch(x1)
        y_pred = my_funct(tf.concat([[x1],inp[1:]],axis=0))
        loss = cost([y],[y_pred])
    grad = tape.gradient(loss,[x1])
    opt.apply_gradients(zip(grad,[x1]))

像处理 tf.Variable 一样处理 tf.concat 的其余输入有点麻烦。可能有更优雅的方法,但我不想过度设计这个简单的例子。

在这个过程结束时,我们应该有一些接近 x1=inp[0] + 1 让我们检查一下:

>>> inp[0] + 1
<tf.Tensor: shape=(),dtype=float32,numpy=2.5110626>
>>> x1
<tf.Variable 'Variable:0' shape=() dtype=float32,numpy=2.4934747>

还不错!

注意: 与这些问题一样,您可以调整一些超参数以获得更快、更好的结果,例如步数、学习率等