J9inceptionv3

news2024/11/23 23:07:02
  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊# 前言

上周学习了inceptionv1网络,这周学习其改进版本inceptionv3

简介

Inception v3是谷歌研究团队提出的深度卷积神经网络架构,通过引入多尺度的Inception模块和辅助分类器等技术,有效解决了深度网络训练中的梯度消失和模型参数过多的问题。该网络利用不同大小的卷积核并行处理图像信息,结合Batch Normalization和全局平均池化等优化策略,以较少的参数实现了优异的图像分类和识别性能,成为了深度学习图像处理领域的重要里程碑之一。下面分别进行介绍

网络结构特点

1.用5x5卷积代替3x3卷积,如下图所示
在这里插入图片描述
在这里插入图片描述
2.将nxn卷积分解
在这里插入图片描述
如将3x3卷积分解为1x3和3x1,为了减少参数量和计算量
在这里插入图片描述

代码实现

import torch.nn as nn
import torch
from torchsummary import summary

class GoogLeNetV3(nn.Module):
    def __init__(self, num_classes=1000, aux_logits=True, init_weights=False):
        super(GoogLeNetV3, self).__init__()
        self.aux_logits = aux_logits
        # 3个3×3卷积替代7×7卷积
        self.conv1_1 = BasicConv2d(3, 32, kernel_size=3, stride=2)
        self.conv1_2 = BasicConv2d(32, 32, kernel_size=3, stride=1)
        self.conv1_3 = BasicConv2d(32, 64, kernel_size=3, stride=1, padding=1)
        # 池化层
        self.maxpool1 = nn.MaxPool2d(3, stride=2, ceil_mode=True)

        self.conv2 = BasicConv2d(64, 80, kernel_size=3)
        self.conv3 = BasicConv2d(80, 192, kernel_size=3, stride=2)
        self.conv4 = BasicConv2d(192, 192, kernel_size=3, padding=1)

        self.inception3a = InceptionV3A(192, 64, 48, 64, 64, 96, 32)
        self.inception3b = InceptionV3A(256, 64, 48, 64, 64, 96, 64)
        self.inception3c = InceptionV3A(288, 64, 48, 64, 64, 96, 64)

        self.inception4a = InceptionV3D(288, 0, 384, 384, 64, 96, 0)
        self.inception4b = InceptionV3B(768, 192, 128, 192, 128, 192, 192)
        self.inception4c = InceptionV3B(768, 192, 160, 192, 160, 192, 192)
        self.inception4d = InceptionV3B(768, 192, 160, 192, 160, 192, 192)
        self.inception4e = InceptionV3D(768, 0, 384, 384, 64, 128, 0)

        if self.aux_logits == True:
            self.aux = InceptionAux(in_channels=768, out_channels=num_classes)

        self.inception5a = InceptionV3C(1280, 320, 384, 384, 448, 384, 192)
        self.inception5b = InceptionV3C(2048, 320, 384, 384, 448, 384, 192)

        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        self.dropout = nn.Dropout(0.5)
        self.fc = nn.Linear(2048, num_classes)
        if init_weights:
            self._initialize_weights()

    def forward(self, x):
        # N x 3 x 299 x 299
        x = self.conv1_1(x)
        # N x 32 x 149 x 149
        x = self.conv1_2(x)
        # N x 32 x 147 x 147
        x = self.conv1_3(x)
        #  N x 32 x 147 x 147
        x = self.maxpool1(x)
        # N x 64 x 73 x 73
        x = self.conv2(x)
        # N x 80 x 71 x 71
        x = self.conv3(x)
        # N x 192 x 35 x 35
        x = self.conv4(x)
        # N x 192 x 35 x 35
        x = self.inception3a(x)
        # N x 256 x 35 x 35
        x = self.inception3b(x)
        # N x 288 x 35 x 35
        x = self.inception3c(x)
        # N x 288 x 35x 35
        x = self.inception4a(x)
        # N x 768 x 17 x 17
        x = self.inception4b(x)
        # N x 768 x 17 x 17
        x = self.inception4c(x)
        # N x 768 x 17 x 17
        x = self.inception4d(x)
        # N x 768 x 17 x 17
        if self.training and self.aux_logits:    # eval model lose this layer
            aux = self.aux(x)
        # N x 768 x 17 x 17
        x = self.inception4e(x)
        # N x 1280 x 8 x 8
        x = self.inception5a(x)
        # N x 2048 x 8 x 8
        x = self.inception5b(x)
        # N x 2048 x 7 x 7
        x = self.avgpool(x)
        # N x 2048 x 1 x 1
        x = torch.flatten(x, 1)
        # N x 1024
        x = self.dropout(x)
        x = self.fc(x)
        # N x 1000(num_classes)
        if self.training and self.aux_logits:  # 训练阶段使用
            return x, aux
        return x
    # 对模型的权重进行初始化操作
    def _initialize_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.Linear):
                nn.init.normal_(m.weight, 0, 0.01)
                nn.init.constant_(m.bias, 0)

