AttributeError: Dataset object has no attribute 'x'

Hi, I am quite new to fastai and pytorch in general. I am using the unet learner of fastai for a segmentation task.

I am getting an error when I run “show_results()” of the learner object which says, “AttributeError: ‘UNIZDataset’ object has no attribute ‘x’” (UNIZDataset is my custom Dataset class). Can you please tell me how I can resolve this issue? Thanks in advance.

Here’s my code:

import torch
import torchvision
from tqdm import tqdm
import os
import cv2
from torch.utils.data import Dataset, DataLoader
import glob
from fastai.vision import *
from fastai.basic_data import *
import torch.nn as nn

root = os.getcwd()
all_files = []
train_files = [] 
valid_files = []

# store all the file names
data_path = os.path.join(root, 'FINAL_DATA')
for folder in os.listdir(data_path):
    all_files.append(os.path.join(data_path,folder))

# separate into training and validation sets
train_folders = all_files[:16]
valid_folders = all_files[16:24]


def extract_files(files,path):
    '''Extract images and labels(masks)'''
    data_x = os.path.join(path,'DATA_X')
    data_y = os.path.join(path,'DATA_Y')
    fileList = glob.glob(os.path.join(data_x,'*.tif'))
    for file in sorted(fileList):
        files.append((os.path.join('DATA_X',file),  os.path.join('DATA_Y',file)))

# Extract images and masks for train and validation sets
for folder in train_folders:
    extract_files(train_files,folder)
for folder in valid_folders:
    extract_files(valid_files,folder)


class UNIZDataset(Dataset):

    def __init__(self, fileslist):
        self.sample = fileslist
        self.c = 5

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

    def __getitem__(self, index):
        X = cv2.resize(cv2.imread(self.sample[index][0]), (224,224))
        Y = cv2.resize(cv2.imread(self.sample[index][1], cv2.IMREAD_GRAYSCALE),(224,224))
        x = torch.from_numpy(X/255).float()
        x = x.permute(2,0,1)
        y = torch.from_numpy(Y/255).long()
        return (x, y)

train_dataset = UNIZDataset(train_files)
valid_dataset = UNIZDataset(valid_files)

databnch = DataBunch.create(train_dataset,valid_dataset, bs = 36, num_workers = 16)

learn = unet_learner(data=databnch, arch=models.resnet34, loss_func = nn.CrossEntropyLoss())
learn.lr_find()

learn.fit(10, lr = 0.01)

learn.show_results()

Here’s the complete traceback of the error:

AttributeError                            Traceback (most recent call last)
<ipython-input-31-c3b657dcc9ae> in <module>
----> 1 learn.show_results()

~/jupyter_py3/lib/python3.6/site-packages/fastai/basic_train.py in show_results(self, ds_type, rows, **kwargs)
397         #TODO: get read of has_arg x and split_kwargs_by_func if possible
398         #TODO: simplify this and refactor with pred_batch(...reconstruct=True)
--> 399         n_items = rows ** 2 if self.data.train_ds.x._square_show_res else rows
400         if self.dl(ds_type).batch_size < n_items: n_items = self.dl(ds_type).batch_size
401         ds = self.dl(ds_type).dataset

AttributeError: 'UNIZDataset' object has no attribute 'x'

@kdesai Hi!
Databunch is collection of train and validation DataLoaders, which is a class that contains datasets, which in turn have x and y as their attributes. I suggest you study about the Datablock API and look at how other datasets are used. That might help you!
The create method of Databunch class takes the datasets directly, but the datasets need to have x and y as their attributes!
Cheers

1 Like

Yes, my bad! Thanks for the help. :smile:

No problem! Happy to help.
I would suggest not to create your own Dataset classes. Fastai has an amazing data block API that takes care of all these small innards. You only need to tell it how to access your data.

1 Like

oh I see, that’s cool! Thanks for the suggestion, really helpful. :slightly_smiling_face: