antande
antande

Reputation: 169

Vectorize row-by-row element-wise product of two different shaped matrices in Tensorflow

In Tensorflow, say I have two matrices M and N, how can I get a tensor whose (i, j) element is the element-wise product of the i-th row of M and j-th row of N?

Upvotes: 1

Views: 415

Answers (1)

Maxim
Maxim

Reputation: 53768

Here's a trick: expand both matrices to 3D and do elemet-wise multiply (a.k.a. Hadamard product).

# Let `a` and `b` be the rank 2 tensors, with the same 2nd dimension
lhs = tf.expand_dims(a, axis=1)
rhs = tf.expand_dims(b, axis=0)
products = lhs * rhs

Let's check that it works:

tf.InteractiveSession()

# 2 x 3
a = tf.constant([
  [1, 2, 3],
  [3, 2, 1],
])

# 3 x 3
b = tf.constant([
  [2, 1, 1],
  [2, 2, 0],
  [1, 2, 1],
])

lhs = tf.expand_dims(a, axis=1)
rhs = tf.expand_dims(b, axis=0)
products = lhs * rhs
print(products.eval())

# [[[2 2 3]
#   [2 4 0]
#   [1 4 3]]
# 
#  [[6 2 1]
#   [6 4 0]
#   [3 4 1]]]

The same trick actually works in numpy as well and with any element-wise binary operation (sum, product, division, ...). Here's an example of row-by-row element-wise sum tensor:

# 2 x 3
a = np.array([
  [1, 2, 3],
  [3, 2, 1],
])

# 3 x 3
b = np.array([
  [2, 1, 1],
  [2, 2, 0],
  [1, 2, 1],
])

lhs = np.expand_dims(a, axis=1)
rhs = np.expand_dims(b, axis=0)
sums = lhs + rhs

# [[[2 2 3]
#   [2 4 0]
#   [1 4 3]]
# 
#  [[6 2 1]
#   [6 4 0]
#   [3 4 1]]]

Upvotes: 2

Related Questions