paddle实现focal loss

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

  1. 使用 paddle 现有的 op 去组合出来所需要的能力
  2. 自己实现 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

参考:paddle 尝试实现 focal loss
参考:sigmoid_focal_loss

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
脊回归(Ridge Regression)是一种线性回归算法,通过引入正则化项来解决数据中存在多重共线性的问题。正则化项的作用是约束模型参数,防止过拟合。在PaddlePaddle中,可以使用`paddle.regularizer.Ridge`来实现脊回归。 以下是一个使用PaddlePaddle实现脊回归的代码示例: ```python import paddle import numpy as np # 生成随机数据 np.random.seed(2022) x = np.random.uniform(-1, 1, size=(100, 10)).astype('float32') y = np.random.uniform(-1, 1, size=(100, 1)).astype('float32') # 定义网络 x = paddle.static.data(name='x', shape=[None, 10], dtype='float32') y = paddle.static.data(name='y', shape=[None, 1], dtype='float32') predict = paddle.static.nn.fc(x, 1, bias_attr=False, param_attr=paddle.ParamAttr( regularizer=paddle.regularizer.Ridge( coeff=0.1))) loss = paddle.mean(paddle.square(predict - y)) # 定义优化器 optimizer = paddle.optimizer.SGD(learning_rate=0.01) optimizer.minimize(loss) # 训练模型 place = paddle.CPUPlace() exe = paddle.static.Executor(place) exe.run(paddle.static.default_startup_program()) for i in range(1000): loss_val, = exe.run(paddle.static.default_main_program(), feed={'x': x, 'y': y}, fetch_list=[loss]) if i % 100 == 0: print("Step %d, Loss %f" % (i, loss_val)) ``` 在上面的代码中,我们使用`paddle.static.nn.fc`来定义一个全连接层作为预测模型,使用`paddle.ParamAttr`来设置参数的正则化方式为脊回归。 通过这个简单的例子,你可以使用PaddlePaddle实现脊回归,并且可以根据自己的需求进行参数的调节和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落花逐流水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值