Keras 的《官方文档》 和早期网友翻译的《文档》都对它的使用进行了较为详细的解释,可能由于篇幅的限制,这些文档对于一些较为细节的问题没有过多的介绍,在这里我在前人的基础上进行一些补充。注意本文主要参照上面两个文档的内容而成,我自己单独补充的部分进行了黑体加粗。
1. ImageDataGenerator 类
下面是关于ImageDataGenerator 类的参数说明
keras.preprocessing.image.ImageDataGenerator(featurewise_center=False,
samplewise_center=False,
featurewise_std_normalization=False,
samplewise_std_normalization=False,
zca_whitening=False,
zca_epsilon=1e-06,
rotation_range=0,
width_shift_range=0.0,
height_shift_range=0.0,
brightness_range=None,
shear_range=0.0,
zoom_range=0.0,
channel_shift_range=0.0,
fill_mode='nearest',
cval=0.0,
horizontal_flip=False,
vertical_flip=False,
rescale=None,
preprocessing_function=None,
data_format=None,
validation_split=0.0,
dtype=None)
这个类用以生成一个batch的图像数据,支持实时数据提升。训练时该函数会无限生成数据,直到达到规定的 epoch 次数为止。
1.1 参数
featurewise_center: 布尔值。将输入数据的均值设置为 0,逐特征进行。这里所谓的逐特征进行,实际上就是逐通道进行,单通道图像减去的均值的是 [[[average]]],三通道图像减去的均值是 [[[R_average, G_average, B_average]]]
samplewise_center: 布尔值。将每个样本的均值设置为 0。
featurewise_std_normalization: 布尔值。将输入除以数据标准差,逐特征进行。
samplewise_std_normalization: 布尔值。将每个输入除以其标准差。
zca_epsilon: ZCA 白化的 epsilon 值,默认为 1e-6。
zca_whitening: 布尔值。是否应用 ZCA 白化。
rotation_range: 整数。随机旋转的度数范围。
width_shift_range: 浮点数、一维数组或整数。随机水平移动的幅度范围。
float: 如果 <1,则是除以总宽度的值,或者如果 >=1,则为像素值。
1-D 数组: 数组中的随机元素。
int: 来自间隔 (-width_shift_range, +width_shift_range) 之间的整数个像素。
width_shift_range=2 时,可能值是整数 [-1, 0, +1],与 width_shift_range=[-1, 0, +1] 相同;而 width_shift_range=1.0 时,可能值是 [-1.0, +1.0) 之间的浮点数。
height_shift_range: 浮点数、一维数组或整数。随机水平移动的幅度范围。
float: 如果 <1,则是除以总宽度的值,或者如果 >=1,则为像素值。
1-D array-like: 数组中的随机元素。
int: 来自间隔 (-height_shift_range, +height_shift_range) 之间的整数个像素。
height_shift_range=2 时,可能值是整数 [-1, 0, +1],与 height_shift_range=[-1, 0, +1] 相同;而 height_shift_range=1.0 时,可能值是 [-1.0, +1.0) 之间的浮点数。
shear_range: 浮点数。剪切强度(以弧度逆时针方向剪切角度)。
补充:什么是剪切变换?
剪切变换是仿射变换的一种原始变换,指的是类似四边形不稳定性的那种性质,方形变四边形,任意一边均可被拉长的过程。
zoom_range: 浮点数 或 [lower, upper]。随机缩放范围。如果是浮点数,[lower, upper] = [1-zoom_range, 1+zoom_range]。
channel_shift_range: 浮点数。随机通道转换的范围,或者可以理解为随机通道偏移的幅度。
fill_mode: {“constant”, “nearest”, “reflect” or “wrap”} 之一。常用于填充由于旋转平移造成的图像空白,默认为 ‘nearest’。输入边界以外的点根据给定的模式填充:
‘constant’: kkkkkkkk|abcd|kkkkkkkk (cval=k)
‘nearest’: aaaaaaaa|abcd|dddddddd
‘reflect’: abcddcba|abcd|dcbaabcd
‘wrap’: abcdabcd|abcd|abcdabcd
cval: 浮点数或整数。用于边界之外的点的值,当 fill_mode = “constant” 时。
horizontal_flip: 布尔值。随机水平翻转。
vertical_flip: 布尔值。随机垂直翻转。
rescale: 重缩放因子。默认为 None。如果是 None 或 0,不进行缩放,否则将数据乘以所提供的值(在应用任何其他转换之前)。常常用于将 [0, 255] 的输入图像缩放到 [0, 1]。
preprocessing_function: 应用于每个输入的函数。这个函数会在任何其他改变之前运行。这个函数需要一个参数:一张图像(秩为 3 的 Numpy 张量),并且应该输出一个同尺寸的 Numpy 张量。
也就是说这是在 Keras 进行实时数据增强之前的预处理。我们需要写这样的一个函数,它的输入是本来进行实时数据增强的图像,输出的是与原来大小相同的图像,相当于先执行一种 Keras 中没有的图像预处理方法。在下面会给出一个使用例子。
data_format: 图像数据格式,{“channels_first”, “channels_last”} 之一。“channels_last” 模式表示图像输入尺寸应该为 (samples, height, width, channels),“channels_first” 模式表示输入尺寸应该为 (samples, channels, height, width)。默认为 在 Keras 配置文件 ~/.keras/keras.json 中的 image_data_format 值。如果你从未设置它,那它就是 “channels_last”。
validation_split: 浮点数。Float. 保留用于验证的图像的比例(严格在0和1之间)。
dtype: 生成数组使用的数据类型。
1.2 关于仿射变换进度的补充
在上面的的各种增强方式中,旋转,平移,剪切变换等各种仿射变换,均采用的是 1 阶的插值方法,具体可以参考如下的代码
cd /usr/local/lib/python2.7/dist-packages/keras_preprocessing
之后找到定义 apply_affine_transform 函数的位置,可以看到
if transform_matrix is not None:
h, w = x.shape[row_axis], x.shape[col_axis]
transform_matrix = transform_matrix_offset_center(
transform_matrix, h, w)
x = np.rollaxis(x, channel_axis, 0)
final_affine_matrix = transform_matrix[:2, :2]
final_offset = transform_matrix[:2, 2]
channel_images = [scipy.ndimage.interpolation.affine_transform(
x_channel,
final_affine_matrix,
final_offset,
order=1,
mode=fill_mode,
x = np.stack(channel_images, axis=0)
x = np.rollaxis(x, 0, channel_axis + 1)
其中 scipy.ndimage.interpolation.affine_transform 的参数 order=1,其代表的含义是样条插值的阶,正常是使用 order=3。而且从 scipy.ndimage.interpolation.affine_transform 的代码可以看到,他实际上没有进行任何插值操作,如下
-def spline_filter(input, order=3, output=numpy.float64):
"""
Multi-dimensional spline filter.
For more details, see `spline_filter1d`.
See Also
--------
spline_filter1d
Notes
-----
The multi-dimensional filter is implemented as a sequence of
one-dimensional spline filters. The intermediate arrays are stored
in the same data type as the output. Therefore, for output types
with a limited precision, the results may be imprecise because
intermediate results may be stored with insufficient precision.
"""
if order < 2 or order > 5:
raise RuntimeError('spline order not supported')
input = numpy.asarray(input)
if numpy.iscomplexobj(input):
raise TypeError('Complex type not supported')
output = _ni_support._get_output(output, input)
if order not in [0, 1] and input.ndim > 0:
for axis in range(input.ndim):
spline_filter1d(input, order, axis, output=output)
input = output
else:
output[...] = input[...]
return output
可以看到,输入是什么样,输出就是什么样。所以直接使用,会降低仿射变换后图像的精度。
2. ImageDataGenerator 类方法2.1 apply_transformapply_transform(x, transform_parameters)根据给定的参数将变换应用于图像。
参数
x: 3D 张量,单张图像。
transform_parameters: 字符串 - 参数 对表示的字典,用于描述转换。目前,使用字典中的以下参数:
‘theta’: 浮点数。旋转角度(度)。
‘tx’: 浮点数。在 x 方向上移动。
‘ty’: 浮点数。在 y 方向上移动。
shear’: 浮点数。剪切角度(度)。
‘zx’: 浮点数。放大 x 方向。
‘zy’: 浮点数。放大 y 方向。
‘flip_horizontal’: 布尔 值。水平翻转。
‘flip_vertical’: 布尔值。垂直翻转。
‘channel_shift_intencity’: 浮点数。频道转换强度。
‘brightness’: 浮点数。亮度转换强度。
返回
输入的转换后版本(相同尺寸)。
2.2 fit
fit(x, augment=False, rounds=1, seed=None)
将数据生成器用于某些示例数据。它基于一组样本数据,计算与数据转换相关的内部数据统计。当且仅当 featurewise_center 或 featurewise_std_normalization 或 zca_whitening 设置为 True 时才需要。
参数
x: 样本数据。秩应该为 4。对于灰度数据,通道轴的值应该为 1;对于 RGB 数据,值应该为 3。
augment: 布尔值(默认为 False)。是否使用随机样本扩张。
rounds: 整数(默认为 1)。如果数据数据增强(augment=True),表明在数据上进行多少次增强。
seed: 整数(默认 None)。随机种子。
关于“去均值”的补充
首先需要科普一个问题,为什么使用图像训练神经网络的时候需要进行去均值,以及应该从那个维度去除均值。去均值把输入数据各个维度都中心化为0,避免数据过多偏差,影响训练效果,同时可以加快模型的收敛速度。一般是从通道的维度去除均值,即分别求出 B, G, R 三个通道的均值,比如说[[[0.21568, 0.22314, 0.25657]]],然后每个图像都减去它。
有一点需要尤为注意,这里减去的均值是 [0, 1] 区间的。这主要是因为在执行诸如 flow_from_directory 的命令时,其首先进行归一化(recale = 1/255.0),然后在进行去均值化。进入定义 image.py 的文件夹
cd /usr/local/lib/python2.7/dist-packages/keras_preprocessing
进入 image.py 文件,找到定义 def standardize(self, x) 的函数,看到其具体实现如下
def standardize(self, x):
"""Applies the normalization configuration to a batch of inputs.
# Arguments
x: Batch of inputs to be normalized.
# Returns
The inputs, normalized.
"""
if self.preprocessing_function:
x = self.preprocessing_function(x)
if self.rescale:
x *= self.rescale
if self.samplewise_center:
x -= np.mean(x, keepdims=True)
if self.samplewise_std_normalization:
x /= (np.std(x, keepdims=True) + 1e-6)
if self.featurewise_center:
if self.mean is not None:
x -= self.mean
else:
warnings.warn('This ImageDataGenerator specifies '
'`featurewise_center`, but it hasn\'t '
'been fit on any training data. Fit it '
'first by calling `.fit(numpy_data)`.')
if self.featurewise_std_normalization:
if self.std is not None:
x /= (self.std + 1e-6)
else:
warnings.warn('This ImageDataGenerator specifies '
'`featurewise_std_normalization`, '
'but it hasn\'t '
'been fit on any training data. Fit it '
'first by calling `.fit(numpy_data)`.')
if self.zca_whitening:
if self.principal_components is not None:
flatx = np.reshape(x, (-1, np.prod(x.shape[-3:])))
whitex = np.dot(flatx, self.principal_components)
x = np.reshape(whitex, x.shape)
else:
warnings.warn('This ImageDataGenerator specifies '
'`zca_whitening`, but it hasn\'t '
'been fit on any training data. Fit it '
'first by calling `.fit(numpy_data)`.')
return x
可以看到它是先进行 rescale,然后再进行减均值,如果你做了 reascale = 1/255.0 ,那么减的均值一定是位与 [0,1] 区间的。
通过手工指定均值,标准差的方法,可以使得 train, validation, test 减去相同的均值,除以相同的标准差。但是样本数据 x 需要将图片读入到内存中,在计算均值等数据,当数据量过大的时候,没有办法一次性将数据读入,这个时候可以考虑使用这样的方法。首先通过手工计算的方式求出当前数据的均值,然后修改 Keras 底层源码,将减去由 x 计算出的均值改为减去人为指定的均值。
具体的修改方式是,进入定义 image.py 的文件夹
cd /usr/local/lib/python2.7/dist-packages/keras_preprocessing
进入 image.py 文件,找到定义类 ImageDataGenerator(object) 中进行初始化 def __init__ 的位置,进行如下的修改,其中在注释的下面
# self.mean = None
self.mean = [[[55, 56, 57]]]
self.std = None
self.principal_components = None
其中被注释掉的是原始的初始化的值,这里改为给定一个数作为初始化的值。其中原理的在于,原始只有经过 fit(x) 之后才可以给 self.mean 赋值为计算出的均值;而我们这里不进行 fir(x) 的计算,直接改变 self.mean 的初始值,这样当调用 def standardize(self, x) 的时候,就可以使用我们手工指定的初值了。
但是在计算均值的过程中有一点需要注意,使用 Opencv 默认读入图片的颜色顺序为BGR,而使用PIL默认读入图片的颜色顺序为 RGB。Keras 在使用图片生成器读入数据的时候调用的是 PIL,所以如果是通过 Opencv 计算的均值需要将顺序从 BGR 调整为 RGB 才可以使用。
2.3 flow
flow(x, y=None, batch_size=32, shuffle=True, sample_weight=None, seed=None,
save_to_dir=None, save_prefix='', save_format='png', subset=None)
接收numpy数组和标签为参数,生成经过数据提升或标准化后的batch数据,并在一个无限循环中不断的返回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。
返回
一个生成元组 (x, y) 的 Iterator,其中 x 是图像数据的 Numpy 数组(在单张图像输入时),或 Numpy 数组列表(在额外多个输入时),y 是对应的标签的 Numpy 数组。如果 ‘sample_weight’ 不是 None,生成的元组形式为 (x, y, sample_weight)。如果 y 是 None, 只有 Numpy 数组 x 被返回。
2.4 flow_from_directory
flow_from_directory(directory, target_size=(256, 256), color_mode='rgb',
classes=None, class_mode='categorical', batch_size=32,
shuffle=True, seed=None, save_to_dir=None, save_prefix='',
save_format='png', follow_links=False, subset=None,
interpolation='nearest')
参数
directory: 目标目录的路径。每个类应该包含一个子目录。任何在子目录树下的 PNG, JPG, BMP, PPM 或 TIF 图像,都将被包含在生成器中。
target_size: 整数元组 (height, width),默认:(256, 256)。所有的图像将被调整到的尺寸。
color_mode: “grayscale”, “rbg” 之一。默认:“rgb”。图像是否被转换成 1 或 3 个颜色通道。
classes: 可选的类的子目录列表(例如 [‘dogs’, ‘cats’])。默认:None。如果未提供,类的列表将自动从 directory 下的 子目录名称/结构 中推断出来,其中每个子目录都将被作为不同的类(类名将按字典序映射到标签的索引)。包含从类名到类索引的映射的字典可以通过 class_indices 属性获得。
class_mode: “categorical”, “binary”, “sparse”, “input” 或 None 之一。默认:“categorical”。决定返回的标签数组的类型:
“categorical” 将是 2D one-hot 编码标签,
“binary” 将是 1D 二进制标签,“sparse” 将是 1D 整数标签,
“input” 将是与输入图像相同的图像(主要用于自动编码器)。
如果为 None,不返回标签(生成器将只产生批量的图像数据,对于 model.predict_generator(), model.evaluate_generator() 等很有用)。请注意,如果 class_mode 为 None,那么数据仍然需要驻留在 directory 的子目录中才能正常工作。
batch_size: 一批数据的大小(默认 32)。
shuffle: 是否混洗数据(默认 True)。
seed: 可选随机种子,用于混洗和转换。
save_to_dir: None 或 字符串(默认 None)。这使你可以最佳地指定正在生成的增强图片要保存的目录(用于可视化你在做什么)。
save_prefix: 字符串。 保存图片的文件名前缀(仅当 save_to_dir 设置时可用)。
save_format: “png”, “jpeg” 之一(仅当 save_to_dir 设置时可用)。默认:“png”。
follow_links: 是否跟踪类子目录中的符号链接(默认为 False)。
subset: 数据子集 (“training” 或 “validation”),如果 在 ImageDataGenerator 中设置了 validation_split。
interpolation: 在目标大小与加载图像的大小不同时,用于重新采样图像的插值方法。 支持的方法有 “nearest”, “bilinear”, and “bicubic”。 如果安装了 1.1.3 以上版本的 PIL 的话,同样支持 “lanczos”。 如果安装了 3.4.0 以上版本的 PIL 的话,同样支持 “box” 和 “hamming”。 默认情况下,使用 “nearest”。这个参数应该是在新版 keras (2.2.4) 中新添加的,在原来的 2.1.5 中是没有的。
从这里可以看出 flow 和 flow_from_directory 的区别在于,flow 的输入是已经读入的图像,而 flow_from_directory 的输入是存放图像的文件夹。
---------------------
作者:独孤呆博
来源:CSDN
原文:
版权声明:本文为博主原创文章,转载请附上博文链接!





































苏公安网备 32011402010933号