残差网络 ResNet

news2025/2/25 5:18:18

目录

1.1 ResNet

2.代码实现


1.1 ResNet

如上图函数的大小代表函数的复杂程度,星星代表最优解,可见加了更多层之后的预测比小模型的预测离真实最优解更远了, ResNet做的事情就是使得模型加深一定会使效果变好而不是变差。

2.代码实现

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


class Residual(nn.Module):
    def __init__(self,input_channels,num_channels,use_1x1conv=False,strides=1):
        super().__init__()
        self.conv1=nn.Conv2d(input_channels,num_channels,kernel_size=3,
                             padding=1,stride=strides)
        self.conv2=nn.Conv2d(input_channels,num_channels,kernel_size=3,padding=1)
        #以上两个卷积都保证了输入输出得大小不变
        
        if use_1x1conv:
            self.conv3=nnn.Conv2d(input_channels,num_channels,kernel_size=1,
                                  stride=strides)
        else:
            self.conv=None
        self.bn1=nn.BatchNorm2d(num_channels)
        self.bn2=nn.BatchNorm2d(num_channels)
        self.relu=nn.ReLU(inplace=True)
        #inplace=True表示原地操作

def forward(self,X):
    Y=F.relu(self.bn1(self.conv1(X)))
    Y=self.bn2(self.conv2(Y))
    if self.conv3:
        X=self.conv3(X)
    Y+=X
    return F.relu(Y)

#查看输入和输出形状一致的情况。
blk=Residual(3)
blk.initialize()
X = np.random.uniform(size=(4, 3, 6, 6))
Y=blk(X)
Y.shape
"""结果输出:
(4, 3, 6, 6)"""


"""在增加输出通道数的同时,减半输出的高和宽。"""
blk=Residul(3,6,use_1x1conv=True,strides=2)
blk.initialize()
blk(X).shape
"""结果输出:
(4, 6, 3, 3)"""



"""ResNet模型"""
#ResNet的前两层跟之前介绍的GoogLeNet中的一样: 在输出通道数为64、步幅为2的7*7卷积层后,
#接步幅为2的3*3的最大汇聚层。 不同之处在于ResNet每个卷积层后增加了批量规范化层。
b1 = nn.Sequential(nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3),
                   nn.BatchNorm2d(64), nn.ReLU(),
                   nn.MaxPool2d(kernel_size=3, stride=2, padding=1))


#ResNet则使用4个由残差块组成的模块,每个模块使用若干个同样输出通道数的残差块。 
#第一个模块的通道数同输入通道数一致。 由于之前已经使用了步幅为2的最大汇聚层,所以无须
#减小高和宽。之后的每个模块在第一个残差块里将上一个模块的通道数翻倍,并将高和宽减半。


#注意,我们对第一个模块做了特别处理。
def resnet_block(input_channels,num_channels,num_residuals,first_block=False):
    blk=[]
    for i in range(num_residuals):
    #num_residuals等于2
        if i==0 and not first_block:
        #first_block此时等于False,说明不是第一个模块,第一个模块的输入已经减半了
            blk.append(Residual(input_channels,num_channels,use_1x1conv=True
                        strides=2))
                        #除开第一个模块,其余每个模块的第一个残差块都strides=2高宽减半
                        #还有输出和输入通道数的变化
        else:
            blk.append(Residual(num_channels,num_channels))
            #其余的所有模块的第二个残差块和第一个模块输入和输出通道数不变
    return blk


#接着在ResNet加入所有残差块,这里每个模块使用2个残差块。
b2=nn.Sequential(*resnet_block(64,64,2,first_block=True))
b3 = nn.Sequential(*resnet_block(64, 128, 2))
b4 = nn.Sequential(*resnet_block(128, 256, 2))
b5 = nn.Sequential(*resnet_block(256, 512, 2))


#在ResNet中加入全局平均汇聚层,以及全连接层输出。
net = nn.Sequential(b1, b2, b3, b4, b5,
                    nn.AdaptiveAvgPool2d((1,1)),
                    nn.Flatten(), nn.Linear(512, 10))


#在训练ResNet之前,让我们观察一下ResNet中不同模块的输入形状是如何变化的。在之前所有架构中,
#分辨率降低,通道数量增加,直到全局平均汇聚层聚集所有特征。
X = torch.rand(size=(1, 1, 224, 224))
for layer in net:
    X = layer(X)
    print(layer.__class__.__name__,'output shape:\t', X.shape)
