Нейронная сеть Javascript не сходится

1

Я пытался создать нейронную сеть, которая печатает ценности, сходящиеся к одной, используя генетический алгоритм.

Я пробовал отлаживать код, но не знаю, что я испортил.

Я использую фитнес, чтобы выбрать лучшие "мозги", а затем пересечь их (размножаться).

На данный момент он только пытается развить "мозги", которые возвращают число. пригодность - это функция разницы между возвращаемым числом и исходным числом.

"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

Как вы можете видеть, фитнес кажется случайным

  • 0
    Этот вопрос, вероятно, будет помечен как слишком широкий, изначально основанный на мнениях, и как поиск помощи в отладке. Пожалуйста, прочитайте Как мне задать хороший вопрос? ,
  • 0
    @The_Black_Smurf У вас есть опыт работы с нейронными сетями? Прошу помощи по нейронным сетям, а не по отладке.
Показать ещё 2 комментария
Теги:
neural-network
artificial-intelligence
genetic-algorithm

1 ответ

-2

Некоторые советы...

  1. Нейронные сети обычно берут вход, который должен каким-то образом быть связан с выходом. Я не мог найти никаких входов для сети? Если вы не можете придумать какие-либо хорошие идеи, просто используйте проблему XOR и попытайтесь ее решить.

  2. Когда вы проверяете, со временем ли ваше население становится лучше, не смотрите на все мозги каждого поколения. Помните, что вы намеренно создаете некоторые рандомизированные сети, которые могут или не могут быть хорошими в вашей задаче. Попробуйте напечатать Top результат каждого поколения и, возможно, средний балл. В рабочем генетическом алгоритме обе ценности должны со временем стать лучше. (хотя верхний балл является более значимым и важным)

  3. (Не прямое обращение к вашей проблеме) Не используйте javascript. Возможно, вы могли бы переписать свой текущий код на java/С#/c++. Эти языки работают быстрее, чем JS.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню