Страницы

Поиск по вопросам

пятница, 13 декабря 2019 г.

Простая нейросеть выдает результат ~0.5

#javascript #нейронные_сети


Пытаюсь реализовать простую нейронную сеть прямого распространения. Но результат,
который она выдает после обучения(методом обратного распространения ошибки) стремиться
к значению 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,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]));

Ответ 2



Благодаря пользователю sanmai я наконец решил свою проблему! Больше недели стараний, и вот у меня уже готовая нейронная сеть. Полностью переписал функцию тренировки, оказалось я использовал неправильные формулы. Привожу код, может кому-нибудь пригодится var hiddenLayer = 4, weight_1 = randArr(hiddenLayer, 2), //(скрытий слой, входной слой) weight_2 = randArr(1, hiddenLayer), //(выходной слой, скрытый слой) learning_rate = 1, data = [ [[0,0], 1], [[0,1], 0], [[1,0], 0], [[1,1], 1] ]; function randArr(rows, cols) { arr = []; for (var i = 0; i

Комментариев нет:

Отправить комментарий