thibaud frere
update trackio design
9a962ce
raw
history blame
3.66 kB
// Data generation utilities for synthetic training data
export function generateRunNames(count) {
const adjectives = [
'ancient', 'brave', 'calm', 'clever', 'crimson', 'daring', 'eager', 'fearless',
'gentle', 'glossy', 'golden', 'hidden', 'icy', 'jolly', 'lively', 'mighty',
'noble', 'proud', 'quick', 'silent', 'swift', 'tiny', 'vivid', 'wild'
];
const nouns = [
'river', 'mountain', 'harbor', 'forest', 'valley', 'ocean', 'meadow', 'desert',
'island', 'canyon', 'harbor', 'trail', 'summit', 'delta', 'lagoon', 'ridge',
'tundra', 'reef', 'plateau', 'prairie', 'grove', 'bay', 'dune', 'cliff'
];
const used = new Set();
const names = [];
const pick = (arr) => arr[Math.floor(Math.random() * arr.length)];
while (names.length < count) {
const name = `${pick(adjectives)}-${pick(nouns)}-${Math.floor(1 + Math.random() * 7)}`;
if (!used.has(name)) {
used.add(name);
names.push(name);
}
}
return names;
}
export function genCurves(n) {
const quality = Math.random();
const good = quality > 0.66;
const poor = quality < 0.33;
const l0 = 2.0 + Math.random() * 4.5;
const targetLoss = good
? l0 * (0.12 + Math.random() * 0.12)
: (poor ? l0 * (0.35 + Math.random() * 0.25) : l0 * (0.22 + Math.random() * 0.16));
const phases = 1 + Math.floor(Math.random() * 3);
const marksSet = new Set();
while (marksSet.size < phases - 1) {
marksSet.add(Math.floor((0.25 + Math.random() * 0.5) * (n - 1)));
}
const marks = [0, ...Array.from(marksSet).sort((a, b) => a - b), n - 1];
let kLoss = 0.02 + Math.random() * 0.08;
const loss = new Array(n);
for (let seg = 0; seg < marks.length - 1; seg++) {
const a = marks[seg];
const b = marks[seg + 1] || a + 1;
for (let i = a; i <= b; i++) {
const t = (i - a) / Math.max(1, (b - a));
const segTarget = targetLoss * Math.pow(0.85, seg);
let v = l0 * Math.exp(-kLoss * (i + 1));
v = 0.6 * v + 0.4 * (l0 + (segTarget - l0) * (seg + t) / Math.max(1, (marks.length - 1)));
const noiseAmp = (0.08 * l0) * (1 - 0.8 * (i / (n - 1)));
v += (Math.random() * 2 - 1) * noiseAmp;
if (Math.random() < 0.02) v += 0.15 * l0;
loss[i] = Math.max(0, v);
}
kLoss *= 1.6;
}
const a0 = 0.1 + Math.random() * 0.35;
const aMax = good
? (0.92 + Math.random() * 0.07)
: (poor ? (0.62 + Math.random() * 0.14) : (0.8 + Math.random() * 0.1));
let kAcc = 0.02 + Math.random() * 0.08;
const acc = new Array(n);
for (let i = 0; i < n; i++) {
let v = aMax - (aMax - a0) * Math.exp(-kAcc * (i + 1));
const noiseAmp = 0.04 * (1 - 0.8 * (i / (n - 1)));
v += (Math.random() * 2 - 1) * noiseAmp;
acc[i] = Math.max(0, Math.min(1, v));
if (marksSet.has(i)) kAcc *= 1.4;
}
const accGap = 0.02 + Math.random() * 0.06;
const lossGap = 0.05 + Math.random() * 0.15;
const accVal = new Array(n);
const lossVal = new Array(n);
let ofStart = Math.floor(((good ? 0.85 : 0.7) + (Math.random() * 0.15 - 0.05)) * (n - 1));
ofStart = Math.max(Math.floor(0.5 * (n - 1)), Math.min(Math.floor(0.95 * (n - 1)), ofStart));
for (let i = 0; i < n; i++) {
let av = acc[i] - accGap + (Math.random() * 0.06 - 0.03);
let lv = loss[i] * (1 + lossGap) + (Math.random() * 0.1 - 0.05) * Math.max(1, l0 * 0.2);
if (i >= ofStart && !poor) {
const t = (i - ofStart) / Math.max(1, (n - 1 - ofStart));
av -= 0.03 * t;
lv += 0.12 * t * loss[i];
}
accVal[i] = Math.max(0, Math.min(1, av));
lossVal[i] = Math.max(0, lv);
}
return { accTrain: acc, lossTrain: loss, accVal, lossVal };
}