我正在尝试微调Keras中修改过的InceptionV3模型 .
我按照this page上的示例"Fine-tune InceptionV3 on a new set of classes" .
所以我首先训练了使用以下代码添加到InceptionV3基本模型中的顶部密集层:
model = Model(inputs=base_model.input, outputs=predictions)
for layer in base_model.layers:
layer.trainable = False
parallel_model = multi_gpu_model(model, gpus=2)
parallel_model.compile(optimizer='rmsprop', loss='categorical_crossentropy')
history = parallel_model.fit_generator(generate_batches(path), steps_per_epoch = num_images/batch_size, epochs = num_epochs)
之后,我尝试微调InceptionV3中的前2个初始块 . 根据这个例子,我应该做的是:
for layer in model.layers[:249]:
layer.trainable = False
for layer in model.layers[249:]:
layer.trainable = True
model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy')
model.fit_generator(...)
但我正在使用 multi_gpu_model
,所以我不知道如何冻结前249层 .
我的意思是,如果我冻结no-gpu模型中的图层(如示例),并使用 parallel_model = multi_gpu_model(model, gpus=2)
来冻结 parallel_model
中的图层,那么刚刚训练并包含在 parallel_model
中的顶部密集图层中的权重将是被覆盖了,对吗?
另一方面,我试图直接使用 for layer in parallel_model.layers[:249]: layer.trainable = False
,但当我检查 parallel_model
中的图层时,它显示:
for i, layer in enumerate(parallel_model.layers):
print(i, layer.name)
(0, 'input_1')
(1, 'lambda_1')
(2, 'lambda_2')
(3, 'model_1')
(4, 'dense_3')
那么'lambda_1','lambda_2'和'model_1'层是什么?为什么它只在 parallel_model
中显示5层?
更重要的是,如何冻结 parallel_model
中的图层?
1 回答
这个例子有点复杂,因为你正在嵌套一个基础模型
进入一个添加自己的密集层的模型,
然后调用multi_gpu_model再次嵌套模型,当它使用lambda为每个GPU分割模型一次,然后将输出连接在一起,以便将模型分布在多个gpus上 .
在这种情况下,请记住两件事:更改base_model中图层的可训练性,并将非并行模型加载到您的cpu中以获得最佳性能 .
这是完整的微调示例,只需更新train_data_dir即可指向您自己的数据位置 .