Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Нейронная сеть на action script, не обучается (http://www.flasher.ru/forum/showthread.php?t=198731)

KokoZzz 03.05.2013 13:38

Нейронная сеть на action script, не обучается
 
Добрый день, уважаемые!

прошу у Вас помощи, ибо 3й день я не могу найти ошибку в написанном мной алгоритме обучения нейросети, казалось бы проще уже не бывает: гомогенная нейронная сеть с биполярной сигмоидной функцией и обучением при помощи обратного распространения ошибки...

один нейрон учится командам AND и OR, однако стоит добавить еще один слой и попытаться обучить команде XOR, как сетка начинает ворочить носом и и выдавать что угодно, лишь бы не "исключающе или" (структура сети для XOR сделана совершенно стандартная, из книжек).


p.s. не нашел более подходящего раздела, ибо исходники у меня на Action Script'e

p.s.s. если появитятся добрые люди, имеющие возможность и желание помочь, выложу исходники и литературу, на которую я опирался при написании своей программы, а также опишу всю структуру нейросети, чтобы Вам не пришлось сидеть и разбираться что у меня к чему (код обучения, кстати, с коментариями).

p.s.s.s. если честно я на панике, это часть моего диплома, защита приддипломной практики которого будет 7 числа =(

Добавлено через 19 минут
конено, у меня есть и примеры и код.
проект лежит в дроп боксе, могу дать ссылку

функция обучения сети:
Код AS1/AS2:

public function train():void{
        var iter:int = 0;
        while (iter++<1000){
 
                for (var ei:int = 0; ei < learningInputArray.length; ei++){//обход обучающих примеров
                        //прямой прогон
                        var output:Number = computeResult(learningInputArray[ei].inputSignalArray);
                        var realOutput:Number = learningInputArray[ei].realOutput;
 
                        for (var li:int = neuralLayerArray.length - 1; li >= 0; li--){//обход слоев сети
                                var neuralLayer:NeuralLayer = neuralLayerArray[li];
 
                                for (var ni:int = 0; ni < neuralLayer.neuronArray.length; ni++){// обход нейронов в сети
                                        var neuron:Neuron = neuralLayer.neuronArray[ni];
                                        var inputSignal:Signaller;
                                        var delta:Number = 0;
                                        var error:Number = 0;
 
                                        if (li == neuralLayerArray.length - 1){//если выходной слой:
                                                //расчет ошибки:
                                                error = output - realOutput;
                                        } else {//если скрытый слой:
                                                error = 0;
                                                //расчет распространения ошибки:
                                                var nextNeuralLayer:NeuralLayer = neuralLayerArray[li+1];
                                                for (var nnl:int = 0; nnl<nextNeuralLayer.neuronArray.length; nnl++){
                                                        var learnedNeuron:Neuron = nextNeuralLayer.neuronArray[nnl];
                                                        error += 0.5*learnedNeuron.learningError * learnedNeuron.synapticPowerArray[ni] * (1 - learnedNeuron.outputSignal*learnedNeuron.outputSignal);
                                                }
                                        }
                                        neuron.learningError = error;
 
                                        //корректировка входных весов нейрона:
                                        for (var spah:int = 0; spah<neuron.synapticPowerArray.length; spah++){
                                                inputSignal = neuron.inputSignalArray[spah];
                                                neuron.synapticPowerArray[spah] = neuron.synapticPowerArray[spah] - 0.5*error*(1 - neuron.outputSignal*neuron.outputSignal)*inputSignal.outputSignal;
                                        }
                                        //корректировка активационного барьера:
                                        neuron.activationBarrier = neuron.activationBarrier + 0.5*error*(1 - neuron.outputSignal*neuron.outputSignal)
                                        trace("first layer");
 
 
                                }
                        }
                }
 
 
        }
}

активационная функция нейрона:
Код AS1/AS2:

override public function compute(v:Number):Number{
        var e:Number = Math.E;
        return 2/(1 + Math.pow(e, (-1*v)))-1;
}

основной материал, на который я опирался: http://www.machinelearning.ru/wiki/i...LDA2011no1.pdf

wvxvw 04.05.2013 01:51

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

Да, еще такой вопрос: не пытаясь проанализировать код. На numeric underflow проверяли? Такое сложение чисел с плавающей запятой как у вас как правило ведет к большим ошибкам (тем более, что у вас значения должны быть в пределах [0,1].
Вместо
Код:

var sum:Number = 0;
for (var i:int = 0; i < N; i++) {
    sum += 0.000XXX; // some small number
}

лучше делать:

вот по этой формуле: http://en.wikipedia.org/wiki/Kahan_summation_algorithm

Код:

function kahanSum(input: Vector.<Number>): Number {
    var sum: Number = 0.0;
    var c: Number = 0.0; //A running compensation for lost low-order bits.
    for (var y: Number, t:Number, i: int = 1; i < input.length; i++) {
        y = input[i] - c    //So far, so good: c is zero.
        t = sum + y        //Alas, sum is big, y small, so low-order digits of y are lost.
        c = (t - sum) - y  //(t - sum) recovers the high-order part of y; subtracting y recovers -(low part of y)
        sum = t            //Algebraically, c should always be zero. Beware eagerly optimising compilers!
        //Next time around, the lost low part will be added to y in a fresh attempt.
    }
    return sum;
}

Адаптировано из Википедии.

А еще есть смысл тут посмотреть. http://www.ibiblio.org/pub/languages/fortran/ch4-9.html Тут есть и посиск арифметического среднего и т.п. Может быть весьма полезно для работы с числами с плавающей запятой.


Часовой пояс GMT +4, время: 18:46.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.