首页 > 解决方案 > 使用 nn.ModuleDict 编码的训练网络

问题描述

我被分配用 nn.ModuleDict 编写一个简单的网络。所以,这里是:

third_model = torch.nn.ModuleDict({
'flatten': torch.nn.Flatten(),

'fc1': torch.nn.Linear(32 * 32 * 3, 1024),
'relu': torch.nn.ReLU(),

'fc2': torch.nn.Linear(1024, 240),
'relu': torch.nn.ReLU(),

'fc3': torch.nn.Linear(240, 10)})

然后我尝试训练它(使用 cuda):

third_model.to(device)

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(third_model.parameters(), lr=0.001, momentum=0.9)

train(third_model, criterion, optimizer, train_dataloader, test_dataloader)

函数“train(model,criteria,optimizer,train_dataloader,test_dataloader)”训练模型并可视化模型的损失和准确性。它工作正常。

火车:

def train(model, criterion, optimizer, train_dataloader, test_dataloader):
    train_loss_log = []
    train_acc_log = []
    val_loss_log = []
    val_acc_log = []
    
    for epoch in range(NUM_EPOCH):
        model.train()
        train_loss = 0.
        train_size = 0
        train_acc = 0.
        for imgs, labels in train_dataloader:
            imgs, labels = imgs.to(device), labels.to(device)
            
            optimizer.zero_grad()
            y_pred = model(imgs)
            loss = criterion(y_pred, labels)
            loss.backward()
            optimizer.step()
            
            train_loss += loss.item()
            train_size += y_pred.size(0)
            train_loss_log.append(loss.data / y_pred.size(0))

            _, pred_classes = torch.max(y_pred, 1)
            train_acc += (pred_classes == labels).sum().item()
            train_acc_log.append(np.mean((pred_classes == labels).cpu().numpy()))


        val_loss = 0.
        val_size = 0
        val_acc = 0.
        model.eval()
        with torch.no_grad():
            for imgs, labels in test_dataloader:
                imgs, labels = imgs.to(device), labels.to(device)
                pred = model(imgs)
                loss = criterion(pred, labels)
                val_loss += loss.item()
                val_size += pred.size(0)

                _, pred_classes = torch.max(pred, 1)
                val_acc += (pred_classes == labels).sum().item()
        val_loss_log.append(val_loss / val_size)
        val_acc_log.append(val_acc / val_size)

        clear_output()
        plot_history(train_loss_log, val_loss_log, 'loss')
        plot_history(train_acc_log, val_acc_log, 'accuracy')

        print('Train loss:', train_loss / train_size)
        print('Train acc:', train_acc / train_size)
        print('Val loss:', val_loss / val_size)
        print('Val acc:', val_acc / val_size)

我已经训练了用 nn.Sequential 编码的模型,一切都很好。但是,使用 nn.ModuleDict 我得到一个错误:

TypeError                                 Traceback (most recent call last)
<ipython-input-144-8b33ad3aad2c> in <module>()
      2 optimizer = optim.SGD(third_model.parameters(), lr=0.001, momentum=0.9)
      3 
----> 4 train(third_model, criterion, optimizer, train_dataloader, test_dataloader)

1 frames
/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
    720             result = self._slow_forward(*input, **kwargs)
    721         else:
--> 722             result = self.forward(*input, **kwargs)
    723         for hook in itertools.chain(
    724                 _global_forward_hooks.values(),

TypeError: forward() takes 1 positional argument but 2 were given

试图在 nn.ModuleDict 上找到任何文档,但似乎没有使用它编码网络的示例。

似乎问题可能出在线性层上,尽管我不知道为什么。

所以,我希望任何人都可以解释错误在哪里。非常感谢任何可能的建议。

标签: pythonmachine-learningneural-networkpytorch

解决方案


Ann.moduleDict是一个容器,它的forward功能没有定义。它应该用于存储子模块/网络。

您应该使用按顺序字典nn.Sequential初始化, :OrderedDict

third_model = torch.nn.Sequential(
    OrderedDict([
       ('flatten', torch.nn.Flatten()),
       ('fc1', torch.nn.Linear(32 * 32 * 3, 1024)),
       ('relu', torch.nn.ReLU()),
       ('fc2', torch.nn.Linear(1024, 240)),
       ('relu', torch.nn.ReLU()),
       ('fc3', torch.nn.Linear(240, 10))]))

推荐阅读