目录
什么是残差块
残差块的底层原理解读
残差块的实现代码
实现波士顿房价预测及代码
什么是残差块
残差块(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卷积)来调整维度。
自提出以来,残差网络及其变体已经成为许多计算机视觉任务的标准架构之一,极大地推动了深度学习领域的发展。
残差块的底层原理解读
如果有堆叠的网络层(F(X))实现了一个不可知的映射H(x) (在这里又称为原始映射),也就是说F(x)将是H(x)的近似函数,其中x表示输入到这些层中的第一层。 现在,我们期待这些堆叠的网络层(F(X))逼近一个新的映射H(x) -x,这里也可以说F(x)是H(x) -x的逼近函数。那么这个不可知的原始映射H(x)就的逼近函数就该是F(x)+x。
F(x)+x的公式可以通过具有“捷径连接”(shortcut connection)的前馈神经网络来实现,这个关系如图2所示。尽管两种形式应该都能H(x) ,但学习的难易程度可能是不同的。
图来自: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。
图来自: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。以下是训练过程的过程误差和预测结果:
训练过程的过程误差:
预测结果:
🌟关于该实验的完整代码🌟
首先非常感谢朋友们对我的文章和公众号的支持!非常高兴能和大家分享一些文献和机器学习相关信息。如果你觉得这篇文章对你有帮助,并对完整的代码感兴趣,两步就可以得到这份代码啦:1)将我的公众号文章(任一)分享到朋友圈,并收集到10个赞;2)完成后,请将分享截图后台私信给我并留下邮箱,我将会稍后发送完整的实验代码给您作为感谢。
这样不仅可以帮助更多的人获得有价值的信息,也能鼓励我继续创作出更多优质内容。感谢你的支持与理解,期待你的截图哦!😊
声明:本公众号分享的前沿学术成果来源于各学术网站,不依法享有其所有权。若原作者发现本次分享中的文字及图片涉及侵权,请立刻联系公众号后台或发送邮件,我们将及时修改或删除!
邮箱:environmodel@sina.com
若您认为有用,欢迎
将Environmodel设为星标,或
点击“在看”或“分享”给他人