从零开始——手把手搭建 深度学习二分类任务(猫狗识别任务)CNN神经网络

  • 1.环境部分
  • 用到的工具
  • 环境和包的下载以搭建
  • 2.开始实现
  • 1.将数据集加载进来
  • 2.搭建CNN神经网络模型
  • 3.CNN神经网络模型其他参数设置
  • 4.训练模型
  • 3.计算准确率
  • 4.使用网上随便找的图片来测试模型
  • 5.遇到的问题解决



本篇从新手开始,手把手搭建CNN深度学习网络,用于猫狗识别或其他二分类任务,请仔细阅读

1.环境部分

用到的工具

系统:win10
环境部分:anaconda
语言:python3.6
框架:keras
数据:数据集下载点击此处

环境和包的下载以搭建

由于这部分内容比较基础,所以关于anaconda下载安装和环境的创建,以及用的到各种包的下载若不能独立完成,请移步至 /anaconda从零到独立搭建环境(编辑中)/

2.开始实现

1.将数据集加载进来

使用keras中的ImageDataGenerator可以批量加载图片
首先把这个包引入进来

from keras.preprocessing.image import ImageDataGenerator

ImageDataGenerator具有批量加载功能的图片,在设置了加载的路径后可以将数据集中的图片一次全部载入

from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale=1./255)
training_set = train_datagen.flow_from_directory('./training_set',target_size=(50,50),batch_size=32,class_mode='binary')

接下来我们来分析代码:
train_datagen = ImageDataGenerator(rescale=1./255)首先使用ImageDataGenerator()
对图片数据进行预处理,rescale参数表示进行归一化处理
training_set = train_datagen.flow_from_directory(’./training_set’,target_size=(50,50),batch_size=32,class_mode=‘binary’)
之后使用设置好的生成器,调用flow_from_directory()加载数据,第一个参数是数据集的路径,target_size参数表示将数据集中的图片统一转换成50*50的尺寸,batch_size表示一次性提取多少张图片投入到CNN神经网络中进行计算,class_mode表示本任务是一个二分类任务

2.搭建CNN神经网络模型

本篇CNN模型采用:
两层的卷积层和两层的池化层
之后使用Flatten进行转换
然后仅有一个128个神经元的全连接层
输出层是一个神经元的二分类模型

基于cnn猫狗主要工作原理的研究论文_tensorflow

#建立CNN模型
from keras.models import Sequential
from keras.layers import Conv2D, MaxPool2D, Flatten,Dense
model = Sequential()
#卷积层
model.add(Conv2D(32,(3,3), input_shape=(50,50,3), activation='relu'))
#池化层
model.add(MaxPool2D(pool_size=(2,2)))
#卷积层
model.add(Conv2D(32,(3,3), activation='relu'))
#池化层
model.add(MaxPool2D(pool_size=(2,2)))
#Flatten
model.add(Flatten())
#全连接层
model.add(Dense(units=128, activation='relu'))
#输出层
model.add(Dense(units=1, activation='sigmoid'))

首先导入 keras中的Sequential , 可以理解为这是一个空的模型结构,需要我们向其中添加卷积层Conv2D, 池化层MaxPool2D, Flatten层Flatten, 全连接层Dense
接下来我们来分析代码:
model = Sequential() 初始化模型,这没什么好说的
model.add(Conv2D(32,(3,3), input_shape=(50,50,3), activation=‘relu’))
这是第一层卷积层,Conv2D()
表示添加一个卷积层到模型中。参数表示:32个33的卷积层,input_shape表示输入数据的维度,由于在之前我们已经把载入的数据集尺寸设置成了5050,所以这里的参数表示输入维度为50503的数据,3表示图片是彩色的,具有RGB三个维度,activation使用relu参数
model.add(MaxPool2D(pool_size=(2,2)))
这是第一个池化层,也是模型的第二层,MaxPool2D()表示为最大值的池化层
pool_size参数表示 池化层是一个2*2的尺寸
model.add(Conv2D(32,(3,3), activation=‘relu’))
model.add(MaxPool2D(pool_size=(2,2)))

这两行代码表示如上图,这个模型是具有两层卷积层和池化层的,所以我们再添加一遍,因为不是第一层,所以不需要input_shape参数

3.CNN神经网络模型其他参数设置

model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.summary()

接下来我们来分析代码:

model.compile(optimizer=‘adam’, loss=‘binary_crossentropy’, metrics=[‘accuracy’])

compile是每一个模型都需要设置参数

optimizer=‘adam’ 表示使用adam的优化器

loss=‘binary_crossentropy’ 表示损失参数使用二分类的损失函数,binary_crossentropy

metrics=[‘accuracy’] 的功能是 每次训练后使用准确率进行评估并打印出来,用于直观的观察模型运行情况

model.summary()

在一条代码可以打印出模型的结构,如图:

基于cnn猫狗主要工作原理的研究论文_人工智能_02

4.训练模型

model.fit_generator(training_set, epochs=25)

接下来我们来分析代码:

model.fit_generator(training_set, epochs=25)

由于数据集图片是使用的ImageDataGenerator生成的,所以再训练的时候需要使用fit_generator(),而不是fit()

第一个参数表示加载进来数据集

epochs=25表示整个模型一共训练25层

训练过程如图:

基于cnn猫狗主要工作原理的研究论文_基于cnn猫狗主要工作原理的研究论文_03

3.计算准确率

accuracy_train = model.evaluate_generator(training_set)
print(accuracy_train)

接下来我们来分析代码:

accuracy_train = model.evaluate_generator(test_set)

采用同样的方式,载入训练数据集test_set,直接放到evaluate_generator()中,便可以自动计算准确率

基于cnn猫狗主要工作原理的研究论文_基于cnn猫狗主要工作原理的研究论文_04


如图,我们可以看到在测试数据集上,准确率只有76%,但是看上图,训练数据集的准确率达到了1 所以这是一个过拟合模型,我们可以通过调整模型的训练次数解决这个问题

4.使用网上随便找的图片来测试模型

from keras.preprocessing.image import load_img, img_to_array
pic_cat_test = 'cat_test.jpg'
pic_cat_test = load_img(pic_cat_test, target_size=(50,50))
pic_cat_test = img_to_array(pic_cat_test)
pic_cat_test = pic_cat_test/255
pic_cat_test = pic_cat_test.reshape(1,50,50,3)
#调用模型
result = model.predict_classes(pic_cat_test)
print(result)

pic_dog_test = 'dog_test.jpg'
pic_dog_test = load_img(pic_dog_test, target_size=(50,50))
pic_dog_test = img_to_array(pic_dog_test)
pic_dog_test = pic_dog_test/255
pic_dog_test = pic_dog_test.reshape(1,50,50,3)
#调用模型
result = model.predict_classes(pic_dog_test)
print(result)

接下来我们来分析代码:

from keras.preprocessing.image import load_img, img_to_array

与上面一次性加载全部图片数据不同,这里由于是使用网上下载的单张图片进行测试,所以使用load_img, img_to_array

pic_cat_test = 'cat_test.jpg’

首先还是设置好图片的路径和名字

pic_cat_test = load_img(pic_cat_test, target_size=(50,50))

使用load_img()进行图片加载,第一个参数将刚才设置好的路径放进来,target_size()和训练时一样,设置成50*50的图片尺寸

pic_cat_test = pic_cat_test/255

别忘了我们对训练图片进行了归一化处理,所以再输入模型前,我们也需要将这张图片进行归一化

pic_cat_test = pic_cat_test.reshape(1,50,50,3)

由于这是一次只加载一张图片,所以我们需要手动给图片添加一个用于计算的维度

result = model.predict_classes(pic_cat_test)

调用我们训练好的模型对单张图片进行载入

返回值为0,1 根据数据集可知,0表示猫,1表示够

运行上面的代码

如图:

基于cnn猫狗主要工作原理的研究论文_人工智能_05


第一个是猫,第二个是狗。正如我们调用的顺序一样

5.遇到的问题解决

在模型训练代码执行时,我们可能会遇到

could not import PIL.Image. 的错误
这是需要使用
pip install pillow
下载pillow包,并且在训练数据代码前添加
from IPython.display import display
 from PIL import Image

最后重启环境就可以解决问题