Tensorflow中如何定义损失函数【优化问题】?

我正在尝试定义一个损失函数,但遇到了困难。也许有人可以帮助我。

我有 x_iy_i 的 N 个数据点,我想在以下条件下拟合一条直线(为简单起见):

Tensorflow中如何定义损失函数【优化问题】?

即找到 h 的最小值,使得对于所有点 |y_i - f(x_i)| tf.losses.mean_squared_error 或 LAD(最小绝对偏差),其中我们最小化绝对值的总和 .

tf_x = tf.placeholder(tf.float32,x.shape)     # input x
tf_y = tf.placeholder(tf.float32,y.shape)     # input y


l1 = tf.layers.dense(tf_x,1)          # assume linear activation
output = tf.layers.dense(l1,1)        # output layer

h = ???
loss = ???
optimizer = tf.train.train.AdamOptimizer(learning_rate=0.1)
train_op = optimizer.minimize(loss)

所以sess.run()应该返回满足上述条件的预测线和h值。

谢谢!

yzhwyf 回答:Tensorflow中如何定义损失函数【优化问题】?

听起来您使用的是 Tensorflow 1.x API,因为您提到使用 tf.placeholdersess.run,所以我提供了使用 Tensorflow 2.x 中的 Tensorflow 1.x API 的解决方案。如果您想在 Tensorflow 1.x 中运行,只需删除 compat.v1

    tf_x = tf.compat.v1.placeholder(tf.float32,[None,1],name='x')  # input x
    tf_y = tf.compat.v1.placeholder(tf.float32,name='y')  # input y
    h = tf.Variable(0.0,name='h')

    l1 = tf.compat.v1.layers.dense(tf_x,1,name='layer_1')  # assume linear activation
    output = tf.compat.v1.layers.dense(l1,name='output')  # output layer
    loss = tf.reduce_max(tf.abs(tf_y - output)) + tf.abs((h - tf.reduce_max(tf.abs(tf_y - output))))
    optimizer = tf.compat.v1.train.GradientDescentOptimizer(learning_rate=0.1).minimize(loss)
    init = tf.compat.v1.global_variables_initializer()
    variables = tf.compat.v1.trainable_variables()

    x = np.expand_dims(np.array([5.0,5.0],dtype=np.float32),axis=-1)
    y = np.expand_dims(np.array([2.0,3.0],axis=-1)

    with tf.compat.v1.Session() as sess:
        sess.run(init)

        for step in range(1000):
            _,val = sess.run([optimizer,loss],feed_dict={tf_x: x,tf_y: y})
            prediction = sess.run(output,feed_dict={'x:0': x})
            print(prediction)
            if step % 5 == 0:
                print("step: {},loss: {}".format(step,val))
            print([{variable.name: sess.run(variable)} for variable in variables])

我包含了一些打印语句来帮助观察训练过程。由于问题陈述,损失函数看起来有点奇怪 - 我们正在学习近似 f(x) 的函数 y 和残差 h。我使用虚拟输入来验证模型的功能——通过提供两个 5 和 2 和 3 的输出,模型被迫妥协并围绕预测 2.5 收敛。从最后的步骤:

step: 990,loss: 0.6000000238418579
[{'h:0': 0.5},{'layer_1/kernel:0': array([[0.04334712]],dtype=float32)},{'layer_1/bias:0': array([-0.2167356],{'output/kernel:0': array([[-1.0096708e-09]],{'output/bias:0': array([2.4000003],dtype=float32)}]
[[2.6000004]
 [2.6000004]]
[{'h:0': 0.6},{'output/bias:0': array([2.6000004],dtype=float32)}]
[[2.4000003]
 [2.4000003]]
[{'h:0': 0.70000005},dtype=float32)}]
[[2.4000003]
 [2.4000003]]
[{'h:0': 0.6},dtype=float32)}]
[[2.4000003]
 [2.4000003]]
[{'h:0': 0.5},dtype=float32)}]
[[2.6000004]
 [2.6000004]]
step: 995,loss: 0.6999993324279785
[{'h:0': 0.6},dtype=float32)}]

请注意,模型对输入和 h 的预测为 2.4-2.6,估计值在 0.5-0.7 之间,接近实际残差 (0.4-0.6)。行为可能会随着真实数据而改变——具体来说,对于真实数据,可能不会有具有不同输出的重复输入,这对模型来说是令人困惑的。为了健全性检查,我们可以使用相同的输出再次运行,但将输入更改为 7:

step: 995,loss: 1.9000002145767212
[{'h:0': 1.8000002},{'layer_1/kernel:0': array([[0.60248166]],{'layer_1/bias:0': array([0.21199825],{'output/kernel:0': array([[1.0599916]],{'output/bias:0': array([0.2],dtype=float32)}]
[[-0.767429 ]
 [-1.0744007]]
[{'h:0': 1.9000002},{'layer_1/kernel:0': array([[-0.88150656]],{'layer_1/bias:0': array([-6.8724134e-08],{'output/kernel:0': array([[0.1741176]],{'output/bias:0': array([0.],dtype=float32)}]
[[3.543093]
 [4.895095]]
[{'h:0': 2.0000002},{'layer_1/kernel:0': array([[-0.6377419]],{'layer_1/bias:0': array([0.03482345],{'output/kernel:0': array([[-1.0599916]],dtype=float32)}]
[[3.543093]
 [4.895095]]
[{'h:0': 1.9000002},dtype=float32)}]
[[3.543093]
 [4.895095]]
[{'h:0': 1.8000002},dtype=float32)}]

它相当准确,因为残差约为 2.1 (7 - 4.89),h 输出为 1.8。

值得注意的是,此损失函数可能需要一些额外的部分 - 例如,边界 output,因为它是线性的并且可以达到无穷大(模型可能会这样做以最小化损失 - tf.reduce_max(tf.abs(tf_y - output))意味着 output 为无穷大导致负无穷大损失) - 但这应该是一个起点。

,

不确定这是否有帮助,但是有一个 scipy.optimize 包,它提供了几种常用的优化算法。这是文档的链接。

https://docs.scipy.org/doc/scipy/reference/tutorial/optimize.html

我最近一直在使用这个,效果非常好!

,

您正在寻找每个数据点 y_true 和 y_pred 之间的增量的 L-inf 范数。 L-inf 范数仅从最大发散数据点计算损失。如果您可以对此进行优化,您会找到最小的 h。

当然,L-inf 是不可微的,因为它只是一种表达“max”的数学方法。所以你可以用一个 Ln 范数来近似它,其中 n 很大。您可以网格搜索在数值上保持稳定的 n 并尝试其他技巧,例如梯度裁剪。

此外,我怀疑如果您使用损失计划近似 L-inf,首先是 L2,您可以逐渐将 n 增加到 L3、L4、L5 等,以帮助训练过程。

本文链接:https://www.f2er.com/1504.html

大家都在问