Skip to main content

Setting Up

You can follow along this tutorial by running this notebook on Google Colab.
🚧 Google Colab Free Tier Running this tutorial on Google Colab is possible but may take a while to complete due to the low computing resources provided in the free tier. We recommend running this tutorial on your local machine, Google Colab Pro, or equivalent.
If you’re running this tutorial on your local machine, install fastdup with:
To verify the installation, run:
This tutorial runs on version 0.906. For a detailed list of installation options and supported platforms, see our installation guide.

Download Dataset

For the purpose of demonstration, we will be using the food-101 dataset which consists of 101 food classes with 1,000 images per class. Download and extract the dataset by running:
Once done, you should have a food-101/images folder which contains the images.
📘 Why this dataset? We use the food-101 dataset in this tutorial because of the general availability of the dataset to the public. Bear in mind this is a highly curated dataset, and we may not find as many issues compared to a non-curated dataset. Feel free to swap out this dataset for your own!

Run fastdup

With the folder set in place, let’s run fastdup:
📘 Parameters
  • work_dir - Path to store the artifacts generated from the run.
  • input_dir - Path to the images.
  • ccthreshold - The cluster threshold parameter. Controls the minimal distance for clustering. Defaults to 0.96. Best value of ccthreshold varies depending on use case and data.
    • A higher threshold clusters images that are highly similar resulting in fewer images in a cluster.
    • A lower threshold clusters less similar images together. Clusters have more diversity and a larger possible difference between images in the cluster.
👍 Reduce run time on free tier of Google Colab If you’re running this tutorial on the free tier of Google Colab, we recommend running the analysis on a subset of the dataset instead of the entire dataset. This is done to reduce the waiting time for the run to complete. You can specify the number of images to run on by specifying the num_images argument in fd.run. For example, fd.run(num_images=40000) runs only on 40,000 images in the dataset.
Once the run completes, you can get a summary of the run with:
which outputs:

Broken Images

Similar to the previous tutorial, let’s start with low-hanging fruit of finding corrupted images:
which outputs:
📘 No broken images! The output shows no broken images. So we are good to go here.
However, if there are broken images present (like in the previous tutorial), you’d see something like the following:

List of Broken Images

To get a list of broken images run:
Since we did not have any broke images the output of the above code is:
If fastdup encounters broken images, the output of the above snippet would look something like:
👍 Tips You can store these output list somewhere to take further action on. You might want to move the files, delete it, or relabel them.

Duplicates

Let’s visualize duplicate image pairs with:
which outputs: Duplicate Image Pairs
👍 Tips
  • Setting num_images=5 shows a gallery of 5 duplicate pairs. Change this value to view more/less.
  • Running fd.vis.duplicates_gallery also saves the resulting duplicates.html file into fastdup_food101_work_dir/gallery/.
  • Distance of 1.0 indicates that the image is an exact copy.

Image Clusters

You can visualize image clusters with:
which outputs:

List of Duplicates

Now let’s single out all duplicates and near-duplicates by running using the connected components function:
which outputs:
fastdup_idcomponent_idsumcountmean_distancemin_distancemax_distanceimg_filenameerror_codeis_valid
0000.00.00.00.00.0apple_pie/1005649.jpgVALIDTrue
1110.00.00.00.00.0apple_pie/1011328.jpgVALIDTrue
2220.00.00.00.00.0apple_pie/101251.jpgVALIDTrue
3330.00.00.00.00.0apple_pie/1014775.jpgVALIDTrue
4440.00.00.00.00.0apple_pie/1026328.jpgVALIDTrue
Let’s now write a utility function to get the clusters:
And run it:
img_filenamemean_distancecount
component_id
23830[clam_chowder/1072684.jpg, clam_chowder/1113834.jpg, clam_chowder/1322415.jpg, clam_chowder/1437241.jpg, clam_chowder/2113399.jpg, clam_chowder/2140703.jpg, clam_chowder/2248997.jpg, clam_chowder/2361787.jpg, clam_chowder/2398168.jpg, clam_chowder/2542800.jpg, clam_chowder/2685745.jpg, clam_chowder/2770581.jpg, clam_chowder/3914755.jpg, clam_chowder/546975.jpg, clam_chowder/75800.jpg, clam_chowder/854517.jpg]0.916316
31637[dumplings/1045500.jpg, dumplings/140004.jpg, dumplings/1630799.jpg, dumplings/1695231.jpg, dumplings/1848359.jpg, dumplings/1872410.jpg, dumplings/1918394.jpg, dumplings/2524385.jpg, dumplings/3683752.jpg, dumplings/3739057.jpg, dumplings/3781725.jpg, dumplings/468796.jpg]0.930212
31767[dumplings/1450685.jpg, dumplings/1564985.jpg, dumplings/2500721.jpg, dumplings/2600333.jpg, dumplings/2606645.jpg, dumplings/2675187.jpg, dumplings/3030550.jpg, dumplings/3242297.jpg, dumplings/3532122.jpg, dumplings/625116.jpg]0.912710
31760[dumplings/1433645.jpg, dumplings/1813271.jpg, dumplings/1881086.jpg, dumplings/1998135.jpg, dumplings/2229749.jpg, dumplings/2561548.jpg, dumplings/2750447.jpg, dumplings/3363745.jpg, dumplings/834049.jpg]0.91199
31699[dumplings/1228546.jpg, dumplings/1270308.jpg, dumplings/231028.jpg, dumplings/2373653.jpg, dumplings/2571523.jpg, dumplings/263589.jpg, dumplings/2909040.jpg, dumplings/2950605.jpg, dumplings/3191742.jpg]0.91809
The above shows the component (clusters) with the highest duplicates/near-duplicates. Now let’s keep one image from each cluster and remove the rest:
outputs:
Inspecting list_of_duplicates:
outputs:
Additional reading: remove_duplicates

Outliers

Now, visualize the outliers with:
which outputs: Outliers
👍 Tips
  • Lower Distance value indicates the image is different than others in the dataset. Hence, the lower the Distance value, the higher the chances of outliers.
  • Since we know that the label of the image is by the name of the parent folder, we can already spot a couple of outliers from this gallery. For example, take the last image in the gallery, the label is given as dumplings but the image does not contain any dumplings.

List of Outliers

Let’s first get the outliers DataFrame:
Which outputs:
indexoutliernearestdistanceimg_filename_outliererror_code_outlieris_valid_outlierimg_filename_nearesterror_code_nearestis_valid_nearest
039999797272210.295020breakfast_burrito/462294.jpgVALIDTruecreme_brulee/1661605.jpgVALIDTrue
1399721410374700.556575chocolate_cake/2518457.jpgVALIDTruefilet_mignon/2685908.jpgVALIDTrue
2399511063167270.563040caesar_salad/1303023.jpgVALIDTruecheesecake/358018.jpgVALIDTrue
339942188526690.564055chocolate_cake/577717.jpgVALIDTruebaklava/3363412.jpgVALIDTrue
4399232123312070.578329dumplings/1339572.jpgVALIDTruedonuts/1750980.jpgVALIDTrue
Let’s treat all images with distance<0.68 as outliers:
Outputs:

Dark, Bright, Blurry Images

Similar to the previous tutorial, we can visualize the dark, bright, and blurry images with:

List of Dark Images

Get a DataFrame of dark images:
If an image has amean<13 then we conclude it’s a dark image:
Outputs:
fastdup_idimg_wimg_huniqueblurmeanminmaxstdvfile_sizecontrastimg_filenameerror_codeis_valid
309030905123060535.73385.52050.0255.015.3110274331.0beef_carpaccio/1259270.jpgVALIDTrue
9797979751151209.08751.84310.030.01.052486931.0breakfast_burrito/462294.jpgVALIDTrue
To get a list of the dark images:
Which outputs:

List of Bright Images

Similar to the above, let’s set that if mean>220.5 we will conclude it’s a bright image:
fastdup_idimg_wimg_huniqueblurmeanminmaxstdvfile_sizecontrastimg_filenameerror_codeis_valid
81815125120538.6821225.82660.0255.032.2799322291.0apple_pie/1289014.jpgVALIDTrue
43643651251201245.6737220.97030.0255.040.3034403441.0apple_pie/2601590.jpgVALIDTrue
58958951251201468.0642227.57420.0255.041.6247504371.0apple_pie/2997124.jpgVALIDTrue
9339335125120554.9135232.68870.0255.041.5226413951.0apple_pie/817552.jpgVALIDTrue
1115111551251201219.0579230.78390.0255.032.7307521541.0baby_back_ribs/1395570.jpgVALIDTrue
Get a list of bright images:
Outputs:

List of Blurry Images

Similarly with blur images
fastdup_idimg_wimg_huniqueblurmeanminmaxstdvfile_sizecontrastimg_filenameerror_codeis_valid
21232123512512041.3781116.22392.0198.030.7362254790.9800baklava/1413667.jpgVALIDTrue
27682768384512045.5609102.817240.0226.037.5435187400.6992baklava/3681797.jpgVALIDTrue
28292829512512038.8840214.021171.0255.025.0954238690.5644baklava/3877397.jpgVALIDTrue
29182918512512047.2227138.16020.0255.024.5464222791.0000baklava/683225.jpgVALIDTrue
69246924384512045.995975.92530.0176.023.9812190181.0000beignets/726875.jpgVALIDTrue
Get list of blurry images
Outputs:

Summary

In this tutorial we found 825 images with potential issues.
Outputs:
In this tutorial, we’ve seen how to use fastdup to analyze an image dataset for potential problems such as broken image, duplicate, outliers and dark/bright/blurry image. For each problem, we got a list of file names for further action. Depending on use cases, you might choose to delete the images, relabel them, or simply move the images elsewhere.
👍 TLDR In this tutorial we learned how to:
  • Find various dataset issues with fastdup.
  • Collect problematic images for further action.