一文搞懂神经网络、Transformer、占据网络

作者 | 山丘
出品 | 焉知
1、Layer Normalization“层归一化”到底是个啥,没了可不可以?
 
这是一种神经网络中常用的技术,它通常应用于每个网络层的输出或者激活值。用于在训练过程中对每一层的输入进行归一化处理,就可以确保每一层的输入都具有相似的分布,每个卷积层的输出会被归一化,然后再传递给下一层,以有助于网络学习和稳定训练。
 
可以用一个简单的卷积神经网络(CNN)来说明层归一化在图像处理中的作用。如果是无层归一化的网络的情况下,每一层的输入可能具有不同的分布,这样再做梯度传递及下降过程中,就会因为不同的分布导致每层更新的模型权值差别较大,此时,模型就会发散。这就是我们经常碰到的梯度爆炸。另外一方面,当网络较深时,梯度需要通过多个层传播反馈结果回到网络的较早层。在无层归一化时,梯度可能会逐渐变小,最终变得非常接近于零,导致网络无法持续性学习找到全局最优,而是在某一时刻就在局部最优处便停止反向传播到输入层。这种情况下,层归一化可以确保每一层的激活值保持在一个合适的范围内,避免梯度过小。
 
实际上你可以看成梯度下降过程就是寻找下降函数与真值不断缩小误差的点,最简单的方式就是两者需要通过做差找到差值最小的梯度点就是需要找的局部优化点,然后如果没有经过层归一化,前后两层神经网络做差都不在一个维度上,类似于一个在以不同的两种单位做差,比如一个是平方米,一个是公顷,两种不在同一个单位层级,仅仅对数值做差。那结果肯定不真实。而层归一化则是可以看作在对这两个做差的数据做单位统一,这样做差结果当然就更真实了。
 
2、神经网络中非线性变换到底是啥?隐藏层和输出层的非线性激活函数的区别在哪里?
 
隐藏层的激活函数和输出层的激活函数在功能上是相似的,都用于引入非线性特性。
 
隐藏层激活函数:隐藏层的激活函数主要作用是引入非线性,使得神经网络能够学习复杂的模式和特征。如果没有非线性激活函数,多个隐藏层堆叠起来的网络与单层网络的表达能力相似,无法捕捉数据中的复杂关系(如输入图像中的边缘、纹理、形状等特征),非线性映射可以在神经网络中将这些特征组合起来,映射到不同类别的概率分布上,从而实现对图像内容的识别和分类。
 
输出层激活函数:输出层的激活函数的选择取决于问题的性质。在多分类问题中,通常使用Softmax函数将输出转化为各个类别的概率分布。
 
因此,总结起来就是,隐藏层通常非线性变换后提取图像特征,而输出层的Softmax这类非线性函数则是将隐藏层提取的原始特征值转换为具体类别概率。
 
在神经网络中,输入可以是由多个图像特征组成的特征向量,经过隐藏层的处理和学习后,输出可以对这些特征进行多对多的映射。但是在这个过程中,向量的数量通常会发生变化。具体来说,在隐藏层中,每个神经元都会学习到一些特定的特征或模式,并对输入数据进行非线性变换。因此,输出可以看作是对输入特征的不同组合和变换,可能会产生新的特征。这种多对多的映射使得神经网络能够学习到输入数据中的复杂结构和关系。
 
这里举个例子说明:识别一个人,如果是线性方式表示,则要求只有输入具备网络模型中要求的一个行人的所有特征,比如一个头、两只手、两只脚,才算基本构建完成输出识别为人的特征。当然对于线性变换来说,输入的如上人的特征还会通过网络线性变换增强某些特征,来助力其神经网络将其识别为人。但是基本的识别输入参数要求基本是固化的。那么问题来了,如果由于自动驾驶汽车在行驶过程中,某一时刻识别不到那个人如上的一些基本属性特征呢?采用这种非线性变换那就肯定无法准确识别到这个人了。这时候我们这里提到的线性变换就显得尤为重要了。比如,此时输入为只识别到人的左边两只手和大半个头,如果采用非线性变化则可以通过类似脑补的方式将整个模型还原出来。这样一个非线性变换的输出已经基本具备人的特征信息,给输出层时,就可以完美的做到尽快匹配到最小损失函数值。
3、池化有多大必要性?自动驾驶感知中针对哪些感知源神经网络需要大力进行池化?
 
