小白教程:卷积神经网络之GoogLeNet原理+Tensorflow2.0实现图片分类

简介:近些天重新学习梳理了一遍卷积神经网络部分的知识,因此写博客总结一下,方便自己以后翻阅,也希望能够帮助到一些同学。第一次写博客,如果内容有不当之处,希望大家能够指正、交流。

科普:近几年来,人工智能,机器学习,深度学习,神经网络这几个词常常出现在我们耳边,它们也不断发展,被应用在生活中的方方面面。举个例子,比如我们手机的人脸识别,刷脸解锁,这就属于人工智能方面的应用。除此之外,还有文字识别,短视频与广告推荐等等。

想知道人工智能、机器学习、深度学习、神经网络的区别及各自的含义可以自行百度,或者点一下这个链接。

本文主要介绍经典的图片分类网络:GoogleNet网络,及基于Tensorflow2.0的实现。

神经网络是模仿人脑中的神经元而搭建出来的一种网络,准确地说应该是一种复杂的函数,通常我们给这个网络输入一组数据,经过网络得到输出数据。简单地说,就是下面的这个数学公式:Y=F(X)。这里的X是输入数据,与数学公式相比,X不仅仅是一个数字了,也可以是一个图片、一句话等等。F呢,就是我们的网络函数,不过更加复杂,大型的网络有亿万个参数。Y就是网络的输出。

神经网络的示意图如下,其中的小圆圈就是神经元,神经元之间的每一条连线都相当于一个函数,函数中的参数是可以训练的。
神经网络
我们通过给搭建出来的网络输入大量的数据X(图片),数据X中的每个样本都带有一个标签y(真实类别),通过网络输出Y(预测类别),这里的Y是网络对于X的预测值,通过一种评判标准与真实的y相比,来判断预测输出Y的好坏,再通过优化算法去修改网络中的参数,这个过程就是网络的训练过程,包括前向传播(预测)与反向传播(更新参数)。训练好网络之后,就可以利用它实现一些功能。

一、原理知识

卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络,是深度学习的代表算法之一。卷积神经网络的研究始于二十世纪80至90年代,卷积神经网络仿造生物的视知觉机制构建,其优点在网络的输入是图像时表现的更为明显,使得图像可以直接作为网络的输入,避免了传统识别算法中复杂的特征提取和数据重建的过程,如网络能够自行抽取图像的特征包括颜色、纹理、形状,深度神经网络的基本思想是通过构建多层网络,对目标进行多层表示,通过多层的高层次特征来表示数据的抽象语义信息,获得更好的特征鲁棒性。一句话,卷积神经网络就是提取图像的特征!

详细了解可以看一下这个链接:卷积神经网络原理

卷积运算

说到卷积网络就不得不提卷积运算,这里的卷积运算与数学中的卷积不同。对图片进行表示时,一副灰度图片可以看作一个一层的矩阵,其中每个元素取值范围为0到255,0为黑色,255为白色(彩色RBG图像是三通道的图片,为3层)。借用一张图对卷积运算进行解释:
卷积运算
以上图为例:

原始图像为一层5x5的矩阵,中间的一层3x3的矩阵就是我们的卷积核,最后得到的就是经过卷积之后提取到的特征图。(这个得到的特征图可以作为新的输入,再次进行卷积操作)

卷积核的每个元素都对应一个权重系数w和一个偏差量b。卷积核在工作时,在原始图像(特征)的左上角开始,向右滑动扫过原始图像,扫至最右侧,再向下移动一个步长,从左向右滑动…在感受野(卷积核所能覆盖的范围)内对输入特征做矩阵元素乘法求和并叠加偏差量,就得到特征图上对应的元素。卷积运算需要对卷积核进行设置。

首先是卷积核的边长,一般设置为正方形,但也可以设置为长方形,边长越大提取的是原图像中面积越大的特征,比如对于人脸来说,提取嘴巴特征的卷积核要比瞳孔特征的大。接着是卷积运算的步长(stride),也就是卷积核在图像上每一步移动的距离,stride为1,则每步移动一个元素的距离。此外,还有一个**填充属性(padding)**的设置,如果不对图像进行填充就进行卷积操作,卷积之后的特征图的大小会变小,如果想要经过卷积操作后还能保持和原来一样的大小,则需要设置padding为"same",不进行填充操作为"valid"。

激活函数

在神经网络里,激活函数的作用是增强网络的非线性表达能力,从而能够进行更复杂的特征表示,因为激活函数都是非线性函数,现在经常用的有Relu函数等。激活函数详解

损失函数

开头说利用神经网络对图片进行分类,需要通过一个判别标准来衡量分类结果的好坏,这里的判别标标准就是损失函数,分类问题中常用的损失函数是交叉熵函数。关于交叉熵函数,下面这个链接比较详细。交叉熵函数详解此外,还可以在损失函数中加入正则项:正则项与损失函数。

优化算法

通过前向传播,我们可以获得对一个输入图片的预测结果,接下来就可以通过优化算法对网络模型的参数进行更新,也就是反向传播。详细链接:优化算法详解

二、GoogleNet网络

