├── app.py ├── test.py ├── main.py └── README.md /app.py: -------------------------------------------------------------------------------- 1 | import tensorflow 2 | from tensorflow.keras.preprocessing import image 3 | from tensorflow.keras.layers import GlobalMaxPooling2D 4 | from tensorflow.keras.applications.resnet50 import ResNet50,preprocess_input 5 | import numpy as np 6 | from numpy.linalg import norm 7 | import os 8 | from tqdm import tqdm 9 | import pickle 10 | 11 | model = ResNet50(weights='imagenet',include_top=False,input_shape=(224,224,3)) 12 | model.trainable = False 13 | 14 | model = tensorflow.keras.Sequential([ 15 | model, 16 | GlobalMaxPooling2D() 17 | ]) 18 | 19 | #print(model.summary()) 20 | 21 | def extract_features(img_path,model): 22 | img = image.load_img(img_path,target_size=(224,224)) 23 | img_array = image.img_to_array(img) 24 | expanded_img_array = np.expand_dims(img_array, axis=0) 25 | preprocessed_img = preprocess_input(expanded_img_array) 26 | result = model.predict(preprocessed_img).flatten() 27 | normalized_result = result / norm(result) 28 | 29 | return normalized_result 30 | 31 | filenames = [] 32 | 33 | for file in os.listdir('images'): 34 | filenames.append(os.path.join('images',file)) 35 | 36 | feature_list = [] 37 | 38 | for file in tqdm(filenames): 39 | feature_list.append(extract_features(file,model)) 40 | 41 | pickle.dump(feature_list,open('embeddings.pkl','wb')) 42 | pickle.dump(filenames,open('filenames.pkl','wb')) 43 | 44 | -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | import pickle 2 | import tensorflow 3 | import numpy as np 4 | from numpy.linalg import norm 5 | from tensorflow.keras.preprocessing import image 6 | from tensorflow.keras.layers import GlobalMaxPooling2D 7 | from tensorflow.keras.applications.resnet50 import ResNet50,preprocess_input 8 | from sklearn.neighbors import NearestNeighbors 9 | import cv2 10 | 11 | feature_list = np.array(pickle.load(open('embeddings.pkl','rb'))) 12 | filenames = pickle.load(open('filenames.pkl','rb')) 13 | 14 | model = ResNet50(weights='imagenet',include_top=False,input_shape=(224,224,3)) 15 | model.trainable = False 16 | 17 | model = tensorflow.keras.Sequential([ 18 | model, 19 | GlobalMaxPooling2D() 20 | ]) 21 | 22 | img = image.load_img('sample/shirt.jpg',target_size=(224,224)) 23 | img_array = image.img_to_array(img) 24 | expanded_img_array = np.expand_dims(img_array, axis=0) 25 | preprocessed_img = preprocess_input(expanded_img_array) 26 | result = model.predict(preprocessed_img).flatten() 27 | normalized_result = result / norm(result) 28 | 29 | neighbors = NearestNeighbors(n_neighbors=6,algorithm='brute',metric='euclidean') 30 | neighbors.fit(feature_list) 31 | 32 | distances,indices = neighbors.kneighbors([normalized_result]) 33 | 34 | print(indices) 35 | 36 | for file in indices[0][1:6]: 37 | temp_img = cv2.imread(filenames[file]) 38 | cv2.imshow('output',cv2.resize(temp_img,(512,512))) 39 | cv2.waitKey(0) 40 | 41 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | import os 3 | from PIL import Image 4 | import numpy as np 5 | import pickle 6 | import tensorflow 7 | from tensorflow.keras.preprocessing import image 8 | from tensorflow.keras.layers import GlobalMaxPooling2D 9 | from tensorflow.keras.applications.resnet50 import ResNet50,preprocess_input 10 | from sklearn.neighbors import NearestNeighbors 11 | from numpy.linalg import norm 12 | 13 | feature_list = np.array(pickle.load(open('embeddings.pkl','rb'))) 14 | filenames = pickle.load(open('filenames.pkl','rb')) 15 | 16 | model = ResNet50(weights='imagenet',include_top=False,input_shape=(224,224,3)) 17 | model.trainable = False 18 | 19 | model = tensorflow.keras.Sequential([ 20 | model, 21 | GlobalMaxPooling2D() 22 | ]) 23 | 24 | st.title('Fashion Recommender System') 25 | 26 | def save_uploaded_file(uploaded_file): 27 | try: 28 | with open(os.path.join('uploads',uploaded_file.name),'wb') as f: 29 | f.write(uploaded_file.getbuffer()) 30 | return 1 31 | except: 32 | return 0 33 | 34 | def feature_extraction(img_path,model): 35 | img = image.load_img(img_path, target_size=(224, 224)) 36 | img_array = image.img_to_array(img) 37 | expanded_img_array = np.expand_dims(img_array, axis=0) 38 | preprocessed_img = preprocess_input(expanded_img_array) 39 | result = model.predict(preprocessed_img).flatten() 40 | normalized_result = result / norm(result) 41 | 42 | return normalized_result 43 | 44 | def recommend(features,feature_list): 45 | neighbors = NearestNeighbors(n_neighbors=6, algorithm='brute', metric='euclidean') 46 | neighbors.fit(feature_list) 47 | 48 | distances, indices = neighbors.kneighbors([features]) 49 | 50 | return indices 51 | 52 | # steps 53 | # file upload -> save 54 | uploaded_file = st.file_uploader("Choose an image") 55 | if uploaded_file is not None: 56 | if save_uploaded_file(uploaded_file): 57 | # display the file 58 | display_image = Image.open(uploaded_file) 59 | st.image(display_image) 60 | # feature extract 61 | features = feature_extraction(os.path.join("uploads",uploaded_file.name),model) 62 | #st.text(features) 63 | # recommendention 64 | indices = recommend(features,feature_list) 65 | # show 66 | col1,col2,col3,col4,col5 = st.beta_columns(5) 67 | 68 | with col1: 69 | st.image(filenames[indices[0][0]]) 70 | with col2: 71 | st.image(filenames[indices[0][1]]) 72 | with col3: 73 | st.image(filenames[indices[0][2]]) 74 | with col4: 75 | st.image(filenames[indices[0][3]]) 76 | with col5: 77 | st.image(filenames[indices[0][4]]) 78 | else: 79 | st.header("Some error occured in file upload") 80 | 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 🚀Introduction 2 | 3 | I developed a fashion recommendation system that utilizes the power of transfer learning using ResNet-50 architecture along with Annoy an optimized K-Nearest Neighbours algorithm to deliver personalized recommendations based on user input. By performing feature extraction on a large dataset of over 45,000 images using transfer learning with ResNet-50, I was able to effectively analyze the image data. To identify the top 5 closest matches to a user's input, I implemented a similarity search approach using K-Nearest Neighbours, providing personalized fashion recommendations. The system is user-friendly and intuitive, and allows for accurate and effective analysis of image data. 4 | 5 | This recommendation system showcases the versatility and power of transfer learning, similarity search, and convolutional neural networks (CNNs), providing a solid foundation for building larger and more comprehensive recommendation systems 6 | 7 | ## 💻Recommendation Engine:Proposed Methodology 8 | 9 | In this project, we propose a model that uses Convolutional Neural Network and the Nearest 10 | neighbour backed recommender. As shown in the figure Initially, the neural networks are trained and then 11 | an inventory is selected for generating recommendations and a database is created for the items in 12 | inventory. The nearest neighbour’s algorithm is used to find the most relevant products based on the 13 | input image and recommendations are generated. 14 | 15 | ![work-model](https://user-images.githubusercontent.com/89743011/170476738-cdfcd048-8bfd-450c-ad58-20ec025d5b7c.png) 16 | 17 | 18 | ## 📊Application Flow-Chart 19 | 20 | 21 | To generate recommendations, our proposed approach uses Sklearn Nearest neighbours . This allows us to find the nearest neighbours for the 22 | given input image. The similarity measure used in this Project is the Cosine Similarity measure. The top 5 23 | recommendations are extracted from the database and their images are displayed. 24 | 25 | ![flow-chart](https://user-images.githubusercontent.com/89743011/170476148-5c472690-675b-4907-91c4-9b9804668f6f.png) 26 | 27 | 28 | ## Convolutional Neural Networks 29 | 30 | - Convolutional Neural Network is a specialized neural network designed for visual data, such as images & videos. But CNNs also work well for non-image data (especially in NLP & text classification). 31 | - Its concept is similar to that of a vanilla neural network (multilayer perceptron) – It follows the same general principle of forwarding & backward propagation. 32 | 33 | - Once the data is pre-processed, the neural networks are trained, utilizing transfer learning 34 | from ResNet50. More additional layers are added in the last layers that replace the architecture and 35 | weights from ResNet50 in order to fine-tune the network model to serve the current issue. The figure 36 | shows the ResNet50 architecture. 37 | 38 | 39 | 40 | ![59954intro to CNN](https://user-images.githubusercontent.com/89743011/170827497-76197e3a-e1b7-4e69-b809-9d6d076100f0.jpg) 41 | 42 | 43 | 44 | ## Getting the inventory 45 | 46 | The images from Kaggle Fashion Product Images Dataset. The 47 | inventory is then run through the neural networks to classify and generate embeddings and the output 48 | is then used to generate recommendations. 49 | 50 | ### The Figure shows a sample set of inventory data 51 | 52 | ![dataset-cover](https://user-images.githubusercontent.com/89743011/170478150-9204c659-06a4-48bf-8420-5fee02a3c4d3.png) 53 | 54 | 55 | 56 | ## Experiment and results 57 | 58 | The concept of Transfer learning is used to overcome the issues of the small size Fashion dataset. 59 | Therefore we pre-train the classification models on the DeepFashion dataset that consists of 44,441 60 | garment images. The networks are trained and validated on the dataset taken. The training results 61 | show a great accuracy of the model with low error, loss and good f-score. 62 | 63 | 64 | 65 | 66 | ## Dataset Link 67 | 68 | - [Kaggle Dataset Big size 15 GB](https://www.kaggle.com/datasets/paramaggarwal/fashion-product-images-dataset) 69 | 70 | - [Kaggle Dataset Small size 572 MB](https://www.kaggle.com/datasets/paramaggarwal/fashion-product-images-small) 71 | 72 | 73 | 74 | 75 | ## Screenshots 76 | 77 | ### Simple App UI 78 | 79 | ![Screenshot (105)](https://user-images.githubusercontent.com/89743011/170464439-56930532-6d7b-4649-b009-09eebfa5a75b.png) 80 | 81 | 82 | ### Outfits generated by our approach for the given input image 83 | 84 | ![Screenshot (107)](https://user-images.githubusercontent.com/89743011/170464638-15a88b15-fd4c-4ac6-9be5-13a72b0b31a1.png) 85 | 86 | 87 | 88 | 89 | ## Installation 90 | 91 | Use pip to install the requirements. 92 | 93 | ~~~bash 94 | pip install -r requirements.txt 95 | ~~~ 96 | 97 | 98 | 99 | 100 | ## 📖Usage 101 | 102 | To run the web server, simply execute streamlit with the main recommender app: 103 | 104 | ```bash 105 | streamlit run main.py 106 | ``` 107 | 108 | 109 | 110 | 111 | ## [Built With/Dependencies](dependencies) 112 | 113 | - **OpenCV** - Open Source Computer Vision and Machine Learning software library 114 | 115 | - **Tensorflow** - TensorFlow is an end-to-end open source platform for machine learning. 116 | 117 | - **Tqdm** - tqdm is a Python library that allows you to output a smart progress bar by wrapping around any iterable. 118 | 119 | - **streamlit** - Streamlit is an open-source app framework for Machine Learning and Data Science teams. Create beautiful data apps in hours, not weeks. 120 | 121 | - **pandas** - pandas is a fast, powerful, flexible and easy to use open source data analysis and manipulation tool, built on top of the Python programming language. 122 | 123 | - **Pillow** - PIL is the Python Imaging Library by Fredrik Lundh and Contributors. 124 | 125 | - **scikit-learn** - Scikit-learn is a free software machine learning library for the Python programming language. 126 | 127 | - **opencv-python** - OpenCV is a huge open-source library for computer vision, machine learning, and image processing. 128 | 129 | 130 | 131 | ## 💡Challenges Faced and Learnings 132 | 133 | - Had very basic knowledge of Deep Learning before the Microsoft Engage Program's qualification announcement. Spentquality time on learning the new concepts attached to Deep Learning and then began the design-build process of this project. 134 | 135 | - Had to learn streamlit for creating graphical UI. 136 | 137 | - Setting the dependencies with proper version is the most critical. 138 | 139 | 140 | ## 📚Resources 141 | 142 | 143 | - [CNN:Convolutional Neural Network](https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.analyticsvidhya.com%2Fblog%2F2022%2F01%2Fconvolutional-neural-network-an-overview%2F&psig=AOvVaw17iUbKlnmXbO9mjLRJ52Tk&ust=1653830434872000&source=images&cd=vfe&ved=0CAwQjRxqFwoTCODLsNOkgvgCFQAAAAAdAAAAABAK) 144 | 145 | - [python](https://www.pythoncheatsheet.org/) 146 | 147 | 148 | 149 | ## ✨Conclusion 150 | 151 | In this project, we have presented a novel framework for fashion recommendation that is driven by data, 152 | visually related and simple effective recommendation systems for generating fashion product images. 153 | The proposed approach uses a two-stage phase. Initially, our proposed approach extracts the features 154 | of the image using CNN classifier ie., for instance allowing the customers to upload any random 155 | fashion image from any E-commerce website and later generating similar images to the uploaded image 156 | based on the features and texture of the input image. It is imperative that such research goes forward 157 | to facilitate greater recommendation accuracy and improve the overall experience of fashion 158 | exploration for direct and indirect consumers alike. 159 | 160 | --------------------------------------------------------------------------------