我想在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.html和https://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)
建立完整的模型
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)数组?
拟合模型
生成器代码的问题在于fit_generator方法需要生成器函数生成适合您未提供的数据.您可以在已链接到的教程中定义生成器,也可以自己创建数据和标签,并自己适合您的模型:
model_complete.fit(images, labels, batch_size=100, nb_epoch=2)
其中图像是您生成的训练图像,标签是相应的标签.
删除最后一层
假设您有一个模型变量和下面描述的"pop"方法,您可以model = pop(model)
删除最后一层.
仅培训特定图层 正如您在代码中所做的那样,您可以执行以下操作:
for layer in base_model.layers: layer.trainable = False
然后,您可以通过将其trainable
属性更改为"解冻"和所需的图层True
.
改变尺寸
要将输出更改为1D阵列,可以使用"展平"图层
流行方法
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