[譯] 在深度學習訓練過程當中如何設置數據加強?

圖像數據加強是人工增長訓練集的一種方式,主要是經過修改數據集中的圖片達成。html

更多的訓練數據帶來的是更有效的深度學習模型,同時,數據加強技術會產生更多的圖片變體,這些變體會提升模型對新圖片的泛化能力。前端

在 Keras 框架中,ImageDataGenerator 類提供了數據加強的相關功能。python

在本教程中,你將學會如何在訓練模型時使用圖像數據加強技術。android

在完成本教程後,你將明白下面幾點:ios

  • 圖像數據加強是爲了擴展訓練數據集從而提升模型的精度和泛化能力。
  • 在 Keras 框架中,你能夠經過 ImageDataGenerator 類使用圖像數據加強方法。
  • 如何使用平移、翻轉、亮度以及縮放的數據加強方法。

讓咱們開始吧。git

教程總覽

本教程被分爲如下八個部分,他們分別是:github

  1. 圖像數據加強
  2. 樣本圖片
  3. 使用 ImageDataGenerator 進行數據加強
  4. 水平和垂直方向的平移加強
  5. 水平和垂直方向的翻轉加強
  6. 隨機旋轉加強
  7. 隨機亮度加強
  8. 隨機縮放加強

數據加強

深度學習網絡的表現老是和數據量成正比的。後端

數據加強是一種人工的在原有數據基礎上增長新訓練數據的方法,是利用特定領域的技術將訓練集的數據轉變成一個新的數據達成的。數組

圖像數據加強大概是最衆所周知的一種數據加強方法,主要是涉及建立一個和原始圖片屬於同一類別的變形後的圖片。網絡

從圖像處理領域咱們能夠得到不少的變形方法,好比:平移、翻轉、縮放等等。

這麼作的主要意圖是用合理的新數據去擴展訓練數據。換句話說,咱們可讓模型看到更多樣性的訓練數據。舉個例子,若是咱們對一隻貓進行水平的翻轉,這個是有意義的,由於攝像頭的拍攝角度多是左邊也多是右邊。可是作垂直翻轉就沒什麼意義而且不太適合,由於模型不太會接收到一個頭上腳下的貓。

因此,咱們應該明白,咱們必定要根據訓練數據和問題領域的具體場景來慎重的選擇應用於訓練集的數據加強方法。此外,有一種比較有效的方法,就是在小的原型數據集上作一些獨立的實驗來度量加強後的模型是否在性能上有所提高。

現代的深度學習方法,像卷積神經網絡(CNN),均可以學習到圖片中的位置無關性特徵。數據加強能夠幫助模型去學習這種性質而且可使得模型對一些變化也不敏感,好比左到右和上到下的順序、照片的光照變化等等。

這些圖片數據的加強通常是應用於訓練集而不是驗證集和測試集。這些數據加強方法不一樣於那些須要在各個與模型交互的數據集上都保持一致的預處理方法,好比調整圖片大小與縮放像素值等。

想要計算機視覺方向的結果?

如今就參加個人7天電子郵件速成課(包含示例代碼)。

點擊註冊還有能夠得到課程的免費 PDF 版本。

下載你的免費迷你課程

樣本圖片

咱們須要一個樣本圖片來展現標準的數據加強技術。

本教程中,咱們會用到一個已經得到使用許可,由 AndYaDontStop 拍攝,名爲 Feathered Friend 的鳥類照片。

下載這張照片,並保存在你的工做目錄命名爲 ‘bird.jpg‘。

Feathered Friend,做者 AndYaDontStop。

Feathered Friend,做者 AndYaDontStop。
保留部分權力.

使用 ImageDataGenerator 進行圖像數據加強

Keras 框架能夠在訓練模型時,自動使用數據加強。

能夠利用 ImageDataGenerator 類 達到這一目的。

首先,能夠在類實例化時傳入特定的參數到構造函數來配置對應的加強方法。

該類支持一系列的加強方法,包括像素值的縮放,可是咱們只關注如下五種主要的圖像數據加強方法:

  • 經過 width_shift_rangeheight_shift_range 參數設置圖像平移。
  • 經過 rotation_range 參數設置圖像翻轉。
  • 經過 brightness_range 參數設置圖像亮度。
  • 經過 zoom_range 參數設置圖像縮放。

一個經過構造函數實例化 ImageDataGenerator 的例子。

# 建立數據生成器
datagen = ImageDataGenerator()
複製代碼

一旦構造完成,這個數據集的迭代器就被建立了。

這個迭代器每次迭代會返回一個批次的加強數據。

