整合来自不同来源的数据,例如图像和文本,是多模态AI的核心。这涉及结合(将数据混合在一起)和表示学习(将数据转换为通用格式或找出格式间的联系)等策略。为了构建实现这些策略的系统,需要特定的结构设计。这里将考察使用神经网络的基本结构或“架构”。这些架构可被视为多模态AI中经常看到的基本蓝图。处理多种数据类型的一种非常常见的方法是,首先分别处理每种类型,然后将它们处理后的信息结合起来。想象一下你有一张图片和一段文字,你希望系统能将它们一起理解。独立处理(编码):图像进入“图像编码器”。系统此部分专门用于理解图像。它可能是一个卷积神经网络(CNN),用于查找边缘、形状、纹理,最终输出一组数字(一个特征向量,我们称之为$v_{\text{图像}}$),这组数字代表重要的视觉信息。同样,文本进入“文本编码器”。此部分擅长理解语言。它可能是一个循环神经网络(RNN)或基于Transformer的模型,将单词转换为数值表示,并试图捕捉句子的含义,同样输出一个特征向量,$v_{\text{文本}}$。特征结合: 一旦我们有了这两个特征向量,$v_{\text{图像}}$和$v_{\text{文本}}$,我们需要将它们结合。一种简单有效的方法是直接将它们首尾相接。此操作称为拼接: $$ v_{\text{结合}} = \text{拼接}(v_{\text{图像}}, v_{\text{文本}}) $$ 这个新的向量,$v_{\text{结合}}$,现在在一个单一表示中包含了来自图像和文本的信息。联合处理: 这个结合后的向量随后被送入神经网络的另一部分,通常称为“联合处理单元”或“结合层”。这个单元,通常由一个或多个密集(全连接)层组成,学习理解结合后的信息以执行特定任务。这可以是从回答关于图像的问题(视觉问答)到为图像生成字幕的任何任务。这种架构模式允许每种模态先由专门组件进行初步理解,然后其信息再被合并。它相当灵活,因为结合点可以发生在早期(如果$v_{\text{图像}}$和$v_{\text{文本}}$是非常原始的特征),也可以稍晚(如果它们是经过更多处理的抽象特征),这与我们之前讨论的早期和中间结合策略很好地吻合。digraph G { rankdir=TB; graph [fontname="Arial"]; node [shape=box, style="filled", fontname="Arial", margin=0.2]; edge [fontname="Arial", fontsize=10]; subgraph cluster_image { label="图像模态"; labeljust="l"; bgcolor="#e9ecef"; image_input [label="图像数据", shape=ellipse, fillcolor="#a5d8ff"]; image_encoder [label="图像编码器\n(例如, CNN)", fillcolor="#74c0fc"]; image_features [label="图像特征\n(v_图像)", shape=parallelogram, fillcolor="#4dabf7"]; image_input -> image_encoder; image_encoder -> image_features; } subgraph cluster_text { label="文本模态"; labeljust="l"; bgcolor="#e9ecef"; text_input [label="文本数据", shape=ellipse, fillcolor="#ffc9c9"]; text_encoder [label="文本编码器\n(例如, RNN)", fillcolor="#ffa8a8"]; text_features [label="文本特征\n(v_文本)", shape=parallelogram, fillcolor="#ff8787"]; text_input -> text_encoder; text_encoder -> text_features; } combine_features [label="特征结合\n(例如, 拼接)", shape=invhouse, fillcolor="#96f2d7"]; joint_processing [label="联合处理单元\n(例如, 全连接层)", fillcolor="#63e6be"]; final_output [label="最终输出\n(例如, 预测, 答案)", shape=ellipse, fillcolor="#38d9a9"]; image_features -> combine_features [label=""]; text_features -> combine_features [label=""]; combine_features -> joint_processing [label="v_结合"]; joint_processing -> final_output; }独立的编码器处理图像和文本数据。它们提取的特征($v_{\text{图像}}$,$v_{\text{文本}}$)随后被结合(例如,拼接成$v_{\text{结合}}$),并送入联合处理单元以产生最终输出。另一种重要架构方法与学习共享表示的想法相符。这里的目标是将来自不同模态的信息投射到一个公共空间中,使其表示可以被直接比较或有意义地结合,就好像它们“说同一种语言”一样。为此设计的架构通常包含:模态专用编码器: 与前一种模式一样,每种数据类型(例如,图像、音频片段)都通过其自己的专用编码器进行初步处理。假设这些编码器输出初始表示$e_{\text{图像}}$和$e_{\text{音频}}$。投影到共享空间: 核心步骤是将这些初始表示转换为一个共同的共享表示空间。这通常通过额外的神经网络层(投影头)完成,这些层将$e_{\text{图像}}$和$e_{\text{音频}}$分别映射到新的向量$s_{\text{图像}}$和$s_{\text{音频}}$,它们存在于这个共享空间中。 $$ s_{\text{图像}} = \text{投影}{\text{图像}}(e{\text{图像}}) $$ $$ s_{\text{音频}} = \text{投影}{\text{音频}}(e{\text{音频}}) $$ 这种架构的训练过程通常涉及一个目标函数(例如对比损失或三元组损失,这些是更高级的话题),该函数促使如果图像和音频对应(例如,一张狗叫的图片和一段狗叫的音频),则$s_{\text{图像}}$和$s_{\text{音频}}$在共享空间中彼此靠近,否则彼此远离。共享空间中的操作: 一旦来自不同模态的表示进入这个共享空间,它们可用于各种任务:相似度测量: 计算图像与一段文本或音频的相似程度。跨模态检索: 为给定文本查询查找最相关的图像,反之亦然。结合处理: 共享空间中的特征可以由另一个网络进一步处理。这种架构对于学习联合嵌入的模型来说是根本的,它有效地在不同类型数据最初表示信息的方式之间架起了一座桥梁。digraph G { rankdir=TB; graph [fontname="Arial"]; node [shape=box, style="filled", fontname="Arial", margin=0.2]; edge [fontname="Arial", fontsize=10]; subgraph cluster_modality_A { label="模态A (例如, 图像)"; labeljust="l"; bgcolor="#e9ecef"; modA_input [label="输入A", shape=ellipse, fillcolor="#bac8ff"]; modA_encoder [label="编码器A", fillcolor="#91a7ff"]; modA_projection [label="投影头A", fillcolor="#748ffc"]; modA_input -> modA_encoder [label=""]; modA_encoder -> modA_projection [label="e_A"]; } subgraph cluster_modality_B { label="模态B (例如, 音频)"; labeljust="l"; bgcolor="#e9ecef"; modB_input [label="输入B", shape=ellipse, fillcolor="#fcc2d7"]; modB_encoder [label="编码器B", fillcolor="#faa2c1"]; modB_projection [label="投影头B", fillcolor="#f783ac"]; modB_input -> modB_encoder [label=""]; modB_encoder -> modB_projection [label="e_B"]; } shared_space_ops [label="共享表示空间\n(操作: 比较, 检索等)", shape=cylinder, fillcolor="#d0bfff", width=3]; final_output_shared [label="最终输出\n(例如, 相似度得分, 检索项)", shape=ellipse, fillcolor="#b197fc"]; modA_projection -> shared_space_ops [label="s_A"]; modB_projection -> shared_space_ops [label="s_B"]; shared_space_ops -> final_output_shared; }来自模态A和模态B的数据被独立编码(生成$e_A$, $e_B$),然后投影(生成$s_A$, $s_B$)到一个共享表示空间,在那里它们可以被比较或用于其他联合任务。有时,更有效的方法是让每种模态几乎完全由其各自的专用模型处理,然后在最后结合它们的个体输出或预测。这种方法称为晚期结合架构。其典型工作方式如下:独立单模态模型: 你为每种模态都拥有独立的、通常是完整的AI模型。例如,一个模型可能分析电影评论(文本)以预测其情感(积极、消极或中性)。假设其预测是$p_{\text{文本}}$。另一个模型可能分析用户在朗读评论的音频录音中的语调,以检测其情绪(快乐、悲伤、愤怒)。我们称其预测为$p_{\text{音频}}$。独立预测/输出: 这些单模态模型中的每一个都产生自己的输出。这些输出可以是类别概率(例如,文本情感为70%积极,30%消极)、类别标签,甚至是数值分数。决策层结合: 最后一步是结合这些独立预测,以得出整体的多模态决策。这种结合可以通过多种方式实现:简单规则: 平均概率分数,如果输出是类别标签则采取多数票,或者如果某个模态被认为更可靠则使用加权平均。小型元模型: 一个简单的模型,如逻辑回归或小型神经网络,可以被训练以单模态预测($p_{\text{文本}}$,$p_{\text{音频}}$)作为输入,并学习将它们结合成最终预测$p_{\text{最终}}$的最佳方式: $$ p_{\text{最终}} = \text{元模型}(p_{\text{文本}}, p_{\text{音频}}) $$当模态差异很大,或者当你已经拥有希望结合而无需从头开始重新训练所有内容的高性能单模态模型时,晚期结合特别有用。它通常比早期或中间结合更容易实现,因为核心单模态处理路径在很大程度上保持独立。digraph G { rankdir=TB; graph [fontname="Arial"]; node [shape=box, style="filled", fontname="Arial", margin=0.2]; edge [fontname="Arial", fontsize=10]; subgraph cluster_model_A { label="单模态路径A"; labeljust="l"; bgcolor="#e9ecef"; input_A [label="模态A数据\n(例如, 文本)", shape=ellipse, fillcolor="#d8f5a2"]; model_A [label="模型A\n(例如, 文本情感分析器)", fillcolor="#c0eb75", width=2.5]; output_A [label="预测A\n(p_文本)", shape=parallelogram, fillcolor="#a9e34b"]; input_A -> model_A; model_A -> output_A; } subgraph cluster_model_B { label="单模态路径B"; labeljust="l"; bgcolor="#e9ecef"; input_B [label="模态B数据\n(例如, 音频)", shape=ellipse, fillcolor="#ffd8a8"]; model_B [label="模型B\n(例如, 音频情绪检测器)", fillcolor="#ffc078", width=2.5]; output_B [label="预测B\n(p_音频)", shape=parallelogram, fillcolor="#ffa94d"]; input_B -> model_B; model_B -> output_B; } decision_fusion [label="决策结合单元\n(例如, 平均, 投票, 元模型)", shape=cds, fillcolor="#99e9f2", width=3]; final_multimodal_output [label="最终多模态输出\n(p_最终)", shape=ellipse, fillcolor="#66d9e8"]; output_A -> decision_fusion; output_B -> decision_fusion; decision_fusion -> final_multimodal_output; }独立模型处理模态A和模态B,产生预测$p_{\text{文本}}$和$p_{\text{音频}}$。这些预测随后由决策结合单元结合,以产生最终的多模态输出$p_{\text{最终}}$。这些架构模式是使用神经网络工具包中的标准工具构建的。尽管第四章将更详细地介绍特定组件,但值得了解的是,这些架构通常使用:编码器网络:对于图像,卷积神经网络(CNN)在提取视觉特征方面非常常见。对于文本,循环神经网络(如LSTM或GRU)或Transformer网络常用于处理词序列。对于音频,CNN(常应用于声音的频谱图表示)或RNN可用于捕捉时间模式。结合与转换层:密集层(也称为全连接层)是结合来自不同来源的特征向量、将特征投影到共享空间或作为联合处理单元一部分的主力。它们在学习数值输入之间的复杂关系方面用途广泛。任务专用输出层:网络的最终层将根据特定任务进行定制。例如,带有softmax激活函数的层用于分类任务(如识别对象或情感类别),而线性层可能用于回归任务(如预测分数)。在此阶段,你无需掌握所有这些层类型。重要要点是,这些多模态架构是通过连接不同类型的神经网络层组装而成的,每种层都擅长特定类型的处理,以有效地处理和整合来自多个数据源的信息。明确地将这些基本架构与我们本章前面讨论的结合策略联系起来会有帮助:独立编码器、联合处理架构高度灵活。它可以实现:早期结合: 如果结合(例如,拼接)发生在原始数据或由浅层编码器提取的非常低级特征时。中间结合: 如果来自编码器深层的、经过更多处理的抽象特征被结合。我们看过的第一个图通常代表这种形式的中间结合。共享表示架构根本在于学习一个共同点。虽然结合主要关乎组合数据流,但共享表示学习侧重于转换模态,使它们变得可比较或可以在这个公共空间中整合。这通常涉及旨在对齐不同模态的专门训练目标。晚期结合架构直接实现了晚期结合策略。在这里,结合发生在决策或预测层面,在每种模态经过其各自专用模型广泛而独立的处理之后。这些模式并非僵化、相互排斥的类别。实际中许多高级多模态系统可能会混合这些基本结构的元素。例如,一个系统可以使用独立的编码器,将其输出投影到半共享空间进行一些初步的联合处理(一个中间结合步骤),甚至可能在最终输出层之前纳入注意力机制(我们接下来会提到)。然而,理解这些基本架构模式为理解你可能遇到的更复杂多模态AI系统提供了扎实的起点。