【知识---ResNet(Residual Network)作用及代码】

2024-02-02 12:52

本文主要是介绍【知识---ResNet(Residual Network)作用及代码】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • ResNet(Residual Network)作用
  • ResNet残差块的示例:
    • tensorflow 版本
    • pytorch 版本
  • 总结


前言

提示:这里可以添加本文要记录的大概内容:

BN(批量归一化)可以解决网络层数太深而出现的梯度消失问题,但是如果网络层数太多,这个方法也是不太管用的。所以就提出了resnet,下面对该网络作进一步学习:


提示:以下是本篇文章正文内容,下面案例可供参考

ResNet(Residual Network)作用

ResNet(Residual Network)是由Microsoft Research提出的一种深度神经网络架构,

其主要特点是使用了残差块(Residual Blocks),通过跳跃连接(skip connection)来解决深度神经网络训练过程中的梯度消失和梯度爆炸问题。

这种结构使得网络可以更容易地学习恒等映射,从而更轻松地训练非常深的网络。

ResNet的基本构建块是残差块,其中输入通过跳跃连接直接添加到输出。

这样的设计有助于信息的流动,避免了梯度在网络中传递时过度减小,从而使得训练更加稳定。

ResNet残差块的示例:

tensorflow 版本

import tensorflow as tf
from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, ReLU, Adddef residual_block(x, filters, kernel_size=3, stride=1):# 主要路径y = Conv2D(filters, kernel_size=kernel_size, strides=stride, padding='same')(x)y = BatchNormalization()(y)y = ReLU()(y)y = Conv2D(filters, kernel_size=kernel_size, padding='same')(y)y = BatchNormalization()(y)# 跳跃连接if stride != 1 or x.shape[-1] != filters:x = Conv2D(filters, kernel_size=1, strides=stride, padding='same')(x)# 相加操作out = Add()([x, y])out = ReLU()(out)return out# 构建简单的ResNet模型
input_tensor = Input(shape=(224, 224, 3))
x = Conv2D(64, kernel_size=7, strides=2, padding='same')(input_tensor)
x = BatchNormalization()(x)
x = ReLU()(x)
x = residual_block(x, filters=64)
x = residual_block(x, filters=64)
x = residual_block(x, filters=128, stride=2)
x = residual_block(x, filters=128)
x = residual_block(x, filters=256, stride=2)
x = residual_block(x, filters=256)
x = residual_block(x, filters=512, stride=2)
x = residual_block(x, filters=512)
output = tf.keras.layers.GlobalAveragePooling2D()(x)model = tf.keras.Model(inputs=input_tensor, outputs=output)model.summary()

上述代码中的residual_block函数定义了一个简单的残差块,而模型则是通过堆叠这些残差块来构建的。

这只是一个简单的ResNet模型示例,实际中可能会使用更深的网络。

pytorch 版本

import torch
import torch.nn as nn
import torch.nn.functional as Fclass BasicBlock(nn.Module):def __init__(self, in_channels, out_channels, stride=1):super(BasicBlock, self).__init__()self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False)self.bn1 = nn.BatchNorm2d(out_channels)self.relu = nn.ReLU(inplace=True)self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False)self.bn2 = nn.BatchNorm2d(out_channels)# 跳跃连接self.shortcut = nn.Sequential()if stride != 1 or in_channels != out_channels:self.shortcut = nn.Sequential(nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False),nn.BatchNorm2d(out_channels))def forward(self, x):residual = xout = self.conv1(x)out = self.bn1(out)out = self.relu(out)out = self.conv2(out)out = self.bn2(out)out += self.shortcut(residual)out = self.relu(out)return outclass ResNet(nn.Module):def __init__(self, block, layers, num_classes=1000):super(ResNet, self).__init__()self.in_channels = 64self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)self.bn1 = nn.BatchNorm2d(64)self.relu = nn.ReLU(inplace=True)self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)self.layer1 = self._make_layer(block, 64, layers[0])self.layer2 = self._make_layer(block, 128, layers[1], stride=2)self.layer3 = self._make_layer(block, 256, layers[2], stride=2)self.layer4 = self._make_layer(block, 512, layers[3], stride=2)self.avgpool = nn.AdaptiveAvgPool2d((1, 1))self.fc = nn.Linear(512, num_classes)def _make_layer(self, block, out_channels, blocks, stride=1):layers = []layers.append(block(self.in_channels, out_channels, stride))self.in_channels = out_channelsfor _ in range(