# InceptionV3A:BasicConv2d+MaxPool2d
class InceptionV3A(nn.Module):
    def __init__(self, in_channels, ch1x1, ch3x3red, ch3x3, ch3x3redX2, ch3x3X2, pool_proj):
        super(InceptionV3A, self).__init__()
        # 1×1卷积
        self.branch1 = BasicConv2d(in_channels, ch1x1, kernel_size=1)
        # 1×1卷积+3×3卷积
        self.branch2 = nn.Sequential(
            BasicConv2d(in_channels, ch3x3red, kernel_size=1),
            BasicConv2d(ch3x3red, ch3x3, kernel_size=3, padding=1)   # 保证输出大小等于输入大小
        )
        # 1×1卷积++3×3卷积+3×3卷积
        self.branch3 = nn.Sequential(
            BasicConv2d(in_channels, ch3x3redX2, kernel_size=1),
            BasicConv2d(ch3x3redX2, ch3x3X2, kernel_size=3, padding=1),
            BasicConv2d(ch3x3X2, ch3x3X2, kernel_size=3, padding=1)         # 保证输出大小等于输入大小
        )
        # 3×3池化+1×1卷积
        self.branch4 = nn.Sequential(
            nn.MaxPool2d(kernel_size=3, stride=1, padding=1),
            BasicConv2d(in_channels, pool_proj, kernel_size=1)
        )
    def forward(self, x):
        branch1 = self.branch1(x)
        branch2 = self.branch2(x)
        branch3 = self.branch3(x)
        branch4 = self.branch4(x)
        # 拼接
        outputs = [branch1, branch2, branch3, branch4]
        return torch.cat(outputs, 1)

# InceptionV3B:BasicConv2d+MaxPool2d
class InceptionV3B(nn.Module):
    def __init__(self, in_channels, ch1x1, ch3x3red, ch3x3, ch3x3redX2, ch3x3X2, pool_proj):
        super(InceptionV3B, self).__init__()
        # 1×1卷积
        self.branch1 = BasicConv2d(in_channels, ch1x1, kernel_size=1)
        # 1×1卷积+1×3卷积+3×1卷积
        self.branch2 = nn.Sequential(
            BasicConv2d(in_channels, ch3x3red, kernel_size=1),
            BasicConv2d(ch3x3red, ch3x3, kernel_size=[1, 3], padding=[0, 1]),
            BasicConv2d(ch3x3, ch3x3, kernel_size=[3, 1], padding=[1, 0])   # 保证输出大小等于输入大小
        )
        # 1×1卷积+1×3卷积+3×1卷积+1×3卷积+3×1卷积
        self.branch3 = nn.Sequential(
            BasicConv2d(in_channels, ch3x3redX2, kernel_size=1),
            BasicConv2d(ch3x3redX2, ch3x3X2, kernel_size=[1, 3], padding=[0, 1]),
            BasicConv2d(ch3x3X2, ch3x3X2, kernel_size=[3, 1], padding=[1, 0]),
            BasicConv2d(ch3x3X2, ch3x3X2, kernel_size=[1, 3], padding=[0, 1]),
            BasicConv2d(ch3x3X2, ch3x3X2, kernel_size=[3, 1], padding=[1, 0])  # 保证输出大小等于输入大小
        )
        # 3×3池化+1×1卷积
        self.branch4 = nn.Sequential(
            nn.MaxPool2d(kernel_size=3, stride=1, padding=1),
            BasicConv2d(in_channels, pool_proj, kernel_size=1)
        )
    def forward(self, x):
        branch1 = self.branch1(x)
        branch2 = self.branch2(x)
        branch3 = self.branch3(x)
        branch4 = self.branch4(x)
        # 拼接
        outputs = [branch1, branch2, branch3, branch4]
        return torch.cat(outputs, 1)

