mini-jstorch 1.8.0 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -124
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ It runs in Node.js and modern browsers, with a simple API inspired by PyTorch-st
|
|
|
6
6
|
|
|
7
7
|
This project prioritizes `clarity`, `numerical correctness`, and `accessibility` over performance or large-scale production use.
|
|
8
8
|
|
|
9
|
-
In this version `1.8.
|
|
9
|
+
In this version `1.8.2`, we Introduce the **SoftmaxCrossEntropyLoss**, and **BCEWithLogitsLoss**
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
@@ -21,9 +21,7 @@ In this version `1.8.0`, we Introduce the **SoftmaxCrossEntropyLoss**, and **BCE
|
|
|
21
21
|
- running simple training loops in the browser
|
|
22
22
|
- environments where large frameworks are unnecessary or unavailable
|
|
23
23
|
|
|
24
|
-
`
|
|
25
|
-
|
|
26
|
-
`It is intentionally scoped to remain small, readable, and easy to debug.`
|
|
24
|
+
`mini-jstorch is intentionally designed to be small, readable, and easy to debug.`
|
|
27
25
|
|
|
28
26
|
---
|
|
29
27
|
|
|
@@ -31,7 +29,7 @@ In this version `1.8.0`, we Introduce the **SoftmaxCrossEntropyLoss**, and **BCE
|
|
|
31
29
|
|
|
32
30
|
- Zero dependencies
|
|
33
31
|
- ESM-first (`type: module`)
|
|
34
|
-
- Works in Node.js and browser environments
|
|
32
|
+
- Works in Node.js or others enviornments and browser environments
|
|
35
33
|
- Explicit, manual forward and backward passes
|
|
36
34
|
- Focused on 2D training logic (`[batch][features]`)
|
|
37
35
|
- Designed for educational and experimental use
|
|
@@ -57,146 +55,55 @@ In Browser/Website:
|
|
|
57
55
|
```html
|
|
58
56
|
<!DOCTYPE html>
|
|
59
57
|
<html>
|
|
60
|
-
<body>
|
|
61
|
-
<
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
</div>
|
|
58
|
+
<body style="font-family:monospace; padding:20px;">
|
|
59
|
+
<h3>mini-jstorch XOR Demo</h3>
|
|
60
|
+
<div id="status">Initializing...</div>
|
|
61
|
+
<pre id="log" style="background:#eee; padding:10px;"></pre>
|
|
62
|
+
<div id="res"></div>
|
|
66
63
|
|
|
67
64
|
<script type="module">
|
|
68
|
-
import { Sequential, Linear, ReLU, MSELoss, Adam, StepLR, Tanh } from 'https://unpkg.com/jstorch';
|
|
69
|
-
|
|
70
|
-
const statusEl = document.getElementById('status');
|
|
71
|
-
const trainingLogEl = document.getElementById('training-log');
|
|
72
|
-
const resultsEl = document.getElementById('results');
|
|
65
|
+
import { Sequential, Linear, ReLU, MSELoss, Adam, StepLR, Tanh } from 'https://unpkg.com/mini-jstorch@1.8.0/index.js';
|
|
73
66
|
|
|
74
|
-
async function
|
|
67
|
+
async function train() {
|
|
68
|
+
const statusEl = document.getElementById('status');
|
|
69
|
+
const logEl = document.getElementById('log');
|
|
70
|
+
|
|
75
71
|
try {
|
|
76
|
-
statusEl.textContent = 'Creating model...';
|
|
77
|
-
|
|
78
72
|
const model = new Sequential([
|
|
79
|
-
new Linear(2, 16),
|
|
80
|
-
new
|
|
81
|
-
new Linear(16, 8),
|
|
82
|
-
new ReLU(),
|
|
73
|
+
new Linear(2, 16), new Tanh(),
|
|
74
|
+
new Linear(16, 8), new ReLU(),
|
|
83
75
|
new Linear(8, 1)
|
|
84
76
|
]);
|
|
85
77
|
|
|
86
78
|
const X = [[0,0], [0,1], [1,0], [1,1]];
|
|
87
79
|
const y = [[0], [1], [1], [0]];
|
|
88
|
-
|
|
89
80
|
const criterion = new MSELoss();
|
|
90
81
|
const optimizer = new Adam(model.parameters(), 0.1);
|
|
91
82
|
const scheduler = new StepLR(optimizer, 25, 0.5);
|
|
92
83
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
statusEl.textContent = 'Training...';
|
|
98
|
-
|
|
99
|
-
for (let epoch = 0; epoch < 1000; epoch++) {
|
|
100
|
-
const pred = model.forward(X);
|
|
101
|
-
const loss = criterion.forward(pred, y);
|
|
102
|
-
const grad = criterion.backward();
|
|
103
|
-
model.backward(grad);
|
|
84
|
+
for (let epoch = 0; epoch <= 1000; epoch++) {
|
|
85
|
+
const loss = criterion.forward(model.forward(X), y);
|
|
86
|
+
model.backward(criterion.backward());
|
|
104
87
|
optimizer.step();
|
|
105
88
|
scheduler.step();
|
|
106
89
|
|
|
107
|
-
if (epoch %
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
// Update status every 100 epochs
|
|
113
|
-
statusEl.textContent = `Training... Epoch ${epoch}/1000 (Loss: ${loss.toFixed(6)})`;
|
|
114
|
-
|
|
115
|
-
await new Promise(resolve => setTimeout(resolve, 10));
|
|
90
|
+
if (epoch % 200 === 0) {
|
|
91
|
+
logEl.textContent += `Epoch ${epoch} | Loss: ${loss.toFixed(6)}\n`;
|
|
92
|
+
statusEl.textContent = `Training: ${epoch}/1000`;
|
|
93
|
+
await new Promise(r => setTimeout(r, 1));
|
|
116
94
|
}
|
|
117
95
|
}
|
|
118
96
|
|
|
119
|
-
statusEl.textContent = '
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
resultsTable.style.width = '300px';
|
|
127
|
-
|
|
128
|
-
// Table header
|
|
129
|
-
const headerRow = document.createElement('tr');
|
|
130
|
-
['Input A', 'Input B', 'Prediction', 'Target'].forEach(text => {
|
|
131
|
-
const th = document.createElement('th');
|
|
132
|
-
th.textContent = text;
|
|
133
|
-
th.style.border = '1px solid #ccc';
|
|
134
|
-
th.style.padding = '8px';
|
|
135
|
-
headerRow.appendChild(th);
|
|
136
|
-
});
|
|
137
|
-
resultsTable.appendChild(headerRow);
|
|
138
|
-
|
|
139
|
-
const predictions = model.forward(X);
|
|
140
|
-
predictions.forEach((pred, i) => {
|
|
141
|
-
const row = document.createElement('tr');
|
|
142
|
-
|
|
143
|
-
const cell1 = document.createElement('td');
|
|
144
|
-
cell1.textContent = X[i][0];
|
|
145
|
-
cell1.style.border = '1px solid #ccc';
|
|
146
|
-
cell1.style.padding = '8px';
|
|
147
|
-
cell1.style.textAlign = 'center';
|
|
148
|
-
|
|
149
|
-
const cell2 = document.createElement('td');
|
|
150
|
-
cell2.textContent = X[i][1];
|
|
151
|
-
cell2.style.border = '1px solid #ccc';
|
|
152
|
-
cell2.style.padding = '8px';
|
|
153
|
-
cell2.style.textAlign = 'center';
|
|
154
|
-
|
|
155
|
-
const cell3 = document.createElement('td');
|
|
156
|
-
cell3.textContent = pred[0].toFixed(4);
|
|
157
|
-
cell3.style.border = '1px solid #ccc';
|
|
158
|
-
cell3.style.padding = '8px';
|
|
159
|
-
cell3.style.textAlign = 'center';
|
|
160
|
-
cell3.style.fontWeight = 'bold';
|
|
161
|
-
cell3.style.color = Math.abs(pred[0] - y[i][0]) < 0.1 ? 'green' : 'red';
|
|
162
|
-
|
|
163
|
-
const cell4 = document.createElement('td');
|
|
164
|
-
cell4.textContent = y[i][0];
|
|
165
|
-
cell4.style.border = '1px solid #ccc';
|
|
166
|
-
cell4.style.padding = '8px';
|
|
167
|
-
cell4.style.textAlign = 'center';
|
|
168
|
-
|
|
169
|
-
row.appendChild(cell1);
|
|
170
|
-
row.appendChild(cell2);
|
|
171
|
-
row.appendChild(cell3);
|
|
172
|
-
row.appendChild(cell4);
|
|
173
|
-
resultsTable.appendChild(row);
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
resultsEl.appendChild(resultsTable);
|
|
177
|
-
|
|
178
|
-
const summary = document.createElement('div');
|
|
179
|
-
summary.style.marginTop = '20px';
|
|
180
|
-
summary.style.padding = '10px';
|
|
181
|
-
summary.style.backgroundColor = '#f0f0f0';
|
|
182
|
-
summary.style.borderRadius = '5px';
|
|
183
|
-
summary.innerHTML = `
|
|
184
|
-
<p><strong>Model Architecture:</strong> 2 → 16 → 8 → 1</p>
|
|
185
|
-
<p><strong>Activation:</strong> Tanh → ReLU</p>
|
|
186
|
-
<p><strong>Loss Function:</strong> MSE</p>
|
|
187
|
-
<p><strong>Optimizer:</strong> Adam (LR: 0.1)</p>
|
|
188
|
-
<p><strong>Epochs:</strong> 1000</p>
|
|
189
|
-
`;
|
|
190
|
-
resultsEl.appendChild(summary);
|
|
191
|
-
|
|
192
|
-
} catch (error) {
|
|
193
|
-
statusEl.textContent = `Error: ${error.message}`;
|
|
194
|
-
statusEl.style.color = 'red';
|
|
195
|
-
console.error(error);
|
|
97
|
+
statusEl.textContent = '✅ Done';
|
|
98
|
+
const preds = model.forward(X);
|
|
99
|
+
document.getElementById('res').innerHTML = `<h4>Results:</h4>` +
|
|
100
|
+
X.map((input, i) => `[${input}] -> <b>${preds[i][0].toFixed(4)}</b> (Target: ${y[i][0]})`).join('<br>');
|
|
101
|
+
|
|
102
|
+
} catch (e) {
|
|
103
|
+
statusEl.textContent = '❌ Error: ' + e.message;
|
|
196
104
|
}
|
|
197
105
|
}
|
|
198
|
-
|
|
199
|
-
trainModel();
|
|
106
|
+
train();
|
|
200
107
|
</script>
|
|
201
108
|
</body>
|
|
202
109
|
</html>
|
|
@@ -267,11 +174,17 @@ In Browser/Website:
|
|
|
267
174
|
|
|
268
175
|
# Installation
|
|
269
176
|
|
|
177
|
+
## Node.js
|
|
270
178
|
```bash
|
|
271
179
|
npm install mini-jstorch
|
|
272
180
|
```
|
|
273
181
|
Node.js v18+ or any modern browser with ES module support is recommended.
|
|
274
182
|
|
|
183
|
+
## Git
|
|
184
|
+
```bash
|
|
185
|
+
git clone https://github.com/Rizal-HID11/mini-jstorch-github
|
|
186
|
+
```
|
|
187
|
+
|
|
275
188
|
---
|
|
276
189
|
|
|
277
190
|
# Quick Start (Recommended Loss)
|
|
@@ -411,4 +324,4 @@ MIT License
|
|
|
411
324
|
Copyright (c) 2024
|
|
412
325
|
rizal-editors
|
|
413
326
|
|
|
414
|
-
---
|
|
327
|
+
---
|
package/package.json
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mini-jstorch",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A lightweight JavaScript neural network library for learning AI concepts and rapid Frontend experimentation. PyTorch-inspired, zero dependencies, perfect for educational use.",
|
|
6
6
|
"main": "index.js",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/Rizal-HID11/mini-jstorch-github.git"
|
|
10
|
+
},
|
|
7
11
|
"keywords": [
|
|
8
12
|
"lightweight-ml",
|
|
9
13
|
"javascript-torch",
|