iT邦幫忙

2022 iThome 鐵人賽

DAY 26
1

前言

本篇是 Regularization的第二篇,講得是DATA Augmentation。是一個非常常見的技巧!

什麼是影像增強(Data Augmentation)?

Data Augmentation是一個非常常用的技巧,大致上就是利用一些Computer Vision的技巧,對影像進行小幅度的修改,確保修改後的影像仍能具有原先希望辨別的特徵,以期望模型即使在圖片加入這些變化間,仍能具有判別影像特徵的能力。

具體實例可以參考albumentation函式庫中的展示圖:

大致上的重點便是同一張圖經過變化以後,還是要能看得出他是一隻鸚鵡(試想,如果連你都看不太懂了,要什麼都不會的模型學習是不是太強"模"所難了呢?),而我們同時也可使用不同的處理方法來疊合,創造出千變萬化的圖片出來讓模型學習!

這個方法同時也非常常見於資料量不大的專案中。但別忘了他的本質仍是一種Regularization,實際上資料量不大的模型訓練中,效果不好的結果,主要的問題是來自於小型的訓練集無法代表整體樣本,因此收斂於小樣本的模型,自然無法適應到整個宏觀世界。此時Data Augmentation的介入,便是盡可能的透過讓資料更接近整個宏觀世界的方式,來去增加模型訓練時收斂的難度,進而去讓模型能有更好的generalization error。

但這東西卻也不是加越多越好,它一樣是個需要tune的超參數組。常見的謬誤有做了過多不合理的變化,使得訓練資料變得已經有點過度扭曲,已經脫離宏觀世界的長相時(宏觀世界的借鑒則是驗證集及測試集),類似像下面這張圖(來源),有一張貓貓的頭已經完全被切掉了,這種難以辨識的東西如果一兩百張有1-2張還沒什麼關係,但太多可就不好了,所以實際也要注意一下。

另外補充一下,還有一個借鑒則是Data Augmentation也要符合資料與domain的知識。例如醫療影像中,即使是不同的人,人體骨頭的生理結構不會差異太大,不宜做過度的扭曲,如果跑出個斜的頭骨那還真不知道該如何是好?

推薦的函式庫

這邊推薦幾個我個人比較常用的函式庫:

  • torchvision
    • torch本家的cv函式庫,基本上簡單強大好用。
  • albumentation
    • 很熱門的Data Augmentation函式庫,各種神奇的處理很多,都可以試試看,但有些處理很特殊,可能會花很多時間進行前處理,要稍微注意一下效率。
  • MONAI
    • 本單元的老朋友,特點是可以支援2d、3d,而且很多專屬於醫療影像用的Augmentation。
  • TorchIO
    • 專門處理3d醫療影像的函式庫,有需要也可以試試看。

另外如果要把非monai的Augmentation整合起來一起使用的話,可以善用monai.transforms.Lambdad

實作

實作基本上不難,基本上一樣是準備一組monai.transforms

def prepare_data_aug(CONFIG: Dict) -> monai.transforms.transform:
    
    prob = CONFIG['train']['data_aug']['prob']
    transforms_data_aug = [
        monai.transforms.RandAffined(keys = ['img'], 
                                     prob=prob, 
                                     rotate_range = [-0.1, 0.1], 
                                     translate_range = [-3, 3], 
                                     scale_range = 0.1),
        monai.transforms.RandGaussianNoised(keys = ['img'], 
                                            prob=prob, 
                                            mean=0.0, std=0.1),
        monai.transforms.RandFlipd(keys = ['img'],
                                   prob=prob, 
                                   spatial_axis = [0])]
    
    transforms_data_aug = monai.transforms.Compose(transforms_data_aug)
    
    return transforms_data_aug

然後在做成dataloader前,套上dataset就可以了!

transforms_data_aug = prepare_data_aug(CONFIG)
processed_datasets['TRAIN'] = monai.data.Dataset(data = processed_datasets['TRAIN'], 
                                                 transform = transforms_data_aug)
  • 這邊注意一點是,通常不建議把Augmentation也套到validation或是test上,通常會造成很多不必要的變數,也會造成挑選模型的不一致性。

然後我們可以試跑看看,一張圖片可能有的變化性:

  • 第一個affine基本上就是各種非破壞結構的形狀變化,可詳見Affine transformation,醫學影像上十分常用(另外可以延伸查一下non-rigid的意思)
  • 有任何牽扯到補值的,醫療影像建議可以使用直接pad zeros的方式,你總不會想多補一塊肋骨進來吧...?
  • 顆粒應該就是高斯模糊
  • 看起來還行?

實作結果

一樣參考這個commit訓練,讓我們直接看結果:

增加了一點幅度的訓練難度,一開始上升的比較少一些。但並沒有脫離宏觀世界太多,一樣是獲得了差不多0.76左右的auroc結果!

本日小節

  • 介紹與實作Data Augmentation
  • 介紹幾個不錯的函式庫
  • 科普一下醫學影像的Data Augmentation

上一篇
[Day25] Label Smooth
下一篇
[Day27] Weight Decay Regularization
系列文
PyTorch 生態鏈實戰運用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言