Реализация Perceptron с ошибкой массива - PullRequest
0 голосов
/ 06 октября 2018

У меня вопрос, была ли проблема в изменении функции 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 голосов
/ 06 октября 2018

Ошибка, с которой вы сталкиваетесь, заключается в том, что step () закодирован для оценки 1 элемента массива за раз, но когда вы передаете ему массив в функции предиката, он должен сделать что-то вроде этого:

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

Интерпретатор не знает, какое значение оценивать, поскольку это массив, и, следовательно, выдает ошибку.Использование любого или всех будет проверять значение «любое» или «все» в массиве и даст вам 0 или 1 соответственно, поэтому вы получаете массив 1 с, когда пишете x.any ().

Еще одна вещь, которая беспокоила меня в коде, который вы импортировали, заключалась в том, что прямой проход выполняется в цикле, который не очень эффективен или питонен.Векторизованная реализация намного лучше.Я изменил пошаговую функцию и функцию подгонки в импортированном коде для векторизации, и он работает нормально для меня.

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

Теперь функция шага возвращает двоичный массив, значение которого равно 1, когда входное значение больше 0 или 0. Например, если у вас есть массив, скажем:

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

будет преобразовано в:

[1,1,0,1]

Я также изменил функцию подгонки, чтобы она делала все векторизованным.

Еще одна вещь, которую я сделал с моим кодом, была такая:

Вместо

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

Я сделал

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

, чтобы заставить его работать.Надеюсь, это поможет.Обязательно спросите что-нибудь, если вы не понимаете.

...