利用 flow() 函數能夠將讀入了內存的數據集建立爲一個迭代器,示例代碼以下:

# 讀取圖片數據集
X, y = ...
# 建立迭代器
it = dataset.flow(X, y)
複製代碼

或者,能夠對指定的文件路徑的數據集建立一個迭代器,在這個文件夾中,不一樣子類的數據須要存放到不一樣的子文件夾中。

...
# 建立迭代器
it = dataset.flow_from_directory(X, y, ...)
複製代碼

迭代器建立完成後,能夠經過調用 fit_generator() 函數來訓練神經網絡。

steps_per_epoch 參數須要設定爲能包含整個數據集的批次數。舉個例子,若是你的原始數據是 10000 張圖片,同時你的 batch_size 設置爲 32,那麼當你訓練一個基於加強數據的模型時,一個合理的 steps_per_epoch 應該設置爲 ceil(10,000/32),或者說 313 個批次。

# 定義模型
model = ...
# 在加強數據集上擬合模型
model.fit_generator(it, steps_per_epoch=313, ...)
複製代碼

數據集中的圖片並無被直接使用,而是將加強後的圖片提供給模型。因爲加強的圖片表現是隨機的,允許修改後的圖片以及接近原圖(例如,幾乎沒有加強的圖片)的數據被生成並在訓練中使用。

數據的生成器也可使用在驗證集和測試集上。一般來講,用於驗證集和測試集的 ImageDataGenerator 會和訓練集的 ImageDataGenerator 有相同的像素值縮放配置(本教程未涉及),可是不會涉及到數據加強。這是由於數據加強的目的是爲了能夠人工的擴充訓練數據集的數量,進而去提升模型在未作加強的數據集上的表現。

如今咱們已經熟悉了 ImageDataGenerator 的用法,那麼我去看幾個具體的針對於圖像數據的加強方法。

咱們會單獨的展現每一種方法加強後的圖片效果圖。這是一種很好的事件方式,建議在在配置大家本身的數據加強時也這麼作。在訓練過程當中,同時採用好幾種加強方法也是很常見的。這裏爲了達到展現的效果,咱們分章節單獨的討論每個加強方法。

水平和垂直平移加強

平移意味着將圖片上的全部像素沿着某一個方向移動,能夠是水平或者垂直,同時要保證大小沒有變化。

這也意味着一些原有的像素點會被移出圖片,那麼就會有一塊區域的像素值須要從新指定。

width_shift_rangeheight_shift_range 兩個參數分別用來控制水平和垂直方向平移的大小,它們是在 ImageDataGenerator 類被構造的時候傳入的。

這兩個參數能夠被指定爲一個 0 到 1 之間的小數,表明着平移距離相對於寬度或者高度的百分比。或者,也能夠被指定爲一個確切的像素值。

具體來講,實際的平移值會在沒有平移和百分比(或者具體的像素值)之間選取一個,用該值來處理圖片,距離來講,就是在 [0, value] 之間選擇。或者,你能夠傳入一組指定的元組或數組,肯定具體的最大和最小值來進行採樣,舉個例子:[-100, 100] 或者 [-0.5, 0.5]。

下面展現的就是一個將平移參數 width_shift_range 設置爲 [-200, 200] 像素,並畫出對應結果的代碼。

# 水平平移加強的例子
from numpy import expand_dims
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.preprocessing.image import ImageDataGenerator
from matplotlib import pyplot
# 讀入圖片
img = load_img('bird.jpg')
# 轉換爲 numpy 數組
data = img_to_array(img)
# 擴展維度
samples = expand_dims(data, 0)
# 生成數據加強迭工廠
datagen = ImageDataGenerator(width_shift_range=[-200,200])
# 準備迭代器
it = datagen.flow(samples, batch_size=1)
# 生成數據並畫圖
for i in range(9):
	# 定義子圖
	pyplot.subplot(330 + 1 + i)
	# 生成一個批次圖片
	batch = it.next()
	# 轉換爲無符號整型方便顯示
	image = batch[0].astype('uint32')
	# 畫圖
	pyplot.imshow(image)
# 展現圖片
pyplot.show()
複製代碼

執行這段代碼,經過配置 ImageDataGenerator 會生成一個圖片加強實例,並建立一個迭代器。這個迭代器會在一個循環中被執行 9 次並畫出每一次通過加強後的圖片。

我經過觀察畫出的結果能夠發現,圖片會進行隨機的正向或者負向的平移,同時平移帶來的空白區域會使用邊緣區域的像素來填充。

