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

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

ただいまの
回答率

89.89%

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

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 79

やりたいこと

・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])

最後に

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

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

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

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

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

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

datagen = ImageDataGenerator(
    rotation_range=15,
    width_shift_range=0.1
    height_shift_range=0.1
    shear_range=0.2,
    zoom_range=[0.4, 0],
    #horizontal_flip=False,
    #vertical_flip=False
)
#データ拡張実施
X_gen = datagen.flow(X_train, y_train, batch_size=2100)

for _ in range(10):
    X_gen_new, y_gen_new = X_gen_1.__next__()

    #教師データを結合
    X_train = np.concatenate([X_train, X_gen_new])
    y_train = np.concatenate([y_train, y_gen_new])

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


【動作確認】

確認コード

from keras.preprocessing.image import ImageDataGenerator
import numpy as np

# ダミーデータを生成
X_train = np.random.randint(0, 255, (4200, 1, 28, 28))
y_train = np.random.randint(0, 1, (4200, 15))

datagen = ImageDataGenerator(
    rotation_range=15,
    width_shift_range=0.1,
    height_shift_range=0.1,
    shear_range=0.2,
    zoom_range=[0.4, 0],
    #horizontal_flip=False,
    #vertical_flip=False
)
#データ拡張実施
X_gen = datagen.flow(X_train, y_train, batch_size=4200)

for _ in range(10):
    #データ生成
    X_gen_new, y_gen_new = X_gen.__next__()
    #データを結合
    X_train = np.concatenate([X_train, X_gen_new])
    y_train = np.concatenate([y_train, y_gen_new])
    #データサイズを表示
    print(X_train.shape, y_train.shape)


結果

(8400, 1, 28, 28) (8400, 15)
(12600, 1, 28, 28) (12600, 15)
(16800, 1, 28, 28) (16800, 15)
(21000, 1, 28, 28) (21000, 15)
(25200, 1, 28, 28) (25200, 15)
(29400, 1, 28, 28) (29400, 15)
(33600, 1, 28, 28) (33600, 15)
(37800, 1, 28, 28) (37800, 15)
(42000, 1, 28, 28) (42000, 15)
(46200, 1, 28, 28) (46200, 15)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/01/16 21:16

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

    キャンセル

  • 2020/01/16 23:07

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

    キャンセル

  • 2020/01/16 23:55

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

    キャンセル

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

  • ただいまの回答率 89.89%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る