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

Decision boundary in perceptron not correct

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

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

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

最后,我正在计算决策边界,即线性方程。分离class 0和1。但是,它似乎关闭了。我尝试了倒置等,但不知道出了什么问题。有趣的是,如果我将学习规则更改为

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

即除以 x_,它工作正常 - 我完全糊涂了。有人有想法吗?

真实解决

现在我向 Perceptron 添加了一个很小但非常重要的部分,我只是忘记了它(也许其他人也可能会忘记它)。你必须做阈值激活! r = r >= 0 - 现在它以 0 为中心,然后它确实有效 - 这基本上是下面的答案。如果不这样做,您 必须更改 classes 以再次获得位于 0 的中心。目前,我更喜欢 classes -1 和 1,因为这提供了更好的决策线(居中),而不是非常接近数据云之一的线。

之前:

现在:

您正在创建目标为 0 和 1 的线性回归(不是逻辑回归!)。您绘制的线是模型预测 0 的线,因此它应该理想情况下,切入标记为 0 的点云,就像在您的第一个图中一样。

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

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