Diego Orellana
Diego Orellana

Reputation: 1024

Multiply a set of constants (1D array) with a set of matrixes (3D array) in Tensorflow

My end goal is to train a 4D multivariate gaussian distribution parameterized on the mean and covariance

enter image description here

where,

enter image description here

and,

enter image description here

Currently I have the following code:

import tensorflow as tf
import numpy as np

value = [[1,2.0,3,4,5],[0,2,4,6,8],[80,7,6,5,4]]

value=tf.constant(value)

cov= tf.slice(value,[0,int(value.shape[1])-1],[int(value.shape[0]),1])
mean= tf.slice(value,[0,0],[int(value.shape[0]),int(value.shape[1])-1])

eyes=tf.eye(int(mean.shape[1]),batch_shape=[int(value.shape[0])])


#eyes = tf.multiply(eyes,cov)



normal = tf.contrib.distributions.MultivariateNormalFullCovariance(
                 loc=mean,
                 covariance_matrix=eyes) 

value = [[1,2.0,3,4,5],[0,2,4,6,8],[80,7,6,5,4]] is an example of what the rest of the code may be receiving.

In the example above

cov = <tf.Tensor 'Slice_2:0' shape=(3, 1) dtype=float32>
eyes = <tf.Tensor 'eye_1/MatrixDiag:0' shape=(3, 4, 4) dtype=float32>

                     cov =  [[5.] [8.] [4.]]` 
                     eyes =  [[[1. 0. 0. 0.]
                              [0. 1. 0. 0.]
                              [0. 0. 1. 0.]
                              [0. 0. 0. 1.]]

                             [[1. 0. 0. 0.]
                              [0. 1. 0. 0.]
                              [0. 0. 1. 0.]
                              [0. 0. 0. 1.]]

                             [[1. 0. 0. 0.]
                              [0. 1. 0. 0.]
                              [0. 0. 1. 0.]
                              [0. 0. 0. 1.]]]`

My question is, How can I obtain result given cov and eyes? where result is as follows:

result = [[[5., 0., 0., 0.],
           [0., 5., 0., 0.],
           [0., 0., 5., 0.],
           [0., 0., 0., 5.]],

          [[8., 0., 0., 0.],
           [0., 8., 0., 0.],
           [0., 0., 8., 0.],
           [0., 0., 0., 8.]],

          [[4., 0., 0., 0.],
           [0., 4., 0., 0.],
           [0., 0., 4., 0.],
           [0., 0., 0., 4.]]]

enter image description here

Thanks, in advance.

Upvotes: 2

Views: 802

Answers (1)

dtward
dtward

Reputation: 869

Tensorflow uses the same type of indexing as numpy, which can be quite powerful.

You can look at details here: https://docs.scipy.org/doc/numpy-1.13.0/user/basics.broadcasting.html Note that np.newaxis is defined to be the same as None.

For your problem, you can add an extra dimension to your data to make sure there's no ambiguity in how arrays get multiplied.

import numpy as np
cov = np.array([[5.],[8.],[4.]])
eyes = np.array([[[1.0,0,0,0],[0.0,1.0,0.0,0],[0.0,0.0,1.0,0],[0.0,0.0,0.0,1.0]],[[1.0,0,0,0],[0.0,1.0,0.0,0],[0.0,0.0,1.0,0],[0.0,0.0,0.0,1.0]],[[1.0,0,0,0],[0.0,1.0,0.0,0],[0.0,0.0,1.0,0],[0.0,0.0,0.0,1.0]]])
result = cov[:,:,None]*eyes

Using None here adds an extra dimension, making cov into a 3x1x1 array, which can unambiguously multiply with a 3x4x4 array. You can use None this way in tensorflow as well.

Two arrays can multiply unambiguously if each corresponding dimensions are either the same size, or one of them has size 1.

Upvotes: 1

Related Questions