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()
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.