resnet残差网络代码_pytorch卷积神经网络

resnet残差网络代码_pytorch卷积神经网络工欲善其事必先利其器,在使用该网络之前要先了解该网络的具体细节,我今天也是第一次查资料,然后加上自己的理解去写这篇学习成长文章。残差模块classResidualBlock(nn.Module):def__init__(self,inchannel,outchannel,stride=1,dowansample=None):super(ResidualBlock,self).__init__()self.left=nn.Sequential

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

工欲善其事必先利其器,在使用该网络之前要先了解该网络的具体细节,我今天也是第一次查资料,然后加上自己的理解去写这篇学习成长文章。

残差模块

class ResidualBlock(nn.Module):
    def __init__(self, inchannel, outchannel, stride=1, dowansample=None):
        super(ResidualBlock, self).__init__()
        self.left = nn.Sequential(
            nn.Conv2d(inchannel, outchannel, 3, stride, 1, bias=False),
            nn.BatchNorm2d(outchannel), 
            nn.ReLU(inplace=True),
            nn.Conv2d(outchannel, outchannel, 3, 1, 1, bias=False),
            nn.BatchNorm2d(outchannel)
        )
        self.dowansample=dowasample
    def forward(self, x):
        out = self.left(x)
        residual = x if self.dowansample is None else self.dowansample(x)
        out += residual
        return F.relu(out)

这是残差模块的代码,下面用一张图来具体介绍
在这里插入图片描述根据这张图和上面的代码,我们可以看出大概的一个过程,在前向传播函数中可以看到,数据传下来后会先通过两次卷积,也就是此案执行 self.left()函数,downsample是一个下采样函数,根据结果来判断是否执行想采样,残差模块的代码很简单,相信可以看明白。
主干网络模块
网络卷积图
在这里插入图片描述图片上的右边是resnet34残差网络的整体卷积过程,慢慢来逐个理解一下。
代码:

class ResNet34(nn.Module):
    def __init__(self, num_classes=1000):
        super(ResNet34, self).__init__()
        self.pre = nn.Sequential(
            nn.Conv2d(3, 64, 7, 2 ,3, bias=False), 
            nn.BatchNorm2d(64),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(3, 1, 1) 
        )
        self.layer1 = self._make_layer(64, 128, 3)              ### 3 个 64 通道的残差单元,输出 128通道,共6层
        self.layer2 = self._make_layer(128, 256, 4, stride=2)   ### 4 个 128通道的残差单元,输出 256通道,共8层
        self.layer3 = self._make_layer(256, 512, 6, stride=2)   ### 6 个 256通道的残差单元,输出 512通道,共12层
        self.layer4 = self._make_layer(512, 512, 3, stride=2)   ### 3 个 512通道的残差单元,输出 512通道,共6层
        ### fc,1层
        self.fc = nn.Linear(512, num_classes)
    def _make_layer(self, inchannel, outchannel, block_num, stride=1):
        dowansample= nn.Sequential(
            nn.Conv2d(inchannel, outchannel, 1, stride, bias=False),
            nn.BatchNorm2d(outchannel)
        )
        layers = []
        layers.append(ResidualBlock(inchannel, outchannel, stride, dowansample))       ### 先来一个残差单元,主要是改变通道数
        for i in range(1, block_num+1): 
            layers.append(ResidualBlock(outchannel, outchannel))
        return nn.Sequential(*layers)
    def forward(self, x):
        ### 第1层
        x = self.pre(x)
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)
        ### 注意 resnet 最后的池化是把一个 feature map 变成一个特征,故池化野大小等于最后 x 的大小
        x = F.avg_pool2d(x, 2)      ### 这里用的 cifar10 数据集,此时的 x size 为 512x2x2,所以池化野为2
        x = x.view(x.size(0), -1)
        return self.fc(x)

结合上图和代码,可以在初始化函数中看到self.pre()函数,这个函数主要是数据输进来时先通过一个7×7的卷积核来改变数据,也就是上图中 7×7, conv, 64 ,/2 这一行,初始化函数中还有一个self.layer1() , self.layer2() , self.layer3(),self.layer4()这几个函数,这几个分别对应上图的 3×3,conv,64。 3×3,conv,128。 3×3,conv,256 。 3×3,conv,512。
再看他们的函数定义的内容:

    def _make_layer(self, inchannel, outchannel, block_num, stride=1):
        downsample= nn.Sequential(
            nn.Conv2d(inchannel, outchannel, 1, stride, bias=False),
            nn.BatchNorm2d(outchannel)
        )
        layers = []
        layers.append(ResidualBlock(inchannel, outchannel, stride, downsample))
        for i in range(1, block_num+1):
            layers.append(ResidualBlock(outchannel, outchannel))
        return nn.Sequential(*layers)

