ALBEF:基于动量蒸馏的视觉语言表示学习

news2024/12/28 10:51:27

Align before Fuse:Vision and Language Representation Learning with Momentum Distillation
ALBEF:基于动量蒸馏的视觉语言表示学习

摘要

大规模的视觉和语言表征学习在各种视觉-语言任务上显示出有希望的改进。大多数现有的方法采用了基于Transformer的多模态编码器来联合建模视觉标记(基于区域的图像特征)和单词标记。由于视觉标记和单词标记是不一致的,多模态编码器要学习图像-文本的相互作用是很有挑战性的。在本文中,我们引入了一种对比性的损失,通过跨模态的注意力,将图像和文本表征进行ALign BEfore Fusing(ALBEF),这使得视觉和语言表征的学习更加接地气。与大多数现有的方法不同,我们的方法不需要边界盒注释,也不需要高分辨率的图像。为了改善对噪声网络数据的学习,我们提出了动量蒸馏法,这是一种自我训练的方法,从动量模型产生的伪目标中学习。我们从相互信息最大化的角度对ALBEF进行了理论分析,表明不同的训练任务可以被解释为产生图像-文本对视图的不同方式。ALBEF在多个下游的视觉语言任务上取得了最先进的性能。在图像-文本检索方面,ALBEF优于那些在更大数量级的数据集上预训练的方法。在VQA和NLVR2上,ALBEF与最先进的方法相比,实现了2.37%和3.84%的绝对改进,同时享有更快的推理速度。

1.简介

视觉与语言预训练(VLP)旨在从大规模的图像-文本对中学习多模态表征,以改善下游的视觉与语言(V+L)任务。大多数现有的VLP方法(如LXMERT、UNITER、OSCAR)依靠预先训练的对象检测器来提取基于区域的图像特征,并采用多模态编码器来融合图像特征和单词标记。多模态编码器被训练来解决需要联合理解图像和文本的任务,如遮蔽语言建模(MLM)和图文匹配(ITM)。虽然有效,但这个VLP框架有几个关键的局限性:(1)图像特征和单词标记嵌入在它们自己的空间中,这使得多模态编码器学习对它们的交互进行建模具有挑战性;(2)对象检测器注释和计算都是昂贵的,因为它在预训练时需要边界框注释,在训练时需要高分辨率(如600×1000)的图像。 (3) 广泛使用的图像-文本数据集是从网络上收集的,本质上是有噪声的,现有的预训练目标,如MLM,可能对噪声文本过度拟合,降低了模型的泛化性能。

我们提出ALign BEfore Fuse(ALBEF),一个新的VLP框架来解决这些限制。我们首先用一个无检测器的图像编码器和一个文本编码器对图像和文本进行独立编码。然后,我们使用一个多模态编码器,通过跨模态注意力将图像特征与文本特征融合起来。我们在单模态编码器的表征上引入了一个中间图文对比(ITC)损失,它有三个目的:(1)它使图像特征和文本特征一致,使多模态编码器更容易进行跨模态学习;(2)它改进了单模态编码器,以更好地理解图像和文本的语义;(3)它学习了一个共同的低维空间来嵌入图像和文本,这使得图像-文本匹配目标能够通过我们的对比性难负样本挖掘找到更多的信息样本。

为了改善嘈杂监督下的学习,我们提出了动量蒸馏法(MoD),这是一种简单的方法,它使模型能够利用更大的未经整理的网络数据集。在训练过程中,我们通过取其参数的移动平均数来保留模型的动量版本,并使用动量模型来生成伪目标作为额外的监督。通过MoD,模型不会因为产生与网络注释不同的其他合理输出而受到惩罚。

我们表明,MoD不仅改善了预训练,而且还改善了下游任务的干净注释。我们从相互信息最大化的角度对ALBEF进行了理论论证。具体来说,我们表明ITC和MLM最大限度地提高了图像-文本对的不同视图之间的相互信息的下限,其中视图是通过从每个对中获取部分信息而产生的。从这个角度来看,我们的动量提炼可以被解释为用语义相似的样本生成新的视图。因此,ALBEF学习视觉语言表征,这些表征对语义保留的转换是不改变的。

我们证明了ALBEF在各种下游V+L任务中的有效性,包括图像-文本检索、视觉问题回答、视觉推理、视觉嵌套和弱监督的视觉定位。与现有的最先进的方法相比,ALBEF实现了实质性的改进。在图像-文本检索方面,它超过了在更大数量级的数据集上预训练的方法(CLIP和ALIGN)。在VQA和NLVR2上,与最先进的方法VILLA相比,它实现了2.37%和3.84%的绝对改进,同时享有更快的推理速度。我们还使用Grad-CAM对ALBEF进行了定量和定性分析,揭示了它能够隐含地执行准确的对象、属性和关系接地的能力。

2.相关工作

2.1视觉-语言表征学习

大多数关于视觉-语言表征学习的现有工作分为两类。第一类侧重于用基于变换器的多模态编码器对图像和文本特征之间的相互作用进行建模。这类方法在需要对图像和文本进行复杂推理的下游V+L任务上取得了卓越的性能,但其中大多数需要高分辨率的输入图像和预先训练的物体检测器。最近的一种方法通过去除物体检测器来提高推理速度,但导致性能降低。第二类侧重于为图像和文本学习单独的单模态编码器。最近的CLIP和ALIGN使用对比性损失,即表示学习最有效的损失之一,对大量的嘈杂网络数据进行预训练。它们在图像-文本检索任务上取得了显著的性能,但缺乏对其他V+L任务的图像和文本之间更复杂的互动进行建模的能力。

ALBEF统一了这两个类别,使得强大的单模态和多模态表征,在检索和推理任务上都有出色的表现。此外,ALBEF不需要对象检测器,这是许多现有方法的主要计算瓶颈。

2.2 知识蒸馏

知识蒸馏旨在通过从教师模型中提炼知识来提高学生模型的性能,通常是通过将学生的预测与教师的预测进行匹配。虽然大多数方法侧重于从预训练的教师模型中提炼知识,但在线提炼同时训练多个模型,并将其组合作为教师。我们的动量蒸馏法可以解释为一种在线自蒸馏的形式,其中学生模型的时间集合被用作教师。类似的想法已经在半监督学习、标签噪声学习以及最近的对比学习中得到了探索。与现有的研究不同,我们在理论上和实验上表明,动量提炼是一种通用的学习算法,可以提高模型在许多V+L任务上的表现。

3.ALBEF预训练

在这里插入图片描述
图1:ALBEF的插图。它由一个图像编码器、一个文本编码器和一个多模态编码器组成。我们提出了一个图像-文本对比损失,以便在融合前对齐图像-文本对的单模态表示。图像-文本匹配损失(使用通过对比相似性挖掘出的in-batch hard negatives)和掩蔽语言模型损失被用于学习图像和文本之间的多模态交互。为了改善对噪声数据的学习,我们使用动量模型(基础模型的移动平均版本)生成伪目标作为训练期间的额外监督。

3.1模型结构

如图1所示,ALBEF包含一个图像编码器、一个文本编码器和一个多模态编码器。我们使用一个12层的ViT-B/16作为图像编码器,并用在ImageNet-1k上预训练的权重对其进行初始化。一个输入图像I被编码为一连串的嵌入序列: {vcls, v1, …, vN },其中vcls是[CLS]标记的嵌入。我们对文本编码器和多模态编码器都使用了一个6层的transformer。文本编码器使用BERTbase模型的前6层进行初始化,而多模态编码器则使用BERTbase的后6层进行初始化。文本编码器将输入文本T转化为嵌入序列{wcls, w1, …, wN },并将其送入多模态编码器。在多模态编码器的每层会通过注意力机制将图像特征和文本特征进行融合。

3.2预训练目标

我们用三个目标对ALBEF进行预训练:在单模态编码器上进行图文对比学习(ITC),在多模态编码器上进行屏蔽语言建模(MLM)和图文匹配(ITM)。我们通过在线难负样本挖掘对比来改善ITM 。

图文对比学习的目的是在融合之前学习更好的单模态表示。它学习一个相似性函数s=gv(vcls)>gw(wcls),这样并行的图像-文本对就有更高的相似性分数。gv和gw是线性变换,将[CLS]嵌入映射到归一化的低维(256-d)表示。受MoCo启发,维护两个队列来存储来自动量单模态编码器的最新的M个图文表示。来自动量编码器的标准化特征被称为g′v(v′cls)和g′w(w′cls)。我们定义
在这里插入图片描述
对于每个图像和文本,我们计算图像-文本和文本-图像的softmax归一化相似度为:在这里插入图片描述
其中,τ 是可学习temperature参数。令yi2t(I) and yt2i(T)表示真实的one-hot相似度,其中负样本对具有概率0且正样本对的概率为1。图文对比损失函数被定义为p和y的交叉熵H:在这里插入图片描述
屏蔽语言模型利用图像和上下文文本来预测被屏蔽的词语。我们以15%的概率随机地掩盖了输入标记,并用特殊的标记[MASK]代替它们。让ˆ T表示被遮蔽的文本,pmsk(I, ˆ T )表示模型对被遮蔽标记的预测概率。MLM使交叉熵损失最小:
在这里插入图片描述
其中ymsk是一个独热词汇分布,其中ground-truth标记的概率为1。

图文匹配预测一对图像和文本是正面的(匹配)还是负面的(不匹配)。我们使用多模态编码器对[CLS]标记的输出嵌入作为图文对的联合表示,并附加一个全连接(FC)层,然后用softmax来预测一个两类概率pitm。ITM的损失是:在这里插入图片描述
其中yitm是一个二维的独热向量,代表ground-truth标签。我们提出了一种策略,以零计算开销的方式为ITM任务抽取难负样本。如果一个负面的图像-文本对具有相似的语义,但在细微的细节上有所不同,那么它们就是难的。我们使用等式1中的对比相似性来寻找批次内的难负样本。对于一个小批次中的每张图片,我们按照对比相似度分布从同一批次中抽取一个负面文本,其中与图片更相似的文本被抽取的机会更高。同样地,我们也为每个文本抽出一个难负样本图像。ALBEF的完整预训练目标是:
在这里插入图片描述

3.3动量蒸馏

用于预训练的图文对大多是从网上收集的,它们往往是有噪声的。正面的文本对通常是弱相关的:文本可能包含与图像无关的词,或者图像可能包含文本中没有描述的实体。对于ITC学习,图像的负面文本也可能与图像的内容相匹配。对于MLM来说,可能存在与注释不同的其他词汇,这些词汇对图像的描述同样良好(或更好)。然而,ITC和MLM的单次标签会惩罚所有的负面预测,无论其正确性如何。

为了解决这个问题,我们建议从动量模型产生的伪目标中学习。动量模型是一个不断发展的教师,它由单模态和多模态编码器的指数移动平均版本组成。在训练过程中,我们训练基础模型,使其预测与动量模型的预测相匹配。具体来说,对于ITC,我们首先使用动量单模态编码器的特征来计算图文的相似性,即
在这里插入图片描述
然后我们通过用等式1中的s′代替s来计算软假目标qi2t和qt2i。ITCMoD损失被定义为:
在这里插入图片描述
同样,对于MLM来说,让qmsk(I, ˆ T)表示动量模型对被掩盖的标记的预测概率,MLMMoD损失为:
在这里插入图片描述
在图2中,我们展示了来自伪目标的前5名候选者的例子,它们有效地捕捉了图像的相关词汇/文本。
在这里插入图片描述
图2:MLM(第一行)和ITC(第二行)的伪目标的例子。伪目标可以捕捉到真实文本所没有描述的视觉概念(例如 “美丽的瀑布”、“年轻的女人”)。

我们还将MoD应用于下游任务。每个任务的最终损失是原始任务的损失和模型的预测与伪目标之间的KL-分歧的加权组合。为了简单起见,我们为所有的预训练和下游任务设置了权重α=0.4。

3.4预训练数据集

按照UNITER,我们使用两个网络数据集(Conceptual Captions,SBU Captions)和两个领域内数据集(COCO和Visual Genome)构建我们的预训练数据。唯一的图像总数为4.0M,而图文对的数量为5.1M。为了证明我们的方法在更大规模的网络数据中是可扩展的,我们还包括噪音更大的Conceptual 12M数据集,将图像总数增加到14.1M。

3.5实现细节

