これは、私が最近 twitter と vimeo に投稿したウェブカメラ pix2pix デモのソース コードと事前トレーニング済みモデルです。これは深層学習を使用しており、いくつかの流行語を取り入れると、深層畳み込み条件付き敵対的生成ネットワーク オートエンコーダーが使用されます。
ビデオ1
ビデオ2
この特定のリポジトリのコードは、実際には pix2pix、GAN、さらには深層学習とは何の関係もありません。事前にトレーニングされた tensorflow モデル (いくつかの制約に準拠している限り) をロードし、処理された Web カメラ入力をそれに供給し、モデルの出力を表示するだけです。たまたま、私がトレーニングして使用したモデルが pix2pix でした (詳細は以下を参照)。
つまり、手順は次のように要約できます。
ウィキメディアの Google アート プロジェクトから世界中のアート コレクションをかき集めました。画像の多くは裕福な白人男性の古典的なポートレートであるため、データを地理的および文化的にできるだけ多様に保つために、約 150 のコレクションのみを使用しました (使用した完全なリストはここにあります)。しかし、データは依然として非常にユーロ中心であり、単一のヨーロッパの博物館からは数百、数千のスキャンが存在する可能性がありますが、アラブの博物館からはわずか 8 件のスキャンしかありません。
画像の 300 ピクセル バージョンをダウンロードし、次のバッチ プロセスを実行しました。
また、(不均一なサイズ変更の代わりに)画像から複数のクロップを取得するバッチプロセスも実行しましたが、それについてはまだトレーニングしていません。私は、巧妙なエッジ検出の代わりに、Xie と Tu による (元の pix2pix 論文で使用されている) はるかに優れた「ホリスティックに入れ子になったエッジ検出」 (別名 HED) についても検討し始めましたが、それについてもまだトレーニングしていません。
これは、preprocess.py スクリプトによって行われます (申し訳ありませんが、コマンド ライン引数はありません。スクリプトを編集してパスと設定を変更します。これは一目瞭然です)。
トレーニング データの小さなサンプル (トレーニングされたモデルの予測を含む) は、ここで見ることができます。右端の列は元の画像、左端の列は前処理されたバージョンです。これら 2 つの画像は、トレーニング対象の「ペア」として pix2pix ネットワークに供給されます。中央の列は、左端の列のみを与えられた場合にモデルが学習して生成するものです。 (画像は各トレーニング反復を示しています。つまり、左側の数字は 20,000 から 58,000 まで変化するため、ページの下に行くほど徐々に改善されます)。
また、無条件 GAN (つまり、同じトレーニング データで通常の DCGAN) をトレーニングしました。その出力の例を以下に示します。(これは、トレーニング データに似た「完全にランダムな」画像を生成します)。
トレーニングとアーキテクチャは、まさに Isola ら (別名 pix2pix) による「 Image-to-Image Translation with Conditional Adversarial Nets 」です。私は @affinelayer (Christopher Hesse) による tensorflow ポートを使用してトレーニングしました。これは、最近話題になった「sketch-to-cat」デモを強化しているものでもあります。彼はまた、pix2pix がどのように機能するかについての素晴らしいチュートリアルも書きました。コードをオープンソースにしてくださった作者 (および彼らが構築したすべての人) に無限の感謝を捧げます。
tensorflow-pix2pix トレーニング コードにごくわずかな変更を 1 つだけ加えました。それは、人間が読める名前でジェネレーターの入力と出力にtf.Identity を追加して、テンソルのフィードとフェッチを簡単にできるようにすることです。したがって、このアプリケーションで独自のモデルを使用したい場合は、同じことを行う必要があります。 (または、入力/出力テンソル名をメモし、それに応じて json を変更します。これについては以下で詳しく説明します)。
私の事前トレーニング済みモデルは、[リリース] タブからダウンロードできます。
この特定のアプリケーションが行うことは、事前トレーニングされたモデルをロードし、Web カメラ入力のライブ前処理を実行し、それをモデルにフィードすることです。 opencv を使用して、昔ながらの基本的なコンピューター ビジョンで前処理を行います。それは本当に最小限で基本的なものです。以下に GUI を示します (GUI では pyqtgraph が使用されます)。
シーンが異なれば、必要な設定も異なります。
たとえば、「実写」の場合、 canny の方が(私見ですが)より良い結果が得られることがわかり、それを最初のビデオで使用しました。しきい値 (canny_t1、canny_t2) は、シーン、詳細の量、および目的の外観によって異なります。
画像に多くのノイズがある場合は、 pre_blurまたはpre_medianを少し追加するとよいでしょう。または、「芸術的効果」を得るためにそれらを使って遊んでください。たとえば、最初のビデオの 1:05 ~ 1:40 あたりに、大量の中央値 (30 ~ 50 程度の値) を追加します。
シーン (2 番目のビデオなど) を描画する場合、適応しきい値の方がキャニーよりも興味深い結果が得られることがわかりました (つまり、キャニーを無効にして適応しきい値を有効にします)。ただし、同意できないかもしれません。
完全に静的な入力の場合 (つまり、キャプチャをフリーズし、カメラの更新を無効にした場合)、モデルが同じ入力に対して異なる予測を行うため、出力はごくわずかにちらつく可能性がありますが、これは通常は非常に微妙です。ただし、ライブカメラ フィードの場合、特にノイズに対するキャニーまたは適応しきい値の感受性が高いため、入力のノイズにより出力に多くのちらつきが発生する可能性があるため、一時的なぼかしが役立つことがあります。
accum_w1とaccum_w2 は、モデルに入る前の入力の時間的ブラー用です: new_image = old_image * w1 + new_image * w2 (したがって、理想的には、これらを合計すると 1 または 1 に近い値になるはずです)。
Prediction.pre_time_lerpとpost_time_lerpも時間的平滑化を行います。 new_image = old_image * xxx_lerp + new_image * (1 - xxx_lerp) pre_time_lerp はモデルに入る前であり、post_time_lerp はモデルから出た後です。
一時的なブラーのいずれかをゼロにすると、それらが無効になります。これらの値は好みによって異なります。上の両方のビデオでは、pre_model ブラー (accum_w1、accum_w2、pre_time_lerp) をすべて 0 に設定し、0.0 (非常にちらつき、点滅) から 0.9 (非常に遅く、フェードで「夢のような」) までのさまざまな post_time_lerp 設定で再生しました。 )。通常、0.5 ~ 0.8 あたりが私の好みの範囲です。
別のモデルを使用したい場合は、以下のような JSON ファイルをセットアップする必要があります。ここでの動機は、実際に app/models フォルダーに大量の JSON があり、それらを動的にスキャンして再ロードできること、モデル データが他のディスク上の別の場所に保存されていること、そしてアプリが実行時およびスケール時にモデル間でロードおよびスワップできることです。入力/出力などを自動的に行います。
{
"name" : "gart_canny_256", # name of the model (for GUI)
"ckpt_path" : "./models/gart_canny_256", # path to saved model (meta + checkpoints). Loads latest if points to a folder, otherwise loads specific checkpoint
"input" : { # info for input tensor
"shape" : [256, 256, 3], # expected shape (height, width, channels) EXCLUDING batch (assumes additional axis==0 will contain batch)
"range" : [-1.0, 1.0], # expected range of values
"opname" : "generator/generator_inputs" # name of tensor (':0' is appended in code)
},
"output" : { # info for output tensor
"shape" : [256, 256, 3], # shape that is output (height, width, channels) EXCLUDING batch (assumes additional axis==0 will contain batch)
"range" : [-1.0, 1.0], # value range that is output
"opname" : "generator/generator_outputs" # name of tensor (':0' is appended in code)
}
}
Ubuntu 16.04 でのみテストされていますが、他のプラットフォームでも動作するはずです。
私は Anaconda Python ディストリビューションを使用しています。これには必要なものがほぼすべて含まれており、(できれば) 次のように簡単です。
https://www.continuum.io/downloads から anaconda をダウンロードしてインストールします
tensorflow をインストールします https://www.tensorflow.org/install/ (anaconda がある場合、ほとんどの依存関係が含まれているため、これは非常に簡単です)
opencv と pyqtgraph をインストールする
conda install -c menpo opencv3 conda install pyqtgraph
改めて無限の感謝を