# InceptionV3C:BasicConv2d+MaxPool2d
class InceptionV3C(nn.Module):
    def __init__(self, in_channels, ch1x1, ch3x3red, ch3x3, ch3x3redX2, ch3x3X2, pool_proj):
        super(InceptionV3C, self).__init__()
        # 1×1卷积
        self.branch1 = BasicConv2d(in_channels, ch1x1, kernel_size=1)
        # 1×1卷积+1×3卷积+3×1卷积
        self.branch2_0 = BasicConv2d(in_channels, ch3x3red, kernel_size=1)
        self.branch2_1 = BasicConv2d(ch3x3red, ch3x3, kernel_size=[1, 3], padding=[0, 1])
        self.branch2_2 = BasicConv2d(ch3x3red, ch3x3, kernel_size=[3, 1], padding=[1, 0])

        # 1×1卷积+3×3卷积+1×3卷积+3×1卷积
        self.branch3_0 = nn.Sequential(
            BasicConv2d(in_channels, ch3x3redX2, kernel_size=1),
            BasicConv2d(ch3x3redX2, ch3x3X2, kernel_size=3, padding=1),
        )
        self.branch3_1 = BasicConv2d(ch3x3X2, ch3x3X2, kernel_size=[1, 3], padding=[0, 1])
        self.branch3_2 = BasicConv2d(ch3x3X2, ch3x3X2, kernel_size=[3, 1], padding=[1, 0])

        # 3×3池化+1×1卷积
        self.branch4 = nn.Sequential(
            nn.MaxPool2d(kernel_size=3, stride=1, padding=1),
            BasicConv2d(in_channels, pool_proj, kernel_size=1)
        )
    def forward(self, x):
        branch1 = self.branch1(x)
        branch2_0 = self.branch2_0(x)
        branch2 = torch.cat([self.branch2_1(branch2_0), self.branch2_2(branch2_0)], dim=1)
        branch3_0 = self.branch3_0(x)
        branch3 = torch.cat([self.branch3_1(branch3_0), self.branch3_2(branch3_0)], dim=1)
        branch4 = self.branch4(x)
        # 拼接
        outputs = [branch1, branch2, branch3, branch4]
        return torch.cat(outputs, 1)

# InceptionV3D:BasicConv2d+MaxPool2d
class InceptionV3D(nn.Module):
    def __init__(self, in_channels, ch1x1, ch3x3red, ch3x3, ch3x3redX2, ch3x3X2, pool_proj):
        super(InceptionV3D, self).__init__()
        # ch1x1:没有1×1卷积
        # 1×1卷积+3×3卷积,步长为2
        self.branch1 = nn.Sequential(
            BasicConv2d(in_channels, ch3x3red, kernel_size=1),
            BasicConv2d(ch3x3red, ch3x3, kernel_size=3, stride=2)
        )
        # 1×1卷积+3×3卷积+3×3卷积,步长为2
        self.branch2 = nn.Sequential(
            BasicConv2d(in_channels, ch3x3redX2, kernel_size=1),
            BasicConv2d(ch3x3redX2, ch3x3X2, kernel_size=3, padding=1),   # 保证输出大小等于输入大小
            BasicConv2d(ch3x3X2, ch3x3X2, kernel_size=3, stride=2)
        )
        # 3×3池化,步长为2
        self.branch3 = nn.Sequential(nn.MaxPool2d(kernel_size=3, stride=2))
        # pool_proj:池化层后不再接卷积层

    def forward(self, x):
        branch1 = self.branch1(x)
        branch2 = self.branch2(x)
        branch3 = self.branch3(x)
        # 拼接
        outputs = [branch1,branch2, branch3]
        return torch.cat(outputs, 1)

