You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

机器学习:为何代价函数无需可导?自定义损失函数运行疑问

为什么不可导的损失函数在TensorFlow中能运行?

这问题问得特别到位!刚接触深度学习优化时,我们都被灌输“优化算法依赖可导的损失函数来计算梯度、更新参数”,结果碰到绝对值、tf.sign这类明显不可导的函数居然没报错,甚至能跑起来,确实会让人疑惑是不是自己漏了什么关键知识点。

下面就拆解一下背后的原因:

1. TensorFlow用**子梯度(Subgradient)**处理不可导点

严格来说,我们常说的“可导”是指函数在定义域内每一点都有唯一的导数,但对于像绝对值函数(|x|)这种在某点不可导的函数,其实可以用子梯度来扩展梯度的定义。比如|x|在x=0处的子梯度是区间[-1, 1]中的任意值,TensorFlow会默认取一个合理的替代值(比如0)来计算梯度,这样优化器就能继续执行更新步骤,而不会因为“导数不存在”直接崩溃。

2. tf.sign这类函数的特殊情况

你定义的:

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

这个函数的特点是:

  • 当x>0时,导数为0;
  • 当x<0时,导数也为0;
  • 仅在x=0处不可导。

也就是说,模型在训练时,几乎所有情况下计算出来的梯度都是0——优化器拿到全0的梯度,自然没法更新参数,所以模型“没学习到内容”,但程序本身不会报错,因为TensorFlow在处理x=0这个极少数情况时,同样会用子梯度(比如0)来兜底,不会触发异常。

3. 框架对数值计算的“容错设计”

深度学习框架(包括TensorFlow)的自动微分机制,本质是为数值计算服务的,而不是严格的数学推导。它们会对不可导点做近似处理,只要能得到一个可以用于参数更新的数值(哪怕不是严格意义上的导数),程序就能继续运行。这也是为什么很多看似“不符合数学可导要求”的操作,在框架里都能正常执行的原因。

实际使用的小提醒

虽然这类不可导损失函数能运行,但绝大多数情况下都不是好选择:

  • 像MAE(平均绝对误差,基于绝对值)这类损失,因为子梯度能提供有效的更新方向,实际中还能使用;
  • 但tf.sign这种几乎处处梯度为0的函数,优化器根本找不到更新参数的方向,完全起不到训练模型的作用,没有实际价值。

内容的提问来源于stack exchange,提问作者kuonb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:33:06