Inception_V2_V3_pytorch

Inception_V2_V3_pytorch

在上一节我们已经精度了Inception_V2_V3这篇论文,本篇我们将用pyorch复现论文中的网络结构!

从论文中我们可以知道InceptionV3的主要改进为:

  • 5 * 5卷积分解为2个3 * 3卷积核
  • 分解为不对称卷积
  • 滤波器组

在这里插入图片描述

我们可将GoogLeNetv3分解为以下5个模块:

  • InceptionV3模块
  • 辅助分类器模块
  • 非对称分离式卷积
  • 滤波器组
  • 用2个3 * 3卷积核代替1个5 * 5 卷积核

接下来我们将在Layers.py中定义Separable_Conv2d,Concat_Separable_Conv2d,Conv2d,Flatten,Squeeze这些类。

  • Separable_Conv2d

实现的是下面这中非对称分离式卷积结构!

在这里插入图片描述

  • Concat_Separable_Conv2d

实现的是下面滤波器组的结构

在这里插入图片描述

Layers.py中代码如下:

import torch
import torch.nn as nn

# 非对称分离式卷积
class Separable_Conv2d(nn.Module):
    def __init__ (self,in_channels,out_channels,kernel_size,stride = 1,padding = 0):
        super(Separable_Conv2d,self).__init__()
        self.conv_h = nn.Conv2d(in_channels,in_channels,(kernel_size,1),stride=(stride,1),padding=(padding,0))
        self.conv_w = nn.Conv2d(in_channels,out_channels,(1,kernel_size),stride=(1,stride),padding=(0,padding))
        self.bn = nn.BatchNorm2d(out_channels)
        self.relu = nn.ReLU(inplace=True)
    
    def forward(self,x):
        x = self.conv_h(x)
        x = self.conv_w(x)
        x = self.bn(x)
        x = self.relu(x)
        return x
    
# 滤波器组
class Concat_Separable_Conv2d(nn.Module):
    def __init__(self,in_channels,out_channels,kernel_size,stride = 1,padding=0):
        super(Concat_Separable_Conv2d,self).__init__()
        self.conv_h = nn.Conv2d(in_channels,in_channels,(kernel_size,1),stride=(stride,1),padding=(padding,0))
        self.conv_w = nn.Conv2d(in_channels,out_channels,(1,kernel_size),stride=(1,stride),padding=(0,padding))
        self.bn = nn.BatchNorm2d(out_channels * 2)
        self.relu = nn.ReLU(inplace=True)
    
    def forward(self,x):
        x_h = self.conv_h(x)
        x_w = self.conv_w(x)
        x = torch.cat([x_h,x_w],dim=1)
        x = self.bn(x)
        x = self.relu(x)
        return x
        

# 定义基础的卷积模块添加BN和ReLU
class Conv2d(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0, output=False):
        super(Conv2d, self).__init__()
        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding)
        self.output = output
        if self.output == False:
            self.bn = nn.BatchNorm2d(out_channels)
            self.relu = nn.ReLU(inplace=True)
    
    def forward(self, x):
        x = self.conv(x)
        if self.output:
            return x
        else:
            x = self.bn(x)
            x = self.relu(x)
            return x
    

class Flatten(nn.Module):
    def __init__(self):
        super(Flatten, self).__init__()
    def forward(self, x):
        return torch.flatten(x, 1)

class Squeeze(nn.Module):
    def __init__(self):
        super(Squeeze, self).__init__()
    def forward(self, x):
        return torch.squeeze(x) 
import torch
import torch.nn as nn
from Layers import *
import torch.nn.functional as F
from functools import partial


