{"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":"code","source":"import os\nimport glob\nfrom tqdm import tqdm\nfrom PIL import Image\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nimport torch\nimport torch.nn as nn\nimport torch.utils.data as data\nimport torchvision.models as models","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class config:\n    img_size = 125\n    batch_size = 64\n    embedding_size = 125","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h3>Get article's images</h3>","metadata":{}},{"cell_type":"code","source":"img_list = glob.glob('../input/h-and-m-personalized-fashion-recommendations/images/*/*')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h3>Define custom dataset class and dataloader</h3>","metadata":{}},{"cell_type":"code","source":"class CustomImageClass(data.Dataset):\n    def __init__(self, data_path, transform=None):\n        self.root = data_path\n        self.transform = transform\n        \n    def __getitem__(self, indx):\n        image = Image.open(self.root[indx]).convert('RGB')\n        if self.transform is not None:\n            image = self.transform(image)\n        return image\n    \n    def __len__(self):\n        return len(self.root)\n    \nfrom torchvision import transforms\n\ntransform = transforms.Compose([\n    transforms.Resize((config.img_size, config.img_size)),\n    transforms.RandomHorizontalFlip(),\n    transforms.ToTensor(),\n    transforms.Normalize([0.485, 0.456, 0.406],\n                        [0.229, 0.224, 0.225])\n])\n\n\nimage_dataset = CustomImageClass(data_path=img_list, \n                                 transform=transform)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"custom_data_loader = torch.utils.data.DataLoader(dataset=image_dataset,\n                                                batch_size=config.batch_size,\n                                                shuffle=True,\n                                                num_workers=2)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h3>Visualize some images in our dataset</h3>","metadata":{}},{"cell_type":"code","source":"def imageshow(image):\n    npimage = image.numpy()\n    plt.imshow(np.transpose(npimage, (1, 2, 0)))\n    plt.show()\n\na = iter(custom_data_loader)\nimages = a.next()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torchvision\n\nimageshow(torchvision.utils.make_grid(images[:4]))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h3>Define the model</h3>","metadata":{}},{"cell_type":"code","source":"class CNNModel(nn.Module):\n    def __init__(self, embedding_size):\n        super(CNNModel, self).__init__()\n        resnet = models.resnet152(pretrained=True)\n        module_list = list(resnet.children())[:-1] # exlude the last layer to get the embeddings\n        self.resnet_module = nn.Sequential(*module_list)\n        self.embedding_layer = nn.Linear(resnet.fc.in_features, embedding_size)\n    \n    def forward(self, input_images):\n        with torch.no_grad():\n            resnet_features = self.resnet_module(input_images)\n        resnet_features = resnet_features.reshape(resnet_features.size(0), -1)\n        embedding = self.embedding_layer(resnet_features)\n        return embedding","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = CNNModel(config.embedding_size)\nmodel.to('cuda')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h3>Generate emeddings</h3>","metadata":{}},{"cell_type":"code","source":"embeddings = []\n\nwith torch.no_grad():\n    for data in tqdm(custom_data_loader):\n        preds = model(data.to(\"cuda\"))\n        preds = preds.detach().cpu().numpy()\n        embeddings.append(preds)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"embeddings = np.concatenate(embeddings)\nimg_embeddings = pd.DataFrame(embeddings)\nimg_embeddings['image_id'] = img_list\n\n# save the embeddings\nimg_embeddings.to_csv(f\"prodemb_img_{config.embedding_size}.csv\", index = False)\n","metadata":{},"execution_count":null,"outputs":[]}]}