Как работает двоичная кросс-энтропийная потеря на автоэнкодерах? - PullRequest
0 голосов
/ 21 сентября 2018

Я написал ванильный автоэнкодер, используя только слой 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) Iне понимаю, как двоичная кроссентропия работает с этими значениями.Двоичная кросс-энтропия для двух значений выхода, верно?

1 Ответ

0 голосов
/ 21 сентября 2018

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

Что касается функции потерь, она снова возвращается к значениям входных данных.Если входные данные только между нулями и единицами (а не значения между ними) , то binary_crossentropy приемлемо в качестве функции потерь.В противном случае вам нужно использовать другие функции потерь, такие как 'mse' (т.е. средняя квадратическая ошибка) или 'mae' (т.е. средняя абсолютная ошибка).Обратите внимание, что в случае входных значений в диапазоне [0,1] вы можете использовать binary_crossentropy, как это обычно используется (например, Учебное пособие по автоэнкодеру Keras и в этой статье ).Однако не ожидайте, что значение потери станет равным нулю, поскольку binary_crossentropy не возвращает ноль, когда и прогноз, и метка не равны нулю или единице (независимо от того, равны они или нет). Здесь - это видео от Уго Ларошеля , где он объясняет функции потерь, используемые в автоэнкодерах (часть об использовании 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 является естественной логарифмической функцией для простоты вычислений):

bce_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, т.е. когда истинная метка равна предсказанной метке, и это именно то, что мы ищем.

...