0

How can I include an outer product (of the previous feature vector and itself) as a layer in chainer, especially in a way that's compatible with batching?

Pavel_K
  • 10,748
  • 13
  • 73
  • 186
  • 1
    Please add necessary tags and be a bit more explanatory on your question. – Anuj Nov 22 '17 at 07:28
  • Check out [this link](https://stackoverflow.com/help/how-to-ask) to know how to ask a question – Anuj Nov 22 '17 at 07:28

2 Answers2

1

F.matmul is also very handy.

Depending on the input shapes, you can combine it with F.expand_dims (of course F.reshape works, too) or use transa/transb arguments.

For details, refer to the official documentation of functions.

Code

import chainer.functions as F
import numpy as np

print("---")
x = np.array([[[1], [2], [3]], [[4], [5], [6]]], 'f')
y = np.array([[[1, 2, 3]], [[4, 5, 6]]], 'f')
print(x.shape)
print(y.shape)
z = F.matmul(x, y)
print(z)


print("---")
x = np.array([[[1], [2], [3]], [[4], [5], [6]]], 'f')
y = np.array([[[1], [2], [3]], [[4], [5], [6]]], 'f')
print(x.shape)
print(y.shape)
z = F.matmul(x, y, transb=True)
print(z)


print("---")
x = np.array([[1, 2, 3], [4, 5, 6]], 'f')
y = np.array([[1, 2, 3], [4, 5, 6]], 'f')
print(x.shape)
print(y.shape)
z = F.matmul(
    F.expand_dims(x, -1),
    F.expand_dims(y, -1),
    transb=True)
print(z)

Output

---
(2, 3, 1)
(2, 1, 3)
variable([[[  1.   2.   3.]
           [  2.   4.   6.]
           [  3.   6.   9.]]

          [[ 16.  20.  24.]
           [ 20.  25.  30.]
           [ 24.  30.  36.]]])
---
(2, 3, 1)
(2, 3, 1)
variable([[[  1.   2.   3.]
           [  2.   4.   6.]
           [  3.   6.   9.]]

          [[ 16.  20.  24.]
           [ 20.  25.  30.]
           [ 24.  30.  36.]]])
---
(2, 3)
(2, 3)
variable([[[  1.   2.   3.]
           [  2.   4.   6.]
           [  3.   6.   9.]]

          [[ 16.  20.  24.]
           [ 20.  25.  30.]
           [ 24.  30.  36.]]])
niboshi
  • 1,448
  • 3
  • 12
  • 20
0

You can use F.reshape and F.broadcast_to to explicitly handle array.

Assume you have 2-dim array h with shape (minibatch, feature). If you want to calculate outer product of h and h, try below code. Is this what you want to do?

import numpy as np
from chainer import functions as F


def outer_product(h):
    s0, s1 = h.shape
    h1 = F.reshape(h, (s0, s1, 1))
    h1 = F.broadcast_to(h1, (s0, s1, s1))
    h2 = F.reshape(h, (s0, 1, s1))
    h2 = F.broadcast_to(h2, (s0, s1, s1))
    h_outer = h1 * h2
    return h_outer

# test code
h = np.arange(12).reshape(3, 4).astype(np.float32)
h_outer = outer_product(h)
print(h.shape)
print(h_outer.shape, h_outer.data)
corochann
  • 1,604
  • 1
  • 13
  • 24
  • I haven't verified what the output shape would be for this, but if this can be used as a layer in a neural network, this looks about right, thanks. Ideally the output would have the shape (batch_size, num_features**2), where the outer product matrix is flattened for each data point in the batch. It would be even better to remove the redundant elements from the matrix, but I'm not sure how to best approach that. – jpeterson Nov 23 '17 at 04:24