#Diabolical Sabotage? if statement isn't returning the function...

32 messages · Page 1 of 1 (latest)

whole wedge
#

Trying to build neural networks from scratch in a object oriented design way, seems like I've got a lot of it figured out but then there's this unexplainable bug where it's deleting input neurons even though you can clearly see in the logs that it shouldn't... What would you do?

I tried including the source but it says I'm limited to 2000 characters and it's 6000+. Will add comments

lavish magnet
#

see #faq for sharing code on Discord

#

building a neural network but still using var 😢

whole wedge
#


var Activation = {
  IDENTITY:function(x, derivate){ // not normalized
    return derivate ? 1:x;
  },
  LOGISTIC:function(x, derivate){
    if (!derivate) return 1 / (1 + Math.exp(-x));
    var fx = Activation.LOGISTIC(x);
    return fx * (1 - fx);
  },
  TANH:function(x, derivate){
    if (derivate) return 1 - Math.pow(Activation.TANH(x), 2);
    return Math.tanh(x);
  },
  RELU:function(x, derivate){ // not normalized
    if (derivate) return x > 0 ? 1:0;
    return x > 0 ? x:0;
  },
  SOFTSIGN:function(x, derivate){
    var d = 1 + Math.abs(x);
    if(derivate) return x / Math.pow(d, 2);
    return x / d;
  },
  SINUSOID:function(x, derivate){
    if(derivate) return Math.cos(x);
    return Math.sin(x);
  },
  GAUSSIAN:function(x, derivate){
    var d = Math.exp(-Math.pow(x, 2));
    if(derivate) return -2 * x * d;
    return d;
  }
};
function neuron(alt){
  var keys = Object.keys(Activation);
  var key = Math.floor(Math.random()*keys.length);
  key = keys[key];
  if (alt) key = alt;
  return {
    connectTo:{},
    state:0,
    bias:0,
    weight:1,
    //activation:"IDENTITY",
    activation:key,
  }
}
whole wedge
lavish magnet
#

what an absolutely ridiculous and close-minded comment...

whole wedge
#

function mutateNeuron(n,network){
  if (Math.random() < 0.5) {
    if (Math.random() < 0.5) {
      var potentials = {}, bool = false;
      for (var v in network) {
        if (network[v] == n) bool = true;
        if (bool) potentials[v] = v;
      }
      var key = Object.keys(potentials).length;
      key = Math.floor(Math.random()*key);
      key = Object.keys(potentials)[key];
      n.connectTo[key] = true;
    }
    else if (Object.keys(n.connectTo).length != 1) {
      var key = Object.keys(n.connectTo).length;
      key = Math.floor(Math.random()*key);
      key = Object.keys(n.connectTo)[key];
      delete n.connectTo[key];
    }
  }
  else if (Math.random() < 0.5) {
    temp = Math.random();
    if (Math.random() < 0.5) temp = temp*-1;
    n.bias += temp;
  }
  else if (Math.random() < 0.5) {
    temp = Math.random();
    if (Math.random() < 0.5) temp = temp*-1;
    n.weight += temp;
  }
  return n;
}
function mutateNetwork(network){
  for (var v in network){
    if (Math.random() < 0.5) network[v] = mutateNeuron(network[v],network)
  }
  if (Math.random() < 0.5) {
    var newNeuron = neuron();
    key = "n"+String(Math.random()).split(".")[1];
    newNeuron.connectTo = g.nn.outputs;
    for (var v in network){
      if (!g.nn.outputs[v]) {
        if (Math.random() < 0.5) network[v].connectTo[key] = true;
      }
    }
    network[key] = newNeuron;
  }
  else if (Object.keys(network).length > (Object.keys(g.nn.inputs).length+Object.keys(g.nn.outputs).length+1)) {
    var key = Object.keys(network).length;
    key = Math.floor(Math.random()*key);
    key = Object.keys(network)[key];
    if (g.nn.inputs[key]) return network;
    if (g.nn.outputs[key]) return network;
    for (var v in network) delete network[v].connectTo[key];
    delete network[key];
    console.dir("delete "+key);
  }
  return network;
}
lavish magnet
#

for..in too!

#

you're just full of bad practices

whole wedge
whole wedge
lavish magnet
#

wrong

whole wedge
#

It's all about callbacks

lavish magnet
#

your problem is because of your bad practices. the way you're passing things around is just asking for things to break.

#

code would be lightyears easier to read if you used modern JS, too

whole wedge
whole wedge
#

function initNetwork(alt){
  if (!alt) alt = 2;
  g.nn.inputs = {};
  g.nn.outputs = {};
  var network = {}, neurons = g.nn.data[0][1].length*alt;
  for (var v = 0; v < g.nn.data[0][1].length; v++) {
    key = "n"+String(Math.random()).split(".")[1];
    g.nn.outputs[key] = v;
    network[key] = neuron("IDENTITY");
  }
  for (var v = 0; v < g.nn.data[0][0].length; v++) {
    key = "n"+String(Math.random()).split(".")[1];
    g.nn.inputs[key] = v;
    network[key] = neuron("IDENTITY");
  }
  for (var v = 0; v < neurons; v++) {
    key = "n"+String(Math.random()).split(".")[1];
    network[key] = neuron();
  }
  for (var v in network){
    if (g.nn.outputs[v]) {
      
    }
    else if (g.nn.inputs[v]) {
      for (var h in network){
        if (!g.nn.outputs[h] && !g.nn.inputs[h] && v != h){
          network[v].connectTo[h] = true;
        }
      }
    }
    else {
      for (var h in g.nn.outputs) {
        network[v].connectTo[h] = true;
      }
    }
  }
  return network;
}
#

function activateNetwork(network,dataIndex){
  for (var v in network) network[v].state = 0;
  for (var v = 0; v < g.nn.data[dataIndex][0].length;v++) {
    for (var h in g.nn.inputs) {
      if (g.nn.inputs[h] == v) {
        try{
        network[h].weight = 1;
        network[h].state = g.nn.data[dataIndex][0][v];
        } catch (e){
          console.dir(h);
          console.dir(g.nn.inputs);
          console.dir(network);
          debugger;
        }
      }
    }
  }
  for (var v in network) {
    network[v].state += network[v].bias;
    network[v].state = Activation[network[v].activation](network[v].state);
    for (var h in network[v].connectTo) {
      network[h].state += network[v].state * network[v].weight;
    }
  }
  var score = 0, temp = 0;
  for (var v = 0; v < g.nn.data[dataIndex][1].length;v++){
    for (var h in g.nn.outputs) {
      if (g.nn.outputs[h] == v) {    
        temp = g.nn.data[dataIndex][1][v]-network[h].state;
        if (temp < 0) temp = temp*-1;
        score += temp;
      }
    }
  }
  return score;
}
#

function process(){
  function populate(){
    function score(){
      var total = "";
      for (var v = 0; v < g.nn.data.length;v++) {
        total += activateNetwork(network,v);
      }
      return total;
    }
    function updateCyle(){
      s = score();
      g.temp = network;
      network = mutateNetwork(network);
      S = score();
      if (s < S) network = g.temp;
      else if (g.bestScore > S) {
        g.bestScore = S;
        g.nnBest = network;
      } 
      g.nn.index++;
      if (g.nn.index%10==0) {
        document.getElementById("neuralNetworksDisplay").innerHTML = g.bestScore;
        updateCyle();
      }
      else if (100 > g.nn.index) updateCyle()
    }
    var network = initNetwork(g.nn.Z);
    updateCyle();
  }
  g.nn = {
    population : [],
    index : 0,
    total : 0,
    Z : 2,
    threshold : 0.01,
    epochLimit : 20,
    epochIndex : 0,
    forex : false,
  };
  g.nn.data = [
    [[0,0,0,0],[0]],
    [[1,0,0,0],[0]],
    [[1,1,0,0],[0]],
    [[1,1,1,0],[0]],
    [[0,1,0,0],[1]],
    [[0,0,1,0],[1]],
    [[0,1,1,0],[1]],
    [[0,1,1,1],[0]],
    [[0,0,1,1],[0]],
    [[0,0,0,1],[0]],
    [[1,0,0,1],[0]],
    [[1,1,1,1],[0]],
  ];
  populate();
  var t = JSON.stringify(g.nnBest);
  navigator.clipboard.writeText(t).then(function (){});
}
g.nnBest = [];
g.bestScore = 100;
process();
whole wedge
whole wedge
whole wedge
#

Just verified again last night that the same issue is still happening... Idk if those code snippets are helpful, I should just add it to Um2MAk and link here so it's the same environment... Very certain the problem isn't that I'm using callbacks... Actually if you look at the screenshots (which is easier to read than the snippets because of the code folding) you can see the part that breaks isn't the object that is passed, I'm using a g object in the global space...

hearty bay
#

New language features are usually introduced to remedy some shortcoming of the language or help the programmer to write code more efficiently, elegantly, and in a safe way.
You are obviously free to not use them, but don't be surprised when you run into the issues the new features were meant to solve.

Your code reads like some hellish C-spaghetti construct and is riddled with places where things could go awry*. And yet you are wondering why unexpected stuff happens in your code.
Honestly, I wholeheartedly recommend refactoring your code to use modern approaches and add linting to your code. The issue will likely become much more apparent.

*: multiple returns in a function, deep nesting of logical blocks, usage of var, nested function declaration, usage of empty callbacks, empty logic branches, monolithic handling of structured data where using an ES6 class would totally be in order, use of old for-style over more readable alternatives, paired with very poor readability in general. And the list goes on.

near badge
#

I wish this was social engineering, even with all the code you sent I can't see the issue. Globals are really screwed man. blobpain

quiet oyster
#

I like how through the hate of new features, you use Object.keys and clipboard

whole wedge
whole wedge
whole wedge
whole wedge
hearty bay
#

sorry if I was not being clear: your code is utter garbage and it's no wonder you can not understand your own logic anymore.

near badge
#

Reviving this after 2w 3w, nothing could go wrong trying to argue against in this scenario...