ニューラルネットワークで多クラス分類をする場合、出力層として分類したいクラスの数と同じ次元のベクトルを出力する。訓練時にはその出力に対して、教師ラベルに対応する要素だけが1で他は0であるOne hotベクトルを教師データとすることで学習させることができる。
TensorflowのMNISTチュートリアルではデータの読み込み時にnumpy
の関数を使ってラベルからOne hotベクトルをあらかじめ作成しているが、Tensforflowのone_hot
関数を使えばラベルを直接入力することができる(one_hot
は後からAPIに追加された模様)。
使い方
import tensorflow as tf
labels = tf.placeholder(tf.int64, [None]) y_ = tf.one_hot(labels, depth=3, dtype=tf.float32)
|
- 教師ラベルを入力するプレースホルダー
labels
を作り、それをtf.one_hotに渡せばよい。
depth
に分類するクラスの数を指定する。
動かしてみる
with tf.Session() as sess: sess.run(tf.initialize_all_variables()) teacher = [1, 2, 0] print sess.run(y_, feed_dict={labels: teacher})
|
- 試しに
[1, 2, 0]
を教師ラベルとしてlabels
に与えてやると、One hotベクトル化されたテンソル[[ 0. 1. 0.], [ 0. 0. 1.], [ 1. 0. 0.]]
が出力される。
訓練で使用
- 出力された
y_
を使えば後はチュートリアルと同様に、NNの出力結果y
を使って二乗誤差やクロスエントロピーでコストを計算してやれば訓練できる。
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
|
判定で使用
- 認識率をNNの出力結果の一番大きな要素が教師ラベルと等しいかどうかで計算するが、その際tf.argmaxが
int64
型で出力するので、教師ラベルのプレースホルダーlabels
もint64
で作成しておくと都合がいい。
tf.argmax(y_, 1)
で教師ラベルを復元する必要はなく、直接labels
とequal
で比較すればよい
correct_prediction = tf.equal(tf.argmax(y, 1), labels) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
|