【论文精读】Attention Bottlenecks for Multimodal Fusion 视频分类任务

news2024/11/16 8:41:43

        本文并非逐句翻译,添加个人理解与疑惑,如有需要,请自行阅读原文。

         

Attention Bottlenecks for Multimodal Fusion

多模态融合的注意力瓶颈

会议:NIPS2021

Benchmark:Audioset、Epic Kitchens和VGGSound等

Backbone:ViT-Base

实验运行环境:

代码地址:

paperwithcode:Attention Bottlenecks for Multimodal Fusion | Papers With Code

Github:https://github.com/google-research/scenic/tree/main/scenic/projects

目前存疑:

1、3.2.2是不是和mult一样的

2、3.2.3中 是两种模态同时对bottleneck进行更新还是异步?

3、4.3.2存疑 Transformer的输入不是定长的吗?

预备知识

  1. 前期融合(Early Fusion):在前期融合中,来自不同模态的信息在输入模型之前就被融合在一起。例如,对于图像和文本模态,可以将它们的特征向量在输入神经网络之前连接起来,形成一个更大的特征向量。这样,模型在处理数据时会同时考虑到所有模态的信息。

  2. 中期融合(Mid-level Fusion):在中期融合中,每个模态的特征分别被送入各自的模型进行处理,然后模型的中间表示会被融合在一起。这种方法涉及到在模型的中间层级合并不同模态的信息,通常是通过加权平均或拼接等方式进行。

  3. 后期融合(Late Fusion):后期融合是指在每个模态分别经过各自的模型处理后,最终的表示或预测结果被融合在一起。在后期融合中,模型在每个模态上独立学习特征和表示,然后将这些表示在最终的决策阶段进行融合。

Abstract

         人类通过多模态输入来处理信息感知世界。机器感知模型却通常是单模态的。从每种模态中合并得到最终表示或预测(“late-fusion”)仍然是多模态视频分类的主要范式。

        相反,本文引入了一种新的基于Transformer的架构,该架构使用“fusion bottlenecks 融合瓶颈”进行多层模态融合。

        与传统的成对自我注意力相比,该模型迫使不同模态之间的信息通过少量的bottleneck latents 瓶颈延迟,要求模型整理和浓缩每个模态中的相关信息,并共享必要的信息

        这种策略提高了融合性能,同时降低了计算成本并在包括Audioset、Epic Kitchens和VGGSound在内的多个视听分类基准上取得了SOTA的结果。


