news 2026/4/16 19:33:37

多模态学习架构

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
多模态学习架构

一、什么是多模态学习?

多模态(Multimodal)指的是不同类型的数据形式:文本、图像、音频、视频、点云、传感器信号等。人类天然就是多模态学习 者——同时通过视觉、听觉、听觉来理解世界。 多模态学习的核心目标是让模型能够联合理解并关联来自不同模态的信息。比如一张狗的图片,同时听到“汪汪”的声音,模型应该能够把这两者关联起来。

二、核心挑战

1.表示不同性

不同模态的数据结构差异巨大:图像是密集的像素网格,文本是离散的符号序列,音频是连续的波形信号。如何把它们映射到一个可比较的语义空间?

2.对齐问题

如何建立跨模态的对应关系? 比如一句话“一只棕色的狗在草地上跑步”,其中“棕色”对应图像的哪个区域?“跑步”对应视频的哪一帧?

3.融合策略

何时融合、如何融合不同模态的信息?过早融合可能会丢失模态信息,过晚融合可能会丢失跨模态交易。

4.模态与不平衡

训练时某些模态数据可能失效或噪声大,如何保证鲁棒性?

三、架构演进路线

1.双塔结构

最简洁的设计思路:每个模态用独立的编码器,最后在共享空间中对齐。

图像 → Image Encoder → 图像向量 ↘ → 对比学习(Contrastive) 文本 → Text Encoder → 文本向量 ↗

代表模型:CLIP (2021)

Python# CLIP的核心思想伪代码 image_features = image_encoder(images) # [B, D] text_features = text_encoder(texts) # [B, D] # L2归一化 image_features = F.normalize(image_features, dim=-1) text_features = F.normalize(text_features, dim=-1) # 计算相似度矩阵 logits = image_features @ text_features.T * temperature # [B, B] # 对比损失:对角线上的配对应该相似度最高 labels = torch.arange(B) loss = (F.cross_entropy(logits, labels) + F.cross_entropy(logits.T, labels)) / 2 **优点**:结构简单,推理高效(可以预计算特征),zero-shot能力强 **缺点**:缺乏深度跨模态交互,难以处理细粒度理解任务

2.融合编码器

在编码过程中就让不同模态交互,通过Cross-Attention实现深度融合。

图像tokens ──┐ ├──→ Transformer (带Cross-Attention) → 融合表示 文本tokens ──┘

代表模型:ViLT、ALBEF、BLIP

# Cross-Attention的核心机制 class CrossAttention(nn.Module): def forward(self, x, context): # x: 查询模态 [B, N, D] # context: 被查询模态 [B, M, D] Q = self.W_q(x) # Query来自x K = self.W_k(context) # Key来自context V = self.W_v(context) # Value来自context attn = softmax(Q @ K.T / sqrt(d)) return attn @ V # x的每个token"看"context

3. 统一序列建模

把所有模态都tokenize成序列,用统一的Transformer处理。

核心思想:

图像 → ViT 切为补丁标记 文本 → 词表标记化 音频 → 声谱图补丁或离散化音频标记
# 统一序列的构建 image_tokens = vit_patchify(image) # [B, 196, D] text_tokens = embed(tokenize(text)) # [B, L, D] # 拼接成统一序列 unified_seq = concat([image_tokens, text_tokens], dim=1) # 统一Transformer处理 output = transformer(unified_seq)

四、关键技术组件深度解析

多模态完整框架

┌─────────────────────────────────────────────────────────────────┐ │ 多模态大模型 │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ 视觉编码器 │ → │ 投影层 │ → │ 跨模态融合 │ → │ LLM │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ ↑ ↓ │ │ ┌──────────┐ ┌──────────┐ │ │ │ 图像输入 │ │ 输出头 │ │ │ └──────────┘ └──────────┘ │ │ ↓ │ │ ┌──────────┐ ┌──────────┐ 生成的文本 │ │ │ 文本输入 │ → │ Tokenizer │ ─────────────────────→ │ │ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────────────────────────┘

1. 视觉编码器

视觉编码器的任务是把图像转换成神经网络能理解的数值表示(特征表达)。

为什么需要它?

图像原始是像素矩阵,比如一张224×224的RGB图像就是[224, 224, 3]数组,里面是0-255的数值。这些原始 像素对模型来说就是“噪声”——它看不出是一只猫还是一只狗。 视觉编码器的作用就是提取抽取特征:把像素信息压缩成包含“这是什么”的功能。

1. 1 CNN系列(本质神经网络)

主流框架
传统的视觉逐层编码器,通过卷积层提取特征:

原始图像 [224, 224, 3] ↓ Conv层 边缘、纹理特征 [112, 112, 64] ↓ Conv层 局部模式特征 [56, 56, 128] ↓ Conv层 物体部件特征 [28, 28, 256] ↓ Conv层 高级语义特征 [7, 7, 512] ↓ 池化 最终特征向量 [512]

代表模型:ResNet、ConvNeXt

1.2 ViT系列(视觉变压器)

现在多模态模型的主流选择。核心思想是把图像破坏小块(补丁),用“视觉单词”来处理:
图示:

