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 は、世界最速の構文解析ツールとして知られています。

ブログ    
ブログ    
ブログ    

推薦する

図 | 武術の観点から STL ソート アルゴリズムの秘密を探る

[[410325]]この記事はWeChatの公開アカウント「Backend Research Ins...

AI人工知能は研究室から生産現場へと進出したが、依然として大きな課題に直面している。

国内企業におけるAI導入の現状アクセンチュアが世界各国の企業幹部を対象に実施した「中国企業はどのよう...

キングソフトAIラボが最初の実装計画を発表、AIの最も難しい部分を選択した

[[255298]] 「2014年に私は、30年前に設立されたKingsoft WPSは雷軍によって...

顔認識技術の原理と応用展望の分析

顔認識技術は人間の顔の特徴に基づいています。まず、入力された顔画像またはビデオ ストリームに顔がある...

...

「ブラックスワン」の翼の下で:情報戦場におけるAIの光と影

[51CTO.comからのオリジナル記事] 突然の流行に直面して、国民は情報の適時性、透明性、伝達効...

Google が基本世界モデルをリリース: 110 億のパラメータ、インタラクティブな仮想世界を生成可能

Sora がリリースされてからまだ 2 週間も経っていないが、Google の世界モデルが登場し、そ...

AI スタートアップはどうすれば成功できるのでしょうか?ガートナー:「以下の点が不可欠」

[[430175]]デジタル変革の波を受けて、さまざまな新興技術が急速に応用され、普及してきました...

なぜロボット起業のチャンスはBサイドにあると言われるのでしょうか?

技術の変化のスピードは常に保守派の想像を超えています。 [[348702]]多くの人々の直感では、過...

ChatGPTは人間よりも優れているか? - チューリングテストの観点からの議論

翻訳者|朱 仙中レビュー | Chonglou概要:機械は考えることができるか?この論文では、この問...

学ぶ価値のある Github 上の 7 つの AI プロジェクト

「Python を学ぶ大きな楽しみの 1 つは、人工知能を学ぶことです。Lao K が GitHub...

人工知能 (AI) は、研究室から実際のアプリケーションまでどのように異なるのでしょうか?

人工知能が実際の応用に入ると、遭遇する問題のほとんどは複雑になります。 しかし、現段階では、人工知能...

...