を実際に回してみようかなと思って Colab 上で実行してみる。MNIST か・・・とは思うのだが、それは置いておいて・・・。gan/gan.py を実行してみると、25 分で 90 epochs 程度。デフォルトで 200 epochs になっているので単純に考えると 55 分くらいになるようだ。意外とかかるな・・・。と思ったら 41 分で終わった。後で調べると Tesla T4
が割り当たっていた。
ま、数字っぽいっちゃそうかな・・・。1
が多いな。とりあえず縦線を生成したら識別器を騙せるって学習しちゃったのかな・・・。CycleGAN 公式コード - らんだむな記憶 で horse2zebra で 36 時間くらいかかりそうって見積もりなので、それに比べたらマシだけど、このくらいか。仕方ない。他の GAN 回す時も大体丸 1〜2 日は回すから仕方ない・・・。
cgan/cgan.py も回してみる。56 分だった。
... [Epoch 199/200] [Batch 933/938] [D loss: 0.048059] [G loss: 0.842562] [Epoch 199/200] [Batch 934/938] [D loss: 0.066721] [G loss: 0.758612] [Epoch 199/200] [Batch 935/938] [D loss: 0.083642] [G loss: 0.996319] [Epoch 199/200] [Batch 936/938] [D loss: 0.186943] [G loss: 0.325044] [Epoch 199/200] [Batch 937/938] [D loss: 0.255771] [G loss: 1.110740]
最後のほうだけ見ても D loss と G loss が行ったり来たりしているようだ。
! cd images && cp $(ls | sort -n | tail -5 | tr '\n' ' ') /content/drive/MyDrive/'Colab Notebooks'/CGAN
こんな感じで最後の 5 枚の画像を保存してみる。
相変わらずガウス分布に従うノイズを潜在表現として画像を生成しているだけなのに、ラベル情報を結合するだけでこれほど変化するのは驚きだ。
import numpy as np import torch import torch.nn as nn from torch.autograd import Variable cuda = True if torch.cuda.is_available() else False FloatTensor = torch.cuda.FloatTensor if cuda else torch.FloatTensor LongTensor = torch.cuda.LongTensor if cuda else torch.LongTensor batch_size = 16 latent_dim = 100 n_classes = 10 n_row = 10 labels = np.array([num for _ in range(n_row) for num in range(n_row)])[:batch_size] labels = Variable(LongTensor(labels)) label_emb = nn.Embedding(10, 10) label_emb.cuda() z = Variable(FloatTensor(np.random.normal(0, 1, (batch_size, latent_dim)))) gen_input = torch.cat((label_emb(labels), z), -1) print(z.shape, labels.shape, label_emb(labels).shape, gen_input.shape)
で
torch.Size([16, 100]) torch.Size([16]) torch.Size([16, 10]) torch.Size([16, 110])
なので本当にノイズの末尾にラベル埋め込みを結合しているだけだと言うのに。