在深度學習中,當數據量不夠大時候,常常采用下面4中方法:
1.
人工增加訓練集的大小. 通過平移, 翻轉, 加噪聲等方法從已有數據中創造出一批"新"的數據.也就是Data Augmentation
2. Regularization. 數據量比較小會導致模型過擬合, 使得訓練誤差很小而測試誤差特別大. 通過在Loss Function 后面加上正則項可以抑制過擬合的產生. 缺點是引入了一個需要手動調整的hyper-parameter. 詳見 https://www.wikiwand.com/en/Regularization_(mathematics)
3. Dropout. 這也是一種正則化手段. 不過跟以上不同的是它通過隨機將部分神經元的輸出置零來實現. 詳見 http://www.cs.toronto.edu/~hinton/absps/JMLRdropout.pdf
4. Unsupervised Pre-training. 用Auto-Encoder或者RBM的卷積形式一層一層地做無監督預訓練, 最后加上分類層做有監督的Fine-Tuning. 參考 http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.207.1102&rep=rep1&type=pdf
2. Regularization. 數據量比較小會導致模型過擬合, 使得訓練誤差很小而測試誤差特別大. 通過在Loss Function 后面加上正則項可以抑制過擬合的產生. 缺點是引入了一個需要手動調整的hyper-parameter. 詳見 https://www.wikiwand.com/en/Regularization_(mathematics)
3. Dropout. 這也是一種正則化手段. 不過跟以上不同的是它通過隨機將部分神經元的輸出置零來實現. 詳見 http://www.cs.toronto.edu/~hinton/absps/JMLRdropout.pdf
4. Unsupervised Pre-training. 用Auto-Encoder或者RBM的卷積形式一層一層地做無監督預訓練, 最后加上分類層做有監督的Fine-Tuning. 參考 http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.207.1102&rep=rep1&type=pdf
下面我們來討論Data Augmentation:
不同的任務背景下, 我們可以通過圖像的幾何變換, 使用以下一種或多種組合數據增強變換來增加輸入數據的量. 這里具體的方法都來自數字圖像處理的內容, 相關的知識點介紹, 網上都有, 就不一一介紹了.
- 旋轉 | 反射變換(Rotation/reflection): 隨機旋轉圖像一定角度; 改變圖像內容的朝向;
- 翻轉變換(flip): 沿着水平或者垂直方向翻轉圖像;
- 縮放變換(zoom): 按照一定的比例放大或者縮小圖像;
- 平移變換(shift): 在圖像平面上對圖像以一定方式進行平移;
可以采用隨機或人為定義的方式指定平移范圍和平移步長, 沿水平或豎直方向進行平移. 改變圖像內容的位置; - 尺度變換(scale): 對圖像按照指定的尺度因子, 進行放大或縮小; 或者參照SIFT特征提取思想, 利用指定的尺度因子對圖像濾波構造尺度空間. 改變圖像內容的大小或模糊程度;
- 對比度變換(contrast): 在圖像的HSV顏色空間,改變飽和度S和V亮度分量,保持色調H不變. 對每個像素的S和V分量進行指數運算(指數因子在0.25到4之間), 增加光照變化;
- 噪聲擾動(noise): 對圖像的每個像素RGB進行隨機擾動, 常用的噪聲模式是椒鹽噪聲和高斯噪聲;
- 顏色變換(color): 在訓練集像素值的RGB顏色空間進行PCA, 得到RGB空間的3個主方向向量,3個特征值, p1, p2, p3, λ1, λ2, λ3. 對每幅圖像的每個像素Ixy=[IRxy,IGxy,IBxy]T進行加上如下的變化:
[p1,p2,p3][α1λ1,α2λ2,α3λ3]T
其中:αi是滿足均值為0,方差為0.1的隨機變量.
代碼實現
作為實現部分, 這里介紹一下在python 環境下, 利用已有的開源代碼庫Keras作為實踐:
1 # -*- coding: utf-8 -*- 2 __author__ = 'Administrator' 3 4 # import packages 5 from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img 6 7 datagen = ImageDataGenerator( 8 rotation_range=0.2, 9 width_shift_range=0.2, 10 height_shift_range=0.2, 11 shear_range=0.2, 12 zoom_range=0.2, 13 horizontal_flip=True, 14 fill_mode='nearest') 15 16 img = load_img('C:\Users\Administrator\Desktop\dataA\lena.jpg') # this is a PIL image, please replace to your own file path 17 x = img_to_array(img) # this is a Numpy array with shape (3, 150, 150) 18 x = x.reshape((1,) + x.shape) # this is a Numpy array with shape (1, 3, 150, 150) 19 20 # the .flow() command below generates batches of randomly transformed images 21 # and saves the results to the `preview/` directory 22 23 i = 0 24 for batch in datagen.flow(x, 25 batch_size=1, 26 save_to_dir='C:\Users\Administrator\Desktop\dataA\pre',#生成后的圖像保存路徑 27 save_prefix='lena', 28 save_format='jpg'): 29 i += 1 30 if i > 20: #這個20指出要擴增多少個數據 31 break # otherwise the generator would loop indefinitely
主要函數:ImageDataGenerator
實現了大多數上文中提到的圖像幾何變換方法.
- rotation_range: 旋轉范圍, 隨機旋轉(0-180)度;
- width_shift and height_shift: 隨機沿着水平或者垂直方向,以圖像的長寬小部分百分比為變化范圍進行平移;
- rescale: 對圖像按照指定的尺度因子, 進行放大或縮小, 設置值在0 - 1之間,通常為1 / 255;
- shear_range: 水平或垂直投影變換, 參考這里 https://keras.io/preprocessing/image/
- zoom_range: 按比例隨機縮放圖像尺寸;
- horizontal_flip: 水平翻轉圖像;
- fill_mode: 填充像素, 出現在旋轉或平移之后.
效果如下圖所示:
轉載於:http://blog.csdn.net/mduanfire/article/details/51674098
為什么要做變形,或者說數據增強。從這個網站可以看出 http://scs.ryerson.ca/~aharley/vis/conv/ 手寫字符稍微變形點,就有可能識別出錯,因此數據增強可以生成一些變形的數據,讓網絡提前適應

