Как работает двоичная кросс-энтропийная потеря на автоэнкодерах?

Я написал ванильный автоэнкодер, используя только Dense слой. Ниже мой код:

iLayer = Input ((784,))
layer1 = Dense(128, activation='relu' ) (iLayer)
layer2 = Dense(64, activation='relu') (layer1)
layer3 = Dense(28, activation ='relu') (layer2)
layer4 = Dense(64, activation='relu') (layer3)
layer5 = Dense(128, activation='relu' ) (layer4)
layer6 = Dense(784, activation='softmax' ) (layer5)
model = Model (iLayer, layer6)
model.compile(loss='binary_crossentropy', optimizer='adam')

(trainX, trainY), (testX, testY) =  mnist.load_data()
print ("shape of the trainX", trainX.shape)
trainX = trainX.reshape(trainX.shape[0], trainX.shape[1]* trainX.shape[2])
print ("shape of the trainX", trainX.shape)
model.fit (trainX, trainX, epochs=5, batch_size=100)

Вопросы:

1) softmax обеспечивает распределение вероятностей. Понял. Это означает, что у меня будет вектор 784 значений с вероятностью от 0 до 1. Например, [ 0,02, 0,03..... до 784 пунктов], суммирование всех 784 элементов дает 1.

2) Я не понимаю, как двоичная кроссентропия работает с этими значениями. Двоичная кросс-энтропия для двух значений выхода, верно?

1 ответ

В контексте автоэнкодеров ввод и вывод модели одинаков. Таким образом, если входные значения находятся в диапазоне [0,1], то допустимо использовать sigmoid как функция активации последнего слоя. В противном случае вам нужно использовать соответствующую функцию активации для последнего слоя (например, linear который по умолчанию).

Что касается функции потерь, то она снова возвращается к значениям входных данных. Если входные данные находятся только между нулями и единицами (а не значения между ними), то binary_crossentropy приемлемо в качестве функции потерь. В противном случае вам нужно использовать другие функции потери, такие как 'mse' (т.е. среднеквадратическая ошибка) или 'mae' (т.е. средняя абсолютная ошибка). Обратите внимание, что в случае входных значений в диапазоне [0,1] ты можешь использовать binary_crossentropy, как это обычно используется (например, учебник по автоэнкодеру Keras и этот документ). Однако не ожидайте, что величина потерь станет нулевой, так как binary_crossentropy не возвращает ноль, когда и прогноз, и метка не равны нулю или единице (независимо от того, равны они или нет). Вот видео от Hugo Larochelle, где он объясняет функции потерь, используемые в автоэнкодерах (часть об использовании binary_crossentropy с входами в диапазоне [0,1] начинается в 5:30)

Конкретно, в вашем примере вы используете набор данных MNIST. Поэтому по умолчанию значения MNIST являются целыми числами в диапазоне [0, 255]. Обычно вам нужно сначала нормализовать их:

trainX = trainX.astype('float32')
trainX /= 255.

Теперь значения будут в диапазоне [0,1]. Так sigmoid может быть использован в качестве функции активации и любой из binary_crossentropy или же mse как функция потерь.


Зачем binary_crossentropy можно использовать, даже когда истинные значения меток (т. е. основание) находятся в диапазоне [0,1]?

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

bce_loss = -y*log(p) - (1-y)*log(1-p)

где y является истинным ярлыком и p это прогнозируемое значение Давайте рассмотрим y как исправить и посмотреть, какое значение p минимизирует эту функцию: нам нужно взять производную по p (Я предположил, log естественная логарифмическая функция для простоты расчетов):

bcd_loss_derivative = -y*(1/p) - (1-y)*(-1/(1-p)) = 0 =>
                      -y/p + (1-y)/(1-p) = 0 =>
                      -y*(1-p) + (1-y)*p = 0 =>
                      -y + y*p + p - y*p = 0 =>
                       p - y = 0 => y = p

Как видите, двоичная кросс-энтропия имеет минимальное значение, когда y=p т.е. когда истинная метка равна предсказанной метке, и это именно то, что мы ищем.

Другие вопросы по тегам