【问题标题】:Implementing BCEWithLogitsLoss from pytorch in keras在 keras 中从 pytorch 实现 BCEWithLogitsLoss
【发布时间】:2020-04-27 09:44:54
【问题描述】:

我有一个模型,我正在尝试在一个类别不平衡的数据集上进行训练。该问题是一个多标签分类问题(每个样本有 1 个或多个标签)。我还为我为我的数据集计算的每个类设置了权重。我确实看到了这个实现: BCEWithLogitsLoss in Keras

这是pytorch中的等价物:

criterion = nn.BCEWithLogitsLoss(pos_weight=trainset.labels_weights.to(DEVICE))

所以我尝试将其传递给我的模型:

def get_weighted_loss(weights):
    def weighted_loss(y_true, y_pred):
        xent = tf.compat.v2.losses.BinaryCrossentropy(from_logits=False, reduction=tf.compat.v2.keras.losses.Reduction.NONE)
        weighted_loss = tf.reduce_mean(xent(y_true, y_pred) * weights)
    return weighted_loss

然后编译模型:

model.compile(optimizer=optim, loss=get_weighted_loss(list(train_generatorLat.labels_weights.values())), metrics=[full_multi_label_metric])

其中list(train_generatorLat.labels_weights.values()) 是从 1.0 到 5.0 的每个类的浮点数(权重)列表,其中示例最多的标签的权重为 1,示例最少的标签的权重为 5.0

但我收到以下错误:

AttributeError                            Traceback (most recent call last)
<ipython-input-108-98496152ec7d> in <module>
----> 1 model.compile(optimizer=optim, loss=get_weighted_loss(list(train_generatorLat.labels_weights.values())), metrics=[full_multi_label_metric])
      2 model.summary()

/gpfs/ysm/project/kl533/conda_envs/dlnn/lib/python3.6/site-packages/keras/engine/training.py in compile(self, optimizer, loss, metrics, loss_weights, sample_weight_mode, weighted_metrics, target_tensors, **kwargs)
    340                 with K.name_scope(self.output_names[i] + '_loss'):
    341                     output_loss = weighted_loss(y_true, y_pred,
--> 342                                                 sample_weight, mask)
    343                 if len(self.outputs) > 1:
    344                     self.metrics_tensors.append(output_loss)

/gpfs/ysm/project/kl533/conda_envs/dlnn/lib/python3.6/site-packages/keras/engine/training_utils.py in weighted(y_true, y_pred, weights, mask)
    415         if weights is not None:
    416             # reduce score_array to same ndim as weight array
--> 417             ndim = K.ndim(score_array)
    418             weight_ndim = K.ndim(weights)
    419             score_array = K.mean(score_array,

/gpfs/ysm/project/kl533/conda_envs/dlnn/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py in ndim(x)
    617     ```
    618     """
--> 619     dims = x.get_shape()._dims
    620     if dims is not None:
    621         return len(dims)

AttributeError: 'NoneType' object has no attribute 'get_shape'

对我将如何做这件事有任何想法吗?

【问题讨论】:

    标签: python keras loss-function multilabel-classification


    【解决方案1】:

    最后一层应该有一个'sigmoid' 激活。

    compile,你的损失应该是loss='binary_crossentropy'

    fitfit_generator 中,您将通过class_weight=dictionary_of_weights

    dictionary_of_weights 类似于:

    dictionary_of_weights = { 0: weight0,
                              1: weight1, 
                              ....
                              n: weightN }
    

    n+1 类的数量。

    【讨论】:

    • 好的,这样就可以处理类不平衡了?模型将如何减少损失?
    • 是的,这就是你传递class_weight的原因。
    • 我明白了,这就是我所怀疑的,并按原样实现了它,但它似乎只是过度适应了训练集。实际上,我正在尝试复制一项关于胸部 X 光片的研究,他们还计算了班级权重,但由于某种原因,将权重从 [1,5] 中剪掉了。他们将权重作为 pytorch 中的位置 BCEWithLogitsLoss 应用,但我不确定这会导致差异吗?
    猜你喜欢
    • 2019-09-05
    • 1970-01-01
    • 1970-01-01
    • 2019-11-23
    • 2022-07-29
    • 1970-01-01
    • 2021-03-17
    • 1970-01-01
    • 2021-07-21
    相关资源
    最近更新 更多