owned this note
owned this note
Published
Linked with GitHub
---
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/)