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

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

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

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

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

YOLO

YOLOとは、画像検出および認識用ニューラルネットワークです。CベースのDarknetというフレームワークを用いて、画像や動画からオブジェクトを検出。リアルタイムでそれが何になるのかを認識し、分類することができます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

Q&A

解決済

1回答

3250閲覧

YOLOv3におけるDataAugmentationについて

haru135

総合スコア3

Keras

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

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

YOLO

YOLOとは、画像検出および認識用ニューラルネットワークです。CベースのDarknetというフレームワークを用いて、画像や動画からオブジェクトを検出。リアルタイムでそれが何になるのかを認識し、分類することができます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

0グッド

0クリップ

投稿2020/09/01 05:58

編集2020/09/01 06:10

前提・実現したいこと

物体検出ライブラリを使ったカメラ解析システムを作成しています。
システムのイメージとしては、監視カメラの映像からYOLOv3によって映像内にいる人間の領域を抽出し、その後映っている人間の見た目の属性(年齢、性別、服装など)を別のモデルで推測するようなものです。

現在データの収集とモデルの学習を並行して行っているのですが、データ不足のためか推論性能が十分ではありません。そこで、学習用データに対して上下左右の反転、回転、色調変化などの処理を行うDataAugmentationの実施を検討しています。

発生している問題

YOLOv3の実装についてあらためて調べてみたところ、私が検討していた「学習用データに事前にDataAugmentataionしておく方法(Preprocess Augmentataion)」とは別に「学習時にコード内でDataAugmentationを行う方法(Realtime Augmentation)」がとられていることに気が付きました。
元のdarknetの実装の場合は以下のサイトで解説されているとおりです。

YOLO V3: Darknetのデータ拡張 https://demura.net/robot/athome/15558.html

私が参考にしているkeras実装(keras-yolo3; https://github.com/qqwweee/keras-yolo3)では"yolo3\utils.py"内のget_random_data()のコードがRealTime Augmentationを行っている部分であるように思われます。

Does it perform data augmentation by default? Is it possible to do real time data augmentation, such as rotation , zoom (1-10%) horizontal and vertical flipping. ) #509
https://github.com/qqwweee/keras-yolo3/issues/509

utils

1def get_random_data(annotation_line, input_shape, random=True, max_boxes=20, jitter=.3, hue=.1, sat=1.5, val=1.5, proc_img=True): 2 '''random preprocessing for real-time data augmentation''' 3 line = annotation_line.split() 4 image = Image.open(line[0]) 5 iw, ih = image.size 6 h, w = input_shape 7 box = np.array([np.array(list(map(int,box.split(',')))) for box in line[1:]]) 8 9 if not random: 10 # resize image 11 scale = min(w/iw, h/ih) 12 nw = int(iw*scale) 13 nh = int(ih*scale) 14 dx = (w-nw)//2 15 dy = (h-nh)//2 16 image_data=0 17 if proc_img: 18 image = image.resize((nw,nh), Image.BICUBIC) 19 new_image = Image.new('RGB', (w,h), (128,128,128)) 20 new_image.paste(image, (dx, dy)) 21 image_data = np.array(new_image)/255. 22 23 # correct boxes 24 box_data = np.zeros((max_boxes,5)) 25 if len(box)>0: 26 np.random.shuffle(box) 27 if len(box)>max_boxes: box = box[:max_boxes] 28 box[:, [0,2]] = box[:, [0,2]]*scale + dx 29 box[:, [1,3]] = box[:, [1,3]]*scale + dy 30 box_data[:len(box)] = box 31 32 return image_data, box_data 33 34 # resize image 35 new_ar = w/h * rand(1-jitter,1+jitter)/rand(1-jitter,1+jitter) 36 scale = rand(.25, 2) 37 if new_ar < 1: 38 nh = int(scale*h) 39 nw = int(nh*new_ar) 40 else: 41 nw = int(scale*w) 42 nh = int(nw/new_ar) 43 image = image.resize((nw,nh), Image.BICUBIC) 44 45 # place image 46 dx = int(rand(0, w-nw)) 47 dy = int(rand(0, h-nh)) 48 new_image = Image.new('RGB', (w,h), (128,128,128)) 49 new_image.paste(image, (dx, dy)) 50 image = new_image 51 52 # flip image or not 53 flip = rand()<.5 54 if flip: image = image.transpose(Image.FLIP_LEFT_RIGHT) 55 56 # distort image 57 hue = rand(-hue, hue) 58 sat = rand(1, sat) if rand()<.5 else 1/rand(1, sat) 59 val = rand(1, val) if rand()<.5 else 1/rand(1, val) 60 x = rgb_to_hsv(np.array(image)/255.) 61 x[..., 0] += hue 62 x[..., 0][x[..., 0]>1] -= 1 63 x[..., 0][x[..., 0]<0] += 1 64 x[..., 1] *= sat 65 x[..., 2] *= val 66 x[x>1] = 1 67 x[x<0] = 0 68 image_data = hsv_to_rgb(x) # numpy array, 0 to 1 69 70 # correct boxes 71 box_data = np.zeros((max_boxes,5)) 72 if len(box)>0: 73 np.random.shuffle(box) 74 box[:, [0,2]] = box[:, [0,2]]*nw/iw + dx 75 box[:, [1,3]] = box[:, [1,3]]*nh/ih + dy 76 if flip: box[:, [0,2]] = w - box[:, [2,0]] 77 box[:, 0:2][box[:, 0:2]<0] = 0 78 box[:, 2][box[:, 2]>w] = w 79 box[:, 3][box[:, 3]>h] = h 80 box_w = box[:, 2] - box[:, 0] 81 box_h = box[:, 3] - box[:, 1] 82 box = box[np.logical_and(box_w>1, box_h>1)] # discard invalid box 83 if len(box)>max_boxes: box = box[:max_boxes] 84 box_data[:len(box)] = box 85 86 return image_data, box_data