class Inceptionv3(nn.Module):
    def __init__(self,input_channels,conv1_channel,conv3_reduce_channel,conv3_channel,
                 conv3_double_reduce_channel,conv3_double_channel,
                 pool_reduce_channel,stride = 1,pool_type = 'AVG',mode = 1):
        super(Inceptionv3,self).__init__()
        self.stride = stride
        if stride == 2:
            padding_conv3 = 0
            padding_conv7 = 2
        else:
            padding_conv3 = 1
            padding_conv7 = 3
        
        if conv1_channel != 0:
            self.conv1 = Conv2d(input_channels,conv1_channel,kernel_size = 1)
        else:
            self.conv1 = None

        self.conv3_reduce = Conv2d(input_channels,conv3_reduce_channel,kernel_size = 1)
        match mode:
            case '1':   # 用两个3*3卷积代替一个5*5卷积
                self.conv3 = Conv2d(conv3_reduce_channel,conv3_channel,kernel_size = 3,stride = stride,padding = padding_conv3)
                self.conv3_double1 = Conv2d(conv3_double_reduce_channel,conv3_double_channel,kernel_size = 3,padding = 1)
                self.conv3_double2 = Conv2d(conv3_double_channel,conv3_double_channel,kernel_size = 3,stride=stride,padding = padding_conv3)

            case '2':   # 非对称分离式卷积
                self.conv3 = Separable_Conv2d(conv3_reduce_channel,conv3_channel,kernel_size = 7,stride = stride,padding = padding_conv7)
                self.conv3_double1 = Separable_Conv2d(conv3_double_reduce_channel,conv3_double_channel,kernel_size = 7,padding = 3)
                self.conv3_double2 = Separable_Conv2d(conv3_double_channel,conv3_double_channel,kernel_size = 7,stride=stride,padding = padding_conv7)

            case '3':   # 滤波器组
                self.conv3 = Concat_Separable_Conv2d(conv3_reduce_channel,conv3_channel,kernel_size = 3,stride = stride,padding = 1)
                self.conv3_double1 = Conv2d(conv3_double_reduce_channel,conv3_double_channel,kernel_size = 3,padding = 1)
                self.conv3_double2 = Concat_Separable_Conv2d(conv3_double_channel,conv3_double_channel,kernel_size = 3,stride=stride,padding = 1)

        self.conv3_double_reduce = Conv2d(input_channels,conv3_double_reduce_channel,kernel_size = 1)
        if pool_type == 'MAX':
            self.pool = nn.MaxPool2d(kernel_size = 3,stride = stride,padding = padding_conv3)
        elif pool_type == 'AVG':
            self.pool = nn.AvgPool2d(kernel_size = 3,stride = stride,padding = padding_conv3)
        if pool_reduce_channel != 0:
            self.pool_reduce = Conv2d(input_channels,pool_reduce_channel,kernel_size = 1)
        else:
            self.pool_reduce = None

    def forward(self,x):
        output_conv3 = self.conv3(self.conv3_reduce(x))
        output_conv3_double = self.conv3_double2(self.conv3_double1(self.conv3_double_reduce(x)))

        if self.pool_reduce != None:
            output_pool = self.pool_reduce(self.pool(x))
        else:
            output_pool = self.pool(x)

        if self.conv1 != None:
            output_conv1 = self.conv1(x)
            outputs = torch.cat([output_conv1,output_conv3,output_conv3_double,output_pool],dim = 1)
        else:
            outputs = torch.cat([output_conv3,output_conv3_double,output_pool],dim = 1)

        return outputs



# 辅助分类器
class InceptionAux(nn.Module):
    def __init__(self,input_channels,num_classes):
        super(InceptionAux,self).__init__()
        self.aux = nn.Sequential(
            nn.AvgPool2d(kernel_size = 5,stride = 3),
            Conv2d(input_channels,128,kernel_size = 1),
            Conv2d(128,1024,kernel_size = 5),
            Conv2d(1024,num_classes,kernel_size = 1,output = True),
            Squeeze()
        )

    def forward(self,x):
        x = self.aux(x)
        return x
