Обучение нейронной сети

Реализация на Scilab процесса обучения нейронной сети

Соберём уже знакомые функции, которые нам понадобятся:

  
clc; clf();

function s = sigmoida(V)  
    x = 1 ./ ( 1 + exp(-V) );  
    s = roundToDecimal(x, 4);
endfunction

function co = computeNeuronLayer(V, W)
    co = W * V;
endfunction

function rd = roundToDecimal(x, m)
    rd = round(x * 10^m) / 10^m;
endfunction

Зададим число узлов (нейронов) и слоёв в нашей сети:

  
rows = 5;
layers = 4;  

И сгенерируем нейросеть со случайными матрицами весовых коэффициентов:

  
[neuralNetwork, weightMatrixes] = createNeuralNetwork(rows, layers);

function [net, matr] = createNeuralNetwork(n, m) 
   net = zeros(n, m);
   net(:, 1) = roundToDecimal( rand(1, n), 2); 
    
   matr = list();   
   for i = 1:m-1
      matr($+1) = roundToDecimal( rand(n, n), 2);
   end
endfunction 
  

здесь
\(net - \) это матрица нейросети размером \( 5\times 4 \), первый столбец которой - случайный входной вектор, например:

\( net = \begin{pmatrix} 0.21 & 0. & 0. & 0. \\ 0.76 & 0. & 0. & 0.\\ 0. & 0. & 0. & 0.\\ 0.33 & 0. & 0. & 0.\\ 0.67 & 0. & 0. & 0. \end{pmatrix} \)

\(matr - \) гипер-структура list, элементами которой являются весовые матрицы размером \( 5\times 5 \) со случайно сгенерированными значениями, например:

\( weightMatrixes(1) = \begin{pmatrix} 0.29 & 0.65 & 0.61 & 0.57 & 0.12\\ 0.86 & 0.99 & 0.85 & 0.57 & 0.73\\ 0.85 & 0.05 & 0.06 & 0.82 & 0.27\\ 0.53 & 0.75 & 0.83 & 0.06 & 0.55\\ 0.99 & 0.41 & 0.93 & 0.56 & 0.99 \end{pmatrix} \)

Зададим количество итераций \( lim \), массив для сбора результата каждой эпохи \( epoch \), скорость обучения нейросети \( educationSpeed \) и эталонный выход \( vectorOutputEtalon \):

  
lim = 200;
epoch = [];
educationSpeed = 0.5;

vectorOutputEtalon = [0.6; 0.8; 0.2; 0.5; 0.1];  

И с помощью цикла \( for \) проведём обучение неросети на Scilab:

  
for i=1:lim             
        // прямое распространение сигнала
        for j = 1:layers-1        
            neuralNetwork(: ,j+1) = sigmoida( computeNeuronLayer(neuralNetwork(: ,j), weightMatrixes(j)) ); 
        end
        
        epoch(:,i) = neuralNetwork(:,layers);        
        
        // ОРО и корректировка весов  
  		
        // ошибка на выходном слое
        errorVector = list();
        errorVector($+1) = vectorOutputEtalon - neuralNetwork(:, layers);
               
        dW = list();    
        for k = layers:-1:2
  
        // ошибка на внутренних слоях
            Ek = errorVector(1);                          
            errorVector(0) = weightMatrixes(k-1)' * Ek;   
            
            j = k - 1;    
        // поправка для весов
            dW(0) = - educationSpeed * Ek .* neuralNetwork(: ,k) .* (1 - neuralNetwork(: ,k)) * neuralNetwork(: ,j)';    
        // обновление j-ой весовой матрицы  
            weightMatrixes(j) =  roundToDecimal( weightMatrixes(j) - dW(1), 4);
        end
    
end 

В первом вложенном цикле происходит прямое распространение сигнала в нейросети - заполнение всех столбцов матрицы \( neuralNetwork \).

Далее в текущий столбец \( epoch \) записывается полученный выходной вектор нейронки, он нам пригодится позже для отслеживания процесса обучения.

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

И, наконец, расчитываем весовую поправку \( dW \) и обновляем коэффициенты весовых матриц \( weightMatrixes \).

Обработка результа тренировки нейронной сети на Scilab

Для того, чтобы не сверять самостоятельно циферки на выходе нейросети с эталонными значениями, выведем график зависимости выходного слоя от эпохи (итерации) обучения:

  
t = 1:lim;

xtitle("Обучение нейронной сети", "эпохи", "значение на выходе");
xgrid();
legendString = '';
for j = 1:length(vectorOutputEtalon)
    plot(t, epoch(j,:) );
    gce().children.foreground = j+1;
    gce().children.thickness = 2;
        
    plot(t, 0*t + vectorOutputEtalon(j));
    gce().children.line_style = 2;
    gce().children.foreground = j+1;   
end
gca().data_bounds = [0, 0; lim, 1];
Приближение выходных значений нейросети к эталонным на Scilab Приближение выходных значений нейросети к эталонным на Scilab

Комментарии

Гость
Ответить
Войдите, чтобы оставить комментарий.
Гость
Ответить
Гость
Ответить
Гость
Ответить
Еще нет комментариев, оставьте первый.