Я использую автоэнкодеры для обнаружения аномалий. Итак, я закончил обучение своей модели и теперь хочу рассчитать потери при реконструкции для каждой записи в наборе данных. так что я могу назначать аномалии точкам данных с высокими потерями реконструкции.
Это мой текущий код для расчета потерь при реконструкции. Но это очень медленно. По моей оценке, просмотр набора данных должен занять 5 часов, тогда как обучение одной эпохи происходит примерно за 55 минут. Я чувствую, что преобразование в тензорную операцию является узким местом в коде, но я не могу найти лучшего способа сделать это.
Я пробовал менять размеры пакетов, но это не имеет большого значения. Я должен использовать преобразование в тензорную часть, потому что K.eval выдает ошибку, если я делаю это нормально.
питон
for i in range(0, encoded_dataset.shape[0], batch_size):
y_true = tf.convert_to_tensor(encoded_dataset[i:i+batch_size].values,
np.float32)
y_pred= tf.convert_to_tensor(ae1.predict(encoded_dataset[i:i+batch_size].values),
np.float32)
# Append the batch losses (numpy array) to the list
reconstruction_loss_transaction.append(K.eval(loss_function( y_true, y_pred)))
Я смог тренироваться за 55 минут в эпоху. Поэтому я чувствую, что предсказание не должно занимать 5 часов в эпоху. encoded_dataset — это переменная, которая имеет весь набор данных в основной памяти в виде фрейма данных.
Я использую экземпляр виртуальной машины Azure.
K.eval(loss_function(y_true,y_pred)
— найти потери для каждой строки партии
Таким образом, y_true будет иметь размер (batch_size,2000)
, как и y_pred.
K.eval(loss_function(y_true,y_pred)
даст мне вывод
(batch_size,1)
evaluating binary cross entropy on each row of y _true and y_pred
я внес изменения.
Как получилось, что ae1.predict
принимает те же данные, что и y_true
? Оба принимают в качестве входных данных encoded_dataset[i:i+batch_size].values
. Если вы выполняете прогнозирование, вы передаете входные данные, но похоже, что вы прогнозируете, используя метки. Я предполагаю, что values
каким-то образом содержит как данные, так и метки, что не очевидно из фрагмента кода. В этом случае вы, вероятно, несколько раз перемещаете полные входные данные. Однако не очень понятно.
Я использую модель автоматического кодировщика. Таким образом, в случае с ауроэнкодерами вы пытаетесь реконструировать ввод с помощью нейронной сети. Вот почему y_true использует то же значение, что и y_pred.
Ну, конечно, брейнфарт, извините. Я подозреваю, что ae1.predict
и K.eval(loss_function
ведут себя неожиданным образом. ae1.predict
обычно следует использовать для вывода значения функции потерь, а также y_pred
. Когда вы создаете модель, укажите, что значение потерь является другим выходом (у вас может быть список нескольких выходов), а затем просто вызовите прогнозирование здесь один раз, чтобы получить оба y_pred
значения потерь за один вызов.
О, хорошо. Спасибо, но я хочу потери для каждой строки. Не будет ли потеря, возвращаемая методом прогнозирования, средней потерей для всей партии?
Отличный вопрос. Ответ зависит от того, как реализована функция потерь. Оба способа дают абсолютно достоверные и идентичные результаты в TF под капотом. Вы можете усреднить потери по партии, прежде чем принимать градиент w.r.t. потери или взять градиент w.r.t. вектор потерь. Операция градиента в TF выполнит для вас усреднение потерь, если вы используете последний подход (см. статьи SO о взятии градиента для каждой партии, это на самом деле сложно сделать).
Если keras реализует потерю с помощью reduce_mean
, встроенной в потерю, вы можете просто определить свою собственную потерю. Если вы используете квадратные потери, замените 'mean_squared_error'
на lambda y_true, y_pred: tf.square(y_pred - y_true)
. Это приведет к квадратичной ошибке вместо MSE (нет разницы с градиентом), но посмотрите здесь вариант, включающий среднее значение: stackoverflow.com/questions/41338509. В любом случае это приводит к потере на выборку, если вы не используете tf.reduce_mean
, что является чисто необязательным в потере. Дайте мне знать, если это решит проблему, и я перенесу обсуждение на ответ.
Это в значительной степени решило это. Большое спасибо
Перенесено из комментариев:
Я подозреваю, что ae1.predict
и K.eval(loss_function)
ведут себя неожиданным образом. ae1.predict
обычно следует использовать для вывода значения функции потерь, а также y_pred
. Когда вы создаете модель, укажите, что значение потерь является другим выходом (у вас может быть список нескольких выходов), а затем просто вызовите прогнозирование здесь один раз, чтобы получить оба y_pred
значения потерь за один вызов.
But I want the loss for each row . Won't the loss returned by the predict method be the mean loss for the entire batch?
Ответ зависит от того, как реализована функция потерь. Оба способа дают абсолютно достоверные и идентичные результаты в TF под капотом. Вы можете усреднить потери по партии, прежде чем принимать градиент w.r.t. потери или взять градиент w.r.t. вектор потерь. Операция градиента в ТФ будет выполнять усреднение убытков, если вы используете последний подход (см. Статьи SO о взятии градиента для выборки, это на самом деле сложно сделать).
Если Keras реализует потерю с помощью reduce_mean
, встроенной в потерю, вы можете просто определить свою собственную потерю. Если вы используете квадратные потери, замените 'mean_squared_error' на лямбда y_true, y_pred: tf.square(y_pred - y_true). Это приведет к квадратичной ошибке вместо MSE (без разницы с градиентом), но ищите здесь вариант, включающий среднее значение.
В любом случае это приводит к потере на выборку, если вы не используете tf.reduce_mean
, что является чисто необязательным в потере. Другой вариант — просто вычислить потери отдельно от того, для чего вы оптимизируете, и сделать это выводом модели, что также является абсолютно достоверным.
Я удалил свой предыдущий ответ, можете ли вы отредактировать свой вопрос, чтобы объяснить, что такое
K.eval(loss_function( y_true, y_pred))
? Я смущен тем, что мы там смотрим.