图像分类任务之GoogLeNet网络模型


前言

图像分类是计算机视觉中最基础的任务,学者对于分类任务的研究进程,基本上等价于深度学习模型的发展史。GoogLeNet是2014年ImageNet比赛的冠军模型,由谷歌工程师设计的网络结构,它在命名上致敬最早的卷积神经网路LeNet。主要特点:不仅有纵向的“深度”,还具有横向的“宽度”。


一、图像分类任务介绍

1.图像分类是什么?

图像分类,顾名思义,分析图像是哪一种类别。举个例子:以下图片你可以一眼看出来,是猫是狗?但计算机做不到这点,卷积运算就像一把钥匙打开了图像处理的大门,而深度学习的发展算是将其发扬光大。
有人提问:如果一只猫和一只狗在一张图片里,那该如何判定呢?这就不是一个简单的图像分类任务,而是更复杂的目标检测任务、图像分割任务、语义分割任务。以后慢慢道来~
在这里插入图片描述
数据集介绍

  • MNIST:MNIST数据集是计算机视觉和机器学习文献中最受研究的数据集之一,这个数据集的目标是正确的分类手写数字0-9,包含60000张训练图片和10000张测试图片。每张图片是784维的特征向量,即对应于图像的28x28的灰阶像素强度。
  • CIFAR10:CIFAR-10是在计算机视觉和机器学习文献中的另一个标准的基准数据集,一共有10个标签:airplane、automobile、bird、cat、deer、dog、frog、horse、ship、truck十个类别,包含60000张特征向量维数为3072的32x32x3(RGB)的图像。
  • ImageNet:自2010年以来,ImageNet项目每年举办一次软件比赛,即ImageNet大规模视觉识别挑战赛(ILSVRC),使用大概120万张图像用于训练,50000张用于验证,100000张用于测试,能够将图像分类到1000个不同的类别中。

2.图像分类如何实现?

图像分类网络结构是卷积层、池化层和全连接层的线性组合。这里借用LeNet网络模型对各层进行说明。

(1)卷积层

  • 通道(channel):使用滤波器的数量,彩色图片输入时通道数为3。输出通道为三个滤波器的参数共享。
  • 卷积核(kernel):一组固定权重的集合,如上图3x3x1。输出通道数等于卷积核个数。
  • 步长(stride):滑移滤波器的时候,平移的距离。步长越大,输出feature map的尺寸越小。
  • 填充(padding):输入数据边缘处填补特定元素,有效使用可以控制输出feature map的尺寸。

(2)池化层

  • 池化的目的是逐渐降低数据体的空间尺寸,从而减少网络中参数的数量,有效控制过拟合。
  • 两种池化操作:MaxPooling和AveragePooling

(3)全连接层

请移步上一遍博客全连接神经网络详解,全连接层的主要功能就是一个分类器,通常使用CrossEntropyLoss。
在这里插入图片描述

3.图像分类用来干什么?

  • 安防领域:人脸识别、行人检测、智能视频分析、行人跟踪等
  • 交通领域:交通场景物体识别、车辆计数、逆行检测、车牌检测与识别等
  • 互联网领域:基于内容的图像检索、相册自动归类等

二、GoogLeNet论文解读

1.挑战及创新工作

以下两张狗狗的照片,你可以区分它们的品种吗?若要提高网络模型的分类精度,最简单的两条途径:增大数据样本和扩大网络模型。GoogLeNet创新性工作便是提出了Inception模块,它允许增加网络的深度和宽度,同时保证调用的计算资源不变。
在这里插入图片描述

  • 挑战一:提高深度神经网络性能最直接的方法是增加它的大小,这包括网络的深度和宽度两个维度。模型规模越大,训练的参数更多,这就使得网络更容易过拟合。
  • 挑战二:高质量的数据集标注需要耗费大量的人力劳动,高效率的数据计算需要高性能的计算机资源,计算资源的有效分配比不加选择的增加大小更可取。

2.Inception模块介绍

图(a)是Inception模块的设计思想,使用3个不同大小的卷积核对输入图片进行卷积操作,并附加最大池化,将这4个操作的输出沿着通道这一维度进行拼接,构成的输出特征图将会包含经过不同大小的卷积核提取出来的特征,从而达到捕捉不同尺度信息的效果。Inception模块采用多通路(multi-path)的设计形式,每个支路使用不同大小的卷积核,最终输出特征图的通道数是每个支路输出通道数的总和,这将会导致输出通道数变得很大,尤其是使用多个Inception模块串联操作的时候,模型参数量会变得非常大。
图(b)中的设计方式可以减少参数量,在每个3x3和5x5的卷积层之前,增加1x1的卷积层来控制输出通道数;在最大池化层后面增加1x1卷积层减小输出通道数。基于这一设计思想,形成了上图所示的结构。

3.Python代码实现

# GoogLeNet模型代码
import numpy as np
import paddle
from paddle.nn import Conv2D, MaxPool2D, AdaptiveAvgPool2D, Linear
## 组网
import paddle.nn.functional as F

# 定义Inception块
class Inception(paddle.nn.Layer):
    def __init__(self, c0, c1, c2, c3, c4, **kwargs):
        '''
        Inception模块的实现代码,
        
        c1,图(b)中第一条支路1x1卷积的输出通道数,数据类型是整数
        c2,图(b)中第二条支路卷积的输出通道数,数据类型是tuple或list, 
               其中c2[0]是1x1卷积的输出通道数,c2[1]是3x3
        c3,图(b)中第三条支路卷积的输出通道数,数据类型是tuple或list, 
               其中c3[0]是1x1卷积的输出通道数,c3[1]是3x3
        c4,图(b)中第一条支路1x1卷积的输出通道数,数据类型是整数
        '''
        super(Inception, self).__init__()
        # 依次创建Inception块每条支路上使用到的操作
        self.p1_1 = Conv2D(in_channels=c0,out_channels=c1, kernel_size=1)
        self.p2_1 = Conv2D(in_channels=c0,out_channels=c2[0], kernel_size=1)
        self.p2_2 = Conv2D(in_channels=c2[0],out_channels=c2[1], kernel_size=3, padding=1)
        self.p3_1 = Conv2D(in_channels=c0,out_channels=c3[0], kernel_size=1)
        self.p3_2 = Conv2D(in_channels=c3[0],out_channels=c3[1], kernel_size=5, padding=2)
        self.p4_1 = MaxPool2D(kernel_size=3, stride=1, padding=1)
        self.p4_2 = Conv2D(in_channels=c0,out_channels=c4, kernel_size=1)

    def forward(self, x):
        # 支路1只包含一个1x1卷积
        p1 = F.relu(self.p1_1(x))
        # 支路2包含 1x1卷积 + 3x3卷积
        p2 = F.relu(self.p2_2(F.relu(self.p2_1(x))))
        # 支路3包含 1x1卷积 + 5x5卷积
        p3 = F.relu(self.p3_2(F.relu(self.p3_1(x))))
        # 支路4包含 最大池化和1x1卷积
        p4 = F.relu(self.p4_2(self.p4_1(x)))
        # 将每个支路的输出特征图拼接在一起作为最终的输出结果
        return paddle.concat([p1, p2, p3, p4], axis=1)

三、总结

Inception模块的提出,给深度学习重新拓展了一个维度,利用密集模块构造最优稀疏结构,是改进计算机神经网络的可行方法,相比较浅和较宽的网络,在计算需求增加的情况下获得显著的质量增益。需要注意的是,论文中构造的GoogLeNet一共有22层,而2015年提出的Resnet网络结构精度更高,网络层数达到101层,并且缓解了梯度消失和梯度爆炸的问题。所以,在选择backbone骨干的时候,普遍采用Resnet预训练的参数。

好的,下面是基于 GoogleNet 模型资源和参考代码的图像分类任务实现步骤: 1. 下载并安装 TensorFlow,可以参考官方文档进行安装:https://www.tensorflow.org/install。 2. 下载 GoogleNet 模型的代码和预训练好的权重参数,可以从 GitHub 上下载:https://github.com/tensorflow/models/tree/master/research/slim。 3. 准备要分类的图像数据集,可以使用公开的数据集,例如 ImageNet 数据集。 4. 对图像数据集进行预处理,将图像转换为模型所需的输入格式。GoogleNet 模型的输入大小为 224x224,输入格式为 RGB 三通道图像,像素值范围在 0~255 之间。可以使用 TensorFlow 中的预处理模块进行处理,例如: ```python from tensorflow.contrib import slim from tensorflow.contrib.slim.nets import inception from tensorflow.contrib.slim.preprocessing import inception_preprocessing image_size = inception.inception_v1.default_image_size preprocessed_image = inception_preprocessing.preprocess_image(raw_image, image_size, image_size, is_training=False) ``` 5. 加载预训练好的 GoogleNet 模型,可以使用 TensorFlow 中的 Saver 对象进行加载,例如: ```python saver = tf.train.Saver() saver.restore(sess, 'path/to/pretrained/model') ``` 6. 对输入图像进行预测,可以使用 TensorFlow 中的 Session 对象进行预测,例如: ```python logits = sess.run(model.logits, feed_dict={model.images: preprocessed_image}) predictions = np.argmax(logits, axis=1) ``` 7. 对预测结果进行后处理,例如将类别编号转换为类别名称,可以使用 ImageNet 数据集中的类别名称对应表进行转换,例如: ```python class_names = np.loadtxt('path/to/class/names', str, delimiter='\t') predicted_class_name = class_names[predictions[0]] ``` 8. 最后得到的 predicted_class_name 即为预测结果,表示输入图像所属的类别。 以上就是基于 GoogleNet 模型资源和参考代码的图像分类任务实现步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值