【轉(zhuǎn)載】Keras-5 基于 ImageDataGenerator 的 Data Augmentation實現(xiàn)

https://blog.csdn.net/weiwei9363/article/details/78635674


Image Data Augmentation In Keras

討論的內(nèi)容包括

Data Augmentation

ImageDataGenerator 的使用方法

在cifar-10數(shù)據(jù)集上使用Data Augmentation

完整代碼在 這里 下載

Data Augmentation

Data Aumentation(數(shù)據(jù)擴充)指的是在使用以下或者其他方法增加數(shù)據(jù)輸入量。這里,我們特指圖像數(shù)據(jù)柱恤。

旋轉(zhuǎn) | 反射變換(Rotation/reflection): 隨機旋轉(zhuǎn)圖像一定角度; 改變圖像內(nèi)容的朝向;

翻轉(zhuǎn)變換(flip): 沿著水平或者垂直方向翻轉(zhuǎn)圖像;

縮放變換(zoom): 按照一定的比例放大或者縮小圖像;

平移變換(shift): 在圖像平面上對圖像以一定方式進行平移;

可以采用隨機或人為定義的方式指定平移范圍和平移步長, 沿水平或豎直方向進行平移. 改變圖像內(nèi)容的位置;

尺度變換(scale): 對圖像按照指定的尺度因子, 進行放大或縮小; 或者參照SIFT特征提取思想, 利用指定的尺度因子對圖像濾波構(gòu)造尺度空間. 改變圖像內(nèi)容的大小或模糊程度;

對比度變換(contrast): 在圖像的HSV顏色空間歼跟,改變飽和度S和V亮度分量灭红,保持色調(diào)H不變. 對每個像素的S和V分量進行指數(shù)運算(指數(shù)因子在0.25到4之間), 增加光照變化;

噪聲擾動(noise): 對圖像的每個像素RGB進行隨機擾動, 常用的噪聲模式是椒鹽噪聲和高斯噪聲;

Data Aumentation 有很多好處悉罕,比如數(shù)據(jù)量太小了台盯,我們用數(shù)據(jù)擴充來增加訓練數(shù)據(jù),或者通過Data Aumentation防止過擬合的問題痴施。

在Keras中,ImageDataGenerator就是干這個事情的,特別方便辣吃。接下來动遭,我們就聊聊ImageDataGenerator的使用方法

from keras.preprocessing.image import ImageDataGenerator

from keras.preprocessing import image

import matplotlib.pyplot as plt

import numpy as np

%matplotlib inline


Using TensorFlow backend.


ImageDataGenerator for Single image

ImageDataGenerator 參數(shù)很多,詳見這里或者在python環(huán)境下輸入ImageDataGenerator?神得,我們先看一個例子厘惦,這個例子將對一張圖片進行數(shù)據(jù)擴充

# 指定參數(shù)

# rotation_range 旋轉(zhuǎn)

# width_shift_range 左右平移

# height_shift_range 上下平移

# zoom_range 隨機放大或縮小

img_generator = ImageDataGenerator(

? ? rotation_range = 90,

? ? width_shift_range = 0.2,

? ? height_shift_range = 0.2,

? ? zoom_range = 0.3

? ? )


# 導入并顯示圖片

img_path = './imgs/dog.jpg'

img = image.load_img(img_path)

plt.imshow(img)


<matplotlib.image.AxesImage at 0x7fd738246d30>


flow()將會返回一個生成器,這個生成器用來擴充數(shù)據(jù)哩簿,每次都會產(chǎn)生batch_size個樣本宵蕉。

因為目前我們只導入了一張圖片,因此每次生成的圖片都是基于這張圖片而產(chǎn)生的节榜,可以看到結(jié)果羡玛,旋轉(zhuǎn)、位移全跨、放大縮小缝左,統(tǒng)統(tǒng)都有。

flow()可以將產(chǎn)生的圖片進行保存浓若,詳見 深度學習中的Data Augmentation方法和代碼實現(xiàn)

生成圖片的過程大概是這樣的渺杉,并且可以一直一直一直無限循環(huán)的生成

# 將圖片轉(zhuǎn)為數(shù)組

x = image.img_to_array(img)

# 擴充一個維度

x = np.expand_dims(x, axis=0)

# 生成圖片

gen = img_generator.flow(x, batch_size=1)

# 顯示生成的圖片

plt.figure()

for i in range(3):

? ? for j in range(3):

? ? ? ? x_batch = next(gen)

? ? ? ? idx = (3*i) + j

? ? ? ? plt.subplot(3, 3, idx+1)

? ? ? ? plt.imshow(x_batch[0]/256)

x_batch.shape


(1, 160, 240, 3)

ImageDataGenerator for Multiple image

單張圖片的數(shù)據(jù)擴展我們已經(jīng)演示完畢了,但是通常情況下挪钓,我們應該是有一個不太大的訓練集需要Data Aumentation或者為了防止過擬合是越,總之,就是對一組數(shù)據(jù)進行Data Aumentation碌上。這里我們以cifar-10數(shù)據(jù)庫做一個演示倚评。

