多模态动态融合模型Predictive Dynamic Fusion阅读与代码分析运行1-信度概念与基础参数指标

多模态动态融合模型Predictive Dynamic Fusion阅读与代码分析运行1-信度概念与基础参数指标

参考文:Cao B, Xia Y, Ding Y, et al. Predictive Dynamic Fusion[J]. arXiv preprint arXiv:2406.04802, 2024.[2406.04802] Predictive Dynamic Fusion

一、理论

今天就先看看论文中的各个指标含义和多模态训练代码的参数吧

文章中一个比较重要的概念就是置信度的概念了,在论文前段,对置信度的扩展比较多同时没有什么具体说明,不知道概念的话读着还是很混乱的;

置信度

在机器学习中,置信度表示模型对其预测结果“有多确定”。
它刻画的是:模型认为自己预测是正确的程度

例如,在分类任务中:“这是正类的概率是 0.92”,那么 0.92 就可以视为模型对该预测的置信度

在监督学习中,给定输入样本 xxx,模型预测类别为 y^\hat{y}y^​,则置信度通常定义为:

即:模型对预测类别的后验概率估计

置信度 和 不确定性(补充)

文中用来衡量整体不确定性,算是置信度的一种扩展:

关于熵的概念,之前在b站看到的一位up主讲的很生动:https://www.bilibili.com/video/BV15V411W7VB/

置信度高 <=> 熵低

分类评价指标对比

指标含义对照

指标一句话解释
Accuracy模型整体准不准
Precision模型说“是”的时候靠谱吗
Recall真正“是”的有没有被找全
F1Precision 和 Recall 的折中
ROC-AUC正样本排在负样本前面的能力

The Mono-Confidences and Holo-Confidences

该文的目的之一是为了解决模态权重融合的权重问题;也就是,多个模态分别从多个维度评价目标的状态,给出不一样的结果,怎么融合这几个结果的问题。

目前可以确定的是:融合权重 ω 应当与损失 l 呈负相关,并且与其他模态的损失呈正相关。也就是:当前模态越可靠 → 权重越大;其他模态越不可靠 → 当前模态权重越大

对单个模态的模型,权重 ω 是要求的权重,损失loss是:

所以,就有人两个信度指标:

The Mono-ConfidencesHolo-Confidences
当前模态本身有多可靠相对其他模态我有多可靠

将他们统合:

Co-Belief(协同信度)

Mono-Confidence:只看自己;Holo-Confidence:只看别人;但多模态融合需要:既考虑自身可靠性,又考虑整体模态状态。

故有:

再由协同信度确定该模态的权重。

理论先到这里,其他的后面再看;

二、代码

1、运行环境

代码训练环境没有明确说明,但根据结构可以看得出来用的是autodl里的云服务器,Ubuntu20.04+python3.11的版本,卡随便租一个都一样。

论文附带代码只有2mb,明显缺失了很多预训练结构与数据集文件;

2、数据集文件

这里选用了代码中可选的第二个训练集MVSA_Single,需要自己到网站下好转到autodl服务器上:MVSA_Single

训练集之类的划分源代码已有了,自己按要求放到同一目录下即可。

3、词向量文件

源代码缺失了预训练好的词向量文件glove.840B.300d,需要自己使用指令下载到指定目录

wget https://nlp.stanford.edu/data/glove.840B.300d.zip

4、源代码逻辑错误

训练代码中的forward函数存在运行逻辑错误,文本和图像的loss(txt_clf_loss和img_clf_loss)定义在了if之外,会运行不成功;估计是作者没有仔细整理,代码算法逻辑倒没什么问题;

原代码150行左右:

