添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account AttributeError: module 'torchvision.transforms.functional' has no attribute 'get_image_size' #4328 AttributeError: module 'torchvision.transforms.functional' has no attribute 'get_image_size' #4328 praveern opened this issue Aug 27, 2021 · 8 comments 41 for epoch in range(num_epochs):
---> 42 train_one_epoch(model, optimizer, data_loader, device, epoch, print_freq=10)
43 lr_scheduler.step()
44 # evaluate on the test dataset

5 frames
/usr/local/lib/python3.7/dist-packages/torch/_utils.py in reraise(self)
423 # have message field
424 raise self.exc_type(message=msg)
--> 425 raise self.exc_type(msg)

AttributeError: Caught AttributeError in DataLoader worker process 0.
Original Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/torch/utils/data/_utils/worker.py", line 287, in _worker_loop
data = fetcher.fetch(index)
File "/usr/local/lib/python3.7/dist-packages/torch/utils/data/_utils/fetch.py", line 44, in fetch
data = [self.dataset[idx] for idx in possibly_batched_index]
File "/usr/local/lib/python3.7/dist-packages/torch/utils/data/_utils/fetch.py", line 44, in
data = [self.dataset[idx] for idx in possibly_batched_index]
File "/usr/local/lib/python3.7/dist-packages/torch/utils/data/dataset.py", line 311, in getitem
return self.dataset[self.indices[idx]]
File "/usr/local/lib/python3.7/dist-packages/torch/utils/data/dataset.py", line 311, in getitem
return self.dataset[self.indices[idx]]
File "", line 83, in getitem
image, target = self._transforms(image, target)
File "/content/transforms.py", line 26, in call
image, target = t(image, target)
File "/usr/local/lib/python3.7/dist-packages/torch/nn/modules/module.py", line 1051, in _call_impl
return forward_call(*input, **kwargs)
File "/content/transforms.py", line 36, in forward
width, _ = F.get_image_size(image)
AttributeError: module 'torchvision.transforms.functional' has no attribute 'get_image_size'

To Reproduce

