一、圖片數據讀取
在做模型訓練前,需要讀取數據集數據,對圖片數據的讀取方法做一下介紹。
數據的存放如下:數據集存放在C:\Users\Administrator\Desktop\train\datasets文件夾,該文件夾下有兩個文件夾,train存放訓練集,test存放測試集。圖片的命名格式為“類別_圖片編號”如下圖:
這個方法利用的是tensorflow的IO,先將數據讀取為二進制格式,然后在解碼為圖片對應的格式的張量。讀取用的是tf.io.read_file,解碼轉換用的是tf.image.decode_jpeg,這里是將jpg格式的圖片進行解碼,其他格式的圖片解碼函數也在tf.image模塊下。
這里先介紹幾個用到的API:
- tf.data.Dataset.list_files(file_pattern) 用來獲取文件路徑列表,可以用來獲得文件夾下面的全部指定文件,file_pattern用的是正則路徑。
- tf.io.read_file(filename) 用來讀取文件。
- tf.image.decode_jpeg(contens) 將圖片文件解碼為張量,這里是jpg格式,其他的格式也在tf.image模塊中。
import tensorflow as tf import os import numpy as np # 訓練集圖片所在的文件夾,以訓練集為例,文件的命名為“類別_順序.jpg” train_path = "C:\\Users\\Administrator\\Desktop\\datasets\\train\\" # 這個函數用於返回符合,可以使用正則路徑,*表示任意字符 path_list = tf.data.Dataset.list_files(train_path + "*.jpg") # 定義一個讀取圖片的函數 def read_image(path_list): ''' :param path_list:文件的路徑list :return: 圖片張量列表,圖片標簽列表 ''' images = [] # 圖片聊表 image_labels = [] # 圖片標簽列表 # 根據文件路徑列表依次讀取 for i in path_list: image_temp = tf.io.read_file(i) # tesnsorflow的io讀取文件 image_temp = tf.image.decode_jpeg(image_temp) # 根據圖片的格式進行編碼轉化為張量,這里圖片是jpg格式 images.append(image_temp) # 圖片加入到數據集 image_labels.append(os.path.basename(str(i)).split('_')[0]) # 獲取文件名加入到標簽,這里要張量i轉化為字符串 return np.array(images), np.array(image_labels) # 讀取訓練圖片 train_images, train_labels = read_image(path_list=path_list)
二、圖片數據增強
當我們在讀入數據之后,數據可能需要做一下強化操作,這些操作可以增加模型的泛性,同時可以擴大我們的數據集,常見的數據強化操作如下:
- 旋轉 | 反射變換(Rotation/reflection): 隨機旋轉圖像一定角度; 改變圖像內容的朝向;
- 翻轉變換(flip): 沿着水平或者垂直方向翻轉圖像;
- 縮放變換(zoom): 按照一定的比例放大或者縮小圖像;
- 平移變換(shift): 在圖像平面上對圖像以一定方式進行平移;可以采用隨機或人為定義的方式指定平移范圍和平移步長, 沿水平或豎直方向進行平移. 改變圖像內容的位置;
- 尺度變換(scale): 對圖像按照指定的尺度因子, 進行放大或縮小; 或者參照SIFT特征提取思想, 利用指定的尺度因子對圖像濾波構造尺度空間. 改變圖像內容的大小或模糊程度;
- 對比度變換(contrast): 在圖像的HSV顏色空間,改變飽和度S和V亮度分量,保持色調H不變. 對每個像素的S和V分量進行指數運算(指數因子在0.25到4之間), 增加光照變化;
- 噪聲擾動(noise): 對圖像的每個像素RGB進行隨機擾動, 常用的噪聲模式是椒鹽噪聲和高斯噪聲;
- 錯切變換(shear):效果就是讓所有點的x坐標(或者y坐標)保持不變,而對應的y坐標(或者x坐標)則按比例發生平移,且平移的大小和該點到x軸(或y軸)的垂直距離成正比。
tensorflow的圖片強化API需要一下的類及類的方法,對應的API如下:
tf.keras.preprocessing.image.ImageDataGenerator() # 用來創建一個圖片數據集迭代器,可以在傳入數據時進行一些數據加強操作
-
rescale:縮放因子,圖像像素值乘以rescale,如果為255可以將像素值歸一到0-1區間。
-
featurewise_center:特征均值化,若為True,對輸入的圖片每個通道減去每個通道對應均值,與rescale=1/255相同。
-
samplewise_center:樣本均值化。
-
rotation_range:隨機旋轉角度范圍
-
zca_epsilon:ZCA 白化的 epsilon 值,默認為 1e-6。
-
zca_whitening: 布爾值。是否應用 ZCA 白化。
-
rotation_range: 整數。隨機旋轉的度數范圍。
-
width_shift_range:隨機寬度偏移量
-
height_shift_range:隨機高度偏移量
-
height_shift_range:水平翻轉量
-
zoom_range:隨機縮放,范圍[1-n,1+n]
ImageDataGenerator.fit() # 傳入圖片數據集,傳入之后會按照設定好的對圖片進行處理
- x: 樣本數據。維度4,即(batch,width,height,channel)的格式。對於灰度數據,channel的值應該為 1;對於 RGB 數據,channel值應該為 3。
- augment: 布爾值(默認為 False)。是否使用隨機樣本擴張。
- rounds: 整數(默認為 1)。如果數據數據增強(augment=True),表明在數據上進行多少次增強。
- seed: 整數(默認 None)。隨機種子。
注意:這一步並不是必須的,當ImageDataGenerator構造函數中需要使用featurewise_center: samplewise_center: featurewise_std_normalization: samplewise_std_normalization:這幾個參數時才需要使用fit方法,因為需要從fit方法中得到原始圖形的統計信息,比如均值、方差等等,否則是不需要此步驟的。
ImageDataGenerator.flow() # 采集數據和標簽數組,生成批量增強數據迭代器,最好按照需要設定batch。
- x: 輸入數據。秩為 4 的 Numpy 矩陣或元組。如果是元組,第一個元素應該包含圖像,第二個元素是另一個 Numpy 數組或一列 Numpy 數組,它們不經過任何修改就傳遞給輸出。可用於將模型雜項數據與圖像一起輸入。對於灰度數據,圖像數組的通道軸的值應該為 1,而對於 RGB 數據,其值應該為 3。
- y: 標簽。
- batch_size: 整數 (默認為 32)。
- shuffle: 布爾值 (默認為 True)。
- sample_weight: 樣本權重。
- seed: 整數(默認為 None)。
- save_to_dir: None 或 字符串(默認為 None)。這使您可以選擇指定要保存的正在生成的增強圖片的目錄(用於可視化您正在執行的操作)。
- save_prefix: 字符串(默認
''
)。保存圖片的文件名前綴(僅當save_to_dir
設置時可用)。 - save_format: "png", "jpeg" 之一(僅當
save_to_dir
設置時可用)。默認:"png"。 - subset: 數據子集 ("training" 或 "validation"),如果 在
ImageDataGenerator
中設置了validation_split
。
注意:flow()生成的迭代器是無限的,且是只能用model.fit_generator()將訓練數據傳入模型中訓練。
import tensorflow as tf import os import numpy as np # 訓練集圖片所在的文件夾,以訓練集為例,文件的命名為“類別_順序.jpg” train_path = "C:\\Users\\Administrator\\Desktop\\datasets\\train\\" # 這個函數用於返回符合,可以使用正則路徑,*表示任意字符 path_list = tf.data.Dataset.list_files(train_path + "*.jpg") # 定義一個讀取圖片的函數 def read_image(path_list): ''' :param path_list:文件的路徑list :return: 圖片張量列表,圖片標簽列表 ''' images = [] # 圖片聊表 image_labels = [] # 圖片標簽列表 # 根據文件路徑列表依次讀取 for i in path_list: image_temp = tf.io.read_file(i) # tesnsorflow的io讀取文件 image_temp = tf.image.decode_jpeg(image_temp) # 根據圖片的格式進行編碼轉化為張量,這里圖片是jpg格式 images.append(image_temp) # 圖片加入到數據集 image_labels.append(os.path.basename(str(i)).split('_')[0]) # 獲取文件名加入到標簽,這里要張量i轉化為字符串 return np.array(images), np.array(image_labels) # 讀取訓練圖片 train_images, train_labels = read_image(path_list=path_list) image_gen = tf.keras.preprocessing.image.ImageDataGenerator(featurewise_center=True, rotation_range=45) # 增強數據,中心化並隨機旋轉45度 image_gen.fit(x=train_images) # featurewise_center等設計均值方差的參數為True才需要使用fit方法 data_gen = image_gen.flow(train_images, train_labels) # 生成強化數據集迭代器 # model = tf.keras.Sequential().fit_generator(data_gen) # 模型訓練