首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Javascript神经网络不收敛

Javascript神经网络不收敛
EN

Stack Overflow用户
提问于 2017-09-12 08:53:23
回答 1查看 82关注 0票数 1

我一直在尝试进化一种神经网络,使用遗传算法打印收敛到1的值。

我试着调试代码,但不知道我搞砸了什么。

我正在使用适应度来选择最好的“大脑”,然后将它们杂交(复制)。

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

代码语言:javascript
复制
"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);

我需要改进/改变什么?

控制台日志如下:

代码语言:javascript
复制
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

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

EN

回答 1

Stack Overflow用户

发布于 2017-09-18 15:53:31

一些建议。

  1. 神经网络通常接受的输入应该以某种方式与输出相关。我找不到网络的任何输入?如果你想不出任何好的想法,那就使用异或问题并尝试解决它。

  1. ,当检查你的人口是否随着时间的推移而变得更好时,不要查看每一代人的所有大脑。请记住,您正在故意创建一些随机网络,这些网络可能适合您的任务,也可能不适合您的任务。尝试打印每一代的Top result,以及可能的平均分数。在一个有效的遗传算法中,随着时间的推移,这两个值都应该变得更好。(尽管最高分更重要& important)
  2. (Not直接解决了你的问题)不要使用javascript。您可以将当前代码转换为java/c#/c++。这些语言的执行速度比JS。

快得多。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46166306

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档