np.ndArray in tensor

Hi everyone, I am trying to run Resnet18 on STL_10, but get the following error message:

RuntimeError: can’t convert a given np.ndarray to a tensor - it has an invalid type. The only supported types are: double, float, int64, int32, and uint8.

On the face of it, my arrays look ok shape-wise

I pass them through, all fine
arch = resnet18 #start off with this, and see how we go
data = ImageClassifierData.from_arrays(PATH, train, valid, tfms=tfms)
learn = ConvLearner.pretrained(arch, data, precompute=True)
learn.lr_find()

but then on learn.lr_find():

~/fastai/courses/dl1/fastai/dataloader.py in get_tensor(batch, pin)
 25 def get_tensor(batch, pin):
 26     if isinstance(batch, (np.ndarray, np.generic)):
---> 27         batch = torch.from_numpy(batch).contiguous()
 28         return batch.pin_memory() if pin else batch
 29     elif isinstance(batch, string_classes): return batch

RuntimeError: can't convert a given np.ndarray to a tensor - it has an invalid type. The only supported types are: double, float, int64, int32, and uint8.

Has anyone else seen this or know what I need to do? How can I tell which is ending up as an ndarray, and how can I change it an array? Thanks!

Type train_X.dtype, it will show you what the datatype of the numpy array. There are some numpy array types that are not compatible with PyTorch. You will need to say train_X.astype(np.float32) or something similar

1 Like

I casted it to int64 and all is good! The colours of the images went funny when casted it to float. Thanks for your help :slight_smile:

So I’m now getting this:

error                                     Traceback (most recent call last)
<ipython-input-95-0ffabd5bbedd> in <module>()
      2 data = ImageClassifierData.from_arrays(PATH, train, valid, tfms=tfms)
      3 learn = ConvLearner.pretrained(arch, data, precompute=False)
----> 4 learn.lr_find()

~/fastai/courses/dl1/fastai/transforms.py in scale_min(im, targ)
     13     ratio = targ/min(r,c)
     14     sz = (scale_to(c, ratio, targ), scale_to(r, ratio, targ))
---> 15     return cv2.resize(im, sz)
     16 
     17 def zoom_cv(x,z):

error: /io/opencv/modules/imgproc/src/imgwarp.cpp:3361: error: (-215) func != 0 in function resize

Things I’ve tried -

  1. I’ve checked for any null values, negative values, or very large values in my data array, but there aren’t any
  2. Catching the exception and returning an empty array ( this just moves the problem down the line)
  3. Changing to array to different dtypes, which hasn’t seemed to have any effect

Anybody have any ideas?

Can you try changing it to np.uint8. If these are images, the values range from 0-255 and uint8 or int16 would be enough.

will do

I’m now getting this when I run fit! It looks like it’s not expecting the ByteTensor, just working out what that corresponds to…
TypeError: CudaClassNLLCriterion_updateOutput received an invalid combination of arguments - got (int, torch.cuda.FloatTensor, torch.cuda.ByteTensor, torch.cuda.FloatTensor, bool, NoneType, torch.cuda.FloatTensor, int), but expected (int state, torch.cuda.FloatTensor input, torch.cuda.LongTensor target, torch.cuda.FloatTensor output, bool sizeA`verage, [torch.cuda.FloatTensor weights or None], torch.cuda.FloatTensor total_weight, int ignore_index)

use np.float32. When you need to plot it typecast to np.uint8. I have seen that pattern followed in many places.

1 Like

I gave that a go:
train_x = np.float32(train_x)
test_x = np.float32(test_x)
train_y = np.uint32(train_y)
test_y = np.uint32(test_y)
arch = resnet18 #start off with this, and see how we go
data = ImageClassifierData.from_arrays(PATH, train, valid, tfms=tfms)
learn = ConvLearner.pretrained(arch, data, precompute=False)
learn.lr_find()

~/src/anaconda3/envs/fastai/lib/python3.6/site-packages/torch/nn/_functions/thnn/auto.py in forward(ctx, input, target, *args)
45 output = input.new(1)
46 getattr(ctx._backend, update_output.name)(ctx._backend.library_state, input, target,
—> 47 output, *ctx.additional_args)
48 return output
49

now it’s just complaining about a Float instead of a long. I tried turning the y’s to uints, but that didn’t seem to do anything
TypeError: CudaClassNLLCriterion_updateOutput received an invalid combination of arguments - got (int, torch.cuda.FloatTensor, torch.cuda.FloatTensor, torch.cuda.FloatTensor, bool, NoneType, torch.cuda.FloatTensor, int), but expected (int state, torch.cuda.FloatTensor input, torch.cuda.LongTensor target, torch.cuda.FloatTensor output, bool sizeAverage, [torch.cuda.FloatTensor weights or None], torch.cuda.FloatTensor total_weight, int ignore_index)

1 Like

It might be complaining about your train_y dtype. Change that to np.int32 instead. Also, if you take a look at Lesson_1 notebook, it has X as uint8 and y as np.int64. If this doesn’t work, can you put your notebook in gist.github.com to take a look?

Ahh good point. I’ll give that a crack first thing tomorrow. Thanks again for your help :smiley:

It removes that, but creates
error: /io/opencv/modules/imgproc/src/imgwarp.cpp:3361: error: (-215) func != 0 in function resize
I think I must have an aloof image

Here’s the gist

@sjdlloyd - Figured it out.
TLDR: Basically the input images needs to be uint8 and Target needs to be int64.

Both train_x, and train_y was loaded as np.uint8. So you had to change just the train_y to int64 (that maps to torch.LongTensor). Also, the y was starting at 1, you will have to start the index at 0.

Details in the updated gist here

1 Like

Ah that’s done it! Amazing, thank you so much :smile: ; I’ve learnt a lot about Torch Tensors and array manipulation from this