Deep Karmaning

技術系の話から日常のことまで色々と書きます

tensorflowでクラス分類とtensorboadによるグラフの可視化

概要

tensorflowでirisデータを用いたクラス分類とそのグラフの可視化を行ったのでそのメモです。

今回使ったコードは以下のgistにあげました。

iris_3class.ipynb · GitHub

また以下の記事を参考に書いています。

IRIS Tensorboard編 · TensorFlow Docs

環境

環境は以下の通り。

  • Mac 10.10.5
  • Jupyter 4.3.0
  • tensorflow 1.1.0
  • pandas 0.20.3
  • numpy 1.12.1

手順

ライブラリ読み込み

ライブラリはnumpypandastensorflowを使います。

import numpy as np
import pandas as pd
import tensorflow as tf

データ準備

irisデータを読み込んでランダムに並び替えます。ちなみにirisはここのもの を使っています。

# データセットの読み込み
dataset = pd.read_csv("data/iris.csv")
# データセットの順序をランダムに並べ替える
dataset = dataset.reindex(np.random.permutation(dataset.index)).reset_index(drop=True)

utility関数の定義

データセットインタフェースする関数を定義します。

def get_labels(dataset):
    """ラベル(正解データ)を1ofKベクトルに変換する"""
    raw_labels = dataset.iloc[:,4]
    labels = []
    for l in raw_labels:
        if l == "Iris-setosa":
            labels.append([1.0,0.0,0.0])
        elif l == "Iris-versicolor":
            labels.append([0.0,1.0,0.0])
        elif l == "Iris-virginica":
            labels.append([0.0,0.0,1.0])
    return np.array(labels)

def get_data(dataset):
    """データセットをnparrayに変換する"""
    raw_data = dataset.ix[:, :dataset.shape[1] - 1]
    return np.array(raw_data)

モデリング

次にモデリングです。

with tf.name_scope('dataset'):
    # ラベル
    labels = get_labels(dataset)
    # データ
    data = get_data(dataset)
    # 訓練データとテストデータに分割する
    # 訓練用データ
    train_labels = labels[:120]
    train_data = data[:120]
    # テスト用データ
    test_labels = labels[120:]
    test_data = data[120:]



### モデルをTensor形式で実装

with tf.name_scope('ph'):
    # ラベルを格納するPlaceholder
    t = tf.placeholder(tf.float32, shape = (None, 3), name = "y")
    # データを格納するPlaceholder
    X = tf.placeholder(tf.float32, shape=(None, 4), name = "X")

with tf.name_scope('hidden_layer1'):
    # 隠れ層のノード数
    node_num = 1024
    w_hidden = tf.Variable(tf.truncated_normal([4, node_num]))
    b_hidden = tf.Variable(tf.zeros([node_num]))
    f_hidden = tf.matmul(X, w_hidden) + b_hidden
    hidden_layer = tf.nn.relu(f_hidden)
    tf.summary.histogram("Hidden_layer_wights", w_hidden)
    tf.summary.histogram("Hidden_layer_biases", b_hidden)


with tf.name_scope('output1'):
    # 出力層
    w_output = tf.Variable(tf.zeros([node_num,3]))
    b_output = tf.Variable(tf.zeros([3]))
    f_output = tf.matmul(hidden_layer, w_output) + b_output
    p = tf.nn.softmax(f_output)
    tf.summary.histogram("Output_layer_wights", w_output)
    tf.summary.histogram("Output_layer_wights", b_output)



with tf.name_scope('loss'):
    # 誤差関数
    cross_entropy = t * tf.log(p)
    loss = -tf.reduce_mean(cross_entropy)
    tf.summary.scalar('loss', loss)


# トレーニングアルゴリズム
# 勾配降下法 学習率0.001
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
train_step = optimizer.minimize(loss)

with tf.name_scope('accuracy'):
    # モデルの予測と正解が一致しているか調べる
    correct_pred = tf.equal(tf.argmax(p, 1), tf.argmax(t, 1))
    # モデルの精度
    accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
    tf.summary.scalar('accuracy', accuracy)

with tf.name_scope():はなくてもよいのですが、こうった形でコードをまとめることで、tensorboadで可視化した際に可視性がよくなります。

またtf.summary.scalar()tf.summary.histogram()で、各パラメタを折れ線グラフや、ヒストグラムによって可視化することを指定します。全てのパラメタを指定したあとtf.summary.merge_all()‘(学習フェーズで実行する)が必要です。

学習

最後に学習です。

### 学習の実行
with tf.Session() as sess:
    # ログの設定
    summary = tf.summary.merge_all()

    writer = tf.summary.FileWriter("iris_cassification_log", sess.graph)
    sess.run(tf.global_variables_initializer())

    i = 0
    for _ in range(2000):
        i += 1
        # トレーニング
        sess.run(train_step, feed_dict={X:train_data,t:train_labels})
        # 200ステップごとに精度を出力
        if i % 200 == 0:
            # コストと精度を出力
            train_summary, train_loss, train_acc = sess.run([summary, loss, accuracy], feed_dict={X:train_data,t:train_labels})
            writer.add_summary(train_summary, i)
            print("Step: %d" % i)
            print("[Train] cost: %f, acc: %f" % (train_loss, train_acc))

tf.summary.merge_all()で先ほど可視化に指定したパラメタを一括で登録します。

またtf.summary.FileWriter("iris_cassification_log", sess.graph)でtensorbad用のログファイルを出力しています。

tensorboadの起動

ターミナルで、

tensorboard --logdir (出力したログの絶対パス) --port 6010

を実行し、アドレスバーで「localhost:6010」と入力し、右上の「GRAPH」をクリックし以下のようなグラフが表示されれば成功です。

f:id:rf00:20170916155541p:plain

参考資料

IRIS Tensorboard編 · TensorFlow Docs