chainerで画像分類をする
Google Colabolatory上でchainerを用いて画像分類をしました。
ランタイムタイプをGPUにします。
準備
Colaboratoryにインストールされているcudaのバージョンを見て、自動的に適切なCuPyをインストールします。
下図のようなmnist_012フォルダを使いました。0、1、2フォルダ内にはそれぞれサイズが28×28で0、1、2が書かれた画像が入っています。
zipにしてColaboratoryにアップロードした後unzipします。
!unzip mnist_012 |
他に必要そうなものもインストールします。
!pip install -U numpy |
pip install chainercv |
画像ファイルをデータセットとして読み込む
%matplotlib inline import matplotlib.pyplot as plt import numpy as np import chainer from PIL import Image from chainer import cuda, Function, gradient_check, report, training, utils, Variable from chainer import datasets, iterators, optimizers, serializers from chainer import Link, Chain, ChainList from chainercv import transforms from chainercv.datasets import DirectoryParsingLabelDataset from chainer import training from chainer.training import extensions from chainer import serializers from numpy import random
# mnist_012フォルダから画像ファイルとラベル(mnist_012内のディレクトリ名)を読み込む dataset = DirectoryParsingLabelDataset('mnist_012')
# 各画像のパスを表示 print(dataset.img_paths) # 各画像のラベルを表示 print(dataset.labels) |
それぞれ以下のように表示されると思います。
# 各画像のパスを表示
print(dataset.img_paths)
# 各画像のラベルを表示
print(dataset.labels)
次にimageという名前のリストに画像をnumpy配列にしたものをアペンド(追加)していきます。
image = [] for i in dataset.img_paths: image.append(np.array(Image.open(i),dtype=np.float32)) |
- 並び順: (color,x,y)という並び順。今回は28×28で白黒画像(1チャンネル)なので(28,28)。3色であれば、(3,28,28)となる。
- データ型: 0~1のfloat32型で定義しておかないとChainerがエラーを吐く。
chainerは学習の際、( [画像(numpy形式) , 正解ラベル] )のような「画像と正解ラベルのリスト」をタプルで並べた形にする必要があります。
from sklearn.model_selection import train_test_split # train(学習用データ)とtest(検証データ)に分割 X_train, X_test, y_train, y_test = train_test_split(image,dataset.labels) # trainデータを( [画像(numpy形式) , 正解ラベル] )の形にする train = [(x,y) for x,y in zip(X_train, y_train)] # testデータを( [画像(numpy形式) , 正解ラベル] )の形にする test = [(x,y) for x,y in zip(X_test, y_test)] |
学習
あとはモデルを書いて実行します。
import chainer.functions as F import chainer.links as L
class NN(Chain): def __init__(self, n_in, n_units, n_out): super(NN, self).__init__() with self.init_scope(): self.l1 = L.Linear(n_in, n_units) self.l2 = L.Linear(n_units, n_units) self.l3 = L.Linear(n_units, n_out)
def __call__(self, x): h1 = F.relu(self.l1(x)) h2 = F.relu(self.l2(h1)) return self.l3(h2)
############# gpu_device = 0 epoch = 30 batch_size = 512 frequency = -1 n_in = 784 # 28×28=784なので入力を784にする n_units = 100 n_out = 3 # 今回正解ラベルの種類は3種類なので3にする #############
model = L.Classifier(NN(n_in, n_units, n_out)) chainer.cuda.get_device_from_id(0) model.to_gpu()
optimizer = chainer.optimizers.Adam() optimizer.setup(model)
train_iter = chainer.iterators.SerialIterator(train, batch_size) test_iter = chainer.iterators.SerialIterator(test, batch_size, repeat=False, shuffle=False)
updater = training.StandardUpdater(train_iter, optimizer, device=gpu_device) trainer = training.Trainer(updater, (epoch, 'epoch'))
trainer.extend(extensions.Evaluator(test_iter, model,device=gpu_device)) trainer.extend(extensions.dump_graph('main/loss'))
frequency = epoch if frequency == -1 else max(1, frequency) trainer.extend(extensions.snapshot(), trigger=(frequency, 'epoch')) trainer.extend(extensions.LogReport()) trainer.extend( extensions.PlotReport(['main/loss', 'validation/main/loss'], 'epoch', file_name='loss.png')) trainer.extend( extensions.PlotReport(['main/accuracy', 'validation/main/accuracy'], 'epoch', file_name='accuracy.png')) trainer.extend(extensions.PrintReport( ['epoch', 'main/loss', 'validation/main/loss', 'main/accuracy', 'validation/main/accuracy', 'elapsed_time']))
trainer.run() |
最終的に精度が90%以上いくと思います。
結果を用いて分類する
実際に分類してみたいと思います。
このモデルの重みをnpz形式で保存します。
serializers.save_npz("mymodel.npz", model) |
保存した重みnpzを読み込みます。
test_model = L.Classifier(NN(n_in, n_units, n_out)) serializers.load_npz("mymodel.npz", test_model) |
test[30][0]に正解ラベルが1の画像があります。これを予測してみます。
# (チャンネル数,Widtth,Height) test_model.predictor(test[30][0].reshape(1,28,28)) |
どうやら1と予測されたようです。
「キャラ塗り上達術決定版」読んでお絵描きした(本のレビュー的な)
お勉強本
「プロ絵師の技を完全マスター キャラ塗り上達術 決定版 CLIP STUDIO PAINT PRO/EX 対応」という本を買って塗りのお勉強をしました。
なんとこの本描き方だけでなく
- レイヤー別完成イラスト
- カスタムカラーセット
- カスタムブラシ
- 練習用線画
のDL特典までついてくる素晴らしい本です。
今まで読んできた塗りの本は
- どんなブラシを使っているのか
- どんなレイヤー構成なのか
- どんな色を選んでいるのか
という指定があまりなく、ただただ作業工程だけを見つめるものがほとんどだった気がします(初心者視点です)。
ですがこの本はそれらをすべて指定して教えてくれるので非常に分かりやすいです。
実際に描いてみる
試しに青紅さんの水彩+厚塗りに挑戦してみました。
(背景はCLIP STUDIO PAINTブラシ素材集 雲から街並み、質感までを使って描いてます)
まずは本に書いてある内容をざっと読んで全体の流れをつかみ、実際に描きながら本とDL特典のレイヤーを同時に確認すると良いと思います。
対象は?
本書に書いてある通りソフト(clip studio paint pro)の基本操作が分かっている人が対象で、最低限カラーイラストを1枚描けるレベルでないと理解できないかなと思いました(といってもクリッピングとか合成レイヤーって何ですかレベルの知識でそこまで敷居の高い基礎知識は必要ないかも)。
基礎知識は以下の2つの参考書が分かりやすいかなと思います(どちらかでいい)。
この本で初心者から中級者へステップアップできるよう頑張ろうと思います。
VAEによる異常検知(マハラノビス距離編)
前回の続きでここではmnistの「1」という数字以外(今回は「9」)の画像に対し異常検知するプログラムで説明していきます。
今回の実装では以上のgithubと、以下のサイトを参考にして実装しました。
VariationalAutoencoderRunner.pyの
X_train, X_test = min_max_scale(mnist.train.images, mnist.test.images)
直下に以下のコードを追加します。
VariationalAutoencoder.pyの最後に以下のコードを追加します。
# インポートと結果画像の保存先指定 %matplotlib inline import matplotlib.pyplot as plt import numpy as np import os
# テストデータを「1」だけにする xx1, yy1 , zz1 = ,, aa=np.array([0,1,0,0,0,0,0,0,0,0]) #「1」のラベル bb=np.array([0,0,0,0,0,0,0,0,0,1]) #「9」のラベル for i in range(len(X_test)): if (y[i] == aa).all(): xx1.append(X_test[i]) yy1.append(y) xx1 = np.array(xx1) yy1 = np.array(yy1)
# テストデータを「9」だけにする xx9, yy9 , zz9 = ,, for i in range(len(X_test)): if (y[i] == bb).all(): xx9.append(X_test[i]) yy9.append(y[i]) xx9 = np.array(xx9) yy9 = np.array(yy9)
# テスト画像「1」と「9」をそれぞれエンコードする dxx1 = autoencoder.transform(xx1) dxx9 = autoencoder.transform(xx9)
# 「1」からのマハラノビス距離をそれぞれ計算する #calculate mahalanobis distance from scipy.spatial.distance import mahalanobis
# calculate covariance matrix for training data sigma = np.cov(dxx1, rowvar=False)
# make inverse of it inv_sigma = np.linalg.inv(np.cov(dxx1, rowvar=False))
# calculate mean for training data mean = np.mean(dxx1, axis=0)
# calculate mahalanobis distances outlier_dists = [mahalanobis(mean, outlier, inv_sigma) for outlier in dxx9] inlier_dists = [mahalanobis(mean, inlier, inv_sigma) for inlier in dxx1]
average_outlier_dist = np.mean(outlier_dists) average_inlier_dist = np.mean(inlier_dists) print('average_outlier_dist', average_outlier_dist) print('average_inlier_dist', average_inlier_dist) print(sigma)
# マハラノビス距離を用いて閾値を決定する THRESHOLD = 0 N_OUTLIERS=len(outlier_dists) N_INLIERS=len(inlier_dists) print(N_OUTLIERS) print(N_INLIERS) thr= f_value= rec= pre= r=0 b=0 for i in range(100): threshold = THRESHOLD + 0.5 * i for a in range(N_OUTLIERS): if outlier_dists[a] > threshold: r=r+1 for a in range(len(inlier_dists)): if inlier_dists[a] > threshold: b=b+1 # the number of predicted outliers n = r + b print("{}回目".format(i+1)) print("n={}".format(n))
precision = r / n recall = r / N_OUTLIERS f = 2 * precision * recall / (precision + recall) # print('thr={},f={},p={},r={}'.format(threshold, f, precision, recall)) print('{} {} {} {}\n'.format(threshold, f, precision, recall)) thr.append(threshold) f_value.append(f) rec.append(recall) pre.append(precision) r=0 b=0
# display F values plt.figure(figsize=(10, 5)) thrs = prs = res = [] plt.xlabel('threshold', fontsize=20) plt.plot(thr, rec, marker='.', label='Recall') plt.plot(thr, f_value, marker='.', label='F value') plt.plot(thr, pre, marker='.', label='Precision')
plt.legend(loc='best') plt.show()
max=np.argmax(f_value) print("thresholdの値が {} のとき".format(round(thr[max],2))) print("F_valueは最大値 {} をとる".format(round(f_value[max],3))) print("このときPrecisionは{}、Recallは{}である。".format(pre[max],rec[max]))
# 閾値を用いて異常検知をする from numpy.random import * plt.figure(figsize=(12, 4)) k=randint(200) batch_xs = X_test[k] batch_xsd=autoencoder.transform(batch_xs.reshape([1,784])) ax = plt.subplot(2, 2, 1) plt.imshow(batch_xs.reshape(28, 28)) plt.gray() ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) mah=mahalanobis(mean, batch_xsd, inv_sigma) print("マハラノビス距離:" + str(mah)) if mah > thr[max]: print('1ではない(異常)') else: print('1である(正常)') |
まったく同じ結果にはなりませんが閾値とそのときのF値などがでます。
最後にテスト画像(「1」か「9」)からランダムに1枚選び検知するようにしました。
以下がそのときの結果です。今回の場合マハラノビス距離が上で求められた閾値17.5以下の場合正常、17.5以上の場合異常と判断するようになっています。
マハラノビス距離を用いた異常検知
参考に「1」と「9」のマハラノビス距離の分布を示すと以下のようになっています。
直観的にも17.5付近でうまく分けることができることが期待できます。
pix2pixについてまとめた
pix2pixについて論文と各サイトを自分用にまとめました。詳しい説明は論文と各サイトを見ることをおすすめします。
論文
https://arxiv.org/pdf/1611.07004v1.pdf
引用・参考サイト
https://qiita.com/miyamotok0105/items/8ed0a8943f5318e826e0
https://qiita.com/mine820/items/36ffc3c0aea0b98027fd
https://www.wantedly.com/companies/xcompass/post_articles/76117
https://www.slideshare.net/motonari728/pix2pix-87334394?next_slideshow=1
https://spjai.com/pix2pix-image-generation/#pix2pix
https://qiita.com/knok/items/4cfa2f9ca06b57cb233b
どんなもの?
pix2pixとは、GANを利用した画像生成アルゴリズムの一種で、2つのペアの画像から画像間の関係を学習することで、1枚の画像からその関係を考慮した補間をしてペアの画像を生成する技術です。
先行研究と比べてどこがすごい?
2つの画像のペアを与えるだけで似たような画像加工を全自動で行ってくれるところである。pix2pixは他のGANとは扱うタスクが異なります。
大体のGANは画像の生成タスクに用いられますが、pix2pixは画像の変換タスクが対象という点で立ち位置が大きく異なります。
pix2pixは変換前画像と変換後画像をペアとしてDiscriminatorに入力し、Discriminatorは本物同士のペアかを判定します(一般的なGANはDiscriminatorが本物かどうかを判定します)。
つまり、学習データに含まれている (変換元画像, 変換先画像) というペアなのか、 (変換元画像, 変換元画像からGeneratorが生成した画像) のペアなのかという判断を下すようになっています。
技術や手法のキモはどこ?
モデルはConditional GANになっていて、入力画像はGとDの両方に与えられます。また、通常Gはノイズをサンプルしますが、このモデルでは直接ノイズをサンプルするのではなく、複数の層に渡ってドロップアウトという形でノイズを入れるようにしています。ドロップアウトは普通学習時だけに入れるものですが、このモデルではテスト時にも入れるようになっています。
つまり一般的なGANとは違い、Generatorにノイズではなく画像を入れる。
学習とテスト時にドロップアウトを入れることでノイズとしています。
また、基本方針はDCGAN ( Conv – BatchNorm - ReLu ) 採用しています。
Generator
生成ネットワーク(Generator)はEncoder-Decoderモデルとなっています。入力画像を低次元ベクトルに埋め込み、期待する出力へと復元する構造です。
エンコーダ・デコーダ間の同じ階層同士を直接繋げるskip connectionを持ったU-Netという構造を用いています。
skip connectionをもたせることによって、中間層同士の特徴を直に伝播させ、細部の復元を忠実に行うことができるようになるようです(共通の特徴量におけるデータ欠損を回避する)。
単純に生成画像だけを用いて真贋判定を行うのではなく、入力画像とペアで判定をさせます。
これによってDiscriminatorは2つの画像間の関係性の特徴を学習することになります。
さらにこの結果はU-Net側の学習にも反映されます。
pix2pixではよりリアルな画像を生成するために、目的関数へのL1正則化項の追加と、PatchGANと呼ばれる仕組みの導入を行っています。L1正則化項は、変換先画像とGeneratorが生成した画像がピクセル単位でどれくらい違っているかということを表しており、これを最小化するということは、ピクセル単位で正解画像に近いような画像を生成するようになるということです。これにより、Discriminatorによって大域的な正しさを判定しつつ、L1正則化でピクセル単位での正しさも勘案する、ということが可能になります。
PatchGANは、Discriminatorに画像を与える際に、画像すべてではなく、16x16や70x70といった小領域(=Patch)を切り出してから与えるようにするという仕組みです。
これにより、ある程度大域的な判定を残しながらも学習パラメータ数を削減することができ、より効率的に学習することができるそうです。
小さい領域で本物/偽物を評価することで狙っていた高周波成分の特徴をとらえているようです。
これはcGANモデルにL1モデルを組み込むことで、大雑把な画像をL1で捉え、cGANがその詳細を捉えるという方法です。L1による画像生成だけでは細部がぼやけ、cGANのみの画像生成だけではDiscriminatorを騙すための違和感が生じてしまうので、これらを組み合わせることで互いの得意な作業を使い分け、精度を向上させます。
論文だと70×70patchが良いとされている。
低周波成分の学習は生成画像と訓練画像とのL1ノルムを求めることにより得ている。論文の中で実験的に確かめられています。
以上のことをまとめると最終的な目的関数は以下のようになります。
どうやって有効だと検証した?
まずはEncoder-decoderとU-Netの比較から。
図よりEncoder-decoderだと写真の基本構造がぼやけてしまっている一方で、U-Netを用いることで写真の基本構造を維持できていることがわかります。やはりEncoder-decoderでは共通の特徴量が欠損しています。
次にL1/cGAN/L1+cGANの比較です。
図からL1だけではかなり画像がぼやけていていることがわかります。
またcGANだけのときも、一見上手く生成できているように思えますが、よく見てみると一部違和感のある部分があります。こうして横並びで比較してみるとL1+cGANが一番上手く生成できていることがよくわかります。
議論はある?
図は地図と航空写真間の生成結果でpix2pixでは地図から航空写真のような一方向ではなく、両方向に生成可能という点で汎用性がかなり高いと考えられます。また、この実験では学習時のPatchサイズと実験時のPatchサイズを変えており、それでも尚このような精度の高い結果が生じています。一方で、このモデルは地図から航空写真のような単純な画像から複雑な画像の生成は得意なのですが、航空写真から地図のような複雑な画像から単純な画像の生成ではL1に劣ることもあります。
次に読むべき論文は?
調べてたらCycleGANとDCGANというものが出てきたので余裕ができたら読みたいと思います。
CGANについてまとめた
CGANについてまとめました。詳しい解説は引用・参考サイトを見ることをおすすめします。
論文
https://arxiv.org/pdf/1411.1784.pdf
引用・参考サイト
https://qiita.com/triwave33/items/f6352a40bcfbfdea0476
https://www.kumilog.net/entry/conditional-dcgan
https://github.com/hwalsuklee/tensorflow-generative-model-collections
https://medium.com/@jonathan_hui/gan-cgan-infogan-using-labels-to-improve-gan-8ba4de5f9c3d
https://qiita.com/taku-buntu/items/0093a68bfae0b0ff879d
どんなもの?
GANでは、Generatorにはノイズだけを入力します。
Generatorが生成する確率分布を制御するアイデアがCGAN (Conditional GAN)です。
GeneratorとDiscriminatorの入力に教師データのカテゴリ(ラベル)情報を加えるだけです。
先行研究と比べてどこがすごい?
Generatorが何を生成するかはGeneratorに委ねられています。
要は乱数から文字を生成させることはできますが、生成させる文字(1とか8とか)を指定することができません。生成データをコントロールするためには、学習時に文字の正解ラベルを取り込む必要があります(conditional-GAN)。
通常のGANは教師あり学習に分類されると思いますが、これはあくまで画像が本物か偽物かに対する教師あり学習で、例えばmnistでは、画像がどのラベルに対応するかの教師あり学習は行なっていません。そのため、生成器(Generator)が明示的に数字を書き分けることはできません。訓練画像のラベルを知らされていないので当然です。Generatorはただ訓練データの分布に近づけるように学習を繰り返します(数字を例にすると、Generator自体には分からないが「1らしいもの」、つまり「1を1たらしめている特徴」はGeneratorの潜在変数に取り込まれます)。どの数字を書くかに関係なく様々な字体の訓練データを学習して、その背後にある字の特徴を潜在空間にマッピングしてほしいというわけです。
そのためには、Generatorの潜在変数とカテゴリ情報を切り離して考え、代わりにカテゴリ情報の条件化での生成モデル、識別モデルを生成する必要があります。それがConditional(条件付き)GANになります。例えばdiscriminatorに「今は、6について本物か偽物かを判定している」、generatorに「今は、3を書くという条件のもとに画像を生成している」ということを教えてあげます。
技術や手法のキモはどこ?
アイデアは非常に簡単でGeneratorとDiscriminatorの各入力にラベル情報を混ぜてあげるだけで他は一緒です。カテゴリ情報を用いるからといって、数値自体の識別モデルを作るわけではなく、あくまで本物か偽物かの識別をするだけです。各GANの派生系において基本構造は変わらないことが重要です。
コスト関数もGANと同じものを使います。
どうやって有効だと検証した?
MNISTを用いて検証した。各行はそれぞれ0~9のラベルの生成画像。
各行正しい数字画像が出力されていることが分かる。
議論はある?
ない
次に読むべき論文は?
CGANがベースになっているImage-to-Image Translation with Conditional Adversarial Networks(pix2pix)を読みたいと思います。
Generative Adversarial Nets(GAN)についてまとめた
GANについて落合フォーマットというものを利用してまとめました。
論文 : https://arxiv.org/pdf/1406.2661.pdf
どんなもの?
Generative Adversarial Nets(GAN)は2014年にIan Goodfellowによって考案され効率的に生成モデルを訓練させるためのモデリング手法。
訓練データを学習してそれらのデータと同じような新しいデータを生成するモデルを生成モデルと呼ぶ。
言い換えると訓練データの分布と生成データの分布が一致するように学習していくようなモデル。
・目標としては真の分布と近いモデル分布を求める。
先行研究と比べてどこがすごい?
先行研究として以下が挙げられます。
制限付きボルツマンマシン(RBM)やディープボルツマンマシン(DBM)はマルコフ連鎖モンテカルロ法によって推定するがこの量と勾配はすべての場合について扱いにくい。また、計算コストも高い。
論文には(おそらく)登場しないが生成モデルとしては以下のものもある。
- 変文オートエンコーダ(VAE)
自己回帰モデルの学習が遅い問題と変分オートエンコーダの輪郭がぼやけやすい問題をカバーできる。
技術や手法のキモはどこ?
GANではGeneratorとDiscriminatorの2つのネットワークがある。
・Generatorは訓練データと同じようなデータを生成しようとする。
・Discriminatorはデータが訓練データから来たものか、それとも生成モデルから来たものかを識別する。
最終的には、Generatorは訓練データと同じようなデータを生成できるようになることが期待される。
このような状態では、訓練データと生成データを見分けることができなくなるため、discriminatorの正答率は50%になる。
この論文ではGeneratorもDiscriminatorもどちらも基本的には多層パーセプトロンで、ドロップアウトを使って学習させている。
VAEでは確率分布を定義して生成モデルを考えてあるが、GANでは暗黙的な生成モデルとして考える。ただし尤度を測れなくなるので以下の密度比を使う。
次に数式を見る。
- G : Generator
- D : Discriminator
- x : 訓練データ
- z : ノイズ
とする。
Gはノイズzを入力としてデータを生成する。
D(x)は、そのデータが訓練データである確率を表す。確率なのでスカラー。
Dは訓練データと生成データに対して正しくラベル付けを行う確率を最大化しようとする。
Gを学習するための目的関数は
よってGはpdataとpgのJS距離を近づけるため、この目的関数を最小化するように学習する。
適切なGが得られないと最適なDは学習できないため目的関数を交互に最適化することを考える。
まとめると以下のようになる。
このような枠組みで学習する生成モデルをGANsと呼ぶ。
GeneratorとDiscriminatorの関係は紙幣の偽造者と警察の関係によく例えられる。偽造者は本物の紙幣とできるだけ似ている偽造紙幣を造る。警察は本物の紙幣と偽造紙幣を見分けようとする。
偽装者はできるだけ本物の紙幣に近い偽装紙幣を作り出すことで、警察の目を騙そうとするし、逆に警察も目利きスキルを上げてより本物の紙幣か偽物の紙幣かを見抜こうとする。
GANではGeneratorはできるだけ本物(オリジナル)に近い画像を生成し、Discriminatorはそれが本物の画像か否かを判定するような構造になっている。Generative Adversarial Nets(GAN)が敵対生成ネットワークという呼び名になっているのも、この競い合いのことを言っている
論文ではDをkステップ更新してGを更新する(ただしk=1とする場合が多い)と書かれている。
どうやって有効だと検証した?
Goodfellow et al.の実験結果を見てみる。
黄色い枠で囲まれている画像は訓練データで、それ以外は生成された画像。
訓練データによく似た画像を生成できている様子が分かる。
議論はある?
論文では主に明示的なpg(x)の表現がないことと、トレーニング中にDとGをうまく同期させる必要があること(Dを更新せずにGを過度にトレーニングしてはいけない)と書いてある。
またネットを調べるとGANには
- 収束性
- Mode collapse
- 勾配消失
の問題があるらしい(これらの問題は互いに関係している)。
なので学習が不安定で高解像度を生成することが難しい。CNNを利用しても高解像度生成は難しいとのこと。
次に読むべき論文は?
大体どのサイト、どの参考書を読んでもGANを説明したらDeep Convolutional GAN(DCGAN)みたいな流れだったので次に読むべきはDCGANの論文かなと思った。
https://arxiv.org/pdf/1511.06434.pdf
参考/引用サイト
3D素材デッサン人形を使ってイラストを描く
使用ソフト:CLIP STUDIO PAINT PRO
使用パソコン:Magnate IM マグネイト IM
使用機材:Parblo Coast10
3Dデッサン人形基本操作
CLIP STUDIO PAINT PROで3Dデッサン人形をいじって描きます。3Dデッサン人形の基本的な使い方(体型調整とポーズ調整)は以下の公式ホームページが非常に分かりやすいと思います。
3Dを使うときの注意
3D素材をもとに描いていくのですがここで注意なのが3D素材をそのままなぞれば良いというものではないということです。
あくまで補助であって、自分の絵柄まで落とし込む必要があります。
つまり、デッサン人形はみんなの絵柄に対して綺麗にフィットするわけではありません(当たり前だけど)。
自分の絵に対して3D素材をのせてみるとよくわかります。
元の絵とどれくらいずれこんでいるかを理解したうえで、3D素材を利用するといいと思います(線画のときだけ気を付ければ良いため)。また、体型からできるだけ自分の絵柄に寄せていくという方法もいいと思います。
3D素材の透過
3D素材を透過して下描きのように表示しましょう。
以下のようなレイヤー配置をしてみます。
この3Dの素材があるレイヤーの不透明度とレイヤーカラーをいじります。
別レイヤーを選択すると色が変わり透過していることが確認できます。
線画を描いていく
さっきもいったとおり自分の絵柄にあわせて線画(またはラフ)を描いていきます。
デッサン本やメイキング本などを参考にして素体や服を整えていきます。
お絵描き全体の流れ
最後に自分が3D素材を使って描いたイラストの簡単な工程を書きます。
あとがき
普段は自分でラフを描いて、難しいポーズのときとか面倒な時はデッサン人形を使うのも一つの手なのかなぁと思います。
3D素材を作るにはそれは手間がかかるでしょうが、こんな感じで使う分には全く手間ではないことが分かりました。