はじめに
1年前に書いたのがこちら。
touch-sp.hatenablog.com
精度がでないので今回はGluonCVのGitHubで公開されているWGANを試してみる。
github.com
環境
Windows10 Pro NVIDIA GeForce GTX1080 CUDA 10.1 Python 3.6.8
バージョン
absl-py==0.7.1 certifi==2019.6.16 chardet==3.0.4 cycler==0.10.0 gluoncv==0.5.0b20190805 graphviz==0.8.4 grpcio==1.22.0 idna==2.6 kiwisolver==1.1.0 Markdown==3.1.1 matplotlib==3.1.1 mxboard==0.1.0 mxnet-cu101==1.6.0b20190805 numpy==1.16.4 Pillow==6.1.0 protobuf==3.9.1 pyparsing==2.4.2 python-dateutil==2.8.0 requests==2.18.4 scipy==1.3.0 six==1.12.0 tensorboard==1.14.0 tqdm==4.32.2 urllib3==1.22 Werkzeug==0.15.5
データの取得
import os import tarfile from mxnet.gluon import utils #Download the LWF Face Dataset lfw_url = 'http://vis-www.cs.umass.edu/lfw/lfw-deepfunneled.tgz' data_path = 'faces' if not os.path.exists(data_path): os.makedirs(data_path) data_file = utils.download(lfw_url) with tarfile.open(data_file) as f: f.extractall(path=data_path)
コードの書き換え
「train_wgan.py」488行目の「for epoch in range(opt.niter):」を「for epoch in range(1, opt.niter+1):」に変更する。
「train_wgan.py」の最後にある「save_params」を「save_parameters」に変更する。
その後実行
python train_wgan.py --dataset lfw --dataroot faces/lfw-deepfunneled --cuda --niter 1000
オリジナル画像
上記学習を実行すると勝手に並べた画像を作ってくれる。
結果1
オリジナル画像同様勝手に並べた画像を作ってくれる。
- 800 epoch
- 1000 epoch
1000エポックまでに約3時間かかった。
おそらく1000エポックではまだまだ少ないと思われる。
追加実験1
最初に人物をSemantic Segmentationで切り抜いておくと結果は変わるのか?
実際に試してみた。
import numpy as np from PIL import Image import mxnet as mx from mxnet import image from mxnet.gluon.data.vision import transforms import gluoncv import glob import os ctx = mx.gpu() #データの正規化 transform_fn = transforms.Compose([ transforms.ToTensor(), transforms.Normalize([.485, .456, .406], [.229, .224, .225]) ]) #モデルを読み込む #初回時に(default)/.mxnet/modelsに保存される #2回目以降はそこから読み込む model= gluoncv.model_zoo.get_model('deeplab_resnet152_voc', pretrained=True) model.collect_params().reset_ctx(ctx) img_list = glob.glob('wgan/faces/lfw-deepfunneled/*/*.jpg') out_dir = 'post_faces/face' for i, filename in enumerate(img_list): #画像をNDArryで読み込む img = image.imread(filename) img = transform_fn(img) img = img.expand_dims(0).as_in_context(ctx) #モデルの適応 #人たけを抽出する(class:15) output = model.predict(img) predict = mx.nd.squeeze(mx.nd.argmax(output, 1)).asnumpy() index = np.where(predict !=15) #画像を改めて読み込み、結果と重ね合わせる img = image.imread(filename).asnumpy() img[:,:,0][index] = 255 img[:,:,1][index] = 255 img[:,:,2][index] = 255 save_img = Image.fromarray(img) save_filename = os.path.join(out_dir, '%d.jpg'%i) save_img.save(save_filename)
結果-追加実験1
- オリジナル画像
一部人物の切り抜きに失敗している(真っ白の画像)。
構わずWGANに突っ込んでみた。
- 1000 epoch
1000エポックまででは大して変わらないと思われる。
ひいき目に見て少し良いような気もする。
さらに学習を進めるとどうなるか?
追加実験2
人物が二人以上写りこんだ写真を除外すれば結果は改善するか?
- 除外された写真の一部
正確性に欠けるが良しとする。
分け方はこちらを参照。
import glob import random import mxnet as mx from mxnet import image from matplotlib import pyplot as plt img_list_all = glob.glob('persons/*.jpg') random.shuffle(img_list_all) img_list = img_list_all[0:16] row = 4 col = 4 array_list = [image.imread(x) for x in img_list] row_list = [] for i in range(row): row_list.append(mx.nd.concat(*array_list[i*col:(i+1)*col], dim = 1)) final = mx.nd.concat(*row_list, dim=0) plt.imshow(final.asnumpy()) plt.axis('off') plt.show()
結果-追加実験2
- オリジナル画像
- 1000 epoch
追加実験3
「追加実験2」→「追加実験1」の順で前処理を行ってみた。