Why cannot I call FloatTensor on a float tensor?

Hongnan_G: <p>So I am doing a classification problem with BCEwithlogits loss, therefore, it expects my integer targets to be float. However, I defined <code>torch.from_numpy(df[FOLDS.class_col_name].values).float()</code> and subsequently return <code>{"y": torch.FloatTensor(target)}</code> and the error is <code>IndexError: slice() cannot be applied to a 0-dim tensor.</code> Once I use <code>{"y": target}</code> it started to work. Why is this the case, I manually checked that <code>target</code> is a float tensor, why cannot I call <code>FloatTensor</code> again on it?</p>
<pre><code class="lang-python">from typing import Dict, Union
import albumentations

import cv2
import pandas as pd
import torch


class CustomDataset(torch.utils.data.Dataset):
    """Dataset class for the {insert competition/project name} dataset."""

    def __init__(
        self,
        df: pd.DataFrame,
        transforms: albumentations.core.composition.Compose = None,
        mode: str = "train",
    ):
        """Constructor for the dataset class.
        Args:
            df (pd.DataFrame): Dataframe for either train, valid or test.
            transforms (albumentations.core.composition.Compose): albumentations transforms to apply to the images.
            mode (str, optional): Defaults to "train". One of ['train', 'valid', 'test', 'gradcam']
        """

        # "image_path" is hardcoded, as that is always defined in prepare_data.
        self.image_path = df["image_path"].values
        self.image_ids = df[FOLDS.image_col_name].values
        self.df = df
        
        self.targets = (
            torch.from_numpy(df[FOLDS.class_col_name].values).float()
            if mode != "test"
            else None
        )
        

        self.transforms = transforms
        self.mode = mode

    def __len__(self) -&gt; int:
        """Return the length of the dataset."""
        return len(self.df)

    def __getitem__(
        self, index: int
    ) -&gt; Union[
        Dict[str, torch.FloatTensor],
        Dict[str, Union[torch.FloatTensor, torch.LongTensor]],
    ]:
        """Implements the getitem method: https://www.geeksforgeeks.org/__getitem__-and-__setitem__-in-python/
        Be careful of Targets:
            BCEWithLogitsLoss expects a target.float()
            CrossEntropyLoss expects a target.long()
        Args:
            index (int): index of the dataset.
        Returns:
            Dict[str, torch.FloatTensor]:{"X": image_tensor}
            Dict[str, Union[torch.FloatTensor, torch.LongTensor]]: {"y": target_tensor} If BCEwithLogitsLoss then FloatTensor, else LongTensor
        """
        image_path = self.image_path[index]
        image = cv2.imread(image_path)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        
        # needed for gradcam.
        original_image = cv2.resize(
            image, (TRANSFORMS.image_size, TRANSFORMS.image_size)
        ).copy()

        # Get target for all modes except for test.
        target = self.targets[index] if self.mode != "test" else None
     
        if self.transforms:
            image = self.transforms(image=image)["image"]
            
        if self.mode in ["train", "valid"]:
            if CRITERION.train_criterion_name == "BCEWithLogitsLoss":                
                return {
                    "X": torch.FloatTensor(image),
                    "y": target,
                }
            return {
                "X": torch.FloatTensor(image),
                "y": torch.LongTensor(target),
            }


        elif self.mode == "test":
            return {"X": torch.FloatTensor(image)}

        elif self.mode == "gradcam":
            return {
                "X": torch.FloatTensor(image),
                "y": target,
                "original_image": torch.FloatTensor(original_image),
                "image_id": self.image_ids[index],
            }
        return None
</code></pre>

ptrblck: <p>I cannot reproduce the issue using:</p>
<pre><code class="lang-python">torch.FloatTensor(torch.randn(10))
</code></pre>
<p>but in any case you shouldn’t use <code>torch.FloatTensor</code> as its usage is deprecated and undocumented due to its unintuitive behavior.<br>
E.g. passing a scalar to it will return a <code>FloatTensor</code> with <code>scalar</code> elements using uninitialized memory, while passing a <code>list</code> would return a <code>FloatTensor</code> which contains the passed values:</p>
<pre><code class="lang-python">torch.FloatTensor(10)
&gt; tensor([-1.3895e+28,  3.0778e-41, -1.3954e+28,  3.0778e-41,  4.9870e-17,
           4.5729e-41, -6.7316e+36,  3.0778e-41,  1.4013e-45,  0.0000e+00])
torch.FloatTensor([10])
&gt; tensor([10.])
</code></pre>
<p>Use the factory methods (<code>torch.randn</code>, <code>torch.empty</code> etc.) or transform the <code>dtypes</code> via <code>to()</code> or the direct call e.g. <code>tensor.float()</code>.</p>

Hongnan_G: <p><a class="mention" href="/u/ptrblck">@ptrblck</a> Thanks, so the better way to ensure the correctness of the dtypes is to just say something like:</p>
<pre><code class="lang-python">return {"y": torch.as_tensor(target, dtype=...)
</code></pre>

ptrblck: <p>Yes, <code>as_tensor</code> would probably work. If the input is a numpy array, you could also use <code>torch.from_numpy</code>.</p>