如何通过 Pytorch __init__ 中的循环定义多个层?

vam*_*tap 6 python pytorch

我正在尝试在 Pytorch 中定义一个多任务模型,其中我需要一组不同的层来执行不同的任务。我在定义层时遇到问题,特别是如果我使用 for 循环在列表中存储不同的层,那么我会从优化器中收到一个错误,指出 model.parameters() 是一个空列表,事实上它是空列表。

\n\n

以下是代码:

\n\n
x_trains=[]\ny_trains=[]\n\nnum_tasks=2\nfor i in range(num_tasks):\n    x_trains.append(torch.from_numpy(np.random.rand(100,1,50)).float())\n    y_trains.append(torch.from_numpy(np.array([np.random.randint(10) for i in range(100)])).long())\nnb_classes=10\n\nclass Net(torch.nn.Module):\ndef __init__(self):\n    super(Net, self).__init__()\n\n    self.all_task_layers=[]\n    for i in range(num_tasks):\n        self.all_task_layers.append(nn.Conv1d(1, 128, 8))\n        self.all_task_layers.append(nn.BatchNorm1d(128))\n        self.all_task_layers.append(nn.Conv1d(128, 256, 5))\n        self.all_task_layers.append(nn.BatchNorm1d(256))\n        self.all_task_layers.append(nn.Conv1d(256, 128, 3))\n        self.all_task_layers.append(nn.BatchNorm1d(128))\n        self.all_task_layers.append(nn.Linear(128, nb_classes))\n    #self.dict_layers_for_tasks[i][1]        \n    self.all_b1s=[]\n    self.all_b2s=[]\n    self.all_b3s=[]\n    self.all_dense1s=[]\n\ndef forward(self, x_num_tasks): \n    for i in range(0,len(self.all_task_layers),num_tasks):\n        self.all_b1s.append(F.relu(self.all_task_layers[i+1](self.all_task_layers[i+0](x_num_tasks[i]))))\n\n    for i in range(0,len(self.all_task_layers),num_tasks):\n        self.all_b2s.append(F.relu(self.all_task_layers[i+3](self.all_task_layers[i+2](self.all_b1s[i]))))\n\n    for i in range(0,len(self.all_task_layers),num_tasks):\n        self.all_b3s.append(F.relu(self.all_task_layers[i+5](self.all_task_layers[i+4](self.all_b2s[i]))))\n\n    for i in range(0,len(self.all_task_layers),num_tasks):\n        self.all_dense1s.append(self.all_task_layers[i+6](self.all_b3s[i]))\n\n    return self.all_dense1s       \n\nmodel = Net()\ncriterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n\nlosses=[]\nfor t in range(50):\n    y_preds= model(x_trains)\n    optimizer.zero_grad()\n    for i in range(num_tasks):\n        loss=criterion(y_preds[i], y_trains[i])\n        losses.append(loss)\n        print(t,i,loss.item())\n        loss.backward(retain_graph=True)\n        optimizer.step()\n
Run Code Online (Sandbox Code Playgroud)\n\n

相同的模型,如果我尝试使用两组 Conv->BatchNorm->Conv->BatchNorm->Conv->BatchNorm->GlobalAveragePooling->Linear 初始化两个任务的层,那么它将起作用。但如果我让\xe2\x80\x99s 说 5 个任务,那么它会变得非常混乱,这就是为什么我创建了一个图层列表,并对它们建立了索引。例如,前 7 层用于任务 1,最后 7 层用于任务 2。但是 model.parameters() 给了我一个空列表。我还能怎样做呢?或者有一个简单的修复方法,我忽略了?

\n

coo*_*ter 8

你应该用它nn.ModuleList()来包装列表。例如
x_trains = nn.ModuleList(x_trains)

请参阅PyTorch:如何正确创建 nn.Linear() 列表