神经网络训练Trick-Focal Loss

Focal Loss由(Kaiming He at., 2017)提出用于解决One-stage中正负样本不平衡的问题,同时使得网络更能挖掘困难样本的知识。
建议在看之前先看一下交叉熵的介绍:交叉熵损失函数原理详解(这篇文章对交叉熵介绍很透彻)
正负样本:在进行物体检测时,图像中的背景为负样本,物体为正样本。负样本数据大于正样本数据。
简单困难样本:出现频率高样本简单样本,出现频率低的样本为困难样本
原始交叉熵函数:
在这里插入图片描述
定义:
在这里插入图片描述
则:
在这里插入图片描述
解决正负样本不平衡问题:
给正负样本加上权重,负样本出现的频次多,那么就降低负样本的权重,正样本数量少,就相对提高正样本的权重。
在这里插入图片描述
其中: α ∈ [ 0 , 1 ] \alpha\in[0,1] α[0,1]正类, 1 − α 1-\alpha 1α负类, α \alpha α一般取0.25。
Focal Loss:
虽然(3)可以控制正负样本的权重,但是没法控制简单样本和困难样本的权重。因此进行如下改进:
在这里插入图片描述
γ \gamma γ:focusing parameter, γ ∈ [ 0 , 5 ] \gamma\in[0,5] γ[0,5] γ \gamma γ一般取2
( 1 − p t ) γ (1-p_t)^\gamma (1pt)γ:调制系数(modulating factor)。
随着对困难样本挖掘,困难样本预测概率也变大,网络对其的关注度降低。
两个重要性质:
1.当一个样本被分错pt很小,调制因子(1-pt)接近1,损失不被影响;当pt→1预测概率很好,因子(1-pt)接近0,那么分的比较好的样本的权值就被调低。因此调制系数趋于1,也就是说相比原来的loss是没有什么大的改变的。当pt趋于1的时候(此时分类正确而且是易分类样本),调制系数趋于0,也就是对于总的loss的贡献很小。
2、当γ=0的时候,focal loss就是传统的交叉熵损失,当γ增加的时候,调制系数也会增加。 专注参数γ平滑地调节了易分样本调低权值的比例。γ增大能增强调制因子的影响,实验发现γ取2最好。直觉上来说,调制因子减少了易分样本的损失贡献,拓宽了样例接收到低损失的范围。当γ一定的时候,比如等于2,一样easy example(pt=0.9)的loss要比标准的交叉熵loss小100+倍,当pt=0.968时,要小1000+倍,但是对于hard example(pt < 0.5),loss最多小了4倍。这样的话hard example的权重相对就提升了很多。这样就增加了那些误分类的重要性。
一般使用时将两者融合,既能调整正负样本的权重,又能控制难易分类样本的权重。
在这里插入图片描述
一般当γ增加的时候,a需要减小(实验中γ=2,a=0.25的效果最好)
语音识别中,例子:

class FocalLoss(nn.Module):
    def __init__(self, ignore_idx, alpha=0.25, gamma=2, smoothing=0, size_average=False):
        super(FocalLoss, self).__init__()
        self.ignore_idx = ignore_idx
        self.alpha = alpha
        self.gamma = gamma
        self.size_average = size_average
        self.smoothing = smoothing
    def forward(self, inputs, targets):
        N = inputs.size(0)
        C = inputs.size(2)
        inputs = inputs.view(-1,C)
        targets = targets.view(-1, 1)
        
        log_p = F.log_softmax(inputs,dim=1)
        
        #print('probs',probs.shape,probs)
        class_mask = inputs.clone().fill_(self.smoothing/(C-1))
        class_mask.scatter_(1, targets, 1.0-self.smoothing)
        #print('class_mask',class_mask.shape,class_mask)
        ce_loss = log_p* class_mask
        probs = torch.exp(log_p)
        #0 -> 1-a
        #1 -> (2a-1) +(1-a)=a
        alpha_facter = class_mask*(2*self.alpha - 1)
        alpha_facter = alpha_facter + (1-self.alpha)
        #print('alpha_facter',alpha_facter.shape,alpha_facter)
        batch_loss = - alpha_facter * torch.pow(1-probs, self.gamma)*ce_loss
        batch_loss = batch_loss.sum(1).view(-1)
        
        non_pad_mask = (targets  != self.ignore_idx).view(-1)
        #print('non_pad_mask',non_pad_mask.shape,non_pad_mask)
        total = non_pad_mask.sum().float()
        preds = probs.max(1)[1]
        n_correct = preds.eq(targets.view(-1))
        #print('n_correct1:',n_correct)
        n_correct = n_correct.masked_select(non_pad_mask).sum().float()
        
        #print('batch_loss',batch_loss.shape,batch_loss)

        loss = batch_loss.masked_select(non_pad_mask)
        #print('loss',loss.shape,loss)
        return loss.sum()/N, n_correct/total*100

参考:
[1] Focal Loss for Dense Object Detection [论文]
[2] Focal loss论文详解 [优快云]

### 神经网络训练过程中的技巧与最佳实践 在神经网络训练过程中,有许多技巧可以帮助提高模型性能、加速收敛以及减少过拟合等问题。以下是几个常见的技巧和最佳实践: #### 数据预处理 数据的质量直接影响模型的效果。通常需要对原始数据进行标准化或归一化处理,使得输入的数据分布在相同的范围内。这有助于优化器更快地找到最优解[^1]。 #### 初始化权重 合适的初始化策略对于深层网络尤为重要。如果初始权设置不当,则可能导致梯度爆炸或者梯度消失现象的发生。Xavier 和 He 初始化是两种常用的初始化方法,它们能够有效缓解上述问题[^2]。 #### 使用正则化技术防止过拟合 为了使模型具有更好的泛化能力,可以在损失函数中加入L1/L2范数作为惩罚项;也可以采用Dropout随机丢弃部分单元的方式来进行隐含层内部的信息交流限制,从而达到降低复杂度的目的[^3]。 #### 调整学习率 动态调整学习速率是一种非常有效的手段。可以通过观察验证集上的表现来决定何时应该减小当前的学习速度。此外还有诸如余弦退火等高级调度算法可供选择[^4]。 #### 利用批量规范化(Batch Normalization) BatchNorm能够在每次mini-batch更新前先对其做一次重新缩放和平移操作,这样即使是在较深架构下也能维持住激活分布的一致性,进而促进更快速稳定的训练进程[^5]。 ```python import tensorflow as tf from tensorflow.keras.layers import BatchNormalization model = tf.keras.Sequential([ ... Dense(64), BatchNormalization(), Activation('relu'), ... ]) ``` #### 运用迁移学习加快新任务适配 当面临资源有限但又有相似领域已有成果可用的情况时,不妨考虑直接拿过来稍作修改再投入使用即可获得不错的结果。例如ImageNet上预训练过的大型CNN可以直接拿来用于其他视觉识别场景下的微调工作。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值