TensorFlow とオートエンコーダー モデルを使用して手書き数字を生成する方法

TensorFlow とオートエンコーダー モデルを使用して手書き数字を生成する方法

[[209419]]

オートエンコーダーは、入力データを効率的にエンコードする方法を学習するために使用できるニューラル ネットワークです。ニューラル ネットワークは、何らかの入力が与えられると、まず一連の変換を使用してデータを低次元空間にマッピングします。ニューラル ネットワークのこの部分はエンコーダーと呼ばれます。

次に、ネットワークはエンコードされた低次元データを使用して入力を再構築しようとします。ネットワークのこの部分はデコーダーと呼ばれます。エンコーダーを使用して、データをニューラル ネットワークが理解できる形式に圧縮できます。ただし、通常はより効率的な手書きのアルゴリズム (jpg 圧縮など) があるため、オートエンコーダーがこの目的で使用されることはほとんどありません。

さらに、オートエンコーダはノイズ除去タスクを実行するためによく使用され、元の画像を再構築する方法を学習できます。

変分オートエンコーダとは何ですか?

オートエンコーダに関連する興味深いアプリケーションは数多くあります。

そのうちの 1 つは変分オートエンコーダと呼ばれます。変分オートエンコーダを使用すると、単にデータを圧縮するだけでなく、オートエンコーダがこれまでに遭遇した新しいオブジェクトを生成することもできます。

一般的なオートエンコーダを使用する場合、ネットワークによって生成される特定のエンコーディングが何であるかはわかりません。異なるエンコーディング オブジェクトを比較することはできますが、内部的にどのようにエンコードされているかを理解することはほぼ不可能です。つまり、エンコーダーを使用して新しいオブジェクトを生成することはできません。入力がどのようになるかさえわかりません。

変分オートエンコーダを使用した逆のアプローチを使用します。潜在ベクトルの分布に注意を払う必要はなく、ネットワークにどのような分布を望むかを伝えるだけで済みます。

通常、単位正規分布特性を持つ潜在ベクトルを生成するようにネットワークを制約します。次に、データを生成するときに、この分布からサンプルを採取し、そのサンプルをデコーダーに渡すだけで、ネットワークのトレーニングに使用したオブジェクトとまったく同じ新しいオブジェクトが返されます。

以下では、Python と TensorFlow を使用してこれを行う方法について説明します。ネットワークに MNIST 文字を描画するように教えます。

最初のステップはトレーニングデータをロードすることです

まず、いくつかの基本的なインポート操作を実行しましょう。 TensorFlow には、MNIST データセットに簡単にアクセスできる非常に便利な関数があります。

  1. tensorflow をtfimportとしてインポートし、numpy を npiimportとしてインポートし、matplotlib.pyplotpltとしてインポートします。
  2.  
  3. %matplotlib インラインから tensorflow.examples.tutorials.mnist インポート input_data
  4.  
  5. mnist = input_data.read_data_sets( 'MNIST_data' )

入力データと出力データの定義

MNIST 画像の寸法は 28 x 28 ピクセルで、モノクロ チャネルのみです。入力データ X_in は MNIST 文字のバッチであり、ネットワークはそれらを再構築する方法を学習します。次に、入力と同じ次元を持つ出力で、プレースホルダー Y にそれらを出力します。

Y_flat は後で損失関数を計算するときに使用され、keep_prob はドロップアウトを適用するときに(正規化方法として)使用されます。トレーニング中は、その値は 0.8 に設定されます。新しいデータを生成するときは、ドロップアウトを使用しないため、その値は 1 になります。

TensorFlow には定義済みの Leaky ReLU 関数がないため、lrelu 関数を独自に定義する必要があります。

  1. tf.reset_default_graph()
  2.  
  3. batch_size = 64 X_in = tf.placeholder(dtype=tf.float32, shape=[None, 28, 28], name = 'X' )
  4. Y = tf.placeholder(dtype=tf.float32, shape=[なし, 28, 28],名前= 'Y' )
  5. Y_flat = tf.reshape(Y, 形状=[-1, 28 * 28])
  6. keep_prob = tf.placeholder(dtype=tf.float32, shape=(), name = 'keep_prob' ) です。
  7.  
  8. dec_in_channels = 1n_latent = 8reshaped_dim = [-1, 7, 7, dec_in_channels]
  9. inputs_decoder = 49 * dec_in_channels / 2def lrelu(x, alpha=0.3): return tf.maximum(x, tf.multiply(x, alpha))

エンコーダの定義

