蛋白质比赛kernel 解读5-inceptionresnet+focal loss

https://www.kaggle.com/achoetwice/focal-loss-with-pre-train-v2

1 首先介绍交叉熵损失,这里以二分类为例,p 表示概率,公式如下:

二分类中y的值是+1 或者-1,p 的范围为0到1,当真实lable 为1,也就是y 为1的时候,假如某个样本x的预测值为1,这个类的概率为p=0.6,loss 为-log(0.6), 这个损失是大于等于0的,如果p=0.9,loss 为-log(0.9), 所以p=0.6 的loss 要大于p=0.9 的loss。

为了方便,用pt 代替p,如公式2:

2 对交叉熵基本的改进,增加一个系数at,跟pt 的定义类相似,当label =1 的时候,at=a,当label =-1 的时候,at=1-a,a的范围也是0到1,因此可以通过设置a的值,(一般而言,假如1这个类的样本数比-1 这个类的样本数多很多,那么a会取0到0.5 来增加-1 这个类的样本权重) 来控制正负样本对总的loss的共享权重。

虽然前面的公式3可以控制正负样本的权重,但是没有办法控制容易分类和难分类的权重,于是有了focal loss:

这里的γ称作focusing parameter,γ>=0

称为调剂系数(modulating factor)

这里介绍下focal loss 的两个重要性质:1 当一个样本被分错的时候,pt 是很小的(当y=1时,p要小于0.5 才是错分类,此时pt 就比较小,反之亦然) ,因此调剂系数就趋于1,也就是说相比原来的loss 是没有什么大的改变的。当pt 趋于1的时候( 此时分类正确而且是易分类的样本) 。调制系数趋于0,也就是对于总的loss的贡献很小,2当y=0的时候,focal loss 就是传统的交叉熵损失,当y增加时,调制系数也会增加。

总的来说,就是用一个合适的函数去度量男分类和易分类样本对总的损失的贡献。

作者在实验室采用的公式5的focal loss (结合3和4,这样既能调整正负样本的权重,又能控制难易分类样本的权重)

keras 

def binary_focal_loss(y_true, y_pred, gamma=2.0, alpha=0.25):
    """
    Implementation of Focal Loss from the paper in multiclass classification
    Formula:
        loss = -alpha_t*((1-p_t)^gamma)*log(p_t)
        
        p_t = y_pred, if y_true = 1
        p_t = 1-y_pred, otherwise
        
        alpha_t = alpha, if y_true=1
        alpha_t = 1-alpha, otherwise
        
        cross_entropy = -log(p_t)
    Parameters:
        alpha -- the same as wighting factor in balanced cross entropy
        gamma -- focusing parameter for modulating factor (1-p)
    Default value:
        gamma -- 2.0 as mentioned in the paper
        alpha -- 0.25 as mentioned in the paper
    """

    # Define epsilon so that the backpropagation will not result in NaN
    # for 0 divisor case
    epsilon = K.epsilon()
    # Add the epsilon to prediction value
    #y_pred = y_pred + epsilon
    # Clip the prediciton value
    y_pred = K.clip(y_pred, epsilon, 1.0-epsilon)
    # Calculate p_t
    p_t = tf.where(K.equal(y_true, 1), y_pred, 1-y_pred)
    # Calculate alpha_t
    alpha_factor = K.ones_like(y_true)*alpha
    alpha_t = tf.where(K.equal(y_true, 1), alpha_factor, 1-alpha_factor)
    # Calculate cross entropy
    cross_entropy = -K.log(p_t)
    weight = alpha_t * K.pow((1-p_t), gamma)
    # Calculate focal loss
    loss = weight * cross_entropy
    # Sum the losses in mini_batch
    loss = K.sum(loss, axis=1)
    
    return loss

fastai :https://www.kaggle.com/iafoss/pretrained-resnet34-with-rgby-0-460-public-lb

keras 版本:https://www.kaggle.com/rejpalcz/focalloss-for-keras/comments

猜你喜欢

转载自blog.csdn.net/qq_16236875/article/details/88371802
今日推荐