python - 使用 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 上找到任何文档,但似乎没有使用它编码网络的示例。
似乎问题可能出在线性层上,尽管我不知道为什么。
所以,我希望任何人都可以解释错误在哪里。非常感谢任何可能的建议。
解决方案
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))]))
推荐阅读
- ruby - 重复字符串
- c++ - 模板参数推导失败和函数参数/参数不匹配
- python - 如何从 .csv 文件中提取值并将它们放入数组中?
- udp - UDP 数据报发送的正确 AT 命令序列
- opencv - OpenCV 在 minAreaRect 中使用什么算法来寻找边界框?
- amazon-web-services - 为什么 Tomcat8 的 webapps 包中的示例失败并出现“未找到”和“NullPointerException”错误?
- c# - 类为 Arg 的 Razor 页面处理程序
- java - Q : 租车计算器 | 使用哨兵值循环
- python - 使用 OPENCV 识别产品
- android - 数据绑定和 MVVM。通过单击按钮显示 DatePickerDIalog