"""结果输出:
Sequential output shape:     torch.Size([1, 64, 56, 56])
Sequential output shape:     torch.Size([1, 64, 56, 56])
Sequential output shape:     torch.Size([1, 128, 28, 28])
Sequential output shape:     torch.Size([1, 256, 14, 14])
Sequential output shape:     torch.Size([1, 512, 7, 7])
AdaptiveAvgPool2d output shape:      torch.Size([1, 512, 1, 1])
Flatten output shape:        torch.Size([1, 512])
Linear output shape:         torch.Size([1, 10])"""



"""训练模型"""
lr, num_epochs, batch_size = 0.05, 10, 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=96)
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())
"""结果输出:
loss 0.012, train acc 0.997, test acc 0.893
5032.7 examples/sec on cuda:0"""

参考:

inplace=True (原地操作)-CSDN博客

Python中initialize的全面讲解_笔记大全_设计学院 (python100.com)

python 中类的初始化方法_python initialize(self)-CSDN博客

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

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

相关文章

java版微信小程序商城 免 费 搭 建 java版直播商城平台规划及常见的营销模式有哪些?电商源码/小程序/三级分销

涉及平台 平台管理、商家端(PC端、手机端)、买家平台(H5/公众号、小程序、APP端(IOS/Android)、微服务平台(业务服务) 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis …

用通俗易懂的方式讲解:使用 LlamaIndex 和 Eleasticsearch 进行大模型 RAG 检索增强生成

检索增强生成(Retrieval-Augmented Generation,RAG)是一种结合了检索(Retrieval)和生成(Generation)的技术,它有效地解决了大语言模型(LLM)的一些问题&#x…

车载音频EMI的产生及典型音频功放AW836XX的解决方案

之前针对 eCall的文章中有提到D类音频功放需要关注EMI问题(点击文章回看《车载eCall系统音频应用解决方案》),在此展开此问题并寻求解决方案。 1. EMI定义与分类 电磁干扰(Electromagnetic Interference,EMI&#xff…

企业为什么要选择软件定制开发?

引言:定制开发的兴起 在商业竞争日益激烈的今天,企业领导者们面临着一个重要的抉择:是选择通用软件解决方案,还是探寻更贴合企业需求的定制开发路径? 在企业决策软件解决方案时,通用软件和软件定制开发各…

IOS-高德地图连续定位-Swift

使用定位功能需要需要接入高德地图定位Api: pod AMapLocation配置Info 在info中新建一个名为Privacy - Location Temporary Usage Description Dictionary的字典,然后在这个字典下新建Privacy - Location When In Use Usage Description、Privacy - Lo…

应用案例 | Softing工业物联网连接解决方案助力汽车零部件供应商实现智能制造升级

随着业务的扩展和技术的进步,某国际先进汽车零部件供应商在其工业物联网的升级方案中使用了Softing的dataFEED OPC Suite——通过MQTT协议将现场控制器和数控系统的数据上传到其物联网云平台,从而实现了设备状态的远程监控,不仅能够提前发现设…

drools开源规则引擎介绍以及在Centos上的具体部署方案,让你的业务规则能够独立于应用程序本身

Drools是一个基于Java的开源规则引擎,用于处理业务规则和复杂事件处理。它提供了一个声明性的规则语言,允许开发人员定义业务规则,并通过引擎执行这些规则。以下是Drools规则引擎的简介和一些应用场景描述。 Drools规则引擎简介 规则引擎概述…

消费增值模式:引领消费者与平台共创双赢的新篇章

在数字化时代,消费模式正在发生深刻变革。消费者不再满足于单纯的购物行为,而是寻求更加个性化和有价值的消费体验。而平台也面临着如何吸引和留住消费者的挑战。消费增值模式作为一种新型的商业模式,正逐渐成为解决这一问题的关键。 消费增…

钢岚芯片:如何获取及鉴别真伪?

在不断变革的高科技时代,芯片技术作为科技前沿的重要标志,已成为衡量一个国家和地区科技实力的重要指标。钢岚芯片,这一神秘而又先进的科技产物,作为当前芯片科技研究的巅峰之作,吸引了无数科技爱好者和业界精英的追捧…

ROS第 6 课 编写简单的订阅器 Subscriber

文章目录 第 6 课 编写简单的订阅器 Subscriber1. 编写订阅者节点2. 测试发布者和订阅者 第 6 课 编写简单的订阅器 Subscriber 订阅器是基于编辑了发布器的基础上创建的,只有发布了消息,才有可能订阅。若未编辑发布器,可前往"ROS第5课 …

SQL注入漏洞的检测及防御,零基础入门到精通

SQL注入(SQL Injection)是一种广泛存在于Web应用程序中的严重安全漏洞,它允许攻击者在不得到授权的情况下访问、修改或删除数据库中的数据。这是一种常见的攻击方式,因此数据库开发者、Web开发者和安全专业人员需要了解它&#xf…

WordPress后台仪表盘自定义添加删除概览项目插件Glance That

成功搭建WordPress站点,登录后台后可以在“仪表盘 – 概览”中看到包括多少篇文章、多少个页面、多少条评论和当前WordPress版本号及所使用的主题。具体如下图所示: 但是如果我们的WordPress站点还有自定义文章类型,也想在概览中显示出来应该…

OpenLayers实战,OpenLayers点聚合有相同经纬度坐标时无法展开问题解决办法,当缩放级别达到一定等级后强行展开聚合为单个点

专栏目录: OpenLayers实战进阶专栏目录 前言 本章用于解决OpenLayers使用Cluster点聚合情况下,要素(Feature)出现有相同经纬度坐标时无法展开成单独图标的问题解决办法以及当缩放级别达到一定等级后强行展开聚合为单个点的功能。 本章展开后由于经纬度坐标还是同一个点,…

Spring Security- 基于角色的访问控制

基于角色 或权限 进行访问控制 hasAuthority方法 如果当前的主体具有指定的权限,则返回true,否则返回false 修改配置类 //当前登录用户 只有具备admins权限才可以访问这个路径.antMatchers("/test/index").hasAuthority("admins") 代码如下: package c…

【面试合集】说说微信小程序的发布流程?

面试官:说说微信小程序的发布流程? 一、背景 在中大型的公司里,人员的分工非常仔细,一般会有不同岗位角色的员工同时参与同一个小程序项目。为此,小程序平台设计了不同的权限管理使得项目管理者可以更加高效管理整个团…

vue3-模板引用

//1.调用ref函数 -> ref对象 const h1Ref ref(null) const comRef ref(null) //组件挂载完毕之后才能获取 onMounted(()>{console.log(h1Ref.value);console.log(comRef.value); })<div class"father"><!-- 通过ref标识绑定ref对象 --><h2 re…

Apache Zeppelin学习记录2

Apache Zeppelin学习记录2 文章目录 Apache Zeppelin学习记录2前言一、基础调用二、带参数调用1.代码块要增加一行z.textbox("folder_path", "input")2.读取result 总结 前言 上一章讲了如何使用zeppelin来接入python&#xff0c;本节我们来看看如何使用R…

什么情况下物理服务器会运行出错?

​  物理服务器&#xff0c;也称为裸机服务器&#xff0c;一般可以提供高性能计算水平和巨大的存储容量。然而&#xff0c;它们也难免会遇到一些问题。运行出错时&#xff0c;可能会导致停机和数据丢失。在这篇文章中&#xff0c;介绍了常见的物理服务器在一些情况下显示出错…

基于D2-NET的图像配准(基于PYQT的可运行界面)

这是之前对D2-NET的一个封装。D2-NET在图像配准领域还是占有一席之地的。 我们在D2-NET的基础上进行了一些小小的改动&#xff0c;也增加了FLANNRANSAC的提纯策略&#xff0c;同时增加了PYQT的一个界面。 参考的代码&#xff1a;代码1 代码2 首先介绍一下这个界面&#x…

LINUX基础培训九之网络管理

前言、本章学习目标 了解LINUX网络接口和主机名配置的方法熟悉网络相关的几个配置文件了解网关和路由熟悉网络相关的命令使用 一、网络IP地址配置 在Linux中配置IP地址的方法有以下这么几种&#xff1a; 1、图形界面配置IP地址&#xff08;操作方式如Windows系统配置IP&…