用keras进行猫狗识别(二)

版权声明:董瑞 https://blog.csdn.net/qq_39226755/article/details/89601490

通过少量的训练集,我们成功训练出了模型,但是正确率只有75%左右,而且出现了过拟合的情况,出现这种情况,我们可以采用数据增强的方法。
通过数据增强,我们可以增加训练样本的数量,来解决样本不够的问题。
数据增强的作用 :

  1. 增加训练的数据量,提高模型的泛化能力
  2. 增加噪声数据,提升模型的鲁棒性

如何获得大量的数据 :
一种方法是获得新的数据,这种方法比较麻烦,需要大量的成本,而第二种方法则是对数据进行增强,即利用已有的数据比如翻转、平移或旋转,创造出更多的数据,来使得神经网络具有更好的泛化效果。

数据增强的分类 :
数据增强可以分为两类,一类是离线增强,一类是在线增强。
离线增强 : 直接对数据集进行处理,数据的数目会变成增强因子 x 原数据集的数目 ,这种方法常常用于数据集很小的时候
在线增强 : 这种增强的方法用于,获得 batch 数据之后,然后对这个 batch 的数据进行增强,如旋转、平移、翻折等相应的变化,由于有些数据集不能接受线性级别的增长,这种方法长用于大的数据集,很多机器学习框架已经支持了这种数据增强方式,并且可以使用 GPU 优化计算。

常用的数据增强方法:
1.旋转: 可通过在原图上先放大图像,然后剪切图像得到。
2.平移:先放大图像,然后水平或垂直偏移位置剪切
3.缩放:缩放图像
4.随机遮挡:对图像进行小区域遮挡
5.水平翻转:以过图像中心的竖直轴为对称轴,将左、右两边像素交换
6.颜色色差:(饱和度、亮度、对比度、 锐度等)
7.噪声扰动: 对图像的每个像素RGB进行随机扰动, 常用的噪声模式是椒盐噪声和高斯噪声;

下边通过数据增强改进我们的模型:

from keras import layers
from keras import models
#设置文件目录
#训练集
trainDir ='./train/'
trainDogDir = './train/train_dog/'
trainCatDir = './train/train_cat/'
#验证集
valDir = './check/'
valDogDir = './check/check_dog/'
valCatDir = './check/check_cat/'
#测试集
testDir = './test/'
testDogDir = './test/test_dog/'
testCatDir = './test/test_cat/'

#创建模型
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu',input_shape=(150, 150, 3)))
#卷积层,输出空间的维数为32,也可以说是输出特征图的深度为32,提取信息的窗口大小(3,3),卷积核的大小也为(3,3)
#激活函数relu,输入图片大小(150,150,3)
model.add(layers.MaxPooling2D((2, 2)))
#池化层,窗口大小为(2,2),缩小特征图的尺寸
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Flatten())
model.add(layers.Dropout(rate=0.5))
#扁平层,将多维的输入转化为一维的输出
model.add(layers.Dense(512, activation='relu'))
#全连接层,将提取的特征组合,得出结果
model.add(layers.Dense(1, activation='sigmoid'))

#设置损失函数,优化器,模型在训练和测试时的性能指标
from keras import optimizers

model.compile(loss='binary_crossentropy',
  optimizer=optimizers.RMSprop(lr=1e-4),
  metrics=['acc'])

#配置图片生成器
from keras.preprocessing.image import ImageDataGenerator
#将图片像素缩小为[0,1]之间的浮点数
train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=40,#图像随机旋转的最大角度
    width_shift_range=0.2,#图片在水平位置上偏移的最大百分比值
    height_shift_range=0.2,#数值位置上
    shear_range=0.2,#随机错位切换的角度
    zoom_range=0.2,#图片随机缩放的范围
    horizontal_flip=True)#随机将一半的图片进行水平翻转

#验证集的数据不能增强
test_datagen = ImageDataGenerator(rescale=1./255)

#创建图片生成器
train_generator = train_datagen.flow_from_directory(
 trainDir,#图片地址
 target_size=(150, 150),#将图片调整为(150,150)大小
 batch_size=32,#设置批量数据的大小为32
 class_mode='binary')#设置返回标签的类型
val_generator = test_datagen.flow_from_directory(
 valDir,
 target_size=(150, 150),
 batch_size=32,
 class_mode='binary')

#拟合模型
history = model.fit_generator(
  train_generator,
  steps_per_epoch=100,#迭代进入下一轮次需要抽取的批次
  epochs=100,#数据迭代的轮数
  validation_data=val_generator,
  validation_steps=50)#验证集用于评估的批次

#保存模型
model.save('cats_and_dogs_small_2.h5')


#画出结果
import matplotlib.pyplot as plt

#查看变量,发现history.history中就只有这四个值,分别是准确度,验证集准确度,损失,验证集损失
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(acc) + 1)

#画两个图,分别是正确率和损失
#正确率
plt.figure(1)
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.savefig('acc2.png')
plt.show()
#验证损失
plt.figure(2)
plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.legend()
plt.savefig('loss2.png')
plt.show()

我们在模型中加了一个Dropout层,这个层可以帮助我们来减弱过拟合的状态。

model.add(layers.Dropout(rate=0.5))

Dropout层模型如下:
在这里插入图片描述
它会让一些节点失效,这样就会使模型去学习更加普遍的特征。

同时因为样本增多,我们增加迭代的次数

history = model.fit_generator(
  train_generator,
  steps_per_epoch=100,#迭代进入下一轮次需要抽取的批次
  epochs=100,#数据迭代的轮数
  validation_data=val_generator,
  validation_steps=50)#验证集用于评估的批次

最终训练处模型,模型的正确率和验证损失如下:
在这里插入图片描述
在这里插入图片描述
可以看出我们的正确率达到了80%
相比普通的直接训练,有很大的提高

猜你喜欢

转载自blog.csdn.net/qq_39226755/article/details/89601490