经典神经网络——GoogLeNet模型论文详解及代码复现

 论文地址:[1409.4842] Going Deeper with Convolutions (arxiv.org)

一、GoogLeNet概述

创新点

       我认为,这篇文章最大的创新点是引入了一个名为Inception块的结构,能够增加神经网络模型大小的同时,减缓参数量的爆炸式增长,从而提升神经网络模型的表现。

准确率

       一个简单的网络,是无法达到很好的表现,因为它的参数简单,表达的信息很少。所以我们想要一个表现很好的网络模型,我们就需要将这个网络变宽、变深。对应到网络模型中就是增加网络的层数(变深),增加通道数(变宽)。

问题

       有过基础知识的我们都知道,增加网络的层数和通道数,这件事会让模型的参数增加,会需要占用很多的算力,我们有可能算不动;而且参数多了,容易过拟合。

       所以我们需要一个能够代替堆叠卷积层,既可以让网络变宽变深的同时,又能够让参数爆炸式增长的东西。

解决方法

       本文提出了一个名为Inception的模块,如图2,可以实现在不改变图片尺寸的前提下,只改变输入输出的通道数,关键这个模块比使用较大的kernel的卷积核所带来的参数量更少,使用Inception模块就可以让网络变宽变深,从而提高模型的准确率。

二、GoogLeNet网络结构

GoogLeNet开始模块

 GoogLeNet架构

Inception Module基本组成结构有四个成分:1x1卷积,3x3卷积,5x5卷积,3x3最大池化,最后对四个成分运算结果进行通道上组合,这就是Naive Inception的核心思想:利用不同大小的卷积核实现不同尺度的感知,最后进行融合,可以得到图像更好的表征。

注意:每个分支得到的特征矩阵高和宽必须相同。

但是Naive Inception有两个非常严重的问题:首先,所有卷积层直接和前一层输入的数据对接,所以卷积层中的计算量会很大;其次,在这个单元中使用的最大池化层保留了输入数据的特征图的深度,所以在最后进行合并时,总的输出的特征图的深度只会增加,这样增加了该单元之后的网络结构的计算量。所以这里使用1x1 卷积核主要目的是进行压缩降维,减少参数量,也就是上图b,从而让网络更深、更宽,更好的提取特征,这种思想也称为Pointwise Conv,简称PW。

三、GoogLeNet使用PyTorch框架实现

因需要对GPU显存要求过高,本人在kaggle上的GPU T4X2上运行的

kaggle地址:GoogLeNet | Kaggle

import torch
from torch import nn
import sys
sys.path.append("../input/d2ld2l")
import d2l
from d2l.torch import load_data_fashion_mnist
from d2l.torch import train_ch6
from d2l.torch import try_gpu
class Inception(nn.Module):def __init__(self,in_channels,c1,c2,c3,c4,**kwarqs):super(Inception,self).__init__(**kwarqs)self.p1 = nn.Sequential(nn.Conv2d(in_channels,c1,kernel_size=1),nn.ReLU())self.p2 = nn.Sequential(nn.Conv2d(in_channels,c2[0],kernel_size=1),nn.ReLU(),nn.Conv2d(c2[0],c2[1],kernel_size=3,padding=1),nn.ReLU())self.p3 = nn.Sequential(nn.Conv2d(in_channels,c3[0],kernel_size=1),nn.ReLU(),nn.Conv2d(c3[0],c3[1],kernel_size=5,padding=2),nn.ReLU())self.p4 = nn.Sequential(nn.MaxPool2d(kernel_size=3,padding=1,stride=1),nn.Conv2d(in_channels,c4,kernel_size=1),nn.ReLU())def forward(self,x):return torch.cat((self.p1(x),self.p2(x),self.p3(x),self.p4(x)),dim=1)
in_channels =1
b1 = nn.Sequential(nn.Conv2d(in_channels,64,kernel_size=7,stride=2,padding=3),nn.ReLU(),nn.MaxPool2d(kernel_size=3,stride=2,padding=1)
)
b2 = nn.Sequential(nn.Conv2d(64,64,kernel_size=1),nn.ReLU(),nn.Conv2d(64,192,kernel_size=3,padding=1),nn.ReLU(),nn.MaxPool2d(kernel_size=3,stride=2,padding=1)
)
b3 = nn.Sequential(Inception(192,64,(96,128),(16,32),32),Inception(256,128,(128,192),(32,96),64),nn.MaxPool2d(kernel_size=3,stride=2,padding=1)
)b4 = nn.Sequential(Inception(480,192,(96,208),(16,48),64),Inception(512,160,(112,224),(24,64),64),Inception(512,128,(128,256),(24,64),64),Inception(512,112,(144,288),(32,64),64),Inception(528,256,(160,320),(32,128),128),nn.MaxPool2d(kernel_size=3,stride=2,padding=1)
)b5 = nn.Sequential(Inception(832,256,(160,320),(32,128),128),Inception(832,384,(192,384),(48,128),128),nn.AdaptiveAvgPool2d((1,1)),nn.Dropout(p=0.4),nn.Flatten()
)
net = nn.Sequential(b1,b2,b3,b4,b5,nn.Linear(1024,10))
test = torch.rand((1,1,224,224))
for layer in net:test = layer(test)print(layer.__class__.__name__,'output shape:\t',test.shape)

