RedisAI/redisai-py

Stacking tensors would cause unexpected behaviour

hhsecond opened this issue · 6 comments

@mnunberg Do you think we need to expect more than one tensors in the BlobTensor __init__ and stack them together while setting up the tensor?
One problem I could see is with the else case. If I am passing a two-dimensional tensor and if my model expects the same, my model will crash because size=1 of the below snippet will add another dimension to my input while setting the tensor.

if len(blobs) > 1:
    blobarr = bytearray()
    for b in blobs:
        if isinstance(b, BlobTensor):
            b = b.value[0]
        blobarr += b
    size = len(blobs)
    blobs = bytes(blobarr)
else:
    blobs = bytes(blobs[0])
    size = 1

@mnunberg Just found another issue with this approach. I can't ever set a single dimensional tensor. redisai.Client always converts it to at least two-dimensional tensor. Or am I doing something wrong?
For example, This will set a tensor of size (1, 2) while I needed a tensor of size (2)

input_shape = rai.Tensor(rai.DType.float, shape=[2], value=[new_shape, new_shape])
con.tensorset('input_shape', input_shape)

I understand the whole idea is for batching the inputs in the zeroth dimension if the user wants to pass more than one tensor. But at least for those who don't need to do that, we should either have a switch that decides whether we need to add a dummy dimension for a batch or we should not add a dummy dimension at all if the user is passing only one tensor, IMO. What do you think?

IMO, a user would stack the tensor and make a batch by themselves before passing that to RedisAI and we don't need to do that from the client, behind the scenes - this could be the most primitive form our API. If you think doing batching is important, perhaps we could check if we are getting a list of tensors and if yes, batch it. If we are getting a single tensor, then pass it as it is. In any case, instances like above are quite often where the user needs to set tensors without batch dimension.

@mnunberg Have you got a chance to look into it. I could give a PR if you think the approach I mentioned suffice. Anyway, without fixing this, the client can't handle lots of use cases.

This is fixed with #5

@mnunberg Just found another issue with this approach. I can't ever set a single dimensional tensor. redisai.Client always converts it to at least two-dimensional tensor. Or am I doing something wrong?
For example, This will set a tensor of size (1, 2) while I needed a tensor of size (2)

input_shape = rai.Tensor(rai.DType.float, shape=[2], value=[new_shape, new_shape])
con.tensorset('input_shape', input_shape)

I understand the whole idea is for batching the inputs in the zeroth dimension if the user wants to pass more than one tensor. But at least for those who don't need to do that, we should either have a switch that decides whether we need to add a dummy dimension for a batch or we should not add a dummy dimension at all if the user is passing only one tensor, IMO. What do you think?

Hi @hhsecond I am able to create image_tensor like that
image_tensor = redisAI.createTensorFromBlob('FLOAT', [1, IMG_SIZE, IMG_SIZE, 3],img_ba) but I am unable to create tensor_shape
shape_tensor = redisAI.createTensorFromValues('FLOAT', [2], [IMG_SIZE,IMG_SIZE])
This line doesn,t work.
kindly suggest any changes.
Thanks