wagenaartje / neataptic

:rocket: Blazing fast neuro-evolution & backpropagation for the browser and Node.js
https://wagenaartje.github.io/neataptic/
Other
1.18k stars 278 forks source link

Copied network using fromJSON is returning outputs different from the original network #165

Open SpicyMelonYT opened 11 months ago

SpicyMelonYT commented 11 months ago

Issue

Hi, so when I use the Network.fromJSON function to copy a myNetwork.toJSON result and then RUN the new network with the same input as the original one, the result is different. I also noticed that when I DON'T train the original the outputs DO become the same. Weird. Please help!

EDIT: oh and also I tested making multiple copies not just one and they are all slightly different in their results. Even when I clear them since this is an LSTM

Lines Of Interest In The Code Below

The nn and nn2 activate functions for checking the result:

  print(nn.activate([0, 1]));
  print(nn2.activate([0, 1]));

The training function:

  train(log = 100, error = 0.000001, iterations = 1000, rate = 0.1) {
    return this.lstm.train(this.trainingData, { log, error, iterations, rate });
  }

Code

function setup() {
  createCanvas(400, 400);

  var nn = new NN(2, 8, 1);

  nn.data([0, 0], [0]);
  nn.data([0, 1], [1]);
  nn.data([1, 0], [1]);
  nn.data([1, 1], [0]);

  nn.train();

  let nn2 = nn.copy();

  print(nn.activate([0, 1]));
  print(nn2.activate([0, 1]));
}

function draw() {
  background(220);
}

class NN {
  constructor(...shape) {
    this.shape = shape;
    this.trainingData = [];
    this.lstm = new neataptic.architect.LSTM(...shape);
  }

  data(input, output) {
    let data = { input, output };
    this.trainingData.push(data);
    return data;
  }

  train(log = 100, error = 0.000001, iterations = 1000, rate = 0.1) {
    return this.lstm.train(this.trainingData, { log, error, iterations, rate });
  }

  mutate(amount = 1) {
    for (let i = 0; i < amount; i++) {
      this.lstm.mutate(neataptic.methods.mutation.MOD_WEIGHT);
      this.lstm.mutate(neataptic.methods.mutation.MOD_BIAS);
    }
  }

  activate(...args) {
    return this.lstm.activate(...args);
  }

  toJSON() {
    let json = this.lstm.toJSON();
    json.shape = this.shape;
    return json;
  }

  static fromJSON(json) {
    let nn = new NN(...json.shape);
    nn.lstm = neataptic.Network.fromJSON(json);
    return nn;
  }

  copy() {
    let nn = NN.fromJSON(this.toJSON());
    return nn;
  }
}