Не должен model.trainable= Ложные веса замораживания под моделью?

Я пытаюсь заморозить бесплатные обученные слои VGG16 ('conv_base' ниже) и добавить поверх них новые слои для извлечения объектов. Я ожидаю получить те же результаты прогнозирования из 'conv_base' до (ret1) / после (ret2) подгонки модели, но это не так. Это неправильный способ проверить вес замерзания?

загрузив VGG16 и установив на необучаемый

conv_base  = applications.VGG16(weights='imagenet', include_top=False, input_shape=[150, 150, 3]) 
conv_base.trainable = False

результат до подгонки модели

ret1 = conv_base.predict(np.ones([1, 150, 150, 3]))

добавить слои поверх VGG16 и скомпилировать модель

model = models.Sequential()
model .add(conv_base)
model .add(layers.Flatten())
model .add(layers.Dense(10, activation='relu'))
model .add(layers.Dense(1, activation='sigmoid'))
m.compile('rmsprop', 'binary_crossentropy', ['accuracy'])

соответствовать модели

m.fit_generator(train_generator, 100, validation_data=validation_generator, validation_steps=50)

результат после подгонки модели

ret2 = conv_base.predict(np.ones([1, 150, 150, 3]))

надеюсь, что это правда, но это не так.

np.equal(ret1, ret2)

2 ответа

Это интересный случай. Почему что-то подобное происходит из-за следующего:

Вы не можете заморозить всю модель после компиляции, и она не будет заморожена, если она не скомпилирована

Если вы установите флаг model.trainable=False затем во время компиляции keras устанавливает все слои не обучаемыми. Если вы установите этот флаг после компиляции - тогда он никак не повлияет на вашу модель. То же самое - если вы установите этот флаг перед компиляцией, а затем повторно используете часть модели для компиляции другой, - это не повлияет на ваши повторно используемые слои. Так model.trainable=False работает только тогда, когда вы примените его в следующем порядке:

# model definition
model.trainable = False
model.compile()

В любом другом сценарии это не сработает, как ожидалось.

Вы должны заморозить слои индивидуально (до компиляции):

for l in conv_base.layers: 
    l.trainable=False

И если это не сработает, вам, вероятно, следует использовать новую последовательную модель для замораживания слоев.

Самый популярный ответ не работает. Как указано в официальной документации Keras (https://keras.io/getting-started/faq/), это следует выполнять для каждого слоя. Хотя для модели есть параметр "обучаемость", он, вероятно, еще не реализован. Самый безопасный способ - сделать следующее:

for layer in model.layers:
    layer.trainable = False
model.compile()
Другие вопросы по тегам