# Week 19: Data Augmentation 大補帖 ###### tags: `技術研討` # outlines 1. 實驗場景簡介 2. 各個 augmentation 的方法與實驗結果 3. 比較各個 augmentation 的特色 4. 針對本次使用場景的小建議 # 1. 實驗場景簡介 * 訓練模型:CRNN+CTC * 訓練專案別:cc_apa_ocr (信用卡自扣申請書辨識) * 訓練集:01.temp_labor + 02.template_matching + 03.yolo * 訓練 Epoch 數:100 * 訓練資料限制:總張數不超過 15 萬張 (原始資料 + augmentation 影像檔) <!-- * 記錄 GPU 用量 * 訓練 * epoch-loss 圖 * epoch-validation accuracy 圖 * augmentation 張數 --> # 2. 各個 augmentation 的方法與實驗結果 ## 2.1 實驗結果比較 * 各方法概述與最後成效 | Method | 說明 | 總training張數 | augmentaion 張數 | Testing Accuracy |實驗者 | | -------- | -------- | -------- | -------- | -------- |-------- | | Baseline | 未做 augmentation <br> epoch:101 | 72,403 | 0 | 0.9372 | 信賢 | | [image_augmentor](https://github.com/codebox/image_augmentor) | - 採用 blur 和 noise <br> - blur 設定 1.0、2.0 <br> - noise 設定 0.01、0.02 <br> - epoch:115 | 149,956 | 77,467 | 0.9264 |信賢 | | [Augmentor](https://github.com/mdbloice/Augmentor) |- random distoration <br> - random_brightness <br>- shear <br> - epoch:100 | 149,893 | 77,490 | 0.9273 |信賢 | | [imgaug](https://imgaug.readthedocs.io/en/latest/source/examples_basics.html) |針對每張圖片隨機應用2種方法:<br>- iaa.Add(-40, 40), per_channel=0.5)<br> - iaa.CoarseDropout((0.0, 0.02), size_percent=(0.02, 0.25))<br>- iaa.AdditiveGaussianNoise(scale=0.2*255)<br>- iaa.Sharpen(alpha=0.5)<br>iaa.Salt(0.1)<br>- iaa.JpegCompression(compression=(70, 99))<br>- iaa.AverageBlur(k=(2, 5))<br>iaa.Affline(scale=0.8, 1))<br>- iaa.Affline(translate_px={"x": (-20, 20), "y": (-20, 20)})<br>- iaa.Affline(rotate=(-5, 5))| 144,894 | 72,774 | 0.9407 | Lili | |[AutoAugmentation](https://github.com/DeepVoltaire/AutoAugment)|每張照片隨機從 subpolicy 選取 0 ~ 2 種方式做擴增|143,533|70,731|0.9218|昱睿| |[Text-Image-Augmentation](https://github.com/RubanSeven/Text-Image-Augmentation-python)|將影像至少進行扭曲、伸縮、透視一種的強化|144,806|72,403|0.9465|昊中| | [RandAugment](https://github.com/ildoonet/pytorch-randaugment) | 可直接使用 [imgaug](https://github.com/ildoonet/pytorch-randaugment) 達成 <br> 參數設定:n=2, m=4 | 144,806 | 72,403 | 0.9299 | 沛筠 | * 各 OCR 子項目成效 | Method | 04.acct_id | 06.bank_acct | 05.bank_code | 03.card_id | 08.post_acct | 07.post_number | avg | | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | | Baseline | 0.9413 | 0.9222 | 0.9670 | 0.9209 | 0.9333 | 0.9555 | 0.9372 | | image_augmentor | 0.9230 | 0.9083 | 0.9484 | 0.9242 | 0.9055 | 0.9555 | 0.9264 | | Augmentor | 0.9230 | 0.9097 | 0.9599 | 0.9176 | 0.9222 | 0.9388 | 0.9273 | | imgaug | 0.9286 | 0.9333 | 0.9685 | 0.9286 | 0.9556 | 0.9444 | 0.9407 | | AutoAugmentation | 0.9157 | 0.9041| 0.9556 | 0.9088 | 0.9166 | 0.9500 |0.9218| |Text-Image-Augmentation| 0.9340 | 0.9417 | 0.9599 | 0.9451 | 0.9444 | 0.9611 | 0.9465 | | RandAugment | 0.9212 | 0.9208 | 0.9542 | 0.9243 | 0.9056 | 0.9500 | 0.9299 | ## 0. Baseline - 訓練過程 ![](https://i.imgur.com/35dJ5jj.png) ![](https://i.imgur.com/GNkqtax.png) ## 1. [Augmentor](https://github.com/mdbloice/Augmentor) ### 1.1. 介紹 augmentation 使用與實驗場景 Augmentor 的目的是自動化圖像增強(人工數據生成),以便將數據集擴展為機器學習算法的輸入,尤其是神經網絡和深度學習。 - Elastic Distortions | No. | Input | Output | | -------- | -------- | -------- | | 1 | ![](https://i.imgur.com/IsCY9NY.png =100x100) | ![](https://i.imgur.com/OahEmK3.gif =100x100) | | 2 | ![](https://i.imgur.com/KMPTf1K.png =100x100) | ![](https://i.imgur.com/J4ieurb.gif =100x100) | - Perspective Transforms ![](https://i.imgur.com/GPCmrpC.png) - Size Preserving Rotations ![](https://i.imgur.com/rrt5r8O.png) - Size Preserving Shearing ![](https://i.imgur.com/oSH0chD.png) - Cropping ![](https://i.imgur.com/iiT3CXL.png) - Random Erasing | Input | Output | | -------- | -------- | | ![](https://i.imgur.com/CxNJryg.png =300x200) | ![](https://i.imgur.com/HtCDfAA.gif =300x200) | ### 1.2. 這次採用的方法 - 隨意扭曲(機率為1) - 隨意亮暗(機率為0.5) - 剪切(機率為0.5) 均從人力貼標裁切的圖片進行資料擴增,有03~08的類別,共6個資料夾 每一類產出12915張圖片,共77490張新資料 ![](https://i.imgur.com/4z9z60W.png) | No | 生成張數 | 時間(秒) | 速率(張/秒) | 方法 | | -------- | -------- | -------- |-------- |-------- | | 1 | 77490 | 1740 | 44.53 |distotion brighness shear | | 2 | 77490 | 1549 | 50.02 |distotion brighness shear (with multi-threaded)| ### 1.3 實驗 - 產生資料 一開始有加歪斜(機率為0.5),但發現有產生一些噪音,因此重新調整採用的方法 ![](https://i.imgur.com/nGmfBVe.png) ![](https://i.imgur.com/bSu0bgY.png) ![](https://i.imgur.com/m1MwpCz.png) > - 調整後訓練資料 ![](https://i.imgur.com/rhx6hYE.png) - 訓練過程 ![](https://i.imgur.com/K4duT8v.png) ![](https://i.imgur.com/EM93R8V.png) - 實驗結果 由於測試資料與訓練資料類似,使用方法太過於花俏會增加噪音。在扭曲的部分,綠底格線亦被扭區,因此下次測試可以將文字單獨做資料擴增並加上綠底背景,會比較像真實資料。 | Method | 04.acct_id | 06.bank_acct | 05.bank_code | 03.card_id | 08.post_acct | 07.post_number | avg | | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | | Baseline | 0.9413 | 0.9222 | 0.9670 | 0.9209 | 0.9333 | 0.9555 | 0.9372 | | Augmentor | 0.9230 | 0.9097 | 0.9599 | 0.9176 | 0.9222 | 0.9388 | 0.9273 | ### 1.4 使用方法 - 優點 - 套件下載 - 只需要指定要增強圖片所在的路徑即可,不用進行讀入、以及numpy數據轉換 - 搭配 pipeline 並支援 Multi-threading - API高度抽象;容易理解、上手! - 可以看進度啊然後去休息喝咖啡 - 支援產資料給 Generator(Generators for Keras and PyTorch) ``` python= # Keras g = p.keras_generator(batch_size=128) images, labels = next(g) # Pytorch import torchvision transforms = torchvision.transforms.Compose([ p.torch_transform(), torchvision.transforms.ToTensor(), ]) ``` ![](https://i.imgur.com/ztxqvBp.png) - 安裝 ``` pip install Augmentor ``` - 快速上手 ```python= import Augmentor # 1. 指定圖片所在目錄 p = Augmentor.Pipeline("./images", output_directory='output') # 2. 增強操作 # 旋轉 概率0.7,向左最大旋轉角度10,向右最大旋轉角度10 p.rotate(probability=0.7,max_left_rotation=10, max_right_rotation=10) # 放大 概率0.3,最小為1.1倍,最大為1.6倍;1不做變換 p.zoom(probability=0.3, min_factor=1.1, max_factor=1.6) # resize 同一尺寸 200 x 200 p.resize(probability=1,height=200,width=200) # 3. 指定增強後圖片數目總量 p.sample(2000) ``` - 其他資源 - [其他操作參考連結](https://blog.csdn.net/qq_33270279/article/details/103505589) - 佛心開發者給教學 - [Multiple-Mask-Augmentation](https://github.com/mdbloice/Augmentor/blob/master/notebooks/Multiple-Mask-Augmentation.ipynb) - [Augmentor_Keras](https://github.com/mdbloice/Augmentor/blob/master/notebooks/Augmentor_Keras.ipynb) - [Per_Class_Augmentation_Strategy](https://github.com/mdbloice/Augmentor/blob/master/notebooks/Per_Class_Augmentation_Strategy.ipynb) ## 2. imgaug ### 2.1. 安裝方式 非常的簡單,一行就結束 ```linux= pip install imgaug ``` ### 2.2 data augmentation 的種類 [直接看 GitHub 介紹頁](https://github.com/aleju/imgaug) ### 2.3 組合技 (推薦:thumbsup:) - Sequential (一個一個來,都會用到不要急) ```python= import imgaug.augmenters as iaa # two example images images = np.zeros((2, 128, 128, 3), dtype=np.uint8) aug = iaa.Sequential([ iaa.Crop(px=(1, 16), keep_size=False), iaa.Fliplr(0.5), iaa.GaussianBlur(sigma=(0, 3.0)) ]) images_aug = aug(images) ``` - OneOf (隨機選一個) ```python= import imgaug.augmenters as iaa # two example images images = np.zeros((2, 128, 128, 3), dtype=np.uint8) aug = iaa.OneOf([ iaa.GaussianBlur((0, 3.0)), # blur images with a sigma between 0 and 3.0 iaa.AverageBlur(k=(2, 7)), # blur image using local means with kernel sizes between 2 and 7 iaa.MedianBlur(k=(3, 11)), # blur image using local medians with kernel sizes between 2 and 7 ]) images_aug = aug(images) ``` - SomeOf (隨機選幾個) ```python= import imgaug.augmenters as iaa # two example images images = np.zeros((2, 128, 128, 3), dtype=np.uint8) aug = iaa.SomeOf((0, 2), [ iaa.GaussianBlur((0, 3.0)), # blur images with a sigma between 0 and 3.0 iaa.AverageBlur(k=(2, 7)), # blur image using local means with kernel sizes between 2 and 7 iaa.MedianBlur(k=(3, 11)), # blur image using local medians with kernel sizes between 2 and 7 ]) images_aug = aug(images) ``` 而且可以批次處理!!! ### 2.4 秒生成 data augmentation 的標籤 (超推薦:thumbsup::thumbsup::thumbsup:) #### [Bounding Box 的作法](https://nbviewer.jupyter.org/github/aleju/imgaug-doc/blob/master/notebooks/B02%20-%20Augment%20Bounding%20Boxes.ipynb) ![](https://i.imgur.com/W3oxP4x.png) ![](https://i.imgur.com/A0R26cw.png) #### [Polygon 的作法](https://nbviewer.jupyter.org/github/aleju/imgaug-doc/blob/master/notebooks/B03%20-%20Augment%20Polygons.ipynb) ![](https://i.imgur.com/SaT8czA.png) ![](https://i.imgur.com/U6IlG6z.png) but 這次用不到XD ### 2.5 本次測試用的作法 ```python= import imgaug.augmenters as iaa aug = iaa.SomeOf(2, [ iaa.Add((-40, 40), per_channel=0.5) # 調整亮度 (直接針對 pixel 數值做加減), iaa.CoarseDropout((0.0, 0.02), size_percent=(0.02, 0.25)), iaa.AdditiveGaussianNoise(scale=0.2*255), iaa.Sharpen(alpha=0.5), iaa.Salt(0.1), iaa.JpegCompression(compression=(70, 99)), iaa.AverageBlur(k=(2, 5)), iaa.Affline(scale=(0.8, 1)), iaa.Affline(translate_px={"x": (-20, 20), "y": (-20, 20)}), iaa.Affline(rotate=(-5, 5)) ]) ``` ### 2.6 模型成效 ![](https://i.imgur.com/QcubHFj.png) ![](https://i.imgur.com/KD30lol.png) | Method | 03.card_id | 04.acct_id | 05.bank_code | 06.bank_acct | 07.post_number | 08.post_acct | avg | | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | | Baseline | 0.9209 | 0.9413 | 0.9670 | 0.9222 | 0.9555 | 0.9333 | 0.9372 | | imgaug | 0.9286 | 0.9286 | 0.9685 | 0.9333 | 0.9444 | 0.9444 | 0.9407 | ## 3. AutoAugment ### 3.1 來源 * 論文連結:[AutoAugment: Learning Augmentation Policies from Data](https://arxiv.org/pdf/1805.09501v1.pdf) * github: [DeepVoltaire/AutoAugment](https://github.com/DeepVoltaire/AutoAugment) * 簡介:在訓練過程中得到一個參數,讓演算法知道 augmentation 的策略給予模型在 accuracy 上的幫助是多還是少,來決定要採取什麼樣的 augmentation 策略 (RL 的概念) * 限制:不過這個 RL 的演算法有點難開發,所以本次只有實驗他的 augmentation 方法 ### 3.2 說明 AutoAugmentation 是由一些基本的 subpolicy 組成,接著每張圖片進來都會被數個 subpolicy 的 augmentation 做轉換,並且選取適當的轉換幅度。所有的 subpolicy 有 (以程式碼表示) ```python= class SubPolicy(object): def __init__( self, p1: float, operation1: str, magnitude_idx1: int, p2: float, operation2: str, magnitude_idx2: int, fillcolor=(128, 128, 128), ): """ Args: p1: 執行第一種策略的機率值 (0 ~ 1 之間) operation1: 第一種策略名稱 (就是下面 ranges 的 keys 之一) magnitude_idx1: 執行策略一的幅度 (整數,選位置) p2: 執行第二種策略的機率值 (0 ~ 1 之間) operation2: 第二種策略名稱 (就是下面 ranges 的 keys 之一) magnitude_idx2: 執行策略二的幅度 (整數,選位置) fillcolor: 填補圖片顏色的 pixel 值 (預設是灰色) """ ranges = { "shearX": np.linspace(0, 0.3, 10), "shearY": np.linspace(0, 0.3, 10), "translateX": np.linspace(0, 150 / 331, 10), "translateY": np.linspace(0, 150 / 331, 10), "rotate": np.linspace(0, 30, 10), "color": np.linspace(0.0, 0.9, 10), "posterize": np.round(np.linspace(8, 4, 10), 0).astype(np.int), "solarize": np.linspace(256, 0, 10), "contrast": np.linspace(0.0, 0.9, 10), "sharpness": np.linspace(0.0, 0.9, 10), "brightness": np.linspace(0.0, 0.9, 10), "autocontrast": [0] * 10, "equalize": [0] * 10, "invert": [0] * 10, } func = { "shearX": ShearX(fillcolor=fillcolor), "shearY": ShearY(fillcolor=fillcolor), "translateX": TranslateX(fillcolor=fillcolor), "translateY": TranslateY(fillcolor=fillcolor), "rotate": Rotate(), "color": Color(), "posterize": Posterize(), "solarize": Solarize(), "contrast": Contrast(), "sharpness": Sharpness(), "brightness": Brightness(), "autocontrast": AutoContrast(), "equalize": Equalize(), "invert": Invert(), } self.p1 = p1 self.operation1 = func[operation1] self.magnitude1 = ranges[operation1][magnitude_idx1] self.p2 = p2 self.operation2 = func[operation2] self.magnitude2 = ranges[operation2][magnitude_idx2] def __call__(self, img): if random.random() < self.p1: img = self.operation1(img, self.magnitude1) if random.random() < self.p2: img = self.operation2(img, self.magnitude2) return img ``` #### 組合技 * 論文作者根據不同的實驗場景開發不同的 augmentation 組合技。以下以 ImageNet 為例 * 每次呼叫 ImageNetPolicy 時,會隨機選取其中一個 policy 執行;而這裡的每個 policy 都是由前述 subpolicy 實體化得出的函數 * 事實上,他可以被放在 Pytorh 的 transforms 裡面,這樣就會自己在訓練過程中生成 ```python= class ImageNetPolicy(object): """Randomly choose one of the best 24 Sub-policies on ImageNet. Example: >>> policy = ImageNetPolicy() >>> transformed = policy(image) Example as a PyTorch Transform: >>> transform = transforms.Compose([ >>> transforms.Resize(256), >>> ImageNetPolicy(), >>> transforms.ToTensor()]) """ def __init__(self, fillcolor=(128, 128, 128)): self.policies = [ SubPolicy(0.4, "posterize", 8, 0.6, "rotate", 9, fillcolor), SubPolicy(0.6, "solarize", 5, 0.6, "autocontrast", 5, fillcolor), SubPolicy(0.8, "equalize", 8, 0.6, "equalize", 3, fillcolor), SubPolicy(0.6, "posterize", 7, 0.6, "posterize", 6, fillcolor), SubPolicy(0.4, "equalize", 7, 0.2, "solarize", 4, fillcolor), SubPolicy(0.4, "equalize", 4, 0.8, "rotate", 8, fillcolor), SubPolicy(0.6, "solarize", 3, 0.6, "equalize", 7, fillcolor), SubPolicy(0.8, "posterize", 5, 1.0, "equalize", 2, fillcolor), SubPolicy(0.2, "rotate", 3, 0.6, "solarize", 8, fillcolor), SubPolicy(0.6, "equalize", 8, 0.4, "posterize", 6, fillcolor), SubPolicy(0.8, "rotate", 8, 0.4, "color", 0, fillcolor), SubPolicy(0.4, "rotate", 9, 0.6, "equalize", 2, fillcolor), SubPolicy(0.0, "equalize", 7, 0.8, "equalize", 8, fillcolor), SubPolicy(0.6, "invert", 4, 1.0, "equalize", 8, fillcolor), SubPolicy(0.6, "color", 4, 1.0, "contrast", 8, fillcolor), SubPolicy(0.8, "rotate", 8, 1.0, "color", 2, fillcolor), SubPolicy(0.8, "color", 8, 0.8, "solarize", 7, fillcolor), SubPolicy(0.4, "sharpness", 7, 0.6, "invert", 8, fillcolor), SubPolicy(0.6, "shearX", 5, 1.0, "equalize", 9, fillcolor), SubPolicy(0.4, "color", 0, 0.6, "equalize", 3, fillcolor), SubPolicy(0.4, "equalize", 7, 0.2, "solarize", 4, fillcolor), SubPolicy(0.6, "solarize", 5, 0.6, "autocontrast", 5, fillcolor), SubPolicy(0.6, "invert", 4, 1.0, "equalize", 8, fillcolor), SubPolicy(0.6, "color", 4, 1.0, "contrast", 8, fillcolor), SubPolicy(0.8, "equalize", 8, 0.6, "equalize", 3, fillcolor), ] def __call__(self, img): policy_idx = random.randint(0, len(self.policies) - 1) return self.policies[policy_idx](img) def __repr__(self): return "AutoAugment ImageNet Policy" ``` #### 各個 Subpolicy 介紹 ##### 1. Shear (碾壓) * 固定圖片的一個邊在座標軸上,另一個邊往正向或負向移動 * X 方向 ![](https://i.imgur.com/gnKOPmh.png) * Y 方向 ![](https://i.imgur.com/N2dG1lJ.png) ##### 2. Translate (平移) * X 方向 ![](https://i.imgur.com/5ajgG4n.png) * Y 方向 ![](https://i.imgur.com/7CeGBQX.png) ##### 3. Rotate (旋轉) * 這邊要注意的是「角度」對我們應用場景的影響是多少 ![](https://i.imgur.com/QLWCpwZ.png) ##### 4. Color * 改變 RGB 的平衡 * 數值 > 0 就會把 RGB 提高 * 數值 < 0 會把有種把 RGB invert 的感覺 (紅變綠,紫變黃,...) ![](https://i.imgur.com/9aIdoWO.png) ##### 5. Posterize * 海報化:會發現 pixel 的顆粒度變粗,經常用於找 contour 的前處理 ![](https://i.imgur.com/AMbX0uY.png) ##### 6. Contrast (對比) * 運用調整 RGB 或者 HSL 來使圖片中的各個輪廓更鮮明 ![](https://i.imgur.com/nisoSUc.png) ##### 7. Sharpeness * 針對 pixel 計算 gradient 來評估這個位置要改變的數字。 gradient 越低代表有點模糊,所以不太尖銳 (sharp)。sharp 的目的是讓解析度看起來好一點,比較有分明 ![](https://i.imgur.com/NVahODb.png) ##### 8. Brightness * 其實就是增加 HSL 的 L 那個維度的值 ![](https://i.imgur.com/kJraxzJ.png) ##### 9. AutoContrast * 根據影像中的最高亮度來調整 contrast 的幅度,而非一開始的絕對值 ![](https://i.imgur.com/yvrqO8B.png) ##### 10. Equal * 讓圖片的 histgram 變得比較平緩 ![](https://i.imgur.com/oMSwGyZ.png) ##### 11. Invert * 就是整張圖片的 pixel 變成是 `255 - pixel`,所以顏色有顛倒的感覺 ![](https://i.imgur.com/XVQ5t0n.png) ### 3.3 實作範例 * 因為我們的應用場景與論文實驗的資料不太一樣,所以我們是採取組合技中的組合技 * 有一個要注意的事情,就是因為我們的應用場景是 OCR ,所以我們不能讓圖片失真太多,比如說因為平移旋轉而少了 1, 2 個字,所以這邊其實我們在 magnitude 上有縮小他的幅度,主要縮小的有 * Shear: 輾壓程度為原預設的 <font color='red'>**1/10**</font> * Rotate: 旋轉角度為原本預設的 <font color='red'>**1/10**</font> * Translate: 平移單位為原本預設的 <font color='red'>**1/10**</font> ```python= from autoaugment import ImageNetPolicy, CIFAR10Policy, SHVNPolicy image_net_policy = ImageNetPolicy() cifar10_policy = CIFAR10Policy() svhn_policy = SHVNPolicy() option_list = ['image_net', 'cifar10', 'shvn'] augmentation_dict = { 'image_net', image_net_policy, 'cifar10': cifar10_policy, 'svhn': svhn_policy } def get_transformed_image(image: np.ndarray): option = random.sample(option_list, 1)[0] transformed_image = np.array( augmentation_dict[option].__call__(Image.fromarray(image)) ) return transformed_image ``` ### 3.4 實驗結果 * 訓練過程的 loss 以及 validation accuracy ![](https://i.imgur.com/gslyacC.jpg) * 最終成效:<font color='blue'>**92.18%**</font> | Method | 04.acct_id | 06.bank_acct | 05.bank_code | 03.card_id | 08.post_acct | 07.post_number | avg | | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | | Baseline| 0.9413 | 0.9222 | 0.9670 | 0.9209 | 0.9333 | 0.9555 | 0.9372 | | AutoAugment| 0.9157 | 0.9041| 0.9556 | 0.9088 | 0.9166 | 0.9500 |0.9218| ### 3.5 個人小結語 * **AutoAugment** 方法的特色在於有個參數可以讓 <font color='red'>RL</font> 模型找到最好的 augmentation 策略,只拿來用產資料的工具似乎就很普通了 * **AutoAugment** 很多 policy 都是在<font color='green'>**顏色轉換**</font>;但本應用場景的 testing data 與 training data 在顏色與光澤上相當一致。因此用<font color='green'>**顏色轉換**</font>所產出來的資料不一定會有幫助 * 這個方法在 cifar10 或 imageNet 預測動物上比較有幫助。個人推測是因為 1. 同一種動物但是如果 training data 與 testing data 的顏色不同,可以使用 AutoAugment 補足 2. training data 與 testing data 在白天晚上的差別,可以用 Invert 解決 3. 動物的動作、移動位置可以被 shear, translate, rotate 等方法補足 ## 4. Text-Image-Augmentation ### 4.1 介紹 augmentation 使用與實驗場景 * Text-Image-Augmentation 主要是實現 Week 14 所介紹的 augmentation ([paper](https://arxiv.org/pdf/2003.06606.pdf)) 結果。 ![](https://i.imgur.com/FcyERVB.jpg) ![](https://i.imgur.com/EMlNKZ7.jpg) * 使用方法: ```python= # 一共有三種augmentation效果 from augment import distort, stretch, perspective im = cv2.imread(".png") # 影像切割個數 segment = 4 # 實現影像扭曲 distort_img = distort(im, segment) # 實現影像左右伸縮 stretch_img = stretch(im, segment) # 實現影像透視效果 perspective_img = perspective(im) ``` * 使用效果範例: * original: ![](https://i.imgur.com/VUqVLLk.png) * distort: ![](https://i.imgur.com/HyjA7wH.jpg) * stretch: ![](https://i.imgur.com/fjb2fCM.jpg) * perspective: ![](https://i.imgur.com/KZRkD7Y.jpg) ### 4.2 實現方法與結果 * 將原dataset上的每一張image套用只少一種的augmentation效果 ```python= ''' 1: 使用效果 0: 不使用效果 [0, 0, 0] 重新random 依[distort(), stretch(), perspective()]順序疊加實現 ''' np.random.randint(2, size=3) ``` * Dataset實驗結果 * original: ![](https://i.imgur.com/HiBfwyG.jpg) * distort: ![](https://i.imgur.com/jenC1RJ.jpg) * stretch: ![](https://i.imgur.com/pj5cCgc.jpg) * perspective: ![](https://i.imgur.com/1LyOIdQ.jpg) * 模型實驗結果 | Method | 04.acct_id | 06.bank_acct | 05.bank_code | 03.card_id | 08.post_acct | 07.post_number | avg | | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | | Baseline | 0.9413 | 0.9222 | 0.9670 | 0.9209 | 0.9333 | 0.9555 | 0.9372 | |Text-Image-Augmentation| 0.9340 | 0.9417 | 0.9599 | 0.9451 | 0.9444 | 0.9611 | 0.9465 | ![](https://i.imgur.com/sHcK1HA.jpg) ## 5. RandAugment [[paper]](https://arxiv.org/pdf/1909.13719.pdf) ### 5.1 簡介 AutoAugment 成效雖好,但它搜尋 augmentation policies 的運算量高,transfer 至其他資料集時也只是次佳解。 例如在 COCO dataset 上,RandAugment 的表現與 AutoAugment 類似,但 search space 卻差距極大。 ![](https://blog.kakaocdn.net/dn/PGuRT/btqEtNoFIc3/brvKKxI24OJpnd4EAyFF3k/img.png) 因此,作者再提出以兩個參數控制 policies(減少計算),並獲得相近結果的 RandAugment。 n:假設機率相同,在 K 種方法內挑選 n 種方法作為 policy(共有 $K^n$ 種組合) m:強度 ![](https://d3i71xaburhd42.cloudfront.net/dfa553707b215910f028d2a58ab79116626cc94a/3-Figure2-1.png) ### 5.2 使用與實驗場景 - [imgaug](https://imgaug.readthedocs.io/en/latest/source/api_augmenters_collections.html#imgaug.augmenters.collections.RandAugment) - 簡便 - p=50% 的默認水平翻轉和裁切 - pytorch 版的延伸 ```python= import imgaug.augmenters as iaa aug = iaa.RandAugment(n=2, m=9) ``` - [tensorflow](https://github.com/tensorflow/tpu/blob/1ebfc4b5fa6b5fad0bd7d422832ae8826e8059f2/models/official/efficientnet/autoaugment.py) - 需注意版本 ```python= def distort_image_with_randaugment(image, num_layers, magnitude): ``` - [pytorch](https://github.com/ildoonet/pytorch-randaugment/blob/master/RandAugment/augmentations.py) - 本次使用的程式碼 - 無 p=50% 的默認水平翻轉和裁切 - 微調數值範圍,使圖片文字盡量完整 - 設置 n = 2、m = 4 ```python= class RandAugment: def __init__(self, n, m): self.n = n self.m = m # [0, 30] self.augment_list = augment_list() def __call__(self, img): ops = random.choices(self.augment_list, k=self.n) for op, minval, maxval in ops: val = (float(self.m) / 30) * float(maxval - minval) + minval img = op(img, val) return img ``` ### 5.3 方法 ```python= def augment_list(): # 16 oeprations and their ranges l = [ (AutoContrast, 0, 1), (Equalize, 0, 1), (Invert, 0, 1), (Rotate, 0, 10), #(Rotate, 0, 30) (Posterize, 0, 4), (Solarize, 0, 256), (SolarizeAdd, 0, 110), (Color, 0.1, 1.9), (Contrast, 0.1, 1.9), (Brightness, 0.1, 1.9), (Sharpness, 0.1, 1.9), (ShearX, 0., 0.3), (ShearY, 0., 0.3), (CutoutAbs, 0, 40), (TranslateXabs, 0., 50), #(TranslateXabs, 0., 100) (TranslateYabs, 0., 50), #(TranslateYabs, 0., 100) ] ``` #### 範例 當 n = 2,而 m 分別為 9、17 和 28 的情況: ![](https://d3i71xaburhd42.cloudfront.net/dfa553707b215910f028d2a58ab79116626cc94a/3-Figure1-1.png) ### 5.4 實驗結果 #### 本次實驗的 RandAugment(n=2, m=4) 效果 * AutoContrast + Rotate ![](https://i.imgur.com/X0gtWc3.jpg) * Rotate + TranslateXabs ![](https://i.imgur.com/72nuhDK.jpg) * TranslateXabs + TranslateYabs ![](https://i.imgur.com/hXZ3WM7.jpg) #### model accuracy 和 training loss (epoch 80~) ![](https://i.imgur.com/jLU8p7O.jpg) #### testing accuracy:0.9299 # 3. 比較各個 augmentation 的特色 | Method | 特色 | 來源 | 推薦度 | | -------- | -------- | -------- | -------- | | Augmentor | 1.套件下載 <br> 2.只需指定所在的路徑即可 <br> 3. 組合技 <br> 4.API高度抽象 <br> 5.可以看進度條 <br> 6. 可以設計每個方法的機率 <br> 7. mutli-threaded 產圖片很快 <br> 8.開發者github寫得很完整有教學 <br> 9.支援直接產資料給generator| [link](https://github.com/mdbloice/Augmentor) | :star::star::star::star:| | | imgaug | 1.套件一鍵安裝 <br> 2.可以使用各種組合技 <br> 3.可以批次處理 <br> 4.可以秒產出對應的標籤 | [aleju/imgaug](https://github.com/aleju/imgaug) | :star::star::star::star: | | AutoAugment |1. 組合技都寫好了,import 即可 <br>2. 這個組合技可以直接放到 torchvision.transforms 裏面,變成 RL 的流程之一<br>3. 但感覺對於分類問題的幫助較大,因為論文也是在分類問題獲得好的成效<br>4. 裡面有很多是顏色轉換,使用者要根據場景去刪減或調整 policy 的種類或者改變幅度|[DeepVoltaire/AutoAugment](https://github.com/DeepVoltaire/AutoAugment)|1. 我覺得使用方式滿簡單的<br>2. 不過看起來好像對分類問題的提升比較有幫助| |Text-Image-Augmentation| 1.只需import即可實現增強功能 <br> 2.需要一點前置實驗確保影像效果 <br> 3.專門增強文字影像,有良好成效|[Text-Image-Augmentation-python](https://github.com/RubanSeven/Text-Image-Augmentation-python)|文字影像很容易馬上實現明顯的變化| | RandAugment | 1. 降低搜尋計算量 <br> 2. 或許更適用在影像分類 | [ildoonet/pytorch-randaugment](https://github.com/ildoonet/pytorch-randaugment/blob/master/RandAugment/augmentations.py) | Text | # 4. 針對本次使用場景的小建議 * 資料是 machine learning :desktop_computer: 的根本,但也不是多多益善,還是要根據預測目的以及模型缺點對症下藥 * 以這個專案的場景 * 適合的內容 * 文字變形 (distort, perspective transform) * 遮擋 (加一點點黑點之類的) * 小角度旋轉 * 不適用 * flip (根據 y 軸或者 x 軸翻轉) * 過大的 rotation * 顏色過大的轉換 (e.g. 黑 -> 白)