1 Introduction

        同时的多模态感觉是人类感知学习的关键推动因素[57]。然而,对于人工学习系统来说,由于许多因素,设计模态融合的统一模型是具有挑战性的:(i)不同模态之间在学习过程中动态变化的差异[63],在多模态学习中,每种模态可能具有不同的数据分布、特征表示和学习特性,因此它们在模型训练过程中的学习动态也会有所不同。这种差异可能表现在许多方面,比如模态之间的学习速度、收敛速度、对噪声的敏感度、对数据分布变化的鲁棒性等。(ii)不同的噪声拓扑,其中一些模态流包含比其他模态流更多的用于手头任务的信息,以及(iii)不同的输入表示。音频和视觉之间的输入表示差异尤其明显——许多最先进的音频分类方法依赖于短期傅立叶分析来生成对数梅尔频谱图,通常将其用作为图像设计的CNN架构的输入[29,55]。这些 time-frequency 表示对图像有不同的分布。相比之下,视频中的视觉流是三维的(两个空间和一个时间),虽然图像的不同空间区域对应于不同的对象,但存在跨多个帧的高冗余的独特挑战。因此,对于不同的模态,输入表示以及神经网络架构和基准往往变化很大。因此,为了简单起见,多模态融合的主导范式通常由涉及通过单独的音频和视觉网络的输出表示或分数来集成它们,即“后期融合 late-fusion”[25,49]。

        本文提出了一种新的基于Transformer的视频视听融合模型。一个最简单的思路就是将音频数据和视觉数据先拼接成一个sequence,然后输入进标准的transformer,不需对transformer结构作大的修改。这样的方式其实就是early-fusion,通过这种方式,transformer里面的attention能够自由、充分地接触和处理来自每个模态的每个维度的信息,但是这种自由是不必要的。因为不同模态间的信息会有冗余,视频的图像帧之间也会有信息冗余。另一方面,这样的attention无法很好进行扩展,对于长时间的视频处理,计算量太大。

         

        针对上述问题,本文提出了两种方式来限制原始Transformer模型中的attention流动问题

        第一种方法遵循多模态学习的一个常见范式,即将跨模态流限制在网络的later layers,允许early layers专门学习和提取单模态特征,被称为“mid- fusion 中期融合”(图1,左中),其中引入跨模态相互作用的层被称为‘融合层’。如同多数多模态fusion模型一样,将fusion部分往后推移,先让模型单独处理单个模态的信息,然后再做fusion。这样能够充分提取单模态内部的信息,毕竟不同模态的数据结构和分布差距很大,使用一样的处理方式是不合理的。

        第二种方法(也是主要贡献)是限制层内tokens之间的跨模态注意力流。通过允许注意力在一个模态内自由流动来做到这一点,但在与另一个模态共享之前,模型必须整理和“浓缩”每个模态的信息。核心思想是引入一小组潜在的融合单元,形成一个“注意力瓶颈”,层内的跨模态交互必须通过该瓶颈。在layer内的不同模态的tokens之间做跨模态的attention。单模态内部仍然是原始的self-attention,但是跨模态的fusion使用每个模态的部分tokens信息来做cross-attention。这样就能降低计算量并且处理部分冗余信息。

         


3 Multimodal fusion transformers

        本节中,将介绍提出的Multimodal Bottleneck Transformer(MBT)。首先总结了最近提出的视觉分类模型Vision Transformer(ViT)和音频分类模型Audio Spectrogram Transformer(AST)。然后描述对视听融合案例的扩展,讨论了三种不同的token融合策略(第3.2节),最后讨论了整个模型中的融合途径(第3.3节),其中包括将多模态融合限制在模型的某些层。 

 3.1 The ViT and AST architectures

         ViT和AST调整了最初为NLP设计的Transformer架构,以在最小变化的情况下处理2D输入。将图像(音频)数据转换为transformer可接受的一维表示,并且尽可能少修改原始transformer结构,以达到处理视觉(音频)数据的目的。

  • ViT从RGB图像(AST从音频频谱图)中提取N个不重叠的patch,(实际上,这里的h和w不是三维图像(H * W* C)的这个意义。这里xi的维度是P^2 \cdot C,其中P是patch的大小,C是图像通道数,具体过程详见ViT论文解释)
  • 通过线性映射矩阵E将每个patches转换为一系列1D标记,并和类别向量 z_{cls} \in \mathbb{R}^d 拼接(zcls是预先添加到该序列的特殊标记,因此它在最后一层的表示可以传递给分类器用于分类任务进行拼接)
  • 最后再加上位置编码 p \in \mathbb{R}^{(N+1) \times d}(p∈R(N1)×d是添加到token的学习的位置嵌入,以保持位置信息(因为所有后续的自注意操作都是置换不变的)
  • 注:"置换不变性"指的是一个系统或模型在输入的数据进行排列顺序变化(置换)时,输出结果保持不变的性质。在深度学习中,自注意力机制等操作通常是置换不变的,因为它们对输入的顺序不敏感,无论输入数据的顺序如何变化,输出结果都应该保持一致。这种性质有助于提高模型对输入数据的鲁棒性和泛化能力。)
  • 就将一张图像转换为了标准transformer可接受的输入形式。如下所示:

         

        然后这些patches(也就是transformer的tokens)被送入后续L个transformer组成的encoder层。每一个transformer层包含使用残差连接的多头自注意力模块 Multi-Headed Self-Attention (MSA)层、正则化模块 Layer Normalisation (LN) 和多层感知机模块 Multilayer Perceptron (MLP) 。将一个transformer层表示为,那么其过程可表示为:

         

        这里,MSA运算[61]计算点积注意力[61],其中查询、键和值都是相同张量通过不同的线性映射得到的线性投影,表示为MSA(X) = Attention(W^QX, W^KX, W^VX)

        本文定义了两个张量X和Y之间的多头交叉注意(MCA),其中X形成查询,Y形成用于重新加权查询的键和值,MCA(X, Y) = Attention(W^QX, W^KY, W^VY),将用于我们的多模态案例,如下所述。 

