介绍

我们需要训练更深的网络来执行复杂的任务。训练深度神经网络很复杂,不仅限于过度拟合、高计算成本,而且还有一些不一般的问题。我们将解决这些问题,以及深度学习社区的人们是如何解决这些问题的。让我们进入文章吧!

目录

  1. 为什么需要跳过连接?

  2. 什么是跳过连接?

  3. 跳过连接的变体

  4. 跳过连接的实现

为什么要跳过连接?

深度神经网络的美妙之处在于它们可以比浅层神经网络更有效地学习复杂的功能。在训练深度神经网络时,模型的性能随着架构深度的增加而下降。这被称为退化问题

但是,随着网络深度的增加,模型的性能下降的原因可能是什么?让我们尝试了解退化问题的原因。

可能的原因之一是过度拟合。随着深度的增加,模型往往会过度拟合,但这里的情况并非如此。从下图可以看出,56 层的深层网络比 20 层的浅层网络具有更多的训练误差。较深的模型表现不如浅模型好。 显然,过拟合不是这里的问题。

20 层和 56 层 NN 的训练和测试误差

另一个可能的原因可能是梯度消失和/或梯度爆炸问题。然而,ResNet(https://arxiv.org/abs/1512.03385)的作者(He 等人)认为,使用批量归一化和通过归一化正确初始化权重可确保梯度具有合适的标准。但是,这里出了什么问题?让我们通过构造来理解这一点。

考虑一个在数据集上训练的浅层神经网络。此外,考虑一个更深的网络,其中初始层与浅层网络(下图中的蓝色层)具有相同的权重矩阵,并添加了一些额外的层(绿色层)。我们将添加层的权重矩阵设置为恒等矩阵(恒等映射)。

从这个构造来看,更深的网络不应产生比其浅的网络更高的训练误差,因为我们实际上是在具有附加恒等层的更深网络中使用浅模型的权重。

但实验证明,与浅层网络相比,深层网络会产生较高的训练误差。这表明更深层无法学习甚至恒等映射

训练精度的下降表明并非所有系统都同样易于优化。

主要原因之一是权重的随机初始化,均值在零、L1 和 L2 正则化附近。结果,模型中的权重总是在零左右,因此更深的层也无法学习恒等映射。

这里出现了跳过连接的概念,它使我们能够训练非常深的神经网络。现在让我们学习这个很棒的概念。

什么是跳过连接?

顾名思义,Skip Connections(或 Shortcut Connections),跳过连接,会跳过神经网络中的某些层,并将一层的输出作为下一层的输入。

引入跳过连接是为了解决不同架构中的不同问题。在 ResNets 的情况下,跳过连接解决了我们之前解决的退化问题,而在 DenseNets 的情况下,它确保了特征的可重用性。我们将在以下部分详细讨论它们。

甚至在残差网络之前,有的文献中就引入了跳过连接。例如,Highway Networks(https://arxiv.org/abs/1505.00387)(Srivastava 等人)跳过了与控制和学习信息流到更深层的门的连接。这个概念类似于 LSTM 中的门控机制。尽管 ResNets 实际上是 Highway Networks的一个特例,但与 ResNets 相比,其性能并不达标。这表明保持 Highway 梯度的畅通比gate机制更好!

神经网络可以学习任意复杂度的任何函数,可以是高维和非凸函数。可视化有可能帮助我们回答几个关于神经网络为何起作用的重要问题。

实际上,Li 等人(https://arxiv.org/abs/1712.09913)做了一些不错的工作。这使我们能够可视化复杂的损失表面。具有跳过连接的网络的结果更令人惊讶!

有跳过连接和没有跳过连接的 ResNet-56 的损失表面

正如你在此处看到的,具有跳跃连接的神经网络的损失表面更平滑,因此比没有任何跳跃连接的网络收敛速度更快。让我们在下一节中看到跳过连接的变体。

跳过连接的变体

在本节中,我们将看到不同架构中跳过连接的变体。跳过连接可以在神经网络中以两种基本方式使用:加法和串联。

残差网络(ResNets)

残差网络是由 He 等人提出的。2015年解决图像分类问题。在 ResNets 中,来自初始层的信息通过矩阵加法传递到更深层。此操作没有任何附加参数,因为前一层的输出被添加到前面的层。具有跳过连接的单个残差块如下所示:

残差块

由于 ResNet 的更深层表示,因为来自该网络的预训练权重可用于解决多个任务。它不仅限于图像分类,还可以解决图像分割、关键点检测和对象检测方面的广泛问题。因此,ResNet 是深度学习社区中最具影响力的架构之一。

接下来,我们将了解 DenseNets 中受 ResNets 启发的另一种跳过连接的变体。

我建议你阅读以下资源以详细了解 ResNet

  • 了解 ResNet 并分析 CIFAR-10 数据集上的各种模型:https://www.analyticsvidhya.com/blog/2021/06/understanding-resnet-and-analyzing-various-models-on-the-cifar-10-dataset/

卷积网络 (DenseNets)

DenseNets(https://arxiv.org/abs/1608.06993)是由 Huang 等人提出的。

ResNets 和 DenseNets 之间的主要区别在于 DenseNets 将层的输出特征图与下一层连接而不是求和。

谈到跳过连接,DenseNets 使用串联,而 ResNets 使用求和

串联背后的想法是在更深的层中使用从早期层学习的特征。这个概念被称为特征可重用性。因此,DenseNets 可以用比传统 CNN 更少的参数来学习映射,因为不需要学习冗余映射。

U-Net:用于生物医学图像分割的卷积网络

跳跃连接的使用也影响了生物医学领域。U-Net(https://arxiv.org/abs/1505.04597)是由 Ronneberger 等人提出的。用于生物医学图像分割。它有一个编码器-解码器部分,包括 Skip Connections。

整体架构看起来像英文字母“U”,因此得名 U-Nets。

编码器部分中的层与解码器部分中的层进行跳跃连接和级联(在上图中以灰线形式提及)。这使得 U-Nets 使用在编码器部分学习的细粒度细节在解码器部分构建图像。

这些类型的连接是长跳跃连接,而我们在 ResNets 中看到的是短跳跃连接。更多关于 U-Nets在这里:https://medium.com/analytics-vidhya/deep-learning-image-segmentation-and-localization-u-net-architecture-ea4cff5595d9。

让我们实现一个讨论过的架构块以及如何在 PyTorch 中加载和使用它们!

跳过连接的实现

在本节中,我们将从头开始使用 Skip Connections 构建 ResNets 和 DesNets。你兴奋吗?我们开始吧!

ResNet – 残差块

首先,我们将使用跳过连接实现一个残差块。PyTorch 是首选,因为它具有超酷的特性——面向对象的结构。

# import required libraries
import torch
from torch import nn
import torch.nn.functional as F
import torchvision# basic resdidual block of ResNet
# This is generic in the sense, it could be used for downsampling of features.
class ResidualBlock(nn.Module):def __init__(self, in_channels, out_channels, stride=[1, 1], downsample=None):"""A basic residual block of ResNetParameters----------in_channels: Number of channels that the input haveout_channels: Number of channels that the output havestride: strides in convolutional layersdownsample: A callable to be applied before addition of residual mapping"""super(ResidualBlock, self).__init__()self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride[0], padding=1, bias=False)self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=stride[1], padding=1, bias=False)self.bn = nn.BatchNorm2d(out_channels)self.downsample = downsampledef forward(self, x):residual = x# applying a downsample function before adding it to the outputif(self.downsample is not None):residual = downsample(residual)out = F.relu(self.bn(self.conv1(x)))out = self.bn(self.conv2(out))# note that adding residual before activation out = out + residualout = F.relu(out)return out

由于我们手上有一个 Residual 块,我们可以构建任意深度的 ResNet 模型!让我们快速构建ResNet-34的前五层,以了解如何连接残差块。

# downsample using 1 * 1 convolution
downsample = nn.Sequential(nn.Conv2d(64, 128, kernel_size=1, stride=2, bias=False),nn.BatchNorm2d(128)
)
# First five layers of ResNet34
resnet_blocks = nn.Sequential(nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False),nn.MaxPool2d(kernel_size=2, stride=2),ResidualBlock(64, 64),ResidualBlock(64, 64),ResidualBlock(64, 128, stride=[2, 1], downsample=downsample)
)# checking the shape
inputs = torch.rand(1, 3, 100, 100) # single 100 * 100 color image
outputs = resnet_blocks(inputs)
print(outputs.shape)    # shape would be (1, 128, 13, 13)

PyTorch 为我们提供了一种简单的方法来加载具有在 ImageNet 数据集上训练的预训练权重的 ResNet 模型。

# one could also use pretrained weights of ResNet trained on ImageNet
resnet34 = torchvision.models.resnet34(pretrained=True)

DenseNet – 残差块

实现完整的残差网络会有点复杂。让我们一步一步实现。

  1. 实现一个 DenseNet 层

  2. 建立一个残差块

  3. 连接多个残差块得到一个残差网络模型

class Dense_Layer(nn.Module):def __init__(self, in_channels, growthrate, bn_size):super(Dense_Layer, self).__init__()self.bn1 = nn.BatchNorm2d(in_channels)self.conv1 = nn.Conv2d(in_channels, bn_size * growthrate, kernel_size=1, bias=False)self.bn2 = nn.BatchNorm2d(bn_size * growthrate)self.conv2 = nn.Conv2d(bn_size * growthrate, growthrate, kernel_size=3, padding=1, bias=False)def forward(self, prev_features):out1 = torch.cat(prev_features, dim=1)out1 = self.conv1(F.relu(self.bn1(out1)))out2 = self.conv2(F.relu(self.bn2(out1)))return out2

接下来,我们将实现一个由任意数量的残差网络层组成的残差块。

class Dense_Block(nn.ModuleDict):def __init__(self, n_layers, in_channels, growthrate, bn_size):"""A Dense block consists of `n_layers` of `Dense_Layer`Parameters----------n_layers: Number of dense layers to be stacked in_channels: Number of input channels for first layer in the blockgrowthrate: Growth rate (k) as mentioned in DenseNet paperbn_size: Multiplicative factor for # of bottleneck layers"""super(Dense_Block, self).__init__()layers = dict()for i in range(n_layers):layer = Dense_Layer(in_channels + i * growthrate, growthrate, bn_size)layers['dense{}'.format(i)] = layerself.block = nn.ModuleDict(layers)def forward(self, features):if(isinstance(features, torch.Tensor)):features = [features]for _, layer in self.block.items():new_features = layer(features)features.append(new_features)return torch.cat(features, dim=1)

从残差块中,让我们构建 DenseNet。在这里,为了简单起见,我省略了 DenseNet 架构(充当下采样)的过渡层。

# a block consists of initial conv layers followed by 6 dense layers
dense_block = nn.Sequential(nn.Conv2d(3, 64, kernel_size=7, padding=3, stride=2, bias=False),nn.BatchNorm2d(64),nn.MaxPool2d(3, 2),Dense_Block(6, 64, growthrate=32, bn_size=4),
)inputs = torch.rand(1, 3, 100, 100)
outputs = dense_block(inputs)
print(outputs.shape)    # shape would be (1, 256, 24, 24)# one could also use pretrained weights of DenseNet trained on ImageNet
densenet121 = torchvision.models.densenet121(pretrained=True)

尾注

在本文中,我们讨论了跳过连接对于训练深度神经网络的重要性,以及如何在 ResNet、DenseNet 和 U-Net 及其实现中使用跳过连接。我知道,这篇文章涵盖了很多不容易一口气掌握的理论。因此,如果你有任何想法,请随时发表评论。

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓

关于跳过连接你需要知道的一切相关推荐

  1. 主板跳线连接方法揭秘

    作为一名新手,要真正从头组装好自己的电脑并不容易,也许你知道CPU应该插哪儿,内存应该插哪儿,但遇到一排排复杂跳线的时候,很多新手都不知道如何下手. 钥匙开机其实并不神秘 还记不记得你第一次见到装电脑 ...

  2. [Xcode 实际操作]九、实用进阶-(24)使用Segue(页面的跳转连接)进行页面跳转并传递参数...

    目录:[Swift]Xcode实际操作 本文将演示使用Segue(页面的跳转连接)进行页面跳转并传递参数. 参照结合:[Xcode10 实际操作]九.实用进阶-(23)多个Storyboard故事板中 ...

  3. 主板跳线连接技巧图解

    作为一名新手,要真正从头组装好自己的电脑并不容易,也许你知道CPU应该插哪儿,内存应该插哪儿,但遇到一排排复杂跳线的时候,很多新手都不知道如何下手. 钥匙开机其实并不神秘 还记不记得你第一次见到装电脑 ...

  4. 计算机主机跳线连接图片,电脑主板跳线怎么接 电脑主板跳线接法【图文】

    我们大部分人对于电脑内部装置并不是非常熟悉,想要自己组装电脑也非常的不容易,也许你知道一些基本的电脑组装技能但面对电脑主板跳线相信大部分朋友还是非常头疼的,今天小编就来教大家如果你的电脑主板跳线如何接 ...

  5. 主板跳线连接方法揭秘[转载]

    作为一名新手,要真正从头组装好自己的电脑并不容易,也许你知道CPU应该插哪儿,内存应该插哪儿,但遇到一排排复杂跳线的时候,很多新手都不知道如何下手. 钥匙开机其实并不神秘 还记不记得你第一次见到装电脑 ...

  6. Windows 11 首次开机OOBE阶段跳过连接网络及登录微软账户,使用本地账号登录的方法

    2022/11/25更新: 以下方法最新版本的Win11 22H1上已失效,最新的方法是在第二步呼出cmd窗口,输入oobe\bypassnro,电脑会重启,再次来到连接网络的页面时选择"我 ...

  7. MS系统老是跳服务器连接不上,无法连接到 DESKTOP-G 1I39VQ\MSSQLSERVER01 解决方法

    SQL Sever在Windows10安装好后,今天用SQL Server Management Studio(SSMS)连接SQL Sever服务器的时候,却出现如下报错: 无法连接到 DESKTO ...

  8. 计算机主机跳线连接图片,电脑主板跳线怎么接?电脑机箱与主板跳线接法图解教程...

    电脑组装其实并不难,对于新手装机来说,最大的难点就是主板与机箱之间的跳线的接法,那么电脑主板跳线怎么接?下面小编分享一下电脑机箱与主板跳线接法图解教程. 这款机箱上的跳线如下,包括前置Usb跳线.前置 ...

  9. 电脑主板跳线_电脑主板跳线连接图

    有很多客户都会组装电脑,但是主板线不会插,今天我教下大家插主板上的线. 1. 这个是接电脑的开机.重启.硬盘指示灯,开机指示灯的线,机箱里面的线上面都是这几个字母的缩写, 开机power和硬盘灯有正反 ...

最新文章

  1. 谈谈机器学习模型的可解释性
  2. Vue2.0 + ElementUI 手写权限管理系统后台模板(一)——简述
  3. 在 Linux 中安装 jdk 和 Tomcat 中遇到的命令
  4. redis 启动加载mysql_Redis分析系列:启动加载过程
  5. phpcmsV9 数据库配置文件(查找、修改)
  6. 浅谈linux性能调优之六:IO调度算法的选择
  7. 【Axure RP8.1】一款专业的快速原型设计工具
  8. 面具更新自定义_面具Magisk如何从稳定版切换到测试版,面具版本切换教程
  9. Spring中的@Autowired,@Qualifier和@Primary注解
  10. LwIP协议栈之数据包pbuf
  11. MEME:motif分析的综合性工具
  12. k线形态python_Python量化分析之K线模式识别
  13. 工程建筑职业院校学校大专学校院校类网站源码织梦模板 (带手机版数据同步)
  14. 微信支付的服务器配置url超时,微信H5支付商家存在未配置的参数,请联系商家解决的...
  15. node 项目打包工具ncc
  16. SpringBoot+ Dubbo + Mybatis + Nacos +Seata整合来实现Dubbo分布式事务
  17. 《摄氏华氏温度转换》
  18. Java调用存储过程(返回:简单类型VARCHAR、自定义对象STRUCT、列表数组VARRAY)
  19. 从右下角出来的广告实例
  20. mysql计算两个日期间的工作时长(参数传入每天上班时间,并剔除周末)

热门文章

  1. 蓝牙耳机哪一款性价比最高?高性价比蓝牙耳机
  2. 【5. MySQL 的执行原理】
  3. RSA加密算法的数学原理
  4. BLOCK IO之PLUG/UNPLUG
  5. SD-WAN三种基础技术架构
  6. 解决chrome无访打开网页的问题,错误代码:ERR_FAILED
  7. window7 破解vs2008的补丁
  8. TechED 展台视频巡礼之联想篇
  9. ConstraintLayout的取消使用 修改默认使用linearLayout不是这个
  10. Knights in Chessboard (找规律)