合肥做网站首选 晨飞网络,开发网站网络公司有哪些,首页公司,网络营销图片Loss 是深度学习算法中重要的一部分#xff0c;它的主要功能是评价网络预测的准确性和指导权重更新。合适 Loss 可以让网络收敛更快#xff0c;预测更准。这个项目介绍了损失函数的基本概念以及7种常用损失函数的形式#xff0c;性质#xff0c;参数#xff0c;使用场景及…Loss 是深度学习算法中重要的一部分它的主要功能是评价网络预测的准确性和指导权重更新。合适 Loss 可以让网络收敛更快预测更准。这个项目介绍了损失函数的基本概念以及7种常用损失函数的形式性质参数使用场景及区别并给出了开箱即用的Paddle实现。目前包含的Loss有
L1(Mean Absolute Error) L2(Mean Square Error) Huber Loss LogCosh Loss Cross Entropy(Log Loss) Focal Loss Hinge Loss 未完待续… 关键概念 先引入一些概念方便后面介绍。功能角度我们可以形容深度学习是一种从训练数据中学习进而形成问题解决方案的算法。如果训练数据是有标签的那么它就属于一个监督学习任务(比如房价预测或手写数字识别)。形式化的我们可以描述监督学习为: 给算法一个有标签的训练数据集 ( , ) (X,Y)希望算法能学习出一个 − X−Y 的映射关系 f使得不仅对于训练集中的 x ( ) f(x) 与对应的 y 接近而且对不在训练集中的 x ( ) f(x) 也与实际的 y 接近。
听起来很美好但具体怎么操作呢 这里就要用到Loss。我们在理解监督学习概念的时候可以用 “接近” 这样定性的描述但是算法需要一个函数来量化模型给出的预测和训练数据中对应标签的差异我们把这个函数叫做Loss。形式化的可以将Loss定义为网络预测值 p 和实际标签 y 的函数 ( , ) L(p,y)。
Loss的性质 Loss函数需要满足一些性质首先最明显的它应该能够描述我们上面概念中的接近。预测值接近标签 Loss 应该小否则 Loss 应该大。 其次深度学习使用的梯度下降优化方法需要让模型权重沿着 Loss 导数的反向更新所以这个函数需要是可导的而且不能导数处处为0(这样权重动不了)。 此外有一些加分项比如 MSE Loss 的梯度正比于 Loss 值因此用 MSE 做训练收敛速度一般比 MAE 快。
Loss的分类 不同的深度学习任务定义 “接近” 的标准不同因此 Loss 也有很多种但大致可以分为两类: 回归 Loss 和 分类 Loss。两类问题最明显的区别是回归预测的结果是连续的(比如房价)而分类预测的结果是离散的(比如手写识别输出这个数字是几)。虽然很多实际的深度学习应用比上面的两个例子复杂但是也可以用回归和分类来描述。比如语义分割可以看成对图像中的每一个像素点进行分类目标检测可以看成对Bounding Box在图像中的位置和大小进行回归NLP总情感倾向分析可以看成对句子进行积极和消极分类。
符号 下面的表达式都按照这个符号标准
x:训练数据集中的一个输入 y:训练数据集中的一个输出 p:网络针对一个输入给出的预测值 M:分类问题中的类别数量 N:输入loss的数据条数可以理解为Batch Size i:第i条数据 j:第j个输出 开篇的废话就这么多下面首先回归之后分类进入正题。
回归 Loss 这里画出了所有 Loss 的函数图像可以对照查看。
Mean Absolute Error (L1 Loss) 和 Mean Square ErrorL2 Loss 1
1 ∑ ∣ − ∣ L1Loss N 1 ∑∣y−p∣ 2
1 ∑ ( − ) 2 L2Loss N 1 ∑(y−p) 2
L1和L2 Loss很类似而且一些性质比较着说更清楚因此放在一起。首先计算方法上 L1 Loss 是求所有预测值和标签距离的平均数L2 Loss 是求预测值和标签距离平方的平均数。二者的结构很类似区别就是一个用了绝对值一个用了平方。在性质上二者主要有三个方面的不同离群点鲁棒性梯度和是否可微。
离群点鲁棒性 离群点是数据中明显偏离整体分布的点。在深度学习任务中离群点一般代表噪声比如整理数据的时候 1.5 忘写小数点了变成了 15其他数据还都是1.x那这条数据就变成了离群点。但是在有些场景下一些数据点可能就是比较特殊它们的确离群但不是数据中的错误。如果是第一种情况我们在训练的过程中会希望降低脏数据对网络的影响。如果是第二种离群点是特殊情况我们会希望考虑这些特殊的信息但不希望他们给网络整体性能带来太大的影响。L2 Loss 对于预测值和标签的距离做了平方当距离大于 1 的时候平方操作会放大误差因此离群点的Loss会非常大导致 L2 Loss 对其倾斜更多的权重。相比之下 L1 Loss 的情况会好一些因为只是做了绝对值所以对离群点不如 L2 敏感。比如下面这组数据
预测值 标签 L1 L1(离群) 变化 L2 L2(离群) 变化比率 1.1 1 0.1 0.1 0.01 0.01 1.2 1.2 0 0 0 0 1.3 1.5/3 0.2 1.7 0.04 2.89 0.1 0.6 6 0.016 0.97 60.6 网络预测值相同的情况下如果数据1.5变成一个离群点L1 Loss变大了6倍L2 Loss变大了60倍。显然用L2 Loss拟合出的结果会对这个离群点更敏感
黑线为用L1的结果红线为用L2的结果
此外可以想象一个直观的例子,拟合一批 x 都一样的数据比如 y 轴上的一些点这样 x 都为0。拟合出来的结果和 y 轴的交点如果用 L1 Loss 应该是中位数如果用 L2 Loss 应该是平均数。对离群点来说中位数比平均数显然更鲁棒。
梯度 对 L1 和 L2 Loss求导可以知道 L1 Loss 的梯度一直是 ± 1 ±1而 L2 Loss 的梯度是正比于 Loss 值的Loss 值越大梯度越大。在梯度的性质上L2是优于L1的体现在两个方面。当Loss非常大的时候L1的梯度一直是 1 1这样收敛的速度比L2慢。其次当 Loss 很接近0的时候L1的梯度还是1这个大梯度容易让网络越过 Loss 最低点导致 Loss 在最低点附近震荡相比之下 L2 在 Loss 接近0的时候梯度也接近0不存在这样震荡的问题。
可微 因为L1 Loss是个分段函数所以在最低点是不可微的。L2则全程可微最后一定会稳定收敛到一个最优解。但是需要注意的是L2不是一个凸函数因此收敛到的解不一定是全局最优解也有可能是一个局部最优解。
L1和L2的选择 总体上来说L2训练收敛的速度快选择L2的情况比较多。如果训练数据中存在比较多的脏数据应该选择L1 Loss避免其影响结果。
下面是实现
In [1]
初始化一些环境这个部分下面所有Loss都会用到
import paddle.fluid as fluid import numpy as np
places fluid.CPUPlace() exe fluid.Executor(places) In [23] def l1_loss(pred, label): loss fluid.layers.abs(pred - label) loss fluid.layers.reduce_mean(loss) return loss
l1_program fluid.Program() with fluid.program_guard(l1_program): pred fluid.data(‘pred’, [3,1], dtype“float32”) gt fluid.data(‘gt’, [3,1], dtype“float32”) loss l1_loss(pred, gt)
pred_val np.array([[1], [2], [3] ],dtype“float32”) gt_val np.array([[1], [3], [6] ],dtype“float32”)
loss_valueexe.run(l1_program, feed{ ‘pred’: pred_val , “gt”: gt_val },fetch_list[loss]) print(“L1 Loss:”, loss_value) L1 Loss: [array([1.3333334], dtypefloat32)] In [24] def l2_loss(pred, label): loss (pred - label) ** 2 loss fluid.layers.reduce_mean(loss) return loss
l2_program fluid.Program() with fluid.program_guard(l2_program): pred fluid.data(‘pred’, shape[3,1], dtype‘float32’) gt fluid.data(‘gt’, shape[3,1], dtype‘float32’) loss l2_loss(pred, gt)
pred_val np.array([[3], [2], [1]], dtype‘float32’) gt_val np.array([[1], [2], [3]], dtype‘float32’)
loss_value exe.run(l2_program, feed{‘pred’: pred_val, ‘gt’: gt_val}, fetch_list [loss]) print(“L2 Loss:”, loss_value) L2 Loss: [array([2.6666667], dtypefloat32)] Mean Bias Error
1 ( − ) MeanBiasError N 1 (p−y)
MBE是不做绝对值的L1 Loss它的一个主要的问题是正负 Loss 会相互抵消在深度学习的应用很少。但是因为没做绝对值所以可以看出网络预测的结果是偏大还是偏小。
In [25] def mean_bias_error(pred, label): loss pred - label loss fluid.layers.reduce_mean(loss) return loss
mbe_program fluid.Program() with fluid.program_guard(mbe_program): pred fluid.data(‘pred’, shape[3,1], dtype‘float32’) gt fluid.data(‘gt’, shape[3,1], dtype‘float32’) loss mean_bias_error(pred, gt)
pred_val np.array([[3], [2], [1]], dtype‘float32’) gt_val np.array([[1], [2], [3]], dtype‘float32’) # 这组数据上正负的bias就抵消了这也是深度学习基本不用这个loss的原因
loss_value exe.run(mbe_program, feed{‘pred’: pred_val, ‘gt’: gt_val}, fetch_list [loss]) print(“MBE:”, loss_value) MBE: [array([0.], dtypefloat32)] Huber loss(Smooth L1 Loss) 注Smooth L1 Loss 并不是Huber的别名而是一个特殊情况。 { 1 2 ( − ) 2 ∣ − ∣ ∣ − ∣ − 1 2 2 ℎ HuberLoss{ 2 1 (y−p) 2
δ∣y−p∣− 2 1 δ 2
∣y−p∣δ otherwise
Huber是 L1 和 L2 Loss 的分段组合。前面我们已经知道 L1 在有离群点时性能好L2 在接近零点处稳定收敛, 于是将二者组合在零点附近用L2其余位置用 L1 就形成了 Huber Loss。具体的选择范围用 δ 划分。 δ 取 1 的 Huber Loss 也叫 Smooth L1 Loss所以说Smooth L1是Huber的一种特殊情况。分段组合克服了两个 Loss 各自的一部分弱点Huber Loss对离群点没有 L2 敏感在零点附近也不会出现 L1 的震荡。通过调节 δ 可以调节 Huber Loss 对离群点的敏感度 δ 越大使用L2的区间越大对离群点越敏感; 反之 δ 越小越不敏感。
In [26] def huber_loss(pred, label, delta1): # 这个实现里面去掉了 1/2常数项 这样不需要用 if更简洁 l2 (pred - label) ** 2 l1 fluid.layers.abs(pred - label) * delta loss fluid.layers.elementwise_min(l1, l2) loss fluid.layers.reduce_mean(loss) return loss
huber_program fluid.Program() with fluid.program_guard(huber_program): pred fluid.data(‘pred’, shape[3,1], dtype‘float32’) gt fluid.data(‘gt’, shape[3,1], dtype‘float32’) loss huber_loss(pred, gt, delta2)
pred_val np.array([[4], [2], [1]], dtype‘float32’) gt_val np.array([[1], [2], [3]], dtype‘float32’)
loss_value exe.run(huber_program, feed{‘pred’: pred_val, ‘gt’: gt_val}, fetch_list [loss]) print(“Huber Loss:”, loss_value) Huber Loss: [array([3.3333333], dtypefloat32)] log-cosh ℎ ( ℎ ( − ) ) LogCoshlog(cosh(y−p))
形如其名Log-cosh 计算上是先做cosh之后做log。这个函数的特点是在 Loss 比较小的时候,值近似于 1 2 2 2 1 x 2 而在值比较大的时候近似于 ∣ − ∣ − ( 2 ) ∣y−p∣−log(2)。 他基本和 Huber Loss的性质相同但是处处二阶可微。(一些优化方法有这个要求)
红色为Log-Cosh紫色为Huber Loss
In [27] def logcosh_loss(pred, label): loss pred - label e np.e * fluid.layers.ones_like(loss) cosh ( fluid.layers.elementwise_pow(e, loss) fluid.layers.elementwise_pow(e, 0-loss) ) / 2 log fluid.layers.log(cosh) loss fluid.layers.reduce_mean(log) return loss
logcosh_program fluid.Program() with fluid.program_guard(logcosh_program): pred fluid.data(‘pred’, shape[3,1], dtype‘float32’) gt fluid.data(‘gt’, shape[3,1], dtype‘float32’) loss logcosh_loss(pred, gt)
pred_val np.array([[4], [2], [1]], dtype‘float32’) gt_val np.array([[1], [2], [3]], dtype‘float32’)
loss_value exe.run(logcosh_program, feed{‘pred’: pred_val, ‘gt’: gt_val}, fetch_list [loss]) print(“Log-Cosh:”, loss_value) Log-Cosh: [array([1.2114438], dtypefloat32)] Quantile Loss(分位数损失)
∑ : ( 1 − ) ∣ − ∣ ∑ : ∣ − ∣ QuantileLoss∑ i:p i y i (1−γ)∣y i −p i ∣∑ i:p i y i
γ∣y i −p i ∣
在一些场景下(比如商业决策)用户可能会希望了解预测中的不确定性并基于此进行决策。这种情况下希望算法给出一个预测区间而不是单一的一个值。 此外前面的 Loss 关注的都是给出单一值的点预测这种预测的假设是输入数据符合一个目标函数 ( ) f(x) 加上一个方差恒定的独立变量残差。 如果训练数据不满足这种性质那么线性回归模型就不成立预测的效果不会好。即便对于具有变化方差或非正态分布的残差基于分位数损失的回归也能给出合理的预测区间。
分位值 gamma 的选择取决于我们对高估和低估的重视程度。 从公式形式上 γ 是低估部分的斜率因此 γ 越大对低估的惩罚越大区间会偏高。
经常会看到的拟合 ( ) sin(x)
In [28] def quantile_loss(pred, label, gamma): dist fluid.layers.abs(pred - label) cond fluid.layers.greater_than(pred, label) ie fluid.layers.IfElse(cond) with ie.true_block(): loss ie.input(dist) loss (1 - gamma) * loss ie.output(loss) with ie.false_block(): loss ie.input(dist) loss gamma * loss ie.output(loss) loss ie()[0] # 返回的是一个list loss fluid.layers.reduce_mean(loss) return loss
quantile_program fluid.Program() with fluid.program_guard(quantile_program): pred fluid.data(‘pred’, shape[4,1], dtype‘float32’) gt fluid.data(‘gt’, shape[4,1], dtype‘float32’) loss quantile_loss(pred, gt, 0.5)
pred_val np.array([[4], [2], [1], [3]], dtype‘float32’) gt_val np.array([[1], [2], [3], [4]], dtype‘float32’)
loss_value exe.run(quantile_program, feed{‘pred’: pred_val, ‘gt’: gt_val}, fetch_list [loss]) print(“quantile loss:”, loss_value) quantile loss: [array([0.75], dtypefloat32)] 最后是一张回归Loss的全家福
在这里查看更清楚
分类 Loss 先说说为什么前面我们有了回归的 Loss 还需要特别分出来一类用来分类的 Loss性质上分类 Loss 和回归 Loss 有什么不同。首先分类问题和回归问题最明显的区别是分类问题输出的是一些概率范围是01。我们一般在网络的输出层用 Sigmoid 函数 1 1 − 1e −x
1 实现这个限制。为了说明方便下文将网络最后一层进入启动函数 Sigmoid 之前的值称为 O将经过 Sigmoid 之后的概率称为 P。下面是 Sigmoid 的函数图像
可以看出这个函数的函数值在输入比较大和比较小的时候都极其接近1函数值在4的时候已经是0.982而且很平导数很小。我们可以设想训练中的一个情况使用MSE Loss而且网络最后一层的 O 比较大初始化如果做的不好很可能第一个batch就是这样。这种情况对应Sigmoid图像中X轴右侧的一个点我们来分析此时 Loss 相对 O 的梯度。在这个位置 Sigmoid 很平所以就算 O 有很大的变化对应的 P 变化也很小反映到 Loss 上变化也很小。因此当 O 较大或较小的时候 Loss 的梯度都很小会导致训练缓慢。相比之下分类 Loss 在输出接近0或1的时候极其敏感一点很小的变化都会给 Loss 带来很大的变化因此训练更快。
额外要说一下分类问题里面有二分类比如猫狗二分类也有分成多类比如ImageNet的情况虽然二分类可以看成一种分成两类的多分类情况但是因为用的比较多而且好理解所以我们这里基本以二分类为例介绍。后期会逐步完善分成多类Loss的实现。
Cross entropy(交叉熵Log Loss)
− 1 ∑
1 [ ( ) ( 1 − ) ( 1 − ) ] BinaryCrossEntropy− N 1 ∑ i1 N [y i log(p i )(1−y i )log(1−p i )] − 1 ∑
1 ∑
1 ( ) CategoricalCrossEntropy− N 1 ∑ i1 N ∑ j1 M y ij log(p ij )
分类问题中最常用的是交叉熵Loss。这个Loss来自香农的信息论原理介绍就略过了但是通过图像可以十分直观的看出来为什么这种 Log 的形式适合做分类的 Loss 。
上升的曲线对应标签
0 y0 的情况下降的曲线对应
1 y1的情况。比如在
0 y0 时如果预测结果 p 也是 0 那么皆大欢喜 Loss 为 0。但是如果 p 不是 0那么 p 越接近 1 Loss 越大而且增长的非常快。
In [29] def bce_loss(pred, label, epsilon1e-05): # 标签都是 0或1但是计算上log(0)不合法所以一般将label和pred卡到[eps, 1-eps]范围内 label fluid.layers.clip(label, epsilon, 1-epsilon) pred fluid.layers.clip(pred, epsilon, 1-epsilon) # 防止出现log(0)
loss -1 * (label * fluid.layers.log(pred) (1 - label) * fluid.layers.log(1 - pred))
loss fluid.layers.reduce_mean(loss)
return lossbce_program fluid.Program() with fluid.program_guard(bce_program): pred fluid.data(‘pred’, shape[3,1], dtype‘float32’) gt fluid.data(‘gt’, shape[3,1], dtype‘float32’) loss bce_loss(pred, gt)
pred_val np.array([[0.9], [0.1], [1]], dtype‘float32’) gt_val np.array([[1], [0], [1]], dtype‘float32’)
loss_value exe.run(bce_program, feed{‘pred’: pred_val, ‘gt’: gt_val}, fetch_list [loss]) print(“BCE Loss:”, loss_value) BCE Loss: [array([0.07029679], dtypefloat32)] Weighed Cross Entropy和Balanced Cross Entropy ℎ
− 1 ∑
1 ( ) ( 1 − ) ( 1 − ) WeighedCrossEntropy− N 1 ∑ i1 N wy i log(p i )(1−y i )log(1−p i ) − 1 ∑
1 ( 1 − ) ( 1 − ) ( 1 − ) ( ) BalancedCrossEntropy− N 1 ∑ i1 N βy i log(1−p i )(1−β)(1−y i )log(p i )
这两个 Loss 都是在BCE的基础上给
1 y1 和
0 y0 赋了不同的权重。这个权重主要解决类别不均衡的问题。比如一个猫狗二分类数据集里面有 80 张猫和 20 张狗。就算算法根本不看输入的是什么而只是全都分类成猫在训练集上也能取得 80% 的准确率。这显然不是我们想要的。WCE和BCE通过给不同的类别的数据产生的 Loss 赋予不同的权重客服标签不均衡。比如 WCE 给
1 y1 的类别一个权重 w,
0 y0 的类别相当于给了权重 1 1。如果 w1 这就是标准交叉熵但是比如现在
1 y1 的类别占数据集中的1/3
0 y0 的类别占数据集中的2/3。这种情况下 w 给2表示可以理解为分错了一个
1 y1 的情况相于分错了两个这就平衡了两个类别数量不均衡的情况。Balanced Cross Entropy也类似只是这个函数分别给了
0 y0 和
1 y1 1 − 1−β 和 β的权重可以认为这个beta设为
0 y0 的类别在数据集中的比例正好能平衡两个类别的不均衡现象。
In [30] def wce_loss(pred, label, w1, epsilon1e-05): # w 是给到 y1 类别的权重越大越重视 label fluid.layers.clip(label, epsilon, 1-epsilon) pred fluid.layers.clip(pred, epsilon, 1-epsilon)
loss -1 * (w * label * fluid.layers.log(pred) (1 - label) * fluid.layers.log(1 - pred))
loss fluid.layers.reduce_mean(loss)
return losswce_program fluid.Program() with fluid.program_guard(wce_program): pred fluid.data(‘pred’, shape[3,1], dtype‘float32’) gt fluid.data(‘gt’, shape[3,1], dtype‘float32’) loss wce_loss(pred, gt)
pred_val np.array([[0.9], [0.1], [1]], dtype‘float32’) gt_val np.array([[1], [0], [1]], dtype‘float32’)
loss_value exe.run(wce_program, feed{‘pred’: pred_val, ‘gt’: gt_val}, fetch_list [loss]) print(“WCE Loss:”, loss_value) WCE Loss: [array([0.07029679], dtypefloat32)] In [31] def balanced_ce_loss(pred, label, beta0.5, epsilon1e-05): # beta 是给到 y1 类别的权重越大越重视范围在(0-1) label fluid.layers.clip(label, epsilon, 1-epsilon) pred fluid.layers.clip(pred, epsilon, 1-epsilon)
loss -1 * (beta * label * fluid.layers.log(pred) (1-beta) * (1 - label) * fluid.layers.log(1 - pred))
loss fluid.layers.reduce_mean(loss)
return lossbalanced_ce_program fluid.Program() with fluid.program_guard(balanced_ce_program): pred fluid.data(‘pred’, shape[3,1], dtype‘float32’) gt fluid.data(‘gt’, shape[3,1], dtype‘float32’) loss balanced_ce_loss(pred, gt)
pred_val np.array([[0.9], [0.1], [1]], dtype‘float32’) gt_val np.array([[1], [0], [1]], dtype‘float32’)
loss_value exe.run(balanced_ce_program, feed{‘pred’: pred_val, ‘gt’: gt_val}, fetch_list [loss]) print(“Balanced Cross Entropy:”, loss_value) Balanced Cross Entropy: [array([0.03514839], dtypefloat32)] Focal Loss
− 1 ∑
1 − ( ( 1 − ) ( ) ) ( 1 − ) ( 1 − ( 1 − ) ) FocalLoss− N 1 ∑ i1 N −(α(1−p i ) γ y i log(p i ))(1−α)p i γ (1−y i log(1−p i ))
Focal Loss 是 Log Loss 的进一步改进。从上面的公式可以看出它在 Balanced Cross Entropy 基础上在
0 y0 时乘上了一个预测值的 γ 次方
1 y1 时乘上了一个 (1-预测值) 的 γ 次方。这项的意思是让算法更加关注那些不确定的情况忽略很确定的情况。比如如果
0 y0 说明我们希望
0 p0 如果此时 p 已经接近 0 了那么 p gamma 就会很接近0这样这项的 Loss 就会很小反之会很大。因此通过这一项Focal Loss实现了让网络关注更难的case的功能。
In [32] def focal_loss(pred, label, alpha0.25,gamma2,epsilon1e-6): ‘’’ alpha 越大越关注y1的情况 gamma 越大越关注不确定的情况 ‘’’ pred fluid.layers.clip(pred,epsilon,1-epsilon) label fluid.layers.clip(label,epsilon,1-epsilon) loss -1 * (alpha * fluid.layers.pow((1 - pred), gamma) * label * fluid.layers.log(pred) (1 - alpha) * fluid.layers.pow(pred, gamma ) * (1 - label) * fluid.layers.log(1 - pred)) loss fluid.layers.reduce_mean(loss) return loss
focal_program fluid.Program() with fluid.program_guard(focal_program): pred fluid.data(‘pred’, shape[3,1], dtype‘float32’) gt fluid.data(‘gt’, shape[3,1], dtype‘float32’) loss focal_loss(pred, gt)
pred_val np.array([[0.9], [0.1], [1]], dtype‘float32’) gt_val np.array([[1], [0], [1]], dtype‘float32’)
loss_value exe.run(focal_program, feed{‘pred’: pred_val, ‘gt’: gt_val}, fetch_list [loss]) print(“Focal Loss:”, loss_value) Focal Loss: [array([0.00035533], dtypefloat32)] Hinge Loss
1 ∑
1 ( 0 , 1 − ) HingeLoss N 1 ∑ i1 N max(0,1−y i p i )
Hinge Loss 主要用在支持向量机中它的标签和之前的0/1不同正例的标签是1负例的标签是-1。Hinge Loss的图像如下
可以看出它不仅惩罚错误的预测而且惩罚不自信的正确预测。和前面的交叉熵相比Hinge Loss形式上更简单运算更快而且因为一些情况下Loss是0不需要进行反向传递因此训练速度较快。如果不是很关注正确性但是需要作出实时决策Hinge是很合适的。
In [33] def hinge_loss(pred, label): ‘’’ alpha 越大越关注y1的情况 gamma 越大越关注不确定的情况 ‘’’ zeros fluid.layers.zeros_like(pred) loss fluid.layers.elementwise_max(zeros, 1 - pred * label) loss fluid.layers.reduce_sum(loss) return loss
hinge_program fluid.Program() with fluid.program_guard(hinge_program): pred fluid.data(‘pred’, shape[3,1], dtype‘float32’) gt fluid.data(‘gt’, shape[3,1], dtype‘float32’) loss focal_loss(pred, gt)
pred_val np.array([[0.9], [-0.1], [1]], dtype‘float32’) gt_val np.array([[1], [-1], [1]], dtype‘float32’)
loss_value exe.run(hinge_program, feed{‘pred’: pred_val, ‘gt’: gt_val}, fetch_list [loss]) print(“Hinge Loss:”,loss_value) Hinge Loss: [array([9.292055e-05], dtypefloat32)]