总结

在实际应用中,可以根据任务的需求和计算资源的限制来选择不同深度的ResNet模型。

这篇关于【知识---ResNet(Residual Network)作用及代码】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/670767

相关文章

HTML5的input标签的`type`属性值详解和代码示例

《HTML5的input标签的`type`属性值详解和代码示例》HTML5的`input`标签提供了多种`type`属性值,用于创建不同类型的输入控件,满足用户输入的多样化需求,从文本输入、密码输入、... 目录一、引言二、文本类输入类型2.1 text2.2 password2.3 textarea(严格

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

JAVA项目swing转javafx语法规则以及示例代码

《JAVA项目swing转javafx语法规则以及示例代码》:本文主要介绍JAVA项目swing转javafx语法规则以及示例代码的相关资料,文中详细讲解了主类继承、窗口创建、布局管理、控件替换、... 目录最常用的“一行换一行”速查表(直接全局替换)实际转换示例(JFramejs → JavaFX)迁移建

Go异常处理、泛型和文件操作实例代码

《Go异常处理、泛型和文件操作实例代码》Go语言的异常处理机制与传统的面向对象语言(如Java、C#)所使用的try-catch结构有所不同,它采用了自己独特的设计理念和方法,:本文主要介绍Go异... 目录一:异常处理常见的异常处理向上抛中断程序恢复程序二:泛型泛型函数泛型结构体泛型切片泛型 map三:文

MyBatis中的两种参数传递类型详解(示例代码)

《MyBatis中的两种参数传递类型详解(示例代码)》文章介绍了MyBatis中传递多个参数的两种方式,使用Map和使用@Param注解或封装POJO,Map方式适用于动态、不固定的参数,但可读性和安... 目录✅ android方式一:使用Map<String, Object>✅ 方式二:使用@Param

SpringBoot实现图形验证码的示例代码

《SpringBoot实现图形验证码的示例代码》验证码的实现方式有很多,可以由前端实现,也可以由后端进行实现,也有很多的插件和工具包可以使用,在这里,我们使用Hutool提供的小工具实现,本文介绍Sp... 目录项目创建前端代码实现约定前后端交互接口需求分析接口定义Hutool工具实现服务器端代码引入依赖获

JAVA transient 关键字作用详解

《JAVAtransient关键字作用详解》Java的transient关键字用于修饰成员变量,使其不参与序列化过程,通过自定义序列化方法,可以手动控制transient变量的序列化行为,本文给大... 目录一、transient关键字作用二、原理详解三、典型使用场景四、代码示例五、注意事项六、与 stat

利用Python在万圣节实现比心弹窗告白代码

《利用Python在万圣节实现比心弹窗告白代码》:本文主要介绍关于利用Python在万圣节实现比心弹窗告白代码的相关资料,每个弹窗会显示一条温馨提示,程序通过参数方程绘制爱心形状,并使用多线程技术... 目录前言效果预览要点1. 爱心曲线方程2. 显示温馨弹窗函数(详细拆解)2.1 函数定义和延迟机制2.2

Spring Boot/Spring MVC核心注解的作用详解

《SpringBoot/SpringMVC核心注解的作用详解》本文详细介绍了SpringBoot和SpringMVC中最常用的15个核心注解,涵盖了请求路由映射、参数绑定、RESTfulAPI、... 目录一、Spring/Spring MVC注解的核心作用二、请求映射与RESTful API注解系列2.1

Springmvc常用的注解代码示例

《Springmvc常用的注解代码示例》本文介绍了SpringMVC中常用的控制器和请求映射注解,包括@Controller、@RequestMapping等,以及请求参数绑定注解,如@Request... 目录一、控制器与请求映射注解二、请求参数绑定注解三、其他常用注解(扩展)四、注解使用注意事项一、控制