Steps to reproduce the behavior:

  • Follow tutorial as per https://pytorch.org/tutorials/intermediate/torchvision_tutorial.html
  • Error happening from the file - references/detection/transforms.py, line 36 (using an alias/local variable for
    torchvision.transforms.functional is not allowing access to the public method in the same file)
  • Expected behavior

    The public method "get_image_size" should be accessed normally (I had to remove the alias "F" and explicitly call the method).

    Environment

    Google Colab (libraries are up to date)

    cc @vfdev-5 @datumbox

    @praveern The method was added just yesterday so it might not be available on nightly yet. I would recommend installing it from source and trying again.

    If you continue facing problems, please provide the minimum code that would allow us to reproduce the problem along with information about the version you are using etc.

    From what I see the following works find on latest main branch:

    >>> import torch
    >>> import torchvision.transforms.functional as F
    >>> F.get_image_size(torch.zeros((3, 300, 400)))
    [400, 300]
              

    Hello @datumbox I'm using the latest stable build v0.10 (pytorch version 1.9.0+cu10.2) (as per the installation section in getting started).

    Regarding code, I am literally using the Pytorch tutorial as it is, with only tweaks being Google Drive paths to data and model checkpoint storage locations.

    The latest stable version version of TorchVsion does not have the get_image_size() public. The change was made yesterday. If you want to access it along with other latest features, I advise you to either try the nightly or install from source.

    If you continue having issues using the latest development version, send me a standalone minimal snippet that reproduces the issue so that we can investigate.

    Okay, so I switched my environment to use the LTS version (pip install torch==1.8.2+cu102 torchvision==0.9.2+cu102 torchaudio===0.8.2 -f https://download.pytorch.org/whl/lts/1.8/torch_lts.html) and the error still persists.

    As for standalone snippet, I think these specific cells of code should help:

    Source - "https://pytorch.org/tutorials/intermediate/torchvision_tutorial.html#writing-a-custom-dataset-for-pennfudan"

    import os
    import numpy as np
    import torch
    from PIL import Image
    class PennFudanDataset(torch.utils.data.Dataset):
        def __init__(self, root, transforms):
            self.root = root
            self.transforms = transforms
            # load all image files, sorting them to
            # ensure that they are aligned
            self.imgs = list(sorted(os.listdir(os.path.join(root, "PNGImages"))))
            self.masks = list(sorted(os.listdir(os.path.join(root, "PedMasks"))))
        def __getitem__(self, idx):
            # load images and masks
            img_path = os.path.join(self.root, "PNGImages", self.imgs[idx])
            mask_path = os.path.join(self.root, "PedMasks", self.masks[idx])
            img = Image.open(img_path).convert("RGB")
            # note that we haven't converted the mask to RGB,
            # because each color corresponds to a different instance
            # with 0 being background
            mask = Image.open(mask_path)
            # convert the PIL Image into a numpy array
            mask = np.array(mask)
            # instances are encoded as different colors
            obj_ids = np.unique(mask)
            # first id is the background, so remove it
            obj_ids = obj_ids[1:]
            # split the color-encoded mask into a set
            # of binary masks
            masks = mask == obj_ids[:, None, None]
            # get bounding box coordinates for each mask
            num_objs = len(obj_ids)
            boxes = []
            for i in range(num_objs):
                pos = np.where(masks[i])
                xmin = np.min(pos[1])
                xmax = np.max(pos[1])
                ymin = np.min(pos[0])
                ymax = np.max(pos[0])
                boxes.append([xmin, ymin, xmax, ymax])
            # convert everything into a torch.Tensor
            boxes = torch.as_tensor(boxes, dtype=torch.float32)
            # there is only one class
            labels = torch.ones((num_objs,), dtype=torch.int64)
            masks = torch.as_tensor(masks, dtype=torch.uint8)
            image_id = torch.tensor([idx])
            area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])
            # suppose all instances are not crowd
            iscrowd = torch.zeros((num_objs,), dtype=torch.int64)
            target = {}
            target["boxes"] = boxes
            target["labels"] = labels
            target["masks"] = masks
            target["image_id"] = image_id
            target["area"] = area
            target["iscrowd"] = iscrowd
            if self.transforms is not None:
                img, target = self.transforms(img, target)
            return img, target
        def __len__(self):
            return len(self.imgs)
    

    Source - "vision/references/detection/transforms.py"

    from torch import nn, Tensor
    from torchvision.transforms import functional as F
    from torchvision.transforms import transforms as T
    from typing import List, Tuple, Dict, Optional
    class RandomHorizontalFlip(T.RandomHorizontalFlip):
        def forward(self, image: Tensor,
                    target: Optional[Dict[str, Tensor]] = None) -> Tuple[Tensor, Optional[Dict[str, Tensor]]]:
            if torch.rand(1) < self.p:
                image = F.hflip(image)
                if target is not None:
                    width, _ = F.get_image_size(image)  ## This line is throwing an error
                    target["boxes"][:, [0, 2]] = width - target["boxes"][:, [2, 0]]
                    if "masks" in target:
                        target["masks"] = target["masks"].flip(-1)
                    if "keypoints" in target:
                        keypoints = target["keypoints"]
                        keypoints = _flip_coco_person_keypoints(keypoints, width)
                        target["keypoints"] = keypoints
            return image, target
    # Importing vision/references/detection/transforms.py (the file is located at same level as Jupyter notebook)
    import transforms as Tf  
    def get_transform(train):
        transforms = []
        transforms.append(Tf.ToTensor())
        if train:
            transforms.append(RandomHorizontalFlip(0.5))
        return Tf.Compose(transforms)
    # Import the custom dataset defined previously,
    dataset = PennFudanDataset(os.path.join('PennFudanPed'), get_transform(train=True))
    print(dataset.__getitem__(45))
    

    --------------------------------------------------------------------------
    Error:

    AttributeError                            Traceback (most recent call last)
    <ipython-input-20-87a7b71fa365> in <module>()
          4 dataset_test = torch.utils.data.Subset(dataset_test, indices[-50:])
    ----> 6 print(dataset.__getitem__(45))
    4 frames
    /usr/local/lib/python3.7/dist-packages/torch/utils/data/dataset.py in __getitem__(self, idx)
        329     def __getitem__(self, idx):
    --> 330         return self.dataset[self.indices[idx]]
        332     def __len__(self):
    <ipython-input-3-73612deaccc4> in __getitem__(self, idx)
         63         if self.transforms is not None:
    ---> 64             img, target = self.transforms(img, target)
         66         return img, target
    /content/transforms.py in __call__(self, image, target)
         24     def __call__(self, image, target):
         25         for t in self.transforms:
    ---> 26             image, target = t(image, target)
         27         return image, target
    /usr/local/lib/python3.7/dist-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
        887             result = self._slow_forward(*input, **kwargs)
        888         else:
    --> 889             result = self.forward(*input, **kwargs)
        890         for hook in itertools.chain(
        891                 _global_forward_hooks.values(),
    <ipython-input-16-75a1255e5fcd> in forward(self, image, target)
         11             image = F.hflip(image)
         12             if target is not None:
    ---> 13                 width, _ = F.get_image_size(image)
         14                 target["boxes"][:, [0, 2]] = width - target["boxes"][:, [2, 0]]
         15                 if "masks" in target:
    AttributeError: module 'torchvision.transforms.functional' has no attribute 'get_image_size'
              

    The reason why you get issues is because you are trying to use code from the latest development branch with an old stable version of TorchVision. When you mix code from different versions you can get issues. As I explained earlier, the PR #4321 which renamed the private method F._get_image_size() to F.get_image_size() was merged yesterday and thus this change is only available to the latest nightly version or if you install TorchVision from source.

    You are currently trying to call a method that does not exist on the TorchVision version you are using. A quick workaround is to replace get_image_size with _get_image_size in your code but you are still at risk because you mix code from different versions. If you want to stick to the latest stable version (0.10.0) you should be using the reference scripts from that version.

    I believe this answers your question and thus I'll close the ticket. If you have further concerns feel free to reopen it.

    Private function _get_image_size was changed to public in torchvision v0.11.
    The use of torchvision v0.11 and above will result in the following error:
    pytorch/vision#4328