想象一档叫“猜图达人”的综艺节目:屏幕上放出一张“戴帽子的猫”的照片,选手看了一眼,主持人问:“这只猫在做什么?”台下坐着十位评审观众,他们早在赛前就各自写下了自己的答案——有人写“睡觉”,有人写“趴着”,有人写“打盹”,还有人写“闭目养神”。现在,选手说出自己的答案,只要他的答案与台上十位评审中至少三位的答案一致,就能得分。 这个节目规则,其实暗藏了人工智能领域一个经典评测任务——视觉问答(Visual Question Answering,VQA) 的评分机制。VQA让AI“看图说话”并回答自然语言问题,但“怎么算答对”却是大难题:同一张图,不同人的描述永远有分歧。如果只设一个标准答案,AI回答“趴着”而标准答案写“睡觉”,明明语义相同却被判错,这对AI公平吗?答案是否定的。我们需要一套能容纳“标注多样性”的评测指标。 今天,我们就从这档“猜图达人”节目出发,把VQA准确率的计算方式彻底讲清楚,看看“软准确率”这个神奇公式是怎么设计出来的。
对AI从业者而言,VQA准确率是发论文、跑榜单、向业务方证明模型能力的核心指标。看懂软准确率的公式与设计动机,能帮你在多模态评测中避坑,用科学口径评估模型。
可视化演示
展示视觉问答的简单准确率、软准确率评分公式及多答案处理机制,直观理解VQA评测如何公平评估模型回答质量。
本节配有交互动效(进入视口后自动加载,约 3KB)。
简单准确率:精确匹配评分 模型回答与参考答案完全一致得1分 任何不一致均得0分过于严格 acc = Σ(match)/N 二元评分低估多答案场景模型能力
看图问答任务
在“猜图达人”节目的开场,主持人总会强调一句:“各位选手注意,这不是选择题,没有ABCD选项,答案要你自己想、自己说。”这正是VQA任务和传统图像分类最大的不同——它不给候选答案列表,AI必须自己读懂图片内容、理解问题意图,再组织一句自然语言回答。
这个任务的全称是 Visual Question Answering,输入是“一张图片 + 一个自然语言问题”,输出是一段自然语言答案。比如输入一张“戴帽子的猫坐在沙发上”的图片,问题是“这只猫在做什么?”,模型需要回答“睡觉”或“趴着”等合理答案。和ImageNet图像分类从1000个固定类别里挑一个标签不同,VQA的答案空间是完全开放的,理论上你可以回答出无限多种表述。
正因为答案开放,评测立刻遇到了挑战:两个模型,一个说“睡觉”,一个说“打盹”,谁能得分、谁不能得分?如果没有一套科学的度量方法,那这档“节目”就失去了公信力。于是,“如何判定回答是否正确”成了VQA领域最基础也最关键的问题。
人工标注多样性
赛前,导演组请来十位普通观众,让他们分别看一眼图片、写下自己的答案,然后把纸条封存。十个人面面相觑,谁也不知道别人写了什么。最终主持人拆开纸条时发现:十张纸条上写着六种不同的说法,有的写“睡觉”,有的写“趴着”,还有的写“休息”。
这就是VQA数据集的标注方式:每个问题由十位标注者独立回答,每位标注者只看到图片和问题,不参考其他人的答案。VQA v2等主流数据集正是通过Amazon Mechanical Turk这样的众包平台,为每张图片的每个问题收集约10条人工答案。
这种标注方式带来的直接结果就是答案分歧:当问题的主观性较强时,标注者之间的答案几乎不可能完全一致。与其说某个答案是“错的”,不如说图像理解本来就是多义的——“睡觉”“趴着”“打盹”都在描述同一个场景,只是角度和措辞不同。这就意味着,任何试图用“唯一正确答案”来评判VQA模型的方案,本质上都违背了任务的开放性。
简单准确率
如果导演组偷懒,只做一张标准答案卡,上面写着“睡觉”,那么选手只要说出“趴着”就会被判错。这种方法在自然语言处理里有个熟悉的名字——精确匹配(Exact Match),也叫简单准确率:模型输出和标准答案字符串一字不差才算对。
简单准确率的数学形式很直观:
其中 \(\hat{a}_i\) 是模型对第 \(i\) 题的预测答案,\(a_i^{*}\) 是该题的标准答案。
这个指标有两个致命缺陷。第一,它对同义表述零容忍,“趴着”和“睡觉”明明表达同一个意思,却被判错;第二,面对10位标注者给出的10个答案,你该选哪一个当标准答案?选“睡觉”的人多,但“趴着”也同样合理。简单准确率把答案开放性问题硬生生做成了“闭卷考试”,对AI显然不公平。
- 判断符号 \(\mathbb{1}\{\cdot\}\)这是一个“指示函数”,大括号里的条件成立时取值为1,否则为0。模型答“睡觉”、标准答案也是“睡觉”,这一项就是1;模型答“趴着”、标准答案是“睡觉”,这一项就是0。
- 累加求和 \(\sum_{i=1}^{N}\)把N道测试题各自的0/1得分相加,得到答对的总题数。
- 取平均 \(\frac{1}{N}\)除以题目总数,把“答对题数”转换成“答对比例”,也就是准确率。
软准确率
导演组最终想出了一个更好的赛制:不设标准答案卡,而是把十位评审的答案全部公开。选手答完题后,主持人当众数一数——有几位评审的纸条上写着和选手一模一样的答案。只要这个数字达到3,选手就得分;数字越大,得分越漂亮。
这就是VQA官方采用的软准确率(VQA Accuracy) 的核心思想。它不追求“唯一正确答案”,而是看模型的预测答案能否获得足够多标注者的“共识票数”。
具体的计算公式如下:
其中 \(c_i\) 表示在第 \(i\) 个测试问题上,十位标注者中与模型预测答案完全相同的人数:
为什么阈值是“3“而不是”1“或”5“?如果是1人认可就算对,那么哪怕标注者随手乱写,模型都能得分,评测失去意义;如果是5人认可才算对,又会让”趴着“这类合理但人数较少的答案全部落榜,评测过于苛刻。3人约占10位标注者的三分之一,足以过滤掉个别标注者的随意性,同时保留开放答案的合理性。这个精心设计的”3“在数学上还有一个好处:当 \(c_i=2\) 时,模型得 \(2/3\) 分,相当于”部分正确“,这就是”软”准确率名字的由来——它不是非黑即白的0或1,而是允许介于两者之间。
- 统计共识人数 \(c_i\)从10位标注者的答案中,逐个数出有多少人的答案和模型预测的 \(\hat{a}_i\) 完全一致。
- 除以基准 \(c_i / 3\)以“3人认可”为参考线做归一化。如果恰好3人认可,该项得分为1;只有1人认可,得分为1/3;有6人认可,该项暂时算作2。
- 取最小值 \(\min(\cdot, 1)\)把得分封顶在1。也就是说,超过3人认可的部分不再加分——只要达到3人这个门槛,本题就算满分。
- 求平均 \(\frac{1}{N}\sum_{i=1}^{N}\)把每个问题的得分相加后除以总题数,得到整个测试集上的软准确率。
评测流程设计
一档成熟的节目必然有标准化的录制流程:邀请观众、密封答案、选手答题、当场统计。VQA的评测也一样,只有流程标准化,分数在业界才有公信力。
整个评测流水线通常分四步。第一步是数据采集:在众包平台上收集图片和问题,并规定每张图片的每个问题都由10位独立标注者作答。第二步是答案聚合:把10条答案和图片、问题绑定在一起,构成测试集的标准答案包。第三步是数据划分:将数据分为训练集、验证集和测试集,其中测试集的标注答案严格保密,防止模型过拟合。第四步是评测实现:加载模型的预测文件,按软准确率公式逐题打分。
在官方评测脚本中,还有一个人性化的细节:分题型统计。VQA问题被分成三类——“是/否类”“数字类”“开放描述类”。是/否问题答案高度一致,数字问题必须精确匹配,开放描述类才完全依靠软准确率。最终报告分数时,除了总体准确率,还会分别给出这三类的准确率,帮助研究者定位模型的短板。
评估任意一个VQA模型的准确率,都需要一个可靠的参考实现。官方VQA评测脚本在GitHub上可以公开获取,任何团队的预测结果上传后都会用相同的代码统一打分——这就保证了不同论文、不同榜单之间的分数可以横向比较。
指标权衡
节目播出几期后,细心的观众发现一个问题:有位选手特别喜欢回答“是”和“睡觉”这类高频答案,虽然偶尔能蒙对几题,但真正需要细致观察的问题他几乎全军覆没。可他的总分居然不低,因为“猜图达人”的评分规则没有惩罚这种“万金油”打法。
软准确率也有类似的局限。它只关心“模型答案是否与标注者共识匹配”,不关心这个答案是否真的建立在图片内容上。如果一个模型总是输出训练集中最常见的答案,那么它在软准确率上的表现可能会虚高。因此,在实际评测中,软准确率从来都不是唯一的指标。
合理做法是多维指标组合:第一,按题型拆分准确率,单独看“是/否”“数字”“开放描述”三类成绩,能暴露模型在计数、颜色、空间关系等具体能力上的短板;第二,配合人工错误分析,把预测错误的样本聚类,观察模型系统性忽略的视觉元素;第三,关注答案的分布鲁棒性,如果模型的答案词汇局限在几十个高频词上,说明它并没有真正理解图片,只是在背答案。
此外,软准确率的标注成本是现实中必须面对的问题——每个测试问题至少需要10条人工标注,如果测试集包含数十万个问题,标注费用会非常可观。部分研究也会在验证阶段用5人标注或直接使用官方预标注数据,以平衡成本与可靠性。总之,软准确率是一个好指标,但它需要配合流程和业务场景来使用,才能真正反映模型的实力。
AI 应用场景
多模态大模型评测
阶段:模型评估与验证
解决的问题:团队训练了一个视觉问答模型,如果只用精确匹配或BLEU来打分,模型给出“趴着”而标注是“睡觉”时会被判错,导致模型真实能力被严重低估。改用软准确率后,评测口径与学术界对齐,分数能直接上排行榜比较。
具体案例:某算法团队在VQA v2验证集上评测开源多模态模型,使用精确匹配时得分只有58.2%,换成软准确率后提升到76.5%——大量“换个说法但语义正确”的答案被释放出来。团队据此把软准确率纳入自动评测流水线,每次训练迭代后同步打印分题型准确率,快速定位模型在“计数类”问题上的退化。
数据标注质量抽检
阶段:数据收集与标注
解决的问题:众包标注员在回答开放式问题时可能随意填写,传统质检只抽检“是否填写了内容”,无法识别答案是否靠谱。用“标注者间一致性”作为抽检指标,能有效发现低质量标注批次。
具体案例:一家数据标注服务商在交付VQA标注任务前,对同一问题由10位标注者作答的结果计算两两一致率。某个批次的标注一致性仅有40%,明显低于75%的合格线,排查发现是新培训的标注员没有理解“尽量具体描述”的规范。重标后标注一致性回升到80%,客户验收一次性通过。
图像理解内容风控
阶段:部署与监控
解决的问题:内容平台需要审核“图片中是否存在违规元素”,这类问题本质上是开放式的,用固定关键词匹配常常误报漏报。用软准确率做线上抽样复核,能更公平地判定模型答案是否与人工审核员的判断一致。
具体案例:某短视频平台的风控系统对图片生成类似VQA的审核问题:“图中是否包含吸烟动作?”线上抽样100条请求,每条由5名资深审核员给出判定,模型答案与至少3人一致记为“通过”,否则触发人工二次审核。上线后,模型误判率下降了约12%,同时减少了纯人工复审的审核成本。
Python 演示
"""VQA软准确率计算演示:对比简单准确率与软准确率"""SAMPLES = [ {"question": "猫在做什么?", "annotations": ["睡觉", "趴着", "睡觉", "打盹", "睡觉", "休息", "躺着", "睡觉", "闭眼", "静卧"], "prediction": "睡觉"}, {"question": "图中水果是什么?", "annotations": ["苹果", "苹果", "苹果", "苹果", "苹果", "苹果", "苹果", "苹果", "苹果", "苹果"], "prediction": "苹果"}, {"question": "天空是什么颜色?", "annotations": ["蓝色", "蓝色", "蓝", "蓝色", "淡蓝", "蓝色", "蓝色", "蓝色", "蓝色", "蓝"], "prediction": "蓝"}, {"question": "地上有几个皮球?", "annotations": ["3", "3", "3", "3", "3", "3", "3", "3", "3", "3"], "prediction": "3"}, {"question": "狗正在干什么?", "annotations": ["跑", "奔跑", "追球", "跑步", "运动", "跑", "跑步", "奔跑", "撒欢", "玩球"], "prediction": "奔跑"},] def normalize(text): """简单归一化: 去首尾空格和句号, 转小写""" return text.strip().strip("。!?!?.").lower() def soft_accuracy(prediction, annotations, threshold=3): """计算单样本软准确率: min(相同人数/阈值, 1)""" same = sum(1 for a in annotations if normalize(a) == normalize(prediction)) return min(same / threshold, 1.0) def exact_accuracy(prediction, annotations): """简单准确率: 只与第一位标注者答案精确匹配""" return 1.0 if normalize(prediction) == normalize(annotations[0]) else 0.0 def main(): exact_total = 0.0 soft_total = 0.0 for idx, sample in enumerate(SAMPLES, 1): ea = exact_accuracy(sample["prediction"], sample["annotations"]) sa = soft_accuracy(sample["prediction"], sample["annotations"]) exact_total += ea soft_total += sa print(f"样本{idx} [{sample['question']}]") print(f" 标注答案分布: {sample['annotations']}") print(f" 模型预测: {sample['prediction']}") print(f" 简单准确率: {ea:.1f} 软准确率: {sa:.1f}") print() n = len(SAMPLES) print(f"总体简单准确率: {exact_total / n:.2f}") print(f"总体软准确率: {soft_total / n:.2f}") if __name__ == "__main__": main()
def normalize(text): return text.strip().strip("。!?!?.").lower()比较前先做归一化,把小写、首尾空格和句号等干扰因素清理掉,避免“Blue“和”blue”被误判为不同答案。same = sum(1 for a in annotations if normalize(a) == normalize(prediction))遍历10位标注者的答案,数一数有多少人与模型预测完全一致,这就是 \(c_i\) 的Python实现。return min(same / threshold, 1.0)软准确率公式落地:\(c_i/3\) 后封顶1,不到3人也允许给部分分数。exact_accuracy(...)简单准确率的实现:只与第一位标注者(当作标准答案)进行比较,答对得1分,答错得0分。总体软准确率: {soft_total / n:.2f}把所有样本的软准确率得分取平均,得到测试集上的最终指标。
常见误区
误区“VQA模型输出一句话,我直接用BLEU或者精确匹配跟标注答案比一下不就行了?反正都是文字,分数高就是答得好。”
正解BLEU是机器翻译和摘要生成里用的指标,对短答案不敏感;精确匹配又对同义表述过于严苛。VQA的标准做法是用软准确率:不再“和一个标准答案比”,而是“和十个人的共识票比”。只有被至少3位标注者写出的答案,才计为正确。
为何常见:很多同学有NLP背景,BLEU和Exact Match用得顺手,下意识就把老一套搬到视觉问答上,忽略了开放答案的评测本质。
误区“既然一个问题有10个人标注,那我统计出现次数最多的答案当标准答案,再跟它做精确匹配,这样总公平了吧?”
正解VQA的答案往往没有绝对多数的胜出者。比如10人给出6种不同说法,最多的一说法只有3人,“多数”并没意义。软准确率的设计恰恰是保留完整分布信息,而不是强行压缩成一个代表性的标准答案。
为何常见:众包数据里“多数投票”是常见的降噪方法,于是直觉上认为VQA也可以这么处理,殊不知多元答案本身就是信息。
误区“我把软准确率阈值从3改成2,模型分数高了不少,汇报给老板好看多了。”
正解阈值"3"是VQA官方在10人标注设定下确定的基准口径。改变阈值等于改变游戏规则,分数就没法和别人家的模型横向比较了。如果在业务上确需宽松判定,应该同时报告官方阈值下的分数,并说明差异。
为何常见:从业者面临KPI压力,容易在指标口径上做手脚,但这会破坏评测的规范性和可信度。
误区“官方评测不就是一个总准确率吗?我照着公式算一遍就完了,不用管题型。”
正解VQA官方脚本实际会把问题拆成"Yes/No""Number"“Other“三类分别计算准确率。是/否问题天然答案集中,数字问题必须精确,”开放描述”才主要依赖软一致性。只报一个总分,容易掩盖模型在计数能力上的明显缺陷。
为何常见:只看了软准确率的总体公式,没有细读官方评测脚本的分类实现,导致评测结果无法定位模型的具体短板。
面试题
Q1. VQA任务中,10个标注者有5人写了“猫”,模型预测“猫”,该题的软准确率得分是?
- A.1.0,直接给满分← 正确答案
- B.0.5,按一半给分
- C.0.0,不足三人一致
- D.5.0,按五倍计分
答案:A。软准确率公式为 min(5/3, 1) = min(1.67, 1) = 1.0。只要被至少3人认可就达到满分线,超过部分不再累计加分,所以不是5.0也不是0.5。
Q2. 软准确率设计的主要动机是什么?
- A.提高模型在榜单上的得分
- B.应对标注者答案的多样性← 正确答案
- C.降低数据集的标注成本支出
- D.压缩模型输出答案的句子长度
答案:B。同一张图片同一个问题,不同标注者会给出不同但合理的表述,单一标准无法公平判定,因此软准确率选择“统计共识人数”。提高得分和降低成本都是副产品,不是设计动机。
Q3. VQA软准确率中,预测答案至少需要被几位标注者写出才算正确?
- A.只需要一人认可就算正确
- B.需要两人认可才算正确
- C.需要至少三人认可才算← 正确答案
- D.必须十个人全部认可
答案:C。VQA官方在10位标注者的设定下,将“3人认可”作为判对阈值。1人不足以排除随意标注,10人又过于严苛,3人是在开放性和可靠性之间的折中。
Q4. 设测试集共 \(N\) 题,第 \(i\) 题有 \(c_i\) 位标注者认同模型预测,则软准确率的公式是?
- A.\(\frac{1}{N}\sum_{i=1}^{N}\min(c_i/3, 1)\)← 正确答案
- B.\(\frac{1}{N}\sum_{i=1}^{N}\max(3-c_i, 0)\)
- C.\(\frac{1}{N}\sum_{i=1}^{N}\frac{c_i}{10}\)
- D.\(\frac{1}{N}\sum_{i=1}^{N}\min(3c_i, 1)\)
答案:A。直接对照VQA软准确率定义。B是“缺票惩罚项”不是正确指标;C把10人平均当得分,无法体现“3人认可”门槛;D把3人倍数当上限,逻辑相反。
Q5. 为什么VQA不用单一标准答案做精确匹配?
- A.因为同义表述多样无法唯一← 正确答案
- B.因为标注者故意写错答案
- C.因为字符串比对的速度太慢
- D.因为开放题答案通常都很长
答案:A。VQA的答案是开放的,“趴着”“躺着”“睡觉”可以描述同一状态。单一标准答案会把语义等价但用词不同的正确答案全部误杀,这正是简单准确率的核心缺陷。
Q6. 一个“是/否”问题,10位标注者全部回答“是”,模型也回答“是”,该题软准确率得分是?
- A.得分折合为零点三分左右
- B.该题得满分一分的分值← 正确答案
- C.得分超过上限变为三分
- D.该题只按三人比例给分
答案:B。\(c_i=10\),代入公式得 min(10/3, 1) = 1。10人全部认可,远超3人门槛,但得分被封顶在1,不会超过满分。A和D混淆了归一化过程,C错误理解了上限。
Q7. 以下哪些是VQA软准确率设计的关键点?
- A.多位标注者共同参与判定← 正确答案
- B.阈值设定为至少三个人← 正确答案
- C.取多数人答案作为标准答案
- D.对共识性答案允许部分给分← 正确答案
答案:ABD。软准确率的关键在于“多位标注者 + 3人门槛 + 部分得分”(\(c_i=2\) 时得2/3分)。C描述的“取多数人答案当标准”恰恰是简单准确率的思路,与软准确率保留全部分布信息的理念相悖。
Q8. 把软准确率的阈值从3改成5,同一数据集上模型分数会出现什么变化?
- A.模型分数会出现大概率上升
- B.模型分数会出现大概率下降← 正确答案
- C.模型分数始终保持基本不变
- D.评测花费的时间会显著缩短
答案:B。阈值提高意味着要求更多人认可模型答案,判对难度增大。对大多数样本而言,\(c_i/5\) 比 \(c_i/3\) 更小,封顶也更难达到,所以分数大概率下降。
Q9. VQA官方评测中需要专门分类统计的题型包括哪些?
- A.是或否类判断题答案类型← 正确答案
- B.数字计数类问题答案类型← 正确答案
- C.开放式短语描述答案类型← 正确答案
- D.图像像素误差分布答案类型
答案:ABC。VQA将问题分为Yes/No、Number、Other三类分别统计。“像素误差”是图像生成或重建任务的评估概念,与VQA答案语义无关。
Q10. 关于VQA软准确率的局限性与补充评测,下列说法正确的是?
- A.高分不代表模型没有取巧漏洞← 正确答案
- B.需辅以分题型和错误案例分析← 正确答案
- C.软准确率能完全替代人工评测
- D.高标注成本是实际评测的约束← 正确答案
答案:ABD。模型可以靠高频答案“蒙题”获得软准确率高分,因此必须结合分题型指标、错误案例聚类等分析手段。每题10人标注成本很高,是评测落地的现实约束。C错在“完全替代”——任何自动指标都只是辅助,最终质量仍需人工验证。