先是一个downsample,里面是一个卷积,然后是一个数组,数组中先放一个残差模块,并且有dawnsample参数,这是在改变两个模块之间的通道数,比如上边3×3,conv,64。 3×3,conv,128。之间,在通道数转变的时候才执行。继续往下看,是一个for循环,循环里面还是向数组中放入残差模块,不同的是这次没有downsample参数了,通过这几行代码产生了上图中3个3×3,conv,64 4个 3×3,conv,128。一次类推,应该可以看明白,self.layer1() , self.layer2() , self.layer3(),self.layer4()这几个函数就是产生了上图竖着的那几十个卷积,接下来就是前向传播了,前向传播很简单,需要明白的是下采样downsample是在两个卷积时通道数不同的时候才执行,如64通过转变成128通道时。这一块也是最经典的地方,加深卷积后,先判断是否有变化,如果有变化,我就把变化加上,然后继续执行下边的卷积,如果没有变化,我就不加,还是继续执行下边的卷积,这样理论上就可以一直往下添加卷积层了。
以上就是我的理解,目前对一些实战中各个卷积层输入输出通道数的选择和卷积核的选择还是有一点疑惑和不解的,需要继续学习。

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

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

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


相关推荐

  • 怎么修改HTML网页的名字_如何修改html文件内容

    怎么修改HTML网页的名字_如何修改html文件内容NetCms默认设置中,只能上传Doc文件,不能上传xls文件和PPT文件。 上传文件类型可以“控制面板–>参数设置–>上传文件允许格式”中设置。但是,仅能上传,添加新闻时,添加附件的文件选择框中无法看到xls文件和ppt文件。 通过查看源文件,添加新闻页面是~/Manage/News/News_add.aspx文件,在该文件中,添加附件位置,通过调用JavaScript的s

    2022年9月29日
    3
  • 三分钟明白 Activity工作流 — java运用[通俗易懂]

    三分钟明白 Activity工作流 — java运用[通俗易懂]一、什么是工作流  以请假为例,现在大多数公司的请假流程是这样的  员工打电话(或网聊)向上级提出请假申请——上级口头同意——上级将请假记录下来——月底将请假记录上交公司——公司将请假录入电脑  采用工作流技术的公司的请假流程是这样的  员工使用账户登录系统——点击请假——上级登录系统点击允许  就这样,一个请假流程就结束了  有人会问,那上级不用向公司提交请假记录?公司不用将记录录入电脑?答案是

    2022年6月11日
    54
  • 难倒刘强东的奥数题,京东智能供应链解开了

    难倒刘强东的奥数题,京东智能供应链解开了原创:谭婧刘强东有几个问题,需要你帮忙做个决策:(一)到货快,花钱爽,建议商品离消费者越近越好。除了京东超级大仓库亚洲一号之外,得增加仓库数量,扩大仓库网络。而仓库又分一二三四好几级,一…

    2022年5月18日
    46
  • Hi3516A开发–视频接口[通俗易懂]

    Hi3516A开发–视频接口[通俗易懂]参看:几种常用的视频接口我们经常在家里的电视机、各种播放器上,视频会议产品和监控产品的编解码器的视频输入输出接口上看到很多视频接口,这些视频接口哪些是模拟接口、哪些是数字接口,哪些接口可以传输高清图像等,下面就做一个详细的介绍。  目前最基本的视频接口是复合视频接口、S-vidio接口;另外常见的还有色差接口、VGA接口、接口、HDMI接口、SDI接口。  1、复合

    2022年5月15日
    64
  • webApp开发心得「建议收藏」

    webApp开发心得「建议收藏」从事单页相关的开发一年有余,期间无比的推崇webapp的网站模式,也整理了很多移动开发的知识点,但是现在回过头来看,webapp究竟是好还是不好真是一言难尽哟!webapp使用JavaScript修改页面;紧接着再从服务器传递更多数据然后再修改页面,如此循环。从性能的角度看,在现代浏览器中单页面WebApp已经能够和普通native应用程序相媲美,而且几乎所有的操作系统都支持现代的浏览器…

    2022年6月29日
    24
  • python hexdump_hexdump用法[通俗易懂]

    python hexdump_hexdump用法[通俗易懂]可用参数[-bcCdovx][-eformat_string][-fformat_file][-nlength][-sskip]file…参数含义:-b单字节八进制显示,十六进制显示偏移量,每行显示16个字符,每字符用三位显示,不足补零,列间以空格分隔-c单字节字符显示,十六进制显示偏移量,每行显示16个字符,每字符三位显示,不足补空格,列间以空格分隔-C标准十六进制…

    2022年9月21日
    2

发表回复

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

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