(2023,大视觉模型 LVM,视觉句子,自回归)序列建模支持大型视觉模型的可扩展学习
Sequential Modeling Enables Scalable Learning for Large Vision Models
公Z号:EDPJ(添加 VX:CV_EDPJ 或直接进 Q 交流群:922230617 获取资料)
目录
0. 摘要
我们介绍一种新颖的序列建模方法,该方法使得能够学习大视觉模型(Large Vision Model,LVM),而无需使用任何语言数据。为此,我们定义了一个通用格式,“视觉句子”(visual sentences),在这种格式中,我们可以表示原始图像和视频,以及带注释的数据源,如语义分割和深度重建,而无需超出像素的任何元知识。一旦将这种各种各样的视觉数据(包括4200亿标记)表示为序列,模型就可以被训练以最小化下一个标记预测的交叉熵损失。通过在各种规模的模型架构和数据多样性之间进行训练,我们提供了经验证据表明我们的模型能够有效扩展。通过在测试时设计适当的视觉提示,可以解决许多不同的视觉任务。
1. 简介
大型语言模型(LLMs)如 GPT [11] 和 LLaMA [80] 席卷全球。构建大型视觉模型(LVM)需要什么?从动物世界来看,我们知道视觉能力不依赖于语言。特别是,许多实验证明非人灵长类动物的视觉世界与人类的视觉世界非常相似。因此,尽管像 LLaVA [54] 这样的视觉语言模型领域很有趣且值得追求,在这篇论文中我们寻求的是一个不同的问题的答案——仅仅通过像素能达到何种程度?
我们希望在 LVM 中模仿的当代 LLMs 的关键特性是:1)在大数据存在的情况下进行扩展,以及 2)通过提示(上下文学习)对任务进行灵活定制。我们如何实现这一点?和往常一样,有三个必须规定的主要组件:
- 数据:我们希望利用视觉数据中的所有显著多样性。首先是仅仅是未注释的原始图像和视频。接下来,我们想要利用过去几十年产生的各种注释视觉数据源的多样性——如语义分割、深度重建、关键点、3D对象的多个视图等。我们定义了一个通用格式,“视觉句子”,用于表示这些不同的注释,而无需超出像素的任何元知识。我们的训练数据集的总大小是16.4亿张图像/帧。
- 架构:我们使用一个大型的 transformer 架构(30亿参数),该架构使用表示为标记序列的视觉数据进行训练(使用了一个学到的标记器,将每个图像映射到一个 256 矢量量化标记的字符串)。
- 损失函数:我们从自然语言社区汲取灵感,其中掩蔽标记建模已经让位于序列自回归预测。一旦图像/视频/注释图像都可以表示为序列,我们就可以训练模型以最小化交叉熵损失,以预测下一个标记。
通过这种极其简单的设计,我们展示了一些值得注意的行为:
- 随着模型大小和数据大小的增加,适当的缩放行为。
- 现在可以通过在测试时设计合适的提示来“解决”许多不同的视觉任务。虽然结果没有显示出像专门训练的定制模型那样高的性能,但单一的视觉模型却能够解决如此多的任务,这是相当令人鼓舞的。
- 我们看到无监督数据量对各种标准视觉任务的性能有明显的好处。
- 我们看到一些通用视觉推理的能力——处理分布外的数据,并执行新颖的任务。但需要进一步的调查。
2. 相关工作
预训练视觉模型。使用预训练模型(例如预训练 ImageNet:AlexNet [46])的价值早在2015年的R-CNN [35]中就已经得到证明,并且自那时以来已经成为计算机视觉的标准实践。自监督预训练被提出作为大大增加可用于预训练的数据量的一种方式 [17, 26, 38, 62, 63, 99]。不幸的是,这并不是很成功,可能是因为当时基于CNN的体系结构没有足够的容量来吸收这些数据。随着Transformer的引入 [84],其容量大大提高,研究人员重新审视了自监督预训练,并展示了基于Transformer的掩蔽图像重建方法,如BEiT [7]、MAE [39]、SimMIM [91],相比于它们基于CNN的对应物 [63] 表现得更好。然而,尽管它们最近取得了成功,但当前的预训练视觉模型在扩展到像LAION [72] 这样的真正大型数据集时仍然存在困难。
多任务学习和上下文学习。从经典的每个任务一个模型的设置中,计算机视觉正在逐渐转向一个模型执行多个不同任务。存在各种多任务学习方法[25, 41, 44, 73, 97],但它们通常仅限于固定的、预定义的任务数量。最近,受LLMs中上下文学习启发的方法摒弃了任务的任何概念,而是让模型直接从输入提示中推断任务。例如,Visual Prompting [8, 87] 在测试时接受任务输入/输出示例对,以及一个查询图像,将它们连接成一个 2x2 的图像,然后使用修复生成所需的输出。但由于修复是使用 MAE [39] 的变体执行的,这些方法也继承了与扩展相关的相同问题。
自回归视觉模型。使用自回归模型合成视觉数据的想法至少可以追溯到 70 年前。受到 Shannon 使用 N-gram 合成语言的启发 [74, 75],许多作品,从 Attneave 的开创性的 1954 年论文开始 [5],应用了这个想法来顺序合成像素 [29, 32, 40, 65]、图像块 [28]、视频帧 [69] 和动作捕捉数据 [4, 45, 49]。随着深度模型的普及,较新的作品用 RNNs 或 CNNs 替代了 N-grams 进行像素合成 [81, 82]。最近,基于 Transformer 的自回归视觉生成方法已被提出 [16, 30, 94, 96],并与语言结合,展示了令人印象深刻的图像合成结果,例如 Parti [95]。?
3. 数据
“数据!数据!数据!没有黏土我就无法制作砖!” ——福尔摩斯
任何大型预训练模型的关键要求是必须在大量数据上进行训练。对于语言模型,非常庞大且非常多样化的数据集相对较容易获得。例如,流行的 Common Crawl 存储库 [1] 包含了跨足整个 Web 的2500 亿个网页,非常多样化,并包括“自然演示”(如语言翻译、问答等)。在计算机视觉领域,我们离拥有一个相当大且多样化的数据源仍然很远。我们工作的一个中心贡献之一是迈向策划这样一个数据集的第一步,我们称之为统一视觉数据集 v1(Unified Vision Dataset,UVDv1)。为了组装它,我们利用了许多不同的视觉数据源:(1)未标记的图像,(2)带有视觉注释的图像,(3)未标记的视频,(4)带有视觉注释的视频和(5)3D合成对象。未标记的图像占我们数据的80% 以上,捕捉了我们视觉世界的大部分内容,并提供了所需的多样性,但质量较低。带有注释的图像具有更受限制的分布,但通常质量较高。视频数据甚至更受限制(通常限制在人类中心活动),但是是时间数据的宝贵来源。3D 合成对象的渲染在多样性方面最低,但可以提供有关 3D 结构行为的宝贵提示。重要的是,UVDv1 是一个纯粹的视觉数据集,没有包含任何非视觉元数据(例如文本)。总的来说,UVDv1 包含 16.4 亿张图像。
与大型语言模型的另一个重要区别是,语言数据具有自然的、统一的一维结构,适用于所有数据——一系列文本。不幸的是,对于视觉数据来说情况并非如此,不同的来源都有不同的结构。在这项工作中,我们提出了 “visual sentence” 作为视觉数据的统一单位,使我们能够从各种来源训练可扩展的模型。视觉句子简单地是一个包含一个或多个图像的序列,后跟一个句子结束(end-of-sentence,EOS)标记。图 1 显示了各种数据源如何被分割成视觉句子。具体而言:
单个图像。单个图像本身就代表了视觉句子的最简单形式——{图像,EOS}。我们使用了 LAION 5B [71] 数据集的 14.9 亿张图像的经过筛选的子集 [88]。这是我们数据的迄今为止最大的部分,占据了 88.5%。?
图像序列。图像序列是一种自然的视觉句子形式。我们通过从各种现有数据集 [12, 13, 22, 36, 37, 47, 51, 52, 56, 58–60, 64, 68, 76–78, 92, 93] 中获取视频数据来创建这样的序列。通过在三个不同的步幅(10、20 和 30)上对视频进行随机采样,形成了包含 16 帧的视觉句子。此外,我们利用Objaverse 数据集 [23] 中的合成 3D 对象,为各种对象生成以对象为中心的多视图序列。对于每个对象,我们在对象中心和摄像机之间采样一个半径长度(从 1.5 到 2.2),并从 -45 度到 45 度采样一个恒定的仰角,然后通过更改方位以 15 度的步长遍历对象的不同视图,并渲染 24 个视图。我们总共为训练渲染了 42000 个这样的序列和 8000 个测试序列。最后,我们还可以将属于相同语义类别的图像表示为(属于)一个序列。我们使用 ImageNet 中的类别,将同一类别中的图像组合在一起(2、4、8 或 16张),形成一个包含 16 张图像的视觉句子。?
带有注释的图像。为了以一致的方式处理不同类型的图像注释,我们选择将所有注释表示为图像。一些数据类型,例如语义分割图 [100]、边缘图 [79]、深度 [66] 和法线图 [6],已经以这种方式表示。对于其他类型的数据,例如:1)目标检测:遵循 [15] 中的方法,我们通过在每个对象周围叠加一个彩色编码的边界框来创建注释;2)人体姿势:利用 MMPose [20],人体骨架在像素空间中呈现,符合OpenPose 格式;3)深度估计、表面法线和边缘检测:给定 ImageNet 和 COCO 图像,我们按照 [55] 中的协议生成注释。3)风格转移 [9]、去雨 [98]、去噪 [85]、低光增强 [89] 和立体数据集 [34]:这些都表示为图像对(例如输入/输出)。4)着色:我们将 ImageNet 图像转换为灰度图,生成图像对。5)修复:这个过程涉及在图像中随机添加黑色框,以模拟破坏,生成图像对。对于上述所有注释类型,我们可以通过将相同注释类型的 8 个图像对连接成一个包含 16 张图像的视觉句子来创建。对于包含 k 个不同注释的相同图像的数据集,我们使用不同的方法:对于每组 1 + k 个图像(输入加上 k 个注释),我们随机选择 m 个元素,其中 m ≤ k + 1 ≤ 16。然后将这些 m 元组连接起来形成视觉序列。
带注释的图像序列。将带注释的视频数据(VIPSeg [57],Hand14K [31],AVA [60],JHMDB [42])转换为视觉句子时,我们采用了两种互补的策略。第一种方法类似于我们处理带有配对注释的图像数据的方法:每个视觉句子由帧及其注释串联而成——{frame1,annot1,frame2,annot2,...}。第二种方法涉及将多个帧与其相应的注释分组——{frame1,frame2,annot1,annot2,...}。在附录中,我们详细总结了 UVDv1 的所有数据来源、注释类型和数据统计。?
4. 方法?
在本节中,我们描述了我们自回归的大型视觉模型的设计。与自然呈现离散序列结构的文本数据不同,对于视觉句子中的图像像素,建模并不直接。在这项工作中,我们采用了两阶段方法:1)训练一个大型的视觉标记器(它对单个图像进行操作),将每个图像转换为一系列视觉标记;2)在视觉句子上训练一个自回归 transformer 模型,每个句子都表示为一系列标记。我们在图 2 中总结了我们的方法。
4.1 图像标记化?
虽然视觉句子在相邻图像之间呈现序列结构,但在图像内部并没有这样的自然序列结构。因此,为了将 transformer 模型应用于图像,先前的研究通常采取以下之一的方法:要么按照扫描线顺序将图像分割成块,并将其视为一个序列 [27],要么使用预先训练的图像标记器,例如 VQVAE [83] 或VQGAN [30],将图像特征聚类到离散标记的网格中,然后再按扫描线顺序将其转换为一个序列。我们采用后一种方法,因为模型的离散分类输出自然形成一个概率分布,可以轻松从中进行采样,从而在视觉句子中实现灵活的条件生成新图像。
具体而言,我们使用由 VQGAN 模型生成的语义标记,这是由 Esser 等人 [30] 引入的概念。该框架包括一个编码和一个解码机制,具有一个将输入图像分配给已建立的代码书中的一系列离散标记的量化层。我们的编码器和解码器完全由卷积层构建。编码器配备了几个降采样模块,以缩小输入的空间尺寸,而解码器则配备了一个相当的上采样模块系列,将图像还原到其初始大小。对于给定的图像,我们的 VQGAN 标记器产生 256 个离散标记。
需要注意的是,我们的标记器独立地在单个图像上操作,而不是一次在整个视觉句子上操作。这种独立性使我们能够将标记器的训练与下游的 Transformer 模型解耦,从而使标记器能够在单个图像的数据集上进行训练,而无需考虑视觉句子的分布。
实施细节:我们采用了 Chang 等人的现成的 VQGAN 架构 [14]。我们遵循 Chang 等人 [14] 中的确切配置,该配置使用了一个降采样因子 f=16 和代码书大小 8192。这意味着对于一个大小为 256 × 256 的图像,我们的 VQGAN 标记器会产生 16 × 16 = 256 个令牌,每个令牌可以取 8192 个不同的值。我们发现使用 ImageNet 预训练标记器的结果在 ImageNet 图像之外泛化效果不佳。因此,我们在 LAION 5B 数据集 [71] 的一个 15 亿子集上训练我们自己的标记器。
4.2 视觉句子的序列建模?
在使用 VQGAN 将图像转换为离散标记之后,我们通过将来自多个图像的离散标记串联成一个 1D 序列来将我们的视觉句子视为一个统一的序列。重要的是,所有的视觉句子都被平等地对待——我们不使用任何特殊标记来指示特定的任务或格式。我们使用因果 Transformer 模型进行训练,使用交叉熵损失进行下一个标记预测,这类似于语言模型的标准方法 [11]。在所有视觉句子上以相同的方式训练模型使得模型能够从上下文中推断图像之间的关系,而不是从任务或格式特定的标记中推断。这为模型提供了一个泛化到其他未见的视觉句子结构的机会。
实施细节:在将每个图像标记化为 256 个标记后,我们将它们串联起来形成一个 1D 标记序列。在视觉标记序列之上,我们的 Transformer 模型实际上与自回归语言模型几乎相同,因此我们采用了LLaMA [80] 的 Transformer 架构,这是一个流行的开源语言模型,具有广泛可用的实现。我们使用 4096 个标记的上下文长度,可以适应我们的 VQGAN 标记器下的 16 个图像。与语言模型类似,我们在每个视觉句子的开头添加一个 [BOS](句子开头)标记和一个 [EOS](句子结尾)标记,并在训练时使用序列连接 [19] 来提高效率。我们在整个 UVDv1 数据集上(4200 亿标记)使用一个 epoch(简单的 epoch 训练是语言模型中的标准做法,以避免潜在的过拟合)进行模型训练。我们训练了 4 个具有不同参数数量的模型:3 亿、6 亿、10 亿和 30 亿,遵循相同的训练配置。我们在附录 6 中提供了详细的训练超参数。
4.3 通过视觉提示进行推理?
由于我们模型中的自回归 Transformer 输出了在先前标记的条件下下一个标记的概率分布,因此我们可以轻松地从这个分布中进行采样,生成视觉句子的新视觉标记。为了在下游任务中使用模型,可以在测试时构建一个定义任务的部分视觉句子,并将模型应用于生成输出。这类似于语言模型中的上下文学习 [10] 或计算机视觉中的视觉提示 [8, 40]。?
5. 实验结果与分析?
在本节中,我们评估了我们训练模型的可扩展性能力,以及其理解和回答各种提示任务的能力。
5.1 可扩展性
我们研究了我们模型的可扩展行为,包括在训练过程中增加模型大小以及在训练过程中看到的标记数量方面的表现。
训练损失。我们首先检查了不同参数大小的 LVM 的训练损失,我们在图 3 中展示了这些结果。由于我们的所有模型仅在数据集上训练了一个 epoch,模型只看到给定的数据样本一次,因此在训练的任何时刻,训练损失与验证损失非常相似。可以观察到随着训练的进行:1)无论模型大小如何,模型的训练损失(困惑度)持续下降;2)随着模型大小(参数数量)的增加,损失下降得更快。这些观察结果表明,LVM 在更大的模型和更多的数据方面表现出很强的可扩展性。
在下游基准测试中的可扩展性。虽然 LVM 整体损失在训练过程中表现出良好的可扩展性,但不能保证更好的整体模型在给定的特定下游任务上也表现更好。因此,我们在四个下游任务上评估不同大小的模型:语义分割、深度估计、表面法线估计和边缘检测。我们在 ImageNet 验证集上评估这些任务,并使用第 3 节中描述的相应方法生成所有的注释。对于每个任务,我们提供了 5 对由输入和相应的地面真实注释组成的对,以及查询图像作为输入提示,并评估我们模型对下一个 256 个标记(一个图像)的预测下地面真实注释的困惑度。我们在图 4 中报告了结果。我们看到更大的模型确实在所有任务中实现了更低的困惑度,显示出我们的可扩展的整体性能确实可以迁移到各种下游任务。
数据集消融。虽然 LVM 通过使用更大的模型和更多的数据获得更好的性能,但自然会问每个我们在 UVDv1 中收集的数据组件是否都有帮助。为了回答这个问题,我们对我们的数据集进行了消融研究,通过在我们数据集的子集上训练多个 3B 模型,并比较它们在下游任务中的性能。我们使用与之前相同的四个下游任务和设置,并在图 5 中呈现结果。我们观察到每个数据组件对下游任务都有积极的贡献。LVM 不仅受益于更大的数据,而且还随着数据集中更多的多样性而改善,其中包括注释和无监督的图像和视频数据。
5.2 序列提示
我们从最直观和直接的视觉提示 LVM 的方法开始:序列推理。在这里,提示构建非常简单:我们向模型呈现 7 张图像的序列,并要求它预测下一张图像(256 个标记)。
视频帧预测。顺序提示的最直接任务是视频预测。图 6 呈现了几个来自 Kinetics-700 验证集的序列提示的下一帧预测示例。在顶部,7 帧提示(蓝色边框)后面是预测的帧(红色边框)。我们观察到在空间定位、视角和物体理解方面存在一定程度的推理能力。在 Kinetics 验证集上的预测困惑度为 49.8。最后 4 行显示了具有更长上下文(15 帧)和更长预测(4 帧)的预测。有关更多示例,请参见附录中的图 17 至 22。
旋转和类别预测。同样类型的简单顺序提示也可以以其他方式使用。例如,图 16 显示了如何通过提示模型使用合成对象围绕任意轴的 3D 旋转的序列,使其能够预测进一步的旋转。或者我们可以将给定类别的项目列表视为一个序列,并预测该类别中的其他想法,如图 15 所示。请注意,尽管该系统是在来自相同 ImageNet 类别的图像组上训练的,但在这里,提示由草图组成,这些草图在任何注释数据中都没有看到过。
上下文长度分析。接下来,我们询问需要多少时间上下文准确预测后续帧。我们在提示长度变化的情况下评估了模型的帧生成困惑度(从1到15帧)。如图 7 所示,在 Kinetics-700 验证集上,我们看到从 1 到 11 帧的困惑度明显提高,之后稳定下来(从 62.1 → 48.4)。
5.3 类比提示
我们的研究通过评估更复杂的提示结构而进行,我们称之为 “类比提示”(Analogy Prompting)。该方法挑战模型理解任意长度和复杂度的类比,从而测试其高级解释能力。
定性结果。图 8 展示了在许多任务上使用类比提示的定性结果的抽样。提示由一个包含各种任务示例的 14 张图像的序列组成,后面是一个第 15 张查询图像。在给定每个提示的情况下,预测的下一张图像是结果。图的顶部显示了定义训练集中任务的几个示例提示(但这些实际图像在训练中从未见过)。图的底部演示了对训练中从未显示的任务的泛化。请参见附录以获取更多定性示例。
未见过的任务和数据集。我们展示了在 Pascal 3D+ [90] 上进行的关键点检测的结果,使用标准的Correct Keypoints 百分比(PCK)度量,阈值为 0.1。值得注意的是,LVM 在没有对该数据集进行训练的情况下实现了 81.2 的PCK,显示出令人印象深刻的泛化能力。相比之下,我们展示了一些现有的任务特定模型:StackedHourglass [61] 得分 68.0 的 PCK,MSS-Net [43] 达到 68.9 的PCK,StarMap [101] 达到 78.6 的 PCK。
与视觉提示的比较。与我们最接近的方法,同时允许定义任意任务的是视觉提示 [8]。在表 1 中,我们比较了各种视觉提示模型在少样本分割、目标检测和着色任务上的表现。请注意,我们的序列LVM 在几乎所有任务上都超过了以前的方法。
任务合成。图 9 展示了在单个提示中将多个任务组合在一起的情况。在这里,我们演示了旋转任务与新颖的关键点对应任务,并要求模型继续模式。模型能够在测试时成功地将这两个任务组合起来,展示了一定程度的组合能力。
5.4 杂项提示
在这里,我们试图通过向模型提供各种以前未见过的提示来看看我们的模型能走多远。图 10 显示了一些效果相当不错的此类提示。图 11 显示了一些难以用词语描述的提示 - 这些是 LVMs 最终可能超越 LLMs 的任务类型。 在图 13 中,我们展示了在典型的非语言人类智商测试中找到的典型视觉推理问题的初始定性结果(雷文渐进矩阵 [67])。通过仔细观察,人们可以想象 LVM 具有掌握抽象视觉模式并将所掌握的模式应用于推断所示视觉序列的潜在能力。这令人兴奋的结果值得进一步研究。
6. 局限性
图 12 展示了当前模型的一些典型失败案例。一个常见的元素是使用视觉提示来定义任务通常是不受约束的(比语言更不受约束,因为图像是非常高维的),或者请求的任务可能超出了当前系统的能力。其他更平凡的失败涉及与标记器的问题和缺乏高质量的视频训练数据。有限的计算资源严重限制了我们探索一系列有趣的问题,包括不同数据集和详细消融研究的影响。重要的是要注意,尽管这是迄今为止最大的视觉模型之一,但与现代大型语言模型相比,它仍然相对较小。因此,大型视觉模型的出现和真正泛化的问题仍然是完全开放且值得进一步研究的。
S. 总结
S.1 主要贡献
本文介绍一种序列建模方法来学习大视觉模型(Large Vision Model,LVM),而无需使用任何语言数据。为此,定义了一个通用格式,“视觉句子”(visual sentences),将各种各样的视觉数据(原始图像和视频,以及带注释的视觉数据源)表示为序列,然后模型被训练利用交叉熵损失预测下一个标记。
S.2 数据处理
统一视觉数据集 v1(Unified Vision Dataset,UVDv1)包含许多不同的视觉数据源:(1)未标记的图像,(2)带有视觉注释的图像,(3)未标记的视频,(4)带有视觉注释的视频和(5)3D合成对象。
视觉句子(visual sentence)是视觉数据的统一单位,是一个包含一个或多个图像的序列,后跟一个句子结束(end-of-sentence,EOS)标记。
- 单个图像:其本身就代表了视觉句子的最简单形式——{图像,EOS}。
- 图像序列。图像序列是一种自然的视觉句子形式。1)对视频进行随机采样,形成了包含 16 帧的视觉句子;2)由对象的不同视图(距离/仰角)渲染的包含 24 个视图的序列;3)将相同语义类别的 16 张图像表示为一个序列。
- 带有注释的图像。将所有注释(语义分割图、边缘图、深度和法线图)表示为图像。对于所有注释类型,通过将相同注释类型的 8 个图像对连接成一个包含 16 张图像的视觉句子来创建。对于包含 k 个不同注释的相同图像的数据集,使用不同的方法:对于每组 1 + k 个图像(输入加上 k 个注释),随机选择 m 个元素,其中 m ≤ k + 1 ≤ 16。然后将这些 m 元组连接起来形成视觉序列。
- 带注释的图像序列。将带注释的视频数据转换为视觉句子时,采用了两种互补的策略。第一种方法:每个视觉句子由帧及其注释串联而成——{frame1,annot1,frame2,annot2,...}。第二种方法涉及将多个帧与其相应的注释分组——{frame1,frame2,annot1,annot2,...}。
S.3 架构和方法
LVM 的架构如图 2 所示。使用两阶段方法:
- 训练一个大型的视觉标记器(例如,VQVAE 或 VQGAN,它对单个图像进行操作),将每个图像转换为一系列视觉标记。
- 在视觉句子上训练一个自回归 transformer 模型,每个句子都表示为一系列标记。
编码器和解码器完全由卷积层构建。编码器配备了几个降采样模块,以缩小输入的空间尺寸,而解码器则配备了一个相当的上采样模块系列,将图像还原到其初始大小。
使用因果 Transformer 模型进行训练,使用交叉熵损失进行下一个标记预测。
由于自回归 Transformer 输出了在先前标记的条件下下一个标记的概率分布,因此可以轻松地从这个分布中进行采样,生成新视觉标记。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!