簡體   English   中英

為什么我的神經網絡無法預測正弦波的下一個值?

[英]Why is my neural network having trouble predicting the next value of a sin wave?

為什么我的神經網絡無法預測正弦波的下一個數字?

我不知道我是否需要更好的損失 function 或問題是什么。 它似乎優化了大約 500 步,然后它只是在看起來一點也不像波浪的預測中掙扎。

model 的輸入是 120。這是正弦波先前數字的 120。 要求 model 預測下一個數字的位置,我將正弦波值存儲在雙端隊列中。 我將下一個 sin wave 值插入到其雙端隊列的末尾。

目標和預測是 arrays,形狀為 (200,)。
數組中低於 100 的每個索引表示一個負數,高於 100 的每個索引表示一個正數。
所有介於-10之間的百分之一的值都由索引 0 到 100 表示。
在 100 以上,表示01之間的百分之一。 換句話說,200 個可能的數組形式的值來顯示神經網絡的目標是什么以及預測是什么。

代碼(我在 Jupyter Notebook 中分解的代碼)...

%matplotlib inline

import torch
import random
import numpy as np
from collections import deque
from matplotlib import pyplot as plt
from matplotlib.pyplot import figure
from torch import nn
import time
import math

plt.rcParams["figure.figsize"]=(12, 8)  

class Network(nn.Module):
    def __init__(self):
        super().__init__()
        
        self.net = nn.Sequential(
            nn.Linear(120, 136),
            nn.ReLU(),
            nn.Dropout(0.05),
            nn.Linear(136, 146),
            nn.ReLU(),
            nn.Dropout(0.05),
            nn.Linear(146, 156),
            nn.ReLU(),
            nn.Dropout(0.05),
            nn.Linear(156, 170),
            nn.ReLU(),
            nn.Linear(170, 188),
            nn.Dropout(0.05),
            nn.ReLU(),
            nn.Linear(188, 200))  

    def forward(self, x):
        return self.net(x)  

online_net = Network().cuda("cuda:2")

optimizer = torch.optim.Adam(online_net.parameters(), lr=1e-5)
device = torch.device("cuda:2" if torch.cuda.is_available() else "cpu")  

sensor_buffer = deque(maxlen=120)
action_buffer = deque(maxlen=120)

[sensor_buffer.append(np.array([random.random() for _ in range(4)]).mean()) for __ in range(121)]
[action_buffer.append(0) for _ in range(121)]  

def format_target(n):
    n = (n * 100)
    l = [-1 for o in range(200)]
    l[int(n)] = 1
    return l  

for steps in range(1400):
    
    adder += (random.random() * 0.2)
    sensor_buffer.append(adder)
    sensor_sinwave = np.sin(sensor_buffer[-1])

    outers = torch.tensor(np.sin(sensor_buffer), dtype=torch.float32).cuda("cuda:2").T

    outer = online_net.forward(outers)

    prediction = torch.argmax(outer).item()

    n_prediction = (prediction * 0.01) -1

    action_buffer.append(n_prediction)

    target = format_target(sensor_sinwave)
    target_t = torch.as_tensor(target, dtype=torch.float32, device=device)

    loss = nn.functional.smooth_l1_loss(outer, target_t)


    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if steps % 150 == 0:
        print(loss.item(), n_prediction, sensor_sinwave)

我試圖預測的罪惡浪潮在此處輸入圖像描述

我的預測在此處輸入圖像描述

您的 model 有兩個主要問題:一個是機械問題,一個是理論問題。

  1. 你的損失(和伴隨的架構)沒有適當地解決 model 問題。 您實際上是在嘗試訓練回歸問題 (R^n -> R),但您將其定義為分類問題 (R^n -> Z^m)。 通常(粗略地),對於分類問題,您將使用交叉熵損失,而對於回歸問題,您將使用 L2 損失。 如果您將 model 的 output 維度更改為 1,並將損失更改為 L2,您的狀態應該會更好。

  2. 你的 model 對於這樣一個簡單的 function 來說太復雜了。你的 model 的參數越多,你可能引入的方差就越大。 這相當於更高的過度擬合可能性和更小的泛化機會。 讓您的 model 淺幾層,您可能會對它的性能感到滿意。

這是一個很小的 C++ 代碼,用於預測下一個 sin() 值。 希望它對你有用。

#include <cmath>
#include <iostream>
#include <vector>
using namespace std;

const float pi = 4.0f * atanf(1.0f);

int main(void)
{
    // Replace these samples with your input data
    vector<float> samples(120, 0.0f);

    for (size_t i = 0; i < samples.size(); i++)
    {
        const float n = (i + 1) / static_cast<float>(samples.size());
        samples[i] = sin(2 * pi * n);

        cout << samples[i] << endl;
    }

    cout << endl;

    vector<float> arc_samples(120, 0.0f);

    for (size_t i = 0; i < arc_samples.size(); i++)
    {
        arc_samples[i] = asin(samples[i]);

        cout << arc_samples[i] << endl;
    }

    cout << endl;

    size_t avg_count = 0;
    float avg_diff = 0.0f;

    for (size_t i = 1; i < arc_samples.size(); i++)
    {
        avg_diff += fabsf(arc_samples[i] - arc_samples[i - 1]);
        avg_count++;
    }

    avg_diff /= avg_count;

    float next_sample = arc_samples[arc_samples.size() - 1] + avg_diff;

    cout << "Next sin() value = " << sin(next_sample) << endl;

    return 0;
}

暫無
暫無

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

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