Реализация BCEWithLogitsLoss из pytorch в керасе - PullRequest
0 голосов
/ 09 января 2020

У меня есть модель, которую я пытаюсь обучить на наборе данных, который имеет дисбаланс классов. Проблема заключается в многослойной классификации (каждый образец имеет 1 или более меток). У меня также есть весовые коэффициенты для каждого класса, которые я рассчитал для своего набора данных. Я видел эту реализацию: BCEWithLogitsLoss в 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'

Любые идеи о том, как бы я go сделал это?

1 Ответ

0 голосов
/ 09 января 2020

Последний слой должен иметь 'sigmoid' активацию.

В compile ваша потеря должна быть loss='binary_crossentropy'.

В fit или fit_generator вы пройдете class_weight=dictionary_of_weights.

Где dictionary_of_weights - это что-то вроде:

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

, являющееся n+1 числом классов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...