深度学习从入门到放弃 | 有代码!今天就掌握深度学习超人气组件 —— 残差块(Residual Block)

文摘   2024-10-22 20:03   新加坡  
点击订阅公众号 | 前沿学术成果每日更新               

目录

  • 什么是残差块

  • 残差块的底层原理解读

  • 残差块的实现代码

  • 实现波士顿房价预测及代码

什么是残差块

残差块(Residual Block)的概念是在2015年论文《Deep Residual Learning for Image Recognition》中提出的,这篇论文由由微软实验室中的何凯明等几位大神(Kaiming He、Xiangyu Zhang、Shaoqing Ren和Jian Sun)撰写,并在2015年的计算机视觉国际会议(CVPR 2016)上发表。该论文介绍了残差网络(ResNet),它通过引入残差学习框架来解决深层神经网络训练中的退化问题,即随着网络深度的增加,网络性能趋于饱和甚至下降。

残差块是残差网络的核心组件,其基本思想是通过添加跨层连接(shortcut connections或skip connections),允许信息直接从一层传递到另一层,从而绕过中间的一层或多层。这种结构有助于缓解梯度消失/爆炸/网络退化的问题,并且可以让更深的网络更容易优化和训练。残差块通常包含两个或三个卷积层,以及一个用于将输入直接加到输出上的跳跃连接。如果输入与输出的维度不匹配,则可以使用线性投影(例如,1x1卷积)来调整维度。

自提出以来,残差网络及其变体已经成为许多计算机视觉任务的标准架构之一,极大地推动了深度学习领域的发展。

残差块的底层原理解读

  1. 如果有堆叠的网络层(F(X))实现了一个不可知的映射H(x) (在这里又称为原始映射),也就是说F(x)将是H(x)的近似函数,其中x表示输入到这些层中的第一层。
  2. 现在,我们期待这些堆叠的网络层(F(X))逼近一个新的映射H(x) -x,这里也可以说F(x)是H(x) -x的逼近函数。那么这个不可知的原始映射H(x)就的逼近函数就该是F(x)+x。

F(x)+x的公式可以通过具有“捷径连接”(shortcut connection)的前馈神经网络来实现,这个关系如图2所示。尽管两种形式应该都能H(x) ,但学习的难易程度可能是不同的。

image-20241021231322632

图来自:He, K., Zhang, X., Ren, S., Sun, J., 2016. Deep Residual Learning for Image Recognition. Presented at the Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition, pp. 770–778.

一个更好理解的例图(左图传统网络连接,右图残差连接):

如图2所示的一个残差块的的数学表达式如下:

这里的 是被考虑的层的输入和输出向量。函数 表示要学习的残差映射。对于图2中的示例,它有两层,,其中 表示ReLu激活函数

注意,这里省略了偏置项,以简化表达。

操作 是通过一条捷径连接和按元素(element-wise)的加法来执行的。在加法之后再次采用ReLu激活函数(即,见图2)。方程(1)中的捷径连接既不引入额外参数也不增加计算复杂度。这不仅在实践中具有吸引力,而且在将普通网络和残差网络进行比较时也很重要。我们可以公正地比较同时具有相同数量的参数、深度、宽度和计算成本(除了可忽略的按元素加法之外)的普通/残差网络。

在方程(1)中, 的维度必须相等。如果不是这种情况(例如,改变输入/输出通道时),我们可以通过捷径连接执行一个线性投影 来匹配维度:

通过实验表明,恒等映射(identity mapping,图2中的X identity)足以解决网络退化问题,并且更经济,因此 只在匹配维度时使用。残差函数 的形式是灵活的,如图5。

image-20241021233605241

图来自:He, K., Zhang, X., Ren, S., Sun, J., 2016. Deep Residual Learning for Image Recognition. Presented at the Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition, pp. 770–778.

图5展示了一个有两层或三层的函数 。但如果 只有一层,方程(1)就类似于线性层:

如果是这样,就没有了没有明显的优势。

虽然上述表示是关于全连接层的简化,但它们也适用于卷积层。函数 可以代表多个卷积层。按元素加法是在两个特征图上进行的,按通道进行。

更多信息建议阅读原论文,或者更多灵感

残差块的实现代码

以下代码可以直接的整合到自己的模型以及实验中

import tensorflow as tf
from tensorflow.keras import layers, Model