lr,num_epochs,batch_size = 0.1,10,128
train_iter,test_iter = load_data_fashion_mnist(batch_size,resize=128)
train_ch6(net,train_iter,test_iter,num_epochs,lr,try_gpu())

四、GoogLeNet使用keras框架实现

1、导入库

import cv2 
import numpy as np 
import keras
import math
import keras.backend as K
import tensorflow as tf
from keras.datasets import cifar10
from keras.models import Model
from keras.layers import Conv2D, MaxPool2D,  \Dropout, Dense, Input, concatenate,      \GlobalAveragePooling2D, AveragePooling2D,\Flatten
from keras.datasets import cifar10 
from keras import backend as K
from keras.utils import to_categorical
from keras.optimizers import SGD
from keras.callbacks import LearningRateScheduler

2、准备数据集

num_classes = 10def load_cifar10_data(img_rows, img_cols):# Load cifar10 training and validation sets(X_train, Y_train), (X_valid, Y_valid) = cifar10.load_data()# Resize training imagesX_train = np.array([cv2.resize(img, (img_rows,img_cols)) for img in X_train[:,:,:,:]])X_valid = np.array([cv2.resize(img, (img_rows,img_cols)) for img in X_valid[:,:,:,:]])# Transform targets to keras compatible formatY_train = to_categorical(Y_train, num_classes)Y_valid = to_categorical(Y_valid, num_classes)X_train = X_train.astype('float32')X_valid = X_valid.astype('float32')# preprocess dataX_train = X_train / 255.0X_valid = X_valid / 255.0return X_train, Y_train, X_valid, Y_valid
X_train, y_train, X_test, y_test = load_cifar10_data(224, 224)

3、创建初始模块

def inception_module(x,filters_1x1,filters_3x3_reduce,filters_3x3,filters_5x5_reduce,filters_5x5,filters_pool_proj,name=None):conv_1x1 = Conv2D(filters_1x1, (1, 1), padding='same', activation='relu', kernel_initializer=kernel_init, bias_initializer=bias_init)(x)conv_3x3 = Conv2D(filters_3x3_reduce, (1, 1), padding='same', activation='relu', kernel_initializer=kernel_init, bias_initializer=bias_init)(x)conv_3x3 = Conv2D(filters_3x3, (3, 3), padding='same', activation='relu', kernel_initializer=kernel_init, bias_initializer=bias_init)(conv_3x3)conv_5x5 = Conv2D(filters_5x5_reduce, (1, 1), padding='same', activation='relu', kernel_initializer=kernel_init, bias_initializer=bias_init)(x)conv_5x5 = Conv2D(filters_5x5, (5, 5), padding='same', activation='relu', kernel_initializer=kernel_init, bias_initializer=bias_init)(conv_5x5)pool_proj = MaxPool2D((3, 3), strides=(1, 1), padding='same')(x)pool_proj = Conv2D(filters_pool_proj, (1, 1), padding='same', activation='relu', kernel_initializer=kernel_init, bias_initializer=bias_init)(pool_proj)output = concatenate([conv_1x1, conv_3x3, conv_5x5, pool_proj], axis=3, name=name)return output

4.创建 GoogLeNet 架构

kernel_init = keras.initializers.glorot_uniform()
bias_init = keras.initializers.Constant(value=0.2)
input_layer = Input(shape=(224, 224, 3))x = Conv2D(64, (7, 7), padding='same', strides=(2, 2), activation='relu', name='conv_1_7x7/2', kernel_initializer=kernel_init, bias_initializer=bias_init)(input_layer)
x = MaxPool2D((3, 3), padding='same', strides=(2, 2), name='max_pool_1_3x3/2')(x)
# x = Conv2D(64, (1, 1) padding='same', strides=(1, 1), activation='relu', name='conv_2a_3x3/1')(x)
x = Conv2D(192, (3, 3), padding='same', strides=(1, 1), activation='relu', name='conv_2b_3x3/1')(x)
x = MaxPool2D((3, 3), padding='same', strides=(2, 2), name='max_pool_2_3x3/2')(x)x = inception_module(x,filters_1x1=64,filters_3x3_reduce=96,filters_3x3=128,filters_5x5_reduce=16,filters_5x5=32,filters_pool_proj=32,name='inception_3a')x = inception_module(x,filters_1x1=128,filters_3x3_reduce=128,filters_3x3=192,filters_5x5_reduce=32,filters_5x5=96,filters_pool_proj=64,name='inception_3b')x = MaxPool2D((3, 3), padding='same', strides=(2, 2), name='max_pool_3_3x3/2')(x)x = inception_module(x,filters_1x1=192,filters_3x3_reduce=96,filters_3x3=208,filters_5x5_reduce=16,filters_5x5=48,filters_pool_proj=64,name='inception_4a')classifier_1 = AveragePooling2D((5, 5), strides=3)(x)
classifier_1 = Conv2D(128, (1, 1), padding='same', activation='relu')(classifier_1)
classifier_1 = Flatten()(classifier_1)
classifier_1 = Dense(1024, activation='relu')(classifier_1)
classifier_1 = Dropout(0.7)(classifier_1)
classifier_1 = Dense(10, activation='softmax', name='auxilliary_output_1')(classifier_1)x = inception_module(x,filters_1x1=160,filters_3x3_reduce=112,filters_3x3=224,filters_5x5_reduce=24,filters_5x5=64,filters_pool_proj=64,name='inception_4b')x = inception_module(x,filters_1x1=128,filters_3x3_reduce=128,filters_3x3=256,filters_5x5_reduce=24,filters_5x5=64,filters_pool_proj=64,name='inception_4c')x = inception_module(x,filters_1x1=112,filters_3x3_reduce=144,filters_3x3=288,filters_5x5_reduce=32,filters_5x5=64,filters_pool_proj=64,name='inception_4d')classifier_2 = AveragePooling2D((5, 5), strides=3)(x)
classifier_2 = Conv2D(128, (1, 1), padding='same', activation='relu')(classifier_2)
classifier_2 = Flatten()(classifier_2)
classifier_2 = Dense(1024, activation='relu')(classifier_2)
classifier_2 = Dropout(0.7)(classifier_2)
classifier_2 = Dense(10, activation='softmax', name='auxilliary_output_2')(classifier_2)x = inception_module(x,filters_1x1=256,filters_3x3_reduce=160,filters_3x3=320,filters_5x5_reduce=32,filters_5x5=128,filters_pool_proj=128,name='inception_4e')x = MaxPool2D((3, 3), padding='same', strides=(2, 2), name='max_pool_4_3x3/2')(x)x = inception_module(x,filters_1x1=256,filters_3x3_reduce=160,filters_3x3=320,filters_5x5_reduce=32,filters_5x5=128,filters_pool_proj=128,name='inception_5a')x = inception_module(x,filters_1x1=384,filters_3x3_reduce=192,filters_3x3=384,filters_5x5_reduce=48,filters_5x5=128,filters_pool_proj=128,name='inception_5b')x = AveragePooling2D(pool_size=(7,7), strides=1, padding='valid',name='avg_pool_5_3x3/1')(x)x = Dropout(0.4)(x)
x = Dense(1000, activation='relu', name='linear')(x)
x = Dense(1000, activation='softmax', name='output')(x)

