欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

搞懂交叉熵损失函数与平方损失的差异:你真的明白了吗?

最编程 2024-02-02 09:11:35
...

1. 写在前面

最近在补ML和DL的相关基础,发现有些非常重要的知识还是了解的太表面,甚至可以说不知其然也不知其所以然了,所以这段时间想借着找工作的这个机会,通过学习一些优秀的文章,来慢慢的把这块短板也补上来。今天学习的这篇文章是交叉熵损失和平方损失,虽然我们一看这俩东西,可能瞬间感觉非常简单吗不是,公式甚至都能不假思索的就写出来,这还有啥不知其然和所以然的,哈哈,好吧,反正我是觉得我没理太明白,所以想重新记录学习下。

拿一个最基本的面试题来说: 为啥二分类问题里面会用到交叉熵损失,而不用平方损失呢? 既然sigmoid输出的是概率值,难道用这个概率值与真实的label0或者1求平方损失,然后更新参数不可以吗?

如果感觉也能不假思索的张口就来,那么应该是真掌握了,可以回退了哈哈,如果感觉还不大行,那么就可以往下看看;)。

这篇文章是转载的一篇文章, 原文来自https://blog.****.net/weixin_41888257/article/details/104894141,想了解更多,可以去看原文章。

因为我比较喜欢发现比较好的文章,就转载下,但是转载的同时,会添加自己的一些理解, 这样感觉会比简单的看一遍会有效果。下面开始正文。

2. 概念区别

首先先理清楚这两个损失的概念:

  1. 均方差损失函数(MSE): 简单来说,均方误差(MSE)的含义是求一个batch中n个样本的n个输出与期望输出的差的平方的平均值, 常用与回归问题
  2. 交叉熵损失: 用来评估当前训练得到的概率分布于真实分布的差异情况。 它刻画的是实际输出(概率)与期望输出(概率)的距离,也就是交叉熵的值越小,两个概率分布就越接近。这个是为啥? 也就是交叉熵为啥能刻画两个分布的差异情况,其实这里是转了一个弯的, 其实真正能衡量概率分布之间差异的(数据的真实分布与模型预测的数据分布)叫做相对熵,也称为KL散度。 这个东西的公式就是真实分布 P ( x ) P(x) P(x)与预测分布 Q ( x ) Q(x) Q(x)的比值然后取log,然后求期望。是一个 Q ( x ) Q(x) Q(x)不断逼近真实分布 P ( x ) P(x) P(x)的过程,而这个东西经过化简会得到交叉熵-信息熵的结果。 所以交叉熵=信息熵+相对熵。 而如果一个数据集给定了之后,其实信息熵就确定了,所以交叉熵正比于相对熵,于是乎,交叉熵损失就能够衡量两个分布之间的差异啦。关于这段,可以参考我之前pytorch里面损失函数的那篇博客,那里面有详细的解释。 这里只是知识的串联下。

3. 为什么不用MSE(两者的区别详解)

3.1 原因1:交叉熵loss权重更新更快

3.1.1 MSE

先看看MSE, 比如对于一个神经元(单输入单输出,sigmoid函数),定义其代价函数为:
C = ( y − a ) 2 2 C=\frac{(y-a)^{2}}{2} C=2(ya)2
其中, C C C是损失, y y y是我们期望的输出(真实值target), a a a是神经元的实际输出, z = w x + b , a = σ ( z ) z=wx+b, a=\sigma(z) z=wx+b,a=σ(z)

在训练神经网络过程中,我们通过梯度下降算法来更新 w w w b b b,因此需要计算损失函数对 w w w b b b的导数:

∂ C ∂ w = ( a − y ) σ ′ ( z ) x = ( a − y ) a ( 1 − a ) x ≈ a σ ′ ( z ) ∂ C ∂ b = ( a − y ) σ ′ ( z ) = ( a − y ) a ( 1 − a ) ≈ a σ ′ ( z ) \begin{array}{l} \frac{\partial C}{\partial w}=(a-y) \sigma^{\prime}(z) x=(a-y) a(1-a) x \approx a \sigma^{\prime}(z) \\ \frac{\partial C}{\partial b}=(a-y) \sigma^{\prime}(z)=(a-y) a(1-a) \approx a \sigma^{\prime}(z) \end{array} wC=(ay)σ(z)x=(ay)a(1a)xaσ(z)bC=(ay)σ(z)=(ay)a(1a)aσ(z)
这里的 x x x y y y都是已知量,因为网络输入都是 ( x i , y i ) (x_i,y_i) (xi,yi)的形式,所以上面直接用 ≈ \approx x x x y y y略去了。

而后更新 w w w b b b:
w = w − η ∂ C ∂ w = w − η a σ ′ ( z ) b = b − η ∂ C ∂ b = b − η a σ ′ ( z ) \begin{array}{l} w=w-\eta \frac{\partial C}{\partial w}=w-\eta a \sigma^{\prime}(z) \\ b=b-\eta \frac{\partial C}{\partial b}=b-\eta a \sigma^{\prime}(z) \end{array} w=wηwC=wηaσ(z)b=bηbC=bηaσ(z)
sigmoid的函数图像我们都知道:
在这里插入图片描述
因为sigmoid函数的性质,如图的两端,几近于平坦,导致 σ ′ ( z ) \sigma'(z) σ(z) z z z取大部分值时会很小,这样会使得 w w w b b b更新非常慢(因为 η a σ ′ ( z ) = = > 0 \eta a \sigma'(z) ==> 0 ηaσ(z)==>0)。这其实是sigmoid的函数带来的一个问题,像回归里面为啥能用? 因为回归里面并不用激活函数把结果转成概率输出。

再定量解释下:
∂ C ∂ w = ( a − y ) σ ′ ( z ) x = ( a − y ) a ( 1 − a ) x ≈ a σ ′ ( z ) \frac{\partial C}{\partial w}=(a-y) \sigma^{\prime}(z) x=(a-y) a(1-a) x \approx a \sigma^{\prime}(z) wC=(ay)σ(z)x=(ay)a(1a)xaσ(z)
分情况讨论下:

  • 当真实值 y = 1 y=1 y=1
    • 若输出值 a = 1 a=1 a=1, 则 ∂ C ∂ w = 0 \frac{\partial C}{\partial w}=0 wC=0
    • 若输出值 a = 0 a=0 a=0, 则 ∂ C ∂ w = 0 \frac{\partial C}{\partial w}=0 wC=0
  • 当真实值 y = 0 y=0 y=0
    • 若输出值 a = 1 a=1 a=1, 则 ∂ C ∂ w = 0 \frac{\partial C}{\partial w}=0 wC=0
    • 若输出值 a = 0 a=0 a=0, 则 ∂ C ∂ w = 0 \frac{\partial C}{\partial w}=0 wC=0

也就是平方损失(MSE)的梯度更新很慢
在这里插入图片描述
还有个问题,就是会发现不管真实值是多少,只要输出值预测的是0或者1,那么梯度都是0. 这其实说明当采用MSE的时候,梯度很小的时候,根本就看不出来是离真实目标很远还是很近。 这就带来实际操作的问题当梯度很小的时候,应该减小步长(否则容易在最优解附近来回震荡), 而用MSE的时候,显然这个操作是不太好进行的,梯度很小的时候,有可能是离真实值还超级远呢。

3.1.2 交叉熵损失

为了克服上述 MSE 不足,引入了categorical_crossentropy(交叉熵损失函数), 二分类交叉熵损失函数
L ( w ) = − 1 N