2017-11-02 16 views
0

私はケラスモデルを訓練し、モデルとウエイトを2つの別々のファイルに保存しました。私の訓練データと検証データは次のように2つのクラスに分類されていますモデルトレーニング後のケラス予測

training_data/ 
    positive/ 
    negative 
validation_data/ 
    positive/ 
    negative/ 

どちらのトレーニングデータディレクトリは900Kサンプルそれぞれが含まれている、検証データディレクトリは20kのサンプルそれぞれが含まれています。すべてのサンプルは43x43pxです。

私のモデルと学習プロセスは、次のように定義されています:20のエポック、1024年のバッチサイズ、1.800.000学習サンプル、および40.000検証サンプルに対する

def get_model(img_width, img_height): 
    model = Sequential() 
    model.add(Conv2D(32, (3, 3), input_shape=(img_width, img_height, 3))) 
    model.add(Activation('relu')) 
    model.add(MaxPooling2D(pool_size=(2, 2))) 

    model.add(Conv2D(32, (3, 3))) 
    model.add(Activation('relu')) 
    model.add(MaxPooling2D(pool_size=(2, 2))) 

    model.add(Conv2D(64, (3, 3))) 
    model.add(Activation('relu')) 
    model.add(MaxPooling2D(pool_size=(2, 2))) 

    model.add(Flatten()) 
    model.add(Dense(64)) 
    model.add(Activation('relu')) 
    model.add(Dropout(0.5)) 
    model.add(Dense(1)) 
    model.add(Activation('sigmoid')) 

    return model 

model = get_model(43, 43) 
model.compile(loss='binary_crossentropy', optimizer='rmsprop', 
       metrics=['accuracy']) 

train_datagen = ImageDataGenerator(
    rescale=1./255, 
    shear_range=0.2, 
    zoom_range=0.2, 
    rotation_range=20, 
    width_shift_range=0.2, 
    height_shift_range=0.2) 

test_datagen = ImageDataGenerator(rescale=1./255) 

train_generator = train_datagen.flow_from_directory(
    train_data_dir, 
    target_size=(img_width, img_height), 
    batch_size=batch_size, 
    class_mode='binary') 

validation_generator = test_datagen.flow_from_directory(
    validation_data_dir, 
    target_size=(img_width, img_height), 
    batch_size=batch_size, 
    class_mode='binary') 

history = model.fit_generator(
    train_generator, 
    steps_per_epoch=nb_train_samples // batch_size, 
    epochs=epochs, 
    validation_data=validation_generator, 
    validation_steps=nb_validation_samples // batch_size) 

model.save(os.path.join('model.h5')) 
model.save_weights(os.path.join('weights.h5')) 
save_model_info(params) 

トレーニングプロセスは、約5時間かかりました。 historyオブジェクトはここにあります。精度と学習グラフも保存しているからです。

ここで、私は、このモデルが、与えられたテストサンプルにどの訓練された2つのクラスが存在するかを予測しようとしています。だから、モデルを作成し、重みをロードして予測を実行しようとします。

model = get_model(43, 43) 
model.load_weights(args.weights_file) 
model.compile(loss='binary_crossentropy', optimizer='rmsprop', 
       metrics=['accuracy']) 

result = [] 
files = os.listdir(input_dir) 
for file in files: 
    image = load_img(file) 
    image = np.asarray(image) 
    image = np.expand_dims(image, axis=0) 
    result.append(model.predict(image)) 

print(result) 

これは機能していますが、私が好きな方法ではありません。出力は次のようになります。

[array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32), array([[ 0.]], dtype=float32)] 

これは私の質問です。それぞれのファイルに予測のように必要です

{'negative': 0.925, 'positive': 0.0725} 

フォーマットはここでは関係ありません。私のポイントは、訓練を受けた各クラスの確率をどのように得るかです。私はすべてのモデル予測メソッドを使用しようとしたと思いますが、それらのどれも私に必要なものを与えませんでした。コードで何か間違っているのですか、どういう形で違うことをする必要がありますか?

+0

1)あなたは無関係な情報(バッチサイズ、データセットのサイズなど)を提供していますが、最も基本的なものは提供していません。バイナリの分類か何か他の? 2)ファイル内のファイルとファイルの追加などを忘れてしまいます(コードは** minimal **となっています)、** single ** 'model.predict()'コマンドの結果を投稿してください – desertnaut

+0

@ desertnautこれはバイナリの分類(肯定/否定)です。申し訳ありませんが、そのことを言いたくて、 '予測結果のリストを投稿しました。単一の結果は' array [[0.]]、dtype = float32) ' –

+0

