前提・実現したいこと
物体検出ライブラリを使ったカメラ解析システムを作成しています。
システムのイメージとしては、監視カメラの映像から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のコードに直接追加すればいいのですが、自信がないため別途の処理にしようと考えています。
以上となります。
よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー