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())

我不明白这一点,因为我没有self.weightVector以任何方式改变UpdateWeights方法。

如果有人能解释为什么会发生这种情况,我们将不胜感激。

4

2 回答 2

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同一个对象的改变。

于 2013-10-19T16:24:49.513 回答
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)

PS 另请注意,文档应该放在文档字符串中,而不是注释中。

于 2013-10-19T16:24:31.157 回答