イラストの印象をコンピュータが推察できるのか

　この記事は[CPS Lab Advent Calender 2020](https://adventar.org/calendars/5298)の20日目の記事です。
　1年かけてIoT周りのことをいろいろ勉強しましたが，IoT開発の実装については優秀な先輩・同級生が多くいるので，以前取り組んでいたCNNに関する取り組みでも紹介しようと思います。ソースまで網羅すると文量が大変なことになってしまうので，取り組みの概形をなぞりながら記事を書いていきます．梗概でも眺める気分でコーヒー片手に読んでいただければ幸いです。[ゼロから作るDeep Learning](https://www.amazon.co.jp/dp/4873117585/ref=cm_sw_r_tw_dp_x_R7K0FbDQQBRMP)に軽く目を通した方を対象読者としています。
# 1. はじめに
　高1当時所属していた水泳部の活動が暇になってくる冬にWacomのペンタブを買い，イラストを描き始めました。拙い作品ばかり量産していましたが，あまり人に評価されたいという承認欲求が無かったためか，のびのび描き続けられました。
　アウトプットも大事ですが，それ以上に多くの作品をpixivや画集を通して見ていく中で，次のような疑問が頭をよぎりました。

　***「イラストに登場するキャラクターの目って，その作品の印象を全て物語っているのではないだろうか」***

　例えば，日本のアニメにおけるキャラクターの目は，解剖学的にはあり得ないサイズの目をしていることは皆様ご存知のことと思います (誤解が無いように補足しますが，私は萌えイラストが大好きです)。しかしpixivを眺めていると，可愛いというよりも美しさが際立つような，非常にリアル志向のイラストを描かれる方もいます (中国や台湾，韓国のイラストレーターが比較的多いような)。
　前者のような萌えキャラが超リアルな背景と共に描かれるケースはほとんどありませんし，逆に後者のようなリアルな人物がポップなアニメ塗りの背景に配置されることもめったにありません。
　加えてキャラクターの置かれた状況についても，目は非常に説得力のある器官だと感じています。例えば戦闘中の萌えキャラが描かれたイラストを想像してみてください。生死を分つような決死の状況下では，睫毛の弧は比較的真っ直ぐで，目尻が上方に向かって尖っている場合が多いです (私調べ)。つまり，置かれた状況やイラスト全体の雰囲気が，そのままキャラクターの目という器官に反映されているのではないかという仮説を立てました。
　本記事は，この仮説の検証を行うものです．分析指標として「印象」を作品に付随させて学習させたCNN評価モデルを構築します。
# 2. 画像収集およびアノテーション
　教師あり機械学習をする上で最も面倒な作業が学習させるデータを用意することです。有名なMNISTやImageNet等のデータセットであれば初めから教師ラベルは付与されていますが，今回はデータの収集，およびアノテーションをゼロから進める必要がありました。本章では，画像収集とアノテーションの流れをまとめています。
## 2.1. 画像収集
　モデル構築を行う入力画像は，pixivから画像を収集するPythonの非公式APIのpixivpy[^1]を用いました。本APIにより，ある程度評価が高い作品を10,000作品ほど収集しました。
　実はこの際，全てのジャンルの作品を収集するのではなく，特定のタグが付いた作品は独断と偏見で除外しています。それらは大まかに「デフォルメ系」，「風景画」，「女性向け」に関連するタグの付いた作品です。
　デフォルメイラストは，対象の特徴を強調，単純化させ，ある種の誇張表現を行っています。つまりイラストレーションに落とし込む段階で，キャラクターの生い立ちや，その場面のストーリーといった情報を大きく削り取っており，そこから感じられる印象に作品間の差が生じにくいです。また風景画については，今回は最終的にキャラクターの目に着目したいという思惑があったため除外しました。
　女性向け，いわゆるBL志向が強い作品は少女漫画同様，登場人物の心情や背景に焦点を当てた描写が多く，見る人によっては画風以上の意味付けを作品に対して行ってしまいます。純粋に絵のスタイルでモデル構築を行うには不適当であると判断しました。
## 2.2. 印象語によるアノテーション
　印象を教師データとしたモデルが機能するためには，作品という画像メディアと，印象を言語化した言語メディアを内容ごとに比較する必要があり，ひとつの簡単な表現で作品の印象を語るのは困難です。そのため，いくつかの単語で作品の雰囲気を表現する必要がありました。
　ひとつひとつの評価因子の定義が明確な単語群として，次の表に示す23項目の印象語を用意しました。
> *すがすがしい，若々しい，洗練された，格調のある，ナチュラルな，清雅な，*
*優雅な，甘美な，かわいい，なごやかな，楽しい，華麗な，*
*躍動的な，柔らかな，重々しい，暖かい，クールな，地味な/落ち着いた，*
*明るい/輝かしい，静かな，固い，清潔な/新鮮な，スポーティー*

　これらの印象語は，栗田氏らが開発しているシステム[^2]における視覚的印象を表現する単語から抜粋したものです。各作品に対し，それぞれの印象語を「そう感じる」or「そう感じない」の2値で評価したデータベースを作成しました。
　ここまでで付与する教師データの方針は定まりました。しかし，その語数は23項目に及び，プレビューで作品を閲覧しながら表計算ソフトに評価を入力するというアノテーションでは時間がかかってしまいます。そこで，評価者 (主に自分)の負担を軽減するため，パソコンだけでなく，スマートフォンやタブレットでもアクセス可能な評価支援WebページをSinatraで作成しました。画像の表示やデータの格納といった処理を自動化することで，データベース作成効率の向上を図っています。後ほどCSVで書き出すのでリレーションとか細かいこと無しの23カラムぶん投げDBです。
![dfghjkh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699329/c655899f-d7fb-1a2d-1b6c-58e1519066cc.png)
# 3. CNNによる機械学習モデル構築
　いよいよモデル構築です。CNNのことは一通りオライリーの[ゼロから作るDeep Learning](https://www.amazon.co.jp/dp/4873117585/ref=cm_sw_r_tw_dp_x_R7K0FbDQQBRMP)で勉強しましたが，ここからはkeras-gpuを使い倒して積み木のようにモデル構築を行いました。本を読みながら誤差逆伝搬の関数を書いてましたが，kerasを使えば1行で畳み込み層が表現できるのだからライブラリの力はすごいと痛感しました。
　本章ではではデータ整形から過学習対策の取り組みまでをまとめています。
## 3.1.  データ整形
　目領域を分析対象とする背景については[1. はじめに](#1-はじめに)で述べた通りですが，検証を進める過程での技術的な壁による要請でもありました。イラスト作品においては，縦横比や背景の有無，キャラクターの人体構造，様々なエフェクトに至るまで，表現が多種多様で統一性がないことは想像に難くありません。そのため特徴的なエッジ，輝度分布，対称性が存在しないのです。加えてCNNの学習は初期値依存性が高く，訓練データが今回のように多く用意できない場合はできるだけ良い初期値を得ることが，過学習を防ぐために重要となります。イラスト作品の過度な表現をそのまま入力してしまっては，いくら一般性の高い特徴量と判断基準を得ることができるNNといえど，期待した結果は得られないと考えました。
　そこで下図のような地獄のトリミング作業を行うことにしました。左手を**cmd+K**に合わせながら，右手でトリミング範囲を選択する作業です．かなり堪える作業ではありましたが，1枚の作品に目は2つ以上含まれていることが多く，さらにトリミングして取得した画像を反転させることで，教師ありサンプル数を1,138枚から5,938枚に水増しすることができました。
![eye.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699329/2ebaf5a0-136f-5199-a5ea-d81c59c4ccc5.png)
　なお色空間についてはRGBやHSVなどのカラーモデルがありますが，全サンプルを正規化，1次元化して主成分分析を行ったところ，HSVよりもRGBの方が低次元において高い累積寄与率を示していたので，構築するモデルの入力画像にはRGBカラーモデルを用いました。最終的に用意できた訓練データは3,800枚，検証データは950枚，テストデータは1,188枚です。機械学習をするには少なすぎる気もしますが，もうこれ以上データ準備で頑張る体力は残されていませんでした。
## 3.2. CNNのチューニング
### 3.2.1. 基本構造
　ここからはモデル構築です。とはいえ損失関数が発散してしまうようなモデルを作るわけにはいかないということもあり，様々な構造のモデルで検証データの損失関数を確認するチューニング作業を行いました。この作業を通して有効な過学習対策を特定します。次の画像は，チューニングで使用したCNNの基本構造です。彼の有名なモデル「VGG16」を踏襲しています。
![initcnnのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699329/4e01e95c-4211-80d9-3854-67b82c180f46.png)
 プーリングにはMax-pooling，最適化関数にはAdamを用い，ハイパーパラメータは提案論文[^3]に従っています。ミニバッチ学習におけるバッチサイズは128としました。以降の図中の「c」，「r」，「d」はそれぞれ畳み込み層，活性化層，全結合層の略記です。また，「B」，「D」はそれぞれ過学習対策のためのBatch Normalization[^4] (以下「BN」)層，Dropout層の略記です。
　教師データは23次元の2進ベクトルとして表現されており，教師データは900通り以上の組み合わせが存在します。one-hotエンコーディングでの分類問題は現実的ではないので，本CNNが解く問題は回帰問題とし，出力層は恒等関数，損失関数は平均二乗誤差としました。
### 3.2.2. チューニング手順
　チューニング手順は次のとおりです。中間層においてBNとDropoutを併用すると性能が悪化することが報告されている[^5]ため，併用した上での検証は行いませんでした。

1. block1において，「crcr」，「cBcr」，「crcBr」，「cBrcBr」の層の組み合わせでそれぞれ学習させ，損失を記録
1. block2 において，「crcr」，「cBcr」，「crcBr」，「cBrcBr」の層の組み合わせでそれぞれ学習させ，損失を記録
1. FCにおいて，「dr」，「dBr」の層の組み合わせでそれぞれ学習させ，損失を記録
1. block1，block2，FC において最も損失が小さかったパターンを組み合わせて学習させ，損失を記録
1. FCを「drD」に変更して学習させ，損失を記録
1. FCを「dBrD」に変更して学習させ，損失を記録
1. 上記までの結果を鑑みて，必要であればBN層の箇所をDropoutに変更して検証し，損失を記録

### 3.2.3. チューニング結果
　block1，block2，FC，および各ブロックを組み合わせた際の損失関数の変化は次のとおりです。どの層でもおよそ損失関数の出力値が0.2となり，MNIST等で勉強した際に比べれば誤差は非常に大きいと言わざるを得ません。とはいえ限られた学習データしかないこともあり，0.5を超えなかっただけ良かったと前向きに捉えることにします。
![over1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699329/521b469f-1180-f360-c592-4c6af813f332.png)![over2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699329/40a98bbf-eb1b-05e3-af32-0adcb6da2406.png)
![over3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699329/d4f63a65-01d6-ab66-b16f-218f38b96813.png)![over4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699329/ede38cdb-3999-9151-68d1-79b0f84fe372.png)
　block1において，BN層の追加は全ての層において改善がみられず，「cBrcr」を除き損失が悪化したことが見て取れます。またblock2において，2つの畳み込み層の直後にそれぞれ追加した「cBrcBr」が，やや過学習傾向が見られるが概ね改善されていました。FCにおいて，BN層の追加はエポック数を重ねるにつれ徐々に安定し改善していることが確認できました。
　そこで組み合わせ検証では，block1からFCにかけて最も良い結果の組み合わせとして「crcr_cBrcBr_dBr」に加え，FC層から浅い中間層に向かってBN層をDropout層に置き換えて検証を行いました。最も良いパフォーマンスを発揮したのは，プーリング層の後，および全結合ノードを活性化させた後にDropoutを使用する「crcrD_crcrD_drD」のモデルで，本データセットとBNとの相性は良くないことが確認できました。これが何故なのかはいまいち理解できていませんが，畳み込み層の正則化よりもDropoutのような仮想アンサンブル学習が有効であるケースがあると知れたのは良かったです。最終的なモデルを図示すると次のようになります。結局典型的なVGG16踏襲版に落ち着いてしまったのでやや面白みに欠けるのが残念なところ。
![cnn.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699329/8f486acd-7b77-964b-934e-9595f2a61332.png)
# 4. モデル評価
　本章では，構築したモデルで本当に印象の予測が可能なのかの検証についてまとめています。
## 4.1. 評価方法
　回帰問題には平均絶対誤差や平均二乗誤差などの評価指標が存在しますが，本モデルにおいてこれらを使用しての評価は不十分です。2つモデルがあったとして，必ずしも平均二乗誤差が小さいモデルが予測に適しているとは限りません。重要となるのは，テストデータの予測が，どれだけ正解データと類似した固有ベクトルを持つ23次元の印象空間となっているかどうかです。
　例えば同じ印象を与えてくれるようなイラストBをイラストAの印象から提示してほしいと思ったら，AとBのユークリッド距離が近い必要があります。そこで，テストデータに対する正解データ，予測データのそれぞれに対して主成分分析を行い，固有ベクトルと寄与率を取得して評価を行いました。
## 4.2. 評価結果
　下図は一つ目の畳み込み層のフィルタとテスト画像入力時の特徴マップの組み合わせ (一部)です。髪の毛や睫毛のエッジに加え，瞳の形状，虹彩の特徴などが検出できており，表現力の高そうな重みを得ることができています。これは期待できそうだと計算をぶん回しながら思いました。
![f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699329/bfce6396-304c-e3f6-30c6-6ae661993a2b.png)
　下の3枚の図は正解データと予測データの固有ベクトルの次元別相関係数を表したものと，次元別寄与率を表したもの，および正解データと相関係数$\times$予測データ (=「補正予測」とする)の累積寄与率を表したものです。
![cc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699329/7d341178-2de4-f14f-0f73-d4b623185555.png)![cr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699329/7c833c3a-6c2b-71a4-180f-275909229c91.png)
![ccr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699329/638d034f-0760-5c90-cc44-3183850f5be1.png)
　第3主成分までの次元において相関係数は0.8を上回っており，正解に近い印象空間の基底を再現できていることが分かります。また折れ線グラフより，上述したように意味のある次元における基底再現性が高いことに加え，それらの次元における寄与率が正解データよりも高いです。よってCNNから出力される印象ベクトルは，少ない次元数で作品の情報を保持できていることが分かります (目だけで！)。しかし，第7主成分以降の予測の寄与率は0.05を下回り，正解よりも低いことから，累積寄与率はほぼ0.8で頭打ちとなっています。補正予測をCNNモデルの性能指標とした時，予測の印象空間の正解との類似度は80%であると言えます。
　以上の結果は，画像のみで作品の印象を特定することは可能であることを示しました。加えて，如何なるテイスト，構図のイラスト作品であったとしても，その作品の印象は目領域に集約されており，目という器官が持つ表現力の高さを保証するものです。
# 5. 結論
　あくまで私の所感ですが，画像を扱うCNNは従来，人が瞬間的に判断できる対象をコンピュータに学習させる目的で開発が進められてきた気がします。そのような中，今回の「印象」のような曖昧な分野を取り扱う回帰問題においても，CNNの高い学習性能を確認することができました。
　これまで絵を見たり描いたりする中で，キャラクターの目はめっちゃ表現力高いということは感覚的に感じていました。とはいえ人に説明する時に説得力がないということで，キャラクターイラスト作品が人に与える印象を作品に付随させ，学習させた作品評価モデルを構築しました。苦労した点として，ImageNetなどの既に用意されたデータを使うわけではなかったので，アノテーションの負担がとんでもないことになっています。今後，何かしらのデータを収集して機械学習をする時には，アノテーションの負担を限りなく0にする工夫をしようと心に決めました。今は環境センシングのIoTにお熱なので，このあたりの工夫を考えるのは楽しそうですね。ここまでお読みいただきありがとうございました。

[^1]: [pixivpy - Github](https://github.com/upbit/pixivpy)
[^2]: 栗田多喜男, 加藤俊一, 福田郁美, 板倉あゆみ: 印象語による絵画データベースの検索, 情報処理学会論文誌, Vol. 33, No. 11, pp. 1373-1383, Nov. 15, 2018.
[^3]: Diederik P. Kingma, Jimmy Ba: Adam: A Method for Stochastic Optimization, a conference paper at ICLR 2015, pp. 1-15, Dec. 22, 2015
[^4]: Sergey Ioffe, Christian Szegedy: Batch normalization: accelerating deep network training by reducing  internal covariate shift, a conference paper at ICML 2015, pp. 448-456, July 06-11, 2015
[^5]: Xiang Li, Shuo Chen, Xiaolin Hu, Jian Yang: Understanding the Disharmony between Dropout and Batch Normalization by Variance Shift, Jan. 16, 2018