Built and signed on GitHub ActionsBuilt and signed on GitHub Actions
Built and signed on GitHub Actions
latest
sauber/deno-neuronsWorks with
•JSR Score100%•This package works with DenoIt is unknown whether this package works with Cloudflare Workers, Node.js, Bun, Browsers




Downloads1/wk
•Published2 months ago (1.2.7)
Pure-deno implementation of neural network inspired by Micrograd.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156import { avg, std } from "jsr:@sauber/statistics@^0.3.1"; import { Value } from "./value.ts"; import { Node } from "./node.ts"; import { Neuron, Normalizer } from "./neuron.ts"; import type { NeuronData, NormalizerData } from "./neuron.ts"; import type { Inputs } from "./train.ts"; /** An exported layer of NeuronData */ export type DenseData = Array<NeuronData>; /** An exported layer of NormalizerData */ export type DeviationData = Array<NormalizerData>; type Offset = { offset: number; factor: number; }; /** Connect one input to one output */ export class Simple extends Node { constructor( public readonly inputs: number, private readonly neurons: Array<Neuron> = Array.from( Array(inputs), (_) => new Neuron(1), ), ) { super(); } public static import(data: DenseData): Simple { const neurons = data.map((data) => Neuron.import(data)); return new Simple(neurons.length, neurons); } public override get export(): DenseData { return this.neurons.map((n) => n.export); } public forward(x: Value[]): Value[] { return this.neurons.map((n, i) => n.forward([x[i]])); } public override get parameters(): Value[] { const params: Value[] = []; for (const neuron of this.neurons) params.push(...neuron.parameters); return params; } } /** All nodes in input layer connected to all nodes in output layer */ export class Dense extends Node { constructor( public readonly inputs: number, public readonly outputs: number, private readonly neurons: Array<Neuron> = Array.from( Array(outputs), (_) => new Neuron(inputs), ), ) { super(); } public static import(data: DenseData): Dense { const neurons = data.map((data) => Neuron.import(data)); const inputs = neurons[0]?.inputs || 0; const outputs = neurons.length; return new Dense(inputs, outputs, neurons); } public override get export(): DenseData { return this.neurons.map((n) => n.export); } public forward(x: Value[]): Value[] { return this.neurons.map((n) => n.forward(x)); } public override get parameters(): Value[] { const params: Value[] = []; for (const neuron of this.neurons) params.push(...neuron.parameters); return params; } } /** Relu Activation Layer */ export class Relu extends Node { public forward(x: Value[]): Value[] { return x.map((n) => n.relu()); } } /** Leaky Relu Activation Layer */ export class LRelu extends Node { public forward(x: Value[]): Value[] { return x.map((n) => n.lrelu()); } } /** Sigmoid Activation Layer */ export class Sigmoid extends Node { public forward(x: Value[]): Value[] { return x.map((n) => n.sigmoid()); } } /** Tanh Activation Layer */ export class Tanh extends Node { public forward(x: Value[]): Value[] { return x.map((n) => n.tanh()); } } /** Shift and scale inputs into a distribution centered around 0 with standard deviation 1 */ export class Normalize extends Node { constructor( public readonly inputs: number, private readonly scalers: Array<Normalizer> = Array.from( Array(inputs), (_) => new Normalizer(), ), ) { super(); } public forward(x: Value[]): Value[] { return this.scalers.map((scaler, index) => scaler.forward(x[index])); } /** Calculate means and variance of input, and set offset and factor accordingly */ public override adapt(inputs: Inputs): void { inputs[0].forEach((_, index) => { const col: number[] = inputs.map((r) => r[index]); const mean: number = avg(col); const variance: number = std(col); // console.log({ mean, variance }); this.scalers[index] = new Normalizer( new Value(mean), new Value(variance), ); }); } /** Export layer of normalizers */ public override get export(): DeviationData { return this.scalers.map((s) => s.export); } /** Generate layer of normalizers from expected mean and variance of input columns */ public static import(data: DeviationData): Normalize { return new Normalize( data.length, data.map((n) => new Normalizer(new Value(n.mean), new Value(n.variance))), ); } }