1. 圖像數據增強
深度學習神經網絡的性能通常會隨着可用數據量的提高而提高。
數據擴充是一種從現有訓練數據中人爲創建新訓練數據的技術。這是通過將特定領域的技術應用於來自訓練數據的樣本(創建新的不同訓練樣本)來完成的。圖像數據增強可能是最廣爲人知的數據增強類型,涉及在訓練數據集中創建與原始圖像屬於同一類的圖像的轉換版本。
變換包括圖像處理領域中的一系列操作,例如平移,翻轉,縮放,隨機裁剪,噪聲等等。目的是通過新的,合理的樣本來擴充訓練數據集。這意味着模型可能會看到訓練集圖像的變化。例如,貓的圖片的水平翻轉可能很有意義,因爲該照片可能是從左側或右側拍攝的。垂直翻轉貓的照片是沒有意義的,並且鑑於模型不太可能看到顛倒的貓的照片,因此可能不合適。
必須仔細選擇訓練數據集所使用的特定數據增強技術,並且要在訓練數據集和問題域知識的範圍內進行選擇。此外,單獨使用數據增強方法進行實驗也是很有用的,以查看它們是否對模型性能產生可衡量的改善。
現代深度學習算法(例如卷積神經網絡或CNN)可以學習與其在圖像中位置不變的特徵。但是,增強可以進一步幫助這種變換不變的方法進行學習,並且可以幫助模型學習對變換也不變的特徵,例如從左到右到從上到下的順序,照片中的光照水平等等。
圖像數據增強通常僅應用於訓練數據集,而不應用於驗證或測試數據集。這與數據準備(例如圖像調整大小和像素縮放)不同。必須在與模型交互的所有數據集中一致地執行它們。
2. 使用ImageDataGenerator進行圖像增強
Keras深度學習庫提供了在訓練模型時自動使用數據增強的功能,通過ImageDataGenerator類實現。其支持多種技術以及像素縮放方法,重點介紹五種主要的圖像數據數據增強技術:
- 圖像通過
width_shift_range
和height_shift_range
參數移動圖像。 - 通過
horizontal_flip
和vertical_flip
參數翻轉圖像。 - 通過
rotation_range
參數旋轉圖像 - 通過
Brightness_range
參數調整圖像亮度。 - 通過
zoom_range
參數縮放圖像。
tf.keras.preprocessing.image.ImageDataGenerator(
featurewise_center=False, samplewise_center=False,
featurewise_std_normalization=False, samplewise_std_normalization=False,
zca_whitening=False, zca_epsilon=1e-06, rotation_range=0, width_shift_range=0.0,
height_shift_range=0.0, brightness_range=None, shear_range=0.0, zoom_range=0.0,
channel_shift_range=0.0, fill_mode='nearest', cval=0.0, horizontal_flip=False,
vertical_flip=False, rescale=None, preprocessing_function=None,
data_format=None, validation_split=0.0, dtype=None
)
2.1 平移圖像
移動圖像意味着在保持圖像尺寸相同的同時,沿一個方向(例如水平或垂直)移動圖像的所有像素。這意味着某些像素將從圖像上剪切下來,並且圖像的某個區域將必須指定新的像素值。ImageDataGenerator構造函數的width_shift_range和height_shift_range參數分別控制水平和垂直移位的量。這些參數可以指定一個浮點值,該值指示要移動的圖像的寬度或高度的百分比(0到1之間)。或者,可以指定許多像素來移動圖像。
from numpy import expand_dims
from keras.preprocessing.image import load_img, img_to_array, ImageDataGenerator
import matplotlib.pyplot as plt
plt.rcParams['figure.dpi'] = 200
img = load_img('dog.jpg')
data = img_to_array(img)
samples = expand_dims(data, 0)
# create image data augmentation generator
datagen = ImageDataGenerator(width_shift_range=[-200,200])
# prepare iterator
it = datagen.flow(samples, batch_size=1)
# generate samples and plot
for i in range(9):
plt.subplot(330 + 1 + i)
# generate batch of images
batch = it.next()
# convert to unsigned integers for viewing
image = batch[0].astype('uint8')
plt.imshow(image)
plt.tight_layout()
plt.show()
輸出:
可以在結果圖中看到,執行了一系列不同的隨機選擇的正向和負向水平移動,並且複製了圖像邊緣的像素值,以填充由該移動創建的圖像的空白部分。
from numpy import expand_dims
from keras.preprocessing.image import load_img, img_to_array, ImageDataGenerator
import matplotlib.pyplot as plt
plt.rcParams['figure.dpi'] = 200
img = load_img('dog.jpg')
data = img_to_array(img)
samples = expand_dims(data, 0)
# create image data augmentation generator
datagen = ImageDataGenerator(height_shift_range=0.5)
# prepare iterator
it = datagen.flow(samples, batch_size=1)
# generate samples and plot
for i in range(9):
plt.subplot(330 + 1 + i)
# generate batch of images
batch = it.next()
# convert to unsigned integers for viewing
image = batch[0].astype('uint8')
plt.imshow(image)
plt.tight_layout()
plt.show()
運行該示例將創建一個由隨機的正負垂直偏移增強的圖像。
可以看到,水平和垂直正向和負向移動都可能對所選照片有意義,但是在某些情況下,圖像邊緣處的複製像素對模型可能沒有意義。其它填充模式可以通過 fill_mode
參數指定。
2.2 水平和垂直翻轉增強
圖像翻轉意味着分別在垂直或水平翻轉的情況下翻轉像素的行或列。
翻轉增強由ImageDataGenerator類的 boolean horizontal_flip
或 vertical_flip
參數指定。本例中所用的狗之類的照片,水平翻轉可能有意義,而垂直翻轉則沒有意義。對於其他類型的圖像,例如航空照片,顯微照片等,也許垂直翻轉是有意義的。
下面的示例演示了通過 horizontal_flip
參數通過水平翻轉來增強所選照片。
from numpy import expand_dims
from keras.preprocessing.image import load_img, img_to_array, ImageDataGenerator
import matplotlib.pyplot as plt
plt.rcParams['figure.dpi'] = 200
img = load_img('dog.jpg')
data = img_to_array(img)
samples = expand_dims(data, 0)
# create image data augmentation generator
datagen = ImageDataGenerator(horizontal_flip=True)
# prepare iterator
it = datagen.flow(samples, batch_size=1)
# generate samples and plot
for i in range(9):
plt.subplot(330 + 1 + i)
# generate batch of images
batch = it.next()
# convert to unsigned integers for viewing
image = batch[0].astype('uint8')
plt.imshow(image)
plt.tight_layout()
plt.show()
輸出:
可以看到水平翻轉是隨機應用於某些圖像。
2.3 隨機旋轉增強
旋轉增強將圖像從0到360隨機順時針旋轉給定度數。旋轉可能會將像素旋轉出圖像幀,並且在該幀的區域中沒有填充的像素數據。
from numpy import expand_dims
from keras.preprocessing.image import load_img, img_to_array, ImageDataGenerator
import matplotlib.pyplot as plt
plt.rcParams['figure.dpi'] = 200
img = load_img('dog.jpg')
data = img_to_array(img)
samples = expand_dims(data, 0)
# create image data augmentation generator
datagen = ImageDataGenerator(rotation_range=90)
# prepare iterator
it = datagen.flow(samples, batch_size=1)
# generate samples and plot
for i in range(9):
plt.subplot(330 + 1 + i)
# generate batch of images
batch = it.next()
# convert to unsigned integers for viewing
image = batch[0].astype('uint8')
plt.imshow(image)
plt.tight_layout()
plt.show()
輸出:
2.4 隨機亮度增強
可以通過使圖像隨機變暗,或使圖像變亮來增強圖像的亮度。目的是允許模型從不同光照水平下的訓練圖像中學習。
可以通過指定 brightness_range
參數來實現,該參數將最小和最大範圍指定爲一個浮點數,該浮點數表示選擇增亮量的百分比。小於1.0的值會使圖像變暗,大於1.0的值會使圖像變亮,其中1.0對亮度沒有影響。
from numpy import expand_dims
from keras.preprocessing.image import load_img, img_to_array, ImageDataGenerator
import matplotlib.pyplot as plt
plt.rcParams['figure.dpi'] = 200
img = load_img('dog.jpg')
data = img_to_array(img)
samples = expand_dims(data, 0)
# create image data augmentation generator
datagen = ImageDataGenerator(brightness_range=[0.3,1.5])
# prepare iterator
it = datagen.flow(samples, batch_size=1)
# generate samples and plot
for i in range(9):
plt.subplot(330 + 1 + i)
# generate batch of images
batch = it.next()
# convert to unsigned integers for viewing
image = batch[0].astype('uint8')
plt.imshow(image)
plt.tight_layout()
plt.show()
2.5 隨機縮放增強
縮放增強會隨機放大圖像,並在圖像周圍添加新的像素值或分別插入像素值。可以通過ImageDataGenerator的 zoom_range
參數配置圖像。將縮放百分比指定爲單個浮點數,或者將範圍指定爲數組或元組。
如果指定了float,則縮放範圍將爲[1-設置值,1+設置值]。例如,如果指定0.3,則範圍將爲[0.7、1.3]之間。分別從每個尺寸(寬度,高度)的縮放區域中均勻地隨機採樣縮放量。
from numpy import expand_dims
from keras.preprocessing.image import load_img, img_to_array, ImageDataGenerator
import matplotlib.pyplot as plt
plt.rcParams['figure.dpi'] = 200
img = load_img('dog.jpg')
data = img_to_array(img)
samples = expand_dims(data, 0)
# create image data augmentation generator
datagen = ImageDataGenerator(zoom_range=[0.5,1.0])
# prepare iterator
it = datagen.flow(samples, batch_size=1)
# generate samples and plot
for i in range(9):
plt.subplot(330 + 1 + i)
# generate batch of images
batch = it.next()
# convert to unsigned integers for viewing
image = batch[0].astype('uint8')
plt.imshow(image)
plt.tight_layout()
plt.show()
參考:
https://machinelearningmastery.com/how-to-configure-image-data-augmentation-when-training-deep-learning-neural-networks/