平移數據加強的結果

隨機平移數據加強結果圖

下面是相似的例子,經過調整 height_shift_range 參數實現垂直平移,其中該參數被設置爲 0.5。

# 垂直平移加強的例子
from numpy import expand_dims
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.preprocessing.image import ImageDataGenerator
from matplotlib import pyplot
# 讀圖
img = load_img('bird.jpg')
# convert to numpy array
data = img_to_array(img)
# 擴展維度
samples = expand_dims(data, 0)
# 建立一個生成器
datagen = ImageDataGenerator(height_shift_range=0.5)
# 準備迭代器
it = datagen.flow(samples, batch_size=1)
# 生成樣本和畫圖
for i in range(9):
	# 定義子圖
	pyplot.subplot(330 + 1 + i)
	# 生成一個批次的圖片
	batch = it.next()
	# 轉換爲整形顯示
	image = batch[0].astype('uint32')
	# 畫圖
	pyplot.imshow(image)
# 顯示
pyplot.show()
複製代碼

運行這段代碼,就能夠隨機的產生經過正向或者負向平移的加強圖片。

能夠發現水平位移或者垂直位移,不管是正向平或者負向均可以有效的加強對應的圖片,可是那些被從新填充的部分對模型就沒什麼意義了。

值得一提的是,其餘的填充方式是能夠經過 「fill_mode」 參數來指定的。

Plot of Augmented Images With a Random Vertical Shift

垂直隨機平移的效果圖

水平和垂直翻轉加強

圖片的翻轉就是在垂直翻轉時顛倒全部行的像素值,在水平翻轉時顛倒全部列的像素值。

翻轉的參數是構造 ImageDataGenerator 類時,分別經過 boolean 型的參數 horizontal_flip 或者 vertical_flip 來指定的。針對於以前提到的鳥的圖片,水平翻轉是有意義的,而垂直翻轉是沒什麼意義的。

而對於航拍圖片、天文圖片和顯微圖片而言,垂直翻轉很大多是有效的。

下面的例子就是經過控制 horizontal_flip 參數來實現圖片翻轉加強的例子。

# 水平翻轉示例
from numpy import expand_dims
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.preprocessing.image import ImageDataGenerator
from matplotlib import pyplot
# 讀圖
img = load_img('bird.jpg')
# 轉爲 numpy 數組
data = img_to_array(img)
# 擴展維度
samples = expand_dims(data, 0)
# 建立生成器
datagen = ImageDataGenerator(horizontal_flip=True)
# 準備迭代器
it = datagen.flow(samples, batch_size=1)
# 生成圖片並畫圖
for i in range(9):
	# 定義子圖
	pyplot.subplot(330 + 1 + i)
	# 生成一個批次圖片
	batch = it.next()
	# 轉化爲整型方便顯示
	image = batch[0].astype('uint32')
	# 畫圖
	pyplot.imshow(image)
# 顯示
pyplot.show()
複製代碼

執行這段程序會產生 9 張加強後的圖片。

咱們會發現水平的翻轉只是在一部分的圖片上被使用了。

Plot of Augmented Images With a Random Horizontal Flip

隨機水平翻轉的加強結果

隨機旋轉加強

旋轉加強是隨機的對圖片進行 0 到 360 度的順時針旋轉。

旋轉也會致使部分的數據被移出圖片框,會產生一些沒有像素值的區域,這些區域也須要被填充

下面的例子經過控制 rotation_range 參數在 0 到 90 度之間去旋轉圖片,來展現隨機旋轉加強的效果。

# 旋轉加強示例
from numpy import expand_dims
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.preprocessing.image import ImageDataGenerator
from matplotlib import pyplot
# 讀圖
img = load_img('bird.jpg')
# 轉爲 numpy 數組
data = img_to_array(img)
# 擴展維度
samples = expand_dims(data, 0)
# 建立生成器
datagen = ImageDataGenerator(rotation_range=90)
# 準備迭代器
it = datagen.flow(samples, batch_size=1)
# 生成圖片並畫圖
for i in range(9):
	# 定義子圖
	pyplot.subplot(330 + 1 + i)
	# 生成一個批次圖片
	batch = it.next()
	# 轉化爲整型方便顯示
	image = batch[0].astype('uint32')
	# 畫圖
	pyplot.imshow(image)
# 顯示
pyplot.show()
複製代碼

執行這個例子,會產生旋轉圖片的示例,其中空白區域是經過最鄰近法進行填充的。

Plot of Images Generated With a Random Rotation Augmentation

隨機旋轉加強的結果圖