class ResidualBlock(layers.Layer):
    def __init__(self, units, activation='relu', **kwargs):
        super(ResidualBlock, self).__init__(**kwargs)
        self.dense1 = layers.Dense(units, activation=activation)
        '''
        这是标准的残差块实现方式就是有self.dense2。第一个全连接层 self.dense1 通常带有激活函数(如 ReLU),而第二个全连接层 self.dense2 不带激活函数。这样设计的原因是希望残差块能够学习到输入和输出之间的差异,而不是直接学习完整的映射。
        '''

        self.dense2 = layers.Dense(units, activation=None)  # No activation here
        self.shortcut = None  # Placeholder for the shortcut connection

    def build(self, input_shape):
        # 如果输入和输出维度不同,则添加一个线性变换层
        if input_shape[-1] != self.dense2.units:
            self.shortcut = layers.Dense(self.dense2.units, activation=None# 在全连接层的情况下是线性变换,相当于1x1卷积

    def call(self, inputs):
        x = self.dense1(inputs)
        x = self.dense2(x)

        # 如果输入和输出维度不同,使用线性变换层即进行调整
        if self.shortcut is not None:
            inputs = self.shortcut(inputs)
        """
        layers.add 操作执行的是逐元素相加,即 outputs = inputs + x。这种操作实现了残差连接,使得网络可以学习到输入和处理后的输出之间的残差。
        """

        return layers.add([inputs, x])  # Add the skip connection

代码解释:上述代码可以在TensorFlow 2.0框架中使用,由于是采用的自定义网络层的方法将残差块封装为类,其使用就像普通Dense层一样也直接添加到自己的网络中。例如:

  • 原来的由Dense层的引入是:

    self.dense_layers = []
    self.dense_layers.append(layers.Dense(units=units_per_layer, activation='relu'))
  • 那么,残差块的引入是:

    self.dense_layers = []
    elf.dense_layers.append(ResidualBlock(units=units_per_layer, activation='relu'))

是不是没有区别?

实现波士顿房价预测及代码

现在利用上面的残差块以及残差网络,进行波士顿房价的预测。

波士顿房价数据集(Boston House Price Dataset)是一个经典的回归问题数据集,常用于机器学习算法的教学和测试。这个数据集包含了美国马萨诸塞州波士顿地区不同郊区的住房数据。它最初由Harrison, D. 和 Rubinfeld, D.L. 在1970年代收集,并在统计学界广泛使用。

数据集特征 波士顿房价数据集包含了506个样本,每个样本有13个数值型特征,以及一个目标变量,即房屋的中位数价格(以千美元计)。这些特征描述了影响房价的各种因素,包括犯罪率、房产税率等。以下是这些特征的详细列表:

CRIM: 按城镇划分的人均犯罪率。ZN: 超过25,000平方英尺住宅用地的比例。INDUS: 城镇中非零售商业用地面积比例。CHAS: 查尔斯河虚拟变量(如果靠近河流则为1;否则为0)。NOX: 一氧化氮浓度(每千万分之一)。RM: 每个住宅的平均房间数。AGE: 1940年之前建成的自住单位比例。DIS: 到波士顿五个中心区的加权距离。RAD: 径向公路可达性指数。TAX: 每万美元的全额财产税率。PTRATIO: 城镇师生比例。B: 1000(Bk - 0.63)^2,其中Bk是按城镇划分的非洲裔美国人比例。LSTAT: 低收入阶层人口百分比。

所使用的残差网络结构,有10个残差层,每个层的节点数为2,采用MAE以及MAPE作为模型评价指标,学习率为0.01,共训练200 epochs。以下是训练过程的过程误差和预测结果:

  • 训练过程的过程误差:

    image-20241022191158876
  • 预测结果:

    image-20241022191312573

🌟关于该实验的完整代码🌟

首先非常感谢朋友们对我的文章和公众号的支持!非常高兴能和大家分享一些文献和机器学习相关信息。如果你觉得这篇文章对你有帮助,并对完整的代码感兴趣,两步就可以得到这份代码啦:1)将我的公众号文章(任一)分享到朋友圈,并收集到10个赞;2)完成后,请将分享截图后台私信给我并留下邮箱,我将会稍后发送完整的实验代码给您作为感谢。

这样不仅可以帮助更多的人获得有价值的信息,也能鼓励我继续创作出更多优质内容。感谢你的支持与理解,期待你的截图哦!😊

               

               

声明:本公众号分享的前沿学术成果来源于各学术网站,不依法享有其所有权。若原作者发现本次分享中的文字及图片涉及侵权,请立刻联系公众号后台或发送邮件,我们将及时修改或删除!         

邮箱:environmodel@sina.com         

若您认为有用,欢迎

Environmodel设为星标,或

点击“在看”或“分享”给他人

Environmodel
Environmodel(环境模型)专注于环境科学与工程领域的建模及模型研究进展,并分享涵盖机器学习、深度学习以及人工智能等相关领域的理论知识、主流工具和Python编程技巧。
 最新文章