はじめに

前回、定番のHelloWorldをやってので、今回は基本的な数学関連の演算についてまとめてみたいと思います。

公式ドキュメント

TensorFlow APIの公式ドキュメントは下記にあります。

https://www.tensorflow.org/api_guides/python/math_ops


数学関連の関数まとめ

公式ドキュメントに合わせた記載にしています

Arithmetic Operators(算術演算子)


演算関数説明
足し算tf.add(x , y , name=None)x + y 
引き算tf.subtract(x , y , name=None) x - y
掛け算tf.multiply(x , y , name=None)x * y
スカラー積tf.scalar_mul(scalar, x)scalar * x
割り算tf.div(x , y , name=None)x / y
(Python2.7 の割り算方式。
x,yどちらかがfloatの場合は結果はfloatになる。それ以外の場合は整数となる)
割り算tf.divide(x , y , name=None)x / y
割り算tf.truediv(x , y , name=None)x / y
(Python3の割り算方式。整数型をfloatに変換して計算する。
ラウンドダウンの整数として計算させたい場合は  x // y もしくは tf.floordivを利用すること)
割り算の商tf.floordiv(x , y , name=None)x // y
x,yともに整数のときの tf.div(x,y) と同じ。ラウンドダウンした整数を返却する
効率のために、floordivは、負の数に対してC言語の処理をする(PythonやNumpyとは異なる)
割り算tf.realdiv(x , y , name=None)x / y 
xとyが実数の場合、浮動小数点除算を返す。
割り算の商tf.truncatediv(x , y , name=None)x / y の商
切り捨ては、負の数が0に向かって丸められる。
例.-7 / 5 = -1
割り算の商tf.floor_div(x , y , name=None)x // y (切り捨て除算)
割り算の余りtf.truncatemod(x , y , name=None)x / y 整数切り捨て
truncate(x / y) * y + truncate_mod(x, y) = x
割り算の余りtf.floormod(x , y , name=None)x / y の余り
x < 0 , y >=0 または x>=0 , y<0 の場合、下記が成り立つ
floor(x / y) * y + mod(x, y) = x
割り算の余りtf.mod(x , y , name=None)tf.floormodのエイリアス
ベクトルの外積tf.cross(x , y , name=None)ベクトル外積

Basic Math Functions(基本的な数学関数)


演算関数説明
テンソルの加算 tf.add_n(inputs,name=None) 同じ形のテンソルのリストを加算する
テンソルの絶対値 tf.abs(x,name=None)

テンソルの絶対値を計算する。xは複素数を含むテンソル返却値はfloat32/float64

tf.Tensor.__abs__はエイリアス

マイナスに変換 tf.negative(x,name=None) y=-x
符号 tf.sign(x,name=None) x<0 の場合 –1
x=0 の場合 0
x>0 の場合 1

※複素数の場合
x !=0 の場合 x / |x|
それ以外の場合 0
逆数 tf.reciprocal(x, name=None) y=1/x
二乗 tf.square(x, name=None) y=x*x
四捨五入 tf.round(x, name=None) 四捨五入
x = tf.constant([0.9, 2.5, 2.3, 1.5, -4.5])
tf.round(x) # [ 1.0, 2.0, 2.0, 2.0, -4.0 ]
平方根 tf.sqrt(x, name=None) tf.sqrt(x*x)= |x|
平方根の逆数 tf.rsqrt(x, name=None) y=1/tf.sqrt(x)
べき乗(n乗) tf.pow(x, y, name=None) xのy乗
x = tf.constant([[2, 2], [3, 3]])
y = tf.constant([[8, 16], [2, 3]])
tf.pow(x, y) # [[256, 65536], [9, 27]]
底がeの指数関数 tf.exp(x, name=None) 底がオイラー数(e)の指数関数
底がeの指数関数から-1 tf.expm1(x, name=None) y=(exp(x))-1
自然対数 tf.log(x, name=None) 底がオイラー数(e)の対数
1+xの自然対数 tf.log1p(x, name=None) y=log(1+x)
最小値 tf.ceil(x, name=None) xの中の最小値を返却
最大値 tf.floor(x, name=None) xの中の最大値を返却
最大値 tf.maximum(x, y, name=None) x と yを比較した最大値を返却
最小値 tf.minimum(x, y, name=None) x と yを比較した最小値を返却
cos(三角関数) tf.cos(x, name=None) コサインを返却
sin(三角関数) tf.sin(x, name=None) サインを返却
tan(三角関数) tf.tan(x, name=None) タンジェントを返却
ベータ関数の対数 tf.lbeta(x, name='lbeta') ln(|Beta(x)|)
acos(逆三角関数) tf.acos(x, name=None) arccos(x)を返却する
asin(逆三角関数) tf.asin(x, name=None) arcsin(x)を返却
atan(逆三角関数) tf.atan(x, name=None) arctan(x)を返却
cosh(双曲線関数) tf.cosh(x, name=None) 双極関数のcosh(x)を返却する
sinh(双曲線関数) tf.sinh(x, name=None) 双極関数のsinh(x)を返却する
tanh(双曲線関数) tf.tanh(x, name=None) 双極関数のtanh(x)を返却する
acosh(逆双曲線関数) tf.acosh(x, name=None) 逆双極関数のarccosh(x)を返却する
asinh(逆双曲線関数) tf.asinh(x, name=None) 逆双極関数のarcsinh(x)を返却する
atanh(逆双曲線関数) tf.atanh(x, name=None) 逆双極関数のarctanh(x)を返却する
ガンマ関数の対数 tf.lgamma(x, name=None) y=log|Gamma(x)|ガンマ関数の絶対値の対数を返却
ガンマ関数の対数微分 tf.digamma(x, name=None) ガンマ関数の対数(lgamma(x))の微分で定義される関数を返却
ガウスの誤差関数 tf.erf(x, name=None) シグモイド形状の特殊関数の一種であるガウスの誤差関数を返却
相補誤差関数 tf.erfc(x, name=None) 相補誤差関数(1-tf.erf(x))を返却
自乗差  tf.squared_difference(x, y, name=None) (x - y)*(x - y)を返却
正規化した第1種不完全ガンマ関数 tf.igamma(a, x, name=None) 正規化した第1種不完全ガンマ関数P(a,x)(lower incomplete gamma function)を返却
定義: P(a,x)=gamma(a,x)/Gamma(a)=1-Q(a,x)
gamma(a,x):第1種不完全ガンマ関数
Gamma(a):ガンマ関数
正規化した第2種不完全ガンマ関数 tf.igammac(a, x, name=None) 正規化した第2種不完全ガンマ関数Q(a,x)(upper incomplete gamma function)を返却
定義: Q(a,x)=Gamma(a,x)/Gamma(a)=1-P(a,x)
Gamma(a,x):第2種不完全ガンマ関数
Gamma(a):ガンマ関数
フルヴィッツのゼータ関数 tf.zeta(x, q, name=None) フルヴィッツのゼータ関数を返却
ポリガンマ関数 tf.polygamma(a, x, name=None) ポリガンマ関数を返却
正則化された不完全ベータ関数 tf.betainc(a, b, x, name=None) 正則化された不完全ベータ関数を返却
整数変換 tf.rint(x, name=None) xに近い整数に変換する
rint(-1.5) ==> -2.0
rint(0.5000001) ==> 1.0
rint([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]) ==> [-2., -2., -0., 0., 2., 2., 2.]


ソースコード



Matrix Math Functions(基本的な数学関数)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf

# tfセッションの作成
sess = tf.Session()


# 値
#  名前を付けておく
x = tf.constant(10, name='x')
y = tf.constant(3 , name='y')

x2 = tf.constant(10.0, name='x')
y2 = tf.constant(3.0 , name='y')

x3 = tf.constant([1, 2, 3, 4, 5, 6, 7, 8, 9], shape=[3, 3])
y3 = tf.constant([9, 8, 7, 6, 5, 4, 3, 2, 1], shape=[3, 3])

# 計算

# 実行
print("tf.add")
print(sess.run(tf.add(x, y)))

print("tf.subtract")
print(sess.run(tf.subtract(x, y)))

print("tf.multiply")
print(sess.run(tf.multiply(x, y)))

print("tf.scalar_mul")
print(sess.run(tf.scalar_mul(x, y)))

print("tf.div")
print(sess.run(tf.div(x, y)))

print("tf.divide")
print(sess.run(tf.divide(x, y)))

print("tf.truediv")
print(sess.run(tf.truediv(x, y)))

print("tf.floordiv")
print(sess.run(tf.floordiv(x, y)))

print("tf.realdiv")
print(sess.run(tf.realdiv(x2, y2)))

print("tf.truncatediv")
print(sess.run(tf.truncatediv(x, y)))

print("tf.floor_div")
print(sess.run(tf.floor_div(x, y)))

print("tf.truncatemod")
print(sess.run(tf.truncatemod(x, y)))

print("tf.floormod")
print(sess.run(tf.floormod(x, y)))

print("tf.mod")
print(sess.run(tf.mod(x, y)))

print("tf.cross")
print(sess.run(tf.cross(x3, y3)))


実行結果

tf.add
13
tf.subtract
7
tf.multiply
30
tf.scalar_mul
30
tf.div
3
tf.divide
3.3333333333333335
tf.truediv
3.3333333333333335
tf.floordiv
3
tf.realdiv
3.3333333
tf.truncatediv
3
tf.floor_div
3
tf.truncatemod
1
tf.floormod
1
tf.mod
1
tf.cross
[[-10  20 -10]
 [-10  20 -10]
 [-10  20 -10]]


Pythonの算術式をそのままTensorFlowで使ってみる

Pythonの算術式をTensorFlowで使ってみました。

内部的にAPIに変換されているように見えます

calc.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf

# tfセッションの作成
sess = tf.Session()

# 値
a = tf.constant(10)
b = tf.constant(32)

# 計算
c1 = a + b
c2 = b - a
c3 = a * b
c4 = b / a

# 表示
print("add")
print(sess.run(c1))

print("minus")
print(sess.run(c2))

print("times")
print(sess.run(c3))

print("divide")
print(sess.run(c4))

結果
# python3.6 calc.py

add 42 minus 22 times 320 divide 3.2

せっかくなので、tensorboardで表示させてみたいと思います


calc2.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf

# tfセッションの作成
sess = tf.Session()

# TensorBoardのデータ格納ディレクトリ
log_dir = '/conteiner_share/tool/tensorflow/tensorboard/'

# log_dirがあれば削除し、再作成
if tf.gfile.Exists(log_dir):
    tf.gfile.DeleteRecursively(log_dir)
tf.gfile.MakeDirs(log_dir)


# 定数と変数の定義
#  それぞれに名前を付けておく
a = tf.constant(10.0,name='a')
x = tf.Variable(1.0,name='var')

# 計算式の定義
y1 = x + a
y2 = x - a
y3 = x * a
y4 = a / x

# TensorFlowにおける変数のインクリメント。1ずつ増える
x_inc = tf.assign(x, x+1, name='increment')

# TensorBoard にscalarとして表示させる

tf.summary.scalar('Add', y1)
tf.summary.scalar('minus', y2)
tf.summary.scalar('times', y3)
tf.summary.scalar('divide', y4)

# 表示したいデータをマージする
merged = tf.summary.merge_all()

# データをグラフとして表示する
writer = tf.summary.FileWriter(log_dir, sess.graph)

# 変数の初期化
init_op = tf.global_variables_initializer()
sess.run(init_op)

# 10回繰り返す
for i in range(10):
        summary = sess.run(merged)
        writer.add_summary(summary,i)
        sess.run(x_inc) # x++を実行


tensorbordの起動
# tensorboard --logdir=/conteiner_share/tool/tensorflow/tensorboard/ --path_prefix=/tensorboard

モデルのグラフ(画面上部にあるGRAPHSをクリック)
WS2018-05-30_10_53_40000000

add_1の詳細
WS2018-05-30_11_02_07000000

add_1にINPUTされているy(add_1/y)の詳細
WS2018-05-30_11_02_21000000

計算グラフの説明
  • 変数(var)と定数(a)がそれぞれのオペレーション add(足し算) , sub(引き算) , mul(掛け算) , truediv(割り算)にINPUT
  • それらの結果がScararグラフとして Add,minus,times,divide に出力
  • 変数(var)は、定数(y=[float]1) とともにオペレーション add_1(足し算。tensorbordの仕様としてオペレーション名がadd_{数字}という形でインクリメントされている)にINPUTされ、変数(var)を更新している




スカラーのグラフ(画面上部にあるSCALARSをクリック)
WS2018-05-23_15_39_29000000
WS2018-05-23_15_42_07000000
WS2018-05-23_15_42_13000000
WS2018-05-23_15_42_20000000
WS2018-05-23_15_42_38000000




一つの計算式に複数のオペレーション(足し算、引き算、掛け算、割り算)が入るような少し複雑な四則演算にしてみる。

calc3.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tensorflow as tf

# tfセッションの作成
sess = tf.Session()

# TensorBoardのデータ格納ディレクトリ
log_dir = '/conteiner_share/tool/tensorflow/tensorboard/'

# log_dirがあれば削除し、再作成
if tf.gfile.Exists(log_dir):
    tf.gfile.DeleteRecursively(log_dir)
tf.gfile.MakeDirs(log_dir)


# 定数と変数の定義
#  名前を付けておく
a = tf.constant(10.0,name='a')
b = tf.constant(5.0,name='b')
x = tf.Variable(1.0,name='var')

# 計算
y1 = x + a - b
y2 = x - a + b
y3 = (x * x * a) / b
y4 = (a / x) * b + a - b

# TensorFlowにおける変数のインクリメント。1ずつ増える
x_inc = tf.assign(x, x+1, name='increment')

# TensorBoard にscalarとして表示させる
# それぞれのスカラー値に名前をつけておく
tf.summary.scalar('calc1', y1)
tf.summary.scalar('calc2', y2)
tf.summary.scalar('calc3', y3)
tf.summary.scalar('calc4', y4)

# 表示したいデータをマージする
merged = tf.summary.merge_all()

# データをグラフとして表示する
writer = tf.summary.FileWriter(log_dir, sess.graph)

# 変数の初期化
init_op = tf.global_variables_initializer()
sess.run(init_op)

# 10回繰り返す
for i in range(10):
        summary = sess.run(merged)
        writer.add_summary(summary,i)
        sess.run(x_inc) # x++を実行

変更点したのは、定数bの追加計算式の修正です

計算グラフ

WS2018-05-30_11_18_12000000



それぞれの計算式において、オペレーションが順番に処理されているのがわかります。
そして最後の結果が scalar のグラフとして出力されています


スカラーグラフ

WS2018-05-30_11_20_59000000
WS2018-05-30_11_21_05000000
WS2018-05-30_11_21_16000000
WS2018-05-30_11_21_23000000