Tensorflow はディープラーニングに基づいて画像補完をどのように実装するのでしょうか?

Tensorflow はディープラーニングに基づいて画像補完をどのように実装するのでしょうか?

[[191038]]

ブランドン・エイモス

編集:モリー・ハン・シャオヤン

目次

1. はじめに

2. ステップ1: 画像を確率分布のサンプルとして理解する

  • 不足している情報をどのように入力すればよいですか?
  • しかし、どうやって数え始めればいいのでしょうか? これらはすべて画像です。
  • では、どうやって画像を完成させるのでしょうか?

3. ステップ2: 偽の画像を素早く生成する

  • 未知の確率分布の下で新しいサンプルを生成するための学習
  • [ML-Heavy] 生成的敵対的ネット (GAN) のアーキテクチャ
  • G(z)を使用して偽の画像を生成する
  • [ML-Heavy] DCGANのトレーニング
  • 既存のGANおよびDCGANの実装
  • [ML-Heavy] Tensorflow で DCGAN を構築する
  • 画像セットでDCGANを実行する

4. ステップ3: 画像補完に最適な疑似画像を見つける

  • DCGANを使用した画像補完
  • [ML-Heavy] pgpgへの投影のための損失関数
  • [ML-Heavy] DCGAN 画像の補完に TensorFlow を使用する
  • 画像を完成させる

5. 結論

1. はじめに

コンテンツに応じた塗りつぶしは、デザイナーや写真家が画像の不要な部分や欠けている部分を塗りつぶすために使用できる強力なツールです。画像の補完と修復は、画像の欠落部分や破損部分を補うための 2 つの密接に関連した手法です。コンテンツに応じた塗りつぶし、画像の補完、およびインペインティングを実装する方法は多数あります。このブログでは、RaymondYeh、Chen Chen らによる論文「Semantic Image Inpainting with Perceptual and ContextualLosses」を紹介します。この論文は2016年7月26日にarXivで公開され、画像補完にDCGANネットワークを使用する方法が紹介されました。このブログ投稿は、一般的な技術的背景を持つ読者を対象としており、一部のコンテンツでは機械学習の背景が必要になります。関連するセクションには [ML-Heavy] のタグを付けましたので、あまり詳細を読みたくない場合は、そのセクションをスキップできます。ここでは、顔画像の欠落部分を埋めるケースのみを取り上げます。ブログ投稿に関連する Tensorflow コードは、GitHub で公開されています: bamos/dcgan-completion.tensorflow。

画像の完成は3つのステップに分かれています。

  • まず、画像を確率分布からのサンプルとして理解します。
  • この理解に基づいて、偽の画像を生成する方法を学びます。
  • 次に、埋め戻すのに最適な疑似画像を見つけます。

Photoshop を使用して画像の欠けている部分を補完し、Photoshop を使用して不要な部分を自動的に削除します。

画像の補完については後ほど紹介します。画像の中心は自動的に生成されます。

これらの画像は、LFW データセットからランダムに取得したサンプルです。

2. ステップ1: 画像を確率分布のサンプルとして理解する

1. 不足している情報をどのように入力しましたか?

上記の例では、不足している部分を補うことができるシステムを構築していると想像してください。どうやってそれを行うのでしょうか?人間の脳はどうやってそれを行うと思いますか?どのような情報を使用しますか?

このブログ投稿では、次の 2 種類の情報に焦点を当てます。

  • コンテキスト情報: 周囲のピクセルから、欠落しているピクセルに関する情報を推測できます。
  • 知覚情報: 実際の生活や他の写真で見たものなどの「通常の」情報を空欄に入力します。

どちらも重要です。文脈情報がなければ、どれを記入すればよいのかどうやってわかるのでしょうか? 知覚情報がなければ、同じ文脈から無数の可能性が生み出される可能性があります。機械学習システムにとって「正常」に見える画像でも、人間にとっては正常に見えない場合があります。

前述の画像完成手順で述べた両方の特性を捉えることができる、正確で直感的なアルゴリズムがあれば素晴らしいでしょう。特定の状況では、そのようなアルゴリズムを構築することが可能です。しかし、一般的な方法はありません。現時点での最善の解決策は、統計と機械学習を使用して近似手法を得ることです。

2. しかし、どうやって数え始めればよいでしょうか? これらはすべて画像です。

思考を刺激するために、よく理解されていて簡潔な形式で記述できる確率分布、つまり正規分布から始めます。これは正規分布の確率密度関数 (PDF) です。 PDF は入力空間内で水平方向に移動しており、垂直軸は特定の値が発生する確率を表していると考えることができます。 (興味があれば、このグラフのコードは bamos/dcgan-completion.tensorflow:simple-distributions.py からダウンロードできます。)

この分布からサンプリングすることで、いくつかのデータを取得できます。明確にする必要があるのは、PDF とサンプルの関係です。

正規分布からのサンプリング:

PDF と 2D 画像のサンプル。 PDF は、サンプル ポイントが上部にプロットされた等高線プロットとして表示されます。

