最近在用keras做图像分类。初次试水,先用现有的模块搭个最简单的模型玩玩。在这个模型中,主要用到两个模块:ImageDataGenerator和inception_v3,前者是用于对图片数据做预处理,后者是inception网络的api。不得不说,keras提供的接口真心强大。
这个类的中文官网解释在http://keras-cn.readthedocs.io/en/latest/preprocessing/image/
类的定义:
keras.preprocessing.image.ImageDataGenerator(featurewise_center=False,
samplewise_center=False,
featurewise_std_normalization=False,
samplewise_std_normalization=False,
zca_whitening=False,
zca_epsilon=1e-6,
rotation_range=0.,
width_shift_range=0.,
height_shift_range=0.,
shear_range=0.,
zoom_range=0.,
channel_shift_range=0.,
fill_mode='nearest',
cval=0.,
horizontal_flip=False,
vertical_flip=False,
rescale=None,
preprocessing_function=None,
data_format=K.image_data_format())
大家总结的图片预处理要做的主要有:滤波、几何变换(旋转、镜像、缩放、裁剪)、规范化、平滑、增强、复原、压缩、分割。对应到上面的可设定的参数来看
(1).featurewise_center:布尔值,使输入数据集去中心化(均值为0), 按feature执行
(2).samplewise_center:布尔值,使输入数据的每个样本均值为0
(3).featurewise_std_normalization:布尔值,将输入除以数据集的标准差以完成标准化, 按feature执行
(4).samplewise_std_normalization:布尔值,将输入的每个样本除以其自身的标准差
(5).zca_whitening:布尔值,对输入数据施加ZCA白化
(6).zca_epsilon: ZCA使用的eposilon,默认1e-6
(7).rotation_range:整数,数据提升时图片随机转动的角度
(8).width_shift_range:浮点数,图片宽度的某个比例,数据提升时图片水平偏移的幅度
(9).height_shift_range:浮点数,图片高度的某个比例,数据提升时图片竖直偏移的幅度
(10).shear_range:浮点数,剪切强度(逆时针方向的剪切变换角度)
(11).zoom_range:浮点数或形如[lower,upper]的列表,随机缩放的幅度,若为浮点数,则相当于[lower,upper] = [1 - zoom_range, 1+zoom_range]
(12).channel_shift_range:浮点数,随机通道偏移的幅度
(13).fill_mode:;‘constant’,‘nearest’,‘reflect’或‘wrap’之一,当进行变换时超出边界的点将根据本参数给定的方法进行处理
(14).cval:浮点数或整数,当fill_mode=constant时,指定要向超出边界的点填充的值
(15).horizontal_flip:布尔值,进行随机水平翻转
(16).vertical_flip:布尔值,进行随机竖直翻转
(17).rescale: 重放缩因子,默认为None. 如果为None或0则不进行放缩,否则会将该数值乘到数据上(在应用其他变换之前)
(18).preprocessing_function: 将被应用于每个输入的函数。该函数将在任何其他修改之前运行。该函数接受一个参数,为一张图片(秩为3的numpy array),并且输出一个具有相同shape的numpy array
data_format:字符串,“channel_first”或“channel_last”之一,代表图像的通道维的位置。该参数是Keras 1.x中的image_dim_ordering,“channel_last”对应原本的“tf”,“channel_first”对应原本的“th”。以128x128的RGB图像为例,“channel_first”应将数据组织为(3,128,128),而“channel_last”应将数据组织为(128,128,3)。该参数的默认值是~/.keras/keras.json中设置的值,若从未设置过,则为“channel_last”
前6个参数都是做规范化的,参数7到17都是做几何变换相关操作,18引入自定义的处理函数。这个类貌似更针对网络输入前的图像预处理,主要是做数据增强的,提高泛化能力的,滤波、平滑什么的基本上没有。
这个类有3个方法:fit、flow、flow_from_directory:
fit(x, augment=False, rounds=1)
flow(self, X, y, batch_size=32, shuffle=True, seed=None, save_to_dir=None, save_prefix='', save_format='png')
flow_from_directory(directory)
第一个方法还没有用到,不太清楚具体功能,第二个方法用于对已经读入内存的图片数据执行处理,第三种方法对文件夹下的数据执行预处理,flow适用于小数据集、flow_from_directory适用于大的数据集。这两个处理方法都无限循环生成预处理后的batch数据,实际在类定义和方法调用时只是定义预处理的功能,在网络训练时才会真正生成batch数据,并且用一个生成一个。
官网例子:
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)
这个比较简单,API集成度也很高。
keras.applications.inception_v3.InceptionV3(include_top=True,
weights='imagenet',
input_tensor=None,
input_shape=None,
pooling=None,
classes=1000)
参数含义:
include_top:是否保留顶层的全连接网络
weights:None代表随机初始化,即不加载预训练权重。'imagenet'代表加载预训练权重
input_tensor:可填入Keras tensor作为模型的图像输出tensor
input_shape:可选,仅当include_top=False有效,应为长为3的tuple,指明输入图片的shape,图片的宽高必须大于197,如(200,200,3)
pooling:当include_top=False时,该参数指定了池化方式。None代表不池化,最后一个卷积层的输出为4D张量。‘avg’代表全局平均池化,‘max’代表全局最大值池化。
classes:可选,图片分类的类别数,仅当include_top=True并且不加载预训练权重时可用。
返回值
weight选择imagenet的话,在运行前先从github上下载inception_v3预训练的参数,并且载入到网络中。
同时,inception-v3的最后一层分类1000类,是imagenet的类别数,通常需要再接一层自己的全连接分类层。选择预训练的参数,top层意外的其他层参数可选择是否训练,不做训练的话,需要把对应的layer的trainable参数设为False。
layer.trainable = False
接下来,model.compile()和model.fit()就可以训练了。