机器学习:为什么成本函数不需要是可导出的?

时间:2018-01-07 03:59:46

标签: tensorflow machine-learning

我正在玩Tensorflow创建一个定制的损失功能,这个关于一般机器学习的问题出现在我脑海里。

我的理解是优化算法需要一个可导出的代价函数来找到/接近最小值,但是我们可以使用不可导出的函数,例如绝对函数(当x = 0时没有导数)。一个更极端的例子,我定义了我的成本函数:

def customLossFun(x,y):
    return tf.sign(x)

我在运行代码时遇到了一个错误,但它实际上有效(它没有学到任何东西,但它并没有崩溃)。

我错过了什么吗?

4 个答案:

答案 0 :(得分:1)

您错过了sign函数的渐变在Tensorflow源代码中手动定义的事实。

正如您所见here

def _SignGrad(op, _):
  """Returns 0."""
  x = op.inputs[0]
  return array_ops.zeros(array_ops.shape(x), dtype=x.dtype)

tf.sign的梯度定义为始终为零。当然,这是衍生物存在的梯度,因此到处都是,但不是零。

tensorflow作者决定不检查输入是否为零并在特定情况下抛出异常

答案 1 :(得分:1)

为了防止TensorFlow抛出错误,唯一真正的要求是对于输入变量的任何值,成本函数求值为数字。从一个纯粹的"它将运行"从视角来看,它并不知道/关心它试图最小化的函数的形式。

为了让您的成本函数在TensorFlow使用它来训练模型时为您提供有意义的结果,它还需要1)变小,因为您的模型做得更好2)受限于下面(即它不能进入​​负无穷大)。通常不需要它是平滑的(例如,abs(x)具有符号翻转的扭结)。 Tensorflow始终能够使用自动区分(https://en.wikipedia.org/wiki/Automatic_differentiationhttps://www.tensorflow.org/versions/r0.12/api_docs/python/train/gradient_computation)计算任何位置的渐变。

当然,如果你选择了一个有意义的成本函数,这些渐变更有用。

答案 2 :(得分:0)

理想情况下,成本函数在任何地方都需要平滑才能应用基于梯度的优化方法(SGD,Momentum,Adam等)。但如果不是,那么没有任何事情会崩溃,你可能会遇到融合到当地最低限度的问题。

当函数在某个点x处不可微分时,如果神经网络收敛到此x,则可能会出现大的振荡。例如,如果损失函数为tf.abs(x),则网络权重可能大部分为正,因此推断x > 0始终为tf.abs,因此网络不会注意到{{} 1}}。但是,x更有可能在0周围反弹,因此渐变是任意正面和负面的。如果学习率没有衰减,则优化不会收敛到局部最小值,但会围绕它进行限制。

在您的特定情况下,渐变始终为零,因此根本不会发生任何变化。

答案 3 :(得分:0)

如果没有学到任何东西,你获得了什么?你的损失函数几乎无处不在,但它几乎是平坦的,所以最小化器无法找出最小的方向。

如果你从一个正值开始,即使左侧的最小值更好(具有更低的值),它也很可能在正面被卡在随机值上。

Tensorflow可用于进行一般的计算,它提供了一种机制,可以自动查找给定表达式的派生,并且可以跨不同的计算平台(CPU,GPU)执行此操作,并在需要时分布在多个GPU和服务器上。

但是你在Tensorflow中实现的并不一定是最小化的目标函数。你可以使用它,例如抛出随机数并执行给定函数的蒙特卡洛积分。