def model_forward(i_epoch, model, args, criterion,optimizer, batch,mode='eval'): txt, segment, mask, img, tgt,idx = batch freeze_img = i_epoch < args.freeze_img freeze_txt = i_epoch < args.freeze_txt if args.model == "bow": txt = txt.cuda() out = model(txt) elif args.model == "img": img = img.cuda() out = model(img) elif args.model == "concatbow": txt, img = txt.cuda(), img.cuda() out = model(txt, img) elif args.model == "bert": txt, mask, segment = txt.cuda(), mask.cuda(), segment.cuda() out = model(txt, mask, segment) elif args.model == "concatbert": txt, img = txt.cuda(), img.cuda() mask, segment = mask.cuda(), segment.cuda() out = model(txt, mask, segment, img) elif args.model == "latefusion_pdf": txt, img = txt.cuda(), img.cuda() mask, segment = mask.cuda(), segment.cuda() tgt = tgt.cuda() maeloss = nn.L1Loss(reduction='mean') out, txt_logits, img_logits, txt_tcp_pred, img_tcp_pred = model(txt, mask,segment,img,'pdf_train') label = F.one_hot(tgt, num_classes=args.n_classes) # [b,c] if args.task_type == "multilabel": txt_pred = torch.sigmoid(txt_logits) img_pred = torch.sigmoid(img_logits) else: txt_pred = torch.nn.functional.softmax(txt_logits, dim=1) img_pred = torch.nn.functional.softmax(img_logits, dim=1) txt_tcp, _ = torch.max(txt_pred * label, dim=1,keepdim=True) img_tcp, _ = torch.max(img_pred * label, dim=1,keepdim=True) tcp_pred_loss = maeloss(txt_tcp_pred, txt_tcp.detach()) + maeloss(img_tcp_pred, img_tcp.detach()) else: assert args.model == "mmbt" for param in model.enc.img_encoder.parameters(): param.requires_grad = not freeze_img for param in model.enc.encoder.parameters(): param.requires_grad = not freeze_txt txt, img = txt.cuda(), img.cuda() mask, segment = mask.cuda(), segment.cuda() out = model(txt, mask, segment, img) tgt = tgt.cuda() txt_clf_loss = nn.CrossEntropyLoss()(txt_logits, tgt) img_clf_loss = nn.CrossEntropyLoss()(img_logits, tgt) clf_loss=txt_clf_loss+img_clf_loss+nn.CrossEntropyLoss()(out,tgt) if mode=='train': loss = torch.mean(clf_loss)+torch.mean(tcp_pred_loss) return loss,out,tgt else: loss= torch.mean(clf_loss)+torch.mean(tcp_pred_loss) return loss,out,tgt

修改后:

def model_forward(i_epoch, model, args, criterion, optimizer, batch, mode='eval'): txt, segment, mask, img, tgt, idx = batch tgt = tgt.cuda() clf_loss = 0.0 tcp_pred_loss = 0.0 # ⭐ 先初始化,避免炸 # ---------- 普通单 / 早期融合模型 ---------- if args.model == "bow": txt = txt.cuda() out = model(txt) clf_loss = criterion(out, tgt) elif args.model == "img": img = img.cuda() out = model(img) clf_loss = criterion(out, tgt) elif args.model == "concatbow": txt, img = txt.cuda(), img.cuda() out = model(txt, img) clf_loss = criterion(out, tgt) elif args.model == "bert": txt, mask, segment = txt.cuda(), mask.cuda(), segment.cuda() out = model(txt, mask, segment) clf_loss = criterion(out, tgt) elif args.model == "concatbert": txt, img = txt.cuda(), img.cuda() mask, segment = mask.cuda(), segment.cuda() out = model(txt, mask, segment, img) clf_loss = criterion(out, tgt) # ---------- late fusion(特例) ---------- elif args.model == "latefusion_pdf": txt, img = txt.cuda(), img.cuda() mask, segment = mask.cuda(), segment.cuda() out, txt_logits, img_logits, txt_tcp_pred, img_tcp_pred = \ model(txt, mask, segment, img, 'pdf_train') # 分类 loss txt_loss = criterion(txt_logits, tgt) img_loss = criterion(img_logits, tgt) clf_loss = txt_loss + img_loss # TCP loss maeloss = nn.L1Loss(reduction='mean') label = F.one_hot(tgt, num_classes=args.n_classes) if args.task_type == "multilabel": txt_pred = torch.sigmoid(txt_logits) img_pred = torch.sigmoid(img_logits) else: txt_pred = F.softmax(txt_logits, dim=1) img_pred = F.softmax(img_logits, dim=1) txt_tcp, _ = torch.max(txt_pred * label, dim=1, keepdim=True) img_tcp, _ = torch.max(img_pred * label, dim=1, keepdim=True) tcp_pred_loss = ( maeloss(txt_tcp_pred, txt_tcp.detach()) + maeloss(img_tcp_pred, img_tcp.detach()) ) # ---------- mmbt ---------- else: assert args.model == "mmbt" txt, img = txt.cuda(), img.cuda() mask, segment = mask.cuda(), segment.cuda() out = model(txt, mask, segment, img) clf_loss = criterion(out, tgt) # ---------- 总 loss ---------- loss = clf_loss + tcp_pred_loss return loss, out, tgt

