2009-08-17 13 views
5

Je travaille à la création d'un réseau de neurones à 2 couches avec rétropropagation. Le NN est censé obtenir ses données à partir d'un vecteur 20001x17 contenant les informations suivantes dans chaque rangée:Matlab - Formation de réseau neuronal

-Les 16 premières cellules contiennent des entiers allant de 0 à 15 qui agissent comme des variables pour nous aider à déterminer laquelle des 26 lettres de l'alphabet que nous voulons exprimer en voyant ces variables. Par exemple, une série de 16 valeurs comme suit est censée représenter la lettre A: [2 8 4 5 2 7 5 3 1 6 0 8 2 7 2 7].

-La 17e cellule contient un nombre allant de 1 à 26 représentant la lettre de l'alphabet que nous voulons. 1 signifie A, 2 signifie B, etc.

La couche de sortie du NN est constituée de 26 sorties. Chaque fois que le NN reçoit une entrée comme celle décrite ci-dessus, il est supposé sortir un vecteur 1x26 contenant des zéros dans toutes les cellules, sauf la cellule correspondant à la lettre que les valeurs d'entrée sont supposées représenter. par exemple, la sortie [1 0 0 ... 0] serait la lettre A, alors que [0 0 0 ... 1] serait la lettre Z.

Certaines choses qui sont importantes avant de présenter le code: I besoin d'utiliser la fonction traingdm et le numéro de couche cachée est fixée (pour l'instant) à 21.

Essayer de créer le concept ci-dessus je l'ai écrit le code Matlab suivant:

%%%%%%%% 
%Start of code% 
%%%%%%%% 

% 
%Initialize the input and target vectors 
% 
p = zeros(16,20001); 
t = zeros(26,20001); 

% 
%Fill the input and training vectors from the dataset provided 
% 
for i=2:20001 
    for k=1:16 
     p(k,i-1) = data(i,k); 
    end 
    t(data(i,17),i-1) = 1; 
end 

net = newff(minmax(p),[21 26],{'logsig' 'logsig'},'traingdm'); 

y1 = sim(net,p); 

net.trainParam.epochs = 200; 
net.trainParam.show = 1; 
net.trainParam.goal = 0.1; 
net.trainParam.lr = 0.8; 
net.trainParam.mc = 0.2; 
net.divideFcn = 'dividerand'; 
net.divideParam.trainRatio = 0.7; 
net.divideParam.testRatio = 0.2; 
net.divideParam.valRatio = 0.1; 

%[pn,ps] = mapminmax(p); 
%[tn,ts] = mapminmax(t); 

net = init(net); 
[net,tr] = train(net,p,t); 

y2 = sim(net,pn); 

%%%%%%%% 
%End of code% 
%%%%%%%% 

maintenant à mon problème: je Je veux que mes sorties soient telles que décrites, à savoir que chaque colonne du vecteur y2 par exemple soit une représentation d'une lettre. Mon code ne fait pas ça. Au lieu de cela, il a produit des résultats qui varient grandement entre 0 et 1, des valeurs de 0,1 à 0,9.

Ma question est la suivante: y at-il une conversion que je dois faire que je ne suis pas? Signification, dois-je convertir mes données d'entrée et/ou de sortie à un formulaire par lequel je peux réellement voir si mon NN apprend correctement?

Toute contribution serait appréciée.

Répondre

2

Ceci est normal. Votre couche de sortie utilise une fonction de transfert log-sigmoïde, et cela vous donnera toujours une sortie intermédiaire entre 0 et 1.

Ce que vous feriez habituellement serait de rechercher la sortie avec la plus grande valeur - dans d'autres mots, le personnage le plus probable. Cela signifie que pour chaque colonne de y2, vous recherchez l'index de la ligne qui contient la plus grande valeur de cette ligne. Vous pouvez calculer cela comme suit:

[dummy, I]=max(y2); 

I est alors un vecteur contenant les indices de la plus grande valeur dans chaque ligne.

+0

Martin, merci pour la réponse. En utilisant max (y2) je peux maintenant obtenir au moins quelques informations sur le nombre de fois que le réseau a eu raison d'identifier les lettres. Ce que j'ai fait cependant avant d'alimenter le réseau les données que j'ai ont été réduites de sorte que 0 <= p (x) <= 1. Voyant que la valeur minimale de p était 0 et le maximum était de 15, j'ai fait un nouveau vecteur d'entrée scaledp = p/15. –

+0

Vous ne devez pas utiliser max comme fonction d'activité, car votre fonction d'erreur doit être définie sur l'activité et non sur l'activation, et max est non différentiable, ce qui signifie que vous ne pouvez pas utiliser back-prop. Vous avez besoin de softmax, voir ma réponse ci-dessous. –

