The picture generated by the generator is always noisy

Viewed 27

I try to imitate DCAGN, using residual structure to build a symmetric generator and discriminator; my structure is as follows, I imitate ACGAN input corresponding labels. However, after training, the images generated by the generator have always been noise maps and have hardly changed.

And I tried to change the loss function from BCEloss to hinge loss and the optimizer from Adam optimizer to RMSprop, but nothing works

class netD(nn.Module):
    def __init__(self,Residual_block,num_classes = 3):
        super(netD,self).__init__()
        self.layer1 = nn.Sequential(
            # nn.Conv2d(3,8,kernel_size=7,stride = 2,padding = 3),
            nn.Conv2d(3,8,kernel_size=5,stride = 2,padding = 2),
            # nn.Conv2d(3,8,kernel_size=3,stride = 2,padding = 1),
            # nn.BatchNorm2d(8),
            nn.LeakyReLU(0.2),
            # nn.ReLU(inplace=True),
            # nn.MaxPool2d(kernel_size=3,stride=2,padding=1)
            nn.Conv2d(8,8,kernel_size=3,stride = 2,padding = 1),
            nn.BatchNorm2d(8),
            nn.LeakyReLU(0.2),
            # nn.ReLU(inplace=True),
            
        )
        def resnet_block(input_channels,output_channels,num_residuals,first_block=False):
            blk = []
            for i in range(num_residuals):
                if i == 0 and not first_block:
                    blk.append(
                        Residual_block(input_channels,output_channels,use_1x1conv = True,stride=2)
                    )
                else:
                    blk.append(
                        Residual_block(output_channels,output_channels)
                    )
            return blk
        
        self.layer2 = nn.Sequential(*resnet_block(8,8,2,first_block = True))
        self.layer3 = nn.Sequential(*resnet_block(8,16,2))
        self.layer4 = nn.Sequential(*resnet_block(16,32,2))
        self.layer5 = nn.Sequential(*resnet_block(32,64,2))
        self.layer6 = nn.Sequential(*resnet_block(64,128,2))
        self.layer7 = nn.Sequential(*resnet_block(128,256,2))
        self.layer8 = nn.Sequential(*resnet_block(256,512,2))
        self.layer9 = nn.Sequential(*resnet_block(512,1024,2))
        
        # self.layer10 = nn.Sequential(
        #                     nn.AdaptiveAvgPool2d((1,1)),
        #                     nn.Flatten(),
        #                     # nn.Linear(512, 1)
        #                 )
        
        self.adv_layer = nn.Sequential(nn.Flatten(),nn.Linear(1024, 1), nn.Sigmoid())
        self.aux_layer = nn.Sequential(nn.Flatten(),nn.Linear(1024, num_classes), nn.Softmax())
class netG(nn.Module):
    def __init__(self,Residual_block,num_classes = 3):
        super(netG,self).__init__()
        self.label_emb = nn.Embedding(3, 100)
        self.layer0 = nn.Sequential(
            nn.ConvTranspose2d(100,1024,kernel_size = 4,stride = 1,padding = 0 ,bias = False),
            nn.GroupNorm(num_channels=1024,num_groups=64),
            # nn.BatchNorm2d(1024),
            # nn.LeakyReLU(0.2, inplace=True),
            nn.ReLU(inplace=True),
            # nn.UpsamplingNearest2d(scale_factor=2)
        )
        # self.linear0 = nn.Linear(100, 512*16*16) #(100,256)
       
        
        
        def resnet_block(input_channels,output_channels,num_residuals):
            blk = []
            for i in range(num_residuals):
                blk.append(
                    Dconv_Residual_block(output_channels,output_channels)
                )
            return blk
        self.layer1 = nn.Sequential(
            *resnet_block(1024,1024,2),
            nn.ConvTranspose2d(1024,512,kernel_size = 4,stride = 2,padding = 1 ,bias = False),
            nn.GroupNorm(num_channels=512,num_groups=32),
            # nn.BatchNorm2d(512),
            # nn.LeakyReLU(0.2, inplace=True),
            nn.ReLU(inplace=True)  
            
        )
        self.layer2 = nn.Sequential(
            *resnet_block(512,512,2),
            nn.ConvTranspose2d(512,256,kernel_size = 4,stride = 2,padding = 1 ,bias = False),
            nn.GroupNorm(num_channels=256,num_groups=16),
            # nn.BatchNorm2d(256),
            # nn.LeakyReLU(0.2, inplace=True),
            nn.ReLU(inplace=True)  
            
        )
        self.layer3 = nn.Sequential(
            *resnet_block(256,256,2),
            nn.ConvTranspose2d(256,128,kernel_size = 4,stride = 2,padding = 1 ,bias = False),
            nn.GroupNorm(num_channels=128,num_groups=8),
            # nn.BatchNorm2d(128),
            # nn.LeakyReLU(0.2, inplace=True),
            nn.ReLU(inplace=True)  
            
        )
        self.layer4 = nn.Sequential(
            *resnet_block(128,128,2),
            nn.ConvTranspose2d(128,64,kernel_size = 4,stride = 2,padding = 1 ,bias = False),
            nn.GroupNorm(num_channels=64,num_groups=4),
            # nn.BatchNorm2d(64),
            # nn.LeakyReLU(0.2, inplace=True)
            nn.ReLU(inplace=True)  
            
        )
        self.layer5 = nn.Sequential(
            *resnet_block(64,64,2),
            nn.ConvTranspose2d(64,32,kernel_size = 4,stride = 2,padding = 1 ,bias = False),
            nn.GroupNorm(num_channels=32,num_groups=2),
            # nn.BatchNorm2d(32),
            # nn.LeakyReLU(0.2, inplace=True)
            nn.ReLU(inplace=True)  
            
        )
        self.layer6 = nn.Sequential(
            *resnet_block(32,32,2),
            nn.ConvTranspose2d(32,16,kernel_size = 4,stride = 2,padding = 1 ,bias = False),
            nn.GroupNorm(num_channels=16,num_groups=1),
            # nn.BatchNorm2d(16),
            nn.ReLU(inplace=True)  
            # nn.LeakyReLU(0.2, inplace=True)
        )
        self.layer7 = nn.Sequential(
            *resnet_block(16,16,2),
            nn.ConvTranspose2d(16,3,kernel_size = 4,stride = 2,padding = 1 ,bias = False),
            # nn.BatchNorm2d(3),
            # nn.LayerNorm([3,512,512]),
            
            nn.Tanh()
        )
            batch_size = imgs.shape[0]

            # Adversarial ground truths
            valid = Variable(FloatTensor(batch_size, 1).fill_(1.0), requires_grad=False)
            fake = Variable(FloatTensor(batch_size, 1).fill_(0.0), requires_grad=False)

            # Configure input
            real_imgs = Variable(imgs.type(FloatTensor))
            labels = Variable(labels.type(LongTensor))
            # -----------------
            #  Train Generator
            # -----------------

            optimizer_G.zero_grad()

            # Sample noise and labels as generator input
            z = Variable(FloatTensor(np.random.normal(0, 1, (batch_size, opt.latent_dim))))
            gen_labels = Variable(LongTensor(np.random.randint(0, opt.n_classes, batch_size)))
            
            # Generate a batch of images
            gen_imgs = generator(z, gen_labels)

            # Loss measures generator's ability to fool the discriminator
            validity, pred_label = discriminator(gen_imgs)
            g_loss = 0.5 * (criterionG(validity, valid) + auxiliary_loss(pred_label, gen_labels))
            
            

            g_loss.backward()
            optimizer_G.step()

            # ---------------------
            #  Train Discriminator
            # ---------------------

            optimizer_D.zero_grad()

            # Loss for real images
            real_pred, real_aux = discriminator(real_imgs)
            d_real_loss = (criterionD(real_pred, valid) + auxiliary_loss(real_aux, labels)) / 2
            

            # Loss for fake images
            fake_pred, fake_aux = discriminator(gen_imgs.detach())
            d_fake_loss = (criterionD(fake_pred, fake) + auxiliary_loss(fake_aux, gen_labels)) / 2
            

            # Total discriminator loss
            d_loss = (d_real_loss + d_fake_loss) / 2

            # Calculate discriminator accuracy
            pred = np.concatenate([real_aux.data.cpu().numpy(), fake_aux.data.cpu().numpy()], axis=0)
            gt = np.concatenate([labels.data.cpu().numpy(), gen_labels.data.cpu().numpy()], axis=0)
            d_acc = np.mean(np.argmax(pred, axis=1) == gt)

            d_loss.backward()
            optimizer_D.step()

I have tried the simplest discriminator combined with the generator I wrote, but this structure has some effects. Why is this ? Is there something wrong with my discriminator structure? My input image is 512x512.

0 Answers
Related