——neozng1@hnu.edu.cn
这波是鸽了一个多月稳定回归了,本账号在升级后将作为HNU跃鹿战队的官方号进行运营。之后会继续保持1~2周一更的速度的。如果你觉得笔者写的还不错的话,请不要吝啬点赞噢。若想继续追更了解本系列的最新动态,来个关注吧!从2022年开始,将会有新的专栏开始更新!
同时,本系列的第六部分即算法的具体应用和部署从下次更新开始会和第五部分同步,因为两个章节的内容都实在有点多,而且光讲理论也确实挺没劲的,那么就来点能用的东西吧。
至此我们已经介绍了4个检测网络,分别是two-stage的代表R-CNN家族和one-stage的开创者yolo,现在可以先小小地来总结一下目标检测网络的设计思想和改进方向了。不过细心的你应该已经发现,我们没有介绍如何训练网络(即loss function的设计思想和具体实现,如何在训练过程中给网络的不同部分提供监督信息?),这其实也是很重要的一部分,我们将在总结完以后大致介绍一下loss funciton和网络pipeline的对应关系。
首先笔者想要再强调一下神经网络作为一个万能的函数拟合器的作用:只要合理的设计网络的任务和其损失函数并且提供对应的训练数据,它就能够完成你想做的事!从Faster-RCNN和YOLO的实现结构我们就可以看出,这些block难道有哪个是有实际物理意义的吗?显然没有,即使使用相同的架构,我也可以通过修改 loss functoin和任务需求来决定最后网络的输出是什么、具有什么意义。因此在设计网络的时候,最需要关注的问题是我们要如何把检测任务拆解成合适的几个子任务和模块、怎么样设计最有效的 loss、使用怎样的策略来减小搜索空间、如何去根据检测任务的特点来有针对性地给网络各个部分赋予实际意义。上面说的这些都是在给网络加入先验知识,告诉网络应该如何更好地去学习目标的特征、完成学习。
很多人说神经网络只不过是在搭积木、炼丹,此言差矣。诚然大部分时候我们需要花大功夫去调试去改参数,但是怎样设计一个网络还是有很大的学问的。现在也有很多科研人员、很多学者尝试让神经网络的设计更具有逻辑性,通过数学的语言更科学地去建模问题、用更成体系的理论去分析网络结构和模型,减少启发式的设计而更多地去基于模型来调参等等...... 和存在已久的传统医学现代医学之争一样,联结主义也一直为人们诟病缺少解释性,被符号主义和行为主义打压(虽然一直被打压但是神经网络还是以不可阻挡之势统治了当前AI的发展,唉呀妈呀真香~),笔者相信随着科研人员在可解释性这条道路越走越远(比如现在火热的可视化),神经网络最终会拥抱科学,完成华丽的蜕变(我们这些小noob就乖乖炼丹把evolution的事情都交给大佬们吧,不过也许你就是将来的大佬!)。
最后笔者想要再次强调强调强调:神经网络是一个万能的函数拟合器,拟合成什么样关键看你的设计!这里所说的设计也就是loss function的设计,LF能够用于衡量网络学习效果的好坏,又作为学习的优化目标,因此我们依据最小化LF的原则使用梯度下降+反向传播对网络的权重进行训练。
所以接下来让我们把网络需要实现的任务的设计思想具体化,看看其中最重要最关键的一环:loss function是如何设计的,并介绍一些对loss的优化方法。这里将会介绍MSE、交叉熵、FL、FCOS、IOU loss等经典方法。
-
MAE (mean average error)和RMSE(root mean square error)
-
MAE即平均绝对值误差,计算得到的是各个样本输入得到的结果相对于对应的标签的差的绝对值,这也是计算误差最直观最简单的方法,输出结果和标签差了多少,我们就记多少误差。![](https://img-blog.csdnimg.cn/f8031965dea94750aa89170471c4cae2.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASE5V6LeD6bm_5oiY6Zif,size_20,color_FFFFFF,t_70,g_se,x_16)
从数学计算角度看,MAE的结果就是残差的平均值。例如有3个西瓜样本的数据x1,x2,x3,每个样本都是一个5维的数据,即:[大小,花纹宽度,重量,颜色深度,拍击是否有回响] ,标签分别为30%,60%,90%将他们输入一个神经网络,希望该神经网络输出的信息为西瓜的甜度;那么,假设该网络对应三个输入的输出值分别为25%,55%,96%,计算其MAE就得到损失值为16/3=5.33。从损失函数这个取名我们也可以看出,其含义就是对于每一个和标签不同的输出,将会产生多少的误差(损失)。
对于目标检测网络,我们要输出目标框的位置(x,y,w,h)和分类,因此标签也需要有对应的5个值。若采用MAE来计算损失函数,那么就是在一个batch结束后,分别统计每个待估值(需要得到的预测值)对于该batch各个样本的平均绝对误差,让损失函数对xi求偏导再将得到的结果作为反向传播的初始值,进行BP训练。分类只有是和不是,因此是一个二元的损失,但你仍然可以使用MAE作为分类损失函数,虽然它不是太好用。MAE还有一个缺点,就是在原点处不可导。
-
RMSE和MAE的区别就在于,他会将误差求平方之后再求平均并在最后开方。![](https://img-blog.csdnimg.cn/2126fbe9dec1455f9733b32dc98eace5.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASE5V6LeD6bm_5oiY6Zif,size_20,color_FFFFFF,t_70,g_se,x_16)
我们之前已经提到过,设计不同的、有针对性的损失函数是神经网络改进的关键,那么RMAE相对MAE又有什么改进呢?可以看到,MAE对于不同的样本的损失采取的策略是“一视同仁”,即不论单个样本产生的损失值有多大,最后都是获得相同的权重。对于那些损失小的样本,我们会认为该样本网络已经学习得比较好,不需要在这些样本上花费过多的精力;而对于损失值较大的样本,更应该“照顾有加”。那么有没有什么办法实现这种操作?铺垫了这么多,RMAE肯定就是一种能实现该需求的损失函数。每个样本在最终损失中的贡献会随着该样本损失的增大而增大(取了平方,不再是线性关系,相当于y=x^2和y=x比较)。因此RMAE会对训练得不好得样本施以更大的惩罚。但是同样,对于离群值(在这里是特别大的异常值)将会有一个巨大的损失,这将会误导模型的训练,MAE就没有这个问题。
此处特别注意,并不是 Loss越大,回传的梯度就越大,梯度只和 Loss function的导数(梯度)有关!网上有很多教程都出现了这个讹误,显然我们从梯度下降法的原理出发就会发现,我们把LF看作是权重ω和b的函数,分别对它们求偏导以得到当前的梯度值并根据往梯度方向更新权重,而LF在参数空间中某一点的大小和梯度是完全无关的!在下面介绍focal loss的时候我们还会再提到这一点。
此处mark。
不过不加开方也是可以的,这时候得到的值为MAE(mean square error),公式类似于我们常说的方差(不过方差计算时的yi是这组数据的平均值,MAE的意义显然不是数据的分散程度)。RMSE相对于MAE,由于在最后进行了开平方的操作,就不那么容易产生梯度爆炸的问题了。
聪明的你应该想到,如果我想让大的更大小的更小,或者让大的不要那么大小的不要那么小,只需要改动误差上的次幂数就行:若选择损失的绝对值的三次方,那么误差大的样本的权重将进一步上升;而选择1.5次方,得到的结果将会比平方更缓和。(那么次幂小于1大于0又是什么情况?)
此外,RMAE/MSE还有一个较大的缺点,在使用sigmoid作为激活函数配合使用时(即用于分类),收敛速度会非常慢。sigmoid激活函数在特别大或接近零时的导数几乎为零,这就导致当预测值落在这些区间时产生的误差非常小,而RMSE又刚好进一步减小了本就很小的梯度(列式计算一下L对xi的i偏导即可,如下图),因此在输出层,神经元的学习速度会非常缓慢。不过好在除了这种方法,还有一些更佳的分类损失函数设计策略(也就是下面要介绍的交叉熵,另外,ReLU系的激活函数几乎已经完全取代了sigmoid,这样在输入激活函数的值大于零的时候会有一个稳定的导数值,不过还是不推荐使用MSE作为分类损失函数)。
![](https://img-blog.csdnimg.cn/7c12a833db3d4ee49c201f43d50041f6.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASE5V6LeD6bm_5oiY6Zif,size_13,color_FFFFFF,t_70,g_se,x_16)
使用MSE作为分类损失函数时求导得到的结果
激活值为0/1或接近0/1时梯度会非常小
![](https://img-blog.csdnimg.cn/cdeafb27a04b4655835bef4b73b4dbb0.jpg?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASE5V6LeD6bm_5oiY6Zif,size_18,color_FFFFFF,t_70,g_se,x_16)
sigmoid的导数
从上面的分析中我们可以得出,这三者在目标检测中一般用于设计距离损失函数,用于计算预测得到的bbox和groundtruth的差别,也就是常说的回归问题。对于分类问题就要使用其他的损失函数了。
-
CE/BCE(cross entropy/ binary cross entropy)
既然已经有了距离损失函数,那我们就来看看交叉熵在分类应用的效果如何吧。这篇文章:损失函数:交叉熵详解 从信息熵的前世今生介绍了交叉熵损失函数的由来,强烈推荐。BCE和CE的区别在于一个用于二分类,一个用于多分类,CE就是BCE的多分类推广形式。上面介绍MSE的时候已经提到,我们希望在样本预测值偏离标签大的时候拥有更大的损失值,而RMSE或MSE恰恰在分类任务上对于这点做的不好,因为分类只有错误和正确(0,1),这两者在这些区间的产生的损失值太小不利于网络的训练。
详细的推导的上方的教程里有,不在此赘述,直接看看BCE的形式:
![](https://img-blog.csdnimg.cn/9d65fd2cb81e4c3da1f3bc653bf385f8.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASE5V6LeD6bm_5oiY6Zif,size_14,color_FFFFFF,t_70,g_se,x_16)
此处时σ(xi)就是将网络最后一层的输出值送入sigmoid函数得到的(将输出归一化为概率,区间为[0,1] )。L由两项构成并且总有一项是零。
求L对xi的偏导,就能算出其结果恰正比于预测值和标签值GT的差。这样就解决了MSE存在的问题。不过前面提到,我们希望让误差大(分类分得不好)的样本拥有更大的权重,CE就无法做到这一点了,欲知如何解决请看Focal Loss。
多分类问题只需要对BCE进行简单的推广,在此直接给出其形式:
![](https://img-blog.csdnimg.cn/4460a9783ccd4e59bdced6c2ec8883d8.png)
其中
![](https://img-blog.csdnimg.cn/0e65d02b6a5546aaa81f86067e402e81.png)
即为softmax函数。
对比BCE的损失函数,细心的你会发现(1-yi)不见了,比如要分为 (apple,banana,pear) 这三个类,最后得到的向量为 [0.2 , 0.5 , 0.3] ,而标签为 [0,1,0] 即最后的分类为banana,apple和pear虽然分别有0.2和0.3的置信度但产生的误差即-0.2和-0.3却不会计入总损失!这样岂不是没办法改善假阳性的问题吗?别担心,我们使用的是softmax函数,由于归一化(除以各个分量的综合),它会让输出的向量各个分量的合即概率合为1,因此提升对yi=1的概率自然就会降低其他分类的预测概率了。
如果你觉得笔者写的还不错的话,请不要吝啬点赞噢。若想继续追更了解本系列的最新动态,来个关注吧!从2022年开始,将会有新的专栏开始更新!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)