如何用小樣本訓練高性能深度網(wǎng)絡

本文借鑒http://blog.csdn.net/caanyee/article/details/52502759,自學使用.

數(shù)據(jù)預處理與數(shù)據(jù)提升

為了盡量利用我們有限的訓練數(shù)據(jù),我們將通過一系列隨機變換對數(shù)據(jù)進行提升,這樣我們的模型將看不到任何兩張完全相同的圖片,這有利于我們抑制過擬合暗膜,使得模型的泛化能力更好赖阻。

在Keras中黍匾,這個步驟可以通過keras.preprocessing.image.ImageGenerator來實現(xiàn)

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())

用以生成一個batch的圖像數(shù)據(jù)赔嚎,支持實時數(shù)據(jù)提升。訓練時該函數(shù)會無限生成數(shù)據(jù)鞋拟,直到達到規(guī)定的epoch次數(shù)為止。

參數(shù)

featurewise_center:布爾值惹资,使輸入數(shù)據(jù)集去中心化(均值為0), 按feature執(zhí)行,默認false

samplewise_center:布爾值贺纲,使輸入數(shù)據(jù)的每個樣本均值為0,默認false

featurewise_std_normalization:布爾值,將輸入除以數(shù)據(jù)集的標準差以完成標準化, 按feature執(zhí)行

samplewise_std_normalization:布爾值布轿,將輸入的每個樣本除以其自身的標準差

zca_whitening:布爾值哮笆,對輸入數(shù)據(jù)施加ZCA白化

zca_epsilon: ZCA使用的eposilon,默認1e-6

rotation_range:整數(shù)汰扭,數(shù)據(jù)提升時圖片隨機轉動的角度

width_shift_range:浮點數(shù)稠肘,圖片寬度的某個比例,數(shù)據(jù)提升時圖片水平偏移的幅度

height_shift_range:浮點數(shù)萝毛,圖片高度的某個比例项阴,數(shù)據(jù)提升時圖片豎直偏移的幅度

shear_range:浮點數(shù),剪切強度(逆時針方向的剪切變換角度)

zoom_range:浮點數(shù)或形如[lower,upper]的列表笆包,隨機縮放的幅度环揽,若為浮點數(shù),則相當于[lower,upper] = [1 - zoom_range, 1+zoom_range]

channel_shift_range:浮點數(shù)庵佣,隨機通道偏移的幅度

fill_mode:歉胶;‘constant’,‘nearest’巴粪,‘reflect’或‘wrap’之一通今,當進行變換時超出邊界的點將根據(jù)本參數(shù)給定的方法進行處理

cval:浮點數(shù)或整數(shù),當fill_mode=constant時肛根,指定要向超出邊界的點填充的值

horizontal_flip:布爾值辫塌,進行隨機水平翻轉

vertical_flip:布爾值,進行隨機豎直翻轉

rescale: 重放縮因子,默認為None. 如果為None或0則不進行放縮,否則會將該數(shù)值乘到數(shù)據(jù)上(在應用其他變換之前)

preprocessing_function: 將被應用于每個輸入的函數(shù)派哲。該函數(shù)將在任何其他修改之前運行臼氨。該函數(shù)接受一個參數(shù),為一張圖片(秩為3的numpy array)芭届,并且輸出一個具有相同shape的numpy array

data_format:字符串储矩,“channel_first”或“channel_last”之一感耙,代表圖像的通道維的位置。該參數(shù)是Keras 1.x中的image_dim_ordering椰苟,“channel_last”對應原本的“tf”抑月,“channel_first”對應原本的“th”。以128x128的RGB圖像為例舆蝴,“channel_first”應將數(shù)據(jù)組織為(3,128,128)谦絮,而“channel_last”應將數(shù)據(jù)組織為(128,128,3)。該參數(shù)的默認值是~/.keras/keras.json中設置的值洁仗,若從未設置過层皱,則為“channel_last”

舉個例子:

datagen = ImageDataGenerator(
        rotation_range=40, (隨機旋轉40度)
        width_shift_range=0.2,(圖片水平偏移20%)
        height_shift_range=0.2,(圖片垂直偏移20%)
        rescale=1./255,(歸一化,縮放至1/255,浮點數(shù),數(shù)值乘以數(shù)據(jù))
        shear_range=0.2,(逆時針方向剪切變換角度)
        zoom_range=0.2,(隨機縮放,[lower,upper],浮點數(shù),[lower,upper]=[1-浮點數(shù),1+浮點數(shù)])
        horizontal_flip=True,(隨機水平翻轉)
        fill_mode='nearest'(超出邊界時怎么處理))

