itchml
v1.0.0-alpha.6
Published
TypeScript & Type-Safe Machine Learning Library
Maintainers
Readme
ItchML
ItchML is an TypeScript module for running machine learning in the browser or Node.js environment. It is not intended as a replacement for TensorFlow or PyTorch. Instead, ItchML provides a minimal implementation of core modern machine learning concepts, designed for educational purposes or experimental projects directly in the browser.
What ItchML Is Not
- It is not intended for training large models in the browser.
- It does not aim to compete with TensorFlow or PyTorch.
- It avoids unnecessary machine learning modules or features.
ItchML focuses on simplicity, accessibility, and learning, making it an ideal foundation for students, educators, and developers experimenting with ML in web-based environments.
Install
npm i itchmlUsage
import {
Tensor,
tensor,
makeTensor,
shapeSize,
//
Sequential,
Linear,
ReLU,
Softmax,
LayerNorm,
type Layer,
//
SGD,
Adam,
mseLoss,
crossEntropyLoss,
params,
//
scaledDotProductAttention,
multiHeadAttention,
//
serialize,
deserialize,
//
Conv2d,
convOutputSize,
BatchNorm2d,
maxPool2d,
flatten4d,
relu4d,
} from "itchml";Tensor
Create type safe tensor:
import { tensor } from "itchml";
const A = tensor([1, 2, 3, 4, 5, 6], [2, 3] as const);
const B = tensor([1, 2, 3, 4, 5, 6], [2, 3] as const);
const C = tensor([
[1, 2],
[3, 4],
[5, 6],
]);
const D = tensor([
[1, 2],
[3, 4],
[5, 6],
] as const);
const E = tensor<3, 2>([
[1, 2],
[3, 4],
[5, 6],
]);Linear & MLP & XOR
import { Sequential, Linear, ReLU, SGD, tensor, mseLoss } from "itchml";
import * as fs from "fs";
const CHECKPOINT = "./xor-checkpoint.json";
const X = [
tensor([0, 0], [1, 2] as const),
tensor([0, 1], [1, 2] as const),
tensor([1, 0], [1, 2] as const),
tensor([1, 1], [1, 2] as const),
];
const Y = [0, 1, 1, 0];
const model = new Sequential([
new Linear(2, 8),
new ReLU<8>(),
new Linear(8, 1),
]);
const opt = new SGD(model.parameters(), 0.15);
// Load checkpoint if exists, otherwise train
if (fs.existsSync(CHECKPOINT)) {
model.load(JSON.parse(fs.readFileSync(CHECKPOINT, "utf-8")));
console.log("Loaded checkpoint.");
} else {
for (let epoch = 1; epoch <= 1000; epoch++) {
let loss = 0;
for (let s = 0; s < 4; s++) {
const pred = model.forward(X[s]);
const l = mseLoss(pred, tensor([Y[s]], [1, 1] as const));
loss += l.data[0];
l.backward();
opt.step();
opt.zeroGrad();
}
if (epoch % 100 === 0)
console.log(`epoch ${epoch} | loss ${(loss / 4).toFixed(4)}`);
}
fs.writeFileSync(CHECKPOINT, JSON.stringify(model.serialize()), "utf-8");
}
// Eval
for (let s = 0; s < 4; s++) {
const pred = model.forward(X[s]).data[0];
console.log(`[${Y[s]}] pred=${pred.toFixed(3)} rounded=${Math.round(pred)}`);
}Browser Usage
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>XOR Training</title>
<style>
body {
font-family: monospace;
background: #0f0f0f;
color: #ccc;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
gap: 1rem;
}
h1 {
color: #7effa0;
font-size: 1.4rem;
margin: 0;
}
button {
background: #1e1e1e;
color: #7effa0;
border: 1px solid #7effa0;
padding: 0.4rem 1.2rem;
font-family: monospace;
cursor: pointer;
border-radius: 4px;
}
button:hover {
background: #7effa0;
color: #0f0f0f;
}
p {
color: #555;
font-size: 0.85rem;
margin: 0;
}
</style>
</head>
<body>
<h1>XOR Training</h1>
<button
onclick="localStorage.removeItem('xor-checkpoint'); location.reload()">
Reset
</button>
<p>Open DevTools console (F12) to see training logs and eval output.</p>
<script type="module">
import {
Sequential,
Linear,
ReLU,
SGD,
tensor,
mseLoss,
} from "https://esm.sh/itchml";
const X = [
tensor([0, 0], [1, 2]),
tensor([0, 1], [1, 2]),
tensor([1, 0], [1, 2]),
tensor([1, 1], [1, 2]),
];
const Y = [0, 1, 1, 0];
const model = new Sequential([
new Linear(2, 8),
new ReLU(),
new Linear(8, 1),
]);
const opt = new SGD(model.parameters(), 0.15);
const saved = localStorage.getItem("xor-checkpoint");
if (saved) {
model.load(JSON.parse(saved));
console.log("Loaded checkpoint.");
} else {
for (let epoch = 1; epoch <= 500; epoch++) {
let loss = 0;
for (let s = 0; s < 4; s++) {
const pred = model.forward(X[s]);
const l = mseLoss(pred, tensor([Y[s]], [1, 1]));
loss += l.data[0];
l.backward();
opt.step();
opt.zeroGrad();
}
if (epoch % 50 === 0)
console.log(`epoch ${epoch} | loss ${(loss / 4).toFixed(4)}`);
}
localStorage.setItem(
"xor-checkpoint",
JSON.stringify(model.serialize())
);
}
for (let s = 0; s < 4; s++) {
const pred = model.forward(X[s]).data[0];
console.log(
`[${Y[s]}] pred=${pred.toFixed(3)} rounded=${Math.round(pred)}`
);
}
</script>
</body>
</html>