Files
Robot_Arm/ml/gen/stats.cjs
T
Hark 5591adb39a ml: 第二轮审查 B-1~B-8 处置 + 一键训练控制台
- B-1 运行时投影护栏恢复 5 mm;老师轨迹按认证最小间隙 < 3 mm 剔除(stats/build_dataset,gapDrop)
- B-2 APG 端点+中点 hinge 取均值;B-3 check_r2 空匹配保护、5000×50000、分块 256,pass=false 时 prep 停下
- B-4 R7 按全部 B/C 题统计;B-5 r8 起点贴柱;B-7 pipeline r4(export_onnx --random,训练前测延迟)
- B-8 起步失败 ≤0.2%、column_gap 分块、pipefail、门禁结果先写 .tmp
- 训练控制台:ml/console.bat|sh → ml/monitor.py(开始/停止/进度/日志接口)+ monitor.html;
  pipeline.sh all 支持 FROM/TO,阶段状态写 ml/runs/pipeline.json(ml/pstate.py);训练/APG 日志加 total、t
- 文档:README 一键运行与训练控制台;审查文档追加第三轮处置;方案余量决策与 R4 时点
2026-10-18 06:40:24 +08:00

29 lines
2.3 KiB
JavaScript

/* M1 统计:node ml/gen/stats.cjs ml/data/shard_*.jsonl > ml/data/stats.json */
'use strict';
const fs = require('fs');
const files = process.argv.slice(2);
/* 2026-10-18:老师样本按认证最小间隙过滤(< MIN_GAP_MM 的轨迹不进训练集,build_dataset.cjs 同值)。
安全护栏(运行时投影 5 mm)不迁就数据分布;样本数与补量只按过滤后计。 */
const MIN_GAP_MM = +(process.env.MIN_GAP_MM || 3);
let gapDrop = 0;
const by = {}; let total = 0, keep = 0, steps = 0, samples = 0, padTail = 0;
const q = a => { a.sort((x, y) => x - y); return a.length ? { p10: +a[Math.floor(a.length * 0.1)].toFixed(1), p50: +a[a.length >> 1].toFixed(1), p90: +a[Math.floor(a.length * 0.9)].toFixed(1), max: +a[a.length - 1].toFixed(1) } : null; };
const plan = [], certMs = [], travel = [], exec = [], gaps = [];
for (const f of files) for (const line of fs.readFileSync(f, 'utf8').split('\n')) {
if (!line) continue; const r = JSON.parse(line); total++;
const k = r.cat + '/' + r.mode; const b = by[k] = by[k] || { n: 0, reached: 0, certFail: 0, keep: 0, demoted: 0, consensusDrop: 0, j6Frozen: 0 };
b.n++; if (r.reached) b.reached++; if (r.cert && !r.cert.ok) b.certFail++; if (r.demoted) b.demoted++; if (r.why === 'consensus') b.consensusDrop++; if (r.j6Frozen) b.j6Frozen++;
if (r.plan_ms != null) plan.push(r.plan_ms); if (r.cert) certMs.push(r.cert.ms); if (r.cert) gaps.push(r.cert.minGap);
if (r.keep && r.cert && r.cert.minGap != null && r.cert.minGap < MIN_GAP_MM) { gapDrop++; b.gapDrop = (b.gapDrop || 0) + 1; }
else if (r.keep) { b.keep++; keep++; travel.push(r.travel_deg); exec.push(r.exec_s);
const n = r.traj.length - 1; steps += n; const s = Math.floor(n / 3) + 1; samples += s;
for (let t = 0; t <= n; t += 3) if (t + 16 > n) padTail++; }
}
const out = { tasks: total, keep, keepRate: +(keep / total).toFixed(3), byCatMode: by,
planMs: q(plan), certMs: q(certMs), vertexMinGapMm: q(gaps), travelDeg: q(travel), execS: q(exec),
samplesEvery3: samples, samplesPerTask: +(samples / keep).toFixed(1), paddedSampleShare: +(padTail / samples).toFixed(3),
projectedSamplesFor50k: Math.round(samples / total * 50000),
gapDrop, minGapFilterMm: MIN_GAP_MM,
consensusDrop: Object.values(by).reduce((a, b) => a + b.consensusDrop, 0) };
console.log(JSON.stringify(out, null, 1));