簡體   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