Нейронная сеть не обучается глубже 1 слоя

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

Пробовал и подбирал самые разные примеры, разное количество слоев и нейронов, но ничего не меняется. Даже y = x1 && x2 не считает (пробовал 0-3 скрытых слоя с разным количеством нейронов).

Использую логистическую функцию для начала.

        function get_test_data(){
            var p = [MyRand(-2, 2), MyRand(-2, 2)];
            return{
                p: p,
                res: [p[0] && p[1] ? 1 : 0]
            }
        }
        function activate_fn1(x, de){
            if(!de){
                return 1/(1 + Math.exp(-x));
            }
            else{
                return activate_fn1(x, false)*(1 - activate_fn1(x, false));
            }
        }
        async function learn(){
            var ggg = 0;
            while(1){
                await sleep(sleeping);
                errors[ggg] = []; // для истории ошибок
                var test_data = get_test_data();
                for (var i = 0; i < test_data.p.length; i++) {
                    layers[0][layers[0].length - i - 1].value = test_data.p[i]; // заполняю х1, х2...
                }

                // прогоняю данные по нейросети
                for (var i = 0; i < connections.length; i++) {
                    for (var k = 0; k < connections[i].length; k++) {
                        if(layers[i + 1][k].is_bias) continue; // пропускаю нейрон смещения
                        layers[i + 1][k].value = 0;
                        for (var j = 0; j < connections[i][k].length; j++) {
                            layers[i + 1][k].value += layers[i][j].value*connections[i][k][j]; // значение += входное * вес связи
                        }
                        layers[i + 1][k].value = activate_fn1(layers[i + 1][k].value, false); // пропускаю значение через ф-ю активации;
                    }
                }
                //вычисляю ошибку
                for (var i = 0; i < test_data.res.length; i++) {
                    var diff = activate_fn1(test_data.res[i], false) - layers[layers.length - 1][i].value; // ожидаемый сигнал - полученный
                    layers[layers.length - 1][i].error = diff;
                    errors[ggg].push(Math.abs(diff));
                }
                // вычисляю ошибки для скрытых нейронов
                for (var i = connections.length - 1; i > 0; i--) {
                    for (var k = 0; k < connections[i][0].length; k++) {
                        layers[i][k].error = 0;
                        for (var j = 0; j < connections[i].length; j++) {
                            if(layers[i][k].is_bias) continue; // пропускаю нейрон смещения
                            layers[i][k].error += layers[i + 1][j].error*connections[i][j][k]; // ошибка += ошбика след. нейрона * вес связи
                        }
                        layers[i][k].error *= activate_fn1(layers[i][k].error, true); // ошибка = f'(x)
                    }
                }
                //исправляю ошибки
                for (var i = 0; i < connections.length; i++) {
                    for (var j = 0; j < connections[i].length; j++) {
                        for (var k = 0; k < connections[i][j].length; k++) {
                            // вес += скорость * ошибку выходного нейрона * значение входного нейрона
                            connections[i][j][k] = connections[i][j][k] + speed*layers[i + 1][j].error*layers[i][k].value;
                        }
                    }
                }
                ggg++;
            }
        }

Ответы (0 шт):