skflowというscikit-learnのようにTensorFlowが使えるライブラリを使えばたった数行でIrisの分類ができるみたいだが、今回はTensorFlowの勉強のためにskflowは使わずに書いてみた。
MNIST For ML Beginnersを参考にしました。
環境
python==3.5.2
tensorflow==0.12.0
データを準備する
まずは必要なモジュールをインポート
import tensorflow as tf
from sklearn import datasets
from sklearn.model_selection import train_test_split
データセットを読み込む
iris = datasets.load_iris()
訓練用とテスト用にデータを分ける
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target)
MNISTのようにミニバッチ学習をするために、とりあえずデータを3つのセットに分けてみた。
k = [0, 38, 76, 112]
train_xs=train_ys=[]
for i in range(1, 4):
tmp_x=tmp_y=[]
for j in range(k[i-1], k[i]):
tmp_x, tmp_y = tmp_x + [X_train[j]], tmp_y + [y_train[j]]
train_xs, train_ys = train_xs + [tmp_x], train_ys + [tmp_y]
MNISTのように教師ラベルをone-hotベクトルに変換する。
train_labels = tf.placeholder(tf.int64, [None])
test_labels = tf.placeholder(tf.int64, [None])
train_ = tf.one_hot(train_labels, depth=3, dtype=tf.float32)
test_ = tf.one_hot(test_labels, depth=3, dtype=tf.float32)
モデル作成
Irisのデータは入力が4次元、出力が3次元になるので以下のようなモデルになった。
x = tf.placeholder(tf.float32, [None, 4])
W = tf.Variable(tf.zeros([4, 3]))
b = tf.Variable(tf.zeros([3]))
y = tf.nn.softmax(tf.matmul(x, W) + b)
モデル訓練
ミニバッチ学習でモデルの訓練をする。
with tf.Session() as sess:
sess.run(init)
ytest.append(sess.run(test_, feed_dict={test_labels: y_test}))
xtest = [sess.run(train_, feed_dict={train_labels: train_ys[i]}) for i in range(3)]
for i in range(300):
for j in range(3):
sess.run(train_step, feed_dict={x: train_xs[j], y_: xtest[j]})
モデル評価
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
res = sess.run(accuracy, feed_dict={x: X_test, y_: ytest[0]})
print("{0:.2f}".format(res))
精度はこんな感じになりました。
0.95
全体のコード
iris-classification1.py
import tensorflow as tf
from sklearn import datasets
from sklearn.model_selection import train_test_split
iris = datasets.load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target)
k = [0, 38, 76, 112]
train_xs=train_ys=[]
for i in range(1, 4):
tmp_x=tmp_y=[]
for j in range(k[i-1], k[i]):
tmp_x, tmp_y = tmp_x + [X_train[j]], tmp_y + [y_train[j]]
train_xs, train_ys = train_xs + [tmp_x], train_ys + [tmp_y]
train_labels = tf.placeholder(tf.int64, [None])
test_labels = tf.placeholder(tf.int64, [None])
train_ = tf.one_hot(train_labels, depth=3, dtype=tf.float32)
test_ = tf.one_hot(test_labels, depth=3, dtype=tf.float32)
x = tf.placeholder(tf.float32, [None, 4])
W = tf.Variable(tf.zeros([4, 3]))
b = tf.Variable(tf.zeros([3]))
y = tf.nn.softmax(tf.matmul(x, W) + b)
y_ = tf.placeholder(tf.float32, [None, 3])
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y, y_))
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
xtest=ytest=[]
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
ytest.append(sess.run(test_, feed_dict={test_labels: y_test}))
xtest = [sess.run(train_, feed_dict={train_labels: train_ys[i]}) for i in range(3)]
for i in range(300):
for j in range(3):
sess.run(train_step, feed_dict={x: train_xs[j], y_: xtest[j]})
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
res = sess.run(accuracy, feed_dict={x: X_test, y_: ytest[0]})
print("{0:.2f}".format(res))