考えられる原因はいくつかあります。 Keras IIRCの旧バージョンはpredict_proba(確率を予測する)と予測(クラス0/1予測)を区別していました。新しいバージョンはpredict/predict_classesを使用しますが、古いバージョンを使用している可能性があります。ですから、予測の代わりにpredict_probaを試してみてください。次に、小さなバッチで1エポックを実行して、どうにかして過度に訓練されていないことを確認し、ネットワークがゼロに収束するだけではないことを確認してください。最後に、間違った種類の出力を持っている可能性がありますが、バイナリの分類には大丈夫です。あなたはどうやって亡くなりますか? –

答えて

1

私が言ったように、まず

...私はあなたの問題の根本的な原因を追跡するため、あなたを助けるためにSOで、ここでの回答のためにそれが簡単に作成するための両方、 方法論を提供してみましょう私のコメントでは、SOのコードは minimalとなっています。つまり、問題を再現するのに十分です。私たちはあなたのデータにアクセスすることができないので、あなたの training_generatorvalidation_generator、ディレクトリ構造、または[...]のような詳細は含まれておらず、回答者にとって役に立たず、注意をそらすことはありませんのみ)あなたはMNISTまたはCIFARのように、一般に入手可能なデータセットを使用していた場合には:

最小

通過することがあるより多くのコード、にくい人は あなたの問題を見つけることができます

おそらく、同じ原理が問題のテキストのためにも保持している...

第二には、私が想定し(あなたががを知っているいくつかの手摘みのサンプルを予測してみてください0はあなたのネガティブです)、すなわち1に近い出力を与えるべきである。私が知っているすべての情報は、あなたが提供した情報では間違っていることはないかもしれません。あなたが試した(わずかな)テストサンプルはすべて確率0(否定)を与えます。それを明示的にチェックする方がよいでしょう。最後の点に明確

:あなたの最後の層は、単一​​のノードを有しているので、あなたの出力は、通常、あなたのクラスのいずれかについての確率pとして解釈されるべきである[0,1]に単一数、あろう(他のものが単純にバイナリ分類で1-pである確率)。だから少なくとも形式の出力は全く変わっていません。

第三に、モデルは&ロードを保存して報告したいくつかの問題(それをグーグル)があったとして、あなたのモデルを保存する前に、いくつかの予測を行い、ロードされたモデルから同じ予測とそれらを比較してみてください。不一致がある場合は、原因の検索を大幅に絞り込んでいます。

希望します。うまくいけば、が本当に何か間違っている場合は、次の手順を実行して問題を自分で解決するか、ここで新しい、より集中的な質問を開くことができる特定のポイントに絞り込んでください。そのような場合、How to create a Minimal, Complete, and Verifiable exampleのSOのガイドラインに従うと、誰かから有益な回答が得られる可能性が大幅に高まります。

+1

ありがとうございました。私はあなたにコードをあまりにもたくさん与えたくはありませんでしたが、ケラス(そして機械学習)を学び始めましたが、コードのどの部分が重要であるかわからなかったので、私はそれを覚えています。私はあなたが言ったようにして、それが助けられたかどうかを知らせます。 –

+0

@MateuszCisekあなたはそれが何らかの形で役に立つと分かっているならば、回答をアップアップすることは大変歓迎されています(回答は回答者のために貴重な時間を費やします)... – desertnaut

1

私は問題を解決して作業しています。問題は、モデルを訓練しながら、私はImageGeneratorでrescaleパラメータを追加したことだった。

train_datagen = ImageDataGenerator(
    rescale=1./255, 
    shear_range=0.2, 
    zoom_range=0.2, 
    rotation_range=20, 
    width_shift_range=0.2, 
    height_shift_range=0.2) 

をや予測を実行している間、私はこれを追加しませんでした:

for file in files: 
    image = load_img(file) 
    image = np.asarray(image) 
    image = np.expand_dims(image, axis=0) 
    result.append(model.predict(image)) 

を私は

image = np.expand_dims(image, axis=0) 
この行を変更します

これは次のようになります

img = np.expand_dims(img/255, axis=0) 

私もモデルをロードし、更新、行が変更された(しかし、ただの予測ではなく、訓練のために):この中

model = get_model(43, 43) 
model.load_weights(args.weights_file) 
model.compile(loss='binary_crossentropy', optimizer='rmsprop', 
      metrics=['accuracy']) 

model = load_model(args.model_file) 

私はすべてのサンプルとして予測を実行します数値の配列に結果を入力し、その配列をイメージに変更して動作させます。助けてくれてありがとう、コードの量についてもう一度申し訳ありません。

+0

良い仕事(+1);うまくいけば私のアドバイスは役に立ちました... – desertnaut