Могу ли я выполнять обучение Keras детерминированным образом?

Я использую модель Keras Sequential, где входные данные и метки одинаковы при каждом запуске. Keras использует бэкенд Tensorflow.

Я установил активацию слоев на «нули» и отключил пакетное перемешивание во время обучения.

model = Sequential()
model.add(Dense(128, 
                activation='relu', 
                kernel_initializer='zeros', 
                bias_initializer='zeros'))
...

model.compile(optimizer='rmsprop', loss='binary_crossentropy') 

model.fit(x_train, y_train, 
          batch_size = 128, verbose = 1, epochs = 200, 
          validation_data=(x_validation, y_validation),
          shuffle=False)

Я также пробовал использовать метод random() Numpy:

np.random.seed(7) # fix random seed for reproducibility

С учетом вышеизложенного я все еще получаю разные значения точности и потерь после обучения.

Я что-то упускаю или нет возможности полностью убрать разницу между тренировками?


person RobertJoseph    schedule 05.09.2017    source источник
comment
Возможно, актуально   -  person sascha    schedule 05.09.2017
comment
Спасибо - да, это известная/открытая проблема.   -  person RobertJoseph    schedule 05.09.2017


Ответы (2)


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

#where you see layers[0], it's possible that the correct layer is layers[1] - I can't test at this moment. 

weights = model.layers[0].get_weights()
ws = np.zeros(weights[0].shape)
bs = np.zeros(weights[1].shape)
model.layers[0].set_weights([ws,bs])
person Daniel Möller    schedule 05.09.2017
comment
Идея состоит именно в том, чтобы избежать этих переданных параметров. Мы доверяем numpy, но доверяем ли мы инициализаторам keras, учитывая эту проблему в ссылке? - person Daniel Möller; 05.09.2017

Кажется, проблема возникает при обучении, а не при инициализации. Вы можете проверить это, сначала инициализировав две модели model1 и model2 и выполнив следующий код:

  w1 = model1.get_weights()
  w2 = model2.get_weights()

  for i in range(len(w1)):
      w1i = w1[i]
      w2i = w2[i]
      assert np.allclose(w1i, w2i), (w1i, w2i)
      print("Weight %i were equal. "%i)

  print("All initial weights were equal. ")

Несмотря на то, что все утверждения прошли успешно, обучение model1 и model2 с shuffle=False дало разные модели. То есть, если я выполняю аналогичные утверждения для весов model1 и model2 после обучения, все утверждения терпят неудачу. Это говорит о том, что проблема кроется в хаотичности от обучения.

На момент написания этого поста мне не удалось выяснить, как это обойти.

person Alexander Mathiasen    schedule 04.08.2018