1 # -*- coding: utf-8 -*- 2 __author__ = 'Administrator' 3 4 # import packages 5 from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img 6 7 datagen = ImageDataGenerator( 8 rotation_range=0.2, 9 width_shift_range=0.2, 10 height_shift_range=0.2, 11 shear_range=0.2, 12 zoom_range=0.2, 13 horizontal_flip=True, 14 fill_mode='nearest') 15 16 for k in range(33): 17 numstr = "{0:d}".format(k); 18 filename='C:\\Users\\Administrator\\Desktop\\bad\\'+numstr+'.jpg'; 19 ufilename = unicode(filename , "utf8") 20 img = load_img(ufilename) # this is a PIL image, please replace to your own file path 21 x = img_to_array(img) # this is a Numpy array with shape (3, 150, 150) 22 x = x.reshape((1,) + x.shape) # this is a Numpy array with shape (1, 3, 150, 150) 23 24 # the .flow() command below generates batches of randomly transformed images 25 # and saves the results to the `preview/` directory 26 27 i = 0 28 29 for batch in datagen.flow(x, 30 batch_size=1, 31 save_to_dir='C:\\Users\\Administrator\\Desktop\\dataA\\',#生成后的圖像保存路徑 32 save_prefix=numstr, 33 save_format='jpg'): 34 i += 1 35 if i > 20: 36 break # otherwise the generator would loop indefinitely 37 end

1 # -*- coding: utf-8 -*- 2 __author__ = 'Administrator' 3 4 # import packages 5 from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img 6 7 datagen = ImageDataGenerator( 8 rotation_range=10, 9 width_shift_range=0.2, 10 height_shift_range=0.2, 11 rescale=1./255, 12 shear_range=0.2, 13 zoom_range=0.2, 14 horizontal_flip=True, 15 fill_mode='nearest') 16 import os 17 18 import sys 19 reload(sys) 20 sys.setdefaultencoding('utf8') 21 22 ufilename = unicode("C:\\Users\\Administrator\\Desktop\\測試" , "utf8") 23 24 for filename in os.listdir(ufilename): #listdir的參數是文件夾的路徑 25 print ( filename) #此時的filename是文件夾中文件的名稱 26 pathname='C:\\Users\\Administrator\\Desktop\\測試\\'+filename; 27 #ufilename = unicode(pathname , "utf8") 28 img = load_img(pathname) # this is a PIL image, please replace to your own file path 29 x = img_to_array(img) # this is a Numpy array with shape (3, 150, 150) 30 x = x.reshape((1,) + x.shape) # this is a Numpy array with shape (1, 3, 150, 150) 31 # the .flow() command below generates batches of randomly transformed images 32 # and saves the results to the `preview/` directory 33 i = 0 34 for batch in datagen.flow(x, 35 batch_size=1, 36 save_to_dir='C:\\Users\\Administrator\\Desktop\\result\\',#生成后的圖像保存路徑 37 save_prefix=filename, 38 save_format='jpg'): 39 i += 1 40 if i > 100: 41 break # otherwise the generator would loop indefinitely 42 43 44 # datagen = ImageDataGenerator( 45 # rotation_range=0.2, 46 # width_shift_range=0.2, 47 # height_shift_range=0.2, 48 # rescale=1./255, 49 # shear_range=0.1, 50 # zoom_range=0.4, 51 # horizontal_flip=True, 52 # fill_mode='nearest') 53 # 54 # ufilename = unicode("C:\\Users\\Administrator\\Desktop\\訓練" , "utf8") 55 # for filename in os.listdir(ufilename): #listdir的參數是文件夾的路徑 56 # print ( filename) #此時的filename是文件夾中文件的名稱 57 # pathname='C:\\Users\\Administrator\\Desktop\\訓練\\'+filename; 58 # # ufilename = unicode(pathname , "utf8") 59 # img = load_img(pathname) # this is a PIL image, please replace to your own file path 60 # x = img_to_array(img) # this is a Numpy array with shape (3, 150, 150) 61 # x = x.reshape((1,) + x.shape) # this is a Numpy array with shape (1, 3, 150, 150) 62 # 63 # # the .flow() command below generates batches of randomly transformed images 64 # # and saves the results to the `preview/` directory 65 # 66 # i = 0 67 # 68 # for batch in datagen.flow(x, 69 # batch_size=1, 70 # save_to_dir='C:\\Users\\Administrator\\Desktop\\result\\',#生成后的圖像保存路徑 71 # save_prefix=filename, 72 # save_format='jpg'): 73 # i += 1 74 # if i > 100: 75 # break # otherwise the generator would loop indefinitely
https://github.com/mdbloice/Augmentor