トレーニングと検証にImageDataGenerator
とflow_from_directory
を使用しました。
これらは私のディレクトリです:
train_dir = Path('D:/Datasets/Trell/images/new_images/training')
test_dir = Path('D:/Datasets/Trell/images/new_images/validation')
pred_dir = Path('D:/Datasets/Trell/images/new_images/testing')
ImageGeneratorコード:
img_width, img_height = 28, 28
batch_size=32
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(
test_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
4つのクラスに属する1852個の画像が見つかりました
4つのクラスに属する115枚の画像が見つかりました
これは私のモデルトレーニングコードです。
history = cnn.fit_generator(
train_generator,
steps_per_Epoch=1852 // batch_size,
epochs=20,
validation_data=validation_generator,
validation_steps=115 // batch_size)
これで、テストフォルダーにいくつかの新しい画像があります(すべての画像は同じフォルダー内にのみあります)。しかし、.predict_generator
を使用すると、次のようになります。
0個のクラスに属する0個の画像が見つかりました
だから私はこれらのソリューションを試しました:
1) Keras:ImageDataGeneratorでpredict_generatorを使用する方法 これは検証セットのみを試行するため、うまくいきませんでした。
2) model.predictを使用して新しい画像を予測する方法module image not found
3) Kerasのストリーミングテストデータでpredict_generatorを使用して予測を取得する方法 これもうまくいきませんでした。
私の列車データは基本的に4つの個別のフォルダ、つまり4つの特定のクラスに保存され、検証も同じ方法で保存され、うまく機能します。
そのため、テストフォルダーには約300個の画像があり、その上で次のようにデータフレームを予測して作成します。
image_name class
gghh.jpg 1
rrtq.png 2
1113.jpg 1
44rf.jpg 4
tyug.png 1
ssgh.jpg 3
次のコードも使用しました。
img = image.load_img(pred_dir, target_size=(28, 28))
img_tensor = image.img_to_array(img)
img_tensor = np.expand_dims(img_tensor, axis=0)
img_tensor /= 255.
cnn.predict(img_tensor)
しかし、私はこのエラーを受け取ります:[Errno 13] Permission denied: 'D:\\Datasets\\Trell\\images\\new_images\\testing'
しかし、テスト画像でpredict_generator
することができませんでした。それでは、Kerasを使用して新しい画像をどのように予測できますか。私は多くのグーグルで検索し、Kaggleカーネルも検索しましたが、解決策を得ることができませんでした。
そのため、最初にすべてのテストイメージをテストフォルダー内の別のフォルダーに配置する必要があります。したがって、私の場合、test
フォルダー内に別のフォルダーを作成し、_all_classes
_という名前を付けました。次に、次のコードを実行しました。
_test_generator = test_datagen.flow_from_directory(
directory=pred_dir,
target_size=(28, 28),
color_mode="rgb",
batch_size=32,
class_mode=None,
shuffle=False
)
_
上記のコードは私に出力を与えます:
1クラスに属する306個の画像が見つかりました
そして最も重要なのは、次のコードを書くことです。
test_generator.reset()
そうでなければ、奇妙な出力が出ます。次に、.predict_generator()
関数を使用します。
pred=cnn.predict_generator(test_generator,verbose=1,steps=306/batch_size)
上記のコードを実行すると、確率で出力が得られるため、最初にクラス番号に変換する必要があります。私の場合、クラスは4つだったので、クラス番号は0、1、2、3でした。
書かれたコード:
predicted_class_indices=np.argmax(pred,axis=1)
次のステップでは、クラスの名前が必要です。
_labels = (train_generator.class_indices)
labels = dict((v,k) for k,v in labels.items())
predictions = [labels[k] for k in predicted_class_indices]
_
クラス番号はクラス名に置き換えられます。 csvファイルに保存する場合の最後のステップは、予測されたクラスが画像名に追加されたデータフレームに配置することです。
_filenames=test_generator.filenames
results=pd.DataFrame({"Filename":filenames,
"Predictions":predictions})
_
データフレームを表示します。すべてが完了しました。画像の予測クラスをすべて取得します。
predict_generator()
で問題が発生しました。ここでのいくつかの投稿は大いに役立ちました。私もここに自分の解決策を投稿し、他の人の助けになることを願っています。私がやること:
predict_generator()
を使用して新しい画像を予測します文書化された here のように、「猫と犬」のようにバイナリ予測を行います。ただし、ロジックはマルチクラスのケースに一般化できます。この場合、予測の結果にはクラスごとに1つの列があります。
まず、保存したモデルをロードして、データジェネレーターをセットアップします。
_import numpy as np
import pandas as pd
from keras.preprocessing.image import ImageDataGenerator
from keras.models import load_model
# Load model
model = load_model('my_model_01.hdf5')
test_datagen = ImageDataGenerator(rescale=1./255)
test_generator = test_datagen.flow_from_directory(
"C:/kerasimages/pred/",
target_size=(150, 150),
batch_size=20,
class_mode='binary',
shuffle=False)
_
注:ファイル名と予測の順序を保持するために、_shuffle=False
_を指定することが重要です。
画像は_C:/kerasimages/pred/images/
_に保存されます。データジェネレーターは、_C:/kerasimages/pred/
_(_test_generator
_で指定された)のサブフォルダーの画像のみを検索します。データジェネレーターのロジックを尊重することが重要なので、サブフォルダー_/images/
_が必要です。 _C:/kerasimages/pred/
_の各サブフォルダーは、ジェネレーターによって1つのクラスとして解釈されます。ここでは、ジェネレーターは_Found x images belonging to 1 classes
_を報告します(サブフォルダーが1つしかないため)。予測を行う場合、クラス(ジェネレーターによって検出される)は関係ありません。
これで、ジェネレーターを使用して予測を行うことができます。
_# Predict from generator (returns probabilities)
pred=model.predict_generator(test_generator, steps=len(test_generator), verbose=1)
_
この場合、ジェネレータをリセットする必要はありませんが、以前にジェネレータを設定したことがある場合は、test_generator.reset()
を使用してリセットする必要があります。
次に、確率を丸めてクラスを取得し、ファイル名を取得します。
_# Get classes by np.round
cl = np.round(pred)
# Get filenames (set shuffle=false in generator is important)
filenames=test_generator.filenames
_
最後に、結果をデータフレームに保存できます。
_# Data frame
results=pd.DataFrame({"file":filenames,"pr":pred[:,0], "class":cl[:,0]})
_
おそらく、flow_from_directory
を使用して間違いを犯している可能性があります。ドキュメントを読む:
flow_from_directory(ディレクトリ、...)
どこで:
ディレクトリ:ターゲットディレクトリへのパス。クラスごとに1つのサブディレクトリを含める必要があります。各サブディレクトリディレクトリツリー内のPNG、JPG、BMP、PPMまたはTIF画像は、ジェネレーターに含まれます。
つまり、この関数に渡すディレクトリ内で、サブディレクトリを作成し、このサブディレクトリ内に画像を配置する必要があります。それ以外の場合、画像が(サブディレクトリではなく)渡すディレクトリにある場合、実際には0個の画像と0個のクラスがあります。
[〜#〜] edit [〜#〜]
わかりましたので、実行したい予測の場合、次のようにpredict
関数を使用したいと思います:(学習中に行ったのと同じ形式でデータをネットワークに提供する必要があることに注意してくださいプロセス)
image = img_to_array(load_img(f"{directory}/{foldername}/{filename}"))
# here you prepare the input data, for example here we take the gray image
# gray scale is the 1st channel in the Lab color space
color_me = rgb2lab((1.0 / 255) * color_me)[:, :, 0]
color_me = color_me.reshape(color_me.shape + (1,))
# here data is in the format which is accepted by, in this case, my model
# for your model you have to do the preparation just the same as in the case of learning process
output = model.predict(np.array([color_me]))
# and here you have your predicted output
テストフォルダーに親フォルダーを作成することを強くお勧めします。次に、テストフォルダーを親フォルダーに移動します。
この方法でテストフォルダを持っている場合:
/root/test/img1.png
/root/test/img2.png
/root/test/img3.png
/root/test/img4.png
predict_generatorを使用するこの間違った方法。次のようにテストフォルダーを更新します。
/root/test_parent/test/img1.png
/root/test_parent/test/img2.png
/root/test_parent/test/img3.png
/root/test_parent/test/img4.png
このコマンドを使用して更新します。
mv /root/test/ ./root/test_parent/test
そして、このようなモデルへのパスを与えることも忘れないでください
"/root/test_parent/"
この方法は私にとっては役に立ちます。