Skip to content

Commit

Permalink
176 if back propagation (#177)
Browse files Browse the repository at this point in the history
* Refactor code to improve performance and readability

* Commented out unused code and disabled console logs

* Update README.md

* Update README.md

---------

Co-authored-by: Nigel (MacBook) <nigel@laptop>
  • Loading branch information
nleck and Nigel (MacBook) authored Jan 7, 2024
1 parent 80fed8f commit 86c6cd9
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 41 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# NEAT Neural Network for DenoJS

This project is a unique implementation of a neural network based on the NEAT (NeuroEvolution of Augmenting Topologies) algorithm, written in DenoJS using TypeScript.

## Unique Features

1. **Extendable Observations**: The observations can be extended over time as the indexing is done via UUIDs, not numbers. This allows for a more flexible and dynamic neural network structure.

2. **Distributed Training**: Training and evolution can be run on multiple independent nodes. The best-of-breed creatures can later be combined on a centralized master node. This feature allows for distributed computing and potentially faster training times.

3. **Life Long Learning**: Unlike many pre-trained neural networks, this project is designed for continuous learning, making it adaptable and potentially more effective in changing environments.

4. **Efficient Model Utilization**: Once trained, the current best model can be utilized efficiently by calling the `noTraceActivate` function.

5. **Unique Squash Functions**: The neural network supports unique squash functions such as IF, MEAN, MAX, MIN, and HYPOT. These functions provide more options for the activation function, which can lead to different network behaviours.

## Usage

This project is designed to be used in a DenoJS environment. Please refer to the DenoJS documentation for setup and usage instructions.

## Contributions

Contributions are welcome. Please submit a pull request or open an issue to discuss potential changes/additions.
22 changes: 11 additions & 11 deletions src/methods/activations/aggregate/IF.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ export class IF

const errorPerLink = error /
(condition > 0 ? positiveCount : negativeCount);
let testWeight = 0;
// let testWeight = 0;
// Iterate over the shuffled indices
for (let i = listLength; i--;) {
const indx = indices[i];
Expand Down Expand Up @@ -381,7 +381,7 @@ export class IF
adjustWeight(cs, targetFromValue2, targetFromActivation);

const aWeight = adjustedWeight(node.network.networkState, c, config);
testWeight = aWeight;
// testWeight = aWeight;
// console.info( `c.from: ${c.from}, c.to: ${c.to}, aWeight: ${aWeight.toFixed(3)}, fromWeight: ${fromWeight.toFixed(3)}, fromActivation: ${fromActivation.toFixed(3)}, improvedFromActivation: ${improvedFromActivation.toFixed(3)}, targetFromActivation: ${targetFromActivation.toFixed(3)}, targetFromValue: ${targetFromValue.toFixed(3)}, targetFromValue2: ${targetFromValue2.toFixed(3)}, thisPerLinkError: ${thisPerLinkError.toFixed(3)}`);
const improvedAdjustedFromValue = improvedFromActivation *
aWeight;
Expand All @@ -397,15 +397,15 @@ export class IF
const aBias = adjustedBias(node, config);

const adjustedActivation = targetWeightedSum + aBias;
if (node.uuid == "output-1") { //&& Math.abs(targetActivation-adjustedActivation) > Math.abs(targetActivation-activation) ) {
console.info(
`${node.uuid}: targetActivation: ${
targetActivation.toFixed(3)
}, activation: ${activation.toFixed(3)}, adjustedActivation: ${
adjustedActivation.toFixed(3)
}, aBias: ${aBias.toFixed(3)}, testWeight: ${testWeight.toFixed(3)}`,
);
}
// if (node.uuid == "output-1") { //&& Math.abs(targetActivation-adjustedActivation) > Math.abs(targetActivation-activation) ) {
// console.info(
// `${node.uuid}: targetActivation: ${
// targetActivation.toFixed(3)
// }, activation: ${activation.toFixed(3)}, adjustedActivation: ${
// adjustedActivation.toFixed(3)
// }, aBias: ${aBias.toFixed(3)}, testWeight: ${testWeight.toFixed(3)}`,
// );
// }
return limitActivation(adjustedActivation);
}
}
61 changes: 31 additions & 30 deletions test/Propagate/IF.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {

import { ensureDirSync } from "https://deno.land/[email protected]/fs/ensure_dir.ts";
import { Costs } from "../../src/Costs.ts";
import { BackPropagationConfig } from "../../src/architecture/BackPropagation.ts";
// import { BackPropagationConfig } from "../../src/architecture/BackPropagation.ts";
import { Network } from "../../src/architecture/Network.ts";
import { NetworkExport } from "../../src/architecture/NetworkInterfaces.ts";

Expand Down Expand Up @@ -71,10 +71,10 @@ Deno.test("PropagateIF", async () => {
creatureC.validate();

const resultC = await creatureC.train(ts, {
iterations: 1,
iterations: 1000,
error: errorB - 0.01,
generations: 10,
useAverageWeight: "Yes",
// useAverageWeight: "Yes",
// disableRandomSamples: true,
});

Expand All @@ -94,43 +94,44 @@ Deno.test("PropagateIF", async () => {
if (errorB <= errorC) continue;
}

if (!resultC.trace) throw new Error("No trace");
const creatureD = Network.fromJSON(
Network.fromJSON(resultC.trace).exportJSON(),
);
const creatureE = Network.fromJSON(resultC.trace);
const config = new BackPropagationConfig({
useAverageWeight: "Yes",
// useAverageDifferenceBias: "Yes",
generations: 0,
});
console.info(config);
// if (!resultC.trace) throw new Error("No trace");
// const creatureD = Network.fromJSON(
// Network.fromJSON(resultC.trace).exportJSON(),
// );
// const creatureE = Network.fromJSON(resultC.trace);
// const config = new BackPropagationConfig({
// // useAverageWeight: "Yes",
// // useAverageDifferenceBias: "Yes",
// // disableRandomSamples:true,
// // generations: 10,
// });
// // console.info(config);

creatureE.applyLearnings(config);
const errorD = calculateError(creatureD, ts);
const errorE = calculateError(creatureE, ts);
// creatureE.applyLearnings(config);
// const errorD = calculateError(creatureD, ts);
// const errorE = calculateError(creatureE, ts);
console.log(
`Error: B: ${errorB}, C: ${errorC}, D: ${errorD}, E: ${errorE}`,
);
`Error: B: ${errorB}, C: ${errorC}`,
); //, D: ${errorD}, E: ${errorE}`,
// );

Deno.writeTextFileSync(
".trace/D-creature.json",
JSON.stringify(creatureD.exportJSON(), null, 2),
);
// Deno.writeTextFileSync(
// ".trace/D-creature.json",
// JSON.stringify(creatureD.exportJSON(), null, 2),
// );

Deno.writeTextFileSync(
".trace/E-creature.json",
JSON.stringify(creatureE.exportJSON(), null, 2),
);
// Deno.writeTextFileSync(
// ".trace/E-creature.json",
// JSON.stringify(creatureE.exportJSON(), null, 2),
// );

assert(
true ||
errorB > errorC,
errorB > errorC,
`Didn't improve error B->C start: ${errorB} end: ${errorC}`,
);

assert(
true || errorB > resultC.error,
errorB > resultC.error,
`Didn't improve error B->C *reported* start: ${errorB} end: ${resultC.error}`,
);

Expand Down

0 comments on commit 86c6cd9

Please sign in to comment.