Керас - классификация по меткам с несколькими весами - PullRequest
1 голос
/ 07 января 2020

Я пытаюсь классифицировать некоторые CXR-изображения, которые имеют несколько меток на образец. Из того, что я понимаю, я должен нанести плотный слой с сигмовидными активациями и использовать бинарную кроссентропию в качестве моей функции потерь. Проблема в том, что существует большой дисбаланс классов (гораздо больше норм, чем ненормальных). Мне любопытно, вот мой модельный софар:

from keras_applications.resnet_v2 import ResNet50V2
from keras.layers import GlobalAveragePooling2D, Dense
from keras import Sequential
ResNet = Sequential()
ResNet.add(ResNet50V2(input_shape=shape, include_top=False, weights=None,backend=keras.backend,
    layers=keras.layers,
    models=keras.models,
    utils=keras.utils))
ResNet.add(GlobalAveragePooling2D(name='avg_pool'))

ResNet.add(Dense(len(label_counts), activation='sigmoid', name='Final_output'))

Как мы можем видеть, я использую сигмоид, чтобы получить вывод, но я немного запутался относительно того, как реализовать веса. Я думаю, что мне нужно использовать пользовательскую функцию потерь, которая использует BCE (use_logits = true). Примерно так:

xent = tf.losses.BinaryCrossEntropy(
    from_logits=True,
    reduction=tf.keras.losses.Reduction.NONE)
loss = tf.reduce_mean(xent(targets, pred) * weights))

Таким образом, он обрабатывает выходные данные как логиты, но в чем я не уверен, так это в активации окончательного вывода. Сохраняю ли я его при активации сигмовидной кишки, или я использую линейную активацию (не активирована)? Я предполагаю, что мы сохраняем сигмовидную кишку, и просто относимся к ней как к git, но я не уверен, так как пиктограммы "torch.nn.BCEWithLogitsLoss" содержат сигмовидный слой

РЕДАКТИРОВАТЬ: Найдено это: https://www.reddit.com/r/tensorflow/comments/dflsgv/binary_cross_entropy_with_from_logits_true/

Согласно: pgaleone

from_logits = True означает, что функция потерь ожидает линейный тензор (выходной уровень вашей сети без какой-либо функции активации, кроме идентификатора), поэтому вы должны удалить сигмовидную оболочку, поскольку сама функция потерь будет применять softmax к выходу вашей сети, а затем вычислять кросс-энтропию

1 Ответ

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

Вы на самом деле не хотели бы использовать from_logits в многослойной классификации.

Из документации [1]:

logits: активация по метке, обычно линейный выход , Эти энергии активации интерпретируются как ненормализованные логарифмические вероятности.

Таким образом, вы правы, говоря, что не хотите использовать функцию активации, когда для нее установлено значение True.

Однако, документация также гласит:

ПРЕДУПРЕЖДЕНИЕ. Эта операция ожидает немасштабированные логиты, так как для эффективности она выполняет softmax для логитов внутри компании. Не вызывайте этот оператор с выводом softmax, поскольку он будет давать неверные результаты

Softmax оптимизирует для одного класса в соответствии с определением. Вот как работает softmax. Поскольку вы выполняете многослойную классификацию, вы должны использовать сигмовидную оболочку, как вы упомянули сами.

Это означает, что если вы хотите использовать сигмовидную оболочку, вы не можете использовать from_logits, поскольку она будет применять softmax после сигмовидной кишки, что обычно не то, что Вы хотите.

Решение состоит в том, чтобы удалить эту строку:

from_logits=True,

[1] https://www.tensorflow.org/api_docs/python/tf/nn/softmax_cross_entropy_with_logits?version=stable

...