CoolFace
Apppublic

lerobot/robot-learning-tutorial

sourceHugging Faceupdated 1y agoView on Hugging Face
508likes
jitter-trackio-data.mjs130 linesDownload Raw Back to scripts
1#!/usr/bin/env node2 3// Jitter Trackio CSV data with small, controlled noise.4// - Preserves comments (# ...) and blank lines5// - Leaves 'epoch' values unchanged6// - Adds mild noise to train/val accuracy (clamped to [0,1])7// - Adds mild noise to train/val loss (kept >= 0)8// - Keeps steps untouched9// Usage:10//   node app/scripts/jitter-trackio-data.mjs \11//     --in app/src/content/assets/data/trackio_wandb_demo.csv \12//     --out app/src/content/assets/data/trackio_wandb_demo.jitter.csv \13//     [--seed 42] [--amount 1.0] [--in-place]14 15import fs from 'node:fs/promises';16import path from 'node:path';17 18function parseArgs(argv){19  const args = { in: '', out: '', seed: undefined, amount: 1, inPlace: false };20  for (let i = 2; i < argv.length; i++){21    const a = argv[i];22    if (a === '--in' && argv[i+1]) { args.in = argv[++i]; continue; }23    if (a === '--out' && argv[i+1]) { args.out = argv[++i]; continue; }24    if (a === '--seed' && argv[i+1]) { args.seed = Number(argv[++i]); continue; }25    if (a === '--amount' && argv[i+1]) { args.amount = Number(argv[++i]) || 3; continue; }26    if (a === '--in-place') { args.inPlace = true; continue; }27  }28  if (!args.in) throw new Error('--in is required');29  if (args.inPlace) args.out = args.in;30  if (!args.out) {31    const { dir, name, ext } = path.parse(args.in);32    args.out = path.join(dir, `${name}.jitter${ext || '.csv'}`);33  }34  return args;35}36 37function mulberry32(seed){38  let t = seed >>> 0;39  return function(){40    t += 0x6D2B79F5;41    let r = Math.imul(t ^ (t >>> 15), 1 | t);42    r ^= r + Math.imul(r ^ (r >>> 7), 61 | r);43    return ((r ^ (r >>> 14)) >>> 0) / 4294967296;44  };45}46 47function makeRng(seed){48  if (Number.isFinite(seed)) return mulberry32(seed);49  return Math.random;50}51 52function randn(rng){53  // Box-Muller transform54  let u = 0, v = 0;55  while (u === 0) u = rng();56  while (v === 0) v = rng();57  return Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);58}59 60function jitterValue(metric, value, amount, rng){61  const m = metric.toLowerCase();62  if (m === 'epoch') return value; // keep as-is63  if (m.includes('accuracy')){64    const n = Math.max(-0.02 * amount, Math.min(0.02 * amount, randn(rng) * 0.01 * amount));65    return Math.max(0, Math.min(1, value + n));66  }67  if (m.includes('loss')){68    const n = Math.max(-0.03 * amount, Math.min(0.03 * amount, randn(rng) * 0.01 * amount));69    return Math.max(0, value + n);70  }71  // default: tiny noise72  const n = Math.max(-0.01 * amount, Math.min(0.01 * amount, randn(rng) * 0.005 * amount));73  return value + n;74}75 76function formatNumberLike(original, value){77  const s = String(original);78  const dot = s.indexOf('.')79  const decimals = dot >= 0 ? (s.length - dot - 1) : 0;80  if (!Number.isFinite(value)) return s;81  if (decimals <= 0) return String(Math.round(value));82  return value.toFixed(decimals);83}84 85async function main(){86  const args = parseArgs(process.argv);87  const rng = makeRng(args.seed);88  const raw = await fs.readFile(args.in, 'utf8');89  const lines = raw.split(/\r?\n/);90  const out = new Array(lines.length);91 92  for (let i = 0; i < lines.length; i++){93    const line = lines[i];94    if (!line || line.trim().length === 0) { out[i] = line; continue; }95    if (/^\s*#/.test(line)) { out[i] = line; continue; }96 97    // Preserve header line unmodified98    if (i === 0 && /^\s*run\s*,\s*step\s*,\s*metric\s*,\s*value\s*,\s*stderr\s*$/i.test(line)) {99      out[i] = line; continue;100    }101 102    const cols = line.split(',');103    if (cols.length < 4) { out[i] = line; continue; }104 105    const [run, stepStr, metric, valueStr, stderrStr = ''] = cols;106    const trimmedMetric = (metric || '').trim();107    const valueNum = Number((valueStr || '').trim());108 109    if (!Number.isFinite(valueNum)) { out[i] = line; continue; }110 111    const jittered = jitterValue(trimmedMetric, valueNum, args.amount, rng);112    const valueOut = formatNumberLike(valueStr, jittered);113 114    // Reassemble with original column count and positions115    const result = [run, stepStr, metric, valueOut, stderrStr].join(',');116    out[i] = result;117  }118 119  const finalText = out.join('\n');120  await fs.writeFile(args.out, finalText, 'utf8');121  const relIn = path.relative(process.cwd(), args.in);122  const relOut = path.relative(process.cwd(), args.out);123  console.log(`Jittered data written: ${relOut} (from ${relIn})`);124}125 126main().catch(err => {127  console.error(err?.stack || String(err));128  process.exit(1);129});130