Python 1-a权重在分类焦点丢失中的应用
我试图在keras/tensorflow中使用多个类别的焦点损失,我想这会导致使用分类焦点损失。我已经找到了一些实现和/或 据我所知,焦损中的参数Python 1-a权重在分类焦点丢失中的应用,python,tensorflow,keras,Python,Tensorflow,Keras,我试图在keras/tensorflow中使用多个类别的焦点损失,我想这会导致使用分类焦点损失。我已经找到了一些实现和/或 据我所知,焦损中的参数a主要用于二进制焦损情况,其中存在两类,一类得到a作为权重,另一类得到1-a作为权重。在分类焦点丢失的情况下,我发现所有实现在每个类丢失之前只使用权重a,如: # Calculate weight that consists of modulating factor and weighting factor weight = alph
a
主要用于二进制焦损情况,其中存在两类,一类得到a
作为权重,另一类得到1-a
作为权重。在分类焦点丢失的情况下,我发现所有实现在每个类丢失之前只使用权重a
,如:
# Calculate weight that consists of modulating factor and weighting factor
weight = alpha * y_true * K.pow((1-y_pred), gamma)
# Calculate focal loss
loss = weight * cross_entropy
或
所以,我的问题是,为什么这样的权重因素会在训练过程中产生任何影响?当然,损失通常用于计算每次迭代后增加的权重(乘以当然是学习率)。但这只是意味着每个类在损失部分之前都得到相同的系数,所以没什么大不了的。这意味着我可以调整学习速度,并有同样的效果?我错过了什么?
参数a
的确切用途是什么
我还发现,在这个实现中,他们似乎也使用(1-a)
作为否定示例,尽管他们将值传递给keras.backend.binary\u crossentropy
,我想这会使它更加复杂
你知道哪一个是正确的实现吗?我和你一样困惑于为什么它们会将损失乘以常数。您提供的代码将
alpha
作为一个参数,默认值设置为0.25
,但是,当您调用函数时,您应该提供一个张量(与y_pred
/y_true
形状相同),并为该参数设置权重?这是我能想到的唯一解释
但是,我确实认为您可以在代码中完全忽略这些权重,而是将权重提供给tf.fit()
的class\u weight
参数,然后这将为您进行权重计算。你能告诉我这是否有效吗;博士
它们是一样的。所以,只需使用更简单的一个
较长版本:
(玩具示例中的计算已在numpy中执行,我认为同样的功能也适用于tensorflow)
在对这个问题做了一些研究之后,我得出以下结论:
- 对于
系数,使用固定方法的方法确实适用于(一种)焦损,因为它们将置信度得分和功率与伽马进行倒数,但这并不完全是原始论文中提到的焦损a
- 第二种方法似乎比原始方法更精确,但本质上是一样的(至少在那些实现中是这样)
gamma = 2
alpha2 = 0.25
preds = np.array(
[[0.3, 0.2, 0.5], [0.1, 0.4, 0.4], [0.1, 0.8, 0.1],
[0.7, 0.2, 0.1], [0.75, 0.15, 0.1], [0.9, 0.05, 0.05],
[0.72, 0.18, 0.1], [0.8, 0.1, 0.1]])
gt = np.array([[1, 0, 0], [0, 1, 0], [0, 1, 0],
[1, 0, 0], [1, 0, 0], [1, 0, 0],
[1, 0, 0], [1, 0, 0]]).astype(float)
两个重点损失是:
focal_log_loss_v1 = -np.sum(alpha2 * gt * np.power((1 - preds), gamma) * np.log(preds), axis=-1)
alpha_factor = np.ones_like(gt) * alpha2
alpha_factor = np.where(gt == 1, alpha_factor, 1 - alpha_factor)
focal_weight2 = np.where(gt == 1, 1 - preds, preds)
focal_weight2 = alpha_factor * np.power(focal_weight2, gamma)
focal_log_loss_v2 = -np.sum(focal_weight2 * gt * np.log(preds), axis=-1)
结果表明:
focal_log_loss_v1
阵列([0.14748667,0.08246617,0.00223144,0.00802519,0.00449503,
0.0002634,0.00643868,0.00223144])
阵列([0.14748667,0.08246617,0.00223144,0.00802519,0.00449503,
0.0002634,0.00643868,0.00223144])
这两种方法是等价的(!)。这是出乎意料的(至少在我这边)。无论如何,下面的命令对此进行了解释:
gt * np.log(preds)
数组([[-1.2039728,-0.,-0.],[-0.,-0.91629073,-0.],
[-0.,-0.22314355,-0.],
[-0.35667494,-0.,-0.],
[-0.28768207,-0.,-0.],
[-0.10536052,-0.,-0.],
[-0.32850407,-0.,-0.],
[-0.22314355,-0.,-0.]] 这基本上消除了所有非基础真相样本的所有贡献(意味着所有不属于基础真相样本的置信度得分)。因此,即使
focal_weight2
包含非gt样本的非零值,它们也会在之后被消除
focal_weight2
数组([[0.1225,0.03,0.1875],[0.0075,0.09,0.12],
[0.0075,0.01,0.0075],
[0.0225,0.03,0.0075],
[0.015625,0.016875,0.0075],
[0.0025,0.001875,0.001875],
[0.0196,0.0243,0.0075],
[0.01,0.0075,0.0075]] 这就是此代码产生相同损失的原因:
alpha_factor = np.ones_like(gt) * alpha2
alpha_factor = np.where(gt == 1, alpha_factor, 0)
focal_weight2 = np.where(gt == 1, 1 - preds, 0)
focal_weight2 = alpha_factor * np.power(focal_weight2, gamma)
focal_log_loss_v3 = -np.sum(focal_weight2 * gt * np.log(preds), axis=-1)
focal_log_loss_v3
阵列([0.14748667,0.08246617,0.00223144,0.00802519,0.00449503,
0.0002634,0.00643868,0.00223144])
不过,我不确定背景和前景样本之间是否应该有任何区别(这是另一个主题问题)。您解决了吗?如果没有,你能在这个问题上悬赏吗?
focal_weight2
alpha_factor = np.ones_like(gt) * alpha2
alpha_factor = np.where(gt == 1, alpha_factor, 0)
focal_weight2 = np.where(gt == 1, 1 - preds, 0)
focal_weight2 = alpha_factor * np.power(focal_weight2, gamma)
focal_log_loss_v3 = -np.sum(focal_weight2 * gt * np.log(preds), axis=-1)
focal_log_loss_v3