Как указать model.compile для binary_crossentropy, Activation = sigmoid и Activation = softmax?

Я пытаюсь понять, как сопоставить activation=sigmoid и activation=softmax с правильными model.compile() параметрами потерь. В частности, те, которые связаны с binary_crossentropy.

Я изучил связанные темы и прочитал документы. Также я построил модель и заставил ее работать с sigmoid, но не с softmax. И я не могу заставить его нормально работать с параметрами "from_logits".

В частности, здесь говорится:

Args:
  • from_logits: ожидается ли, что output будет тензором логитов. По умолчанию мы считаем, что output кодирует распределение вероятностей.

Это говорит мне, что если вы используете sigmoid активацию, вам нужно "from_logits=True". А для softmax активации вы хотите "from_logits=False" по умолчанию. Здесь я предполагаю, что sigmoid обеспечивает logits, а softmax обеспечивает распределение вероятностей.

Далее код:

model = Sequential()
model.add(LSTM(units=128,
               input_shape=(n_timesteps, n_features), 
               return_sequences=True))
model.add(Dropout(0.3))
model.add(LSTM(units=64, return_sequences=True))
model.add(Dropout(0.3))
model.add(LSTM(units=32))
model.add(Dropout(0.3))
model.add(Dense(16, activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(1, activation='sigmoid'))

Обратите внимание, что последняя строка использует активацию sigmoid. Потом:

model.compile(optimizer=optimizer,
              loss='binary_crossentropy',  
              metrics=['accuracy'])

Это работает нормально, но работает со значением по умолчанию «from_logits = False», которое предполагает распределение вероятностей.

Если я сделаю следующее, это не удастся:

model.compile(optimizer=optimizer,
              loss='binary_crossentropy',  
              metrics=['accuracy'],
              from_logits=True) # For 'sigmoid' in above Dense

с этим сообщением об ошибке:

ValueError: недопустимый аргумент from_logits передан функции K. с помощью бэкэнда TensorFlow

Если я попробую использовать активацию softmax как:

model.add(Dense(1, activation='softmax'))

Он работает, но я получаю результаты с точностью 50%. С sigmoid я получаю + 99% точности. (Я использую очень надуманный набор данных для отладки своих моделей и ожидаю очень высокой точности. Кроме того, это очень маленький набор данных, и он будет слишком подходящим, но пока это нормально.)

Поэтому я ожидаю, что смогу использовать параметр «from_logits» в функции компиляции. Но он не распознает этот параметр.

Также я хотел бы знать, почему он работает с sigmoid активацией, а не с softmax, и как мне заставить его работать с softmax активацией.

Спасибо,

Джон.


person Jon    schedule 30.04.2019    source источник
comment
Какой у вас keras.__version__, tf.__version__? Документы, которые вы цитируете, предназначены для tf.__version__=='1.13.1'.   -  person Vlad    schedule 01.05.2019


Ответы (1)


Чтобы использовать from_logits в своей функции потерь, вы должны передать его в BinaryCrossentropy, а не при компиляции модели.

Вы должны изменить это:

model.compile(optimizer=optimizer,
              loss='binary_crossentropy',  
              metrics=['accuracy'],
              from_logits=True)

к этому:

model.compile(optimizer=optimizer,
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),  
              metrics=['accuracy'])

Однако, если вы используете softmax или сигмоид в последнем слое сети, вам не нужен from_logits=True. Softmax и сигмовидный вывод нормализованные значения между [0, 1], которые в данном контексте считаются вероятностями.

См. Этот вопрос для получения дополнительной информации: Что означает слово logits в TensorFlow?


Теперь, чтобы исправить проблему с точностью 50% с softmax, измените следующий код:

model.add(Dense(1, activation='softmax'))

к этому:

model.add(Dense(2, activation='softmax'))  # number of units = number of classes

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

person Gabriel Ibagon    schedule 01.05.2019