隨機亮度加強

圖片的亮度加強能夠是使圖片變亮、使圖片變暗或者兼顧二者。

這樣是爲了使模型在訓練過程當中覆蓋不一樣的亮度水平。

我能夠在 ImageDataGenerator() 的構造函數中傳入 brightness_range 參數來指定一個最大值和最小值範圍來選擇一個亮度數值。

值小於 1.0 的時候,會變暗圖片,如 [0.5 , 1.0],相反的,值大於 1.0 時,會使圖片變亮,如 [1.0,1.5],當值爲 1.0 時,亮度不會變化。

下面的例子展現了亮度在 0.2(20%) 到 1 之間變化的隨機亮度加強的效果。

# 亮度加強示例
from numpy import expand_dims
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.preprocessing.image import ImageDataGenerator
from matplotlib import pyplot
# 讀圖
img = load_img('bird.jpg')
# 轉爲 numpy 數組
data = img_to_array(img)
# 擴展維度
samples = expand_dims(data, 0)
# 建立生成器
datagen = ImageDataGenerator(brightness_range=[0.2,1.0])
# 準備迭代器
it = datagen.flow(samples, batch_size=1)
# 生成圖片並畫圖
for i in range(9):
	# 定義子圖
	pyplot.subplot(330 + 1 + i)
	# 生成一個批次圖片
	batch = it.next()
	# 轉化爲整型方便顯示
	image = batch[0].astype('uint32')
	# 畫圖
	pyplot.imshow(image)
# 顯示
pyplot.show()
複製代碼

運行示例你會看到不一樣數值調暗圖片的效果。

Plot of Images Generated With a Random Brightness Augmentation

隨機亮度加強生成的圖片

隨機縮放加強

縮放加強就是隨機的縮放圖片,利用在圖片周圍新增像素或者插值來實現。

ImageDataGenerator 類的構造函數內傳入 zoom_range 來配置縮放的尺度。該參數能夠是一個浮點數也能夠是數組或者元組。

若是指定爲一個浮點數,那麼縮放的範圍是 [1 - value , 1 + value] 之間。舉個例子,若是你設置的參數爲 0.3,那麼你的縮放範圍就是 [0.7, 1.3] 之間,換言之就是 70% (放大)到 130%(縮小)之間。

縮放量是從縮放區域中對每一個維度(寬,高)分別均勻隨機抽樣獲得的。

縮放參數有點不直觀。須要明白一點,當數值小於 1.0 時圖片會放大,如 [ 0.5 , 0.5] 會使圖片中的目標變大或者拉近 50%,一樣的,若是數值大於 1.0 時,圖拼啊會被縮小 50%,如 [ 1.5 , 1.5 ] 目標會被縮小到或者拉遠。當係數爲 1.0 時,圖片不會有什麼變化。

下面的例子展現了讓圖片中目標變大的例子。

# 尺度縮放加強示例
from numpy import expand_dims
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.preprocessing.image import ImageDataGenerator
from matplotlib import pyplot
# 讀圖
img = load_img('bird.jpg')
# 轉爲 numpy 數組
data = img_to_array(img)
# 擴展維度
samples = expand_dims(data, 0)
# 建立生成器
datagen = ImageDataGenerator(zoom_range=[0.5,1.0])
# 準備迭代器
it = datagen.flow(samples, batch_size=1)
# 生成圖片並畫圖
for i in range(9):
	# 定義子圖
	pyplot.subplot(330 + 1 + i)
	# 生成一個批次圖片
	batch = it.next()
	# 轉化爲整型方便顯示
	image = batch[0].astype('uint32')
	# 畫圖
	pyplot.imshow(image)
# 顯示
pyplot.show()
複製代碼

運行示例就能夠獲得縮放圖片,該圖片展現了一個在寬和高尺度變化不一樣的例子,因爲寬高的縮放尺度不一樣,圖像的縱橫比也會發生變化。

Plot of Images Generated With a Random Zoom Augmentation

隨機縮放加強的效果圖

擴展閱讀

該部分會提供更多的資源供你進一步的學習。

出版物

API

文章

總結

本教程帶你探索了圖像數據加強在模型訓練時的應用。

你應該有如下收穫:

  • 圖像數據加強是爲了擴展訓練數據集,從而提升模型的性能和泛化能力。
  • 經過使用 ImageDataGenerator 類,你能夠在 Keras 上得到圖像數據加強的支持。
  • 如何使用平移、翻轉、亮度和縮放加強方法。

還有別的問題? 請在下方留言,我會盡我所能回答你的問題。

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索