{"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":"# Inference with Lightning⚡Flash\n\nSee the example: https://lightning-flash.readthedocs.io/en/stable/reference/image_embedder.html\n\n**This is follow-up of https://www.kaggle.com/jirkaborovec/whale-dolphin-embedding-lit-flash-simclr**","metadata":{}},{"cell_type":"code","source":"!pip install -q vissl fairscale 'lightning-flash[image]' -U --pre --find-links /kaggle/input/whale-dolphin-embedding-lit-flash-simclr/frozen_packages/ --no-index\n!pip uninstall -y wandb","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-03-08T21:26:11.805396Z","iopub.execute_input":"2022-03-08T21:26:11.805872Z","iopub.status.idle":"2022-03-08T21:26:23.836879Z","shell.execute_reply.started":"2022-03-08T21:26:11.805805Z","shell.execute_reply":"2022-03-08T21:26:23.835627Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\n\nimport flash\nfrom flash.core.data.utils import download_data\nfrom flash.image import ImageClassificationData, ImageEmbedder","metadata":{"execution":{"iopub.status.busy":"2022-03-08T21:26:23.83994Z","iopub.execute_input":"2022-03-08T21:26:23.840254Z","iopub.status.idle":"2022-03-08T21:26:23.844877Z","shell.execute_reply.started":"2022-03-08T21:26:23.840223Z","shell.execute_reply":"2022-03-08T21:26:23.84428Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 1. Load the task ⚙️","metadata":{}},{"cell_type":"code","source":"embedder = ImageEmbedder.load_from_checkpoint(\n#     \"/kaggle/input/whale-dolphin-embedding-lit-flash-simclr/image_embedder_model.pt\"\n    \"/kaggle/input/happywhale-submissions/happywhale_embedder_model.pt\"\n)\n\nprint(embedder)","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-03-08T21:26:23.846092Z","iopub.execute_input":"2022-03-08T21:26:23.846416Z","iopub.status.idle":"2022-03-08T21:26:25.670444Z","shell.execute_reply.started":"2022-03-08T21:26:23.846388Z","shell.execute_reply":"2022-03-08T21:26:25.669265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"GPUS = int(torch.cuda.is_available())  # Set to 1 if GPU is enabled for notebook\n\ntrainer = flash.Trainer(gpus=GPUS)","metadata":{"execution":{"iopub.status.busy":"2022-03-08T21:26:25.673258Z","iopub.execute_input":"2022-03-08T21:26:25.673592Z","iopub.status.idle":"2022-03-08T21:26:25.682739Z","shell.execute_reply.started":"2022-03-08T21:26:25.673547Z","shell.execute_reply":"2022-03-08T21:26:25.681723Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 2. Run predictions 🎉","metadata":{}},{"cell_type":"code","source":"!ls -l /kaggle/input/happy-whale-and-dolphin\n\nPATH_DATASET = \"/kaggle/input/happy-whale-and-dolphin\"","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-03-08T21:26:25.684038Z","iopub.execute_input":"2022-03-08T21:26:25.684251Z","iopub.status.idle":"2022-03-08T21:26:26.52336Z","shell.execute_reply.started":"2022-03-08T21:26:25.684223Z","shell.execute_reply":"2022-03-08T21:26:26.52245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport pandas as pd\nfrom pprint import pprint\n\ndf_train = pd.read_csv(os.path.join(PATH_DATASET, \"train.csv\"))\ndisplay(df_train.head())\nprint(f\"Dataset size: {len(df_train)}\")\nprint(f\"Unique ids: {len(df_train['individual_id'].unique())}\")","metadata":{"execution":{"iopub.status.busy":"2022-03-08T21:26:26.525344Z","iopub.execute_input":"2022-03-08T21:26:26.526712Z","iopub.status.idle":"2022-03-08T21:26:26.628958Z","shell.execute_reply.started":"2022-03-08T21:26:26.526636Z","shell.execute_reply":"2022-03-08T21:26:26.628047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Train images","metadata":{}},{"cell_type":"code","source":"datamodule = ImageClassificationData.from_files(\n    predict_files=[f\"{PATH_DATASET}/train_images/{im}\" for im in df_train[\"image\"]],\n    batch_size=12,\n    num_workers=4,\n)\n\nembedder.input_transform = None\ntrain_embeddings = []\nfor emb in trainer.predict(embedder, datamodule=datamodule):\n    train_embeddings += emb\n\n# list of embeddings for images sent to the predict function\nprint(len(train_embeddings))\npprint(train_embeddings[:5])","metadata":{"execution":{"iopub.status.busy":"2022-03-08T21:26:26.630192Z","iopub.execute_input":"2022-03-08T21:26:26.630411Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Test images","metadata":{}},{"cell_type":"code","source":"import glob\n\nimgs = glob.glob(f\"{PATH_DATASET}/test_images/*.jpg\")\ndatamodule = ImageClassificationData.from_files(\n    predict_files=imgs,\n    batch_size=12,\n    num_workers=4,\n)\n\nembedder.input_transform = None\ntest_embeddings = []\nfor emb in trainer.predict(embedder, datamodule=datamodule):\n    test_embeddings += emb\n\n# list of embeddings for images sent to the predict function\nprint(len(test_embeddings))\npprint(test_embeddings[:5])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 3. Compute distances 🛣️","metadata":{}},{"cell_type":"code","source":"device = \"cuda\" if GPUS else \"cpu\"\n\ndist_embeddings = torch.cdist(\n    torch.stack(train_embeddings).to(device).to(torch.float32),\n    torch.stack(test_embeddings).to(device).to(torch.float32),\n    p=1,\n).T.cpu()\nprint(dist_embeddings.shape)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Format predictions","metadata":{}},{"cell_type":"code","source":"from tqdm.auto import tqdm\n\nsubmission = []\nfor im, dist in tqdm(zip(imgs, dist_embeddings), total=len(imgs)):\n    #print(im)\n    sorted_embs = [emb for _, emb in sorted(zip(dist.numpy(), df_train[\"individual_id\"]))]\n    for i in range(3, len(sorted_embs)):\n        embs = set(sorted_embs[:i])\n        if len(embs) == 4:\n            break\n    #print(embs)\n    submission.append({\"image\": os.path.basename(im), \"predictions\": \" \".join(list(embs) + [\"new_individual\"])})\n\n\ndf_submission = pd.DataFrame(submission).set_index(\"image\")\ndisplay(df_submission.head())","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submission.to_csv(\"submission.csv\")\n\n!head submission.csv","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}