想要通过少量数据集来训练一个识别程度非常好的模型,是一个具有挑战性的机器学习问题,但它也是一个现实的问题:在许多现实世界的使用案例中,即使是小规模的数据收集也可能非常昂贵或有时几乎不可能(例如在医学成像中)
因此我们尽可能的充分利用我们的一些训练样例,我们将通过一系列随机变换来“扩充”它们,这样我们的模型就不会看到完全相同的两次图像。这有助于防止过度拟合,并有助于模型更好地概括.kerars提供了相关模块。
我们将使用一只哈士奇的图片来举例子
(我是一只披着狼皮的狼..)
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
datagen = ImageDataGenerator(
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
'''
rotation_range 是一个度数(0-180)的值,是一个随机旋转图片的范围
width_shift并且height_shift是在垂直或水平方向上随机平移图片的范围(作为总宽度或高度的一部分)
rescale是一个值,我们将在任何其他处理之前将数据相乘。我们的原始图像包含0-255中的RGB系数,但是这些值对于我们的模型来说太高了(给定典型的学习速率),所以我们将目标值设置在0和1之间,而不是用1/255进行缩放。因子。
shear_range用于随机应用剪切变换
zoom_range 用于随机缩放图片内部
horizontal_flip 用于水平地随机翻转一半图像 - 当没有水平不对称假设时(例如真实世界的图片)是相关的。
fill_mode 是用于填充新创建的像素的策略,可以在旋转或宽度/高度偏移后出现。
'''
img = load_img('./dog2ha.jpg') # this is a PIL image
x = img_to_array(img) # this is a Numpy array with shape (3, 150, 150)
x = x.reshape((1,) + x.shape) # this is a Numpy array with shape (1, 3, 150, 150)
# the .flow() command below generates batches of randomly transformed images
# and saves the results to the `preview/` directory
i = 0
for batch in datagen.flow(x, batch_size=1, #save_to_dir 文件夹 prefix图片名字 format格式
save_to_dir='Model', save_prefix='cat', save_format='jpeg'):
i += 1
if i > 20: #如果不break会无限循环
break # otherwise the generator would loop indefinitely
让我们开始使用这个工具生成一些图片并将它们保存到临时目录中,这样我们就可以了解我们的增强策略正在做什么 - 我们在这种情况下禁用重新缩放以保持图像可显示:
这是我们得到的样子:
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(3, 150, 150)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
# the model so far outputs 3D feature maps (height, width, features)
model.add(Flatten()) # this converts our 3D feature maps to 1D feature vectors
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
batch_size = 16
# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1./255)
# this is a generator that will read pictures found in
# subfolers of 'data/train', and indefinitely generate
# batches of augmented image data
train_generator = train_datagen.flow_from_directory(
'data/train', # this is the target directory
target_size=(150, 150), # all images will be resized to 150x150
batch_size=batch_size,
class_mode='binary') # since we use binary_crossentropy loss, we need binary labels
# this is a similar generator, for validation data
validation_generator = test_datagen.flow_from_directory(
'data/validation',
target_size=(150, 150),
batch_size=batch_size,
class_mode='binary')
model.fit_generator(
train_generator,
steps_per_epoch=2000 // batch_size,
epochs=50,
validation_data=validation_generator,
validation_steps=800 // batch_size)
model.save_weights('first_try.h5') # always save your weights after training or during training