feat(actpred): log_range 归一化——spk 两列对数尺度修正精度错配
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 模式/元数据自动识别合并。
This commit is contained in:
1 parent
fc310c9081
commit
1cf428f384
11 files changed
+306
-66
No files matched your search
@@ -0,0 +1,82 @@
|
||||
# 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 系列实验定位到两个结构性难题:
|
||||
|
||||
1. **尺度放大**:fixed_range 线性 min-max 下 spk.F 的 1 个归一化单位 = 5000Hz 原始量,闭环反馈中误差滚雪球(模型 C/D 发散根因之一)
|
||||
2. **精度错配**:常用值(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. **舵机 1°/箱而非 5°/箱**:录制数据的微动作插值粒度为 0.75°,箱宽必须匹配数据粒度;5° 箱会把 45.0°/45.75° 压进同一箱,模型学不到特意录制的插值结构
|
||||
2. **软标签**:804 样本对 1864 logits 偏少,多数箱极少被访问。真值 one-hot 高斯扩散到邻近箱,未访问箱也能获得梯度
|
||||
3. **期望值解码补序数信息**:one-hot 丢失"45° 和 46° 相邻"先验,期望值解码在推理端部分恢复;训练端靠软标签缓解
|
||||
4. **pybot 契约零变化**:predict 输出仍是 18 维原始量纲,闭环与录制数据无感知
|
||||
5. **与现有归一化链路的兼容**: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
|
||||
Reference in new issue
Block a user