| class NeuralNetwork{ | |
| constructor(neuronCounts){ | |
| this.levels=[]; | |
| for(let i=0;i<neuronCounts.length-1;i++){ | |
| this.levels.push(new Level( | |
| neuronCounts[i],neuronCounts[i+1] | |
| )); | |
| } | |
| } | |
| static feedForward(givenInputs,network){ | |
| let outputs=Level.feedForward( | |
| givenInputs,network.levels[0]); | |
| for(let i=1;i<network.levels.length;i++){ | |
| outputs=Level.feedForward( | |
| outputs,network.levels[i]); | |
| } | |
| return outputs; | |
| } | |
| static mutate(network,amount=1){ | |
| network.levels.forEach(level => { | |
| for(let i=0;i<level.biases.length;i++){ | |
| level.biases[i]=lerp( | |
| level.biases[i], | |
| Math.random()*2-1, | |
| amount | |
| ) | |
| } | |
| for(let i=0;i<level.weights.length;i++){ | |
| for(let j=0;j<level.weights[i].length;j++){ | |
| level.weights[i][j]=lerp( | |
| level.weights[i][j], | |
| Math.random()*2-1, | |
| amount | |
| ) | |
| } | |
| } | |
| }); | |
| } | |
| } | |
| class Level{ | |
| constructor(inputCount,outputCount){ | |
| this.inputs=new Array(inputCount); | |
| this.outputs=new Array(outputCount); | |
| this.biases=new Array(outputCount); | |
| this.weights=[]; | |
| for(let i=0;i<inputCount;i++){ | |
| this.weights[i]=new Array(outputCount); | |
| } | |
| Level.#randomize(this); | |
| } | |
| static #randomize(level){ | |
| for(let i=0;i<level.inputs.length;i++){ | |
| for(let j=0;j<level.outputs.length;j++){ | |
| level.weights[i][j]=Math.random()*2-1; | |
| } | |
| } | |
| for(let i=0;i<level.biases.length;i++){ | |
| level.biases[i]=Math.random()*2-1; | |
| } | |
| } | |
| static feedForward(givenInputs,level){ | |
| level.inputs=[...givenInputs]; | |
| for(let i=0;i<level.outputs.length;i++){ | |
| let sum=0 | |
| for(let j=0;j<level.inputs.length;j++){ | |
| sum+=level.inputs[j]*level.weights[j][i]; | |
| } | |
| if(sum>level.biases[i]){ | |
| level.outputs[i]=1; | |
| }else{ | |
| level.outputs[i]=0; | |
| } | |
| } | |
| return level.outputs; | |
| } | |
| } |