Почему бинарная кроссэнтропия более точна, чем категориальная кроссэнтропия для многоклассовой классификации в Керасе?



Я учусь создания сверточных нейронных сетей с использованием выбранной позиции. Я пытаюсь получить высокую точность для набора данных MNIST.



По-видимому, categorical_crossentropy относится к более чем 2 классам, а binary_crossentropy - к 2 классам. Поскольку существует 10 цифр, я должен использовать categorical_crossentropy. Однако после обучения и тестирования десятков моделей binary_crossentropy последовательно значительно превосходит categorical_crossentropy.



На Kaggle я получил точность 99+%, используя binary_crossentropy и 10 эпох. Между тем, я не могу подняться выше 97%, используя categorical_crossentropy, даже использование 30 эпох (что не так уж много, но у меня нет графического процессора, поэтому обучение занимает целую вечность).



Вот как сейчас выглядит моя модель:





model = Sequential()
model.add(Convolution2D(100, 5, 5, border_mode='valid', input_shape=(28, 28, 1), init='glorot_uniform', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(100, 3, 3, init='glorot_uniform', activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.3))
model.add(Flatten())
model.add(Dense(100, init='glorot_uniform', activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(100, init='glorot_uniform', activation='relu'))
model.add(Dropout(0.3))
model.add(Dense(10, init='glorot_uniform', activation='softmax'))
model.compile(loss='binary_crossentropy', optimizer='adamax', metrics=['accuracy'])
784   2  

2 ответов:

Короткий ответ: это не.

Чтобы увидеть это, просто попробуйте вычислить точность "вручную", и вы увидите, что она отличается от той, о которой сообщил Керас с помощью метода model.evaluate:
# Keras reported accuracy:
score = model.evaluate(x_test, y_test, verbose=0) 
score[1]
# 0.99794011611938471

# Actual accuracy calculated manually:
import numpy as np
y_pred = model.predict(x_test)
acc = sum([np.argmax(y_test[i])==np.argmax(y_pred[i]) for i in range(10000)])/10000
acc
# 0.98999999999999999

Причина, по которой этокажется так, - это довольно тонкий вопрос о том, как Керас на самом делеугадывает , какую точность использовать, в зависимости от выбранной вами функции потерь, когда вы включаете просто metrics=['accuracy'] в компиляцию модели.

Если вы проверите исходный код , Keras определяет не одну метрику точности, а несколько различных, среди них binary_accuracy и categorical_accuracy. Что происходит под капотом, так это то, что, поскольку вы выбрали двоичную перекрестную энтропию в качестве функции потерь и не указали конкретную метрику точности, Керас (ошибочно...) делает вывод, что вы заинтересованы в binary_accuracy, и это то, что он возвращает.

Чтобы избежать этого, то есть использовать действительно двоичную перекрестную энтропию в качестве функции потерь (ничего плохого с этим, в принципе), все еще получая категориальную точность, требуемую рассматриваемой проблемой (т. е. классификацией MNIST), вы должны явно попросить categorical_accuracy в компиляции модели следующим образом:

from keras.metrics import categorical_accuracy
model.compile(loss='binary_crossentropy', optimizer='adamax', metrics=[categorical_accuracy])

И после обучения, оценки и прогнозирования набора тестов, как я показал выше, эти две метрики теперь одинаковы, как и должны быть:

sum([np.argmax(y_test[i])==np.argmax(y_pred[i]) for i in range(10000)])/10000 == score[1]
# True

(HT к этому великому ответу на аналогичную проблему, которая помогла мне понять вопрос...)

UPDATE : После моего сообщения я обнаружил, что эта проблема уже была определена в этом ответе.

Во-первых, binary_crossentropy не существует, когда есть два класса.

"двоичное" имя потому, что оно адаптировано для двоичного вывода, и каждое число softmax нацелено на то, чтобы быть 0 или 1. Здесь он проверяет каждое число выходных данных.

Это не объясняет ваш результат, так как categorical_entropy использует тот факт, что это проблема классификации.

Уверены ли вы, что при чтении ваших данных существует один и только один класс на выборку? Он единственный. объяснение я могу дать.

Comments

    Ничего не найдено.