当前位置: 首页 > 编程日记 > 正文

手把手快速实现 Resnet 残差模型实战

作者 | 李秋键

出品 | AI科技大本营(ID:rgznai100)

引言:随着深度学习的发展,网络模型的深度也随之越来越深,但随着网络模型深度的加深,往往会曾在这随着模型深度的加大,模型准确率反而下降的问题,而深度残差模型的提出就是为了解决这个问题。

一般来讲,网络的层数越深,提取到的特征越丰富,模型对目标函数的拟合能力越强。但过深的网络容易导致过拟合,且由于梯度消失等问题,深层的网络难以训练。深度残差网络Resnet由卷积神经网络发展变换得来。2015年,由微软研究院Kaiming He等提出的深度残差网络通过引入恒等路径使权重参数有效传递与更新,解决了卷积神经网络层数加深导致的过拟合、权重衰减、梯度消失等问题,性能表现优异。

在深层次的网络中训练时,由于反向传播的连乘机制,常常会出现在越靠近输入层的地方出现梯度消失。Resnet将网络结构调整为,将靠近输入层的网络层进行短接到输出层。这样网络就被设计成只需要拟合输入x和目标输出的残差y-x的模型,这也是模型被称为Resnet的原因。这样即使是多加了一层,那模型的效果也不会变差,因为新加的层会被短接到两层以后,相当于是学习了个恒等映射,而跳过的两层只需要拟合上层输出与目标之间的残差即可。

故今天我们将实现python搭建resnet模型辅助我们理解残差网络:

c5eba4f277db60c5ee80fd3d38a3475c.png

Resnet基本介绍

深度残差网络的结构包括输入层、卷积层、多个残差模块、激活函数、批标准化层、全局平均池化层、正则化层和多标签分类层。其中卷积层可以有效地提取特征图的局部特征,减少了可训练的权重参数。卷积层将卷积核与上层输入数据卷积运算后叠加一个偏置,得出的结果经过激活函数计算得到的输出特征值作为下层的输入。批标准化层可以减小样本数据和特征的差异,减轻初始化参数的依赖,使训练的收敛速度更快。其优化了方差的大小和均值的位置,对可训练参数进行正态分布处理并进行归一化处理,使得数据更均匀的分布在0~1,增强了模型的泛化能力。

残差模块的引入有效地解决了深度卷积网络的退化问题,提升模型的特征提取能力。残差模块包含由多层堆叠卷积组成的残差路径和短路路径。由于在卷积运算的过程中不同的卷积步长会改变输出特征图的维度,如果卷积运算没有改变输入特征图的维度,可采用恒等映射型残差模块。恒等映射型残差模块的短路路径将输入特征图恒等输出,并将其与残差路径的输出特征图相加,得到残差模块的输出特征图。如果卷积运算改变了输入特征图的维度,则无法将短路路径和残差路径的输出特征图直接相加,需通过降采样型残差模块,在短路路径上进行1×1卷积运算降采样以保持短路路径与残差路径输出特征图维度相同后,两者方可相加。

af7b64007f6cf2a1bba425dedabaaf47.png

(1)Relu缓解的梯度消失和Resnet缓解的梯度消失有何不同?

Relu解决的使用sigmoid等激活函数时造成的梯度消失,原因在于sigmoid激活函数值域范围为0到1,当输出值特别大或特别小时,根据图像特点可知此时的梯度接近于0,从而造成梯度消失。而relu激活函数不存在这种情况。

a03fa18c18227859d5b39777fda71ee4.png

但是即使使用Relu激活函数,当网络层数加深时,多个深度网络反向传播链式传递的多个参数连乘仍然会出现梯度消失。故使用Resnet来改善网络深度造成的梯度消失,使用残差模块和短接模块进行训练,当模型效果已经达到期望值时,使得新加入的层直接学习恒等映射,并不会使得模型效果变差。

(2)Resnet是如何解决梯度消失的?

