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

ブログ    
ブログ    
ブログ    
ブログ    
ブログ    

推薦する

...

CUDA と TensorRT モデルの展開の最適化: 重要な考慮事項と実践的な戦略

この記事は、Heart of Autonomous Driving の公開アカウントから許可を得て転...

チップレベルのエッジAIが次世代のIoTを推進

エッジ コンピューティングは、IT アーキテクトや組み込み開発者にさまざまな選択肢を提示する難しい問...

...

Adobe、フォトショップで加工された人間の顔を自動検出できるAIツールを開発

偽の動画や画像の拡散に対する懸念は世界中で高まっており、Adobe もその懸念を共有していると述べて...

2020 年の予測: 今年はサイバー犯罪サービスが普及する年になるか?

業界メディアeWEEKの2020年の予測:人工知能と機械学習の「中毒」についての予測も見られ、これが...

Kindred AIは、ロボットをより賢くするために、人々にVRメガネをかけて訓練することを望んでいる

(原題: Kindred AI は強化学習を利用して、人間やサルに VR メガネをかけてロボットを訓...

2021 年に注目すべき 5 つのロボティック プロセス オートメーション (RPA) トレンド

過去2、3年で、中国におけるロボティック・プロセス・オートメーション(RPA)の応用は急速に拡大しま...

人工知能はどこにでもありますが、計画とコーディングは始めましたか?

人々は「ソフトウェア 2.0」の時代に入りつつあります。人工知能、ディープラーニング、機械学習、高度...

最新レビュー!拡散モデルと画像編集の愛憎関係

この記事は、Heart of Autonomous Driving の公開アカウントから許可を得て転...

...

分散ストレージシステムにおけるDHTアルゴリズムの改善

1. 概要通常、分散ストレージ システムや分散キャッシュ システムでは、分散ハッシュ (DHT) ア...

脳に埋め込まれたAIチップはてんかん発作を予測し、2時間で充電して1週間持続する

脳にAIチップを埋め込むことで、てんかん発作をいつでも予測し、制御できるようになります。これは、我が...

中国の博士課程の学生が、2つのトランスフォーマーを使ってGANを構築しようとした。

[[382526]]最近、CV 研究者は変圧器に大きな関心を示し、多くのブレークスルーを達成しまし...

AIがプログラマーの仕事を奪う:2040年にはAIがプログラマーに取って代わる可能性

米国のオークリッジ国立研究所の一部専門家は、2040年までにAI技術がプログラマーに取って代わるほど...