AIファンタジー

最新のAIが作成した「ファンタジーの作品」を 88,888枚 調査及び評価用に公開しています。
※ブラウザの横幅は1024px以上が必要です。左側がサムネイル、右側に画像が表示されます。(パソコン推奨)

  



このサイトは Takeshi Okamoto が運営する「おもちゃのAI研究室」の分室です。

これらのファンタジーの作品はNVIDIAが2020年10月に公開した「StyleGAN2-ADA」を利用した成果物です。ここで公開されている画像のライセンスには「Nvidiaソースコードライセンス」(英語)が適用されます。

人工知能(AI)はNVIDIAの「GeForce GTX 1080 Ti」(11GB)を使用して35時間、学習させました。AIに喰わせた「1500枚」の元画像のライセンスは著作権表示なし、再配布が許諾されているものです。入手先は非公開とさせて頂きます。通常、GAN(敵対的生成ネットワーク)では5万枚から10万枚の画像が必要ですがNVIDIAによると「StyleGAN2-ADA」で1500枚にも満たない小規模なデータセットで「成功した事例」があるようなので1500枚にしています。

TensorFlowやPyTorchなどで機械学習、ディープラーニング(深層学習)の勉強を行いたくてもNVIDIAの高性能グラフィックボード(GPU)を持ち合わせていない方は、Googleが運営する「Colaboratory Pro」(2021年3月26日に日本でサービス開始)を使用すれば月額1072円で約80万円の「NVIDIA Tesla P100」(16GB)などを使用できます。Pythonの「Jupyter Notebook」のように気軽に高速なGPUでAIを学習できます。

※このページは画像ファイルの転送量の問題があるのでメインサーバーではなくレンタルサーバーで稼働させています( ゚Д゚)

StyleGAN2-ADAの使い方

データセット(画像ファイル)を準備して、それらをTFレコードファイルに変換してトレーニングをするだけです。

Colab Proを使用する方はColab Proの使い方。WindowsでGPUがある方はWindowsでTensorFlow(GPU)の環境を構築するを先にご参照ください。

次はWindowsの場合ですが、Linux(Ubuntu)などでも同様な手順となります。 ※WindowsはTensorFlow 1.14.0です。

// カレントディレクトリ ※各自の環境に合わせる
cd C:\Users\xxx\Desktop\stylegan2-ada

// 「D:\images」にある複数の画像ファイルから「.\datasets\custom\」にTFレコードファイルを作成します。 
python dataset_tool.py create_from_images ./datasets/custom/ d:/images

// 初回トレーニング
python train.py --outdir=C:/Users/xxx/Desktop/stylegan2-ada/output --gpus=1 ^
--data=C:/Users/xxx/Desktop/stylegan2-ada/datasets/custom/ --snap=5 ^
--resume=C:/Users/xxx/Desktop/stylegan2-ada/ffhq-res256-mirror-paper256-noaug.pkl --metrics=none

// (2回目以降)前回のトレーニングの続きを実行する
python train.py --outdir=C:/Users/xxx/Desktop/stylegan2-ada/output --gpus=1 ^
--data=C:/Users/xxx/Desktop/stylegan2-ada/datasets/custom/ --snap=5 ^
--resume=network-snapshot-??????.pkl --metrics=none

データセットの全ての画像サイズは統一する必要があります。256x256、512x512、1024x1024など。「--outdir」はモデルなどの出力先です。「--gpus」はGPUの個数。「--data」はTFレコードファイルのパス。「--snap」はトレーニングの「tick」がその回数になればモデルの保存と確認用の画像が自動で生成されます。データセット1500枚で512x512、snapが5の場合はGPU(11GB)で1時間20分くらいです。目安にして下さい。「--resume」はトレーニングの再開です。初回トレーニングは「転移学習」(この例ではffhq256を利用)を用いれば非常に高速な収束をもたらす傾向があります。train.pyのソースコード内の「ffhq256、ffhq512、ffhq1024、celebahq256、lsundog256」(事前訓練済みモデル)を確認してください。末尾の数値が画像サイズとなっています。Windowsの場合は前述の事前訓練済みモデルを「手動」でダウンロードする必要があります。例えば、ffhq256の場合は「https://nvlabs-fi-cdn.nvidia.com/stylegan2-ada/pretrained/transfer-learning-source-nets/ffhq-res256-mirror-paper256-noaug.pkl」をブラウザで実行すると手動でダウンロードできます。転移学習を使用しないで新規に学習させる場合は「--resume」は不要です。その代わり長時間の学習時間が必要となります。私が試した所、新規作成したモデルが出力する画像サイズはTFレコードファイル(データセット)の画像サイズと同じになるようです。512x512のデータセットならば512になっています。「--metrics」のnoneはFIDの自動計算を無効にしています。これによりトレーニングが高速になります。

次は「学習済みモデル」(*.pkl)で画像ファイルを生成する方法です。

