Я продолжаю цикл статей по разработке метода безытеративного обучения нейронных сетей. В этой статье будем обучать однослойный персептрон с сигмоидальной активационной ф-ей. Но этот метод можно применить для любых нелинейных биективных активационных ф-й с насыщением и первые производные которых симметричны относительно оси OY.

В прошлой статье мы рассмотрели метод обучения основанный на решении СЛАУ, решать ее мы не будем т.к. это слишком трудоемкий процесс. Сейчас нас интересует из этого метода только вектор «B», в этом векторе отражено насколько важен тот или иной признак для классификации.

$\\B=\{b_1...b_m\}; \\b_k=-\sum_{i=1}^nx_k^i \cdot y^i; \\k \in [1,m];$



И тут из-за того, что имеется активационная ф-я с насыщением можно выразить веса как:

$\\W=\{w_1,...,w_m\}; \\W=K\cdot B; $



Первое, что необходимо сделать — это заменить $y^i$ на $t^i$. Т.к. в задачи классификации «y» может быть либо 1(принадлежит), либо 0(не принадлежит). То t должно быть либо 1, либо -1. Отсюда $t^i=2\cdot y^i-1$. Теперь

$b_k=-\sum_{i =1}^nx^i_k\cdot t^i;$



Теперь выразим коэффициент «K» как дробь, где в числителе функция, обратная ф-и активации от 0.99(от единицы взять нельзя т.к. будет +бесконечность), а в знаменателе сумма значений модулей всех элементов входящих в выборку(вероятно, можно использовать квадратный корень из энергии). И умножается все это на -1.

Итоговая формула получается:

$w_k=\frac{ f^{-1}_a(0.999)\cdot \sum_{i=1}^nx^i_k\cdot t^i}{\sum^n_{i=1}\sum^m_{j=1}|x^i_j|};$



Для сигмоиды, которая имеет вид $f_a(x) = \frac{1}{1+exp(-\beta\cdot x)}$, обратная ф-я — $f^{-1}_a(x) = -\frac{ln(\frac{1}{x}-1)}{\beta}$, при $\beta = 1; f^{-1}_a(0.99) = 4.6$

*Небольшая проверка
Пусть есть две пары $x^1 = \{1,0,1,0\}; y^1 = 1; x^2 = \{0.7,1,0.1,1\}; y^2 = 0; $. Рассчитаем веса по формуле приведенной выше:

$\\w_1= -1.83; \\w_2= -6.1; \\w_3= 5.49; \\w_4= -6.1; $



Теперь «прогоним» наши вектора через получившийся нейрон, напомню формулу отклика нейрона:

$y(x) = f_a(\sum_{i=1}^nw_ix_i);$



Первый вектор дал результат 0.997, второй — $ 2\cdot 10^{-6} $, что очень похоже на правду.

*Тестирование

Для тестирования была взята обучающая выборка 2 сигнала без шума, 1 и 2 Гц, 200 отсчетов. Одному герцу соответствует отклик НС {0,1}, двум {1,0}.

Во время тестирования распознавался сигнал + гауссов шум. ОСШ = 0.33

Ниже представлено распознавание:
1Гц, самый хороший результат
image
2 Гц, самый хороший результат

1 Гц, самый плохой результат


Учитывая, то что точность очень высокая(тестировал и на других сигналах). Я предполагаю, что данный метод сводит функцию ошибки в глобальный минимум.

Код обучения:
	public void Train(Vector[] inp, Vector[] outp)
		{
			OutNew = new Vector[outp.Length];
			In = new Vector[outp.Length];
			Array.Copy(outp, OutNew, outp.Length);
			Array.Copy(inp, In, inp.Length);
			
			
			for (int i = 0; i < OutNew.Length; i++)
			{
				OutNew[i] = 2*OutNew[i]-1;
			}
			
			
			K = 4.6*inp[0].N*inp.Length;
			
			double summ = 0;
			
			for (int i = 0; i < inp.Length; i++)
			{
				summ += Functions.Summ(MathFunc.abs(In[i]));
			}
			
			K /= summ;
			
			
			Parallel.For(0, _neurons.Length, LoopTrain);
		}
		
		
		void LoopTrain(int i)
		{
			
			for (int k = 0; k < In[0].N; k++) {
				
				for (int j = 0; j < OutNew.Length; j++)
				{
					_neurons[i].B.Vecktor[k] += OutNew[j].Vecktor[i]*In[j].Vecktor[k];
				}
			
			}
			
			_neurons[i].W = K*_neurons[i].B;
		}


В дальнейших статьях планирую рассмотреть, обучение многослойных сетей, генерацию сетей с оптимальной архитектурой и обучение сверточных сетей.
Поделиться с друзьями
-->

Комментарии (16)


  1. Firstprime
    16.07.2017 10:35
    +1

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


    1. Zachar_5
      16.07.2017 10:43
      +1

      Ну мне хватает))
      Цифры назвать не могу.
      Вообще хочу открыть свое дело на своих разработках, но это не реально сложно, вряд ли получится, но надо по пробовать. Вот мой основной проект, если интересно. Возможно и о нем напишу. Как закончу с НС.



      1. GoldenStar
        16.07.2017 11:57
        +1

        Впечатляет! Хороший уровень… просто завидую в хорошем смысле этого слова )
        Хочу поработать в области оптического распознавания образов, но пока что не хватает времени, так как надо освоить железячную часть.


  1. alexeykuzmin0
    18.07.2017 18:08

    Пожалуйста, объясните, почему веса нейронов — это константа, умноженная на b?


    1. Zachar_5
      18.07.2017 23:34

      K — это нормировочный коэффициент. А b_k показывает насколько важен k-й признак для классификации.


      1. alexeykuzmin0
        19.07.2017 13:15

        Тогда почему для b_k используется именно такая функция, а не что-нибудь другое, показывающее важность признака, скажем, корреляция какая-нибудь? Это было проверено на практике и работает лучше, чем другие решения?
        И, кстати, а почему берется именно f(0.99), а не f(0.98) или f(0.995)?


        1. Zachar_5
          19.07.2017 15:17

          Да было проведено несколько тестов, вообще-то до сих пор тестирую. Вариант с корреляцией был проверен, вот ссылка на него https://vk.com/ai_2016?w=wall-64012508_204.
          Я изменил на f(0.999). Вообще этот коэффициент пока подбирается экспериментально. По логике он должен стремиться к +inf. Но на практике, я получил хорошие результаты когда подставил вместо f(x) 25.


          1. alexeykuzmin0
            20.07.2017 12:24

            Здорово, что эти значения были взяты именно из практики. А вы сравниваете полученные результаты с другими методами обучения той же самой модели, скажем, градиентным спуском? Было бы очень интересно посмотреть, насколько отличается качество и скорость на разных реальных задачах.

            А насчет коэффициента, повышающего веса — интуитивно кажется, что чем он больше, тем выше будет качество модели, и тем проще переобучиться. Не зря же во всяких L1,2 и иже с ними штрафуют слишком большие коэффициенты.


        1. AC130
          19.07.2017 21:15

          Для линейно сепарабельного случая конкретно такая пропорциональность весов вполне может иметь место. А более сложные случаи однослойный персептрон и не должен охватывать.


          1. Zachar_5
            20.07.2017 00:02

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


    1. Zachar_5
      19.07.2017 01:08

      Я имею право так делать, т.к. стоит задача классификации, а не регрессии. И имеется ф-я с насыщением, которая "сгладит" все неточности.


      1. alexeykuzmin0
        19.07.2017 13:18

        И все же непонятно, почему вы имеете право так делать. Здесь ведь нет итераций, значит, мы хотим получить точный ответ сразу, разве не так?


        1. Zachar_5
          19.07.2017 15:39

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



          1. alexeykuzmin0
            20.07.2017 12:27

            Есть ли какие-то основания полагать, что та же самая формула будет оптимальна и при решении любой другой задачи классификации?


            1. Zachar_5
              20.07.2017 18:05

              Ну что тут сказать, тестирую! На MNIST`е буду сегодня завтра гонять.


            1. Zachar_5
              24.07.2017 16:52
              +1

              На MNIST плохой результат, 63%. Сейчас дорабатываю метод обучения скрытого слоя.