More Related Content Similar to 深層学習とTensorFlow入門 (20) 深層学習とTensorFlow入門10. 10
機械学習のモデル
機械学習のモデルといっても様々なものがある
決定木法
線形回帰、ロジスティック回帰
SVM
ニューラルネットワーク
K-means,階層型クラスタリング, MeanShift
pLSI, NMF, LDA
Lasso回帰、Ridge回帰、Elastic Net
ベイジアンネットワーク
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
「教師あり、教師なし」「分類、回帰」「2値分類、多値分類」などやりたいことに
応じて適切な手法を選択することが大切。
今日はこれに特化します
18. 18
連鎖律と誤差逆伝播法
勾配の定義
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
𝛁𝑬 = (
𝝏𝑬
𝝏𝒘 𝟏
,
𝝏𝑬
𝝏𝒘 𝟐
,
𝝏𝑬
𝝏𝒘 𝟑
, ・・・・)
関数を、それを構成するパラメータでそれぞれ偏微分したものを並べた配列
ΔE =
𝜕𝐸
𝜕𝑤1
Δ𝑤1 +
𝜕𝐸
𝜕𝑤2
Δ𝑤2 + ・・・= 𝑗
𝜕𝐸
𝜕𝑤 𝑗
∆𝑤𝑗
= 𝛁𝑬∆𝒘
∆𝑤 =
∆𝑤1
∆𝑤2
∆𝑤3
すると、実際に動かすパラメータの変化量の配列 を用いて、
19. 19
連鎖律と誤差逆伝播法
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
∆𝐸 = 𝛻𝐸∆𝑤 の中で、我々が決めることができるのは∆wだけ!!
∆Eが0以下の値になれば訓練するたびに誤差は減っていく。
とすればその条件を満たせる。
∆𝒘 = −𝜶 × (
𝝏𝑬
𝝏𝒘 𝟏
,
𝝏𝑬
𝝏𝒘 𝟐
,
𝝏𝑬
𝝏𝒘 𝟑
, ・・・・) 𝑇
𝑤 = 𝑤 − 𝛼𝛻𝐸更新するルールは α:学習率(0< α <= 1.0)
21. 21
連鎖律と誤差逆伝播法
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
𝑦 = 𝑥2
+ 2𝑥 + 1 の時、𝑧 = 𝑦2
を𝑥で微分せよ。
𝑑𝑧
𝑑𝑥
=
𝑑𝑧
𝑑𝑦
×
𝑑𝑦
𝑑𝑥
(xが変化することによるzの変化量)
=(yが変化することによるxの変化量)×(xが変化することによるyの変化量)
NNでは各層の出力が、 次の層の入力になるために、
連鎖律を意識して勾配計算
を行う
25. 25
多層NNにした時の欠点
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
誤差伝播
高レイヤ:
フィードバックをしっかり
受けているが、訓練
データの影響が強く出
すぎている。
低レイヤ:
フィードバックが
分散しすぎて届
かない。
・・・・・・
勾配消失が起こってしまい、学習が上手くいかない(進まない)
解決策:関係ある結合(パラメータ)だけを残してその他の結合を切る
漠然としててどうしたらいいものか・・・
41. 41
そもそもTensorって
テンソル(英: tensor, 独: Tensor)とは、線形的な量または線形的な幾何概念
を一般化したもので、基底を選べば、多次元の配列として表現できるようなもの
である。 しかし、テンソル自身は、特定の座標系によらないで定まる対象である。
出典:Wikipedia
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
多次元配列ということで
大丈夫です。
44. 44
apt周りのインストール
依存関係のあるものをインストールしていきます
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#apt-getのライブラリのインデックスを更新
sudo apt-get update
#既存で入っているものを更新
sudo apt-get upgrade
#aptパッケージで必要なものを取得
sudo apt-get install -y build-essential python-pip python-dev git python-numpy
swig python-dev ipython pkg-config zip g++ zlib1g-dev unzip
45. 45
bazelの導入
Googleが開発したbuildツール「bazel」を導入します。
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#bazelのインストール jdk8を入れる(apt-get周りの時にやってても大丈夫)
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java8-installer
#bazelのインストーラ(バイナリ)をサーバに持ってくる(バージョンはその時の
最新んい置き換えてください)
wget https://github.com/bazelbuild/bazel/releases/download/0.2.1/bazel-
0.2.1-installer-linux-x86_64.sh
#権限変更して実行
chmod +x bazel-0.2.1-installer-linux-x86_64.sh
./bazel-0.2.1-installer-linux-x86_64.sh --user
#パスを通してあげる(.bashrcに記述)
export PATH="$PATH:$HOME/bin"
46. 46
TensorFlowのインストール
Gitリポジトリからソースをcloneしてきてからbuild
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#git からtensorflowをcloneしてくる
git clone https://github.com/tensorflow/tensorflow
#versionを指定したいときは必要なブランチをcheckout
Git checkout (バージョン)
#いつもの(GPUサポートに関する質問はNoと答えてください)
./configure
#pipパッケージ作成をターゲットにビルド
bazel build -c opt //tensorflow/tools/pip_package:build_pip_package
#pipパッケージ作成を実行(/tmp/tensorflow_pkg直下に作ります)
bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
sudo pip install /tmp/tensorflow_pkg/(出来上がったTensorFlowのパッケージ)
47. 47
動作確認
Pythonでインポートしてみる
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
python
>>>import tensorflow as tf
#すぐに動作確認しようとして、現在いるtensorflowのソースコードのディレクト
リでimport tensorflow as tfをするとエラー吐くので、それ以外のところで動作
確認すべし
色々書きましたが、とりあえず試したい・練習したいとのことなら
pip install tensorflow
でも大丈夫です。
48. 48
TensorFlowの特徴
計算グラフを用いたBuild & Run
実行環境のSessionで構築モデルを実行
計算グラフにおけるノードは各種オペレーション
計算グラフにおけるエッジはオペレーションの入出力となるTensor
(buildツールにBazel), データのシリアライズ、でシリアライズに
ProtocolBuffurを採用することで大規模分散に特化
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
?????
50. 50
計算グラフ
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
Variable
val1
const1 val1
add
定数:3 変数:初期値0
加算の結果
a = tf.constant(3, name="const1")
b = tf.Variable(0, name="val1")
add = tf.add(a, b)
Variableやconstantは、変数・定数を出力
するという演算を行うという認識。
51. 51
計算グラフ
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
Variable
val1
const1 val1
add
Input
assign = tf.assign(b, add)
c = tf.placeholder(tf.int32, name="input")
mul = tf.multiply(assign, c)
変数に対する値の更新はassignを用いる
assign
placeholder
実行時の引数
mul
掛け算の結果
52. 52
計算グラフ
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
Variable
val1
const1 val1
add
Input
Init = tf. global_variables_initializer ()
変数は初期化が必要
assign
placeholder
mul
掛け算の結果 init
構築したグラフをセッション上で動かす
初期化オペレーション
53. 53
計算グラフ
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
Variable
val1
const1 val1
add
Input
with tf.Session() as sess:
sess.run(init)
assign
placeholder
mul
掛け算の結果 init
構築したグラフをセッション上で動かす
まずは初期化だけ実行
54. 54
計算グラフ
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
Variable
val1
const1 val1
add
Input
for i in range(3):
print(sess.run(mul, feed_dict={c: 3}))
assign
placeholder
mul
掛け算の結果 init
mulの結果を3回実行
feed_dict: 2
55. 55
計算グラフ
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
Variable
val1
const1 val1
add
Input
for i in range(3):
print(sess.run(add))
assign
placeholder
mul
掛け算の結果 init
Addの部分だけ実行する際は、このグラフ
でplaceholderは関係ないのでいらない。
assignも通らないので変数も更新されない
61. 61
ミニバッチについて
そこで毎ステップ、訓練に用いるデータはランダムにとってくる
計算速度も向上
毎回勾配を計算する関数が変わるので局所解に陥りにくい
データの中からランダムにサンプリングしているために、寄り道しな
がらも着実に真の解に近づいていく
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
Stocastic Gradient Descent (SGD)
確率的勾配降下方
毎ステップごとに用いられる訓練データ群をミニバッチ
そのサイズをバッチサイズと呼ぶ。
バッチサイズはハイパーパラメータ。
62. 62
入出力データ
入力データ
(ミニバッチサイズ,画素数)の2階テンソル(行列)
出力データ
(ミニバッチサイズ,数字の種類)の2回テンソル
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
0 ⋯ 0.1
⋮ ⋱ ⋮
0.2 ⋯ 1.0
1番目の画像の画素値
n番目の画像の画素値
1行が1つの画像の全
画素(784画素)を表す
0.1 ⋯ 0.1
⋮ ⋱ ⋮
0.2 ⋯ 0.3
1番目の画像がそれぞれ
の数字である確率
n番目の画像がそれぞれ
の数字である確率
0である確率 9である確率
1行が1つの画像がどの数字
であるか(10種類)の確率を
表す
63. 63
入出力データ
正解データ
出力データと同じ形
ただし、正解の数字の部分のみが1.0その他は0.0のワンホットベク
トルを並べた行列
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
1.0 ⋯ 0.0
⋮ ⋱ ⋮
0.0 ⋯ 1.0
1番目の画像は0だと
いう正解
n番目の画像は9だと
いう正解
65. 65
プログラム作成
importおよびデータセット準備
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#-*- coding:utf-8 -*-
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
#mnistデータを格納したオブジェクトを呼び出す
mnist = input_data.read_data_sets('data/’, one_hot=True)
mnistデータを呼び出す
関数
mnist.train.image・・・訓練用入力データの配列
mnist.train.labels・・・訓練用正解データの配列
mnist.train.next_batch(50)
訓練データ50個を取り出して、(入力データ,正解データ)
のタプルで返却してくれる
66. 66
プログラム作成
モデル構築(入力層〜中間層)
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#入力データを定義
x = tf.placeholder(tf.float32, [None, 784])
#入力層から中間層
w_1 = tf.Variable(tf.truncated_normal([784, 64], stddev=0.1), name="w1")
b_1 = tf.Variable(tf.zeros([64]), name="b1”)
h_1 = tf.nn.relu(tf.matmul(x, w_1) + b_1)
重みwとバイアスbは学習して更新する
変数なので、Variableで定義する。
初期値を与えて、初期化する
必要がある
67. 67
プログラム作成
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#784×64の行列を平均0、標準偏差0.1で初期化
tf.truncated_normal([784, 64], stddev=0.1)
なぜこれで重みの定義になるのか?
0.03 ⋯ 0.2
⋮ ⋱ ⋮
−0.4 ⋯ −0.1
𝑤1,1 ⋯ 𝑤1,64
⋮ ⋱ ⋮
𝑤784,1 ⋯ 𝑤784,64
入力層の784番目と中
間層の64番目をつな
ぐ重み
0 ⋯ 0.1
⋮ ⋱ ⋮
0.2 ⋯ 1.0
= 1番目の画像を重みにかけた中間層への
入力
68. 68
プログラム作成
モデル構築(入力層〜中間層)
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
b_1 = tf.Variable(tf.zeros([64]), name="b1”)
h_1 = tf.nn.relu(tf.matmul(x, w_1) + b_1)
tf.matmul(x, w_1) の結果は(バッチサイズ, 64)の2階テンソル
1階テンソルのb_1をそのまま足せるのはなぜ?
Numpyにもある、ブロードキャスティン
グ機能
69. 69
プログラム作成
モデル構築(中間層〜出力層)
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#中間層から出力層
w_2 = tf.Variable(tf.truncated_normal([64, 10], stddev=0.1), name="w2")
b_2 = tf.Variable(tf.zeros([10]), name="b2")
out = tf.nn.softmax(tf.matmul(h_1, w_2) + b_2)
入力層〜中間層とほとんど同じ。
発火関数がsoftmax関数になっている。
70. 70
プログラム作成
モデル構築(誤差計算と訓練)
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#誤差関数
loss = tf.reduce_mean(tf.square(y - out))
#訓練
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(loss)
reduce_mean, reduce_sumは平均や合計を取りながら次元を削減してくれる。
axisを指定しなければ全ての要素や平均を取ってスカラーにする。
学習率
0.1 ⋯ 0.1
⋮ ⋱ ⋮
0.2 ⋯ 0.3
( 𝑥0 … 𝑥 𝑚)
𝑦0
⋮
𝑦 𝑛
axis=0
axis=1
Optimizerのminimizeを実行すること
で自動的に勾配を計算して値を更新
してくれる。
compute_gradients
+
apply_gradients
71. 71
プログラム作成
モデル構築(評価)
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#評価
correct = tf.equal(tf.argmax(out,1), tf.argmax(y,1))
accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))
0.1 ⋯ 0.1
⋮ ⋱ ⋮
0.2 ⋯ 0.3
tf.argmaxは指定したランクの最大値の添字を返す
今回の場合は、行で比
較して最大値のの添字
の1階テンソルを返す
73. 73
プログラム作成
実行(訓練)
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
with tf.Session() as sess:
#初期化
init =tf.global_variables_initializer()
sess.run(init)
#テストデータをロード
test_images = mnist.test.images
test_labels = mnist.test.labels
for i in range(1000):
step = i+1
train_images, train_labels = mnist.train.next_batch(50)
sess.run(train_step, feed_dict={x:train_images ,y:train_labels})
Placeholderに値を与え
て、訓練のオペレーショ
ンを実行
実行数=stepと数を合わ
せるため
75. 75
プログラム作成
実行(評価)
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#10回に1回精度を検証
if step % 10 == 0:
acc_val = sess.run(accuracy ,feed_dict={x:test_images, y:test_labels})
print('Step %d: accuracy = %.2f' % (step, acc_val))
10ステップごとに誤差計算や訓練は行わず
に精度だけをテストデータで計算
プログラムの実行は
>>python mnist.py
だいたい90%程度の精度
83. 83
プログラム作成
importおよびデータセット準備
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#-*- coding:utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
#mnistデータを格納したオブジェクトを呼び出す
mnist = input_data.read_data_sets('data')
さっきと同じ
84. 84
プログラム作成
モデル構築(入力層〜畳み込み層1)
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#入力データを定義
x = tf.placeholder(tf.float32, [None, 784])
#(バッチサイズ, 高さ, 横幅, チャンネル数)に変更
img = tf.reshape(x,[-1,28,28,1])
#畳み込み層1
f1 = tf.Variable(tf.truncated_normal([5,5,1,32], stddev=0.1))
conv1 = tf.nn.conv2d(img, f1, strides=[1,1,1,1], padding='SAME')
畳み込みに用いるフィルタをVariable
で定義して、tf.nn.conv2dに渡す。
[高さ, 幅,
畳み込み前チャンネル数,
畳み込み後チャンネル数]
ストライドはフィルタをどれほど動かす
か?のパラメータ。入力画像と同様の形
式をとるため、「バッチ」・「チャンネル」の
strides[0], strides[3]は必ず1
85. 85
プログラム作成
モデル構築(バイアス+プーリング層2)
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
b1 = tf.Variable(tf.constant(0.1, shape=[32]))
h_conv1 = tf.nn.relu(conv1+b1)
#プーリング層1
h_pool1 = tf.nn.max_pool(h_conv1, ksize=[1,2,2,1], strides=[1,2,2,1],
padding='SAME')
カーネルサイズが畳み込みとは異なり、
ストライドと同じ構成をとる。
バッチ方向、カーネル方向にプーリング
することはないので、ksize[0], ksize[3]
は必ず1
86. 86
プログラム作成
モデル構築(畳み込み層2〜プーリング層2)
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#畳み込み層2
f2 = tf.Variable(tf.truncated_normal([5,5,32,64], stddev=0.1))
conv2 = tf.nn.conv2d(h_pool1, f2, strides=[1,1,1,1], padding='SAME')
b2 = tf.Variable(tf.constant(0.1, shape=[64]))
h_conv2 = tf.nn.relu(conv2+b2)
#プーリング層2
h_pool2 = tf.nn.max_pool(h_conv2, ksize=[1,2,2,1], strides=[1,2,2,1],
padding='SAME')
先ほどと同じ要領で
87. 87
プログラム作成
モデル構築(全結合層)
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#畳み込まれているものをフラットな形に変換
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
#全結合層
w_fc1 = tf.Variable(tf.truncated_normal([7*7*64, 1024], stddev=0.1))
b_fc1 = tf.Variable(tf.constant(0.1, shape=[1024]))
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, w_fc1) + b_fc1)
プーリング層2を通過した後の画像は
7×7の64チャンネル画像になっている
のでただのNNの中間層に変換。
※手計算してもいいし、
shapeをとってきて掛け算し
ても良い
88. 88
プログラム作成
モデル構築(出力層〜誤差関数)
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#出力層
w_fc2 = tf.Variable(tf.truncated_normal([1024, 10], stddev=0.1))
b_fc2 = tf.Variable(tf.constant(0.1, shape=[10]))
out = tf.nn.softmax(tf.matmul(h_fc1, w_fc2) + b_fc2)
#正解データの型を定義
y = tf.placeholder(tf.float32, [None, 10])
#誤差関数(クロスエントロピー)
loss = tf.reduce_mean(-tf.reduce_sum(y * tf.log(out), reduction_indices=[1]))
クロスエントロピーを素で実装するとこうなる。
89. 89
プログラム作成
モデル構築(訓練〜評価)
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#訓練
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
#評価
correct = tf.equal(tf.argmax(out,1), tf.argmax(y,1))
accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))
先ほどと同じ
94. 94
TFのモデルの保存方法
TensorFlowから読み込めるCheckpointファイル
基本的な方法はこちら
実行環境にPython/TensorFlowがインストールされている場合に用
いる
ProtocolBuffers形式でのエクスポート
学習したモデルをiOSやAndroidで動かす際に用いる
Pythonで学習したモデルを他の端末で実行するとき
2017/9/19
Singularity Copyright 2016 Singularity Inc. All rights
reserved
ProtocolBuffers
Googleが開発したシリアライズフォーマット。JSONやXMLのようなもの。
今回はTFがインストールされていることを前提として
Checkpointを用いたモデル保存を説明します。
99. 99
ファイルの説明
checkpoint
1ファイルのみ生成
今このディレクトリにどのファイルがあって、最新がどのファイルかを
記載している
エディタで開ける
2017/9/19
Singularity Copyright 2016 Singularity Inc. All rights
reserved
model_checkpoint_path: "my_model-1000”
all_model_checkpoint_paths: "my_model-600”
all_model_checkpoint_paths: "my_model-700”
all_model_checkpoint_paths: "my_model-800”
all_model_checkpoint_paths: "my_model-900”
all_model_checkpoint_paths: "my_model-1000"
最新のモデル
全てのモデル
100. 100
ファイルの説明
拡張子metaファイル
例: my_model-1000.meta
構築したモデルの構造を記述したファイル
重みなどのは保持しない
モデル構築をプログラム内で記述する限りは何ステップ目であろう
が普通は変更されることはない(ファイル出力するだけ無駄)
2017/9/19
Singularity Copyright 2016 Singularity Inc. All rights
reserved
saver.save(sess, ‘models/my_model’, global_step = step, write_meta_graph=False)
こうしておけば生成されなくなる
101. 101
ファイルの説明
拡張子dataファイル
実際の重みの値が入ったバイナリ
拡張子indexファイル
どのファイルがどのstepのものかを一意に特定するためのバイナリ
2017/9/19
Singularity Copyright 2016 Singularity Inc. All rights
reserved
これらはsaveメソッドを呼んだ数だけ
生成される 100-1000ステップまで10件ずつ出
来上がるはずなのにどうして600-
1000の5件しかないのだろう?
105. 105
補足
2017/9/19
Singularity Copyright 2016 Singularity Inc. All rights
reserved
model_checkpoint_path: "my_model-1000”
all_model_checkpoint_paths: "my_model-800”
all_model_checkpoint_paths: "my_model-900”
all_model_checkpoint_paths: "my_model-1000"
last_model = ckpt_state.model_checkpoint_path
saver.restore(sess, last_model) これのこと
残り三つはProtocolBuffers
の定義上は配列
model = ckpt_state. all_model_checkpoint_paths[0]
saver.restore(sess, model)
こうすれば上記だと800ステップ目のファイルを読み込める
※tensorflow/tensorflow/python/training/checkpoint_state.protoをご覧ください
106. 106
ステップ数の制御
1回訓練が終わってしまうと今何ステップ目かわからない
checkpointのファイルをopenして文字処理してステップ数取得!
現在のステップ数も変数として保存してしまう
2017/9/19
Singularity Copyright 2016 Singularity Inc. All rights
reserved
美しくない
global_step = tf.Variable(0, name='global_step', trainable=False)
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(loss,
global_step=global_step)
minimizeメソッドにメソッドのglobal_step引数に変数を入れておく
とminimizeメソッドを呼ぶ時にincrementしてくれる!
111. 111
TensorBoard
TensorBoardとは?
Webベースの構築モデル及び各種ログ可視化ツール
Scalars ・・・スカラ情報と時系列情報の関係
Images・・・画像データ
Audio・・・音声データ
Graphs・・・データフロー、使用デバイス、計算量などの可視化
Distributions・・・確率分布情報と時系列情報の関係
Histograms・・・度数分布情報と時系列情報の関係
Embeddings・・・データを空間に組み込んで可視化
Text・・・r1.1から追加。テキスト情報
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
デバッグや結果の考察に利用
することにより機械学習のイテ
レーションをサポートする非常に
強力なツール
112. 112
TensorBoardの使うには?
1. 必要なところにログを取得するオペレーションを定義
2. 定義したらこれらのオペレーションをマージすることも可能
2017/9/19
Singularity Copyright 2016 Singularity Inc. All rights
reserved
loss_summary = tf.summary.scalar(‘loss’, loss) # Scalars
img_summary = tf.summary.image(‘input_data’, images, 10) # Images
w_histogram = tf.summary.histogram('w', w) # Histograms, Distributions
# 全てのログをマージするオペレーション
summary_op = tf.summary.merge_all()
# 一部のログをマージするオペレーション
summary_op = tf.summary.merge([loss_summary, img_summary])
※出力結果などを得るのと同様、ログもSession内で実行しないとログを取ってくれない
116. 116
Images(画像データ出力)
注意点
画像でなければモデル構築時にエラー
(batch_size, width, height, channel)の4階テンソル
チャンネル数は1, 3, 4に対応
活用例
DataAugumentation時の画像確認
いちいち画像出力をしてlocalに落としてきてみる手間の削減
重みの可視化(グレースケール扱い)
畳み込み層のカーネルの可視化
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
124. 124
前準備
定数なども増えてくるのでtf.app.flagsを用いて一元管理
2017/9/19
Singularity Copyright 2016 Singularity Inc. All rights
reserved
import tensorflow as tf
FLAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_string('data_dir', 'data/', "data set directory.")
tf.app.flags.DEFINE_float(‘learning_rate’, 0.5, “learning rate.”)’
・
・
・
def main(argv):
# 行う処理
if __name__ == '__main__':
tf.app.run()
こう書くことでargparseなどを用いる必要がなくなる
125. 125
入力画像のログを取る
画像ではなくバイナリできているので、パーサーがうまく動いているか不
安な時など
第一引数は保存する際のname, 第二引数が画像のTensor
tf.summary.imageの第三引数は最大で何枚保存するかを指定
2017/9/19
Singularity Copyright 2016 Singularity Inc. All rights
reserved
#データセット作成
mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True)
x = tf.placeholder(tf.float32, [None, 784], name='input')
#入力画像を確認
images = tf.reshape(x,[-1,28,28,1])
tf.summary.image("input_data", images, 10)
入力画像は3階テンソルでないといけないのでreshapeする。
127. 127
分布やスカラーの誤差を取る
tf.summary.histogramを定義するとDistributions, Histograms両
方の画面が活用できる
Tensorのshapeはなんでも良い
Scalarについてはその名の通りスカラー(0階テンソルを入れる必要が
ある)
2017/9/19
Singularity Copyright 2016 Singularity Inc. All rights
reserved
#誤差
with tf.name_scope('loss'):
each_loss = tf.reduce_mean(tf.square(y-out), axis=[1])
loss = tf.reduce_mean(each_loss)
tf.summary.histogram('each_loss', each_loss)
tf.summary.scalar("loss", loss)
単なる平均誤差時だけでなく、分布を取ると最大誤差や最小誤差
もTensorBoardで確認できる
134. 134
学習済みのデータからロード
2017/9/19
Singularity Copyright 2016 Singularity Inc. All rights
reserved
with tf.Session() as sess:
state = tf.train.get_checkpoint_state(FLAGS.model_dir)
#構築済みのmetaデータをロードしてくる。
#グラフを定義していないのでdefaultグラフにロードされる
meta_path = FLAGS.model_dir + FLAGS.meta_file
saver = tf.train.import_meta_graph(meta_path)
#最新の値でモデルをロード
saver.restore(sess, state.model_checkpoint_path)
前章ではあまり話さなかった.metaファイルを用いてロードすると楽
135. 135
必要な値にアクセス
特に定義していないとデフォルトのグラフにロードされる
ネームスペースに注意して必要な情報にアクセス
2017/9/19
Singularity Copyright 2016 Singularity Inc. All rights
reserved
#デフォルトグラフにアクセス
graph = tf.get_default_graph()
#グラフから必要な要素を取得してくる
x = graph.get_tensor_by_name('input:0')
feature = graph.get_tensor_by_name('inference/hidden/feature:0')
test_images = mnist.test.images
#feature_valにテストデータを入力した時の実際の値が入る
feature_val = sess.run(feature, feed_dict={x: test_images})
name_spaceに注意して値をロード
143. 143
Textの使い方
Text型のTensorを使うことはあまりないが、普通のテンソルと変わらな
い
一応別のname_scopeでもとってみる
2017/9/19
Singularity Copyright 2016 Singularity Inc. All rights
reserved
text_list = ['text0','text1','text2','text3','text4','text5']
# tf.constantを使ってもいい
test_string = tf.convert_to_tensor('Test String.')
outer_summary = tf.summary.text('out',test_string)
with tf.name_scope('scope_test') as scope:
text_ph = tf.placeholder(tf.string,name='input')
inner_summary = tf.summary.text('in', text_ph)
summary_op = tf.summary.merge_all()
あとは割愛
160. 160
RNNのややこしいところ
一方RNNは
(バッチサイズ, 時間, 中間層ユニット数)のtensorが
tf.nn.dynamic_rnnにおける出力
この後出力層を定義するが、そのままoutputを使うことができない
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
適切にデータを整形する必要がある
162. 162
many to one
必要なのは最終ステップの出力のみ
例:1行ずつ画像を読み込んで行って、その画像のクラス分類
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
入力1 入力2 入力3
中間1 中間2 中間2
出力3
163. 163
many to one実装
ポイントはtf.nn.dynamic_rnnの出力の最終時系列のデータだけを
引っ張ってくること
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
Tensor操作になるのでちょっと手間
165. 165
プログラム作成
インポートなど
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#-*- coding:utf-8 -*-
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
#mnistデータを格納したオブジェクトを呼び出す
mnist = input_data.read_data_sets("data/", one_hot=True)
166. 166
プログラム作成
モデル構築(入力データ整形)
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#入力データ整形
num_seq = 28
num_input = 28
x = tf.placeholder(tf.float32, [None, 784])
input = tf.reshape(x, [-1, num_seq, num_input])
dynamic_rnnへの入力は[バッチサイズ, sequenceサイズ, 入力長]
tf.reshapeで整形 ※num_seq* num_input=784にするように
167. 167
プログラム作成
モデル構築(rnn cell作成)
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#ユニット数128個のLSTMセル
#三段に積む
stacked_cells = []
for i in range(3):
stacked_cells.append(tf.nn.rnn_cell.LSTMCell(num_units=128))
cell = tf.nn.rnn_cell.MultiRNNCell(cells=stacked_cells)
168. 168
プログラム作成
モデル構築(dynamic_rnn構築、最終時間のみのスライス)
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#dynamic_rnn構築
outputs, states = tf.nn.dynamic_rnn(cell=cell, inputs=input, dtype=tf.float32,
time_major=False)
#シーケンス軸のランクを最初に来るように入れ替え
#type_major=Trueにしていれば必要ない
outputs = tf.transpose(outputs,[1, 0, 2])
#最後のシーケンスのデータのみスライス
last_output = tf.gather(outputs, int(outputs.get_shape()[0]) -1)
Last_outputは最終時間における[バッチサイズ, 出力長]となり、
いつものニューラルネットワークと同じ!!
169. 169
プログラム作成
モデル構築(出力層)
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#出力層
w = tf.Variable(tf.truncated_normal([128,10], stddev=0.1))
b = tf.Variable(tf.zeros([10]))
out = tf.nn.softmax(tf.matmul(last_output, w ) + b)
以前書いたものと同じ。以降、lossや評価、実行も全て他のプログラムと同じ
RNNなので計算時間もかかる上に、収束も遅い。
171. 171
コンピュータ上での単語表現
従来手法
単語にIDを振る
ミコロフ革命以降
単語をベクトルして扱う!!
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
犬=1024, 猫=1025, こんにちは=543 ….
共起を計算して統計的に類似度などの解析はできるけど、相当数のデータは必要
だし、本当にそれでいいのか?
172. 172
単語埋め込み
Word2Vec
ニューラル言語モデルを用いた単語埋め込み
単語の意味獲得を行えるように
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
Yoshua Bengio, Réjean Ducharme, Pascal
Vincent, Christian Jauvin. A Neural
Probabilistic Language Model. Journal of
Machine Learning Research 3(2003):p1137–
1155
犬=(0.1, 0.5, 2.0, 0.4, 2.4)
猫=(0.1, 0.4, 1.5, 0.3, 2.4)
次に来る単語を予測するモデルを作る
ことによって、
のように、各単語にベクトルを割り当てる。
王様 – 男性 + 女性 = 女王様
のようなベクトル演算が可能に
173. 173
単語埋め込み
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
0.1 ⋯ 0.1
⋮ ⋱ ⋮
0.2 ⋯ 0.3
‘dog’を表すパラメータ
dog
human
‘human’を表すパラメータ単語ベクトルを集めた行列を用意してそれを辞書として利用
内積をとることで似ている単語を推定するなどが可能
単語のベクトルをニューラルネットワークの入力にも可能
どうやってその辞書を作るの?
174. 174
作り方(skip gram版)
単語に注目して、そこの周りにどんな単語があるか予測するNNを作る
重みは最初は適当な値で初期化
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
0.1 ⋯ 0.1
⋮ ⋱ ⋮
0.2 ⋯ 0.3
dog
単語ID1のドッグのベクトルを取得(これ
が中間層の出力に)
(0.1, 0.2,0.3・・・,0.1)
dogのN次元埋め込みベクトル
N×Vの重みを用意してあげてそれをか
けて、それぞれの単語が次に来る確率を
出力
𝑦0
⋮
𝑦 𝑛
dogの出現確率
human
humanの出現確率
学習された後の前半の
重みが単語の埋め込み
辞書になる
175. 175
負荷サンプリング
そのまま最終層のsoftmaxの計算をすると、単語数j分の𝑒 𝑥 𝑗
を計算しなければいけない
全部相手にせずに、分布にしたがって異なる単語を抜き出して、それら
にが出現する確率が0かつ、正解データが出現確率確率が1になる確
率の積が大きい値になるようになるような誤差関数を定義
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
𝑦 =
𝑒 𝑥 𝑖
𝑗 𝑒 𝑥 𝑗
単語数が数十万になると凄まじい計算量になる
計算量を減らすsoftmax + cross entorypyのような
もの
177. 177
プログラム
入力層〜中間層
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#入力データ正解データのph
train_inputs = tf.placeholder(tf.int32, shape=[batch_size])
train_labels = tf.placeholder(tf.int32, shape=[batch_size, 1])
#中間層
embeddings = tf.Variable(tf.random_uniform([vocab_size, embedding_size], -
1.0, 1.0))
embed = tf.nn.embedding_lookup(embeddings, train_inputs)
入力は単語IDの配列
それをenbeddings_lookupすることで内部的に計算して各単語ごと
の組み込みベクトルを返してくれる
178. 178
プログラム
出力層〜誤差
2017/9/19
C8Lab Copyright 2014 C8Lab Inc. All rights reserved
#出力層側の[単語サイズ, 組み込みサイズ]の重みとバイアスを定義
nce_weights = tf.Variable(tf.truncated_normal([vocab_size, embedding_size], stddev=
1.0/ math.sqrt(embedding_size)))
nce_biases = tf.Variable(tf.zeros([vocab_size]))
#誤差関数を定義
nce_loss = tf.nn.nce_loss(nce_weights, nce_biases, embed, train_labels, num_sampled,
vocab_size)
loss = tf.reduce_mean(nce_loss)
出力層側の重み、バイアス、中間層出力、正解データ、サンプリン
グ数、総単語サイズを与えたら一気に計算してくれる。