PaddleClas-圖像分類中的8種數據增廣方法(cutmix, autoaugment,..)

本文主要來源於PaddleClas這個代碼倉庫中的數據增廣文檔:https://github.com/PaddlePaddle/PaddleClas/blob/master/docs/zh_CN/advanced_tutorials/image_augmentation/ImageAugment.md

一、數據增廣

在圖像分類任務中,圖像數據的增廣是一種常用的正則化方法,常用於數據量不足或者模型參數較多的場景。PaddleClas中將對除 ImageNet 分類任務標準數據增廣外的8種數據增廣方式進行簡單的介紹和對比,這8種數據增廣方式在ImageNet上的精度指標如下所示。

在這裏插入圖片描述

二、常用數據增廣方法

ImageNet 分類訓練階段的標準數據增廣方式分爲以下幾個步驟:

  1. 圖像解碼:簡寫爲 ImageDecode
  2. 隨機裁剪到長寬均爲 224 的圖像:簡寫爲 RandCrop
  3. 水平方向隨機翻轉:簡寫爲 RandFlip
  4. 圖像數據的歸一化:簡寫爲 Normalize
  5. 圖像數據的重排,[224, 224, 3] 變爲 [3, 224, 224]:簡寫爲 Transpose
  6. 多幅圖像數據組成 batch 數據,如 batch-size[3, 224, 224] 的圖像數據拼組成 [batch-size, 3, 224, 224]:簡寫爲 Batch

相比於上述標準的圖像增廣方法,研究者也提出了很多改進的圖像增廣策略,這些策略均是在標準增廣方法的不同階段插入一定的操作,基於這些策略操作所處的不同階段,PaddleClas中將其分爲了三類:

  1. RandCrop 後的 224 的圖像進行一些變換: AutoAugment,RandAugment
  2. Transpose 後的 224 的圖像進行一些裁剪: CutOut,RandErasing,HideAndSeek,GridMask
  3. Batch 後的數據進行混合: Mixup,Cutmix

具體如下表所示:

變換方法 輸入 輸出 Auto-
Augment[1]
Rand-
Augment[2]
CutOut[3] Rand
Erasing[4]
HideAnd-
Seek[5]
GridMask[6] Mixup[7] Cutmix[8]
Image
Decode
Binary (224, 224, 3)
uint8
Y Y Y Y Y Y Y Y
RandCrop (:, :, 3)
uint8
(224, 224, 3)
uint8
Y Y Y Y Y Y Y Y
Process (224, 224, 3)
uint8
(224, 224, 3)
uint8
Y Y - - - - - -
RandFlip (224, 224, 3)
uint8
(224, 224, 3)
float32
Y Y Y Y Y Y Y Y
Normalize (224, 224, 3)
uint8
(3, 224, 224)
float32
Y Y Y Y Y Y Y Y
Transpose (224, 224, 3)
float32
(3, 224, 224)
float32
Y Y Y Y Y Y Y Y
Process (3, 224, 224)
float32
(3, 224, 224)
float32
- - Y Y Y Y - -
Batch (3, 224, 224)
float32
(N, 3, 224, 224)
float32
Y Y Y Y Y Y Y Y
Process (N, 3, 224, 224)
float32
(N, 3, 224, 224)
float32
- - - - - - Y Y

PaddleClas中集成了上述所有的數據增廣策略,每種數據增廣策略的參考論文與參考開源代碼均在下面的介紹中列出。下文將介紹這些策略的原理與使用方法,並以下圖爲例,對變換後的效果進行可視化。

在這裏插入圖片描述

三、圖像變換類

圖像變換類指的是對 RandCrop 後的 224 的圖像進行一些變換,主要包括

  • AutoAugment
  • RandAugment

3.1 AutoAugment

論文地址:https://arxiv.org/abs/1805.09501v1

開源代碼github地址:https://github.com/DeepVoltaire/AutoAugment

不同於常規的人工設計圖像增廣方式,AutoAugment 是在一系列圖像增廣子策略的搜索空間中通過搜索算法找到的適合特定數據集的圖像增廣方案。針對 ImageNet 數據集,最終搜索出來的數據增廣方案包含 25 個子策略組合,每個子策略中都包含兩種變換,針對每幅圖像都隨機的挑選一個子策略組合,然後以一定的概率來決定是否執行子策略中的每種變換。

PaddleClas中AutoAugment的使用方法如下所示。

from ppcls.data.imaug import DecodeImage
from ppcls.data.imaug import ResizeImage
from ppcls.data.imaug import ImageNetPolicy
from ppcls.data.imaug import transform

size = 224

decode_op = DecodeImage()
resize_op = ResizeImage(size=(size, size))
autoaugment_op = ImageNetPolicy()

ops = [decode_op, resize_op, autoaugment_op]

imgs_dir = 圖像路徑
fnames = os.listdir(imgs_dir)
for f in fnames:
    data = open(os.path.join(imgs_dir, f)).read()
    img = transform(data, ops)

結果如下圖所示。

在這裏插入圖片描述

3.2 RandAugment

論文地址:https://arxiv.org/pdf/1909.13719.pdf

開源代碼github地址:https://github.com/heartInsert/randaugment

AutoAugment 的搜索方法比較暴力,直接在數據集上搜索針對該數據集的最優策略,其計算量很大。在 RandAugment 文章中作者發現,一方面,針對越大的模型,越大的數據集,使用 AutoAugment 方式搜索到的增廣方式產生的收益也就越小;另一方面,這種搜索出的最優策略是針對該數據集的,其遷移能力較差,並不太適合遷移到其他數據集上。

RandAugment 中,作者提出了一種隨機增廣的方式,不再像 AutoAugment 中那樣使用特定的概率確定是否使用某種子策略,而是所有的子策略都會以同樣的概率被選擇到,論文中的實驗也表明這種數據增廣方式即使在大模型的訓練中也具有很好的效果。

PaddleClas中RandAugment的使用方法如下所示。

from ppcls.data.imaug import DecodeImage
from ppcls.data.imaug import ResizeImage
from ppcls.data.imaug import RandAugment
from ppcls.data.imaug import transform

size = 224

decode_op = DecodeImage()
resize_op = ResizeImage(size=(size, size))
randaugment_op = RandAugment()

ops = [decode_op, resize_op, randaugment_op]

imgs_dir = 圖像路徑
fnames = os.listdir(imgs_dir)
for f in fnames:
    data = open(os.path.join(imgs_dir, f)).read()
    img = transform(data, ops)

結果如下圖所示。

在這裏插入圖片描述

四、圖像裁剪類

圖像裁剪類主要是對Transpose 後的 224 的圖像進行一些裁剪,並將裁剪區域的像素值置爲特定的常數(默認爲0),主要包括:

  • CutOut
  • RandErasing
  • HideAndSeek
  • GridMask

圖像裁剪的這些增廣並非一定要放在歸一化之後,也有不少實現是放在歸一化之前的,也就是直接對 uint8 的圖像進行操作,兩種方式的差別是:如果直接對 uint8 的圖像進行操作,那麼再經過歸一化之後被裁剪的區域將不再是純黑或純白(減均值除方差之後像素值不爲0)。而對歸一後之後的數據進行操作,裁剪的區域會是純黑或純白。

上述的裁剪變換思路是相同的,都是爲了解決訓練出的模型在有遮擋數據上泛化能力較差的問題,不同的是他們的裁剪方式、區域不太一樣。

4.1 Cutout

論文地址:https://arxiv.org/abs/1708.04552

開源代碼github地址:https://github.com/uoguelph-mlrg/Cutout

Cutout 可以理解爲 Dropout 的一種擴展操作,不同的是 Dropout 是對圖像經過網絡後生成的特徵進行遮擋,而 Cutout 是直接對輸入的圖像進行遮擋,相對於Dropout對噪聲的魯棒性更好。作者在論文中也進行了說明,這樣做法有以下兩點優勢:(1) 通過 Cutout 可以模擬真實場景中主體被部分遮擋時的分類場景;(2) 可以促進模型充分利用圖像中更多的內容來進行分類,防止網絡只關注顯著性的圖像區域,從而發生過擬合。

PaddleClas中Cutout的使用方法如下所示。

from ppcls.data.imaug import DecodeImage
from ppcls.data.imaug import ResizeImage
from ppcls.data.imaug import Cutout
from ppcls.data.imaug import transform

size = 224

decode_op = DecodeImage()
resize_op = ResizeImage(size=(size, size))
cutout_op = Cutout(n_holes=1, length=112)

ops = [decode_op, resize_op, cutout_op]

imgs_dir = 圖像路徑
fnames = os.listdir(imgs_dir)
for f in fnames:
    data = open(os.path.join(imgs_dir, f)).read()
    img = transform(data, ops)

結果如下圖所示。

在這裏插入圖片描述

4.2 RandomErasing

論文地址:https://arxiv.org/pdf/1708.04896.pdf

開源代碼github地址:https://github.com/zhunzhong07/Random-Erasing

RandomErasingCutout 方法類似,同樣是爲了解決訓練出的模型在有遮擋數據上泛化能力較差的問題,作者在論文中也指出,隨機裁剪的方式與隨機水平翻轉具有一定的互補性。作者也在行人再識別(REID)上驗證了該方法的有效性。與Cutout不同的是,在RandomErasing中,圖片以一定的概率接受該種預處理方法,生成掩碼的尺寸大小與長寬比也是根據預設的超參數隨機生成。

PaddleClas中RandomErasing的使用方法如下所示。

from ppcls.data.imaug import DecodeImage
from ppcls.data.imaug import ResizeImage
from ppcls.data.imaug import ToCHWImage
from ppcls.data.imaug import RandomErasing
from ppcls.data.imaug import transform

size = 224

decode_op = DecodeImage()
resize_op = ResizeImage(size=(size, size))
randomerasing_op = RandomErasing()

ops = [decode_op, resize_op, tochw_op, randomerasing_op]

imgs_dir = 圖像路徑
fnames = os.listdir(imgs_dir)
for f in fnames:
    data = open(os.path.join(imgs_dir, f)).read()
    img = transform(data, ops)
    img = img.transpose((1, 2, 0))

結果如下圖所示。

在這裏插入圖片描述

4.3 HideAndSeek

論文地址:https://arxiv.org/pdf/1811.02545.pdf

開源代碼github地址:https://github.com/kkanshul/Hide-and-Seek

HideAndSeek論文將圖像分爲若干塊區域(patch),對於每塊區域,都以一定的概率生成掩碼,不同區域的掩碼含義如下圖所示。

在這裏插入圖片描述

PaddleClas中HideAndSeek的使用方法如下所示。

from ppcls.data.imaug import DecodeImage
from ppcls.data.imaug import ResizeImage
from ppcls.data.imaug import ToCHWImage
from ppcls.data.imaug import HideAndSeek
from ppcls.data.imaug import transform

size = 224

decode_op = DecodeImage()
resize_op = ResizeImage(size=(size, size))
hide_and_seek_op = HideAndSeek()

ops = [decode_op, resize_op, tochw_op, hide_and_seek_op]

imgs_dir = 圖像路徑
fnames = os.listdir(imgs_dir)
for f in fnames:
    data = open(os.path.join(imgs_dir, f)).read()
    img = transform(data, ops)
    img = img.transpose((1, 2, 0))

結果如下圖所示。

在這裏插入圖片描述

4.4 GridMask

論文地址:https://arxiv.org/abs/2001.04086

開源代碼github地址:https://github.com/akuxcw/GridMask

作者在論文中指出,此前存在的基於對圖像 crop 的方法存在兩個問題,如下圖所示:

  1. 過度刪除區域可能造成目標主體大部分甚至全部被刪除,或者導致上下文信息的丟失,導致增廣後的數據成爲噪聲數據;
  2. 保留過多的區域,對目標主體及上下文基本產生不了什麼影響,失去增廣的意義。

![][gridmask-0]

因此如果避免過度刪除或過度保留成爲需要解決的核心問題。

GridMask是通過生成一個與原圖分辨率相同的掩碼,並將掩碼進行隨機翻轉,與原圖相乘,從而得到增廣後的圖像,通過超參數控制生成的掩碼網格的大小。

在訓練過程中,有兩種以下使用方法:

  1. 設置一個概率p,從訓練開始就對圖片以概率p使用GridMask進行增廣。
  2. 一開始設置增廣概率爲0,隨着迭代輪數增加,對訓練圖片進行GridMask增廣的概率逐漸增大,最後變爲p。

論文中驗證上述第二種方法的訓練效果更好一些。

PaddleClas中GridMask的使用方法如下所示。

from data.imaug import DecodeImage
from data.imaug import ResizeImage
from data.imaug import ToCHWImage
from data.imaug import GridMask
from data.imaug import transform

size = 224

decode_op = DecodeImage()
resize_op = ResizeImage(size=(size, size))
tochw_op = ToCHWImage()
gridmask_op = GridMask(d1=96, d2=224, rotate=1, ratio=0.6, mode=1, prob=0.8)

ops = [decode_op, resize_op, tochw_op, gridmask_op]

imgs_dir = 圖像路徑
fnames = os.listdir(imgs_dir)
for f in fnames:
    data = open(os.path.join(imgs_dir, f)).read()
    img = transform(data, ops)
    img = img.transpose((1, 2, 0))

結果如下圖所示。

在這裏插入圖片描述

五、圖像混疊

圖像混疊主要對 Batch 後的數據進行混合,包括:

  • Mixup
  • Cutmix

前文所述的圖像變換與圖像裁剪都是針對單幅圖像進行的操作,而圖像混疊是對兩幅圖像進行融合,生成一幅圖像,兩種方法的主要區別爲混疊的方式不太一樣。

5.1 Mixup

論文地址:https://arxiv.org/pdf/1710.09412.pdf

開源代碼github地址:https://github.com/facebookresearch/mixup-cifar10

Mixup 是最先提出的圖像混疊增廣方案,其原理簡單、方便實現,不僅在圖像分類上,在目標檢測上也取得了不錯的效果。爲了便於實現,通常只對一個 batch 內的數據進行混疊,在 Cutmix 中也是如此。

如下是 imaug 中的實現,需要指出的是,下述實現會出現對同一幅進行相加的情況,也就是最終得到的圖和原圖一樣,隨着 batch-size 的增加這種情況出現的概率也會逐漸減小。

PaddleClas中Mixup的使用方法如下所示。

from ppcls.data.imaug import DecodeImage
from ppcls.data.imaug import ResizeImage
from ppcls.data.imaug import ToCHWImage
from ppcls.data.imaug import transform
from ppcls.data.imaug import MixupOperator

size = 224

decode_op = DecodeImage()
resize_op = ResizeImage(size=(size, size))
tochw_op = ToCHWImage()
hide_and_seek_op = HideAndSeek()
mixup_op = MixupOperator()
cutmix_op = CutmixOperator()

ops = [decode_op, resize_op, tochw_op]

imgs_dir = 圖像路徑

batch = []
fnames = os.listdir(imgs_dir)
for idx, f in enumerate(fnames):
    data = open(os.path.join(imgs_dir, f)).read()
    img = transform(data, ops)
    batch.append( (img, idx) ) # fake label

new_batch = mixup_op(batch)

結果如下圖所示。

在這裏插入圖片描述

5.2 Cutmix

論文地址:https://arxiv.org/pdf/1905.04899v2.pdf

開源代碼github地址:https://github.com/clovaai/CutMix-PyTorch

Mixup 直接對兩幅圖進行相加不一樣,Cutmix 是從一幅圖中隨機裁剪出一個 ROI,然後覆蓋當前圖像中對應的區域,代碼實現如下所示:

rom ppcls.data.imaug import DecodeImage
from ppcls.data.imaug import ResizeImage
from ppcls.data.imaug import ToCHWImage
from ppcls.data.imaug import transform
from ppcls.data.imaug import CutmixOperator

size = 224

decode_op = DecodeImage()
resize_op = ResizeImage(size=(size, size))
tochw_op = ToCHWImage()
hide_and_seek_op = HideAndSeek()
cutmix_op = CutmixOperator()

ops = [decode_op, resize_op, tochw_op]

imgs_dir = 圖像路徑

batch = []
fnames = os.listdir(imgs_dir)
for idx, f in enumerate(fnames):
    data = open(os.path.join(imgs_dir, f)).read()
    img = transform(data, ops)
    batch.append( (img, idx) ) # fake label