Resnet将网络结构调整为,将靠近输入层的网络层进行短接到输出层。这样网络就被设计成只需要拟合输入x和目标输出的残差y-x的模型。这样即使是多加了一层,那模型的效果也不会变差,因为新加的层会被短接到两层以后,相当于是学习了个恒等映射,反向传播时对后面的参数依赖减少,使得跳过的两层只需要拟合上层输出与目标之间的残差即可。从而缓解连乘参数多带来的梯度消失问题。

Resnet模型搭建

为了从代码层面理解模型,下面用pytorch简单搭建手写字体识别模型。

这里程序的设计分为以下几个步骤,分别为预准备、模型搭建以及训练等几个步骤。

2.1 模型预准备

这里包括的预准备首先包括GPU或CPU训练的选择,迭代次数、batch一次训练样本数,学习率。然后通过pytorch中的transforms对数据变换,包括数据增强和转为Tensor等格式以及读入训练和测试数据等,代码如下:

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
num_epochs = 100
batch_size = 32
learning_rate = 0.001
transform = transforms.Compose([transforms.Pad(4),transforms.RandomHorizontalFlip(),transforms.RandomCrop(32),transforms.ToTensor()
])
train_datatset = torchvision.datasets.MNIST(root='./data/',train=True,transform=transform,download=True,)
test_datatset = torchvision.datasets.MNIST(root='./data/',train=False,transform=transforms.ToTensor())
train_loader = torch.utils.data.DataLoader(dataset=train_datatset,batch_size=batch_size,shuffle=True
)
test_loader = torch.utils.data.DataLoader(dataset=test_datatset,batch_size=batch_size,shuffle=True
)

2.2 残差模块

构建残差神经网络模型,与一般神经网络搭建类似,但需要判断输出是否为短接加和。代码如下:

class ResidualBlock(nn.Module):def __init__(self, in_channels, out_channels, stride=1, downsample=None):super(ResidualBlock, self).__init__()self.conv1 = conv3x3(in_channels, out_channels, stride)self.bn1 = nn.BatchNorm2d(out_channels)self.relu = nn.ReLU(inplace=True)self.conv2 = conv3x3(out_channels, out_channels)self.bn2 = nn.BatchNorm2d(out_channels)self.downsample = downsampledef forward(self, x):residual = xout = self.conv1(x)out = self.bn1(out)out = self.relu(out)out = self.conv2(out)out = self.bn2(out)if self.downsample:residual = self.downsample(x)out += residualout = self.relu(out)return out

2.3 Resnet模型搭建

构建Resnet整体网络模型。代码如下:

class ResNet(nn.Module):def __init__(self, block, layers, num_classes=10):super(ResNet, self).__init__()self.in_channels = 16self.conv = conv3x3(1, 16)self.bn = nn.BatchNorm2d(16)self.relu = nn.ReLU(inplace=True)self.layer1 = self.make_layer(block, 16, layers[0])self.layer2 = self.make_layer(block, 32, layers[1], 2)self.layer3 = self.make_layer(block, 64, layers[2], 2)self.avg_pool = nn.AvgPool2d(8)self.fc = nn.Linear(64, num_classes)def make_layer(self, block, out_channels, blocks, stride=1):downsample = Noneif (stride != 1) or (self.in_channels != out_channels):downsample = nn.Sequential(conv3x3(self.in_channels, out_channels, stride=stride),nn.BatchNorm2d(out_channels))layers = []layers.append(block(self.in_channels, out_channels, stride, downsample))self.in_channels = out_channelsfor i in range(1, blocks):layers.append(block(self.in_channels, out_channels))return nn.Sequential(*layers)def forward(self, x):out = self.conv(x)out = self.bn(out)out = self.relu(out)out = self.layer1(out)out = self.layer2(out)out = self.layer3(out)out = self.avg_pool(out)out = out.view(out.size(0), -1)out = self.fc(out)return out
model = ResNet(ResidualBlock, [2, 2, 2]).to(device)

2.4 模型训练

