Image Clustering Using k-Means. Using transfer learning model for... | by Shubham Gupta | Towards Data Science

In an image classification problem we have to classify a given set of images into a given number of categories. Training data is available in classification problem but what to do when there is no training data available, to solve this problem we can use clustering to group similar images together.
Clustering is an unsupervised machine learning where we group similar features together. It interprets the input data and finds natural groups or clusters in feature space.
Here I have used k-means for image clustering. I have taken cats vs dogs dataset.
I have separated cat and dog images into separate folders and show how clustering can be done in images.
I have used transfer learning model InceptionV3 to extract features from images and use those features for clustering.
First, let us get all the required libraries,
from tensorflow.keras.applications.inception_v3 import InceptionV3from tensorflow.keras.applications.inception_v3 import preprocess_inputfrom tensorflow.keras.preprocessing import imagefrom tensorflow.keras.preprocessing.image import img_to_arrayfrom sklearn.cluster import KMeansimport pandas as pdimport numpy as npfrom tqdm import tqdmimport osimport shutil
The dataset is available on Kaggle, it can be downloaded from here. I have taken only 700 images for clustering, 350 images of each class.
These images are put in one folder and the features are extracted using transfer learning model. Below is the method to extract features from the images using InceptionV3 model and I have saved the image name in order to tell which image is in which cluster.
# Function to Extract features from the imagesdef image_feature(direc):    model = InceptionV3(weights='imagenet', include_top=False)    features = [];    img_name = [];    for i in tqdm(direc):        fname='cluster'+'/'+i        img=image.load_img(fname,target_size=(224,224))        x = img_to_array(img)        x=np.expand_dims(x,axis=0)        x=preprocess_input(x)        feat=model.predict(x)        feat=feat.flatten()        features.append(feat)        img_name.append(i)    return features,img_name
Using the above function, I extracted the features and name and stored them in img_features,img_name.
img_path=os.listdir('cluster')img_features,img_name=image_feature(img_path)
Now, these extracted features are used for clustering, k-Means clustering is used. Below is the code for k-Means clustering, The value of k is 2 because there are only 2 classes.
#Creating Clustersk = 2clusters = KMeans(k, random_state = 40)clusters.fit(img_features)
The 2 clusters are created, the img_name that was extracted was converted to dataframe and I added another column to show which image belongs to which cluster and after that, I saved the images in their respective cluster.
image_cluster = pd.DataFrame(img_name,columns=['image'])image_cluster["clusterid"] = clusters.labels_image_cluster # 0 denotes cat and 1 denotes dog
Now I have saved images of cats and dogs in a separate folder.
# Made folder to seperate imagesos.mkdir('cats')os.mkdir('dogs')# Images will be seperated according to cluster they belongfor i in range(len(image_cluster)):    if image_cluster['clusterid'][i]==0:        shutil.move(os.path.join('cluster', image_cluster['image']               [i]), 'cats')    else:        shutil.move(os.path.join('cluster', image_cluster['image'][i]), 'dogs')
The above code will separate the images in different files based on the clusterid.
In this blog, we have discussed how to extract features from images using transfer learning and then perform clustering to separate images of cats and dogs in a different folders. It can be used for labelling where we don’t know about the classes of the images as manually labelling will be a challenge.
All the code in this article resides on this Github link: