拟合正弦波的神经网络

时间:2019-11-19 02:41:24

标签: python neural-network activation sigmoid relu

因此,我一直在学习神经网络,并尝试从头开始对它们进行编码,并在某些情况下取得了成功。因此,我想到将一个简单的单层神经网络拟合到一个正弦波上。 我知道我可以使用keras,但我想学习内部工作。 我的输入x是使用numpy从0到10的值以0.1步长生成的,并且y = sin(x) 我初始化了网络的权重和偏差,还对反向传播进行了编码。但是在拟合数据后,当我尝试进行预测时会给我一条直线。我将层的激活从S形变化为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(learningrate)和reg(lambda正则化器)值不同的值 我究竟做错了什么?我应该在这里尝试RNN吗? 我看到某个地方使用顺序模型来使用keras,并且使用泄漏的relu作为激活函数。我没有尝试使用该激活。那是我应该尝试的东西吗?

1 个答案:

答案 0 :(得分:0)

训练时,您显示的神经网络x值介于0到10之间。在预测过程中,您使用的x值介于10到20之间。这些值大于神经网络以前看到的值,因此它将无法给你一个正弦波。

当值超出其所见范围时,神经网络无法很好地进行推断。如果您想了解神经网络正弦波在0到10之间的样子并预测在训练过程中未看到的点,则可以在0到10之间获取1000个随机点及其sin(x)值,并使用80%那些训练网络的人和20%的人测试预测。我认为那您将获得良好的结果。

但是,当您要预测正弦波如何超过10时,您应该在例如4点的元组上训练模型,并以5点作为标签。预测时,给定净4个连续y值,然后让它预测第五个。对于下一个预测,您将使用3个旧点以及之前的预测,然后再次预测下一个点。不要使用任何x值进行训练。

让我知道是否还不清楚。如果没有,我将作画。