基于keras的CNN图片分类模型的搭建以及参数调试

基于keras的CNN图片分类模型的搭建与调参


更新一下这篇博客,因为最近在CNN调参方面取得了一些进展,顺便做一下总结。


我的项目目标是搭建一个可以分五类的卷积神经网络,然后我找了一些资料看了一些博客,发现keras搭建CNN,还是比较简单快捷的,模块化,易扩展,极简,让我最终选择了keras。本质上keras相对于python,就相当于python相对于c/c++。就是一个封装的一个关系。

然后讲讲我的模型吧。我的模型是由两层卷积层,两层池化层,两层全连接层组成。这个结构 应该算是最简单的卷积神经网络了。可调的参数也并不多。整个分类系统代码组成也很简单,主要就三部分,一个是数据读取处理部分,一个是模型训练部分,一个是模型测试部分。我分类的数据集是通过热成像仪拍摄得到的热成像图,然后经过简单处理之后得到的灰度图。原本这个模型是一个人脸识别系统,把其中摄像头拍摄部分去掉了。只保留图像分类部分的代码,就做成了我的系统了。基本思想还是很简单的。

但是在接触了代码之后,还是发现了很多坑。经过掉坑,爬坑的洗礼之后,写下这篇博客,记载下一些有价值的知识。

1. 数据读取

这里写图片描述

这部分代码开始我就没读懂 ,reshape函数不是将图片的大小改变的嘛?咋改成了四维的?
查了好多博客,都没说出个所以然。后来我想起手上还有三本TensorFlow的电子书,通过书终于发现了问题所在。
这里写图片描述
这段代码(来自《TensorFlow技术解析与实战》)表示keras分别以theano和TensorFlow为backend实现图像大小重置与存取的区别。同时我还明白了这个代码里面各个参数代表的意思。就比如TensorFlow的吧。

x_test=x_test.reshape(x_test.shape[0],img_rows,img_cols,1)

这个x_test.shape[0]表示总共有多少个照片,因为当时读进照片数据的时候,照片都被放在了list里面了,然后他的大小就是整个list就是照片的数目。然后img_rows,img_cols就是每张照片的大小。
.

2. 调参数

由于优化器和批归一化,对最终的结果产生了很大的影响,我将在下面的内容详细地解释一下这两者的优化原理。


要将一个模型的性能达到一个比较高的水准,必定需要调节相关的参数。作为一名小白。一开始我是一脸闷逼的。不知道该调哪些参数,不知道应该调到多大的数值才算合适。虽然现在的分类准确率还是没达到一个令人满意的程度,但是相较于开始已经提升了很多。先记下来一些吧。
我主要调整了两个部分。

  • (一)输入图像的大小。这个是我在数据读取部分改的。我将读入的图片长宽调整的更加接近。
  • (二)增加了dropout函数,dropout函数说白了就是在训练时将部分神经元暂停工作,提升模型的抗过拟合能力。我在每一层都加入了dropout函数,开始的两层都是比较小的概率(0.15),后面到了全连接层比较大(0.5)
  • (三)将模型的优化器由原来的Adagrad,改为adadelta。这一篇文章里面给出了比较详细的优化方法的总结:深度学习最全优化方法总结比较(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)这个地方,还有一个值得挖掘的地方就是模型的优化器,optimizor对最终结果影响原来这么大。我在代码中用到的优化器依次是Adagrad,adadelta,Adam,效果依次上升。

Adagrad:

Adagrad A d a g r a d 其 实 就 是 对 学 习 率 进 行 了 一 个 约 束 ,
nt=nt1+g2t n t = n t − 1 + g t 2
Δθt=ηnt+ϵgt Δ θ t = − η n t + ϵ ∗ g t
gt1tregularizer, Δθt=1tr=1(gr)2+ϵ,ϵ,0 Δ θ t = − 1 ∑ r = 1 t ( g r ) 2 + ϵ , ϵ , 用 来 保 证 分 母 非 0
特点:
前期 gtregularizer g t 较 小 的 时 候 , r e g u l a r i z e r 较 大 , 能 够 放 大 梯 度
前期 gtregularizer g t 较 大 的 时 候 , r e g u l a r i z e r 较 小 , 能 约 束 梯 度
适合处理稀疏梯度

Adadelta:

AdadeltaAdagradAdagradAdadelta A d a d e l t a 是 对 A d a g r a d 的 扩 展 , 最 初 的 方 案 依 然 是 对 学 习 率 进 行 自 适 应 的 约 束 , 但 是 进 行 了 计 算 上 的 简 化 。 A d a g r a d 会 累 加 之 前 所 有 梯 度 的 平 方 , 而 A d a d e l t a 只 累 加 固 定 大 小 的 项 , 并 且 不 直 接 存 储 这 些 项 , 仅 仅 是 近 似 计 算 对 应 的 平 均 值 。 即 :
nt=vnt1+(1v)g2t n t = v ∗ n t − 1 + ( 1 − v ) ∗ g t 2
Δθt=ηnt+ϵgt Δ θ t = − η n t + ϵ ∗ g t
此处 Adadelta A d a d e l t a 其 实 还 是 依 赖 于 全 局 学 习 率 的 , 但 是 经 过 近 似 牛 顿 迭 代 法 之 后 :
E|g2|t=ρE|g2|t1+(1ρ)g2t E | g 2 | t = ρ ∗ E | g 2 | t − 1 + ( 1 − ρ ) ∗ g t 2
Δxt=t1r=1ΔxrE|g2|t+ϵ Δ x t = − ∑ r = 1 t − 1 Δ x r E | g 2 | t + ϵ
EAdadelta 其 中 , E 代 表 期 望 , 可 以 看 出 A d a d e l t a 已 经 不 用 依 赖 于 全 局 学 习 率 了 。
特点:
训练初中期,加速效果不错,很快
训练后期,反复在局部最小值附近抖动

Adam:

Adam(AdaptiveMomentEstimation)RMSpropAdam使 A d a m ( A d a p t i v e M o m e n t E s t i m a t i o n ) 本 质 上 是 带 有 动 量 项 的 R M S p r o p , 它 利 用 梯 度 的 一 阶 矩 估 计 和 二 阶 矩 估 计 动 态 调 整 每 个 参 数 的 学 习 率 。 A d a m 的 优 点 是 经 过 偏 置 校 正 之 后 , 每 次 迭 代 学 习 率 都 有 一 个 确 定 的 范 围 , 使 得 参 数 比 较 平 稳 , 公 式 如 下 :
mt=μmt1+(1μ)gt m t = μ ∗ m t − 1 + ( 1 − μ ) ∗ g t
nt=vnt1+(1v)g2t n t = v ∗ n t − 1 + ( 1 − v ) ∗ g t 2
m^t=mt1μt m ^ t = m t 1 − μ t
n^t=nt1vt n ^ t = n t 1 − v t
Δθt=m^tn^t+ϵη Δ θ t = − m ^ t n ^ t + ϵ ∗ η
mt,ntE|gt|,E|g2t|m^t,n^tmt,nt 其 中 , m t , n t 分 别 是 对 梯 度 的 一 阶 矩 估 计 和 二 阶 矩 估 计 , 可 以 看 作 对 期 望 E | g t | , E | g t 2 | 的 估 计 ; m ^ t , n ^ t 是 对 m t , n t 的 校 正 , 这 样 可 以 近 似 为 对 期 望 的 无 偏 估 计 。
m^tn^t+ϵ 可 以 看 出 , 直 接 对 梯 度 的 矩 估 计 , 对 内 存 没 有 额 外 的 要 求 , 并 且 可 以 根 据 梯 度 进 行 动 态 调 整 , 而 − m ^ t n ^ t + ϵ 对 学 习 率 形 成 了 一 个 动 态 约 束 , 并 且 有 明 确 的 范 围 。
特点:
结合了 AdagradRMSprop A d a g r a d 善 于 处 理 稀 疏 梯 度 和 R M S p r o p 善 于 处 理 非 平 稳 目 标 的 特 点
对 内 存 要 求 比 较 小
为 不 同 参 数 计 算 不 同 的 自 适 应 学 习 率
适 用 于 大 多 数 非 凸 优 化 , 适 用 于 大 数 据 集 和 高 维 空 间


  • (四)Batch_normalization(批归一化处理)开始我没注意到有这个优化手段。后来看了些别人博客,于是我想着尝试一下这个BN,我在看的视频里面,也多次提及这个优化手段。但是在使用的时候,我就犯难了,到底应该把代码加在哪儿呢?各种百度不得其解,后来百度了一下终于明白了。CNN with BatchNormalization in Keras 94% 这个代码应用的也是keras实现的CNN,简洁明了,适合小白。

我在这再讲解一下批归一化的原理和作用。
批归一化也叫做批标准化,通俗来说就是对每一层神经网络进行标准化,输入数据进行标准化能让机器学习更加有效地学习。除此之外 batchnormalization b a t c h n o r m a l i z a t i o n 还能有效控制坏的参数初始化,比如说 Relu R e l u 这种激励函数最怕所有值都落在附属区间。


但是现在遇到的一个问题是训练的准确率还可以能够达到90%+,但是测试准确率只有70%+,因此下一步准备将这个过拟合问题解决。等我将各方面问题解决好,我就会将代码上传到我的GitHub上,供大家学习借鉴。

对了,这一篇知乎专栏是我看到写的比较好的调参博客《如何一步一步提高图像分类准确率?》-曹荣禹,推荐一下

写在最后关于CNN的学习,我开始了大约五六个月,当然这里面是有间断的,关于CNN的认识,现在好多还是停留在纸面上。没法真正完美地解决工程问题。还需要继续努力。以后有新技巧习得,再更!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值