同一般网络模型训练相同,包括数据转为GPU读入格式,模型计算输出,设置损失函数计算损失,梯度置零初始化,误差反向传播和参数更新等,代码如下:

for epoch in range(num_epochs):for i, (images, labels) in enumerate(train_loader):images = images.to(device)labels = labels.to(device)outputs = model(images)loss = criterion(outputs, labels)optimizer.zero_grad()loss.backward()optimizer.step()if (i + 1) % 100 == 0:print("Epoch[{}/{}], Step[{}/{}] Loss: {:.4f}".format(epoch + 1, num_epochs, i + 1, total_step, loss.item()))losss.append(loss.item())

完整代码:

链接:

https://pan.baidu.com/s/1PwDHFI70k7pzpMdATulG_g

提取码:k2kq

李秋键,CSDN博客专家,CSDN达人课作者。硕士在读于中国矿业大学,开发有taptap竞赛获奖等。

相关文章:

JHipster开发环境安装

这里采用官方推荐的Yarn安装方法,默认操作系统为CentOS 7.4。 1 安装JDK 推荐版本:OpenJDK 1.8.0-64bit。 完整安装说明,请参考这里 2 安装Nodejs 推荐版本: v8.11.3 完整安装说明,请参考这里 3 安装Yarn 推荐版本&…

用C语言写PHP扩展

用C语言写PHP扩展 1:预定义 在home目录,也可以其他任意目录,写一个文件,例如caleng_module.def 内容是你希望定义的函数名以及参数: int a(int x,int y)string b(string str,int n) 2:到php源码目录的ext目…

Pandas 数据挖掘与分析时的常用方法

今天我们来讲一下用Pandas模块对数据集进行分析的时候,一些经常会用到的配置,通过这些配置的帮助,我们可以更加有效地来分析和挖掘出有价值的数据。数据集的准备这次我们需要用到的数据集是广为人所知的泰坦尼克号的乘客数据,我们…

MySQL基本概念

1. 分清几个概念:数据库,数据库对象和数据; 数据库分为:系统数据库和用户数据库; 系统数据库 是安装完MySQL服务器后自带的数据库,会记录一些必要的信息,用户不能直接修改这些系统数据库。转载…

SpringMvc+ajax实现文件跨域上传

最近开始学习SpringMVC框架,在学习数据绑定的时候,发现可以使用RequestParam注解绑定请求数据,实现了文件上传。但是如果一个项目是前后端分离的,前端系统向后端服务上传文件该怎么解决了? 首先考虑前端用哪一种方式进…

使用Nmap获取目标服务器开放的服务以及操作系统信息

http://nmap.org/download.html 1.下载安装rpm -vhU http://nmap.org/dist/nmap-5.61TEST5-1.i386.rpmrpm -vhU http://nmap.org/dist/zenmap-5.61TEST5-1.noarch.rpmrpm -vhU http://nmap.org/dist/ncat-5.61TEST5-1.i386.rpmrpm -vhU http://nmap.org/dist/nping-0.5.61TEST5…

Pandas 数据类型概述与转换实战

作者 | 周萝卜 来源 | 萝卜大杂烩 在进行数据分析时,确保使用正确的数据类型是很重要的,否则我们可能会得到意想不到的结果或甚至是错误结果。对于 pandas 来说,它会在许多情况下自动推断出数据类型 尽管 pandas 已经自我推断的很好了&#x…

7.10 数据注解特性--NotMapped

NotMapped特性可以应用到领域类的属性中,Code-First默认的约定,是为所有带有get,和set属性选择器的属性创建数据列。。 NotManpped特性打破了这个约定,你可以使用NotMapped特性到某个属性上面,然后Code-First就不会为这个属性就不…

Condition

2019独角兽企业重金招聘Python工程师标准>>> 1、Condition的简介 线程通信中的互斥除了用synchronized、Object类的wait()和notify()/notifyAll()方式实现外,方法JDK1.5中提供的Condition配套Lock可以实现相同的功能。Condition中的await()和signal()/si…

