在 pytorch 中将 ImageFolder 与相册一起使用
using ImageFolder with albumentations in pytorch
我遇到一种情况,我需要将 ImageFolder 与相册库一起使用以在 pytorch 中进行扩充 - 自定义数据加载器不是一个选项。
为此,我很困惑,我无法让 ImageFolder 处理相册。我已经尝试过这些方法:
class Transforms:
def __init__(self, transforms: A.Compose):
self.transforms = transforms
def __call__(self, img, *args, **kwargs):
return self.transforms(image=np.array(img))['image']
然后:
trainset = datasets.ImageFolder(traindir,transform=Transforms(transforms=A.Resize(32 , 32)))
其中 traindir
是一些带有图像的目录。然而,我得到了一个奇怪的错误:
RuntimeError: Given groups=1, weight of size [16, 3, 3, 3], expected input[1024, 32, 32, 3] to have 3 channels, but got 32 channels instead
而且我似乎无法找到一个可重现的示例来使简单的 aug pipleline 与 imagefolder 一起工作。
更新
在@Shai的推荐下,我现在这样做了:
class Transforms:
def __init__(self):
self.transforms = A.Compose([A.Resize(224,224),ToTensorV2()])
def __call__(self, img, *args, **kwargs):
return self.transforms(image=np.array(img))['image']
trainset = datasets.ImageFolder(traindir,transform=Transforms())
但我被抛出:
self.padding, self.dilation, self.groups)
RuntimeError: Input type (torch.cuda.ByteTensor) and weight type (torch.cuda.FloatTensor) should be the same
您需要使用 ToTensorV2
转换作为最后一个:
trainset = datasets.ImageFolder(traindir,transform=Transforms(transforms=A.Compose([A.Resize(32 , 32), ToTensorV2()]))
通过研究 PyTorch 上的 ImageFolder 实现[link] and some proposed work in Kaggle [link]。我提出以下解决方案(已从我这边成功测试):
import numpy as np
from typing import Any, Callable, Optional, Tuple
from torchvision.datasets.folder import DatasetFolder, default_loader, IMG_EXTENSIONS
class CustomImageFolder(DatasetFolder):
def __init__(
self,
root: str,
transform: Optional[Callable] = None,
target_transform: Optional[Callable] = None,
loader: Callable[[str], Any] = default_loader,
is_valid_file: Optional[Callable[[str], bool]] = None,
):
super().__init__(
root,
loader,
IMG_EXTENSIONS if is_valid_file is None else None,
transform=transform,
target_transform=target_transform,
is_valid_file=is_valid_file,
)
self.imgs = self.samples
def __getitem__(self, index: int) -> Tuple[Any, Any]:
"""
Args:
index (int): Index
Returns:
tuple: (sample, target) where target is class_index of the target class.
"""
path, target = self.samples[index]
sample = self.loader(path)
if self.transform is not None:
try:
sample = self.transform(sample)
except Exception:
sample = self.transform(image=np.array(sample))["image"]
if self.target_transform is not None:
target = self.target_transform(target)
return sample, target
def __len__(self) -> int:
return len(self.samples)
现在可以运行代码如下:
trainset = CustomImageFolder(traindir,transform=Transforms(transforms=A.Resize(32 , 32)))
我遇到一种情况,我需要将 ImageFolder 与相册库一起使用以在 pytorch 中进行扩充 - 自定义数据加载器不是一个选项。
为此,我很困惑,我无法让 ImageFolder 处理相册。我已经尝试过这些方法:
class Transforms:
def __init__(self, transforms: A.Compose):
self.transforms = transforms
def __call__(self, img, *args, **kwargs):
return self.transforms(image=np.array(img))['image']
然后:
trainset = datasets.ImageFolder(traindir,transform=Transforms(transforms=A.Resize(32 , 32)))
其中 traindir
是一些带有图像的目录。然而,我得到了一个奇怪的错误:
RuntimeError: Given groups=1, weight of size [16, 3, 3, 3], expected input[1024, 32, 32, 3] to have 3 channels, but got 32 channels instead
而且我似乎无法找到一个可重现的示例来使简单的 aug pipleline 与 imagefolder 一起工作。
更新 在@Shai的推荐下,我现在这样做了:
class Transforms:
def __init__(self):
self.transforms = A.Compose([A.Resize(224,224),ToTensorV2()])
def __call__(self, img, *args, **kwargs):
return self.transforms(image=np.array(img))['image']
trainset = datasets.ImageFolder(traindir,transform=Transforms())
但我被抛出:
self.padding, self.dilation, self.groups)
RuntimeError: Input type (torch.cuda.ByteTensor) and weight type (torch.cuda.FloatTensor) should be the same
您需要使用 ToTensorV2
转换作为最后一个:
trainset = datasets.ImageFolder(traindir,transform=Transforms(transforms=A.Compose([A.Resize(32 , 32), ToTensorV2()]))
通过研究 PyTorch 上的 ImageFolder 实现[link] and some proposed work in Kaggle [link]。我提出以下解决方案(已从我这边成功测试):
import numpy as np
from typing import Any, Callable, Optional, Tuple
from torchvision.datasets.folder import DatasetFolder, default_loader, IMG_EXTENSIONS
class CustomImageFolder(DatasetFolder):
def __init__(
self,
root: str,
transform: Optional[Callable] = None,
target_transform: Optional[Callable] = None,
loader: Callable[[str], Any] = default_loader,
is_valid_file: Optional[Callable[[str], bool]] = None,
):
super().__init__(
root,
loader,
IMG_EXTENSIONS if is_valid_file is None else None,
transform=transform,
target_transform=target_transform,
is_valid_file=is_valid_file,
)
self.imgs = self.samples
def __getitem__(self, index: int) -> Tuple[Any, Any]:
"""
Args:
index (int): Index
Returns:
tuple: (sample, target) where target is class_index of the target class.
"""
path, target = self.samples[index]
sample = self.loader(path)
if self.transform is not None:
try:
sample = self.transform(sample)
except Exception:
sample = self.transform(image=np.array(sample))["image"]
if self.target_transform is not None:
target = self.target_transform(target)
return sample, target
def __len__(self) -> int:
return len(self.samples)
现在可以运行代码如下:
trainset = CustomImageFolder(traindir,transform=Transforms(transforms=A.Resize(32 , 32)))