本文借鑒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ù)提升貓貓的圖像
最后給出訓練結果,最好的val_acc已經(jīng)達到0.9399