{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Product Similarity with EfficientNet\n\nIn this notebook we will use a pretrained CNN (EfficientNetB0) to create embeddings for our embeddings. Afterwards, we will save these In a following notebook, we will use these embeddings to find simiilar products. ","metadata":{}},{"cell_type":"code","source":"import os\nimport pandas as pd\n\ndef get_article_images_df(path='../input/h-and-m-personalized-fashion-recommendations/images'):\n    article_ids = []\n    image_paths = []\n    for dirname, _, filenames in os.walk(path):\n        for filename in filenames:\n            fullpath = os.path.join(dirname, filename)\n            image_path = fullpath\n            article_id = fullpath.split('/')[-1].replace('.jpg', '')\n            article_ids.append(article_id)\n            image_paths.append(fullpath)\n    return pd.DataFrame({'article_id': article_ids, 'image': image_paths})","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:26:56.963377Z","iopub.execute_input":"2022-02-15T19:26:56.963631Z","iopub.status.idle":"2022-02-15T19:26:56.970319Z","shell.execute_reply.started":"2022-02-15T19:26:56.963602Z","shell.execute_reply":"2022-02-15T19:26:56.969475Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = get_article_images_df()","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:27:01.338351Z","iopub.execute_input":"2022-02-15T19:27:01.338644Z","iopub.status.idle":"2022-02-15T19:27:26.796545Z","shell.execute_reply.started":"2022-02-15T19:27:01.338611Z","shell.execute_reply":"2022-02-15T19:27:26.795849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\nimport numpy as np\nimport tensorflow as tf\n\n\nclass DataGenerator(tf.keras.utils.Sequence):\n    'Generates data for Keras'\n    def __init__(self, df, img_size=256, batch_size=32):\n        self.df = df\n        self.img_size = img_size\n        self.batch_size = batch_size\n        self.indexes = np.arange(len(self.df))\n\n    def __len__(self):\n        'Denotes the number of batches per epoch'\n        ct = len(self.df) // self.batch_size\n        ct += int(((len(self.df)) % self.batch_size) != 0)\n        return ct\n\n    def __getitem__(self, index):\n        'Generate one batch of data'\n        indexes = self.indexes[index * self.batch_size:(index + 1) * self.batch_size]\n        X = self.__data_generation(indexes)\n        return X\n\n    def __data_generation(self, indexes):\n        'Generates data containing batch_size samples'\n        X = np.zeros((len(indexes), self.img_size, self.img_size, 3), dtype='float32')\n        df = self.df.iloc[indexes]\n        for i, (index, row) in enumerate(df.iterrows()):\n            img = cv2.imread(row.image)\n            X[i,] = cv2.resize(img, (self.img_size, self.img_size))  # /128.0 - 1.0\n        return X","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-02-15T19:29:55.965751Z","iopub.execute_input":"2022-02-15T19:29:55.966328Z","iopub.status.idle":"2022-02-15T19:30:01.364482Z","shell.execute_reply.started":"2022-02-15T19:29:55.966282Z","shell.execute_reply":"2022-02-15T19:30:01.363756Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Image Embeddings\n\nLet's create the embeddings using EfficientNetB0, the lightest model of the EfficientNet series.","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import EfficientNetB0\nfrom sklearn.neighbors import NearestNeighbors\n\nmodel = EfficientNetB0(weights='imagenet', include_top=False, pooling='avg', input_shape=None)\ntrain_gen = DataGenerator(df, batch_size=32)\nimage_embeddings = model.predict(train_gen, verbose=1)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:35:13.655196Z","iopub.execute_input":"2022-02-15T19:35:13.656130Z","iopub.status.idle":"2022-02-15T19:35:21.220094Z","shell.execute_reply.started":"2022-02-15T19:35:13.656088Z","shell.execute_reply":"2022-02-15T19:35:21.219317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with open('hm_embeddings_effb0.npy', 'wb') as f:\n    np.save(f, image_embeddings)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:30:30.973388Z","iopub.execute_input":"2022-02-15T19:30:30.973651Z","iopub.status.idle":"2022-02-15T19:30:30.978605Z","shell.execute_reply.started":"2022-02-15T19:30:30.973621Z","shell.execute_reply":"2022-02-15T19:30:30.977926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## KNN Training","metadata":{}},{"cell_type":"code","source":"print('image embeddings shape is', image_embeddings.shape)\nKNN = 12\nknn = NearestNeighbors(n_neighbors=KNN)\nknn.fit(image_embeddings)","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:34:12.947711Z","iopub.execute_input":"2022-02-15T19:34:12.948418Z","iopub.status.idle":"2022-02-15T19:34:12.966519Z","shell.execute_reply.started":"2022-02-15T19:34:12.948371Z","shell.execute_reply":"2022-02-15T19:34:12.965772Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from joblib import dump, load\ndump(knn, 'knn.joblib')","metadata":{"execution":{"iopub.status.busy":"2022-02-15T19:34:14.977707Z","iopub.execute_input":"2022-02-15T19:34:14.978166Z","iopub.status.idle":"2022-02-15T19:34:14.997174Z","shell.execute_reply.started":"2022-02-15T19:34:14.978123Z","shell.execute_reply":"2022-02-15T19:34:14.996507Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"A following notebook will be published using the KNN and the embeddings to find similar products.","metadata":{}}]}