Search code examples
cntk

How to use gather on 1D vector?


Have been trying to use cntk.ops.gather on 1D vectors. Here is a snippet illustrating what doesn't work:

import cntk
import numpy as np

def main():
    xx = cntk.input_variable(shape=(1))
    yy = cntk.input_variable(shape=(1))
    zz = cntk.sequence.gather(xx, yy)

    xx_value = np.arange(15, dtype=np.float64)
    yy_value = np.array([1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1], dtype=np.float64)
    aa = zz.eval({xx: xx_value.reshape(-1, 1), yy: yy_value.reshape(-1, 1)})
    print(aa)

if __name__ == "__main__":
    main()

Solution

  • The reason for this is that cntk expects a batch of examples to be provided. When it sees, a (15,1) array it converts it to a batch of 15 examples each of length 1. Then when gather is applied cntk is unhappy because some examples in the minibatch produce empty sequences (those for which there is a 0 in yy_value).

    You can solve your problem by specifying the fact that you only have one example in the minibatch in a couple different ways.

    • you can provide the values in lists like this

      aa = zz.eval({xx: [xx_value.reshape(-1, 1)], yy: [yy_value.reshape(-1, 1)]})

    • you can provide the values in a tensor of shape (1,15,1) like this:

      aa = zz.eval({xx: xx_value.reshape(1, -1, 1), yy: yy_value.reshape(1, -1, 1)})

    The latter works only if all the sequences in a minibatch have the same length.