Le réseau neuronal n'apprend pas - données MNIST-reconnaissance de L'écriture

j'ai écrit un programme de réseau neuronal. Il fonctionne pour les portes de logique, mais quand je tente de l'utiliser pour la reconnaissance des chiffres manuscrits - il n'apprend tout simplement pas.

vous trouverez le code ci-dessous:

/ / il s'agit d'un seul neurone; cela pourrait être nécessaire pour comprendre le code restant

typedef struct SingleNeuron
{
    double                  outputValue;
    std::vector<double>     weight;
    std::vector<double>     deltaWeight;
    double                  gradient;
    double                  sum;
}SingleNeuron;

puis j'initialise le net. J'ai fixé les poids à une valeur aléatoire de -0,5 à + 0,5, somme à 0, deltaWeight à 0

Puis vient le Anticipation:

for (unsigned i = 0; i < inputValues.size(); ++i)
{
    neuralNet[0][i].outputValue = inputValues[i];
    neuralNet[0][i].sum = 0.0;
    //  std::cout << "o/p Val = " << neuralNet[0][i].outputValue << std::endl;
}

for (unsigned i = 1; i < neuralNet.size(); ++i)
{
    std::vector<SingleNeuron> prevLayerNeurons = neuralNet[i - 1];
    unsigned j = 0;
    double thisNeuronOPVal = 0;
    //  std::cout << std::endl;
    for (j = 0; j < neuralNet[i].size() - 1; ++j)
    {
        double sum = 0;
        for (unsigned k = 0; k < prevLayerNeurons.size(); ++k)
        {
            sum += prevLayerNeurons[k].outputValue * prevLayerNeurons[k].weight[j];
        }
        neuralNet[i][j].sum = sum;
        neuralNet[i][j].outputValue = TransferFunction(sum);
        //      std::cout << neuralNet[i][j].outputValue << "t";
    }
    //      std::cout << std::endl;
}

ma fonction de transfert et sa dérivée est mentionnée à la fin.

Après ce que j'ai essayer de l'arrière-propager à l'aide de:

// calculate output layer gradients
for (unsigned i = 0; i < outputLayer.size() - 1; ++i)
{
    double delta = actualOutput[i] - outputLayer[i].outputValue;
    outputLayer[i].gradient = delta * TransferFunctionDerivative(outputLayer[i].sum);
}
//  std::cout << "Found Output gradients "<< std::endl;
// calculate hidden layer gradients
for (unsigned i = neuralNet.size() - 2; i > 0; --i)
{
    std::vector<SingleNeuron>& hiddenLayer = neuralNet[i];
    std::vector<SingleNeuron>& nextLayer = neuralNet[i + 1];

    for (unsigned j = 0; j < hiddenLayer.size(); ++j)
    {
        double dow = 0.0;
        for (unsigned k = 0; k < nextLayer.size() - 1; ++k)
        {
            dow += nextLayer[k].gradient * hiddenLayer[j].weight[k];
        }
        hiddenLayer[j].gradient = dow * TransferFunctionDerivative(hiddenLayer[j].sum);
    }
}
//  std::cout << "Found hidden layer gradients "<< std::endl;

// from output to 1st hidden layer, update all weights
for (unsigned i = neuralNet.size() - 1; i > 0; --i)
{
    std::vector <SingleNeuron>& currentLayer = neuralNet[i];
    std::vector <SingleNeuron>& prevLayer = neuralNet[i - 1];

    for (unsigned j = 0; j < currentLayer.size() - 1; ++j)
    {
        for (unsigned k = 0; k < prevLayer.size(); ++k)
        {
            SingleNeuron& thisNeueon = prevLayer[k];
            double oldDeltaWeight = thisNeueon.deltaWeight[j];
            double newDeltaWeight = ETA * thisNeueon.outputValue * currentLayer[j].gradient + (ALPHA * oldDeltaWeight);
            thisNeueon.deltaWeight[j] = newDeltaWeight;
            thisNeueon.weight[j] += newDeltaWeight;
        }
    }
}

ce sont les TransferFuntion et de ses dérivés;

double TransferFunction(double x)
{
    double val;
    //val = tanh(x);
    val = 1 / (1 + exp(x * -1));
    return val;
}

double TransferFunctionDerivative(double x)
{
    //return 1 - x * x;
    double val = exp(x * -1) / pow((exp(x * -1) + 1), 2);
    return val;
}

une chose que j'ai observée si j'utilise la fonction sigmoïde standard pour être ma fonction de transfert et si je passe la sortie du neurone à la fonction de transfert - résultat est L'infini. Mais tanh (x) fonctionne bien avec cette valeur

donc si je j'utilise 1/1+e^(- x) comme fonction de transfert je dois passer Sum of Net Inputs et tanh étant ma fonction de transfert je dois passer output du neurone actuel.

Je ne comprends pas tout à fait pourquoi c'est ainsi, peut-être que cela appelle une autre question.

Mais cette question est vraiment quelque chose d'autre: LE RÉSEAU FONCTIONNE POUR DES PORTES LOGIQUES MAIS PAS POUR LA RECONNAISSANCE DE CARACTÈRES

j'ai essayé beaucoup de variations/combinaisons de Learning Rate et Acceleration et # hidden layers et their sizes. Vous trouverez les résultats ci-dessous:

AvgErr: 0.299399          #Pass799
AvgErr : 0.305071         #Pass809
AvgErr : 0.303046         #Pass819
AvgErr : 0.299569         #Pass829
AvgErr : 0.30413          #Pass839
AvgErr : 0.304165         #Pass849
AvgErr : 0.300529         #Pass859
AvgErr : 0.302973         #Pass869
AvgErr : 0.299238         #Pass879
AvgErr : 0.304708         #Pass889
AvgErr : 0.30068          #Pass899
AvgErr : 0.302582         #Pass909
AvgErr : 0.301767         #Pass919
AvgErr : 0.303167         #Pass929
AvgErr : 0.299551         #Pass939
AvgErr : 0.301295         #Pass949
AvgErr : 0.300651         #Pass959
AvgErr : 0.297867         #Pass969
AvgErr : 0.304221         #Pass979
AvgErr : 0.303702         #Pass989

après avoir regardé les résultats, vous pourriez penser que ce gars est simplement coincé dans les minima locaux, mais s'il vous plaît attendre et lire à travers:

Input = [0, 0, 0, 0, 0, 0, 1, 0, 0, 0]          
Output = 0.0910903, 0.105674, 0.064575, 0.0864824, 0.128682, 0.0878434, 0.0946296, 0.154405, 0.0678767, 0.0666924

Input = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Output = 0.0916106, 0.105958, 0.0655508, 0.086579, 0.126461, 0.0884082, 0.110953, 0.163343, 0.0689315, 0.0675822

Input = [0, 0, 0, 1, 0, 0, 0, 0, 0, 0]          
Output = 0.105344, 0.105021, 0.0659517, 0.0858077, 0.123104, 0.0884107, 0.116917, 0.161911, 0.0693426, 0.0675156

Input = [0, 0, 0, 0, 0, 0, 1, 0, 0, 0]          
Output = , 0.107113, 0.101838, 0.0641632, 0.0967766, 0.117149, 0.085271, 0.11469, 0.153649, 0.0672772, 0.0652416

ci-dessus est la sortie de l'époque #996, #997,#998 et #999

Donc simplement de réseau n'est pas l'apprentissage. Pour cela, par exemple, J'ai utilisé ALPHA = 0,4, ETA = 0,7, 10 couches cachées de 100 neurones chacune et la moyenne est supérieure à 10 époques. Si vous sont préoccupés par le taux D'apprentissage étant 0,4 ou tant de couches cachées que j'ai déjà essayé leurs variations. Par exemple pour taux d'apprentissage étant 0,1 et 4 couches cachées - chacune de 16

Input = [0, 0, 0, 0, 0, 0, 1, 0, 0, 0]          
Output = 0.0883238, 0.0983253, 0.0613749, 0.0809751, 0.124972, 0.0897194, 0.0911235, 0.179984, 0.0681346, 0.0660039

Input = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]          
Output = 0.0868767, 0.0966924, 0.0612488, 0.0798343, 0.120353, 0.0882381, 0.111925, 0.169309, 0.0676711, 0.0656819

Input = [0, 0, 0, 1, 0, 0, 0, 0, 0, 0]          
Output = 0.105252, 0.0943837, 0.0604416, 0.0781779, 0.116231, 0.0858496, 0.108437, 0.1588, 0.0663156, 0.0645477

Input = [0, 0, 0, 0, 0, 0, 1, 0, 0, 0]          
Output = 0.102023, 0.0914957, 0.059178, 0.09339, 0.111851, 0.0842454, 0.104834, 0.149892, 0.0651799, 0.063558

je suis tellement sûr que j'ai manqué quelque chose. Je ne suis pas en mesure de le comprendre. J'ai lu L'algorithme de Tom Mitchel tant de fois, mais je ne sais pas ce qui ne va pas. Quel que soit l'exemple que je résous à la main! (Merci de ne pas me demander de résoudre MNIST de données d'images à la main ;) ) je ne sais pas où changer le code, quoi faire.. s'il vous plaît aider..

MODIFIER -- le Téléchargement de plus de données que par des suggestions dans les commentaires

1 couche cachée de 32 -- toujours pas d'apprentissage.

Prévue de Sortie-Entrée est des images entre 0 à 9, de sorte qu'un simple vecteur décrivant ce qui est de l'image courante, que le bit est à 1, tous les autres sont à 0. Donc je voudrais que la sortie soit aussi proche de 1 pour ce bit particulier et que les autres soient proches de 0 pour par exemple si input est Input = [0, 0, 0, 0, 0, 0, 1, 0, 0, 0] je voudrais la sortie de quelque chose comme Output = 0.002023, 0.0914957, 0.059178, 0.09339, 0.011851, 0.0842454, 0.924834, 0.049892, 0.0651799, 0.063558 (C'est vague, la main-généré)

Voici les liens des travaux d'autres chercheurs.

Stanford

SourceForge -- C'est plutôt une bibliothèque

non seulement ces deux-là, mais il y a tellement de sites qui montrent les démos.

les choses fonctionnent très bien pour eux. Si je mets mes paramètres réseau (Alpha, ETA) comme eux, je n'obtiens pas de résultats comme eux, donc ceci c'est rassurant que quelque chose ne va pas avec mon code.

EDIT 2

Ajout de plus de cas d'insuffisance

Accelaration - 0.7, L'Apprentissage Des Taux De 0,1

Accelaration - 0.7, L'Apprentissage Des Taux De 0,6

dans les deux cas ci-dessus, les couches cachées étaient de 3, chacune de 32 neurones.

22
demandé sur ace 2015-02-26 18:52:29

1 réponses

cette réponse est tirée du commentaire de L'OP sur la question.

j'ai résolu le puzzle. J'avais fait la pire erreur possible. Je donnais une mauvaise réponse. J'ai utilisé opencv pour numériser les images, au lieu d'utiliser reshape j'ai été en utilisant resize et ainsi l'entrée était l'interpolation linéaire des images. Donc ma contribution était fausse. Il n'y avait rien de mal avec le code. Mon réseau est 784 - 65 - 10 donnant une précision de 96,43%.

4
répondu ace 2015-05-09 02:00:42