池化层在神经网络中起到了减少特征数量、提取主要特征和减少过拟合的作用。也就是前面提到的对于输入层所提取的特征参数参照一定的规则进行降维和参量裁剪。如下两图所示,表示了针对一幅图像中的一部分灰度值,对这个特征图进行2×2的最大池化,步长为2,那么池化操作将会对每个2×2的区域取最大值,得到一个2×2的输出。
 
可以看到,池化保留每个区域的最大值或平均值,这有助于提取图像中的主要特征。如上池化过程大大降低了图像的矩阵维度。保留了区域中感兴趣的高亮度识别值,这样方便后续计算,减少运算时间。这样模型处理的复杂度将大大降低,在后续训练数据是就可以有效的避免过度拟合的情况。
 
过拟合是指机器学习模型在训练数据上表现很好,但在测试数据或新数据上表现较差的现象。过拟合通常发生在模型过于复杂或者训练数据过少的情况下,导致模型学习到了训练数据中的噪声或不重要的特征,而忽略了数据中的真实规律。
 
这里需要举例说明自动驾驶场景中需要怎样才能进行有效的池化保留住最重要的主要特征数据。比如我们在场景中需要探测前方的骑行者目标,训练数据中可能只有标准的单人骑行者这种情况下的骑行者目标能够被准确检测到。而当道路上出现双人骑行在车辆上时,有可能就会存在由于场景库中未存在该匹配模型,而神经网络学习过程中过分关注双人这一未知信息,而忽略了二轮车的基础特征信息,从而导致无法准确匹配识别到的情况。
 
正确的做法是在处理过程中,主要提取识别二轮车重点关注的特征信息,如二轮、车身看长度、车身高度、主驾驶位的驾驶员信息等,并基于一定的提取特征矩阵和步长对如上这些特征矩阵进行进一步池化。最终,基于前序特征进一步提取关键特征便可很容易的识别出感兴趣的目标信息。
 
当然,随着需要自动驾驶系统感知的环境目标要求越来越高,如果训练数据足够多,并且希望尽可能保留图像的细节和特征(无论是进行场景重构还是考虑对于一些异形目标可能带来的碰撞风险),此时可以考虑不使用池化操作,而是使用全量数据信息处理。全量处理可以保留更多的图像信息,但也会增加模型的计算量和参数数量,可能导致过拟合的风险增加。
 
因此,在选择是否使用池化操作时,需要考虑以下因素:
 
数据量和模型复杂度:如果训练数据量充足,并且模型复杂度适中,那么可以尝试不使用池化操作,以保留更多的图像细节。
 
计算资源和效率:全量处理会增加模型的计算量和内存消耗,尤其是在处理大分辨率图像时。如果计算资源有限或者需要快速训练和推理,可以考虑使用池化操作来降低计算成本。
 
任务要求:不同的任务对图像细节的需求不同。对于一些需要准确的像素级别信息的任务(如图像分割),保留更多的细节可能更重要。而对于一些分类任务,可能可以适当地使用池化操作来提高计算效率。
 
4、transformer中的那种自注意力机制和交叉注意力机制是分别怎么工作的呢?
 
考虑自动驾驶中多摄像头输入过程而论,如果针对不同方位的摄像头探测到的环境目标数据而言,就是自注意力是针对同一个摄像头的前后帧之间,自注意力可以帮助模型在同一个摄像头的前后帧之间建立起有效的依赖关系,从而更好地理解同一个摄像头在不同时间点拍摄到的图像。交叉注意力是针对不同摄像头在同一时刻的不同位置处,帮助模型在不同摄像头在同一时刻的不同位置处建立起有效的关联,从而更好地理解不同摄像头之间的空间关系,以及在同一时刻不同位置处的环境目标数据。
 
也就是说自注意力机制寻找的关联是同一个视频序列帧之间的关联度,而交叉注意力机制则是寻找多视角视频序列帧之间的关联度。但相比于RNN这种短时间距离补充关联度而言,自注意力机制可以帮助模型在序列中捕捉长距离的依赖关系,同时可以并行计算,提高了模型的效率。
 
这里举例说明下自注意力和交叉注意力在自动驾驶系统中的多视角视频采集中的有效利用方式。
 
如果是考虑车道居中保持这类驾驶辅助功能而言,如果能够前视摄像头采集到自车道信息,通过神经网络分割出感兴趣的前方车辆目标,则后续可以完全通过提取该车辆的特征信息后,通过自注意力机制对该目标车辆进行有效的tracking过程。而如果考虑到智驾行驶过程中,可能有其他车辆潜在cutin和cutout的风险,则需要对旁车道同步进行监控,那么就需要借助周边视觉感知进行补充识别,这里很多就会想要利用BEV这类鸟瞰图拼接的方式获取环境中的全量目标信息。既然是拼图,那么就少不了利用类似视差重复数据进行有效的拼接变换实现。如前面所述,交叉注意力机制正是很好处理视差空间关系的策略手段。这样,自注意力配合交叉注意力便可以很好的完成对感知识别的特征目标跟踪。
 
5、Transformer编码其中的K(键)V(值)Q(查询)矩阵到底是什么?
 
在Transformer中,编码器的作用是将输入序列转换为模型能够理解和处理的表示形式,并将这些表示传递给解码器进行后续处理。比如输入一幅图像,编码器模型中已有的特征提取器去提取图像中的颜色、纹理、形状等特定信息。随后,提前参考后续模型可以处理的类型对如上特征信息进行组合后,可以生成为后续模型理解的语义信息。这样该图像中的关键部分就可以完全被识别出来了。
 
当然,编码器处理过程并不是直接编码这些原始特征语义信息。首先,编码过程只存储指向对应语义识别模型的“指针”信息。这里说指针是借用了C语言的说法,实际上transformer里面叫K(键)V(值)Q(查询)矩阵。编码器中生成的向量看作是K(键)、V(值)、Q(查询)这三种类型的表示。在自注意力机制中,每个位置的表示都会被用作K、V、Q三种类型的输入,用于计算与其他位置的注意力权重。这种机制允许模型根据序列中不同位置的表示来动态地计算注意力权重,从而更好地理解序列中不同位置之间的关系。
 
如上这类编码器的表示形式对很多人看起来比较晦涩难懂。这里我们仍旧列举指针的例子来说明就好了。
 
在Transformer并不完全是在单个函数内部的概念,而是类比为函数调用中的嵌套函数的关系,对于当前输入序列需要的编码权值调用哪个嵌套函数,则是由具体嵌套函数与当前输入函数的关联度来确定的,这也就是另一个注意力机制的表示。但是,仍然查询(Q)、键(K)和值(V)可以参考函数的概念加以理解,且以函数做类比来可以参考做出如下解释。
 
1)查询(Q):可以看作是函数中的输入变量,它代表了当前位置或当前处理的内容。查询向量用于确定当前位置要关注的其他位置或信息。比如当前需要识别智驾系统感知中前方的形式车辆,那么查询向量就是从当前视频帧中指向其他视频帧中对应到该车辆的索引向量。视频编码和transformer都涉及了对序列数据中的相关性和相似性的分析,以便更有效地进行数据处理和编码。与视频编码不同的地方在于,视频编码是需要对第一幅图(我们称之为关键帧intra-frame)的完整语义信息进行编码存储,而在Transformer中,存储第一个intra-frame也是一个将这个关键帧进行更加完整的特征提取后存储到一个特定编码器中。所以,transformer的首帧也是存储的特征向量(如汽车的颜色、形状、纹理等)而非直接的语义(如汽车这一属性信息)。
 
2)键(K):可以类比为函数中的指针信息,也可以看作是引用的其他函数头,用于表示序列中各个位置的语义信息。它用于与查询向量进行比较,以确定与当前位置最相关的其他位置。
 
基于上图所示,加入键K向量,则类似于图中的黑色箭头,该箭头可以用于对当前帧Current frame输入的红色方块指向本序列(即自注意力机制)中的其他帧对应到这个感兴趣红色方块的具体位置。这样,就可以很好的追踪到这个感兴趣红色方块在其余每一帧中的具体位置信息了。
 
