张量流中的损失函数(带有 if - else)
Loss functions in tensorflow (with an if - else)
我正在尝试在 tensorflow 中使用不同的损失函数。
我想要的损失函数是一种epsilon不敏感函数(这是componentwise):
if(|yData-yModel|<epsilon):
loss=0
else
loss=|yData-yModel|
我试过这个解决方案:
yData=tf.placeholder("float",[None,numberOutputs])
yModel=model(...
epsilon=0.2
epsilonTensor=epsilon*tf.ones_like(yData)
loss=tf.maximum(tf.abs(yData-yModel)-epsilonTensor,tf.zeros_like(yData))
optimizer = tf.train.GradientDescentOptimizer(0.25)
train = optimizer.minimize(loss)
我也用过
optimizer = tf.train.MomentumOptimizer(0.001,0.9)
我在执行过程中没有发现任何错误。然而,它不收敛,而loss = tf.square(yData-yModel) 收敛并且loss=tf.maximum(tf.square(yData-yModel)-epsilonTensor,tf.zeros_like( yData)) 也收敛了。
所以,我也尝试了一些更简单的 loss=tf.abs(yData-yModel) ,它也不收敛。我是在犯错,还是在 abs 为零或其他情况下的不可微性方面有问题? abs 函数发生了什么?
当你的损失类似于Loss(x)=abs(x-y)
,那么解就是SGD的不稳定不动点——从任意接近解的点开始你的最小化,下一步会增加损失。
具有稳定的不动点是像 SGD 这样的迭代过程收敛的要求。在实践中,这意味着您的优化将朝着局部最小值移动,但在足够接近之后,将以与学习率成比例的步长在解决方案周围跳跃。这是一个说明问题的玩具 TensorFlow 程序
x = tf.Variable(0.)
loss_op = tf.abs(x-1.05)
opt = tf.train.GradientDescentOptimizer(0.1)
train_op = opt.minimize(loss_op)
sess = tf.InteractiveSession()
sess.run(tf.initialize_all_variables())
xvals = []
for i in range(20):
unused, loss, xval = sess.run([train_op, loss_op, x])
xvals.append(xval)
pyplot.plot(xvals)
问题的一些解决方案:
- 使用更强大的求解器,例如近端梯度法
- 使用更多对 SGD 友好的损失函数,例如 Huber Loss
- 使用学习率时间表逐渐降低学习率
这里有一个方法来实现 (3) 上面的玩具问题
x = tf.Variable(0.)
loss_op = tf.abs(x-1.05)
step = tf.Variable(0)
learning_rate = tf.train.exponential_decay(
0.2, # Base learning rate.
step, # Current index into the dataset.
1, # Decay step.
0.9 # Decay rate
)
opt = tf.train.GradientDescentOptimizer(learning_rate)
train_op = opt.minimize(loss_op, global_step=step)
sess = tf.InteractiveSession()
sess.run(tf.initialize_all_variables())
xvals = []
for i in range(40):
unused, loss, xval = sess.run([train_op, loss_op, x])
xvals.append(xval)
pyplot.plot(xvals)
我正在尝试在 tensorflow 中使用不同的损失函数。
我想要的损失函数是一种epsilon不敏感函数(这是componentwise):
if(|yData-yModel|<epsilon):
loss=0
else
loss=|yData-yModel|
我试过这个解决方案:
yData=tf.placeholder("float",[None,numberOutputs])
yModel=model(...
epsilon=0.2
epsilonTensor=epsilon*tf.ones_like(yData)
loss=tf.maximum(tf.abs(yData-yModel)-epsilonTensor,tf.zeros_like(yData))
optimizer = tf.train.GradientDescentOptimizer(0.25)
train = optimizer.minimize(loss)
我也用过
optimizer = tf.train.MomentumOptimizer(0.001,0.9)
我在执行过程中没有发现任何错误。然而,它不收敛,而loss = tf.square(yData-yModel) 收敛并且loss=tf.maximum(tf.square(yData-yModel)-epsilonTensor,tf.zeros_like( yData)) 也收敛了。
所以,我也尝试了一些更简单的 loss=tf.abs(yData-yModel) ,它也不收敛。我是在犯错,还是在 abs 为零或其他情况下的不可微性方面有问题? abs 函数发生了什么?
当你的损失类似于Loss(x)=abs(x-y)
,那么解就是SGD的不稳定不动点——从任意接近解的点开始你的最小化,下一步会增加损失。
具有稳定的不动点是像 SGD 这样的迭代过程收敛的要求。在实践中,这意味着您的优化将朝着局部最小值移动,但在足够接近之后,将以与学习率成比例的步长在解决方案周围跳跃。这是一个说明问题的玩具 TensorFlow 程序
x = tf.Variable(0.)
loss_op = tf.abs(x-1.05)
opt = tf.train.GradientDescentOptimizer(0.1)
train_op = opt.minimize(loss_op)
sess = tf.InteractiveSession()
sess.run(tf.initialize_all_variables())
xvals = []
for i in range(20):
unused, loss, xval = sess.run([train_op, loss_op, x])
xvals.append(xval)
pyplot.plot(xvals)
问题的一些解决方案:
- 使用更强大的求解器,例如近端梯度法
- 使用更多对 SGD 友好的损失函数,例如 Huber Loss
- 使用学习率时间表逐渐降低学习率
这里有一个方法来实现 (3) 上面的玩具问题
x = tf.Variable(0.)
loss_op = tf.abs(x-1.05)
step = tf.Variable(0)
learning_rate = tf.train.exponential_decay(
0.2, # Base learning rate.
step, # Current index into the dataset.
1, # Decay step.
0.9 # Decay rate
)
opt = tf.train.GradientDescentOptimizer(learning_rate)
train_op = opt.minimize(loss_op, global_step=step)
sess = tf.InteractiveSession()
sess.run(tf.initialize_all_variables())
xvals = []
for i in range(40):
unused, loss, xval = sess.run([train_op, loss_op, x])
xvals.append(xval)
pyplot.plot(xvals)