附帶一個錯切的程序

import cv
import math

def Warp(image, angle):
    a = math.tan(angle * math.pi / 180.0)
    W = image.width
    H = int(image.height + W * a)
    size = (W, H)
    iWarp = cv.CreateImage(size, image.depth, image.nChannels)
    for i in range(image.height):
        for j in range(image.width):
            x = int(i + j * a)
            iWarp[x, j] = image[i, j]
    return iWarp

image = cv.LoadImage('data/train/cat.7.jpg', 1)
iWarp1 = Warp(image, 15)
cv.ShowImage('image', image)
cv.ShowImage('1', iWarp1)
cv.WaitKey(0)

數(shù)據(jù)提升是對抗過擬合問題的一個武器,但還不夠赠潦,因為提升過的數(shù)據(jù)仍然是高度相關的叫胖。對抗過擬合的你應該主要關注的是模型的“熵容量”——模型允許存儲的信息量。能夠存儲更多信息的模型能夠利用更多的特征取得更好的性能她奥,但也有存儲不相關特征的風險瓮增。另一方面,只能存儲少量信息的模型會將存儲的特征主要集中在真正相關的特征上哩俭,并有更好的泛化性能绷跑。

有很多不同的方法來調整模型的“熵容量”,常見的一種選擇是調整模型的參數(shù)數(shù)目凡资,即模型的層數(shù)和每層的規(guī)模砸捏。另一種方法是對權重進行正則化約束,如L1或L2.這種約束會使模型的權重偏向較小的值隙赁。

在我們的模型里垦藏,我們使用了很小的卷積網(wǎng)絡,只有很少的幾層伞访,每層的濾波器數(shù)目也不多绝页。再加上數(shù)據(jù)提升和Dropout谆焊,就差不多了铣墨。Dropout通過防止一層看到兩次完全一樣的模式來防止過擬合食零,相當于也是一種數(shù)據(jù)提升的方法。(你可以說dropout和數(shù)據(jù)提升都在隨機擾亂數(shù)據(jù)的相關性)

我們再來回顧一下數(shù)據(jù)提升的用法, ImageDataGenerator

from keras.preprocessing.image import ImageDataGenerator

然后對訓練集,驗證集進行數(shù)據(jù)提升

  • 首先,生成提升訓練集的類:
train_datagen = ImageDataGenerator(
rescale = 1./255, (歸一化,這個不可少)
shear_range = 0.2, (錯切,正的話就是逆向)
zoom_range = 0.2, (隨機縮放,[1-0.2,1+0.2])
horizontal_flip = True (橫向的翻轉))
  • 然后,生成提升驗證集的類:
validation_datagen = ImageDataGenerator(
rescale = 1./255(歸一化,因為是驗證集,沒有必要進行其他的數(shù)據(jù)提升處理))
  • 然后, 通過指定路徑等參數(shù),將提升訓練集以及提升驗證集進行數(shù)據(jù)的實例化,通過flow或者flow_from_directory(directory)實現(xiàn)
  • 首先,是提升訓練集的實例化
train_generator = train_datagen.flow_from_directory(
**directory=train_data_dir(這個參數(shù)最重要,指定提升數(shù)據(jù)的來源)**,
target_size = 整數(shù)tuple,默認為(256, 256). 圖像將被resize成該尺寸,
color_mode = 顏色模式,為"grayscale","rgb"之一,默認為"rgb",
batch_size =batch數(shù)據(jù)的大小,默認32,
shuffle =  是否打亂數(shù)據(jù),默認為True,
class_mode="categorical", "binary", "sparse"或None之一. 默認為"categorical. 
該參數(shù)決定了返回的標簽數(shù)組的形式, 
"categorical"會返回2D的one-hot編碼標簽,
"binary"返回1D的二值標簽.
"sparse"返回1D的整數(shù)標簽,
如果為None則不返回任何標簽, 
生成器將僅僅生成batch數(shù)據(jù), 這種情況在使用model.predict_generator()和
model.evaluate_generator()等函數(shù)時會用到.
)

class_mode是很重要的,返回標簽,如果是categorical,那么就是one-hot型,如果是binary,那么就是0,1,如果是sparse那么就是1或者8這樣的.

  • 然后,是提升測試集的實例化
