自分のサイトでは、tensorflow上の四則演算は全てtensorflowのメソッドで行っていました。しかし、他のサイトやtensorflowのチュートリアルを見ればわかるようにプラスやマイナス、アスタリスクなどを使用した計算も可能です。しかし、プログラミング言語で定義されている変数と区別しにくくなるので、私個人としてはメソッドを使用した四則演算をお勧めします。さて、早速プログラム上で確認していきましょう…という前に、tensorflow におけるブロードキャストルールというものについて学びましょう。
ブロードキャストルール
ブロードキャストルールというものは、別に恐ろしく複雑なルールではありません。ざっくりというならば、ベクトル・行列とスカラーの計算規則に関するルールを定めたものです。内容はとても簡単で、ベクトル・行列・スカラーの四則演算を行う際には、次元が一致するように自動で変形されるというものです。変形後の空白に入る数字は、元となった値と同じです。ベクトルが行列に拡張される際には、ベクトルの長さと、行列の次元の1つは必ず同じでなければなりません。また、この応用としてスカラーを引数とする関数をベクトル・行列に使用した場合、ベクトル・行列の各要素にその関数の処理が行われます。
式で示すと
$$
\begin{pmatrix} a & b \\ c & d \end{pmatrix}
+
x
=
\begin{pmatrix} a & b \\ c & d \end{pmatrix}
+
\begin{pmatrix} x & x \\ x & x \end{pmatrix}
$$
というイメージです。
四則演算の略記
では、ブロードキャストルールについてわかったところで、実際に四則演算を記号を用いて行ってみましょう。注意するべきなのは、スカラー以外の乗算と割算です。これらは、要素ごとの計算となります。式で表すのならば
$$
\left( \begin{array}{c} a_1 \\ a_2 \\ \vdots \\ a_n \end{array}\right)
\times
\left( \begin{array}{c} b_1 \\ b_2 \\ \vdots \\ b_n \end{array}\right)
=
\left( \begin{array}{c} a_1 \times b_1 \\ a_2 \times b_2 \\ \vdots \\ a_n \times b_n \end{array}\right)
$$
$$
\left( \begin{array}{c} a_1 \\ a_2 \\ \vdots \\ a_n \end{array}\right)
\div
\left( \begin{array}{c} b_1 \\ b_2 \\ \vdots \\ b_n \end{array}\right)
=
\left( \begin{array}{c} a_1 \div b_1 \\ a_2 \div b_2 \\ \vdots \\ a_n \div b_n \end{array}\right)
$$
$$
\begin{eqnarray}
\left(
\begin{array}{cccc}
a_{ 11 } & a_{ 12 } & \ldots & a_{ 1n } \\
a_{ 21 } & a_{ 22 } & \ldots & a_{ 2n } \\
\vdots & \vdots & \ddots & \vdots \\
a_{ m1 } & a_{ m2 } & \ldots & a_{ mn }
\end{array}
\right)
\times
\left(
\begin{array}{cccc}
b_{ 11 } & b_{ 12 } & \ldots & b_{ 1n } \\
b_{ 21 } & b_{ 22 } & \ldots & b_{ 2n } \\
\vdots & \vdots & \ddots & \vdots \\
b_{ m1 } & b_{ m2 } & \ldots & b_{ mn }
\end{array}
\right)
=
\left(
\begin{array}{cccc}
a_{ 11 } \times b_{ 11 } & a_{ 12 } \times b_{ 12 } & \ldots & a_{ 1n } \times b_{ 1n } \\
a_{ 21 } \times b_{ 21 } & a_{ 22 } \times b_{ 22 } & \ldots & a_{ 2n } \times b_{ 2n } \\
\vdots & \vdots & \ddots & \vdots \\
a_{ m1 } \times b_{ m1 } & a_{ m2 } \times b_{ m2 } & \ldots & a_{ mn } \times b_{ mn }
\end{array}
\right)
\end{eqnarray}
$$
$$
\begin{eqnarray}
\left(
\begin{array}{cccc}
a_{ 11 } & a_{ 12 } & \ldots & a_{ 1n } \\
a_{ 21 } & a_{ 22 } & \ldots & a_{ 2n } \\
\vdots & \vdots & \ddots & \vdots \\
a_{ m1 } & a_{ m2 } & \ldots & a_{ mn }
\end{array}
\right)
\div
\left(
\begin{array}{cccc}
b_{ 11 } & b_{ 12 } & \ldots & b_{ 1n } \\
b_{ 21 } & b_{ 22 } & \ldots & b_{ 2n } \\
\vdots & \vdots & \ddots & \vdots \\
b_{ m1 } & b_{ m2 } & \ldots & b_{ mn }
\end{array}
\right)
=
\left(
\begin{array}{cccc}
a_{ 11 } \div b_{ 11 } & a_{ 12 } \div b_{ 12 } & \ldots & a_{ 1n } \div b_{ 1n } \\
a_{ 21 } \div b_{ 21 } & a_{ 22 } \div b_{ 22 } & \ldots & a_{ 2n } \div b_{ 2n } \\
\vdots & \vdots & \ddots & \vdots \\
a_{ m1 } \div b_{ m1 } & a_{ m2 } \div b_{ m2 } & \ldots & a_{ mn } \div b_{ mn }
\end{array}
\right)
\end{eqnarray}
$$
となります。
import tensorflow as tf
#式の宣言
# スカラーの定数宣言
s1=tf.constant(5)
s2=tf.constant(3)
# ベクトルの定数定義
v1=tf.constant([1,2])
v2=tf.constant([2,1])
# 行列の定数定義
m1=tf.constant([[1,2],[3,4]])
m2=tf.constant([[3,4],[1,2]])
#式の宣言終了
#セッションの実行
with tf.Session() as s:
list1=[s1,v1,m1]
list2=[s2,v2,m2]
list3=["スカラー","ベクトル","行列"]
for i in range(0,3):
for k in range(0,3):
print("< "+list3[i]+" & "+list3[k]+" >")
print(" 加算:\n"+str(s.run(list1[i]+list2[k]))+"\n")
print(" 減算:\n"+str(s.run(list1[i]-list2[k]))+"\n")
print(" 乗算:\n"+str(s.run(list1[i]*list2[k]))+"\n")
print(" 割算:\n"+str(s.run(list1[i]/list2[k]))+"\n")
<実行結果>
< スカラー & スカラー >
加算:
8
減算:
2
乗算:
15
割算:
1.6666666666666667
< スカラー & ベクトル >
加算:
[7 6]
減算:
[3 4]
乗算:
[10 5]
割算:
[2.5 5. ]
< スカラー & 行列 >
加算:
[[8 9]
[6 7]]
減算:
[[2 1]
[4 3]]
乗算:
[[15 20]
[ 5 10]]
割算:
[[1.66666667 1.25 ]
[5. 2.5 ]]
< ベクトル & スカラー >
加算:
[4 5]
減算:
[-2 -1]
乗算:
[3 6]
割算:
[0.33333333 0.66666667]
< ベクトル & ベクトル >
加算:
[3 3]
減算:
[-1 1]
乗算:
[2 2]
割算:
[0.5 2. ]
< ベクトル & 行列 >
加算:
[[4 6]
[2 4]]
減算:
[[-2 -2]
[ 0 0]]
乗算:
[[3 8]
[1 4]]
割算:
[[0.33333333 0.5 ]
[1. 1. ]]
< 行列 & スカラー >
加算:
[[4 5]
[6 7]]
減算:
[[-2 -1]
[ 0 1]]
乗算:
[[ 3 6]
[ 9 12]]
割算:
[[0.33333333 0.66666667]
[1. 1.33333333]]
< 行列 & ベクトル >
加算:
[[3 3]
[5 5]]
減算:
[[-1 1]
[ 1 3]]
乗算:
[[2 2]
[6 4]]
割算:
[[0.5 2. ]
[1.5 4. ]]
< 行列 & 行列 >
加算:
[[4 6]
[4 6]]
減算:
[[-2 -2]
[ 2 2]]
乗算:
[[3 8]
[3 8]]
割算:
[[0.33333333 0.5 ]
[3. 2. ]]
まとめ
- 四則演算は記号を使用しても行うことができる
- 次元数が異なるもの同士の計算では、次元数が少ない方が自動で拡張される
- スカラーが入力の関数に行列・ベクトルを入力すると要素毎に処理される