2013-10-19 22 views
1

在我的博士学位课程中,我们被分配到一个单一的神经元神经网络,用Python脚本计算OR,AND,XOR操作。我有一个非常奇怪的错误,在我的代码中让我疯狂。一个变量没有任何明显的原因

首先我有一个Vector类:

class Vector3D:                   # Defines the Vector3D class 
    def __init__(self,bias,x,y):               # Defines the variables for the Vector3D class 
     self.bias = bias 
     self.x = x 
     self.y = y 
    def __add__(self,other):                # Defines the built-in "add" ("+") operation for Vector3D 
     return Vector3D(self.bias+other.bias,self.x+other.x,self.y+other.y) 
    def __mul__(self,other):                # Defines the built-in "multipication" ("*") operation for Vector3D 
     if(isinstance(other,int)): 
      return Vector3D(self.bias * other, self.x * other, self.y * other) 
     else: 
      return Vector3D(self.bias * other.bias, self.x * other.x, self.y * other.y) 
    def __str__(self):                  # Defines the built-in string return value for Vector3D 
     return "Vector(%f,%f,%f)" % (self.bias, self.x, self.y) 
    def UpdateWeights(self,eta, targetOutput, currentOutput, valueX, valueY, valueBias): # Function for updating the weights 
     self.bias = self.bias + (eta * (targetOutput - currentOutput) * valueBias) 
     self.x = self.x + (eta * (targetOutput - currentOutput) * valueX) 
     self.y = self.y + (eta * (targetOutput - currentOutput) * valueY) 
     return Vector3D(self.bias,self.x, self.y) 
    def getX(self):                  # Function for getting the x value of a vector 
     return self.x 
    def getY(self):                  # Function for getting the y value of a vector 
     return self.y 
    def getBias(self):                  # Function for getting the bias value of a vector 
     return self.bias 

其次,我有一个神经元类:

class Neuron:                     # Defines the Neuron class 
    def __init__(self, dataTable, eta, theta, targetArrayOr, targetArrayAnd, targetArrayXor): # Function for defining the variables for initialization 
     self.dataTable = dataTable 

     self.eta = eta 
     self.theta = theta 

     self.targetArrayOr = targetArrayOr 
     self.targetArrayAnd = targetArrayAnd 
     self.targetArrayXor = targetArrayXor 

     self.wVbias = random.uniform(-0.2, 0.2) 
     self.wVX = random.uniform(-0.2, 0.2) 
     self.wVY = random.uniform(-0.2, 0.2) 
     self.weightVector = Vector3D(self.wVbias,self.wVX,self.wVY) 

     self.weightVectorOr = Vector3D(0,0,0) 
     self.weightVectorAnd = Vector3D(0,0,0) 
     self.weightVectorXor = Vector3D(0,0,0) 

    def TrainForOr(self) :                  # Function training the weight vector for OR operation 
     iteration = 0                   # Number of iterations 
     check = 0                    # Initial value of the while loop 
     finalCheck = 200                   # Final value of the while loop 
     targetReached = False                 # Boolean variable for if the target is reached 
     rowNb = 0                    # Initial value of the index number in the data table 
     weightVector = self.weightVector            # Initial weight vector 
     print(self.weightVector) 
     while check < finalCheck :                # Makes sure that the entire loop runs 200 times for accuracy 
      while rowNb < len(self.dataTable) :             # Makes sure every row is iterated 
       while targetReached == False: 
        D1dotW = DotProduct(self.dataTable[rowNb],weightVector)      # Dot product of the input vector and the weight vector 
        if(D1dotW > self.theta): 
         currentOutput = 1 
        elif(D1dotW <= self.theta): 
         currentOutput = 0 
        if(currentOutput == self.targetArrayOr[rowNb]): 
         targetReached = True 
        else: 
         iteration = iteration + 1 
         print(self.weightVector) 
         weightVector = weightVector.UpdateWeights(self.eta,self.targetArrayOr[rowNb], currentOutput, self.dataTable[rowNb].getX(), self.dataTable[rowNb].getY(), self.dataTable[rowNb].getBias()) 
         print(self.weightVector) 
         targetReached = False 


       targetReached = False 
       rowNb = rowNb + 1 

      check = check + 1 
      rowNb = 0 
     self.weightVectorOr = weightVector              # Sets the OR weight vector 
     return "OR - Final weight vector is " + str(weightVector) + " " + "("+ str(iteration) + " iteration(s))" 

我也有AND和XOR等方法,但它们具有相同以上略有改动。

现在上面的代码“工作”作为“错误”是非常小的,不会改变最终结果。但我想明白为什么会发生。

当我与GUI的其余代码等一起运行上述片段,我得到控制台的结果:

Vector(-0.051856,-0.099352,0.079270) 
Vector(-0.051856,-0.099352,0.079270) 
Vector(-0.001856,-0.099352,0.079270) 
Vector(-0.001856,-0.099352,0.079270) 
Vector(-0.001856,-0.099352,0.079270) 
Vector(-0.001856,-0.099352,0.079270) 
Vector(-0.001856,-0.099352,0.079270) 
Vector(-0.001856,-0.099352,0.079270) 
Vector(-0.001856,-0.099352,0.079270) 
Vector(-0.001856,-0.099352,0.079270) 
Vector(-0.001856,-0.099352,0.079270) 
Vector(-0.001856,-0.099352,0.079270) 
Vector(-0.001856,-0.099352,0.079270) 
Vector(-0.001856,-0.099352,0.079270) 
Vector(-0.001856,-0.099352,0.079270) 
Vector(-0.001856,-0.099352,0.079270) 
Vector(-0.001856,-0.099352,0.079270) 

这意味着,初始self.weightVector在所述线转换:

weightVector = weightVector.UpdateWeights(self.eta,self.targetArrayOr[rowNb], currentOutput, self.dataTable[rowNb].getX(), self.dataTable[rowNb].getY(), self.dataTable[rowNb].getBias()) 

我不明白这一点,因为我不会在UpdateWeights方法中以任何方式更改self.weightVector

如果有人可以解释为什么发生这种情况,将不胜感激。

+1

“当我运行上面的代码片段时...”我没有看到你真正实例化并使用这些代码片段驴。你能否包括这个? –

回答

1

UpdateWeights()方法修改向量。这就是为什么当你呼叫UpdateWeights()时矢量会发生变化。

这里有一个固定的版本:

def UpdateWeights(self, eta, targetOutput, currentOutput, 
        valueX, valueY, valueBias): 
    """Returns a new vector with updated weights.""" 
    bias = self.bias + (eta * (targetOutput - currentOutput) * valueBias) 
    x = self.x + (eta * (targetOutput - currentOutput) * valueX) 
    y = self.y + (eta * (targetOutput - currentOutput) * valueY) 
    return Vector3D(bias, x, y) 

附:另请注意,文档应该放在docstrings中,而不是注释中。

3

看看这个方法:

def UpdateWeights(self,eta, targetOutput, currentOutput, valueX, valueY, valueBias): 
    self.bias = self.bias + (eta * (targetOutput - currentOutput) * valueBias) 
    self.x = self.x + (eta * (targetOutput - currentOutput) * valueX) 
    self.y = self.y + (eta * (targetOutput - currentOutput) * valueY) 
    return Vector3D(self.bias,self.x, self.y) 

它不仅返回一个新Vector3D还要修改自身(self)和更早的版本设置:

weightVector = self.weightVector 

所以调用weightVector.UpdateWeights会导致改变self

相关问题