### 使用PyTorch进行训练数据的分离

我有一段代码,我希望用它来训练一个神经网络,并将完成的模型保存为文件。但由于训练数据和验证数据的分配不正确,我遇到了错误。我不明白为什么会这样:`import torch

import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F

class ChatBot(nn.Module):
    def __init__(self, input_size, hidden_size, num_layers, output_size):
        super().__init__()
        self.hidden_size = hidden_size
        self.num_layers = num_layers
        self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
        self.fc = nn.Linear(hidden_size, output_size)

    def forward(self, x, hidden):
        out, hidden = self.lstm(x, hidden)
        out = self.fc(out[:, -1, :])
        return out, hidden

    def init_hidden(self, batch_size):
        weight = next(self.parameters()).data
        hidden = (weight.new(self.num_layers, batch_size, self.hidden_size).zero_(),
                  weight.new(self.num_layers, batch_size, self.hidden_size).zero_())
        return hidden

class ChatDataset(torch.utils.data.Dataset):
    def __init__(self, data):
        self.data = data

    def __len__(self):
        return len(self.data)

    def __getitem__(self, index):
        return self.data[index]

def train(model, train_loader, loss_fn, optimizer, device):
    model.train()
    for inputs, targets in train_loader:
        inputs = inputs.to(device)
        targets = targets.to(device)

        hidden = model.init_hidden(inputs.size(0))
        hidden = tuple([each.data for each in hidden])

        optimizer.zero_grad()
        outputs, _ = model(inputs, hidden)
        loss = loss_fn(outputs.view(-1), targets.view(-1))
        loss.backward()
        optimizer.step()

def evaluate(model, val_loader, loss_fn, device):
    model.eval()
    total_loss = 0
    with torch.no_grad():
        for inputs, targets in val_loader:
            inputs = inputs.to(device)
            targets = targets.to(device)

            hidden = model.init_hidden(inputs.size(0))
            hidden = tuple([each.data for each in hidden])

            outputs, _ = model(inputs, hidden)
            total_loss += loss_fn(outputs, targets).item()
    return total_loss / len(val_loader)

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
input_size = 500
hidden_size = 128
num_layers = 2
output_size = 500

model = ChatBot(input_size, hidden_size, num_layers, output_size)
model = model.to(device)

data = [("Hi, how are you?", "I'm doing well, thank you for asking."),
        ("What's your name?", "I'm a chatbot, I don't have a name."),
        ("What's the weather like?", "I'm not sure, I don't have access to current weather information."),
        ("What's the time?", "I'm not sure, I don't have access to the current time.")]

dataset = ChatDataset(data)
train_dataset, val_dataset = torch.utils.data.random_split(dataset, [int(0.8 * len(dataset)), int(0.2 * len(dataset))])
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=32, shuffle=True)
val_loader = torch.utils.data.DataLoader(val_dataset, batch_size=32, shuffle=False)

loss_fn = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
num_epochs = 100

for epoch in range(num_epochs):
    train(model, train_loader, loss_fn, optimizer, device)
    val_loss = evaluate(model, val_loader, loss_fn, device)
    print("Epoch [{}/{}], Validation Loss: {:.4f}".format(epoch+1, num_epochs, val_loss))

torch.save(model.state_dict(), 'chatbot_model.pt')

但是,当我运行这段代码时,我遇到了错误:` ValueError
Traceback (most recent call last)

<ipython-input-8-ae2a6dd1bc7c> in <module>
 78 dataset = ChatDataset(data)
 79 ---> 80 train_dataset, val_dataset = torch.utils.data.random_split(dataset, [int(0.8 * len(dataset)), int(0.2 * len(dataset))])
 81
 82 train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=32, shuffle=True)
/usr/local/lib/python3.8/dist-packages/torch/utils/data/dataset.py in random_split(dataset, lengths, generator)
345     # Cannot verify that dataset is Sized
346     if sum(lengths) != len(dataset):    # type: ignore[arg-type]
--> 347         raise ValueError("Sum of input lengths does not equal the length of the input dataset!")
348
349     indices = randperm(sum(lengths), generator=generator).tolist()  # type: ignore[call-overload]
ValueError: Sum of input lengths does not equal the length of the input dataset!`

我不知道为什么会出现这个错误。一切看起来都是正确的。


回答:

将值转换为整数导致数据集中图像总数与训练和测试图像数量的分配之间存在差异。

虽然不是最理想的代码,但用以下代码替换可以解决问题:

num_train_images = int(0.8 * len(dataset))
train_dataset, val_dataset = torch.utils.data.random_split(dataset, [num_train_images, len(dataset) - num_train_images])

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注