用于拟合正弦波的神经网络
Posted
技术标签:
【中文标题】用于拟合正弦波的神经网络【英文标题】:Neural network for fitting a sine wave 【发布时间】:2020-03-14 11:45:35 【问题描述】:所以,我一直在学习神经网络,并尝试从头开始对其进行编码,并且在某些情况下取得了成功。所以,我想到了将一个简单的单层神经网络拟合到正弦波。 我知道我可以使用 keras,但我想学习内部工作。 我的输入 x 是使用 numpy 生成的,值范围从 0 到 10,步长为 0.1,y = sin(x) 我初始化了网络的权重和偏差,还对反向传播进行了编码。但是在我尝试预测时拟合数据后给了我一条直线。我将层的激活从 sigmoid 更改为 tanh 以及它们各自的梯度,但输出不能预测正弦波。 翻遍论坛,不断有人说这种周期函数用的是RNN。
import numpy as np
from matplotlib import pyplot as plt
from tqdm import tqdm
def init_weight_and_bias_NN(M1, M2):
W = np.random.randn(M1, M2) / np.sqrt(M1 + M2)
b = np.zeros(M2)
return W.astype(np.float32), b.astype(np.float32)
def out(x, w, b):
return np.add(np.dot(x, w), b)
def softmax(A):
expA = np.exp(A)
return expA / expA.sum(axis=1, keepdims=True)
def relu(x):
return x * (x > 0)
def start(x, y):
alpha = 0.01
reg = 0.3
epochs = 1
hiddennodes = 3
M, D = x.shape
w1, b1 = init_weight_and_bias_NN(D, hiddennodes)
w2, b2 = init_weight_and_bias_NN(hiddennodes, 1)
with tqdm(total=epochs, desc="Training") as prog:
for i in range(epochs):
hidden = relu(out(x, w1, b1))
output = softmax(out(hidden, w2, b2))
w2 = np.subtract(w2, np.multiply(alpha, np.add(np.dot(hidden.T, np.subtract(output, y)), reg * w2)))
b2 = np.subtract(b2, np.multiply(alpha, np.sum(np.subtract(output, y))))
hiddenError = np.dot(np.subtract(output, y), w2.T)
w1 = np.subtract(w1, np.multiply(alpha, np.add(np.dot(x.T, hiddenError), reg * w1)))
b1 = np.subtract(b1, np.multiply(alpha, np.sum(hiddenError)))
prog.update(1)
return w1, b1, w2, b2
def predict(w1, b1, w2, b2, x):
y = []
for val in x:
hidden = relu(out(val, w1, b1))
y.append(softmax(out(hidden, w2, b2)).tolist().pop().pop())
return np.array(y)
if __name__ == '__main__':
x = np.arange(0, 10, 0.1)
x1 = x.reshape((1, x.shape[0]))
y = np.sin(x)
w1, b1, w2, b2 = start(x1, y)
x2 = np.arange(10, 20, 0.1)
ynew = predict(w1, b1, w2, b2, x2)
plt.plot(x, y, c='r')
plt.plot(x, ynew, c='b')
plt.title("Original vs machine produced")
plt.legend(["Original", "Machine"])
plt.show()
Final plot 这是我得到的结果。 我知道我不应该在最后一层使用 softmax。但我已经尝试了一切,这是我最新的代码。 同样对于不同的激活,我尝试了许多时期和许多隐藏节点,它们具有不同的 alpha(学习率)和 reg(lambda 正则化器)值 我究竟做错了什么?我应该在这里尝试RNN吗? 我在某处看到使用顺序模型使用了 keras,并且使用了泄漏的 relu 作为激活函数。我没有尝试使用该激活。这是我应该尝试的吗?
【问题讨论】:
看看phased LSTM 这是一个回归问题,而不是一个分类问题。所以,要修复的一件事是: output = relu(out(hidden, w2, b2)) 【参考方案1】:在训练时,您显示的神经网络 x 值介于 0 到 10 之间。在预测期间,您使用的 x 值在 10 到 20 之间。这些值比网络以前见过的值大,因此它无法给你一个漂亮的正弦波。
当值超出他们所看到的范围时,神经网络无法很好地推断。如果你想学习神经网络在 0 到 10 之间的正弦波是什么样子并预测它在训练期间没有看到的点,你可以取 0 到 10 之间的 1000 个随机点及其 sin(x) 值并使用 80%其中用于训练网络,20% 用于测试预测。我想你会得到很好的结果。
但是,当您想预测正弦波如何超过 10 时,您应该在元组上训练您的模型,例如 4 个点,第 5 个点作为标签。在预测时,您给出净 4 个连续的 y 值并让它预测第五个。对于下一个预测,您使用 3 个旧点加上之前的预测,然后再次预测下一个点。不要使用任何 x 值进行训练。
如果这还不完全清楚,请告诉我。如果没有,我会画一个。
【讨论】:
是的,我尝试了新方法,但仍然没有得到正弦波。以上是关于用于拟合正弦波的神经网络的主要内容,如果未能解决你的问题,请参考以下文章