入力は 1 つの次元に沿ってのみ可能であるため、これは 1D 分布です。同じことは 2 次元でも実行できます。

画像と統計の間の重要なつながりは、画像を高次元の確率分布からのサンプルとして見ることができることです。確率分布は画像のピクセルに対応します。カメラで写真を撮っているところを想像してください。結果の画像は有限の数のピクセルで構成されます。カメラで写真を撮るときは、この複雑な確率分布からサンプリングしていることになります。この確率分布によって、画像が正常であるか異常であるかが判断されます。画像の場合、正規分布とは異なり、真の確率分布を知ることはできず、サンプルを収集することしかできません。

この記事では、RGB カラーで表されるカラー画像を使用します。画像の幅は 64 ピクセル、高さは 64 ピクセルなので、確率分布は 64⋅64⋅3≈12k 次元になります。

3. では、画像を完成させるにはどうすればよいでしょうか?

まず、インスピレーションを得るために多変量正規分布を考えてみましょう。 x=1 の場合、y の最も可能性の高い値は何でしょうか? x の値を固定し、PDF を最大化する y を見つけることができます。

多次元正規分布において、xが与えられたとき、yの最大値を求める

この概念は、画像の確率分布に自然に拡張できます。いくつかの値はわかっており、欠落している値を入力したいと考えています。これは単純に最大化問題として理解できます。可能性のあるすべての欠損値を検索し、最も確率の高い画像が補完に使用されます。

正規分布のサンプルからは、サンプリングするだけで PDF を取得できます。好きな統計モデルを選択して、データに適合させるだけです。

ただし、実際にはこのアプローチは使用しません。シンプルな配布の場合、PDF は簡単に見つかります。しかし、より複雑な画像分布の場合、処理が非常に困難になります。この複雑さの理由の一部は、複雑な条件依存関係です。つまり、1 つのピクセルの値は、画像内の他のピクセルの値に依存します。さらに、一般的な PDF を最大化することは、非常に困難で解決困難な非凸最適化問題です。

ステップ2: 偽の画像を素早く生成する

1. 未知の確率分布の下で新しいサンプルを生成する学習

PDF を計算する方法を学ぶことに加え、統計学で確立されたもう 1 つの考え方は、生成モデルを使用して新しい (ランダムな) サンプルを生成する方法を学ぶことです。生成モデルのトレーニングと処理は一般的に困難ですが、ディープラーニング コミュニティはこの分野で驚くべき進歩を遂げました。 Yann LeCun 氏は、この Quora の回答で、生成モデルのトレーニング方法について興味深い議論を展開し、これを過去 10 年間の機械学習における最も興味深いアイデアと呼んでいます。

ヤン・ルカンによる生成的敵対ネットワークの紹介

[[191041]]

生成的敵対ネットワークをアーケード ゲームと比較します。 2つのネットワークは互いに競争しながら、共に進歩していきます。それはまるでゲームで対決する二人の人間のようなものだ。

変分オートエンコーダ (VAE) などの他のディープラーニング手法も、生成モデルのトレーニングに使用できます。このブログ投稿では、Generative Adversarial Nets (GAN) を使用します。

2. [ML-Heavy] 生成的敵対的ネット (GAN) のアーキテクチャ

このアイデアは、2014 年の Neural Information Processing Systems (NIPS) ワークショップで発表された画期的な論文「Generative Adversarial Nets (GANs)」で Ian Goodfellow らによって提案されました。主なアイデアは、pzpz で表される、単純で一般的に使用される分布を定義することです。以下では、pzpz を使用して、-1 から 1 までの閉区間上の均一分布を表します。分布からのサンプルをz∼pzz∼pzと表します。 pzpz が 5 次元の場合、1 行の Python numpy コードでサンプリングを実行できます。

  1. z = np .random.uniform(-1, 1, 5)
  2.  
  3. 配列([0.77356483, 0.95258473,-0.18345086, 0.69224724, -0.34718733])

サンプルを採取するための単純な分布ができたので、元の確率分布からサンプルを採取するための関数 G(z) を定義します。

  1. G(z)の定義:
  2.  
  3. ...
  4.  
  5. 画像サンプルを返す
  6.  
  7. z = np .random.uniform(-1,1,5)
  8.  
  9. 画像サンプル= G (z)

では、ベクトルを入力して画像を出力するように G(z) をどのように定義するのでしょうか? ディープ ニューラル ネットワークを使用します。ニューラル ネットワークの基礎に関するチュートリアルはたくさんあるので、ここでは説明しません。スタンフォード大学の CS231n コース、Ian Goodfellow らのディープラーニング ブック、「Image Kernels Explained Visually」、畳み込み演算ガイドなど、優れた参考資料をお勧めします。

