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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • leetcode 三数之和_leetcode 三数之和

    leetcode 三数之和_leetcode 三数之和原题链接给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。示例 1:输入:nums = [-1,0,1,2,-1,-4]输出:[[-1,-1,2],[-1,0,1]]示例 2:输入:nums = []输出:[]示例 3:输入:nums = [0]输出:[] 提示:0 <= nums.length <= 300

    2022年8月8日
    3
  • 开源四足机器人 附设计图及代码「建议收藏」

    斯坦福学生机器人俱乐部(StanfordStudentRoboticsclub)ExtremeMobility团队最近迎来了一名新成员——一个名为StanfordDoggo的四足机器人。这个机器人能跳1米多高,还能表演后空翻。与其他四足机器人动辄上万美元的成本不同,这个机器人的成本降到了3000美元以下,而且设计团队开源了该机器人的设计图、代码以及材料清单。任何感兴趣的人…

    2022年4月6日
    62
  • vue-router路由懒加载以及三种实现方式「建议收藏」

    vue-router路由懒加载以及三种实现方式「建议收藏」什么是路由懒加载?也叫延迟加载,即在需要的时候进行加载,随用随载。官方解释: 1:当打包构建应用时,JavaScript包会变得非常大,影响页面加载。 2:如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。官方在说什么呢?为什么需要懒加载? 1:首先,我们知道路由中通常会定义很多不同的页面。 2:这个页面这项目build打包后,一般情况下,会放在一个单独的js文件中 3:但是,如果很多的页面都放在同一个js文件.

    2022年10月6日
    3
  • 十四、迭代器模式—— 一个一个的遍历 #和设计模式一起旅行#「建议收藏」

    套路要深…故事背景今天要介绍一下迭代器,首先简单说明一下,什么是迭代器,为什么要使用迭代器。 迭代器(Iterate) 的意思就是反复做某件事情。那为什么要反复做某件事情呢,比如我们有个容器里面装了很好东西(这些东西都是同一类型的),要从容器中取每一个东西出来,就要反复去做一个取出的事情。故事主角迭代器模式 : 提供一种方法顺序访问一个聚合对象中的各个元素,而…

    2022年2月27日
    39
  • aws 将俄勒冈的ami 镜像复制到东京地区

    aws 将俄勒冈的ami 镜像复制到东京地区

    2022年2月18日
    54
  • 概率中的PDF,PMF,CDF

    概率中的PDF,PMF,CDF一概念解释二数学表示三概念分析四分布函数的意义五参考文献一.概念解释PDF:概率密度函数(probabilitydensityfunction),在数学中,连续型随机变量的概率密度函数(在不至于混淆时可以简称为密度函数)是一个描述这个随机变量的输出值,在某个确定的取值点附近的可能性的函数。PMF:概率质量函数(probabilitymassfunction),在概率

    2022年5月10日
    52

发表回复

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

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