1. Picture categorization network
This is a binary classification network which can be any one of alxnet ,vgg,resnet and is responsible for binary classification of images to differentiate whether the image is a real image or a generated image
2. Image generation network
The input is a random noise and the output is a picture using an inverse convolutional layer
I'm sure anyone who has studied deep learning can write these two networks, but of course if you can't, that's okay, someone else has written it for you
First is the image categorization network:
It is simply cnn+relu+sogmid, which can be replaced by any classification network, such as bgg,resnet, etc.
class Discriminator(): def __init__(self, ngpu): super(Discriminator, self).__init__() = ngpu = ( # input is (nc) x 64 x 64 nn.Conv2d(nc, ndf, 4, 2, 1, bias=False), (0.2, inplace=True), # state size. (ndf) x 32 x 32 nn.Conv2d(ndf, ndf * 2, 4, 2, 1, bias=False), nn.BatchNorm2d(ndf * 2), (0.2, inplace=True), # state size. (ndf*2) x 16 x 16 nn.Conv2d(ndf * 2, ndf * 4, 4, 2, 1, bias=False), nn.BatchNorm2d(ndf * 4), (0.2, inplace=True), # state size. (ndf*4) x 8 x 8 nn.Conv2d(ndf * 4, ndf * 8, 4, 2, 1, bias=False), nn.BatchNorm2d(ndf * 8), (0.2, inplace=True), # state size. (ndf*8) x 4 x 4 nn.Conv2d(ndf * 8, 1, 4, 1, 0, bias=False), () ) def forward(self, input): return (input)
Focus on generating networks
The code is as follows, actually it is the anti-convolution + bn + relu
class Generator(): def __init__(self, ngpu): super(Generator, self).__init__() = ngpu = ( # input is Z, going into a convolution nn.ConvTranspose2d( nz, ngf * 8, 4, 1, 0, bias=False), nn.BatchNorm2d(ngf * 8), (True), # state size. (ngf*8) x 4 x 4 nn.ConvTranspose2d(ngf * 8, ngf * 4, 4, 2, 1, bias=False), nn.BatchNorm2d(ngf * 4), (True), # state size. (ngf*4) x 8 x 8 nn.ConvTranspose2d( ngf * 4, ngf * 2, 4, 2, 1, bias=False), nn.BatchNorm2d(ngf * 2), (True), # state size. (ngf*2) x 16 x 16 nn.ConvTranspose2d( ngf * 2, ngf, 4, 2, 1, bias=False), nn.BatchNorm2d(ngf), (True), # state size. (ngf) x 32 x 32 nn.ConvTranspose2d( ngf, nc, 4, 2, 1, bias=False), () # state size. (nc) x 64 x 64 ) def forward(self, input): return (input)
To be fair, both of the above networks are pretty simple.
Here's the real kicker. How to train.
Each STEP is divided into three steps:
- Training II Classification Networks
1. Input real pictures, after binary classification, hope to be determined as real pictures, update the binary classification network
2. Input noise, into the generative network, generate a picture, input binary classification network, hope to determine the false picture, update the binary classification network - Training a generative network
3. Input noise, into the generative network, generate a picture, input binary classification network, hope to determine the real picture, update the generative network
Without further ado, let's get to the code.
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 = ((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 = ().item() ## Train with all-fake batch # Generate batch of latent vectors noise = (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(()).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 = ().item() # Add the gradients from the all-real and all-fake batches errD = errD_real + errD_fake # Update D () ############################ # (2) Update G network: maximize log(D(G(z))) ########################### netG.zero_grad() label.fill_(real_label) # fake labels are real for generator cost # Since we just updated D, perform another forward pass of all-fake batch through D output = netD(fake).view(-1) # Calculate G's loss based on this output errG = criterion(output, label) # Calculate gradients for G () D_G_z2 = ().item() # Update G () # Output training stats if i % 50 == 0: print('[%d/%d][%d/%d]\tLoss_D: %.4f\tLoss_G: %.4f\tD(x): %.4f\tD(G(z)): %.4f / %.4f' % (epoch, num_epochs, i, len(dataloader), (), (), D_x, D_G_z1, D_G_z2)) # Save Losses for plotting later G_losses.append(()) D_losses.append(()) # Check how the generator is doing by saving G's output on fixed_noise if (iters % 500 == 0) or ((epoch == num_epochs-1) and (i == len(dataloader)-1)): with torch.no_grad(): fake = netG(fixed_noise).detach().cpu() img_list.append(vutils.make_grid(fake, padding=2, normalize=True)) iters += 1
Above is the detailed content of Pytorch Learning Notes DCGAN Minimalist Getting Started Tutorial, for more information about Pytorch Learning DCGAN Getting Started Tutorial, please follow my other related articles!