Error (pytorch?): Expected object of scalar type Long but got scalar type Float for argument #2 'other

Hi mates. I’m being hindered by the runtime error below while trying to perform a 3-class classification over a bunch of images. Wondering if you can provide some clue about the causes.

  • all the images were verified with verify_images()
  • I’m using the latest fastai release (1.0.39-1)

Data acquired as follows:

data = ImageDataBunch.from_df(path, allthestuff, ds_tfms=tfms, bs=bs, size=299, 
                              valid_pct=0.2,
                              fn_col='imagefile',
                              label_col=classez
                              ).normalize(imagenet_stats)

calling data shows an apparently sound databunch… Correct categories, correct train/valid split, etc…

Learner created the simplest way:

learn = create_cnn(data, models.resnet50, metrics=error_rate)

The error.

Training starts regularly, then it arrives at the end of the 1st epoch (100% reached) and outputs the following just as validation begins:

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-25-95e1dcd22eb1> in <module>
----> 1 learn.fit_one_cycle(3)

~/anaconda3/envs/dmx1/lib/python3.7/site-packages/fastai/train.py in fit_one_cycle(learn, cyc_len, max_lr, moms, div_factor, pct_start, wd, callbacks, **kwargs)
     20     callbacks.append(OneCycleScheduler(learn, max_lr, moms=moms, div_factor=div_factor,
     21                                         pct_start=pct_start, **kwargs))
---> 22     learn.fit(cyc_len, max_lr, wd=wd, callbacks=callbacks)
     23 
     24 def lr_find(learn:Learner, start_lr:Floats=1e-7, end_lr:Floats=10, num_it:int=100, stop_div:bool=True, **kwargs:Any):

~/anaconda3/envs/dmx1/lib/python3.7/site-packages/fastai/basic_train.py in fit(self, epochs, lr, wd, callbacks)
    170         callbacks = [cb(self) for cb in self.callback_fns] + listify(callbacks)
    171         fit(epochs, self.model, self.loss_func, opt=self.opt, data=self.data, metrics=self.metrics,
--> 172             callbacks=self.callbacks+callbacks)
    173 
    174     def create_opt(self, lr:Floats, wd:Floats=0.)->None:

~/anaconda3/envs/dmx1/lib/python3.7/site-packages/fastai/basic_train.py in fit(epochs, model, loss_func, opt, data, callbacks, metrics)
     92     except Exception as e:
     93         exception = e
---> 94         raise e
     95     finally: cb_handler.on_train_end(exception)
     96 

~/anaconda3/envs/dmx1/lib/python3.7/site-packages/fastai/basic_train.py in fit(epochs, model, loss_func, opt, data, callbacks, metrics)
     87             if not data.empty_val:
     88                 val_loss = validate(model, data.valid_dl, loss_func=loss_func,
---> 89                                        cb_handler=cb_handler, pbar=pbar)
     90             else: val_loss=None
     91             if cb_handler.on_epoch_end(val_loss): break

~/anaconda3/envs/dmx1/lib/python3.7/site-packages/fastai/basic_train.py in validate(model, dl, loss_func, cb_handler, pbar, average, n_batch)
     52             if not is_listy(yb): yb = [yb]
     53             nums.append(yb[0].shape[0])
---> 54             if cb_handler and cb_handler.on_batch_end(val_losses[-1]): break
     55             if n_batch and (len(nums)>=n_batch): break
     56         nums = np.array(nums, dtype=np.float32)

~/anaconda3/envs/dmx1/lib/python3.7/site-packages/fastai/callback.py in on_batch_end(self, loss)
    237         "Handle end of processing one batch with `loss`."
    238         self.state_dict['last_loss'] = loss
--> 239         stop = np.any(self('batch_end', not self.state_dict['train']))
    240         if self.state_dict['train']:
    241             self.state_dict['iteration'] += 1

~/anaconda3/envs/dmx1/lib/python3.7/site-packages/fastai/callback.py in __call__(self, cb_name, call_mets, **kwargs)
    185     def __call__(self, cb_name, call_mets=True, **kwargs)->None:
    186         "Call through to all of the `CallbakHandler` functions."
--> 187         if call_mets: [getattr(met, f'on_{cb_name}')(**self.state_dict, **kwargs) for met in self.metrics]
    188         return [getattr(cb, f'on_{cb_name}')(**self.state_dict, **kwargs) for cb in self.callbacks]
    189 

~/anaconda3/envs/dmx1/lib/python3.7/site-packages/fastai/callback.py in <listcomp>(.0)
    185     def __call__(self, cb_name, call_mets=True, **kwargs)->None:
    186         "Call through to all of the `CallbakHandler` functions."
