#python #tensorflow #keras #tensorflow2.0
Вопрос:
У меня есть регрессионная модель тензорного потока. Я не думаю, что детали слоев модели связаны с вопросом, поэтому я пропускаю это. Я могу добавить это, если вы считаете, что это было бы полезно.
Я компилирую со следующим кодом. Потеря и показатель — это среднеквадратичная ошибка.
model.compile(
loss=tf.keras.losses.MeanSquaredError(), optimizer=tf.keras.optimizers.Adam(lr=0.001),
metrics=['mse']
)
Теперь я запускаю следующий код для обучения сети и ее оценки. Я тренирую его в течение 2 эпох, затем оцениваю модель по тем же данным с evaluate
помощью метода и оцениваю ее вручную, используя predict
метод и формулу MSE.
print('fit')
model.fit(X, y, epochs=2, batch_size=32)
print('evaluate')
print(model.evaluate(X, y))
print('manual evaluate')
print(((y - model.predict(X).ravel()) ** 2).mean())
Вот результат:
3152/3152 [==============================] - 12s 3ms/step - loss: 7.7276 - mse: 7.7275
Epoch 2/2
3152/3152 [==============================] - 11s 4ms/step - loss: 0.9898 - mse: 0.9894
evaluate
3152/3152 [==============================] - 2s 686us/step - loss: 1.3753 - mse: 1.3748
[1.3753225803375244, 1.3747814893722534]
manual evaluate
1.3747820755885116
У меня есть небольшая регуляризация, поэтому потери немного больше, чем ожидалось, как и ожидалось.
Но, как вы можете видеть, MSE составляет 0,98 в конце последней эпохи. Тем не менее, я получаю 1,37 MSE, когда оцениваю его evaluate
методом или когда я фактически вычисляю его вручную. Насколько я знаю, модель использует веса после последней эпохи, поэтому эти два числа должны быть равны, верно? Чего мне здесь не хватает? Я пробовал использовать разные размеры пакетов и количество эпох. Оцененный MSE всегда выше, чем MSE в последнюю эпоху метода подгонки.
Примечание: y
является одномерным массивом NumPy
y.shape
> (100836,)
Изменить: Я запускаю fit
метод с validation_data
параметром, используя те (X, y)
же данные проверки:
model.fit(X, y, epochs=2, batch_size=32, validation_data=(X, y))
Выход:
Epoch 1/2
3152/3152 [==============================] - 23s 7ms/step - loss: 7.9766 - mse: 7.9764 - val_loss: 2.0284 - val_mse: 2.0280
Epoch 2/2
3152/3152 [==============================] - 22s 7ms/step - loss: 0.9839 - mse: 0.9836 - val_loss: 1.3436 - val_mse: 1.3431
evaluate
[1.3436073064804077, 1.3430677652359009]
Теперь в этом есть какой-то смысл. Последняя val_mse
эпоха, похоже, совпадает с evaluate
результатом. Но я ожидал mse
, что значения и val_mse
значения будут одинаковыми в индикаторе выполнения, поскольку данные обучения и данные проверки совпадают. Я думаю, что мое понимание того, что показывает индикатор выполнения, неверно. Может ли кто-нибудь объяснить, как я должен интерпретировать индикатор выполнения и почему mse
и val_mse
значения на индикаторе выполнения отличаются?
Комментарии:
1. У вас есть слои BatchNorm?
2. @Frightera, нет, в модели нет никакого слоя пакетной нормализации.
Ответ №1:
Причина, по которой для одних и тех же данных показатели (в вашем случае потери) различаются на этапах обучения и проверки, проста. А именно, во время обучения ваша модель тренируется, изменяя свои параметры от партии к партии. На индикаторе выполнения вы видите среднее значение показателя для всех партий. Напротив, на этапе проверки параметры вашей сети замораживаются. Используемые параметры-это параметры, полученные после обработки последней партии, которую видела сеть. Это объясняет разницу.
Вопрос о том, почему потеря валидации оказалась большей потерей при обучении, является тонким. Одной из причин может быть то, что в вашей модели есть слои, которые ведут себя по-разному во время обучения и проверки (например, BatchNorm, как заметил Frightera). Другой причиной может быть неправильная скорость обучения. Если он слишком велик, параметры будут слишком сильно меняться, тем самым пропуская реальный минимум. Даже с оптимизацией адама это может быть так.
Чтобы понять, в чем проблема со скоростью обучения, попробуйте сделать ее намного меньше. Если разница в метрике сохраняется, то слои вашей сети ведут себя по-разному на этапах обучения и проверки.
Могут быть и другие причины разницы в показателях. Например, обучающие данные зашумлены, так что сеть не может хорошо тренироваться. Это приведет к тому, что потери будут колебаться вблизи среднего значения, что является нормальным. Чтобы понять, так ли это, вам следует изучить графики потерь для разных партий (например, с помощью тензорной доски).
Комментарии:
1. Большое спасибо. Позвольте мне задать следующий вопрос, допустим, мои данные проверки совпадают с данными обучения, у меня есть 3 пакета, и каждый пакет содержит одни и те же данные. И допустим, после первой партии mse рассчитывается как 1,4. После второй партии он равен 1,2, а после последней партии-0,4. Таким образом, индикатор выполнения покажет 1,0 в качестве обучающего mse (путем усреднения всех значений mse пакета), но mse проверки будет 0,4 (так как параметры заморожены после 3-й партии). Это правда? Если это так, можем ли мы сказать, что mse должен увеличиваться от партии к партии в эпоху, чтобы наблюдать val_mse > train_mse?
2. Кроме того, нормализацию пакетов замечает Страхтера, а не я.
3. По первому вопросу. Я предполагаю, что во время обучения TF сначала вычисляет убыток, а затем обновляет параметры (будет странно, если TF вычислит убыток дважды, до и после обновления параметров). Следовательно, потеря проверки может отличаться от потери для последней партии (поскольку параметры изменились). По второму вопросу. Не обязательно — он может колебаться, в то время как в среднем все еще снижается. Колебания могут быть большими из-за неправильной скорости обучения или зашумленных данных.
4. Кстати, если вы хотите получить потери или какие-либо другие показатели по конкретным (проверочным) данным после обработки каждой партии , вы можете написать пользовательский
callback
. Подробнее о том, как это сделать, см. в этом руководстве .