【深度学习】再次学习lstm,能够跑通的回归任务【history 5 future 1】many-to-one

发布于:2024-07-20 ⋅ 阅读:(153) ⋅ 点赞:(0)
from torch.utils.data import DataLoader,Dataset
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from tqdm import tqdm
device = "cuda" if torch.cuda.is_available() else "cpu"
class CustomDataset(Dataset):
    def __init__(self, seq_len = 5, max_len = 1000) -> None:
        super().__init__()
        self.datalist = np.arange(0,max_len)
        self.data,self.targets = self.timeseries(self.datalist, seq_len)
    def __len__(self):
        return len(self.data)
    
    def timeseries(self, data, window):
        temp = []
        targ = data[window:]
        for i in range(len(data) - window):
            temp.append(data[i:i+window])
        return temp, targ
    
    def __getitem__(self,index):
        x = torch.tensor(self.data[index]).type(torch.Tensor)
        y = torch.tensor(self.targets[index]).type(torch.Tensor)
        return x,y
    
class RNN(nn.Module):
    def __init__(self,input_size, hidden_size, nums_layer) -> None:
        super().__init__()
        self.lstm = nn.LSTM(input_size,hidden_size,nums_layer,batch_first=True)
        self.linear = nn.Linear(hidden_size, 1)
    
    def forward(self,x):
        out,(hn,cn) = self.lstm(x)
        out = out[:,-1,:]
        return self.linear(out)
model = RNN(1,8,2).to(device=device)
loss_function = nn.MSELoss()
learning_rate = 1e-3
optimizer = optim.Adam(model.parameters(),lr=learning_rate)

if __name__ == "__main__":
    dataset = CustomDataset(seq_len=5,max_len=1000)
    dataloader = DataLoader(dataset=dataset,batch_size=4,shuffle=True)
    for e in tqdm(range(50)):
        e_loss = 0.0
        for x,y in dataloader:
            optimizer.zero_grad()
            x = x.unsqueeze(0).permute(1,2,0).type(torch.Tensor).to(device)
            predictions = model(x)
            predictions = predictions.view(-1)
            y = y.type(torch.Tensor).to(device)
            loss = loss_function(predictions, y)
            e_loss += loss.cpu().detach().numpy()
            loss.backward()
            optimizer.step()
        if e%5==0:
            print(e_loss)
    res = model(torch.Tensor([1,2,3,4,5]).view(1,-1,1).to(device))
    print(res)
    inputs = torch.Tensor([[6,7,8,9,10],[7,8,9,10,11]]).view(2,-1,1).to(device)
    print(inputs.shape)
    res = model(inputs)
    print(res)

是不是的要回来看看是怎么回事。

几个关键点:
相当于是拿过去5天的数据预测第6天的数据,每天一个元素。
torch.Size([1, 5, 1])
输入:

 [
 	[[1.], [2.],[3.],[4.],[5.] ]
 ]

输出:

tensor([[-0.2429]], grad_fn=<AddmmBackward0>)

然后将按照这个输入和输入进行整改,train过程中计算loss损失的是这样的。
这是回归模型。
再看一下type的使用,torch.Tensor,是把他转成了float32.

x = torch.tensor(self.data[index]).type(torch.Tensor)

另外,predictions的输出是个二维的数据,另外需要

predictions = predictions.view(-1)
y = y.type(torch.Tensor).to(device)
e_loss += loss.cpu().detach().numpy()

这个detach,是只计算数值不要梯度。
这两个本质是一个东西,会返回True

aa = torch.tensor(1.0,requires_grad=True)
print(aa.detach().data.item() == aa.detach().numpy())
print(aa.detach().data.item()print(aa.detach().numpy())

1, True

aa = torch.tensor(1.0,requires_grad=True)
print(aa.detach().data.item() == aa.detach().numpy())
print(aa.detach().data.item()print(aa.detach().numpy())

[1], True