繁体   English   中英

Javascript神经网络不收敛

[英]Javascript neural network not converging

我一直在尝试开发一种使用遗传算法来打印收敛到一个值的神经网络。

我已经尝试调试代码,但不知道自己搞砸了什么。

我正在使用健身方法来选择最佳的“大脑”,然后将它们交叉(复制)。

目前,它只是试图演化出返回数字的“大脑”。 适应度是返回数字和原始数字之间差异的函数。

"use strict";



function sigmoid(x) {

    return 1 / (1 + Math.E ** -x);

}



function random(min, max) {

    return (max - min) * Math.random() + min

}



function toss() {

    return random(-1, 1)

}



function Brain(inputs, hiddens, outputs) {

    this.structure = [...arguments];

    if (this.structure.length < 3) throw "Invalid layer count";

    this.layers = [];

    this.layers[this.structure.length - 1] = {

        nodes: []

    };

    for (var i = this.structure.length - 1; i--;) this.layers[i] = {

        bias: toss(),

        nodes: []

    };

    for (var i = 1; i < this.structure.length; i++) {

        var nodes = this.layers[i].nodes;;

        for (var j = this.structure[i]; j--;) {

            var node = nodes[j] = {

                weights: []

            };

            for (var k = this.structure[i - 1]; k--;) node.weights[k] = toss();

        }

    };

}



Brain.prototype.compute = function() {

    if (arguments[0] !== this.structure[0]) throw "Invalid input count";

    for (var i = arguments.length; i--;) this.layers[0].nodes[i] = {

        value: arguments[i]

    };

    for (var i = 1; i < this.layers.length - 1; i++) {

        var layer = this.layers[i];

        var feeder = this.layers[i - 1];

        for (var j = layer.nodes.length; j--;) {

            var node = layer.nodes[j];

            var dot = 0;

            for (var k = node.weights.length; k--;) dot += node.weights[k] * feeder.nodes[k].value;

            node.value = sigmoid(dot + feeder.bias);

        }

    }

    var result = [];

    var layer = this.layers[this.layers.length - 1];

    var feeder = this.layers[this.layers.length - 2];

    for (var j = layer.nodes.length; j--;) {

        var node = layer.nodes[j];

        var dot = 0;

        for (var k = node.weights.length; k--;) dot += node.weights[k] * feeder.nodes[k].value;

        result[j] = sigmoid(dot + feeder.bias);

    }

    return result;

}

Brain.prototype.cross = function() {

    var newBrain = new Brain(...this.structure);

    var brains = [this, ...arguments];

    for (var i = 1; i < newBrain.layers.length; i++) {

        var layer = newBrain.layers[i];

        for (var j = layer.nodes.length; j--;) {

            var node = layer.nodes[j];

            for (var k = node.weights.length; k--;) node.weights[k] = mutate() ||

                brains[Math.floor(Math.random() * brains.length)]

                .layers[i].nodes[j].weights[k];

        }

    }

    for (var i = newBrain.layers.length - 1; i--;) newBrain.layers[i].bias = mutate() ||

        brains[Math.floor(Math.random() * brains.length)]

        .layers[i].bias;

    return newBrain;

}



function mutate(key, nodes) {

    if (Math.random() > 0.05) return toss();

}



var brain = new Brain(1, 5, 1);

var newBrain = new Brain(1, 5, 1)

var result = brain.compute(1);

var cross = brain.cross(newBrain);



var brains = [];

for (var node = 45; node--;) brains.push({

    brain: new Brain(1, 5, 4, 3, 2, 1)

});

for (var count = 1000000; count--;) {

    brains.push({

        brain: new Brain(1, 5, 4, 3, 2, 1)

    });

    for (var node = brains.length; node--;) {

        var brain = brains[node];

        var number = 1;

        var target = number;

        brain.fitness = 1 / Math.abs(number - brain.brain.compute(number));

    }

    brains.sort((a, b) => a.fitness < b.fitness);

    if (count % 10000 === 0) console.log(brains.length, brains[0].fitness);



    var newBrains = [];

    for (var node = 10; node--;)

        for (var j = node; j--;) newBrains.push({

            brain: brains[node].brain.cross(brains[j].brain)

        });

    brains = newBrains;

}

console.log(brains);

我需要改进/更改什么?

这是控制台日志:

46 1.468903884218341

46 1.1881817088540865

46 4.899728181582378

46 1.5494097713447523

46 2.4958253537304644

46 2.4091648830940953

46 1.4000955420478967

46 1.7560836401632383

46 3.3419380735652897

46 2.8290305398668245

46 2.951901023302089

46 2.9400525658126675

46 2.6769575714598948

46 1.55835425177616

如您所见,适应度似乎是随机的

一些忠告...

  1. 神经网络通常采用输入,该输入应以某种方式与输出相关。 我找不到该网络的任何输入? 如果您无法提出任何好主意,请使用XOR问题并尝试解决它。

  2. 在检查您的人口是否随着时间的推移而变得更好时,请不要注视每一代人的大脑。 请记住,您是故意创建一些随机网络,这些随机网络可能无法完成您的任务。 尝试打印每一代的最高成绩,也许是平均分数。 在可行的遗传算法中,两个值都应随时间而变好。 (尽管最高分更有意义,也更重要)

  3. (不直接解决您的问题)请勿使用javascript。 您可能可以将当前代码转换为java / c#/ c ++。 这些语言的执行速度比JS快。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM