我试图在Pytorch中定义一个多任务模型,在该模型中我需要一组不同的层来完成不同的任务。我在定义图层时遇到问题,尤其是如果我使用for循环将不同图层存储在列表中时,我会从优化器收到错误消息,指出model.parameters()是一个空列表,实际上是一个空列表。
以下是代码:
x_trains=[]
y_trains=[]
num_tasks=2
for i in range(num_tasks):
x_trains.append(torch.from_numpy(np.random.rand(100,1,50)).float())
y_trains.append(torch.from_numpy(np.array([np.random.randint(10) for i in range(100)])).long())
nb_classes=10
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.all_task_layers=[]
for i in range(num_tasks):
self.all_task_layers.append(nn.Conv1d(1, 128, 8))
self.all_task_layers.append(nn.BatchNorm1d(128))
self.all_task_layers.append(nn.Conv1d(128, 256, 5))
self.all_task_layers.append(nn.BatchNorm1d(256))
self.all_task_layers.append(nn.Conv1d(256, 128, 3))
self.all_task_layers.append(nn.BatchNorm1d(128))
self.all_task_layers.append(nn.Linear(128, nb_classes))
#self.dict_layers_for_tasks[i][1]
self.all_b1s=[]
self.all_b2s=[]
self.all_b3s=[]
self.all_dense1s=[]
def forward(self, x_num_tasks):
for i in range(0,len(self.all_task_layers),num_tasks):
self.all_b1s.append(F.relu(self.all_task_layers[i+1](self.all_task_layers[i+0](x_num_tasks[i]))))
for i in range(0,len(self.all_task_layers),num_tasks):
self.all_b2s.append(F.relu(self.all_task_layers[i+3](self.all_task_layers[i+2](self.all_b1s[i]))))
for i in range(0,len(self.all_task_layers),num_tasks):
self.all_b3s.append(F.relu(self.all_task_layers[i+5](self.all_task_layers[i+4](self.all_b2s[i]))))
for i in range(0,len(self.all_task_layers),num_tasks):
self.all_dense1s.append(self.all_task_layers[i+6](self.all_b3s[i]))
return self.all_dense1s
model = Net()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
losses=[]
for t in range(50):
y_preds= model(x_trains)
optimizer.zero_grad()
for i in range(num_tasks):
loss=criterion(y_preds[i], y_trains[i])
losses.append(loss)
print(t,i,loss.item())
loss.backward(retain_graph=True)
optimizer.step()
如果我尝试使用两组Conv-> BatchNorm-> Conv-> BatchNorm-> Conv-> BatchNorm-> GlobalAveragePooling-> Linear来初始化两个任务的层,则使用相同的模型。但是,如果我说5个任务,那么它可能会变得很混乱,这就是为什么我创建了一个图层列表并为其编制索引的原因。例如,前7层用于任务1,然后最后7层用于任务2。但是,然后model.parameters()给了我一个空列表。我还能怎么做?还是有一个简单的解决方法,我正在忽略?
答案 0 :(得分:2)
您应该使用nn.ModuleList()
包装列表。例如
x_trains = nn.ModuleList(x_trains)