3.2 Multmodal transformer

         现在描述本文对多模态案例的扩展。首先讨论三种不同的token融合策略。

 3.2.1 Fusion via vanilla self-attention 用最平凡的self-attention做fusion

        本质:early fusion的transformer,将多模态的输入直接输入transformer。

        最直接的处理多模态信息的方式就是将视觉和音频信息拼接为一个sequence,然后输入原始的不更改任何结构的transformer中处理。该模型对长 t 秒的视频采样出 F 帧图像,并将音频波形转换为单个频谱图。然后使用ViT中的方式对图像和音频分别进行编码,最后将视觉和音频表示拼接在一起作为一个单独的sequence。

        用公式来表示,假设从 F 帧图像中一共提取出 N_v 个RGB pathces,每个patches表示为x_{rgb} \in \mathbb{R}^{N_v \times d},以及 N_a个频谱图patches,记为x_{spec} \in \mathbb{R}^{N_a \times d},那么最终得到的 sequence表示是(将图像和频谱图的一个个patch视为一个个token) :

        

        其中  || 代表拼接操作,视觉和音频的映射矩阵 E_{rgb}, E_{spec} 是不同的,他们的类别标签z_{cls-rgb}, z_{cls-spec}也是每个模态特有的。

        然后使用原始的transformer对上述sequence进行处理:z^{l+1} = Transformer(z^l; \theta )

该模型下,transformer中的self-attention模块能够自由地提取和处理来自不同模态的所有信息(视觉patches和音频patches)。

3.2.2 Fusion with modality-specific parameters 用odality-specific参数做fusion

        本质:允许每个模态有属于自己的参数,仍用attention交换信息。本质就是在计算 时,使用的self-attention中query是,key和value是,利用单模态独自的信息作为query来做attention。至于维数的不同,使用参数向量W来升维降维即可。

        作者将3.2.1的模型改为每种模态各自训练自己的参数(即modality-specific),然后使用cross-attention来做信息交换。因此,作者定义了一个cross-transformer层:

        

        其中的拼接, corss-transformer的输入是不完全一样的两个输入(不同于原始transformer),它的过程与原始transformer的差距在于公式(2)变为下面的公式(6),用cross-attention替换了原始attention。当参数\theta_{rgb}, \theta_{spec}一样时,本节的方法和3.2.1就是一样的

         

3.2.3 Fusion via attention bottlenecks

        本质:将 zrgb 和 zspec 分别与 zfsn 组合到一起进行self-attention,做了两个attention,由于zfsn的维度远小于前两者,所以计算量由N方变成了N,zrgb 和 zspec的信息交换只通过zfsn来进行,相当于各自的信息都浓缩进了zfsn中,减少了冗余,只是把必要的信息传递给另一个模态。

         为了降低原始attention的成对注意力机制的N方计算复杂性(成对注意力机制的复杂度是N方,其中N是序列长度,是因为每个位置需要与序列中的其他位置进行配对计算。对于每个位置,都需要计算其与序列中所有其他位置的注意力权重,然后根据这些权重对其他位置的值进行加权求和,从而得到最终的输出表示。),作者在transformer的输入sequence中引入了B个 fusion bottleneck tokens ,记为,如图2:

        

        那么现在的输入就变成了:

        

        然后作者将跨模态的attention限制在这些bottlenecks内,对于层layer而言,计算过程变为:

         

         i 是模态的索引,在这种情况下是RGB和Spec,zrgb和zspec只能通过转换器层内的瓶颈zfsn交换信息。我们首先创建特定于模态的临时瓶颈融合tokens(modality specific temporary bottleneck fusion tokens)zfsni^,这些tokens与音频和视觉信息分开并同时更新(等式8)。

        然后在等式9中对来自每个跨模态更新的最终融合token进行平均。

        作者还对bottleneck tokens的非对称更新进行了实验(见附录),发现这种选择的性能是稳健的。作者保持网络中bottleneck tokens的数量远小于每个模态的潜在单元的总数(B<<Nv和B<<Na)。

        由于所有跨模态注意力流都必须通过这些单元,这些紧密的“融合”bottlenecks迫使模型压缩来自每个模态的信息,并共享必要的信息。正如在实验中所示,这增加或保持了多模态融合的性能,同时降低了计算复杂性。作者还注意到,此提法对模态的类型和数量是通用的。

