查看网站主机,网页制作免费模板,外贸销售模式,宜春seo网站推广文章目录 一、卷积神经网络的介绍1.1 什么是卷积神经网络1.2 重要层的说明1.3 应用领域二、 软件、环境配置2.1 安装Anaconda2.2 环境准备 三、猫狗分类示例3.1 图像数据预处理3.2 基准模型3.3 数据增强3.4 dropout层四、总结 一、卷积神经网络的介绍
1.1 什么是卷积神经网络 … 文章目录 一、卷积神经网络的介绍1.1 什么是卷积神经网络1.2 重要层的说明1.3 应用领域二、 软件、环境配置2.1 安装Anaconda2.2 环境准备 三、猫狗分类示例3.1 图像数据预处理3.2 基准模型3.3 数据增强3.4 dropout层四、总结 一、卷积神经网络的介绍
1.1 什么是卷积神经网络
卷积神经网络Convolutional Neural Networks, CNN是一类包含卷积计算且具有深度结构的前馈神经网络Feedforward Neural Networks是深度学习deep learning的代表算法之一。 顾名思义就是将卷积与前馈神经网络结合所衍生出来的一种深度学习算法。
卷积神经网络CNN的结构图
1.2 重要层的说明 上面图中是33的卷积核卷积核一般采用33和2*2 与上一层的结果输入层进行卷积的过程 ②池化层 最大池化它只是输出在区域中观察到的最大输入值 均值池化它只是输出在区域中观察到的平均输入值 两者最大区别在于卷积核的不同池化是一种特殊的卷积过程 ③全连接层 全连接过程跟神经网络一样就是每个神经元与上一层的所有神经元相连 输出层
卷积神经网络中输出层的上游通常是全连接层因此其结构和工作原理与传统前馈神经网络中的输出层相同。 对于图像分类问题输出层使用逻辑函数或归一化指数函数softmax function输出分类标签。 在物体识别object detection问题中输出层可设计为输出物体的中心坐标、大小和分类。 在图像语义分割中输出层直接输出每个像素的分类结果。
1.3 应用领域
计算机视觉 图像识别 物体识别 行为认知 姿态估计 神经风格迁移自然语言处理其它 物理学 遥感科学 大气科学 卷积神经网络在计算机视觉识别上的全过程如下图所示
二、 软件、环境配置
2.1 安装Anaconda
参考https://blog.csdn.net/ssj925319/article/details/114947425
2.2 环境准备
打开 cmd 命令终端创建虚拟环境。
conda create -n tf1 python3.6激活环境
activate
conda activate tf1安装 tensorflow、keras 库。在新建的虚拟环境 tf1 内使用以下命令安装两个库
pip install tensorflow1.14.0 -i “https://pypi.doubanio.com/simple/”
pip install keras2.2.5 -i “https://pypi.doubanio.com/simple/”
安装 nb_conda_kernels 包。
conda install nb_conda_kernels重新打开 Jupyter Notebooktf1环境下的。 点击【New】→【Python[tf1环境下的]】创建 python 文件。 三、猫狗分类示例
3.1 图像数据预处理
对猫狗图像进行分类代码如下
import os, shutil
# 原始目录所在的路径
original_dataset_dir E:\\Cat_And_Dog\\train\\# 数据集分类后的目录
base_dir E:\\Cat_And_Dog\\train1
os.mkdir(base_dir)# # 训练、验证、测试数据集的目录
train_dir os.path.join(base_dir, train)
os.mkdir(train_dir)
validation_dir os.path.join(base_dir, validation)
os.mkdir(validation_dir)
test_dir os.path.join(base_dir, test)
os.mkdir(test_dir)# 猫训练图片所在目录
train_cats_dir os.path.join(train_dir, cats)
os.mkdir(train_cats_dir)# 狗训练图片所在目录
train_dogs_dir os.path.join(train_dir, dogs)
os.mkdir(train_dogs_dir)# 猫验证图片所在目录
validation_cats_dir os.path.join(validation_dir, cats)
os.mkdir(validation_cats_dir)# 狗验证数据集所在目录
validation_dogs_dir os.path.join(validation_dir, dogs)
os.mkdir(validation_dogs_dir)# 猫测试数据集所在目录
test_cats_dir os.path.join(test_dir, cats)
os.mkdir(test_cats_dir)# 狗测试数据集所在目录
test_dogs_dir os.path.join(test_dir, dogs)
os.mkdir(test_dogs_dir)# 将前1000张猫图像复制到train_cats_dir
fnames [cat.{}.jpg.format(i) for i in range(1000)]
for fname in fnames:src os.path.join(original_dataset_dir, fname)dst os.path.join(train_cats_dir, fname)shutil.copyfile(src, dst)# 将下500张猫图像复制到validation_cats_dir
fnames [cat.{}.jpg.format(i) for i in range(1000, 1500)]
for fname in fnames:src os.path.join(original_dataset_dir, fname)dst os.path.join(validation_cats_dir, fname)shutil.copyfile(src, dst)# 将下500张猫图像复制到test_cats_dir
fnames [cat.{}.jpg.format(i) for i in range(1500, 2000)]
for fname in fnames:src os.path.join(original_dataset_dir, fname)dst os.path.join(test_cats_dir, fname)shutil.copyfile(src, dst)# 将前1000张狗图像复制到train_dogs_dir
fnames [dog.{}.jpg.format(i) for i in range(1000)]
for fname in fnames:src os.path.join(original_dataset_dir, fname)dst os.path.join(train_dogs_dir, fname)shutil.copyfile(src, dst)# 将下500张狗图像复制到validation_dogs_dir
fnames [dog.{}.jpg.format(i) for i in range(1000, 1500)]
for fname in fnames:src os.path.join(original_dataset_dir, fname)dst os.path.join(validation_dogs_dir, fname)shutil.copyfile(src, dst)# 将下500张狗图像复制到test_dogs_dir
fnames [dog.{}.jpg.format(i) for i in range(1500, 2000)]
for fname in fnames:src os.path.join(original_dataset_dir, fname)dst os.path.join(test_dogs_dir, fname)shutil.copyfile(src, dst)
分类后如下图所示
查看分类后对应目录下的图片数量
#输出数据集对应目录下图片数量
print(total training cat images:, len(os.listdir(train_cats_dir)))
print(total training dog images:, len(os.listdir(train_dogs_dir)))
print(total validation cat images:, len(os.listdir(validation_cats_dir)))
print(total validation dog images:, len(os.listdir(validation_dogs_dir)))
print(total test cat images:, len(os.listdir(test_cats_dir)))
print(total test dog images:, len(os.listdir(test_dogs_dir))) 猫狗训练图片各 1000 张验证图片各 500 张测试图片各 500 张。
3.2 基准模型
第①步构建网络模型
#网络模型构建
from keras import layers
from keras import models
#keras的序贯模型
model models.Sequential()
#卷积层卷积核是3*3激活函数relu
model.add(layers.Conv2D(32, (3, 3), activationrelu,input_shape(150, 150, 3)))
#最大池化层
model.add(layers.MaxPooling2D((2, 2)))
#卷积层卷积核2*2激活函数relu
model.add(layers.Conv2D(64, (3, 3), activationrelu))
#最大池化层
model.add(layers.MaxPooling2D((2, 2)))
#卷积层卷积核是3*3激活函数relu
model.add(layers.Conv2D(128, (3, 3), activationrelu))
#最大池化层
model.add(layers.MaxPooling2D((2, 2)))
#卷积层卷积核是3*3激活函数relu
model.add(layers.Conv2D(128, (3, 3), activationrelu))
#最大池化层
model.add(layers.MaxPooling2D((2, 2)))
#flatten层用于将多维的输入一维化用于卷积层和全连接层的过渡
model.add(layers.Flatten())
#全连接激活函数relu
model.add(layers.Dense(512, activationrelu))
#全连接激活函数sigmoid
model.add(layers.Dense(1, activationsigmoid))
查看模型各层的参数状况
#输出模型各层的参数状况
model.summary()结果如下 第②步配置优化器 loss计算损失这里用的是交叉熵损失 metrics列表包含评估模型在训练和测试时的性能的指标
from keras import optimizersmodel.compile(lossbinary_crossentropy,optimizeroptimizers.RMSprop(lr1e-4),metrics[acc])
第③步图片格式转化 所有图片2000张重设尺寸大小为 150x150 大小并使用 ImageDataGenerator 工具将本地图片 .jpg 格式转化成 RGB 像素网格再转化成浮点张量上传到网络上。
from keras.preprocessing.image import ImageDataGenerator# 所有图像将按1/255重新缩放
train_datagen ImageDataGenerator(rescale1./255)
test_datagen ImageDataGenerator(rescale1./255)train_generator train_datagen.flow_from_directory(# 这是目标目录train_dir,# 所有图像将调整为150x150target_size(150, 150),batch_size20,# 因为我们使用二元交叉熵损失我们需要二元标签class_modebinary)validation_generator test_datagen.flow_from_directory(validation_dir,target_size(150, 150),batch_size20,class_modebinary)
输出结果 查看上述图像预处理过程中生成器的输出
#查看上面对于图片预处理的处理结果
for data_batch, labels_batch in train_generator:print(data batch shape:, data_batch.shape)print(labels batch shape:, labels_batch.shape)break
如果出现错误ImportError: Could not import PIL.Image. The use of load_img requires PIL是因为没有安装 pillow 库导致的使用如下命令在 tf1 虚拟环境中安装
pip install pillow -i “https://pypi.doubanio.com/simple/”
安装完毕后关闭 Jupyter Notebook 重新打开重新运行一遍程序即可。 输出结果如下 第④步开始训练模型。
#模型训练过程
history model.fit_generator(train_generator,steps_per_epoch100,epochs30,validation_datavalidation_generator,validation_steps50)
电脑性能越好它训练得越快。 第⑤步保存模型。
#保存训练得到的的模型
model.save(G:\\Cat_And_Dog\\kaggle\\cats_and_dogs_small_1.h5)第⑥步结果可视化需要在 tf1 虚拟环境中安装 matplotlib 库命令pip install matplotlib -i “https://pypi.doubanio.com/simple/”。
#对于模型进行评估查看预测的准确性
import matplotlib.pyplot as pltacc history.history[acc]
val_acc history.history[val_acc]
loss history.history[loss]
val_loss history.history[val_loss]epochs range(len(acc))plt.plot(epochs, acc, bo, labelTraining acc)
plt.plot(epochs, val_acc, b, labelValidation acc)
plt.title(Training and validation accuracy)
plt.legend()plt.figure()plt.plot(epochs, loss, bo, labelTraining loss)
plt.plot(epochs, val_loss, b, labelValidation loss)
plt.title(Training and validation loss)
plt.legend()plt.show() 训练结果如上图所示很明显模型上来就过拟合了主要原因是数据不够或者说相对于数据量模型过复杂训练损失在第30个epoch就降为0了训练精度随着时间线性增长直到接近100%而我们的验证精度停留在70-72%。我们的验证损失在5个epoch后达到最小然后停止而训练损失继续线性下降直到接近0。 这里先解释下什么是过拟合 过拟合的定义 给定一个假设空间 H HH一个假设 h hh 属于 H HH如果存在其他的假设 h ’ h’h’ 属于 H HH使得在训练样例上 h hh 的错误率比 h ’ h’h’ 小但在整个实例分布上 h ’ h’h’ 比 h hh 的错误率小那么就说假设 h hh 过度拟合训练数据。 举个简单的例子( a )( b )过拟合( c )( d )不过拟合如下图所示
过拟合常见解决方法 1在神经网络模型中可使用权值衰减的方法即每次迭代过程中以某个小因子降低每个权值。 2选取合适的停止训练标准使对机器的训练在合适的程度 3保留验证数据集对训练成果进行验证 4获取额外数据进行交叉验证 5正则化即在进行目标函数或代价函数优化时在目标函数或代价函数后面加上一个正则项一般有L1正则与L2正则等。 不过接下来将使用一种新的方法专门针对计算机视觉在深度学习模型处理图像时几乎普遍使用——数据增强。
3.3 数据增强
数据集增强主要是为了减少网络的过拟合现象通过对训练图片进行变换可以得到泛化能力更强的网络更好的适应应用场景。
重新构建模型
上面建完的模型就保留着我们重新建一个 .ipynb 文件重新开始建模。 首先猫狗图像预处理只不过这里将分类好的数据集放在 train2 文件夹中其它的都一样。 然后配置网络模型、构建优化器然后进行数据增强代码如下 图像数据生成器增强数据
from keras.preprocessing.image import ImageDataGenerator
datagen ImageDataGenerator(rotation_range40,width_shift_range0.2,height_shift_range0.2,shear_range0.2,zoom_range0.2,horizontal_flipTrue,fill_modenearest)
查看数据增强后的效果
import matplotlib.pyplot as plt
# This is module with image preprocessing utilities
from keras.preprocessing import image
fnames [os.path.join(train_cats_dir, fname) for fname in os.listdir(train_cats_dir)]
# We pick one image to augment
img_path fnames[3]
# Read the image and resize it
img image.load_img(img_path, target_size(150, 150))
# Convert it to a Numpy array with shape (150, 150, 3)
x image.img_to_array(img)
# Reshape it to (1, 150, 150, 3)
x x.reshape((1,) x.shape)
# The .flow() command below generates batches of randomly transformed images.
# It will loop indefinitely, so we need to break the loop at some point!
i 0
for batch in datagen.flow(x, batch_size1):plt.figure(i)imgplot plt.imshow(image.array_to_img(batch[0]))i 1if i % 4 0:break
plt.show()
结果如下共4张这里只截取了三张 图片格式转化。
train_datagen ImageDataGenerator(rescale1./255,rotation_range40,width_shift_range0.2,height_shift_range0.2,shear_range0.2,zoom_range0.2,horizontal_flipTrue,)
# Note that the validation data should not be augmented!
test_datagen ImageDataGenerator(rescale1./255)
train_generator train_datagen.flow_from_directory(# This is the target directorytrain_dir,# All images will be resized to 150x150target_size(150, 150),batch_size32,# Since we use binary_crossentropy loss, we need binary labelsclass_modebinary)
validation_generator test_datagen.flow_from_directory(validation_dir,target_size(150, 150),batch_size32,class_modebinary)
开始训练并保存结果。
history model.fit_generator(train_generator,steps_per_epoch100,epochs100,validation_datavalidation_generator,validation_steps50)
model.save(E:\\Cat_And_Dog\\kaggle\\cats_and_dogs_small_2.h5)
训练结果如下 结果可视化
acc history.history[acc]
val_acc history.history[val_acc]
loss history.history[loss]
val_loss history.history[val_loss]
epochs range(len(acc))
plt.plot(epochs, acc, bo, labelTraining acc)
plt.plot(epochs, val_acc, b, labelValidation acc)
plt.title(Training and validation accuracy)
plt.legend()
plt.figure()
plt.plot(epochs, loss, bo, labelTraining loss)
plt.plot(epochs, val_loss, b, labelValidation loss)
plt.title(Training and validation loss)
plt.legend()
plt.show()
如下图所示 由于数据量的增加对比基准模型可以很明显的观察到曲线没有过度拟合了训练曲线紧密地跟踪验证曲线这也就是数据增强带来的影响但是可以发现它的波动幅度还是比较大的。 下面在此数据增强的基础上再增加一层 dropout 层再来训练看看。
3.4 dropout层
什么是dropout层
Dropout层在神经网络层当中是用来干嘛的呢它是一种可以用于减少神经网络过拟合的结构那么它具体是怎么实现的呢 假设下图是我们用来训练的原始神经网络 一共有四个输入 x i x_ix i 一个输出 y yy。Dropout 则是在每一个 batch 的训练当中随机减掉一些神经元而作为编程者我们可以设定每一层 dropout将神经元去除的的多少的概率在设定之后就可以得到第一个 batch 进行训练的结果 从上图我们可以看到一些神经元之间断开了连接因此它们被 dropout 了dropout顾名思义就是被拿掉的意思正因为我们在神经网络当中拿掉了一些神经元所以才叫做 dropout 层。
具体实现
在数据增强的基础上再添加一个 dropout 层。
#退出层
model.add(layers.Dropout(0.5))如下图所示仅在构建网络模型时添加一层即可其余部分不变 再次训练模型查看训练结果如下 相比于只使用数据增强的效果来看额外添加一层 dropout 层仔细对比可以发现训练曲线更加紧密地跟踪验证曲线波动的幅度也降低了些训练效果更棒了。
四、总结
使用卷积神经网络CNN实现猫狗分类是一种有效的方法它能够自动从图像中学习特征并进行分类提高准确性。
参考链接 https://blog.csdn.net/qq_43279579/article/details/117298169 https://blog.csdn.net/ssj925319/article/details/117787737 https://www.cnblogs.com/geeksongs/p/13446980.html