我一直在尝试进化一种神经网络,使用遗传算法打印收敛到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如你所见,适应度似乎是随机的。
发布于 2017-09-18 15:53:31
一些建议。
,
快得多。
https://stackoverflow.com/questions/46166306
复制相似问题