DCGANで識別機に偽データを2回流す理由
解決したいこと
PyTorchチュートリアルhttps://colab.research.google.com/github/YutaroOgawa/pytorch_tutorials_jp/blob/main/notebook/2_Image_Video/2_4_dcgan_faces_tutorial_jp.ipynb
でDCGANの勉強をしていたところ、識別機に同じ偽データを2回流した後に、その結果を用いて生成機の学習を進めていました。直感的に非合理的であると感じてしまうのですが、何か理由があるのでしょうか?
該当するソースコード
# 訓練のループ
# 訓練の進捗状況を把握するためのリスト
img_list = []
G_losses = []
D_losses = []
iters = 0
print("Starting Training Loop...")
# 各エポックについて
for epoch in range(num_epochs):
# dataloader内の各バッチについて
for i, data in enumerate(dataloader, 0):
############################
# (1) 識別器Dのネットワーク更新: maximize log(D(x)+ log(1 - D(G(z)) )
###########################
## 本物画像のバッチを使った訓練
netD.zero_grad()
# バッチの形式をランタイムに合わせる
real_cpu = data[0].to(device)
b_size = real_cpu.size(0)
label = torch.full((b_size,), real_label, dtype=torch.float, device=device)
# 本物画像のバッチをDに順伝播させる
output = netD(real_cpu).view(-1)
# 全ての本物画像のバッチの損失を計算する
errD_real = criterion(output, label)
# 逆伝播で勾配を計算する
errD_real.backward()
D_x = output.mean().item()
## 偽物画像のバッチを使った訓練
# 潜在ベクトルのバッチを生成
noise = torch.randn(b_size, nz, 1, 1, device=device)
# Gを使って、偽画像のバッチを生成
fake = netG(noise)
label.fill_(fake_label)
# Dを使って、全ての偽画像を分類
output = netD(fake.detach()).view(-1)
# 全ての偽画像に対するDの損失を計算
errD_fake = criterion(output, label)
# 偽画像に対する勾配を計算
errD_fake.backward()
D_G_z1 = output.mean().item()
# 全ての本物画像のバッチの勾配と、全ての偽画像のバッチの勾配を足す
errD = errD_real + errD_fake
# Dのパラメータを更新
optimizerD.step()
############################
# (2) 生成器Gのネットワークを更新: maximize log(D(G(z)))
###########################
netG.zero_grad()
label.fill_(real_label) # 生成器の損失にとっては、偽画像ラベルが正解になる
# ちょうど識別器Dを更新したので、偽画像バッチをもう一度識別器Dに順伝播させる
output = netD(fake).view(-1)
# この出力に対するGの損失をもう一度計算
errG = criterion(output, label)
# Gの勾配を計算
errG.backward()
D_G_z2 = output.mean().item()
# Gを更新
optimizerG.step()
0