Блок выполнения при вызове загрузчика данных с самостоятельными функциями в классе dataset

#image #pytorch #dataset #transformation

Вопрос:

Я запускаю свой код в Colab. Я использую Dataloader для загрузки набора данных в виде пакетов для обучения и проверки, а tqdm также для визуализации процесса обучения. Но каждый раз, когда я выполняю свой код, я застреваю в случайной точке (в эпоху 0, что означает, что набор данных никогда не был пройден), говоря, что программа все еще работает, но индикатор выполнения заморожен. Интересное явление заключается в самостоятельных функциях преобразования входных данных, поскольку, как только я отбросил эти преобразования, все прошло гладко. Функции заключаются в следующем:

 class Sharpen(object):
    def __init__(self, p=0.5):
        self.p = p
    
    def __call__(self, sample):
        if random.uniform(0.0, 1.0) < self.p:
            return sample
        kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], np.float32)
        for i in range(len(sample['img_list'])):
            sample['img_list'][i] = cv2.filter2D(sample['img_list'][i], -1, kernel=kernel)
            
        return sample


class Rotation(object):
    def __init__(self, angle=5, fill_value=0, p=0.5):
        self.angle = angle
        self.fill_value = fill_value
        self.p = p

    def __call__(self, sample):
        if random.uniform(0.0, 1.0) < self.p:
            return sample
        for i in range(len(sample['img_list'])):
            ang_rot = np.random.uniform(self.angle) - self.angle / 2
            h, w, _ = sample["img_list"][i].shape 
            if h*w == 0:
                continue 
            transform = cv2.getRotationMatrix2D((w / 2, h / 2), ang_rot, 1)
            sample["img_list"][i] = cv2.warpAffine(sample["img_list"][i], transform, (w, h),
                              borderValue=self.fill_value)
            
        return sample


class Translation(object):
    def __init__(self, fill_value=0, p=0.5):
        self.fill_value = fill_value
        self.p = p
        self.SIGMA = 1e-3

    def __call__(self, sample):
        rand_num = random.uniform(0.0, 1.0)
        if rand_num <= self.p:
            return sample
        
        for i in range(len(sample['img_list'])):
            h, w, _ = sample["img_list"][i].shape
            if h*w == 0:
                continue
            trans_range = (w / 10, h / 10)
            tr_x = trans_range[0] * rand_num - trans_range[0] / 2   self.SIGMA
            tr_y = trans_range[1] * rand_num - trans_range[1] / 2   self.SIGMA
            transform = np.float32([[1, 0, tr_x], [0, 1, tr_y]])
            sample["img_list"][i] = cv2.warpAffine(sample["img_list"][i], transform, (w, h), 
                                borderValue=self.fill_value)
        
        return sample

class Normalization(object):
    def __init__(self, mean=(0,0,0), std=(255,255,255)):
        self.mean = mean
        self.std = std
    
    def __call__(self, sample):
        # norm_func = transforms.Normalize(self.mean, self.std)
        for i in range(len(sample['img_list'])):
            for j in range(3):  # for colored image
                sample['img_list'][i][:,:,j] = np.array(list(map(lambda x: (x-self.mean[j])/self.std[j], sample['img_list'][i][:,:,j])),
                                     dtype=np.float32)
            # sample['img_list'][i] = norm_func(torch.Tensor(sample['img_list'][i]))
        return sample
 

Параметр sample представляет собой словарь, а ключ: img_list представляет список изображений (numpy.ndarray), обработанных cv2.imread. Форма каждого изображения равна (h, w, c), а размер не одинаков для всех изображений.

Я создал класс набора данных и продолжил вводить изображения Compose([Sharpen(), Rotation(), Translation(), Normalization()]) . Теперь я не знаю, что не так с кодом преобразования. Мы ценим любую помощь!

Комментарии:

1. Последующие действия: Я обнаружил, что проблема заключается в цикле работы OpenCV, потому что программа работает гладко только с нормализацией в качестве класса преобразования. Должны быть некоторые проблемы внутри операций cv2…. в трех других функциях вызова каждого класса.

Ответ №1:

Проблема решена. Это из-за данных. Если входное изображение пустое, процедура загрузки застрянет.