Как отлаживать код Pytorch, который вылетает, когда NUM_WORKERS> 0 - PullRequest
0 голосов
/ 13 февраля 2019

Итак, я пытаюсь использовать DataLoader в pytorch для обучения нейронной сети.В каждой партии я хотел бы получить изображения, маски и имена файлов.Чтобы сопоставить имена файлов, я написал собственную функцию сортировки.

По некоторым причинам мой код вылетает всякий раз, когда я устанавливаю num_workers > 0 в DataLoader, но отлично работает, когда num_workers = 0.Я получаю сообщение об ошибке, подобное приведенному ниже, которое не очень полезно:

RuntimeError: работник DataLoader (pid 10449) прерывается сигналом: прекращено.Детали теряются из-за многопроцессорности.Повторный запуск с num_workers = 0 может дать лучшую трассировку ошибок.

Кто-нибудь знает, что не так и как я могу отлаживать многопроцессорные процессы в pytorch?

class MyDataset(Dataset):

    def __init__(self, df=None):
        self.folderlist = []
       # Load path of files here... df is just a dataframe of which specifies which files to load.

    def __len__(self):
        return len(self.folderlist)

    def __getitem__(self, idx):
        imglist = os.listdir( self.folderlist[idx])

        image_name = [x for x in imglist if x.endswith(('_img.jpg'))][0]
        mask_name = [x for x in imglist if x.endswith(('_mask.png'))][0]

        image = np.array(Image.open(os.path.join(self.folderlist[idx], image_name)))
        mask = Image.open(os.path.join(self.folderlist[idx], mask_name))

        # Some transforms here

        image = transforms.ToTensor()(image)
        mask = transforms.ToTensor()(mask)

        return (image, mask, self.folderlist[idx])  # returns the filename as well

def collate_fn(batch, default=False, depth=0):
    if default:
        return default_collate(batch)
    else:
        if isinstance(batch[0], torch.Tensor):
            if True:
                # If we're in a background process, concatenate directly into a
                # shared memory tensor to avoid an extra copy
                numel = sum([x.numel() for x in batch])
                storage = batch[0].storage()._new_shared(numel)
                out = batch[0].new(storage)
            return torch.stack(batch, 0, out=out)
        elif isinstance(batch[0], int_classes):
            return torch.LongTensor(batch)
        elif isinstance(batch[0], float):
            return torch.DoubleTensor(batch)
        elif isinstance(batch[0], string_classes):
            return batch
        elif (depth==0):
            # Puts the first two data fields into a tensor with outer dimension batch size
            transposed = zip(*batch)
            return [collate_fn(samples, depth=depth+1) for samples in transposed]
        else:
            return batch            # Don't zip up second+ order lists

# Some class function
def train():
    # ...
    train_dataset = MyDataset(df=df_train)
    train_loader = DataLoader(train_dataset, batch_size=self.config.TRAIN_BS, shuffle=True, num_workers=self.config.NUM_WORKERS, collate_fn=collate_fn)
    val_dataset = MyDataset(df=df_val)
    val_loader = DataLoader(val_dataset, batch_size=self.config.VAL_BS, shuffle=True, num_workers=self.config.NUM_WORKERS, collate_fn=collate_fn)

    nfiles = 0
    for i, (images, masks, filenames) in enumerate(train_loader):
        nfiles += len(filenames)
        print('train {}; nfiles: {}'.format(filenames, nfiles))
    for i, (images, masks, filenames) in enumerate(val_loader):
        print('val {}; nfiles: {}'.format(filenames, nfiles))

Сбои программы после завершения итерации через train_loader.

...