.. _sec_imgdataset: Image Prediction - Properly load any image dataset as ImageDataset ================================================================== Preparing the dataset for ImagePredictor is not difficult at all, however, we’d like to introduce the recommended ways to initialize the dataset, so you will have a smoother experience using ``autogluon.vision.ImagePredictor``. There are generally three ways to load a dataset for ImagePredictor: - Load a csv file or construct your own pandas ``DataFrame`` with ``image`` and ``label`` columns - Load a image folder directly with ``ImageDataset`` - Convert a list of images into a dataset directly with ``ImageDataset`` We will go through these four methods one by one. First of all, let’s import AutoGluon: .. code:: python %matplotlib inline import autogluon.core as ag from autogluon.vision import ImageDataset import pandas as pd .. parsed-literal:: :class: output /home/ci/opt/venv/lib/python3.8/site-packages/gluoncv/__init__.py:40: UserWarning: Both `mxnet==1.9.1` and `torch==1.12.1+cu102` are installed. You might encounter increased GPU memory footprint if both framework are used at the same time. warnings.warn(f'Both `mxnet=={mx.__version__}` and `torch=={torch.__version__}` are installed. ' INFO:torch.distributed.nn.jit.instantiator:Created a temporary directory at /tmp/tmpe7lfr0a3 INFO:torch.distributed.nn.jit.instantiator:Writing /tmp/tmpe7lfr0a3/_remote_module_non_scriptable.py INFO:root:Generating grammar tables from /usr/lib/python3.8/lib2to3/Grammar.txt INFO:root:Generating grammar tables from /usr/lib/python3.8/lib2to3/PatternGrammar.txt Load a csv file or construct a DataFrame object ----------------------------------------------- We use a csv file from PetFinder competition as an example. You may use any tabular data as long as you can create ``image``\ (absolute or relative paths to images) and ``label``\ (category for each image) columns. .. code:: python csv_file = ag.utils.download('https://autogluon.s3-us-west-2.amazonaws.com/datasets/petfinder_example.csv') df = pd.read_csv(csv_file) df.head() .. parsed-literal:: :class: output Downloading petfinder_example.csv from https://autogluon.s3-us-west-2.amazonaws.com/datasets/petfinder_example.csv... 100%|██████████| 820/820 [00:00<00:00, 2707.62KB/s] .. raw:: html
image PetID label
0 petfinder_data/train_images/015da9e87-1.jpg 015da9e87 0
1 petfinder_data/train_images/022606901-1.jpg 022606901 0
2 petfinder_data/train_images/02f89bdcb-1.jpg 02f89bdcb 0
3 petfinder_data/train_images/03f217352-1.jpg 03f217352 0
4 petfinder_data/train_images/040a9a6f9-1.jpg 040a9a6f9 0
If the image paths are not relative to the current working directory, you may use the helper function to prepend a prefix for each image. Using absolute paths can reduce the chance of an OSError happening during file access: .. code:: python df = ImageDataset.from_csv(csv_file, root='/home/ubuntu') df.head() .. raw:: html
image PetID label
0 /home/ubuntu/petfinder_data/train_images/015da... 015da9e87 0
1 /home/ubuntu/petfinder_data/train_images/02260... 022606901 0
2 /home/ubuntu/petfinder_data/train_images/02f89... 02f89bdcb 0
3 /home/ubuntu/petfinder_data/train_images/03f21... 03f217352 0
4 /home/ubuntu/petfinder_data/train_images/040a9... 040a9a6f9 0
Or you can perform the correction by yourself: .. code:: python import os df['image'] = df['image'].apply(lambda x: os.path.join('/home/ubuntu', x)) df.head() .. raw:: html
image PetID label
0 /home/ubuntu/petfinder_data/train_images/015da... 015da9e87 0
1 /home/ubuntu/petfinder_data/train_images/02260... 022606901 0
2 /home/ubuntu/petfinder_data/train_images/02f89... 02f89bdcb 0
3 /home/ubuntu/petfinder_data/train_images/03f21... 03f217352 0
4 /home/ubuntu/petfinder_data/train_images/040a9... 040a9a6f9 0
Otherwise you may use the ``DataFrame`` as-is, ``ImagePredictor`` will apply auto conversion during ``fit`` to ensure other metadata is available for training. You can have multiple columns in the ``DataFrame``, ``ImagePredictor`` only cares about ``image`` and ``label`` columns during training. Load an image directory ----------------------- It’s pretty common that sometimes you only have a folder of images, organized by the category names. Recursively looping through images is tedious. You can use ``ImageDataset.from_folders`` or ``ImageDataset.from_folder`` to avoid implementing recursive search. The difference between ``from_folders`` and ``from_folder`` is the targeting folder structure. If you have a folder with splits, e.g., ``train``, ``test``, like: - root/train/car/0001.jpg - root/train/car/xxxa.jpg - root/val/bus/123.png - root/test/bus/023.jpg Then you can load the splits with ``from_folders``: .. code:: python train_data, _, test_data = ImageDataset.from_folders('https://autogluon.s3.amazonaws.com/datasets/shopee-iet.zip', train='train', test='test') print('train #', len(train_data), 'test #', len(test_data)) train_data.head() .. parsed-literal:: :class: output data/ ├── test/ └── train/ train # 800 test # 80 .. raw:: html
image label
0 /home/ci/.gluoncv/datasets/shopee-iet/data/tra... 0
1 /home/ci/.gluoncv/datasets/shopee-iet/data/tra... 0
2 /home/ci/.gluoncv/datasets/shopee-iet/data/tra... 0
3 /home/ci/.gluoncv/datasets/shopee-iet/data/tra... 0
4 /home/ci/.gluoncv/datasets/shopee-iet/data/tra... 0
If you have a folder without ``train`` or ``test`` root folders, like: - root/car/0001.jpg - root/car/xxxa.jpg - root/bus/123.png - root/bus/023.jpg Then you can load the splits with ``from_folder``: .. code:: python # use the train from shopee-iet as new root root = os.path.join(os.path.dirname(train_data.iloc[0]['image']), '..') all_data = ImageDataset.from_folder(root) all_data.head() .. raw:: html
image label
0 /home/ci/.gluoncv/datasets/shopee-iet/data/tra... 0
1 /home/ci/.gluoncv/datasets/shopee-iet/data/tra... 0
2 /home/ci/.gluoncv/datasets/shopee-iet/data/tra... 0
3 /home/ci/.gluoncv/datasets/shopee-iet/data/tra... 0
4 /home/ci/.gluoncv/datasets/shopee-iet/data/tra... 0
.. code:: python # you can manually split the dataset or use `random_split` train, val, test = all_data.random_split(val_size=0.1, test_size=0.1) print('train #:', len(train), 'test #:', len(test)) .. parsed-literal:: :class: output train #: 616 test #: 94 Convert a list of images to dataset ----------------------------------- You can create a dataset from a list of images with a function, the function is used to determine the label of each image. We use the Oxford-IIIT Pet Dataset mini pack as an example, where images are scattered in ``images`` directory but with a unique pattern: filenames of cats start with a capital letter, otherwise they are dogs. So we can use a function to distinguish and assign a label to each image: .. code:: python pets = ag.utils.download('https://autogluon.s3-us-west-2.amazonaws.com/datasets/oxford-iiit-pet-mini.zip') pets = ag.utils.unzip(pets) image_list = [x for x in os.listdir(os.path.join(pets, 'images')) if x.endswith('jpg')] def label_fn(x): return 'cat' if os.path.basename(x)[0].isupper() else 'dog' new_data = ImageDataset.from_name_func(image_list, label_fn, root=os.path.join(os.getcwd(), pets, 'images')) new_data .. parsed-literal:: :class: output Downloading oxford-iiit-pet-mini.zip from https://autogluon.s3-us-west-2.amazonaws.com/datasets/oxford-iiit-pet-mini.zip... 100%|██████████| 35730/35730 [00:01<00:00, 21282.39KB/s] .. raw:: html
image label
0 /home/ci/autogluon/docs/_build/eval/tutorials/... 0
1 /home/ci/autogluon/docs/_build/eval/tutorials/... 1
2 /home/ci/autogluon/docs/_build/eval/tutorials/... 1
3 /home/ci/autogluon/docs/_build/eval/tutorials/... 0
4 /home/ci/autogluon/docs/_build/eval/tutorials/... 1
... ... ...
95 /home/ci/autogluon/docs/_build/eval/tutorials/... 1
96 /home/ci/autogluon/docs/_build/eval/tutorials/... 1
97 /home/ci/autogluon/docs/_build/eval/tutorials/... 0
98 /home/ci/autogluon/docs/_build/eval/tutorials/... 1
99 /home/ci/autogluon/docs/_build/eval/tutorials/... 0

100 rows × 2 columns

Visualize images ---------------- You can use ``show_images`` to visualize the images, as well as the corresponding labels: .. code:: python new_data.show_images() .. figure:: output_dataset_4aa41c_16_0.png For raw DataFrame objects, you can convert them to Dataset first to use ``show_images``. Congratulations, you can now proceed to :ref:`sec_imgquick` to start training the ``ImagePredictor``.