Керас: лучшая модель в соответствии с обратным вызовом ModelCheckpoint дает разные потери в обучающем наборе, чем лучшие потери эпох, отображаемые во время обучения.

Я пытаюсь обучить очень простую модель Keras с бэкендом TensorFlow на Python.

Я знаю, что потери эпох, отображаемые в консоли во время тренировки, рассчитываются «на лету» для повышения эффективности и, следовательно, не обязательно являются реальными потерями промежуточных моделей. Но, насколько я понимаю, они действительно должны быть, если каждая эпоха состояла только из одного пакета, который представляет собой весь обучающий набор. Причина этого ожидания заключается в том, что в этом случае веса модели обновляются только один раз в конце каждой эпохи, что означает, что модель не изменяется, пока вычисляются потери эпохи.

К сожалению, даже если я установил размер пакета равным размеру обучающего набора, потеря лучшей эпохи отличается от потери модели, которая является лучшей в соответствии с обратным вызовом ModelCheckpoint.

Может кто-нибудь объяснить мне такое поведение? Может ли обратный вызов ModelCheckpoint вычислять только потери промежуточных моделей, тоже своего рода «на лету»?

Вот мой код, в котором bestEpochLoss и bestModelLoss никогда не совпадают:

import numpy
import keras

#Create train data
trainInput = numpy.array([4,3,1,0,2])
trainOutput = numpy.array([0,2,2,0,1])

#Create and train model 
model = keras.Sequential([
    keras.layers.Dense(200, input_shape=(1,), activation='tanh'),
    keras.layers.Dense(1, activation='linear')
])
model.compile(loss='mean_squared_error', optimizer=keras.optimizers.Adam(lr=0.1))
callbacks = [keras.callbacks.ModelCheckpoint(filepath='model.hdf5', monitor='loss', verbose=1, save_best_only=True)]
history = model.fit(trainInput, trainOutput, callbacks=callbacks, epochs=20, batch_size=len(trainInput))

#Evaluate best training epoch's loss vs best model's loss
bestEpochLoss = numpy.min(history.history['loss'])
bestModel = keras.models.load_model('model.hdf5')
bestModelLoss = bestModel.evaluate(trainInput, trainOutput)
print('Best training epoch\'s loss: ' + str(bestEpochLoss))
print('Best model\'s loss: ' + str(bestModelLoss))

person Schmax    schedule 27.12.2018    source источник


Ответы (1)


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

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

person ixeption    schedule 27.12.2018
comment
И если каждая эпоха состоит ровно из одного пакета (как в моем случае), это означает, что в конце каждой эпохи есть только обновления веса, верно? - person Schmax; 28.12.2018
comment
Да, в этом случае это должно быть - person ixeption; 28.12.2018