2017-04-30 4 views
0

J'ai mis en œuvre un algorithme de propagation de retour de réseau neuronal dans MATLAB, mais il ne s'entraîne pas correctement. Les données d'apprentissage est une matrice X = [x1, x2], dimension 2 x 200 et j'ai une matrice cible T = [target1, target2], dimension 2 x 200. Les 100 premières colonnes T peuvent être [1; -1] pour la classe 1, et la seconde 100 colonnes T peuvent être [-1; 1] pour la classe 2.Mise en œuvre de l'algorithme de rétropropagation de réseau neuronal

theta = 0.1; % criterion to stop 
eta = 0.1; % step size 
Nh = 10; % number of hidden nodes 

Pour une raison quelconque l'erreur de formation totale est toujours 1.000, il ne va jamais près de le theta, donc il fonctionne pour toujours.

J'utilise les formules suivantes:

enter image description here

enter image description here

enter image description here

enter image description here

L'erreur de formation totale: enter image description here

Le code est bien documenté ci-dessous. J'apprécierais toute aide.

clear; 
close all; 
clc; 

%%('---------------------') 
%%('Generating dummy data') 
%%('---------------------') 
d11 = [2;2]*ones(1,70)+2.*randn(2,70); 
d12 = [-2;-2]*ones(1,30)+randn(2,30); 
d1 = [d11,d12]; 

d21 = [3;-3]*ones(1,50)+randn([2,50]); 
d22 = [-3;3]*ones(1,50)+randn([2,50]); 
d2 = [d21,d22]; 

hw5_1 = d1; 
hw5_2 = d2; 

save hw5.mat hw5_1 hw5_2 

x1 = hw5_1; 
x2 = hw5_2; 

% step 1: Construct training data matrix X=[x1,x2], dimension 2x200 
training_data = [x1, x2]; 

% step 2: Construct target matrix T=[target1, target2], dimension 2x200 
target1 = repmat([1; -1], 1, 100); % class 1 
target2 = repmat([-1; 1], 1, 100); % class 2 
T = [target1, target2]; 

% step 3: normalize training data 
training_data = training_data - mean(training_data(:)); 
training_data = training_data/std(training_data(:)); 

% step 4: specify parameters 
theta = 0.1; % criterion to stop 
eta = 0.1; % step size 
Nh = 10; % number of hidden nodes, actual hidden nodes should be 11 (including a biase) 
Ni = 2; % dimension of input vector = number of input nodes, actual input nodes should be 3 (including a biase) 
No = 2; % number of class = number of out nodes 

% step 5: Initialize the weights 
a = -1/sqrt(No); 
b = +1/sqrt(No); 
inputLayerToHiddenLayerWeight = (b-a).*rand(Ni, Nh) + a 
hiddenLayerToOutputLayerWeight = (b-a).*rand(Nh, No) + a 

J = inf; 

p = 1; 

% activation function 
% f(net) = a*tanh(b*net), 
% f'(net) = a*b*sech2(b*net) 
a = 1.716; 
b = 2/3; 

