如何设置 Tensorflow 变量的边界和约束 (tf.Variable)

Mar*_*hoh 2 tensorflow tensorflow2.0

我正在使用 Tensorflow 来最小化函数。该函数需要大约 10 个参数。每个参数都有界限,例如参数允许采用的最小值和最大值。例如,参数 x1 需要在 1 到 10 之间。

我还有一对参数需要具有以下约束 x2 > x3。换句话说,x2 必须始终大于 x3。(除此之外,x2 和 x3 也有界限,与上面 x1 的示例类似。)

我知道 tf.Variable 有一个“约束”参数,但是我找不到任何关于如何使用它来实现上述边界和约束的示例或文档。

谢谢你!

Slo*_*oke 5

在我看来(我可能会弄错),约束优化(你可以在tensorflow中谷歌搜索它)并不完全是tensroflow设计的情况。你可能想看看这个 repo,它可能会满足你的需求,但据我了解,它仍然没有解决任意约束优化,只是一些带有标签和特征的分类问题,与精度/召回分数兼容。

如果您想对张量流变量使用约束(即在梯度步骤之后应用一些函数 - 您也可以手动执行 - 通过获取变量值,进行操作,然后重新分配),这意味着您将在每个步骤之后切割变量在一般空间中使用渐变完成。问题是你是否能以这种方式成功达到正确的优化目标,或者你的变量是否会停留在边界上,因为general梯度会指向外部的某个地方。

我的方法1

如果你的问题足够简单。您可以尝试参数化您的x2x3as x2 = x3 + t,然后尝试在图中进行切割:

x3 = tf.get_variable('x3',
                   dtype=tf.float32,
                   shape=(1,),
                   initializer=tf.random_uniform_initializer(minval=1., maxval=10.),
                   constraint=lambda z: tf.clip_by_value(z, 1, 10))
t = tf.get_variable('t',
                   dtype=tf.float32,
                   shape=(1,),
                   initializer=tf.random_uniform_initializer(minval=1., maxval=10.),
                   constraint=lambda z: tf.clip_by_value(z, 1, 10))
x2 = x3 + t
Run Code Online (Sandbox Code Playgroud)

然后,在单独的电话中另外做

sess.run(tf.assign(x2, tf.clip_by_value(x2, 1.0, 10.0)))

但我的意见是,效果不会很好。

我的方法2

我还会尝试发明一些损失项来将变量保持在约束范围内,这更有可能起作用。例如,x2 位于区间内的约束[1,10]为:

loss += alpha*tf.abs(tf.math.tan(((x-5.5)/4.5)*pi/2))

这里将下面的表达式tan带入-pi/2,pi/2,然后tan使用函数使其在到达边界时快速增长。在这种情况下,我认为您更有可能找到最佳值,但同样,alpha如果所需的值位于边界附近,则损失重量可能太大,并且训练将陷入附近的某个位置x2。在这种情况下,您可以尝试使用较小的alpha.