Ошибка Input_size в LSTM PyTorch: RuntimeError: shape '[10, 30, 1]' недопустим для ввода размера 150 - PullRequest
0 голосов
/ 10 марта 2019

каждый, я использую LSTM для прогнозирования фондового индекса когда-нибудь, используя данные за 30 дней до него в качестве входных данных.Я думаю, что в этом примере размер ввода LSTM должен быть [10,30,1], поэтому я использую t_x=x.view(10,30,1) для изменения формы ввода.Но когда я запускаю приведенный ниже код, возникает RuntimeError (shape '[10, 30, 1]' is invalid for input of size 150). Не могли бы вы помочь мне найти проблему?Спасибо:)

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import Dataset, DataLoader
from torch.utils.data import TensorDataset


dataread_df=pd.read_csv('D:/Desktop/399300.csv')
dataread_series=pd.Series(dataread_df['value'].values)
plt.plot(dataread_series)
plt.show()


def generate_data_df(series, n):
    if len(series) <= n:
        raise Exception("The Length of series is %d, while affect by (n=%d)." % (len(series), n))
    df = pd.DataFrame()
    for i in range(n):
        df['x%d' % i] = series.tolist()[i:-(n - i)]
    df['y'] = series.tolist()[n:]
    return df
data_df = generate_data_df(dataread_series, 30)

data_numpy=np.array(data_df)
mean=np.mean(data_numpy)
std=np.std(data_numpy)
data_numpy = (data_numpy-mean)/std
train_size=int(len(data_numpy)*0.7)
test_size=len(data_numpy)-train_size
trainset_np=data_numpy[:train_size]
testset_np=data_numpy[train_size:]
train_x_np=trainset_np[:,:30]
train_y_np=trainset_np[:,30:]
test_x_np=testset_np[:,:30]
test_y_np=testset_np[:,30:]

train_x=torch.Tensor(train_x_np)
train_y=torch.Tensor(train_y_np)
test_x=torch.Tensor(test_x_np)
test_y=torch.Tensor(test_y_np)
trainset=TensorDataset(train_x,train_y)
testset=TensorDataset(test_x,test_y)
trainloader = DataLoader(trainset, batch_size=10, shuffle=True)
testloader=DataLoader(testset,batch_size=10,shuffle=True)

class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.rnn=nn.LSTM(input_size=1,hidden_size=64,num_layers=1,batch_first=True)
        self.out=nn.Sequential(nn.Linear(64,1))
    def forward(self,x):
        r_out,(h_n,h_c)=self.rnn(x,None)
        out=self.out(r_out[:,-1,:])
        return out
rnn = Net()
print(rnn)

optimizer = torch.optim.Adam(rnn.parameters(), lr=0.0001)  
criterion = nn.MSELoss()
train_correct=0
test_correct=0
train_total=0
test_total=0
prediction_list=[]

for epoch in range(10):
    running_loss_train=0
    running_loss_test=0
    for i,(x1,y1) in enumerate(trainloader):
        t_x1=x1.view(10,30,1)
        output=rnn(t_x1)
        loss_train=criterion(output,y1)
        optimizer.zero_grad() 
        loss_train.backward() 
        optimizer.step()
        running_loss_train+=loss_train.item()
    for i,(x2,y2) in enumerate(testloader):
        t_x2=x2.view(10,30,1)
        prediction=rnn(t_x2)
        loss_test=criterion(prediction,y2)
        running_loss_test+=loss_test.item()
        prediction_list.append(prediction)
    print('Epoch {} Train Loss:{}, Test Loss:{}'.format(epoch+1,running_loss_train,running_loss_test))
    prediction_list_plot=np.array(prediction_list)
    plt.plot(test_y_np.flatten(),'r-',linewidth=0.1,label='real data')
    plt.plot(prediction_list_plot.flatten(),'b-',linewidth=0.1,label='predicted data')
    plt.show()
print('Finish training')

RuntimeError:

RuntimeError                              Traceback (most recent call last)
<ipython-input-3-fb8cb4c93775> in <module>
     71     running_loss_test=0
     72     for i,(x1,y1) in enumerate(trainloader):
---> 73         t_x1=x1.view(10,30,1)
     74         output=rnn(t_x1)
     75         loss_train=criterion(output,y1)

RuntimeError: shape '[10, 30, 1]' is invalid for input of size 150

Ответы [ 3 ]

0 голосов
/ 11 марта 2019

Из документации метода view (), 'Возвращенный тензор разделяет те же данные, и должен иметь одинаковое количество элементов , но может иметь другой размер.'

x1 = torch.randn((150,))
t_x1 = x1.view(10,30,1)

RuntimeError: форма '[10, 30, 1]' недопустима для ввода размером 150

Это потому, что 150! = 10 * 30. Если вы хотите использовать 30 временных шагов, тогда ваш размер выборки должен быть 150/30 = 5. Итак, правильный путь -

t_x1 = x1.view(5,30,1)
0 голосов
/ 12 марта 2019

Учитывая, что вы используете batch_first=True и предполагаете, что размер пакета равен 10, (10, 30, 1) в качестве правильной формы ввода, поскольку оно (batch_size, seq_len, input_size).

Вопрос в том, откуда взялся 150.Какова форма x1, прежде чем пытаться применить .view(...)?Можете ли вы проверить следующее:

for i,(x1,y1) in enumerate(trainloader):
    print(x1.shape)
    ...

Интуитивно, это должно быть что-то вроде (10, ???), так как вы установили 10 в качестве размера партии.Прямо сейчас я предполагаю, что что-то с вами, данные тренировок и тестов отключены.

0 голосов
/ 10 марта 2019

Изменить это

t_x1=x1.view(10,30,1)

в

t_x1=x1.view(150,150,1)

и попробуйте

...