改变样本权重
减小最有偏置的样本的重要程度:比如那些不需要看图片就能够回答正确的样本
这样会让模型不再依赖于两个模态,而是使用统计概率解决问题
我们使用了一个只有问题的模型,能够通过识别不想要的规律被使用,来捕获语言偏置
代码 github.com/cdancette/rubi.bootstrap.pytorch
1.介绍
将what color banana 链接到yellow。利用了只有问题的模型是偏向问题模态的事实。在训练时,增加一个只有问题的分支,动态的调整损失来补充偏置。所以,反向传播会减少最偏置的样本,增加少偏置的样本。有点像重加权
2.相关工作
在数据集和模型中评估单峰偏差
Agrawal2018 提出了新的数据集VQA-CP GVQA明确地将图像中呈现的视觉概念的识别与给定问题的似是而非的答案空间的识别区分开来,使模型能够更稳健地在不同的答案分布之间进行概括。 区分出要识别什么和潜在的答案空间。将任务分为两步,第一步找到和识别出需要回答问题的视觉区域 第二步根据只有问题的分支识别出潜在答案的空间。平衡数据集避免单峰偏差
justin2017 和 drew2019 合成了数据集 最小化问题条件偏差,通过拒绝抽样相关问题。增加补充样本 每一个VQA v1的问题,VQA v2都包含一个相同的图片但是不同的回答。网络结构和训练方法减小单峰偏差
Ramakrishnan2018 使用一个只有问题的模型来训练,得到损失,然后用这个损失的梯度否定来阻止问题编码器捕获不想要的一些偏差 这些偏差能够被VQA模型利用
3.减少单峰偏差的方法
nnq 神经网络
经典学习策略和陷阱
3.1
让VQA模型专注于那些只是用问题模态就不能回答的样本
通过预测掩膜阻止偏置。通过sigmoid函数将nnq神经网络的输出变为0-1 称为掩膜,使用这个掩膜修改VQA模型的预测 动态变换了损失。使用点乘
只有问题的分支输出一个掩膜,这个掩膜会让正确答案的分数增大,让别的答案的分数减小,所以,对于这些偏置的样本,损失会更低。因此,这些样本的反向传播会更小,所以就减小了这些样本的重要程度
联合学习过程:
L_QM与方程4有关 用来更新θ_QM 包含了编码器和nnq L_QO与方程3有关 用来更新θ_QO cq和nnq中的参数,这里并不反向传播给问题编码器
3.2 基线模型结构
使用FasterR-CNN 处理图片得到一包图片的特征,使用GRU编码问题,将问题表示q和图像每个区域的特征vi融合,结果向量输入MLP分类器 输出最后的预测结果
代码:
具体的运行方法可以看这篇文章作者的github。rubi把另一个vqa模型作为输入,在上面添加一个问题分支 。 问题分支的预测与原始的预测合并,然后rubi会输出一个新的预测来训练模型
基线模型需要在softmax之前通过字典返回原始的预测 。 key是logits
训练模型:
boostrap/run.py 加载了选项 创建对应的实验并开始训练
训练指令 python -m bootstrap.run -o rubi/options/vqacp2/rubi.yaml
在logs/vqa2/rubi里面生成的
评估模型:
对于vqa-cp v2 没有测试集 直接使用评价集。对于vqa v2可以在测试集上评估 。 此时,模型恢复最好的参数 然后在测试集上评估 并且logs会使用不同的名字
python -m bootstrap.run \
-o logs/vqa2/rubi/baseline.yaml \
--exp.resume best_accuracy_top1 \
--dataset.train_split \
--dataset.eval_split test \
--misc.logs_name test
复现结果:
在vqa-cp v2上
基线模型
python -m bootstrap.run \
-o rubi/options/vqacp2/baseline.yaml \
--exp.dir logs/vqacp2/baseline
rubi
python -m bootstrap.run \
-o rubi/options/vqacp2/rubi.yaml \
--exp.dir logs/vqacp2/rubi
比较结果
python -m rubi.compare_vqacp2_rubi -d logs/vqacp2/rubi logs/vqacp2/baseline
使用tensorboard来查看结果
python -m bootstrap.run -o rubi/options/vqacp2/rubi.yaml \
--view.name tensorboard
tensorboard --logdir=logs/vqa2
指定gpu
For a specific experiment:
CUDA_VISIBLE_DEVICES=0 python -m boostrap.run -o rubi/options/vqacp2/rubi.yaml
For the current terminal session:
export CUDA_VISIBLE_DEVICES=0
重写参数
python -m bootstrap.run -o rubi/options/vqacp2/rubi.yaml \
--optimizer.lr 0.0003 \
--exp.dir logs/vqacp2/rubi_lr,0.0003
运行过程
首先run函数 找到yarml文件把里面的参数放进option 根据option的各种键值 先设置engine(后面会用engine来train val等)然后调用model model再找到network(找网络的过程是先找factory确定是哪个网络,然后就可以调用自己写的主网络了),建立优化器
每次调用都是调用factor函数,由他来确定具体是用什么模型 什么网络等
训练的epoch和loss等的规定 都在默认model里