使用who.is查域名DNS信息以及用sameip.org查其他网站

www.who.is网站可以查域名信息,非常好用:例如查 hack-test.com然后我们可以找找同个IP上的其他站点(旁站:sameip.org)参考: 黑客是怎么攻击一个网站的?

基于 OpenCV 的人脸追踪

作者 | 努比 来源 | 小白学视觉 在Raspberry上启动项目很简单,所以让我们开始吧。 01. 产品清单 Raspberry Pi 4 Model B — 4GB 适用于Raspberry Pi的Pan-Tilt HAT Pi Camera v2 8MP 微型SD卡 迷你HDMI电缆 Raspberry Pi摄像头电缆—尺寸:457mm x …

-bash: /bin/rm: Argument list too long的解决办法

-bash: /bin/rm: Argument list too long的解决办法 当目录下文件太多时,用rm删除文件会报错: -bash: /bin/rm: Argument list too long 提示文件数目太多。 解决的办法是使用如下命令: ls | xargs -n 10 rm -fr ls 输出所有的文件名(用…

React使用ES6语法重构组件代码

首次使用react&#xff0c;要注意react不同版本库&#xff0c;是ES5还是ES6的写法&#xff0c;如何做到统一。下面对于ES6语法重构组件的代码如下&#xff1a;&#xff08;1&#xff09;原始代码&#xff1a; <script type"text/babel">var destinationdocumen…

PHP哈希表碰撞攻击原理

哈希表碰撞攻击&#xff08;Hashtable collisions as DOS attack&#xff09;的话题不断被提起&#xff0c;各种语言纷纷中招。本文结合PHP内核源码&#xff0c;聊一聊这种攻击的原理及实现。 哈希表碰撞攻击的基本原理 哈希表是一种查找效率极高的数据结构&#xff0c;很多语言…

Java8(jdk1.8)中文档注释处理工具javadoc的环境参量配置及使用方法

Java8(jdk1.8)中文档注释处理工具javadoc的环境参量配置及使用方法Java语言提供了一种功能强大的注释形式&#xff1a;文档注释。如果编写Java源代码时添加了合适的文档注释&#xff0c;然后通过JDK提供的javadoc工具可以直接将源代码里的文档注释提取成一份系统的API文档。jav…

如何读取Excel表格中不同sheet表的同一位置单元格数据,并绘制条形图呢?

作者 | 黄伟呢来源 | 数据分析与统计学之美今天&#xff0c;有位朋友在群里面咨询了一个问题&#xff1a;如何读取Excel表格中"不同sheet表"的同一位置单元格数据&#xff0c;并绘制条形图呢&#xff1f;有人提议用vba&#xff0c;但是不得不说&#xff0c;没有学过v…

vue-router学习笔记

配置路由模式 const routernew VueRouter({routes }) hash模式(默认):通过url的hash来模拟一个完整的url&#xff0c;于是当url改变时&#xff0c;页面不会重新加载。history模式&#xff1a;通过history完成url跳转而不需要重新加载页面。注意&#xff1a;为了防止404错误&…

PHP防止注入攻击

注入攻击不多说了PHP addslashes() 函数--单撇号加斜线转义PHP String 函数定义和用法addslashes() 函数在指定的预定义字符前添加反斜杠。这些预定义字符是&#xff1a;单引号 ()双引号 (")反斜杠 (\)NULL语法addslashes(string)参数描述string必需。规定要检查的字符串。…

首届腾讯数字安全创新大赛在京启动,挖掘新锐力量推动产业创新

3月10日&#xff0c;首届腾讯数字安全创新大赛在京正式启动。本次大赛由腾讯安全和中国产业互联网发展联盟联合主办&#xff0c;腾讯安全、KEEN、元起资本、赛博英杰、数世咨询等多家企业联合发起&#xff0c;中国产业互联网发展联盟安全专委会承办。 大赛旨在寻找网络安全新力…

oracle数据库无监听程序

在电脑---服务---启动oracle tns 如果还是出现错误的话&#xff0c;找到Net Manager&#xff0c;将网络的ip监听删除&#xff0c;将本机的主机名配好&#xff0c;即可打开tns服务 转载于:https://www.cnblogs.com/jiangsheng3/p/5025201.html

个人开发者即时到账收款方案 BufPay.com

BufPay 个人即时到账支付平台前言 作为独立开发者&#xff0c;一般只有一个人独立奋战&#xff0c;做出了产品需要收款是非常麻烦的&#xff0c;接入支付宝微信支付都需要公司公户&#xff0c;而注册公司、开公户等一系列操作非常麻烦&#xff0c;成本也很高一年也要 1w 左右。…

用 Python 制作数据大屏,超简单

作者 | 俊欣来源 | 关于数据分析与可视化今天我们用Streamlit模块来制作一个数据面板&#xff0c;将数据更加直观地呈现给别人观看&#xff0c;整个页面大致如下图所示&#xff1a;制作工具栏在页面的左侧是一个工具栏&#xff0c;工具栏中有多个按钮&#xff0c;分别是“About…

Oracle 12C -- 清空audit记录

1.使用job清空 SQL> dbms_audit_mgmt.create_purge_job(audit_trail_type> DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED,audit_trail_purge_interval>12&#xff0c;audit_trail_purge_name>audit_trail_pj,use_last_arch_timestamp>TRUE,container>dbms_audit_mgm…

魔法引用函数magic_quotes_gpc和magic_quotes_runtime的区别和用法

PHP提供两个方便我们引用数据的魔法引用函数magic_quotes_gpc和magic_quotes_runtime&#xff0c; 这两个函数如果在php.ini设置为ON的时候&#xff0c;就会为我们引用的数据碰到单引号和双引号"是自动加上反斜线&#xff0c;帮我们自动转译符号&#xff0c;确保数据操作的…

Unity脚本生成插件:Script Create Dialog

最近写代码又犯懒了...感觉每次新建脚本都要写一堆简单重复的东西好无聊&#xff0c;所以搜索了一下有没有自动生成脚本的插件。结果还真被我发现了&#xff0c;官方在N久之前就制作了自动生成脚本的插件[Script Create Dialog]&#xff0c;大概是名字起的和脚本生成器相差太多…

多路IO复用模型 select epoll 等

同步阻塞IO在等待数据就绪上花去太多时间&#xff0c;而传统的同步非阻塞IO虽然不会阻塞进程&#xff0c;但是结合轮询来判断数据是否就绪仍然会耗费大量的CPU时间。多路IO复用提供了对大量文件描述符进行就绪检查的高性能方案。selectselect诞生于4.2BSD&#xff0c;在几乎所有…

可操作性强!Python实现一个电影订票系统!

来源丨Python小二一、效果展示通过Python实现一个电影订票系统&#xff0c;效果如下所示&#xff1a;二、整体结构图三、代码分解3.1 infos.py一部电影的详细信息适合用 字典 结构来存储&#xff0c;我们可以给字典里添加多个键值对来保存电影的名称、座位表和宣传时用的字符画…

centos7 install mysql

1. 下载mysql的repo源 $ wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm 2. 安装mysql-community-release-el7-5.noarch.rpm包 $ sudo rpm -ivh mysql-community-release-el7-5.noarch.rpm 安装这个包后&#xff0c;会获得两个mysql的yum repo源&#x…

unity加载ab后,场景shader不起效问题(物件表现黑色)

需要把unity自带的shader&#xff0c;加入到默认列表转载于:https://www.cnblogs.com/lancidie/p/9293827.html

Linux下各类TCP网络服务器的实现源代码

http://www.linuxeden.com/forum/t146870.html大家都知道各类网络服务器程序的编写步骤&#xff0c;并且都知道网络服务器就两大类&#xff1a;循环服务和并发服务。这里附上源代码来个小结吧。首先&#xff0c;循环网络服务器编程实现的步骤是这样的&#xff1a; 这种服务器模…