ResNet18复现「建议收藏」

ResNet18复现「建议收藏」ResNet18的网络架构图首先将网络分为四层(layers),每层有两个模块组成,除了第一层是两个普通的残差块组成,其它三层有一个普通的残差块和下采样的卷积块组成。输入图像为3x224x224格式,经过卷积池化后为64x112x112格式进入主网络架构。代码如下:importtorchfromtorchimportnnfromtorch.nnimportfunctionalasFclassBasicBlock(nn.Module):def__ini

大家好,又见面了,我是你们的朋友全栈君。

ResNet18的网络架构图

ResNet18复现「建议收藏」

首先将网络分为四层(layers),每层有两个模块组成,除了第一层是两个普通的残差块组成,其它三层有一个普通的残差块和下采样的卷积块组成。输入图像为3x224x224格式,经过卷积池化后为64x112x112格式进入主网络架构。

代码如下:

import torch
from torch import nn
from torch.nn import functional as F

class BasicBlock(nn.Module):
    def __init__(self,in_channels,out_channels,kernel_size,stride):
        super(BasicBlock,self).__init__()
        self.conv1=nn.Conv2d(in_channels,out_channels,kernel_size,stride,padding=1)
        self.bn1=nn.BatchNorm2d(out_channels)
        self.conv2=nn.Conv2d(out_channels,out_channels,kernel_size,stride,padding=1)
        self.bn2=nn.BatchNorm2d(out_channels)
        
    def forward(self,x):
        output=self.bn1(self.conv1(x))
        output=self.bn2(self.conv2(output))
        return F.relu(x+output)
    

class BasicDownBlock(nn.Module):
    def __init__(self,in_channels,out_channels,kernel_size,stride):
        super(BasicDownBlock,self).__init__()     
        self.conv1=nn.Conv2d(in_channels,out_channels,kernel_size[0],stride[0],padding=1)
        self.bn1=nn.BatchNorm2d(out_channels)
        self.conv2=nn.Conv2d(out_channels,out_channels,kernel_size[0],stride[1],padding=1)
        self.bn2=nn.BatchNorm2d(out_channels)
        self.conv3=nn.Conv2d(in_channels,out_channels,kernel_size[1],stride[0])
        self.bn3=nn.BatchNorm2d(out_channels)
        
    def forward(self,x):
        output=self.bn1(self.conv1(x))
        output=self.bn2(self.conv2(output))
        output1=self.bn3(self.conv3(x))
        return F.relu(output1+output)

class ResNet18(nn.Module):
    def __init__(self):
        super().__init__()
        # 3x224x224-->64x112x112
        self.conv1=nn.Conv2d(in_channels=3,out_channels=64,kernel_size=7,stride=2,padding=3)
        self.bn1=nn.BatchNorm2d(64)
        # 64x112x112-->64x56x56
        self.pool1=nn.MaxPool2d(kernel_size=3,stride=2,padding=1)
        
        # 64x56x56-->64x56x56
        self.layer1=nn.Sequential(
            BasicBlock(64,64,3,1),
            BasicBlock(64,64,3,1)
        )
        # 64x56x56-->128*28*28
        self.layer2=nn.Sequential(
            BasicDownBlock(64,128,[3,1],[2,1]),
            BasicBlock(128,128,3,1)
        )
        # 128*28*28-->256*14*14
        self.layer3=nn.Sequential(
            BasicDownBlock(128,256,[3,1],[2,1]),
            BasicBlock(256,256,3,1)
        )
        # 256*14*14-->512x7x7
        self.layer4=nn.Sequential(
            BasicDownBlock(256,512,[7,1],[2,1]),
            BasicBlock(512,512,3,1)
        )
        # 512x7x7-->512x1x1
        self.avgpool=nn.AdaptiveMaxPool2d(output_size=(1,1))
        self.flat=nn.Flatten()
        self.linear=nn.Linear(512,10)
        
    def forward(self,x):
        output=self.pool1(F.relu(self.bn1(self.conv1(x))))
        output=self.layer1(output)
        output=self.layer2(output)
        output=self.layer3(output)
        output=self.layer4(output)
        output=self.avgpool(output)
        output=self.flat(output)
        output=self.linear(output)
        return output
    