GoogleNet是谷歌提出来的一个网络模型,其中提出来了一个叫做inception的网络模块。那为什么提出这样一个模块,它的作用是什么呢?

一个网络网络越宽、越深,其表示复杂特征的能力越强,但是参数会不可避免地增大,inception模块就是在保证网络规模更大的同时,使参数规模减小,提高计算效率

卷积的作用是为了提取特征,为了能提取出不同的特征,可以利用不同的卷积核去与原图像进行卷积运算,也就是增加网络的宽度。inception模块如下所示:
inception
可以看到,inception模块中采用了多个卷积核提取特征,最后将特征图连接在一起,包括一个1x1卷积、一个3x3卷积、一个5x5卷积,还有一个3x3的最大池化层(池化层与卷积层类似,但不是卷积操作,而是取感受野下的最大值)。

网络变宽了,但是怎么减少参数量呢?在此基础上,inception模块又加入了1x1的卷积运算。1x1卷积的作用
加入1x1卷积后的inception
在第二、三、四分支分别加入了1x1卷积进行降维,比如输入为深度为100(通道数为100)的特征,希望得到输出特征图的深度也为100。如果直接用3x3卷积核去卷积,需要3x3x100x100个参数量,用50个1x1卷积核去卷积,得到的特征图深度为50,然后再用3x3的卷积核去卷积,需要的参数量为1x1x100x50+3x3x50x100个,可以看到参数量明显减小。这就是inception模块的原理和作用。

GoogleNet的整体框图及参数设置可以从论文原文中获得:论文地址,这里贴出来,整体框图如下。

在这里插入图片描述
首先要确定输入图片的大小,输入图片大小为224x224,如果不是这么大,请对输入图片进行预处理,reshape为224x224。

从输入到输出,前几层网络并没有用inception模块,只是卷积与池化层相连,LocalRespNorm是一种归一化方法,但现在用的并不多,可以用批量归一化(BN方法详解链接)来代替,后面一共连接了9个inception模块。最终进行平均池化,并将其拉平,传入最终的全连接层(最终的全连接层个数为图片的类别个数),为了防止过拟合,中间还要加入dropout层(dropout详解链接)。最终经过softmax函数,输出该图像的类别预测结果。

可以看到网络的中间部分引出来了两个softmax分类器作为辅助分类器,它们的作用是为了让网络加速收敛(缓解梯度消失,在反向传播的过程中也能训练到前面几层的参数)。在训练过程,辅助分类器的loss乘以0.3加到主干网络的loss上,作为总的loss。训练完之后,利用模型去推理,辅助分类器就不会产生作用。(但听有的博主说好像效果不是很大,也可以不加辅助分类器)

网络结构的介绍到此结束,下面上手操作。

三、GoogleNet实现图片分类

环境不再多说,为tensorflow2.0,在pycharm上编程实现。

本文代码参考的github链接,侵权必删

首先新建文件夹,在文件夹中放入训练数据集和测试数据集。我是在桌面上的AI文件夹里新建了文件夹GoogleNet,然后将训练集train与测试集val放入其中。

按照GoogleNet的结构和参数搭建网络模型,在GoogleNet下新建文件model.py:

from tensorflow.keras import layers, models, Model, Sequential

def GoogLeNet(im_height=224, im_width=224, class_num=2, aux_logits=False):
    # 输入224*224的3通道彩色图片
    input_image = layers.Input(shape=(im_height, im_width, 3), dtype="float32")
    x = layers.Conv2D(64, kernel_size=7, strides=2, padding="SAME", activation="relu", name="conv2d_1")(input_image)
    x = layers.MaxPool2D(pool_size=3, strides=2, padding="SAME", name="maxpool_1")(x)
    x = layers.Conv2D(64, kernel_size=1, activation="relu", name="conv2d_2")(x)
    x = layers.Conv2D(192, kernel_size=3, padding=
  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
TensorFlow 2.0中,可以使用`kernel_regularizer`来实现L2正则化。2正则化是一种通过惩罚较大的权重值来减少过拟合的技术。在代码中,可以使用`regularizers.l1_l2`函数来指定L2正则化的参数。例如,下面的代码展示了如何在TensorFlow 2.0中使用L2正则化: ``` from tensorflow.keras import layers from tensorflow.keras import regularizers layer = layers.Dense(units=64, kernel_regularizer=regularizers.l1_l2(l1=1e-5, l2=1e-4)) ``` 这里,`kernel_regularizer`参数接受一个`regularizers.l1_l2`对象,该对象的参数`l1`和`l2`分别代表L1正则化和L2正则化的权重。通过调整这些参数的值,可以控制正则化的强度。 值得一提的是,上述代码只展示了L2正则化的实现,并未给出L1正则化的代码。如果你想了解如何实现L1正则化,可以参考一些相关的教程或自行实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【小白学PyTorch】扩展之Tensorflow2.0 | 21 Keras的API详解(上)卷积、激活、初始化、正则...](https://blog.csdn.net/fengdu78/article/details/109020054)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [简洁明了的tensorflow2.0教程——正则化操作](https://blog.csdn.net/JohnLeeK/article/details/106335532)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值