DCGAN

学習目標: 畳み込みを使ったGANの構造と安定した学習のためのテクニックを理解する

DCGANとは

DCGAN(Deep Convolutional GAN)は、畳み込み層を使用したGANで、 画像生成において大きな成功を収めました。

DCGANのガイドライン

  1. プーリング層の代わりにストライド畳み込みを使用
  2. 生成器と識別器の両方でBatchNormを使用
  3. 全結合層を削除し、全畳み込みアーキテクチャを採用
  4. 生成器: 出力層以外はReLU、出力層はTanh
  5. 識別器: すべての層でLeakyReLU

PyTorch実装

class DCGenerator(nn.Module):
    def __init__(self, latent_dim=100, channels=3):
        super().__init__()
        self.model = nn.Sequential(
            # 入力: (latent_dim,) → (512, 4, 4)
            nn.ConvTranspose2d(latent_dim, 512, 4, 1, 0, bias=False),
            nn.BatchNorm2d(512),
            nn.ReLU(True),

            # (512, 4, 4) → (256, 8, 8)
            nn.ConvTranspose2d(512, 256, 4, 2, 1, bias=False),
            nn.BatchNorm2d(256),
            nn.ReLU(True),

            # (256, 8, 8) → (128, 16, 16)
            nn.ConvTranspose2d(256, 128, 4, 2, 1, bias=False),
            nn.BatchNorm2d(128),
            nn.ReLU(True),

            # (128, 16, 16) → (64, 32, 32)
            nn.ConvTranspose2d(128, 64, 4, 2, 1, bias=False),
            nn.BatchNorm2d(64),
            nn.ReLU(True),

            # (64, 32, 32) → (channels, 64, 64)
            nn.ConvTranspose2d(64, channels, 4, 2, 1, bias=False),
            nn.Tanh()
        )

    def forward(self, z):
        return self.model(z.view(-1, z.size(1), 1, 1))


class DCDiscriminator(nn.Module):
    def __init__(self, channels=3):
        super().__init__()
        self.model = nn.Sequential(
            # (channels, 64, 64) → (64, 32, 32)
            nn.Conv2d(channels, 64, 4, 2, 1, bias=False),
            nn.LeakyReLU(0.2, inplace=True),

            # (64, 32, 32) → (128, 16, 16)
            nn.Conv2d(64, 128, 4, 2, 1, bias=False),
            nn.BatchNorm2d(128),
            nn.LeakyReLU(0.2, inplace=True),

            # (128, 16, 16) → (256, 8, 8)
            nn.Conv2d(128, 256, 4, 2, 1, bias=False),
            nn.BatchNorm2d(256),
            nn.LeakyReLU(0.2, inplace=True),

            # (256, 8, 8) → (512, 4, 4)
            nn.Conv2d(256, 512, 4, 2, 1, bias=False),
            nn.BatchNorm2d(512),
            nn.LeakyReLU(0.2, inplace=True),

            # (512, 4, 4) → (1, 1, 1)
            nn.Conv2d(512, 1, 4, 1, 0, bias=False),
            nn.Sigmoid()
        )

    def forward(self, x):
        return self.model(x).view(-1, 1)

転置畳み込み(アップサンプリング)

nn.ConvTranspose2dは特徴マップを拡大します(畳み込みの逆操作)。

nn.ConvTranspose2d(in_ch, out_ch, kernel=4, stride=2, padding=1)

出力サイズ = 入力サイズ × 2

理解度チェック

Q. DCGANの生成器で使用される活性化関数は?(出力層以外)