AJGAN
def train(self): """Train StarGAN within a single dataset.""" # Set data loader. data_loader = self.celeba_loader data_iter = iter(data_loader) # Learning rate cache for decaying. g_lr = self.g_lr d_lr = self.d_lr # Start training from scratch or resume training. start_iters = 0 #加入加载模型 self.resume_iters = start_iters if self.resume_iters: #参数resume_iters 设置为none start_iters = self.resume_iters #可以不连续训练,从之前训练好后的结果处开始 self.restore_model(self.resume_iters, 'both') # Start training. print('Start training...') start_time = time.time() for i in range(start_iters, self.num_iters): # =================================================================================== # # 1. Preprocess input data # # =================================================================================== # # Fetch real images and labels. try: x_fixed, x_illumination,label_org = next(data_iter) except: data_iter = iter(data_loader) x_fixed, x_illumination,label_org = next(data_iter) x_fixed = x_fixed.to(self.device) x_illumination = x_illumination.to(self.device) label_org = label_org.to(self.device) # =================================================================================== # # #加上gluon中的网络,normalizaion # # =================================================================================== # fake_out = self.netG1(x_illumination) # update D self.set_requires_grad(self.netD1, True) self.optimizer_D.zero_grad() self.backward_D(x_illumination,fake_out,x_fixed) self.optimizer_D.step() # update G self.set_requires_grad(self.netD1, False) self.optimizer_G.zero_grad() self.backward_G(x_illumination,fake_out,x_fixed,label_org) self.optimizer_G.step() # =================================================================================== # # 2. Train the discriminator # # =================================================================================== # # Compute loss with real images. out_src, out_cls = self.D(x_illumination) #D接受的就只是一幅图像,真实的具有光照的图像 #判别器以一个batch(16张)的真实图片为输入,输出out_src[16, 1, 2, 2],用来判断图片真假。 #out_cls[16, 5],得到图片的标签估计。 d_loss_real = - torch.mean(out_src) # d_loss_real最小,那么 out_src 最大==1 (针对图像) d_loss_cls = self.classification_loss(out_cls, label_org, self.dataset) #针对标签 #d_loss_cls = -self.classification_loss(out_cls, label_org, dataset = 'RaFD') ##衡量真实标签与标签估计的差距 x_fake = self.G(x_fixed, label_org) #x_fake 生成一个图像数据 out_src, out_cls = self.D(x_fake.detach())#在这里表示不用求上面一行中的G的梯度 d_loss_fake = torch.mean(out_src) #假图像为0 #判定越接近为假,损失越小 #加到这个地方,归类生成图像的光照 #d_loss_cls = self.classification_loss(out_cls, label_org, self.dataset) # Compute loss for gradient penalty. #计算梯度惩罚因子alpha,根据alpha结合x_real,x_fake,输入判别网络,计算梯度,得到梯度损失函数, alpha = torch.rand(x_fixed.size(0), 1, 1, 1).to(self.device) # alpha是一个随机数 tensor([[[[ 0.7610]]]]) x_hat = (alpha * x_fixed.data + (1 - alpha) * x_fake.data).requires_grad_(True) # x_hat是一个图像大小的张量数据,随着alpha的改变而变化 out_src, _ = self.D(x_hat) #x_hat 表示梯度惩罚因子 d_loss_gp = self.gradient_penalty(out_src, x_hat) d_loss = d_loss_real + d_loss_fake + self.lambda_cls * d_loss_cls + self.lambda_gp * d_loss_gp #print(d_loss_real,d_loss_fake,d_loss_cls,d_loss_gp) #(1.00000e-04 *1.1113) (1.00000e-05 * -3.0589) (13.8667) (0.9953) self.reset_grad() d_loss.backward() self.d_optimizer.step() # Logging. loss = {} loss['D/loss_real'] = d_loss_real.item() loss['D/loss_fake'] = d_loss_fake.item() loss['D/loss_cls'] = (self.lambda_cls *d_loss_cls).item() loss['D/loss_gp'] = (self.lambda_gp * d_loss_gp).item() # =================================================================================== # # 3. Train the generator # # =================================================================================== # #生成网络的作用是,输入original域的图可以生成目标域的图像,输入为目标域的图像,生成original域的图像(重建) if (i+1) % self.n_critic == 0: #每更新5次判别器再更新一次生成器 # Original-to-target domain. #将真实图像输入x_real和假的标签c_trg输入生成网络,得到生成图像x_fake x_fake = self.G(x_fixed, label_org) out_src, out_cls = self.D(x_fake) g_loss_fake = - torch.mean(out_src) #这里是对抗损失,希望生成的假图像为1 g_loss_cls = self.classification_loss(out_cls, label_org, self.dataset)#向目标标签进行转化 #g_loss_cls = -self.classification_loss(out_cls, label_org, dataset = 'RaFD') # Target-to-original domain. # 这里结合另一个GAN 进行重建 #x_reconst = self.G(x_fake, c_org) #g_loss_rec = torch.mean(torch.abs(x_fixed - x_reconst)) g_ground_truth = torch.mean(torch.abs(x_illumination - x_fake)) #和normlization结合进行重建 g_loss_rec = torch.mean(torch.abs(self.G(self.netG1(x_illumination),label_org) - x_illumination)) # Backward and optimize. g_loss = g_loss_fake + 100 * g_ground_truth + self.lambda_cls * g_loss_cls +\ self.lambda_rec * g_loss_rec #print(g_loss_fake,g_ground_truth,g_loss_cls,g_loss_rec) #tensor(-0.4776) tensor(0.4306) tensor(5.2388) tensor(0.4283) self.reset_grad() g_loss.backward() self.g_optimizer.step() # Logging. loss['G/loss_fake'] = g_loss_fake.item() loss['G/loss_gt'] = (self.lambda_rec *g_ground_truth).item() loss['G/loss_rec'] = (self.lambda_rec *g_loss_rec).item() loss['G/loss_cls'] = g_loss_cls.item() # =================================================================================== # # 4. Miscellaneous # # =================================================================================== # # Print out training information. if (i+1) % self.log_step == 0: et = time.time() - start_time et = str(datetime.timedelta(seconds=et))[:-7] log = "Elapsed [{}], Iteration [{}/{}]".format(et, i+1, self.num_iters) for tag, value in loss.items(): log += ", {}: {:.4f}".format(tag, value) print(log) if self.use_tensorboard: for tag, value in loss.items(): self.logger.scalar_summary(tag, value, i+1) # Translate fixed images for debugging. 每100轮保存一次图像 if (i+1) % self.sample_step == 0: with torch.no_grad(): x_fake_list = [x_fixed] x_fake_list.append(self.G(x_fixed, label_org)) x_concat = torch.cat(x_fake_list, dim=3) sample_path = os.path.join(self.sample_dir, '{}-images.jpg'.format(i+1)) save_image(self.denorm(x_concat.data.cpu()), sample_path, nrow=1, padding=0) print('Saved real and fake images into {}...'.format(sample_path)) # Save model checkpoints. 每100轮保存一下模型 if (i+1) % self.model_save_step == 0: G_path = os.path.join(self.model_save_dir, '{}-G.ckpt'.format(i+1)) D_path = os.path.join(self.model_save_dir, '{}-D.ckpt'.format(i+1)) torch.save(self.G.state_dict(), G_path) torch.save(self.D.state_dict(), D_path) G1_path = os.path.join(self.model_save_dir, '{}-G1.ckpt'.format(i+1)) D1_path = os.path.join(self.model_save_dir, '{}-D1.ckpt'.format(i+1)) torch.save(self.netG1.state_dict(), G1_path) torch.save(self.netD1.state_dict(), D1_path) print('Saved model checkpoints into {}...'.format(self.model_save_dir)) # Decay learning rates. 降低学习率 if (i+1) % self.lr_update_step == 0 and (i+1) > (self.num_iters - self.num_iters_decay): g_lr -= (self.g_lr / float(self.num_iters_decay)) d_lr -= (self.d_lr / float(self.num_iters_decay)) self.update_lr(g_lr, d_lr) print ('Decayed learning rates, g_lr: {}, d_lr: {}.'.format(g_lr, d_lr))