做语义分割任务的时候要用到交叉熵损失,然后就去网上搜相关的教程,但感觉越看越迷糊,好不容易想的有点清楚了,先记下来再说。
1、逻辑回归
其实就是多元线性回归外面套了一个函数:
多元线性回归
多个自变量与因变量之间构成如下线性关系:
有时为了记号方便,用矩阵形式表示:
所以逻辑回归的表达式是这样:
由于函数的值域为,所以回归函数的取值可以看作一个概率值,并且表示取值为1的概率。
逻辑回归一般用于处理二分类问题,该类问题用0,1分别表示负类和正类。当回归函数的计算值越大,即取值越接近1,表示该样本越接近正样本(或者说“样本为正样本的概率越大”),所以“回归函数的取值表示样本为正样本的概率”算是一种直观上的理解,但实际上这是逻辑回归的定义(参考《统计学习方法》)。
2、逻辑回归的损失函数
损失函数是为了衡量我们自己训练的模型的预测结果与真实结果之间的差距:如果预测结果与真实结果相差很大,则损失函数也会很大;反之,损失函数值较小。
对于一个参数空间中的模型参数,上面的逻辑回归模型预测结果为一个取值范围在0到1之间的数,且表示预测为正类的概率。可以想象一下,如果对于一个正样本,它的标签为,模型的预测结果为。如果模型的性能良好,应该接近1,损失应该较小;反之,如果模型性能很差,则应该接近0,损失也很大。
也就是说,需要找到一个函数,当靠近0,损失函数值大;当靠近1,损失函数值小,即需要一个关于的减函数。那么统计学习里面比较符合这一要求的就是对数损失函数:
其中是模型对样本的预测结果(样本为正类的概率),为样本的真实标签。
在《统计学习方法》这本书里面,它的形式为:
需要注意的是,上面的损失是针对正样本而言的。那么对于负样本而言,当越接近0时,说明预测结果也准确,损失应该越小;反之,越接近1,说明预测结果越不准,损失应该越大。即此时应该需要一个关于的增函数。同样的,可以采用对数损失函数:
综上,逻辑回归的损失函数可以写为:
很明显这是一个分段函数,如果采用梯度方法进行参数优化,这样的形式是不太方便的。考虑到真实标签只有0和1,因此,上述的损失函数可以改写为:
实际上对于一个确定的样本,上述分段的损失函数只会选择一个分支。这里说“形式不太方便”可能是指采用分段函数对整体性(比如表达式的整体性,又或者说对后面程序计算的整体性,使用单个式子可以直接通过矩阵运算计算这两项,而采用分段函数则需要进行额外的判断)有一定破坏。
既然写出了一个样本的预测损失,那么对于整个样本集,整体的损失(损失函数的自变量实际上为模型参数,上面一个样本的损失也是关于的函数,因为对于一个确定的样本,是确定的)为:
我们希望模型尽可能准确,也就是损失函数尽可能小,那么以最小化损失函数为目标进行参数的搜索即可。
3、从极大似然估计的角度看损失函数
逻辑回归模型进行学习时(学习就是找到参数),可以用极大似然估计法估计模型参数。
极大似然估计是推断模型参数的常用办法。它的基本想法是,当给定样本时,如果对于某一组模型参数,使得似然函数为似然函数集合中的最大者,则参数的真实值为的“似然性”在参数空间内是最大的,即模型参数取的可能性是最大的。
似然函数的表达式和概率函数的表达式是一致的,但是意义不同。
概率函数是当模型参数固定时关于的函数,它更倾向于表示当外界环境固定下来后事件发生的概率(比如,一枚均质的硬币就是外界环境,推测事件“抛掷10次硬币出现5次正面”的概率就是0.5);而似然函数是参数固定时关于的函数,它更倾向于表示当一个事件已经发生了(或者说已经观测到了某一个现象)我们想推测外界环境是怎样的(比如,现在观测到一个现象“抛掷10次硬币出现了5次正面”,推测硬币是均质的)。
极大似然估计告诉我们,当给定了样本集时,我们只需要寻找使得似然函数取值最大的参数就好了。下面来推导逻辑回归范围下的似然函数(下面的就相当于这里的,表示模型参数)。
首先要确定概率函数,即给定模型参数的情况下,事件发生的概率。针对样本来考虑,逻辑回归预测的结果实际上表示的是预测为正类的概率(前面说过,回归函数的值表示取值为1的概率)
由于只有两类,那么
同样这是一个分段的表示,为了写成一个整体的表达式,借助的取值可以改写为
怎么理解概率函数?在《数理统计》中,它的定义是这样:
设参数分布族,为参数空间。令为从中抽取的简单随机样本,则为样本的概率函数。当总体分布为离散型时,为样本的概率分布,即。
显然,现在逻辑回归的样本集是离散的点,因此总体分布视为离散分布。如果样本的标签为1,则事件的发生概率为
如果标签为0,则事件的发生概率为
所以事件发生的概率为
有了单个样本的概率函数后,就可以导出整体的似然函数了(样本之间视作独立的):
通常会转换为对数似然函数
尽管这里似然函数的自变量有两个,但实际上只是关于的函数,因为样本是已知的。则模型的最优参数为
将上式与上一节的损失函数进行对比,可以发现它们其实是等价的(只相差了一个系数):
4、从熵的角度看损失函数
经典的信息论观点
1、信息量
顾名思义,就是一条信息的容量,它与信息的不确定性有关,不确定性越强,信息量越大。通常事件的不确定性用概率表示,因此信息量也用概率表示。对于随机变量,它的取值可能为,对应的概率为,则任一事件发生的信息量为:
2、熵
随机变量的熵就是信息量的期望值(平均信息量):
直观上,如果的可能取值越多,信息熵越大。特别的,如果各个取值都是等可能,即,此时熵最大为。
3、交叉熵
对于随机变量的两个分布
和
假设为真实分布,为非真实分布,则交叉熵是指用非真实分布衡量真实分布时随机变量的熵,此时信息量为(个人理解,因为样本是确定的,即随机变量取中的值的概率是固定的,在熵的计算公式中可变的只有信息量,因此“用非真实分布衡量真实分布”应该是指每个事件发生的信息量改变,否则变取值概率的话不符合实际情况),因此此时的熵为:
非真实分布可以有很多个,它实际上表征用非真实分布衡量一个已知分布式时所携带的平均信息量,因此修改符号为:
(上面针对连续型变量的交叉熵计算公式同样可以用于熵的计算和下面散度的计算)
4、KL散度(Kullback–Leibler divergence,又称相对熵)
用于衡量两个分布之间的差异。
利用上面的记号,对的散度为:
当两个分布一致时,散度为0,否则散度的值大于0,关于散度的相关性质可以参考其他文章。
前面说过,逻辑回归模型本身就是一个概率分布,我们想用这个模型很好的表示已有样本,则这个分布应该与样本原本的分布尽可能一致,即:
这里为什么又对求和?
上面交叉熵和散度那里是针对一个随机变量的两个分布求的,我们现有拥有的样本集为,并且也说逻辑回归模型本身就是概率分布。那么它是谁的概率分布呢?其实是给定样本下,预测值的分布:
那么此时的随机变量实际上是,并且的取值只可能是0或1。
所以现在我们有个样本,就会有个预测值,也意味着有个随机变量。对求和就相当于把个随机变量的散度相加(当然可以再取一个平均,即乘以)。
相对应的,分别表示真实分布下随机变量取0和取1值的概率。预测值的真实分布就是样本对应的标签,注意到标签只有两个值,并且是事先给定的。 可以这样考虑:
当标签为1时,
当标签为0时,
即标签值与取值一样。所以,对于标签有。将其带入上面的公式可以得到:
注意到,在给定样本集后,是确定的常数,因此上面的最小化问题等价于:
可以看到,如果从最小化散度的观点来推断参数,它的结果就相当于最小化交叉熵,最小化损失函数,最大化似然函数。
5、多分类问题
尽管逻辑回归最初用于解决二分类问题,但是只需要换个角度稍作修改就能使得逻辑回归处理多分类问题。
现在假设有个类:,我们针对每一个单独的类别考虑二分类问题:对于第个类,判断当前样本是否属于该类。那么,问题由一个多分类问题转变为个二分类问题,最终结果由概率值最大的决定。
比如,
对于第1类,当前样本属于该类的概率为,
对于第2类,当前样本属于该类的概率为,
。。。。。。
对于第类,当前样本属于该类的概率为,
最终的分类结果由所对应的类别确定。
显然,现在有个模型参数需要求解,并且需要对它们分别求解,因为各个模型之间算是独立的。那么按照前面的介绍,可以从最小化损失的角度、最大似然估计的角度、最小化散度(或交叉熵)的角度求模型参数。此时针对每个子问题,样本集的标签也相应的发生变化:
假如原始样本集为,如果用于第类的分类问题,则样本集变为,且满足
即属于该类的样本标签置为1,不属于该类的标签置为0。
上面的讨论是基于逻辑回归进行的,因为逻辑回归函数的输出值表示“属于正样本的概率”,又或者说“属于当前类的概率”,所以将多分类问题拆分成多个二分类问题。可以认为是因为逻辑回归只输出一个值的“缺陷性”导致了它只能判断“是”或“不是”,而不能判断“是哪一个”,因此无法直接处理多分类问题,那如果它能输出多个值呢?
回顾逻辑回归的表达式:
它只能输出一个值的原因在于参数只有一组,那有多组参数是不是就能输出多个值了?没错,既然给定一组模型参数能获得样本属于当前类的概率,我们让每一个类别关联一组参数,那么就能获得属于各个类别的概率。
需要注意,我们讨论整个问题的原因是,多元线性回归输出连续的值,为了处理分类问题,通过函数将回归值转化为了概率。所以分类用到的关键依据还是多元线性回归这个值。
利用上面的记号,关联第1类,关联第2类,。。。,关联第类,多元线性回归的值向量可以表示为:
矩阵表示为:
同样的,能否用函数把多个回归值转变为概率呢?根据它的表达式就知道当然是不行的,解决方法就是用它的推广形式函数:
所以这个多分类模型的运算结果是一个向量,如何评价预测结果和真实之间的差距,换言之如何确定损失函数?
首先需要知道,这个预测结果的每一个值表示当前样本属于对应类别的概率,
比如,表示样本属于第1类的概率,表示样本属于第类的概率
但是我们样本的标签是一个具体的类别,说白了就是一个范围在上的整数。参照上面针对二分类的逻辑回归的思想,如果模型越准确,则属于类的概率越大,损失越小;否则,属于该类的概率越小,损失越大,同样可以选择对数损失函数
所以总的样本集上的损失为:
上标表示是第个样本,下标表示第个样本的真实类别。即,
这里为什么和二分类时候的损失函数不一样了?
二分类情况下,求和号里由两项相加得到,这是因为对于单个样本进行预测的损失函数是分段函数,为了避免分段函数带来的“不连续性”,将分段函数借助样本标签改写为了两项相加的形式。但是实际计算的过程中,由于是二分类,只有一项参与计算(另一项变成了0)。
对于多分类的情况,实际上损失函数也应该是一个分段函数,那为什么不也借助样本标签改写成多项相加的形式呢?实际上,它也用到了标签,只不过通过其他方式克服了分段函数带来的“不连续性”,即充当了索引。借助样本标签我们就可以找到预测为标签类的概率了,进而求对数损失。那为什么在二分类的时候不充当索引,反而用更麻烦的和式表示?因为二分类的情况下模型预测值只是一个数而已,根本没有索引。可以想象,如果能让二分类模型的输出值也是向量的话,那是不是就可以用索引的方式了呢?个人感觉是可以的,但此时索引只有两个值。
6、语义分割任务中的交叉熵损失
语义分割就是像素级分类,因此本质上是一个多分类任务。对于一张输入图片,通常情况下网络会输出和原图尺寸相同大小,但是通道数为类别数的结果。用Pytorch中的表示就是,
通常为3,表示RGB彩色图片,输出通道为总类别数,每一个通道表示每个像素点属于该通道对应类别的概率。
比如,取10,则总共分为10个类别(通常会用0表示背景),第一个通道表示像素点属于类别0的概率,第10个通道表示属于类别9的概率。(下面为了方便还是采用的记号)
对于一张RGB输入图片,它的标签是单通道图片,每个像素点的灰度值表示该点所属的类别。那么如何计算损失?我们借助上面多元线性回归处理多分类问题的思路来看待分割任务。
分割网络(卷积运算)计算一张输入图片的操作实际上和多元线性回归进行的操作是一致的,都是计算线性组合。那么网络的输出就相当于对每个像素点用多个模型参数做了多次“多元线性回归”,这里把每个像素点看成了回归里面的样本,把三个通道的值看成了的具体取值。然后对该像素点的计算结果就是一个长度等于类别数的向量,可以将这个长度等同于网络输出结果的通道数。通过这样的类比就很清楚了,完全可以借助上一节的式子计算这里的损失。
现在样本集为,网络的计算结果为,每一个都是一个长度等于类别数的向量,即第个像素点在各个通道上的值,经过函数转化为概率,则总损失为:
这里的表示网络的参数。
那这个损失与交叉熵是个什么关系?先求一下再说。
前面介绍了交叉熵的定义,那在式子中的真实分布和非真实分布又是什么?还是对一个随机变量进行考虑,同样这里的随机变量是给定样本(这里就是像素点)的条件下模型预测的类别,取值范围为。那么这个随机变量的真实分布也是根据给定的样本标签而来的,为
非真实分布则是模型输出值经过函数转化后的概率分布,
代入交叉熵公式就得到单个随机变量的交叉熵,
这里的表示的是类别编号。
总体交叉熵就是所有随机变量的交叉熵的和平均,即
这里的表示的是样本编号,表示样本为时的交叉熵。
可以看到交叉熵与损失函数是一样的,最小化损失函数相当于最小化交叉熵。
虽然两个结果一样,但是它们的导出方式是不一样的,换言之,计算流程不一样。
1、用多元回归导出的损失函数,它是以样本标签作为索引,直接取到了模型预测为该类的概率值,进而计算对数损失;
2、计算交叉熵,则是借助样本标签构造了一个真实概率分布,对真实分布和模型计算结果经过函数转化后得到的非真实分布进行线性组合的运算。
现有的深度学习框架多采用第二种计算方式。因为已知样本集的话很好构建真实概率分布,也就是对标签进行现在经常使用的One-Hot编码,非真实分布只需对网络计算结果进行函数转化,那么交叉熵的计算就是一个矩阵运算:
个人看法:利用索引取值虽然很直观,但是对于计算机实现的话,一旦类别数很多,那么它需要频繁借助索引去找到我们想要的值,可能会频繁进行内存读写,效率肯定不如矩阵运算,况且这些框架对矩阵运算都有优化。而对于我们自己手算的话,还是通过索引更加方便。
7、总结
- 对于二分类的逻辑回归,可以从四个角度进行参数搜索:最小化损失函数、最大化似然函数、最小化散度、最小化交叉熵,并且它们是等价的。
- 逻辑回归的损失函数实际上就是交叉熵公式在随机变量只取两个值时的特殊形式,因此这个损失函数又叫做二元交叉熵公式(Binary Cross Entropy,BCE)
- 多分类的损失函数与交叉熵公式是一致的,只是计算过程不同,但实际使用中因为矩阵运算的优势,所以主要采用了交叉熵的计算方式,因此称这个损失函数为交叉熵损失。
- 中间推导损失函数的部分都基于单个样本的对数损失函数,可以看到它其实就是信息量。可以想象,我们在搜索模型参数的过程中,如果发现当前模型参数在某一个样本上分类错了,那么它带来的信息量是巨大的(相当于告诉我们当前参数不行,得换一个),这刚好与损失函数的特点相符合(分类错误导致损失很大)。也许正是信息论指导了损失函数的设计?
8、参考资料
- 《统计学习方法》
- 《数理统计》
- https://www.cnblogs.com/kyrieng/p/8694705.html
- 最详细的语义分割---07交叉熵到底在干什么?_语义分割交叉熵损失_正在学习的浅语的博客-CSDN博客
写得真累啊~~~~~~~~感觉捋顺太不容易了。
希望下次看能看得懂!O.O!