Вопрос или проблема
Для той же задачи бинарной классификации изображений, если на последнем слое я использую 1 узел
с Sigmoid
активацией и binary_crossentropy
функцией потерь, процесс обучения проходит довольно гладко (92% точности после 3 эпох на валидационных данных).
Однако, если я изменю последний слой на 2 узла
и использую Softmax
активацию с sparse_categorical_crossentropy
функцией потерь, то модель, похоже, вообще не обучается и застревает на 55% точности (соотношение отрицательного класса).
Эта разница в производительности нормальна? Я думал, что для задачи бинарной классификации Sigmoid с Binary Crossentropy
и Softmax с Sparse Categorical Crossentropy
должны выдавать похожие, если не идентичные результаты? Или я что-то сделал не так?
Примечание: Я использую оптимизатор Adam и есть один столбец меток, содержащий 0 и 1.
Редактировать: Код для 2 случаев
Случай 1: Sigmoid с binary_crossentropy
def addTopModelMobilNetV1(bottom_model, num_classes):
top_model = bottom_model.output
top_model = layers.GlobalAveragePooling2D()(top_model)
top_model = layers.Dense(1024, activation='relu')(top_model)
top_model = layers.Dense(1024, activation='relu')(top_model)
top_model = layers.Dense(512, activation='relu')(top_model)
top_model = layers.Dense(1, activation='sigmoid')(top_model)
return top_model
fc_head = addTopModelMobilNetV1(mobilnet_model, num_classes)
model = Model(inputs=mobilnet_model.input, outputs=fc_head)
# print(model.summary())
earlystopping_cb = callbacks.EarlyStopping(patience=3, restore_best_weights=True)
model.compile(loss="binary_crossentropy", optimizer=optimizers.Adam(), metrics=['accuracy'])
history = model.fit_generator(generator=train_generator,
steps_per_epoch=train_df.shape[0]//TRAIN_BATCH_SIZE,
validation_data = val_generator,
epochs = 10,
callbacks = [earlystopping_cb]
)
Случай 2: Softmax с sparse_categorical_crossentropy
def addTopModelMobilNetV1(bottom_model, num_classes):
top_model = bottom_model.output
top_model = layers.GlobalAveragePooling2D()(top_model)
top_model = layers.Dense(1024, activation='relu')(top_model)
top_model = layers.Dense(1024, activation='relu')(top_model)
top_model = layers.Dense(512, activation='relu')(top_model)
top_model = layers.Dense(2, activation='softmax')(top_model)
return top_model
fc_head = addTopModelMobilNetV1(mobilnet_model, num_classes)
model = Model(inputs=mobilnet_model.input, outputs=fc_head)
earlystopping_cb = callbacks.EarlyStopping(patience=3, restore_best_weights=True)
model.compile(loss="sparse_categorical_crossentropy", optimizer=optimizers.Adam(), metrics=['accuracy'])
history = model.fit_generator(generator=train_generator,
steps_per_epoch=train_df.shape[0]//TRAIN_BATCH_SIZE,
validation_data = val_generator,
epochs = 10,
callbacks = [earlystopping_cb]
)
Это зависит от того, являются ли выходные классы взаимно исключающими. Например, в задаче многоклассовой классификации мы используем несколько сигмоидных функций для каждого выхода, потому что это считается несколькими задачами бинарной классификации.
Но если выходные классы являются взаимно исключающими, в этом случае лучше использовать softmax, потому что он даст вероятность для каждого класса, и сумма всех вероятностей = 1. Например, если изображение собаки, выход будет 90% собака и 10% кошка.
В бинарной классификации единственный выход не является взаимно исключающим, мы определенно используем сигмоидную функцию. Потому что нет других классов, чтобы применить взаимную исключительность.
Вы можете найти краткое резюме здесь: https://stackoverflow.com/a/55936594/16310106
Ответ или решение
Вопрос о разнице в производительности между функциями активации Sigmoid и Softmax в контексте задачи бинарной классификации на изображениях является актуальным и интересным.
Основные различия между Sigmoid и Softmax
-
Архитектура выходного слоя:
- Функция активации Sigmoid используется, когда у вас есть один выходной нейрон для бинарной классификации, который выдает значение от 0 до 1, интерпретируемое как вероятность принадлежности к положительному классу. В этом случае применяется функция потерь binary_crossentropy.
- Функция активации Softmax обычно применяется в многоклассовых задачах, где количество нейронов в выходном слое соответствует количеству классов, и выход каждого нейрона интерпретируется как вероятность принадлежности к каждому из классов. При этом используется функция потерь sparse_categorical_crossentropy.
-
Муниципальная исключительность классов:
- В случае с Sigmoid, каждая метка классов является независимой, так что выходной нейрон не понимает отношения между классами.
- В случае с Softmax, классы считаются взаимно исключающими, и выходной слой рассчитывает вероятности таким образом, что их сумма равна 1 (например, если у вас два класса, один нейрон может выдавать 0.9 для одного класса и 0.1 для другого).
Почему разные метрики производительности?
Ваши результаты показывают, что использование Softmax с двумя выходными нейронными слоями дает плохие результаты (55% точности), наиболее вероятно, по следующим причинам:
-
Неправильная интерпретация меток: При использовании Softmax ваши метки должны быть закодированы как целочисленные категории (0 и 1 для двух классов). Если вы используете 0 и 1 как метки и сохраняете их в виде целых чисел (как это делается для sparse_categorical_crossentropy), это не будет работать должным образом, если входные классы не ассоциированы с нейронами правильно. Обратите внимание, что ваши метки должны соответствовать ожиданиям функции потерь.
-
Неправильное количество нейронов: При замене одной сигмоидной выходной единицы на два нейрона с Softmax необходимо убедиться, что количество выходных узлов и структура ваших данных соответствуют друг другу. Например, ваша модель должна правильно обрабатывать классы 0 и 1 как два отдельных класса.
-
Проблемы с обучением: Возможно, сеть при использовании Softmax просто не может схватить нужные зависимости из ваших данных на начальных этапах обучения. Отсутствие прогресса в процессе тренировки (остановка на уровне 55%) указывает на то, что модель не обучается должным образом.
Рекомендации
- Если у вас бинарная классификация, лучше сохранять архитектуру с одним нейроном и использовать Sigmoid с binary_crossentropy.
- Если вы решите использовать Softmax, убедитесь, что выходные данные корректно сопоставлены и закодированы.
- Вы можете протестировать, изменив и улучшив параметры модели, такие как количество эпох, размер пакета, или изменяя архитектуру модели.
Таким образом, использование Sigmoid и Softmax в бинарной классификации имеет свои особенности, и понимание этих отличий поможет вам более эффективно настраивать архитектуру вашей модели для достижения лучших результатов.