2017-01-20 2 views
4

Я хочу использовать предварительно проработанную модель VGG16 в keras и добавить собственную небольшую конвейн сверху. Я заинтересован только в особенностях, а не предсказаниеТонкая настройка предварительно подготовленной модели в keras

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 

Как это делается?

Как бы это сделать, если бы я хотел заменить последний сверточный блок (conv block5 в VGG16) вместо добавления чего-то?

Как я мог бы обучать только узкие места?

Характеристики выходного сигнала features имеет форму (4, 512, 7, 7). Есть четыре изображения, но что в других измерениях? Как я могу уменьшить это до массива (1, x)?

ответ

5

Fitting моделирует

Проблемы с кодом генератора является то, что метод fit_generator ожидает функциональный генератор для генерирования данных для фитинга, которые не предоставляют. Вы можете либо определить генератор, как это сделано в учебнике, что вы связаны с или создавать данные и этикетки себя и приспосабливать вашу модель себя:

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

, где изображения ваши сгенерированные учебные изображения и метки являются соответствующие метки ,

Удаление последнего слоя

Если у вас есть переменная модель и метод «поп», описанный ниже, вы можете сделать model = pop(model) удалить последний слой.

Обучение только определенные слои Как вы сделали в вашем коде, вы можете сделать:

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

Тогда вы можете «разморозить» и слой, который вы хотите, изменяя их trainable свойства True.

Изменение размеров

Чтобы изменить вывод в массив 1D можно использовать Flatten layer


поп метод

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 
+1

представляет собой слой сплющить то же самое, что и изменение (-1)? – spore234

+1

Я не использовал его как таковой, но, насколько я знаю, результаты должны быть одинаковыми. – ginge

1

Использование model.fit(X, y) для обучения на наборе данных, как описано здесь: https://keras.io/models/model/#fit

Кроме того, вы должны добавить слой Flatten и плотный слой с Ouput формой 1, чтобы получить правильную форму результата.

Смежные вопросы