@dniskav/neuron 0.1.1 → 0.1.3
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 +46 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +10 -3
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# @dniskav/neuron
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@dniskav/neuron)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
|
|
3
6
|
A minimal, dependency-free neural network library built from scratch in TypeScript. Designed for learning and experimentation — every line of math is readable.
|
|
4
7
|
|
|
5
8
|
## What's inside
|
|
@@ -11,6 +14,8 @@ A minimal, dependency-free neural network library built from scratch in TypeScri
|
|
|
11
14
|
| `Layer` | A group of `NeuronN` neurons that share the same inputs. |
|
|
12
15
|
| `Network` | Two-layer network (hidden + output) with backpropagation. |
|
|
13
16
|
| `NetworkN` | Deep network of arbitrary depth. Define your architecture as `[inputs, ...hidden, outputs]`. |
|
|
17
|
+
| `LSTMLayer` | Recurrent layer with persistent hidden and cell state. Learns sequences via BPTT. |
|
|
18
|
+
| `NetworkLSTM` | Wraps an `LSTMLayer` + dense layers. Maintains memory across steps within an episode. |
|
|
14
19
|
|
|
15
20
|
## Install
|
|
16
21
|
|
|
@@ -95,6 +100,47 @@ const [out1, out2] = net.predict([0.5, 0.3, 0.8]);
|
|
|
95
100
|
net.trainWithDeltas(inputs, [0.4, -0.2], 0.05);
|
|
96
101
|
```
|
|
97
102
|
|
|
103
|
+
### NetworkLSTM — recurrent network with memory
|
|
104
|
+
|
|
105
|
+
`NetworkLSTM` adds within-episode memory: the network can remember what happened in previous steps of the same sequence.
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { NetworkLSTM } from "@dniskav/neuron";
|
|
109
|
+
|
|
110
|
+
// 1 input → LSTM(8 hidden) → Dense(4) → 1 output
|
|
111
|
+
const net = new NetworkLSTM(1, 8, [4, 1]);
|
|
112
|
+
|
|
113
|
+
// Task: predict 1 if we're past step 3 in the episode, else 0
|
|
114
|
+
// A feedforward net can't do this — it has no memory of step count.
|
|
115
|
+
|
|
116
|
+
for (let epoch = 0; epoch < 300; epoch++) {
|
|
117
|
+
net.resetState(); // clear memory at episode start
|
|
118
|
+
|
|
119
|
+
const targets: number[][] = [];
|
|
120
|
+
for (let step = 0; step < 6; step++) {
|
|
121
|
+
net.predict([1]); // same input every step
|
|
122
|
+
targets.push([step >= 3 ? 1 : 0]);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
net.train(targets, 0.05); // BPTT across the full episode
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Run a fresh episode and check predictions
|
|
129
|
+
net.resetState();
|
|
130
|
+
for (let step = 0; step < 6; step++) {
|
|
131
|
+
const [out] = net.predict([1]);
|
|
132
|
+
console.log(`step ${step}: ${out.toFixed(2)} (expected: ${step >= 3 ? 1 : 0})`);
|
|
133
|
+
}
|
|
134
|
+
// step 0: 0.07 (expected: 0)
|
|
135
|
+
// step 1: 0.11 (expected: 0)
|
|
136
|
+
// step 2: 0.18 (expected: 0)
|
|
137
|
+
// step 3: 0.81 (expected: 1)
|
|
138
|
+
// step 4: 0.89 (expected: 1)
|
|
139
|
+
// step 5: 0.93 (expected: 1)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The network learns to count steps using its hidden state — no external counter needed.
|
|
143
|
+
|
|
98
144
|
## How it works
|
|
99
145
|
|
|
100
146
|
Every class uses **sigmoid** as its activation function and **gradient descent** to update weights:
|
package/dist/index.js
CHANGED
|
@@ -372,7 +372,7 @@ var NetworkLSTM = class {
|
|
|
372
372
|
const grad = denseGrads[l];
|
|
373
373
|
const prevDeltas = layerIn.map((out, j) => {
|
|
374
374
|
const errProp = layer.neurons.reduce((s, n, k) => s + deltas[k] * n.weights[j], 0);
|
|
375
|
-
return errProp * out * (1 - out);
|
|
375
|
+
return l === 0 ? errProp : errProp * out * (1 - out);
|
|
376
376
|
});
|
|
377
377
|
layer.neurons.forEach((n, k) => {
|
|
378
378
|
n.weights.forEach((_, j) => {
|
package/dist/index.mjs
CHANGED
|
@@ -340,7 +340,7 @@ var NetworkLSTM = class {
|
|
|
340
340
|
const grad = denseGrads[l];
|
|
341
341
|
const prevDeltas = layerIn.map((out, j) => {
|
|
342
342
|
const errProp = layer.neurons.reduce((s, n, k) => s + deltas[k] * n.weights[j], 0);
|
|
343
|
-
return errProp * out * (1 - out);
|
|
343
|
+
return l === 0 ? errProp : errProp * out * (1 - out);
|
|
344
344
|
});
|
|
345
345
|
layer.neurons.forEach((n, k) => {
|
|
346
346
|
n.weights.forEach((_, j) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dniskav/neuron",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Minimal neural network from scratch — neuron, layer, network, backpropagation. No dependencies.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -12,12 +12,19 @@
|
|
|
12
12
|
"types": "./dist/index.d.ts"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
|
-
"files": [
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
16
18
|
"scripts": {
|
|
17
19
|
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
18
20
|
"dev": "tsup src/index.ts --format cjs,esm --dts --watch"
|
|
19
21
|
},
|
|
20
|
-
"keywords": [
|
|
22
|
+
"keywords": [
|
|
23
|
+
"neural-network",
|
|
24
|
+
"machine-learning",
|
|
25
|
+
"backpropagation",
|
|
26
|
+
"typescript"
|
|
27
|
+
],
|
|
21
28
|
"author": "dniskav",
|
|
22
29
|
"license": "MIT",
|
|
23
30
|
"devDependencies": {
|