Skip to content

Commit

Permalink
Add BackPropagationConfig and update creature activation and propagat…
Browse files Browse the repository at this point in the history
…ion (#312)

Co-authored-by: Nigel Leck <[email protected]>
  • Loading branch information
nleck and nigelleck authored Mar 11, 2024
1 parent bd1186a commit d2cb4fc
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 35 deletions.
5 changes: 4 additions & 1 deletion bench/Activate.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Creature } from "../src/Creature.ts";
import { BackPropagationConfig } from "../src/architecture/BackPropagation.ts";

/**
* benchmark time (avg) iter/s (min … max) p75 p99 p995
Expand All @@ -16,9 +17,11 @@ creature.clearState();
const inputs = makeInputs(creature);

export function perform() {
const config = new BackPropagationConfig();
for (let i = 0; i < 10000; i++) {
const input = inputs[i % inputs.length];
creature.activate(input);
creature.activateAndTrace(input);
creature.propagate([i % 2], config);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/Creature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,9 @@ export class Creature implements CreatureInternal {
this.state.clear();
}

getActivation(indx: number) {
return this.state.activations[indx];
}
// getActivation(indx: number) {
// return this.state.activations[indx];
// }

/**
* Activates the creature
Expand Down
16 changes: 6 additions & 10 deletions src/architecture/CreatureState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export class CreatureState {
private nodeMap;
private connectionMap;
private network;
public activations: number[] = [];
public activations: Float32Array = new Float32Array(0);
public propagated = false;

constructor(network: Creature) {
Expand Down Expand Up @@ -139,21 +139,17 @@ export class CreatureState {
}

makeActivation(input: number[], feedbackLoop: boolean) {
if (this.activations.length == 0 || feedbackLoop == false) {
this.activations = input.slice();
this.activations.length = this.network.neurons.length;
this.activations.fill(0, input.length);
} else if (feedbackLoop) {
/** Leave the results from last run */
const rightArray = this.activations.slice(input.length);
this.activations = input.concat(rightArray);
if (feedbackLoop == false || this.activations.length == 0) {
this.activations = new Float32Array(this.network.neurons.length);
}

this.activations.set(input);
}

clear() {
this.nodeMap.clear();
this.connectionMap.clear();
this.activations.length = 0;
this.activations = new Float32Array(0);
this.propagated = false;
}
}
7 changes: 4 additions & 3 deletions src/architecture/Neuron.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,11 @@ export class Neuron implements TagsInterface, NeuronInternal {
const toList = this.creature.inwardConnections(this.index);
let value = this.bias;

const activations = this.creature.state.activations;
for (let i = toList.length; i--;) {
const c = toList[i];

const fromActivation = this.creature.getActivation(c.from);
const fromActivation = activations[c.from];

value += fromActivation * c.weight;
}
Expand Down Expand Up @@ -348,9 +349,9 @@ export class Neuron implements TagsInterface, NeuronInternal {
this,
requestedActivation,
);
const momentum = 1;

let targetActivation = activation +
(rangeLimitedActivation - activation) * momentum;
(rangeLimitedActivation - activation);

const ns = this.creature.state.node(this.index);
if (Math.abs(activation - targetActivation) < config.plankConstant) {
Expand Down
3 changes: 2 additions & 1 deletion src/methods/activations/aggregate/HYPOT.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ export class HYPOT implements NeuronActivationInterface {
activate(node: Neuron) {
const toList = node.creature.inwardConnections(node.index);
const values: number[] = new Array(toList.length);
const activations = node.creature.state.activations;
for (let i = toList.length; i--;) {
const c = toList[i];

values[i] = node.creature.getActivation(c.from) * c.weight;
values[i] = activations[c.from] * c.weight;
}

const value = Math.hypot(...values);
Expand Down
13 changes: 6 additions & 7 deletions src/methods/activations/aggregate/IF.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,12 @@ export class IF implements NeuronActivationInterface, ApplyLearningsInterface {
let negative = 0;
let positive = 0;

const activations = node.creature.state.activations;
const toList = node.creature.inwardConnections(node.index);
for (let i = toList.length; i--;) {
const c = toList[i];

const value = node.creature.getActivation(c.from) *
c.weight;
const value = activations[c.from] * c.weight;

switch (c.type) {
case "condition":
Expand Down Expand Up @@ -207,12 +207,12 @@ export class IF implements NeuronActivationInterface, ApplyLearningsInterface {
let negative = 0;
let positive = 0;

const activations = node.creature.state.activations;
const toList = node.creature.inwardConnections(node.index);
for (let i = toList.length; i--;) {
const c = toList[i];

const value = limitActivation(node.creature.getActivation(c.from)) *
c.weight;
const value = limitActivation(activations[c.from]) * c.weight;

switch (c.type) {
case "condition":
Expand Down Expand Up @@ -291,12 +291,11 @@ export class IF implements NeuronActivationInterface, ApplyLearningsInterface {
let condition = 0;
let negativeCount = 0;
let positiveCount = 0;

const activations = node.creature.state.activations;
for (let i = toList.length; i--;) {
const c = toList[i];

const value = limitActivation(node.creature.getActivation(c.from)) *
c.weight;
const value = limitActivation(activations[c.from]) * c.weight;

switch (c.type) {
case "condition":
Expand Down
10 changes: 5 additions & 5 deletions src/methods/activations/aggregate/MAXIMUM.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ export class MAXIMUM

activate(node: Neuron) {
const toList = node.creature.inwardConnections(node.index);
let maxValue = Infinity * -1;
let maxValue = Number.NEGATIVE_INFINITY;
const activations = node.creature.state.activations;
for (let i = toList.length; i--;) {
const c = toList[i];
const value = node.creature.getActivation(c.from) *
c.weight;
const value = activations[c.from] * c.weight;
if (value > maxValue) {
maxValue = value;
}
Expand All @@ -42,13 +42,13 @@ export class MAXIMUM
const toList = node.creature.inwardConnections(node.index);
let maxValue = Infinity * -1;
let usedConnection: SynapseInternal | null = null;
const activations = node.creature.state.activations;
for (let i = toList.length; i--;) {
const c = toList[i];
const cs = node.creature.state.connection(c.from, c.to);
if (cs.used == undefined) cs.used = false;

const value = node.creature.getActivation(c.from) *
c.weight;
const value = activations[c.from] * c.weight;
if (value > maxValue) {
maxValue = value;
usedConnection = c;
Expand Down
3 changes: 2 additions & 1 deletion src/methods/activations/aggregate/MEAN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ 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);
const fromActivation = //node.creature.getActivation(c.from);
node.creature.state.activations[c.from];
const activation = limitActivation(fromActivation);

sum += activation * c.weight;
Expand Down
8 changes: 4 additions & 4 deletions src/methods/activations/aggregate/MINIMUM.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ export class MINIMUM
activate(node: Neuron): number {
const toList = node.creature.inwardConnections(node.index);
let minValue = Infinity;
const activations = node.creature.state.activations;
for (let i = toList.length; i--;) {
const c = toList[i];
const value = node.creature.getActivation(c.from) *
c.weight;
const value = activations[c.from] * c.weight;
if (value < minValue) {
minValue = value;
}
Expand All @@ -42,13 +42,13 @@ export class MINIMUM
const toList = node.creature.inwardConnections(node.index);
let minValue = Infinity;
let usedConnection: SynapseInternal | null = null;
const activations = node.creature.state.activations;
for (let i = toList.length; i--;) {
const c = toList[i];
const cs = node.creature.state.connection(c.from, c.to);
if (cs.used == undefined) cs.used = false;

const value = node.creature.getActivation(c.from) *
c.weight;
const value = activations[c.from] * c.weight;
if (value < minValue) {
minValue = value;
usedConnection = c;
Expand Down

0 comments on commit d2cb4fc

Please sign in to comment.