くろたんくブログ

Practice Makes Permanent

このエントリーをはてなブックマークに追加

2019年 11月 10日 日曜日 18:43:24 JST(modified: 2019年 11月 10日 日曜日 18:45:49 JST)
views: 450, keywords: tech, StyleGAN

イラストで学習したStyleGANを試した

数年前にイラストのGANで可愛い子を作るのに挑戦したが64x64でも大変で、まだまだデータセットもモデルもイケてない時代だったけど
今年の頭にStyleGANが出てきたこと、Danbooruのセットが充実してきたこと、さらには学習済みモデルがupされているのでとりあえず試すのが気軽にできるのでやってみた

  • モデル:Gwern氏作成の30_Apr_2019モデル(ここのGwernさんのHPにある)
  • 𝛙=0.7

基本、ノイズのガチャ感満載だけど、512x512でここまでの画像が生成できる

この投稿をInstagramで見る

飽きないなー #StyleGAN #Danbooru

くろたんく(@black_tank_top)がシェアした投稿 -

この投稿をInstagramで見る

かわいい #StyleGAN #Danbooru

くろたんく(@black_tank_top)がシェアした投稿 -

学習済みモデルは用意しておく
自身のデータセットで学習したい時は、ここを参考にするとよい。非常にお金と時間がかかるので注意
モデルができたら

# 初期化とロード
        rnd = np.random.RandomState(10)
        
        tflib.init_tf()
        with open(model.pkl, 'rb') as f:
            _G, _D, Gs = pickle.load(f)

あとで潜在変数を使える処理と、画像は連番で保存

# 生成
        for i in range(100):
            latents = rnd.randn(1, Gs.input_shape[1])
            if i == 0:
                latents_tmp = latents
            else:
                latents_tmp = np.vstack([latents_tmp, latents])
            fmt = dict(func=tflib.convert_images_to_uint8, nchw_to_nhwc=True)
            images = Gs.run(latents, None, truncation_psi=0.7, randomize_noise=True, output_transform=fmt)
            os.makedirs('results', exist_ok=True)
            # あとでgifやmp4にするために連番振っておく
            png_filename = os.path.join('results', 'photo'+'{0:04d}'.format(i)+'.png')
            PIL.Image.fromarray(images[0], 'RGB').save(png_filename)

こういう画像が生成される

さらに、各潜在変数のベクトルの差を20分割して元の画像に足すことで遷移させる

num_split = 19
        for i in range(len(success_latents) - 1):
            print("i: ", i)
            latents_a = success_latents[i].reshape(1, -1)
            latents_b = success_latents[i + 1].reshape(1, -1)
            for j in range(num_split + 1):
                print("j: ", j)
                latents = latents_a + (latents_b - latents_a) * j / num_split
        
               
                fmt = dict(func=tflib.convert_images_to_uint8, nchw_to_nhwc=True)
                images = Gs.run(latents, None, truncation_psi=0.7, randomize_noise=True, output_transform=fmt)
        
               
                os.makedirs('results', exist_ok=True)
                png_filename = os.path.join('results', 'photo'+'{0:04d}'.format(i * 20 + j)+'.png')
                PIL.Image.fromarray(images[0], 'RGB').save(png_filename)

あとはGIFやmp4にすると遷移が見やすい

# GIF
        files = sorted(glob.glob('results/*.png'))
        images = list(map(lambda file: PIL.Image.open(file).resize([512, 512]), files))
        images[0].save('success_animation.gif', save_all=True,
                       append_images=images[1:],
                       duration=100, loop=0)
# mp4
        import os
        import cv2
        import numpy as np
        
        IMG_SIZE   = 512
        img_outdir = './results'
        os.makedirs(img_outdir, exist_ok=True)
        
        fourcc = cv2.VideoWriter_fourcc(*'MP4V')
        video  = cv2.VideoWriter('success_animation_' + str(IMG_SIZE) + '.mp4', fourcc, 10, (IMG_SIZE, IMG_SIZE))
        
        files = sorted(glob.glob('results/*.png'))
        
        for i in files:
            img = cv2.imread(i)
            if img is None:
                break
            video.write(img)
        video.release()

StyleGANがすごいのは、こういった生成画像の潜在変数のベクトルの差分を細かく遷移させても自然な変化をする

この投稿をInstagramで見る

モーフィング #StyleGAN

くろたんく(@black_tank_top)がシェアした投稿 -

なかなか楽しい

prev:データ分析について next:簿記検定試験