不带 1 类和 2 类过滤器的 GoogleNet 模型

model = Model(input_layer, [x], name='googlenet')
model.summary()

添加分类器 1 和 2 后的 GoogLeNet 模型

model_with_classifiers = Model(input_layer, [x, classifier_1, classifier_2], name='googlenet_complete_architecture')
model_with_classifiers.summary()

用三个模型编制网络

epochs = 25
initial_lrate = 0.01def decay(epoch, steps=100):initial_lrate = 0.01drop = 0.96epochs_drop = 8lrate = initial_lrate * math.pow(drop, math.floor((1+epoch)/epochs_drop))return lratesgd = SGD(lr=initial_lrate, momentum=0.9, nesterov=False)lr_sc = LearningRateScheduler(decay, verbose=1)model_with_classifiers.compile(loss=['categorical_crossentropy', 'categorical_crossentropy', 'categorical_crossentropy'], loss_weights=[1, 0.3, 0.3], optimizer=sgd, metrics=['accuracy'])history = model_with_classifiers.fit(X_train, [y_train, y_train, y_train], validation_data=(X_test, [y_test, y_test, y_test]), epochs=epochs, batch_size=256, callbacks=[lr_sc])

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/174428.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】图<简单认识图>

对于下面的内容,大家着重观察和理解图即可,可以直接绕过一些文字性的概念,对图有一个大概的认识。 图 简单认识图图的定义有向图和无向图完全图无向完全图有向完全图 图的基本存储结构邻接矩阵存储邻接矩阵的优点 网络的邻接矩阵邻接表无向图…

计算机视觉面试题-02

图像处理和计算机视觉基础 什么是图像滤波?有哪些常见的图像滤波器? 图像滤波是一种通过在图像上应用滤波器(卷积核)来改变图像外观或提取图像特征的图像处理技术。滤波器通常是一个小的矩阵,通过在图像上进行卷积…

pytorch安装GPU版本 (Cuda12.1)教程

使用本教程前,默认您已经安装并配置好了python3以上版本 1. 去官网下载匹配的Cuda Cuda下载地址 当前最高版本的Cuda是12.1 我安装的就是这个版本 小提示:自定义安装可以只选择安装Cuda Runtime。Nvidia全家桶不必全部安装。把全家桶全部安装完直接系统…

C#学习-8课时

