使用数据增强技术提升模型泛化能力
在《提高模型性能,你可以嘗試這幾招...》一文中,我們給出了幾種提高模型性能的方法,但這篇文章是在訓(xùn)練數(shù)據(jù)集不變的前提下提出的優(yōu)化方案。其實對于深度學(xué)習(xí)而言,數(shù)據(jù)量的多寡通常對模型性能的影響更大,所以擴(kuò)充數(shù)據(jù)規(guī)模一般情況是一個非常有效的方法。
對于Google、Facebook來說,收集幾百萬張圖片,訓(xùn)練超大規(guī)模的深度學(xué)習(xí)模型,自然不在話下。但是對于個人或者小型企業(yè)而言,收集現(xiàn)實世界的數(shù)據(jù),特別是帶標(biāo)簽的數(shù)據(jù),將是一件非常費(fèi)時費(fèi)力的事。本文探討一種技術(shù),在現(xiàn)有數(shù)據(jù)集的基礎(chǔ)上,進(jìn)行數(shù)據(jù)增強(qiáng)(data augmentation),增加參與模型訓(xùn)練的數(shù)據(jù)量,從而提升模型的性能。
什么是數(shù)據(jù)增強(qiáng)
所謂數(shù)據(jù)增強(qiáng),就是采用在原有數(shù)據(jù)上隨機(jī)增加抖動和擾動,從而生成新的訓(xùn)練樣本,新樣本的標(biāo)簽和原始數(shù)據(jù)相同。這個也很好理解,對于一張標(biāo)簽為“狗”的圖片,做一定的模糊、裁剪、變形等處理,并不會改變這張圖片的類別。數(shù)據(jù)增強(qiáng)也不僅局限于圖片分類應(yīng)用,比如有如下圖所示的數(shù)據(jù),數(shù)據(jù)滿足正態(tài)分布:
我們在數(shù)據(jù)集的基礎(chǔ)上,增加一些擾動處理,數(shù)據(jù)分布如下:
數(shù)據(jù)就在原來的基礎(chǔ)上增加了幾倍,但整體上仍然滿足正態(tài)分布。有人可能會說,這樣的出來的模型不是沒有原來精確了嗎?考慮到現(xiàn)實世界的復(fù)雜性,我們采集到的數(shù)據(jù)很難完全滿足正態(tài)分布,所以這樣增加數(shù)據(jù)擾動,不僅不會降低模型的精確度,然而增強(qiáng)了泛化能力。
對于圖片數(shù)據(jù)而言,能夠做的數(shù)據(jù)增強(qiáng)的方法有很多,通常的方法是:
- 平移
- 旋轉(zhuǎn)
- 縮放
- 裁剪
- 切變(shearing)
- 水平/垂直翻轉(zhuǎn)
- ...
上面幾種方法,可能切變(shearing)比較難以理解,看一張圖就明白了:
我們要親自編寫這些數(shù)據(jù)增強(qiáng)算法嗎?通常不需要,比如keras就提供了批量處理圖片變形的方法。
keras中的數(shù)據(jù)增強(qiáng)方法
keras中提供了ImageDataGenerator類,其構(gòu)造方法如下:
ImageDataGenerator(featurewise_center=False,samplewise_center=False,featurewise_std_normalization = False,samplewise_std_normalization = False,zca_whitening = False,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.0,horizontal_flip = False,vertical_flip = False,rescale = None,preprocessing_function = None,data_format = K.image_data_format(), ) 復(fù)制代碼參數(shù)很多,常用的參數(shù)有:
- rotation_range: 控制隨機(jī)的度數(shù)范圍旋轉(zhuǎn)。
- width_shift_range和height_shift_range: 分別用于水平和垂直移位。
- zoom_range: 根據(jù)[1 - zoom_range,1 + zoom_range]范圍均勻?qū)D像“放大”或“縮小”。
- horizontal_flip:控制是否水平翻轉(zhuǎn)。
完整的參數(shù)說明請參考keras文檔。
下面一段代碼將1張給定的圖片擴(kuò)充為10張,當(dāng)然你還可以擴(kuò)充更多:
image = load_img(args["image"]) image = img_to_array(image) image = np.expand_dims(image, axis=0)aug = ImageDataGenerator(rotation_range=30, width_shift_range=0.1, height_shift_range=0.1,shear_range=0.2, zoom_range=0.2, horizontal_flip=True, fill_mode="nearest")aug.fit(image)imageGen = aug.flow(image, batch_size=1, save_to_dir=args["output"], save_prefix=args["prefix"],save_format="jpeg")total = 0 for image in imageGen:# increment out countertotal += 1if total == 10:break 復(fù)制代碼需要指出的是,上述代碼的最后一個迭代是必須的,否在不會在output目錄下生成圖片,另外output目錄必須存在,否則會出現(xiàn)一下錯誤:
Traceback (most recent call last):File "augmentation_demo.py", line 35, in <module>for image in imageGen:File "/data/ai/anaconda3/envs/keras/lib/python3.6/site-packages/keras_preprocessing/image.py", line 1526, in __next__return self.next(*args, **kwargs)File "/data/ai/anaconda3/envs/keras/lib/python3.6/site-packages/keras_preprocessing/image.py", line 1704, in nextreturn self._get_batches_of_transformed_samples(index_array)File "/data/ai/anaconda3/envs/keras/lib/python3.6/site-packages/keras_preprocessing/image.py", line 1681, in _get_batches_of_transformed_samplesimg.save(os.path.join(self.save_to_dir, fname))File "/data/ai/anaconda3/envs/keras/lib/python3.6/site-packages/PIL/Image.py", line 1947, in savefp = builtins.open(filename, "w+b") FileNotFoundError: [Errno 2] No such file or directory: 'output/image_0_1091.jpeg' 復(fù)制代碼如下一張狗狗的圖片:
經(jīng)過數(shù)據(jù)增強(qiáng)技術(shù)處理之后,可以得到如下10張形態(tài)稍微不同的狗狗的圖片,這相當(dāng)于在原有數(shù)據(jù)集上增加了10倍的數(shù)據(jù),其實我們還可以擴(kuò)充得最多:
數(shù)據(jù)增強(qiáng)之后的比較
我們以MiniVGGNet模型為例,說明在其在17flowers數(shù)據(jù)集上進(jìn)行訓(xùn)練的效果。17flowers是一個非常小的數(shù)據(jù)集,包含17中品類的花卉圖案,每個品類包含80張圖片,這對于深度學(xué)習(xí)而言,數(shù)據(jù)量實在是太小了。一般而言,要讓深度學(xué)習(xí)模型有一定的精確度,每個類別的圖片至少需要1000~5000張。這樣的數(shù)據(jù)集可以很好的說明數(shù)據(jù)增強(qiáng)技術(shù)的必要性。
從網(wǎng)站上下載的17flowers數(shù)據(jù),所有的圖片都放在一個目錄下,而我們通常訓(xùn)練時的目錄結(jié)構(gòu)為:
{類別名}/{圖片文件} 復(fù)制代碼為此我寫了一個organize_flowers17.py腳本。
在沒有使用數(shù)據(jù)增強(qiáng)的情況下,在訓(xùn)練數(shù)據(jù)集和驗證數(shù)據(jù)集上精度、損失隨著訓(xùn)練輪次的變化曲線圖:
可以看到,大約經(jīng)過十幾輪的訓(xùn)練,在訓(xùn)練數(shù)據(jù)集上的準(zhǔn)確率很快就達(dá)到了接近100%,然而在驗證數(shù)據(jù)集上的準(zhǔn)確率卻無法再上升,只能達(dá)到60%左右。這個圖可以明顯的看出模型出現(xiàn)了非常嚴(yán)重的過擬合。
如果采用數(shù)據(jù)增強(qiáng)技術(shù)呢?曲線圖如下:
從圖中可以看到,雖然在訓(xùn)練數(shù)據(jù)集上的準(zhǔn)確率有所下降,但在驗證數(shù)據(jù)集上的準(zhǔn)確率有比較明顯的提升,說明模型的泛化能力有所增強(qiáng)。
也許在我們看來,準(zhǔn)確率從60%多增加到70%,只有10%的提升,并不是什么了不得的成績。但要考慮到我們采用的數(shù)據(jù)集樣本數(shù)量實在是太少,能夠達(dá)到這樣的提升已經(jīng)是非常難得,在實際項目中,有時為了提升1%的準(zhǔn)確率,都會花費(fèi)不少的功夫。
總結(jié)
數(shù)據(jù)增強(qiáng)技術(shù)在一定程度上能夠提高模型的泛化能力,減少過擬合,但在實際中,我們?nèi)绻軌蚴占礁嗾鎸嵉臄?shù)據(jù),還是要盡量使用真實數(shù)據(jù)。另外,數(shù)據(jù)增強(qiáng)只需應(yīng)用于訓(xùn)練數(shù)據(jù)集,驗證集上則不需要,畢竟我們希望在驗證集上測試真實數(shù)據(jù)的準(zhǔn)確。
以上實例均有完整的代碼,點擊閱讀原文,跳轉(zhuǎn)到我在github上建的示例代碼。
另外,我在閱讀《Deep Learning for Computer Vision with Python》這本書,在微信公眾號后臺回復(fù)“計算機(jī)視覺”關(guān)鍵字,可以免費(fèi)下載這本書的電子版。
參考閱讀
提高模型性能,你可以嘗試這幾招...
計算機(jī)視覺與深度學(xué)習(xí),看這本書就夠了
總結(jié)
以上是生活随笔為你收集整理的使用数据增强技术提升模型泛化能力的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Excel·VBA自定义函数扩展VLOO
- 下一篇: 应对无协议脱欧 葡萄牙机场将为英籍旅客设