Source code for aitlas.datasets.sat6

import random
import csv

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import scipy.io
import seaborn as sns

from ..base import BaseDataset
from .schemas import MatDatasetSchema


"""
The format of the mat dataset is:
train_x 28x28x4x400000 uint8 (containing 400000 training samples of 28x28 images each with 4 channels)
train_y 400000x6 uint8 (containing 6x1 vectors having labels for the 400000 training samples)
test_x  28x28x4x100000 uint8 (containing 100000 test samples of 28x28 images each with 4 channels)
test_y  100000x6 uint8 (containing 6x1 vectors having labels for the 100000 test samples)
"""

LABELS = ["buildings", "barren land", "trees", "grassland", "roads", "water bodies"]


[docs]class SAT6Dataset(BaseDataset): schema = MatDatasetSchema url = "http://csc.lsu.edu/~saikat/deepsat/" labels = LABELS name = "SAT-6 dataset" def __init__(self, config): # now call the constructor to validate the schema super().__init__(config) # load the data self.mode = self.config.mode self.csv_file = self.config.csv_file self.data = self.load_dataset(self.config.mat_file) def __getitem__(self, index): """ Args: index (int): Index Returns: tuple: (image, target) where target is index of the target class. """ # load image img = 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(self.data[index][1]) return img, target def __len__(self): return len(self.data)
[docs] def get_labels(self): return self.labels
[docs] def data_distribution_table(self): mat_data = scipy.io.loadmat(self.config.mat_file) img_labels = mat_data[f"{self.mode}_y"].transpose() indices = None if self.csv_file: with open(self.csv_file) as infile: data = csv.reader(infile) indices = [int(row[0]) for row in data] indices = sorted(indices, reverse=True) if indices: # generate list of indices indices_range = list(range(len(img_labels))) for idx in indices: if idx < len(img_labels): indices_range.pop(idx) img_labels = np.delete(img_labels, indices_range, 0) data = list(np.where(img_labels == 1)[1]) res_list = [[i, self.labels[index]] for i, index in enumerate(data)] df = pd.DataFrame(res_list, columns=["id", "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_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, mat_file): if not self.labels: raise ValueError("You need to provide the list of labels for the dataset") indices = None if self.csv_file: with open(self.csv_file) as infile: data = csv.reader(infile) indices = [int(row[0]) for row in data] indices = sorted(indices, reverse=True) data = [] if mat_file: mat_data = scipy.io.loadmat(mat_file) images = mat_data[f"{self.mode}_x"].transpose(3, 0, 1, 2) img_labels = mat_data[f"{self.mode}_y"].transpose() if indices: # generate list of indices indices_range = list(range(len(images))) for idx in indices: if idx < len(images): indices_range.pop(idx) images = np.delete(images, indices_range, 0) img_labels = np.delete(img_labels, indices_range, 0) data = list(zip(images[:, :, :, 0:3], np.where(img_labels == 1)[1])) return data
[docs] def re_map_labels(self, labels_remapping): # re mapp the labels tmp_data = [] if self.data: for i, (img, label) in enumerate(self.data): if label in labels_remapping.keys(): tmp_data.append((img, labels_remapping[label])) self.data = tmp_data