P10 输入输出程序编写 相同类型的可以直接相加; cwtabtabconsole.Writeline(); using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace C_8_1 { class Program { s…

性能压测工具:wrk

一般我们压测的时候,需要了解衡量系统性能的一些参数指标,比如。 1、性能指标简介 1.1 延迟 简单易懂。green:一般指响应时间 95线:P95。平均100%的请求中95%已经响应的时间 99线:P99。平均100%的请求中99%已经响应的时间 平…

案例030:基于微信小程序的英语学习交流平台

文末获取源码 开发语言:Java 框架:SSM JDK版本:JDK1.8 数据库:mysql 5.7 开发软件:eclipse/myeclipse/idea Maven包:Maven3.5.4 小程序框架:uniapp 小程序开发软件:HBuilder X 小程序…

电子学会C/C++编程等级考试2021年12月(三级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:我家的门牌号 我家住在一条短胡同里,这条胡同的门牌号从1开始顺序编号。 若所有的门牌号之和减去我家门牌号的两倍,恰好等于n,求我家的门牌号及总共有多少家。 数据保证有唯一解。 时间限制:1000 内存限制:65536输入 一个…

CSGO搬砖如何选品?选品软件和教程靠谱吗?

说到CSGO搬砖项目,目前平台最火的就是CSGO游戏搬砖。在CSGO搬砖项目中,选品是至关重要的环节,直接影响到利润。而选品软件可以帮助我们更快地了解市场变化、计算成本利润等关键信息,提高选品的效率和准确性。可靠的选品软件还能够…

简易版王者荣耀

所有包和类 GameFrame类 package newKingOfHonor;import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.io.File; import java.util.ArrayList;im…

如何使用技术SEO来优化产品轮播

SEO(搜索引擎优化)对你来说并不陌生。现代电子商务系统通常包含旨在吸引谷歌等搜索引擎机器人注意的关键字。 但是,技术 SEO 在代码和服务器级别调查电子商务 SEO 策略。它改善了网站的技术因素,例如页面加载的速度以及抓取的直接…

【华为OD】统一考试B\C卷真题 100%通过:开源项目热榜 C/C++实现

目录 题目描述: 示例1 示例2 题目描述: 某个开源社区希望将最近热度比较高的开源项目出一个榜单,推荐给社区里面的开发者。对于每个开源项目,开发者可以进行关注(watch)、收藏(star)、fork、提issue、提交合并请求(MR)等。 数…

一觉睡到大天亮,dido P1S智能手环体验

智能穿戴设备对于有关注健康的朋友来说,是非常使用的工具,它们可以帮助我们实时监测一些健康数据,最近几年,国产的智能穿戴设备突飞猛进,大幅拉低了价格门槛,而且使用体验也很不错,现在我用的也…

Maven回顾

Maven 下载(前提要有jdk) Maven 下载地址:Maven – Download Apache Maven 设置 Maven 环境变量 添加环境变量 MAVEN_HOME: 右键 "计算机",选择 "属性",之后点击 "高级系统设置…

Python---练习:使用Python函数编写通讯录系统

预览通讯录系统最终效果 首先,进行需求分析,整个系统功能,分为6个板块,功能如下: ① 添加学员信息 ② 删除学员信息 ③ 修改学员信息 ④ 查询学员信息 ⑤ 遍历所有学员信息 ⑥ 退出系统 系统共6个功能&#xff…

Lighthouse(灯塔)—— Chrome浏览器强大的性能测试工具

本文浏览器版本参考如下: 一、认识Lighthouse Lighthouse 是 Google 开发的一款工具,用于分析网络应用和网页,收集现代性能指标并提供对开发人员最佳实践的意见。 为 Lighthouse 提供一个需要审查的网址,它将针对此页面运行一连…

TIME_WAIT状态套接字重新使用

《TIME_WAIT相关知识》里边有相关理论知识。 《TIME_WAIT状态TCP连接导致套接字无法重用实验》有相关实验。 现代Linux的TCP协议栈已经做了许多升级,所以可以让我们直接重用TIME_WAIT状态套接字而不会引起问题。下边是优化的内容: 1.新连接的SYN告知序列…

持续集成部署-k8s-配置与存储-存储类:动态创建NFS-PV案例

动态创建NFS-PV案例 1. 前置条件2. StorageClass 存储类的概念和使用3. RBAC 配置4. storageClass 配置5. 创建应用,测试 PVC 的自动配置6. 解决 PVC 为 Pending 状态问题7. 单独测试自动创建 PVC 1. 前置条件 这里使用 NFS 存储的方式,来演示动态创建 …

【JVM系列】- 穿插·对象的实例化与直接内存

对象的实例化与直接内存 😄生命不息,写作不止 🔥 继续踏上学习之路,学之分享笔记 👊 总有一天我也能像各位大佬一样 🌝分享学习心得,欢迎指正,大家一起学习成长! 文章目录…

域名邮箱与企业邮箱的区别:功能、应用与优势

根据使用者的不同需求,电子邮件分为域名邮箱和企业邮箱两种类型。那么这两种邮箱之间究竟存在哪些区别呢?本文将从定义、优势和劣势三个方面进行详细解析。 什么是域名邮箱? 域名邮箱,顾名思义是以域名作为后缀的电子邮箱。域名邮…

【UGUI】制作用户注册UI界面

这里面主要的操作思想就是 1.打组 同一个事情里面包含两个UI元素都应该打组便于管理和查找 2.设置锚点位置 每次创建一个UI都应该设置他的锚点以便于跟随画布控制自己的:相对位置 3. 设置尺寸(像素大小) 每一次UI元素哪怕是作为父物体的…