PyTorch normalize two sets of gradients during training
In this GAN tutorial, if you scroll down to the training loop you can see they combine the gradients 
 errD = errD_real + errD_fake like this. Where errD_real = criterion(output, label) and errD_fake = criterion(output, label) and criterion = nn.BCELoss(). I want to do the same thing but before doing a backward pass I want to normalize both gradients to the lower Euclidean norm of the two. How would I do that?

I know I can access the gradients of each weight individually on netD by printing out netD.weight.grad, but is there some way to batchnorm them to the lower Euclidean norm of the two?

Here's the part of the training loop I'm talking about:

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()
        ...


You mentioned two things which are incorrect. 


errD = errD_real + errD_fake basically combines two objective function, not gradients. 
You need to change the gradients after the backward pass, not before. With the backward pass, the gradients will be computed and then you can modify the gradients before calling optimizer.step() which updates the model parameters.


Answer to your question:

I believe there is no direct API support from PyTorch to achieve your goal. However, you can easily modify the gradients by yourself after the backward pass. To compute the Euclidean norm, you can use the norm function. Then you can simply divide the gradients (inplace).