// 画像ファイルを「D:\output」に10枚、生成する
python generate.py --outdir=d:/output/ --trunc=0.8 --seeds=1-10 ^
--network=network-snapshot-??????.pkl

「--outdir」は出力先。「--trunc」は創造度(?)で0.3から2.0ぐらいです。0.8が無難だと思います。「--seeds」の1-10とは1から10の画像を出力します。使い方はgenerate.pyにコメントでいくつかの例があります。「--network」は学習済みモデル(*.pkl)です。私は進捗状況のプログレスバーなどの設定をしたかったので、このコマンドは使用してないです。generate.pyのgenerate_images()がメイン関数なのでそれを書き換えると良いです。seedsに関しては「0から4294967295」(42億種類)の範囲。truncは「0.3から2.0」(0.3/0.4/0.5 ... 1.8/1.9/2.0の0.1毎がベスト)なので、ほぼ無限の画像が作成できます。

ついでなので、私が88,888枚の画像を作成したコードも記載しておきます。リファクタリングをしてないので各自で調整して下さい。

次のコードを「Jupyter Notebook」で実行するとtqdmが進捗状況をプログレスバーで表示します。

# 元のコード
# https://github.com/NVlabs/stylegan2-ada/blob/main/generate.py

# Copyright (c) 2020, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.

import argparse
import os
import pickle
import re

import numpy as np
import PIL.Image

import dnnlib
import dnnlib.tflib as tflib

def generate_images(network_pkl, truncation_psi, outdir, class_idx, dlatents_npz):
    tflib.init_tf()
    print('Loading networks from "%s"...' % network_pkl)
    with dnnlib.util.open_url(network_pkl) as fp:
        _G, _D, Gs = pickle.load(fp)

    os.makedirs(outdir, exist_ok=True)

    # Render images for a given dlatent vector.
    if dlatents_npz is not None:
        print(f'Generating images from dlatents file "{dlatents_npz}"')
        dlatents = np.load(dlatents_npz)['dlatents']
        assert dlatents.shape[1:] == (18, 512) # [N, 18, 512]
        imgs = Gs.components.synthesis.run(dlatents, output_transform=dict(func=tflib.convert_images_to_uint8, nchw_to_nhwc=True))
        for i, img in enumerate(imgs):
            fname = f'{outdir}/dlatent{i:02d}.png'
            print (f'Saved {fname}')
            PIL.Image.fromarray(img, 'RGB').save(fname)
        return

    # Render images for dlatents initialized from random seeds.
    Gs_kwargs = {
        'output_transform': dict(func=tflib.convert_images_to_uint8, nchw_to_nhwc=True),
        'randomize_noise': False
    }
    if truncation_psi is not None:
        Gs_kwargs['truncation_psi'] = truncation_psi

    noise_vars = [var for name, var in Gs.components.synthesis.vars.items() if name.startswith('noise')]
    label = np.zeros([1] + Gs.input_shapes[1][1:])
    if class_idx is not None:
        label[:, class_idx] = 1
    
    # ココから変更
    import random
    from tqdm import tqdm # プログレスバー
    
    seeds = []
    for i in range(88888):
        seeds.append(
            random.randint(0, 4294967295)
        )
    
    for i, seed in enumerate(tqdm(seeds)):
        rnd = np.random.RandomState(seed)
        z = rnd.randn(1, *Gs.input_shape[1:]) # [minibatch, component]
        tflib.set_vars({var: rnd.randn(*var.shape.as_list()) for var in noise_vars}) # [height, width]
        images = Gs.run(z, label, **Gs_kwargs) # [minibatch, height, width, channel]
        
        image = PIL.Image.fromarray(images[0], 'RGB')
        # 512x512 ※ココのサイズはモデルによって異なる
        image.save(f'{outdir}/raw/'+ str(i+1)+'.jpg')
        # 64x64
        image.resize((64,64)).save(f'{outdir}/thumbnail/'+ str(i+1)+'.jpg')

# 実行        
outdir ='d:/output/images/'
trunc=0.8
network_pkl='network-snapshot-??????.pkl'
generate_images(network_pkl=network_pkl,outdir=outdir,truncation_psi=trunc,
                class_idx=None,dlatents_npz=None)

generate.pyの標準だとPNGで保存されますが、このコードだと512x512と64x64の2枚のJPEGファイルで保存しています。

ダウンロード

調査、評価用に「学習済みモデル」(*.pkl)をダウンロードできます。

network-snapshot-000472.pkl ここで使用しているAIモデル(データセットA 1500枚)
network-snapshot-000400.pkl ここで未使用のAIモデル(データセットB 2000枚)
network-snapshot-001648.pkl ここで未使用のAIモデル(データセットB 2000枚)

未使用のAIモデルはデータセットが異なります。出力されるファンタジー画像はある意味、芸術的です。未使用は2つありますがデータセットは同一で単に訓練数が異なるだけです。kimg400、kimg1648となっています。ファンタジーの画像もダウンロード可能(4.5MB)ですが、上述のようにライセンスには「Nvidiaソースコードライセンス」が適用されます。