Os valores de perda e métricas de Keras não correspondem à mesma função em cada
Estou usando keras com uma função de perda personalizada como abaixo:
def custom_fn(y_true, y_pred):
# changing y_true, y_pred values systematically
return mean_absolute_percentage_error(y_true, y_pred)
Então eu estou ligando model.compile(loss=custom_fn)
emodel.fit(X, y,..validation_data=(X_val, y_val)..)
Keras está salvando loss
e val_loss
no histórico do modelo. Como uma verificação de sanidade, quando o modelo terminar de treinar, estou usando model.predict(X_val)
para que eu possa calcular a perda de validação manualmente custom_fn
usando o modelo treinado.
Estou salvando o modelo com a melhor época usando este callback:
callbacks.append(ModelCheckpoint(path, save_best_only=True, monitor='val_loss', mode='min'))
então, depois de calcular isso, a perda de validação deve corresponder ao valor de keras val_loss
da melhor época. Mas isto não esta acontecendo.
Como outra tentativa de resolver esse problema, também estou fazendo isso:
model.compile(loss=custom_fn, metrics=[custom_fn])
E para minha surpresa, val_loss
e val_custom_fn
não combinam (nem loss
ou loss_custom_fn
pelo menos).
Isso é realmente estranho, my custom_fn
é essencialmente keras embutido mape
com the y_true
e y_pred
ligeiramente manipulado. o que está acontecendo aqui?
PS : as camadas que estou usando são camadas e uma camada LSTM
final . Dense
Mas acho que essa informação não é relevante para o problema. Também estou usando regularização como hiperparâmetro, mas não abandono.
Atualizar
Mesmo removendo custom_fn
e usando o keras embutido mape
como uma função de perda e métrica da seguinte forma:
model.compile(loss='mape', metrics=['mape'])
e para simplificar, remover ModelCheckpoint
o retorno de chamada tem o mesmo efeito; val_loss
e val_mape
para cada época não são equivalentes . Isso é extremamente estranho para mim. Estou perdendo alguma coisa ou há um bug no código Keras ... o primeiro pode ser mais realista.
Respostas
Esta postagem no blog sugere que o keras adicione qualquer regularização usada no treinamento ao calcular a perda de validação. E obviamente, ao calcular a métrica escolhida, nenhuma regularização é aplicada. É por isso que ocorre com qualquer função de perda de escolha, conforme indicado na pergunta.
Isso é algo que não consegui encontrar nenhuma documentação de Keras. No entanto, parece aguentar desde quando removo todos os hiperparâmetros de regularização, val_loss
e val_custom_fn
correspondem exatamente em cada época.
Uma solução fácil é usar o custom_fn
como uma métrica e salvar o melhor modelo com base na métrica ( val_custom_fn
) do que no val_loss
. Ou então Percorra cada época manualmente e calcule o correto val_loss
manualmente após o treinamento de cada época. O último parece fazer mais sentido, pois não há razão para incluir custom_fn
tanto como métrica quanto como função de perda.
Se alguém puder encontrar alguma evidência disso na documentação do Keras, isso seria útil.