diff --git a/src/Creature.ts b/src/Creature.ts index b96c9e73..7e7d675f 100644 --- a/src/Creature.ts +++ b/src/Creature.ts @@ -29,6 +29,7 @@ import { } from "./architecture/NeuronInterfaces.ts"; import { cacheDataFile, dataFiles } from "./architecture/Training.ts"; import { NeatOptions } from "./config/NeatOptions.ts"; +import { NeatConfig } from "./architecture/Neat.ts"; import { CostInterface } from "./Costs.ts"; import { Activations } from "./methods/activations/Activations.ts"; import { IDENTITY } from "./methods/activations/types/IDENTITY.ts"; @@ -660,7 +661,7 @@ export class Creature implements CreatureInternal { let lastTo = -1; this.synapses.forEach((c, indx) => { stats.connections++; - const toNode = this.getNeuron(c.to); + const toNode = this.neurons[c.to]; if (toNode.type === "input") { throw new Error(indx + ") connection points to an input node"); @@ -767,19 +768,6 @@ export class Creature implements CreatureInternal { return results; } - getNeuron(indx: number): Neuron { - if (Number.isInteger(indx) == false || indx < 0) { - throw new Error("POS should be a non-negative integer was: " + indx); - } - const tmp = this.neurons[indx]; - - if (tmp === undefined) { - throw new Error("getNeuron( " + indx + ") " + (typeof tmp)); - } - - return tmp; - } - getSynapse(from: number, to: number): Synapse | null { if (Number.isInteger(from) == false || from < 0) { throw new Error("FROM should be a non-negative integer was: " + from); @@ -792,8 +780,14 @@ export class Creature implements CreatureInternal { for (let pos = this.synapses.length; pos--;) { const c = this.synapses[pos]; - if (c.from == from && c.to == to) { - return c; + if (c.from == from) { + if (c.to == to) { + return c; + } else if (c.to < to) { + break; + } + } else if (c.from < from) { + break; } } @@ -1029,7 +1023,7 @@ export class Creature implements CreatureInternal { : 0; const workers: WorkerHandler[] = []; - + const config = new NeatConfig(options); const threads = Math.round( Math.max( options.threads ? options.threads : navigator.hardwareConcurrency, @@ -1039,7 +1033,7 @@ export class Creature implements CreatureInternal { for (let i = threads; i--;) { workers.push( - new WorkerHandler(dataSetDir, options.costName ?? "MSE", threads == 1), + new WorkerHandler(dataSetDir, config.costName, threads == 1), ); } diff --git a/src/architecture/Neat.ts b/src/architecture/Neat.ts index 965be53e..44d4c136 100644 --- a/src/architecture/Neat.ts +++ b/src/architecture/Neat.ts @@ -23,7 +23,7 @@ import { Fitness } from "./Fitness.ts"; import { Offspring } from "./Offspring.ts"; import { assert } from "https://deno.land/std@0.220.1/assert/assert.ts"; -class NeatConfig implements NeatOptions { +export class NeatConfig implements NeatOptions { /** List of creatures to start with */ creatures: CreatureInternal[] | CreatureExport[]; diff --git a/src/methods/activations/aggregate/MEAN.ts b/src/methods/activations/aggregate/MEAN.ts index 33cfee57..4a15c2de 100644 --- a/src/methods/activations/aggregate/MEAN.ts +++ b/src/methods/activations/aggregate/MEAN.ts @@ -27,17 +27,11 @@ export class MEAN implements NeuronActivationInterface { const toList = node.creature.inwardConnections(node.index); for (let i = toList.length; i--;) { const c = toList[i]; - const fromActivation = //node.creature.getActivation(c.from); - node.creature.state.activations[c.from]; - const activation = limitActivation(fromActivation); - - sum += activation * c.weight; - if (Number.isFinite(sum) == false) { - throw new Error( - `Node: ${node.uuid} connection: ${ - c.from + ":" + c.to - }, SUM: ${sum} is not finite. From Activation: ${fromActivation}, Activation: ${activation}, Weight: ${c.weight}`, - ); + const fromActivation = node.creature.state.activations[c.from]; + if (fromActivation) { + const activation = limitActivation(fromActivation); + + sum += activation * c.weight; } } diff --git a/src/multithreading/workers/WorkerHandler.ts b/src/multithreading/workers/WorkerHandler.ts index a58df2ae..3b6803ef 100644 --- a/src/multithreading/workers/WorkerHandler.ts +++ b/src/multithreading/workers/WorkerHandler.ts @@ -2,6 +2,7 @@ import { addTag, getTag } from "https://deno.land/x/tags@v1.0.2/mod.ts"; import { Creature } from "../../Creature.ts"; import { TrainOptions } from "../../config/TrainOptions.ts"; import { MockWorker } from "./MockWorker.ts"; +import { assert } from "https://deno.land/std@0.220.1/assert/assert.ts"; export interface RequestData { taskID: number; @@ -73,11 +74,9 @@ export class WorkerHandler { constructor( dataSetDir: string, costName: string, - direct: boolean = false, + direct: boolean, ) { - if (typeof dataSetDir === "undefined") { - throw new Error("dataSet is mandatory"); - } + assert(dataSetDir, "dataSet is mandatory"); const data: RequestData = { taskID: this.taskID++, initialize: { @@ -117,13 +116,8 @@ export class WorkerHandler { private callback(data: ResponseData) { const call = this.callbacks[data.taskID.toString()]; - if (call) { - call(data); - } else { - const msg = "No callback"; - console.warn(this.workerID, msg); - throw new Error(msg); - } + assert(call, "No callback"); + call(data); } private makePromise(data: RequestData) { @@ -202,12 +196,12 @@ export class WorkerHandler { addTag( json, "untrained-error", - getTag(creature, "error") || Number.MAX_SAFE_INTEGER.toString(), + `${getTag(creature, "error")}`, ); addTag( json, "untrained-score", - creature.score?.toString() || Number.MIN_SAFE_INTEGER.toString(), + `${creature.score}`, ); const data: RequestData = { diff --git a/src/multithreading/workers/WorkerProcessor.ts b/src/multithreading/workers/WorkerProcessor.ts index d19a9bf3..6b4b8fce 100644 --- a/src/multithreading/workers/WorkerProcessor.ts +++ b/src/multithreading/workers/WorkerProcessor.ts @@ -3,27 +3,16 @@ import { RequestData, ResponseData } from "./WorkerHandler.ts"; import { CostInterface, Costs } from "../../Costs.ts"; import { Creature } from "../../Creature.ts"; import { trainDir } from "../../architecture/Training.ts"; +import { assert } from "https://deno.land/std@0.220.1/assert/assert.ts"; export class WorkerProcessor { - private costName?: string; private dataSetDir: string | null = null; private cost?: CostInterface; - private workerName: string; - - constructor(workerName?: string) { - if (workerName) { - this.workerName = workerName; - } else { - this.workerName = "main"; - } - } - async process(data: RequestData): Promise { const start = Date.now(); if (data.initialize) { - this.costName = data.initialize.costName; this.cost = Costs.find(data.initialize.costName); this.dataSetDir = data.initialize.dataSetDir; return { @@ -34,7 +23,7 @@ export class WorkerProcessor { }, }; } else if (data.evaluate) { - if (!this.dataSetDir) throw new Error("no data directory"); + assert(this.dataSetDir, "No data dir"); if (!this.cost) throw new Error("no cost"); const network = Creature.fromJSON(JSON.parse(data.evaluate.creature)); @@ -63,7 +52,7 @@ export class WorkerProcessor { /* release some memory*/ data.train.creature = ""; - if (!this.dataSetDir) throw new Error("No data dir"); + assert(this.dataSetDir, "No data dir"); network.validate(); const result = await trainDir( @@ -97,7 +86,6 @@ export class WorkerProcessor { }, }; } else { - console.error(data); throw new Error("unknown message"); } } diff --git a/src/multithreading/workers/deno/worker.ts b/src/multithreading/workers/deno/worker.ts index 6c8df4dc..d758dcc1 100644 --- a/src/multithreading/workers/deno/worker.ts +++ b/src/multithreading/workers/deno/worker.ts @@ -1,7 +1,7 @@ import { RequestData } from "../WorkerHandler.ts"; import { WorkerProcessor } from "../WorkerProcessor.ts"; -const processor = new WorkerProcessor(self.name); +const processor = new WorkerProcessor(); const workerHandler = // deno-lint-ignore ban-types (self as unknown) as { onmessage: Function; postMessage: Function }; diff --git a/test/CRISPR/CRISPR.ts b/test/CRISPR/CRISPR.ts index d9ef61e0..1a59ec60 100644 --- a/test/CRISPR/CRISPR.ts +++ b/test/CRISPR/CRISPR.ts @@ -123,9 +123,7 @@ Deno.test("REMOVE", () => { } const tag = getTag(node, "CRISPR"); - if (tag) { - assert(false, "Should have removed CRISPER"); - } + assert(!tag, "Should have removed CRISPER"); } } diff --git a/test/Clipped.ts b/test/Clipped.ts index 8ad23f89..a6a9c028 100644 --- a/test/Clipped.ts +++ b/test/Clipped.ts @@ -31,10 +31,6 @@ Deno.test("CLIPPED", () => { ); const expected = Math.max(-1, Math.min(1, a)); - if (Math.abs(expected - actual) >= 0.00001) { - const actual3 = network.activateAndTrace(data)[0]; - console.info(actual3); - } assert( Math.abs(expected - actual) < 0.00001, p + ") Expected: " + expected + ", actual: " + actual + ", data: " + data, diff --git a/test/Compact/Compact.ts b/test/Compact/Compact.ts index 613ce3d1..ea14d015 100644 --- a/test/Compact/Compact.ts +++ b/test/Compact/Compact.ts @@ -48,11 +48,8 @@ Deno.test("removeDanglingHidden", () => { const a = Creature.fromJSON(json); const b = a.compact(); - if (b) { - b.validate(); - } else { - fail("Should have compacted"); - } + assert(b, "should have compacted the network"); + b.validate(); }); Deno.test("CompactSimple", () => { @@ -81,27 +78,26 @@ Deno.test("CompactSimple", () => { Deno.writeTextFileSync(".a.json", JSON.stringify(a.internalJSON(), null, 2)); const b = a.compact(); - if (!b) { - assert(false, "should have compacted the network"); - } else { - b.validate(); - Deno.writeTextFileSync( - ".b.json", - JSON.stringify(b.internalJSON(), null, 2), - ); - const endNodes = b.neurons.length; - const endConnections = b.synapses.length; - const endOut = b.activate(input); + assert(b, "should have compacted the network"); - assertAlmostEquals(startOut[0], endOut[0], 0.001); - assertAlmostEquals(startOut[1], endOut[1], 0.001); - assert(endNodes < startNodes); - assert(endConnections < startConnections); + b.validate(); + Deno.writeTextFileSync( + ".b.json", + JSON.stringify(b.internalJSON(), null, 2), + ); + const endNodes = b.neurons.length; + const endConnections = b.synapses.length; - const c = b.compact(); - assert(!c); - } + const endOut = b.activate(input); + + assertAlmostEquals(startOut[0], endOut[0], 0.001); + assertAlmostEquals(startOut[1], endOut[1], 0.001); + assert(endNodes < startNodes); + assert(endConnections < startConnections); + + const c = b.compact(); + assert(!c); }); Deno.test("RandomizeCompact", () => { @@ -228,24 +224,23 @@ Deno.test("CompactSelf", () => { assertAlmostEquals(aOut[0], aOut2[0], 0.001); const b = a.compact(); - if (!b) { - assert(false, "should have compacted the network"); - } else { - b.validate(); - Deno.writeTextFileSync( - ".b.json", - JSON.stringify(b.internalJSON(), null, 2), - ); - const endNodes = b.neurons.length; - const endConnections = b.synapses.length; - const endOut = b.activate(input); + assert(b, "should have compacted the network"); - assertAlmostEquals(aOut[0], endOut[0], 0.001); - assert(endNodes < startNodes); - assert(endConnections < startConnections); + b.validate(); + Deno.writeTextFileSync( + ".b.json", + JSON.stringify(b.internalJSON(), null, 2), + ); + const endNodes = b.neurons.length; + const endConnections = b.synapses.length; - const c = b.compact(); - assert(!c); - } + const endOut = b.activate(input); + + assertAlmostEquals(aOut[0], endOut[0], 0.001); + assert(endNodes < startNodes); + assert(endConnections < startConnections); + + const c = b.compact(); + assert(!c); }); diff --git a/test/ELU.ts b/test/ELU.ts index fae630d0..c78d0aae 100644 --- a/test/ELU.ts +++ b/test/ELU.ts @@ -32,10 +32,6 @@ Deno.test("ELU", () => { ); const expected = activation.squash(a); - if (Math.abs(expected - actual) >= 0.00001) { - const actual3 = network.activateAndTrace(data)[0]; - console.info(actual3); - } assert( Math.abs(expected - actual) < 0.00001, p + ") Expected: " + expected + ", actual: " + actual + ", data: " + data, diff --git a/test/Hypot.ts b/test/Hypot.ts index 14fb570c..54975ae2 100644 --- a/test/Hypot.ts +++ b/test/Hypot.ts @@ -38,10 +38,6 @@ Deno.test("Hypot", () => { ); const expected = Math.hypot(a, b, c); - if (Math.abs(expected - actual) >= 0.00001) { - const actual3 = network.activateAndTrace(data)[0]; - console.info(actual3); - } assert( Math.abs(expected - actual) < 0.00001, p + ") Expected: " + expected + ", actual: " + actual + ", data: " + data, diff --git a/test/LeakyReLU.ts b/test/LeakyReLU.ts index 4f7a932d..5ac4d68c 100644 --- a/test/LeakyReLU.ts +++ b/test/LeakyReLU.ts @@ -31,10 +31,6 @@ Deno.test("Leaky ReLU:", () => { ); const expected = a > 0 ? a : a * 0.01; - if (Math.abs(expected - actual) >= 0.00001) { - const actual3 = network.activateAndTrace(data)[0]; - console.info(actual3); - } assert( Math.abs(expected - actual) < 0.00001, p + ") Expected: " + expected + ", actual: " + actual + ", data: " + data, diff --git a/test/Maximum.ts b/test/Maximum.ts index 0b64782c..90dc6f2c 100644 --- a/test/Maximum.ts +++ b/test/Maximum.ts @@ -37,10 +37,6 @@ Deno.test("Maximum", () => { ); const expected = Math.max(a, b, c); - if (Math.abs(expected - actual) >= 0.00001) { - const actual3 = network.activateAndTrace(data)[0]; - console.info(actual3); - } assert( Math.abs(expected - actual) < 0.00001, p + ") Expected: " + expected + ", actual: " + actual + ", data: " + data, diff --git a/test/Mean.ts b/test/Mean.ts index d210ad50..ab3a0796 100644 --- a/test/Mean.ts +++ b/test/Mean.ts @@ -38,10 +38,6 @@ Deno.test("Mean", () => { ); const expected = (a + b + c) / 3; - if (Math.abs(expected - actual) >= 0.00001) { - const actual3 = network.activateAndTrace(data)[0]; - console.info(actual3); - } assert( Math.abs(expected - actual) < 0.00001, p + ") Expected: " + expected + ", actual: " + actual + ", data: " + data, diff --git a/test/Minimum.ts b/test/Minimum.ts index 368965ff..4f8b5b4a 100644 --- a/test/Minimum.ts +++ b/test/Minimum.ts @@ -37,10 +37,6 @@ Deno.test("Minimum", () => { ); const expected = Math.min(a, b, c); - if (Math.abs(expected - actual) >= 0.00001) { - const actual3 = network.activateAndTrace(data)[0]; - console.info(actual3); - } assert( Math.abs(expected - actual) < 0.00001, p + ") Expected: " + expected + ", actual: " + actual + ", data: " + data, diff --git a/test/Mish.ts b/test/Mish.ts index c0926679..aa028b09 100644 --- a/test/Mish.ts +++ b/test/Mish.ts @@ -32,10 +32,6 @@ Deno.test("Mish", () => { ); const expected = activation.squash(a); - if (Math.abs(expected - actual) >= 0.00001) { - const actual3 = network.activateAndTrace(data)[0]; - console.info(actual3); - } assert( Math.abs(expected - actual) < 0.00001, p + ") Expected: " + expected + ", actual: " + actual + ", data: " + data, diff --git a/test/Softplus.ts b/test/Softplus.ts index aee2f10e..1061824f 100644 --- a/test/Softplus.ts +++ b/test/Softplus.ts @@ -32,10 +32,6 @@ Deno.test("Softplus", () => { ); const expected = activation.squash(a); - if (Math.abs(expected - actual) >= 0.00001) { - const actual3 = network.activateAndTrace(data)[0]; - console.info(actual3); - } assert( Math.abs(expected - actual) < 0.00001, p + ") Expected: " + expected + ", actual: " + actual + ", data: " + data, diff --git a/test/Swish.ts b/test/Swish.ts index b5270fa4..8ff29410 100644 --- a/test/Swish.ts +++ b/test/Swish.ts @@ -32,10 +32,6 @@ Deno.test("Swish", () => { ); const expected = activation.squash(a); - if (Math.abs(expected - actual) >= 0.00001) { - const actual3 = network.activateAndTrace(data)[0]; - console.info(actual3); - } assert( Math.abs(expected - actual) < 0.00001, p + ") Expected: " + expected + ", actual: " + actual + ", data: " + data, diff --git a/test/TraceNeuron.ts b/test/TraceNeuron.ts index 3dfdd58b..2c63c98d 100644 --- a/test/TraceNeuron.ts +++ b/test/TraceNeuron.ts @@ -59,9 +59,6 @@ Deno.test("traceNode", async () => { }; await network.evolveDataSet(ts, options); - // let errorResponsibilityCount = 0; - // let errorProjectedCount = 0; - // let batchSizeCount = 0; let totalValueCount = 0; for (const dirEntry of Deno.readDirSync(traceDir)) { @@ -72,27 +69,6 @@ Deno.test("traceNode", async () => { if (!json.neurons) continue; json.neurons.forEach((n: NeuronTrace) => { if (n.trace) { - // if ( - // Number.isFinite(n.trace.errorResponsibility) && - // n.trace.errorResponsibility != 0 - // ) { - // errorResponsibilityCount++; - // } - - // if ( - // Number.isFinite(n.trace.errorProjected) && - // n.trace.errorProjected != 0 - // ) { - // errorProjectedCount++; - // } - - // if ( - // Number.isFinite(n.trace.batchSize) && - // n.trace.batchSize != 0 - // ) { - // batchSizeCount++; - // } - if ( Number.isFinite(n.trace.totalValue) && n.trace.totalValue != 0 @@ -103,15 +79,6 @@ Deno.test("traceNode", async () => { }); } } - // assert( - // batchSizeCount > 0, - // "Should have batchSizeCount", - // ); - - // assert( - // errorProjectedCount > 0, - // "Should have errorProjectedCount", - // ); assert( totalValueCount > 0,