はじめに
前回、定番の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をクリック)

add_1の詳細

add_1にINPUTされているy(add_1/y)の詳細

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





一つの計算式に複数のオペレーション(足し算、引き算、掛け算、割り算)が入るような少し複雑な四則演算にしてみる。
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の追加と計算式の修正です
計算グラフ

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




コメント