Tensorflowにおける各種演算まとめ

  • 22
    いいね
  • 0
    コメント

はじめに

Tensorflowではテンソルと呼ばれる量を扱うので、Numpyのメソッド等は使えません。そのためTensorflowに用意されているメソッドを用いる必要があります。

ここでは基本的な四則演算と行列演算についてまとめています。特にPythonで定義されている各種演算(+, -, /, //, %)と比べています。

注意
- すべての演算をまとめているわけではないので、その他の演算については公式ドキュメントを参照ください。
- Tensorflowでは全てテンソルを扱うので、データの種類に言及するときは、テンソルを飛ばして「リストは〜」「ベクトルは〜」などと書いています。その点注意していただければと思います。

動作環境

Tensorflow 1.2.1

四則演算

足し算 tf.add

import tensorflow as tf

const1 = tf.constant(2)
const2 = tf.constant(3)
add_op = tf.add(const1, const2) # 2 + 3
with tf.Session() as sess:
    result = sess.run(add_op)
    print(result)
5

Python3の加算+に相当する。

引き算 tf.subtract

import tensorflow as tf

const1 = tf.constant(2)
const2 = tf.constant(3)
subt_op = tf.subtract(const1, const2) # 2 - 3

with tf.Session() as sess:
    result = sess.run(subt_op)
    print(result)
-1

これは-と同じもの。

割り算 - Python2 ver - tf.div


import tensorflow as tf

const1 = tf.constant(2)
const2 = tf.constant(3)
div2_op = tf.div(const1, const2) # 2 / 3 in Python2

with tf.Session() as sess:
    result = sess.run(div_op)
    print(result)
0

Python2での割り算/に相当する。公式では、次のtf.divideが推奨されている。

割り算 - Python3 ver - tf.divide

import tensorflow as tf

const1 = tf.constant(2)
const2 = tf.constant(3)
div_op = tf.divide(const1, const2) # 2 / 3 in Python3

with tf.Session() as sess:
    result = sess.run(div_op)
    print(result)
0.666666666667

Python3での/に相当

整数除算 tf.floordiv

import tensorflow as tf

const1 = tf.constant(2)
const2 = tf.constant(3)
fdiv_op = tf.floordiv(const1, const2) # 2 // 3

with tf.Session() as sess:
    result = sess.run(fdiv_op)
    print(result)
0

Python3の//に相当する。(小数点以下切り捨て)

剰余演算 tf.mod

import tensorflow as tf

const1 = tf.constant(2)
const2 = tf.constant(4)
mod_op = tf.mod(const1, const2) # 2 % 3 

with tf.Session() as sess:
    result = sess.run(mod_op)
    print(result)
2

Python3の%に相当する。

スカラー積 tf.scalar_mul

import tensorflow as tf

const1 = tf.constant(2) #定数を宣言(値は2)
const2 = tf.constant(3)
smul_op = tf.scalar_mul(const1, const2) # 2 * 3 

with tf.Session() as sess:
    result = sess.run(smul_op)
    print(result)
6

定数同士の積。

ベクトル外積 tf.cross

import tensorflow as tf

const1 = tf.constant([1, 2, 3])
const2 = tf.constant([4, 5, 6])
cross_op = tf.cross(const1, const2) # [1, 2, 3] x [4, 5, 6]

with tf.Session() as sess:
    result = sess.run(cross_op)
    print(result)
[-3  6 -3]

ベクトル積(外積)についてはググれば定義が出てくるのでここでは省略します。

行列演算

要素が全て1の行列 tf.ones


import numpy as np
import tensorflow as tf

t = tf.ones([3, 2])

with tf.Session() as sess:
    print("tf.ones([3, 2]) = %s" % sess.run(t))    
tf.ones([3, 2]) = [[ 1.  1.]
 [ 1.  1.]
 [ 1.  1.]]

tf.ones([3,2]): すべての要素が1の3x2行列を作成

要素がすべて0の行列 tf.zeros


import numpy as np
import tensorflow as tf

t = tf.zeros([5])

with tf.Session() as sess:
    print("tf.zeros([5]) = %s" % sess.run(t))
tf.zeros([5]) = [ 0.  0.  0.  0.  0.]

tf.zeros([5]): すべての要素が0の1x5行列(要素数5のベクトル)を作成

乱数を要素とする行列 tf.random_uniform


import numpy as np
import tensorflow as tf

t = tf.random_uniform([1, 3])

with tf.Session() as sess:
    print("tf.random_uniform([1, 3]) = %s" % sess.run(t))
tf.random_uniform([1, 3]) = [[ 0.16699052  0.04628575  0.38685966]]

tf.random_uniform([1,3]): 0から1までのランダムに生成された数を要素とする、1x3行列(要素数3のベクトル)を作成する。

指定された区間の要素数をリストとして出力 tf.linspace


import numpy as np
import tensorflow as tf

t = tf.linspace(1.0, 7.0, 4)

with tf.Session() as sess:
    print("tf.linspace(1.0, 7.0, 4) = %s" % sess.run(t))
tf.linspace(1.0, 7.0, 4) = [ 1.  3.  5.  7.]

tf.linspace(1.0,7.0,4):1.0から4.0までを4つに区切って数を昇順に生成し、リスト(ベクトル)として出力する。

行列積

import tensorflow as tf

const1 = tf.random_uniform([3,2])
const2 = tf.random_uniform([2,3])
mul_op = tf.matmul(const1, const2)

with tf.Session() as sess:
    print("const1: %s" % sess.run(const1))
    print("const2: %s" % sess.run(const2))
    print("tf.matmul(const1, const2) = %s" % sess.run(mul_op))
const1: [[ 0.22310185  0.76020801]
 [ 0.04765964  0.81115341]
 [ 0.15238702  0.24294829]]
const2: [[ 0.89871132  0.3882308   0.54530931]
 [ 0.60662949  0.27270687  0.20178115]]
tf.matmul(const1, const2) = [[ 0.55778277  0.5268842   0.72335124]
 [ 0.42495638  0.3350077   0.66840851]
 [ 0.45947441  0.2069075   0.99706292]]

考える行列を$A_{ij}$, $B_{ij}$とする。AはNxM行列. BはKxL行列とする。このとき、積を行うには、

  • tf.matmul(A,B)が可能であるためには M=K
  • tf.matmul(B,A)が可能であるためには L=N

が成り立つ必要がある。(つまり一つ目の行列の列と、2つめの行列の行の要素数が一致しないといけない。) これを疎かにするとエラーが多発するので注意する。特に行列を転地するにはtf.transposeを使うか、tf.matmulのオプションで転置をTrueにすればいい。このあたりは公式ドキュメントを参照すること。

Numpyリストをテンソルに変換 tf.convert_to_tensor


import numpy as np
import tensorflow as tf

t = tf.convert_to_tensor(np.linspace(1, 7, 4))

with tf.Session() as sess:
    print("tf.convert_to_tensor( np.linspace(1, 7, 4) ) = %s" % sess.run(t))
tf.convert_to_tensor( np.linspace(1, 7, 4) ) = [ 1.  3.  5.  7.]

tf.convert_to_tensor: 生成されたNumpyリストをテンソルに変換する。

その他

値の代入


import tensorflow as tf

# see https://www.tensorflow.org/api_guides/python/state_ops
print("\n変数\n=====================")

w = tf.Variable(tf.zeros([3, 2])) #変数(行列)wの宣言. 初期値はゼロ行列

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    print("w = %s" % sess.run(w))
    sess.run(tf.assign(w, tf.ones([3, 2])))

    wn = sess.run(w)
    print("w = %s" % wn)
変数
=====================
w = [[ 0.  0.]
 [ 0.  0.]
 [ 0.  0.]]
w = [[ 1.  1.]
 [ 1.  1.]
 [ 1.  1.]]
  • tf.assign(w, tf.ones([3, 2]): 変数wtf.ones([3,2])(要素がすべて1の3x2行列を代入する.

この演算は行列だけに限らない。(スカラー変数にも可能)

シンボリック演算


import tensorflow as tf

print("\nシンボリック変数\n=====================")

a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
a_times_b1 = tf.multiply(a, b) #  multiplication of a and b
a_times_b2 = a * b

with tf.Session() as sess:
    # where "name" is the python symbol
    print("%f should equal 2.0" % sess.run(a_times_b1, feed_dict={a: 1, b: 2}))
    print("%f should equal 9.0" % sess.run(a_times_b1, feed_dict={a: 3, b: 3}))
    print("%f should equal 9.0" % sess.run(a_times_b2, feed_dict={a: 3, b: 3}))
シンボリック変数
=====================
2.000000 should equal 2.0
9.000000 should equal 9.0
9.000000 should equal 9.0

一つだけの値を固定せずに、いくつかの値をfeed_dictを用いて後から代入する。

参考: ポテチ製造から学ぶTensorflowの考え方

各種関数


import tensorflow as tf

print("\n数学関数\n=====================")

x = tf.linspace(0., 4., 5)

with tf.Session() as sess:
    print("x = %s" % sess.run(x))
    print("(x+1)**2 - 2) = %s" % sess.run( (x+1)**2 - 2))
    print("sin(x) = %s" % sess.run( tf.sin(x) ))
    print("sum(x) = %s" % sess.run( tf.reduce_sum(x) ))
数学関数
=====================
x = [ 0.  1.  2.  3.  4.]
(x+1)**2 - 2) = [ -1.   2.   7.  14.  23.]
sin(x) = [ 0.          0.84147096  0.90929741  0.14112    -0.7568025 ]
sum(x) = 10.0

詳しくは公式ドキュメント参照

変数としてリストを取る

これらの関数は変数としてリストを取れる:

print("\n引数にベクトル(シーケンス, リスト)を取れる。 (Numpyライク)\n=====================")
tf.sin(3.)
tf.sin([1., 2., 3.])
tf.sin(tf.linspace(0., 10., 20))
tf.sin(np.linspace(0, 10, 20))  # equivalent
tf.sin(tf.ones(shape=(2, 3, 4)))  # 2x3x4 tensor

# Operators (+, -, /, *)
a = tf.zeros(shape=(2, 3))
b = tf.ones(shape=(2, 3))
c = tf.ones(shape=(3, 2))

with tf.Session() as sess:
    print('a + b: %s'% sess.run(a + b))  # same as tf.add(a, b)
    print('a - b: %s' % sess.run(a - b))  # same as tf.subtract(a, b)
    print('a * b: %s' % sess.run(a * b))  # same as tf.mul(a, b)
    print('a / b: %s' % sess.run(a / b))  # same as tf.division(a, b)
# a + c  # doesn't work; tensors need to be of same shape
引数にベクトル(シーケンス, リスト)を取れる。 (Numpyライク)
=====================
a + b: [[ 1.  1.  1.]
 [ 1.  1.  1.]]
a - b: [[-1. -1. -1.]
 [-1. -1. -1.]]
a * b: [[ 0.  0.  0.]
 [ 0.  0.  0.]]
a / b: [[ 0.  0.  0.]
 [ 0.  0.  0.]]