基于CNN卷积神经网络的猫狗分类

  • 一、CNN卷积神经网络介绍
  • 二、相应包的导入
  • 三、模型的结构
  • 四、模型的构建
  • 五、优化器的数据的归一化处理
  • 六、测试数据和训练数据导入


一、CNN卷积神经网络介绍

见主页文章基于cnn的手写数字识别文字,CNN的介绍

二、相应包的导入

2.1分别从keras.layers包中导入卷积神经网络的2D卷积层、2D池化层、全连接层(Dense)、以及随机关闭神经元(Dropout)、扁平化(Flatten),如下

from keras.layers import Convolution2D,MaxPool2D#卷积层和池化层
from keras.layers import Dropout,Flatten,Dense#随机关闭神经元,扁平化,全连接层

2.2导入优化器和顺序模型,以及图像预处理包

from tensorflow.keras.optimizers import Adam#定义优化器
from keras.models import Sequential#定义顺序模型
from keras.preprocessing.image import ImageDataGenerator#定义图像预处理

三、模型的结构

该实验包含6个2D卷积层,3个最大池化层,两个全连接层,模型结构如下。

pythontensorflow猫狗分类 cnn猫狗分类_keras

四、模型的构建

4.1首先构建一个顺序模型,如下

model=Sequential()#构建顺序模型

4.2在构建的模型中依次添加卷积层、池化层等。构建第一个卷积层,卷积层包含输入平面尺寸,relu激活函数、卷积核大小以及卷积核的个数和步长。以same方式进行卷积,保证了卷积后的平面尺寸大小不变。结果如下:

model.add(Convolution2D(
    input_shape=(150,150,3),#输入格式(150,150,3)
    filters=32,#卷积核32个
    kernel_size=3,#卷积核大小3x3
    strides=1,#步长为1
    padding='same',#same方式
    activation='relu'#relu激活函数
))

4.3卷积层和池化层的构造如下:

model.add(Convolution2D(
    input_shape=(150,150,3),#输入格式(150,150,3)
    filters=32,#卷积核32个
    kernel_size=3,#卷积核大小3x3
    strides=1,#步长为1
    padding='same',#same方式
    activation='relu'#relu激活函数
))
model.add(Convolution2D(
    filters=32,#卷积核32个
    kernel_size=3,#卷积核大小3x3
    strides=1,
    padding='same',
    activation='relu'
))
model.add(MaxPool2D(
    pool_size=2,
    strides=2,
    padding='valid'
))
model.add(Convolution2D(
    filters=64,#卷积核64个
    kernel_size=3,#卷积核大小3x3
    strides=1,
    padding='same',
    activation='relu'
))
model.add(Convolution2D(
    filters=64,#卷积核64个
    kernel_size=3,#卷积核大小3x3
    strides=1,
    padding='same',
    activation='relu'
))
model.add(MaxPool2D(
    pool_size=2,
    strides=2,
    padding='valid'
))
model.add(Convolution2D(
    filters=128,#卷积核128个
    kernel_size=3,#卷积核大小3x3
    strides=1,
    padding='same',
    activation='relu'
))
model.add(Convolution2D(
    filters=128,#卷积核128个
    kernel_size=3,#卷积核大小3x3
    strides=1,
    padding='same',
    activation='relu'
))
model.add(MaxPool2D(
    pool_size=2,
    strides=2,
    padding='valid'
))

4.4扁平化与全连接层
结果卷积和池化操作后在进入全连接层时需要将数据变成一维数据,因此需要在model中添加Flatten()进行扁平化。进入第一个全连接层后使用的是relu激活函数,进入第二个全连接层后输出2个类,因此要采用的softmax激活函数

model.add(Flatten())#扁平化
model.add(Dense(64,activation='relu'))#64个神经元

4.5Dropout方式对全连接层的神经元进行随机关闭,防止过拟合。

model.add(Dropout(0.5))#随机关闭50%的神经元,防止过拟合
五、优化器的数据的归一化处理

采用Adam优化器,loss方选为交叉熵函数,准确率为accuracy。再对训练数据和测试数据进行归一化处理,节约运行时间。

