Skip to content

Commit

Permalink
Refactor CRISPR functionality and fix DNA ID retrieval in ElitismUtil… (
Browse files Browse the repository at this point in the history
#358)

* Refactor CRISPR functionality and fix DNA ID retrieval in ElitismUtils.ts

* Refactor CRISPR functionality and adjust neuron and synapse connections in CRISPR.ts

* Refactor CRISPR functionality and remove tags from synapses in Append.ts

* Refactor CRISPR imports to use the latest version of the std library

---------

Co-authored-by: Nigel Leck <[email protected]>
  • Loading branch information
nleck and nigelleck authored Apr 26, 2024
1 parent f2b6154 commit c7922f0
Show file tree
Hide file tree
Showing 96 changed files with 2,016 additions and 656 deletions.
8 changes: 4 additions & 4 deletions src/Creature.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { assert } from "https://deno.land/std@0.223.0/assert/mod.ts";
import { yellow } from "https://deno.land/std@0.223.0/fmt/colors.ts";
import { format } from "https://deno.land/std@0.223.0/fmt/duration.ts";
import { emptyDirSync } from "https://deno.land/std@0.223.0/fs/mod.ts";
import { assert } from "https://deno.land/std@0.224.0/assert/mod.ts";
import { yellow } from "https://deno.land/std@0.224.0/fmt/colors.ts";
import { format } from "https://deno.land/std@0.224.0/fmt/duration.ts";
import { emptyDirSync } from "https://deno.land/std@0.224.0/fs/mod.ts";
import {
addTag,
getTag,
Expand Down
2 changes: 1 addition & 1 deletion src/architecture/CreatureUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { generate as generateV5 } from "https://deno.land/std@0.223.0/uuid/v5.ts";
import { generate as generateV5 } from "https://deno.land/std@0.224.0/uuid/v5.ts";
import { Creature } from "../Creature.ts";

export class CreatureUtil {
Expand Down
2 changes: 1 addition & 1 deletion src/architecture/ElitismUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
red,
white,
yellow,
} from "https://deno.land/std@0.223.0/fmt/colors.ts";
} from "https://deno.land/std@0.224.0/fmt/colors.ts";
import { addTag, getTag } from "https://deno.land/x/[email protected]/mod.ts";
import { Creature } from "../Creature.ts";

Expand Down
2 changes: 1 addition & 1 deletion src/architecture/FineTune.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { blue, bold, cyan } from "https://deno.land/std@0.223.0/fmt/colors.ts";
import { blue, bold, cyan } from "https://deno.land/std@0.224.0/fmt/colors.ts";
import { addTag, getTag } from "https://deno.land/x/[email protected]/mod.ts";
import { Creature } from "../Creature.ts";
import { CreatureUtil } from "./CreatureUtils.ts";
Expand Down
8 changes: 4 additions & 4 deletions src/architecture/Neat.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { blue } from "https://deno.land/std@0.223.0/fmt/colors.ts";
import { format } from "https://deno.land/std@0.223.0/fmt/duration.ts";
import { ensureDirSync } from "https://deno.land/std@0.223.0/fs/mod.ts";
import { blue } from "https://deno.land/std@0.224.0/fmt/colors.ts";
import { format } from "https://deno.land/std@0.224.0/fmt/duration.ts";
import { ensureDirSync } from "https://deno.land/std@0.224.0/fs/mod.ts";
import {
addTag,
getTag,
Expand All @@ -21,7 +21,7 @@ import { makeElitists } from "./ElitismUtils.ts";
import { fineTuneImprovement } from "./FineTune.ts";
import { Fitness } from "./Fitness.ts";
import { Offspring } from "./Offspring.ts";
import { assert } from "https://deno.land/std@0.223.0/assert/assert.ts";
import { assert } from "https://deno.land/std@0.224.0/assert/assert.ts";
import { creatureValidate } from "./CreatureValidate.ts";
import { DeDuplicator } from "./DeDuplicator.ts";

Expand Down
2 changes: 1 addition & 1 deletion src/architecture/Offspring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Creature } from "../Creature.ts";
import { SynapseExport, SynapseInternal } from "./SynapseInterfaces.ts";
import { Neuron } from "./Neuron.ts";
import { creatureValidate } from "./CreatureValidate.ts";
import { assert } from "https://deno.land/std@0.223.0/assert/mod.ts";
import { assert } from "https://deno.land/std@0.224.0/assert/mod.ts";

class OffspringError extends Error {
constructor(message: string) {
Expand Down
6 changes: 3 additions & 3 deletions src/architecture/Training.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { blue, yellow } from "https://deno.land/std@0.223.0/fmt/colors.ts";
import { format } from "https://deno.land/std@0.223.0/fmt/duration.ts";
import { ensureDirSync } from "https://deno.land/std@0.223.0/fs/mod.ts";
import { blue, yellow } from "https://deno.land/std@0.224.0/fmt/colors.ts";
import { format } from "https://deno.land/std@0.224.0/fmt/duration.ts";
import { ensureDirSync } from "https://deno.land/std@0.224.0/fs/mod.ts";
import { Costs } from "../Costs.ts";
import { Creature } from "../Creature.ts";
import { TrainOptions } from "../config/TrainOptions.ts";
Expand Down
2 changes: 1 addition & 1 deletion src/multithreading/workers/WorkerHandler.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assert } from "https://deno.land/std@0.223.0/assert/mod.ts";
import { assert } from "https://deno.land/std@0.224.0/assert/mod.ts";
import { addTag, getTag } from "https://deno.land/x/[email protected]/mod.ts";
import { Creature } from "../../Creature.ts";
import { TrainOptions } from "../../config/TrainOptions.ts";
Expand Down
2 changes: 1 addition & 1 deletion src/multithreading/workers/WorkerProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ 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.223.0/assert/assert.ts";
import { assert } from "https://deno.land/std@0.224.0/assert/assert.ts";
import { creatureValidate } from "../../architecture/CreatureValidate.ts";

export class WorkerProcessor {
Expand Down
144 changes: 85 additions & 59 deletions src/reconstruct/CRISPR.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assert } from "https://deno.land/std@0.223.0/assert/mod.ts";
import { assert } from "https://deno.land/std@0.224.0/assert/mod.ts";
import {
addTag,
getTag,
Expand Down Expand Up @@ -80,6 +80,7 @@ export class CRISPR {
UUIDs.set(node.uuid, node.index);
});

let adjustIndx = 0;
if (dna.neurons) {
let firstDnaOutputIndex: number = -1;
dna.neurons.forEach((neuron) => {
Expand All @@ -98,12 +99,20 @@ export class CRISPR {
}
((neuron as unknown) as { type: string }).type = "hidden";
if (neuron.uuid?.startsWith("output-")) {
neuron.uuid = crypto.randomUUID();
const uuid = crypto.randomUUID();
dna.synapses.forEach((synapse) => {
if (synapse.fromUUID == neuron.uuid) {
synapse.fromUUID = uuid;
}
});

neuron.uuid = uuid;
UUIDs.set(uuid, indx);
}
}
});

const adjustIndx = firstNetworkOutputIndex - firstDnaOutputIndex +
adjustIndx = firstNetworkOutputIndex - firstDnaOutputIndex +
dna.neurons.length;

let outputIndx: number = 0;
Expand All @@ -117,15 +126,15 @@ export class CRISPR {
? UUIDs.has(dnaNeuron.uuid) ? crypto.randomUUID() : dnaNeuron.uuid
: crypto.randomUUID();

if (uuid.startsWith("output-")) {
uuid = crypto.randomUUID();
}
// if (uuid.startsWith("output-")) {
// uuid = crypto.randomUUID();
// }
}
let indx;
if (dnaNeuron.index !== undefined) {
indx = dnaNeuron.index + adjustIndx;
} else {
indx = tmpCreature.neurons.length;
indx = UUIDs.size - 1; //tmpCreature.neurons.length;
}

const neuron = new Neuron(
Expand All @@ -136,72 +145,84 @@ export class CRISPR {
dnaNeuron.squash,
);
neuron.index = indx;

UUIDs.set(uuid, indx);
addTag(neuron, "CRISPR", dna.id);
if (dnaNeuron.comment) {
addTag(neuron, "comment", dnaNeuron.comment);
}
tmpCreature.neurons.push(neuron);
if (dnaNeuron.type == "output") {
if (firstDnaOutputIndex == -1) {
firstDnaOutputIndex = indx;
}
}
});

dna.synapses.forEach((c) => {
const from = c.from !== undefined
? c.from
: ((c.fromRelative ? c.fromRelative : 0) + adjustIndx);
assert(
from !== undefined,
"Invalid connection (from): " + JSON.stringify(c),
);

const to = c.to !== undefined
? c.to
: ((c.toRelative ? c.toRelative : 0) + adjustIndx);

assert(
to !== undefined,
"Invalid connection (to): " + JSON.stringify(c),
);

tmpCreature.connect(from, to, c.weight, c.type);
// if (dnaNeuron.type == "output") {
// if (firstDnaOutputIndex == -1) {
// firstDnaOutputIndex = indx;
// }
// }
});
}

