–Tensorflow
を使った判別解析
–
小森 理
日時:2018年10月31日(水)
Tensorflow
のインストール
I
TensorflowはPythonの1つのモジュール.大学のパソコンにはすでに
Python(+Python開発環境Anaconda)はインストールされているが,Tensorflow
はインストールされていない.まずはTensorflowをインストールする.
.
. 1 Anaconda Promptを立ち上げる. ..
. 2 Anaconda Prompt上で以下のコマンドを入力(base) C:\Users\komori>conda create -n tensorflow python=3.5
.
.
.
3 tensorflowを有効化する.
(base) C:\Users\komori>activate tensorflow
.
.
.
4 pip(Pip installs Packagesの略)を使いtensorflowをインストール
(base) C:\Users\komori>pip install --ignore-installed --upgrade https://storage.googleapis.com/tensorflow/windows/cpu/ tensorflow-1.0.1-cp35-cp35m-win_amd64.whl 詳しくはhttps://www.rivercrane.com/blog/658/を参照. .
.
. 5 idleを立ち上げる (base) C:\Users\komori>idle 小森 理(成蹊大学) Tensorflow 2018年10月31日(水) 2 / 39Tensorflow I
TensorflowはGoogleによって開発されたオープンソースライブラリであり, データフロープログラミングを基本的な考えてとしている.C++とPythonで 書かれている. データフロープログラミング . . . . . 有効グラフを用いてデータの流れ(flow)をプログラミングする.並列プログラ ミングが容易になり,大規模データを扱いやすくなる.デバックもしやすい. 何故GoogleはTensorflowのコードをオープンにしたのか? ⇒真に価値あるものはデータそのものであり,データ解析を実装する環境は重 要ではない! 小森 理(成蹊大学) Tensorflow 2018年10月31日(水) 3 / 39Tensor
とは?
I
Tensorとはデータを格納する多次元配列のこと.Tensorflowではデータ (tensor)の流れ(flow)をデータフローグラフとして定式化し,実際のデータ解 析を行う. tensor . . . . .>>> import numpy as np #多次元配列を実装するための python のモジュール >>> M1=np.array([1,2,3]) #ベクトル >>> M1 array([1, 2, 3]) >>> M1.ndim # M1 の次元数 1 >>> M1.shape # M1の配列の大きさ (3,) >>> M2=np.array([[1,2,3],[4,5,6]]) #行列 >>> M2 array([[1, 2, 3], [4, 5, 6]]) >>> M2.ndim # M2の次元数 2 >>> M2.shape # M2 の配列の大きさ (2, 3) 小森 理(成蹊大学) Tensorflow 2018年10月31日(水) 5 / 39
Tensor
とは?
II
tensor(続) . . . .. . . . >>> M3=np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]],[[1,1,1],[1,1,1]],[[2,2,2],[2,2,2]]]) >>> M3 #配列 array([[[ 1, 2, 3], [ 4, 5, 6]], [[ 7, 8, 9], [10, 11, 12]], [[ 1, 1, 1], [ 1, 1, 1]], [[ 2, 2, 2], [ 2, 2, 2]]]) >>> M3.ndim # M3の次元数 3 >>> M3.shape # M3の配列の大きさ (4, 2, 3) 小森 理(成蹊大学) Tensorflow 2018年10月31日(水) 6 / 39Tensorflow
の基本構造
I
Tensorflowは2段階のステップを踏んでデータ解析を行う. Tensorflowの基本形式 . . . .. . . . ..
. 1 データフローグラフ(dataflow graph)を作成.データ解析の設計図に 相当. ..
. 2 Tensorflowセッション(session)をつくり,実際に解析を実行する. データフローグラフの中身node(節):演算子,関数(operation, op), tensor(データ)
edge(辺): tensor(データ)の流れ
Tensorflow
の基本構造
II
tensorにはいくつか種類がある(グラフには必ずtensorが必要!) tensorの基本形式 . . . .. . . . constant:定数tensor(不変)Variable:変数tensor(可変).trainable(パラメータ)とnon-trainable(繰り
返し数)がある.使う前には必ず初期化が必要.変数wに対して
sess.run(w.initializer),または全ての変数を一度に初期化したい場合は
sees.run(tf.global variables initializer())とする.
placeholder:空のtensor.データが入る場所だけ確保.session実行時に
実際のデータが辞書形式で供給されるfeed dict={ データの名前:データ
の値}
注:tf.initialize all variablesは2017年に廃止
Tensorflow
を起動する
I
Tensorflowを使うためには,コマンドプロンプト上で最初にactivateをする必 要がある. tensorflowのactivate . . . .. . . . C:\\Users\\komori\\Desktop>activate tensorflow そうすると以下のように頭に(tensorflow)が付く. . tensorflowのactivate . . . .. . . . (tensorflow)C:\\Users\\komori\\Desktop>この状態でpythonの総合開発環境(idle: integrated development environment)
を立ち上げる. . pythonの起動 . . . .. . . . (tensorflow)C:\\Users\\komori\\Desktop>idle
但しpython a.pyで,事前に作ったpythonのプログラムファイルa.pyを実行
してもよい.
Session
とは?
I
Sessionは演算子(operation)を実行し,データ(tensor)を評価するための環境
を作る. 基本的な使い方 . . . . .
>>> import tensorflow as tf # tensorflowを import し tf で参照する # Build a graph.
>>> a = tf.constant(5.0) >>> b = tf.constant(6.0) >>> c = tf.constant(7.0) >>> d = a * b + c
# Launch the graph in a session. >>> sess = tf.Session()
# Evaluate the tensor d.
>>> print(sess.run(d)) # データフローグラフを実行する. 37.0
>>> sess.close() #立ち上げた session は必ず閉じる >>> print(d)#dはデータフローグラフの node のまま Tensor("mul:0", shape=(), dtype=float32)
データフローグラフの可視化
I
データフローグラフを可視化するのにTensorboardを使う. データフローグラフの可視化 . . . .. . . .>>> import tensorflow as tf # tensorflowを import し tf で参照する # Build a graph. >>> a=tf.constant(5.0, name="a") #名前を付ける. >>> b=tf.constant(6.0, name="b") #データフローグラフが見やすくなる >>> c=tf.constant(7.0, name="c") >>> d=a * b + c >>> tf.summary.scalar(’d’, d) # dをグラフに出力 # Launch the graph in a session.
>>> sess = tf.Session()
>>> writer=tf.summary.FileWriter(’./log’, sess.graph) # log フォ ルダに graph の情報を吐き出す
>>> sess.close() #立ち上げた session は必ず閉じる >>> writer.close() # writerも必ず閉じる
以下のようにコマンドプロンプト上でtensorboardを起動
データフローグラフの可視化
II
tensorboardの実行 . . . .. . . .(tensorflow) C:\\Users\\komori\\Desktop>tensorboard --logdir=’./log’
その後ブラウザーでhttp://133.220.115.132:6006にアクセスすると,データフ ローグラフが見れる. コマンドプロンプトを強制終了させる必要が出た場合は . コマンドプロンプトの強制終了 . . . . . C:\\Users\\komori\\Desktop>tasklist # PIDの確認, 例 2528 C:\\Users\\komori\\Desktop>taskkill /F /PID 2528
C:\\Users\\komori\\Desktop>help taskkill # help画面表示
Iris
データ
I
データフレームを扱うのに便利なpandasモジュールをインストールする. pandasのインストール . . . .. . . .C:\\Users\\komori\\Desktop>pip install pandas
pipの意味: ”Pip installs Packages”, ”Pip installs Python” pandasの意味: panel data (xit,i= 1, . . . , n,t= 1, . . . , T),
. irisデータの読み込み . . . .. . . . >>> import pandas as pd >>> iris=pd.read_csv("iris100.csv")
>>> iris.iloc[0:3,] #iloc, integer location 1行から3行まで表示 Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
Iris
データ
II
irisデータの読み込み(続) . . . . . >>> iris.index Int64Index([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100], dtype=’int64’) >>> iris.columnsIndex([’Sepal.Length’, ’Sepal.Width’, ’Petal.Length’, ’Petal.Width’, ’Species’],
dtype=’object’) >>> iris.shape
(100, 5)
Iris
データ
III
データを描画するのに便利なmatplotlibモジュールをインストールする. pandasのインストール . . . .. . . .C:\\Users\\komori\\Desktop>pip install matplotlib
. irisデータの描画 . . . .. . . .
>>> import matplotlib.pyplot as plt #matplotlib のメソッド pyplot を plt として参照 >>> plt.scatter(iris.iloc[0:50,0],iris.iloc[0:50,1]) >>> plt.scatter(iris.iloc[49:100,0],iris.iloc[49:100,1]) >>> plt.xlabel(iris.columns[0]) >>> plt.ylabel(iris.columns[1]) >>> plt.show() 小森 理(成蹊大学) Tensorflow 2018年10月31日(水) 16 / 39
tf.matmul
関数
I
行列の掛け算はmatmulメソッド(関数)を使う 行列の掛け算 . . . .. . . . >>> import tensorflow as tf >>> impoart numpy as np >>> X=np.array([[1,2,3,4],[5,6,7,8]]) >>> W=np.array([1,1,-1,-1]) # W: 1× 4 の行列 >>> W.shape=(4,1) # 4× 1 の行列に変形 >>> A=tf.matmul(X,W)>>> with tf.Session() as sess: #:を忘れずに print(sess.run(A))
[[-4] [-4]]
with構文を使うとsess.close()を省略できる(プログラミングが簡潔になる).
変数
a
のアップデート
I
変数のアップデートにはtf.assign使う. update.py . . . .. . . . import tensorflow as tf a = tf.Variable(0, name="a") b= tf.assign(a, a+1)with tf.Session() as sess:
sess.run(tf.global_variables_initializer()) #tf.Variableには 初期化が必要
print(sess.run(b))
for _ in range(3): # for文の引数を_で省略できる
print(sess.run(b))
tf.assign(ref,value): Update ’ref’ by assigning ’value’ to it.
結果を受け取る
(fetching) I
sess.run()の結果を明示的に受け取ることもできる. fetch.py . . . .. . . . import tensorflow as tfa=tf.constant(1) # default graphが生成される! #a=1 # default graphは生成されない (エラー) b=2
c=3 d=a+b e=a*b+c
with tf.Session() as sess:
res1, res2 = sess.run ([d,e]) # d,eが fetch print(res1,res2)
fetch:連れてくる.取ってくる.
入力が複数の場合はリスト[ ]を使う
グラフ
I
グラフを明示的に作ることもできる. graph.py . . . . . import tensorflow as tf g = tf.Graph() #graph gの生成with g.as_default():# Define operations and tensors in ‘g‘. a=tf.constant(1) # graph gに要素 (tensor)a を追加
b=2 c=3 d=a+b e=a*b+c
A=tf.constant(30) # default graphに要素 (tensor)A を追加 with tf.Session(graph=g) as sess:
print(sess.run([d,e]))
with tf.Session(graph=tf.get_default_graph()) as sess: print(sess.run(A))
default graphの呼び出しにはtf.get default graph()を使う.
placeholder
の使い方
I
データが入力される場所だけ予め明示する方法.関数の変数のようなもの. placeholder.py . . . .. . . . import tensorflow as tf import numpy as np x = tf.placeholder(tf.int32, shape=(3, 3)) #データの場所だけグラフ に確保 y = tf.matmul(x, x)+1 with tf.Session() as sess:A = np.random.randint(10,size=(3,3)) #実際のデータを生成 print(A)
print(sess.run(y, feed_dict={x: A})) #データの代入 (feed)
np.random.randint()は整数乱数を生成.np.random.rand()は一様乱数,
np.random.normal()は正規分布,np.random.binomial()は二項分布
tf.reduce sum
の使い方
I
reduce.py . . . .. . . . import tensorflow as tf x = tf.constant([[1, 1, 1], [1, 1, 1]]) a1=tf.reduce_sum(x) a2=tf.reduce_sum(x, 0) a3=tf.reduce_sum(x, 1) a4=tf.reduce_sum(x, [0, 1]) with tf.Session() as sess:x, a1, a2, a3, a4=sess.run([x,a1,a2,a3,a4])
print("x= %s,a1=%s, a2=%s, a3=%s, a4=%s" % (x,a1,a2,a3,a4))
結果はx= [[1 1 1] [1 1 1]],a1=6, a2=[2 2 2], a3=[3 3], a4=6
reduce sumの第二引数はaxis.
%s: stringとして表示.cf %d
cf. reduce prod
Iris
データ解析
I
logistic.py . . . .. . . . import numpy as np import pandas as pd import tensorflow as tf iris=pd.read_csv("iris100.csv") #データの取り込み data=iris.iloc[:,0:4] #4変量を抜き出す X=tf.placeholder(tf.float32,[None,4]) W=tf.Variable(tf.zeros([4,1])) w0=tf.Variable(tf.zeros(1)) Fx=tf.matmul(X,W)+w0 #Fxは 100 × 1 の行列 Fx=tf.reshape(Fx,shape=[100]) #Fxをベクトルに直す prob=tf.sigmoid(Fx) #Fxを確率 prob に直す y=tf.concat([tf.zeros(50),tf.ones(50)],0) #irisのラベル tf.concat([t1,t2], axis) tf.sigmoid: y = 1 / (1 + exp(-x)) y: setosa 0, sersicolor 1 小森 理(成蹊大学) Tensorflow 2018年10月31日(水) 24 / 39Iris
データ解析
II
logistic.py(続) . . . .. . . . likelihood=tf.reduce_sum(y*tf.log(prob)+(1-y)*tf.log(1-prob)) loss=-likelihood learning_rate=0.001 #学習率 train= tf.train.GradientDescentOptimizer(learning_rate).minimize(loss) likelihood: 二項分布の尤度lossを2乗誤差(tf.reduce mean(tf.square(y-prob)))に変換しても動きます
(learning rate=0.1にすること) 学習率η:W = W − η∂loss∂W いくつかのOptimizer GradientDescentOptimizer:勾配降下法 AdagradOptimize: AdaGrad法 MomentumOptimizer:モメンタム法 AdamOptimizer: Adam法 小森 理(成蹊大学) Tensorflow 2018年10月31日(水) 25 / 39
Iris
データ解析
III
以下のようにSessionを立ち上げて実行する. logistic.py(続) . . . .. . . .with tf.Session() as sess:
sess.run(tf.global_variables_initializer()) #Variables初期化 for i in range(100): #100回の学習 sess.run(train,feed_dict={X:data}) if i % 10 == 0: #10回ごとに途中結果を表示 print("%5d:(loss,W,w0)=(%f, %s,%.4f)" % (i, sess.run(loss,feed_dict={X:data}), sess.run(tf.reshape(W,shape=[4])), sess.run(w0))) print("%d:prob=%s" % (i, sess.run([prob[0:50],prob[49:100]], feed_dict={X:data})))
sess.run(train,feed dict={X:data})が核のプログラム.これを100回繰り返し てモデルを学習する.
Iris
データ解析
IV
結果の表示 . . . . . 99:prob=[array([0.05188024, 0.08912963, 0.06669012, 0.10111529, 0.04822054, 0.05778961, 0.06967285, 0.06836263, 0.1111423 , 0.0880551 , 0.04567991, 0.0835014 , 0.08588763, 0.0626291 , 0.01893461, 0.02362813, 0.03128402, 0.055362 , 0.05524711, 0.04780443, 0.08290517, 0.05636013, 0.02897625, 0.11831485, 0.12846342, 0.11592321, 0.08993023, 0.05878907, 0.05580139, 0.10362343, 0.11099757, 0.06998195, 0.03011787, 0.02291222, 0.09372462, 0.05299381, 0.04000121, 0.04639078, 0.0875022 , 0.06659891, 0.04883502, 0.17240585, 0.0721186 , 0.09260346, 0.09266059, 0.09729531, 0.05215724, 0.07941735, 0.04691749, 0.064922 ], dtype=float32), array([0.064922 , 0.95223546, 0.948271 , 0.97111017, 0.95957834, 0.9695602 , 0.96731794, 0.96161586, 0.8700995 , 0.960485 , 0.939309 , 0.9317998 , 0.94146186, 0.94912225, 0.9723449 , 0.86616206, 0.9370603 , 0.96587247, 0.93197024, 0.98227733, 0.9328552 , 0.9767007 , 0.92228276, 0.98678815, 0.9714649 , 0.94079584, 0.9444666 , 0.9741459 , 0.9815429 , 0.96563816, 0.8567132 , 0.93112504, 0.9149091 , 0.91937625, 0.9898162 , 0.9676729 , 0.94681376, 0.96268344, 0.9729944 , 0.9285226 , 0.9505959 , 0.96847165, 0.96423984, 0.93698525, 0.8785579 , 0.95433486, 0.93263644, 0.9427612 , 0.9438422 , 0.79055864, 0.9397015 ], dtype=float32)] 小森 理(成蹊大学) Tensorflow 2018年10月31日(水) 27 / 39名前空間
(name scope, name space) I
名前を一意に特定できるようにするための空間.名前の衝突が回避できる.
Tensorboardによるグラフの表示も簡潔になる.入れ子構造も可能.tensorflow
ではtf.name scopeを用いる.tf.name scopeは必ず閉じる必要があるため
with構文を取る. 名前空間 . . . .. . . . with tf.variable_scope("probability"): with tf.name_scope("X"): X=tf.placeholder(tf.float32,[None,4]) with tf.name_scope("W"): W=tf.Variable(tf.zeros([4,1])) with tf.name_scope("w0"): w0=tf.Variable(tf.zeros(1)) with tf.name_scope("Fx"): Fx=tf.matmul(X,W)+w0 Fx=tf.reshape(Fx,shape=[100]) with tf.name_scope("prob"): prob=tf.sigmoid(Fx) 変数Wの名前はW.nameで参照できる.上の例では 小森 理(成蹊大学) Tensorflow 2018年10月31日(水) 28 / 39
名前空間
(name scope, name space) II
変数の名前 . . . .. . . . >>> print(W.name,w0.name) probability/W/Variable:0 probability/w0/Variable:0 最後の数字0は変数のindex.変数を2つ以上返す関数では0以外の数値を取る . 変数のindex . . . .. . . . >>> a,b=tf.nn.top_k([1,4,2], 1) # k 番目の大きいものとその index を返す >>> a.name ’TopKV2_2:0’ >>> b.name ’TopKV2_2:1’ 小森 理(成蹊大学) Tensorflow 2018年10月31日(水) 29 / 39要約統計量
(summary) I
計算結果の要約をtf.summaryでまとめると,tensorboardでその結果を描画し てくれる. 要約統計量 . . . .. . . . with tf.name_scope(’summary’): tf.summary.scalar("loss",loss) tf.summary.scalar("mean.W",tf.reduce_mean(W)) tf.summary.histogram("hist.W",W) 要約統計量が複数ある場合,それをまとめることができる(sess.runのときに まとめて入力できるので便利). . 要約統計量をまとめる . . . .. . . . merged = tf.summary.merge_all() 小森 理(成蹊大学) Tensorflow 2018年10月31日(水) 30 / 39要約統計量
(summary) II
グラフと要約統計量をlogフォルダに記録する(logistic.writer.py) . . . .. . . .log_dir = ’C:\Users\komori\Desktop\log’ #log フォルダの path with tf.Session() as sess:
sess.run(tf.global_variables_initializer()) #Variableの初期化
writer = tf.summary.FileWriter(log_dir, sess.graph) #グラフを log に記録 print(sess.run([loss,y],feed_dict={X:data}))
for i in range(100): #100 回の学習
summary,_=sess.run([merged,train],feed_dict={X:data})
writer.add_summary(summary, i) #mergedから吐き出される summary を log に追加
writer.close() #writerを閉じる . tensorboardで結果の確認 . . . . .
(tensorflow) C:\Users\komori\Desktop>tensorboard --logdir="./log"
Tensorflowインストール https://www.rivercrane.com/blog/658/ Tensorflow公式サイト https://www.tensorflow.org/ Rとpandas対応表 https://qiita.com/takaiyuk/items/4cb1708a3f886b3d2043 小森 理(成蹊大学) Tensorflow 2018年10月31日(水) 37 / 39
プログラムコード
I
logistic.writer.py . . . .. . . . import numpy as np import pandas as pd import tensorflow as tf iris=pd.read_csv("iris100.csv") data=iris.iloc[:,0:4] with tf.variable_scope("probability"): with tf.name_scope("X"): X=tf.placeholder(tf.float32,[None,4]) with tf.name_scope("W"): W=tf.Variable(tf.zeros([4,1])) WW=tf.Variable(tf.zeros([4,1])) with tf.name_scope("w0"): w0=tf.Variable(tf.zeros(1)) with tf.name_scope("Fx"): Fx=tf.matmul(X,W)+w0 Fx=tf.reshape(Fx,shape=[100]) with tf.name_scope("prob"): prob=tf.sigmoid(Fx) with tf.name_scope("label"): y=tf.concat([tf.zeros(50),tf.ones(50)],0) 小森 理(成蹊大学) Tensorflow 2018年10月31日(水) 38 / 39プログラムコード
II
logistic.writer.py(続) . . . . . with tf.name_scope("loss"): likelihood=tf.reduce_sum(y*tf.log(prob)+(1-y)*tf.log(1-prob)) loss=-likelihood learning_rate=0.001 train= tf.train.GradientDescentOptimizer(learning_rate).minimize(loss) with tf.name_scope(’summary’): tf.summary.scalar("loss",loss) tf.summary.scalar("mean.W",tf.reduce_mean(W)) tf.summary.histogram("hist.W",W) merged = tf.summary.merge_all() log_dir = ’C:\Users\komori\Desktop\log’ with tf.Session() as sess:sess.run(tf.global_variables_initializer()) writer = tf.summary.FileWriter(log_dir, sess.graph) print(sess.run([loss,y],feed_dict={X:data})) for i in range(100): summary,_=sess.run([merged,train],feed_dict={X:data}) writer.add_summary(summary, i) writer.close() 小森 理(成蹊大学) Tensorflow 2018年10月31日(水) 39 / 39