上一篇文章:【深度学习】CNN卷积神经网络-识别阿喵阿汪(上)
在看这篇文章之前,请先阅读上一篇文章,以方便了解大体原理
上篇已经大体介绍了CNN的大体原理、结构
本篇文章是识别 猫,狗 代码的实战!
看一下我们的数据集,全都是图片哈
training_set中的cats、dogs都包含4000图片
test_set中的两个文件夹各包含1000张图片
图片的提取码
链接:https://pan.baidu.com/s/1_oHr2XDr3jilsC8ATe-vgA
提取码:uug3
============================================================================
1.初始化CNN
classifier = Sequential()
Step 1 - 添加卷积层
classifier.add(Convolution2D(32, 3, 3, input_shape = (64, 64, 3), activation = 'relu'))
- filters 特征探测器的个数 一般是64 /32 过大的话 运算时间会非常长
- kernel_size 特征探测器的大小 3*3
- activation 激活函数 线性整流函数 relu
- 这是添加的第一个卷积层 要写清楚输入图像的大小 input_shape() 64*64 像素大小 3的意思是彩色图片
Step 2 - 最大池化
classifier.add(MaxPooling2D(pool_size = (2, 2)))
- 可以做到降维 降维之后进而扁平化
- 虽然丢失了一些信息 但是不会太影响性能
- pool_size 最大池化的矩阵大小 2*2最常用
- 提高性能
============================================================================
这是只有一层卷积层时,训练结果并不理想时做出的改进代码
添加第二个卷积层
classifier.add(Convolution2D(32, 3, 3, activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
Step 3 - Flattening
扁平化之后 形成的超级大的一列多行矩阵 包括所有的小的一维矩阵
classifier.add(Flatten())
Step 4 - Full connection
units 隐藏层神经元个数 输入层(前一步的扁瓶层) 与 输出层(这里是1)神经元的个数的平均数
一般为2的次方 隐藏层激活函数activation 线性整流
输出层 两个类别 输出一个类别就行 units=1 输出的是概率 所以用sigmoid
classifier.add(Dense(units= 128, activation = 'relu'))
classifier.add(Dense(units = 1, activation = 'sigmoid'))
Compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
-
optimizer 优化器 进行优化的算法 adam 更加先进的随机梯度下降
-
loss 损失函数,分成两类binary_crossenttopy 三类的话 categorical_crossenttopy
-
metrics 模型性能的评估器 accuracy准确度
keras的中文文档中查看图片预处理的代码
直接借鉴里面的代码
图像预处理 8000张图片是远远不够的,要扩大训练集 可以有效地防止过度拟合
最简单的方法就是多爬一些图片,我们这种方法就是扩大或者缩小图片,改变了矩阵对应的数字,但同时图片性质不变
train_datagen = ImageDataGenerator(rescale = 1./255,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True)
- rescale 缩放 1./255 直接将像素值当成数值 像素值的 0~255 转换成 0~1
- 直接输入像素值会影响性能,所以进行缩放处理
- shear_range cuo qi 变换 所有的都朝向一个方向
- zoom_range 放大或者缩小 整个图片的
- horizontal_flip 水平的翻转
============================================================================
test_datagen = ImageDataGenerator(rescale = 1./255)
- 创建好的两个对象
============================================================================
对应的训练集
training_set = train_datagen.flow_from_directory('dataset/training_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'binary')
- target_size input_size 输入图片的大小应该是一致的
- batch_size 图像生成器形成 新的图像时的数目
- class_mode 生成的类别 两个
对应测试集
test_set = test_datagen.flow_from_directory('dataset/test_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'binary')
==============================================================================
classifier.fit_generator(training_set,
samples_per_epoch = 250,
nb_epoch = 25,
validation_data = test_set,
validation_steps = 62.5)
拟合模型
- 用到的数据是生成器生成的 一批一批的生成
- training_set 用来拟合的数据
- samples_per_epoch 有多少步,用来拟合的数据的数目/batch的数目 就是8000/32=250
- epochs=25 训练的批数
- validation_data = test_set 测试集
- validation_steps 与 samples_per_epoch类似,对应测试集 2000/32=62.5
============================================================================
训练的结果将近80%,效果并不是很理想,那么我们添加第二个卷积层,结果最后的训练结果预测集是87.23%,测试集的结果是82.15%
我们的这个实战呢,由于图片数量远远不够,大家也知道,一般在学校内做的图像识别项目,数据集小则几百G,大则几十T,训练的时间也会很长,我们这个项目的训练集很少很少,用的时间也只有一个小时左右,结果肯定达不到好的层次,仅仅用来练手,入门。更好的实战还有待你们的发现。