Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trace average needs counter must increment even if short circuited v2 #325

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 12 additions & 18 deletions src/Creature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
}

Expand Down Expand Up @@ -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,
Expand All @@ -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),
);
}

Expand Down
2 changes: 1 addition & 1 deletion src/architecture/Neat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { Fitness } from "./Fitness.ts";
import { Offspring } from "./Offspring.ts";
import { assert } from "https://deno.land/[email protected]/assert/assert.ts";

class NeatConfig implements NeatOptions {
export class NeatConfig implements NeatOptions {
/** List of creatures to start with */
creatures: CreatureInternal[] | CreatureExport[];

Expand Down
16 changes: 5 additions & 11 deletions src/methods/activations/aggregate/MEAN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand Down
20 changes: 7 additions & 13 deletions src/multithreading/workers/WorkerHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { addTag, getTag } from "https://deno.land/x/[email protected]/mod.ts";
import { Creature } from "../../Creature.ts";
import { TrainOptions } from "../../config/TrainOptions.ts";
import { MockWorker } from "./MockWorker.ts";
import { assert } from "https://deno.land/[email protected]/assert/assert.ts";

export interface RequestData {
taskID: number;
Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 = {
Expand Down
18 changes: 3 additions & 15 deletions src/multithreading/workers/WorkerProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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/[email protected]/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<ResponseData> {
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 {
Expand All @@ -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));
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -97,7 +86,6 @@ export class WorkerProcessor {
},
};
} else {
console.error(data);
throw new Error("unknown message");
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/multithreading/workers/deno/worker.ts
Original file line number Diff line number Diff line change
@@ -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 };
Expand Down
4 changes: 1 addition & 3 deletions test/CRISPR/CRISPR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}

Expand Down
4 changes: 0 additions & 4 deletions test/Clipped.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
75 changes: 35 additions & 40 deletions test/Compact/Compact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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", () => {
Expand Down Expand Up @@ -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", () => {
Expand Down Expand Up @@ -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);
});
4 changes: 0 additions & 4 deletions test/ELU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 0 additions & 4 deletions test/Hypot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 0 additions & 4 deletions test/LeakyReLU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 0 additions & 4 deletions test/Maximum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 0 additions & 4 deletions test/Mean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading