Python 中的感知器 – 偏差不正确
Perceptron in Python – Bias is incorrect
对于某些输入 X
,例如:
[[ 1.456044 -7.058824]
[-4.478022 -2.072829]
[-7.664835 -6.890756]
[-5.137363 2.352941]
...
和Y
,例如:
[ 1. 1. 1. -1. ...
这是我的感知器训练函数:
def train(self, X, Y, iterations=1000):
# Add biases to every sample.
biases = np.ones(X.shape[0])
X = np.vstack((biases, X.T)).T
w = np.random.randn(X.shape[1])
errors = []
for _ in range(iterations):
all_corr = True
num_err = 0
for x, y in zip(X, Y):
correct = np.dot(w, x) * y > 0
if not correct:
num_err += 1
all_corr = False
w += y * x
errors.append(num_err)
# Exit early if all samples are correctly classified.
if all_corr:
break
self.w = perpendicular(w[1:])
self.b = w[0]
return self.w, self.b, errors
当我打印错误时,我通常会看到如下内容:
[28, 12, 10, 7, 10, 8, 11, 8, 0]
请注意,我得到 0 个错误,但数据显然因某些偏差而偏离:
例如,这里是 b
一个 运行:
-28.6778508366
我查看了 this SO,但没有发现我们的算法有什么不同。我想也许这就是我解释和绘制 w
和 b
的方式?我只是做一些非常简单的事情:
def plot(X, Y, w, b):
area = 20
fig = plt.figure()
ax = fig.add_subplot(111)
p = X[Y == 1]
n = X[Y == -1]
ax.scatter(p[:, 0], p[:, 1], s=area, c='r', marker="o", label='pos')
ax.scatter(n[:, 0], n[:, 1], s=area, c='b', marker="s", label='neg')
neg_w = -w
xs = [neg_w[0], w[0]]
ys = [neg_w[1], w[1]] # My guess is that this is where the bias goes?
ax.plot(xs, ys, 'r--', label='hyperplane')
...
是的,我认为您学得正确 w
但没有正确绘制分隔线。
你有一个二维数据集。所以你的 w
有两个维度。比方说,w = [w1, w2]
。
分隔线应该是w1 x x1 + w2 x x2 + b = 0
。
我认为您是在该线上使用两个点来绘制分隔线。这两点可以在下面找到:
- 首先,我们将
x1
设置为 0。我们得到 x2 = -b/w2
。
- 其次,让我们将
x2
设置为 0。我们得到 x1 = -b/w1
。
因此这两个点应该是(0, -b/w2)
和(-b/w1, 0)
。在你的xs
和ys
的公式中,我没有看到b
是如何使用的。您可以尝试设置:
# Note w[0] = w1, w[1] = w2.
xs = [0, -b/w[0]] # x-coordinate of the two points on line.
ys = [-b/w[1], 0] # y-coordinate.
见下图,摘自@gwg 提到的 this 幻灯片。红色实线是你通过 w
学到的分隔符(不是 self.w
)。红色虚线箭头表示:在分隔符的那一侧,sum(wx) > 0 的符号。它在基于边际的模型(感知器就是这样的模型)中也很有用,可以计算你学习的模型的边际。也就是说,如果你从分隔符开始,并沿着分隔符的垂直方向,你到达的第一个例子定义了那一侧的"margin",这是你到目前为止行进的距离(注意你可以开始从分隔符上的任何位置)。
对于某些输入 X
,例如:
[[ 1.456044 -7.058824]
[-4.478022 -2.072829]
[-7.664835 -6.890756]
[-5.137363 2.352941]
...
和Y
,例如:
[ 1. 1. 1. -1. ...
这是我的感知器训练函数:
def train(self, X, Y, iterations=1000):
# Add biases to every sample.
biases = np.ones(X.shape[0])
X = np.vstack((biases, X.T)).T
w = np.random.randn(X.shape[1])
errors = []
for _ in range(iterations):
all_corr = True
num_err = 0
for x, y in zip(X, Y):
correct = np.dot(w, x) * y > 0
if not correct:
num_err += 1
all_corr = False
w += y * x
errors.append(num_err)
# Exit early if all samples are correctly classified.
if all_corr:
break
self.w = perpendicular(w[1:])
self.b = w[0]
return self.w, self.b, errors
当我打印错误时,我通常会看到如下内容:
[28, 12, 10, 7, 10, 8, 11, 8, 0]
请注意,我得到 0 个错误,但数据显然因某些偏差而偏离:
例如,这里是 b
一个 运行:
-28.6778508366
我查看了 this SO,但没有发现我们的算法有什么不同。我想也许这就是我解释和绘制 w
和 b
的方式?我只是做一些非常简单的事情:
def plot(X, Y, w, b):
area = 20
fig = plt.figure()
ax = fig.add_subplot(111)
p = X[Y == 1]
n = X[Y == -1]
ax.scatter(p[:, 0], p[:, 1], s=area, c='r', marker="o", label='pos')
ax.scatter(n[:, 0], n[:, 1], s=area, c='b', marker="s", label='neg')
neg_w = -w
xs = [neg_w[0], w[0]]
ys = [neg_w[1], w[1]] # My guess is that this is where the bias goes?
ax.plot(xs, ys, 'r--', label='hyperplane')
...
是的,我认为您学得正确 w
但没有正确绘制分隔线。
你有一个二维数据集。所以你的 w
有两个维度。比方说,w = [w1, w2]
。
分隔线应该是w1 x x1 + w2 x x2 + b = 0
。
我认为您是在该线上使用两个点来绘制分隔线。这两点可以在下面找到:
- 首先,我们将
x1
设置为 0。我们得到x2 = -b/w2
。 - 其次,让我们将
x2
设置为 0。我们得到x1 = -b/w1
。
因此这两个点应该是(0, -b/w2)
和(-b/w1, 0)
。在你的xs
和ys
的公式中,我没有看到b
是如何使用的。您可以尝试设置:
# Note w[0] = w1, w[1] = w2.
xs = [0, -b/w[0]] # x-coordinate of the two points on line.
ys = [-b/w[1], 0] # y-coordinate.
见下图,摘自@gwg 提到的 this 幻灯片。红色实线是你通过 w
学到的分隔符(不是 self.w
)。红色虚线箭头表示:在分隔符的那一侧,sum(wx) > 0 的符号。它在基于边际的模型(感知器就是这样的模型)中也很有用,可以计算你学习的模型的边际。也就是说,如果你从分隔符开始,并沿着分隔符的垂直方向,你到达的第一个例子定义了那一侧的"margin",这是你到目前为止行进的距离(注意你可以开始从分隔符上的任何位置)。