3.3 Where to fuse: early, mid and late

        上述策略讨论了层内的融合,在大多数transformer架构(如ViT)中,每个层都由一组相同的操作组成。然而,多模态学习的一个常见范式是限制网络的早期层专注于单模态处理,而只在后期层引入跨模态连接。

        我们通常认为较低层参与处理低级别特征,而较高层专注于学习语义概念,这在概念上是直观的——图像中的边缘和角落等低级别视觉特征可能没有特定的声音特征,因此可能不会从与音频的早期融合中受益。也就是说low-level的不同模态的特征之间可能还没有出现明显的关联关系,所以融合要放到后面层进行。

        本文采用这样的方式实现对fuse位置的控制:

        最初在 Lf 层的单个模态的token之间执行普通的self-attention。此后,我们将所有潜在的token连接在一起,,并将它们穿过剩余的L−Lf层,根据第3.2节融合tokens。这里,Lf=0对应于“早期融合”模型,Lf=L对应于“晚期融合”模型;0<Lf<L对应于‘中期融合’模型。这可以表示为

        

        其中transformer(·)可以指第3.2节中描述的3种融合策略中的任何一种。 

 (3.2节介绍的不同layer内fusion方法,在这一节的应用其实只在后面L-L_f层。因为后面这些才是fusion层,前面的L_f层是单独处理每个模态信息的部分,不做fusion。一个错误的理解是前面L_f层不是很像3.2.1的计算方式吗?其实概念完全不同。)

3.4 Classfication

        得到两个模态各自的特征向量,输入分类器,分类结果求平均。

        对本文中所有模型及其变体,都使用CLS token作为分类器的输入。作者将z^{L}_{CLS-rgb}, z^{L}_{CLS-spec}输入相同的线性分类器,然后得到pre-softmax logits的均值。 

        注:CLS token是Transformer模型中的一个特殊标记,通常用于进行分类任务。在BERT等预训练模型中,CLS token位于输入序列的开头,并且经过模型处理后的CLS token表示被用作整个序列的汇总表示。

        在处理分类任务时,模型会将经过最终的CLS token表示送入分类器进行分类。这样做的好处是,CLS token经过多层Transformer的编码和自注意力计算后,会包含整个输入序列的信息,并且经过训练可以学习到适合该任务的上下文表示。因此,CLS token的表示可以看作是对整个序列信息的综合提取。


4 Experiments

        作者将MBT应用于视频分类任务

        4.1描述了用于训练和测试多模态融合的数据集及其各自的评估协议;

        4.2实现细节;

        4.3模型中的关键设计选择 分析;

        4.4将模型与现有技术进行比较。

