You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
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'
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