我们的模型由一个具有1.237亿个参数的BERTbase和一个具有8580万个参数的ViT-B/16组成。我们在8个NVIDIA A100 GPU上使用512的批处理规模对模型进行了30个epochs的预训练。我们使用AdamW优化器,权重衰减为0.02。在最初的1000次迭代中,学习率被预热到1e-4,然后按照余弦计划衰减到1e-5。在预训练期间,我们将分辨率为256×256的随机图像裁剪作为输入,并应用RandAugment。在微调过程中,我们将图像分辨率提高到384×384,并对图像patchs的位置编码进行插值。用于更新动量模型的动量参数被设置为0.995,用于图文对比学习的队列大小被设置为65,536。我们在第一个epoch内将蒸馏权重α从0线性上升到0.4。

4.交互信息最大化的观点

ITC、MLM和MoD可以被解释为产生观点的不同方式。形式上,我们将两个随机变量a和b作为一个数据点的两个不同观点。 在自监督学习中,a和b是同一图像的两个增强值。在视觉-语言表征学习中,我们认为a和b是一个图像-文本对的不同变化,可以捕捉其语义。 我们的目标是学习对视图变化不变的表征。 这可以通过最大化a和b之间的MI来实现。 在实践中,我们通过最小化InfoNCE损失来最大化MI(a,b)的下限:
在这里插入图片描述
其中s(a, b)是一个评分函数(例如,两个表征之间的点乘),而ˆB包含正样本b和|ˆB|-1从提议分布中抽取的负样本。我们的ITC损失(等式2)可以重新写成:
在这里插入图片描述
最小化Litc可以被看作是最大化InfoNCE的对称版本。因此,ITC将两个单独的模态(即I和T)视为图文对的两个视图,并训练单模态编码器以最大化正向对的图像和文本视图之间的MI。

我们也可以将MLM解释为最大化一个被遮蔽的单词标记与其被遮蔽的背景(即图像+被遮蔽的文本)之间的MI。具体来说,我们可以将MLM损失与单次标签(公式3)重写为:在这里插入图片描述
其中ψ(y): V→Rd是多模态编码器输出层中的一个查找函数,它将一个单词标记y映射成一个向量,V是完整的词汇集,f(I,ˆ T)是一个函数,它返回多模态编码器的最终隐藏状态,对应于被屏蔽的上下文。因此,MLM认为图文对的两个视图是:(1)一个随机选择的单词标记,以及(2)图像+该单词被掩盖的上下文文本。

ITC和MLM都是通过从图文对中获取部分信息,通过模式分离或单词屏蔽来生成视图。我们的动量提炼可以被视为从整个提议的分布中生成替代的观点。以等式6中的ITCMoD为例,最小化KL(pi2t(I), qi2t(I))等同于最小化以下目标:在这里插入图片描述
对于与图像I有相似语义的文本,它能使MI(I, Tm)最大化,因为这些文本会有更大的qi2tm (I)。同样,对于与T相似的图像,ITCMoD也能使MI(Im, T )最大化。我们可以按照同样的方法来说明,MLMMoD为被掩盖的词ymsk生成替代的观点y′∈V,并使y′和(I,ˆ T)之间的MI最大化。因此,我们的动量提炼可以被认为是对原始视图进行了数据增强。动量模型产生了一组在原始图像-文本对中没有的多样化的视图,并鼓励基础模型学习捕捉视图变量语义信息的表示。

5.下游的V+L任务

图像-文本检索包含两个子任务:图像-文本检索(TR)和文本-图像检索(IR)。我们在Flickr30K和COCO基准上评估ALBEF,并利用每个数据集的训练样本对预训练模型进行微调。对于Flickr30K上的零样本检索,我们用COCO上的微调模型进行评估。在微调过程中,我们共同优化了ITC损失(公式2)和ITM损失(公式4)。ITC根据单模态特征的相似性学习图像-文本评分函数,而ITM则对图像和文本之间的细粒度互动进行建模,以预测匹配分数。由于下游数据集包含每个图像的多个文本,我们改变了ITC的ground-truth标签,以考虑队列中的多个正例,其中每个正例的ground-truth概率为1/#正例。在推理过程中,我们首先计算所有图像-文本对的特征相似度得分。然后,我们选取前k个候选者,并计算其ITM分数以进行排名。由于k可以设置得非常小,我们的推理速度比那些需要计算所有图像-文本对的ITM分数的方法要快得多。

6.实验

6.1对所提方法的评估