4.1 数据集和评估协议

        我们对三个视频分类数据集进行了实验——AudioSet[24]、Epic-Kitchens-100[14]和VGGSound[12],详细描述如下。附录中提供了时间矩[47]和动力学[35]两个附加数据集的结果。

        AudioSet[24]由来自YouTube的近200万个10秒的视频片段组成,注释有527个类。与其他YouTube数据集一样,这是一个动态数据集(我们只使用仍然在线可用的片段)。这为我们提供了20361个用于平衡训练集的剪辑(以下称为迷你音频集或迷你as)和18589个用于测试集的剪辑。这个测试集与我们比较的最近的作品完全相同,包括Perceiver[32]。我们不使用2M个不平衡训练集,而是在由500K个样本(AS-500K)组成的(稍微更)平衡子集上进行训练。附录中提供了详细信息。由于每个样本都有多个标签,我们使用二进制交叉熵(BCE)损失进行训练,并按照标准实践报告所有类别的平均精度(mAP)。

        Epic Kitchens 100[14]由捕捉日常厨房活动的以自我为中心的视频组成。该数据集由90000个可变长度的剪辑组成,跨度为100小时。我们根据标准协议[14]报告了动作识别的结果——每个动作标签都是动词和名词的组合,我们使用具有两个“头”的单个网络来预测两者,这两个网络都是用交叉熵损失训练的。使用网络预测的得分最高的动词和动作对,排名前1的动作准确性是主要指标。动作以短期为主(平均长度2.6s,最小长度0.25s)。

        VGGSound[12]包含近200K个长度为10s的视频片段,注释有309个声音类别,包括人类动作、声音发射物体和人与物体的互动。与AudioSet不同的是,每个剪辑的声源在视频中都是“视觉呈现”的。这是通过使用图像分类器在数据集创建过程中确保的。在过滤了YouTube上不再提供的片段后,我们最终获得了172427个训练片段和14448个测试片段。我们使用标准交叉熵损失进行分类训练,并报告Top-1和Top-5分类精度。

4.2 实现细节        

        作者提到本文主干架构完全遵循ViT的架构,特别是使用从ImageNet-21K[16]初始化的ViT-Base(ViT-B,L=12,NH=12,d=3072),但注意到他们的方法与Transformer主干无关。除非另有专门说明,否则对所有瓶颈融合实验都使用B=4个瓶颈令牌。瓶颈令牌使用均值为0、标准偏差为0.02的高斯进行初始化,类似于公共ViT代码中的位置嵌入

        细节详见原文。

4.3 消融分析

        在本节中,研究了MBT中不同架构选择的影响。除非另有规定,否则使用迷你AudioSet分割进行训练,并在AudioSet评估分割上报告结果。更多关于backbone大小和预训练初始化的消融可以在附录中找到。 

4.3.1融合策略

        实施第3.2节中描述的所有三种融合策略:

        (i)最平凡的self-attention —— 一层内所有隐式单元之间的不受限制的成对注意力(也就是视觉和音频的单模态表示拼接之后直接输入后面原始的transformer层做fusion)

        (ii)cross-attention与单独的权重:与上文相同,但现在对每个模态都有单独的权重。通过与来自两种模态的所有其他潜在单元成对关注来更新潜在单元;不同模态的transformer层参数不同,每种模态的表示的更新都会访问到所有模态的信息(理解主要看3.2.2的公式),也就是attention依然是面向所有模态信息的;

        (iii)Bottleneck fusion:在这里,所有跨模态注意力都必须通过bottleneck fusion latents。此方式下的每种模态的表示的更新只能通过访问bottleneck tokens进行,也就是attention只在单模态信息bottleneck tokens之间进行。

        请注意,这三种融合策略仅描述了单层内token之间的注意力流。

        对于策略(ii)和(iii),我们还进行了实验,显示了将跨模态注意力限制在固定融合层Lf之后的层的影响。我们研究了具有不同融合层的模型,Lf=0,2,4,6,8,10,12,并在图中给出了结果。