ディープラーニングベースの G(z) を構築する方法は多数あります。オリジナルの GAN 論文では、アイデア、トレーニング手順、およびいくつかの予備的な実験結果が提示されました。このアイデアは大幅に拡張され、その 1 つのアイデアは、2016 年の国際表現学習会議 (ICLR、「アイクリア」と発音) で発表された、Alec Radford、Luke Metz、および Soumith Chintala による論文「Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks」で提案されました。この論文では、マイクロストライド畳み込みを使用して画像をアップサンプリングする Deep Convolutional GAN (DCGAN と呼ばれる) を提案しています。

では、マイクロストライド畳み込みとは何でしょうか。また、どのように画像をアップサンプリングするのでしょうか。ディープラーニングにおける畳み込みの非常に優れた入門書として、Vincent Dumoulin と Francesco Visin および Convolutions プロジェクトによる論文「ディープラーニングのための畳み込み演算ガイド」が挙げられます。イラストは素晴らしく、マイクロストライド畳み込みがどのように機能するかを直感的に理解できます。まず、一般的な畳み込みがカーネルを入力空間 (青) にスライドさせ、出力空間 (緑) を生成する仕組みを理解していることを確認してください。ここでは、出力は入力よりも小さくなります。 (わからない場合はCS231n CNNセクションまたは畳み込み演算ガイドを参照してください)

畳み込み演算の図。青が入力、緑が出力です。

次に、3X3 入力があるとします。私たちの目標は、より大きな出力が得られるようにアップサンプリングすることです。マイクロストライド畳み込みは、入力画像を拡大し、ピクセル間にゼロを挿入するものと考えることができます。次に、この拡大された画像に対して畳み込み演算を実行し、より大きな出力を取得します。ここで、出力は 5X5 です。

マイクロステップ畳み込み演算の図。青が入力、緑が出力です。

補足: アップサンプリングを実行する畳み込み層には、フル畳み込み、ネットワーク内アップサンプリング、分数ストライド畳み込み、後方畳み込み、逆畳み込み、アップ畳み込み、転置畳み込みなど、さまざまな名前があります。 「デコンボリューション」という用語はすでに他の文脈で使用されているため、使用しないことを強くお勧めします。特定の数学演算やコンピューター ビジョンの他のアプリケーションでは、この用語はまったく異なる意味を持ちます。

マイクロストライド畳み込み構造ができたので、ベクトルz∼pzz∼pzを入力として受け取り、64x64x3のRGB画像を出力するG(z)の表現を得ることができます。

DCGAN を使用したジェネレーターの構築方法。 DCGAN 論文からの画像。

DCGAN の論文では、バッチ正規化やリーキー RELU など、DCGAN をトレーニングする際の他の手法や調整も提案されています。

3. G(z)を使用して偽の画像を生成する

ちょっと立ち止まって、G(z) がいかに強力であるかを実感してみましょう。 DCGAN の論文では、寝室のデータセットでトレーニングした後の DCGAN の様子が示されています。すると、G(z) は次の疑似画像を生成します。これは、ジェネレータが寝室がどのように見えると考えているかを示しています。以下の写真は元のデータセットには含まれていません。

あるいは、入力空間 z に対して代数演算を実行することもできます。以下は顔を生成するネットワークです。

DCGAN に基づく顔の代数演算に関する DCGAN 論文。

4. [ML-Heavy] DCGANのトレーニング

これで、G(z) を定義し、それがいかに強力であるかを確認しました。では、どのようにトレーニングするのでしょうか? 未知の変数 (パラメーター) が多数あるため、それらを見つける必要があります。この時点で、敵対的ネットワークを使用する必要があります。

まず、いくつかのシンボルを定義する必要があります。データ (未知) の確率分布は pdatapdata で表されます。するとG(z)(ただしz∼pzz∼pz)は確率分布からのサンプリングとして理解できる。この確率分布をpgpgと表記します。

シンボル pzpdatapg は、単純で既知の z の確率分布を意味します。画像 (未知) の確率分布は、画像データ サンプルのソースです。ジェネレータ G は、確率分布をサンプリングするために使用されます。pg==pdata であることを期待します。シンボルは、単純で既知の pzz の確率分布を意味します。画像 pdata (未知) の確率分布は、画像データ サンプルのソースです。ジェネレータ G は、確率分布をサンプリングするために使用されます。pg==pdata であることを期待します。識別器ネットワーク D(x) は、画像 x を入力し、画像 x が pdatapdata の分布からサンプリングされる確率を返します。理論的には、入力画像が pdatapdata からサンプリングされた場合、識別器は 1 に近い値を出力し、入力画像が pgpg からサンプリングされた画像などの疑似画像の場合、識別器は 0 に近い値を出力します。 DCGAN では、D(x) は従来の畳み込みニューラル ネットワークです。

識別器畳み込みニューラルネットワーク、画像復元論文からの画像

識別器をトレーニングする目標は次のとおりです。

  • 真のデータ分布x∼pdatax∼pdataの各画像について、D(x)を最大化します。
  • 真のデータ分布x≁pdataからではないすべての画像について、D(x)を最小化します。

