mini-jstorch 1.2.0 → 1.2.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 +8 -124
- package/package.json +1 -1
- package/{engine → src}/Dummy/msg +1 -1
- package/src/MainEngine.js +1 -0
- package/src/startup.cpu +12 -0
- package/CHANGELOG.md +0 -32
- package/engine/MainEngine.js +0 -209
- package/engine/startup.cpu +0 -8
package/README.md
CHANGED
|
@@ -1,133 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
## SORRY GUYS FOR THE DISTURB BECAUSE VERSION 1.1.9 I FORGOT PLACE THE FULL SYSTEM FOR THE UPDATE NOT PLACED ON MAINENGINE BUT AT EXPERIMENTS FILES
|
|
4
|
-
|
|
5
|
-
# IMPORTANT!
|
|
6
|
-
|
|
7
|
-
This Module will not gonna Run *Well* In at GPU or a Backend.
|
|
8
|
-
We're will gonna *Optimize* So all User can still use this Module.
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
**Mini JSTorch** is a lightweight, high-performance JavaScript library designed for rapid prototyping of neural networks directly in the frontend environment and for low-end devices. Its core purpose is to enable experimentation and learning on devices with limited computing resources, without compromising stability or training reliability.
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
## Vision
|
|
17
|
-
|
|
18
|
-
Our vision is to democratize AI experimentation by providing a tool that is:
|
|
19
|
-
|
|
20
|
-
- **Accessible**: Runs efficiently on *low-end* laptops or mobile devices.
|
|
21
|
-
- **Stable**: Handles gradient calculations and NaN values robustly.
|
|
22
|
-
- **Educational**: Clear abstractions for neural network layers, activations, and optimizers.
|
|
23
|
-
- **Fast**: Immediate output without lengthy training delays.
|
|
24
|
-
|
|
25
|
-
*Mini JSTorch* aims to bridge the gap between conceptual AI learning and hands-on experimentation, making it possible to explore neural network behavior interactively, even on minimal hardware.
|
|
1
|
+
# MINI JSTORCH #
|
|
26
2
|
|
|
27
3
|
---
|
|
28
4
|
|
|
29
|
-
## Features
|
|
30
5
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- **Activations**
|
|
34
|
-
- `ReLU`: Rectified Linear Unit activation.
|
|
35
|
-
- `Sigmoid`: Sigmoid activation function.
|
|
36
|
-
- **Loss Functions**
|
|
37
|
-
- `CrossEntropyLoss`: Combines softmax and cross-entropy for classification tasks.
|
|
38
|
-
- **Optimizers**
|
|
39
|
-
- `Adam`: Adaptive optimizer for stable and efficient training.
|
|
40
|
-
- **Utilities**
|
|
41
|
-
- `zeros(rows, cols)`: Generate a zero matrix.
|
|
42
|
-
- `randomMatrix(rows, cols, scale)`: Random initialization for weights.
|
|
43
|
-
- `softmax(x)`: Compute softmax probabilities.
|
|
44
|
-
- `crossEntropy(pred, target)`: Compute cross-entropy loss.
|
|
45
|
-
- `dot(a, b)`: Matrix multiplication.
|
|
46
|
-
- `addMatrices(a, b)`: Element-wise addition of matrices.
|
|
47
|
-
- **Model Container**
|
|
48
|
-
- `Sequential`: Container to stack layers sequentially with easy forward and backward passes.
|
|
6
|
+
**Just Empty.. this versions only an note do not use it for your projects models.**
|
|
7
|
+
**I ONLY WANNA GIVE A MESSAGES IF THE MAJOR UPDATE WOULD BE COMING AT TIME 2:22 AM JUST BE READY FOR IT GUYS!**
|
|
49
8
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
## Installation
|
|
9
|
+
# HUGE THANKS 🎉 #
|
|
53
10
|
|
|
54
|
-
|
|
55
|
-
npm install mini-jstorch
|
|
56
|
-
# Node.js v20+ recommended for a good experience while using module
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
---
|
|
11
|
+
I genuinely appreciate everyone who has taken the time to install and try out this module. Every download isn’t just a number it’s a real person spending their time to explore, learn, or build something with this module!
|
|
60
12
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
```javascript
|
|
64
|
-
import { Sequential, Linear, ReLU, Sigmoid, CrossEntropy, Adam } from './engine/MainEngine.js'; // use import to import the modules
|
|
65
|
-
|
|
66
|
-
// Construct a model with two hidden layers
|
|
67
|
-
const model = new Sequential([
|
|
68
|
-
new Linear(2, 4),
|
|
69
|
-
new ReLU(),
|
|
70
|
-
new Linear(4, 4),
|
|
71
|
-
new ReLU(),
|
|
72
|
-
new Linear(4, 2),
|
|
73
|
-
new Sigmoid()
|
|
74
|
-
]);
|
|
75
|
-
|
|
76
|
-
// Training data (XOR)
|
|
77
|
-
const inputs = [
|
|
78
|
-
[0,0], [0,1], [1,0], [1,1]
|
|
79
|
-
];
|
|
80
|
-
const targets = [
|
|
81
|
-
[1,0], [0,1], [0,1], [1,0]
|
|
82
|
-
];
|
|
83
|
-
|
|
84
|
-
// Optimizer and loss
|
|
85
|
-
const optimizer = new Adam(model.parameters(), 0.01);
|
|
86
|
-
const lossFunc = CrossEntropy;
|
|
87
|
-
|
|
88
|
-
// Training loop
|
|
89
|
-
for(let epoch = 1; epoch <= 5000; epoch++) {
|
|
90
|
-
let totalLoss = 0;
|
|
91
|
-
for(let i = 0; i < inputs.length; i++) {
|
|
92
|
-
const output = model.forward([inputs[i]]);
|
|
93
|
-
const loss = lossFunc(output, [targets[i]]);
|
|
94
|
-
totalLoss += loss;
|
|
95
|
-
model.zeroGrad();
|
|
96
|
-
model.backward(lossFunc.backward());
|
|
97
|
-
optimizer.step();
|
|
98
|
-
}
|
|
99
|
-
if(epoch % 500 === 0) console.log(`Epoch ${epoch}, Loss: ${totalLoss.toFixed(6)}`);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Predictions
|
|
103
|
-
inputs.forEach(inp => {
|
|
104
|
-
const pred = model.forward([inp]);
|
|
105
|
-
console.log(`${inp} -> ${pred.map(p => p.toFixed(4))}`);
|
|
106
|
-
});
|
|
107
|
-
```
|
|
108
|
-
---
|
|
109
|
-
|
|
110
|
-
## Intended Use Cases
|
|
111
|
-
|
|
112
|
-
- **Experimentation on low-end devices or mobile browsers.**
|
|
113
|
-
- **Learning and teaching foundational neural network concepts.**
|
|
114
|
-
- **Testing small to medium feedforward models in real-time.**
|
|
115
|
-
- **Quick prototyping without GPU dependency or complex setup.**
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## Roadmap
|
|
120
|
-
|
|
121
|
-
- **Browser-based interactive playground.**
|
|
122
|
-
- **Additional activation functions and loss options.**
|
|
123
|
-
- **Visualization of training metrics and loss curves in real-time.**
|
|
124
|
-
- **Support for small convolutional networks in frontend environments.**
|
|
125
|
-
|
|
126
|
-
---
|
|
13
|
+
Reaching 400+ weekly downloads might sound small compared to giant frameworks, but for me it’s huge. It means this project is actually helping people out there, and that alone makes every late-night coding session worth it.
|
|
127
14
|
|
|
128
|
-
|
|
15
|
+
Thank you for giving this module a chance. Your support and trust are what keep this project moving forward! 🚀
|
|
129
16
|
|
|
130
|
-
|
|
131
|
-
- **The `Dummy` folder contains modules used for development, testing, and debugging before integration into the main engine.**
|
|
132
|
-
- **This module was created by a `single` developer.**
|
|
133
|
-
- **Date 23 Would be `CRAZY`.**
|
|
17
|
+
# BE READY FOR IT... SET YOUR TIME CLOCK. #
|
package/package.json
CHANGED
package/{engine → src}/Dummy/msg
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
**File Unavailable**
|
|
2
|
-
|
|
2
|
+
file inside this folder has been restricted by the developer.
|
|
3
3
|
|
|
4
4
|
It is intended solely for experimental purposes in future versions, including optimizations and bug fixes before full integration into the Main Engine.
|
|
5
5
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log("MAJOR UPDATE IN 2:22 AM BE READY GUYS! this was empty because this versions only for an major note.")
|
package/src/startup.cpu
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// you can delete this files this files are not important for the engine runtime.
|
|
2
|
+
|
|
3
|
+
e=run=[cpu[runtime]]
|
|
4
|
+
e.set.runtime('beta')
|
|
5
|
+
e.rnt()
|
|
6
|
+
e.set()
|
|
7
|
+
e.register('vanilla',expe='Experiments.js',main='MainEngine.js')
|
|
8
|
+
l=e.prog('asm')
|
|
9
|
+
r=l.gv=[0xCAFEBABE]
|
|
10
|
+
eng=e.load(register,r,'vanilla')
|
|
11
|
+
eng.boot(e,r,'dp')
|
|
12
|
+
eng.load()
|
package/CHANGELOG.md
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
## Changelog ##
|
|
2
|
-
|
|
3
|
-
**Official Release:** 2025-Monday-August-18
|
|
4
|
-
**Version:** 1.1.9
|
|
5
|
-
|
|
6
|
-
New Files that will All notable changes to *Mini-JSTorch* will be documented in this file.
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## [1.1.9] - 2025-Monday-August-18
|
|
11
|
-
|
|
12
|
-
### Added
|
|
13
|
-
- Complete overhaul of core engine for stability and full feature support.
|
|
14
|
-
- Adam optimizer fully integrated with batch gradient handling.
|
|
15
|
-
- NaN-safe operations for forward/backward passes and loss calculations.
|
|
16
|
-
- Sequential container with robust parameter tracking.
|
|
17
|
-
- Utility functions enhanced for numeric safety and matrix operations.
|
|
18
|
-
- Ready-to-use example scripts with multiple hidden layers for frontend experimentation.
|
|
19
|
-
- Full handling for lightweight devices, optimized for speed and low memory usage.
|
|
20
|
-
|
|
21
|
-
### Fixed
|
|
22
|
-
- bugs in ReLU and gradient propagation causing NaN loss values.
|
|
23
|
-
- Backward propagation errors for batch matrices corrected.
|
|
24
|
-
- Critical Error while startup Engine.
|
|
25
|
-
|
|
26
|
-
### Changed
|
|
27
|
-
- Layer and activation API standardized for consistency.
|
|
28
|
-
- CrossEntropyLoss now safely handles edge cases in probability computations.
|
|
29
|
-
- Improvements systems for make experiences more stable and not heavy.
|
|
30
|
-
- Minor numeric stability improvements.
|
|
31
|
-
|
|
32
|
-
---
|
package/engine/MainEngine.js
DELETED
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
// MAINENGINE FILES [PACK IN AT ONE FILES]
|
|
3
|
-
// CURRENT VERSIONS: 0.0.4
|
|
4
|
-
// AUTHOR: Rizal
|
|
5
|
-
// LICENSE: MIT(R)
|
|
6
|
-
|
|
7
|
-
// Utils
|
|
8
|
-
export function zeros(rows, cols) {
|
|
9
|
-
return Array.from({length: rows}, () => Array(cols).fill(0));
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function randomMatrix(rows, cols, scale=0.1) {
|
|
13
|
-
return Array.from({length: rows}, () =>
|
|
14
|
-
Array.from({length: cols}, () => (Math.random()*2-1)*scale)
|
|
15
|
-
);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function softmax(x) {
|
|
19
|
-
const maxVal = Math.max(...x);
|
|
20
|
-
const exps = x.map(v => Math.exp(v - maxVal));
|
|
21
|
-
const sumExps = exps.reduce((a,b)=>a+b, 0);
|
|
22
|
-
return exps.map(v => v / sumExps);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function crossEntropy(pred, target) {
|
|
26
|
-
const eps = 1e-12;
|
|
27
|
-
return -target.reduce((sum, t, i) => sum + t * Math.log(pred[i] + eps), 0);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function addMatrices(a, b) {
|
|
31
|
-
return a.map((row, i) =>
|
|
32
|
-
row.map((v, j) => v + (b[i] && b[i][j] !== undefined ? b[i][j] : 0))
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function dot(a, b) {
|
|
37
|
-
const result = zeros(a.length, b[0].length);
|
|
38
|
-
for (let i=0;i<a.length;i++) {
|
|
39
|
-
for (let j=0;j<b[0].length;j++) {
|
|
40
|
-
let sum=0;
|
|
41
|
-
for (let k=0;k<a[0].length;k++) sum += a[i][k]*b[k][j];
|
|
42
|
-
result[i][j]=sum;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return result;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Layers
|
|
49
|
-
export class Linear {
|
|
50
|
-
constructor(inputDim, outputDim) {
|
|
51
|
-
this.W = randomMatrix(inputDim, outputDim);
|
|
52
|
-
this.b = Array(outputDim).fill(0);
|
|
53
|
-
this.gradW = zeros(inputDim, outputDim);
|
|
54
|
-
this.gradb = Array(outputDim).fill(0);
|
|
55
|
-
this.x = null;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
forward(x) {
|
|
59
|
-
this.x = x;
|
|
60
|
-
const out = dot(x, this.W);
|
|
61
|
-
return out.map((row,i) => row.map((v,j)=>v+this.b[j]));
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
backward(grad) {
|
|
65
|
-
// grad shape: batch x outputDim
|
|
66
|
-
for (let i=0;i<this.W.length;i++)
|
|
67
|
-
for (let j=0;j<this.W[0].length;j++)
|
|
68
|
-
this.gradW[i][j] = this.x.reduce((sum,row,k)=>sum+row[i]*grad[k][j],0);
|
|
69
|
-
|
|
70
|
-
for (let j=0;j<this.b.length;j++)
|
|
71
|
-
this.gradb[j] = grad.reduce((sum,row)=>sum+row[j],0);
|
|
72
|
-
|
|
73
|
-
// propagate to input
|
|
74
|
-
const gradInput = zeros(this.x.length, this.W.length);
|
|
75
|
-
for (let i=0;i<this.x.length;i++)
|
|
76
|
-
for (let j=0;j<this.W.length;j++)
|
|
77
|
-
for (let k=0;k<this.W[0].length;k++)
|
|
78
|
-
gradInput[i][j]+=grad[i][k]*this.W[j][k];
|
|
79
|
-
return gradInput;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
parameters() {
|
|
83
|
-
return [
|
|
84
|
-
{param: this.W, grad: this.gradW},
|
|
85
|
-
{param: [this.b], grad: [this.gradb]} // wrap b in array for consistency
|
|
86
|
-
];
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Activations
|
|
91
|
-
export class ReLU {
|
|
92
|
-
constructor() { this.out=null; }
|
|
93
|
-
forward(x) {
|
|
94
|
-
this.out = Array.isArray(x[0]) ? x.map(r=>r.map(v=>Math.max(0,v))) : x.map(v=>Math.max(0,v));
|
|
95
|
-
return this.out;
|
|
96
|
-
}
|
|
97
|
-
backward(grad) {
|
|
98
|
-
return Array.isArray(grad[0])
|
|
99
|
-
? grad.map((r,i)=>r.map((v,j)=>v*(this.out[i][j]>0?1:0)))
|
|
100
|
-
: grad.map((v,i)=>v*(this.out[i]>0?1:0));
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export class Sigmoid {
|
|
105
|
-
constructor() { this.out=null; }
|
|
106
|
-
forward(x) {
|
|
107
|
-
const sigmoidFn = v=>1/(1+Math.exp(-v));
|
|
108
|
-
this.out = Array.isArray(x[0]) ? x.map(r=>r.map(sigmoidFn)) : x.map(sigmoidFn);
|
|
109
|
-
return this.out;
|
|
110
|
-
}
|
|
111
|
-
backward(grad) {
|
|
112
|
-
return Array.isArray(grad[0])
|
|
113
|
-
? grad.map((r,i)=>r.map((v,j)=>v*this.out[i][j]*(1-this.out[i][j])))
|
|
114
|
-
: grad.map((v,i)=>v*this.out[i]*(1-this.out[i]));
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Loss wrapper
|
|
119
|
-
export class CrossEntropyLoss {
|
|
120
|
-
forward(pred, target) {
|
|
121
|
-
// pred: batch x classes, target: batch x classes
|
|
122
|
-
const losses = pred.map((p,i)=>crossEntropy(softmax(p), target[i]));
|
|
123
|
-
this.pred = pred;
|
|
124
|
-
this.target = target;
|
|
125
|
-
return losses.reduce((a,b)=>a+b,0)/pred.length;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
backward() {
|
|
129
|
-
// gradient of softmax + CE
|
|
130
|
-
const grad = [];
|
|
131
|
-
for (let i=0;i<this.pred.length;i++) {
|
|
132
|
-
const s = softmax(this.pred[i]);
|
|
133
|
-
grad.push(s.map((v,j)=>v-this.target[i][j]));
|
|
134
|
-
}
|
|
135
|
-
return grad.map(r=>r.map(v=>v/this.pred.length));
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Optimizer: Adam
|
|
140
|
-
export class Adam {
|
|
141
|
-
constructor(params, lr=0.001, beta1=0.9, beta2=0.999, eps=1e-8) {
|
|
142
|
-
this.params = params;
|
|
143
|
-
this.lr = lr;
|
|
144
|
-
this.beta1 = beta1;
|
|
145
|
-
this.beta2 = beta2;
|
|
146
|
-
this.eps = eps;
|
|
147
|
-
this.m = params.map(p=>zeros(p.param.length, p.param[0].length || 1));
|
|
148
|
-
this.v = params.map(p=>zeros(p.param.length, p.param[0].length || 1));
|
|
149
|
-
this.t=0;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
step() {
|
|
153
|
-
this.t++;
|
|
154
|
-
this.params.forEach((p,idx)=>{
|
|
155
|
-
for (let i=0;i<p.param.length;i++){
|
|
156
|
-
for (let j=0;j<(p.param[0].length||1);j++){
|
|
157
|
-
const g = p.grad[i][j];
|
|
158
|
-
this.m[idx][i][j] = this.beta1*this.m[idx][i][j] + (1-this.beta1)*g;
|
|
159
|
-
this.v[idx][i][j] = this.beta2*this.v[idx][i][j] + (1-this.beta2)*g*g;
|
|
160
|
-
const mHat = this.m[idx][i][j]/(1-Math.pow(this.beta1,this.t));
|
|
161
|
-
const vHat = this.v[idx][i][j]/(1-Math.pow(this.beta2,this.t));
|
|
162
|
-
p.param[i][j]-= this.lr*mHat/(Math.sqrt(vHat)+this.eps);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Sequential container
|
|
170
|
-
export class Sequential {
|
|
171
|
-
constructor(layers=[]) { this.layers=layers; }
|
|
172
|
-
forward(x) {
|
|
173
|
-
return this.layers.reduce((input, layer)=>layer.forward(input), x);
|
|
174
|
-
}
|
|
175
|
-
backward(grad) {
|
|
176
|
-
return this.layers.reduceRight((g,layer)=>layer.backward(g), grad);
|
|
177
|
-
}
|
|
178
|
-
parameters() {
|
|
179
|
-
return this.layers.flatMap(l=>l.parameters ? l.parameters() : []);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Tambahin ke akhir file utama mini-jstorch
|
|
184
|
-
export function saveModel(model) {
|
|
185
|
-
if (!(model instanceof Sequential)) {
|
|
186
|
-
throw new Error("saveModel only supports Sequential models");
|
|
187
|
-
}
|
|
188
|
-
const weights = model.layers.map(layer => ({
|
|
189
|
-
weights: layer.W ? layer.W : null,
|
|
190
|
-
biases: layer.b ? layer.b : null
|
|
191
|
-
}));
|
|
192
|
-
return JSON.stringify(weights);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
export function loadModel(model, json) {
|
|
196
|
-
if (!(model instanceof Sequential)) {
|
|
197
|
-
throw new Error("loadModel only supports Sequential models");
|
|
198
|
-
}
|
|
199
|
-
const weights = JSON.parse(json);
|
|
200
|
-
model.layers.forEach((layer, i) => {
|
|
201
|
-
if (layer.W && weights[i].weights) {
|
|
202
|
-
layer.W = weights[i].weights;
|
|
203
|
-
}
|
|
204
|
-
if (layer.b && weights[i].biases) {
|
|
205
|
-
layer.b = weights[i].biases;
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
|