两种模态的共享权重 Sharing weights for both modalities:

        首先研究了共享两种模态编码器权重的影响(策略(i)与(ii))。结果如附录中的图7所示。当模态在早期层融合时,使用单独的编码器可以提高性能。对于具有后期融合层的模型,两种模型的性能相似。因此,我们使用单独的模态权重进行进一步的实验。当fusion的层数较早时,使用separate的参数效果更好。当late fusion时,是否share weights差距不大。(这是否说明模型的前面层所捕获的信息更modal-specfic,后面的更multimodal了)

        mAP代表平均准确率(mean Average Precision),是评估目标检测和图像检索等任务性能的常用指标之一。在训练网络中,mAP通常用于衡量模型在处理目标检测任务时的准确性和效果。

        

融合层 Fusion layer:

        然后,我们研究了改变融合层Lf 对后两种策略的影响。用Lf=0,2,4,6,8,10,12进行实验。

        

        我们将输入跨度 t 固定为4s,将瓶颈令牌B的数量固定为4。我们对每个实验进行3次运行,并报告平均值和标准偏差。从图中可以看出,“中间融合”的性能优于早期(Lf=0)和晚期融合(Lf=12),这意味着将融合层放在later的位置,前面的层用来提取模态各自的特征,是有效果的。

注意力瓶颈 Attention bottlenecks:

        在上图3左中可以看出,使用attention bottleneck的模型在所有fusion层数选择下结果都比简单的cross-attention模型好。本文还对模型的计算量进行了实验,使用GFLOPs指标,如上图3右。从中可以看出只用很少的bottleneck tokens数目(B=4),本文的模型计算量(红色线条)就比cross-attention(蓝色线条)低很多,且不随着Lf的变化而变化。

        GFLOPs是指每秒十亿次浮点运算(Giga Floating Point Operations Per Second),通常用于衡量计算机或计算设备的浮点运算能力。在深度学习领域,特别是在评估和比较神经网络模型的性能时,GFLOPs通常用来表示模型的计算复杂度和计算效率。

瓶颈令牌的数量B Number of bottleneck tokens B:

        本文还对B=4,36,64,256,1024进行了实验。发现实验结果差距不大(少于0.5mPA),所以本文后续实验均设置B=4。只用4个bottleneck tokens就可以实现多模态融合的性能提升,以及大大降低模型计算量,说明本文的设计很有用。

4.3.2 输入采样和数据集大小

        本节探讨了不同模态上采样策略的影响,同时和单模态模型baselines——仅作用于RGB图像上的纯视觉的transformer和仅作用于音频上的纯音频的transformer进行了对比。

采样窗口大小 t

        本文transformer模型的一个优势就是可以处理变长的输入token长度。(存疑)

        本文对视频的不同采样窗口t值2,4,6,8进行了实验,结果如下图4所示。在推理时,作者统一采样多个窗口以便能覆盖整个视频。当音频的频谱图 patches数目N_a随着t变化时,作者保持RGB patches的数目N_v不变而改变采样帧的步长(避免内存溢出)。从图4中可以看出,随着输入的增多,audio-only和audio-visual的模型性能跟着增加,但是纯视觉的模型visual-only性能却在降低(作者猜测,可能是增大的步长导致采样出的帧数目减少,训练数据少了)。后文实验中设置t=8s。

         

同步采样与异步采样

        因为视频中音频和视频(图像)并不一定是完全对齐的,这里实验了不同模态中异步采样带来的影响。结果与分析详见附录。作者发现采样方式对结果影响不大,所以最终选择了同步采样。

模态混合

        在将 Mixup rerularization 应用于训练时,有两种不同的方法可以将其应用于多模态输入——标准方法是使用概率参数 α 对一组混合权重进行采样,并使用它来生成所有虚拟模态 -标签对。 此外,本文还探索了一个称之为模态混合的修改版本,它为每个模态采样一个独立的权重。 模态混合比标准混合施加更强的增强,带来 AudioSet 上的性能略有提高。

         

数据集规模的影响:图5中体现了训练样本规模不同的差距。

4.4 结果

与单模态性能对比:见下表1,2,3.

与SOTA模型对比:见下表1,2,3.

         

        

        

attention maps的可视化: 

        