首先,我们对所提方法(即图像-文本对比学习、对比性难负样本挖掘和动量蒸馏)的有效性进行评估。表1显示了使用我们方法的不同变体的下游任务的性能。与基线预训练任务(MLM+ITM)相比,加入ITC大大改善了预训练模型在所有任务中的表现。所提出的难负样本挖掘通过寻找更多信息的训练样本来改善ITM。此外,加入动量蒸馏法可以改善ITC(第4行)、MLM(第5行)以及所有下游任务(第6行)的学习。在最后一行,我们表明ALBEF可以有效地利用更多的噪声网络数据来提高预训练性能。
在这里插入图片描述
表1:在四个下游的V+L任务上对所提方法的评估。对于文本检索(TR)和图像检索(IR),我们报告了R@1、R@5和R@10的平均值。ITC:图像-文本对比学习。MLM:掩蔽式语言建模。ITMhard:图像-文本匹配与对比性难负样本挖掘。MoD:动量蒸馏法。MoDDownstream: 下游任务的动量蒸馏。

6.2对图文检索的评估

表2和表3分别报告了微调和零样本图文检索的结果。我们的ALBEF达到了最先进的性能,超过了CLIP和ALIGN,它们是在大得多的数据集上训练出来的。鉴于当训练图像的数量从4M增加到14M时,ALBEF有了相当大的改进,我们假设它有可能通过在更大规模的网络图像-文本对上进行训练而进一步增长。
在这里插入图片描述
表2: Flickr30K和COCO数据集的微调图文检索结果
在这里插入图片描述
表3:Flickr30K上的零样本图文检索结果

表6研究了各种设计选择对图文检索的影响。由于我们在推理过程中使用sitc来过滤top-k候选,我们改变k并报告其效果。一般来说,sitm获得的排名结果对k的变化并不敏感。我们还在最后一栏中验证了难负样本挖掘的效果。在这里插入图片描述
表6:关于微调图像-文本检索的消融研究。报告了测试集上的平均召回率。我们使用sitc来过滤top-k候选,并计算他们的sitm得分来进行排名。

7.结论

本文提出了ALBEF,一个用于视觉-语言表征学习的新框架。ALBEF首先将单模态图像表征和文本表征统一起来,然后将它们与多模态编码器融合。我们从理论上和实验上验证了所提出的图像-文本对比学习和动量蒸馏的有效性。与现有的方法相比,ALBEF在多个下游的V+L任务上具有更好的性能和更快的推理速度。
推荐阅读:
ALBEF:《Align before Fuse》
多模态对比学习新方法ALBEF,取得比SOTA更优的效果

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

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

相关文章

【平衡二叉搜索树(AVL)-- 旋转】

目录: 前言1、二叉搜索树的插入2、AVL树的旋转(1)右单旋(LL)(2)左单旋(RR)(3)右左双旋(LR)(4)左右…

第18章 项目风险管理

文章目录 18.1.2 风险的分类 54318.1.3 风险的性质 544项目风险管理6个过程(风险管理、识别风险、实施定性风险分析、实施定量风险分析、规划风险应对、控制风险)组织和干系人的风险态度影响因素18.3.3 规划风险管理的输出 550风险识别的原则18.4.2 识别…

vim编辑文件

目录 一、vi和vim (1)介绍 (2)相同点 (3)不同点 二、使用vim打开文件 三、使用vim编辑文件 (1)vim的四个模式 (2)命令模式下的编辑命令 删除 复制 …

树莓派4:跑通Tensorflow的Sequential模型用于图片分类

重要提示:由于树莓派相对孱弱的性能,直接在其上训练模型可能花(lang4)费非常长的时间。本文仅作为示例性的可行性参考,请酌情考虑实验平台。 著名的Tensorflow框架也可以运行在树莓派上。理论还没吃透,但使…

【量化交易笔记】5.SMA,EMA 和WMA区别

