2017-01-20 10 views
4

kerasでpretrained imagenet VGG16モデルを使い、自分の小さなconvnetを上に追加したいと思います。私は(dirは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) 

、ベースモデルを読み込む前処理の入力や機能

を取得する機能、いないディレクトリからの予測

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 

ロード・イメージでのみ興味があります

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/を読みましたが、それらを結びつけることはできません。

上に私のモデルを追加:学習さから完全なモデルに

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

ストップベース層を構築

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) 

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)です。 4つのイメージがありますが、他の次元には何がありますか?私はそれを(1、x)配列にどのように減らすでしょうか?

答えて

5

モデル

フィッティングあなたの発電機のコードの問題は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 

次にあなたが「フリーズ解除」とあなたはTrueに自分のtrainableプロパティを変更して欲しい層ができます。

変更寸法

は、あなたが使用できる1次元配列に出力を変更するにはFlatten layer


popメソッド

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

また、あなたが正しい結果形状を得るために、1の出力に含ま形状と平坦化層と緻密層を追加する必要があります。

関連する問題