tensorflowでクラス分類とtensorboadによるグラフの可視化
概要
tensorflowでirisデータを用いたクラス分類とそのグラフの可視化を行ったのでそのメモです。
今回使ったコードは以下のgistにあげました。
また以下の記事を参考に書いています。
IRIS Tensorboard編 · TensorFlow Docs
環境
環境は以下の通り。
- Mac 10.10.5
- Jupyter 4.3.0
- tensorflow 1.1.0
- pandas 0.20.3
- numpy 1.12.1
手順
ライブラリ読み込み
ライブラリはnumpy
、pandas
、tensorflow
を使います。
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」をクリックし以下のようなグラフが表示されれば成功です。