使いたい
flow_from_directory
の方法
ImageDataGenerator
回帰モデルのトレーニングデータを生成します。ターゲット値は、1〜-1の任意の浮動小数点値にすることができます。
flow_from_directory
説明付きの「class_mode」パラメータがあります
class_mode:「categorical」、「binary」、「sparse」、または「None」のいずれか。デフォルト:「カテゴリ」。返されるラベル配列のタイプを決定します。「カテゴリ」は2Dワンホットエンコードラベル、「バイナリ」は1Dバイナリラベル、「スパース」は1D整数ラベルになります。
これらの値のどれをとるべきですか?それらのどれも実際には収まらないようです...
現時点(2017年1月21日のKerasの最新バージョン)では、flow_from_directory
は次の方法でのみ機能しました。
次のように構造化されたディレクトリが必要です。
directory with images\
1st label\
1st picture from 1st label
2nd picture from 1st label
3rd picture from 1st label
...
2nd label\
1st picture from 2nd label
2nd picture from 2nd label
3rd picture from 2nd label
...
...
flow_from_directory
は、固定サイズのバッチを(picture, label)
の形式で返します。ご覧のとおり、これは分類の場合にのみ使用でき、ドキュメントで提供されるすべてのオプションは、クラスが分類子に提供される方法のみを指定します。しかし、flow_from_directory
を退行タスクに役立てることができる巧妙なハックがあります。
次の方法でディレクトリを構造化する必要があります。
directory with images\
1st value (e.g. -0.95423)\
1st picture from 1st value
2nd picture from 1st value
3rd picture from 1st value
...
2nd value (e.g. - 0.9143242)\
1st picture from 2nd value
2nd picture from 2nd value
3rd picture from 2nd value
...
...
リストlist_of_values = [1st value, 2nd value, ...]
も必要です。次に、ジェネレーターを次のように定義します。
def regression_flow_from_directory(flow_from_directory_gen, list_of_values):
for x, y in flow_from_directory_gen:
yield x, list_of_values[y]
そして、これを機能させるためには、flow_from_directory_gen
がclass_mode='sparse'
を持つことが重要です。もちろん、これは少し面倒ですが、動作します(私はこのソリューションを使用しました:))
Keras 2.2.4では、やりたいことを解決する「.flow_from_dataframe」を使用して、回帰問題のディレクトリから画像を流すことができます。すべての画像をフォルダーに保存し、一方の列に画像IDを、もう一方の列に回帰スコア(ラベル)を含むデータフレームをロードし、「。flow_from_dataframe」に「class_mode = 'other'」を設定する必要があります。
ここでは、画像が「image_dir」にある例を見つけることができます。画像IDと回帰スコアを含むデータフレームは、pandas from "train file"でロードされます。
train_label_df = pd.read_csv(train_file, delimiter=' ', header=None, names=['id', 'score'])
train_datagen = ImageDataGenerator(rescale = 1./255, horizontal_flip = True,
fill_mode = "nearest", zoom_range = 0.2,
width_shift_range = 0.2, height_shift_range=0.2,
rotation_range=30)
train_generator = train_datagen.flow_from_dataframe(dataframe=train_label_df, directory=image_dir,
x_col="id", y_col="score", has_ext=True,
class_mode="other", target_size=(img_width, img_height),
batch_size=bs)
データを別の方法で整理し、DataFrameを使用して(必ずしもイメージを新しい場所に移動せずに)回帰モデルを実行できると思います。つまり、各画像のファイルパスとターゲット値を含む列をDataFrameに作成します。これにより、各エポックでデータをシャッフルした場合でも、ジェネレーターは回帰値と画像を適切に同期させることができます。
画像を二項ターゲット、多項ターゲット、回帰ターゲットにリンクして、「ターゲットはターゲットはターゲットである」ことを示し、モデルのみが変更される可能性があることを示す例を次に示します。
df['path'] = df.object_id.apply(file_path_from_db_id)
df
object_id bi multi path target
index
0 461756 dog white /path/to/imgs/756/61/blah_461756.png 0.166831
1 1161756 cat black /path/to/imgs/756/61/blah_1161756.png 0.058793
2 3303651 dog white /path/to/imgs/651/03/blah_3303651.png 0.582970
3 3367756 dog grey /path/to/imgs/756/67/blah_3367756.png -0.421429
4 3767756 dog grey /path/to/imgs/756/67/blah_3767756.png -0.706608
5 5467756 cat black /path/to/imgs/756/67/blah_5467756.png -0.415115
6 5561756 dog white /path/to/imgs/756/61/blah_5561756.png -0.631041
7 31255756 cat grey /path/to/imgs/756/55/blah_31255756.png -0.148226
8 35903651 cat black /path/to/imgs/651/03/blah_35903651.png -0.785671
9 44603651 dog black /path/to/imgs/651/03/blah_44603651.png -0.538359
10 49557622 cat black /path/to/imgs/622/57/blah_49557622.png -0.295279
11 58164756 dog grey /path/to/imgs/756/64/blah_58164756.png 0.407096
12 95403651 cat white /path/to/imgs/651/03/blah_95403651.png 0.790274
13 95555756 dog grey /path/to/imgs/756/55/blah_95555756.png 0.060669
ここで例を挙げて、これを非常に詳細に説明します。
認められた回答には、指摘したいグリッチが1つだけあります。上記のコードは失敗し、次のようなエラーメッセージが表示されます。
TypeError: only integer scalar arrays can be converted to a scalar index
これは、yが配列であるためです。修正は簡単です:
def regression_flow_from_directory(flow_from_directory_gen,
list_of_values):
for x, y in flow_from_directory_gen:
values = [list_of_values[y[i]] for i in range(len(y))]
yield x, values
List_of_valuesを生成するメソッドは https://stackoverflow.com/a/47944082/4082092 にあります