все началось с того, что я призадумался о возможных переменах в мире, в том числе, на рынке труда, и решил минимизировать риски потери клиентов и заказов восстановлением навыка программирования. типа если вдруг консалтинг накроется, на продавцах будут экономить, а среди тренеров возникнет безумная конкуренция, - почему бы не прокачаться еще по одной специальности, - вдруг, это поможет увеличить шансы?
короче, я послушал кучу обучающих видео, стал разбираться в Python, прошелся по разным полезным библиотекам, вспомнил JavaScript и SQL. тяжело идет Django, но я почти освоил.
запрограммировал пару интересных (для меня) задачек.
но это общие слова.
в этом тексте хочу рассказать о том, как решил задачку по созданию и исследованию нейронной сети (без использования библиотек для работы с нейронными сетями), то есть прям вот с нуля.
задачка такая.
дано:
сеть из двух слоев, 1 нейрон в выходном слое, 4 нейрона в скрытом.
надо ее обучить так, чтобы она выдавала 1, 2, 3 или 4 в зависимости от того, какая комбинация единиц и нулей подается на вход из вектора 1x4, ну или 2x2.
типа как-бы есть картинка 2 на 2 пикселя черно-белых, и сеть надо так научить, чтобы она правильно выдавала соответствующее число для данной "картинки".
в принципе, задачу можно расширить на более сложную, типа распознавать изображения букв или чисел, записанные черно-белыми пикселями, но решил начать с простого.
с чего я начал?
полез в книжный шкаф и достал книжки, которые я лет 20 назад привез из Америки, по которым писал диссертацию (в области neuro-fuzzy систем). перечитал, проштудировал, вспомнил теорию.
попытался почитать что-то современное на русском, но ничего более продвинутого не нашел.
стал программировать.
выбрал функцию активации.
нарисовал полную топологию сети.
сделал пробный прогон без обучения, - понятно, получилась фигня.
пора обучать.
выбираю, что учить буду простым BackPropagation.
первая проблема, с которой столкнулся: формулы из книжки по изменению весов кривые. и если их применять в лоб, сеть не учится, а идет вразнос.
пришлось исследовать и выбирать подходящую формулу коррекции весов для разных слоев.
вторая проблема: в каком порядке проводить обучение? то есть учить каждый вход-выход по порядку, пока не научится? или как-то чередовать в процессе? или что?
тоже было прикольно, - мало кто об этом пишет, как о задачке, - а тут не все тривиально.
третья проблема: выбор количества эпох (циклов) обучения. для опытных это уже не проблема, я теперь понимаю, - гоняй-учи столько, пока не научится. а я реально день-два не мог сообразить, почему сеть отлично и быстро учится 3 из 4, а 4-му входу никак не может. много чего перепробовал, пока не рискнул увеличить количество циклов в 100 раз.. ;) получилось!
смотрите, какие красивые графики сходимости ошибки для 3 параметров (и как быстро сходится),
и как оно для всех 4х:
в итоге все получилось.
но надо было проверить еще одну вещь: а какова в результате чувствительность обученной сети?
и я был бы рад громко заявить, что нейронная сеть, - просто чудо техники и природы, и что после обучения она может предсказывать промежуточные значения, и все такое, что непрофессионалы ей приписывают.
но нет. сорри.
как показало исследование, сетка хорошо себя ведет только в пределах допуска обучения. дальше либо непредсказуемо, либо с серьезными ошибками.
смотрите на картинке (здесь график варьирования по каждой координате (4) для каждого входа (4)):
здесь 20 по оси X, - это целевое значение, для которого сетка обучалась по каждой координате. согласитесь, очень хорошо.
по 10 точек влево и вправо от значения 20, - это в диапазоне ошибки обучения. скажу, что довольно неплохо.
а дальше, - от 10 влево и от 30 вправо, - по разному. точнее, без гарантий.
а чего вы хотели?
такие пироги.
Удачи!
P.S. я не ставил своей целью кого-то переубедить, что нейронные сети позволяют творить чудеса.
просто знайте, что в этой области чудес нет.
то есть нет никаких гарантий, что сеть будет предсказывать то, чему ее не учили.
как бы вам круто эту идею ни продавали.. ;)