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