Нейроны в действии

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

    Задача: Определить четность или нечетность числа по его двоичному представлению.

    Собственно говоря это задача классификации объектов с которой нейронные сети справляются достаточно хорошо (нейронные сети могут решать ограниченный спектр задач). Приступим.


    Немного теории


    Нейрон — составная часть любой нейронной сети. В состав нейрона входят умножители (входы), сумматор и нелинейный преобразователь. Входы осуществляют связь между нейронами и умножают входной сигнал на число, характеризующее силу связи, весовой коэффициент входа. Сумматор выполняет сложение сигналов, поступающих по входным связям от других нейронов, и внешних входных сигналов. Нелинейный преобразователь реализует нелинейную функцию одного аргумента — выхода сумматора. Эта функция называется «функция активации» или «передаточная функция» нейрона. Нейрон в целом реализует скалярную функцию векторного аргумента.

    Синтез сети


    Синтез сети является в общем случае сложной задачей. В нашем случае для решения этой задачи нам хватит сети из одного нейрона. На входы нейрона будем подавать соответствующие разряды числа в двоичном виде (для простоты ограничимся диапазоном от 0 до 255). Т.е. наш нейрон будет иметь восемь входов и один выход.

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

    Теперь определим как мы будем модифицировать весовые коэффициенты во время работы нейрона. Если ответ нейрона был верным необходимо увеличить веса входов которые были активированы, и уменьшить в противном случае. К исходному весу нейрона мы будем прибавлять (вычитать) произведение соответствующего входа на исходный вес и на коэффициент обучения и все это деленное на сумму весов нейрона. Коэффициент обучения влияет на скорость обучения, но его увеличение может привести к ошибочной работе нейрона.

    Реализация


    Класс на C# реализующий наш нейрон.

    1. public class Neuron
    2.   {
    3.     int[] input = new int[8];      //входы
    4.     double[] weight = new double[8];  //веса входов
    5.  
    6.     double mx = 0;           //средний вес
    7.     double sum = 0;           //сумма входов умноженных на вес
    8.     int k = 1;             //коэфициент обучения
    9.  
    10.     public Neuron()
    11.     {
    12.       for (int i = 0; i < 8; i++)
    13.       {
    14.         weight[i] = 1;       //начальные веса можно задать любые
    15.                       //согласно с принятыми ограничениями
    16.       }
    17.     }
    18.     public byte Analyze(byte b)
    19.     {
    20.       for (int i = 0; i < 8; i++)
    21.       {
    22.         input[i] = 0;
    23.       }
    24.       for (int i = 0; i < 8; i++)   //кривенькое преобразование в двоичный вид
    25.       {
    26.         if ((b / 2) != 0)
    27.         {
    28.           input[i] = b % 2;
    29.           b = Convert.ToByte(b / 2);
    30.         }
    31.         else
    32.         {
    33.           input[i] = b % 2;
    34.           break;
    35.         }
    36.       }
    37.  
    38.       sum = 0;
    39.       mx = weight.Sum() / 8;     //считаем средний вес
    40.  
    41.       for (int i = 0; i < 8; i++)
    42.       {
    43.         if (weight[i] > 0)     //считаем сумму
    44.           sum += weight[i] * input[i];
    45.       }
    46.  
    47.       if (sum > mx)          //определяем выход нейрона
    48.         return 1;
    49.       else
    50.         return 0;
    51.     }
    52.     public void Yes()          //обучение при верном ответе
    53.     {
    54.       double s = weight.Sum();
    55.       for (int i = 0; i < 8; i++)
    56.       {
    57.         weight[i] += input[i] * (weight[i] / s) * k;
    58.       }
    59.       this.Normalize();
    60.     }
    61.     public void No()          //обучение при неверном ответе
    62.     {
    63.       double s = weight.Sum();
    64.       for (int i = 0; i < 8; i++)
    65.       {
    66.         weight[i] -= input[i] * (weight[i] / s) * k;
    67.       }
    68.       this.Normalize();
    69.     }
    70.     private void Normalize()      //чтобы коэфициенты не зашкаливали и для наглядности
    71.     {                  //оставляем в них не более двух разрядов до запятой
    72.       double min = weight.Min();
    73.       double max = weight.Max();
    74.       int pow = 0;
    75.       double b = max / 10;
    76.       while (b > 1)
    77.       {
    78.         b = b / 10;
    79.         pow++;
    80.       }
    81.  
    82.       for (int i = 0; i < 8; i++)
    83.       {
    84.         weight[i] = weight[i] / Math.Pow(10, pow - 1);
    85.       }
    86.     }
    87.     public void Reset()         //сброс весов
    88.     {
    89.       for (int i = 0; i < 8; i++)
    90.       {
    91.         weight[i] = 1;
    92.       }
    93.     }
    94.                       //свойства по вкусу
    95.     public string Bytes
    96.     {
    97.       get
    98.       {
    99.         string str = "";
    100.         for (int i = 0; i < 8; i++)
    101.         {
    102.           str += input[i].ToString();
    103.         }
    104.         return str;
    105.       }
    106.     }
    107.     public string Weights
    108.     {
    109.       get
    110.       {
    111.         string str = "";
    112.         for (int i = 0; i < 8; i++)
    113.         {
    114.           str += weight[i].ToString();
    115.           str += " ";
    116.         }
    117.         return str;
    118.       }
    119.     }
    120.     public string Mx
    121.     {
    122.       get
    123.       {
    124.         return mx.ToString();
    125.       }
    126.     }
    127.     public string Sum
    128.     {
    129.       get
    130.       {
    131.         return sum.ToString();
    132.       }
    133.     }
    134.   }
    * This source code was highlighted with Source Code Highlighter.

    Замечания


    Обучение нейрона организовать очень просто, нужно альтернативным способом проверить четность (нечетность) числа и сказать ему верный или нет был его ответ. В итоге у правильного обученного нейрона все веса кроме веса при первом разряде (собственно если он равен 1 число нечетное, если 0 то четное) станут крайне малыми, что говорит о том что они не как не влияют на четность (нечетность), а этот единственный вес будет расти, что говорит о его значимости. Наш нейрон безошибочно будет работать в выбранном диапазоне чисел уже после пары тысяч обучающих прогонов, а вот если, например, веса поменять на 1 и 0, и изменять соответственно на единицу то нейрон обучить можно за десяток прогонов и у обученного нейрона все веса кроме веса при первом разряде будут равны 0, а он будет равен 1.
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 21

      0
      орактического применения этому не вижу, но познавательно, заинтересовали нейронные сети
        –6
        Convert.ToString(b, 2);
          –4
          mov ax, 100101b ;some int
          div 2
          cmp ah, 0
          jz some_proc
            –2
            ~penis-comparator mode on~

            Слишишь? Ти умный такой, да?

            mov ax,
            and ax, 1
            jz l_odd_value

            ~penis-comparator mode off~

            ЗЫ. А вообще, тут какбэ топик про нейронки :-P

        • НЛО прилетело и опубликовало эту надпись здесь
            0
            Пожалуйста. Если позволит график, постараюсь написать в ближайшее время об агентах с нейронными сетями внутри, а попозже о структуре сетей, и алгоритмах обучения. Тема разрабатывается давно, много уже написано до нас, так что далее буду приводит ссылки на использованную литературу.
            –3
            Статья ни о чем
              0
              я бы не сказал… конкретно этот пример может быть и не имеет практического применения, но общая тематика интересна и мне кажется еще проявит себя.
                +1
                По этой тематике на хабре уже есть куча статей гораздо лучшего качества
                  –1
                  *мысля в воздух*
                  Если бы я хотел подобным комментарием помочь людям — я бы сразу дал ссылку на эти статьи или на страницу поиска с выдачей этих статей…
              0
              Поддерживаю. Совершенно бессмысленный пример задачи и не очень красивый код. Да и тема заезженная, хотя и интересная.
              0
              Судя по комментариям народ тут в основной своей массе не сталкивался с нейронным программированием, за исключением всяких там файнреадеров.

              Статья наглядная и простая, но только для тех, кто «в теме». Начинающим «нейронщикам» может и помочь.
                0
                было бы интересно узнать про другие применения в примерах…
                  0
                  Как пример — распознавание и обучение распознавания текста в файнриадере.
                    0
                    обучение — это отличное свойство. обширная тема для изучения.
                +3
                Статья ничего, только один пример из нейросети на одном нейроне — это мало, узко, и довольно неинтересно. Очень хочется почитать об организации более сложных сетей: как, зачем, как рассчитать, как запрограммировать. Как одиночная статья — мало и пусто. Если будет продолжение — то это введение — очень ничего:)
                  0
                  Например
                  — регулирование каких-либо процессов на основе показаний различных датчиков.
                  — измерение каких-либо величин на основе этих же показаний (например тех, что напрямую измерять либо очень дорого, либо очень сложно ввиду специфики измерений).
                  — сортировка по каким-либо неявным признакам (например фотографий по наличию веснушек на лице или по форме глаз)
                  и т.д.

                  Если как-нибудь собирусь — напишу об этом статью, если конечно ничего подобного еще не писали и вообще кому-то это интересно.
                    0
                    нейросети интересны. Поэтому по ним и пишут заметки.
                  –1
                  ужас насколько автор далёко от темы :(
                    0
                    Перенесите в соответствующий блог, пожалуйста.

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое