Проблема с простой искусственной нейронной сетью - добавление - PullRequest
11 голосов
/ 01 мая 2011

Я пытаюсь заставить простую искусственную нейронную сеть работать с алгоритмом обратного распространения. Я создал ANN и считаю, что правильно реализовал алгоритм BP, но, конечно, могу ошибаться.

Прямо сейчас я пытаюсь обучить сеть, задав ей два случайных числа (a, b) между 0 и 0.5 и добавив их. Затем, конечно, каждый раз, когда выходной сигнал сети сравнивается с теоретическим ответом a + b (который всегда будет достигнут функцией сигмоида).

Странно, но вывод всегда сходится к числу от 0 до 1 (как и должно быть из-за сигмоидальной функции), но вводимые мной случайные числа, похоже, не влияют на него.

Редактировать: Извините, похоже, он не сходится. Вот изображение вывода:

enter image description here

Веса случайным образом распределены между -1 и 1, но я также пробовал между 0 и 1.

Я также попытался дать ему два постоянных числа (0,35,0,9) и попытаться обучить его выплевывать 0,5. Это работает и сходится очень быстро до 0,5. Я также научил его выплевывать 0,5, если я даю ему любые два случайных числа от 0 до 1, и это тоже работает.

Если вместо этого моя цель:

vector<double> target;
target.push_back(.5);

Тогда он очень быстро сходится, даже при случайных входах:

enter image description here

Я пробовал пару разных сетей, так как я очень легко добавил слои в свою сеть. Стандартный, который я использую, - один с двумя входами, один слой из 2 нейронов и второй слой только с одним нейроном (выходной нейрон). Однако я также попытался добавить несколько слоев и добавить к ним нейроны. Кажется, это ничего не меняет. Моя скорость обучения равна 1,0, хотя я пробовал ее на 0,5, и она не сильно отличалась.

Кто-нибудь знает, что я могу попробовать?

Это даже на что способен ANN? Я не могу себе представить, что этого не произойдет, поскольку их можно научить делать такие сложные вещи.

Любой совет? Спасибо!

Вот где я тренируюсь:

//Initialize it. This will be one with 2 layers, the first having 2 Neurons and the second (output layer) having 1.
vector<int> networkSize;
networkSize.push_back(2);
networkSize.push_back(1);
NeuralNetwork myNet(networkSize,2);

for(int i = 0; i<5000; i++){
    double a = randSmallNum();
    double b = randSmallNum();
    cout << "\n\n\nInputs: " << a << ", " << b << " with expected target: " << a + b;

    vector<double> myInput;
    myInput.push_back(a);   
    myInput.push_back(b);   

    vector<double> target;
    target.push_back(a + b);

    cout << endl << "Iteration " << i;
    vector<double> output = myNet.backPropagate(myInput,target);
    cout << "Output gotten: " << output[0];
    resultPlot << i << "\t" << abs(output[0] - target[0]) << endl;
}

Редактировать: я настроил свою сеть и следовал этому руководству: A pdf . Я реализовал «Рабочий пример 3.1» и получил те же точные результаты, что и они, поэтому я думаю, что моя реализация верна, по крайней мере, настолько, насколько у них.

Ответы [ 2 ]

3 голосов
/ 01 мая 2011

В такой модели, как эта, сигмовидная функция (как в выходном, так и в промежуточном слоях) используется в основном для создания чего-то, что напоминает тумблер 0/1, хотя и является непрерывной функцией, поэтому ее используют длядиапазон номеров не то, для чего предназначена эта сеть.Это потому, что он разработан в основном с учетом проблем классификации.Конечно, есть и другие модели NN, которые могут делать подобные вещи (например, отбрасывать сигмоид на выходе и просто сохранять его как сумму своих дочерних элементов).

Если вы можете переопределить вашу модельс точки зрения классификации входных данных вы, вероятно, получите лучшие результаты.

Некоторые примеры аналогичных задач, для которых сеть будет более подходящей:

  1. Проверьте, больше ли выходили меньше определенной константы - это должно быть очень просто.
  2. Выход: серия выходов, каждый из которых представляет различное потенциальное значение (например, один выход для значений от 0 до 10, один для«больше 10» и один для «меньше 0»).Вы хотите, чтобы ваша сеть округляла результат до ближайшего целого числа
  3. Сложнее будет попытаться создать логическое представление вывода, имея несколько выходных узлов.

Нетиз них вы получите точность, которую вы можете пожелать, поскольку по своей природе NN более «размыты»

3 голосов
/ 01 мая 2011

Как утверждает @macs, максимальный вывод стандартной сигмоиды равен 1, поэтому, если вы попытаетесь добавить n чисел из [0, 1], тогда ваша цель должна быть нормализована, то есть сумма (A1, A2, ..., An) / n.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...