【问题标题】:Perceptron Learning Algorithm diverging感知器学习算法发散
【发布时间】:2017-09-12 10:44:06
【问题描述】:

这是我第一次从头开始编写感知器学习算法。我以前使用过开箱即用的 ML 解决方案,但想真正理解它并自己编写它。出于某种原因,我的错误率一直在增加而不是减少。所以看来我的算法是发散而不是收敛。我写在一个公差范围内,因为它有时会接近但从未完全达到目标。

我有三个重量; 1 表示偏差,2 表示 X 和 Y。

我发现我的判别: D = (weight0 + weight1 * Xi) + (weight2 * Yi)

如果判别式与预期输出不匹配,我会更新权重: 注意:假设 c 和 k 是预定义的常量,并且 d = 预期输出 w0 = w0 + cdkw1 = w1 + cdXiw2 = w2 + cdYi

以下是我在 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

感谢您的所有帮助。

【问题讨论】:

  • 请阅读并遵循帮助文档中的发布指南。 Minimal, complete, verifiable example 适用于此。在您发布 MCVE 代码并准确描述问题之前,我们无法有效地帮助您。我们应该能够将您发布的代码粘贴到文本文件中并重现您描述的问题。这段代码只定义了两个函数,然后退出而不执行。
  • weights[0] = weights[0] + constantC,你在做梯度 ascend 而不是下降。切换到减号,你应该没问题。确保constantC 足够小。
  • @Prune,我遇到的问题在于这两个函数。更新我的权重或我的函数来训练我的模型。所以这就是为什么我不得不发布这么多。读者还需要一些背景信息。
  • @ThomasJungblut 感谢您成为唯一一个尝试并提出建议的人。

标签: python machine-learning perceptron


【解决方案1】:

感知器学习算法 (PLA) 不需要阈值。此外,PLA 要求只有判别式和预期输出的符号应该匹配,即sign(Discriminant) == d,因此无需收敛于实际输出。以下是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

【讨论】:

    猜你喜欢
    • 2017-05-02
    • 2017-04-01
    • 2014-07-03
    • 2011-02-15
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多