validation_generator = validation_datagen.flow_from_direction(
direction = validation_data_dir,
target_size = (img_width,img_height),
batch_size=batch_size,
color_mode = 'rgb',
class_mode = 'binary')

再次強調一下class_mode的重要性,因為ImageDataGenerator這種圖像的提升是對所有類別的圖像進行的(包括在directory中),而送入train_generator中以及fit_generator中時是不分訓練集和標簽集的,所以保存圖像的時候要按類別分別保存在不同的文件夾中,文件名可以無所謂.有幾個文件夾就可以分幾類,像貓狗大戰(zhàn)這個問題,由于是2分類問題,所以class_mode可以是binary,而在二分類時,model.compile可以選用的loss可以是'binary_crossentropy',還可以是別的嗎,loss還要再想一想.

然后就可以訓練模型了

model.fit_generator(
generator = train_generator,
step_per_epoch = nb_train_samples//batch_size(每個epoch有多少步),
epochs=EPOCHS,
verbose=1,
validation_dataz = validation_generator,
validation_steps = nb_validation_samples//batch_size,
callbacks = [callbacks](Tensorboard.ModelCheckpoint...))
  • 最后進行一個總結:
    使用數(shù)據(jù)提升需要用到
keras.preprocessing.image.ImageDataGenerator

所以第一步:

from keras.preprocessing.image import ImageDataGenerator

第二步,寫出提升訓練集的類

train_datagen = ImageDataGenerator(
scale = 1./255(這個一般要有)
shear_range = 0.2,(這個是錯切,其實是仿射變化)
zoom_range = 0.2,
horizontal_flip = True)

第三步,提升訓練集類的實體化

traindata_generator = train_datagen.flow_from_direction
(direction = train_data_dir,
color_mode = 'rgb',
target_size=(img_width,img_height),
class_mode = 'binary')

第四步,訓練

model.fit_generator
(generator = traindata_generator,
step_per_epoch = nb_train_samples//batch_size,
epochs = EPOCHS,
verbose = 1,
validation_data =validation_generator,
validation_steps = nb_validation_samples//batch_size,
callbacks=[callback] )

最后,附上幾張數(shù)據(jù)提升貓貓的圖像

圖片.png

最后給出訓練結果,最好的val_acc已經(jīng)達到0.9399

Firefox_Screenshot_2017-10-19T01-24-58.288Z.png
Firefox_Screenshot_2017-10-19T01-24-40.874Z.png
Firefox_Screenshot_2017-10-19T01-24-26.805Z.png
Firefox_Screenshot_2017-10-19T01-24-10.142Z.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末蝗肪,一起剝皮案震驚了整個濱河市袜爪,隨后出現(xiàn)的幾起案子蠕趁,更是在濱河造成了極大的恐慌薛闪,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件俺陋,死亡現(xiàn)場離奇詭異豁延,居然都是意外死亡昙篙,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門诱咏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來苔可,“玉大人,你說我怎么就攤上這事袋狞》俑ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵苟鸯,是天一觀的道長同蜻。 經(jīng)常有香客問我,道長早处,這世上最難降的妖魔是什么湾蔓? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮砌梆,結果婚禮上默责,老公的妹妹穿的比我還像新娘。我一直安慰自己咸包,他們只是感情好桃序,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著诉儒,像睡著了一般葡缰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上忱反,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天泛释,我揣著相機與錄音,去河邊找鬼温算。 笑死怜校,一個胖子當著我的面吹牛,可吹牛的內容都是我干的注竿。 我是一名探鬼主播茄茁,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼巩割!你這毒婦竟也來了裙顽?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤宣谈,失蹤者是張志新(化名)和其女友劉穎愈犹,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡漩怎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年勋颖,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片勋锤。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡饭玲,死狀恐怖,靈堂內的尸體忽然破棺而出叁执,到底是詐尸還是另有隱情茄厘,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布谈宛,位于F島的核電站蚕断,受9級特大地震影響,放射性物質發(fā)生泄漏入挣。R本人自食惡果不足惜亿乳,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望径筏。 院中可真熱鬧葛假,春花似錦、人聲如沸滋恬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽恢氯。三九已至带斑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間勋拟,已是汗流浹背勋磕。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留敢靡,地道東北人挂滓。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像啸胧,于是被迫代替她去往敵國和親赶站。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內容