5 Conclusion

        本文提出了一个新的基于transformer的音视频融合结构,探讨了一些列使用cross-attention进行模态融合的策略。

        未来可以考虑将MBT应用于更多模态,比如文本和光流。

        进一步的影响:

                多模态融合是机器学习中的一个重要领域,对许多单模态问题的解决提供了新的思路。
                transformer很好用但是计算量较大,本文提出的bottlenecks策略可以有效降低其计算复杂性。有利于transformer的广泛利用。
                作者发现训练数据集如果包含偏差,可能会使在其上训练的模型不适合某些任务。因此,人们可能会(有意或无意)使用分类模型来做出对社会不同群体产生不同影响的决策,在部署、分析和构建这些模型时牢记这一点很重要。
 


部分内容参考于

感谢 me_tundou博主的文章!受益匪浅!

【论文阅读】Attention Bottlenecks for Multimodal Fusion---多模态融合,音视频分类,注意力机制-CSDN博客

【attention系列】使用attention模块来做多模态融合 - 知乎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1490731.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

白酒:原料的预处理技术对白酒品质的影响

在豪迈白酒的酿造过程中&#xff0c;原料的预处理技术对白酒的品质起着至关重要的作用。预处理技术包括原料的选择、清洗、破碎、润料等环节&#xff0c;这些环节的处理方式直接影响着白酒的口感、香气和品质。云仓酒庄在原料的预处理技术方面进行了深入研究和探索&#xff0c;…

图扑数字孪生水电站,水力发电可视化运维

自水轮机的早期发明被用于农业灌溉&#xff0c;到 18 世纪末期的工业革命促使水轮机技术的改良&#xff0c;再到 19 世纪末水利发电的崛起&#xff0c;直至今日&#xff0c;智慧水电站数字孪生技术正处于蓬勃发展之中。通过整合物联网、大数据、云计算等现代信息技术&#xff0…

Python图像处理【21】基于卷积神经网络增强微光图像

基于卷积神经网络增强微光图像 0. 前言1. MBLLEN 网络架构2. 增强微光图像小结系列链接 0. 前言 在本节中&#xff0c;我们将学习如何基于预训练的深度学习模型执行微光/夜间图像增强。由于难以同时处理包括亮度、对比度、伪影和噪声在内的所有因素&#xff0c;因此微光图像增…

vscode设置打开浏览器

安装这个插件 Open Browser Preview

linemap | 这样好看的山峦地图真的可以快速绘制啦~~

上一次介绍了Python绘制svg的优秀可视化库Pygal&#xff0c;今天我们介绍一下一个优秀的R地图可视化绘制包-linemap包&#xff0c;顾名思义&#xff0c;该包是是为了绘制由线组成的地图&#xff0c;其官网如下&#xff1a;https://github.com/rCarto/linemap。该包主要拥有两个…

鸿蒙实战开发:【SIM卡管理】

概述 本示例展示了电话服务中SIM卡相关功能&#xff0c;包含SIM卡的服务提供商、ISO国家码、归属PLMN号信息&#xff0c;以及默认语音卡功能。 样例展示 基础信息 介绍 本示例使用sim相关接口&#xff0c;展示了电话服务中SIM卡相关功能&#xff0c;包含SIM卡的服务提供商、…

Android Studio Iguana | 2023.2.1版本

Android Gradle 插件和 Android Studio 兼容性 Android Studio 构建系统基于 Gradle&#xff0c;并且 Android Gradle 插件 (AGP) 添加了一些特定于构建 Android 应用程序的功能。下表列出了每个版本的 Android Studio 所需的 AGP 版本。 如果特定版本的 Android Studio 不支持…

pandas数据分析42——读取和写入stata和spss的数据格式

python就是胶水语言&#xff0c;啥文件基本都能读取&#xff0c;而且pandas作为数据分析最好用的包&#xff0c;其功能自然也很多&#xff0c;可以读取各种数据文件。 本次就来演示一下怎么读取stata文件&#xff0c;和spss文件&#xff0c;他们不仅储存了数据和变量&#xff…

