【发布时间】:2019-01-06 04:37:08
【问题描述】:
我目前正在研究基于补丁的超分辨率。大多数论文将图像分成较小的补丁,然后将补丁用作模型的输入。我能够使用自定义数据加载器创建补丁。代码如下:
import torch.utils.data as data
from torchvision.transforms import CenterCrop, ToTensor, Compose, ToPILImage, Resize, RandomHorizontalFlip, RandomVerticalFlip
from os import listdir
from os.path import join
from PIL import Image
import random
import os
import numpy as np
import torch
def is_image_file(filename):
return any(filename.endswith(extension) for extension in [".png", ".jpg", ".jpeg", ".bmp"])
class TrainDatasetFromFolder(data.Dataset):
def __init__(self, dataset_dir, patch_size, is_gray, stride):
super(TrainDatasetFromFolder, self).__init__()
self.imageHrfilenames = []
self.imageHrfilenames.extend(join(dataset_dir, x)
for x in sorted(listdir(dataset_dir)) if is_image_file(x))
self.is_gray = is_gray
self.patchSize = patch_size
self.stride = stride
def _load_file(self, index):
filename = self.imageHrfilenames[index]
hr = Image.open(self.imageHrfilenames[index])
downsizes = (1, 0.7, 0.45)
downsize = 2
w_ = int(hr.width * downsizes[downsize])
h_ = int(hr.height * downsizes[downsize])
aug = Compose([Resize([h_, w_], interpolation=Image.BICUBIC),
RandomHorizontalFlip(),
RandomVerticalFlip()])
hr = aug(hr)
rv = random.randint(0, 4)
hr = hr.rotate(90*rv, expand=1)
filename = os.path.splitext(os.path.split(filename)[-1])[0]
return hr, filename
def _patching(self, img):
img = ToTensor()(img)
LR_ = Compose([ToPILImage(), Resize(self.patchSize//2, interpolation=Image.BICUBIC), ToTensor()])
HR_p, LR_p = [], []
for i in range(0, img.shape[1] - self.patchSize, self.stride):
for j in range(0, img.shape[2] - self.patchSize, self.stride):
temp = img[:, i:i + self.patchSize, j:j + self.patchSize]
HR_p += [temp]
LR_p += [LR_(temp)]
return torch.stack(LR_p),torch.stack(HR_p)
def __getitem__(self, index):
HR_, filename = self._load_file(index)
LR_p, HR_p = self._patching(HR_)
return LR_p, HR_p
def __len__(self):
return len(self.imageHrfilenames)
假设批量大小为 1,它获取一张图像并给出大小为[x,3,patchsize,patchsize] 的输出。当批量大小为 2 时,我将有两个大小为 [x,3,patchsize,patchsize] 的不同输出(例如图像 1 可能给出[50,3,patchsize,patchsize],图像 2 可能给出[75,3,patchsize,patchsize])。为了处理这个问题,需要一个自定义的整理函数,将这两个输出沿维度 0 堆叠。整理函数如下所示:
def my_collate(batch):
data = torch.cat([item[0] for item in batch],dim = 0)
target = torch.cat([item[1] for item in batch],dim = 0)
return [data, target]
这个 collate 函数沿 x 连接(从上面的示例中,我终于得到 [125,3,patchsize,pathsize]。出于训练目的,我需要使用 25 的 minibatch 大小来训练模型。有什么方法或函数可以吗?使用必要数量的图像作为数据加载器的输入,直接从数据加载器获取大小为[25 , 3, patchsize, pathsize] 的输出?
【问题讨论】:
-
所以你希望你的 data_loader 总是返回一个大小为 [25,3, patch size, patchsize] 的输出,不管需要多少图像(即你希望它加载尽可能多的图像需要生成上述大小的输出)?
-
请。有什么办法吗?
-
一种简单的方法可能是定义一个自定义采样器,该采样器在达到 25 阈值之前不会加载图像,然后将其返回,同时保留其余的用于下一次迭代。我大概可以给你写一个简单的蓝图。
-
我想过使用采样器,但我不知道它的结构。如果您能提供蓝图,我将非常高兴。我可以以此为基础。
标签: python-3.x image-processing pytorch