#定义优化器
adam=Adam(1e-4)
#定义优化器,loss,准确度
model.compile(optimizer=adam,loss='categorical_crossentropy',metrics=['accuracy'])
#看结构
model.summary()
#训练数据处理
train_datagen=ImageDataGenerator(rescale=1/255)
#测试数据集处理
test_datagen=ImageDataGenerator(rescale=1/255)#归一化
六、测试数据和训练数据导入
#训练数据
train_generator=train_datagen.flow_from_directory(#flow_from_directory从哪一个文件夹获取
    'D:/深度学习/猫狗分类/image/train/',#训练数据路径
    target_size=(150,150),#设置图片大小
    batch_size=batch_size#批次大小
)
#测试数据
test_generator=train_datagen.flow_from_directory(#flow_from_directory从哪一个文件夹获取
    'D:/深度学习/猫狗分类/image/test1/',#训练数据路径
    target_size=(150,150),#设置图片大小
    batch_size=batch_size#批次大小
)
#训练模型
model.fit_generator(
    train_generator,#输入
    steps_per_epoch=6700/batch_size,
    epochs=2,
    validation_data=test_generator,#验证集,每个epoch到来都验证一下
    validation_steps=2500/batch_size
)

最终准确率在98%,能很好的识别猫狗,最终代码如下:

from keras.models import Sequential
from keras.layers import Convolution2D,MaxPool2D
from keras.layers import Dropout,Flatten,Dense
from tensorflow.keras.optimizers import Adam
from keras.preprocessing.image import ImageDataGenerator
#模型定义
model=Sequential()
model.add(Convolution2D(
    input_shape=(150,150,3),#输入格式(150,150,3)
    filters=32,#卷积核32个
    kernel_size=3,#卷积核大小3x3
    strides=1,#步长为1
    padding='same',#same方式
    activation='relu'#relu激活函数
))
model.add(Convolution2D(
    filters=32,#卷积核32个
    kernel_size=3,#卷积核大小3x3
    strides=1,
    padding='same',
    activation='relu'
))
model.add(MaxPool2D(
    pool_size=2,
    strides=2,
    padding='valid'
))
model.add(Convolution2D(
    filters=64,#卷积核64个
    kernel_size=3,#卷积核大小3x3
    strides=1,
    padding='same',
    activation='relu'
))
model.add(Convolution2D(
    filters=64,#卷积核64个
    kernel_size=3,#卷积核大小3x3
    strides=1,
    padding='same',
    activation='relu'
))
model.add(MaxPool2D(
    pool_size=2,
    strides=2,
    padding='valid'
))
model.add(Convolution2D(
    filters=128,#卷积核128个
    kernel_size=3,#卷积核大小3x3
    strides=1,
    padding='same',
    activation='relu'
))
model.add(Convolution2D(
    filters=128,#卷积核128个
    kernel_size=3,#卷积核大小3x3
    strides=1,
    padding='same',
    activation='relu'
))
model.add(MaxPool2D(
    pool_size=2,
    strides=2,
    padding='valid'
))

model.add(Flatten())#扁平化
model.add(Dense(64,activation='relu'))#64个神经元
model.add(Dropout(0.5))
model.add(Dense(2,activation='softmax'))#输出为两个神经元
#定义优化器
adam=Adam(1e-4)
#定义优化器,loss,准确度
model.compile(optimizer=adam,loss='categorical_crossentropy',metrics=['accuracy'])
#看结构
model.summary()
#训练数据处理
train_datagen=ImageDataGenerator(rescale=1/255)
#测试数据集处理
test_datagen=ImageDataGenerator(rescale=1/255)#归一化
batch_size=32
#训练数据
train_generator=train_datagen.flow_from_directory(#flow_from_directory从哪一个文件夹获取
    'D:/深度学习/猫狗分类/image/train/',#训练数据路径
    target_size=(150,150),#设置图片大小
    batch_size=batch_size#批次大小
)
#测试数据
test_generator=train_datagen.flow_from_directory(#flow_from_directory从哪一个文件夹获取
    'D:/深度学习/猫狗分类/image/test1/',#训练数据路径
    target_size=(150,150),#设置图片大小
    batch_size=batch_size#批次大小
)
#训练模型
model.fit_generator(
    train_generator,#输入
    steps_per_epoch=6700/batch_size,
    epochs=2,
    validation_data=test_generator,#验证集,每个epoch到来都验证一下
    validation_steps=2500/batch_size
)