一方で、"yolov3.cfg"にもdarknet実装と類似したパラメータとしてsaturation, exposure, hue, jitter, randomが残されています。

質問内容

自分でもコードを追いながら考えてみたのですが、確信がもてなかったため以下の点について教えていただけないでしょうか。

質問1.
kears実装においてRealtime Augmentationで行われている具体的な処理はget_random_data()に含まれる以下の内容で合っているでしょうか。
・resize image(画像サイズの変更)
・place image(画像位置の変更)
・flip image or not(左右の反転)
・distort image(色相、彩度、明度の変更)

質問2.
Realtime Augmentationとして行われている処理が質問1の内容のとき、それ以外の処理(上下の反転、回転)を自分でPreprocess Augmentationとして行ったデータを学習に加えることは意味があるでしょうか。
本当はRealtime Augmentationのコードに直接追加すればいいのですが、自信がないため別途の処理にしようと考えています。

以上となります。
よろしくお願いいたします。

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

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

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

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

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

shocora

2020/12/15 09:20

質問への追記です。keras実装のRealtime Augmentationでは、元の学習画像に対してそれぞれの処理分1枚ずつ水増しが行われているという認識であっているのでしょうか。また、画像の反転の処理を止めたいのですが、その場合、flip imageに関するコードを削除すればよいのでしょうか。
haru135

2020/12/16 05:01

勉強中の立場なので合っているか分かりませんが、一応書きます。 どなたか詳しい方が追記してくださるといいのですが……。 > keras実装のRealtime Augmentationでは、元の学習画像に対してそれぞれの処理分1枚ずつ水増しが行われているという認識であっているのでしょうか。 get_random_data()とdata_generator()のコードを読む限り、訓練データ1枚ごとにRealtime augmentationが行われているように私には見えます。 ただし、元の画像と水増し画像の両方が訓練データとして保存されているかはコードからは分かりませんでした。両方とも保存しないと訓練データの総数が増えないですが、data_generator()を読むと水増し画像しか保存されていないような……? > 画像の反転の処理を止めたいのですが、その場合、flip imageに関するコードを削除すればよいのでしょうか。 実際に試してはいませんが、flip image部分のコードは他の処理には干渉していないと思うので、utils.pyのL88-89を削除するだけでいい気がします。 flip = rand()<.5 if flip: image = image.transpose(Image.FLIP_LEFT_RIGHT) コードを丸ごと消すのに抵抗があれば、flip = rand()<.5 の閾値を変えることでflipが生じないようにしてもいいと思います。
shocora

2020/12/16 09:44