while J > theta 

    % step 6: randomly choose one training sample vector from X, 
    % together with its target vector 
    k = randi([1, size(training_data, 2)]); 
    input_X = training_data(:,k); 
    input_T = T(:,k); 

    % step 7: Calculate net_j values for hidden nodes in layer 1 
    % hidden layer output before activation function applied 
    netj = inputLayerToHiddenLayerWeight' * input_X; 

    % step 8: Calculate hidden node output Y using activation function 
    % apply activation function to hidden layer neurons 
    Y = a*tanh(b*netj); 

    % step 9: Calculate net_k values for output nodes in layer 2 
    % output later output before activation function applied 
    netk = hiddenLayerToOutputLayerWeight' * Y; 

    % step 10: Calculate output node output Z using the activation function 
    % apply activation function to the output layer neurons 
    Z = a*tanh(b*netk); 

    % step 11: Calculate sensitivity delta_k = (target - Z) * f'(Z) 
    % find the error between the expected_output and the neuron output 
    % we got using the weights 
    % delta_k = (expected - output) * activation(output) 
    delta_k = []; 
    for i=1:size(Z) 
     yi = Z(i,:); 
     expected_output = input_T(i,:); 
     delta_k = [delta_k; (expected_output - yi) ... 
           * a*b*(sech(b*yi)).^2]; 
    end 

    % step 12: Calculate sensitivity 
    % delta_j = Sum_k(delta_k * hidden-to-out weights) * f'(net_j) 
    % error = (weight_k * error_j) * activation(output) 
    delta_j = []; 
    for j=1:size(Y) 
     yi = Y(j,:); 
     error = 0; 
     for k=1:size(delta_k) 
      error = error + delta_k(k,:)*hiddenLayerToOutputLayerWeight(j, k); 
     end 
     delta_j = [delta_j; error * (a*b*(sech(b*yi)).^2)]; 
    end 

    % step 13: update weights 

    %2x10 
    inputLayerToHiddenLayerWeight = []; 
    for i=1:size(input_X) 
     xi = input_X(i,:); 
     wji = []; 
     for j=1:size(delta_j) 
      wji = [wji, eta * xi * delta_j(j,:)]; 
     end 
     inputLayerToHiddenLayerWeight = [inputLayerToHiddenLayerWeight; wji]; 
    end 

    inputLayerToHiddenLayerWeight 

    %10x2 
    hiddenLayerToOutputLayerWeight = []; 
    for j=1:size(Y) 
     yi = Y(j,:); 
     wjk = []; 
     for k=1:size(delta_k) 
      wjk = [wjk, eta * delta_k(k,:) * yi]; 
     end 
     hiddenLayerToOutputLayerWeight = [hiddenLayerToOutputLayerWeight; wjk]; 
    end 

    hiddenLayerToOutputLayerWeight 

    % Mean Square Error 
    J = 0; 
    for j=1:size(training_data, 2) 
     X = training_data(:,j); 
     t = T(:,j); 
     netj = inputLayerToHiddenLayerWeight' * X; 
     Y = a*tanh(b*netj); 
     netk = hiddenLayerToOutputLayerWeight' * Y; 
     Z = a*tanh(b*netk); 
     J = J + immse(t, Z); 
    end 

    J = J/size(training_data, 2) 

    p = p + 1; 
    if p == 4 
     break; 
    end 
end 

% testing neural network using the inputs 
test_data = [[2; -2], [-3; -3], [-2; 5], [3; -4]]; 

for i=1:size(test_data, 2) 

end 

Répondre

-1

La désintégration du poids n'est pas essentielle pour l'entraînement du réseau neuronal.

Ce que j'ai remarqué, c'est que la normalisation de vos fonctionnalités n'était pas correcte.

Le algorthim correct pour mise à l'échelle des données sur la plage de 0 à 1 est

(max - x)/(max - min)

Note: vous appliquez ce pour chaque élément dans le tableau (ou vecteur). Les entrées de données pour NN doivent être comprises entre [0,1]. (Techniquement, ils peuvent être un peu en dehors de cette ~ [-3,3] mais les valeurs furthur de 0 faire une formation difficile)

modifier *

Je suis pas au courant de cette fonction d'activation

a = 1.716; 
b = 2/3; 
% f(net) = a*tanh(b*net), 
% f'(net) = a*b*sech2(b*net) 

Cela ressemble à une variation sur tanh. Pourriez-vous élaborer ce que c'est?

Si votre réseau ne fonctionne toujours pas, donnez-moi une mise à jour et je regarderai votre code de plus près.

+0

la normalisation à 0 et la std 1 (qui est utilisée dans le code OP) est en fait une meilleure méthode que celle que vous proposez (qui est biaisée vers les valeurs aberrantes) – lejlot

+0

Il est généralement supposé que vous n'avez pas de valeurs aberrantes votre ensemble d'entraînement. Votre méthode est toujours biaisée vers les valeurs aberrantes (bien qu'un peu plus résilient). Généralement, il est absurde de former un modèle prédictif avec des valeurs aberrantes (car elles ne reflètent pas la majorité que vous essayez de prédire) Votre données met également les données dans la plage -1,1, ce qui est quelque peu atypique par rapport à la pratique standard. – Jjoseph

+0

ce n'est pas "ma" méthode mais plutôt une norme dans l'analyse statistique.Il fait ne met pas de données dans [-1,1], il fait simplement que la covariance empirique (diagonale) devient identité et met la valeur attendue à 0, rien d'autre. En particulier, la deuxième propriété a de bonnes propriétés, ce qui est perdu si l'on écrase simplement les valeurs à [0,1] - mais bien sûr tout dépend de l'application/du problème. Aucune de ces approches ne devrait conduire à l'échec décrit dans la question. En termes de votre question à l'OP - 1.716 et 2/3 sont anciennes constantes (à partir de 90), qui ont été considérés comme bien ajustés. – lejlot