🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Keras

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

CNN (Convolutional Neural Network)

CNN (Convolutional Neural Network)は、全結合層のみではなく畳み込み層とプーリング層で構成されるニューラルネットワークです。画像認識において優れた性能を持ち、畳み込みニューラルネットワークとも呼ばれています。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

687閲覧

画像の処理をMixup→Random Erasing→ImageDataGeneratorの変換の順で処理したい

semisemi

総合スコア18

Keras

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

CNN (Convolutional Neural Network)

CNN (Convolutional Neural Network)は、全結合層のみではなく畳み込み層とプーリング層で構成されるニューラルネットワークです。画像認識において優れた性能を持ち、畳み込みニューラルネットワークとも呼ばれています。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2022/12/15 07:34

編集2023/01/09 10:11

前提

kerasのImageDataGeneratorをカスタマイズしてRandom ErasingとMixupの実装ができたのですが、画像を変換する際の処理順をMixup→Random Erasing→ImageDataGeneratorの変換の順に処理することは可能でしょうか?

また、できればMixupの発生させる確立を指定したいです。

実現したいこと

・画像の処理順をMixup→Random Erasing→ImageDataGeneratorの変換の順で処理
・Mixupの発生させる確立を指定

発生している問題

・apply_transform内でmixupがうまくできていない

該当のソースコード

python

1from random_eraser import get_random_eraser 2 3class MyImageDataGenerator(ImageDataGenerator): 4 def __init__(self,mix_up_alpha = 0.0, *args, **kwargs): 5 self.random_eraser = get_random_eraser() 6 super().__init__(*args, **kwargs) 7 assert mix_up_alpha >= 0.0 8 self.mix_up_alpha = mix_up_alpha 9 10 ##mixup用 11 def img(gen: ImageDataGenerator): 12 for x, y in gen: 13 yield x, y 14 15 def mix_up(self, X1, y1, X2, y2): 16 assert X1.shape[0] == y1.shape[0] == X2.shape[0] == y2.shape[0] 17 batch_size = X1.shape[0] 18 l = np.random.beta(self.mix_up_alpha, self.mix_up_alpha, batch_size) 19 X_l = l.reshape(batch_size, 1, 1, 1) 20 y_l = l.reshape(batch_size, 1) 21 X = X1 * X_l + X2 * (1-X_l) 22 y = y1 * y_l + y2 * (1-y_l) 23 return X, y 24 25 def apply_transform(self, x, transform_parameters): 26 27 x = self.mix_up_alpha(x) # 先に処理する 28 x = self.random_eraser(x) 29 return super().apply_transform(x, transform_parameters) 30 31

試したこと

回答を参考にmixupを実装したかったのですが、どのようにdef imgの画像ジェネレーターとmixupするのか詰まっている状況です。

補足情報(FW/ツールのバージョンなど)

https://dev.classmethod.jp/articles/tensorflow-image-generator-custom/
https://dev.classmethod.jp/articles/tensorflow-image-generator-custom-mixup/
上記二つのサイトを参考に実装しました。

使用ツール
anacondaを使用
python 3.8.13
TensorFlow 2.3
Spyder 5.3.3

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

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

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

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

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

PondVillege

2022/12/15 07:47

super().flow()からのnext(batch_gen)の時点でImageDataGeneratorの変換結果が生成されているので,これを後に持っていくよう記述するべきです.
semisemi

2022/12/15 08:41 編集

コメントありがとうございます。 def flow内のwhile True下にある batch_x, batch_y = next(batch_gen) batch_x_2, batch_y_2 = next(batch_gen2) をif self.random_erasing_probabilityとself.mixup_alphaより下に書くということでしょうか?
PondVillege

2022/12/15 11:40

それをしてしまうと,random_erasingやmixup_alphaをするデータはどこから持ってくるか論になってしまいます.flowはOverrideせずに,apply_transformをOverrideしてかつapply_transform()の最後でsuper().apply_transform()するべきです.
semisemi

2022/12/16 14:47

まだ、私自身の理解が出来ていないですが質問のソースコードに、apply_transformメソッドを追記しておりますので確認していただけると幸いです。
PondVillege

2022/12/26 11:10

返信を失念していました.確認お願いいたします.
guest

回答1

0

ベストアンサー

簡単のためgithubにあったrandom_eraserを利用して次のように実装します.

コマンドで

shell

1wget https://raw.githubusercontent.com/yu4u/cutout-random-erasing/master/random_eraser.py -O random_eraser.py

と実行すればカレントディレクトリ配下にrandom_eraser.pyがダウンロードされるので,これを利用して

Python

1from random_eraser import get_random_eraser 2import csv 3import numpy as np 4import tensorflow as tf 5from keras.preprocessing.image import ImageDataGenerator 6from matplotlib import pyplot as plt 7 8def mix_up(X1, y1, X2, y2, mix_up_alpha): 9 assert X1.shape[0] == y1.shape[0] == X2.shape[0] == y2.shape[0] 10 batch_size = X1.shape[0] 11 l = np.random.beta(mix_up_alpha, mix_up_alpha, batch_size) 12 X_l = l.reshape(batch_size, 1, 1, 1) 13 y_l = l.reshape(batch_size, 1) 14 X = X1 * X_l + X2 * (1 - X_l) 15 y = y1 * y_l + y2 * (1 - y_l) 16 return X, y 17 18class MyImageDataGenerator(ImageDataGenerator): 19 def __init__(self, *args, **kwargs): 20 self.random_eraser = get_random_eraser() 21 super().__init__(*args, **kwargs) 22 23 def apply_transform(self, x, transform_parameters): 24 x = self.random_eraser(x) # 先に処理する 25 return super().apply_transform(x, transform_parameters) 26 27from keras.datasets import mnist 28(X, y), (_, _) = mnist.load_data() 29X = X[:, :, :, np.newaxis] 30 31mix_up_gen = ImageDataGenerator( 32 rescale = 1/255, 33).flow(X, y) 34train_gen = MyImageDataGenerator( 35 rescale = 1/255, 36 rotation_range = 90 37).flow(X, y) 38 39def my_flow(mix_up_gen, gen): 40 for (X1, y1), (X2, y2) in zip(mix_up_gen, gen): 41 yield mix_up(X1, y1, X2, y2, 0.5) 42 43fig = plt.figure(figsize = (10, 7)) 44rows, cols = 3, 3 45one_batch = next(my_flow(mix_up_gen, train_gen)) 46for i, (img, label) in enumerate(zip(one_batch[0], one_batch[1])): 47 if i >= rows * cols: 48 break 49 fig.add_subplot(rows, cols, i + 1) 50 img = img.reshape(28, 28) 51 plt.imshow(img, vmin = 0, vmax = 1) 52 plt.axis("off")

イメージ説明

apply_transform()に要求されている引数は,GitHubのコードからも分かるとおり,単一画像xとその変換方法transform_parameterなので,これが処理されてしまう前に,単一画像xを独自の方法で変換します.

また,MixUpをImageDataGeneratorによる変換前に挿入するのはIteratorの書き換えが必要であることがわかり現実的ではないので,従来通りジェネレータを定義するしかありません.

投稿2022/12/26 11:08

編集2023/01/10 22:25
PondVillege

総合スコア1579

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

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

PondVillege

2022/12/26 12:04 編集

mixupに関しては,画像変換において複数画像を持てるシーンが存在しなかったので,mixup用の画像ジェネレータを別でbatch_size = 1で生成してMyImageDataGeneratorに渡しておき,apply_transformで逐次mixupする方法を取るのが良さそうに見えます. とにかく,super().flow()では既にNumpyArrayIteratorを介して変換済み画像が返されており,これがジェネレータとして機能することから,これより前に画像を変換しようとすると,書き換えることになるのはNumpyArrayIterator._get_batches_of_transformed_samplesかapply_transformの二択になります. 前者であれば,変換対象のindex_arrayに対して,mixupに必要なもう一つの画像のindex_arrayを用意してやって,mixupをすることが可能に見えます.
semisemi

2023/01/09 09:00

返信遅れて申し訳ないです。 回答ありがとうございます。 前の質問に回答していただいた際の下記コードでMyImageDataGeneratorに組み込むことでbatch_size = 1を実装できていますか? def img(gen: ImageDataGenerator): for x, y in gen: yield x, y
PondVillege

2023/01/09 09:06

そうですね,それで組み合わせることが可能です
semisemi

2023/01/09 10:11

質問に追記いたしましたので確認いただけると幸いです。
PondVillege

2023/01/10 22:25

回答に追記しました.ImageDataGeneratorにMixUpを組み込むのは諦めた方が良さそうです.
semisemi

2023/01/13 05:14

ありがとうございます。 回答いただいた手法で学習を行ってみようと思います。
semisemi

2023/01/15 10:50 編集

この質問に関連する質問を投稿いたしましたのでできればアドバイスをいただけると幸いです よろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問