回答ありがとうございます。 Realtime augmentationでの処理として、例えば1枚の元画像が入力されたとき、resize_image,place_image,flip_image,distort_imageでflip_imageとdistort_imageをしきい値を変更して無効化したら、水増しした画像4枚が出力され、その内2枚は元画像と同じものが残るということなのでしょうか。 flip image部分のコードは削除すると、utils.pyのL114の以下のコードに影響してしまって動作しなかったので、flip = rand()<.0に変更して動かすことにしました。 L114: if flip: box[:, [0,2]] = w - box[:, [2,0]]
haru135

2020/12/17 09:38

直接の回答にはなっていないかもしれませんが、改めてコードを追って考えたことを共有します。私自身初心者なので合っているとは限りませんので、参考程度に読んでくださると幸いです。 なお、新規のトピックのほうが気づかれやすいので、shocoraさんが気になるところだけ取り出して新しくトピックを立てたほうが詳しい方が気づいてくれるかもしれません。力不足で申し訳ないです……。 >Realtime augmentationでの処理として、例えば1枚の元画像が入力されたとき、resize_image,place_image,flip_image,distort_imageでflip_imageとdistort_imageをしきい値を変更して無効化したら、水増しした画像4枚が出力され、その内2枚は元画像と同じものが残るということなのでしょうか。 get_random_data()では入力画像1枚(image)に乱数に応じてresize、place、flip、distortの4つの処理を連続的に施し、最終的に処理済みの画像1枚(image_data)と処理済みのアノテーション座標1つ(box_data)を生成しています。この処理はランダムな画像を生成するためのものであって、画像の枚数は増えていません。途中の4つの処理のいずれかを無効化しても出てくる画像は1枚であり、生じる画像のバリエーションが減るだけです。 keras-yolo3のモデル学習はfit_generator()を使っているので、ジェネレータによりバッチ毎に生成されたデータでモデルを訓練します(https://keras.io/ja/models/model/)。自信はないのですが、たぶん以下のような手順かと推測します。 1) ジェネレーターであるdata_generator()が訓練データから指定のバッチサイズのデータを取り出し、get_random_data()によってランダムに処理されたデータ群(n=バッチサイズ)を生成する。 2) fit_generator()がこの処理済みのデータ群を受け取り学習を行う。 3) バッチ単位で1)と2)を繰り返していき、最終的に訓練データすべてからランダム処理されたデータ群が生成されてモデル学習に用いられる。 4) 1)-3)をエポック数だけ繰り返し、損失関数が収束したら終了。 したがって、1)-3)では1枚の画像から1枚の画像しか生み出されておらずデータ量は増えませんが、4)でエポック数だけ繰り返しが生じることで水増しが達成されているのかなと思っています。 > flip image部分のコードは削除すると、utils.pyのL114の以下のコードに影響してしまって動作しなかったので、flip = rand()<.0に変更して動かすことにしました。 L114: if flip: box[:, [0,2]] = w - box[:, [2,0]] すみません、私の確認不足でした。画像のAugmentationに応じてアノテーションの座標も動かす必要があるのでL114以下のコードに干渉してましたね。
shocora

2020/12/18 13:28

ご丁寧に回答ありがとうございます。 get_random_data()の最後のreturnで複数画像を返してるとは思えなかったので、処理の流れを理解できてスッキリしました。ありがとうございます。 また自分でもコードを見直し、理解を深めようと思います。
guest

回答1

0

ベストアンサー

kears実装においてRealtime Augmentationで行われている具体的な処理はget_random_data()に含まれる以下の内容で合っているでしょうか。

合ってます。

Realtime Augmentationとして行われている処理が質問1の内容のとき、それ以外の処理(上下の反転、回転)を自分でPreprocess Augmentationとして行ったデータを学習に加えることは意味があるでしょうか。

推論時の入力として上下反転や回転している場合もあるなら、意味はあると思います。
例えば、人の検出であれば、上下反転した画像が入力されることはないと思うので、そうであればあまり有効ではないと思います。

投稿2020/09/01 10:21

編集2020/09/01 10:22
tiitoi

総合スコア21956

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

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

haru135

2020/09/01 14:27

tiitoiさん、いつもご回答いただきありがとうございます。 ご指摘の通り、推論時を想定したAugmentationでないと有効でないですね。 上下反転は不要そうなので、回転に絞って試してみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問