Пытаюсь реализовать простую нейронную сеть прямого распространения. Но результат, который она выдает после обучения(методом обратного распространения ошибки) стремиться к значению 0.5. Хоть после 1000 эпох обучения, хоть после 10000. Она имеет 3 входа, 2 нейрона в скрытом слое и 1 нейрон результирующий.
А если не обучать её, а с только что сгенерированными весами заставить принимать решение, то её ответ колебается в диапазоне от 0.5 к 1.
Вот код того, что есть на данный момент.
/*var weight_1 = [[0.79, 0.44, 0.43],
[0.85, 0.43, 0.29]],
weight_2 = [[0.5, 0.52]],*/
var weight_1 = randArr(2, 3),
weight_2 = randArr(1, 2),
learning_rate = 0.05,
data = [
[[0,0,0], 0],
[[0,0,1], 1],
[[0,1,0], 1],
[[0,1,1], 0],
[[1,0,0], 1],
[[1,0,1], 0],
[[1,1,0], 0],
[[1,1,1], 1]
];
console.log("---------До тренировки---------");
console.groupCollapsed("Prediction before");
predictSet(data);
console.groupEnd();
function randArr(rows, cols) {
arr = [];
for (var i = 0; i
Было бы неплохо если у кого-нибудь найдется похожая, но рабочая нейронная сеть. Тогда я мог бы получить результат тренировки на определенных статичных весах и ориентироваться на правильности своей нейросети.
Ответ
Возьмём фреймворк для постройки сетей, воссоздадим архитектуру вашей сети и... Увидим что даже заведомо правильная работающая сеть не может выявить закономерности в ваших входных данных. Для заведомо отрицательного образца [1,1,0] сеть показывает результат в пределах 0.5. Если посмотреть на ошибку обучения, то на 20000 итерациях она будет порядка 0.2, из чего самого по себе можно сделать вывод что архитектуры сети недостаточно.
Вы можете сколько угодно пытаться исправить алгоритм, но у вас ничего не получится без изменения и усложнения архитектуры. В качестве эксперимента можно попробовать руками подобрать веса, которые бы давали правильный ответ. Уверен что это невозможно сделать даже человеку, что уж говорить об алгоритмах, которые даже с горы толком спуститься не могут
var myNetwork = new synaptic.Architect.Perceptron(3, 2, 1)
var trainer = new synaptic.Trainer(myNetwork)
var trainingSet = [
{
input: [0,0,0],
output: [0]
}, {
input: [0,0,1],
output: [1]
}, {
input: [0,1,0],
output: [1]
}, {
input: [0,1,1],
output: [0]
}, {
input: [1,0,0],
output: [1]
}, {
input: [1,0,1],
output: [0]
}, {
input: [1,1,0],
output: [0]
}, {
input: [1,1,1],
output: [1]
}
]
var trainingOptions = {
rate: .1,
iterations: 20000,
error: .005,
}
console.log(trainer.train(trainingSet, trainingOptions));
console.log(myNetwork.activate([0,0,1]));
console.log(myNetwork.activate([1,0,0]));
console.log(myNetwork.activate([1,1,1]));
console.log(myNetwork.activate([1,1,0]));
Если усложнить структуру, добавив три нейрона в скрытом слое... То система для того же отрицательного образца [1,1,0] показывает результат близкий к 0.1, то есть - ожидаемо негативный. Ошибка обучения минимальная. Это, конечно, не обязательно хорошо, но для нашего минимального
и исчерпывающего набора данных к ошибке нет вопросов.
(Хватило бы добавить и двух нейронов, но для надёжности - лучше больше.)
var myNetwork = new synaptic.Architect.Perceptron(3, 5, 1)
var trainer = new synaptic.Trainer(myNetwork)
var trainingSet = [
{
input: [0,0,0],
output: [0]
}, {
input: [0,0,1],
output: [1]
}, {
input: [0,1,0],
output: [1]
}, {
input: [0,1,1],
output: [0]
}, {
input: [1,0,0],
output: [1]
}, {
input: [1,0,1],
output: [0]
}, {
input: [1,1,0],
output: [0]
}, {
input: [1,1,1],
output: [1]
}
]
var trainingOptions = {
rate: .1,
iterations: 20000,
error: .005,
}
console.log(trainer.train(trainingSet, trainingOptions));
console.log(myNetwork.activate([0,0,1]));
console.log(myNetwork.activate([1,0,0]));
console.log(myNetwork.activate([1,1,1]));
console.log(myNetwork.activate([1,1,0]));
Комментариев нет:
Отправить комментарий