首页 文章

RNN无法学习积分函数

提问于
浏览
0

为了研究深度学习,RNN,LSTM等我试图使RNN适合整合功能 . 我把0到1的随机信号作为RNN的输入,并通过-0.5输入信号偏置成为积分,使0:1之间的积分限制并作为RNN目标学习 . Blue - random input, orange - integrated input

所以我的时间序列只有一个输入(随机)和一个输出(输入的有限积分),我希望RNN通过输入预测输出 . 我使用了Pytorch并尝试使用香草RNN,GRU单元,不同大小的隐藏层,堆叠几个RNN,将密集连接层放入RNN输出,不同深度反向传播到时间(从2到50梯度回滚) . 而且我可以找到一种精确匹配积分函数的方法 . 这是我最好的结果:green - RNN output . Green line (model output) does not fit orange line in many cases - that is the problem.

Here is my source code in jupyter . 我的问题:是否有可能 - 通过RNN学习饱和积分函数?我的问题在哪里?我可以做些什么来获得更好的质量? Ideally I want to RNN output be equal desired output (integral function) through all time series.

PS:原始格式的代码:

import numpy as np
from scipy.stats import truncnorm
import random
import math
import copy
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import matplotlib.cm as cm

def generate_data(num_of_data):
    input_data=[]
    output_data=[]
    current_input_value=0
    current_output_value=0
    for i in range(num_of_data):
        if (random.random()<0.1):
            current_input_value=random.random()
#            current_output_value=0
        current_input_value=current_input_value+(random.random()-0.5)*0
        current_output_value=current_output_value+0.0*(current_input_value-current_output_value)+(current_input_value-0.5)*0.1
        if (current_output_value<0):
            current_output_value=0
        if (current_output_value>1):
            current_output_value=1

        input_data.append(current_input_value)
        output_data.append(current_output_value)
    return input_data,output_data

%matplotlib inline
matplotlib.rcParams['figure.figsize'] = (20, 6)

input_data,output_data=generate_data(500)
plt.plot(input_data)
plt.plot(output_data)
plt.show()


import torch
import torch.nn as nn
from torch.autograd import Variable
from torch import optim


class RNN(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(RNN, self).__init__()
        self.number_of_layers=1
        self.hidden_size = hidden_size
        self.gru = nn.GRU(input_size, hidden_size,self.number_of_layers)
        self.Dense1 = nn.Linear(hidden_size, hidden_size)
        self.Dense1A = nn.ReLU()
        self.Dense2 = nn.Linear(hidden_size, output_size)


    def forward(self, input, hidden):
        gru_output, hidden = self.gru(input, hidden)
        Dense1Out=self.Dense1(gru_output)
        Dense1OutAct=self.Dense1A(Dense1Out)
        output=self.Dense2(Dense1OutAct)
        return output, hidden

    def initHidden(self):
        return Variable(torch.zeros(self.number_of_layers,1,self.hidden_size))



import time
import math
import operator

def timeSince(since):
    now = time.time()
    s = now - since
    m = math.floor(s / 60)
    s -= m * 60
    return '%dm %ds' % (m, s)
rnn = RNN(1, 50, 1)

n_iters = 250000
print_every = 2000
plot_every = 2000
all_losses = []
total_loss_print = 0
total_loss_plot = 0

criterion=nn.L1Loss()

print("training...\n")

start = time.time()
optimizer = optim.Adam(rnn.parameters(), lr=0.0002)
rnn_hidden = rnn.initHidden()
rnn.zero_grad()
loss = 0
#for gata_q in range(int(n_iters/500)):
#    rnn_hidden = rnn.initHidden()

input_data,output_data=generate_data(n_iters)
for data_index in range(len(input_data)):
    input_tensor=torch.zeros(1, 1, 1)
    input_tensor[0][0][0]=input_data[data_index]

    output_tensor=torch.zeros(1, 1, 1)
    output_tensor[0][0][0]=output_data[data_index]

    rnn_output, rnn_hidden = rnn(Variable(input_tensor), rnn_hidden)
    loss += criterion(rnn_output, Variable(output_tensor))


    if data_index%2==0:
        loss.backward()

        total_loss_print += loss.data[0]
        total_loss_plot += loss.data[0]
        optimizer.step()
        rnn_hidden=Variable(rnn_hidden.data)
        rnn.zero_grad()
        loss = 0

    if data_index % print_every == 0:
        print('%s (%d %d%%) tl=%.4f' % (timeSince(start), data_index, data_index / n_iters * 100,total_loss_print/print_every))
        total_loss_print = 0

    if data_index % plot_every == 0:
        all_losses.append(total_loss_plot / plot_every)
        total_loss_plot = 0



import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

plt.figure()
plt.plot(all_losses)
plt.show()

rnn_hidden = rnn.initHidden()

rnn.zero_grad()
loss = 0

rnn_output_data=[]
input_data,output_data=generate_data(1500)
for data_index in range(len(input_data)):
    input_tensor=torch.zeros(1, 1, 1)
    input_tensor[0][0][0]=input_data[data_index]
    rnn_output, rnn_hidden = rnn(Variable(input_tensor), rnn_hidden)
    rnn_output_data.append(rnn_output.data.numpy()[0][0][0])

plt.plot(input_data)#blue
plt.plot(output_data)#ogange
plt.plot(rnn_output_data)#green
plt.show()

1 回答

  • 0

    我自己发现了这个问题 . 在某些情况下,问题是对最新数据的过度拟合,因为在强化学习案例中,过度拟合可能会在利用最新策略时发生 . 因为我没有使用任何迷你批次并且在新数据点之后直接应用优化器,并且由于数据点类似于20-50个样本,优化器只是简单地将网络安装到忘记先前拟合的最新点 . 我通过时间收集50个点的梯度数据来解决它,并且只有在我应用了一步优化器之后才解决它 . 网络现在可以学得更好,但仍然不完美 .

    以下是修改代码以使其工作:

    rnn_output, rnn_hidden = rnn(Variable(input_tensor), rnn_hidden)
    
    loss += criterion(rnn_output, Variable(output_tensor))
    
    if data_index % 2==0:
        loss.backward()
        total_loss_print += loss.data[0]
        rnn_hidden=Variable(rnn_hidden.data)
        loss = 0
       # torch.nn.utils.clip_grad_norm(rnn.parameters(), 0.01)
    if data_index % 50==0:
        optimizer.step()
        rnn.zero_grad()
    

    学习积分的新结果:pic .

相关问题