四、各训练参数

主要是get_args里面的参数解释:

训练与优化相关参数

参数名默认值含义说明影响阶段备注 / 建议
batch_sz128每个 batch 的样本数量训练大 batch 更稳定,但占显存
gradient_accumulation_steps24梯度累积步数训练等效 batch = batch_sz × steps
lr1e-4初始学习率训练BERT 微调常用 1e-5~5e-5
weight_decay0.0权重衰减系数(L2 正则)训练防止过拟合
dropout0.1Dropout 概率模型Transformer 常用 0.1
max_epochs100最大训练轮数训练搭配 early stopping
patience10Early stopping 容忍轮数训练验证集无提升时停止
warmup0.1学习率 warmup 比例训练防止初期梯度震荡
lr_factor0.5学习率衰减倍率训练ReduceLROnPlateau
lr_patience2学习率衰减等待轮数训练验证集不提升则降 lr
seed123随机种子全局保证实验可复现
n_workers12DataLoader 线程数数据加载与 CPU 核数相关

文本模态:

参数名默认值含义说明影响阶段备注
bert_model./bert-base-uncasedBERT 预训练模型路径模型可换成 large
freeze_txt0是否冻结文本编码器训练1 表示不更新 BERT
max_seq_len512文本最大 token 长度数据BERT 上限
embed_sz300词向量维度模型对应 GloVe
glove_pathglove.840B.300d.txtGloVe 文件路径数据300 维
hidden_sz768文本隐藏层维度模型BERT-base 默认

图像模态(Image)相关参数

参数名默认值含义说明影响阶段备注
img_hidden_sz2048图像特征维度模型ResNet 输出
num_image_embeds1图像 token 数模型MMBT 中常见
img_embed_pool_typeavg图像特征池化方式模型avg / max
freeze_img0是否冻结图像编码器训练1 表示冻结
drop_img_percent0.0随机丢弃图像比例数据增强模态缺失模拟

融合参数:

参数名默认值含义说明影响阶段备注
modellatefusion_pdf使用的模型结构模型PDF = Predictive Dynamic Fusion
hidden[]额外隐藏层结构模型如 [512,256]
include_bnTrue是否使用 BatchNorm模型提高训练稳定性
dfTrue是否启用动态融合模型PDF 核心开关
baselineNone对比方法名称实验仅用于记录

任务与数据相关参数:

参数名默认值含义说明影响阶段备注
taskMVSA_Single使用的数据集数据多模态情绪识别
task_typeclassification任务类型训练单标签 / 多标签
weight_classes1是否类别加权loss类别不平衡时用
noise0.0标签噪声比例数据鲁棒性实验
data_path/path/to/data_dir/数据集路径数据必须配置
savedir/path/to/save_dir/模型保存路径输出checkpoint

其中,很多任务数据相关参数都需要调整

Read more

Clawdbot(Moltbot) 飞书机器人配置,体验老板和助手沟通的感觉

Clawdbot(Moltbot) 飞书机器人配置,体验老板和助手沟通的感觉

