一、图片数据读取
在做模型训练前,需要读取数据集数据,对图片数据的读取方法做一下介绍。
数据的存放如下:数据集存放在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) # 模型训练