我按书上打的一个单神经元学习sin曲线,代码如下
import numpy as np
import matplotlib.pyplot as plt
X = np.linspace(-np.pi/2, np.pi/2)
T = (np.sin(X) + 1) / 2
data = len(T)
def forward(x, w, b):
u = w * x + b
y = 1 / (1 + np.exp(-u))
return y
def backward(x, y, t):
delta = (y - t) * (1 - y) * y
grad_w = x * delta
grad_b = delta
return grad_w, grad_b
def show_out(X, Y , T, epoch):
plt.plot(X, T, linestyle="dashed")
plt.scatter(X, Y, marker="+")
plt.grid()
plt.show()
print("epoch", epoch)
print("Eorror", (1 / 2) * np.sum((Y - T) ** 2))
eta = 0.1
epoch = 100
w = 0.2
b = -0.2
for i in range(epoch):
if i < 2:
Y = forward(X, w, b)
show_out(X, Y, T, epoch)
idx_data = np.arange(data)
np.random.shuffle(idx_data)
for j in idx_data:
x = X[j]
t = T[j]
y = forward(x, w, b)
grad_w, grad_b = backward(x, y, t)
w -= eta * grad_w
b -= eta * grad_b
Y = forward(X, w, b)
show_out(X, Y, T, epoch)
这个代码可以学习正确数据X=np.linspace(-np.pi/2,np.pi/2), T=(np.sin(X) + 1)/ 2之间曲线。如下图
可是,一但把正确数据中的sin换成cos之后,在X=np.linspace(-np.pi/2, no.pi/2)之间的曲线就不能够学习了。
如下图
我觉得这应该是因为(-np.pi/2, np.pi/2)这个区间里cos曲线不是单调的,虽然一个x只有一个对应的y,但一个y却有两个对应的x,你的学习算法可能不支持这种非单调的情况,把区间改成(0, np.pi)试试?
能把整齐的代码贴出来嘛,或者把书上的那个步骤贴出来也行,我看着感觉有问题,sin0 不应该是 0 嘛,第一个如果是sin的图那也不对吧