{"id":6128,"date":"2022-11-25T06:29:00","date_gmt":"2022-11-25T06:29:00","guid":{"rendered":"https:\/\/www.aiproblog.com\/index.php\/2022\/11\/25\/loading-and-providing-datasets-in-pytorch\/"},"modified":"2022-11-25T06:29:00","modified_gmt":"2022-11-25T06:29:00","slug":"loading-and-providing-datasets-in-pytorch","status":"publish","type":"post","link":"https:\/\/www.aiproblog.com\/index.php\/2022\/11\/25\/loading-and-providing-datasets-in-pytorch\/","title":{"rendered":"Loading and Providing Datasets in PyTorch"},"content":{"rendered":"<p>Author: Muhammad Asad Iqbal Khan<\/p>\n<div>\n<p>Structuring the data pipeline in a way that it can be effortlessly linked to your deep learning model is an important aspect of any deep learning-based system. PyTorch packs everything to do just that.<\/p>\n<p>While in the <a href=\"https:\/\/machinelearningmastery.com\/using-dataset-classes-in-pytorch\/\">previous tutorial<\/a>, we used simple datasets, we\u2019ll need to work with larger datasets in real world scenarios in order to fully exploit the potential of deep learning and neural networks.<\/p>\n<p>In this tutorial, you\u2019ll learn how to build custom datasets in PyTorch. While the focus here remains only on the image data, concepts learned in this session can be applied to any form of dataset such as text or tabular datasets. So, here you\u2019ll learn:<\/p>\n<ul>\n<li>How to work with pre-loaded image datasets in PyTorch.<\/li>\n<li>How to apply torchvision transforms on preloaded datasets.<\/li>\n<li>How to build custom image dataset class in PyTorch and apply various transforms on it.<\/li>\n<\/ul>\n<p>Let\u2019s get started.<\/p>\n<div id=\"attachment_13162\" style=\"width: 810px\" class=\"wp-caption aligncenter\">\n<img aria-describedby=\"caption-attachment-13162\" decoding=\"async\" class=\"size-full wp-image-13162\" src=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/11\/uriel-sc-11KDtiUWRq4-unsplash-scaled.jpg\" alt=\"\" width=\"800\"><\/p>\n<p id=\"caption-attachment-13162\" class=\"wp-caption-text\">Loading and Providing Datasets in PyTorch<br \/>Picture by <a href=\"https:\/\/unsplash.com\/photos\/11KDtiUWRq4\">Uriel SC<\/a>. Some rights reserved.<\/p>\n<\/div>\n<h1>Overview<\/h1>\n<p>This tutorial is in three parts; they are<\/p>\n<ul>\n<li>Preloaded Datasets in PyTorch<\/li>\n<li>Applying Torchvision Transforms on Image Datasets<\/li>\n<li>Building Custom Image Datasets<\/li>\n<\/ul>\n<h1>Preloaded Datasets in PyTorch<\/h1>\n<p>A variety of preloaded datasets such as CIFAR-10, MNIST, Fashion-MNIST, etc. are available in the PyTorch domain library. You can import them from torchvision and perform your experiments. Additionally, you can benchmark your model using these datasets.<\/p>\n<p>We\u2019ll move on by importing Fashion-MNIST dataset from torchvision. The Fashion-MNIST dataset includes 70,000 grayscale images in 28\u00d728 pixels, divided into ten classes, and each class contains 7,000 images. There are 60,000 images for training and 10,000 for testing.<\/p>\n<p>Let\u2019s start by importing a few libraries we\u2019ll use in this tutorial.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">import torch\r\nfrom torch.utils.data import Dataset\r\nfrom torchvision import datasets\r\nimport torchvision.transforms as transforms\r\nimport numpy as np\r\nimport matplotlib.pyplot as plt\r\ntorch.manual_seed(42)<\/pre>\n<p>Let\u2019s also define a helper function to display the sample elements in the dataset using matplotlib.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">def imshow(sample_element, shape = (28, 28)):\r\n    plt.imshow(sample_element[0].numpy().reshape(shape), cmap='gray')\r\n    plt.title('Label = ' + str(sample_element[1]))\r\n    plt.show()<\/pre>\n<p>Now, we\u2019ll load the Fashion-MNIST dataset, using the function <code>FashionMNIST()<\/code> from <code>torchvision.datasets<\/code>. This function takes some arguments:<\/p>\n<ul>\n<li>\n<code>root<\/code>: specifies the path where we are going to store our data.<\/li>\n<li>\n<code>train<\/code>: indicates whether it\u2019s train or test data. We\u2019ll set it to False as we don\u2019t yet need it for training.<\/li>\n<li>\n<code>download<\/code>: set to <code>True<\/code>, meaning it will download the data from the internet.<\/li>\n<li>\n<code>transform<\/code>: allows us to use any of the available transforms that we need to apply on our dataset.<\/li>\n<\/ul>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">dataset = datasets.FashionMNIST(\r\n    root='.\/data',\r\n    train=False,\r\n    download=True,\r\n    transform=transforms.ToTensor()\r\n)<\/pre>\n<p>Let\u2019s check the class names along with their corresponding labels we have in the Fashion-MNIST dataset.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">classes = dataset.classes\r\nprint(classes)<\/pre>\n<p>It prints<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">['T-shirt\/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']<\/pre>\n<p>Similarly, for class labels:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">print(dataset.class_to_idx)<\/pre>\n<p>It prints<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">{'T-shirt\/top': 0, 'Trouser': 1, 'Pullover': 2, 'Dress': 3, 'Coat': 4, 'Sandal': 5, 'Shirt': 6, 'Sneaker': 7, 'Bag': 8, 'Ankle boot': 9}<\/pre>\n<p>Here is how we can visualize the first element of the dataset with its corresponding label using the helper function defined above.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">imshow(dataset[0])<\/pre>\n<\/p>\n<div id=\"attachment_14304\" style=\"width: 426px\" class=\"wp-caption aligncenter\">\n<img aria-describedby=\"caption-attachment-14304\" decoding=\"async\" loading=\"lazy\" class=\"wp-image-14304 size-full\" src=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/11\/pytorchdata-1.png\" alt=\"First element of the Fashion MNIST dataset\" width=\"416\" height=\"435\" srcset=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/11\/pytorchdata-1.png 416w, https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/11\/pytorchdata-1-287x300.png 287w\" sizes=\"(max-width: 416px) 100vw, 416px\"><\/p>\n<p id=\"caption-attachment-14304\" class=\"wp-caption-text\">First element of the Fashion MNIST dataset<\/p>\n<\/div>\n<h1>Applying Torchvision Transforms on Image Datasets<\/h1>\n<p>In many cases, we\u2019ll have to apply several transforms before feeding the images to neural networks. For instance, a lot of times we\u2019ll need to <code>RandomCrop<\/code> the images for data augmentation.<\/p>\n<p>As you can see below, PyTorch enables us to choose from a variety of transforms.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">print(dir(transforms))<\/pre>\n<p>This shows all available transform functions:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">['AugMix', 'AutoAugment', 'AutoAugmentPolicy', 'CenterCrop', 'ColorJitter',\r\n 'Compose', 'ConvertImageDtype', 'ElasticTransform', 'FiveCrop', 'GaussianBlur',\r\n'Grayscale', 'InterpolationMode', 'Lambda', 'LinearTransformation',\r\n'Normalize', 'PILToTensor', 'Pad', 'RandAugment', 'RandomAdjustSharpness',\r\n'RandomAffine', 'RandomApply', 'RandomAutocontrast', 'RandomChoice', 'RandomCrop',\r\n'RandomEqualize', 'RandomErasing', 'RandomGrayscale', 'RandomHorizontalFlip',\r\n'RandomInvert', 'RandomOrder', 'RandomPerspective', 'RandomPosterize',\r\n'RandomResizedCrop', 'RandomRotation', 'RandomSolarize', 'RandomVerticalFlip',\r\n'Resize', 'TenCrop', 'ToPILImage', 'ToTensor', 'TrivialAugmentWide',\r\n...]<\/pre>\n<p>As an example, let\u2019s apply the <code>RandomCrop<\/code> transform to the Fashion-MNIST images and convert them to a tensor. We can use <code>transform.Compose<\/code> to combine multiple transforms as we learned from the previous tutorial.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">randomcrop_totensor_transform = transforms.Compose([transforms.CenterCrop(16),\r\n                                                    transforms.ToTensor()])\r\ndataset = datasets.FashionMNIST(root='.\/data',\r\n                                train=False, download=True,\r\n                                transform=randomcrop_totensor_transform)\r\nprint(\"shape of the first data sample: \", dataset[0][0].shape)<\/pre>\n<p>This prints<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">shape of the first data sample:  torch.Size([1, 16, 16])<\/pre>\n<p>As you can see image has now been cropped to $16times 16$ pixels. Now, let\u2019s plot the first element of the dataset to see how they have been randomly cropped.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">imshow(dataset[0], shape=(16, 16))<\/pre>\n<p>This shows the following image<\/p>\n<div id=\"attachment_14305\" style=\"width: 426px\" class=\"wp-caption aligncenter\">\n<img aria-describedby=\"caption-attachment-14305\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-14305\" src=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/11\/pytorchdata-2.png\" alt=\"\" width=\"416\" height=\"435\" srcset=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/11\/pytorchdata-2.png 416w, https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2022\/11\/pytorchdata-2-287x300.png 287w\" sizes=\"(max-width: 416px) 100vw, 416px\"><\/p>\n<p id=\"caption-attachment-14305\" class=\"wp-caption-text\">Cropped image from Fashion MNIST dataset<\/p>\n<\/div>\n<p>Putting everything together, the complete code is as follows:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">import torch\r\nfrom torch.utils.data import Dataset\r\nfrom torchvision import datasets\r\nimport torchvision.transforms as transforms\r\nimport numpy as np\r\nimport matplotlib.pyplot as plt\r\ntorch.manual_seed(42)\r\n\r\ndef imshow(sample_element, shape = (28, 28)):\r\n    plt.imshow(sample_element[0].numpy().reshape(shape), cmap='gray')\r\n    plt.title('Label = ' + str(sample_element[1]))\r\n    plt.show()\r\n\r\ndataset = datasets.FashionMNIST(\r\n    root='.\/data',\r\n    train=False,\r\n    download=True,\r\n    transform=transforms.ToTensor()\r\n)\r\n\r\nclasses = dataset.classes\r\nprint(classes)\r\nprint(dataset.class_to_idx)\r\n\r\nimshow(dataset[0])\r\n\r\nrandomcrop_totensor_transform = transforms.Compose([transforms.CenterCrop(16),\r\n                                                    transforms.ToTensor()])\r\ndataset = datasets.FashionMNIST(\r\n    root='.\/data',\r\n    train=False,\r\n    download=True,\r\n    transform=randomcrop_totensor_transform)\r\n)\r\n\r\nprint(\"shape of the first data sample: \", dataset[0][0].shape)\r\nimshow(dataset[0], shape=(16, 16))<\/pre>\n<\/p>\n<h1>Building Custom Image Datasets<\/h1>\n<p>Until now we have been discussing prebuilt datasets in PyTorch, but what if we have to build a custom dataset class for our image dataset? While in the <a href=\"https:\/\/machinelearningmastery.com\/using-dataset-classes-in-pytorch\/\">previous tutorial<\/a> we only had a simple overview about the components of the <code>Dataset<\/code> class, here we\u2019ll build a custom image dataset class from scratch.<\/p>\n<p>Firstly, in the constructor we define the parameters of the class. The <code>__init__<\/code> function in the class instantiates the <code>Dataset<\/code> object. The directory where images and annotations are stored is initialized along with the transforms if we want to apply them on our dataset later. Here we assume we have some images in a directory structure like the following:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">attface\/\r\n|-- imagedata.csv\r\n|-- s1\/\r\n|   |-- 1.png\r\n|   |-- 2.png\r\n|   |-- 3.png\r\n|   ...\r\n|-- s2\/\r\n|   |-- 1.png\r\n|   |-- 2.png\r\n|   |-- 3.png\r\n|   ...\r\n...<\/pre>\n<p>and the annotation is a CSV file like the following, located under the root directory of the images (i.e., \u201cattface\u201d above):<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">s1\/1.png,1\r\ns1\/2.png,1\r\ns1\/3.png,1\r\n...\r\ns12\/1.png,12\r\ns12\/2.png,12\r\ns12\/3.png,12<\/pre>\n<p>where the first column of the CSV data is the path to the image and the second column is the label.<\/p>\n<p>Similarly, we define the <code>__len__<\/code> function in the class that returns the total number of samples in our image dataset while the <code>__getitem__<\/code> method reads and returns a data element from the dataset at a given index.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">import os\r\nimport pandas as pd\r\nimport numpy as np\r\nfrom torchvision.io import read_image\r\n\r\n# creating object for our image dataset\r\nclass CustomDatasetForImages(Dataset):\r\n    # defining constructor\r\n    def __init__(self, annotations, directory, transform=None):\r\n        # directory containing the images\r\n        self.directory = directory\r\n        annotations_file_dir = os.path.join(self.directory, annotations)\r\n        # loading the csv with info about images\r\n        self.labels = pd.read_csv(annotations_file_dir)\r\n        # transform to be applied on images\r\n        self.transform = transform\r\n\r\n        # Number of images in dataset\r\n        self.len = self.labels.shape[0]\r\n\r\n    # getting the length\r\n    def __len__(self):\r\n        return len(self.labels)\r\n\r\n    # getting the data items\r\n    def __getitem__(self, idx):\r\n        # defining the image path\r\n        image_path = os.path.join(self.directory, self.labels.iloc[idx, 0])\r\n        # reading the images\r\n        image = read_image(image_path)\r\n        # corresponding class labels of the images \r\n        label = self.labels.iloc[idx, 1]\r\n\r\n        # apply the transform if not set to None\r\n        if self.transform:\r\n            image = self.transform(image)\r\n        \r\n        # returning the image and label\r\n        return image, label<\/pre>\n<p>Now, we can create our dataset object and apply the transforms on it. We assume the image data are located under the directory named \u201cattface\u201d and the annotation CSV file is at \u201cattface\/imagedata.csv\u201d. Then the dataset is created as follows:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">directory = \"attface\"\r\nannotations = \"imagedata.csv\"\r\ncustom_dataset = CustomDatasetForImages(annotations=annotations,\r\n                                        directory=directory)<\/pre>\n<p>Optionally, you can add the transform function to the dataset as well:<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">randomcrop_totensor_transform = transforms.RandomCrop(16)\r\ndataset = CustomDatasetForImages(annotations=annotations,\r\n                                 directory=directory,\r\n                                 transform=randomcrop_totensor_transform)<\/pre>\n<p>You can use this custom image dataset class to any of your datasets stored in your directory and apply the transforms for your requirements.<\/p>\n<h1>Summary<\/h1>\n<p>In this tutorial, you learned how to work with image datasets and transforms in PyTorch. Particularly, you learned:<\/p>\n<ul>\n<li>How to work with pre-loaded image datasets in PyTorch.<\/li>\n<li>How to apply torchvision transforms on pre-loaded datasets.<\/li>\n<li>How to build custom image dataset class in PyTorch and apply various transforms on it.<\/li>\n<\/ul>\n<p>The post <a rel=\"nofollow\" href=\"https:\/\/machinelearningmastery.com\/loading-and-providing-datasets-in-pytorch\/\">Loading and Providing Datasets in PyTorch<\/a> appeared first on <a rel=\"nofollow\" href=\"https:\/\/machinelearningmastery.com\/\">MachineLearningMastery.com<\/a>.<\/p>\n<\/div>\n<p><a href=\"https:\/\/machinelearningmastery.com\/loading-and-providing-datasets-in-pytorch\/\">Go to Source<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Author: Muhammad Asad Iqbal Khan Structuring the data pipeline in a way that it can be effortlessly linked to your deep learning model is an [&hellip;] <span class=\"read-more-link\"><a class=\"read-more\" href=\"https:\/\/www.aiproblog.com\/index.php\/2022\/11\/25\/loading-and-providing-datasets-in-pytorch\/\">Read More<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":6129,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"footnotes":""},"categories":[24],"tags":[],"_links":{"self":[{"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/posts\/6128"}],"collection":[{"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/comments?post=6128"}],"version-history":[{"count":0,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/posts\/6128\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/media\/6129"}],"wp:attachment":[{"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/media?parent=6128"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/categories?post=6128"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/tags?post=6128"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}