{"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 for 🌿Herbarium with Lightning⚡Flash\n\n\n**This is just inference version fo the original work: https://www.kaggle.com/jirkaborovec/herbarium-eda-baseline-flash-efficientnet**\n\nSee our story: [Best Practices to Rank on Kaggle Competition with PyTorch Lightning and Grid.ai Spot Instances](https://devblog.pytorchlightning.ai/best-practices-to-rank-on-kaggle-competition-with-pytorch-lightning-and-grid-ai-spot-instances-54aa5248aa8e)\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-02-15T09:52:20.579025Z","iopub.execute_input":"2022-02-15T09:52:20.579391Z","iopub.status.idle":"2022-02-15T09:52:20.583893Z","shell.execute_reply.started":"2022-02-15T09:52:20.579358Z","shell.execute_reply":"2022-02-15T09:52:20.583227Z"}}},{"cell_type":"code","source":"! ls -l /kaggle/input/","metadata":{"execution":{"iopub.status.busy":"2022-05-13T11:44:32.911142Z","iopub.execute_input":"2022-05-13T11:44:32.912915Z","iopub.status.idle":"2022-05-13T11:44:33.721302Z","shell.execute_reply.started":"2022-05-13T11:44:32.912758Z","shell.execute_reply":"2022-05-13T11:44:33.720151Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Browse test images ","metadata":{}},{"cell_type":"code","source":"import os\nimport json\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\nPATH_DATASET = \"/kaggle/input/herbarium-2022-fgvc9\"\n\nwith open(os.path.join(PATH_DATASET, \"test_metadata.json\")) as fp:\n    test_data = json.load(fp)\n\nprint(len(test_data))\ndf_test = pd.DataFrame(test_data).set_index(\"image_id\")\ndisplay(df_test.head())","metadata":{"execution":{"iopub.status.busy":"2022-05-13T11:44:33.723834Z","iopub.execute_input":"2022-05-13T11:44:33.724087Z","iopub.status.idle":"2022-05-13T11:44:34.566732Z","shell.execute_reply.started":"2022-05-13T11:44:33.724057Z","shell.execute_reply":"2022-05-13T11:44:34.565947Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axarr = plt.subplots(nrows=2, ncols=5, figsize=(12, 6))\nfor i, (_, row) in enumerate(df_test[:10].iterrows()):\n    img_path = os.path.join(PATH_DATASET, \"test_images\", row[\"file_name\"])\n    img = plt.imread(img_path)\n    axarr[i // 5, i % 5].imshow(img)\n#     print(row)\nfig.tight_layout()","metadata":{"execution":{"iopub.status.busy":"2022-05-13T11:44:34.573086Z","iopub.execute_input":"2022-05-13T11:44:34.573447Z","iopub.status.idle":"2022-05-13T11:44:37.418949Z","shell.execute_reply.started":"2022-05-13T11:44:34.573401Z","shell.execute_reply":"2022-05-13T11:44:37.417526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Inference with Lightning⚡Flash\n","metadata":{}},{"cell_type":"code","source":"!pip install -q 'lightning-flash[image]' \"torchmetrics==0.7.*\" --find-links /kaggle/input/herbarium-eda-baseline-flash-efficientnet/frozen_packages/ --no-index\n!pip install -q timm -U --find-links /kaggle/input/herbarium-submissions/packages/ --no-index\n!pip uninstall -y wandb","metadata":{"_kg_hide-input":false,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-05-13T11:44:37.420737Z","iopub.execute_input":"2022-05-13T11:44:37.421194Z","iopub.status.idle":"2022-05-13T11:45:20.874393Z","shell.execute_reply.started":"2022-05-13T11:44:37.421138Z","shell.execute_reply":"2022-05-13T11:45:20.87347Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport flash\nfrom flash.image import ImageClassificationData, ImageClassifier","metadata":{"execution":{"iopub.status.busy":"2022-05-13T11:45:20.876454Z","iopub.execute_input":"2022-05-13T11:45:20.876851Z","iopub.status.idle":"2022-05-13T11:45:34.521284Z","shell.execute_reply.started":"2022-05-13T11:45:20.876782Z","shell.execute_reply":"2022-05-13T11:45:34.520255Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 1. Load the task ⚙️","metadata":{}},{"cell_type":"code","source":"model = ImageClassifier.load_from_checkpoint(\n#     \"/kaggle/input/herbarium-eda-baseline-flash-efficientnet/image_classification_model.pt\"\n    \"/kaggle/input/herbarium-submissions/herbarium-classif-2nwcf7mv_convnext_base_384_in22ft1k-384px.pt\"\n)","metadata":{"execution":{"iopub.status.busy":"2022-05-13T11:45:34.522584Z","iopub.execute_input":"2022-05-13T11:45:34.522865Z","iopub.status.idle":"2022-05-13T11:46:08.4772Z","shell.execute_reply.started":"2022-05-13T11:45:34.522832Z","shell.execute_reply":"2022-05-13T11:46:08.476224Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Trainer Args\nGPUS = int(torch.cuda.is_available())  # Set to 1 if GPU is enabled for notebook\ntrainer = flash.Trainer(gpus=GPUS)","metadata":{"_kg_hide-output":false,"execution":{"iopub.status.busy":"2022-05-13T11:46:08.478981Z","iopub.execute_input":"2022-05-13T11:46:08.4797Z","iopub.status.idle":"2022-05-13T11:46:08.487888Z","shell.execute_reply.started":"2022-05-13T11:46:08.479649Z","shell.execute_reply":"2022-05-13T11:46:08.487129Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 2. Run predictions 🎉","metadata":{}},{"cell_type":"code","source":"from dataclasses import dataclass\nfrom torchvision import transforms as T\nfrom typing import Tuple, Callable\nfrom flash.core.data.io.input_transform import InputTransform\n\n@dataclass\nclass ImageClassificationInputTransform(InputTransform):\n\n    image_size: Tuple[int, int] = (224, 224)\n    color_mean = (0.778, 0.756, 0.709)\n    color_std = (0.246, 0.250, 0.253)\n\n    def input_per_sample_transform(self):\n        return T.Compose([\n            T.ToTensor(),\n            T.Resize(self.image_size),\n            T.Normalize(self.color_mean, self.color_std),\n        ])\n\n    def target_per_sample_transform(self) -> Callable:\n        return torch.as_tensor","metadata":{"execution":{"iopub.status.busy":"2022-05-13T11:46:08.489027Z","iopub.execute_input":"2022-05-13T11:46:08.489245Z","iopub.status.idle":"2022-05-13T11:46:08.507635Z","shell.execute_reply.started":"2022-05-13T11:46:08.489219Z","shell.execute_reply":"2022-05-13T11:46:08.506695Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"datamodule = ImageClassificationData.from_data_frame(\n    input_field=\"file_name\",\n    predict_data_frame=df_test,\n    # for simplicity take just fraction of the data\n    # predict_data_frame=df_test[:len(df_test) // 1000],\n    predict_images_root=os.path.join(PATH_DATASET, \"test_images\"),\n    predict_transform=ImageClassificationInputTransform,\n    batch_size=3,\n    transform_kwargs={\"image_size\": (384, 384)},\n    num_workers=3,\n)","metadata":{"execution":{"iopub.status.busy":"2022-05-13T11:46:08.510182Z","iopub.execute_input":"2022-05-13T11:46:08.5108Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = []\nfor lbs in trainer.predict(model, datamodule=datamodule, output=\"labels\"):\n    # lbs = [torch.argmax(p[\"preds\"].float()).item() for p in preds]\n    predictions += lbs","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.DataFrame({\"id\": df_test.index, \"Predicted\": predictions}).set_index(\"id\")\nsubmission.to_csv(\"submission.csv\")\n\n! head submission.csv","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}