dna.synapses.forEach((c) => {
let toIndx: number = -1;
if (c.toUUID) {
const indx = UUIDs.get(c.toUUID);
assert(indx !== undefined, "missing toUUID " + c.toUUID);
toIndx = indx;
tmpCreature.clearCache();
dna.synapses.forEach((s) => {
let from;
if (s.fromUUID) {
from = UUIDs.get(s.fromUUID);
}

let fromIndx: number = -1;
if (c.fromUUID) {
const indx = UUIDs.get(c.fromUUID);
assert(indx !== undefined, "missing fromUUID " + c.fromUUID);
fromIndx = indx;
if (from == undefined) {
if (s.from !== undefined) {
from = s.from;
} else if (s.fromRelative !== undefined) {
from = s.fromRelative + adjustIndx;
} else {
throw new Error("Invalid connection (from): " + JSON.stringify(s));
}
}

if (fromIndx !== -1 && toIndx !== -1) {
if (!tmpCreature.getSynapse(fromIndx, toIndx)) {
const synapse = tmpCreature.connect(
fromIndx,
toIndx,
c.weight,
c.type,
);
addTag(synapse, "CRISPR", dna.id);
if (c.comment) {
addTag(synapse, "comment", c.comment);
}
let to;
if (s.toUUID) {
to = UUIDs.get(s.toUUID);
}
if (to == undefined) {
if (s.to !== undefined) {
to = s.to;
} else if (s.toRelative !== undefined) {
to = s.toRelative + adjustIndx;
} else {
throw new Error("Invalid connection (to): " + JSON.stringify(s));
}
}

const synapse = tmpCreature.connect(from, to, s.weight, s.type);
addTag(synapse, "CRISPR", dna.id);
});

// dna.synapses.forEach((c) => {
// let toIndx: number = -1;
// if (c.toUUID) {
// const indx = UUIDs.get(c.toUUID);
// assert(indx !== undefined, "missing toUUID " + c.toUUID);
// toIndx = indx;
// }

// let fromIndx: number = -1;
// if (c.fromUUID) {
// const indx = UUIDs.get(c.fromUUID);
// assert(indx !== undefined, "missing fromUUID " + c.fromUUID);
// fromIndx = indx;
// }

// if (fromIndx !== -1 && toIndx !== -1) {
// if (!tmpCreature.getSynapse(fromIndx, toIndx)) {
// const synapse = tmpCreature.connect(
// fromIndx,
// toIndx,
// c.weight,
// c.type,
// );
// addTag(synapse, "CRISPR", dna.id);
// if (c.comment) {
// addTag(synapse, "comment", c.comment);
// }
// }
// }
// });

return tmpCreature;
}

Expand Down Expand Up @@ -396,6 +417,11 @@ export class CRISPR {
}

delete modifiedCreature.uuid;
modifiedCreature.DEBUG = false;
Deno.writeTextFileSync(
".crispr.json",
JSON.stringify(modifiedCreature.exportJSON(), null, 2),
);
modifiedCreature.validate();
const modifiedUUID = await CreatureUtil.makeUUID(modifiedCreature);
if (uuid !== modifiedUUID) {
Expand Down
2 changes: 1 addition & 1 deletion src/reconstruct/Upgrade.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assert } from "https://deno.land/std@0.223.0/assert/mod.ts";
import { assert } from "https://deno.land/std@0.224.0/assert/mod.ts";
import { CreatureExport } from "../architecture/CreatureInterfaces.ts";
import { Creature } from "../Creature.ts";
import { creatureValidate } from "../architecture/CreatureValidate.ts";
Expand Down
2 changes: 1 addition & 1 deletion test/ActivationNames.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
assert,
assertNotEquals,
} from "https://deno.land/std@0.223.0/assert/mod.ts";
} from "https://deno.land/std@0.224.0/assert/mod.ts";
import { Activations } from "../src/methods/activations/Activations.ts";

Deno.test("ActivationNames", () => {
Expand Down
2 changes: 1 addition & 1 deletion test/CRISPR/Aliases.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
assert,
assertEquals,
} from "https://deno.land/std@0.223.0/assert/mod.ts";
} from "https://deno.land/std@0.224.0/assert/mod.ts";
import { CRISPR, CrisprInterface } from "../../src/reconstruct/CRISPR.ts";

Deno.test("editAliases", () => {
Expand Down
57 changes: 57 additions & 0 deletions test/CRISPR/Append.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { assertEquals } from "https://deno.land/[email protected]/assert/mod.ts";
import { Creature } from "../../src/Creature.ts";
import { CRISPR } from "../../src/reconstruct/CRISPR.ts";
import { CreatureInternal } from "../../src/architecture/CreatureInterfaces.ts";

((globalThis as unknown) as { DEBUG: boolean }).DEBUG = true;

Deno.test("CRISPR/Append", async () => {
const networkTXT = Deno.readTextFileSync("test/data/CRISPR/network.json");
const network = Creature.fromJSON(JSON.parse(networkTXT));
network.validate();

const crispr = new CRISPR(network);
const dnaTXT = Deno.readTextFileSync("test/data/CRISPR/DNA-RANGE.json");

const networkIF = await crispr.cleaveDNA(JSON.parse(dnaTXT));
(networkIF as Creature).validate();
const expectedJSON = JSON.parse(
Deno.readTextFileSync("test/data/CRISPR/expected-range.json"),
);

const expectedTXT = JSON.stringify(
clean(Creature.fromJSON(expectedJSON).internalJSON()),
null,
2,
);
Deno.writeTextFileSync("test/data/CRISPR/.expected-range.txt", expectedTXT);

const actualJSON = clean((networkIF as Creature).internalJSON());

const actualTXT = JSON.stringify(
actualJSON,
null,
2,
);

Deno.writeTextFileSync(
"test/data/CRISPR/.actual-range.json",
JSON.stringify((networkIF as Creature).exportJSON(), null, 2),
);
Deno.writeTextFileSync("test/data/CRISPR/.actual-range.txt", actualTXT);
assertEquals(actualTXT, expectedTXT, "should have converted");
});

function clean(creature: CreatureInternal): { uuid: string | undefined } {
const cleanCreature = JSON.parse(JSON.stringify(creature));
delete cleanCreature.tags;
delete cleanCreature.uuid;
cleanCreature.neurons.forEach((neuron: { uuid: string | undefined }) => {
delete neuron.uuid;
});

cleanCreature.synapses.forEach((synapse: { tags: string | undefined }) => {
delete synapse.tags;
});
return cleanCreature;
}
2 changes: 1 addition & 1 deletion test/CRISPR/CRISPR.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
assert,
assertEquals,
} from "https://deno.land/std@0.223.0/assert/mod.ts";
} from "https://deno.land/std@0.224.0/assert/mod.ts";
import { getTag } from "https://deno.land/x/[email protected]/mod.ts";
import { Creature } from "../../src/Creature.ts";
import { CreatureInternal } from "../../src/architecture/CreatureInterfaces.ts";
Expand Down
2 changes: 1 addition & 1 deletion test/CRISPR/From.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
assert,
assertAlmostEquals,
} from "https://deno.land/std@0.223.0/assert/mod.ts";
} from "https://deno.land/std@0.224.0/assert/mod.ts";
import { getTag } from "https://deno.land/x/[email protected]/mod.ts";
import { Creature } from "../../src/Creature.ts";
import { CRISPR } from "../../src/reconstruct/CRISPR.ts";
Expand Down
2 changes: 1 addition & 1 deletion test/Clipped.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assert } from "https://deno.land/std@0.223.0/assert/mod.ts";
import { assert } from "https://deno.land/std@0.224.0/assert/mod.ts";
import { Creature } from "../src/Creature.ts";

import { CreatureInternal } from "../src/architecture/CreatureInterfaces.ts";
Expand Down
Loading

0 comments on commit c7922f0

Please sign in to comment.