Numpy 感知器中的决策边界不正确

Numpy 感知器中的决策边界不正确,numpy,machine-learning,deep-learning,perceptron,Numpy,Machine Learning,Deep Learning,Perceptron,我正在为一次讲座准备一些代码,并重新实现了一个简单的感知器:2个输入和1个输出。目的:一种线性分类器 下面是创建数据、设置感知器并对其进行训练的代码: from ipywidgets import interact import numpy as np import matplotlib.pyplot as plt # Two randoms clouds x = [(1,3)]*10+[(3,1)]*10 x = np.asarray([(i+np.random.rand(), j+np.r

我正在为一次讲座准备一些代码,并重新实现了一个简单的感知器:2个输入和1个输出。目的:一种线性分类器

下面是创建数据、设置感知器并对其进行训练的代码:

from ipywidgets import interact
import numpy as np
import matplotlib.pyplot as plt

# Two randoms clouds
x = [(1,3)]*10+[(3,1)]*10
x = np.asarray([(i+np.random.rand(), j+np.random.rand()) for i,j in x])

# Colors
cs = "m"*10+"b"*10
# classes
y = [0]*10+[1]*10



class Perceptron:
    def __init__(self):
        self.w = np.random.randn(3)
        self.lr = 0.01

    def train(self, x, y, verbose=False):
        errs = 0.

        for xi, yi in zip(x,y):
            x_ = np.insert(xi, 0, 1)
            r = self.w @ x_

            ######## HERE IS THE MAGIC HAPPENING #####
            r = r >= 0
            ##########################################

            err = float(yi)-float(r)

            errs += np.abs(err)

            if verbose:
                print(yi, r)

            self.w = self.w + self.lr * err * x_

        return errs

    def predict(self, x):
        return np.round(self.w @ np.insert(x, 0, 1, 1).T)

    def decisionLine(self):
        w = self.w
        slope =  -(w[0]/w[2]) / (w[0]/w[1])
        intercept = -w[0]/w[2]
        return slope, intercept

p = Perceptron()

line_properties = []
errs = []

for i in range(20):
    errs.append(p.train(x, y, True if i == 999 else False))
    line_properties.append(p.decisionLine())

print(p.predict(x)) # works like a charm!



@interact
def showLine(i:(0,len(line_properties)-1,1)=0):
    xs = np.linspace(1, 4)
    a, b = line_properties[i]

    ys = a * xs + b

    plt.scatter(*x.T)
    plt.plot(xs, ys, "k--")
最后,我计算决策边界,即分离0类和1类的线性等式。然而,它似乎是关闭的。我试过倒装等,但不知道出了什么问题。有趣的是,如果我将学习规则更改为

self.w = self.w + self.lr * err / x_
i、 e.除以
x
,它工作正常-我完全困惑了。有人有主意吗

真正解决 现在我给感知机添加了一个很小但很重要的部分,我刚刚忘记了(也许其他人也会忘记)。你必须进行阈值激活
r=r>=0
-现在它以0为中心,然后它就开始工作了-这基本上就是下面的答案。如果不这样做,必须更改类,才能在0处再次获得中心。目前,我更喜欢使用类-1和1,因为这样可以提供更好的决策线(居中),而不是非常接近某个数据云的线

之前:

现在:


您正在创建一个目标为0和1的线性回归(不是逻辑回归!)。你画的线是模型预测为0的线,所以它最好穿过标记为0的点云,就像你第一次画的那样

如果不希望为逻辑回归实现sigmoid,那么至少需要显示一条对应于0.5而不是0的值的边界线


至于反转权重,提供一个看起来像你想要的图,我认为这只是这个数据的巧合。

错误很好地收敛,顺便说一句……我明白你的意思,我用类-1和+1测试了它(假设中心线在0),现在,这条线正好是它应该在的位置。但我不确定这个推理是否正确;感知器本身就是,不是吗?它只是取决于数据格式的更新规则和决策边界的细节。正如您所说,您可以使用targets
-1,1
,或者您可以稍微修改targets
0,1
的规则。感谢Ben,在您的帮助下,我发现了我的逻辑错误,我没有使用激活(请参见上面的答案),因此它实际上是以0为中心的,同样是以
[0,1]
类为中心的。然后它就如预期的那样工作了。很简单,但很重要。正如您所提到的,更改的类也会发生相同的居中情况。这真的很有帮助!