1

Vous pouvez penser y2 comme une distribution de probabilité de sortie pour chaque entrée étant l'un des 26 caractères de l'alphabet, par exemple, si une colonne de y2 dit:

.2 
.5 
.15 
.15 

alors sa probabilité de 50% que ce caractère est B (si nous supposons seulement 4 sorties possibles).



== == REMARQUE

La couche de sortie du NN est constitué d' 26 sorties. Chaque fois que le NN est alimenté une entrée comme celle décrite ci-dessus il est censé produire un vecteur 1x26 contenant des zéros dans tous, mais une cellule qui correspond à la lettre que les valeurs d'entrée étaient destinées à représenter. par exemple la sortie [1 0 0 ... 0] serait lettre A, alors que [0 0 0 ... 1] serait la lettre Z.

Il est préférable d'éviter d'utiliser des valeurs cibles de 0,1 pour coder la sortie du réseau.
La raison d'éviter les valeurs cibles de 0 et 1 est que 'logsig' La fonction de transfert sigmoïde ne peut pas produire ces valeurs de sortie étant donné les poids finis. Si vous tentez de former le réseau pour qu'il s'adapte exactement aux valeurs cibles de 0 et 1, la descente en gradient forcera les poids à croître sans limite. Par conséquent, au lieu des valeurs 0 et 1, essayez d'utiliser des valeurs de 0,04 et 0,9, de sorte que [0,9,0,04, ..., 0,04] ​​est le vecteur de sortie cible pour la lettre A.


Référence:
Thomas M. Mitchell, Machine Learning, McGraw-Hill Higher Education, 1997, p114-115

+0

Je ne pense pas que ce soit correct. Chaque élément du vecteur de sortie aura une valeur variant entre 0,00 et 1,00 mais la somme de n'importe quelle colonne (ou n'importe quel élément de cette colonne d'ailleurs) ne représentera jamais réellement un pourcentage. –

+0

vous pouvez toujours le normaliser vous-même: y2Normalized = y2 ./ repmat (somme (y2), 26, 1) – Amro

+0

Vous pouvez également utiliser la différence entre la valeur la plus élevée de y2 et la deuxième valeur la plus élevée comme mesure de confiance de la prédiction. – Amro

1
  1. Utilisation hardlin fcn dans la couche de sortie.
    1. Utilisez trainlm ou trainrp pour l'apprentissage du réseau.
    2. Pour connaître votre réseau, utilisez une boucle for et une condition qui compare la sortie et la cible. Quand c'est le meilleur usage, cassez pour sortir de la boucle d'apprentissage.
    3. Utilisez une autre méthode au lieu de mapminmax pour pré-traiter un ensemble de données.
0

Je ne sais pas si cela constitue une réponse réelle ou non: mais voici quelques remarques.

  • Je ne comprends pas votre schéma de codage. Comment un 'A' est-il représenté comme cet ensemble de nombres? Il semble que vous tombiez dans un piège assez commun d'utiliser des nombres arbitraires pour coder des valeurs catégorielles. Ne faites pas ceci: par exemple si 'a' vaut 1, 'b' vaut 2 et 'c' vaut 3, votre codage a implicitement indiqué que 'a' ressemble plus à 'b' qu'à 'c' (parce que le réseau a des entrées de valeur réelle, les propriétés ordinales sont importantes). La façon de le faire correctement est d'avoir chaque lettre représentée comme 26 entrées de valeur binaire, où un seul est toujours actif, représentant la lettre.
  • Vos sorties sont correctes, l'activation à la couche de sortie ne sera jamais être 0 ou 1, mais les nombres réels. Vous pouvez prendre le max comme votre fonction d'activité, mais c'est problématique parce que ce n'est pas différentiable, donc vous ne pouvez pas utiliser back-prop. Qu'est-ce que vous devez faire est coupler les sorties avec le softmax function, de sorte que leur somme est un.Vous pouvez ensuite traiter les sorties comme des probabilités conditionnelles étant donné les entrées, si vous le désirez. Alors que le réseau n'est pas explicitement probabiliste, avec l'activité correcte et activation fonctions sera identique dans la structure à un modèle log-linéaire (éventuellement avec des variables latentes correspondant à la couche cachée), et les gens le font tout le temps .

Voir David Mackay's textbook pour une introduction intéressante aux réseaux de neurones qui rendra claire la connexion probabiliste. Jetez un oeil à this paper from Geoff Hinton's group qui décrit la tâche de prédire le caractère suivant étant donné le contexte pour les détails sur la représentation correcte et les fonctions d'activation/activité (bien que leur méthode soit non triviale et utilise un réseau récurrent avec une méthode d'entraînement différente).