入力は画像なので、畳み込み変換を使用する方が合理的です。最も注目すべき点は、エンコーダーはガウス分布に従うオブジェクトを作成する必要があるため、エンコーダー内に 2 つのベクトルを作成することです。

  • 1つは平均ベクトル
  • 1つは標準偏差ベクトルである

後で、エンコーダーが正規分布に従うデータ ポイントを実際に生成するように「強制」する方法を説明します。デコーダーに入力されるエンコードされた値は、z として表すことができます。損失関数を計算するときは、選択した分布の平均と標準偏差が必要になります。

  1. エンコーダの定義(X_in、keep_prob):
  2. activation = lrelutf.variable_scope( "encoder" 、reuse=None):
  3. X = tf.reshape(X_in、形状=[-1、28、28、1])
  4. x = tf.layers.conv2d(X、フィルター=64、カーネルサイズ=4、ストライド=2、パディング= 'same' 、アクティベーション=アクティベーション)
  5. x = tf.nn.dropout(x, keep_prob)
  6. x = tf.layers.conv2d(x, フィルター=64, カーネルサイズ=4, ストライド=2, パディング= 'same' , アクティベーション=アクティベーション)
  7. x = tf.nn.dropout(x, keep_prob)
  8. x = tf.layers.conv2d(x, フィルター=64, カーネルサイズ=4, ストライド=1, パディング= 'same' , アクティベーション=アクティベーション)
  9. x = tf.nn.dropout(x, keep_prob)
  10. x = tf.contrib.layers.flatten(x)
  11. mn = tf.layers.dense(x, 単位=n_latent)
  12. sd = 0.5 * tf.layers.dense(x, 単位=n_latent)
  13. イプシロン = tf.random_normal(tf.stack([tf.shape(x)[0], n_latent]))
  14. z = mn + tf.multiply(イプシロン、tf.exp(sd))
  15. z、mn、sdを返す

デコーダーの定義

デコーダーは、入力値が定義した特定の分布からサンプリングされたかどうかを気にしません。単純に入力画像を再構築しようとします。最後に、一連の転置畳み込みを使用します。

  1. def デコーダー(sampled_z, keep_prob): tf.variable_scope ( "デコーダー" 、reuse=None):
  2. x = tf.layers.dense(sampled_z、単位=inputs_decoder、アクティベーション=lrelu)
  3. x = tf.layers.dense(x, 単位 = inputs_decoder * 2 + 1, アクティベーション = lrelu)
  4. x = tf.reshape(x, reshaped_dim)
  5. x = tf.layers.conv2d_transpose(x、フィルター=64、カーネルサイズ=4、ストライド=2、パディング= 'same' 、アクティベーション=tf.nn.relu)
  6. x = tf.nn.dropout(x, keep_prob)
  7. x = tf.layers.conv2d_transpose(x、フィルター=64、カーネルサイズ=4、ストライド=1、パディング= 'same' 、アクティベーション=tf.nn.relu)
  8. x = tf.nn.dropout(x, keep_prob)
  9. x = tf.layers.conv2d_transpose(x、フィルター=64、カーネルサイズ=4、ストライド=1、パディング= 'same' 、アクティベーション=tf.nn.relu)
  10.          
  11. x = tf.contrib.layers.flatten(x)
  12. x = tf.layers.dense(x, 単位=28*28, 活性化=tf.nn.sigmoid)
  13. img = tf.reshape(x, shape=[-1, 28, 28])画像を返す

ここで、2 つの部分を接続します。

  1. サンプリング、mn、sd = エンコーダ(X_in、keep_prob)
  2.  
  3. dec = デコーダー(サンプリング、keep_prob)

損失関数を計算し、ガウス隠れ分布を実装する