一、背景说明 Clawdbot可以24小时待命(参考配置方式:Clawdbot(Moltbot) windows安装配置教程(含各种问题处理)),但是网页端使用起来比毕竟没那么方便,然而clawdbot支持多种渠道交互,这也正是这个AI助理的魅力所在,想想飞书发送一个消息,一个任务就完成了,这不就是老板指挥我做事的方式吗,来赶紧体验一波老板的感觉~ 二、飞书机器人创建 飞书开放平台构建机器人:https://open.feishu.cn/ 记录App ID 和 App Secret,一会要用: 三、自动安装插件 项目地址:https://github.com/m1heng/Clawdbot-feishu 这时候,就可以发挥clawdbot的能力了,直接让clawdbot给我安装: 我要安装飞书机器人,帮我按照这个命令安装:Clawdbot plugins install @m1heng-clawd/feishu 到这个过程有点慢,安装了好一会没反应,我开始问了: 又过了好一会没反应,

【无人机避障算法核心技术】:揭秘五种主流算法原理与实战应用场景

第一章:无人机避障算法概述 无人机避障算法是实现自主飞行的核心技术之一,其目标是在复杂环境中实时感知障碍物,并规划安全路径以避免碰撞。随着传感器技术和计算能力的提升,避障系统已从简单的距离检测发展为融合多源信息的智能决策体系。 避障系统的基本组成 典型的无人机避障系统包含以下关键模块: * 感知模块:利用激光雷达、超声波、立体视觉或RGB-D相机获取环境数据 * 数据处理模块:对原始传感器数据进行滤波、特征提取和障碍物识别 * 决策与规划模块:基于环境模型生成避障轨迹,常用算法包括A*、Dijkstra、RRT和动态窗口法(DWA) 常见避障算法对比 算法优点缺点适用场景A*路径最优,搜索效率高高维空间计算开销大静态环境全局规划DWA实时性强,适合动态避障局部最优风险室内低速飞行RRT*渐进最优,适应复杂空间收敛速度慢三维未知环境 基于深度学习的避障方法示例 近年来,端到端神经网络被用于直接从图像生成控制指令。以下是一个简化的行为克隆模型推理代码片段: import torch import torchvision.transforms as tran

把 Vivado 项目放心交给 Git:一篇 FPGA 工程师必读的实战指南

之前分享过一篇文章《FPGA 版本管理三种方式:你会选哪一种?》,评论区很多人都推荐使用Git进行版本管理,今天这篇文章主题就是使用Git进行备份指南。 在 FPGA 开发中,掌握 Git 等源码管理工具已经是必备技能。 当然,在使用 Vivado 时,我们不仅需要处理源代码控制,还需要处理以 IP 为中心的设计产品。 Vivado 的工程通常是 IP 为中心 的设计,包含: * IP Integrator Block Diagram * 各类 IP 实例(独立 IP 或 BD 内 IP) * 自动生成的包装文件与工程产物 这让很多 FPGA 工程师一开始会觉得: “Vivado 项目到底该怎么和 Git 一起用?” 好消息是,从 Vivado

政安晨【零基础玩转开源AI项目】OpenClaw飞书通信端机器人配置指南(手把手配置OpenClaw飞书/Lark机器人,实现多渠道AI助手集成)(作者自己配置时留存使用,小伙伴们可酌情参考)

政安晨【零基础玩转开源AI项目】OpenClaw飞书通信端机器人配置指南(手把手配置OpenClaw飞书/Lark机器人,实现多渠道AI助手集成)(作者自己配置时留存使用,小伙伴们可酌情参考)

政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正! 目录 一、前言 1.1 为什么需要配置飞书机器人? 1.2 飞书机器人支持的功能 二、准备工作 2.1 环境要求 2.2 OpenClaw安装(本篇主要介绍飞书端的配置,这里可参考我上一篇博客) 2.3 飞书账号要求 三、飞书应用创建 3.1 创建企业应用 3.2 获取应用凭证 编辑3.3 开通权限 3.4 配置事件订阅 Webhook URL配置 订阅事件 3.5