Contenu connexe Similaire à [第2版]Python機械学習プログラミング 第14章 (20) Plus de Haruki Eguchi (14) [第2版]Python機械学習プログラミング 第14章6. TensorFlowの計算グラフ
● 計算グラフ
● 複数のノードからなるネットワーク。
● TensorFlowでは計算グラフを構築、コンパイル
して実行する。
6
g = tf.Graph()
with g.as_default():
a = tf.constant(1, name='a')
b = tf.constant(2, name='b')
c = tf.constant(3, name='c')
z = 2*(a-b) + c
with tf.Session(graph=g) as sess:
print('2*(a-b)+c => ', sess.run(z))
7. TensorFlowのプレースホルダ
● プレースホルダ
● 特定の型と形状に基づいて事前に定義されたテンソル。
● プレースホルダには値は含まれていないので、ノードの実行時に値を供給する。
7
g = tf.Graph()
with g.as_default():
tf_a = tf.placeholder(tf.int32, shape=[], name='tf_a')
tf_b = tf.placeholder(tf.int32, shape=[], name='tf_b')
tf_c = tf.placeholder(tf.int32, shape=[], name='tf_c')
r1 = tf_a - tf_b
r2 = 2*r1
z = r2 + tf_c
with tf.Session(graph=g) as sess:
feed = {tf_a: 1, tf_b: 2, tf_c: 3}
print('z:', sess.run(z, feed_dict=feed))
z: 1
8. TensorFlowのプレースホルダ
● バッチサイズに合わせたプレースホルダ
● 次元の大きさが可変である場合に Noneを指定することができる。
8
g = tf.Graph()
with g.as_default():
tf_x = tf.placeholder(tf.float32, shape=[None, 2], name='tf_x')
x_mean = tf.reduce_mean(tf_x, axis=0, name='mean')
np.random.seed(123)
np.set_printoptions(precision=2)
with tf.Session(graph=g) as sess:
x1 = np.random.uniform(low=0, high=1, size=(5,2))
print('Feeding data with shape', x1.shape)
print('Result:', sess.run(x_mean, feed_dict={tf_x:x1}))
x2 = np.random.uniform(low=0, high=1, size=(10,2))
print('Feeding data with shape', x2.shape)
print('Result:', sess.run(x_mean, feed_dict={tf_x:x2}))
Feeding data with shape (5, 2)
Result: [ 0.62 0.47]
Feeding data with shape (10, 2)
Result: [ 0.46 0.49]
9. TensorFlowの変数
● 変数
● ニューラルネットワークで使う重みなど、更新可能なパラメータを格納する。
● 初期化する必要がある。
9
g1 = tf.Graph()
with g1.as_default():
w = tf.Variable(np.array([[1, 2, 3, 4], [5, 6, 7, 8]]), name='w')
with tf.Session(graph=g1) as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(w))
[[1 2 3 4]
[5 6 7 8]]
10. TensorFlowの変数
● 変数スコープ
● 変数を別々のグループに分けることができる。
● reuseオプションを使って変数をスコープ間で再利用することもできる。
10
g = tf.Graph()
with g.as_default():
with tf.variable_scope('net_A'):
with tf.variable_scope('layer-1'):
w1 = tf.Variable(tf.random_normal(shape=(10,4)), name='weights')
with tf.variable_scope('layer-2'):
w2 = tf.Variable(tf.random_normal(shape=(20,10)), name='weights')
with tf.variable_scope('net_B'):
with tf.variable_scope('layer-1'):
w3 = tf.Variable(tf.random_normal(shape=(10,4)), name='weights')
print(w1)
print(w2)
print(w3)
<tf.Variable 'net_A/layer-1/weights:0' shape=(10, 4) dtype=float32_ref>
<tf.Variable 'net_A/layer-2/weights:0' shape=(20, 10) dtype=float32_ref>
<tf.Variable 'net_B/layer-1/weights:0' shape=(10, 4) dtype=float32_ref>
12. 回帰モデルの構築
● 線形回帰モデル
● 前章で作成したものと同じ y=wx+bを考える。
● コスト関数には平均二乗誤差 (MSE)を使用。
● TensorFlowとの対応
● 入力 x: プレースホルダ tf_x
● 入力 y: プレースホルダ tf_y
● モデルのパラメータ w: 変数 wight
● モデルのパラメータ b: 変数 bias
● モデルの出力 y^: TensorFlowの演算によって返される y_hat
12
13. 回帰モデルの構築
● 計算グラフの構築
13
g = tf.Graph()
with g.as_default():
tf.set_random_seed(123)
tf_x = tf.placeholder(shape=(None), dtype=tf.float32, name='tf_x')
tf_y = tf.placeholder(shape=(None), dtype=tf.float32, name='tf_y')
weight = tf.Variable(tf.random_normal(shape=(1, 1), stddev=0.25), name='weight')
bias = tf.Variable(0.0, name='bias')
y_hat = tf.add(weight * tf_x, bias, name='y_hat')
cost = tf.reduce_mean(tf.square(tf_y - y_hat), name='cost')
optim = tf.train.GradientDescentOptimizer(learning_rate=0.001)
train_op = optim.minimize(cost, name='train_op')
14. 回帰モデルの構築
● ランダムデータセットの作成
● トレーニングデータ100件
テストデータ100件
14
● モデルのトレーニング
n_epochs = 500
training_costs = []
with tf.Session(graph=g) as sess:
sess.run(tf.global_variables_initializer())
for e in range(n_epochs):
c, _ = sess.run([cost, train_op],
feed_dict={tf_x: x_train,
tf_y: y_train})
training_costs.append(c)
16. TensorFlowでのモデルの保存と復元
● tf.train.Saver
● 計算グラフにSaverを追加し、呼び出すことでモデルの保存が可能。
16
with g.as_default():
saver = tf.train.Saver()
n_epochs = 500
training_costs = []
with tf.Session(graph=g) as sess:
sess.run(tf.global_variables_initializer())
for e in range(n_epochs):
c, _ = sess.run(['cost:0', 'train_op'],
feed_dict={'tf_x:0':x_train, 'tf_y:0':y_train})
training_costs.append(c)
saver.save(sess, './trained-model')
出力されるファイル
18. テンソルを多次元配列として変換する
● 多次元配列の操作
● 1つの次元を”-1”に設定すると、配列の大きさと指定した次元から推定可能。
18
g = tf.Graph()
with g.as_default():
arr = np.array([[1., 2., 3., 3.5], [4., 5., 6., 6.5], [7., 8., 9., 9.5]])
T1 = tf.constant(arr, name='T1')
T2 = tf.reshape(T1, shape=[1, 1, -1], name='T2')
T3 = tf.reshape(T1, shape=[1, 3, -1], name='T3')
T4 = tf.transpose(T3, perm=[2, 1, 0], name='T4')
Tensor("T1:0", shape=(3, 4), dtype=float64)
Tensor("T2:0", shape=(1, 1, 12), dtype=float64)
Tensor("T3:0", shape=(1, 3, 4), dtype=float64)
Tensor("T4:0", shape=(4, 3, 1), dtype=float64)
19. テンソルを多次元配列として変換する
● 多次元配列の操作
● 多次元配列の分割と結合
19
g = tf.Graph()
with g.as_default():
t1 = tf.ones(shape=(5, 1), dtype=tf.float32, name='t1')
t2 = tf.zeros(shape=(5, 1), dtype=tf.float32, name='t2')
t3 = tf.concat([t1, t2], axis=0, name='t3')
t4 = tf.concat([t1, t2], axis=1, name='t4')
Tensor("t1:0", shape=(5, 1), dtype=float32)
Tensor("t2:0", shape=(5, 1), dtype=float32)
Tensor("t3:0", shape=(10, 1), dtype=float32)
Tensor("t4:0", shape=(5, 2), dtype=float32)
20. ● TensorFlowの制御フロー
● 次の式を実装する悪い例
x, y = 1.0, 2.0
g = tf.Graph()
with g.as_default():
tf_x = tf.placeholder(dtype=tf.float32, shape=None, name='tf_x')
tf_y = tf.placeholder(dtype=tf.float32, shape=None, name='tf_y')
if x < y:
res = tf.add(tf_x, tf_y, name='result_add')
else:
res = tf.subtract(tf_x, tf_y, name='result_sub')
print('Object: ', res)
with tf.Session(graph=g) as sess:
print('x < y: %s -> Result:' % (x < y), res.eval(feed_dict={'tf_x:0': x, 'tf_y:0': y}))
x, y = 2.0, 1.0
print('x < y: %s -> Result:' % (x < y), res.eval(feed_dict={'tf_x:0': x, 'tf_y:0': y}))
計算グラフの構築に制御フローを使用する
20
Object: Tensor("result_add:0", dtype=float32)
x < y: True -> Result: 3.0
x < y: False -> Result: 3.0
計算グラフが実行したのは
加算演算子が含まれた分岐のみ
21. ● TensorFlowの制御フロー
● 次の式を実装する正しい例
x, y = 1.0, 2.0
g = tf.Graph()
with g.as_default():
tf_x = tf.placeholder(dtype=tf.float32, shape=None, name='tf_x')
tf_y = tf.placeholder(dtype=tf.float32, shape=None, name='tf_y')
res = tf.cond(tf_x < tf_y,
lambda: tf.add(tf_x, tf_y, name='result_add'),
lambda: tf.subtract(tf_x, tf_y, name='result_sub'))
print('Object: ', res)
with tf.Session(graph=g) as sess:
print('x < y: %s -> Result:' % (x < y), res.eval(feed_dict={'tf_x:0': x, 'tf_y:0': y}))
x, y = 2.0, 1.0
print('x < y: %s -> Result:' % (x < y), res.eval(feed_dict={'tf_x:0': x, 'tf_y:0': y}))
計算グラフの構築に制御フローを使用する
21
Object: Tensor("cond/Merge:0", dtype=float32)
x < y: True -> Result: 3.0
x < y: False -> Result: 1.0
TensorFlowが提供している
制御フロー関数を使用する