Keras - правильный способ извлечения весов из вложенной модели - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть вложенная модель, которая имеет входной слой и имеет несколько окончательных плотных слоев перед выводом. Вот код для этого:

image_input = Input(shape, name='image_input')
x = DenseNet121(input_shape=shape, include_top=False, weights=None,backend=keras.backend,
layers=keras.layers,
models=keras.models,
utils=keras.utils)(image_input)
x = GlobalAveragePooling2D(name='avg_pool')(x)
x = Dense(1024, activation='relu', name='dense_layer1_image')(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)        
x = Dense(512, activation='relu', name='dense_layer2_image')(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)
output = Dense(num_class, activation='softmax', name='image_output')(x)
classificationModel = Model(inputs=[image_input], outputs=[output])

Теперь Если, скажем, я хотел извлечь веса плотных сетей из этой модели и выполнить обучение переносу на другую более крупную модель, которая также имеет ту же модель плотности enet, вложенную, но также имеет некоторые другие слои после плотного net, такие как:

image_input = Input(shape, name='image_input')
x = DenseNet121(input_shape=shape, include_top=False, weights=None,backend=keras.backend,
layers=keras.layers,
models=keras.models,
utils=keras.utils)(image_input)
x = GlobalAveragePooling2D(name='avg_pool')(x)
x = Dense(1024, activation='relu', name='dense_layer1_image')(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)        
x = Dense(512, activation='relu', name='dense_layer2_image')(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)
x = Dense(256, activation='relu', name='dense_layer3_image')(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)
output = Dense(num_class, activation='sigmoid', name='image_output')(x)
classificationModel = Model(inputs=[image_input], outputs=[output])

Нужно ли мне просто сделать: modelB.load_weights(<weights.hdf5>, by_name=True)? Также я должен назвать внутренние логова enet? и если да, то как?

Ответы [ 2 ]

1 голос
/ 05 февраля 2020

Перед использованием вложенной модели вы можете поместить ее в переменную. Все становится намного проще:

densenet = DenseNet121(input_shape=shape, include_top=False, 
                       weights=None,backend=keras.backend,
                       layers=keras.layers,
                       models=keras.models,
                       utils=keras.utils)

image_input = Input(shape, name='image_input')
x = densenet(image_input)
x = GlobalAveragePooling2D(name='avg_pool')(x)
......

Теперь это очень просто:

weights = densenet.get_weights()
another_densenet.set_weights(weights)

Загруженный файл

Вы также можете распечатать model.summary() вашей загруженной модели. Плотный net будет первым или вторым слоем (вы должны проверить это).

Затем вы можете получить его как densenet = loaded_model.layers[i].

Затем вы можете перенести эти веса в новый плотный net, как с помощью метода в предыдущем ответе, так и с помощью new_model.layers[i].set_weights(densenet.get_weights())

.
1 голос
/ 05 февраля 2020

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

image_input = Input(shape, name='image_input')
# ... intermediery layers elided
x = BatchNormalization()(x)
output = Dropout(0.5)(x)
model_output = Dense(num_class, activation='softmax', name='image_output')(output)
smaller_model = Model(inputs=[image_input], outputs=[model_output])

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

new_model = Model(image_input, output) # Model that uses trained weights

main_input = Input(shape, name='main_input')
x = new_model(main_input)
x = Dense(256, activation='relu', name='dense_layer3_image')(x)
x = BatchNormalization()(x)
x = Dropout(0.5)(x)
output = Dense(num_class, activation='sigmoid', name='image_output')(x)
final_model = Model(inputs=[main_input], outputs=[output])

Если что-то неясно, я был бы более чем рад разработать.

...