ジェネレータG(z)のトレーニング目標は、Dを混乱させる可能性のあるサンプルを生成することです。出力は、識別器への入力として使用できる画像です。したがって、ジェネレーターは D(G(z)) を最大化すること、つまり (1-D(G(z))) を最小化することを目指します。これは、D が 0 から 1 までの値を持つ確率であるためです。

この論文では、敵対的ネットワークを以下の最小および最大戦略を通じて実装することを提案しています。最初の項の数学的期待値は真のデータ分布を横断し、2番目の項の数学的期待値はpzpz内のサンプルを横断します。つまり、G(z)∼pgG(z)∼pgを横断します。

  1. 最小GmaxDEx∼pdatalog(D(x)+Ez∼pz[log(1−D(G(z)))]最小GmaxDEx∼pdatalog(D(x)+Ez∼pz[log(1−D(G(z)))]

この式の勾配を D と G のパラメータに関して取ることで、それらをトレーニングすることができます。この式の各部分を素早く評価する方法がわかっています。数学的期待値はサイズ m の小さなデータ バッチによって推定でき、内部最大化は k ステップの勾配によって推定できます。トレーニングには k=1 がより適した値であることが示されています。

識別器のパラメータを表すためにθdθdを使用し、生成器のパラメータを表すためにθgθgを使用します。 D と G は両方とも本格的なニューラル ネットワーク モジュールで構成されているため、θdθd と θgθg に関する損失の勾配はバックプロパゲーションによって計算できます。以下は、GAN 論文のトレーニング戦略です。理論的には、トレーニング後、pg==pdatapg==pdata になります。したがって、G(z)はpdatapdata分布に従うサンプルを生成できます。

GAN 論文からのトレーニング アルゴリズム。

5. 既存のGANとDCGANの実装

Github では、素晴らしい GAN および DCGAN の実装を多数見ることができます。

  • goodfeli/adversarial: GAN 論文の著者によって書かれた Theano GAN 実装。
  • tqchen/mxnet-gan: 非公式の MXNet GAN 実装。
  • Newmu/dcgan_code: DCGAN 論文の著者によって書かれた Theano GAN 実装。
  • soumith/dcgan.torch: DCGAN 論文著者の 1 人 (Soumith Chintala) による Torch DCGAN 実装。
  • carpedm20/DCGAN-tensorflow: 非公式の TensorFlow DCGAN 実装。
  • openai/improved-gan: OpenAI の最初の論文の背後にあるコード。 carpedm20/DCGAN-tensorflow をベースに多くの変更が加えられました。
  • mattya/chainer-DCGAN: 非公式の Chainer DCGAN 実装。
  • jacobgil/keras-dcgan: 非公式 (未完成) KerasDCGAN 実装。

carpedm20/DCGAN-tensorflowをベースにモデルを構築します。

6. [ML-Heavy] Tensorflow 上での DCGAN の構築

この部分の実装は、私の bamos/dcgan-completion.tensorflow Github リポジトリにあります。この部分のコードは Taehoon Kim による carpedm20/DCGAN-tensorflow からのものであることを強調する必要があります。これを自分のライブラリで使用して、画像完成の次の部分で使用できるようにします。

実装コードのほとんどは、model.py の Python クラス DCGAN にあります。すべてを 1 つのクラスにまとめると、トレーニング後に中間プロセスを保存し、後で使用するために読み込むことができるため、多くの利点があります。

まず、ジェネレータとディスクリミネータの構造を定義します。 linear、conv2d_transpose、conv2d、および lrelu 関数は ops.py で定義されています。

  1. ジェネレータの定義(self, z):  
  2. self.z_、self.h0_w、 self.h0_b =線形(z、self.gf_dim*8*4*4、'g_h0_lin'、 with_w = True )   
  3.  
  4. self.h0 = tf .reshape(self.z_, [-1, 4, 4, self.gf_dim * 8])  
  5. h0 = tf.nn.relu (self.g_bn0(self.h0))   
  6.  
  7. self.h1、self.h1_w、 self.h1_b = conv2d_transpose (h0、  
  8. [self.batch_size, 8, 8, self.gf_dim*4]、名前= 'g_h1' with_w = True )  
  9. h1 = tf.nn.relu (self.g_bn1(self.h1))   
  10.  
  11. h2、self.h2_w、 self.h2_b = conv2d_transpose (h1、  
  12. [self.batch_size, 16, 16, self.gf_dim*2]、名前= 'g_h2' with_w = True )  
  13. h2 = tf.nn.relu (self.g_bn2(h2))   
  14.  
  15. h3、self.h3_w、 self.h3_b = conv2d_transpose (h2、  
  16. [self.batch_size, 32, 32, self.gf_dim*1]、名前= 'g_h3' with_w = True )  
  17. h3 = tf.nn.relu (self.g_bn3(h3))   
  18.  
  19. h4、self.h4_w、 self.h4_b = conv2d_transpose (h3、  
  20. [self.batch_size, 64, 64, 3]、 name = 'g_h4' with_w = True )   
  21.  
  22. tf.nn.tanh(h4) を返す  
  23.  
  24. defdiscriminator(自己、イメージ、再利用= False ):  
  25. 再利用する場合:  
  26. tf.get_variable_scope().reuse_variables()
  27. h0 = lrelu (conv2d(イメージ、self.df_dim、名前= 'd_h0_conv' ))  
  28. h1 = lrelu (self.d_bn1(conv2d(h0,self.df_dim*2,名前= 'd_h1_conv' )))  
  29. h2 = lrelu (self.d_bn2(conv2d(h1,self.df_dim*4,名前= 'd_h2_conv' )))  
  30. h3 = lrelu (self.d_bn3(conv2d(h2,self.df_dim*8,名前= 'd_h3_conv' )))  
  31. h4 =線形(tf.reshape(h3, [-1, 8192]), 1,'d_h3_lin')
  32.  
  33. tf.nn.sigmoid(h4)、h4を返す

このクラスを初期化するときに、これら 2 つの関数を使用してモデルを構築します。パラメータを共有(再利用)する 2 つの識別子が必要です。 1 つはデータ分布からの画像のミニバッチ用で、もう 1 つはジェネレータによって生成された画像のミニバッチ用です。

  1. 自己self.G = self.generator(self.z)  
  2. self.D、 self self.D_logits = self.discriminator(self.images)  
  3. self.D_、 self self.D_logits_ = self.discriminator(self.G、 reuse = True )

次に、損失関数を定義します。合計する代わりに、より実用的なため、D の予測値と実際の値の間のクロスエントロピーを使用します。識別器は、すべての「実際の」データに対して 1 を予測し、ジェネレータによって生成されたすべての「偽の」データに対して 0 を予測します。ジェネレーターは、識別器が両方に対して 1 を予測することを望んでいます。

  1. 自己.d_loss_real = tf.reduce_mean (
  2. tf.nn.sigmoid_cross_entropy_with_logits(self.D_logits,
  3. tf.ones_like(self.D)))
  4. 自己.d_loss_fake = tf.reduce_mean (
  5. tf.nn.sigmoid_cross_entropy_with_logits(self.D_logits_,
  6. tf.zeros_like(self.D_)))
  7. 自己.g_loss = tf.reduce_mean (
  8. tf.nn.sigmoid_cross_entropy_with_logits(self.D_logits_,
  9. tf.ones_like(self.D_)))
  10. 自己self.d_loss = self.d_loss_real + self.d_loss_fake

各モデルの変数を集約して、個別にトレーニングできるようにします。

  1. t_vars = tf.trainable_variables ()です。
  2.   
  3. self.d_vars = [var for var in t_vars if 'd_' in var.name]
  4. self.g_vars = [var for var in t_vars if 'g_' in var.name]

ここで、ADAM 最適化を使用してパラメータの最適化を開始します。これは、SGD と非常に競争力のある適応型非凸最適化手法であり、通常、学習率、運動量、およびその他のハイパーパラメータの手動調整を必要としません。

  1. d_optim = tf .train.AdamOptimizer(config.learning_rate, beta1 = config .beta1) \
  2. .minimize(self.d_loss, var_list = self.d_vars )を最小化します。
  3. g_optim = tf .train.AdamOptimizer(config.learning_rate, beta1 = config .beta1) \
  4. .minimize(self.g_loss, var_list = self.g_vars )を最小化します。

次に、データを反復処理します。各反復で、データのミニバッチをサンプリングし、オプティマイザーを使用してネットワークを更新します。興味深いことに、G が 1 回だけ更新された場合、識別器の損失は 0 になりません。また、これらの値はすでに d_optim と g_optim で計算されているため、d_loss_fake と d_loss_real への最後の呼び出しでは不要な計算が実行されると思います。 Tensorflow の連絡先として、この部分を最適化し、元のリポジトリに PR を送信してみてください。

  1. エポック inxrange(config.epoch) の場合:
  2. ...
  3. xrange(0, batch_idxs) 内の idx の場合:
  4. batch_images = ...
  5.   
  6. batch_z = np .random.uniform(-1, 1,[config.batch_size, self.z_dim]) \
  7. .astype(np.float32)
  8.   
  9. # Dネットワークを更新
  10. _, summary_str = self .sess.run([d_optim, self.d_sum],
  11. feed_dict = { self.images:batch_images, self.z:batch_z })
  12.   
  13.   
  14. # Gネットワ​​ークを更新
  15. _, summary_str = self .sess.run([g_optim, self.g_sum],
  16. feed_dict = { self.z: batch_z })
  17.   
  18.   
  19. # g_optim を 2 回実行して、d_loss がゼロにならないことを確認します (論文とは異なります)
  20. _, summary_str = self .sess.run([g_optim, self.g_sum],
  21. feed_dict = { self.z: batch_z })
  22.   
  23.   
  24. errD_fake = self .d_loss_fake.eval({self.z: batch_z})
  25. errD_real = self .d_loss_real.eval({self.images: batch_images})
  26. errG = self .g_loss.eval({self.z:batch_z})

終わり!もちろん、完全なコードにはさらに多くのコメントが含まれており、model.py で確認できます。

7. 画像セットに対してDCGANを実行する

前のセクションをスキップしたが、コードを試してみたい場合は、bamos/dcgan-completion.tensorflow Github リポジトリで入手できます。このコードは Taehoon Kim による carpedm20/DCGAN-tensorflow からのものであることを再度強調しておきます。次のステップに進む方が便利なので、ここでは私のライブラリを使用します。警告: CUDA 対応の GPU がない場合、ネットワークのこの部分のトレーニングは非常に遅くなります。

まず、私の bamos/dcgan-completion.tensorflow Github リポジトリをクローンし、OpenFace をローカルにクローンします。 OpenFace の Python のみの部分を使用して、画像の前処理を実行します。心配しないでください。OpenFace の Torch 依存関係をインストールする必要はありません。新しいディレクトリを作成し、次のリポジトリをクローンします。

  1. git クローンhttps://github.com/cmusatyalab/openface.git
  2.  
  3. git クローンhttps://github.com/bamos/dcgan-completion.tensorflow.git

次に、Python2 をサポートする OpenCV と dlib をインストールします。興味があれば、python3 の dlib サポートを実装してみてください。インストールにはいくつかヒントがあり、OpenFace セットアップ ガイドに、インストールしたバージョンやインストール方法などのメモをいくつか書きました。次に、画像を前処理できるように OpenFace Python ライブラリをインストールします。仮想環境を使用していない場合は、setup.py を実行してグローバルにインストールするときに sudo を使用する必要があります。 (この部分が難しい場合は、OpenFace の Docker インストールを使用することもできます。)

顔画像データセットをダウンロードしましょう。データセットに注釈があるかどうかは関係なく、削除されます。網羅的ではないリストは次のとおりです: MS-Celeb-1M、CelebA、CASIA-WebFace、FaceScrub、LFW、MegaFace。データセットの生データであることを示すために、画像を dcgan-completion.tensorflow/data/your-dataset/raw ディレクトリに配置します。

ここで、OpenFace の位置合わせツールを使用して、画像を 64X64 データに前処理します。

  1. ./openface/util/align-dlib.pydata/dcgan-completion.tensorflow/data/your-dataset/raw aligninnerEyesAndBottomLipdata/dcgan-completion.tensorflow/data/your-dataset/aligned --size 64

最後に、処理済みの画像を含むディレクトリをフラット化して、サブフォルダーがなく、画像のみが含まれるようにします。

  1. cddcgan-completion.tensorflow/data/your-dataset/aligned
  2.  
  3. find . -name'*.png' -exec mv {} . \;
  4.  
  5. 検索 . -type d-empty -delete
  6.  
  7. CD ../../..

これで、DCGAN をトレーニングできます。 Tensorflow をインストールしてトレーニングを開始します。

  1. ./train-dcgan.py --dataset ./data/your-dataset/aligned --epoch 20

ジェネレータからランダムにサンプリングされたサンプル画像がサンプル フォルダーでどのように見えるかを確認できます。手元にあった CASIA-WebFace データセットと FaceScrub データセットでトレーニングしました。 14 ラウンドのトレーニング後、サンプルは次のようになりました。

CASIA-WebFace と FaceScrub で 14 エポックのトレーニングを行った後の DCGAN のサンプル

TensorBoard で Tensorflow グラフと損失関数を表示することもできます。

  1. テンソルボード --logdir ./logs

TensorBoard 損失の視覚化。トレーニング中にリアルタイムで更新されます。

DCGAN ネットワークの TensorBoard 可視化

ステップ3: 画像補完に最適な疑似画像を見つける

1. DCGANを使用した画像補完

識別器 D(x) と生成器 G(z) ができたので、これを画像補完にどのように使用すればよいでしょうか。この章では、RaymondYeh、Chen Chen らによる論文「知覚的損失と文脈的損失によるセマンティック画像インペインティング」を紹介します。この論文は2016年7月26日にarXivに掲載されました。

特定の画像 y の場合、欠落しているピクセルの D(y) を最大化することが合理的だが実現不可能な解決策です。結果は、データ分布 (pdatapdata) でも生成された分布 (pgpg) でもありません。私たちが望むのは、y を生成分布に投影することです。

(a) 生成された分布(青い表面)からの y の理想的な再構築。 (b) D(y)を最大化してyを再構築しようとして失敗した例。 Image Inpainting 論文からの画像。

2. [ML-Heavy] pgpgへの投影の損失関数

投影の適切な定義を与えるために、まず画像補完のためのいくつかの表記法を定義します。 0 と 1 の 2 つの値のみを持つバイナリ マスク M (マスク) を使用します。値が 1 の場合、画像のこの部分を保持することを示し、値が 0 の場合、この部分を完了することを示します。ここで、バイナリマスク M が与えられた場合に y を完了する方法を定義できます。 y の要素を M の要素で乗算します。 2 つの行列の対応する位置にある要素の乗算は、アダマール積とも呼ばれ、M⊙yM⊙y で表されます。 M⊙yM⊙yは画像の元部分を表します。

バイナリマスクの凡例

次に、欠損値を再構築する適切な G(z^)G(z^) を生成できる z^z^ を見つけたと仮定します。完成したピクセル(1−M)⊙G(z^)(1−M)⊙G(z^)を元のピクセルに追加して再構成された画像を得ることができます。

  1. x再構成= M ⊙y+(1−M)⊙G(z^) x再構成= M ⊙y+(1−M)⊙G(z^)

ここで私たちがしなければならないことは、画像を完成させるのに適した G(z^)G(z^) を見つけることです。 z^z^ を見つけるために、この記事の冒頭で述べたコンテキストと認識を思い出し、それらを DCGAN のコンテキストとして使用します。この目的のために、任意のz∼pzz∼pzに対して損失関数を定義します。損失関数が小さいほど、z^z^ は適切になります。

コンテキスト損失: 入力画像と同じコンテキストを取得するには、既知のピクセル位置 y に対応する G(z)G(z) が可能な限り類似していることを確認する必要があります。したがって、G(z) の出力が y の既知の位置の画像と類似していない場合、G(z) にペナルティを課す必要があります。これを行うには、y の対応する位置にあるピクセルを G(z) から減算し、それらの相違点を調べます。

  1. L文脈(z)=||M⊙G(z)−M⊙y||L文脈(z)=||M⊙G(z)−M⊙y||

ここで、||x||1=∑i|xi|||x||1=∑i|xi| はベクトル x の l1l1 ノルムです。 l2l2 規範も望ましいですが、この論文では、実践では l1l1 規範の方が効果的であることが示されていると指摘しています。

理想的には、既知の部分 y と G(z) のピクセルは等しくなります。つまり、既知の位置にあるピクセルiについて、

  1. ||M⊙G(z)i−M⊙yi||=0||M⊙G(z)i−M⊙yi||=0 、Lcontextual(z)=0Lcontextual(z)=0

知覚損失: 本物に見える画像を再構築するには、識別器が画像が本物に見えると判断できるようにする必要があります。これを行うには、DCGAN のトレーニングと同じ手順に従います。

  1. L知覚的(z)=log(1−D(G(z)))L知覚的(z)=log(1−D(G(z)))

最後に、文脈的損失と知覚的損失を組み合わせることで、z^z^; を見つけることができます。

  1. L(z)=L文脈(z)+λL知覚(z)z^=argminzL(z)L(z)=L文脈(z)+λL知覚(z)z^=argminzL(z)

ここで、λ は知覚損失に対する文脈損失の重要性を制御するハイパーパラメータです。 (私はデフォルトの λ=0.1λ=0.1 を使用し、この値を詳細に調整しませんでした。) 次に、G(z) を使用して、以前と同じように y の欠落部分を再構築します。

  1. L文脈(z)=||M⊙G(z)−M⊙y||L文脈(z)=||M⊙G(z)−M⊙y||

この画像では、ポアソンブレンディングを使用して画像を滑らかにしています。

3. [ML-Heavy] TensorFlow を使用した DCGAN 画像補完

この章では、画像補完のための Taehoon Kim の carpedm20/DCGAN-tensorflow コードに対する私の変更点について説明します。

  1. self.mask = tf .placeholder(tf.float32, [なし] + self.image_shape, name = 'mask' )

勾配∇zL(z)∇zL(z)に対して勾配降下法を実行することで、argminzL(z)argminzL(z)を反復的に見つけることができます。損失関数を定義すると、Tensorflow の自動微分によってこの値が自動的に計算されます。したがって、既存の DCGAN 実装に 4 行の Tensorflow コードを追加するだけで、完全な DCGAN ベースの実装が完成します。 (もちろん、これを実装するには Tensorflow 以外のコードも必要です。)

  1. 自己.コンテキスト損失= tf.reduce_sum (  
  2. tf.contrib.layers.flatten() は、  
  3. tf.abs(tf.mul(self.mask, self.G) -tf.mul(self.mask, self.images))), 1)  
  4. 自己self.perceptual_loss = self.g_loss  
  5. 自己自己.完全損失= 自己.文脈損失 + 自己.lam*自己.知覚損失 
  6. self.grad_complete_loss = tf.gradients (self.complete_loss、self.z)の計算結果です。

次に、マスクを定義します。画像の中央領域に 1 つ追加しましたが、ランダム マスクなど、他のものを追加して、プル リクエストを送信することもできます。

  1. ifconfig.maskType == 'center':  
  2. スケール= 0.25  
  3. アサート(スケール< = 0.5)  
  4. マスク= np.ones (self.image_shape)  
  5. l = int (self.image_size*スケール)  
  6. u = int (self.image_size*(1.0-スケール))  
  7. マスク[l:u, l:u, :] = 0.0

勾配降下法では、zを[-1, 1]に投影するために、運動量を使用したミニバッチ投影勾配降下法を使用します。

  1. idx inxrange(0, batch_idxs)の場合:
  2. batch_images = ...
  3. batch_mask = np .resize(mask,[self.batch_size] + self.image_shape)
  4. zhats = np .random.uniform(-1, 1,サイズ=(self.batch_size, self.z_dim))
  5.   
  6. 0 = 0です 
  7. xrange(config.nIter) 内の i の場合:
  8. fd = {
  9. self.z: zhats、
  10. 自己マスク: バッチマスク、
  11. self.images: バッチイメージ、
  12. }
  13. 実行= [self.complete_loss,self.grad_complete_loss, self.G]
  14. 損失、g、 G_imgs = self .sess.run(run、 feed_dict = fd )
  15.   
  16. v_prev = np .copy(v)
  17. v = config.momentum *v - config.lr*g[0]
  18. zhats += -config.momentum * v_prev +(1+config.momentum)*v
  19. zhats = np .clip(zhats, -1, 1)

4. 画像を完成させる

画像補完用にいくつかの画像を選択し、 dcgan-completion.tensorflow/your-test-data/raw に配置します。次に、dcgan-completion.tensorflow/your-test-data/aligned で前と同じようにアラインします。ここではLFWからランダムにいくつかの画像を選びました。私の DCGAN は LFW 画像を使用してトレーニングされていません。

次のようにして画像を完成させることができます。

  1. ./complete.py ./data/your-test-data/aligned/* --outDir 出力画像

このコードは画像を生成し、定期的に --outDir フォルダーに出力します。 ImageMagick を使用して gif を生成できます。

  1. cd 出力画像
  2. 変換 -delay10 -loop 0 完了/*.png 完了.gif

最終画像の完了。画像の中心は自動的に生成されます。ソースコードはここからダウンロードできます。 LFWからランダムに選んだサンプルです。

V. 結論

読んでくれてありがとう、この記事では、画像の完成方法を取り上げました。

1.確率の分布として画像を理解する。

2。偽の画像を生成します。

3.完了に最適な擬似画像を見つけます。

私の例は顔でしたが、DCGANは他のタイプの画像でも使用できます。一般に、GANはトレーニングが困難であり、特定のクラスのオブジェクトでそれらをトレーニングする方法、または大きな画像でそれらをトレーニングする方法は明確ではありません。しかし、これは大きな可能性を秘めたモデルであり、Gansが将来私たちのために何を作成するかを見て興奮しています!

オリジナル記事: http://bamos.github.io/2016/08/09/deep-completion/?utm_source =mybridge&utm_medium=blog&utm_campaign = read_more

[この記事は51CTOコラムBig Data Digest、WeChatパブリックアカウント「Big Data Digest(id: BigDataDigest)」のオリジナル翻訳です]

この著者の他の記事を読むにはここをクリックしてください

<<:  いつ表面的に調べ、いつ深く掘り下げるべきか - 機械学習は1ページで説明できるものではありません

>>:  機械学習とディープラーニングとは何ですか?ファイザン・シャイクがお手伝いします

ブログ    

推薦する

SCO Unix ディスク ブロック割り当てアルゴリズム

私は Unix オペレーティング システムに関する知識を頻繁に学んでおり、Unix オペレーティング...

米国労働統計局は機械学習を使用してデータコーディングを自動化しています

政府機関には常にさまざまな文書が詰まっていますが、その多くは紙の文書であり、電子文書であっても、実際...

ICLR 2022: AI が「目に見えないもの」を認識する方法

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

...

自然言語処理の他に、Word2Vec で何ができるのでしょうか?

機械学習の手法を使用して問題を解決する場合、適切なデータを持つことが重要です。残念ながら、生データは...

崑崙Core2が量産開始:性能が2~3倍向上し、中国の産業知能に強力な「コア」を注入

8月18日、百度とCCTVニュースは共同で「百度ワールド2021」カンファレンスを開催し、AIが何千...

顧客の声: AI はあなたにとって優先事項ですか? データ戦略から始める必要があります

[[337768]]現在、世界中のあらゆる部門が人工知能(AI)の研究を行っています。 AI の画...

...

キング・オブ・グローリーのプレイからサッカーのプレイまで、テンセントのAIが再び進化

テンセントは12月30日、同社の人工知能チームが第1回Google Football Kaggleコ...

ビジネスリーダーが AI を活用して人々の心をつかみ、成果を上げる 5 つの方法

AI がリーダーシップ能力を強化できるとしたらどうでしょうか? チームをより深く理解し、チームのニー...

爆発力で動く昆虫ロボットは、自重の22倍を運ぶことができ、垂直に59cmジャンプできる。

この小さなロボットはエネルギーに溢れています。体は昆虫ほどの大きさですが、自分の体重の22倍の重さの...

...

...

TensorFlow、危険です! Google自身が放棄している

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...