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

ブログ    

推薦する

...

...

DeepMindがMuJoCoをオープンソース化!メタは「スケルトンハンド」にクルミをプレイさせるために使用されます

「クルミで遊んでいる」骸骨の手を見たことがありますか? この魔法の「手」は、Meta が新たにリリー...

LLaMAが使用するオープンソースデータセットは棚から削除されました。これには約20万冊の本が含まれており、OpenAIデータセットに匹敵します。

オープンソースのデータセットは著作権侵害のため棚から削除されました。例えば、LLaMA、GPT-J ...

...

ドローンの将来の用途

ドローンは、1960年代以降、政府と軍隊によるインテリジェントな戦闘装備の需要から生まれました。米軍...

...

イアン・マッシンガム:AWSはモノのインターネットと人工知能への投資を継続

[51CTO.com からのオリジナル記事] 先進的なクラウドサービスプロバイダーとして、AWS は...

AIはクラウドコンピューティング大手の次の競争の焦点となる

人工知能が今日の情報技術分野で最もホットな話題であることは疑いの余地がなく、情報産業を豊かにし、改善...

上位 10 の古典的なソート アルゴリズムの詳細な説明: バブル ソート、選択ソート、挿入ソート

[[377307]] 1. アルゴリズムの評価基準ソートアルゴリズムを説明する前に、まずアルゴリズム...

Kingsoft WPS Office 2019 正式リリース: Word、Excel、PPT を 1 つのソフトウェアで操作

7月3日、キングソフトは北京オリンピックタワーで「シンプル・クリエイティブ・シンプルではない」をテー...

3つの主要なSQL ServerアルゴリズムのI/Oコストの簡単な分析

1. ネストループ結合アルゴリズム:考え方は非常に単純かつ直接的です。関係 R の各タプル r を、...

機械学習を学ぶ必要がない5つの理由

機械学習を学び始めるべきだと言うインフルエンサーが増えています。彼らの言うことを聞くべきでしょうか?...

人工知能教育の現状と動向

人工知能への熱狂が世界を席巻している。国は人工知能の分野で戦略的な配置を開始しており、人工知能の人材...

...