画像再構成の損失関数を計算するために、単純に二乗差を使用しました (これにより、画像が少しぼやけることがあります)。この損失関数には KL ダイバージェンスも組み込まれており、これにより、隠し値が標準分布からサンプリングされることが保証されます。このトピックについて詳しく知りたい場合は、この記事 (https://jaan.io/what-is-variational-autoencoder-vae-tutorial/) をご覧ください。

  1. 再形成しない = tf.reshape( dec , [-1, 28*28])
  2. img_loss = tf.reduce_sum(tf.squared_difference(未整形, Y_flat), 1)
  3. 潜在損失 = -0.5 * tf.reduce_sum(1.0 + 2.0 * sd - tf.square(mn) - tf.exp(2.0 * sd), 1)
  4. 損失 = tf.reduce_mean(img_loss + latent_loss)
  5. オプティマイザー = tf.train.AdamOptimizer(0.0005).minimize(損失)
  6. sess = tf.Session()
  7. sess.run(tf.global_variables_initializer())

ネットワークのトレーニング

これで、ついに VAE をトレーニングできるようになりました。

200 ステップごとに、現在の再構築がどのようになっているかを確認します。約 2000 回の反復の後、ほとんどの再構築は妥当なものに見えました。

  1. iが範囲(30000)内にある場合:
  2. バッチ = [np.reshape(b, [28, 28])、 bの場合、mnist.train.next_batch (batch_size=batch_size)[0]]
  3. sess.run(オプティマイザー、feed_dict = {X_in: バッチ、Y: バッチ、keep_prob: 0.8})
  4. そうでない場合i % 200:
  5. ls、d、i_ls、d_ls、mu、sigm = sess.run([loss、 dec 、img_loss、dst_loss、mn、sd]、feed_dict = {X_in: batch、Y: batch、keep_prob: 1.0})
  6. plt.imshow(np.reshape(バッチ[0]、[28, 28])、cmap= 'グレー' )
  7. plt.show()
  8. plt.imshow(d[0], cmap= '灰色' )
  9. plt.show()
  10. print(i, ls, np.mean(i_ls), np.mean(d_ls))

新しいデータを生成する

最も驚くべきことは、新しいキャラクターを生成できるようになったことです。最後に、単位正規分布から値をサンプリングし、それをデコーダーに入力します。生成された文字のほとんどは人間の手書き文字と同一です。

  1. ランダム = [np.random.normal(0, 1, n_latent) _範囲(10)]
  2. imgs = sess.run( dec 、 feed_dict = {sampled: randoms、 keep_prob: 1.0}) です。
  3. imgs = [np.reshape(imgs[i], [28, 28])、 i がrange(len(imgs))内にある場合img がimgs内にある場合:
  4. plt.figure(図サイズ=(1,1))
  5. plt.axis( 'オフ' )
  6. plt.imshow(画像、cmap= 'グレー' )

一部自動生成された文字。

要約する

これは、VAE アプリケーションの非常に単純な例です。しかし、可能性を想像してみてください。ニューラル ネットワークは音楽の作曲を学習でき、本やゲームの説明を自動的に作成できます。革新的な思考により、VAE は斬新なプロジェクトのためのスペースを創出できます。

<<:  AIは敵ではなく友達でしょうか?自殺防止技術が25人の命を救うことに成功

>>:  Python の高レベル自然言語処理ライブラリである SpaCy は、世界最速の構文解析ツールとして知られています。

ブログ    
ブログ    
ブログ    

推薦する

...

AI+CRMの啓示:人工知能は、アプリケーションシナリオに実装された場合にのみ、大きな可能性を発揮できます。

[51CTO.comより] 両会期中の政府活動報告に人工知能が盛り込まれた。万鋼科学技術部長は、中...

オックスフォード大学の最新調査:AIはベンチマーク危機に直面し、NLPは推論テストの「取り組み」に注力

人工知能 (AI) ベンチマークは、モデルを測定および比較するための方法を提供します。ベンチマークを...

舌先にAI

世界中の食べ物は、まさに世界の花火のボウルに過ぎません。人工知能は、新しい技術科学として、日常生活に...

人工知能の分野に早く参入したいJavaプログラマーですか?準備はできたか?

導入今日は、Java プログラマーとして人工知能の分野に素早く参入する方法について説明します。現在、...

注目の話題 | 3年生が独力でAIモデルを解読

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

人工知能がビジネスを徐々に変えていく

確かに、人工知能(AI)主導のテクノロジーが人間を不要にするか否かをめぐる議論は、少なくともこの聴衆...

...

AI に「大きな力と小さな心」を与える - ユニバーサル CNN アクセラレーション設計

[[207759]]導入FPGA ベースの汎用 CNN アクセラレーション設計により、FPGA 開発...

...

...

マイクロソフトCEOナデラ氏:AIはルールを変えるインターネットの波のようなもの

8月18日、マイクロソフトが人工知能(AI)技術の研究開発に注力し、OpenAIに100億ドル以上を...

求人検索サイトIndeedの統計:AI採用は減速、求職者の関心は低下

6月末、わが国各省市で大学入試結果が次々と発表される中、学生の専攻選択は統計的な傾向に新たな波を起こ...

7つのダイナミックなトレンドが将来のAIサービス市場を形作る

[Lieyun.com (WeChat ID: )] 9月14日レポート(小白訳)ソフトウェアは世界...