Keras 在fit_generator訓(xùn)練方式中加入圖像random_crop操作
使用Keras作前端寫(xiě)網(wǎng)絡(luò)時(shí),由于訓(xùn)練圖像尺寸較大,需要做類(lèi)似 tf.random_crop 圖像裁剪操作。
為此研究了一番Keras下已封裝的API。
Data Augmentation(數(shù)據(jù)擴(kuò)充)
Data Aumentation 指使用下面或其他方法增加輸入數(shù)據(jù)量。我們默認(rèn)圖像數(shù)據(jù)。
旋轉(zhuǎn)&反射變換(Rotation/reflection): 隨機(jī)旋轉(zhuǎn)圖像一定角度; 改變圖像內(nèi)容的朝向;
翻轉(zhuǎn)變換(flip): 沿著水平或者垂直方向翻轉(zhuǎn)圖像;
縮放變換(zoom): 按照一定的比例放大或者縮小圖像;
平移變換(shift): 在圖像平面上對(duì)圖像以一定方式進(jìn)行平移;
可以采用隨機(jī)或人為定義的方式指定平移范圍和平移步長(zhǎng), 沿水平或豎直方向進(jìn)行平移. 改變圖像內(nèi)容的位置;
尺度變換(scale): 對(duì)圖像按照指定的尺度因子, 進(jìn)行放大或縮小; 或者參照SIFT特征提取思想, 利用指定的尺度因子對(duì)圖像濾波構(gòu)造尺度空間. 改變圖像內(nèi)容的大小或模糊程度;
對(duì)比度變換(contrast): 在圖像的HSV顏色空間,改變飽和度S和V亮度分量,保持色調(diào)H不變. 對(duì)每個(gè)像素的S和V分量進(jìn)行指數(shù)運(yùn)算(指數(shù)因子在0.25到4之間), 增加光照變化;
噪聲擾動(dòng)(noise): 對(duì)圖像的每個(gè)像素RGB進(jìn)行隨機(jī)擾動(dòng), 常用的噪聲模式是椒鹽噪聲和高斯噪聲;
Data Aumentation 有很多好處,比如數(shù)據(jù)量較少時(shí),用數(shù)據(jù)擴(kuò)充來(lái)增加訓(xùn)練數(shù)據(jù),防止過(guò)擬合。
ImageDataGenerator
在Keras中,ImageDataGenerator就是專(zhuān)門(mén)做數(shù)據(jù)擴(kuò)充的。
from keras.preprocessing.image import ImageDataGenerator
注:Using TensorFlow backend.
官方寫(xiě)法如下:
(x_train, y_train), (x_test, y_test) = cifar10.load_data() datagen = ImageDataGenerator( featurewise_center=True, ... horizontal_flip=True) # compute quantities required for featurewise normalization datagen.fit(x_train) # 使用fit_generator的【自動(dòng)】訓(xùn)練方法: fits the model on batches with real-time data augmentation model.fit_generator(datagen.flow(x_train, y_train, batch_size=32), steps_per_epoch=len(x_train), epochs=epochs) # 自己寫(xiě)range循環(huán)的【手動(dòng)】訓(xùn)練方法 for e in range(epochs): print 'Epoch', e batches = 0 for x_batch, y_batch in datagen.flow(x_train, y_train, batch_size=32): loss = model.train(x_batch, y_batch) batches += 1 if batches >= len(x_train) / 32: # we need to break the loop by hand because # the generator loops indefinitely break
ImageDataGenerator的參數(shù)說(shuō)明見(jiàn)官網(wǎng)文檔。
上面兩種訓(xùn)練方法的差異不討論,我們要關(guān)注的是:官方封裝的訓(xùn)練集batch生成器是ImageDataGenerator對(duì)象的flow方法(或flow_from_directory),該函數(shù)返回一個(gè)和python定義相似的generator。在它前一步,數(shù)據(jù)變換是ImageDataGenerator對(duì)象的fit方法。
random_crop并未在ImageDataGenerator中內(nèi)置,但參數(shù)中給了一個(gè)preprocessing_function,我們可以利用它自定義my_random_crop函數(shù),像下面這樣寫(xiě):
def my_random_crop(image): random_arr = numpy.random.randint(img_sz-crop_sz+1, size=2) y = int(random_arr[0]) x = int(random_arr[1]) h = img_crop w = img_crop image_crop = image[y:y+h, x:x+w, :] return image_crop datagen = ImageDataGenerator( featurewise_center=False, ··· preprocessing_function=my_random_crop) datagen.fit(x_train)
fit方法調(diào)用時(shí)將預(yù)設(shè)的變換應(yīng)用到x_train的每張圖上,包括圖像crop,因?yàn)槭菃螐堃来翁幚?,每張圖的crop位置隨機(jī)。
在訓(xùn)練數(shù)據(jù)(x=image, y=class_label)時(shí)這樣寫(xiě)已滿足要求;
但在(x=image, y=image_mask)時(shí)該方法就不成立了。圖像單張?zhí)幚淼木壒?,一?duì)(image, image_mask)分別crop的位置無(wú)法保持一致。
雖然官網(wǎng)也給出了同時(shí)變換image和mask的寫(xiě)法,但它提出的方案能保證二者內(nèi)置函數(shù)的變換一致,自定義函數(shù)的random變量仍是隨機(jī)的。
fit_generator
既然ImageDataGenerator和flow方法不能滿足我們的random_crop預(yù)處理要求,就在fit_generator函數(shù)處想方法修改。
先看它的定義:
def fit_generator(self, generator, samples_per_epoch, nb_epoch, verbose=1, callbacks=[], validation_data=None, nb_val_samples=None, class_weight=None, max_q_size=10, **kwargs):
第一個(gè)參數(shù)generator,可以傳入一個(gè)方法,也可以直接傳入數(shù)據(jù)集。前面的 datagen.flow() 即是Keras封裝的批量數(shù)據(jù)傳入方法。
顯然,我們可以自定義。
def generate_batch_data_random(x, y, batch_size): """分批取batch數(shù)據(jù)加載到顯存""" total_num = len(x) batches = total_num // batch_size while (True): i = randint(0, batches) x_batch = x[i*batch_size:(i+1)*batch_size] y_batch = y[i*batch_size:(i+1)*batch_size] random_arr = numpy.random.randint(img_sz-crop_sz+1, size=2) y_pos = int(random_arr[0]) x_pos = int(random_arr[1]) x_crop = x_batch[:, y_pos:y_pos+crop_sz, x_pos:x_pos+crop_sz, :] y_crop = y_batch[:, y_pos:y_pos+crop_sz, x_pos:x_pos+crop_sz, :] yield (x_crop, y_crop)
這樣寫(xiě)就符合我們同組image和mask位置一致的random_crop要求。
注意:
由于沒(méi)有使用ImageDataGenerator內(nèi)置的數(shù)據(jù)變換方法,數(shù)據(jù)擴(kuò)充則也需要自定義;由于沒(méi)有使用flow(…, shuffle=True,)方法,每個(gè)epoch的數(shù)據(jù)打亂需要自定義。
generator自定義時(shí)要寫(xiě)成死循環(huán),因?yàn)樵诿總€(gè)epoch內(nèi),generate_batch_data_random是不會(huì)重復(fù)調(diào)用的。
補(bǔ)充知識(shí):tensorflow中的隨機(jī)裁剪函數(shù)random_crop
tf.random_crop是tensorflow中的隨機(jī)裁剪函數(shù),可以用來(lái)裁剪圖片。我采用如下圖片進(jìn)行隨機(jī)裁剪,裁剪大小為原圖的一半。
如下是實(shí)驗(yàn)代碼
import tensorflow as tf import matplotlib.image as img import matplotlib.pyplot as plt sess = tf.InteractiveSession() image = img.imread('D:/Documents/Pictures/logo3.jpg') reshaped_image = tf.cast(image,tf.float32) size = tf.cast(tf.shape(reshaped_image).eval(),tf.int32) height = sess.run(size[0]//2) width = sess.run(size[1]//2) distorted_image = tf.random_crop(reshaped_image,[height,width,3]) print(tf.shape(reshaped_image).eval()) print(tf.shape(distorted_image).eval()) fig = plt.figure() fig1 = plt.figure() ax = fig.add_subplot(111) ax1 = fig1.add_subplot(111) ax.imshow(sess.run(tf.cast(reshaped_image,tf.uint8))) ax1.imshow(sess.run(tf.cast(distorted_image,tf.uint8))) plt.show()
如下是隨機(jī)實(shí)驗(yàn)兩次的結(jié)果
以上這篇Keras 在fit_generator訓(xùn)練方式中加入圖像random_crop操作就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
快速解決Django關(guān)閉Debug模式無(wú)法加載media圖片與static靜態(tài)文件
這篇文章主要介紹了快速解決Django關(guān)閉Debug模式無(wú)法加載media圖片與static靜態(tài)文件的操作方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04Python基于httpx模塊實(shí)現(xiàn)發(fā)送請(qǐng)求
這篇文章主要介紹了Python基于httpx模塊實(shí)現(xiàn)發(fā)送請(qǐng)求,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07Python 抓取微信公眾號(hào)賬號(hào)信息的方法
搜狗微信搜索提供兩種類(lèi)型的關(guān)鍵詞搜索,一種是搜索公眾號(hào)文章內(nèi)容,另一種是直接搜索微信公眾號(hào)。這篇文章主要介紹了Python 抓取微信公眾號(hào)賬號(hào)信息,需要的朋友可以參考下2019-06-06python數(shù)據(jù)結(jié)構(gòu)鏈表之單向鏈表(實(shí)例講解)
下面小編就為大家?guī)?lái)一篇python數(shù)據(jù)結(jié)構(gòu)鏈表之單向鏈表(實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07python使用py2neo創(chuàng)建neo4j的節(jié)點(diǎn)和關(guān)系
這篇文章主要介紹了python使用py2neo創(chuàng)建neo4j的節(jié)點(diǎn)和關(guān)系,第一步使用py2neo連接neo4j的方法然后根據(jù)dict創(chuàng)建Node,更多相關(guān)資料需要的朋友參考下面文章內(nèi)容2022-02-02使用Python實(shí)現(xiàn)微信提醒備忘錄功能
最近工作比較繁雜,經(jīng)常忘事,有時(shí)候記了備忘錄結(jié)果卻忘記看備忘錄,但是微信是每天都會(huì)看的,于是就想到寫(xiě) 一個(gè)基于微信的提醒系統(tǒng)。這篇文章主要介紹了使用Python實(shí)現(xiàn)微信提醒備忘錄功能,需要的朋友可以參考下2018-12-12網(wǎng)絡(luò)瀏覽器中運(yùn)行Python腳本PyScript剖析
這篇文章主要為大家介紹了網(wǎng)絡(luò)瀏覽器中運(yùn)行Python腳本PyScript剖析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08