DCGAN の例,PyTorch 公式チュートリアルの実装を使い,新しい顔を生成してみる

PyTorch 公式のDCGANチュートリアルは, Generative Adversarial Networks (GAN) の一種である DCGAN (Deep Convolutional Generative Adversarial Networks) を PyTorch で実装したもの.celebA データセットを用いて,実在しない人物の顔画像を生成する学習を行う.

手順の要点: 前準備として,NVIDIA CUDA Toolkit 12.8,NVIDIA cuDNN 9.19.0,Python 3.12,PyTorch 等をインストールする.

ソフトウェア等の利用条件等は,利用者で確認すること.

DCGAN (Deep Convolutional Generative Adversarial Networks) の参考文献情報: https://arxiv.org/abs/1511.06434

PyTorch 公式のDCGANチュートリアルの Web ページ: https://docs.pytorch.org/tutorials/beginner/dcgan_faces_tutorial.html

前準備

Build Tools for Visual Studio 2026(ビルドツール)のインストール

Build Tools for Visual Studio は,Visual Studio の IDE を含まない C/C++ コンパイラ,ライブラリ,ビルドツール等のコマンドライン向け開発ツールセットである.インストール済みの場合,この手順は不要である.

以下のコマンドは,Build Tools が未インストールの場合は winget で新規インストールし,インストール済みの場合は setup.exe modify でコンポーネントを追加する(バージョンは変更しない).

管理者権限のコマンドプロンプトで以下を実行する(手順:Windows キーまたはスタートメニュー → cmd と入力 → 右クリック → 「管理者として実行」).

REM VC++ ランタイム
winget install --scope machine --id Microsoft.VCRedist.2015+.x64 -e --silent --disable-interactivity --force --accept-source-agreements --accept-package-agreements --override "/quiet /norestart"

REM Build Tools + Desktop development with C++(VCTools)+ 追加コンポーネント(一括)
winget list --id Microsoft.VisualStudio.BuildTools 2>nul | findstr /i "BuildTools" >nul 2>&1
if %ERRORLEVEL% EQU 0 (
    for /f "delims=" %P in ('"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -products * -property installationPath') do start /wait "" "C:\Program Files (x86)\Microsoft Visual Studio\Installer\setup.exe" modify --installPath "%P" --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Workload.MSBuildTools --add Microsoft.VisualStudio.Component.VC.CMake.Project --add Microsoft.VisualStudio.Component.VC.Llvm.Clang --add Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset --add Microsoft.VisualStudio.Component.Windows11SDK.26100 --includeRecommended --quiet --norestart
) else (
    winget install --scope machine --id Microsoft.VisualStudio.BuildTools -e --silent --disable-interactivity --force --accept-source-agreements --accept-package-agreements --override "--quiet --wait --norestart --nocache --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --add Microsoft.VisualStudio.Workload.MSBuildTools --add Microsoft.VisualStudio.Component.VC.CMake.Project --add Microsoft.VisualStudio.Component.VC.Llvm.Clang --add Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset --add Microsoft.VisualStudio.Component.Windows11SDK.26100"
)

インストール完了の確認

winget list Microsoft.VisualStudio.BuildTools

Python 3.12 のインストール(Windows 上) [クリックして展開]

以下のいずれかの方法で Python 3.12 をインストールする.Python がインストール済みの場合,この手順は不要である.

方法1:winget によるインストール

管理者権限のコマンドプロンプトで以下を実行する.管理者権限のコマンドプロンプトを起動するには,Windows キーまたはスタートメニューから「cmd」と入力し,表示された「コマンドプロンプト」を右クリックして「管理者として実行」を選択する.

winget install --id Python.Python.3.12 -e --scope machine --silent --accept-source-agreements --accept-package-agreements --override "/quiet InstallAllUsers=1 PrependPath=1 Include_test=0 Include_pip=1 Include_launcher=1 InstallLauncherAllUsers=1 TargetDir=\"C:\Program Files\Python312\""

--scope machine を指定することで,システム全体(全ユーザー向け)にインストールされる.このオプションの実行には管理者権限が必要である.インストール完了後,コマンドプロンプトを再起動すると PATH が自動的に設定される.

