paddle 尝试实现 focal loss

paddle 里面没有 focal loss 的API,不过这个loss函数比较简单,所以决定自己实现尝试一下。在 paddle 里面实现类似这样的功能有两种选择:

  • 使用 paddle 现有的 op 去组合出来所需要的能力
  • 自己实现 op
    • python 端实现 op
    • C++ 端实现 op

两种思路都可以实现,但是难度相差很多,前者比较简单,熟悉 paddle 的数学操作,理解公式含义即可。后者又分两种方式,python 端实现相对简单,C++端实现比较复杂。这次尝试用 paddle 的 op 组合实现。

理解 focal loss

最早出现在单阶段目标检测当中。单阶段训练时正负样本比例难以控制,loss 被大量的负样本充斥,导致反向传播时向着调整负样本方向前进,而正样本的训练不佳。为了解决这个问题,何凯明大神提出了 focal loss 损失函数调节正负样本权重,同时还能进一步调节难易样本的权重。进一步的理解可上网查看,资料很多。原版 focal loss 的公式如下:

loss = -at·(1 - pt)^r · log(pt)

at和r 是超参数,分别用于控制正负样本的权重和难易样本的权重。对于多分类而言。at 不太好处理,因此这次实现暂时忽略,后续想法是根据各个类别占总样本中的比例设置

# 调试打印函数,通过 py_func 实现打印参数值的 op,方便调试
def print_func(var):
    logger.info("in py func type: {0}".format(type(var)))
    print(np.array(var))
 
 
# 不带类别平衡的 focal loss,仅仅区分类别难易;猜测此时算出来的梯度有一个 gama 倍,所以学习率可以比以往更小一点
def focal_loss(pred, label, gama):
    # 使用打印函数查看当前 Tensor,
    # fluid.layers.py_func(func=print_func, x=pred, out=None)
    one_hot = paddle.fluid.layers.one_hot(label, train_parameters['class_dim'])
    prob = one_hot * pred
    cross_entropy = one_hot * fluid.layers.log(pred)
    cross_entropy = fluid.layers.reduce_sum(cross_entropy, dim=-1)
    sum = paddle.fluid.layers.sum(cross_entropy)
    weight = -1.0 * one_hot * paddle.fluid.layers.pow((1.0 - pred), gama)
    weight = fluid.layers.reduce_sum(weight, dim=-1)
    return weight * cross_entropy
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值