はじめに
数式をTensorFlowのモデルとして記述する際、演算記号がTensorFlowのどのAPIに対応しているかをまとめてみました。
演算対象のテンソル\(x\)の定義
\[
x_{i,j}=
\begin{pmatrix}
x_{1,1} & x_{1,2} & \ldots & x_{1,n} \\
x_{2,1} & x_{2,2} & \ldots & x_{2,n} \\
\vdots & \vdots & \ddots & & \vdots \\
x_{m,1} & x_{m,2} & \ldots & x_{m,n}
\end{pmatrix}
(1 \lt i \lt m,1 \lt j \lt n)
\]
x = tf.constant([1., 2., 3., 4., 5., 6., 7., 8., 9.], shape=[3, 3])
以降、下記の様な完全なプログラムに組み込んだときの出力結果もあわせて記載します。
import tensorflow as tf
x = tf.constant([1., 2., 3., 4., 5., 6., 7., 8., 9.], shape=[3, 3])
y = x # この行を置き換えて確認します。
with tf.Session() as sess:
print(sess.run(y))
このプログラムを実行すると、下記の様な出力を得られます。
[[ 1. 2. 3.]
[ 4. 5. 6.]
[ 7. 8. 9.]]
tf.negative 符号反転
\[
y = –x
\]
y = tf.negative(x)
# y = -x
# y = tf.multiply(-1., x)
[[-1. -2. -3.]
[-4. -5. -6.]
[-7. -8. -9.]]
TensorFlow 1.0で、tf.negから変更されました。
tf.abs 絶対値
\[
y= |x|
\]
y = tf.abs(x)
[[ 1. 2. 3.]
[ 4. 5. 6.]
[ 7. 8. 9.]]
tf.reciprocal 逆数
\[
y = \frac{1}{x}
\]
y = tf.reciprocal(x)
[[ 1. 0.5 0.33333334]
[ 0.25 0.2 0.16666667]
[ 0.14285715 0.125 0.11111111]]
TensorFlow 1.0で、tf.invから変更されました。
tf.square 2乗
\[
y = x^{2}
\]
y = tf.square(x)
[[ 1. 4. 9.]
[ 16. 25. 36.]
[ 49. 64. 81.]]
tf.sqrt べき根
\[
y = \sqrt{x}
\]
y = tf.sqrt(x)
[[ 0.99999994 1.41421342 1.73205078]
[ 1.99999988 2.23606801 2.44948959]
[ 2.64575124 2.82842684 3. ]]
TensorFlowのべき根計算は誤差を含むようですね。
\[
y = (\sqrt{x})^2 = x
\]
y = tf.square(tf.sqrt(x))
[[ 0.99999988 1.99999964 3. ]
[ 3.99999952 5. 5.99999905]
[ 6.99999952 7.99999857 9. ]]
先に2乗してからべき根をとるとどうでしょうか。
\[
y = \sqrt{x^2} = x
\]
y = tf.sqrt(tf.square(x))
[[ 0.99999994 1.99999988 2.99999976]
[ 3.99999976 5. 5.99999952]
[ 6.99999952 7.99999952 9. ]]
tf.rsqrt べき根の逆数
\[
y = \frac{1}{\sqrt{x}}
\]
y = tf.rsqrt(x)
[[ 0.99999994 0.70710671 0.57735026]
[ 0.49999997 0.44721359 0.40824828]
[ 0.37796447 0.35355335 0.33333334]]
べき根の逆数と元の値を掛けてみて、べき根計算の結果と比べてみましょう。
\[
y = \frac{1}{\sqrt{x}} \times x = \sqrt{x}
\]
y = tf.rsqrt(x) * x
[[ 0.99999994 1.41421342 1.73205078]
[ 1.99999988 2.23606801 2.44948959]
[ 2.64575124 2.82842684 3. ]]
tf.exp 指数
\[
y = e^{x}
\]
y = tf.exp(x)
[[ 2.71828175e+00 7.38905621e+00 2.00855370e+01]
[ 5.45981522e+01 1.48413162e+02 4.03428802e+02]
[ 1.09663318e+03 2.98095801e+03 8.10308398e+03]]
tf.log 自然対数
\[
y = \log_e x
\]
y = tf.log(x)
[[ 0. 0.69314718 1.09861231]
[ 1.38629436 1.60943794 1.79175949]
[ 1.94591022 2.07944155 2.19722462]]
指数と自然対数について誤差を確認してみました。
\[
y = \log_e e^{x} = x \log_e e = x
\]
(定義より、\(x = a^{p} \)のとき、\( p = \log_a x\) である。\( p = 1 \) ならば \( x = a\)、\(1 = \log_a a\))
y = tf.log(tf.exp(x))
[[ 1. 2. 3.]
[ 4. 5. 6.]
[ 7. 8. 9.]]
\[
y = e^{\log_e x} = x
\]
(定義より、\( x = a^{p} \) のとき、\( p = \log_a x \) である。pを消去して、\( x = a^{\log_a x} \))
y = tf.exp(tf.log(x))
[[ 1. 2. 3. ]
[ 4. 5. 6. ]
[ 7.00000048 8. 9. ]]
tf.reduce_sum 総和
reduce_sum はテンソルの任意の次元の要素を足し合わせて新しいテンソルを返します。何次元目を足し合わせるかは、第2引数またはreduction_indicesで指定します。指定がなければすべての次元で足し合わせて、1つの値を返します。
\( i \) (1次元目)で足し合わせ
\[
y = \sum_{i=1}^{m} x_{ij}
\]
y = tf.reduce_sum(x, 0)
[12. 15. 18.]
\( j \) (2次元目)で足し合わせ
\[
y = \sum_{j=1}^{n} x_{ij}
\]
y = tf.reduce_sum(x, 1)
[ 6. 15. 24.]
すべての次元で足し合わせ
\[
y = \sum_{i=1}^{m} \sum_{j=1}^{n} x_{ij}
\]
y = tf.reduce_sum(x)
45.0
tf.reduce_prod 総乗
reduce_sum はテンソルの任意の次元の要素をかけ合わせて新しいテンソルを返します。何次元目をかけ合わせるかは、第2引数またはreduction_indicesで指定します。指定がなければすべての次元でかけ合わせて、1つの値を返します。
\(i\) (1次元目)でかけ合わせ
\[
y = \prod^{m}_{i=1} x_{ij}
\]
y = tf.reduce_prod(x, 0)
[ 28. 80. 162.]
\(j\) (2次元目)でかけ合わせ
\[
y = \prod^{n}_{j=1} x_{ij}
\]
y = tf.reduce_prod(x, 1)
[ 6. 120. 504.]
すべての次元でかけ合わせ
\[
y = \prod^{m}_{i=1} \prod^{n}_{j=1} x_{ij}
\]
y = tf.reduce_prod(x)
362880.0
tf.reduce_mean 平均
reduce_mean はテンソルの任意の次元の要素の平均を計算して、新しいテンソルを返します。何次元目の平均をとるかは、第2引数またはreduction_indicesで指定します。指定がなければすべての次元の要素の平均を計算して、1つの値を返します。
\(i\) (1次元目)の平均
\[
y = \frac{1}{m} \prod^{m}_{i=1} x_{ij}
\]
y = tf.reduce_mean(x, 0)
[ 4. 5. 6.]
\(j\) (2次元目)の平均
\[
y = \frac{1}{n} \prod^{1}_{j=1} x_{ij}
\]
y = tf.reduce_mean(x, 1)
[ 2. 5. 8.]
すべての次元の平均
\[
y = \frac{1}{mn} \prod^{m}_{i=1} \prod^{n}_{j=1} x_{ij}
\]
y = tf.reduce_mean(x)
5.0