如何解决iQOO手机运行uniapp真机调试时无法识别的问题

打开开发者选项&#xff0c;打开USB设置&#xff0c;把默认USB选项改成MIDI模式&#xff0c;就可以检测到手机了

Golang高级微调技术

本文分享了一些小技巧&#xff0c;可以帮助我们写出更简化、高效的Golang代码&#xff0c;从而获得更好的开发体验。原文: Fine-Tuning Golang: Advanced Techniques for Code Optimization 本文是Golang代码优化技术的综合指南&#xff0c;帮助我们释放 Golang 应用程序的全部…

微信小程序(五十)请求拦截器实现携token获取用户信息

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.个人信息框基本样式 2.请求拦截器携token获取个人信息进行渲染 源码&#xff1a; utils/http.js import http from "wechat-http"//设置全局默认请求地址 http.baseURL "https://live-api.it…

Mybatis_plus-基础

一、简介 1.概述 文档地址&#xff1a;https://baomidou.com/ 概述&#xff1a;MyBatis-Plus (opens new window)&#xff08;简称 MP&#xff09;是一个 MyBatis (opens new window) 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提…

前后端分离项目Docker部署指南(上)

目录 前言 一.搭建局域网 1.搭建net-ry局域网&#xff0c;用于部署若依项目 2.注意点 二.安装redis 创建目录 将容器进行挂载 ​编辑 测试是否安装成功 ​编辑 三. 安装MySQL 创建文件夹 上传配置文件并且修改 .启动MySQL容器服务 充许远程连接 四.部署后端 使用…

RISCV 中断控制器 PLIC APLIC (非MSI部分)

以下包含了 PLIC & APLIC 着重解释 APLIC 部分 参考 github 中 riscv-aia 规范1.0 &#xff0c;第四章 APLIC 注&#xff1a;关于MSI的部分简略&#xff08;等后续搞清楚&#xff09; 本人处于学习阶段&#xff0c;不清晰的地方&#xff0c;请见谅 一、关于 PLIC 配置 1、…

【Python】-----基础知识

注释 定义&#xff1a;让计算机跳过这个代码执行用三个单引号/双引号都表示注释信息&#xff0c;在Python中单引号与双引号没有区别&#xff0c;但必须是成对出现 输出与输入 程序是有开始&#xff0c;有结束的&#xff0c;程序运行规则&#xff1a;从上而下&#xff0c;由内…

(1)预处理

我们需要的文件结构如上 main.cpp add.h add.cpp add.h 这里使用riscv的工具链编译为.i文件&#xff0c;需要使用-E&#xff0c;就是只进行预处理&#xff0c;我们可以得到两个.i文件即main.i和add.i main.i 这里看到main.i里头文件全部替换&#xff0c;然后多了三万多行 所以…

力扣经典题目解析--合并两个有序链表

原题地址: . - 力扣&#xff08;LeetCode&#xff09; 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 迭代 链表节点结构…

Day12-【Java SE进阶】JDK8新特性:Lambda表达式、方法引用、常见算法、正则表达式、异常

一、JDK8新特性 1.Lambda表达式 Lambda表达式是JDK 8开始新增的一种语法形式;作用:用于简化名内部类的代码写法。 注意:Lambda表达式并不是说能简化全部匿名内部类的写法&#xff0c;只能简化函数式接口的匿名内部类。 有且仅有一个抽象方法的接口。注意:将来我们见到的大部…

【音视频开发好书推荐】《RTC程序设计:实时音视频权威指南》

1、WebRTC概述 WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个由Google发起的实时音视频通讯C开源库&#xff0c;其提供了音视频采集、编码、网络传输&#xff0c;解码显示等一整套音视频解决方案&#xff0c;我们可以通过该开源库快速地构建出一个音视频通…

【前端寻宝之路】总结学习使用CSS的引入方式

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法|MySQL| ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-BNJBIEvpN0GHNeJ1 {font-family:"trebuchet ms",verdana,arial,sans-serif;f…