--- tags: 'ML notes' --- # Image Data Augmentation for Deep Learning ![](https://i.imgur.com/4ae5SbT.jpg) ## Based on basic image manipulations - 每一個 data augmentation 方法都應該考慮到其 safety - 舉例來說,若是在辨識ImageNet的圖片,就可以使用 rotation 或是 flip,但若是 Cifar 的手寫圖片辨識就不行,會造成 no safety ### Geometric transformations - 針對圖片的位置做操作 - 適合處理 positional bias,比如人臉辨識 - 包含 flipping, Cropping, Scaling, Rotation, Translation, Noise injection #### flipping - 翻轉圖片 - horizontal flip 比 vertical 更常見 - 最常見也最簡單的方法之一 ```python= # 為了簡化code, 範例皆假設已有 import albumentations as A A.Flip(p=0.5) # d=0: vertical flip, d=1: horizontal flip # d=-1: vertical and horizontal flipping A.VerticalFlip(p=0.5) A.HorizontalFlip(p=0.5) ``` #### Cropping - 可以裁切中間的一塊區域或是隨機裁切(random cropping),有可能會不是 label-preserving transformation,取決於 cropping 的 threshold ```python= A.Crop(x_min=0, y_min=0, x_max=1024, y_max=1024, always_apply=False, p=1.0) A.RandomCrop(height, width, always_apply=False, p=1.0) A.RandomSizedCrop(min_max_height, height, width, w2h_ratio=1.0, interpolation=1, always_apply=False, p=1.0) # min_max_heigth((int, int)) 為 crop size limit # RandomSizedCrop 的 height 和 width 為 crop 後圖片的尺寸 A.CenterCrop(height, width, always_apply=False, p=1.0) ``` #### Scaling - 在不改變圖片大小的前提下縮放圖片 - 可分成 scaled outward 或是 inward,前者是放大圖片,後者是縮小圖片 ```python= A.RandomScale(scale_limit=0.1, interpolation=1, always_apply=False, p=0.5) A.LongestMaxSize(max_size=1024, interpolation=1, always_apply=False, p=1) A.SmallestMaxSize(max_size=1024, interpolation=1, always_apply=False, p=1) ``` #### Rotation - 輕微的旋轉通常是 1~20 度或是 -1~-20度,若要再增加的話有可能造成 data 的 label 不再保有 post-transformation ```python= A.RandomRotate90(p=0.5) A.Rotate (limit=90, interpolation=1, border_mode=4, value=None, mask_value=None, always_apply=False, p=0.5) ``` #### Translation - Shifting images left, right, up, or down - Shift 之後所缺少的圖片空間可以用 0 或是 255 來填補起來或是用 random noise 跟 Gaussian noise - Padding 會保留 spatial dimensions of the image post-augmentation ```python= # 同時做 translation, scale, and rotate # limit 皆為其 factor 範圍,會自動 apply 為 (-limit, limit) # value 和 mask_value 皆為 padding value,取決於 border_mode A.ShiftScaleRotate (shift_limit=0.0625, scale_limit=0.1, rotate_limit=45, interpolation=1, border_mode=4,value=None, mask_value=None, shift_limit_x=None, shift_limit_y=None, always_apply=False, p=0.5) ``` ### Noise injection - 隨機插入 Gaussian noise, Salt and Pepper noise, Speckle Noise, ISO noise 之類的進去圖片作為隨機噪音 ![](https://i.imgur.com/oFBD2F7.jpg) ```python= # var_limit = variance range for noise # per_channel 若為 True,就會分別對每一個 channel 抽樣做 noise,若否則對全部 channel 一起抽樣做 A.GaussNoise (var_limit=(10.0, 50.0), mean=0, per_channel=True, always_apply=False, p=0.5) # multiplier 也可指定為單一數字,那就會直接乘上這個數字 A.MultiplicativeNoise (multiplier=(0.9, 1.1), per_channel=False, elementwise=False, always_apply=False, p=0.5) # color_shift = variance range for color hue change. Measured as a fraction of 360 degree Hue angle in HLS colorspace. # intensity = Multiplicative factor that control strength of color and luminace noise. A.ISONoise (color_shift=(0.01, 0.05), intensity=(0.1, 0.5), always_apply=False, p=0.5) ``` ### Color space transformations - 對 color channel 做操作,比如獨立切出一個 channel、對所有 channel 持續增加/減少一個常數數值 - 又稱 photometric transformations ![](https://i.imgur.com/eY81tlp.jpg) - 包含 Color jitter, Fancy PCA #### Color Jitter - 指的是 Random color manipulation 或是調整圖片的亮度、飽和度與對比度 (Brightness, Saturation, Contrast) - `albumentations.augmentations.transforms.ColorJitter (brightness=0.2, contrast=0.2, saturation=0.2, hue=0.2, always_apply=False, p=0.5)` - brightness = 從 [max(0, 1 - brightness), 1 + brightness] 隨機均勻抽一個數或是給定範圍 - contrast, saturation 算法同上 - hue = 從 [-hue, hue] 中隨機均勻抽一個數或是給定範圍 - [doc](https://albumentations.ai/docs/api_reference/augmentations/transforms/#albumentations.augmentations.transforms.ColorJitter) ```python= A.ColorJitter (brightness=0.2, contrast=0.2, saturation=0.2, hue=0.2, always_apply=False, p=0.5) ``` #### PCA Color Augmentation (Fancy PCA) - 首次出現在 2012 年 Krizhevsky, Sutskever & Hinton 的 AlexNet - 在 color channel 上面做 PCA,根據算出來的成分判斷出 RGB 的分布,並以此來決定增加的偏移量 - 例如圖片中 R 跟 G 成分較多,B 較少的時候在偏移的時候就會在 R 跟 G 加入較多偏移,在 B 加入更少偏移,使得圖片的整體色調不變 ![](https://i.imgur.com/QGLp5yt.jpg) ```python= # alpha 為 eigenvalue/eigenvector 的 scale facto, sampled from gaussian(mu=0, sigma=alpha) A.FancyPCA (alpha=0.1, always_apply=False, p=0.5) ``` #### Comparsion - 參考用 - 結果是有做 cropping 的結果最好 ![](https://i.imgur.com/isMzSzB.jpg) ### Kernel filters - 使用特定的 filter 對整張圖片做 Conv 來強化影像中的某些特徵並移除其他不想要的特徵,比如模糊(blur)、邊緣偵測(edge detection)、邊緣強化(edge enhancement)、噪點移除(noise removal) - 但 Kernel filter 的方法有點太像 CNNs 的運作,實際上更好的方法是直接變成網路中的一層 (反正都是做卷積操作),而不是用來做 data augmentation - **Blur :** GaussianBlur - **Edge detection :** Sobel Edge Detection (圖中上), Sobel Edge Detection on RGB (圖右上), Prewitt edge detection (圖左下), Laplacian Edge Detection (圖中下), Canny Edge Detection (圖右下) ![](https://i.imgur.com/JJy2B4I.jpg) - **Edge enhancement :** unsharp masking ![](https://i.imgur.com/KCgUkkF.jpg) - **Noise removal :** - Morphology - Opening: 先 erosion 再 dilation,用來消除細小的物體(noise),在細小的連接點處分開物體,平滑處理過後的物體邊界 - Closing: 先 dilation 再 erosion,去除小暗點(空洞),將物體中的小空缺填補起來 - Top Hat: 原圖 - 開運算圖,增強暗背景中的明亮物體 - Black Hat: 原圖 - 閉運算圖,增加明亮背景中的暗物體 - Mean Filter, Median filter ```python= # blur_limit 為最大 kernel size A.Blur (blur_limit=7, always_apply=False, p=0.5) A.MedianBlur (blur_limit=7, always_apply=False, p=0.5) # sigma_limit 為 Gaussian kernel standard deviation,若為單一值則為 (0, sigma_limit),若為 0 sigma 則為 sigma = 0.3*((ksize-1)*0.5 - 1) + 0.8 A.GaussianBlur (blur_limit=(3, 7), sigma_limit=0, always_apply=False, p=0.5) ``` ### Random erasing - 從 Dropout 獲得啟發 - 隨機去除掉圖片中的某個區域 - 可用來對抗 occlusion,也就是圖片中的某個區域過於不清楚的挑戰 - 有可能不是一個 label-preserving transformation (例如手寫辨識圖片的數字8被移除了一塊變成6) ![](https://i.imgur.com/bX8nSFc.jpg) ![](https://i.imgur.com/46iGVm6.jpg) - **CutOut, 2017:** 隨機將部分區域移除掉並以0填充 - **Random Erasing, 2017:** 隨機將部分區域移除掉並以隨機值或是平均值填充 - **Hide and Seek (HaS), 2017:** 將圖片切為 $S \times S$ 個 patches,每一個 patch 都根據機率 $P_{hide}$ 來決定是否遮蔽,然後輸入到 CNN 中訓練 - 可用在 Weak-Supervised Learning 來產生更多標註資料,given 圖片和 label 來訓練模型可以在測試資料集輸出 bounding box 和 label ![](https://i.imgur.com/xFUQ2AD.jpg) - **GridMask, 2020:** 根據 given parameter (r, d, δx, δy) 產生 mask,把 mask 與原圖做 multiply 疊加起來產生被遮罩的圖片 - r 是一個 unit 中 gray edge 的比例, d 是一個 unit 的長度 - δx 和 δy 是第一個完整 unit 和圖片邊界的距離 ![](https://i.imgur.com/1ujhxBM.png) ![](https://i.imgur.com/l14s6oR.jpg) - GridMask 的刪除區域不再是隨機不可控的,而是使用結構化的方式來刪除,這樣可以避免像 CutOut 移除一個連續的大區域也可以避免 HaS 的隨機性把 整個 label 刪除掉 - GridMask 為目前此類的 SOTA ![](https://i.imgur.com/CIZyRmH.jpg) ```python= A.dropout.cutout.Cutout (num_holes=8, max_h_size=8, max_w_size=8, fill_value=0, always_apply=False, p=0.5) # GridMask A.dropout.grid_dropout.GridDropout (ratio=0.5, unit_size_min=None, unit_size_max=None, holes_number_x=None, holes_number_y=None, shift_x=0, shift_y=0, random_offset=False, fill_value=0, mask_fill_value=None, always_apply=False, p=0.5) ``` [Random erasing in timm](https://fastai.github.io/timmdocs/RandomErase) ```python= from timm.data.random_erasing import RandomErasing # get input images and convert to `torch.tensor` X, y = input_training_batch() X = convert_to_torch_tensor(X) # perform RandomErase data augmentation random_erase = RandomErasing(probability=0.5) # get augmented batch X_aug = random_erase(X) ``` ### Mixing images - 把不同的圖片混合在一起 - 由於違反人類直覺,雖然很有效但缺乏可解釋性 ![](https://i.imgur.com/IDyBejr.jpg) - **MixUp, 2018:** 將圖片按照比例融合,label 按 pixel value 所佔比例輸出 ![](https://i.imgur.com/N8RyGLb.jpg) - 之後有衍伸出 MixMatch, Manifold mixup - **SamplePairing, 2018**: 隨機選兩個不同 label 的圖片做基本操作後 mixing ![](https://i.imgur.com/S7XXs42.jpg) - **[CutMix](https://arxiv.org/abs/1905.04899), 2019 (結合 MixUp 和 CutOut):** 隨機刪除一個區域並以另一張圖片的同一個位置的 pixel value 來填充,label 也根據 pixel value 所占比例輸出 - CutMix 為目前此類的 SOTA - [Mixup, Cutmix in timm](https://fastai.github.io/timmdocs/mixup_cutmix) ![](https://i.imgur.com/3M4JKtD.jpg) ![](https://i.imgur.com/kJSAj79.png) - 各種 mixing methods from [Improved Mixed-Example Data Augmentation](https://arxiv.org/pdf/1805.11272.pdf) ![](https://i.imgur.com/BbyEm50.png) ![](https://i.imgur.com/4RmXcDz.png) [mixed example 實作](https://github.com/ceciliaresearch/MixedExample/blob/master/mixed_example.py) ## Based on Deep Learning ### Feature space augmentation - 對 CNNs 擷取出來的 feature 做操作 - **SMOTE**: 用來解決 class imblance 的 augmentation 技巧,將整個 feature space 用 SMOTE 來產生相似的新 feature - 也能利用 auto encoder 將 new instance 轉回 input space,例如把 CNN 的 output layer拿掉,把得到的 feature (embeddings) 拿去訓練其他模型,產生出新的資料 - 缺點是 feature space augmentation 頂多只能用 auto-encoder 來解釋產生出來的 vector data,但這其實需要把整個 CNN 的 encoding part 複製一份出來,非常耗計算 ### Adversarial training - 利用兩個或多個在 loss function 中有 contrasting objectives 的網路來產生出新的資料 - 對抗式攻擊的效果在圖片解析度越高的時候越有效,能夠找出並加強分類模型較無法分類的弱點 (Weak Spots in decision boundary) ![](https://i.imgur.com/V9yvq0j.jpg) - 對抗式訓練雖然不會增加整體的 test accuracy,但可以增強模型面對到對抗式樣本時的 accuracy ![](https://i.imgur.com/NQqq9yR.jpg) - 另外也有些方法是產生出對抗式的 label,例如 [DisturbLabel, 2016](https://arxiv.org/abs/1605.00055) 就用另一個對抗式模型來隨機在每一個 iteration 取代掉訓練資料中的 label,並往取代之後會造成原模型的 error rate 最高去學習 - **對抗式訓練可以增加 noise 以及證明能讓模型更好處理對抗式樣本,但未必能減少模型的 overfitting** ### GAN‑based Data Augmentation - GANs 目前是生成式模型應用在 data augmentation 中最 promising 的領域 - DCGANs, Growing GANs, Conditional GANs ![](https://i.imgur.com/Wg5kJFy.jpg) - DCGANs : 用 CNNs 來做 generator 和 discriminator networks,架構是以 Deconvolution 反覆產生圖片,再將生成的圖片放入 discriminator 中訓練 ![](https://i.imgur.com/aIOZfc9.jpg) ![](https://i.imgur.com/kkaTeOC.jpg) - Progressive Growing GANs (PG-GAN): 先從解析度小的圖片開始訓練,再慢慢增大解析度 ![](https://i.imgur.com/9UqoBL7.jpg) ![](https://i.imgur.com/Q8tixU3.jpg) - Cycle GANs: 學習如何把一個領域的圖片轉換到另一個領域,比如把中立的人臉表情圖轉換到厭惡的人臉表情圖 ![](https://i.imgur.com/1Yynksr.jpg) ![](https://i.imgur.com/zPL7WXy.jpg) - t-SNE 可以用來了解 GAN-generated instance 和正常樣本的差別 ![](https://i.imgur.com/SIiRtDz.jpg) - Conditional GANs: 在 generator 和 discriminator 中加入 conditional vector 來緩解 mode collapse 問題 (產生很多看起來很像的 data 的問題) ![](https://i.imgur.com/RE1sVe2.jpg) - 除了以上幾種應用以外,GANs也能用來 oversampling 那些很少數的 sample,解決 class imblance 問題,例如 [DOPING, 2018](https://arxiv.org/abs/1808.07632) ![](https://i.imgur.com/1YC01ZJ.jpg) - 缺點是目前的 GANs 架構很難產生出高解析度的照片,若直接增加 output image size 很有可能導致訓練不穩定或是無法收斂,除此之外還有 **GANs 需要非常多的資料才有辦法訓練** ### Neural Style Transfer - 風格轉換的基本概念是操作 CNNs 所擷取出的 representation 來對圖片風格做轉換 - [Fast Style Transfer](https://arxiv.org/abs/1603.08155): 將 pixel-wise loss 改成 perceptual loss 並利用 feed-forward network 來轉換圖片的風格 - Perceptual loss 是指將真實圖片卷積和生成圖片卷積得到的 feature 做比較來算 loss ![](https://i.imgur.com/CniNkPF.jpg) ![](https://i.imgur.com/OF6nt58.jpg) - 如何選擇哪一個 style 來 sample 是 style transfer 的一大挑戰,比如自駕車需要 night-to-day scale, winter-to-summer, or rainy-to-sunny scale 的 transfer - 但 **Data Augmentation 為了實作上的方便,會挑選 k 個 styles 並 apply 到 training set 中的所有圖片上** - 在需要模擬的情境下,增強 Style transfer 中的 diversity 比盡全力模擬出現實環境還要有效率 - Neural Style Transfer Data Augmentation 最大的缺點是如何決定圖片要轉換的 styles 有哪些 - 假如 style set 太小,可能會引入更多的 bias 到 dataset 中 - 假如 style set 太大,又會造成計算量太大 ### Meta learning Data Augmentations - Meta-learning 的基本概念是訓練一個神經網路來優化神經網路 - [Neural Architecture Search, 2017](https://arxiv.org/abs/1611.01578) ![](https://i.imgur.com/apaJ8Iq.jpg) - Meta-learning for Data Aug-mentation 的方法不乏就是 mixing images, Neural Style Transfer, and geometric transformations ![](https://i.imgur.com/fDNeu11.jpg) - Meta-learning 的缺點是它仍是一個新領域並且研究還不夠多,除此之外它也非常 time-consuming to implement,所以我暫時不做深入研究 ## Comparing Augmentations [Research on data augmentation for image classification based on convolutional neural networks, 2017](https://ieeexplore.ieee.org/document/8243510) 在 CIFAR-10 和 ImageNet 中比較了 GANs, WGANs, flipping, cropping, shifting, PCA jittering, color jittering, adding noise, rotation 幾種方法的表現 - 單個方法來說,cropping, flipping, WGAN, and rotation 一般來講都比其他方法表現更好 - 混合方法來說,flipping+cropping 和 flipping + WGAN 表現最好 ## References - [A survey on Image Data Augmentation for Deep Learning](https://journalofbigdata.springeropen.com/track/pdf/10.1186/s40537-019-0197-0.pdf) - [Improving Deep Learning using Generic Data Augmentation](https://arxiv.org/pdf/1708.06020) - [What is PCA Color Augmentation?](https://aparico.github.io/) - [【影像處理】非銳化濾鏡 Unsharp Masking](https://jason-chen-1992.weebly.com/home/-unsharp-masking) - [Morphological Transformations in opencv](https://docs.opencv.org/4.5.3/d4/d76/tutorial_js_morphological_ops.html) - [数据增强 - Cutout、Random Erasing、Mixup、Cutmix](https://blog.csdn.net/irving512/article/details/113846570) - [Cutmix.. vs Mixup.. vs Gridmask ..vs Cutout... on Kaggle ](https://www.kaggle.com/saife245/cutmix-vs-mixup-vs-gridmask-vs-cutout#Cutout-data-augmentation) - [Survey: Image Mixing and Deleting for Data Augmentation](https://arxiv.org/pdf/2106.07085.pdf) - [albumentations docs](https://albumentations.ai/docs/api_reference/augmentations/) - [awesome-data-augmentation](https://brunokrinski.github.io/awesome-data-augmentation/)