OR 函数的感知器不收敛
perceptron for OR function doesnt converge
我正在实现一个简单的感知器,用于在 python 中对 OR 函数进行分类。但是错误并没有改变。任何建议将不胜感激。
def activation_function(x):
if x<0:
return 0
else:
return 1
training_set = [((0, 0), 0), ((0, 1), 1), ((1, 0), 1), ((1, 1), 1)]
w = random.rand(2)
errors = []
eta = .2
n = 100
for i in range(n):
for x, y in training_set:
u = sum(x*w)
error = y - activation_function(u)
errors.append(error)
for index, value in enumerate(x):
w[index] += eta * error * value
ylim([-1,1])
plot(errors)
错误图:
我会说你错过了偏见 b...
如果你添加它,它会收敛得很漂亮。
import numpy as np
import matplotlib.pyplot as py
np.random.seed(42)
w = np.random.rand(2)
b = 0
errors = []
eta = .2
n = 10
for i in range(n):
for x, y in training_set:
u = np.sum(x*w)+b
error = y - activation_function(u)
errors.append(error)
for index, value in enumerate(x):
#print(index, " ", value)
w[index] += eta * error * value
b += eta*error
请注意,我用一些更合理的名称导入了与您不同的库,这样我就知道哪个函数来自哪里...如果这对您有帮助请告诉我...
顺便说一句,这是分类的结果。我希望颜色有意义......红色和蓝色有点华而不实,但你明白了。请注意,您可以找到此问题的无限解决方案。因此,如果您更改随机种子,您将得到一条不同的线,该线将线性分隔您的点。
此外,您的算法不会收敛,因为当您的线穿过 (0,0) 时,尽管您的预测是错误的,但自此特定点的 value=0
以来,权重将不会更新。所以问题是你的更新不会做任何事情。这就是你的错误振荡的原因。
EDIT 根据要求,我写了一个小教程(一个 Jupyter 笔记本),其中包含一些关于如何绘制分类器决策边界的示例。您可以在 github
上找到它
github 存储库:https://github.com/michelucci/python-Utils
希望有用。
编辑 2:如果你想要快速且非常脏的版本(我用于红色和蓝色情节的版本),这里是代码
lim = 3.0
X1 = [x1 for x1 in np.arange(-lim,lim,0.1)]
X2 = [x2 for x2 in np.arange(-lim,lim,0.1)]
XX = [(x1,x2) for x1 in np.arange(-lim,lim,0.1) for x2 in np.arange(-lim,lim,0.1)]
Xcolor = ["blue" if np.sum(w[0]*x1+w[1]*x2)+b > 0 else "red" for x1 in X1 for x2 in X2]
x,y = zip(*XX)
py.scatter(x,y, c = Xcolor)
py.scatter(0,0, c = "black")
py.scatter(1,0, c = "white")
py.scatter(0,1, c = "white")
py.scatter(1,1, c = "white")
py.show()
我正在实现一个简单的感知器,用于在 python 中对 OR 函数进行分类。但是错误并没有改变。任何建议将不胜感激。
def activation_function(x):
if x<0:
return 0
else:
return 1
training_set = [((0, 0), 0), ((0, 1), 1), ((1, 0), 1), ((1, 1), 1)]
w = random.rand(2)
errors = []
eta = .2
n = 100
for i in range(n):
for x, y in training_set:
u = sum(x*w)
error = y - activation_function(u)
errors.append(error)
for index, value in enumerate(x):
w[index] += eta * error * value
ylim([-1,1])
plot(errors)
错误图:
我会说你错过了偏见 b...
如果你添加它,它会收敛得很漂亮。
import numpy as np
import matplotlib.pyplot as py
np.random.seed(42)
w = np.random.rand(2)
b = 0
errors = []
eta = .2
n = 10
for i in range(n):
for x, y in training_set:
u = np.sum(x*w)+b
error = y - activation_function(u)
errors.append(error)
for index, value in enumerate(x):
#print(index, " ", value)
w[index] += eta * error * value
b += eta*error
请注意,我用一些更合理的名称导入了与您不同的库,这样我就知道哪个函数来自哪里...如果这对您有帮助请告诉我...
顺便说一句,这是分类的结果。我希望颜色有意义......红色和蓝色有点华而不实,但你明白了。请注意,您可以找到此问题的无限解决方案。因此,如果您更改随机种子,您将得到一条不同的线,该线将线性分隔您的点。
此外,您的算法不会收敛,因为当您的线穿过 (0,0) 时,尽管您的预测是错误的,但自此特定点的 value=0
以来,权重将不会更新。所以问题是你的更新不会做任何事情。这就是你的错误振荡的原因。
EDIT 根据要求,我写了一个小教程(一个 Jupyter 笔记本),其中包含一些关于如何绘制分类器决策边界的示例。您可以在 github
上找到它github 存储库:https://github.com/michelucci/python-Utils
希望有用。
编辑 2:如果你想要快速且非常脏的版本(我用于红色和蓝色情节的版本),这里是代码
lim = 3.0
X1 = [x1 for x1 in np.arange(-lim,lim,0.1)]
X2 = [x2 for x2 in np.arange(-lim,lim,0.1)]
XX = [(x1,x2) for x1 in np.arange(-lim,lim,0.1) for x2 in np.arange(-lim,lim,0.1)]
Xcolor = ["blue" if np.sum(w[0]*x1+w[1]*x2)+b > 0 else "red" for x1 in X1 for x2 in X2]
x,y = zip(*XX)
py.scatter(x,y, c = Xcolor)
py.scatter(0,0, c = "black")
py.scatter(1,0, c = "white")
py.scatter(0,1, c = "white")
py.scatter(1,1, c = "white")
py.show()