0

我正在使用 mobilenet v2 在我的图像上训练模型。除了几层外,我已经冻结了所有层,然后添加了额外的层进行训练。我希望能够从中间层而不是从一开始进行训练。我的问题:

  1. 是否可以提供最后一个冻结层的输出作为训练的输入(它将是 (?, 7,7,1280) 的张量)?
  2. 如何指定训练从第一个可训练(非冻结)层开始?在这种情况下,mbnetv2_conv.layer[153]。
  3. 在这种情况下 y_train 是什么?我不太明白 y_train 在训练过程中是如何使用的——一般来说,CNN 什么时候引用 y_train?

加载mobilenet v2

image_size = 224
mbnetv2_conv = MobileNetV2(weights='imagenet', include_top=False, input_shape=(image_size, image_size, 3))

    # Freeze all layers except the last 3 layers
    for layer in mbnetv2_conv.layers[:-3]:
        layer.trainable = False

    # Create the model
    model = models.Sequential()
    model.add(mbnetv2_conv)
    model.add(layers.Flatten())
    model.add(layers.Dense(16, activation='relu')) 
    model.add(layers.Dropout(0.5)) 
    model.add(layers.Dense(3, activation='softmax')) 
    model.summary()

    # Build an array (?,224,224,3) from images
    x_train = np.array(all_images)

    # Get layer output
    from keras import backend as K
    get_last_frozen_layer_output = K.function([mbnetv2_conv.layers[0].input],
                                  [mbnetv2_conv.layers[152].output])
    last_frozen_layer_output = get_last_frozen_layer_output([x_train])[0]

    # Compile the model
    from keras.optimizers import SGD
    sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
    model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['acc'])

    # how to train from a specific layer and what should y_train be?
    model.fit(last_frozen_layer_output, y_train, batch_size=2, epochs=10)
4

1 回答 1

0

是的你可以。两种不同的方式。

首先,困难的方法是让你构建两个新模型,一个包含所有冻结层,一个包含所有可训练层。将 Flatten() 层添加到仅冻结层的模型。您将逐层复制 mobilenet v2 中的权重,以填充仅冻结层模型的权重。然后,您将通过仅冻结层模型运行输入图像,将输出以 CSV 或 pickle 形式保存到磁盘。现在这是您的可训练层模型的输入,您可以像上面那样使用 model.fit() 命令进行训练。完成训练后保存权重。然后你必须用两组层构建原始模型,并将权重加载到每一层,并保存整个东西。你完成了!

但是,更简单的方法是将模型的权重与架构分开保存:

model.save_weights(filename)

然后修改 MobileNetV2 中层的 layer.trainable 属性,然后将其添加到新的空模型中:

mbnetv2_conv = MobileNetV2(weights='imagenet', include_top=False, input_shape=(image_size, image_size, 3))
for layer in mbnetv2_conv.layers[:153]:
    layer.trainable = False
model = models.Sequential() 
model.add(mbnetv2_conv) 

然后重新加载权重

newmodel.load_weights(filename)

这使您可以在 mbnetv2_conv 模型中调整您将在运行中训练的层,然后只需调用 model.fit() 继续训练。

于 2019-05-31T00:38:53.710 回答