首页 文章

在keras中微调预训练模型

提问于
浏览
5

我想在keras中使用预训练的imagenet VGG16模型,并在顶部添加我自己的小型网站 . 我只对功能感兴趣,而不是对预测感兴趣

from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
from keras.applications.vgg16 import VGG16
from keras.preprocessing import image
from keras.applications.vgg16 import preprocess_input
import numpy as np
import os
from keras.models import Model
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense

从目录加载图像(目录包含4个图像)

IF = '/home/ubu/files/png/'
files = os.listdir(IF)

imgs = [img_to_array(load_img(IF + p, target_size=[224,224])) for p in files]
im = np.array(imgs)

加载基础模型,预处理输入并获取功能

base_model = VGG16(weights='imagenet', include_top=False)

x = preprocess_input(aa)
features = base_model.predict(x)

这是有效的,我在预训练的VGG上获得了我的图像的功能 .

我现在想要微调模型并添加一些卷积层 . 我读了https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.htmlhttps://keras.io/applications/但是不能把它们放在一起 .

在顶部添加我的模型:

x = base_model.output
x = Convolution2D(32, 3, 3)(x)
x = Activation('relu')(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Convolution2D(32, 3, 3)(x)
x = Activation('relu')(x)
feat = MaxPooling2D(pool_size=(2, 2))(x)

Build 完整的模型

model_complete = Model(input=base_model.input, output=feat)

停止学习基础层

for layer in base_model.layers:
layer.trainable = False

新模式

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

现在适合新模型,模型是4个图像,[1,0,1,0]是类标签 . 但这显然是错误的:

model_complete.fit_generator((x, [1,0,1,0]), samples_per_epoch=100, nb_epoch=2)

ValueError: output of generator should be a tuple (x, y, sample_weight) or (x, y). Found: None

这是怎么做到的?

如果我只想替换最后一个卷积块(VGG16中的conv block5)而不是添加某些东西,我该怎么办呢?

我怎么只训练瓶颈功能?

功能输出 features 具有形状(4,512,7,7) . 有四个图像,但其他维度是什么?我如何将其减少为(1,x)数组?

2 回答

  • 1

    Fitting model

    生成器代码的问题在于fit_generator方法需要生成器函数生成适合您未提供的数据 . 您可以在已链接到的教程中定义生成器,也可以自己创建数据和标签,并自己适合您的模型:

    model_complete.fit(images, labels, batch_size=100, nb_epoch=2)
    

    其中图像是您生成的训练图像,标签是相应的标签 .

    Removing last layer

    假设您有一个模型变量和下面描述的"pop"方法,您可以执行 model = pop(model) 删除最后一层 .

    Training only specific layers 正如您在代码中所做的那样,您可以:

    for layer in base_model.layers:
        layer.trainable = False
    

    然后,您可以通过将 trainable 属性更改为 True 来"unfreeze"和所需的图层 .

    Changing dimensions

    要将输出更改为1D阵列,可以使用Flatten layer


    The pop method

    def pop(model):
        '''Removes a layer instance on top of the layer stack.
        This code is thanks to @joelthchao https://github.com/fchollet/keras/issues/2371#issuecomment-211734276
        '''
        if not model.outputs:
            raise Exception('Sequential model cannot be popped: model is empty.')
        else:
            model.layers.pop()
            if not model.layers:
                model.outputs = []
                model.inbound_nodes = []
                model.outbound_nodes = []
            else:
                model.layers[-1].outbound_nodes = []
                model.outputs = [model.layers[-1].output]
            model.built = False
    
        return model
    
  • 7

    使用 model.fit(X, y) 训练您的数据集,如下所述:https://keras.io/models/model/#fit

    此外,您应添加一个Flatten图层和一个输出形状为1的致密图层,以获得正确的结果形状 .

相关问题