--> 187         if call_mets: [getattr(met, f'on_{cb_name}')(**self.state_dict, **kwargs) for met in self.metrics]
    188         return [getattr(cb, f'on_{cb_name}')(**self.state_dict, **kwargs) for cb in self.callbacks]
    189 

~/anaconda3/envs/dmx1/lib/python3.7/site-packages/fastai/callback.py in on_batch_end(self, last_output, last_target, **kwargs)
    272         if not is_listy(last_target): last_target=[last_target]
    273         self.count += last_target[0].size(0)
--> 274         self.val += last_target[0].size(0) * self.func(last_output, *last_target).detach().cpu()
    275 
    276     def on_epoch_end(self, **kwargs):

~/anaconda3/envs/dmx1/lib/python3.7/site-packages/fastai/metrics.py in error_rate(input, targs)
     45 def error_rate(input:Tensor, targs:Tensor)->Rank0Tensor:
     46     "1 - `accuracy`"
---> 47     return 1 - accuracy(input, targs)
     48 
     49 

~/anaconda3/envs/dmx1/lib/python3.7/site-packages/fastai/metrics.py in accuracy(input, targs)
     28     input = input.argmax(dim=-1).view(n,-1)
     29     targs = targs.view(n,-1)
---> 30     return (input==targs).float().mean()
     31 
     32 

RuntimeError: Expected object of scalar type Long but got scalar type Float for argument #2 'other'
4 Likes

I just had the same error. Did you solve it in the end?

No, but I’ll keep you posted in case I succeed. Do the same if you want :wink:

Did you acquire the images via DF or csv?

Not sure why it’s occurring but it appears your targs are a FloatTensor instead of a LongTensor. Try creating your own accuracy function by copying the fastai accuracy function and changing the following line by adding a .long() and supplying that as your accuracy method.

targs = targs.view(-1).long()
8 Likes

I can confirm that creating your own implementation of a metric solved the issue for me. @stephenjohnson Thanks!

1 Like

It worked for me too. Thanks, @stephenjohnson :slight_smile:

Another solution would be writing a bit of code to grab the labels from the df and split the dataset in folders.

1 Like

Can you help me understand what targs are, and how to change them? I can see several spots in the error stack trace that use “targs”, but when I use the code you provided I get:

NameError: name ‘targs’ is not defined

which makes sense to me because I haven’t defined it elsewhere.

1 Like

targs stands for target arguments It’s the values that are the truth values (the Y values) that are being compared to your model’s predicted values. The accuracy metric above takes two arguments the input (predicted values) and targs (target values) and calculates the accuracy. The error encountered above was due to the fact that the input had Long values but targs had Float values. All my suggestion did was to have them convert the Float values to Long values so they could be properly compared by the == operator.

2 Likes

In case anyone experiences this error in a regression task, it can arise due to using error_rate or accuracy as a metric in the learner. Using MAE will fix it.

Changing metrics helped me multi-label classification problem
learn = cnn_learner(data, models.resnet34, metrics=accuracy_thresh)

3 Likes

Which means you use metrics=mean_squared_error

@retepvan @jeremy uses accuracy as a metric in lesson 4 of practical guide to ML for coders. Any idea why this works for him but not us? (He is doing a regression problem)

If anyone just wants code:

def accuracy_1(input:Tensor, targs:Tensor)->Rank0Tensor:
“Compute accuracy with targs when input is bs * n_classes.”
targs = targs.view(-1).long()
n = targs.shape[0]
input = input.argmax(dim=-1).view(n,-1)
targs = targs.view(n,-1)
return (input==targs).float().mean()

So use metrics=accuracy_1 instead of accuracy

4 Likes

Could you please explain it a little more step by step? It is not clear to me and I got the same error.

hello @stephenjohnson … I ran into the same type of problem

Expected object of scalar type Float but got scalar type Long for argument #2 'other'

i then modified the accuracy function and included it in metrics arguments and it worked like a charm. My problem comes a bit later when i try to plot the confusion matrix. The same error pops up. What should I do now?

3 Likes

I too get the error while plotting confusion matrix. Did you solve it?

I converted my label column from float type to int type, and it solved the problem.

df = df.assign(label=df.label.astype('int'))
1 Like

Got this error

RuntimeError: shape ‘[70912, -1]’ is invalid for input of size 64

when i implemented

def accuracy_1(input:Tensor, targs:Tensor)->Rank0Tensor:
‘Compute accuracy with targs when input is bs * n_classes.’
targs = targs.view(-1).long()
n = targs.shape[0]
input = input.argmax(dim=-1).view(n,-1)
targs = targs.view(n,-1)
return (input==targs).float().mean()

RuntimeError Traceback (most recent call last)
in
1 #Fit the model
----> 2 learn.fit_one_cycle(1,slice(lr))#5

