- 追加された行はこの色です。
- 削除された行はこの色です。
*はじめに [#ja3312a3]
ここでは、Googleが公開しているオープン・ソース・ソフトウェア (OSS) のTensorFlowをMac (OS X) にインストールして使います。
*環境 [#kd6c49b9]
-OS X Yosemite 10.10.5
-Python 3.5.1
-TensorFlow 0.7
-TensorFlow 0.7.1
*Python3のインストール(アップグレード) [#zf2975fa]
まず、Python3を最新版にアップグレードします。
下記のサイトから''Mac OS X 64-bit/32-bit installer''をダウンロードして、インストール。
-[[Python 3.5.1:https://www.python.org/downloads/release/python-351/]]
*TensorFlowのインストール [#seb185d6]
基本的にはここに書いてある通りなんですが、なぜかsixのeasy_installが先にできなかったので、順序を逆にしました。
-[[Download and Setup:https://www.tensorflow.org/versions/r0.7/get_started/os_setup.html#download-and-setup]] - TensorFlow
#geshi(sh){{
sudo pip3 install --upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.7.1-cp35-none-any.whl
$ sudo easy_install --upgrade six
}}
*Virtualenvのインストール [#ab5cc2c7]
#geshi(sh){{
$ sudo pip3 install --upgrade virtualenv
$ virtualenv --system-site-packages /Users/Shared/tools/tensorflow
$ source /Users/Shared/tools/tensorflow/bin/activate
(tensorflow)$ pip3 install --upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.7.1-cp35-none-any.whl
(tensorflow)$ deactivate
}}
私の研究室では、共有フォルダーのtoolsというフォルダー (/Users/Shared/tools/) に、みんなで使うツールをインストールしています。
/Users/Shared/tools/tensorflow を ~/tensorflow などTensorFlowをインストールしたいフォルダーに変更してください。
*TensorFlowを動かす [#te2b5012]
TesorFlowのサイトに掲載されているHello Worldを動かします。
-[[Test the TensorFlow installation:https://www.tensorflow.org/versions/r0.7/get_started/os_setup.html#test-the-tensorflow-installation]] - TensorFlow
#geshi(sh){{
$ source /Users/Shared/tools/tensorflow/bin/activate
(tensorflow) $ python3
Python 3.5.1 (v3.5.1:37a07cee5969, Dec 5 2015, 21:12:44)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow as tf
>>> hello = tf.constant('Hello, TensorFlow!')
>>> sess = tf.Session()
>>> print(sess.run(hello))
b'Hello, TensorFlow!'
>>> a = tf.constant(10)
>>> b = tf.constant(32)
>>> print(sess.run(a + b))
42
>>> quit()
(tensorflow) $ deactivate
}}
*TensorFlowでIrisをやってみる [#ka2954e2]
TensorFlowの最初のチュートリアルは手書き数字認識のMNISTですが、irisデータセットで分類をやってみます。
**データの準備 [#p76609a7]
irisデータセットは、4つの説明変数(花びらの長さ、幅、がく片の長さ、幅)とカテゴリー (setosa, versicolor, virginica) からなるデータセットです。
UCI Machine Learning Repositoryからファイル iris.data をダウンロードします。
中身はこんな感じです。
#geshi(txt){{
$ head -5 iris.data
5.1,3.5,1.4,0.2,Iris-setosa
4.9,3.0,1.4,0.2,Iris-setosa
4.7,3.2,1.3,0.2,Iris-setosa
4.6,3.1,1.5,0.2,Iris-setosa
5.0,3.6,1.4,0.2,Iris-setosa
}}
3クラスの分類なので、カテゴリーのラベルを3次元の0/1ベクトルに変換します。
つまり、setosaは 1,0,0、versicolorは 0,1,0、virginicaは 0,0,1 とします。
irisデータには、それぞれ、50個ずつ150個のデータが並んでいるので、次のように変換します。
#geshi(sh){{
$ head -50 iris.data | awk -F, '{printf("%s,%s,%s,%s,1,0,0\n",$1,$2,$3,$4);}' > iris.csv
$ head -100 iris.data | tail -50 | awk -F, '{printf("%s,%s,%s,%s,0,1,0\n",$1,$2,$3,$4);}' >> iris.csv
$ head -150 iris.data | tail -50 | awk -F, '{printf("%s,%s,%s,%s,0,0,1\n",$1,$2,$3,$4);}' >> iris.csv
}}
これで、データの準備は完了です。
このデータをdataフォルダーにおいておきます。
**分類用ソースコード [#xeaf4449]
TensorFlowのTutorialsについてる最初の手書き文字データセットMNIST用のサンプルをほとんどそのまま使ったソースコードはこんな感じです。
#geshi(python){{
# Iris classification for TensorFlow
#
#
# Copyright 2016 Tohgoroh Matsui All Rights Reserved.
#
# This includes software developed by Google, Inc.
# licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import tensorflow as tf
import numpy as np
# for TensorBoard
def variable_summaries(var, name):
with tf.name_scope('summaries'):
mean = tf.reduce_mean(var)
tf.scalar_summary('mean/' + name, mean)
with tf.name_scope('stddev'):
stddev = tf.sqrt(tf.reduce_sum(tf.square(var - mean)))
tf.scalar_summary('sttdev/' + name, stddev)
tf.scalar_summary('max/' + name, tf.reduce_max(var))
tf.scalar_summary('min/' + name, tf.reduce_min(var))
tf.histogram_summary(name, var)
# パラメーター
flags = tf.app.flags
FLAGS = flags.FLAGS
flags.DEFINE_integer('samples', 120, 'Number of training samples.')
flags.DEFINE_integer('max_steps', 1001, 'Number of steps to run trainer.')
flags.DEFINE_float( 'learning_rate', 0.001, 'Initial learning rate.')
flags.DEFINE_float( 'dropout', 0.9, 'Keep probability for training dropout.')
flags.DEFINE_string( 'data_dir', 'data', 'Directory for storing data.')
flags.DEFINE_string( 'summaries_dir', 'log', 'Summaries directory.')
def train():
# CSVファイルの読み込み
iris = np.genfromtxt(FLAGS.data_dir + '/iris.csv', delimiter=",", skip_header=1)
# データをシャッフル
np.random.shuffle(iris)
# 学習データ (train) とテストデータ (test) に分割
# 訓練データ (train) とテストデータ (test) に分割
x_train, x_test = np.vsplit(iris[:,0:4].astype(np.float32), [FLAGS.samples])
y_train, y_test = np.vsplit(iris[:,4:7].astype(np.float32), [FLAGS.samples])
# セッション
sess = tf.InteractiveSession()
# 入力
with tf.name_scope('input'):
x = tf.placeholder(tf.float32, shape=[None, 4])
# 出力
with tf.name_scope('output'):
y_ = tf.placeholder(tf.float32, shape=[None, 3])
# ドロップアウト
with tf.name_scope('dropout'):
keep_prob = tf.placeholder(tf.float32)
tf.scalar_summary('dropout_keep_probability', keep_prob)
# 重み(係数)
def weight_variable(shape):
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
# バイアス(定数項)
def bias_variable(shape):
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)
# for TensorBoard
def variable_summaries(var, name):
with tf.name_scope('summaries'):
mean = tf.reduce_mean(var)
tf.scalar_summary('mean/' + name, mean)
with tf.name_scope('stddev'):
stddev = tf.sqrt(tf.reduce_sum(tf.square(var - mean)))
tf.scalar_summary('sttdev/' + name, stddev)
tf.scalar_summary('max/' + name, tf.reduce_max(var))
tf.scalar_summary('min/' + name, tf.reduce_min(var))
tf.histogram_summary(name, var)
# ニューラル・ネットワークの層
def nn_layer(input_tensor, input_dim, output_dim, layer_name, act=tf.nn.relu):
with tf.name_scope(layer_name):
with tf.name_scope('weights'):
weights = weight_variable([input_dim, output_dim])
variable_summaries(weights, layer_name + '/weights')
with tf.name_scope('biases'):
biases = bias_variable([output_dim])
variable_summaries(biases, layer_name + '/biases')
with tf.name_scope('Wx_plus_b'):
preactivate = tf.matmul(input_tensor, weights) + biases
tf.histogram_summary(layer_name + '/pre_activations', preactivate)
activations = act(preactivate, 'activation')
tf.histogram_summary(layer_name + '/acctivations', activations)
return activations
# 入力層
hidden1 = nn_layer(x, 4, 64, 'layer1')
dropped1 = tf.nn.dropout(hidden1, keep_prob)
# 中間層
hidden2 = nn_layer(dropped1, 64, 64, 'layer2')
dropped2 = tf.nn.dropout(hidden2, keep_prob)
# 出力層
y = nn_layer(dropped2, 64, 3, 'layer3', act=tf.nn.softmax)
# クロス・エントロピー
with tf.name_scope('cross_entropy'):
#diff = y_ * tf.log(y)
#with tf.name_scope('total'):
# cross_entropy = -tf.reduce_mean(diff)
cross_entropy = -tf.reduce_sum(y_*tf.log(tf.clip_by_value(y,1e-10,1.0)))
tf.scalar_summary('cross entropy', cross_entropy)
# 学習
with tf.name_scope('train'):
train_step = tf.train.AdamOptimizer(FLAGS.learning_rate).minimize(cross_entropy)
# 精度
with tf.name_scope('accuracy'):
with tf.name_scope('correct_prediction'):
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
with tf.name_scope('accuracy'):
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
tf.scalar_summary('accuracy', accuracy)
# for TensorBoard
merged = tf.merge_all_summaries()
train_writer = tf.train.SummaryWriter(FLAGS.summaries_dir + '/train', sess.graph)
train_writer = tf.train.SummaryWriter(FLAGS.summaries_dir + '/train', sess.graph_def)
test_writer = tf.train.SummaryWriter(FLAGS.summaries_dir + '/test')
tf.initialize_all_variables().run()
# データとドロップアウト・キープ率の切り替え
def feed_dict(train):
if train:
xs, ys = x_train, y_train
k = FLAGS.dropout
else:
xs, ys = x_test, y_test
k = 1.0
return {x: xs, y_: ys, keep_prob: k}
# 学習ルーチン
for i in range(FLAGS.max_steps):
summary, acc, cp = sess.run([merged, accuracy, cross_entropy], feed_dict=feed_dict(False))
test_writer.add_summary(summary, i)
summary, _ = sess.run([merged, train_step], feed_dict=feed_dict(True))
train_writer.add_summary(summary, i)
if i == 0 or i % np.power(10, np.floor(np.log10(i))) == 0:
print('Accuracy and Cross Entropy at step %s: %s, %s' % (i, acc, cp))
def main(_):
if tf.gfile.Exists(FLAGS.summaries_dir):
tf.gfile.DeleteRecursively(FLAGS.summaries_dir)
tf.gfile.MakeDirs(FLAGS.summaries_dir)
train()
if __name__ == '__main__':
tf.app.run()
}}
MNISTからいくつか変更点があります。
-iris.csvからデータを読み込む
-データをシャッフルして120個を訓練データに、残りの30個をテスト・データにする
-入力は4次元、出力は3次元
-中間層(活性化関数はReLU)を追加
-入力層は4x64ユニット、中間層は64x64ユニット、出力層は64x3ユニット
-クロス・エントロピーの定義を変更(元の定義だとNaNになってしまうことがあるため)
-TensorBoardにグラフを出力しない(エラーになってしまうため)
-10回中9回学習して1回テストを行うのではなく、毎回学習とテストを行う
-標準出力に精度とクロス・エントロピーを出力
**実行 [#f0d2b637]
#geshi(sh){{
$ source /Users/Shared/tools/tensorflow/bin/activate
(tensorflow) $ python3 tfc_iris.py
Accuracy and Cross Entropy at step 0: 0.325, 132.007
Accuracy and Cross Entropy at step 1: 0.341667, 128.534
Accuracy and Cross Entropy at step 2: 0.275, 128.389
Accuracy and Cross Entropy at step 3: 0.258333, 126.72
Accuracy and Cross Entropy at step 4: 0.408333, 124.004
Accuracy and Cross Entropy at step 5: 0.283333, 125.581
Accuracy and Cross Entropy at step 6: 0.316667, 122.983
Accuracy and Cross Entropy at step 7: 0.45, 120.915
Accuracy and Cross Entropy at step 8: 0.508333, 119.768
Accuracy and Cross Entropy at step 9: 0.558333, 118.938
Accuracy and Cross Entropy at step 10: 0.616667, 117.524
Accuracy and Cross Entropy at step 20: 0.716667, 103.102
Accuracy and Cross Entropy at step 30: 0.791667, 86.5923
Accuracy and Cross Entropy at step 40: 0.766667, 71.941
Accuracy and Cross Entropy at step 50: 0.883333, 59.7601
Accuracy and Cross Entropy at step 60: 0.9, 51.6576
Accuracy and Cross Entropy at step 70: 0.908333, 45.2846
Accuracy and Cross Entropy at step 80: 0.941667, 39.4717
Accuracy and Cross Entropy at step 90: 0.916667, 34.6735
Accuracy and Cross Entropy at step 100: 0.95, 28.6601
Accuracy and Cross Entropy at step 200: 0.975, 10.2124
Accuracy and Cross Entropy at step 300: 0.975, 8.91163
Accuracy and Cross Entropy at step 400: 0.975, 7.53242
Accuracy and Cross Entropy at step 500: 0.983333, 7.67529
Accuracy and Cross Entropy at step 600: 0.966667, 8.6403
Accuracy and Cross Entropy at step 700: 0.966667, 7.6847
Accuracy and Cross Entropy at step 800: 0.975, 5.9193
Accuracy and Cross Entropy at step 900: 0.983333, 7.32202
Accuracy and Cross Entropy at step 1000: 0.983333, 4.97897
}}
**TensorBoardによるログの確認 [#nd118cd7]
TensorBoardでログを確認します。
次のようにしてTensorBoardを起動すると、6006番ポートでHTTPサーバーが起動します。
#geshi(sh){{
(tensorflow) $ tensorboard --logdir=log
}}
Webブラウザーで [[http://localhost:6006]] にアクセスします。
#ref(./iris_c.png,nolink,25%)