Здравствуйте. Во многих описаниях метода нашёл такую нестыковку. Вот, например http://www.aiportal.ru/articles/neural-networks/back-propagation.html. Обращаю внимание на формулу out = 1/(1+exp(-alpha w x)) alpha - параметр наклона сигмоиды. далее, при расчёте поправок весов умножают на частную производную от сигмоидальной функции по ошибке w: out (1 - out) x А куда делось alpha? самое интересное, данная ошибка присутствует практически во всех описаниях алгоритма. Вот я и не могу понять - то ли меня глючит, то ли всё содрано с одного и того-же источника? В учебнике "Нечёткая логика и нейронные сети" описано всё правильно, то есть вводится сигмоида, в выражении для производной присутствует параметр alpha. Но потом, видимо, для упрощения выкладок, берут alpha == 1 и оно везде пропадает. В педивикии производная вообще как-то по другому считается. Кстати, не исключено, что тоже косячно. На самом деле ошибка не такая уж и страшная. Если alpha не сильно отличается от единицы, то устойчивость не должна нарушиться. Это приведёт лишь к изменению скорости сходимости.
Вот, нашёл нормальное описание алгоритма, написал свою НС. Такая проблема. Задаю обучающий набор, запускаю сеть на обучение. Ошибка сначала уменьшается, потом останавливается вблизи некоторого числа и прыгает вокруг него. Я пробовал увеличивать число слоёв, изменять функцию активации - не помогло. Скорее всего, что-то апортачил с алгоритмом обучения. В некоторых статьях написано, что к функции активации нужно добавлять поправку, типа так: f(sum(x_i * w_i)) + delta и при обучении подгонять веса и эту самую дельту. В других про дельту ничего не говорится. Я дельту добавлять не стал. Могло это как-то на результат повлиять?
cupuyc Я когда разглядывал нейронные сети, нашёл книжку, в которой, в частности был пример -- там были входные данные и веса нейронов после обучения. Поищи что-нибудь в этом стиле. Или просто найди готовую реализацию и доточи свою до точного совпадения всех чисел. Сетка маловата, скорее всего. Попробуй обучить сеть решать неравенство x^2+y^2<1. Короче пускай сеть "угадывает" попадает ли точка в единичный круг с центром в начале координат. И после обучения нарисуй те точки, которые сеть считает принадлежащими кругу. А после этого поиграйся с количеством слоёв и их "толстотой", не забывая разглядывать те фигуры, которые сеть будет считать кругом. Там достаточно любопытно выходит -- какие-то треугольники вылезают (надо думать три плоскости сложенные пирамидкой и срезанные плоскостью координат), есть достаточно нарастить количество нейронов, то появляются шестиугольники и более сложные многоугольники (со сглаженными углами). Думается мне, что эти появление этих фигур где-то описано и обосновано математически, и соответственно, зная допустимый уровень ошибок, можно вычислить количество слоёв и нейронов в каждом слое, но я честно говоря уже не вдавался в эти подробности.
r90, спасибо за советы. Буду экспериментировать. Не подскажешь, хотя бы примерно, размер сетки для решения такого уравнения?
В общем х.з. Пробовал и скорость обучения менять и добавить пороговое значение и размер сети менять - всё без толку. Застопаривается на одном значении и прыгает вокруг него. Если увеличить размер сети - значение ошибки тоже увеличивается. Пробовал научит умножать 2 числа. У сети 2 входа, 1 выход, 10 внутренних слоёв, в каждом по 10 нейронов. Точно так же. Сначала ошибка уменьшается, потом встаёт на одном месте. Собственно вопрос: а ошибка вообще должна снижаться? Могу я добиться изменением конфигурации, параметров сети добиться того, чтобы ошибка по каждому из примеров (умножение двух чисел, каждое в пределах от 0..1) не превышала, скажем 0.0001? Алгоритм проверил.. всё, вроде, правильно..
cupuyc Если в качестве выхода сети брать не полный диапазон значений сигмоиды, то конструкция сети значительно упрощается: первый нейрон вычисляет функцию S(a) второй нейрон вычисляет функцию S(a+b) третий нейрон вычисляет их разность S(S(a+b)-S(a)) Для A входным диапазоном берём участок где производная сигмоиды почти линейна(слева или справа от своего максимума), а для B входной диапазон еще меньше. Но это не проблема, так как добавив еще 2 входных нейрона мы можем получить нужный сдвиг и масштабирование. Возможно, что еще один нейрона нужен будет для сдвига результата.
3 нейрона пожалуй маловато, но вот вроде бы рабочий вариант с 4мя нейронами: Пусть S(s)=s/(1+|s|) - рациональная сигмоида, далее модуль рисовать не будем, считая что аргумент у нас положительный. первый нейрон вычисляет S(a)=a/(1+a) второй нейрон вычисляет S(b)=b/(1+b) третий нейрон вычисляет S(a+b)=(a+b)/(1+a+b) а четвёртый вычисляет S(S(a)+S(b)-S(a+b)) S(a)+S(b)-S(a+b)=2ab*(1+a/2+b/2)/(1+a)/(1+b)/(1+a+b) - это точное выражение если мы возьмём a,b<1/500, то полученная сумма будет отличаться от 2ab не более, чем на 1%. А искажения вносимые 4м нейрном будут еще менее значительны. Если мы хотим перемножать числа в диапазоне от 0 до 1, то просто делим их на k, чтобы они попали в диапазон вычислений с нужной точностью, а потом результат умножаем на k^2/2.
Выкладываю свою нейросеть. Немного поправил алгоритм обучения. Умножению нейросеть научить получилось.
10 нейронов в скрытом, 2 во входном, 1 в выходном. Кстати, я пример поменял, новый залил. Сейчас решает именно такую задачу - перемножает 2 числа. Хотелось бы, чтобы чтобы кто-нибудь попробовал уменьшить ошибку вычислений. А то у меня слабенький ноут, довольно долго сеть обучается. Ошибка уменьшается, но медленно.