13 KiB
附件二未对齐版到 Q2 的输入适配:Relative 模式原理
当前统一接口、调用方式和全量审计以 UNIFIED_ADAPTER.md 为准。本文继续解释 Relative 坐标的假设、长度处理和限制。旧 unaligned_adapter.py 现在只是委托给统一接口的兼容层;Q2 实际调用 adapter.adapt_official_split。
结论与适用范围
unaligned_50.pkl 只有独立的序列索引,没有原始视频 PTS、音频采样时刻或词边界。Q1 主干的物理时间区间投影不能直接用于该文件。这里复用 Q1 的“来源区间与目标区间求交、只汇聚真实观测”算子,将每个模态的相对索引进程 [0,1) 分成 50 段,供 Q2 的固定 50 步接口开展探索性训练。结果不是秒级同步结果,也不能生成原词到音频窗/视频帧的物理查询矩阵。《E题V2》4.5.3 的原式使用视频真实时长 D_i,本文件没有 D_i,因此这里是受其启发的近似适配,并非该式的严格复现。5.1.1 要求的可核验共同时间步仍需真实时间戳才能确立;本适配的 Q2 指标应单列为探索性结果。
Q1 的 B0 可借用区间交叠的计算形式,但权重中的区间在这里是归一化索引而非秒。B1 的 OpenFace 几何处理、B2 的 CTC 词边界后验、B4 的 Wav2Vec2 辅助特征和 B5 的原词查询矩阵都要求本文件未提供的来源定义或原始素材,不能因为维度相同就接到官方预计算特征上。Q2 使用的仍是附件二原有 text/audio/vision 特征列,只改变时序组织。
| 对比项 | Q1 原始素材主干 | 本适配器 |
|---|---|---|
| 来源定位 | 词边界、音频采样/窗口、视频帧 PTS | 各模态自身的整数行索引和可用长度 |
| 目标轴 | 真实秒数划分的 0.1 秒主网格 | 没有秒单位的 50 个相对索引进程格 |
| 可核验结论 | 可回查某词、某秒对应的原始素材 | 可回查目标格聚合了哪些预计算来源行 |
| 不能互换的内容 | 原生特征、真实质量与物理来源图 | 官方预计算特征、索引覆盖和长度歧义 |
为什么需要单独适配
Q1 原始样本流程知道词的起止秒数、音频窗口对应的采样范围、视频帧的真实 PTS,因此可以先定义共同的物理时间区间,再计算各来源与目标区间的交长。附件二未对齐版只给三组已提取的数字序列:文本最多 50 行,音频和视觉各最多 500 行。它们的第 10 行既不表示同一个时刻,也不带有足以恢复时刻的采样率和起点。直接把三个数组裁到前 50 行,或者把第 r 行视为共同时间步,都会制造未经数据支持的对应关系。
适配器采用一项明确的近似假设:每个模态的有效索引范围分别覆盖同一片段的相对进程,索引顺序不变。它把“片段前 2%”映射到统一的第 0 格,把“片段最后 2%”映射到第 49 格。若不同模态的采样不均匀、起止范围不同或存在长段未标注缺口,相同进程格也未必对应相同真实秒数。这是 Q2 固定长度输入的工程接口,不是从数字特征中推回了物理时间。
这里没有用情感标签、内容相似度、DTW 或可学习注意力去移动来源位置。附件二没有可核验的时间真值,用这些分数重排序列无法证明音画或词帧的物理对应正确;原始行顺序和来源索引因此始终保留。
第一步:确定来源范围与真实观测
对每条样本、每个模态分别记来源行数为 L,行观测标记为 o_r。适配器首先核对形状和数值是否有限,再按下表确定来源范围。来源全维零行仅用来判断官方预计算特征的行观测状态,不能把单个维度的正常零值判为缺失。
| 模态 | 原数组与维度 | 采用的 L |
行观测规则与例外 |
|---|---|---|---|
| 文本 | text[50,768] |
text_bert 注意力掩码中连续有效前缀的长度 |
有效前缀内 text 行非全零才观测;掩码外的非零填充向量也排除。raw_text 不参与投影。 |
| 音频 | audio[500,74] |
官方 audio_lengths |
长度内非全零行才观测;若长度后仍有非零行,直接报错,不静默截断。 |
| 视觉 | vision[500,35] |
max(vision_lengths, 最后一个非零行索引 + 1) |
若官方长度后仍有非零行,保留这些已知观测,并标记 length_conflict 与 tail_ambiguous。此时 L 只是包含所有已知观测的最小跨度,不代表已证实的真实帧数。 |
视觉长度冲突时,最后一个非零行之后的零尾段可能是填充,也可能仍属于有效但缺失的内容;数组本身无法区分。适配器没有把这段零尾宣布为已确认填充,也没有把缺失行数值插补后送入 Q2。文本注意力掩码还必须是从位置 0 开始的连续前缀;异常输入直接报错。
第二步:在相对进程轴上做区间投影
对某模态的 L 个来源行,以从 0 开始的索引 r=0,…,L-1 定义来源区间;对目标索引 t=0,…,49 定义统一的 50 个目标区间:
J_r = [r/L, (r+1)/L)
I_t = [t/50, (t+1)/50)
w_tr = o_r · max(0, min((t+1)/50, (r+1)/L) - max(t/50, r/L))
W_t = Σ_r w_tr
只有真正观测的来源行才获得非零权重。区间均采用左闭右开形式;交长由区间端点确定,不通过情感标签或内容相似度调整顺序。W_t>0 时,第 d 个特征维度的投影值为
x̂_t,d = (Σ_r w_tr · x_r,d) / W_t
P_tr = w_tr / W_t
P_tr 是目标位置 t 对来源行 r 的归一化贡献,整行和为 1。若 W_t=0,输出数值零仅作占位,目标观测掩码为假,P 的这一行保持全零;后续模型不能把占位零当成实际观测。计算不跨缺失区间插值,也不依据语义相似度把来源行重排。没有可靠的来源质量字段,因此所有有效行只使用单位质量权重。
一个简单例子:某音频片段有 L=100 个来源行,目标第 0 格覆盖 [0,0.02),恰好与来源行 0、1 各重叠 0.01。若两行同一维取值分别为 2 和 4,投影值就是 3,来源权重各为 0.5。若来源行 1 缺失,投影值为 2、来源权重变为 1,但该格只有一半的索引区间有观测;不会用零把均值拉到 1。若某格内所有来源行均缺失,该格的掩码为假。这些数值展示的是索引交叠规则,不意味着每行对应 0.01 秒。
第三步:保存可回查的投影信息
project_modality(...) 对单条样本的一个模态返回 ProjectedView,各字段含义如下。
| 字段 | 形状或类型 | 含义 |
|---|---|---|
x |
(50,d),float32 |
交叠加权后的特征;d 保持为文本 768、音频 74、视觉 35。 |
observed |
(50,),布尔值 |
目标格是否得到至少一个实际观测来源。 |
coverage |
(50,) |
min(1,50·W_t);目标格在相对索引区间内的观测覆盖比例,并非秒级覆盖率。 |
source_count |
(50,) |
对该目标格贡献非零交长的观测来源行数。 |
first_source、last_source |
各 (50,) |
首末贡献来源索引;空格记为 -1。它们只是摘要,不能替代完整来源权重。 |
source_weights |
CSR 稀疏矩阵 (50,L) |
每个目标格到各原始来源行的 P_tr;可追溯平均值究竟来自哪些行。 |
reported_length、source_span、length_conflict、tail_ambiguous |
样本级字段 | 对比官方长度与本次投影采用的跨度,保留视觉长度歧义。 |
例如 source_weights.getrow(10) 可列出目标第 10 格使用的原始索引及其权重。多格可能共享一个原始来源行,因为来源区间可能跨过 50 格的边界;共享不会产生新的独立观测。完整权重保存在单样本返回对象中,批量训练接口不会把所有样本的 CSR 矩阵装入模型。
第四步:交给 Q2 训练
adapt_split(...) 对一个官方划分逐样本调用上述算子,返回三个模态的 (N,50,d) 特征、(N,50,3) 观测掩码和划分级审计。math/Q2/data.py 的 load_official_splits(..., version="unaligned_50") 将它们封装成原有 SplitData;显式传入投影掩码,避免有效的正负特征在均值中恰好抵消为全零时被误判为缺失。样本 ID、官方 train/valid/test 划分和标签原样保留。
Q2 随后从官方训练集再按来源 video_id 划出拟合、可靠度选择和温度校准组。标准化器只在拟合组的已观测行上拟合;标准化后缺失位置继续保持零占位及假掩码。C5 按既有流程生成特征层连续缺口进行训练,模型输入仍为文本/音频/视觉 50 位序列及观测掩码。当前 C5 不读取 coverage、source_count 或 CSR 权重作为质量值;官方未对齐文件没有真实质量分数,可靠度分支按 q*=1, J_Q=0 的回退规则运行。覆盖率可用于核验投影和后续独立研究,但不能直接宣称为检测质量。
适配过程不读情感标签,raw_text 不进入学生模型,也不使用验证或测试集拟合对齐参数。Q2 才读取标签执行监督训练与评估。附件二的 train、valid、test 都通过同一转换规则,测试集只用于最终评估。
接口
unaligned_adapter.py 的 project_modality(...) 返回一条样本的 50 位特征、观测掩码、覆盖率、来源行数、首末来源索引及完整的 CSR 来源权重矩阵;adapt_split(...) 处理官方一个划分并返回审计摘要。Q2 的 load_official_splits(path, version="unaligned_50") 直接调用此适配器,输出既有 SplitData 接口。调用方可按下面的方式读取一个划分,代码在仓库根目录运行时需把 math/Q2 加入 Python 导入路径:
import sys
from pathlib import Path
sys.path.insert(0, "math/Q2")
from data import load_official_splits
splits = load_official_splits(
Path("E题数据/附件2-数据集特征文件/unaligned_50.pkl"),
version="unaligned_50",
)
train = splits["train"]
audio_features = train.x["audio"] # (3395, 50, 74)
observed = train.mask # (3395, 50, 3),顺序为文本、音频、视觉
audit = train.alignment_audit
单样本核验时直接调用 project_modality,可从 source_weights.getrow(t) 得到第 t 个目标格的原始行索引与权重。load_official_splits 只把三模态特征、掩码及审计摘要交给 Q2;单样本覆盖率和 CSR 来源权重不会默认送入预测网络。
Q2 训练入口:
uv run --project math/Q1 python math/Q2/train_unaligned_c5.py
未对齐版权重、尺度、指标和清单单独写入 math/Q2/results_unaligned/,与原有 aligned 版结果隔离。该入口固定使用原 aligned 实验已选定的 C5 结构,在未对齐版训练数据上重新拟合全部参数;未对齐版只选择可靠度与温度,不重新挑选架构。若需要完整 C0–C7 对照,可使用 train.py --input-version unaligned_50 --skip-attachment3。
批量转换在内存中确定性执行,没有另存一份接近原数据体积的派生特征文件;每次训练都从官方未对齐文件重建同一 50 位视图。results_unaligned/ 保存权重、训练折尺度、指标、预测和含输入 SHA-256 的运行清单,不保存原始数据或大体积缓存。
已核对的输入异常与专项推理限制
附件二 train/valid/test 分别为 3395/728/727 条;vision_lengths 后仍出现观测行的样本分别为 618/141/131 条。文本注意力掩码外的非零 text 行分别有 86078/17772/18041 行,均按填充排除。这些数字是输入结构审计,不是对齐准确率。没有人工时间真值,不能报告秒级边界误差。
固定 C5 后,未对齐索引视图的验证集 Accuracy/Macro-F1/MAE 为 0.6099/0.5253/0.6701,测试集为 0.6726/0.5668/0.7059。这些指标说明该输入接口能够完成 Q2 训练与预测,不测量某个目标格是否与真实视频秒数吻合。与 aligned 版的指标差异还受到特征组织、训练随机性和视觉长度歧义影响,不能单独归因于投影规则。测试预测、视频组 Bootstrap 区间和运行参数分别保存在 math/Q2/results_unaligned/test_predictions.csv、group_bootstrap_ci.csv 和 run_manifest.json。
附件三的未对齐版本只有 raw_text、audio、vision,没有 text、text_bert、audio_lengths 或 vision_lengths。直接用 raw_text 重编码会绕过专项文本缺失;从最后一个非零行推断完整长度也无法区分尾部缺失和填充。因此当前训练比较不输出附件三未对齐版预测;要完成同版本专项推理,需补充可信长度/填充元数据,并为文本提供不泄漏缺失状态的数值特征或明确将文本全程标为不可观测。