/opt/conda/lib/python3.6/site-packages/fastai/train.py in fit_one_cycle(learn, cyc_len, max_lr, moms, div_factor, pct_start, final_div, wd, callbacks, tot_epochs, start_epoch)
20 callbacks.append(OneCycleScheduler(learn, max_lr, moms=moms, div_factor=div_factor, pct_start=pct_start,
21 final_div=final_div, tot_epochs=tot_epochs, start_epoch=start_epoch))
—> 22 learn.fit(cyc_len, max_lr, wd=wd, callbacks=callbacks)
23
24 def lr_find(learn:Learner, start_lr:Floats=1e-7, end_lr:Floats=10, num_it:int=100, stop_div:bool=True, wd:float=None):

/opt/conda/lib/python3.6/site-packages/fastai/basic_train.py in fit(self, epochs, lr, wd, callbacks)
200 callbacks = [cb(self) for cb in self.callback_fns + listify(defaults.extra_callback_fns)] + listify(callbacks)
201 self.cb_fns_registered = True
→ 202 fit(epochs, self, metrics=self.metrics, callbacks=self.callbacks+callbacks)
203
204 def create_opt(self, lr:Floats, wd:Floats=0.)->None:

/opt/conda/lib/python3.6/site-packages/fastai/basic_train.py in fit(epochs, learn, callbacks, metrics)
104 if not cb_handler.skip_validate and not learn.data.empty_val:
105 val_loss = validate(learn.model, learn.data.valid_dl, loss_func=learn.loss_func,
→ 106 cb_handler=cb_handler, pbar=pbar)
107 else: val_loss=None
108 if cb_handler.on_epoch_end(val_loss): break

/opt/conda/lib/python3.6/site-packages/fastai/basic_train.py in validate(model, dl, loss_func, cb_handler, pbar, average, n_batch)
61 if not is_listy(yb): yb = [yb]
62 nums.append(first_el(yb).shape[0])
—> 63 if cb_handler and cb_handler.on_batch_end(val_losses[-1]): break
64 if n_batch and (len(nums)>=n_batch): break
65 nums = np.array(nums, dtype=np.float32)

/opt/conda/lib/python3.6/site-packages/fastai/callback.py in on_batch_end(self, loss)
306 “Handle end of processing one batch with loss.”
307 self.state_dict[‘last_loss’] = loss
→ 308 self(‘batch_end’, call_mets = not self.state_dict[‘train’])
309 if self.state_dict[‘train’]:
310 self.state_dict[‘iteration’] += 1

/opt/conda/lib/python3.6/site-packages/fastai/callback.py in call(self, cb_name, call_mets, **kwargs)
248 “Call through to all of the CallbakHandler functions.”
249 if call_mets:
→ 250 for met in self.metrics: self._call_and_update(met, cb_name, **kwargs)
251 for cb in self.callbacks: self._call_and_update(cb, cb_name, **kwargs)
252

/opt/conda/lib/python3.6/site-packages/fastai/callback.py in _call_and_update(self, cb, cb_name, **kwargs)
239 def call_and_update(self, cb, cb_name, **kwargs)->None:
240 “Call cb_name on cb and update the inner state.”
→ 241 new = ifnone(getattr(cb, f’on
{cb_name}')(**self.state_dict, **kwargs), dict())
242 for k,v in new.items():
243 if k not in self.state_dict:

/opt/conda/lib/python3.6/site-packages/fastai/callback.py in on_batch_end(self, last_output, last_target, **kwargs)
342 if not is_listy(last_target): last_target=[last_target]
343 self.count += first_el(last_target).size(0)
→ 344 val = self.func(last_output, *last_target)
345 if self.world:
346 val = val.clone()

in accuracy_1(input, targs)
5 targs = targs.view(-1).long()
6 n = targs.shape[0]
----> 7 input = input.argmax(dim=-1).view(n,-1)
8 targs = targs.view(n,-1)
9 return (input==targs).float().mean()

RuntimeError: shape ‘[70912, -1]’ is invalid for input of size 64

1 Like

Hi Tony,
Currently I am facing same issue.Were you able to solve this error?

Regards,
Faiz

Same here but my labels (from df) are all ints. Makes no sense to me why fastai converted the labels to float for some reason.

data = ImageDataBunch.from_df('patches/', df.iloc[:640], label_col=list(df.columns[1:]), bs=32)
print([df[col].dtype for col in df.columns[1:]])

# [dtype('int64'), dtype('int64'), dtype('int64'), dtype('int64'), dtype('int64'), dtype('int64')]

I used a simple wrapper with casting and it works:

def accuracy_cast(input:Tensor, targs:Tensor)->Rank0Tensor:
    targs = targs.long()
    return accuracy(input, targs)

learn = cnn_learner(data, models.resnet18, metrics=accuracy_cast)
learn.fit(1)

But this smells like a true bug.

3 Likes