2017-09-11 5 views
0

C'est la première fois que j'écris un algorithme d'apprentissage perceptron à partir de zéro. J'ai déjà utilisé des solutions ML hors de la boîte, mais je voulais vraiment le comprendre et l'écrire moi-même. Pour une raison ou une autre, mon taux d'erreur continue d'augmenter plutôt que de diminuer. Il semble donc que mon algorithme est divergent au lieu de converger. J'ai écrit dans une plage de tolérance parce que ça se rapprochait parfois mais jamais vraiment.Algorithme d'apprentissage Perceptron divergent

J'ai trois poids; 1 pour le biais et 2 pour X et Y, respectivement.

je trouve mon discriminante avec: D = (weight0 + weight1 * Xi) + (weight2 * Yi)

Si le discriminant ne correspond pas à la sortie attendue, puis mettre à jour les poids avec: Note: Supposons que c et k sont des constantes prédéfinies et d = prévu sortie w0 = w0 + cdk, w1 = w1 + cdXi, w2 = w2 + cdYi

Voici mon implémentation en Python:

def weightsUpdate(weights, constantC, constantK, classificationd, x, y): 
    weights[0] = weights[0] + constantC * classificationd * constantK # w0 = w0 + cdk 
    weights[1] = weights[1] + constantC * classificationd * x #w1 = w1 + cdx 
    weights[2] = weights[2] + constantC * classificationd * y #w2 = w2 + cdy 

    return weights 

def trainModel(df, weights, constantC, constantK, maxIter, threshHold): 
    #grab the values in a list 
    x = df['X'].values 
    y = df['Y'].values 
    d = df['Class'].values 

    #define some variables to keep track 
    numTurns = 0 

    while numTurns < maxIter: 
      errorRate = 0 
      falsePosNeg = 0 
      truePosNeg = 0 

      '''assign som threshhold values. must accomodate for slight variance.''' 
      posThreshHoldCeiling = 1 + threshHold 
      posThreshHoldFloor = 1 - threshHold 
      negThreshHoldFloor = -1 - threshHold 
      negThreshHoldCeiling = -1 + threshHold 

      for i in range(len(x)): 
       ''' calculate the discriminant D = w0 + w1*xi + w2*yi ''' 
       discriminant = weights[0] + (weights[1] * x[i]) + (weights[2] * y[i]) 

       '''if the discriminant is not correct when compared to the correct output''' 
       if ((discriminant >= posThreshHoldFloor and discriminant <= posThreshHoldCeiling) or 
       (discriminant >= negThreshHoldFloor and discriminant <= negThreshHoldCeiling)): 
        truePosNeg += 1 
       #weights = weightsUpdate(weights, constantC, constantK, d[i], x[i], y[i]) 
     else: 
       '''update the weights''' 
       weights = weightsUpdate(weights, constantC, constantK, d[i], x[i], y[i]) 
       falsePosNeg += 1 


      numTurns += 1 #increase number of turns by 1 iteration 
      print("Number of False Positive/Negative: " + str(falsePosNeg)) 
      print("Number of True Positive/Negative: " + str(truePosNeg)) 
      errorRate = falsePosNeg/len(x) * 100 
      print("Error rate: " + str(errorRate) + "%") 


     '''add stop conditions''' 
     if (errorRate < 25): 
      break 
     else: 
      continue 

Merci pour toute l'aide.

+1

Veuillez lire et suivre les consignes de publication dans la documentation d'aide. [Exemple minimal, complet, vérifiable] (http://stackoverflow.com/help/mcve) s'applique ici. Nous ne pouvons pas vous aider efficacement tant que vous n'afficherez pas votre code MCVE et que vous ne décrivez pas précisément le problème. Nous devrions pouvoir coller votre code posté dans un fichier texte et reproduire le problème que vous avez décrit. Ce code définit simplement deux fonctions, puis se ferme sans exécuter l'une ou l'autre. – Prune

+1

'poids [0] = poids [0] + constanteC', vous faites gradient * ascend * pas de descente. Passer à un moins et vous devriez aller bien. Assurez-vous que 'constantC' est assez petit. –

+0

@ Prune, le problème que j'avais était situé dans ces deux fonctions. Mettre à jour mes poids ou ma fonction pour former mon modèle. C'est pourquoi j'ai dû poster tellement. Des informations générales étaient également nécessaires pour le lecteur. –

Répondre

0

L'algorithme d'apprentissage Perceptron (PLA) ne devrait pas avoir besoin d'un seuil. Le PLA exige également que seuls les signes de la sortie discriminante et attendue correspondent, c'est-à-dire sign(Discriminant) == d, de sorte qu'il n'est pas nécessaire de converger vers la sortie réelle. Voici une version modifiée de trainModel().

def trainModel(df, weights, constantC, constantK, maxIter): 
#grab the values in a list 
x = df['X'].values 
y = df['Y'].values 
d = df['Class'].values 
globalErrorRate = 0 

#define some variables to keep track 
numTurns = 0 

while numTurns < maxIter: 
    localErrorRate = 0 
    successRate = 0 
    falsePosNeg = 0 
    truePosNeg = 0 

    for i in range(len(x)): 
     #calculate the discriminant 
     discriminant = weights[0] + (weights[1] * x[i]) + (weights[2] * y[i]) 

     if(isPos(discriminant) and d[i] == 1): 
      truePosNeg += 1 

     elif(isPos(discriminant) == False and d[i] == -1): 
      truePosNeg += 1 

     else: 
      falsePosNeg += 1 
      weights = weightsUpdate(weights, constantC, constantK, d[i], x[i], y[i]) 

    numTurns += 1 #increase number of turns by 1 iteration 
    print("Number of False Positive/Negative: " + str(falsePosNeg)) 
    print("Number of True Positive/Negative: " + str(truePosNeg)) 
    localErrorRate = falsePosNeg/len(x) * 100 
    successRate = truePosNeg/len(x) * 100 
    print("Error rate: " + str(localErrorRate) + "%") 
    print("Success rate: " + str(successRate) + "%") 

    if successRate == 100: 
     print("Trained Weight Values: " + str(weights)) 
     break 
    else: 
     continue