class GoogLeNetv3(nn.Module):
    def __init__(self,num_classes,mode = 'train'):
        super(GoogLeNetv3,self).__init__()
        self.num_classes = num_classes
        self.mode = mode
        self.layers = nn.Sequential(
            Conv2d(3,32,3,stride=2),
            Conv2d(32,32,3,stride = 1),
            Conv2d(32,64,kernel_size = 3,stride=1,padding = 1),
            nn.MaxPool2d(kernel_size= 3 ,stride = 2),
            Conv2d(64,80,kernel_size = 3),
            Conv2d(80,192,kernel_size=3,stride=2),
            Conv2d(192,288,kernel_size=3,stride=1,padding=1),

            Inceptionv3(288,64,48,64,64,96,64,mode='1'),    #3a
            Inceptionv3(288,64,48,64,64,96,64,mode='1'),    #3b
            Inceptionv3(288,0,128,384,64,96,0,stride=2,pool_type='MAX',mode='1'),   #3c

            Inceptionv3(768,192,128,192,128,192,192,mode='2'),  #4a
            Inceptionv3(768,192,160,192,160,192,192,mode='2'),  #4b
            Inceptionv3(768,192,160,192,160,192,192,mode='2'),  #4c
            Inceptionv3(768,192,192,192,192,192,192,mode='2'),  #4d
            Inceptionv3(768,0,192,320,192,192,0,stride=2,pool_type='MAX',mode='2'), #4e

            Inceptionv3(1280,320,384,384,448,384,192,mode='3'), #5a
            Inceptionv3(2048,320,384,384,448,384,192,pool_type='MAX',mode='3'), #5b
            nn.AvgPool2d(8,1),
            Conv2d(2048,num_classes,kernel_size=1,output=True),
            Squeeze(),
            
        )

        if mode == 'train':
            self.aux = InceptionAux(768,num_classes)

    
    def forward(self,x):
        for idx,layer in enumerate(self.layers):
            if(idx == 14 and self.mode == 'train'):
                aux = self.aux(x)
            x = layer(x)
        if self.mode == 'train':
            return x,aux
        else:
            return x
        
    def init_weights(self,init_mode = 'VGG'):
        def init_function(m,init_mode):
            if type(m) == nn.Linear or type(m) == nn.Conv2d:
                if init_mode == 'VGG':
                    torch.nn.init.normal_(m.weight,mean=0.0,std=0.01)
                elif init_mode == 'XAVIER':
                    fan_in,fan_out = torch.nn.init._calculate_fan_in_and_fan_out(m.weight)
                    std = (2.0 / float(fan_in + fan_out)) ** 0.5
                    a = (3.0)**0.5 * std
                    with torch.no_grad():
                        m.weight.uniform_(-a,a)
                elif init_mode == 'KAMING':
                    torch.nn.init.kaiming_uniform(m.weight)

                
                m.bias.data.fill_(0)
        _ = self.apply(partial(init_function,init_mode = init_mode))
from torchsummary import summary
net = GoogLeNetv3(1000).cuda()
summary(net, (3, 299, 299))
----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Conv2d-1         [-1, 32, 149, 149]             896
       BatchNorm2d-2         [-1, 32, 149, 149]              64
              ReLU-3         [-1, 32, 149, 149]               0
            Conv2d-4         [-1, 32, 149, 149]               0
            Conv2d-5         [-1, 32, 147, 147]           9,248
       BatchNorm2d-6         [-1, 32, 147, 147]              64
              ReLU-7         [-1, 32, 147, 147]               0
            Conv2d-8         [-1, 32, 147, 147]               0
