前言: 主要总结了数据增强(Data augmentation)常用的一些方法,包括了翻转(flip)、旋转(rotation)、缩放(scale)、裁剪(crop)、移位(translation)和其他一些方法,列出了使用opencv、numpy、tensorflow和其他一些库进行实现的函数。还有展示了keras中的实现数据增强的工具。
数据增强可以有效提高数据量,可以扩充训练数据集。但也并非万能的,有时过度信任数据增强会带来负面效果,还会增加网络训练时间。需酌情使用。
相关总结如下:
import cv2
import numpy as np
import tensorflow as tf
import imutils
import skimage
import pillow
path = '/home/zhangwei/workfiles/deeplearning/dogVScat/data/cat_1.jpg'
img = cv2.imread(path)
# tensorflow加载图片
# img = tf.gfile.FastGFile(path).read()
# img_data = tf.image.decode_jpeg(img)
#-----> 翻转(flip)<--------------#
# 用opencv实现
flip_11 = cv2.flip(img, 1, dst = None) # 1:水平,0:垂直,-1:对角
# 用numpy实现
flip_21 = np.fliplr(img) # 水平翻转
flip_22 = np.transpose # 转置
# 用tensorfolw实现
flip_31 = tf.image.flip_up_down(img)
flip_32 = tf.image.flip_left_right
flip_33 = tf.image.random_flip_up_down # 随机翻转,50%概率
flip_34 = tf.image.random_flip_left_right
flip_35 = tf.image.transpose_image # 转置图像
#----> 旋转(rotation)<-----------#
# 用opencv实现
M = cv2.getRotationMatrix2D(center, 45, 1.0)
rotation_11 = cv2.warpAffine(img, M, (w,h))
rotation_12 = imutils.rotate(img, angles)
# 用numpy实现
rotation_21 = np.rot90(img, k, axes)
# 用tensorflow实现
rotation_31 = tf.image.rot90(img, k = 1) # k:旋转次数
rotation_32 = tf.contrib.image.rotate(img, angles = 3.14) # 旋转任意角度
# 用其他方式
rotation_41 = skimage.transform.rotate(img, angles = 45, mode = 'reflect')
#----> 缩放(scale)<-------------#
# 用opencv实现
scale_11 = cv2.resize(img, dsize, fx, fy, interpolation)
# 用numpy实现
reshape() x
resize() x
# 用tensorflow实现
tf.image.resize_images(img, [M,N], method)
tf.image.resize_image_with_crop_or_pad(img, M, N)
tf.image.central_crop(img, factor)
# 用其他方式
scale_41 = skimage.transform.rescale(img, scale, mode)
#---->裁剪(crop)<-------------#
# 用切片即可实现
# 用tensorflow实现
crop_31 = tf.random_crop(img, size, seed)
crop_32 = tf.image.crop_to_bounding_box()
#---->移位(translation)<------------#
# 用opencv实现
M = np.float32([[x1,y1,z1],[x2,y2,z2]])
translation_11 = cv2.warpAffine(img, M, (w,h))
# 用numpy实现
None
# 用tensorflow实现
translation_31 = tf.image.pad_to_bounding_box(img, pad_bottom, pad_right,height, width)
#----->其他一些方法<----------------#
# 光照对比度
tf.image.adjust_brightness
tf.image.random_brightness
tf.iamge.adjust_constrast
tf.image.random_constrast
# 增加噪声
# 其他有创造性的想法
# !!!keras中有提供了批量数据增强的函数ImageDataGenerator!!!#
from keras.preprocessing.image import ImageDataGenerator
# 图像增强
train_datagen = ImageDataGenerator(
featurewise_center=False, # 去中心化
samplewise_center=False, # 样本均值为0
featurewise_std_normalization = False, # 样本值/数据集标准差
samplewise_std_normalization = False, # 样本值/自身标准差
zca_whitening = False, # ZCA白化
rotation_range = 0., # 随机旋转角度*
width_shift_range = 0., # 宽度比例0-1*
height_shift_range = 0., # 高度比例0-1*
shear_range = 0., # 剪切强度*
zoom_range = 0., # 随机缩放幅度*
channel_shift_range = 0., # 随机通道偏移幅度,颜色变化
fill_mode = 'nearest', # 当变换处理超出边界时,处理方式:constant,nearest,reflect,wrap
cval = 0.0, # 超出边界时,填充的值
horizontal_flip = False, # 随机水平翻转*
vertical_flip = False, # 随机垂直翻转*
rescale = None, # 比例系数
preprocessing_function = None, # 预处理函数*
data_format = K.image_data_format()
)
# 生成(x,y)元组的目标迭代器,x:图像numpy数组,y:标签numpy数组
train_generator = train_datagen.flow_from_directory(
directory: Any, # 寻找该目录下的图像
target_size: Tuple[int, int] = (256, 256), # 调整找到的所有图像尺寸
color_mode: str = 'rgb', # 图像颜色模式
classes: Any = None, # 子目录,类列表
class_mode: str = 'categorical', # 类模式
batch_size: int = 32, # 批次大小
shuffle: bool = True, # 随机数据,否则按照字母排序
seed: Any = None, # 种子,用于洗牌和切换
save_to_dir: Any = None, # 保存路径
save_prefix: str = '', # 保存前缀
save_format: str = 'png', # 保存格式:png,jpeg
follow_links: bool = False, # 跟随链接
subset: Any = None, # 子集(验证集)
interpolation: str = 'nearest' # 插值方式
)
# 使用其训练模型,返回值为一个对象
model.fit_generator(
generator = train_generator, # 生成器
steps_per_epoch, # 次数
epochs=1, # 迭代轮数
verbose=1, # 日志显示,0:不输出,1:输出进度条信息,2:每个epoch出一行记录
callbacks=None, # 回调
validation_data=None, # 生成验证集生成器:tuple
validation_steps=None, # 当validation为生成器,指定返回次数
class_weight=None, # 类别权重字典
max_q_size=10, # 生成器队列最大容量
workers=1, # 最大进程数
pickle_safe=False, # 基于进程的线程
initial_epoch=0 # 从该参数指定的epoch开始训练
)