我們將進行一組實驗,比較訓練之后的測試結(jié)果:

cifar-10 20%數(shù)據(jù)

cifar-10 20%數(shù)據(jù) + Data Augmentation

from keras.datasets import cifar10

from keras.layers.core import Dense, Flatten, Activation, Dropout

from keras.layers.convolutional import Conv2D

from keras.layers.pooling import MaxPooling2D

from keras.layers.normalization import BatchNormalization

from keras.models import Sequential

from keras.utils import np_utils


(x_train, y_train),(x_test, y_test) = cifar10.load_data()

print(x_train.shape, y_train.shape, x_test.shape, y_test.shape)


(50000, 32, 32, 3) (50000, 1) (10000, 32, 32, 3) (10000, 1)


def preprocess_data(x):

? ? x /= 255

? ? x -= 0.5

? ? x *= 2

? ? return x


# 預處理

x_train = x_train.astype(np.float32)

x_test = x_test.astype(np.float32)

x_train = preprocess_data(x_train)

x_test = preprocess_data(x_test)

# one-hot encoding

n_classes = 10

y_train = np_utils.to_categorical(y_train, n_classes)

y_test = np_utils.to_categorical(y_test, n_classes)


# 取 20% 的訓練數(shù)據(jù)

x_train_part = x_train[:10000]

y_train_part = y_train[:10000]

print(x_train_part.shape, y_train_part.shape)


(10000, 32, 32, 3) (10000, 10)


# 建立一個簡單的卷積神經(jīng)網(wǎng)絡

def build_model():

? ? model = Sequential()

? ? model.add(Conv2D(64, (3,3), input_shape=(32,32,3)))

? ? model.add(Activation('relu'))

? ? model.add(BatchNormalization(scale=False, center=False))

? ? model.add(Conv2D(32, (3,3)))

? ? model.add(Activation('relu'))

? ? model.add(MaxPooling2D((2,2)))

? ? model.add(Dropout(0.2))

? ? model.add(BatchNormalization(scale=False, center=False))

? ? model.add(Flatten())

? ? model.add(Dense(256))

? ? model.add(Activation('relu'))

? ? model.add(Dropout(0.2))

? ? model.add(BatchNormalization())

? ? model.add(Dense(n_classes))

? ? model.add(Activation('softmax'))

? ? return model


# 訓練參數(shù)

batch_size = 128

epochs = 20


cifar-10 20%數(shù)據(jù)

model = build_model()

model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

model.fit(x_train_part, y_train_part, epochs=epochs, batch_size=batch_size, verbose=1, validation_split=0.1)


Train on 9000 samples, validate on 1000 samples

Epoch 1/20

9000/9000 [==============================] - 8s 844us/step - loss: 1.8075 - acc: 0.4040 - val_loss: 2.9955 - val_acc: 0.1150

Epoch 2/20

9000/9000 [==============================] - 3s 343us/step - loss: 1.2029 - acc: 0.5742 - val_loss: 3.0341 - val_acc: 0.1910

Epoch 3/20

9000/9000 [==============================] - 3s 342us/step - loss: 0.9389 - acc: 0.6690 - val_loss: 2.8508 - val_acc: 0.1580

...........

...........

Epoch 18/20

9000/9000 [==============================] - 5s 597us/step - loss: 0.0668 - acc: 0.9824 - val_loss: 1.6110 - val_acc: 0.5840

Epoch 19/20

9000/9000 [==============================] - 6s 629us/step - loss: 0.0681 - acc: 0.9826 - val_loss: 1.5807 - val_acc: 0.5980

Epoch 20/20

9000/9000 [==============================] - 5s 607us/step - loss: 0.0597 - acc: 0.9847 - val_loss: 1.6222 - val_acc: 0.5930


loss, acc = model.evaluate(x_test, y_test, batch_size=32)

print('Loss: ', loss)

print('Accuracy: ', acc)


10000/10000 [==============================] - 4s 444us/step

Loss:? 1.65560287151

Accuracy:? 0.6058


經(jīng)過20輪的訓練之后馏予,在訓練集上已經(jīng)有98%以上的準確率天梧,但是在測試集上只有60%左右的準確率,可以說是過擬合了霞丧,主要原因就是訓練集太小了呢岗,無法達到很好的效果。那么接下來我們試試經(jīng)過Data Augmentation之后的準確率如何

cifar-10 20%數(shù)據(jù) + Data Augmentation

在進行Data Augmentation時要注意的就是:生成的數(shù)據(jù)是有意義的蛹尝。比如說對于某些醫(yī)療圖像后豫,如果進行了旋轉(zhuǎn),那么這個數(shù)據(jù)就屬于采樣錯誤突那,是沒用的了挫酿。因此,在設置生成參數(shù)時要結(jié)合實際的情況愕难。

# 設置生成參數(shù)

img_generator = ImageDataGenerator(

? ? rotation_range = 20,

? ? width_shift_range = 0.2,

? ? height_shift_range = 0.2,

? ? zoom_range = 0.2

? ? )


下面的代碼是一種“手動”的訓練方式早龟,Progbar是進度條惫霸,用于顯示訓練進度。

另外一種“自動”的方法拄衰,請參考 官網(wǎng)給的例子 中 model.fit_generator的用法

from keras.utils import generic_utils

model_2 = build_model()

model_2.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# Data Augmentation后它褪,數(shù)據(jù)變多了,因此我們需要更的訓練次數(shù)

for e in range(epochs*4):

? ? print('Epoch', e)

? ? print('Training...')

? ? progbar = generic_utils.Progbar(x_train_part.shape[0])

? ? batches = 0

? ? for x_batch, y_batch in img_generator.flow(x_train_part, y_train_part, batch_size=batch_size, shuffle=True):

? ? ? ? loss,train_acc = model_2.train_on_batch(x_batch, y_batch)

? ? ? ? batches += x_batch.shape[0]

? ? ? ? if batches > x_train_part.shape[0]:

? ? ? ? ? ? break

? ? ? ? progbar.add(x_batch.shape[0], values=[('train loss', loss),('train acc', train_acc)])


Epoch 0

Training...

10000/10000 [==============================] - 13s 1ms/step - train loss: 2.0455 - train acc: 0.3187

Epoch 1

Training...

10000/10000 [==============================] - 10s 1ms/step - train loss: 1.7304 - train acc: 0.3857

Epoch 2

Training...

10000/10000 [==============================] - 10s 1ms/step - train loss: 1.6195 - train acc: 0.4220

Epoch 3

Training...

10000/10000 [==============================] - 10s 1ms/step - train loss: 1.5595 - train acc: 0.4417

.........

.........

Epoch 76

Training...

10000/10000 [==============================] - 9s 874us/step - train loss: 0.8809 - train acc: 0.6890

Epoch 77

Training...

10000/10000 [==============================] - 9s 891us/step - train loss: 0.8776 - train acc: 0.6949

Epoch 78

Training...

10000/10000 [==============================] - 9s 892us/step - train loss: 0.8723 - train acc: 0.6916

Epoch 79

Training...

10000/10000 [==============================] - 9s 892us/step - train loss: 0.8737 - train acc: 0.6919


loss, acc = model_2.evaluate(x_test, y_test, batch_size=32)

print('Loss: ', loss)

print('Accuracy: ', acc)


10000/10000 [==============================] - 5s 455us/step

Loss:? 0.842164948082

Accuracy:? 0.7057


哇塞翘悉!經(jīng)過Data Augmentation之后茫打,測試的準去率已經(jīng)有70%,提高了10%妖混。并且我相信繼續(xù)增加訓練次數(shù)準確率將會繼續(xù)上升老赤。

好的,實驗到此結(jié)束制市,這里只是給出一個簡單的Data Augmentation實現(xiàn)方法抬旺,ImageDataGenerator這個類,還有其他有趣的功能我們還沒有用到祥楣,有興趣的同學可以在 這里 進行詳細的閱讀开财。網(wǎng)絡上也有很多關于Data Augenmentation的討論,希望可以幫助到大家误褪。

使用深度學習(CNN)算法進行圖像識別工作時责鳍,有哪些data augmentation 的奇技淫巧?

The Effectiveness of Data Augmentation in Image Classification using Deep

Learning

keras面向小數(shù)據(jù)集的圖像分類(VGG-16基礎上fine-tune)實現(xiàn)(附代碼)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末兽间,一起剝皮案震驚了整個濱河市历葛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嘀略,老刑警劉巖恤溶,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異帜羊,居然都是意外死亡咒程,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門讼育,熙熙樓的掌柜王于貴愁眉苦臉地迎上來孵坚,“玉大人,你說我怎么就攤上這事窥淆。” “怎么了巍杈?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵忧饭,是天一觀的道長。 經(jīng)常有香客問我筷畦,道長词裤,這世上最難降的妖魔是什么刺洒? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮吼砂,結(jié)果婚禮上逆航,老公的妹妹穿的比我還像新娘。我一直安慰自己渔肩,他們只是感情好因俐,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著周偎,像睡著了一般抹剩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蓉坎,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天澳眷,我揣著相機與錄音,去河邊找鬼蛉艾。 笑死钳踊,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的勿侯。 我是一名探鬼主播拓瞪,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼罐监!你這毒婦竟也來了吴藻?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤弓柱,失蹤者是張志新(化名)和其女友劉穎沟堡,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體矢空,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡航罗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了屁药。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粥血。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖酿箭,靈堂內(nèi)的尸體忽然破棺而出复亏,到底是詐尸還是另有隱情,我是刑警寧澤缭嫡,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布缔御,位于F島的核電站,受9級特大地震影響妇蛀,放射性物質(zhì)發(fā)生泄漏耕突。R本人自食惡果不足惜笤成,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望眷茁。 院中可真熱鬧炕泳,春花似錦、人聲如沸上祈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽雇逞。三九已至荤懂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間塘砸,已是汗流浹背节仿。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留掉蔬,地道東北人廊宪。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像女轿,于是被迫代替她去往敵國和親箭启。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容