#python #tensorflow #machine-learning #keras #loss-function
#python #tensorflow #машинное обучение #keras #функция потерь
Вопрос:
У меня возникли проблемы с созданием пользовательских функций потерь в Keras.
В нашей модели размер конечного слоя ( y_pred
) равен [32, 365], что рассматривается как квантованные ставки для следующих 365 таймфреймов.
Я хотел бы создать пользовательскую функцию потерь, которая включает в себя как перекрестную энтропию, так и RMSE. Таким образом, операции требуют 1) дополнительной предварительной обработки y_pred
для генерации логитов размера [32,1] для вычисления перекрестной энтропии с двоичными метками (y_true)
, и 2) другой предварительной обработки y_pred
для генерации дополнительных значений [32,1] для вычисления RMSE с числовыми метками.
Насколько я знаю, y_true
и y_pred
должны иметь одинаковое измерение в пользовательской функции потерь Keras. Но в моем случае размер y_pred
равен [32, 365]. Должен ли я либо сделать измерение y_true как [32, 365], либо добавить вышеупомянутые шаги предварительной обработки в модель Keras перед вычислением двух потерь?
В моем предыдущем решении я создал пользовательскую функцию потерь таким образом, но теперь я сомневаюсь, что размерность y_true равна [32, 2]. Если измерение равно [32, 365], какими будут значения данных???
def losses(y_true, y_pred):
a = 0.2
loss1 = rmse_loss(y_true, preprocess1(y_pred))
loss2 = ce_loss(y_true, preprocess2(y_pred))
loss = 0.2*loss1 0.8*loss2
return loss
Дополнительная информация:
Вывод train_generator
представляет собой кортеж размеров [32, 10], [32, 2], где 32 — размер мини-пакета, 10 — количество ковариаций, а 2 — количество меток (двоичных, числовых)
train_data = self.train_data_generator()
ntd = next(train_data)
print(ntd[0].shape, ntd[1].shape)
>>> [32, 10], [32, 2]
Ответ №1:
Одной из альтернатив является выполнение операций в самой модели. Таким образом, у вас будет модель с двумя выходами, и вы сможете применить функцию потерь отдельно к каждому из них, с их собственными метками и весами потерь:
from keras.layers import Lambda
# the model definition goes here...
out1 = Lambda(preprocess1)(final_out) # you can also implement this using existing layers
out2 = Lambda(preprocess2)(final_out)
model = Model(inp, [out1, out2])
model.compile(loss=[rmse_loss, ce_loss], loss_weights=[0.2, 0.8], ...)
Комментарии:
1. Спасибо, что поделились своим решением. Я пытался избежать включения операций в модель, поскольку эти операции являются последующими и не требуют никаких обучаемых весов. Кстати, не хотели бы вы объяснить, как метки из генератора данных проходят через y_true в вашем примере?
2. @SUNDONG Отсутствие обучаемых весов не является веской причиной не включать их в модель. На самом деле, если вы используете TensorFlow в качестве серверной части, то разделение модели и потерь не имеет смысла, поскольку у нас есть только один вычислительный график, содержащий и вычисляющий все вещи. Что касается меток, вам следует настроить определение generator для возврата кортежа таким образом, чтобы вторым элементом кортежа был список из двух массивов , соответствующих двум выходным слоям.