...
Concat_Separable_Conv2d-331            [-1, 768, 8, 8]               0
       MaxPool2d-332           [-1, 2048, 8, 8]               0
          Conv2d-333            [-1, 192, 8, 8]         393,408
     BatchNorm2d-334            [-1, 192, 8, 8]             384
            ReLU-335            [-1, 192, 8, 8]               0
          Conv2d-336            [-1, 192, 8, 8]               0
          Conv2d-337            [-1, 320, 8, 8]         655,680
     BatchNorm2d-338            [-1, 320, 8, 8]             640
            ReLU-339            [-1, 320, 8, 8]               0
          Conv2d-340            [-1, 320, 8, 8]               0
     Inceptionv3-341           [-1, 2048, 8, 8]               0
       AvgPool2d-342           [-1, 2048, 1, 1]               0
          Conv2d-343           [-1, 1000, 1, 1]       2,049,000
          Conv2d-344           [-1, 1000, 1, 1]               0
         Squeeze-345                 [-1, 1000]               0
================================================================
Total params: 28,850,400
Trainable params: 28,850,400
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 1.02
Forward/backward pass size (MB): 270.86
Params size (MB): 110.06
Estimated Total Size (MB): 381.94
----------------------------------------------------------------

1, 1000, 1, 1] 2,049,000
Conv2d-344 [-1, 1000, 1, 1] 0
Squeeze-345 [-1, 1000] 0
================================================================
Total params: 28,850,400
Trainable params: 28,850,400
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 1.02
Forward/backward pass size (MB): 270.86
Params size (MB): 110.06
Estimated Total Size (MB): 381.94
----------------------------------------------------------------

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【专利】一种光伏产品缺陷检测AI深度学习算法

申请号CN202410053849.9公开号(公开)CN118037635A申请日2024.01.12申请人(公开)超音速人工智能科技股份有限公司发明人(公开)张俊峰(总); 叶长春(总); 廖绍伟 摘要 本发明公开一种光伏产品缺陷检测AI深度…

区块链实验室(37) - 交叉编译百度xuperchain for arm64

纠结了很久,终于成功编译xuperchain for arm64。踩到1个坑,说明如下。 1、官方文档是这么说的:go语言版本推荐1.5-1.8 2、但是同一个页面,又是这么说的:不推荐使用1.11之前的版本。 3、问题来了:用什么版本…

ONLYOFFICE 编辑器8.1,一个功能全面的编辑器

目录 官网地址:ONLYOFFICE - 企业在线办公应用软件 | ONLYOFFICE 一、PDF编辑 二、PPT播放 1. 多样化的幻灯片样式与布局 2. 强大的文本编辑与格式化功能 3. 丰富的图形与图表插入功能 4. 灵活的过渡效果与动画设置 5. 舒适的呈现与演讲辅助功能 6. 便捷的团…

Mac清理系统数据小技巧,告别卡顿烦恼 苹果电脑清理内存怎么清理

任何使用Mac的用户都会同意:没有什么比一台运行缓慢的电脑更能消磨人的耐心了。那些无休止的彩球旋转、程序响应迟缓、突然的系统冻结,这一切都让人想抓狂!但别担心,这里有一些简单的Mac清理系统数据小技巧和CleanMyMac X的神助攻…

游戏高度可配置化(一)通用数据引擎(data-e)及其在模块化游戏开发中的应用构想图解

游戏高度可配置化(一)通用数据引擎(data-e)及其在模块化游戏开发中的应用构想图解 码客 卢益贵 ygluu 关键词:游戏策划 可配置化 模块化配置 数据引擎 条件系统 红点系统 一、前言 在插件式模块化软件开发当中,既要模块高度独…

DDD(data display debugger)调试工具

文章目录 DDD安装界面说明 DDD data display debugger是命令行调试程序,可以理解为可视化的GDB。 安装 CentOS下使用以下命令进行安装: yum install ddd等待安装完成即可。 界面说明 顺便写一个测试程序,编译可执行文件 终端命令行输入…

[C++深入] --- malloc/free和new/delete

1 new运算符的拓展 1.1 自由存储区与堆的概念 在C++中,内存区分为5个区,分别是堆、栈、自由存储区、全局/静态存储区、常量存储区。 自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。 new操作符从自由存储区(free st…

十大排序算法之->基数排序

一、计数排序简介 基数排序(Radix Sort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。具体做法是用0-9之间的所有整数作为键值,对数据集中的每一个数,按照从…

无线领夹麦克风哪个品牌音质最好,揭秘无线麦克风哪个牌子最好!

​在这个数字化、信息化的时代,短视频和直播已经成为了人们生活中不可或缺的一部分。而无线麦克风,则是这些活动中不可或缺的重要工具。它们能够轻松捕捉声音,让内容更加生动、真实。然而,市场上的无线麦克风种类繁多,…

深入解析与解决高并发下的线程池死锁问题

问题背景 在现代互联网应用中,高并发场景是常态,为了高效处理大量用户请求,后端服务通常会采用线程池来管理线程资源。然而,在一个复杂的微服务架构项目中,我们遇到了一个棘手的问题:在业务高峰期&#xf…

收银系统源码-千呼新零售2.0【线上营销】

千呼新零售2.0系统是零售行业连锁店一体化收银系统,包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体,线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货等连锁店使用。 详细介绍请查看&a…

数据结构-顺序表的插入排序

顺序表的排序可以看作数组排序的拓展。基本逻辑和数组排序的逻辑大同小异。 由于顺序表中可以存放不同种的数据类型,进而和结构体排序又有相似之处。其中要注意的是(->)和(.)的区别。 -> 符号是针对指针进行的操…

《计算机英语》Unit 1 Computer Overview 计算机概述

期末试卷组成 1、选择20道 2、判断20道 3、词汇翻译(单词词组,参照课后习题) 4、翻译2道(一道原题,参照作业) SectionA About Computer 关于计算机 algorithm n. 算法 operate v.…

6.19长难句打卡

The Flatiron School, where people pay to learn programming, started as one of the many coding bootcamps that’s become popular for adults looking for a career change. 人们在Flatiron学校里花钱学习编程,且Flatiron学校也成为在寻求职业变化的成年人之中…

超越招聘技术人才目标的最佳技术招聘统计数据

研究发现,难以找到的人才比以往任何时候都更难找到:根据新人才委员会招聘调查报告:2024年难以找到的人才的战略和战略,60%的受访者表示,熟练人才的招聘时间比一年前长。调查进一步揭示了以下关于招聘技术的关键事实&am…

与亚马逊云科技深度合作,再获WAPP、ISV认证

上半年,VERYCLOUD睿鸿股份加入亚马逊云科技的WAPP(Well-Architected Partner Programs)和ISV加速计划(ISV Accelerate Program),为客户带来更坚实优质的海外云服务。 Well-Architected 获得WAPP这项认证代表…

揭秘,如何轻松选出那瓶专属于你的心动红酒?

红酒,这个充满神秘与浪漫的液体,总能在不经意间触动我们的味蕾,引发无尽的遐想。然而,面对琳琅满目的红酒选择,如何挑选一瓶适合自己的红酒呢?今天,就让我们一起探讨这个话题,并特别…

艾斯迪克MPU60压力控制单元维修

一、艾斯迪克压力控制单元故障识别与诊断 首先,当出现ESTIC压力控制单元MPU60故障时,我们需要进行故障识别与诊断。这通常包括检查设备的显示屏、指示灯以及传感器等部分,以确定故障的具体位置。此外,还可以使用专业的故障诊断工具…

Conda创建与激活虚拟环境(指定虚拟环境创建位置)

1.Conda优势 Conda是一个开源的软件包管理系统和环境管理系统,主要用于在不同的计算环境中安装和管理软件包和其依赖项。它最初是为Python而设计的,但现在也可以用于管理其他语言的软件包。 Conda提供了对虚拟环境的支持,这使得用户可以在同…

解锁分布式云多集群统一监控的云上最佳实践

作者:在峰 引言 在当今数字化转型加速的时代,随着混合云、多云多集群环境等技术被众多企业广泛应用,分布式云架构已成为众多企业和组织推动业务创新、实现弹性扩展的首选,分布式云容器平台 ACK One(Distributed Clou…