【问题标题】:Decision boundary in perceptron not correct感知器中的决策边界不正确
【发布时间】:2021-05-19 10:14:22
【问题描述】:

我正在为讲座准备一些代码并重新实现了一个简单的感知器: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_

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

真正解决

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

之前:

现在:

【问题讨论】:

  • 错误很好地收敛了顺便说一句...

标签: numpy machine-learning deep-learning perceptron


【解决方案1】:

您正在创建目标为 0 和 1 的线性回归(不是逻辑回归!)。您绘制的线是模型预测为 0 的线,因此它应该理想地穿过云标记为 0 的点数,如您的第一个图所示。

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

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

【讨论】:

  • 我明白你的意思,我用 -1 和 +1 类对其进行了测试(假设中心线在 0 处),你走了,这条线正好在它应该在的地方。但我不确定推理是否正确;感知器本身就是linear classifier,不是吗?
  • 它只是根据数据的格式归结为更新规则和决策边界的细节。你可以按照你说的使用目标-1, 1,也可以对目标0, 1稍微修改规则。
  • 感谢 Ben,在您的帮助下,我发现了我的逻辑错误,我没有使用激活(请参阅上面的答案),因此它实际上是 0 居中的,也使用 [0, 1] 类。然后它按预期工作。简单的事情,但很重要。正如您所提到的,更改后的类也会发生相同的居中。真的很有帮助!
猜你喜欢
  • 2013-10-04
  • 2017-08-29
  • 2013-10-04
  • 2018-07-16
  • 2015-12-31
  • 2020-05-05
  • 2016-10-27
  • 2019-10-03
相关资源
最近更新 更多