首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Pytorch中的LSTM :如何添加/更改序列长度维度?

Pytorch中的LSTM :如何添加/更改序列长度维度?
EN

Stack Overflow用户
提问于 2019-12-18 04:33:29
回答 2查看 3K关注 0票数 4

我在pytorch中运行LSTM,但据我所知,它只接受序列长度= 1。当我将序列长度重塑为4或其他数字时,我在输入和目标中得到一个长度不匹配的错误。如果我同时重塑输入和目标,那么模型会抱怨它不接受多目标标签。

我的训练数据集有66512行和16839列,目标中有3个类别/类。我想使用批大小为200,序列长度为4,即在一个序列中使用4行数据。

请建议如何调整我的模型和/或数据,以便能够运行各种序列长度的模型(例如,4)。

代码语言:javascript
复制
batch_size=200
import torch  
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader
train_target = torch.tensor(train_data[['Label1','Label2','Label3']].values.astype(np.float32))
train_target = np.argmax(train_target, axis=1)
train = torch.tensor(train_data.drop(['Label1','Label2','Label3'], axis = 1).values.astype(np.float32)) 
train_tensor = TensorDataset(train.unsqueeze(1), train_target) 
train_loader = DataLoader(dataset = train_tensor, batch_size = batch_size, shuffle = True)

print(train.shape)
print(train_target.shape)

torch.Size([66512, 16839])
torch.Size([66512])


import torch.nn as nn

class LSTMModel(nn.Module):
    def __init__(self, input_dim, hidden_dim, layer_dim, output_dim):
        super(LSTMModel, self).__init__()
        # Hidden dimensions
        self.hidden_dim = hidden_dim

        # Number of hidden layers
        self.layer_dim = layer_dim

        # Building LSTM
        self.lstm = nn.LSTM(input_dim, hidden_dim, layer_dim, batch_first=True)

        # Readout layer
        self.fc = nn.Linear(hidden_dim, output_dim)

    def forward(self, x):

        # Initialize hidden state with zeros
        h0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_().to(device)

        # Initialize cell state
        c0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_().to(device)

        out, (hn, cn) = self.lstm(x, (h0,c0))

        # Index hidden state of last time step
        out = self.fc(out[:, -1, :]) 

        return out        


input_dim = 16839
hidden_dim = 100
output_dim = 3
layer_dim = 1

batch_size = batch_size
num_epochs = 1

model = LSTMModel(input_dim, hidden_dim, layer_dim, output_dim)

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)

criterion = nn.CrossEntropyLoss()
learning_rate = 0.1

optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)        

print(len(list(model.parameters())))
for i in range(len(list(model.parameters()))):
    print(list(model.parameters())[i].size())

6
torch.Size([400, 16839])
torch.Size([400, 100])
torch.Size([400])
torch.Size([400])
torch.Size([3, 100])
torch.Size([3])


for epoch in range(num_epochs):
    for i, (train, train_target) in enumerate(train_loader):
        # Load data as a torch tensor with gradient accumulation abilities
        train = train.requires_grad_().to(device)
        train_target = train_target.to(device)

        # Clear gradients w.r.t. parameters
        optimizer.zero_grad()

        # Forward pass to get output/logits
        outputs = model(train)

        # Calculate Loss: softmax --> cross entropy loss
        loss = criterion(outputs, train_target)

        # Getting gradients w.r.t. parameters
        loss.backward()

        # Updating parameters
        optimizer.step()
print('Epoch: {}. Loss: {}. Accuracy: {}'.format(epoch, np.around(loss.item(), 4), np.around(accuracy,4)))
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-01-16 08:27:30

这就是最终有效的方法-将输入数据重塑为4的序列,每个序列有一个目标值,为此,我根据我的问题逻辑选择了目标序列中的最后一个值。现在看起来很容易,但那时候却很棘手。发布代码的其余部分是相同的。

代码语言:javascript
复制
train_target = torch.tensor(train_data[['Label1','Label2','Label3']].iloc[3::4].values.astype(np.float32))
train_target = np.argmax(train_target, axis=1)
train = torch.tensor(train_data.drop(['Label1','Label2','Label3'], axis = 1).values.reshape(-1, 4, 16839).astype(np.float32)) 
train_tensor = TensorDataset(train, train_target) 
train_loader = DataLoader(dataset = train_tensor, batch_size = batch_size, shuffle = True)

print(train.shape)
print(train_target.shape)

torch.Size([16628, 4, 16839])
torch.Size([16628])
票数 2
EN

Stack Overflow用户

发布于 2020-01-08 22:56:25

您已经设置了input_dim = 16839,所以您的模型需要shape (batch_size, seq_len, 16839)的输入。

您要从中绘制批次的train_tensor的形状为(66512, 1, 16839)。所以你的批次是(batch_size, 1, 16839)形状的。这是可行的,因为它满足了上述要求。

但是,如果您尝试重塑相同的训练张量,使seq_len = 4,您的input_dim维度将不再是16839,因此将不会与模型预期的维度匹配,这就是为什么会出现维度不匹配错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59381695

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档