new_batch = cutmix_op(batch)

結果如下圖所示。

在這裏插入圖片描述

六、實驗

基於PaddleClas,在ImageNet1k數據集上的分類精度如下。

模型 初始學習率策略 l2 decay batch size epoch 數據變化策略 Top1 Acc 論文中結論
ResNet50 0.1/cosine_decay 0.0001 256 300 標準變換 0.7731 -
ResNet50 0.1/cosine_decay 0.0001 256 300 AutoAugment 0.7795 0.7763
ResNet50 0.1/cosine_decay 0.0001 256 300 mixup 0.7828 0.7790
ResNet50 0.1/cosine_decay 0.0001 256 300 cutmix 0.7839 0.7860
ResNet50 0.1/cosine_decay 0.0001 256 300 cutout 0.7801 -
ResNet50 0.1/cosine_decay 0.0001 256 300 gridmask 0.7785 0.7790
ResNet50 0.1/cosine_decay 0.0001 256 300 random-augment 0.7770 0.7760
ResNet50 0.1/cosine_decay 0.0001 256 300 random erasing 0.7791 -
ResNet50 0.1/cosine_decay 0.0001 256 300 hide and seek 0.7743 0.7720

注意

  • 在這裏的實驗中,爲了便於對比,將l2 decay固定設置爲1e-4,在實際使用中,更小的l2 decay一般效果會更好。結合數據增廣,將l2 decay由1e-4減小爲7e-5均能帶來至少0.3~0.5%的精度提升。

7.3 PaddleClas數據增廣避坑指南以及部分注意事項

  • 在使用圖像混疊類的數據處理時,需要將配置文件中的use_mix設置爲True,另外由於圖像混疊時需對label進行混疊,無法計算訓練數據的準確率,所以在訓練過程中沒有打印訓練準確率。

  • 在使用數據增廣後,由於訓練數據更難,所以訓練損失函數可能較大,訓練集的準確率相對較低,但其有擁更好的泛化能力,所以驗證集的準確率相對較高。

  • 在使用數據增廣後,模型可能會趨於欠擬合狀態,建議可以適當的調小l2_decay的值來獲得更高的驗證集準確率。

  • 幾乎每一類圖像增廣均含有超參數,PaddleClas在這裏只提供了基於ImageNet-1k的超參數,其他數據集需要用戶自己調試超參數,當然如果對於超參數的含義不太清楚的話,可以閱讀相關的論文,調試方法也可以參考訓練技巧的章節(https://github.com/PaddlePaddle/PaddleClas/blob/master/docs/zh_CN/models/Tricks.md)

參考文獻

[1] Cubuk E D, Zoph B, Mane D, et al. Autoaugment: Learning augmentation strategies from data[C]//Proceedings of the IEEE conference on computer vision and pattern recognition. 2019: 113-123.

[2] Cubuk E D, Zoph B, Shlens J, et al. Randaugment: Practical automated data augmentation with a reduced search space[J]. arXiv preprint arXiv:1909.13719, 2019.

[3] DeVries T, Taylor G W. Improved regularization of convolutional neural networks with cutout[J]. arXiv preprint arXiv:1708.04552, 2017.

[4] Zhong Z, Zheng L, Kang G, et al. Random erasing data augmentation[J]. arXiv preprint arXiv:1708.04896, 2017.

[5] Singh K K, Lee Y J. Hide-and-seek: Forcing a network to be meticulous for weakly-supervised object and action localization[C]//2017 IEEE international conference on computer vision (ICCV). IEEE, 2017: 3544-3553.

[6] Chen P. GridMask Data Augmentation[J]. arXiv preprint arXiv:2001.04086, 2020.

[7] Zhang H, Cisse M, Dauphin Y N, et al. mixup: Beyond empirical risk minimization[J]. arXiv preprint arXiv:1710.09412, 2017.

[8] Yun S, Han D, Oh S J, et al. Cutmix: Regularization strategy to train strong classifiers with localizable features[C]//Proceedings of the IEEE International Conference on Computer Vision. 2019: 6023-6032.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章