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

Refactor CRISPR functionality and fix DNA ID retrieval in ElitismUtil… #358

Merged
merged 4 commits into from
Apr 26, 2024
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
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