Edited at

世界の認識が壊れている画像生成アプリ

この記事は【クソアプリAdvent Calendar2018】 13日目向けに書いていたものでした(過去形)。期日過ぎていたせいかリストから削除されていましたが、一応作ったので投げておきます。


アプリ

http://tackman.info/kusoapuri2018/

手元の画像を選択して、Nextボタンを押すたびに現実の認識が壊れた感じの画像が生成されます。

マシンパワー的な問題でPCでの利用を想定しています。非力なマシンだとブラウザごと落ちるかもしれません。確認したブラウザはFiefoxとChrome/Chromium(Windows及びArch Linux)。割とプラットフォーム依存してそうな予感はするので、モバイルOSやSafari, IEでは動かないかもしれません。


コンセプト

GANの学習失敗をしている画像を見て「世界の認識が壊れるとこんな感じになるんだろうな~」→じゃあそういう認識を再現したアプリにできるんどえは?


技術的にやっていること


GANの学習失敗モデルの利用

もともとPyTorchでpix2pixを回していたので、そこから学習 ”失敗” したモデルを取ってきました。以前に学習失敗した時のモデルファイルは残していなかったので、記憶を頼りに設定変更をして学習を回しました。


  • 動かしたコードは原著者の公開しているものほぼそのまま https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix

  • 普段は学習を安定させるため、下記の疑似コードのようにGeneratorとDiscriminatorの性能差が付きすぎないように学習アルゴリズムに手を入れています。が、学習失敗させるために条件分岐をやめて元に戻した

adversarial_factor = 0.5

if generator_loss > adversarial_factor * discriminator_loss:
generator_loss.backward()
else:
discriminator_loss.backward()


  • L1ペナルティ項の係数を通常の10倍(普段0.02にしているところを0.2)にした

以上の設定で一晩ほど自宅マシンで回したところ、いい感じに学習失敗しているモデルができました。


ブラウザ向けエクスポート

PyTorchのモデルはそのままブラウザ上で動かす方法がないので、エクスポートが必要です。「ちょっと調べりゃどうとでもなるでしょ」と思っていたここで地味にハマって時間を食いました。


  • 当初案:Webdnn


    • PyTorchConverter()でセグフォォ

    • インストール方法が悪かったのか結局原因不明。あまりにつらそうだったので早々に切り上げた



  • 第二案:ONNX.js


    • PyTorch本体にONNXエクスポート機能があるので、これが一番素直に使えそうに思えた

    • が、PyTorchが利用している演算子の1つ(Scalar)がONNX.js側で未実装のため動かせなかった

    • 絶賛実装中らしいので、あと一週間あれば何とかできたのかもしれないけど12/13の前日だったので断念




最終的なエクスポート&フロント実行構成

PyTorch -> (pytorch2keras) -> Keras HDF5 -> (tensorflowjs_converter) -> TensorFlow model

ブラウザ上では TensorFlow.js で実行

ONNXエクスポートで動けばもっと素直にやれるのではという思いがあるので、ONNX.jsの様子を見ながらフロントの実行エンジンは機会を見て差し替えたいと思っています。


アプリ本体フロント部分の実装

クソアプリ~~という感じの実装になっています。 https://github.com/tackman/kusoapuri2018

最近はフロントエンド組む時はnuxt.jsを使うことが多いのですが、なんかそういうのどうでもいいレベルだよねってことでべた書きしました。画像前処理部分でOpenCV.jsを使ったんですが、これ間接的にemscripten使ったことになるんですね。意外と身近な技術だった。


CDN

このアプリは上記でエクスポートしたTensorFlowモデルをクライアントサイドで実行させるため、1個数百MBのファイル×Nをユーザにダウンロードさせます。さすがにS3からの直接配信だと死にそうなので、CloudFrontを噛ませています。

ただCloudFrontでも従量課金なので、個人利用の範囲だと無料 or 定額のCloudflareに乗り換えられないかなーとか考えています。その場合Route53と共存できないようなので、現在Route53を使っているドメインレジストラの引っ越しからに必要になりそう・・・


むすび

「失敗した学習モデルの再利用だしちゃちゃっと作れるでしょ~~」という程度のノリで始めましたが、結果的にディープのプロダクトのデプロイ一式勉強させていただく感じで良い学びがありました(大遅刻すいませんでした・・・)