I valori di perdita e metrica di Keras non corrispondono alla stessa funzione in ciascuno
Sto usando keras con una funzione di perdita personalizzata come di seguito:
def custom_fn(y_true, y_pred):
# changing y_true, y_pred values systematically
return mean_absolute_percentage_error(y_true, y_pred)
Poi sto chiamando model.compile(loss=custom_fn)
emodel.fit(X, y,..validation_data=(X_val, y_val)..)
Keras sta quindi salvando loss
e val_loss
nella cronologia del modello. Come controllo di integrità, quando il modello termina l'addestramento, lo sto utilizzando model.predict(X_val)
in modo da poter calcolare manualmente la perdita di convalida con il mio custom_fn
utilizzo del modello addestrato.
Sto salvando il modello con l'epoca migliore usando questo callback:
callbacks.append(ModelCheckpoint(path, save_best_only=True, monitor='val_loss', mode='min'))
quindi, dopo aver calcolato questo, la perdita di convalida dovrebbe corrispondere al val_loss
valore di keras dell'epoca migliore. Ma questo non sta accadendo.
Come altro tentativo di capire questo problema, sto anche facendo questo:
model.compile(loss=custom_fn, metrics=[custom_fn])
E con mia sorpresa, val_loss
e val_custom_fn
non corrispondono (né loss
o loss_custom_fn
per quella materia).
Questo è davvero strano, il mio custom_fn
è essenzialmente integrato mape
con keras y_true
e y_pred
leggermente manipolato. Cosa sta succedendo qui?
PS : i livelli che sto usando sono LSTM
livelli e un Dense
livello finale. Ma penso che questa informazione non sia rilevante per il problema. Sto anche usando la regolarizzazione come iperparametro ma non l'abbandono.
Aggiornare
Anche rimuovendo custom_fn
e utilizzando il built-in di keras mape
come funzione di perdita e metrica in questo modo:
model.compile(loss='mape', metrics=['mape'])
e per semplicità, la rimozione ModelCheckpoint
della richiamata ha lo stesso effetto; val_loss
e val_mape
per ogni epoca non sono equivalenti . Questo è estremamente strano per me. O mi manca qualcosa o c'è un bug nel codice di Keras... il primo potrebbe essere più realistico.
Risposte
Questo post del blog suggerisce che Keras aggiunga qualsiasi regolarizzazione utilizzata nella formazione durante il calcolo della perdita di convalida. E ovviamente, nel calcolo della metrica di scelta non viene applicata alcuna regolarizzazione. Questo è il motivo per cui si verifica con qualsiasi funzione di perdita di scelta come indicato nella domanda.
Questo è qualcosa su cui non sono riuscito a trovare alcuna documentazione da Keras. Tuttavia, sembra reggere da quando rimuovo tutti gli iperparametri di regolarizzazione, val_loss
e val_custom_fn
corrispondono esattamente in ogni epoca.
Una semplice soluzione consiste nell'utilizzare custom_fn
come metrica e salvare il modello migliore basato sulla metrica ( val_custom_fn
) piuttosto che sul val_loss
. Oppure passa manualmente attraverso ogni epoca e calcola val_loss
manualmente il corretto dopo aver addestrato ogni epoca. Quest'ultimo sembra avere più senso poiché non c'è motivo di includere custom_fn
sia come metrica che come funzione di perdita.
Se qualcuno può trovare una prova di ciò nella documentazione di Keras sarebbe utile.