fixed_range 线性 min-max 下常用值挤在低端(10Hz→0.002),闭环反馈 中小绝对误差=大相对误差(模型 C/D 发散根因)。新增 normalize_mode= log_range:spk.F/spk.delay 用 log10(1+x) 对数尺度(10Hz→0.27), 舵机列保持线性。全链路接入(dataset/pretrain/predict/onnx/hailo/ calibration/export),与 v3 审计 none 模式/元数据自动识别合并。
5.0 KiB
5.0 KiB
actpred 多头 one-hot 分类输出开发方案
文档类型:开发方案 模块:actpred(联动 pybot 数据契约) 作者:自动生成 日期:2026-08-14 前置实验:
pybot_actpred_dataset_training_eval_20260814.md、actpred_fixed_range_weighted_experiment_20260814.md(模型 A-E 系列)
1. 背景与动机
模型 A-E 系列实验定位到两个结构性难题:
- 尺度放大:fixed_range 线性 min-max 下 spk.F 的 1 个归一化单位 = 5000Hz 原始量,闭环反馈中误差滚雪球(模型 C/D 发散根因之一)
- 精度错配:常用值(10Hz → 0.002)挤在线性尺度的低端,[0,1] 精度预算被浪费(log_range 正在验证的对数尺度解法)
多头 one-hot 是本问题的结构性解法:把 18 维连续回归换成 18 组独立分类头,每组输出一个 one-hot 分布。分类天然消除尺度放大(每箱等距)与物理界问题(箱只覆盖物理范围),且多列 softmax 是 NPU(Hailo)最擅长的计算形态。
2. 方案设计
2.1 分箱设计(每组 one-hot 的维度)
| 列组 | 分箱方式 | 箱数/列 | 依据 |
|---|---|---|---|
| 舵机 0-9(10 列) | 均匀 1°/箱 | 180 | 匹配数据粒度:微动作插值 0.75°/步,5° 箱会把相邻步量化进同一箱、毁掉插值结构 |
| spk.F(10) | 对数分箱 | 32 | 频率对数感知,低端聚集;log10(1+x) 均匀切 |
| spk.delay(11) | 对数分箱 | 32 | 同左 |
| 保留位 12-17 | 无头 | 0 | 恒 0,不参与 |
输出总量:10×180 + 32 + 32 = 1864 logits(当前 18)。最后层 128→1864 ≈ 238K 参数,模型 409K → ~650K,仍属轻量。
2.2 各层改动
| 文件 | 改动 |
|---|---|
actpred/bins.py(新增) |
分箱表 + encode(x)→one-hot / decode(p)→连续值(含对数箱);纯 numpy,供推理/部署复用 |
model.py |
PredictionHead 输出 1864 维 → reshape (B, 18, bins) → 逐组 softmax |
dataset.py |
target 从 (B,18) 连续值 → 每组 one-hot;软标签:真值高斯扩散到 ±1-2 箱 |
train.py |
损失 = Σ 列权重 × CE(组输出, one-hot 真值);列权重沿用 default_column_weights |
predict.py |
输出 decode:期望值 Σ pᵢ·箱中心(推荐)或 argmax 箱中心 → 18 维原始量纲 |
evaluate.py |
无感——predict 返回仍是 18 维原始量纲 |
export_deploy / Hailo |
多组 softmax 为 NPU 友好形态 |
2.3 解码策略(执行时如何取连续值)
| 方式 | 行为 | 评估 |
|---|---|---|
| 期望值(推荐) | Σ pᵢ × 箱中心 |
平滑连续,分辨率超越箱宽(1° 箱可出 46.4°);单峰假设 |
| argmax | 取最大概率箱中心 | 确定性,量化到 1° |
| 按分布采样 | 随机抽箱 | 探索用,后续离线 RL 可复用 |
3. 关键决策点与理由
- 舵机 1°/箱而非 5°/箱:录制数据的微动作插值粒度为 0.75°,箱宽必须匹配数据粒度;5° 箱会把 45.0°/45.75° 压进同一箱,模型学不到特意录制的插值结构
- 软标签:804 样本对 1864 logits 偏少,多数箱极少被访问。真值 one-hot 高斯扩散到邻近箱,未访问箱也能获得梯度
- 期望值解码补序数信息:one-hot 丢失"45° 和 46° 相邻"先验,期望值解码在推理端部分恢复;训练端靠软标签缓解
- pybot 契约零变化:predict 输出仍是 18 维原始量纲,闭环与录制数据无感知
- 与现有归一化链路的兼容:one-hot 方案独立于 zscore/fixed_range/log_range——分箱编码替代归一化,不叠加使用
4. 实施步骤
| 步骤 | 内容 | 产出 |
|---|---|---|
| 1 | bins.py:分箱表 + encode/decode + 对数箱 + 软标签工具 |
独立纯 numpy 模块 + 单测 |
| 2 | dataset.py:目标 one-hot 化(软标签可开关) |
数据链路 + 单测 |
| 3 | model.py + train.py:多头 softmax + 加权 CE |
模型与训练 + 单测 |
| 4 | predict.py:期望值/argmax 解码集成 + 冒烟 |
推理链路 + 单测 |
| 5 | 训练模型 F,与 A-E 闭环五方对比 | 对比报告 |
5. 与其他方案的定位
- 模型 E(log_range)正在训练:若对数尺度已解决精度错配与闭环发散,one-hot 降级为可选优化(分类头天然有界、免归一化常量表的优势仍在)
- 若 E 仍失败:one-hot 是下一个强候选(结构性消除尺度放大)
- 互补关系:one-hot 方案与逐列权重、R1-B rollout 正交,可叠加(rollout 治 exposure bias 的结论不变,任何损失形式都需要它)
6. 决策记录
- 箱宽:初拟 5°/箱(保守,顾虑数据量),讨论后定为 1°/箱——数据插值粒度 0.75° 决定箱宽下限;spk 两列对数 32 箱
- 单头多选 vs 多头单选:softmax 单头在数学上是单选择分布;"多组 one-hot" = 18 个独立 softmax 头并行,每列一个选择
- 多峰分布:当前数据单峰为主,期望值解码够用;若未来出现双峰(如跨脚本姿态冲突),升级为逐箱 sigmoid 或 MDN