计算机系统应用教程网站

网站首页 > 技术文章 正文

机器学习:从头开始编写 ResNet

btikc 2024-09-09 01:42:10 技术文章 18 ℃ 0 评论

ResNet 的架构

来源:维基共享资源,根据知识共享署名 -相同方式共享 4.0 国际许可协议获得许可。

早在 2010 年代初,自从 AlexNet 赢得 2012 年 ImageNet 竞赛以来,人们就一直致力于让这些架构变得更深,这意味着要添加越来越多的层,但研究人员发现,仅仅增加深度并不能提高性能,相反,更深的模型实际上比浅层模型表现更差。人们发现,造成这种情况的原因是梯度消失/爆炸。因此,在 2015 年,来自微软的研究人员引入了残差网络架构,他们使用快捷方式/跳过连接让梯度更容易地流过网络。

来源:维基共享资源,根据知识共享署名 -相同方式共享 4.0 国际许可协议获得许可。

对于 ResNet-50,研究人员引入了这些瓶颈架构,首先使用 1x1 卷积降低维度,然后使用 3x3 卷积执行主要计算,最后使用另一个 1x1 卷积恢复维度。由于训练时间受限,这种瓶颈的主要目标是减少计算并提高效率。

ResNet-50 从头实现

好吧,让我们看看这个架构在代码中是什么样的,

以上代码基于:pytorch resnet 代码

一次性解释代码会非常困难,因此我将把它分解成更小的块来逐步解释架构,但首先让我们了解一些常见主题:

卷积

来源:维基共享资源,根据知识共享署名 -相同方式共享 4.0 国际许可协议获得许可。

在架构中,我们看到了 1x1 卷积或 7x7 卷积之类的东西,但这到底是什么意思呢?卷积可以简单地被认为是在整个输入上滑动一个过滤器,然后每个位置的过滤器执行元素乘法和求和,生成捕获边缘等局部信息的特征图,这些过滤器权重就是我们在训练期间最终要学习的!要记住的关键一点是,这些过滤器总是扩展输入体积的整个深度。对于图像,卷积通常比全连接层更受欢迎,因为它们通过保留像素之间的空间关系可以更好地捕获局部数据,还可以减少要学习的参数总数。

这里需要记住的一些关键术语是:

  • 步幅——用于指定滤波器在输入上移动的步长
  • 填充——用于指定在输入中添加额外的像素,以控制输出的尺寸并保留边框信息。
  • 内核大小——这是我们的过滤器的大小,以高 x 宽来描述
  • 输入通道——这是输入通道的数量
  • 输出通道——这是卷积层产生的输出通道的数量

卷积需要记住的一个关键公式是:

当没有明确说明时,上述公式对于确定填充或步幅应该是多少非常有用。

为什么我们需要批量标准化?

批量归一化是一种广泛采用的技术,可以更快、更稳定地训练深度神经网络。批量归一化将每层的输入标准化,使每个小批量内的平均值为 0,方差为 1。当它在 2015 年首次推出时,据说这种更快、更稳定的训练的原因是批量归一化减少了内部协方差偏移,但在2019 年的一篇论文中,作者认为 BatchNorm 通过使损失图景更加平滑来影响网络训练,从而有助于训练网络。

为什么我们需要非线性?

我们在架构中引入了非线性(ReLU),以便我们能够学习复杂的非线性决策边界。如果我们不使用非线性,那么我们的模型就只是一堆线性运算,无论其深度如何。

为什么需要池化?

池化减少了特征图的空间维度,有助于减少计算量和参数数量。它独立地对每个激活图进行操作。池化有助于提取清晰(maxpool)和平滑(avgpool)的特征。池化的工作也可以通过增加步幅的卷积来完成,但池化的计算速度比卷积更快。

代码演练

好的,现在让我们看一下代码,了解每个部分的作用

好的,首先我们的输入形状为 [批量大小、通道、高度、宽度],对我们来说是 [1, 3, 224, 224]。它首先经过步长为 2、填充为 3 的 7x7 卷积,然后经过批量归一化,最后经过 ReLU。然后它经过步长为 2、填充为 1 的 3x3 最大池化,最终尺寸为 [1, 64, 56, 56]。测试您的架构是否具有正确尺寸的一个好方法是传递一个随机张量来查看输出的形状。

好的,接下来我们将重点介绍这些层。在每一层中,输出通道是 4* 中间通道,每一层由重复一定次数的瓶颈块组成。layer_channels 数组保存瓶颈层的中间通道,layer_repeats数组保存每一层重复的次数。对于每一层,我们调用一个函数“layer”,该函数返回该层中每个操作顺序的顺序容器。每一层都由瓶颈块组成,我们将在下文中看到

在每个瓶颈块中,卷积都按上述顺序应用,最后,我们将输入重新添加到输出中以进行残差连接。下采样部分是必需的,以确保输入转换为与输出相同的空间维度,以便将它们相加。

经过所有这些层之后,我们最终进行自适应平均池化,然后将其通过具有所需数量的输出类的完全连接层以获得最终输出。

我在 CIFAR-10 上测试了我的实现,经过 10 个时期的训练后,我的从头开始的实现获得了 75% 的准确率,而使用pretrained=False从 pytorch 训练 resnet50获得了 77% 的准确率。

概括

正如我们上面看到的,自己实现 ResNet 非常简单,而且它是一个非常好的模型,可以用来学习基础知识。ResNet 对残差连接的使用简化了深度网络的训练,并提供了一种很好的方式来理解与深度学习架构相关的挑战和解决方案。在应用方面,CNN 在计算机视觉领域非常受欢迎,可用于图像分类、对象检测、分割等任务。

参考:

https://levelup.gitconnected.com/deeper-is-better-coding-resnet-from-scratch-b90ee301a301

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表