原始图像 224×224 ┌──┬──┬──┬──┐ │P1│P2│P3│..│ 切成14×14=196个patch ├──┼──┼──┼──┤ 每个patch 16×16像素 │P4│P5│P6│..│ ├──┼──┼──┼──┤ │..│..│..│..│ └──┴──┴──┴──┘ ↓ 展平 + 线性投影 [CLS] [P1] [P2] ... [P196] ← 197个tokens ↓ Transformer处理 [全局特征] [局部特征1] [局部特征2] ... [局部特征196]

常用的预训练视觉编码器

模型训练方式特点
CLIP ViT图文对比学习语义理解强,适合多模态
DINOv2自监督学习细粒度特征好,适合分割定位
SigLIP改进的对比学习比CLIP更稳定

1.3 LLM (Large Language Model,大语言模型)

LLM是处理和生成文本的大型神经网络,本质是一个强大的"文字接龙"机器。

核心能力

给定前文,预测下一个词:

输入: "今天天气真" 输出概率: "好"(0.6), "差"(0.2), "热"(0.1), ... ## 2. 投影层 / 连接器 视觉编码器和LLM是独立预训练的,它们的特征空间完全不同。投影层的任务是桥接两个世界,把视觉特征“翻译”成LLM能理解 的语言。 打个比方:编码器说“法语”,LLM说“中文”,投影层就是翻译官 但因为在海量文本上训练,它学会了:语言规律、世界知识、推理能力、指令遵循

架构:仅解码器变压器
现代LLM(GPT系列、LLaMA、Qwen等)都采用了这个架构:

class LLMBlock(nn.Module): def forward(self, x): # 1. 自注意力(Causal/Masked):每个token只能看到之前的tokens x = x + self.self_attention(x, mask=causal_mask) # 2. 前馈网络:非线性变换 x = x + self.feed_forward(x) return x class LLM(nn.Module): def forward(self, input_ids): # 1. 词嵌入:token ID → 向量 x = self.embedding(input_ids) # [B, L, D] # 2. 通过多层Transformer Block for block in self.blocks: # 比如32层 x = block(x) # 3. 预测下一个token的概率分布 logits = self.lm_head(x) # [B, L, vocab_size] return logits

五、训练策略

第一阶段:特征扫描预训练
目标:视觉特征和语言空间景观

# 典型任务:Image Captioning for image, caption in dataloader: visual_tokens = projector(vision_encoder(image)) input_ids = concat([visual_tokens, tokenize(caption)]) loss = llm.forward(input_ids, labels=caption_ids)

第二阶段:指令调优
目标:让模型能够遵循饮食的指令

# 数据格式 { "image": "path/to/image.jpg", "conversations": [ {"from": "human", "value": "<image>\n这张图片里有什么?"}, {"from": "gpt", "value": "这张图片显示了一只金毛犬在海滩上奔跑..."}, {"from": "human", "value": "狗看起来开心吗?"}, {"from": "gpt", "value": "是的,从它张开的嘴巴和..."} ] }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 14:36:23

再见了ThreadLocal,我决定用ScopedValue!

今天我们来聊聊一个即将改变我们编程习惯的新特性——ScopedValue。有些小伙伴在工作中&#xff0c;一提到线程内数据传递就想到ThreadLocal&#xff0c;但真正用起来却遇到各种坑&#xff1a;内存泄漏、数据污染、性能问题等等。其实&#xff0c;ScopedValue就像ThreadLocal的…

作者头像 李华
网站建设 2026/4/16 16:01:29

【机器人路径规划】基于6种算法(黑翅鸢优化算法BKA、SSA、MSA、RTH、TROA、COA)求解机器人路径规划研究附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码及仿真咨询…

作者头像 李华
网站建设 2026/4/16 19:33:20

华为OD机试 B卷 - 稀疏矩阵扫描 (C++ Python JAVA JS GO)

稀疏矩阵扫描 华为OD机试B卷 - 华为OD上机考试B卷 100分题型 华为OD机试真题目录点击查看: 华为OD机试真题题库目录&#xff5c;机考题库 算法考点详解 题目描述 如果矩阵中的许多系数都为零&#xff0c;那么该矩阵就是稀疏的。对稀疏现象有兴趣是因为它的开发可以带来巨大…

作者头像 李华
网站建设 2026/4/15 23:48:02

Go Module构建

添加依赖包 在Go Module项目中添加新依赖包&#xff0c;可以通过修改源码并执行相关命令完成。以添加github.com/google/uuid为例&#xff1a; package mainimport ("github.com/google/uuid""github.com/sirupsen/logrus" )func main() {logrus.Println(&…

作者头像 李华
网站建设 2026/4/15 17:01:21

Python类入门:用“汽车工厂”理解面向对象编程

引言&#xff1a;为什么需要“类”&#xff1f; 想象你是一家汽车工厂的工程师&#xff0c;每天要生产不同型号的汽车。如果每生产一辆车都要重新设计图纸、组装零件&#xff0c;效率会非常低。聪明的做法是&#xff1a;先设计一个“汽车模板”&#xff08;类&#xff09;&…

作者头像 李华