簡體   English   中英

用於擬合正弦波的神經網絡

[英]Neural network for fitting a sine wave

所以,我一直在學習神經網絡,並嘗試從頭開始編寫它們,並在某些情況下取得了成功。 所以,我想到了將一個簡單的單層神經網絡擬合到正弦波。 我知道我可以使用 keras 但我想了解內部工作。 我的輸入 x 是使用 numpy 從 0 到 10 的值以 0.1 步和 y = sin(x) 生成的,我初始化了網絡的權重和偏差,還對反向傳播進行了編碼。 但是在我嘗試預測時擬合數據后給了我一條直線。 我將層的激活從 sigmoid 更改為 tanh 以及它們各自的梯度,但 output 不能預測正弦波。 翻遍論壇后,不斷出現這種周期性函數,使用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()

最終 plot這是我得到的結果。 我知道我不應該在最后一層使用 softmax。 但我已經嘗試了一切,這是我最新的代碼。 同樣對於不同的激活,我嘗試了許多時期和許多隱藏節點,它們的 alpha(learningrate) 和 reg(lambda 正則化器) 值不同我做錯了什么? 我應該在這里嘗試RNN嗎? 我在某處看到 keras 使用順序 model 和泄漏 relu 用作激活 function。 我沒有嘗試使用該激活。 那是我應該嘗試的嗎?

訓練時,您顯示的神經網絡 x 值介於 0 和 10 之間。在預測期間,您使用的 x 值介於 10 和 20 之間。這些值比網絡以前見過的值更大,因此它無法為您提供漂亮的正弦波。

當值超出他們所看到的范圍時,神經網絡無法很好地推斷。 如果你想學習神經網絡在 0 到 10 之間的正弦波是什么樣子並預測它在訓練期間沒有看到的點,你可以取 0 到 10 之間的 1000 個隨機點及其 sin(x) 值並使用 80%其中用於訓練網絡,20% 用於測試預測。 我想你會得到很好的結果。

但是,當您想預測正弦波如何超過 10 時,您應該在元組上訓練您的 model,例如 4 點,第 5 點為 label。 在預測時,您給出凈 4 個連續的 y 值並讓它預測第五個。 對於下一個預測,您使用 3 個舊點加上之前的預測,然后再次預測下一個點。 不要使用任何 x 值進行訓練。

讓我知道這是否不完全清楚。 如果沒有,我會畫一個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM