2010-03-10 11 views
6

Je me suis entraîné réseau de neurones XOR dans Matlab et obtenu ces poids:réseau de neurones dans Matlab

iw: [-2.162 2.1706; 2.1565 -2.1688] 

lw: [-3.9174 -3.9183] 

b{1} [2.001; 2.0033] 

b{2} [3.8093] 

Juste par curiosité, j'ai essayé d'écrire du code MATLAB qui calcule la sortie de ce réseau (2 neurones dans la couche cachée , et 1 en sortie, fonction d'activation TANSIG).

code

que je suis:

l1w = [-2.162 2.1706; 2.1565 -2.1688]; 
l2w = [-3.9174 -3.9183]; 
b1w = [2.001 2.0033]; 
b2w = [3.8093]; 

input = [1, 0]; 

out1 = tansig (input(1)*l1w(1,1) + input(2)*l1w(1,2) + b1w(1)); 
out2 = tansig (input(1)*l1w(2,1) + input(2)*l1w(2,2) + b1w(2)); 
out3 = tansig (out1*l2w(1) + out2*l2w(2) + b2w(1)) 

Le problème est quand l'entrée est permet de dire [1,1], il émet -0,9989, lorsque [0,1] 0,4902. Tout en simulant le réseau généré avec les sorties MATLAB de manière adéquate sont 0.00055875 et 0,99943.

Qu'est-ce que je fais mal?

+2

pourquoi ne pas poster le code que vous avez utilisé pour construire et former le réseau? – Amro

Répondre

10

J'ai utilisé newpr, qui par défaut tansig fonction de transfert pour les couches cachées et de sortie.

input = [0 0 1 1; 0 1 0 1];    %# each column is an input vector 
ouputActual = [0 1 1 0]; 

net = newpr(input, ouputActual, 2);  %# 1 hidden layer with 2 neurons 
net.divideFcn = '';      %# use the entire input for training 

net = init(net);       %# initialize net 
net = train(net, input, ouputActual);  %# train 
outputPredicted = sim(net, input);  %# predict 

puis nous vérifions le résultat en calculant la sortie nous-mêmes. La chose importante à retenir est que par défaut, les entrées/sorties sont mis à l'échelle à la [-1,1] Plage:

scaledIn = (2*input - 1);   %# from [0,1] to [-1,1] 
for i=1:size(input,2) 
    in = scaledIn(:,i);    %# i-th input vector 
    hidden(1) = tansig(net.IW{1}(1,1)*in(1) + net.IW{1}(1,2)*in(2) + net.b{1}(1)); 
    hidden(2) = tansig(net.IW{1}(2,1)*in(1) + net.IW{1}(2,2)*in(2) + net.b{1}(2)); 
    out(i) = tansig(hidden(1)*net.LW{2,1}(1) + hidden(2)*net.LW{2,1}(2) + net.b{2}); 
end 
scaledOut = (out+1)/2;    %# from [-1,1] to [0,1] 

ou plus efficacement exprimé en tant que produit de matrice en une ligne:

scaledIn = (2*input - 1);   %# from [0,1] to [-1,1] 
out = tansig(net.LW{2,1} * tansig(net.IW{1}*scaledIn + repmat(net.b{1},1,size(input,2))) + repmat(net.b{2},1,size(input,2))); 
scaledOut = (1 + out)/2;   %# from [-1,1] to [0,1] 
+2

Ceci est vraiment une réponse en profondeur, merci l'homme! – spacemonkey

-1

Généralement, vous n'utilisez pas de sigmoïde sur votre couche de sortie. Êtes-vous sûr que vous devriez avoir le tansig sur out3? Et êtes-vous sûr de regarder les poids du réseau correctement formé? On dirait que vous avez un réseau formé pour faire XOR sur [1,1] [1, -1] [-1,1] et [-1, -1], avec +1 signifiant "xor" et -1 signifiant "même". J'ai écrit un exemple simple d'un réseau XOR.

+0

Alors, comment normalisez-vous votre sortie si vous n'utilisez pas Sigmoid dans la couche de sortie? De plus, comment mesurez-vous l'erreur si votre sortie n'est pas normalisée? – Kiril

+0

Pour un classificateur, vous choisissez la sortie avec la valeur la plus élevée (ou basculez au point 50%) pour prendre votre décision. Vous n'avez pas besoin de la non-linéarité. Dans ce cas, c'est _okay_ pour le faire, mais cela n'ajoute pas grand-chose. –

+1

Le problème de l'utilisation d'une fonction linéaire dans la couche de sortie devient apparent lorsque vous voulez obtenir des probabilités postérieures de chaque classe en plus des classifications. – Amro