net=ResNet18()
x=torch.randn(32,3,224,224)
print(x.shape)
y=net(x)
print(y.shape)

代码中BasicBlock为普通的残差块,注意步长和卷积核的大小,BasicDownBlock为下采样的残差块,然后将四层的网络表示出来,最后进行验证x.shape为torch.Size([32, 3, 224, 224]),y.shape为torch.Size([32, 10])。 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/141545.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 湖北新东方烹饪培训学校_新东方烹饪学校总部在哪

    湖北新东方烹饪培训学校_新东方烹饪学校总部在哪前言:本人将在2017年八月出国留学。在出国之前,决定去新东方学习烹饪,这样可以在异国他乡更好的生存和生活。练就一番好的烹饪手艺,做出自己喜欢的菜肴,在国外哪里都能品尝到家的味道。

    2022年9月13日
    0
  • 异步fifo的深度,如何确定?_二叉树的最小深度和最大深度

    异步fifo的深度,如何确定?_二叉树的最小深度和最大深度目录1.异步FIFO最小深度计算1.1异步FIFO最小深度计算原理1.2异步FIFO最小深度常用计算公式1.2.1假如读写FIFO是同时进行的1.2.2读写FIFO不是同时进行的情况2.异步FIFO最小深度计算实例2.1用于SDRAM中的读写FIFO2.2异步时钟数据接口3.FIFO实例1.异步FIFO最小深度计算计算FIF…

    2022年8月13日
    6
  • es6数组和对象常用方法

    es6数组和对象常用方法数组forEach()方法对数组的每个元素执行一次给定的函数。vararr=[1,2,3]arr.forEach((value,index)=>{console.log(‘数组值:’+value);console.log(‘数组索引:’+index);})map()方法创建一个新数组,其结果是该数组中的每个元素都调用一次提供的函数后的返回值。vararr=[1,2,3]vararr1=arr.map((value,in

    2022年5月26日
    46
  • macbookpro双系统分区_macbook双系统分区调整

    macbookpro双系统分区_macbook双系统分区调整一些前序知识:1、Mac系统不是Intel的i386架构,没有Bios,但是有EFI,通过EFI管理系统的引导。2、Mac系统的分区表采用GUID,不是MBR。因此如果硬盘完全交给windows控制,会导致Mac系统无法启动。3、任何对MBR的强行操作,会导致已经装好的双系统引导失效。4、Mac的EFI分区会用GPT锁定,不要尝试去操作这个分区。我们…

    2022年10月5日
    0
  • 蒂森MC2服务器显示FC00,蒂森电梯MC2常用功能地址参数设置说明.pdf[通俗易懂]

    蒂森MC2服务器显示FC00,蒂森电梯MC2常用功能地址参数设置说明.pdf[通俗易懂]C1/12MC2A00TEXXXX–TS1.MC21.1.A000/F000A001/F0011.2.MF3/MF4/MS3A/BMP1MPMS31.3.//j1.4.1.5.A3001.6.1.7.1.8.C2/12MC2A00TEXXXX–TSA2C21MP1.71.9.1.10.C…

    2022年5月20日
    364
  • onmouseover 和onmousemove的区别「建议收藏」

    onmouseover 和onmousemove的区别「建议收藏」时间上 onmousemove事件触发后,再触发onmouseover事件。按钮上 不区分鼠标按钮。动作上 onmouseover只在刚进入区域时触发。onmousemove除了刚进入区域触发外,在区域内移动鼠标,也会触发该事件。当鼠标移动很快时,可能不会触发这两个事件。 onmouseover与onmousemove的区别是:当鼠标移过当…

    2022年8月30日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号