3)值(V):可以看作是引用的其他函数的具体计算结果,用于生成当前位置的输出的具体结果返回值。值向量包含了序列中各个位置的具体信息或特征。值向量根据注意力权重与查询向量的加权和来生成当前位置的输出。
 
基于上图中所示的情况,如果加入值(V)向量组合后,每个索引键K都可以在对应的帧中找到感兴趣的红色方块,且访问到对应每个视频帧红色方块中的具体特征信息。比如该位置的特征信息包括具体的颜色、形状、纹理等。最后,在通过对这些所有特征信息进行加权组合后与模型库进行比对,红色的方块便有了语义,比如车辆、行人等语义信息了。
 
6、Transformer中的编码器和解码器到底如何工作和配合的?
 
之前有了解一些关于transformer中的编码器和解码器中比较抽象的描述,很多同学也并未完全理解。这里我们就直接以自动驾驶系统中对行驶车辆的图像视频处理举例说明编码器的处理原理,就会一清二楚了。
 
当处理图像中行驶车辆的特征信息时,可以使用编码器将图像中的特征转换为一系列表示,以便后续任务(如车辆检测、车辆分类等)能够更好地理解和处理这些信息。
 
Step1:输入图像:假设我们有一幅道路场景的图像,其中包含一辆行驶中的汽车。
 
Step2:特征提取:首先,我们可以使用卷积神经网络(CNN)等方法从图像中提取特征。这些特征可以包括车辆自身部件(如车轮、车窗等)的形状、颜色、纹理等信息。
 
Step3:位置编码:对于每个提取到的特征(比如这里的车轮特征信息),我们可以为其分配一个位置编码,以表示特征在图像中的位置信息。车轮这一明显的特征可以帮助模型理解车辆在图像中的具体位置。
 
Step4:特征表示:对于每个位置的特征,我们可以使用自注意力机制等方法,将其与其他位置的特征进行关联。这有助于捕捉图像中不同位置之间的语义关系。
具体来说,在车辆识别的例子中,捕捉图像中不同位置之间的语义关系可以包括以下几个方面。
 
局部特征关联:模型能够理解图像中不同部分之间的局部特征关联,例如车辆的车轮与车身之间的关系,车头与车尾之间的关系等。
 
全局语境:模型能够利用整个图像的语境信息,而不仅仅是局部信息。例如,模型能够理解车辆通常出现在道路上的情境,从而更好地识别图像中的车辆。
 
Step5:重要性关联:模型能够确定图像中不同部分的重要性,并据此调整特征表示。例如,车辆的车身可能比车轮更重要,因此模型可能会更加关注车身的特征。对应到车辆这一属性上的车身形状这一特征本身给模型识别带来的认知度肯定大于车轮,因此,车身关联度权重值将被赋值较大值。
 
Step6:编码处理:最后,对经过位置编码和向量表示的特征进行编码处理,生成一系列具有上下文信息的表示。上下文信息指的是图像中一个像素或一个区域的周围像素或区域的信息,这些周围像素或区域的信息可以帮助理解当前像素或区域的语义和特征。比如,这个例子中,空间上下文信息,可以提供关于图像中对象形状、轮廓和边缘的信息。语境上下文信息表示图像中是否存在其他车辆或道路标志等。领域上下文知识涉及关于车辆外观、形状和颜色的常识。结合以上各种包含的特征自身信息及关联上下文信息所映射的K、Q、V信息进行加权编码,就可以完整的勾勒出Transformer编码器结果,并通过前向传播输出给解码器。
 
解码器在接收到编码器生成的车辆特征信息后,会使用这些信息来生成具体的车辆探测结果信息。
 
Step1:接收编码器生成的特征表示。通过K、Q、V查询并加权组合称图像中车辆的各种特征信息,如车辆的形状、颜色、纹理等。
 
Step2: 上下文信息提取解码器通过理解编码器生成的特征表示中的上下文信息,通过关联度较高的K、Q、V查询到车辆在图像中的位置、周围环境等,来帮助理解车辆的具体特征。
 
