PyTorch在训练期间将两组梯度标准化

PyTorch在训练期间将两组梯度标准化,pytorch,normalization,Pytorch,Normalization,在这种情况下,如果向下滚动到训练循环,可以看到它们组合了渐变 像这样。其中errD\u real=criteria(output,label)和errD\u fake=criteria(output,label)和criteria=nn.BCELoss()。我想做同样的事情,但在做一个反向传递之前,我想将两个梯度标准化为两个梯度中较低的欧几里德范数。我该怎么做 我知道我可以通过打印出netD.weight.grad,在netD上单独访问每个权重的梯度,但是有什么方法可以将它们批量标准化为两个中较

在这种情况下,如果向下滚动到训练循环,可以看到它们组合了渐变 像这样。其中
errD\u real=criteria(output,label)
errD\u fake=criteria(output,label)
criteria=nn.BCELoss()
。我想做同样的事情,但在做一个反向传递之前,我想将两个梯度标准化为两个梯度中较低的欧几里德范数。我该怎么做

我知道我可以通过打印出
netD.weight.grad
,在netD上单独访问每个权重的梯度,但是有什么方法可以将它们批量标准化为两个中较低的欧几里德标准吗

以下是我所说的训练循环的一部分:

for epoch in range(num_epochs):
    # For each batch in the dataloader
    for i, data in enumerate(dataloader, 0):

        ############################
        # (1) Update D network: maximize log(D(x)) + log(1 - D(G(z)))
        ###########################
        ## Train with all-real batch
        netD.zero_grad()
        # Format batch
        real_cpu = data[0].to(device)
        b_size = real_cpu.size(0)
        label = torch.full((b_size,), real_label, device=device)
        # Forward pass real batch through D
        output = netD(real_cpu).view(-1)
        # Calculate loss on all-real batch
        errD_real = criterion(output, label)
        # Calculate gradients for D in backward pass
        errD_real.backward()
        D_x = output.mean().item()

        ## Train with all-fake batch
        # Generate batch of latent vectors
        noise = torch.randn(b_size, nz, 1, 1, device=device)
        # Generate fake image batch with G
        fake = netG(noise)
        label.fill_(fake_label)
        # Classify all fake batch with D
        output = netD(fake.detach()).view(-1)
        # Calculate D's loss on the all-fake batch
        errD_fake = criterion(output, label)
        # Calculate the gradients for this batch
        errD_fake.backward()
        D_G_z1 = output.mean().item()
        # Add the gradients from the all-real and all-fake batches
        errD = errD_real + errD_fake
        # Update D
        optimizerD.step()
        ...

你提到了两件不正确的事情

  • errD=errD_real+errD_fake基本上结合了两个目标函数,而不是梯度
  • 您需要在向后传递之后而不是之前更改渐变。使用向后传递,将计算梯度,然后您可以在调用更新模型参数的
    optimizer.step()
    之前修改梯度
  • 回答你的问题:


    我相信PyTorch没有直接的API支持来实现您的目标。但是,在向后传递后,您可以自己轻松修改渐变。要计算欧几里德范数,可以使用该函数。然后你可以简单地将梯度(就地)调整。

    你提到的两件事是不正确的

  • errD=errD_real+errD_fake基本上结合了两个目标函数,而不是梯度
  • 您需要在向后传递之后而不是之前更改渐变。使用向后传递,将计算梯度,然后您可以在调用更新模型参数的
    optimizer.step()
    之前修改梯度
  • 回答你的问题:


    我相信PyTorch没有直接的API支持来实现您的目标。但是,在向后传递后,您可以自己轻松修改渐变。要计算欧几里德范数,可以使用该函数。然后,您可以简单地将渐变(就地)保存。

    您最好保持渐变不变,并制作您的优化器,以便它计算您需要的效果

    在大多数情况下,渐变将在新的前进之前被删除

    一些较新的算法,如按您的计划执行参数(分层)梯度归一化(本例中为MSE)


    此外,检查论文,以及他们为什么使用
    nn.utils.spectral\u norm
    ,因为你使用了GANs。

    你最好保持梯度不变,并制作你的优化器,以便计算你需要的效果

    在大多数情况下,渐变将在新的前进之前被删除

    一些较新的算法,如按您的计划执行参数(分层)梯度归一化(本例中为MSE)


    另外,检查论文,以及为什么他们使用了
    nn.utils.spectral\u norm
    ,因为您使用了GANs。

    好的,我是否只需要循环所有梯度来进行就地计算?是的,您需要循环模型的所有参数。使用
    model.named_parameters()
    函数。好的,我是否只需循环所有渐变以进行就地计算?是的,您需要循环模型的所有参数。使用
    model.named_parameters()
    函数。谢谢,这很有用,但是,在我的情况下,我更担心的是,我同时有两个丢失更新,一个基本上压倒了另一个。我认为你在这里发布的案例更多的是关于培训优化的,是吗?我只是想确保这两个梯度更新对我的优化步骤有同等的影响是的,想想梯度,比如已经准备好的食物,这样你就不需要再准备了,而优化程序就是你用它做的,或者说你的内脏。谢谢,这很有用,在我的情况下,我更担心的情况是,我同时有两个丢失更新,一个基本上压倒了另一个。我认为你在这里所发的案例更多的是关于培训优化的是吗?我只是想确保这两个梯度更新对我的优化步骤有同等的影响是的,想想梯度,就像已经准备好的食物,这样你就不需要再准备了,而优化程序就是你用它做的,或者说你的内脏。