Керас: Почему потери отличаются для train_on_batch () и test_on_batch (), когда одни и те же входные данные передаются обеим функциям? - PullRequest
2 голосов
/ 07 ноября 2019

Я передаю те же входные данные, т.е. те же данные и те же метки истинного значения, в keras train_on_batch () и test_on_batch (). Я хочу знать, почему я получаю разные значения потерь для обеих функций.

код:

model_del_fin.compile(optimizer=SGD(lr=0.001,decay=0.001/15), loss='categorical_crossentropy',metrics=['accuracy'])
iters_per_epoch = 1285 // 50
print(iters_per_epoch)
num_epochs = 15
outs_store_freq = 20 # in iters
print_loss_freq = 20 # in iters

iter_num = 0
epoch_num = 0
model_outputs = []
loss_history  = []

while epoch_num < num_epochs:
  print("ok")
  while iter_num < iters_per_epoch:
    x_train, y_train = next(train_it2)
    loss_history += [model_del_fin.train_on_batch([x_train,x_train], y_train)]
    print("Iter {} loss: {}".format(iter_num, loss_history[-1]))
    print(model_del_fin.test_on_batch([x_train,x_train], y_train))
    iter_num += 1
  print("EPOCH {} FINISHED".format(epoch_num + 1))

  epoch_num += 1
  iter_num = 0 # reset counter

** Результат: **

Потери в Iter: [5.860205, 0.24] [2.5426426, 0.68] Потери в Iter: [3.5718067, 0.48] [1.7102847, 0.68] Потери в Iter 2: [2.0221999, 0.68] [1.310905, 0.94] Iter 3потери: [1,6114614, 0,74] [1,2987132, 0,92]

1 Ответ

4 голосов
/ 07 ноября 2019

Проблема связана с передачей данных в модель в режиме поезда против в режиме вывода ;различия включают в себя:

  • Режим поезда : Dropout активен, BatchNormalization использует партия статистика для среднего и дисперсии
  • Логический вывод : все значения Dropout установлены на ноль, а BatchNormalization использует экспоненциальное скользящее среднее статистика для среднего значения и дисперсии, вычисленная во время обучения

Другоеразличия также применяются. Предполагая, что модели, используемые в вашем коде, основаны на других вопросах (например, VGG) - это будут слои BN. В качестве обходного пути вы можете временно установить глобальную фазу обучения с помощью:

K.set_learning_phase(0) # INFERENCE MODE
K.set_learning_phase(1) # TRAIN MODE

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

Наконец, если вы сначала вызовите train_on_batch() и , а затем вызовите test_on_batch(), оба не согласятся, потому что test выполняется после того, как train обновил весовые коэффициенты - таким образом, вызовите test_on_batch()сначала , затем train_on_batch().


Полный пример :

from tensorflow.keras.layers import Input, Dense, Dropout
from tensorflow.keras.models import Model
import tensorflow.keras.backend as K
import numpy as np

K.set_learning_phase(0)

ipt = Input((12,))
x   = Dropout(0.1)(ipt)
out = Dense(12)(x)

model = Model(ipt, out)
model.compile('adam', 'mse')
X = np.random.randn(32, 12)

print(model.train_on_batch(X, X))
print(model.test_on_batch(X, X))
print(model.train_on_batch(X, X))
2.1212778 # train_on_batch()
2.1128066 # test_on_batch()
2.1128066 # train_on_batch()

Попробуйте использовать K.set_learning_phase(1) вместопосмотрите на разницу - или закомментируйте ее полностью, поскольку 1 является значением по умолчанию в любом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...