在pytorch中使用ImageFolder和蛋白质

to94eoyn  于 2023-10-20  发布在  其他
关注(0)|答案(3)|浏览(109)

我有一个情况,我需要使用ImageFolder与albumentations库,使pytorch的扩增-自定义dataloader是不是一个选项。
为此,我被难住了,我不能让ImageFolder与Albumenations一起工作。我已经尝试了沿着这些路线的东西:

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管道与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
pdtvr36n

pdtvr36n1#

你需要使用ToTensorV2转换作为最后一个:

trainset = datasets.ImageFolder(traindir,transform=Transforms(transforms=A.Compose([A.Resize(32 , 32), ToTensorV2()]))
n3ipq98p

n3ipq98p2#

通过查看PyTorch上的ImageFolder实现[链接]和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)))
b1payxdu

b1payxdu3#

Albumentations库利用opencv将图像表示为numpy数组,因此您必须提供一个可调用的加载器函数,将img返回为numpy数组,该数组可以传递给albummentation转换。

train_transform=A.Compose([A.HorizontalFlip(),
                           A.ShiftScaleRotate(rotate_limit=5,value=0,
                                              border_mode=cv2.BORDER_CONSTANT),

                           A.OneOf(
                                   [A.CLAHE(),
                                    A.RandomBrightnessContrast(),
                                    A.HueSaturationValue()],p=1),
                           A.GaussNoise(),
                           A.RandomResizedCrop(height=480,width=480),
                           A.Normalize(),
                           ToTensorV2()])

 def open_img(img_path):
     img=Image.open(img_path)
     return np.array(img)

 class Transform():
     def __init__(self,transform):
        self.transform=transform
     def __call__(self,image):
        return self.transform(image=image)["image"]


train_ds=ImageFolder(train_dir,transform=Transform(train_transform),loader=open_img)

相关问题