三年前我第一次把摄像头、麦克风和一片压阻薄膜接到同一块采集板上跑通了整条数据链路才真正明白多模态学习难在哪。难的从来不是把三路数据拼进一个张量而是让模型相信这三路信号在描述同一件事。视觉告诉你“这是什么形状”听觉告诉你“它正在发出什么动静”触觉告诉你“它摸起来多硬、多滑、有没有在滑动”。这三者凑在一起机器才勉强拥有了接近人的物体感知能力。这篇内容就把我这几年在视觉、听觉、触觉三模态融合上踩过的坑、验证过的方案、能直接抄的参数一次性摊开讲清楚。适合刚入门多模态学习、准备做机器人感知或人机交互项目的同学也适合已经在做双模态、想补上触觉这一环的从业者。不管你是只会跑通MNIST的新手还是调过跨模态注意力的老手下面这些内容应该都能对得上你的某个具体问题。1. 为什么非要把三个模态塞进一个模型1.1 单模态的天花板到底卡在哪里先说清楚一件事单模态模型不是不能用而是在真实场景里经常“看走眼”。纯视觉模型在识别一个透明玻璃杯时很容易把它判成背景因为玻璃边缘的梯度太弱、反光又干扰颜色分布但如果同时有听觉信号——手指敲击杯壁那一声清脆的衰减音——分类置信度立刻能拉起来。纯触觉也有类似的尴尬压阻阵列能感知到接触力和接触面积却完全不知道摸的是什么形状的物体因为它只有局部接触点的信息没有全局几何。单模态的第二个瓶颈是分布外泛化。视觉模型在光照突变、遮挡、反光条件下掉点非常快听觉模型在背景噪声、混响环境下识别率会断崖式下跌触觉模型换个材质、换个接触角度读数漂移得很厉害。这三种失效模式恰好是互补的——光照坏了对听觉没影响噪声大了对触觉没影响材质换了视觉还能兜底。多模态学习的核心价值就在这儿它不是在单一维度上刷点而是用模态之间的冗余性换鲁棒性。第三个瓶颈更隐蔽是标注成本。视觉标注要框、要掩码听觉标注要转写、要对齐触觉标注最贵——你得真的让机械手去摸几百次还得保证每次接触条件一致。多模态的对比式预训练恰好能缓解这个问题不需要人工标签只要同一时刻采集到的三路信号被认为是“正样本对”模型就能自己学出跨模态的对应关系。这个思路后面会详细讲。1.2 三个模态在物理世界里各自补什么位我把这三个模态的分工总结成一句话视觉给空间与几何听觉给事件与材质线索触觉给力学与物性。视觉擅长的是二维投影到三维结构的推断包括轮廓、纹理、部件分割、位姿。它的信息密度最高一个224×224的RGB帧里塞了几十万个像素值但它的弱点在于“间接”——它看到的永远是表面反射的光不是物体本身。听觉擅长捕捉瞬态事件。物体掉落、碰撞、刮擦、液体倾倒这些过程在视觉上可能只有两三帧的变化但在音频波形上是几百毫秒的完整包络。材质的刚度、空心还是实心、表面粗糙度都会在敲击声的频谱包络里留下痕迹。所以听觉特别适合做“事件触发”和“材质粗分类”。触觉则是唯一直接接触物理世界的模态。它能给出法向力、切向力、接触面积、滑动趋势、表面微观纹理这些视觉和听觉都拿不到的量。抓取任务里判断“有没有抓住”“会不会滑”这件事本质上只能靠触觉。我见过不少团队花大力气用视觉估计抓取力最后发现不如在指尖贴一片几十块钱的压阻薄膜。把这三者放在一起你能做的事情就变成看到一个物体听一下敲击声摸一下表面然后综合判断它是什么材质、有多重、能不能抓、该用多大力。这条链路在分拣、装配、服务机器人、辅助器具里都有直接落地的价值。1.3 我为什么选“分模态编码 中层融合”这套骨架多模态融合的方案大致三类早期拼接、晚期投票、中层融合。我一开始图省事用了早期拼接把图像特征、音频特征、触觉特征归一化后直接concat接个MLP分类头。结果很惨——视觉特征维度是512音频是256触觉只有64拼接之后触觉那点信息被彻底淹没模型基本退化成纯视觉模型。晚期融合每个模态单独出一个预测再加权平均倒是稳但它的致命问题是模态之间不交互。视觉判断是“杯子”听觉判断是“陶瓷”两者都是高置信度加权平均能work可如果视觉说“不确定”听觉说“陶瓷”晚期融合就没法让听觉去修正视觉的特征表示只能修预测结果。最后我锁定的是分模态独立编码 中层交叉注意力融合。每个模态用自己的编码器提特征保证各自的归纳偏置不被破坏然后在中间层用交叉注意力让模态之间互相查询视觉的token可以去“问”触觉的token“你那边接触力多大”触觉也可以反过来问视觉“我这个接触点落在物体的哪个部位”。这套结构的好处是模态缺失时可以直接跳过对应的注意力分支降级非常自然训练时还能做模态dropout逼模型学会单模态也能出结果。提示不要一上来就上复杂的融合结构。先用晚期融合跑一个baseline记录每个单模态的独立性能和融合后的性能这个差值才是你后面所有融合改进的参照系。没有这个baseline你根本判断不了融合模块到底有没有起作用。2. 三个模态的编码器怎么选、怎么调2.1 视觉分支别急着上大模型先把输入规范定死视觉编码器的选型取决于你的任务是不是需要时序。如果只是单帧物体识别或材质分类残差网络类的轻量骨干十几层到三十几层足够用参数量在10M到25M之间推理延迟可控如果涉及抓取过程中的动态变化就需要视频级编码可以用视觉Transformer沿时间维展开或者用轻量的3D卷积。我在实际项目里更看重的是输入规范而不是骨干选型。这几项必须提前定死分辨率、色彩空间、归一化参数、裁剪策略。听起来很琐碎但多模态项目里80%的对齐问题都出在这儿。视觉分支如果用了ImageNet统计量做归一化而其他分支用的是自计算的均值方差融合层的输入分布就是错位的训练会非常不稳定。具体配置我常用这套输入缩放到224×224保持长宽比做中心裁剪RGB三通道均值方差用数据集自统计的值不要图省事直接套公开统计量工业相机和手机摄像头的色彩响应差异很大。如果是视频采样帧率固定到10fps每个样本取16帧这样单样本的视觉token数是196×16量级上还能接受。有一个细节容易被忽略视觉分支的预训练权重是否冻结。我的经验是前两个epoch冻结骨干只训融合层等融合层稳定后再解冻做小学习率微调。直接全参数训练在小数据集上几乎必然过拟合而且会把预训练学到的通用特征洗掉。2.2 听觉分支从波形到log-mel每一步都有讲究听觉这条链路我踩的坑最多。原始波形是16kHz的一维长序列1秒钟就是16000个点直接喂给模型既慢又难学。标准做法是先做短时傅里叶变换转成时频谱再用mel滤波器组压缩到人耳感知相关的频带。参数我一般这么定采样率16kHz足够覆盖材质敲击的主要能量频段再高只会增加计算量窗长25ms对应400个采样点帧移10ms对应160个点这样1秒音频得到约100帧。mel滤波器取80个通道取对数后得到80×100的log-mel谱。这个尺寸对后续的卷积或Transformer都很友好。为什么不直接用MFCC因为MFCC做了离散余弦变换会丢掉频带之间的相关性而材质判别恰恰依赖频谱包络的整体形状不是某几个倒谱系数。做语音识别用MFCC没问题做材质和事件判别我建议保留log-mel。编码器方面小数据集上用几层二维卷积沿着时间和频率方向降采样就够数据量上来了可以换成自监督预训练的语音编码器做初始化效果提升明显但要注意它的输入期望是原始波形还是频谱别搞反了。这里有个隐蔽的坑很多预训练语音模型是在16kHz干净语音上训的你拿工业环境的噪声敲击声去喂它特征分布是偏移的需要做一轮目标域适配哪怕只是用无标签数据跑几百步自监督微调。2.3 触觉分支最容易被低估、也最容易翻车的一环触觉是我认为整个多模态链路里最值得投入的部分因为大部分团队对它的处理都太粗糙了。触觉传感器大致分三类压阻或电容阵列输出二维的力分布图、光学式触觉传感器凝胶表面加相机输出高分辨率的形变图、动态触觉传感器加速度计或麦克风捕捉接触瞬间的振动。不同类型对应的编码方式完全不同。阵列类输出的是一张低分辨率的“力图像”比如16×16用两层卷积就能提特征但要特别注意时域统计量——均值、峰值、方差、接触面积变化率这些手工特征往往比卷积学出来的还稳。光学式输出的图像分辨率高可以复用视觉分支的小型骨干但帧率高、数据量大需要做帧采样。动态触觉本质是音频可以直接复用听觉分支的频谱管线这是个很划算的复用点。我踩过最深的坑是触觉信号的量纲和漂移。压阻传感器的读数受温度影响连续工作两小时后基线会漂不同批次的传感器灵敏度也有差异。所以触觉分支前面必须做两件事一是按通道做滑动窗口的基线校正减去最近若干秒的中位数二是做逐通道的标准化。这两步不做模型学到的就是“这次实验的传感器状态”换个时间采集就废了。还有一个原则触觉特征不要一上来就做全局池化。接触位置在传感器面上的空间分布是有强语义的池化掉就没了。我的做法是保留空间维度做注意力池化让模型自己学哪些接触区域更重要。2.4 三模态传感器的参数对照把三个模态的采集参数放在一张表里对比你就能看出对齐的难点在哪维度视觉听觉触觉阵列触觉动态典型采样率30fps16kHz100Hz1kHz到10kHz单样本时长0.5到2秒0.5到2秒0.5到2秒0.1到0.5秒单样本原始数据量约10MB视频约32KB约1.6KB约10KB时间分辨率33ms0.06ms10ms0.1ms主要噪声源光照、反光、遮挡环境噪声、混响温漂、批次差异结构共振对齐精度要求中等高中等极高从这张表能看出动态触觉的时间分辨率比视觉高两个数量级意味着你不能简单按帧对齐。后面第3节会专门讲对齐方案。3. 对齐与融合真正的难点在这3.1 数据层对齐不是“时间戳取整”这么简单多模态项目里最常见的翻车现场是训练集上指标很漂亮一上真实设备就崩。八成原因是数据层的对齐有系统性偏差。最典型的错误是时间戳取整。视觉30fps触觉100Hz你按最近邻取整把触觉对齐到视觉帧误差最大能到16ms。听起来很小但抓取过程的接触建立和滑移往往就发生在几十毫秒内16ms的错位足以让模型学到错误的因果关联——它会认为“力上升”发生在“物体开始动”之后实际上反了。我的做法是分三级处理。第一级是硬件同步所有传感器用同一个触发信号或同一个时钟源打时间戳这一级的成本最低、收益最大能用硬件解决就别用软件补。第二级是软件重采样把高频模态按时间戳做线性插值重采样到统一的时间栅格上比如统一到100Hz。第三级是时间容差窗口在训练时给每个模态的时间戳加一个小范围的随机抖动正负一个帧周期让模型学会对小幅错位不敏感。这个技巧叫时间抖动增强实测对鲁棒性提升很明显成本几乎为零。还有一个坑是起止点不一致。视觉的录制起止由相机控制触觉由采集板控制两边差个几百毫秒很常见。所以每个样本必须记录绝对时间戳切窗时按时间戳切绝对不能按“第几个采样点”切。这个错误我至少见过三个团队犯过。3.2 表征层对齐对比学习是把三路信号拉到同一坐标系的最省力办法数据层对齐解决的是“同一时刻”表征层对齐解决的是“同一语义”。即使时间对上了视觉特征空间和触觉特征空间仍然是两套完全不同的坐标系——视觉特征的第37维可能代表“边缘强度”触觉特征的第37维可能代表“通道3的基线漂移”。直接拼接或者做注意力等于让两个说不同语言的人对话。对比学习就是给它们配一个翻译。核心思路很朴素同一时刻采集的三路信号是正样本不同样本、不同时刻的组合是负样本训练目标是把正样本在联合空间里拉近、负样本推远。损失函数用InfoNCE温度系数取0.07是常见起点数据量小可以调大到0.1避免过于尖锐。这套方法的价值在于不需要人工标签。你只要采集了大量同步的三模态数据哪怕完全没标注也能先训出一个对齐好的联合表征然后再用少量标注数据接下游任务。对触觉这种标注极贵的模态来说这是唯一现实的路子。实操上有几个细节很关键。负样本的构造要小心同一个物体在不同时刻采集的样本如果强行当负样本会把模型教坏因为它俩语义其实是一样的。所以我一般用跨样本但跨类别的方式构造负样本或者用动量编码器维护一个队列来扩大负样本池。另外三个模态两两之间的对比损失要加权视觉和听觉之间的语义关联比视觉和触觉之间更强因为触觉需要接触很多样本根本没有有效接触权重不能均分。注意事项对比学习阶段千万不要用随机裁剪这类会破坏时间对齐的增强。视觉上裁剪可能把物体裁掉一半听觉上加噪可能改变材质感知这些增强在单模态任务里是好东西在多模态对齐里会直接制造假负样本。3.3 融合策略的横向对比与我的选择依据下面这张表是我在多个项目里实测后整理的供你选型时参考融合方式实现复杂度模态缺失时的表现小样本表现适合场景早期拼接低差需补零占位一般模态维度相近、数据量大晚期加权低好直接去掉权重较好各模态都能独立出结果交叉注意力中高好跳过对应分支需要足够数据模态间有强互补关系门控融合中好门控自然归零好模态可靠性动态变化混合专家高好差易欠拟合超大规模多任务我的默认选择是交叉注意力 门控的组合交叉注意力负责让模态之间交换信息门控负责根据当前样本的可靠性动态调整每个模态的贡献。比如一个样本里触觉信号很弱接触不充分门控会自动把触觉权重压下去避免噪声污染。具体实现上我把视觉特征作为query听觉和触觉特征作为key和value做一次交叉注意力再把结果反过来做一次最后三路特征加原始残差一起送进门控网络。门控就是一个两层MLP加softmax输出三个标量权重。这个结构参数量不大但效果比单纯的拼接稳定得多。4. 从零搭一个三模态模型完整实操4.1 数据管线的搭建步骤第一步定义统一的样本结构。我习惯用这样一个字典视觉是形状为[T_v, 3, 224, 224]的张量听觉是[T_a, 80]的log-mel谱触觉是[T_t, C, H, W]的序列另外附带一个时间戳数组和标签。所有模态的时间长度按统一的时间窗切比如2秒。第二步写一个Dataset类核心逻辑是先按绝对时间戳确定窗口再对每个模态做重采样和插值。这里要注意插值一定要在原始采样率上做不要先把数据降采样再插值那样会引入额外的相位误差。第三步处理缺失模态。真实数据里经常出现某个模态整段无效的情况比如没有接触就没有触觉我的做法是给每个样本加一个模态有效性掩码训练时只在有效模态上算损失无效模态对应位置填零并由门控自动压权重。import numpy as np def resample_to_grid(timestamps, values, grid, methodlinear): 把任意采样率的序列重采样到统一时间栅格 if len(timestamps) 2: return np.zeros((len(grid),) values.shape[1:], dtypenp.float32) out np.empty((len(grid),) values.shape[1:], dtypenp.float32) for i in range(values.shape[1] if values.ndim 1 else 1): v values if values.ndim 1 else values[:, i] out[:, i] np.interp(grid, timestamps, v) return out def build_window(sample, win_sec2.0, grid_hz100): t0 sample[start_ts] grid t0 np.arange(0, win_sec, 1.0 / grid_hz) out {} for mod in [vision, audio, touch]: if mod not in sample or sample[mod] is None: out[mod] None continue ts, val sample[mod][ts], sample[mod][value] out[mod] resample_to_grid(ts, val, grid) out[grid] grid out[mask] {m: out[m] is not None for m in [vision, audio, touch]} return out这段代码的重点不在插值本身而在统一栅格这个设计。所有模态都落到同一个时间轴上之后后面做任何对齐都不用再操心时间戳问题了。栅格频率取100Hz是个折中高于视觉帧率、低于动态触觉能覆盖大多数场景。4.2 模型骨架的关键代码编码器部分按前面说的分模态独立搭建融合层用交叉注意力。这里给出融合部分的核心实现import torch import torch.nn as nn class CrossModalFusion(nn.Module): def __init__(self, d_model256, nhead4, dropout0.1): super().__init__() self.vis_proj nn.Linear(512, d_model) self.aud_proj nn.Linear(256, d_model) self.tac_proj nn.Linear(128, d_model) self.attn_va nn.MultiheadAttention(d_model, nhead, dropoutdropout, batch_firstTrue) self.attn_tv nn.MultiheadAttention(d_model, nhead, dropoutdropout, batch_firstTrue) self.gate nn.Sequential( nn.Linear(d_model * 3, 64), nn.ReLU(), nn.Linear(64, 3) ) self.norm nn.LayerNorm(d_model) def forward(self, v, a, t, masks): v, a, t self.vis_proj(v), self.aud_proj(a), self.tac_proj(t) # 视觉查询听觉与触觉 ctx, _ self.attn_va(v, torch.cat([a, t], dim1), torch.cat([a, t], dim1)) v2 self.norm(v ctx) # 触觉查询视觉让触觉知道自己摸在哪儿 ctx2, _ self.attn_tv(t, v, v) t2 self.norm(t ctx2) pooled torch.cat([v2.mean(1), a.mean(1), t2.mean(1)], dim-1) w torch.softmax(self.gate(pooled), dim-1) # 无效模态权重置零后归一化 valid torch.stack([masks[vision], masks[audio], masks[touch]], dim-1).float() w w * valid w w / (w.sum(-1, keepdimTrue) 1e-6) feats torch.stack([v2.mean(1), a.mean(1), t2.mean(1)], dim1) return (feats * w.unsqueeze(-1)).sum(1), w这段代码里最值得看的是掩码参与权重归一化这一步。很多实现只把无效模态的特征置零但门控仍然会给它分配权重导致有效信息的比例被稀释。把掩码直接乘进权重再重新归一化这才是正确的处理方式。4.3 训练策略分阶段比调参更重要我的训练分三个阶段每个阶段的目标不同。阶段一单模态预热。三个编码器各自接一个简单的分类头独立训练到收敛。这一步的目的是让每个编码器先学到本模态的基本表征避免融合层在早期被随机特征干扰。学习率用3e-4AdamW权重衰减0.01warmup占5%的步数。阶段二对比对齐。去掉分类头用InfoNCE做跨模态对齐。三个模态两两配对视觉-听觉、视觉-触觉、听觉-触觉三个损失的权重我一般取1.0、0.6、0.6。触觉权重低是因为有效触觉样本本来就少权重太高会让模型过度关注接触部分而忽略全局。这个阶段训练20到30个epochbatch size尽量大因为对比学习对负样本数量敏感。阶段三下游微调。加载对齐好的编码器接上融合层和任务头用较小的学习率1e-4左右做端到端微调。这个阶段开模态dropout每个模态以0.2的概率被整体丢弃强制模型学会在模态缺失时也能出结果。关于损失函数的组合下游任务用交叉熵同时保留一个弱的对比损失作为正则权重0.1到0.3。实测这个正则能明显缓解小数据上的过拟合因为它持续约束着特征空间的跨模态结构。4.4 显存与算力的估算方法很多人卡在第一步跑不动。我给出一个粗糙但够用的估算方法。视觉分支用轻量骨干加16帧输入单样本激活大约占几十MB听觉分支的log-mel加卷积编码器占得很少触觉分支最轻。融合层的交叉注意力序列长度在几百的级别注意力矩阵的开销可以忽略。真正吃显存的是视觉分支的中间激活。以224×224、16帧为例第一层卷积的输出就是16×64×112×112单个样本激活量已经很可观。所以batch size不能照搬图像分类的经验。我的经验值24GB显存的卡三模态联合训练batch size取16到24比较稳配合梯度累积到等效64。还有一个省显存的实用技巧视觉分支用混合精度加梯度检查点能省下大约40%的显存代价是训练慢20%左右。在小数据集上这个交换非常划算因为训练本身不慢瓶颈在显存。推理阶段的预算完全不同。如果部署到边缘设备视觉帧率可以降到5fps听觉特征缓存最近1秒触觉保持100Hz这样整体功耗能压到很低。触觉和听觉的数据量小是天然的“常开”传感器视觉可以按需唤醒——这个设计思路在低功耗场景里非常实用。5. 常见问题与排查实录5.1 模型只学一个模态其他两个像摆设这是最常见的问题表现出来就是融合模型的性能和单模态最好的那个差不多消融掉其他模态指标几乎不变。原因通常有两个。一是模态竞争视觉特征维度和信息量都远大于其他两个梯度下降自然会走最省力的路。二是归一化不当各模态特征经过投影后量级差太多注意力会被大量级的分支主导。排查方法很直接训练完打印门控权重的分布。如果某个模态的权重长期低于0.1基本可以确认是被压制了。解决办法我试过有效的有两个一是给每个模态的损失单独加权让弱模态的梯度不被淹没可以用不确定性加权自动学习权重二是做梯度归一化每个模态分支的梯度范数在反传时统一缩放到同一量级这个改动小但效果显著。还有一个偏方简单粗暴但管用在训练早期随机关掉视觉分支的一部分token逼模型去看别的模态。实测能明显改善模态均衡性。5.2 触觉数据太少模型学不动触觉数据的稀缺是结构性的没法靠多采集几个星期解决。我的应对策略有三条。第一用其他模态做代理任务。视觉和听觉数据相对好采可以先在这两个模态上完成对齐预训练再把触觉编码器接到已经对齐好的空间里做少量微调。这样触觉只需要学“如何映射”不需要从零学“什么是语义”。第二数据增强要贴合物理规律。触觉信号的增强不能随便加噪声那会破坏力曲线的物理合理性。合理的增强包括时间轴上的轻微拉伸模拟不同接触速度、幅值的整体缩放模拟传感器灵敏度差异、接触区域的平移模拟接触点偏移。这些增强在物理上是说得通的不会制造出不可能的信号。第三合成数据辅助。用简化的接触力学模型生成虚拟的力曲线虽然保真度有限但能提供大量“形状正确”的样本帮助模型学到力随时间变化的基本模式。合成数据只用作预训练微调阶段必须用真实数据。5.3 推理时某个模态突然没有数据这是工程落地必须面对的问题。摄像头被遮挡、麦克风被拔掉、触觉传感器接触不良这些在实验室里不出现在现场天天出现。我的处理是三层防线。第一层是数据有效性检测每个模态进来先做一个简单的健康检查比如视觉检查亮度均值和梯度能量听觉检查信噪比触觉检查基线是否在合理范围。不健康就直接标记为无效。第二层是门控重归一化无效模态的权重置零后重新归一化这个前面代码里已经体现。第三层是降级策略如果有效模态少于两个直接切到对应的单模态模型不要硬走融合路径。这里有个容易忽略的点训练时开的模态dropout概率要覆盖推理时的真实缺失率。如果现场经常缺触觉训练时触觉的dropout概率就该调高到0.3甚至0.4让模型充分见过这种情形。5.4 问题速查表现象最可能的原因优先排查动作融合后不如单模态模态竞争、特征量级失衡打印门控权重分布检查各分支梯度范数训练loss震荡不收敛对齐错位、学习率过大抽样可视化三模态时间轴是否重合验证集好、现场差传感器漂移、环境分布差异检查触觉基线校正和视觉归一化参数某个模态梯度为0掩码逻辑错误、该模态全无效统计每个batch的有效模态比例小样本严重过拟合融合层参数过多冻结编码器只训融合层加对比正则推理延迟超标视觉帧率过高降帧率、缓存听觉特征、触觉常开按需视觉5.5 我踩过的最贵的一个坑最后说个具体教训。早期做抓取项目时我把三个模态的采集程序写在了三个独立进程里各自记录自己的时间戳然后靠系统时间对齐。实验室里跑得好好的到了现场设备一多系统时间同步精度掉到几十毫秒模型直接失效——它学到的跨模态关联全部错位了。后来改成单一采集进程统一打时间戳用一块采集板同时触发相机和触觉音频走同一个时钟源问题才彻底解决。这件事让我明白一个道理多模态项目里数据采集的工程质量决定了模型性能的上限模型结构再精巧也补不回对齐的损失。所以我现在做任何多模态项目第一阶段永远是花两三天把采集链路和时间同步做扎实宁可在数据层多花时间也不在模型层反复救火。另外一个体会是关于评估指标的不要只看融合后的总体准确率一定要做逐模态缺失的消融矩阵。把七种模态组合三单模态、三双模态、全模态的性能全测一遍你才能知道融合到底在哪些组合下真正带来了增益。我见过太多项目报告里只写“融合模型达到多少点”一测消融发现增益全来自视觉其他模态纯属装饰。这种模型在现场一遇到视觉失效就彻底没辙。触觉这一环还有个后续可以深挖的方向把触觉信号当成一种“主动感知”的手段让模型自己决定什么时候该去摸一下。现在大多数多模态模型都是被动接收三路数据但人不是这么工作的——人看一眼不确定会伸手去摸摸完再判断。把这个主动采样的策略学出来样本效率还能再上一个台阶。这条路我也在摸索有进展再拿出来聊。