Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

TensorFlowでAutoEncoderを可視化してみたよ

More than 3 years have passed since last update.

TensorFlow?

Google製の機械学習ライブラリTensorFlowを触りはじめました。
その名のとおり、テンソル(多次元配列)のデータフローを組み立てると、その計算グラフから自動微分してくれる仕組みを提供してくれるため、とてもディープラーニング(深層学習)と相性がいいです。
さらにTensorFlowにはTensorBoardというログ可視化ツールが付いていて、これが素晴らしいです。ちょっとしたコードで達成感が味わえるので、入門用にもうってつけです。
ということで私も『ディープラーニング勉強会 AutoEncoder』で勉強したDenoising AutoEncoderを、ザクッと実装して可視化してみました。今回はミニバッチ学習も取り入れてます。

TensorBoard!

TensorBoardで可視化したデータフローは、こんな感じになります。

GRAPHS

入力層にノイズをかけて、隠れ層でエンコードして、出力層でデコードして、入力と出力を比較して損失を計算する。という一連のフローがそのまま描かれていますね。
上図は分りやすいようにグルーピングしていて、たとえば隠れ層の「hidden」をクリックすると、もっと詳しいフローを見ることができます。

GRAPHS_hidden

重みを掛けて、バイアスを足して、活性化関数に食わせる、というニューラルネットワークの基本的な計算手順が、グラフとして描かれているのが面白いところですね。
Variableと表示されているノードは、自動微分による最適化の対象となります。

またTensorBoardは、他にもいろいろと可視化することができます。
今回はMNISTの手書き数字画像をAutoEncoderに学習させてみたので、本当に出力画像がノイズのかかった入力画像を引きもどせているのか確認したり、

IMAGES

学習が進むにつれ損失が減少していることを確認することもできます。

EVENTS

こうやって気軽に試行錯誤しながら、良さそうなモデルが出来たら、そのままGoogle Cloud Machine Learningで大規模データをブン回せると、とても楽しそうですね。夢が広がります。

実装

autoencoder.py
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

flags = tf.app.flags
FLAGS = flags.FLAGS
flags.DEFINE_integer('batch_size', 256, '')
flags.DEFINE_integer('epoch_num', 10, '')
flags.DEFINE_integer('hidden_num', 64, '')
flags.DEFINE_float('learning_rate', 0.01, '')
flags.DEFINE_float('noise_rate', 0.3, '')
flags.DEFINE_float('noise_strength', 0.2, '')
flags.DEFINE_string('summary_dir', 'summary', '')


def main():
    mnist_data = input_data.read_data_sets('MNIST_data', one_hot=True)

    with tf.name_scope('input'):
        input_layer = tf.placeholder(tf.float32, shape=[None, 784])
        input_summary = tf.image_summary('tag', tf.reshape(input_layer, [-1, 28, 28, 1]), 10)

    with tf.name_scope('noisy_input'):
        noise_layer = tf.maximum(tf.random_uniform(shape=tf.shape(input_layer),
                                                   minval=-FLAGS.noise_strength * (2 / FLAGS.noise_rate - 1),
                                                   maxval=FLAGS.noise_strength),
                                 -FLAGS.noise_strength)
        noisy_input_layer = tf.minimum(tf.maximum(input_layer + noise_layer, 0.0), 1.0)
        noisy_input_summary = tf.image_summary('tag', tf.reshape(noisy_input_layer, [-1, 28, 28, 1]), 10)

    with tf.name_scope('hidden'):
        w1 = tf.Variable(tf.random_uniform([784, FLAGS.hidden_num], minval=-1, maxval=1))
        b1 = tf.Variable(tf.zeros([FLAGS.hidden_num]))
        hidden_layer = tf.sigmoid(tf.matmul(noisy_input_layer, w1) + b1)

    with tf.name_scope('output'):
        w2 = tf.transpose(w1)
        b2 = tf.Variable(tf.zeros([784]))
        output_layer = tf.sigmoid(tf.matmul(hidden_layer, w2) + b2)
        output_summary = tf.image_summary('tag', tf.reshape(output_layer, [-1, 28, 28, 1]), 10)

    with tf.name_scope('loss'):
        loss = tf.nn.l2_loss(input_layer - output_layer)
        loss_summary = tf.scalar_summary('loss', loss)

    train_step = tf.train.GradientDescentOptimizer(FLAGS.learning_rate).minimize(loss)

    sess = tf.InteractiveSession()
    sess.run(tf.initialize_all_variables())

    if tf.gfile.Exists(FLAGS.summary_dir):
        tf.gfile.DeleteRecursively(FLAGS.summary_dir)

    input_writer = tf.train.SummaryWriter(FLAGS.summary_dir + '/input', sess.graph)
    noisy_input_writer = tf.train.SummaryWriter(FLAGS.summary_dir + '/noisy_input')
    output_writer = tf.train.SummaryWriter(FLAGS.summary_dir + '/output')

    step = 0
    while mnist_data.train.epochs_completed < FLAGS.epoch_num:
        step += 1
        images, _ = mnist_data.train.next_batch(FLAGS.batch_size)
        loss_result, _ = sess.run([loss_summary, train_step], feed_dict={input_layer: images})
        input_writer.add_summary(loss_result, step)

    input_result, noisy_input_result, output_result =\
        sess.run([input_summary, noisy_input_summary, output_summary], feed_dict={input_layer: images})
    input_writer.add_summary(input_result)
    noisy_input_writer.add_summary(noisy_input_result)
    output_writer.add_summary(output_result)


if __name__ == '__main__':
    main()
$ python autoencoder.py 
Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz

$ tensorboard --logdir=summary/

実行環境

$ python --version
Python 3.5.1
requirements.txt
numpy==1.11.1             # via tensorflow
protobuf==3.0.0b2         # via tensorflow
six==1.10.0               # via protobuf, tensorflow
tensorflow==0.9.0
wheel==0.29.0             # via tensorflow
piyo7
機械の言葉と、数学の言葉と、それから人間の言葉を喋るよ♪
https://piyo7.github.io/deep-sister/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away