深度學習基礎系列(十一)| Keras中圖像加強技術詳解

  在深度學習中,數據短缺是咱們常常面臨的一個問題,雖然如今有很多公開數據集,但跟大公司掌握的海量數據集相比,數量上仍然偏少,而某些特定領域的數據採集更是很是困難。根據以前的學習可知,數據量少帶來的最直接影響就是過擬合。那有沒有辦法在現有少許數據基礎上,下降或解決過擬合問題呢?學習

      答案是有的,就是數據加強技術。咱們能夠對現有的數據,如圖片數據進行平移、翻轉、旋轉、縮放、亮度加強等操做,以生成新的圖片來參與訓練或測試。這種操做能夠將圖片數量提高數倍,由此大大下降了過擬合的可能。本文將詳解圖像加強技術在Keras中的原理和應用。測試

 

1、Keras中的ImageDataGenerator類

  圖像加強的官網地址是:https://keras.io/preprocessing/image/ ,API使用相對簡單,功能也很強大。spa

  先介紹的是ImageDataGenerator類,這個類定義了圖片該如何進行加強操做,其API及參數定義以下:rest

keras.preprocessing.image.ImageDataGenerator(
    featurewise_center=False, #輸入值按照均值爲0進行處理     samplewise_center=False, #每一個樣本的均值按0處理     featurewise_std_normalization=False, #輸入值按照標準正態化處理
    samplewise_std_normalization=False, #每一個樣本按照標準正態化處理     zca_whitening=False, # 是否開啓增白     zca_epsilon=1e-06,     rotation_range=0, #圖像隨機旋轉必定角度,最大旋轉角度爲設定值     width_shift_range=0.0, #圖像隨機水平平移,最大平移值爲設定值。若值爲小於1的float值,則可認爲是按比例平移,若大於1,則平移的是像素;若值爲整型,平移的也是像素;假設像素爲2.0,則移動範圍爲[-1,1]之間     height_shift_range=0.0, #圖像隨機垂直平移,同上     brightness_range=None, # 圖像隨機亮度加強,給定一個含兩個float值的list,亮度值取自上下限值間     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)

   下文將以mnist和花類的數據集進行圖片操做,其中花類(17種花,共1360張圖片)數據集可見個人百度網盤: https://pan.baidu.com/s/1YDA_VOBlJSQEijcCoGC60w 。讓咱們以直觀地方式看看各參數能帶來什麼樣的圖片變化。code

   隨機旋轉orm

  咱們可用mnist數據集對圖片進行隨機旋轉,旋轉的最大角度由參數定義。blog

from keras.datasets import mnist
from keras.preprocessing.image import ImageDataGenerator
from matplotlib import pyplot
from keras import backend as K

K.set_image_dim_ordering('th')

(train_data, train_label), (test_data, test_label) = mnist.load_data()
train_data = train_data.reshape(train_data.shape[0], 1, 28, 28)
train_data = train_data.astype('float32')

# 建立圖像生成器,指定對圖像操做的內容
datagen = ImageDataGenerator(rotation_range=90)
# 圖像生成器要訓練的數據
datagen.fit(train_data)

# 這是個圖像生成迭代器,是能夠無限生成各類新圖片,咱們指定每輪迭代只生成9張圖片
for batch_data, batch_label in datagen.flow(train_data, train_label, batch_size=9):
    for i in range(0, 9):
        # 建立一個 3*3的九宮格,以顯示圖片
        pyplot.subplot(330 + 1 + i)
        pyplot.imshow(batch_data[i].reshape(28, 28), cmap=pyplot.get_cmap('gray'))
    pyplot.show()
    break

  生成結果爲:圖片

  隨機平移ip

  咱們可用花類數據集對圖片進行隨機平移,能夠在垂直和水平方向上平移,平移最大值由參數定義。內存

from keras.preprocessing.image import ImageDataGenerator
from matplotlib import pyplot
from keras.preprocessing.image import array_to_img

IMAGE_SIZE = 224
NUM_CLASSES = 17
TRAIN_PATH = '/home/yourname/Documents/tensorflow/images/17flowerclasses/train'
TEST_PATH = '/home/yourname/Documents/tensorflow/images/17flowerclasses/test'
FLOWER_CLASSES = ['Bluebell', 'ButterCup', 'ColtsFoot', 'Cowslip', 'Crocus', 'Daffodil', 'Daisy',
                  'Dandelion', 'Fritillary', 'Iris', 'LilyValley', 'Pansy', 'Snowdrop', 'Sunflower',
                  'Tigerlily', 'tulip', 'WindFlower']

# 建立圖像生成器,指定對圖像操做的內容,平移的最大比例爲50%
train_datagen = ImageDataGenerator(width_shift_range=0.5, height_shift_range=0.5)

# 這是個圖像生成迭代器,是能夠無限生成各類新圖片,咱們指定每輪迭代只生成9張圖片
for X_batch, y_batch in train_datagen.flow_from_directory(directory=TRAIN_PATH, target_size=(IMAGE_SIZE, IMAGE_SIZE),batch_size=9, classes=FLOWER_CLASSES):
    for i in range(0, 9):
        pyplot.subplot(330 + 1 + i)
        pyplot.imshow(array_to_img(X_batch[i]))
    pyplot.show()
    break

  生成結果爲:

  能夠觀察到,圖片除了實現平移外,其原來的位置都被最近的圖案給填充,由於默認給的填充方式是nearest。

  隨機亮度調整

  咱們可用花類數據集對圖片進行隨機亮度調整,亮度範圍由參數定義。

from keras.preprocessing.image import ImageDataGenerator
from matplotlib import pyplot
from keras.preprocessing.image import array_to_img

IMAGE_SIZE = 224
NUM_CLASSES = 17
TRAIN_PATH = '/home/yourname/Documents/tensorflow/images/17flowerclasses/train'
TEST_PATH = '/home/yourname/Documents/tensorflow/images/17flowerclasses/test'
FLOWER_CLASSES = ['Bluebell', 'ButterCup', 'ColtsFoot', 'Cowslip', 'Crocus', 'Daffodil', 'Daisy',
                  'Dandelion', 'Fritillary', 'Iris', 'LilyValley', 'Pansy', 'Snowdrop', 'Sunflower',
                  'Tigerlily', 'tulip', 'WindFlower']

# 建立圖像生成器,指定對圖像操做的內容,亮度範圍在0.1~10之間隨機選擇
train_datagen = ImageDataGenerator(brightness_range=[0.1, 10])

# 這是個圖像生成迭代器,是能夠無限生成各類新圖片,咱們指定每輪迭代只生成9張圖片
for X_batch, y_batch in train_datagen.flow_from_directory(directory=TRAIN_PATH, target_size=(IMAGE_SIZE, IMAGE_SIZE),batch_size=9, classes=FLOWER_CLASSES):
    for i in range(0, 9):
        pyplot.subplot(330 + 1 + i)
        pyplot.imshow(array_to_img(X_batch[i]))
    pyplot.show()
    break

  生成結果爲:

  隨機焦距調整

  咱們可用mnist數據集對圖片進行隨機焦距調整,焦距調整值由參數定義。

from keras.datasets import mnist
from keras.preprocessing.image import ImageDataGenerator
from matplotlib import pyplot
from keras import backend as K

K.set_image_dim_ordering('th')

(train_data, train_label), (test_data, test_label) = mnist.load_data()
train_data = train_data.reshape(train_data.shape[0], 1, 28, 28)
train_data = train_data.astype('float32')

# 建立圖像生成器,指定對圖像操做的內容,焦距值在0.1~1之間
datagen = ImageDataGenerator(zoom_range=[0.1, 1])
# 圖像生成器要訓練的數據
datagen.fit(train_data)

# 這是個圖像生成迭代器,是能夠無限生成各類新圖片,咱們指定每輪迭代只生成9張圖片
for batch_data, batch_label in datagen.flow(train_data, train_label, batch_size=9):
    for i in range(0, 9):
        # 建立一個 3*3的九宮格,以顯示圖片
        pyplot.subplot(330 + 1 + i)
        pyplot.imshow(batch_data[i].reshape(28, 28), cmap=pyplot.get_cmap('gray'))
    pyplot.show()
    break

  生成結果爲:

  能夠看出這跟相機調焦同樣,能夠放大或縮小焦距。

  隨機翻轉

  咱們可用花類數據集對圖片進行隨機翻轉。

from keras.preprocessing.image import ImageDataGenerator
from matplotlib import pyplot
from keras.preprocessing.image import array_to_img

IMAGE_SIZE = 224
NUM_CLASSES = 17
TRAIN_PATH = '/home/hutao/Documents/tensorflow/images/17flowerclasses/train'
TEST_PATH = '/home/hutao/Documents/tensorflow/images/17flowerclasses/test'
FLOWER_CLASSES = ['Bluebell', 'ButterCup', 'ColtsFoot', 'Cowslip', 'Crocus', 'Daffodil', 'Daisy',
                  'Dandelion', 'Fritillary', 'Iris', 'LilyValley', 'Pansy', 'Snowdrop', 'Sunflower',
                  'Tigerlily', 'tulip', 'WindFlower']

# 建立圖像生成器,指定對圖像操做的內容,圖片隨機翻轉
train_datagen = ImageDataGenerator(horizontal_flip=True, vertical_flip=True)

# 這是個圖像生成迭代器,是能夠無限生成各類新圖片,咱們指定每輪迭代只生成9張圖片
for X_batch, y_batch in train_datagen.flow_from_directory(directory=TRAIN_PATH, target_size=(IMAGE_SIZE, IMAGE_SIZE),batch_size=9, classes=FLOWER_CLASSES):
    for i in range(0, 9):
        pyplot.subplot(330 + 1 + i)
        pyplot.imshow(array_to_img(X_batch[i]))
    pyplot.show()
    break

  生成結果爲:

  從上圖可看出,有些圖片水平翻轉了,有些是垂直翻轉了。

  ZCA圖像增白

  說實在我不太清楚該技術有何用,用花類圖片實驗結果顯示zca不支持,能夠用mnist數據集來看看效果。

from keras.datasets import mnist
from keras.preprocessing.image import ImageDataGenerator
from matplotlib import pyplot
from keras import backend as K

K.set_image_dim_ordering('th')

(train_data, train_label), (test_data, test_label) = mnist.load_data()
train_data = train_data.reshape(train_data.shape[0], 1, 28, 28)
train_data = train_data.astype('float32')

# 建立圖像生成器,指定對圖像操做的內容,增白圖片
datagen = ImageDataGenerator(zca_whitening=True)
# 圖像生成器要訓練的數據
datagen.fit(train_data)

# 這是個圖像生成迭代器,是能夠無限生成各類新圖片,咱們指定每輪迭代只生成9張圖片
for batch_data, batch_label in datagen.flow(train_data, train_label, batch_size=9):
    for i in range(0, 9):
        # 建立一個 3*3的九宮格,以顯示圖片
        pyplot.subplot(330 + 1 + i)
        pyplot.imshow(batch_data[i].reshape(28, 28), cmap=pyplot.get_cmap('gray'))
    pyplot.show()
    break

  生成結果爲:

  特徵標準化

  特徵標準化的含義是使圖片的像素均值爲0,標準差爲1,不過我試了屢次,直觀效果不明顯。

from keras.datasets import mnist
from keras.preprocessing.image import ImageDataGenerator
from matplotlib import pyplot
from keras import backend as K

K.set_image_dim_ordering('th')

(train_data, train_label), (test_data, test_label) = mnist.load_data()
train_data = train_data.reshape(train_data.shape[0], 1, 28, 28)
train_data = train_data.astype('float32')

# 建立圖像生成器,指定對圖像操做的內容,容許圖片標準化處理
datagen = ImageDataGenerator(featurewise_center=True, featurewise_std_normalization=True)
# 圖像生成器要訓練的數據
datagen.fit(train_data)

# 這是個圖像生成迭代器,是能夠無限生成各類新圖片,咱們指定每輪迭代只生成9張圖片
for batch_data, batch_label in datagen.flow(train_data, train_label, batch_size=9):
    for i in range(0, 9):
        # 建立一個 3*3的九宮格,以顯示圖片
        pyplot.subplot(330 + 1 + i)
        pyplot.imshow(batch_data[i].reshape(28, 28), cmap=pyplot.get_cmap('gray'))
    pyplot.show()
    break

  生成結果爲:

  就我的而言,我傾向於在圖像加強中使用旋轉、亮度調整、翻轉和平移操做。

 

2、Keras如何進行圖像加強數據訓練

  在以前的文章中我已經展示過數據加強的使用。在Keras中,加強圖片有三種來源:

  • 圖片來源於已知數據集,如mnist、cifar,數據格式爲numpy格式;
  • 圖片來源於咱們本身蒐集的圖片,如本文引入的花類數據集,其圖片爲jpg、png等格式;
  • 圖片來源於panda數據集;

  其中數據來源已知數據集,其操做方法以下:

(x_train, y_train), (x_test, y_test) = cifar10.load_data()
y_train = np_utils.to_categorical(y_train, num_classes)
y_test = np_utils.to_categorical(y_test, num_classes)

datagen = ImageDataGenerator(
    featurewise_center=True,
    featurewise_std_normalization=True,
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    horizontal_flip=True)

#生成器綁定訓練集
datagen.fit(x_train)

# 模型綁定生成器,並不停地迭代產生數據,可指定迭代次數,假設圖片總數爲1000張,batch默認爲32,則每次迭代須要產生1000/32=32個步驟
history = model.fit_generator(datagen.flow(x_train, y_train, batch_size=32),
                    steps_per_epoch=len(x_train) / 32, epochs=epochs)

  數據來源圖片集,其操做方法以下:

batch_size = 32
# 迭代50次
epochs = 50
# 依照模型規定,圖片大小被設定爲224
IMAGE_SIZE = 224
TRAIN_PATH = '/home/yourname/Documents/tensorflow/images/17flowerclasses/train'
TEST_PATH = '/home/yourname/Documents/tensorflow/images/17flowerclasses/test'
FLOWER_CLASSES = ['Bluebell', 'ButterCup', 'ColtsFoot', 'Cowslip', 'Crocus', 'Daffodil', 'Daisy','Dandelion', 'Fritillary', 'Iris', 'LilyValley', 'Pansy', 'Snowdrop', 'Sunflower','Tigerlily', 'tulip', 'WindFlower']

# 使用數據加強
train_datagen = ImageDataGenerator(rotation_range=90)
# 可指定輸出圖片大小,由於深度學習要求訓練圖片大小保持一致 train_generator
= train_datagen.flow_from_directory(directory=TRAIN_PATH, target_size=(IMAGE_SIZE, IMAGE_SIZE), classes=FLOWER_CLASSES) test_datagen = ImageDataGenerator() test_generator = test_datagen.flow_from_directory(directory=TEST_PATH, target_size=(IMAGE_SIZE, IMAGE_SIZE), classes=FLOWER_CLASSES) # 運行模型 history = model.fit_generator(train_generator, epochs=epochs, validation_data=test_generator)

   須要說明的是,這些加強圖片都是在內存中實時批量迭代生成的,不是一次性被讀入內存,這樣能夠極大地節約內存空間,加快處理速度。若想保留中間過程生成的加強圖片,能夠在上述方法中添加保存路徑等參數,此處再也不贅述。

 

3、結論

  本文介紹瞭如何在Keras中使用圖像加強技術,對圖片能夠進行各類操做,以生成數倍於原圖片的加強圖片集。這些數據集可幫助咱們有效地對抗過擬合問題,更好地生成理想的模型。

相關文章
相關標籤/搜索