Keras .ImageDataGenerator图像增强用法大全以及如何和模型结合起来(有代码)
圖像增強
在做圖像任務時,我們常常需要圖像增強。今天來講解下keras中的圖像增強
ImageDataGenerator
官網
https://keras.io/api/preprocessing/image/
可能用到的函數fit
fit(x, augment=False, rounds=1):計算依賴于數據的變換所需要的統計信息(均值方差等),只有使用featurewise_center,featurewise_std_normalization或zca_whitening時需要此函數。 X:numpy array,樣本數據,秩應為4.在黑白圖像的情況下channel軸的值為1,在彩色圖像情況下值為3augment:布爾值,確定是否使用隨即提升過的數據round:若設augment=True,確定要在數據上進行多少輪數據提升,默認值為1seed: 整數,隨機數種子用到的函數flow
flow: flow(self, X, y, batch_size=32, shuffle=True, seed=None, save_to_dir=None, save_prefix='', save_format='png'):接收numpy數組和標簽為參數,生成經過數據提升或標準化后的batch數據,并在一個無限循環中不斷的返回batch數據x:樣本數據,秩應為4.在黑白圖像的情況下channel軸的值為1,在彩色圖像情況下值為3y:標簽batch_size:整數,默認32shuffle:布爾值,是否隨機打亂數據,默認為Truesave_to_dir:None或字符串,該參數能讓你將提升后的圖片保存起來,用以可視化save_prefix:字符串,保存提升后圖片時使用的前綴, 僅當設置了save_to_dir時生效save_format:"png"或"jpeg"之一,指定保存圖片的數據格式,默認"jpeg"yields:形如(x,y)的tuple,x是代表圖像數據的numpy數組.y是代表標簽的numpy數組.該迭代器無限循環.seed: 整數,隨機數種子用到的函數flow_from_directory :
flow_from_directory(directory):
以文件夾路徑為參數,生成經過數據提升/歸一化后的數據,在一個無限循環中無限產生batch數據
- directory: 目標文件夾路徑,對于每一個類,該文件夾都要包含一個子文件夾.子文件夾中任何JPG、PNG、BNP、PPM的圖片都會被生成器使用.詳情請查看此腳本
- target_size: 整數tuple,默認為(256, 256). 圖像將被resize成該尺寸
- color_mode: 顏色模式,為"grayscale",“rgb"之一,默認為"rgb”.代表這些圖片是否會被轉換為單通道或三通道的圖片.
- classes: 可選參數,為子文件夾的列表,如[‘dogs’,‘cats’]默認為None. 若未提供,則該類別列表將從directory下的子文件夾名稱/結構自動推斷。每一個子文件夾都會被認為是一個新的類。(類別的順序將按照字母表順序映射到標簽值)。通過屬性class_indices可獲得文件夾名與類的序號的對應字典。
- class_mode: “categorical”, “binary”, "sparse"或None之一. 默認為"categorical. 該參數決定了返回的標簽數組的形式, "categorical"會返回2D的one-hot編碼標簽,"binary"返回1D的二值標簽."sparse"返回1D的整數標簽,如果為None則不返回任何標簽, 生成器將僅僅生成batch數據, 這種情況在使用model.predict_generator()和model.evaluate_generator()等函數時會用到.
- batch_size: batch數據的大小,默認32
- shuffle: 是否打亂數據,默認為True
- seed: 可選參數,打亂數據和進行變換時的隨機數種子
- save_to_dir: None或字符串,該參數能讓你將提升后的圖片保存起來,用以可視化
- save_prefix:字符串,保存提升后圖片時使用的前綴, 僅當設置了save_to_dir時生效
- save_format:“png"或"jpeg"之一,指定保存圖片的數據格式,默認"jpeg”
- flollow_links: 是否訪問子文件夾中的軟鏈接
flow_from_directory(directory)偽代碼如下
xm,y=getDataIndex()#獲取所有文件夾中所有圖片索引,以及文件夾名也即標簽while(True):if shuffle==True:shuffle(xm,y)#打亂圖片索引及其標簽for i in range(0,len(x),batch_size):xm_batch=xm[i:i+batch_size]#文件索引y_batch=y[i:i+batch_size]x_batch=getImg(xm_batch)#根據文件索引,獲取圖像數據ImagePro(x_batch)#數據增強#保存提升后的圖片#saveToFile()yield (x_batch,y_batch)算例flow
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img import numpy as npdatagen = ImageDataGenerator(rotation_range=40,width_shift_range=0.2,height_shift_range=0.2,rescale=1/255.0,shear_range=0.2,zoom_range=0.2,horizontal_flip=True,fill_mode='nearest' )from keras.preprocessing import image import matplotlib.pyplot as plt img_path1 = 'meinv.jpg'img1 = image.load_img(img_path1) # plt格式的圖片。x = img_to_array(img1) x = np.expand_dims(x, 0)#擴展維度y_train = [1] # 標簽# [生成圖片]: 其中,gen可以作為生成器,用model.fit_generate(generate,)中來訓練。 #datagen.fit(x, y_train) #fit這里用不上 gen = datagen.flow(x, y_train, batch_size=2) # x_train —— 要求類型:numpy.array; 要求形狀: (image_num, 長, 寬, 通道)# y_train —— 要求類型:numpy.array; 要求形狀: (image_num)# 注: (1) 每個batch中生成的圖片是 從數據集的所有圖片中,隨機抽取一張并進行圖片尺寸大小啥的變換后放入batch中, 這樣抽取batch_size張圖片后就形成一個batch。# (2) 對圖片進行旋轉尺寸大小變換后的圖片,圖片大小[不會]改變。for i in range(9):plt.subplot(3,3,i+1)x,y=next(gen)print(x.shape)i=np.squeeze(x)#降維i==np.array(i,dtype=np.uint8)#轉換為圖像格式,必須使用==plt.imshow(i) plt.show()結果
多圖
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img import numpy as npdatagen = ImageDataGenerator(rotation_range=40,width_shift_range=0.2,height_shift_range=0.2,rescale=1/255.0,)from keras.preprocessing import image import matplotlib.pyplot as plt img_path1 = 'meinv.jpg' img_path2 = 'meinv1.jpg' img1 = image.load_img(img_path1) # plt格式的圖片。 img2 = image.load_img(img_path2) # plt格式的圖片。 x1 = np.array(img1) x1=np.resize(x1,(600,400,3))x2 = np.array(img2) x2=np.resize(x2,(600,400,3))x_train=np.array([x1,x2])#多圖,必須統一尺寸 y_train = [1,2] # 標簽#print(x_train.shape)#(2, 400, 400, 3)gen = datagen.flow(x_train, y_train, batch_size=2) # x_train —— 要求類型:numpy.array; 要求形狀: (image_num, 長, 寬, 通道)# y_train —— 要求類型:numpy.array; 要求形狀: (image_num)# 注: (1) 每個batch中生成的圖片是 從數據集的所有圖片中,隨機抽取一張并進行圖片尺寸大小啥的變換后放入batch中, 這樣抽取batch_size張圖片后就形成一個batch。# (2) 對圖片進行旋轉尺寸大小變換后的圖片,圖片大小[不會]改變。for i in range(3):x,y=next(gen)print(y)print(x.shape)photo1=np.squeeze(x[0])#降維photo2=np.squeeze(x[1])#降維photo1==np.array(photo1,dtype=np.uint8)#轉換為圖像格式,必須使用==photo2 == np.array(photo2, dtype=np.uint8) # 轉換為圖像格式,必須使用==plt.subplot(3,2,(i+1)*2-1)plt.imshow(photo1)plt.subplot(3,2, (i+1)*2)plt.imshow(photo2)plt.show()批量生成保存到文件夾中
# -*- coding: utf-8 -*-from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img import numpy as npdatagen = ImageDataGenerator(rotation_range=40,width_shift_range=0.2,height_shift_range=0.2,rescale=1/255.0,shear_range=0.2,zoom_range=0.2,horizontal_flip=True,fill_mode='nearest' )import osfor root ,dirs,files in os.walk(r'C:\Users\Shineion\Desktop\新建文件夾'):for name in files:file_path=os.path.join(root,name)#包含路徑的文件print(file_path)img = load_img(file_path)x = img_to_array(img)#print(x.shape)x = np.expand_dims(x, 0)#print(x.shape)i = 0for batch in datagen.flow(x, batch_size=1, save_to_dir='C:\\Users\\Shineion\\Desktop\\新建文件夾',save_prefix='new_photo', save_format='png'):i += 1if i == 20:breakprint('finished!')原始文件夾
結果文件夾42張圖
算例flow_from_directory
原始文件夾
cat dog文件夾里有圖
relult文件夾無圖
結果
在模型中使用圖像數據增強
還是使用上例中的文件夾,不同的是我擴充啦貓狗的數據集
貓和狗各有30張左右圖
用到的知識點
對于小型,簡單化的數據集,使用Keras的.fit函數是完全可以接受的。
這些數據集通常不是很具有挑戰性,不需要任何數據增強。
但是,真實世界的數據集很少這么簡單:
真實世界的數據集通常太大而無法放入內存中
它們也往往具有挑戰性,要求我們執行數據增強以避免過擬合并增加我們的模型的泛化能力,這時候我們需要用到利用Keras的.fit_generator函數
優點:通過Python generator產生一批批的數據用于訓練模型。generator可以和模型并行運行,例如,可以使用CPU生成批數據同時在GPU上訓練模型。
- generator:一個generator或Sequence實例,為了避免在使用multiprocessing時直接復制數據。
- steps_per_epoch:從generator產生的步驟的總數(樣本批次總數)。通常情況下,應該等于數據集的樣本數量除以批量的大小。(即一次多少樣本)
- epochs:整數,在數據集上迭代的總數。
- works:在使用基于進程的線程時,最多需要啟動的進程數量。
代碼可以運行
預測代碼
from matplotlib import image as mping from matplotlib import pyplot as plt import numpy as np img=mping.imread(r'C:\Users\Shineion\Desktop\新建文件夾\catdog\dog\dog.3.jpg')#image.read() plt.imshow(img)#圖片顯示 plt.show()#畫布顯示img=np.array(img) img=np.resize(img,(200, 200, 3)) img=np.expand_dims(img, 0)#擴展維度predict=model.predict(img) print(predict)結果
為狗的概率0.49
我只有幾十張圖,當然準確度低
注意問題
在把數據增強和模型結合起來時容易出現這個問題
IOError: broken data stream when reading image file
這是因為數據在增強時出現損壞。
我還未研究如何解決,可能有些增強操作會造成文件損壞。
為保證萬無一失,我還是傾向于先數據增強,把圖保存到文件夾中。再使用模型,這樣做的缺點是占內存。存儲需要內存的
更多模型代碼
下面代碼來源于keras ImageDataGenerator用法
使用flow
(x_train, y_train), (x_test, y_test) = cifar10.load_data() y_train = np_utils.to_categorical(y_train, num_classes) y_test = np_utils.to_categorical(y_test, num_classes)datagen = ImageDataGenerator(featurewise_center=True,featurewise_std_normalization=True,rotation_range=20,width_shift_range=0.2,height_shift_range=0.2,horizontal_flip=True)# compute quantities required for featurewise normalization # (std, mean, and principal components if ZCA whitening is applied) datagen.fit(x_train)# 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)# here's a more "manual" example for e in range(epochs):print 'Epoch', ebatches = 0for x_batch, y_batch in datagen.flow(x_train, y_train, batch_size=32):loss = model.train(x_batch, y_batch)batches += 1if batches >= len(x_train) / 32:# we need to break the loop by hand because# the generator loops indefinitelybreak使用flow_from_directory(directory)
train_datagen = ImageDataGenerator(rescale=1./255,shear_range=0.2,zoom_range=0.2,horizontal_flip=True)test_datagen = ImageDataGenerator(rescale=1./255)train_generator = train_datagen.flow_from_directory('data/train',target_size=(150, 150),batch_size=32,class_mode='binary')validation_generator = test_datagen.flow_from_directory('data/validation',target_size=(150, 150),batch_size=32,class_mode='binary')model.fit_generator(train_generator,steps_per_epoch=2000,epochs=50,validation_data=validation_generator,validation_steps=800)
作者:重慶電網準新人-余登武
總結
以上是生活随笔為你收集整理的Keras .ImageDataGenerator图像增强用法大全以及如何和模型结合起来(有代码)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我小鹅花钱逾期72天有事吗
- 下一篇: 一篇带你搞透回溯算法