圖片數據集太少?看我七十二變,Keras Image Data Augmentation 各...

2020-12-08 雷鋒網

雷鋒網(公眾號:雷鋒網) AI科技評論按,本文作者Professor ho,該文首發於知乎專欄Keras花式工具箱,雷鋒網 AI科技評論獲其授權轉載。

圖像深度學習任務中,面對小數據集,我們往往需要利用Image Data Augmentation圖像增廣技術來擴充我們的數據集,而keras的內置ImageDataGenerator很好地幫我們實現圖像增廣。但是面對ImageDataGenerator中眾多的參數,每個參數所得到的效果分別是怎樣的呢?本文針對Keras中ImageDataGenerator的各項參數數值的效果進行了詳細解釋,為各位深度學習研究者們提供一個參考。

我們先來看看ImageDataGenerator的官方說明(https://keras.io/preprocessing/image/):

keras.preprocessing.image.ImageDataGenerator(featurewise_center=False,
   samplewise_center=False,
   featurewise_std_normalization=False,
   samplewise_std_normalization=False,
   zca_whitening=False,
   zca_epsilon=1e-6,
   rotation_range=0.,
   width_shift_range=0.,
   height_shift_range=0.,
   shear_range=0.,
   zoom_range=0.,
   channel_shift_range=0.,
   fill_mode='nearest',
   cval=0.,
   horizontal_flip=False,
   vertical_flip=False,
   rescale=None,
   preprocessing_function=None,
   data_format=K.image_data_format())

官方提供的參數解釋因為太長就不貼出來了,大家可以直接點開上面的連結看英文原介紹,我們現在就從每一個參數開始看看它會帶來何種效果。

我們測試選用的是kaggle dogs vs cats redux 貓狗大戰的數據集,隨機選取了9張狗狗的照片,這9張均被resize成224×224的尺寸,如圖1:

圖1

1. featurewise

datagen = image.ImageDataGenerator(featurewise_center=True,
   featurewise_std_normalization=True)

featurewise_center的官方解釋:"Set input mean to 0 over the dataset, feature-wise." 大意為使數據集去中心化(使得其均值為0),而samplewise_std_normalization的官方解釋是「 Divide inputs by std of the dataset, feature-wise.」,大意為將輸入的每個樣本除以其自身的標準差。這兩個參數都是從數據集整體上對每張圖片進行標準化處理,我們看看效果如何:

圖2

與圖1原圖相比,經過處理後的圖片在視覺上稍微「變暗」了一點。

2. samplewise

datagen = image.ImageDataGenerator(samplewise_center=True,
   samplewise_std_normalization=True)

samplewise_center的官方解釋為:「 Set each sample mean to 0.」,使輸入數據的每個樣本均值為0;samplewise_std_normalization的官方解釋為:「Divide each input by its std.」,將輸入的每個樣本除以其自身的標準差。這個月featurewise的處理不同,featurewise是從整個數據集的分布去考慮的,而samplewise只是針對自身圖片,效果如圖3:

圖3

看來針對自身數據分布的處理在貓狗大戰數據集上沒有什麼意義,或許在mnist這類灰度圖上有用?讀者可以試試。

3. zca_whtening

datagen = image.ImageDataGenerator(zca_whitening=True)

zca白化的作用是針對圖片進行PCA降維操作,減少圖片的冗餘信息,保留最重要的特徵,細節可參看:Whitening transformation--維基百科,Whitening--斯坦福。

很抱歉的是,本人使用keras的官方演示代碼,並沒有復現出zca_whitening的效果,當我的圖片resize成224×224時,代碼報內存錯誤,應該是在計算SVD的過程中數值太大。後來resize成28×28,就沒有內存錯誤了,但是代碼運行了一晚上都不結束,因此使用貓狗大戰圖片無法復現效果,這裡轉發另外一個博客使用mnist復現出的結果,如下圖4。針對mnist的其它DataAugmentation結果可以看這個博客:Image Augmentation for Deep Learning With Keras,有修改意見的朋友歡迎留言。

圖4

4. rotation range

datagen = image.ImageDataGenerator(rotation_range=30)

rotation range的作用是用戶指定旋轉角度範圍,其參數只需指定一個整數即可,但並不是固定以這個角度進行旋轉,而是在 [0, 指定角度] 範圍內進行隨機角度旋轉。效果如圖5:

圖5

5. width_shift_range & height_shift_range

datagen = image.ImageDataGenerator(width_shift_range=0.5,height_shift_range=0.5)

width_shift_range & height_shift_range 分別是水平位置評議和上下位置平移,其參數可以是[0, 1]的浮點數,也可以大於1,其最大平移距離為圖片長或寬的尺寸乘以參數,同樣平移距離並不固定為最大平移距離,平移距離在 [0, 最大平移距離] 區間內。效果如圖6:

圖6

平移圖片的時候一般會出現超出原圖範圍的區域,這部分區域會根據fill_mode的參數來補全,具體參數看下文。當參數設置過大時,會出現圖7的情況,因此儘量不要設置太大的數值。

圖7

6. shear_range

datagen = image.ImageDataGenerator(shear_range=0.5)

shear_range就是錯切變換,效果就是讓所有點的x坐標(或者y坐標)保持不變,而對應的y坐標(或者x坐標)則按比例發生平移,且平移的大小和該點到x軸(或y軸)的垂直距離成正比。

如圖8所示,一個黑色矩形圖案變換為藍色平行四邊形圖案。狗狗圖片變換效果如圖9所示。

圖8

圖9

7. zoom_range

datagen = image.ImageDataGenerator(zoom_range=0.5)

zoom_range參數可以讓圖片在長或寬的方向進行放大,可以理解為某方向的resize,因此這個參數可以是一個數或者是一個list。當給出一個數時,圖片同時在長寬兩個方向進行同等程度的放縮操作;當給出一個list時,則代表[width_zoom_range, height_zoom_range],即分別對長寬進行不同程度的放縮。而參數大於0小於1時,執行的是放大操作,當參數大於1時,執行的是縮小操作。

參數大於0小於1時,效果如圖10:

圖10

參數等於4時,效果如圖11:

圖11

8. channel_shift_range

datagen = image.ImageDataGenerator(channel_shift_range=10)

channel_shift_range可以理解成改變圖片的顏色,通過對顏色通道的數值偏移,改變圖片的整體的顏色,這意味著是「整張圖」呈現某一種顏色,像是加了一塊有色玻璃在圖片前面一樣,因此它並不能單獨改變圖片某一元素的顏色,如黑色小狗不能變成白色小狗。當數值為10時,效果如圖12;當數值為100時,效果如圖13,可見當數值越大時,顏色變深的效果越強。

圖12

圖13

9. horizontal_flip & vertical_flip

datagen = image.ImageDataGenerator(horizontal_flip=True)

horizontal_flip的作用是隨機對圖片執行水平翻轉操作,意味著不一定對所有圖片都會執行水平翻轉,每次生成均是隨機選取圖片進行翻轉。效果如圖14。

圖14

datagen = image.ImageDataGenerator(vertical_flip=True

vertical_flip是作用是對圖片執行上下翻轉操作,和horizontal_flip一樣,每次生成均是隨機選取圖片進行翻轉,效果如圖15。

圖15

當然了,在貓狗大戰數據集當中不適合使用vertical_flip,因為一般沒有倒過來的動物。

10. rescale

datagen = image.ImageDataGenerator(rescale= 1/255, width_shift_range=0.1)

rescale的作用是對圖片的每個像素值均乘上這個放縮因子,這個操作在所有其它變換操作之前執行,在一些模型當中,直接輸入原圖的像素值可能會落入激活函數的「死亡區」,因此設置放縮因子為1/255,把像素值放縮到0和1之間有利於模型的收斂,避免神經元「死亡」。

圖片經過rescale之後,保存到本地的圖片用肉眼看是沒有任何區別的,如果我們在內存中直接列印圖片的數值,可以看到以下結果:

圖16

可以從圖16看到,圖片像素值都被縮小到0和1之間,但如果打開保存在本地的圖片,其數值依然不變,如圖17。

圖17

應該是在保存到本地的時候,keras把圖像像素值恢復為原來的尺度了,在內存中查看則不會。

11. fill_mode

datagen = image.ImageDataGenerator(fill_mode='wrap', zoom_range=[4, 4])

fill_mode為填充模式,如前面提到,當對圖片進行平移、放縮、錯切等操作時,圖片中會出現一些缺失的地方,那這些缺失的地方該用什麼方式補全呢?就由fill_mode中的參數確定,包括:「constant」、「nearest」(默認)、「reflect」和「wrap」。這四種填充方式的效果對比如圖18所示,從左到右,從上到下分別為:「reflect」、「wrap」、「nearest」、「constant」。

圖18

當設置為「constant」時,還有一個可選參數,cval,代表使用某個固定數值的顏色來進行填充。圖19為cval=100時的效果,可以與圖18右下角的無cval參數的圖對比。

圖19

自己動手來測試?

這裡給出一段小小的代碼,作為進行這些參數調試時的代碼,你也可以使用jupyter notebook來試驗這些參數,把圖片結果列印到你的網頁上。

%matplotlib inline
import matplotlib.pyplot as plt
from PIL import Image
from keras.preprocessing import image
import glob

# 設置生成器參數
datagen = image.ImageDataGenerator(fill_mode='wrap', zoom_range=[4, 4])

gen_data = datagen.flow_from_directory(PATH,
                                      batch_size=1,
                                      shuffle=False,
                                      save_to_dir=SAVE_PATH,
                                      save_prefix='gen',
      target_size=(224, 224))

# 生成9張圖
for i in range(9):
   gen_data.next()


# 找到本地生成圖,把9張圖列印到同一張figure上
name_list = glob.glob(gen_path+'16/*')
fig = plt.figure()
for i in range(9):
   img = Image.open(name_list[i])
   sub_img = fig.add_subplot(331 + i)
   sub_img.imshow(img)
plt.show()

結語

面對小數據集時,使用DataAugmentation擴充你的數據集就變得非常重要,但在使用DataAugmentation之前,先要了解你的數據集需不需要這類圖片,如貓狗大戰數據集不需要上下翻轉的圖片,以及思考一下變換的程度是不是合理的,例如把目標水平偏移到圖像外面就是不合理的。多試幾次效果,再最終確定使用哪些參數。上面所有內容已經公布在我的github(https://github.com/JustinhoCHN/keras-image-data-augmentation)上面,附上了實驗時的jupyter notebook文件,大家可以玩一玩,have fun!

雷鋒網版權文章,未經授權禁止轉載。詳情見轉載須知。

相關焦點

  • 用Keras和「直方圖均衡」為深度學習實現「圖像擴充」
    如果你對「Silicon Valley」這個電視節目不太熟悉,請注意以下視頻中的語言是NSFW:我們通過擴充圖像數據的方式,從一個已有的資料庫中生成更多新的訓練圖像,以降低收集訓練圖像的成本。「圖像擴充」其實就是從已有的訓練數據集中取出一些圖像,然後根據這些圖像創建出許多修改版本的圖像。
  • 初學者怎樣使用Keras進行遷移學習
    import MobileNetfrom keras.preprocessing import imagefrom keras.applications.mobilenet import preprocess_inputfrom keras.preprocessing.image import ImageDataGeneratorfrom keras.models
  • 用TensorFlow和Keras構建卷積神經網絡
    圖片來源: Brilliant卷積層上的輸出是對前一層神經元的子集進行卷積的結果,然後得出激活函數。數據集下面將訓練一個神經網絡來預測一幅圖像包含的是一隻狗還是一隻貓。為此,將使用Kaggle的相關數據集,其中包含不同解析度的12500隻貓和12500隻狗的圖片。
  • 5分鐘入門GANS:原理解釋和keras代碼實現
    本篇文章包含以下內容介紹歷史直觀解釋訓練過程GAN在MNIST數據集上的KERAS實現鑑別器網絡的目的是獲取這個輸入,並預測這個圖像是來自真實的數據集還是合成的。正如我們剛才看到的,這實際上就是GANs,兩個相互競爭的敵對網絡。GAN的訓練過程GANS的訓練是出了名的困難。在CNN中,我們使用梯度下降來改變權重以減少損失。
  • 掌握深度學習,數據不足也能進行圖像分類!
    在本文中,小芯將示範如何在數據不足的情況下應用深度學習。現已創建特製汽車和巴士分類器兩個數據集,每個數據集包含100個圖像。其中,訓練集有70個圖像,驗證集有30個。挑戰1. 視點變化:基於相機,單一對象實例可以從多個視角聚焦。2. 尺度變化:視覺分類常常存在尺度變化(這裡的尺度指的是現實世界中的物體的大小,而不僅僅就圖像而言)。
  • 如何利用TensorFlow.js部署簡單的AI版「你畫我猜」圖像識別應用
    zaidalyafeai/zaidalyafeai.github.io/tree/master/sketcher請通過以下連結在谷歌 Colab 上測試自己的 notebook:https://colab.research.google.com/github/zaidalyafeai/zaidalyafeai.github.io/blob/master/sketcher/Sketcher.ipynb數據集
  • 使用Keras將音樂分類為不同類型
    我們將使用GTZAN genre collection數據集。此機器學習數據集可以從此處獲取(http://opihi.cs.uvic.ca/sound/genres.tar.gz)。該機器學習數據集由10種類型組成,每種類型由100個音樂片段組成,每個音樂片段長30秒。  我們將使用Keras,採用tensorflow作為後端。
  • TensorFlow(Keras)中的正則化技術及其實現(附代碼)
    缺點是神經網絡更容易過度擬合訓練數據集。過度擬合:此問題涉及算法過於精確地預測在訓練過程中觀察和學習到的模式實例,從而預測向其呈現的模式的新實例。這可能導致機器學習算法無法準確地推廣到看不見的數據。如果訓練數據不能準確表示測試數據的分布,則可能會發生過度擬合。
  • 一圖勝千言: 解讀阿里的Deep Image CTR Model
    基於 PS 的分布式訓練的思想還是很簡單的: 1.一開始是data parallelism。每臺 worker 只利用本地的訓練數據前代、回代,計算 gradient,並發往 server。Server 匯總(平均)各 worker 發來的 gradient,更新模型,並把更新過的模型同步給各 worker。
  • 教程 | 如何利用TensorFlow.js部署簡單的AI版「你畫我猜」圖像識別應用
    這個卷積神經網絡將在 Quick Draw 數據集(https://github.com/googlecreativelab/quickdraw-dataset)上接受訓練。該數據集包含 345 個類別的大約 5 千萬張手繪圖像。
  • 圖像分類入門,輕鬆拿下90%準確率|教你用Keras搞Fashion-MNIST
    想深入了解這個數據集,推薦閱讀量子位之前的報導:連LeCun都推薦的Fashion-MNIST數據集,是這位華人博士的成果或者去GitHub:https://github.com/zalandoresearch/fashion-mnisttf.keras是用來在TensorFlow中導入Keras的函數。
  • 小白學CNN以及Keras的速成
    Keras Documentation 就是Keras的官方文檔,裡面可以查閱所有的函數,並且可以在github上看他的開原始碼,非常方便。安裝也很簡單,打開終端,輸入pip install keras 就可以等待安裝了。下面就給一個簡單的例子,來看一看Keras到底有多簡單。
  • 用PyTorch重新創建Keras API
    介紹Francois Chollet寫的《Deep Learning with Python》一書讓我進入了深度學習的世界。從那時起我就愛上了Keras的風格。Keras是我的第一個框架,然後是Tensorflow,接著進入PyTorch。老實說,在Keras的模型訓練中,我很興奮這個進度條,真是太棒了。
  • 如何在Keras中訓練大型數據集
    深度學習算法成功的主要原因是數據集的不斷增大。現在,深度學習算法在大型數據集上進行訓練,這些數據集甚至不適合內存。問題是:如何在如此巨的數據集中訓練我們的深度學習模型呢?本文分為以下幾個部分:下載和了解數據集數據集的準備 - 批量加載數據集數據集在訓練和驗證集中的Shuffling和拆分創建自定義生成器定義模型體系結構和訓練模型結論作為一個例子,我們將解決Kaggle「Plant Seedlings Classification」的挑戰。這個數據集並不大,但我們將假設數據集太大,無法裝入內存,然後將批量加載數據集。
  • 調參俠看過來!兩個提高深度學習訓練效率的絕技
    提高GPU利用率:CPU vs GPUGPU利用率低, 主要原因是CPU處理的效率跟不上GPU2.1 CPU vs GPU的通信 CPU負責加載數據+數據預處理,並不斷的在內存和顯存之間交互數據  GPU負責模型訓練(圖片來自網絡)
  • 手把手教你用Keras進行多標籤分類(附代碼)
    在第一部分,我將討論我們的多標籤分類數據集(以及如何快速構建屬於你自己的數據集)。 之後我們將簡要討論SmallerVGGNet,它是我們將要實現的一個用於多標籤分類的Keras神經網絡結構。 我構建該數據集通過遵循我之前發布過的博文:How to (quickly) build a deep learning image dataset下載圖片以及手動為該6個類別剔除不相關圖片的整個過程將耗費大概30分鐘。