Adil Hydari
Adil Hydari

Reputation: 5

object of type 'ESC50Data' has no len() in my audio classification script

so I'm running into the error that my class ESC50Data does not have any length.

from torch.utils.data import Dataset, DataLoader
class ESC50Data(Dataset):
      def __init__(self, base, df, in_col, out_col):
        self.df = df
        self.data = []
        self.labels = []
        self.c2i={}
        self.i2c={}
        self.categories = sorted(df[out_col].unique())
        for i, category in enumerate(self.categories):
            self.c2i[category]=i
            self.i2c[i]=category
        for ind in tqdm(range(len(df))):
            row = df.iloc[ind]
            file_path = os.path.join(base,row[in_col])
            self.data.append(spec_to_image(get_melspectrogram(file_path))[np.newaxis,...])
            self.labels.append(self.c2i[row['category']])
            def __len__(self):
                                    return len(self.data)
            def __getitem__(self, idx):
                                                return self.data[idx], self.labels[idx]
train_data = ESC50Data('audio', train, 'filename', 'category')
valid_data = ESC50Data('audio', valid, 'filename', 'category')
train_loader = DataLoader(train_data, batch_size=16, shuffle=True)
valid_loader = DataLoader(valid_data, batch_size=16, shuffle=True)

This is the point at which I get my error. Using Jypter Notebooks as a sidenote.

TypeError                                 Traceback (most recent call last)
Input In [47], in <cell line: 1>()
----> 1 train_loader = DataLoader(train_data, batch_size=16, shuffle=True)
      2 valid_loader = DataLoader(valid_data, batch_size=16, shuffle=True)

File ~/opt/anaconda3/lib/python3.9/site-packages/torch/utils/data/dataloader.py:353, in DataLoader.__init__(self, dataset, batch_size, shuffle, sampler, batch_sampler, num_workers, collate_fn, pin_memory, drop_last, timeout, worker_init_fn, multiprocessing_context, generator, prefetch_factor, persistent_workers, pin_memory_device)
    351 else:  # map-style
    352     if shuffle:
--> 353         sampler = RandomSampler(dataset, generator=generator)  # type: ignore[arg-type]
    354     else:
    355         sampler = SequentialSampler(dataset)  # type: ignore[arg-type]

File ~/opt/anaconda3/lib/python3.9/site-packages/torch/utils/data/sampler.py:106, in RandomSampler.__init__(self, data_source, replacement, num_samples, generator)
    102 if not isinstance(self.replacement, bool):
    103     raise TypeError("replacement should be a boolean value, but got "
    104                     "replacement={}".format(self.replacement))
--> 106 if not isinstance(self.num_samples, int) or self.num_samples <= 0:
    107     raise ValueError("num_samples should be a positive integer "
    108                      "value, but got num_samples={}".format(self.num_samples))

File ~/opt/anaconda3/lib/python3.9/site-packages/torch/utils/data/sampler.py:114, in RandomSampler.num_samples(self)
    110 @property
    111 def num_samples(self) -> int:
    112     # dataset size might change at runtime
    113     if self._num_samples is None:
--> 114         return len(self.data_source)
    115     return self._num_samples

TypeError: object of type 'ESC50Data' has no len()

Any ideas as to what could be happening? I created the class ESC50Data and then I gave it the child class called Dataset that will inherent the properties of ESC50Data. I also loaded the data into pytorch with train and valid data.

Upvotes: 0

Views: 147

Answers (1)

Shai
Shai

Reputation: 114796

Check the indentation of __len__(self) and __getitem__(self, idx) methods in your class ESC50Data code. Right now, it seems like these methods are defined inside the __init__ method, and not under the class itself.

See, e.g., this answer.

Upvotes: 1

Related Questions