Эффективный способ расчета функции потерь в пакетном режиме?

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

Это мой текущий код для расчета потерь при реконструкции. Но это очень медленно. По моей оценке, просмотр набора данных должен занять 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

Я удалил свой предыдущий ответ, можете ли вы отредактировать свой вопрос, чтобы объяснить, что такое K.eval(loss_function( y_true, y_pred))? Я смущен тем, что мы там смотрим.

David Parks 23.05.2019 00:18

я внес изменения.

ashes 23.05.2019 08:05

Как получилось, что ae1.predict принимает те же данные, что и y_true? Оба принимают в качестве входных данных encoded_dataset[i:i+batch_size].values. Если вы выполняете прогнозирование, вы передаете входные данные, но похоже, что вы прогнозируете, используя метки. Я предполагаю, что values каким-то образом содержит как данные, так и метки, что не очевидно из фрагмента кода. В этом случае вы, вероятно, несколько раз перемещаете полные входные данные. Однако не очень понятно.

David Parks 23.05.2019 19:32

Я использую модель автоматического кодировщика. Таким образом, в случае с ауроэнкодерами вы пытаетесь реконструировать ввод с помощью нейронной сети. Вот почему y_true использует то же значение, что и y_pred.

ashes 24.05.2019 05:56

Ну, конечно, брейнфарт, извините. Я подозреваю, что ae1.predict и K.eval(loss_function ведут себя неожиданным образом. ae1.predict обычно следует использовать для вывода значения функции потерь, а также y_pred. Когда вы создаете модель, укажите, что значение потерь является другим выходом (у вас может быть список нескольких выходов), а затем просто вызовите прогнозирование здесь один раз, чтобы получить оба y_pred значения потерь за один вызов.

David Parks 24.05.2019 15:46

О, хорошо. Спасибо, но я хочу потери для каждой строки. Не будет ли потеря, возвращаемая методом прогнозирования, средней потерей для всей партии?

ashes 25.05.2019 16:04

Отличный вопрос. Ответ зависит от того, как реализована функция потерь. Оба способа дают абсолютно достоверные и идентичные результаты в TF под капотом. Вы можете усреднить потери по партии, прежде чем принимать градиент w.r.t. потери или взять градиент w.r.t. вектор потерь. Операция градиента в TF выполнит для вас усреднение потерь, если вы используете последний подход (см. статьи SO о взятии градиента для каждой партии, это на самом деле сложно сделать).

David Parks 25.05.2019 17:18

Если 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, что является чисто необязательным в потере. Дайте мне знать, если это решит проблему, и я перенесу обсуждение на ответ.

David Parks 25.05.2019 17:26

Это в значительной степени решило это. Большое спасибо

ashes 26.05.2019 18:30
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
1
9
411
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Перенесено из комментариев:

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

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