Step3:特征提取和重构。实际上就是基于前面几步所提取的特征参照一定的规则进行特征组合,从而对车辆的特征进行进一步提取和重构,以生成更具体和准确的特征表示。
 
Step4:车辆探测结果生成。实际就是组合特征提取和重构的信息并结合模型中学习到的知识进行处理的过程。解码生成的是目标数据:即车辆的位置、类别等信息。这类信息实际是可以完全用于后续规控模块处理的类型。
 
7、tranformer里面的softmax函数到底是什么,有什么用?
 
官方解释这里就不说了。直接上例子就很容易明白了。
 
假设我们有一个简单的图像分类任务,要求将输入的图像分为猫、狗和鸟三类。神经网络的输出层有三个节点,分别对应这三类动物。在经过网络前向传播后,输出层的三个节点会得到对应的如下表示了图像处理分类后的原始分数向量:
 
猫:cat=3.2
狗:dog=1.5
鸟:bird=0.8
 
这些原始分数反映了网络对于每个类别的预测程度,值越大则未知物体被预测成该分类的概率就越大。当然这里只是一整个神经网络中不同的神经节点输出来的分类值,看起来区别还是明显的。但是如果考虑自动驾驶不同位置摄像头对同一位置目标看到的结果可能会有所不同,这种纯以来原始分数向量出来的分类结果差异就不会那么明显了,这对于后续分类识别实际是不利的。
 
然而,经过如下Softmax函数处理后,这些原始分数被转换为了概率分布,
 
其中,z 是原始分数向量,softmax(z)i是第 i个类别的概率值。softmax处理后如下所示:
 
猫:softmax(cat)≈0.84
狗:softmax(dog)≈0.12
鸟:softmax(bird)≈0.04
 
这里你一定要问了,为什么上述函数可以做到这一点。对于上面的例子中的猫、狗、人这三个类别,K 就是3,表示总共有3个类别需要进行分类。对于特定的输入,因为类别的总数 K 是固定的,Softmax函数的分母在计算时是固定的。因此,通过指数化计算较大指数分子对固定的分子相除,对于原始分数较大的类别,其指数值会相对较大,从而导致对应的概率值更接近1。
8、占据网络这种方式到底如何工作,它与传统freespace的检测有哪些区别?
 
与传统的自由空间检测相比,占据网格检测在处理复杂环境时可能具有更好的性能。传统的自由空间检测free space通常基于几何或运动模型,因此,需要首先对需要划分场景中的各种目标进行分类及位置信息等检测。而占据网络实际是基于神经网络进行空间划分的,神经网络还可以从大量数据中学习。因此,占据网络实际上可以更好地处理不规则形状和复杂的背景环境,使得其在各种场景下的适应性更强。
 
还是老规矩,举例说明。
 
假设输入为智驾系统检测到的一幅视频图像,通常情况下,占据网络会将传感器数据(比如激光雷达或者摄像头采集到的图像)处理成分割完的图像块(传统CNN)或者是特征向量(可以是transformer)的形式输入到神经网络中进行处理。实际上,占据网络输入到神经网络中的输入端数量是不是由分割的图像子块数量来决定的。神经网络会学习如何从这些图像块或者特征向量中提取特征,并对每个位置进行分类,判断该位置是否被障碍物占据。这里的位置分类可以看成是对输入图像块或特征向量进行像素级别的分类,即对每个像素点进行分类,以确定其是否属于障碍物。
 
通常情况下,在占据网络中,对每个位置的判断标准通常是二元的,即该位置是被占据(occupied)还是未被占据(free)。这种判断通常是根据传感器数据和场景特征来进行的,这与传统free space的检测方案中依据具体的物体类别来进行判别简化了不少。
 
此外,如果是参照GPU处理的方式,每个GPU上可以跑一个神经网络来专门处理占据网络的检测。且对于单个摄像头输入的视频序列,GPU处理占据网络的方式取决于具体的实现和需求。通常情况下,每个GPU会逐帧处理视频序列,将每一帧作为输入,并输出相应的预测结果。这里如果智驾系统有11个摄像头,那么理论上至少需要11个GPU单元就可以完成处理了。

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注