Alexnet论文介绍(超详细)——ImageNet Classification with Deep Convolutional Neural Networks
Posted 小卓搞AI
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Alexnet论文介绍(超详细)——ImageNet Classification with Deep Convolutional Neural Networks相关的知识,希望对你有一定的参考价值。
近期开始阅读cv领域的一些经典论文,本文整理计算机视觉的奠基之作——Alexnet
论文原文:ImageNet Classification with Deep Convolutional Neural Networks(有需要论文原文的可以私信联系我)
本文的阅读方法是基于李沐老师的B站讲解视频,需要细致去看的小伙伴可以去搜索,链接如下:
9年后重读深度学习奠基作之一:AlexNet【论文精读】_哔哩哔哩_bilibili
本文整理用于之后自己能够更快的回忆起这篇论文,所以有些地方记录的可能没那么严谨,有问题的地方欢迎各位指出和讨论,我及时修改,谢谢各位!
如果该论文笔记对你有所帮助,希望可以点个赞关注一下,之后会继续更新cv领域的一些经典论文的笔记,谢谢大家!
当我们在阅读一篇论文时,可以分为三遍阅读:
目录
Training on Multiple GPUs—用多个GPU训练
Local Response Normalization——局部归一化
第一遍阅读:
Abstract—摘要:
摘要简单总结来说提出了以下四点:
- 表示了我们用了一个深度卷积神经网络来进行图片分类,取得了一个非常好的效果。
- 深度卷积网络由60million个参数,65w个神经元,以及五个卷积层和三个全连接层组成。
- 为了加快训练,用到了GPU加速实现。
- 用了dropout这个正则化方法来减少过拟合。
Discussion—讨论
总结来说讨论就是作者的一些吐槽以及后续的一些工作打算,大概分为了以下三点:
- 我们的研究表明深度很重要,如果去掉一个卷积层,那么准确率会下降2%。(这一点现在看来没那么准确,因为少一层导致准确率下降也有可能是因为参数没找好,找好参数也可以达到之前的准确率的,所以现在来看,深度和宽度都很重要)
- 没有使用无监督进行预训练。这个是有一定历史背景的,在Alexnet网络提出之前有监督学习打不过无监督学习,但是在Alexnet提出之后,引起了有监督学习的热潮,直到最新的语言模型bert的提出,才慢慢的将人们又拉回了无监督学习。
- 最后提出想将更大更深的神经网络应用到video上,因为video计算量非常大,且有时序信息(时序信息有很多能帮助你理解在空间的图片信息)。时序信息在现在来看发展也是比较慢的。
Figure and Table—重要的图和表
- 左侧图:八张ILSVRC-2010测试图像和我们的模型认为最可能的五个标签。正确的标签写在每张图片下面,分配给正确标签的概率也用红色条显示(如果恰好位于前5位)。
- 右侧图:第一列中有五幅ILSVRC-2010测试图像。剩下的列显示了在最后一个隐藏层中生成特征向量的六个训练图像,这些特征向量与测试图像的特征向量之间的欧氏距离最小(简单来说可以理解为倒数第二层提取出的特征向量最相似的几个图像,也就是说我们的神经网络在最后第二层输出的特征,在语义空间里面表现的非常好)。
下面两张表格是与之前最好的模型做的对比以及一些数据,这里不做详细解释了:
结构流程图非常重要,在第二遍阅读时再详细解释:
第二遍阅读:
Introduce—介绍
Introduce部分主要说了以下几点:
- 引出ImageNet这个数据集很大很好。
- 对于ImageNet这个很大的模型,我们采用CNN来作为我们的模型。
- 对于CNN计算成本高(容易overfitting+训练不动),我们利用GPU以及高度优化的2D卷积来实现CNN的训练。
- 主要贡献:我们训练了一个很大很好的模型,结果特别好。我们是怎么做的?用了一些不寻常的方法以及用了什么方法来避免过拟合,并且说明深度似乎很重要。
- 网络的大小受到了GPU的可用内存以及我们可容忍时间的影响,说了一下他们用的GPU。
The Dataset—数据集
- ImageNet数据集包含超过1500万张高分辨率图像的数据集,这些图像属于大约22000个类别。ILSVRC的比赛,ILSVRC使用ImageNet的一个子集,1000个类别中的每一个都有大约1000个图像。总共大约有120万张培训图像、50000张验证图像和150000张测试图像。
- 图像处理:ImageNet这个数据集不像其他数据集一样,它没有对数据进行裁剪。所以我们要先对数据集进行裁剪,裁剪为:256*256的尺寸大小。具体裁剪方法:先对原始图片进行缩放,将短边变成256的大小,另一个长边在这一步操作中也会根据长宽比进行调整,然后第二步从图片中心对长边进行两侧的裁剪,得到256*256的尺寸大小。
- 我们没有对图像进行任何的预先处理,比如抽取特征、抽取SIFT特征等等,我们实现了一个end to end 的方式,也就是说直接将原始图片(原始文本)输入到神经网络模型,他就能实现我们想要的功能。
The Architecture—网络结构
网络架构分为八个层,其中有五个卷积层和三个全连接层。下面每一小节都介绍了一些新颖的不同寻常的功能:
ReLU Nonlinearity—非线性激活函数ReLU
讲述了一下我们采用的激活函数是非线性的ReLU函数。这个非线性激活函数是不饱和的,但是训练速度要比饱和的非线性激活函数tanh和sigmoid要快的多。(但具体为什么快没具体说,现在的视角看来也没快多少,都差不多,但是ReLU函数要简单所以用的多)
下图的实线为采用ReLU的误差下降率,虚线则是tanh的下降率,明显ReLU下降起来要快得多。
Training on Multiple GPUs—用多个GPU训练
这一部分偏工程型,不用太注意这些细节,主要是说了图片太多我们无法在一个GPU上训练,所以把网络切开训练,之后的架构图中会说明怎么切的,切完之后用了两个GPU去训练。
Local Response Normalization——局部归一化
总结来说,在ReLU层之前我们应用了normalization得到了一个更好的效果。(注:这个现在看来不重要了,因为之后没人用过这种normalization技术,而且我们有了更好的normalization方法,下述方法也不用了,所以不重要)
首先说了ReLU虽然有一个性质是说不需要input normalization来避免饱和,但是用一下normalization效果会更好
下面复杂的公式可以忽略掉,但是这里我们也放上了:
Overlapping Pooling—重叠池化
采用了重叠pooling。
总结一些:一般来说两个pooling是不重叠的,但是这里采用了一种对传统的pooling改进的方式,效果很好。知道这些即可。
Overall Architecture—整体网络架构
上图为整体流程图,说明几点:
- 因为在两个GPU上运行,所以网络结构被一切为二,上下两部分各自训练各自的,各有各的参数核,结构都是一样的;
- 整个结构有八层,前五层为卷积层,后三层为全连接层,最后再跟一个1000路的分类激活函数softmax,相当于多个logistic回归来进行多元分类。
- 二、四、五层只与自己之前的核有关系,就是只与自己这个GPU前一层训练的输出有关系。第三层卷积层与前一层的两个GPU训练出来的都有关系,在通道维度上做了一个融合。全连接层就与前一层中所有神经元相连。
- 之前提到的Response-normalization应用在了第一层和第二层的卷积层。
- 上一节提到的Max—pooling应用在了有Response-normalization的层以及第五卷积层。
- 八层每一层都应用了ReLU函数。
- 这些层的顺序:Response-normalization放在ReLU之前,然后Max—pooling跟在ReLU之后。
- 规律:我们输入的图片从一个又高又宽又扁的一个形状,慢慢变为了一个宽和高都很小,但是很长的一个张量,这是说我们的空间信息被压缩了也就是从一开始的224变为了后面的13,也就是13中的一个像素能表示之后一大片像素。通道数变多也就是变长了,通道数可以理解为对于一个模式的识别,例如通道数为192那么说明可以识别图中192个模式,例如猫腿、爪子这种模式。所以说整个过程就是空间信息被压缩,但是语义信息空间慢慢增加。
总结:整个过程就是一张图片,经过模型处理变为了一个4096维的向量,这个向量可以把中间的语义信息表示出来。机器学习可以认为是一个压缩知识的过程;具体来讲就是我们原始的一个图片,文字或者视频输入到一个模型中,这个模型就会把它压缩为一个向量,这个向量机器可以识别,用来实现别的任务,例如分类等等。
Reducing Overfitting—减少过拟合
避免过拟合采用了两种方法:数据增强和dropout
Data Augmentation—数据增强
减少图像数据过度拟合的最简单也是最常见的方法是使用保留标签的变换人为地放大数据集。这里用了两种方式:
- 通过从256×256图像中随机提取224×224的图像,并在这些提取的图像上训练我们的网络来实现这一点。这将使我们的培训集的规模增加了2048倍。但是有个问题也不能说就是2048倍,因为很多图片都是相似的。
- 采用PCA的方式对RGB图像的channel进行了一些改变,使图像发生了一些变化,从而扩大了数据集。
Dropout—正则化
随机的将隐藏层的输出以50%的概率设为0,相当于一个L2的正则化,只不过用了这种方式实现了L2正则化的功能。
Details of learning—学习的细节
-
SGD:我们使用随机梯度下降法(SGD)训练我们的模型,批量大小为128,momentum为0.9(对传统SGD增加了动量这个观点,来解决传统SGD的一些问题,例如优化过程非常不平滑或者梯度下降很低效的时候),weight decay为0.0005(可以理解为是一个L2的正则化项,用在优化算法上而不是模型上)。我们发现,这种少量的weight decay对模型的学习很重要。换句话说,这里的weight decay不仅仅是一个正则化器:它减少了模型的训练误差。权重w的更新规则为
-
初始化参数:用均值为0 ,方差为0.01的高斯随机变量去初始化了权重参数(0.01是一个非常好的数,不大也不小,如果网络过大,例如BERT ,我们才用到0.02)。然后偏置bias也进行了初始化,不过这里不太重要,因为数据平衡的话初始为0最好,但是这里初始1效果更好一些,这个地方也没有继续深入研究。
-
学习率:我们在所有层上使用相同的学习率,设为0.01。但验证误差不降的时候我们就手动的乘以0.1,也就是降低十倍。也有自动的方法,例如Resnet,训练120轮epoch,初始学习率也是设为0.01,每30轮降低十倍,本文是训练了90个epoch,每一次是120w张图片。当然现在我们都不采用十倍十倍去降低了,我们采用更平滑的降低方式,例如利用cos函数去降低,如下图,蓝色线为本文中的降低方式,十倍十倍去降,红色线是我们现在用的,一开始学习率设的大一些,慢慢下降,这样更高效。
Results—实验结果
实验部分就知道效果就可以了,具体怎么实验的不用关心,除非你需要重复他的实验。
小知识:训练集、验证集、测试集。验证集就是说用来调参的数据集,可以一直用来调参,但是测试集就运行几次用来看这个模型的效果怎么样。
Qualitative Evaluations—定性评估
第一遍阅读时讲的图,不作详述了。
这里记录一点:就是说神经网络一直被人诟病的一个问题,不知道神经网络内部到底训练了一个什么东西,这里右边这个图展示出了最后4096维的向量,可以在一定程度证明神经网络内部的特征到底是一个什么东西。
总结:偏底层的神经元学习的是一些纹理、方向等;偏上的神经元则是学到的是全局点,例如一个手、一个头之类的。
第三遍阅读
再看一些第二遍未看懂的细节,例如激活函数的饱和和非饱和,这里不带着读第三遍了。
YOLO系列YOLOv4论文超详细解读2(网络详解)
上一篇我们一起读了YOLOv4的论文《YOLOv4:Optimal Speed and Accuracy of Object Detection》(直通车→【YOLO系列】YOLOv4论文超详细解读1(翻译 +学习笔记)),有了初步的印象,论文里面涉及到很多tricks,上一篇介绍的比较简略,我们这篇来详细介绍一下。
目录
一、YOLOv4的简介
YOLOv4一共有如下三点贡献:
(1)开发了一个高效、强大的目标检测模型。它使每个人都可以使用1080ti或2080ti GPU来训练一个非常快速和准确的目标检测器。
(2)验证了最先进的 Bag-of-Freebies和 Bag-of-Specials对象检测在检测器训练时的影响。
(3)对现有的方法进行了改进,使其更加高效,更适合于单个GPU的训练,包括CBN,PAN,SAM等。
二、YOLOv4的网络结构
YOLOv4的整体原理图如下:和v3还是比较接近的
可以看到由以下四个部分组成:
输入端: 训练时对输入端的改进,主要包括Mosaic数据增强、cmBN、SAT自对抗训练
BackBone主干网络: 各种方法技巧结合起来,包括:CSPDarknet53、Mish激活函数、Dropblock
Neck: 目标检测网络在BackBone和最后的输出层之间往往会插入一些层,比如YOLOv4中的SPP模块、FPN+PAN、SAM结构
Head: 输出层的锚框机制和YOLOv3相同,主要改进的是训练时的回归框位置损失函数CIOU Loss,以及预测框筛选的nms变为DIOU nms
下面我们就按着这个顺序来介绍~
三、输入端
Yolov4对训练时的输入端进行改进,使得训练时在单张GPU上跑的结果也蛮好的。比如数据增强Mosaic、cmBN、SAT自对抗训练。
数据增强①CutMix
数据增强的原因:在平时项目训练时,小目标的AP一般比中目标和大目标低很多。而Coco数据集中也包含大量的小目标,但比较麻烦的是小目标的分布并不均匀。Coco数据集中小目标占比达到41.4%,数量比中目标和大目标都要多。但在所有的训练集图片中,只有52.3%的图片有小目标,而中目标和大目标的分布相对来说更加均匀一些。
核心思想:将一部分区域cut掉但不填充0像素,而是随机填充训练集中的其他数据的区域像素值,分类结果按一定的比例分配。
处理方式:对一对图片做操作,随机生成一个裁剪框Box,裁剪掉A图的相应位置,然后用B图片相应位置的ROI放到A图中被裁剪的区域形成新的样本,ground truth标签会根据patch的面积按比例进行调整。
另外两种数据增强的方式:
(1)Mixup: 将随机的两张样本按比例混合,分类的结果按比例分配
(2)Cutout: 随机的将样本中的部分区域Cut掉,并且填充0像素值,分类的结果不变
数据增强②Mosaic
Yolov4中使用的Mosaic是参考2019年底提出的CutMix数据增强的方式,但CutMix只使用了两张图片进行拼接,而Mosaic数据增强则采用了4张图片,随机缩放、随机裁剪、随机排布的方式进行拼接。
优点:
(1)丰富数据集: 随机使用4张图片,随机缩放,再随机分布进行拼接,大大丰富了检测数据集,特别是随机缩放增加了很多小目标,让网络的鲁棒性更好。
(2)batch不需要很大: Mosaic增强训练时,可以直接计算4张图片的数据,使得Mini-batch大小并不需要很大,一个GPU就可以达到比较好的效果。
SAT自对抗训练
自对抗训练(SAT)也代表了一种新的数据增加技术,在两个前后阶段操作。
(1)在第一阶段: 神经网络改变原始图像而不是网络权值。通过这种方式,神经网络对自己执行一种对抗性攻击,改变原始图像,以制造图像上没有期望对象的假象。
(2)在第二阶段: 神经网络以正常的方式对这个修改后的图像进行检测。
通过引入噪音点进行数据增强
cmBN
BN: 无论每个batch被分割为多少个mini batch,其算法就是在每个mini batch前向传播后统计当前的BN数据(即每个神经元的期望和方差)并进行Nomalization,BN数据与其他mini batch的数据无关。
CBN: 每次iteration中的BN数据是其之前n次数据和当前数据的和(对非当前batch统计的数据进行了补偿再参与计算),用该累加值对当前的batch进行Nomalization。好处在于每个batch可以设置较小的size。
CmBN: 只在每个Batch内部使用CBN的方法,若每个Batch被分割为一个mini batch,则其效果与BN一致;若分割为多个mini batch,则与CBN类似,只是把mini batch当作batch进行计算,其区别在于权重更新时间点不同,同一个batch内权重参数一样,因此计算不需要进行补偿。
Label Smoothing类标签平滑
原因:对预测有100%的信心可能表明模型是在记忆数据,而不是在学习。如果训练样本中会出现少量的错误样本,而模型过于相信训练样本,在训练过程中调整参数极力去逼近样本,这就导致了这些错误样本的负面影响变大。
具体做法:标签平滑调整预测的目标上限为一个较低的值,比如0.9。它将使用这个值而不是1.0来计算损失。这样就缓解了过度拟合。说白了,这个平滑就是一定程度缩小label中min和max的差距,label平滑可以减小过拟合。所以,适当调整label,让两端的极值往中间凑凑,可以增加泛化性能。
四、主干网络BackBone
CSPDarknet53
简介:CSPNet(Cross Stage Partial Networks),也就是跨阶段局部网络。CSPNet解决了其他大型卷积神经网络框架Backbone中网络优化的梯度信息重复问题,CSPNet的主要目的是使网络架构能够实现获取更丰富的梯度融合信息并降低计算量。
具体做法:CSPNet实际上是基于Densnet的思想,即首先将数据划分成Part 1和Part 2两部分,Part 2通过dense block发送副本到下一个阶段,接着将两个分支的信息在通道方向进行Concat拼接,最后再通过Transition层进一步融合。CSPNet思想可以和ResNet、ResNeXt和DenseNet结合,目前主流的有CSPResNext50 和CSPDarknet53两种改造Backbone网络。
具体改进点:
①用 Concat 代替 Add,提取更丰富的特征。
②引入 transition layer (1 * 1conv + 2 * 2pooling),提取特征,降低计算量,提升速度。
③将 Base layer 分为两部分进行融合,提取更丰富的特征。
Mish激活函数
简介:Mish是一个平滑的曲线,平滑的激活函数允许更好的信息深入神经网络,从而得到更好的准确性和泛化;在负值的时候并不是完全截断,允许比较小的负梯度流入。Mish是一个与ReLU和Swish非常相似的激活函数,但是Relu在小于0时完全杀死了梯度,不太符合实际情况,所以可以在不同数据集的许多深度网络中胜过它们。
公式:y=x∗tanh(ln(1+ex))
Mish图像:
Mish和Leaky_relu激活函数的图形对比如下:
优点:
(1)从图中可以看出该激活函数,在负值时并不是完全截断,而允许比较小的负梯度流入从而保证了信息的流动
(2)Mish激活函数无边界,这让他避免了饱和(有下界,无上界)且每一点连续平滑且非单调性,从而使得梯度下降更好。
Dropblock正则化
传统的Dropout:随机删除减少神经元的数量,使网络变得更简单。
Dropblock:DropBlock技术在称为块的相邻相关区域中丢弃特征。Dropblock方法的引入是为了克服Dropout随机丢弃特征的主要缺点,Dropout主要作用在全连接层,而Dropblock可以作用在任何卷积层之上。这样既可以实现生成更简单模型的目的,又可以在每次训练迭代中引入学习部分网络权值的概念,对权值矩阵进行补偿,从而减少过拟合。
之前的Dropout是随机选择点(b),现在随机选择一个区域
Q:全连接层上效果很好的Dropout在卷积层上效果并不好?
中间Dropout的方式会随机的删减丢弃一些信息,但Dropblock的研究者认为,卷积层对于这种随机丢弃并不敏感,因为卷积层通常是三层连用:卷积+激活+池化层,池化层本身就是对相邻单元起作用。
而且即使随机丢弃,卷积层仍然可以从相邻的激活单元学习到相同的信息。因此,在全连接层上效果很好的Dropout在卷积层上效果并不好。所以右图Dropblock的研究者则干脆整个局部区域进行删减丢弃。
五、Neck
SPP
简介:SPP-Net全称Spatial Pyramid Pooling Networks,是何恺明大佬提出的,主要是用来解决不同尺寸的特征图如何进入全连接层的,在网络的最后一层concat所有特征图,后面能够继续接CNN模块。
如下图所示,下图中对任意尺寸的特征图直接进行固定尺寸的池化,来得到固定数量的特征。
具体结构如下:
PAN
YOLOv3中的neck只有自顶向下的FPN,对特征图进行特征融合,而YOLOv4中则是FPN+PAN的方式对特征进一步的融合。引入了自底向上的路径,使得底层信息更容易传到顶部
下面是YOLOv3的neck中的FPN,如图所示:
FPN是自顶向下的,将高层的特征信息通过上采样的方式进行传递融合,得到进行预测的特征图。
YOLOv4中的neck如下:
YOLOv4在原始PAN结构上进行了一点改进,原本的PANet网络的PAN结构中,特征层之间融合时是直接通过addition的方式进行融合的,而Yolov4中则采用在通道方向concat拼接操作融合的,如下图所示。
Q:为什么要把add改为concat?
add: 将两个特征图直接相加,是resnet中的融合方法,基于这种残差堆叠相加,可以有效地减小因为网络层数加深而导致的cnn网络退化问题。add改变特征图像素值,并没有完全保留原本特征图信息,更多的可以看作对原特征图信息的一种补充,深层特征图在卷积过程中丢失了许多细节信息,通过add的方式得以补全,是在二维的平面上对特征图的增强。因此add在进行图像特征增强时使用最佳。
concat: 将两个特征图在通道数方向叠加在一起,原特征图信息完全保留下来,再对原特征图增加一些我们认为是较好的特征图,丰富了特征图的多样性,是在空间上对原特征图的增强,这样在下一次卷积的过程中我们能得到更好的特征图。
SAM
SAM源自于论文CBAM(Convolutional Block Attention Module)的论文,提出了两种注意力机制的技巧。
先来介绍一下CBAM
如下图所示,输入一个特征F,先进行Channel attention module后得到权重系数和原来的特征F相乘,然后在进行Spatial attention module后得到权重系数和原来的特征F相乘,最后就可以得到缩放后的新特征。不仅每个通道有注意力,而且特征图每个位置有注意力。
接着我们来介绍Channel attention module(通道注意力模块)
该模块就是将输入的特征F分别进行全局的Maxpooling与Averagepooling,接着将这两个输入到一个权重共享的MLP,再将这两个进行element-wise summation操作后经过Sigmoid函数会得到权重系数Mc,再将这个权重系数与原来的特征F相乘,就可以得到缩放后的新特征。
我们再看看Spatial attention module(空间注意力模块)
首先对不同的feature map上相同位置的像素值进行全局的Maxpooling与Average pooling,接着将这两个spatial attention map 进行concat,再利用一个7X7的卷积后经过Sigmoid函数会得到权重系数Ms,在将这个权重系数与原来的特征F相乘,就可以得到缩放后的新特征,如下所示:
YOLOv4将SAM从空间注意修改为点注意,不应用最大值池化和平均池化,而是直接接一个7X7的卷积层,这样使速度相对快一些。
六、Head
Loss
经典IoU loss
IoU算法是使用最广泛的算法,大部分的检测算法都是使用的这个算法。
不足:没有相交则IOU=0无法梯度计算,相同的IOU却反映不出实际情况
GIOU(Generalized IoU)损失
GIoU考虑到,当检测框和真实框没有出现重叠的时候IoU的loss都是一样的,因此GIoU就引入了最小封闭形状C(C可以把A,B包含在内),在不重叠情况下能让预测框尽可能朝着真实框前进,这样就可以解决检测框和真实框没有重叠的问题。
公式:
不足:但是在两个预测框完全重叠的情况下,不能反映出实际情况
DIOU(Distance IoU)损失
DIoU考虑到GIoU的缺点,也是增加了C检测框,将真实框和预测框都包含了进来,但是DIoU计算的不是框之间的交并,而是计算的每个检测框之间的欧氏距离,这样就可以解决GIoU包含出现的问题。
公式:其中分子计算预测框与真实框的中心点欧式距离d 分母是能覆盖预测框与真实框的最小BOX的对角线长度c
CIOU(Complete IoU)损失
CIoU就是在DIoU的基础上增加了检测框尺度的loss,增加了长和宽的loss,这样预测框就会更加的符合真实框。
公式:损失函数必须考虑三个几何因素:重叠面积,中心点距离,长宽比 其中α可以当做权重参数
NMS
DIOU-NMS
DIOU-NMS不仅考虑IOU的值,还考虑两个框的中心点的距离。如果两个框之间的IOU比较大,但是他们中心点之间的距离比较远,则会被认为是不同物体的检测框而不会被过滤掉。
公式: 不仅考虑了IoU的值,还考虑了两个Box中心点之间的距离 其中M表示高置信度候选框,Bi就是遍历各个框跟置信度高的重合情况
SOFT-NMS
对于重合度较大的不是直接剔除,而是施加惩罚。
本文参考:
以上是关于Alexnet论文介绍(超详细)——ImageNet Classification with Deep Convolutional Neural Networks的主要内容,如果未能解决你的问题,请参考以下文章
CV开山之作:《AlexNet》深度学习图像分类经典论文总结学习笔记(原文+总结)