質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1057閲覧

画像のデータ拡張について

yusuke_yamamoto

総合スコア16

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2020/01/15 07:03

やりたいこと

・2100枚の手書き文字画像を用いた15クラス分類問題
・手書き文字をオリジナルデータ以上にデータ拡張したい
・手元には2100枚の画像データとそれに対応するラベルデータがある状態です

悩んでいること

①データ拡張を実施してもオリジナルデータと同じ枚数しか増やせない
そのため、現在は何度も拡張を実施して最後に結合している。かなり手間がかかる
②画像データとラベルデータの順番がバラバラになっているのか学習を実施すると精度が悪くなる

ご教示していただきたいこと

①画像データをオリジナルデータ以上に増やし、
その際、画像データとラベルデータも同時に一致させながらデータ拡張をしたいです

ソースコード

#data1 datagen_1 = ImageDataGenerator( rotation_range=10, width_shift_range=0.05, height_shift_range=0.05, shear_range=0.2, zoom_range=[0.4, 0.05], #horizontal_flip=False, #vertical_flip=False ) #data2 datagen_2 = ImageDataGenerator( rotation_range=15, width_shift_range=0.1, height_shift_range=0.1, shear_range=0.2, zoom_range=[0.3, 0], #horizontal_flip=False, #vertical_flip=False ) #データ拡張実施1 X_gen_1 = datagen_1.flow(X_train, y_train, batch_size=2100) #データ拡張実施2 X_gen_2 = datagen_2.flow(X_train, y_train, batch_size=2100) # ジェネレータからデータ生成1 X_gen_new_1, y_gen_new_1 = X_gen_1.__next__() # ジェネレータからデータ生成2 X_gen_new_2, y_gen_new_2 = X_gen_2.__next__() #教師データを結合 X_train_new = np.concatenate([X_train, X_gen_new_1, X_gen_new_2]) #正解ラベルも結合 y_train_new = np.concatenate([y_train, y_gen_new_1,y_gen_new_2])

最後に

初心者のため的はずれなことを言っている部分もあるかと思いますが
よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

何かしら大きな勘違いがあるようなきがします。

まずImgageDataGenerator() の引数ですが、
例えば
rotation_range=15
パラメータは「画像をランダムに回転する回転範囲」を設定するものです。

https://keras.io/ja/preprocessing/image/

これを設定することで -15度~15度の範囲で乱数を生成し、毎回違った角度で画面を回転させます。
他のパラメータも同様に基本的には乱数の範囲の設定や、ランダムで変更を加えることのEnable/Disableを設定ですので、質問のコードのように パラメータを変更したGeneratorを2つ以上生成する必要はないかと思います。

また、上記に書いたように ImageDataGeneratorは乱数を使って画像の変更を行いますので、next() を何度も呼び出すことにより新しい画像をほぼ無限に作成します。
ですので必要であれば乱数の範囲を大きめにとってループ処理などで next() を何度も呼び出すとよろしいのではないでしょうか

Python

1datagen = ImageDataGenerator( 2 rotation_range=15, 3 width_shift_range=0.1 4 height_shift_range=0.1 5 shear_range=0.2, 6 zoom_range=[0.4, 0], 7 #horizontal_flip=False, 8 #vertical_flip=False 9) 10#データ拡張実施 11X_gen = datagen.flow(X_train, y_train, batch_size=2100) 12 13for _ in range(10): 14 X_gen_new, y_gen_new = X_gen_1.__next__() 15 16 #教師データを結合 17 X_train = np.concatenate([X_train, X_gen_new]) 18 y_train = np.concatenate([y_train, y_gen_new])

ただ、このように学習前に前処理として画像を増やしておくと、メモリを圧迫しますので、通常はmodel.fit_generator() を使って学習時にリアルタイムで新規の画像を生成する方法が一般的ではないでしょうか。


【動作確認】

確認コード

Python

1from keras.preprocessing.image import ImageDataGenerator 2import numpy as np 3 4# ダミーデータを生成 5X_train = np.random.randint(0, 255, (4200, 1, 28, 28)) 6y_train = np.random.randint(0, 1, (4200, 15)) 7 8datagen = ImageDataGenerator( 9 rotation_range=15, 10 width_shift_range=0.1, 11 height_shift_range=0.1, 12 shear_range=0.2, 13 zoom_range=[0.4, 0], 14 #horizontal_flip=False, 15 #vertical_flip=False 16) 17#データ拡張実施 18X_gen = datagen.flow(X_train, y_train, batch_size=4200) 19 20for _ in range(10): 21 #データ生成 22 X_gen_new, y_gen_new = X_gen.__next__() 23 #データを結合 24 X_train = np.concatenate([X_train, X_gen_new]) 25 y_train = np.concatenate([y_train, y_gen_new]) 26 #データサイズを表示 27 print(X_train.shape, y_train.shape)

結果

Text

1(8400, 1, 28, 28) (8400, 15) 2(12600, 1, 28, 28) (12600, 15) 3(16800, 1, 28, 28) (16800, 15) 4(21000, 1, 28, 28) (21000, 15) 5(25200, 1, 28, 28) (25200, 15) 6(29400, 1, 28, 28) (29400, 15) 7(33600, 1, 28, 28) (33600, 15) 8(37800, 1, 28, 28) (37800, 15) 9(42000, 1, 28, 28) (42000, 15) 10(46200, 1, 28, 28) (46200, 15)

投稿2020/01/16 07:31

編集2020/01/16 14:06
magichan

総合スコア15898

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yusuke_yamamoto

2020/01/16 10:51

ありがとうございます。 とてもよくわかりやすかったです。 度々恐縮なのですが、 for _ in range(10): X_gen_new, y_gen_new = X_gen_1.__next__() こちらのコードを実行したのですがforループになりませんでした。 このコードをそのまま使うことはできないですか? 初歩的な質問で大変申し訳ないのですがお答えをお願いできますでしょうか。
magichan

2020/01/16 11:35

ループになると思うけど、なりませんか? for _ in range(10): にて単純に10回ループするはずです。 プリント文など挿入して確認してみたください。
yusuke_yamamoto

2020/01/16 11:49

すいません、ループはしていましたが print("X_train.shape=", X_train.shape) print("y_train.shape=", y_train.shape) 上記を実行したところ、 X_train.shape= (4200, 1, 28, 28) y_train.shape= (4200, 15) と返ってきました。 X_train = np.concatenate([X_train, X_gen_new]) y_train = np.concatenate([y_train, y_gen_new]) こちらの結合時に画像枚数が増えていないように感じたのですが、いかがでしょうか?
yusuke_yamamoto

2020/01/16 11:51

ループは10回行いました。 新規の質問の方が良ければそちらで行います。 度々申し訳ありませんが、何卒よろしくお願い致します。
magichan

2020/01/16 12:07

なるほど、データが追加できていないのですね。 確認します。(この部分は、あまり検証しないで元のコードを流用してました。。)
magichan

2020/01/16 12:10

新規の質問云々に関しては、解決するまでここを使っても全く問題ありません。が 現在移動中で動作確認できる環境がないのでちょっと時間がかかるかもしれません。 もし、お急ぎであれば新しい質問を立ててくださっても構いません。
yusuke_yamamoto

2020/01/16 12:16

急ぎではないのでこちらで継続させてください。 お忙しいのにありがとうございます。
magichan

2020/01/16 14:07

一応確認コードを書いてみましたが、問題なくデータが増加しているようです。
yusuke_yamamoto

2020/01/16 14:55

ありがとうございます!問題なくできるようですね。 改めて実行してみます。 この度はありがとうございます。本当に助かりました。 また今後とも宜しくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問