# 辅助分类器:AvgPool2d+BasicConv2d+Linear+dropout
class InceptionAux(nn.Module):
    def __init__(self, in_channels, out_channels):
        super(InceptionAux, self).__init__()

        self.averagePool = nn.AvgPool2d(kernel_size=5, stride=3)
        self.conv1 = BasicConv2d(in_channels=in_channels, out_channels=128, kernel_size=1)
        self.conv2 = BasicConv2d(in_channels=128, out_channels=768, kernel_size=5, stride=1)
        self.dropout = nn.Dropout(p=0.7)
        self.linear = nn.Linear(in_features=768, out_features=out_channels)
    def forward(self, x):
        # N x 768 x 17 x 17
        x = self.averagePool(x)
        # N x 768 x 5 x 5
        x = self.conv1(x)
        # N x 128 x 5 x 5
        x = self.conv2(x)
        # N x 768 x 1 x 1
        x = x.view(x.size(0), -1)
        # N x 768
        out = self.linear(self.dropout(x))
        # N x num_classes
        return out

# 卷积组: Conv2d+BN+ReLU
class BasicConv2d(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0):
        super(BasicConv2d, self).__init__()
        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding)
        self.bn = nn.BatchNorm2d(out_channels)
        self.relu = nn.ReLU(inplace=True)
    def forward(self, x):
        x = self.conv(x)
        x = self.bn(x)
        x = self.relu(x)
        return x

# if __name__ == '__main__':
#     device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
#     model = GoogLeNetV3().to(device)
#     summary(model, input_size=(3, 299, 299))

model = GoogLeNetV3(num_classes=4).to(device)

summary(model, input_size=( 3, 299, 299))

模型验证

使用天气分类数据集
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

Inception v3使用不同大小的卷积核并行处理输入,允许网络同时学习局部和全局特征,提高了特征提取的效率和准确性。通过把大的卷积核分解为小卷积核可减少参数量。Inception模型中广泛使用了多尺度卷积,通过并行使用不同大小的卷积核,有效地提高了模型对图像特征的提取效率和准确性。

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

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

相关文章

碳化硅片有哪些比较重要的参数?

知识星球(星球名:芯片制造与封测社区)里的学员问:请问碳化硅衬底片到客户端验证主要测试什么项目,比较重要的参数有哪些? Lattice Parameters:晶格参数。确保衬底的晶格常数与将要生长的外延层…

数据结构之顺序表深度讲解

从这节课开始就要进入数据结构的课了,小伙伴们,你们准备好了吗?系好安全带,我们要发了。 顺序表的引入 概念 相互存在一种或多种特定关系的数据元素的集合 大白话:一个结构体包含了一些数据元素 概念不重要&#x…

代码随想录算法训练营第五天:哈希表的初步认识[1]

代码随想录算法训练营第五天:哈希表的初步认识 数组就是简单的哈希表,但是数组的大小可不是无限开辟的 前言 我们已经学习了数组、字符串、链表等数据结构,但是大家有没有发现,如果我们想要找到其中某个元素或者节点&#xff0…

pytho爬取南京房源成交价信息并导入到excel

# encoding: utf-8 # File_name: import requests from bs4 import BeautifulSoup import xlrd #导入xlrd库 import pandas as pd import openpyxl# 定义函数来获取南京最新的二手房房子成交价 def get_nanjing_latest_second_hand_prices():cookies {select_city: 320100,li…

【MySQL 数据宝典】【索引原理】- 001 索引原理分析 (AVL树、B-Tree、B+Tree)

一、索引定义 MySQL官方对索引定义:是存储引擎用于快速查找记录的一种数据结构。需要额外开辟空间和数据维护工作。 索引是物理数据页存储,在数据文件中(InnoDB,ibd文件),利用数据页(page)存储。 索引可以…

Java数据结构堆

堆的概念 所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中。 小根堆:根节点的大小小于孩子节点。整棵树都是小根堆必须满足每颗子树都是小根堆。 堆的存储方式 从堆的概念可知,堆是一棵完全二叉树,因此可以层序的规则采用顺序的…

Java虚拟机(JVM)之字节码文件

让我们先来简单了解一下JVM。 JVM功能: 1、解释和运行:对字节码文件中的指令,实时的解释成机器码让计算机执行。 2、内存管理:自动为对象、方法等分配内存;自动的垃圾回收机制,回收不再使用的对象。 3、即…

树莓派4B安装安卓系统LineageOS 21(Android14)

1:系统下载 2:下载好镜像后,准备写入SD卡,我这边使用的是 balenaetcher 3:插入树莓派,按照指示一步一步进行配置,可以配置时区,语言。 注意点 1》:想返回的时候按F2 2》:进入系统…

解密C语言内存分配奥秘,遨游动态内存管理海洋

一.C语言内存分区 C语言内存区从低地址到高地址分为代码区、常量区、全局(静态)区、堆区、栈区。 1.栈区 栈区介绍 栈区由编译器自动分配释放,由操作系统自动管理,无须手动管理。栈区上的内容只在函数范围内存在,当…

【软件开发规范篇】JAVA后端开发编码命名规范

作者介绍:本人笔名姑苏老陈,从事JAVA开发工作十多年了,带过大学刚毕业的实习生,也带过技术团队。最近有个朋友的表弟,马上要大学毕业了,想从事JAVA开发工作,但不知道从何处入手。于是&#xff0…

阿里云服务器(Ubuntu22)上的MySQL8更改为大小写不敏感

因为windows上默认的mysql8.0是大小写不敏感的,部署到服务器上之后发现ubuntu默认的是大小写敏感,所以为了不更改代码,需要将mysql数据库设置为大小写不敏感的。 !!!重要一定要做好数据库的备份&#xff0…

docker如何关闭证书认证

目录 前言关闭Docker认证的步骤修改pom 前言 当docker认证证书过期了,项目又要马上上线怎么办?重新生成证书,时间来不及,这时最快的方法就是关闭证书认证。 关闭Docker认证的步骤 停止Docker服务 systemctl stop docker编辑Do…

【C++】对文章分词,并对词频用不同排序方法排序,比较各排序算法效率(功能全面,通俗易懂)

文章分词 1.问题描述2.需求分析3.概要设计3.1 主程序流程3.2 函数调用关系 4.主函数实现4.1 main.h4.2 main.cpp 5. 函数实现5.1 processDic函数5.2 forwardMax函数5.3 countWordFreq函数5.4 quickResult函数5.5 其它排序算法效率…

异地组网、网络部署、无线覆盖,贝锐蒲公英一步到位

面对网络架构复杂的企业总部,分散在各地的分支机构,以及出差的远程办公人员,如何才能高效异地组网? 为了确保总部、分部网络实现远程稳定、高速互访,以及远程人员安全访问总部业务系统,基于自研SD-WAN的贝…

elementui el-date-picker禁止选择今年、今天、之前、时间范围限制18个月

1、禁止选择今年之前的所有年份 <el-date-pickerv-if"tabsActive 0":clearable"false"v-model"yearValue"change"yearTimeChange"type"year"placeholder"选择年"value-format"yyyy":picker-options…

手搓数组栈(C语言)

stack.h #pragma once#include <stdio.h> #include <stdlib.h> #include <assert.h> #include <stdbool.h> // 支持动态增长的栈 typedef int STDataType; typedef struct Stack {STDataType* a;int top; // 栈顶int capacity; // 容量 }Stack; //…

光伏储能系统的主要作用都有什么?

光伏储能系统&#xff0c;结合了光伏技术和储能技术&#xff0c;已经成为当今可再生能源领域的重要一环。它不仅在电力供应中扮演着关键角色&#xff0c;还在许多其他领域展现出其广泛的应用价值。本文将详细探讨光伏储能系统的主要作用。 首先&#xff0c;光伏储能系统在家庭住…

Java苍穹外卖03-Redis-营业状态-HttpClient-微信小程序开发-微信登录以及浏览

一、Redis入门 1.Redis简介 是对MySQL数据库的补充 2.下载安装 启动redis&#xff1a; 再开一个cmd&#xff1a;连接本地redis数据库 如果想连接其他地方的redis数据库&#xff1a;h为ip&#xff0c;p为端口 a为密码 3.数据类型 哈希适合存储对象&#xff0c;列表适合存储…

【问题实操】银河麒麟高级服务器操作系统实例,CPU软锁报错触发宕机

1.服务器环境以及配置 处理器&#xff1a; Kunpeng 920 内存&#xff1a; 256G DDR4 整机类型/架构&#xff1a; TaiShan 200 (Model 2280) 内核版本 4.19.90-23.8.v2101.ky10.aarch64 2.问题现象描述 两台搭载麒麟v10 sp1的机器均在系统CPU软锁报错时&#xff0c;触…