Source code for aitlas.datasets.multiclass_classification

import csv
import os
import random

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

from ..base import BaseDataset
from ..utils import image_loader
from .schemas import ClassificationDatasetSchema


"""
The format of the multiclass classification dataset is:
image_path1,label1
image_path2,label2
...
"""


[docs]class MultiClassClassificationDataset(BaseDataset): schema = ClassificationDatasetSchema def __init__(self, config): # now call the constructor to validate the schema super().__init__(config) # load the data self.data_dir = self.config.data_dir self.csv_file = self.config.csv_file self.data = self.load_dataset() def __getitem__(self, index): """ :param index: Index :type index: int :return: tuple where target is index of the target class. :rtype: tuple (image, target) """ # load image img = image_loader(self.data[index][0]) # apply transformations if self.transform: img = self.transform(img) target = self.data[index][1] if self.target_transform: target = self.target_transform(target) return img, target def __len__(self): return len(self.data)
[docs] def get_labels(self): return self.labels
[docs] def data_distribution_table(self): df = pd.read_csv(self.csv_file, sep=",", names=["File name", "Label"]) label_count = df.groupby("Label").count().reset_index() label_count.columns = ["Label", "Count"] return label_count
[docs] def data_distribution_barchart(self): label_count = self.data_distribution_table() fig, ax = plt.subplots(figsize=(12, 10)) sns.barplot(y="Label", x="Count", data=label_count, ax=ax) ax.set_title( "Labels distribution for {}".format(self.get_name()), pad=20, fontsize=18 ) return fig
[docs] def show_samples(self): df = pd.read_csv(self.csv_file, sep=",", names=["File name", "Label"]) return df.head(20)
[docs] def show_image(self, index): label = self.labels[self[index][1]] fig = plt.figure(figsize=(8, 6)) plt.title( f"Image with index {index} from the dataset {self.get_name()}, with label {label}\n", fontsize=14, ) plt.axis("off") plt.imshow(self[index][0]) return fig
[docs] def show_batch(self, size, show_title=True): if size % 5: raise ValueError("The provided size should be divided by 5!") image_indices = random.sample(range(0, len(self.data)), size) figure, ax = plt.subplots( int(size / 5), 5, figsize=(13.75, 2.8 * int(size / 5)) ) if show_title: figure.suptitle( "Example images with labels from {}".format(self.get_name()), fontsize=32, y=1.006, ) for axes, image_index in zip(ax.flatten(), image_indices): axes.imshow(self[image_index][0]) axes.set_title(self.labels[self[image_index][1]], fontsize=18, pad=10) axes.set_xticks([]) axes.set_yticks([]) figure.tight_layout() return figure
[docs] def load_dataset(self): data = [] if self.csv_file: with open(self.csv_file, "r") as f: csv_reader = csv.reader(f) raw_data = list(csv_reader) # If not provided initialize the labels from the csv file if not self.labels: self.labels = [] for index, row in enumerate(raw_data): self.labels.append(row[1]) self.labels = list(sorted(set(self.labels))) for index, row in enumerate(raw_data): file_name = row[0] item = ( os.path.join(self.data_dir, file_name), self.labels.index(row[1]), ) data.append(item) if not self.labels: raise ValueError("You need to provide the list of labels for the dataset") return data
[docs] def re_map_labels(self, labels_remapping): # re mapp the labels tmp_data = [] if self.data: for i, (path, label) in enumerate(self.data): if label in labels_remapping.keys(): tmp_data.append((path, labels_remapping[label])) self.data = tmp_data