【问题标题】:Model weights are not being updatesd, but loss is decreasing模型权重没有更新,但损失正在减少
【发布时间】:2020-01-20 13:23:43
【问题描述】:

以下代码是用大小为 64*64 的图像训练 MLP,同时使用损失 ||output - input||^2。

由于某种原因,我每个时期的权重没有更新,如最后所示。

class MLP(nn.Module):
    def __init__(self, size_list):
        super(MLP, self).__init__()
        layers = []
        self.size_list = size_list
        for i in range(len(size_list) - 2):
            layers.append(nn.Linear(size_list[i],size_list[i+1]))
            layers.append(nn.ReLU())
        layers.append(nn.Linear(size_list[-2], size_list[-1]))
        self.net = nn.Sequential(*layers)

    def forward(self, x):
        return self.net(x)

model_1 = MLP([4096, 64, 4096])

对于每个 epoch 的训练:

def train_epoch(model, train_loader, criterion, optimizer):
    model.train()
    model.to(device)

running_loss = 0.0

    start_time = time.time()
    # train batch
    for batch_idx, (data) in enumerate(train_loader):   
        optimizer.zero_grad() 

        data = data.to(device)

        outputs = model(data)
        loss = criterion(outputs, data)
        running_loss += loss.item()

        loss.backward()
        optimizer.step()

    end_time = time.time()

    weight_ll = model.net[0].weight
    running_loss /= len(train_loader)

    print('Training Loss: ', running_loss, 'Time: ',end_time - start_time, 's')
    return running_loss, outputs, weight_ll

用于训练数据:

n_epochs = 20
Train_loss = []
weights=[]

criterion = nn.MSELoss()

optimizer = optim.SGD(model_1.parameters(), lr = 0.1)


for i in range(n_epochs):
    train_loss, output, weights_ll = train_epoch(model_1, trainloader, criterion, optimizer)
    Train_loss.append(train_loss)
    weights.append(weights_ll)
    print('='*20)

现在,当我打印每个 epoch 的第一个全连接层的权重时,它们并没有被更新。

print(weights[0][0])
print(weights[19][0])

上面的输出是(显示 epoch 0 和 epoch 19 的权重):

tensor([ 0.0086,  0.0069, -0.0048,  ..., -0.0082, -0.0115, -0.0133],
       grad_fn=<SelectBackward>)
tensor([ 0.0086,  0.0069, -0.0048,  ..., -0.0082, -0.0115, -0.0133],
       grad_fn=<SelectBackward>)

可能出了什么问题?看看我的损失,它以稳定的速度减少,但权重没有变化。

【问题讨论】:

  • loss.backword() 之后,您是否检查了网络的计算梯度?
  • @zihaozhihao 在每个epoch打印出 grad = model.net[0].weight.grad 之后,好像连他们都没有更新!
  • 您正在更新权重。但是你打印权重的方式是不正确的。请检查我的答案。

标签: python machine-learning neural-network pytorch


【解决方案1】:

尝试在您的train_epoch() 函数中更改它weight_ll = model.net[0].weight.clone().detach() 或只是weight_ll = model.net[0].weight.clone()。你会看到权重不同。

解释:weights_ll 如果你不克隆它,它总是最后的 epoch 值。它将被视为图中相同的张量。这就是为什么你的weights[0][0] 等于weights[19][0],它们实际上是同一个张量。

【讨论】:

  • 我尝试了您的建议,但没有任何好处。然后我尝试使用复制模块中的 deepcopy,我看到这里和那里的权重有 0.001 的差异,但没有别的。
  • 这很奇怪。因为我可以重现结果。
  • @dankpenny 我发现有人和你有同样的问题。请检查这个问题stackoverflow.com/questions/51717874/…
猜你喜欢
  • 2021-07-25
  • 1970-01-01
  • 1970-01-01
  • 2019-09-18
  • 2018-02-09
  • 2019-08-18
  • 2018-01-31
  • 2023-03-13
  • 2018-09-17
相关资源
最近更新 更多