使用数组错误实现Perceptron

时间:2018-10-06 10:06:36

标签: python neural-network perceptron

我的问题是,由于原始错误,更改def step(self,x)函数是否存在问题。

我试图将def step(self,x)更改为x.any。它导致了一个预测错误,其中所有预测均为1。我尝试按照给定的代码从书中实现OR Perceptron神经网络。但是,我收到了一个错误The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

这是代码:

from nn import Perceptron
import numpy as np

X = np.array([[0,0],[0,1],[1,0],[1,1]])
print(X[1])
y = np.array([0],[1],[1],[0])

print("[INFO] training perceptron...")
p = Perceptron(X.shape[1],alpha = 0.1)
p.fit(X,y,epochs=20)

print("[INFO] testing perceptron...")

for (x,target) in zip(X,y):
    pred=p.predict(X)
    print("[INFO] data={}, ground-truth={}, pred={}". format(x, target[0], pred))

我导入的软件包是:

import numpy as np

class Perceptron:
    def __init__(self, N, alpha = 0.1):
        self.W = np.random.randn(N+1)/np.sqrt(N)
        self.alpha  = alpha

    def step(self,x):
        if x>0:
            return 1
        else:
            return 0

    def fit(self, X, y, epochs = 10):
        X = np.c_[X,np.ones((X.shape[0]))]
        for epoch in np.arange(0, epochs):
            for (x,target) in zip(X,y):
                p = self.step(np.dot(x, self.W))
                if p!= target:
                    error = p-target
                    self.W += -self.alpha * error * x

    def predict(self,X,addBias=True):
        X = np.atleast_2d(X)
        if addBias:
            X=np.c_[X, np.ones((X.shape[0]))]

        return self.step(np.dot(X,self.W))

如果我一整天都在思考这个问题,那真是愚蠢的问题,我道歉。

谢谢!

1 个答案:

答案 0 :(得分:1)

您面临的错误是因为将step()编码为一次评估数组的1个元素,但是当您在预报函数中将数组传递给它时,它必须执行以下操作:

[0.266,1.272,-1.282,0.889] > 1

解释器不知道要评估哪个值,因为它是一个数组,因此会给出错误。使用any或all将检查数组中的“ any”或“ all”值,并相应地为您提供0或1,这就是为什么在编写x.any()时得到1的数组。

令我烦恼的是您导入的代码的另一件事是,前向传递是在循环中完成的,这不是很有效,也不是Python式的。向量化的实现会更好。我已经更改了导入函数中的步进函数和拟合函数,以对其进行矢量化处理,它对我来说运行得很好。

 import numpy as np

class Perceptron:
    def __init__(self, N, alpha = 0.1):
        self.W = np.random.randn(N+1)/np.sqrt(N)
        self.alpha  = alpha

    def step(self,x):
        return 1. * (x > 0)

    def fit(self, X, y, epochs = 10):
        X = np.c_[X,np.ones((X.shape[0]))]
        for epoch in np.arange(0, epochs):
            Z = np.dot(X, self.W)
            p = self.step(Z)
            if np.any(p != y):
                error = (p-y)
                self.W += -self.alpha * np.dot(X.T,error)

    def predict(self,X,addBias=True):
        X = np.atleast_2d(X)
        if addBias:
            X=np.c_[X, np.ones((X.shape[0]))]

        return self.step(np.dot(X,self.W))

现在,step函数将返回一个二进制数组,当输入大于0时,该值为1;否则返回0。例如,如果您有一个数组,则说:

X= [0.266,1.272,-1.282,0.889]

将被转换为:

[1,1,0,1]

我还更改了fit函数,使其可以向量化所有功能。

我对代码所做的另一件事是:

代替

y = np.array([0],[1],[1],[0])

我做了

y = np.array([0,1,1,0])

使其正常运行。我希望这有帮助。如果您听不懂,一定要问什么。