tensorflow は numpy とほぼ同じなので、numpy でまず考えていきます。
for i in range(N):
z[i] = x[i] * y[i]
は、z = x * y[..., np.newaxis]
と同値です。
y[..., np.newaxis]
とすることで、y
の形状を (N,) から (N, 1) と変更しており、
x * y[..., np.newaxis]
は (N, M) * (N, 1) の要素ごとの積になります。
形状が一致していないので、ブロードキャストの規則が適用され、(N, 1) -> (N, M) にした上で計算されます。
python
1import numpy as np
2import tensorflow as tf
3
4N, M = 5, 3
5x = np.random.rand(N, M)
6y = np.random.rand(N)
7z1 = np.zeros((N, M))
8
9for i in range(N):
10 z1[i] = x[i] * y[i]
11
12# これは以下と同値
13z2 = x * y[..., np.newaxis]
14print(np.allclose(z1, z2))
TensorFlow も同様に形状が (None, N) の y を末尾 (axis=-1) に次元を1つ挿入して (None, N, 1) にした上で、形状が (None, N, M) の x と演算を行います。
すると、同様にブロードキャストが行われ、望む結果が得られます。
python
1import numpy as np
2import tensorflow as tf
3
4N, M = 5, 3
5x = np.random.rand(10, N, M)
6y = np.random.rand(10, N)
7
8x_in = tf.placeholder(tf.float32, shape=[None, N, M])
9y_in = tf.placeholder(tf.float32, shape=[None, N])
10
11z_out = x_in * tf.expand_dims(y_in, axis=-1)
12
13with tf.Session() as sess:
14 ret = sess.run(z_out, feed_dict={x_in: x, y_in: y})
15
16print(ret)
numpy, TensorFlow でコードを書く場合は、ブロードキャスト及び関数を利用することで基本的には for 文を書く必要はないはずです。
特に TensorFlow のテンソルは要素ごとにアクセスしてそこに値を代入するといったことはできないので、ブロードキャストを使った演算を習得することが必須となります。
numpy では for 文を使って要素に1つずつ代入することはできるのですが、コードがかなり遅くなるので、おすすめできません。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。