股票中的SMA,EMA和WMA是常用的技术分析指标。这些指标基于历史股价计算得出,可以帮助投资者了解股票的趋势,为决策提供依据。虽然它们都是平均值算法,但它们之间还是有一些区别的。 SMA 简单移动平均线(Simple Moving…

参与辅助服务的用户侧储能优化配置及经济分析(matlab代码)

目录 1 主要内容 目标函数 2 部分程序 3 程序结果 4 程序链接 1 主要内容 该程序方法复现《参与辅助服务的用户侧储能优化配置及经济分析》,首先, 建立了用户侧储能的全生命周期成本和考虑辅助服务的收益模型;其次,在两部…

一文读懂UML用例图

一、概述 用例是描述系统需求的一种手段,即系统应该做什么。用例图由参与者、用例和主题组成。每个用例的主题都代表了一个用例所适用的系统。用户和任何其他可以与主体交互的系统都被表示为行动者。 用例是一种行为规范。用例的实例指的是紧急行为的发生符合相应…

【前端客栈】基于HTML、CSS、JavaScript的羊了个羊静态仿写页面小游戏

🏜哈喽,大家好,我是小浪。前段时间羊了个羊火遍了大江南北,大家是否都通过第二关了呢?哈哈,没关系,既然通不过,那咋们不如自己来做一个这样的羊了个羊的仿写页面,学会了赶…

文本中的关键词提取方法

目录 1. TF-IDF(Term Frequency-Inverse Document Frequency)算法: 2. TextRank算法: 3. LDA(Latent Dirichlet Allocation)算法: 4. RAKE(Rapid Automatic Keyword Extraction&…

基于SLM调制器,MIT研发高效率全息显示方案

此前,青亭网曾报道过NVIDIA、三星、剑桥大学等对空间光调制器(SLM)全息方案的探索。空间光调制器可调节光波的空间分布,在电驱动信号控制下,可改变光在空间中传播的振幅、强度、相位、偏振态等特性,从而形成…

MySQL性能优化之(explain)工具

慢SQL的定位 在MySQL当中,我们有时候写的SQL执行效率太慢此时我们需要将其优化。但是SQL可能非常的多,难道我们一条一条的进行查看吗?在MySQL当当中我们可以查看慢查询日志,看看那些SQL这么慢。但是这个默认情况下这个慢查询日志…

sqoop使用

sqoop使用 1. 导入数据2. 从mysql向hive导入数据2.1 导入用户信息表 2.导入订单表2.2 导入订单表2.3 导入商品信息表2.4 导入国家信息表2.5 导入省份信息表2.6 导入城市信息表2.7 创建hive临时表文件 在使用sqoop之前,需要提前启动hadoop, yarn和对应的数据库mysql …

当音乐遇上Python:用Pydub自动分割音频

🎵 🎵 🎵 当音乐遇上Python:用Pydub自动分割音频 随着短视频应用的普及,越来越多人开始了解并尝试制作自己的短视频作品。而在制作短视频时,背景音乐的选择和使用也是非常重要的一步。很多人喜欢选择一首长…

倒立摆控制器的设计(分别用极点配置,LQR方法,Robust H-无穷方法)

G01倒立摆控制器设计 Author:DargonNote date:2020/12/13课程用书:LMIs in Control Systems Analysis,Design and Applications 1,倒立摆控制系统简介 倒立摆系统是一个复杂的控制系统,具有非线性、强耦合、多变量、不稳定等特…

干货 | 正念,寻求属于你的存在之道

Hello,大家好! 这里是壹脑云科研圈,我是喵君姐姐~ 你是否也曾感到内心无法平静?如果是,不妨了解一下正念,它或许能为你带来改变。 正念作为一种古老的修行方式,如今已经在世界范围内广为流传,…

《Netty》从零开始学netty源码(四十九)之PoolArena

目录 PoolArenaallocate()创建newByteBuf()分配具体的内存空间allocate() PoolArena Netty中分配内存是委托给PoolArena来管理的,它主要有两个实现类: 默认情况下使用的DirectArena,它的数据结构如下: 从属性中我们看到PoolA…

人生若只如初见,你不来看看Django吗

前言 本文介绍python三大主流web框架之一的Django框架的基本使用,如何创建django项目,如何运行django项目以及django项目的目录结构,另外django又是如何返回不同的数据和页面? python三大主流web框架 Python有三大主流的web框架…

JS手写实现Promise.all

Promise.all() 方法接收一个 Promise 对象数组作为参数,返回一个新的 Promise 对象。该 Promise 对象在所有的 Promise 对象都成功时才会成功,其中一个 Promise 对象失败时,则该 Promise 对象立即失败。 本篇博客将手写实现 Promise.all() 方…