方法2:インストーラーによるインストール

  1. Python 公式サイト(https://www.python.org/downloads/)にアクセスし,「Download Python 3.x.x」ボタンから Windows 用インストーラーをダウンロードする.
  2. ダウンロードしたインストーラーを実行する.
  3. 初期画面の下部に表示される「Add python.exe to PATH」に必ずチェックを入れてから「Customize installation」を選択する.このチェックを入れ忘れると,コマンドプロンプトから python コマンドを実行できない.
  4. 「Install Python 3.xx for all users」にチェックを入れ,「Install」をクリックする.

インストールの確認

コマンドプロンプトで以下を実行する.

python --version

バージョン番号(例:Python 3.12.x)が表示されればインストール成功である.「'python' は,内部コマンドまたは外部コマンドとして認識されていません.」と表示される場合は,インストールが正常に完了していない.

Git のインストール(Windows 上) [クリックして展開]

管理者権限のコマンドプロンプトで以下を実行する.管理者権限は,winget の --scope machine オプションでシステム全体にインストールするために必要となる.

REM Git をシステム領域にインストール
winget install --scope machine --id Git.Git -e --silent --disable-interactivity --force --accept-source-agreements --accept-package-agreements --override "/VERYSILENT /NORESTART /NOCANCEL /SP- /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /COMPONENTS=""icons,ext\reg\shellhere,assoc,assoc_sh"" /o:PathOption=Cmd /o:CRLFOption=CRLFCommitAsIs /o:BashTerminalOption=MinTTY /o:DefaultBranchOption=main /o:EditorOption=VIM /o:SSHOption=OpenSSH /o:UseCredentialManager=Enabled /o:PerformanceTweaksFSCache=Enabled /o:EnableSymlinks=Disabled /o:EnableFSMonitor=Disabled"

NVIDIA ドライバのインストール(Windows 上)

NVIDIA ドライバ

NVIDIA ドライバは,NVIDIA製GPUを動作させるための重要なソフトウェアである.このドライバをインストールすることにより,GPUの性能を引き出すことができ,グラフィックス関連のアプリ,AI関連のアプリの高速化が期待できる.

ドライバはNVIDIA公式サイトである https://www.nvidia.co.jp/Download/index.aspx?lang=jp からダウンロードできる.このサイトからダウンロードするときには,グラフィックスカードとオペレーティングシステムを選択する. なお,NVIDIA app を用いてインストールすることも可能である.

【サイト内の関連ページ】

  1. NVIDIA グラフィックス・ボードの確認

    Windows で,NVIDIA グラフィックス・ボードの種類を調べたいときは, 次のコマンドを実行することにより調べることができる.

    powershell -command "Get-CimInstance Win32_VideoController | Select-Object -ExpandProperty Name"
    
  2. NVIDIA ドライバのダウンロード

    NVIDIA ドライバは,以下の NVIDIA 公式サイトからダウンロードできる.

    https://www.nvidia.co.jp/Download/index.aspx?lang=jp

  3. ダウンロードの際には,使用しているグラフィックス・ボードの型番とオペレーティングシステムを選択する.

NVIDIA CUDA Toolkit 12.8 のインストール(Windows 上)

NVIDIA CUDA Toolkit のインストール時の注意点

NVIDIAのGPUを使用して並列計算を行うためのツールセット

主な機能: GPU を利用した並列処理,GPU のメモリ管理,C++をベースとした拡張言語とAPIとライブラリ

【NVIDIA CUDA Toolkit の動作に必要なもの】

【Windows でインストールするときの注意点】

【関連する外部ページ】

以下のコマンドを管理者権限のコマンドプロンプトで実行する (手順:Windows キーまたはスタートメニュー → cmd と入力 → 右クリック → 「管理者として実行」).

REM NVIDIA CUDA Toolkit 12.8 をシステム領域にインストール
winget install --scope machine --id Nvidia.CUDA --version 12.8 -e --silent --disable-interactivity --force --uninstall-previous --accept-source-agreements --accept-package-agreements --override "-s -n"

REM 環境変数 TEMP, TMP の設定(一時ファイルの保存先を短いパスに変更)
mkdir C:\TEMP
set "TEMP_PATH=C:\TEMP"
setx TEMP "%TEMP_PATH%" /M >nul
setx TMP "%TEMP_PATH%" /M >nul

NVIDIA cuDNN 9.19.0 のインストール

インストールするNVIDIA cuDNN のバージョンは 9.19.0 for CUDA 12.8

NVIDIA cuDNN

NVIDIA cuDNN は,NVIDIA CUDA Toolkit上で動作する高性能なディープラーニング用ライブラリである.畳み込みニューラルネットワーク (CNN) やリカレントニューラルネットワーク (RNN) など,さまざまなディープラーニングモデルのトレーニングと推論を高速化する.

【関連する外部ページ】

NVIDIA cuDNN のインストール(Windows 上)の概要

  1. NVIDIA Developer Program メンバーシップへの加入: cuDNN のダウンロードには無料のメンバーシップ登録が必要である.

    NVIDIA Developer Program の公式ページ: https://developer.nvidia.com/developer-program

  2. 互換バージョンの選択とダウンロード: インストール済みの CUDA Toolkit のバージョン(今回は 12.8)に適合する cuDNN のバージョン(今回は v9.19.0)を選択し,Windows 用のインストーラ(exe)または zip ファイルをダウンロードする.
  3. インストール: インストーラを使用する場合は,インストーラを実行し,対象の CUDA バージョンを選択してインストールする.zip ファイルを使用する場合は,展開し,中のファイル(bin, include, lib\x64 フォルダ内)を cuDNN のインストールディレクトリ(C:\Program Files\NVIDIA\CUDNN\v9.x)にコピーする.
  4. 環境変数の設定: cuDNN の bin ディレクトリ(C:\Program Files\NVIDIA\CUDNN\v9.x\bin)をシステム環境変数 Path に追加する.必要に応じて CUDNN_PATH も設定する.
  5. 動作確認: cuDNN ライブラリ(cudnn*.dll)にパスが通っているか確認する.

パスの確認

次の操作により,NVIDIA cuDNN のライブラリにパスが通っていることを確認する

Windows のコマンドプロンプトを開き,次のコマンドを実行する.エラーメッセージが出ないことを確認.

where cudnn64_9.dll

PyTorch のインストール(Windows 上)

  1. 以下の手順を管理者権限のコマンドプロンプトで実行する (手順:Windows キーまたはスタートメニュー → cmd と入力 → 右クリック → 「管理者として実行」).
  2. PyTorch のページを確認

    PyTorch の公式ページ: https://pytorch.org/index.html

  3. 次のようなコマンドを実行(実行するコマンドは,PyTorch のページの表示されるコマンドを使う).

    次のコマンドを実行することにより, PyTorch (NVIDIA CUDA 12.8 用)がインストールされる.

    事前に NVIDIA CUDA のバージョンを確認しておくこと(ここでは,NVIDIA CUDA Toolkit 12.8 が前もってインストール済みであるとする).

    PyTorch で,GPU が動作している場合には,「torch.cuda.is_available()」により,True が表示される.

    python -m pip install -U --ignore-installed pip
    python -m pip uninstall -y torch torchvision torchaudio torchtext xformers
    python -m pip install -U torch torchvision torchaudio numpy matplotlib --index-url https://download.pytorch.org/whl/cu128
    
    python -c "import torch; print(torch.__version__, torch.cuda.is_available())"
    

    【サイト内の関連ページ】

    【関連する外部ページ】

celebA データセットのダウンロードと展開(解凍)

Windows での手順を下に示す.Ubuntu でも同様の手順になる.

  1. Windows で,コマンドプロンプトを管理者として実行.
  2. celebA データセット用のディレクトリを作成
    mkdir %USERPROFILE%\dcgan-pytorch\data\celeba\img_align_celeba
    
  3. celebA データセットのダウンロード
    1. Web ブラウザで次の URL を開く

      http://mmlab.ie.cuhk.edu.hk/projects/CelebA.html

    2. 「Google Drive」をクリック
    3. 画面が変わる.「img」ディレクトリの下の「img_align_celeba.zip」を選ぶ
    4. メニューで「Download」を選ぶ
    5. ダウンロードしたいので,「無視してダウンロード (DOWNLOAD ANYWAY)」をクリック
    6. ダウンロードが始まるので確認する.
    7. ダウンロードしたファイルを展開(解凍)する.
      Windows での展開(解凍)に便利な 7-Zip: 別ページ »で説明
    8. 展開(解凍)してできたディレクトリ img_align_celeba を確認する.

      img_align_celeba の下に,多数の顔画像ファイルがあることを確認する.

    9. 顔画像ファイルを %USERPROFILE%\dcgan-pytorch\data\celeba\img_align_celeba の下に置く

    時間がかかるので待つ.

  4. celebA データセットの確認

    %USERPROFILE%\dcgan-pytorch の下の data の下の celeba の下の img_align_celeba の下に,多数の顔画像ファイルがあることを確認する.

    PyTorch の torchvision.datasets.ImageFolder は,指定したディレクトリの下にサブディレクトリがあることを前提とするため,画像ファイルは data\celeba\img_align_celeba のように,1階層下に置く必要がある.

celebA データセットを使って DCGAN を学習させる

Windows での手順を下に示す.Ubuntu でも同様の手順になる.

プログラムは,PyTorch 公式のDCGANチュートリアルのプログラムをもとにしている.

  1. 以下の操作をコマンドプロンプトで実行する (手順:Windows キーまたはスタートメニュー → cmd と入力 →「コマンドプロンプト」を選択).

  2. エディタを起動
    cd /d %USERPROFILE%\dcgan-pytorch
    notepad dcgan_celeba.py
    
  3. エディタで,次のプログラムを保存

    このプログラムは,celebA データセットを用いて DCGAN の学習を行い,学習途中の生成画像を output ディレクトリに保存する.学習には時間がかかるので待つ.

    import os
    import random
    import torch
    import torch.nn as nn
    import torch.optim as optim
    import torch.utils.data
    import torchvision.datasets as dset
    import torchvision.transforms as transforms
    import torchvision.utils as vutils
    
    # 前準備
    dataroot = "data/celeba"
    output_dir = "output"
    os.makedirs(output_dir, exist_ok=True)
    
    workers = 2
    batch_size = 128
    image_size = 64
    nc = 3          # 出力画像のチャンネル数(カラー画像は 3)
    nz = 100        # 潜在ベクトルの次元数
    ngf = 64        # Generator の特徴マップのサイズ
    ndf = 64        # Discriminator の特徴マップのサイズ
    num_epochs = 5
    lr = 0.0002
    beta1 = 0.5
    ngpu = 1
    
    manualSeed = 999
    random.seed(manualSeed)
    torch.manual_seed(manualSeed)
    
    device = torch.device("cuda:0" if (torch.cuda.is_available() and ngpu > 0) else "cpu")
    print("使用デバイス:", device)
    
    # データセットの読み込み
    dataset = dset.ImageFolder(root=dataroot, transform=transforms.Compose([
        transforms.Resize(image_size),
        transforms.CenterCrop(image_size),
        transforms.ToTensor(),
        transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
    ]))
    dataloader = torch.utils.data.DataLoader(dataset, batch_size=batch_size, shuffle=True, num_workers=workers)
    
    # 重み初期化
    def weights_init(m):
        classname = m.__class__.__name__
        if classname.find('Conv') != -1:
            nn.init.normal_(m.weight.data, 0.0, 0.02)
        elif classname.find('BatchNorm') != -1:
            nn.init.normal_(m.weight.data, 1.0, 0.02)
            nn.init.constant_(m.bias.data, 0)
    
    # Generator
    class Generator(nn.Module):
        def __init__(self, ngpu):
            super(Generator, self).__init__()
            self.ngpu = ngpu
            self.main = nn.Sequential(
                nn.ConvTranspose2d(nz, ngf * 8, 4, 1, 0, bias=False),
                nn.BatchNorm2d(ngf * 8),
                nn.ReLU(True),
                nn.ConvTranspose2d(ngf * 8, ngf * 4, 4, 2, 1, bias=False),
                nn.BatchNorm2d(ngf * 4),
                nn.ReLU(True),
                nn.ConvTranspose2d(ngf * 4, ngf * 2, 4, 2, 1, bias=False),
                nn.BatchNorm2d(ngf * 2),
                nn.ReLU(True),
                nn.ConvTranspose2d(ngf * 2, ngf, 4, 2, 1, bias=False),
                nn.BatchNorm2d(ngf),
                nn.ReLU(True),
                nn.ConvTranspose2d(ngf, nc, 4, 2, 1, bias=False),
                nn.Tanh()
            )
    
        def forward(self, input):
            return self.main(input)
    
    # Discriminator
    class Discriminator(nn.Module):
        def __init__(self, ngpu):
            super(Discriminator, self).__init__()
            self.ngpu = ngpu
            self.main = nn.Sequential(
                nn.Conv2d(nc, ndf, 4, 2, 1, bias=False),
                nn.LeakyReLU(0.2, inplace=True),
                nn.Conv2d(ndf, ndf * 2, 4, 2, 1, bias=False),
                nn.BatchNorm2d(ndf * 2),
                nn.LeakyReLU(0.2, inplace=True),
                nn.Conv2d(ndf * 2, ndf * 4, 4, 2, 1, bias=False),
                nn.BatchNorm2d(ndf * 4),
                nn.LeakyReLU(0.2, inplace=True),
                nn.Conv2d(ndf * 4, ndf * 8, 4, 2, 1, bias=False),
                nn.BatchNorm2d(ndf * 8),
                nn.LeakyReLU(0.2, inplace=True),
                nn.Conv2d(ndf * 8, 1, 4, 1, 0, bias=False),
                nn.Sigmoid()
            )
    
        def forward(self, input):
            return self.main(input)
    
    netG = Generator(ngpu).to(device)
    netG.apply(weights_init)
    
    netD = Discriminator(ngpu).to(device)
    netD.apply(weights_init)
    
    criterion = nn.BCELoss()
    fixed_noise = torch.randn(64, nz, 1, 1, device=device)
    real_label = 1.
    fake_label = 0.
    
    optimizerD = optim.Adam(netD.parameters(), lr=lr, betas=(beta1, 0.999))
    optimizerG = optim.Adam(netG.parameters(), lr=lr, betas=(beta1, 0.999))
    
    # 学習ループ
    print("学習を開始する")
    for epoch in range(num_epochs):
        for i, data in enumerate(dataloader, 0):
            # Discriminator の更新
            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)
            output = netD(real_cpu).view(-1)
            errD_real = criterion(output, label)
            errD_real.backward()
    
            noise = torch.randn(b_size, nz, 1, 1, device=device)
            fake = netG(noise)
            label.fill_(fake_label)
            output = netD(fake.detach()).view(-1)
            errD_fake = criterion(output, label)
            errD_fake.backward()
            errD = errD_real + errD_fake
            optimizerD.step()
    
            # Generator の更新
            netG.zero_grad()
            label.fill_(real_label)
            output = netD(fake).view(-1)
            errG = criterion(output, label)
            errG.backward()
            optimizerG.step()
    
            if i % 50 == 0:
                print('[%d/%d][%d/%d]\tLoss_D: %.4f\tLoss_G: %.4f' %
                      (epoch, num_epochs, i, len(dataloader), errD.item(), errG.item()))
    
        # 各エポック終了後に生成画像を保存
        with torch.no_grad():
            fake = netG(fixed_noise).detach().cpu()
        vutils.save_image(fake, os.path.join(output_dir, f'epoch_{epoch:03d}.png'), normalize=True)
    
    print("学習が終了した.生成画像は", output_dir, "の下に保存されている.")
    
  4. Python プログラムの実行
    cd /d %USERPROFILE%\dcgan-pytorch
    python dcgan_celeba.py
    
  5. 学習の終了の確認

    「学習が終了した」と表示されればよい.

  6. 結果の確認

    output ディレクトリの下に,各エポック終了時点の生成画像(epoch_000.png など)が保存されている.エポックを重ねるごとに,生成される顔画像が実際の顔らしくなっていく様子を確認できる.