{"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":"!pip install -q transformers","metadata":{"execution":{"iopub.status.busy":"2022-03-12T15:12:44.571821Z","iopub.execute_input":"2022-03-12T15:12:44.572678Z","iopub.status.idle":"2022-03-12T15:12:53.100814Z","shell.execute_reply.started":"2022-03-12T15:12:44.572586Z","shell.execute_reply":"2022-03-12T15:12:53.099996Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport json\nfrom torch.utils.data import Dataset, DataLoader\nfrom transformers import Trainer, TrainingArguments, BeitFeatureExtractor, BeitForImageClassification, default_data_collator\nfrom sklearn.model_selection import train_test_split\nfrom tqdm.notebook import tqdm\nfrom PIL import Image\nimport torch\nimport cv2\nimport random\nfrom sklearn.metrics import f1_score\n\nRANDOM_SEED = 56\nrandom.seed(RANDOM_SEED)\nnp.random.seed(RANDOM_SEED)\ntorch.manual_seed(RANDOM_SEED)\ntorch.cuda.manual_seed_all(RANDOM_SEED)","metadata":{"execution":{"iopub.status.busy":"2022-03-12T15:19:28.767567Z","iopub.execute_input":"2022-03-12T15:19:28.767888Z","iopub.status.idle":"2022-03-12T15:19:28.779484Z","shell.execute_reply.started":"2022-03-12T15:19:28.767853Z","shell.execute_reply":"2022-03-12T15:19:28.778722Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TRAIN_DIR = \"../input/herbarium-2022-fgvc9/train_images/\"\nTEST_DIR = \"../input/herbarium-2022-fgvc9/test_images/\"\n\nwith open(\"../input/herbarium-2022-fgvc9/train_metadata.json\") as json_file:\n    train_meta = json.load(json_file)\nwith open(\"../input/herbarium-2022-fgvc9/test_metadata.json\") as json_file:\n    test_meta = json.load(json_file)\n    \nimage_ids = [image[\"image_id\"] for image in train_meta[\"images\"]]\nimage_dirs = [TRAIN_DIR + image[\"file_name\"] for image in train_meta[\"images\"]]\ncategory_ids = [annot[\"category_id\"] for annot in train_meta[\"annotations\"]]\ngenus_ids = [annot[\"genus_id\"] for annot in train_meta[\"annotations\"] ]\ntest_ids = [image[\"image_id\"] for image in test_meta]\ntest_dirs = [TEST_DIR + image[\"file_name\"] for image in test_meta ]\n\ntrain_df = pd.DataFrame(data =np.array([image_ids , image_dirs, genus_ids, category_ids ]).T, \n                     columns = [\"image_id\", \"directory\",\"genus_id\", \"category\",])\ntest_df = pd.DataFrame(data =np.array([test_ids  , test_dirs ]).T, \n                    columns = [\"image_id\", \"directory\",])","metadata":{"execution":{"iopub.status.busy":"2022-03-12T15:12:59.541951Z","iopub.execute_input":"2022-03-12T15:12:59.543458Z","iopub.status.idle":"2022-03-12T15:13:15.858098Z","shell.execute_reply.started":"2022-03-12T15:12:59.543417Z","shell.execute_reply":"2022-03-12T15:13:15.857348Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class HerbariumDataset(Dataset):\n    def __init__(self, paths, labels, feature_extractor):\n        self.paths = list(paths)\n        self.labels = list(labels)\n        self.feature_extractor = feature_extractor\n        \n\n    def __len__(self):\n        return len(self.paths)\n\n    def __getitem__(self, idx):\n        path = self.paths[idx]\n        if self.labels:\n            label = self.labels[idx]\n        image = Image.open(path).convert(\"RGB\")\n        pixel_values = self.feature_extractor(image, return_tensors=\"pt\").pixel_values\n        if self.labels:\n            return {\"pixel_values\": pixel_values.squeeze(), \"labels\": torch.tensor(int(label))}\n        return {\"pixel_values\": pixel_values.squeeze()}","metadata":{"execution":{"iopub.status.busy":"2022-03-12T15:22:27.287929Z","iopub.execute_input":"2022-03-12T15:22:27.288412Z","iopub.status.idle":"2022-03-12T15:22:27.301204Z","shell.execute_reply.started":"2022-03-12T15:22:27.288374Z","shell.execute_reply":"2022-03-12T15:22:27.300489Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_name = 'microsoft/beit-base-patch16-224-pt22k-ft22k'\nmodel = BeitForImageClassification.from_pretrained(model_name, num_labels=len(train_df.category.unique()), ignore_mismatched_sizes=True)","metadata":{"execution":{"iopub.status.busy":"2022-03-12T15:13:15.86834Z","iopub.execute_input":"2022-03-12T15:13:15.868981Z","iopub.status.idle":"2022-03-12T15:13:48.030954Z","shell.execute_reply.started":"2022-03-12T15:13:15.868935Z","shell.execute_reply":"2022-03-12T15:13:48.030213Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"feature_extractor = BeitFeatureExtractor.from_pretrained(model_name)\ntrain_df, val_df = train_test_split(train_df, test_size=0.02)\ntrain_ds = HerbariumDataset(train_df['directory'], train_df['category'], feature_extractor)\nval_ds = HerbariumDataset(val_df['directory'], val_df['category'], feature_extractor)","metadata":{"execution":{"iopub.status.busy":"2022-03-12T15:13:48.032402Z","iopub.execute_input":"2022-03-12T15:13:48.032713Z","iopub.status.idle":"2022-03-12T15:13:50.852472Z","shell.execute_reply.started":"2022-03-12T15:13:48.032673Z","shell.execute_reply":"2022-03-12T15:13:50.851699Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training_args = TrainingArguments(\n    evaluation_strategy=\"steps\",\n    per_device_train_batch_size=16,\n    per_device_eval_batch_size=16,\n    fp16=True, \n    overwrite_output_dir=True,\n    output_dir=\"./\",\n    logging_steps=5,\n    num_train_epochs=1,\n    save_steps=10000,\n    eval_steps=10000,\n    report_to=\"none\"\n)","metadata":{"execution":{"iopub.status.busy":"2022-03-12T15:15:07.132503Z","iopub.execute_input":"2022-03-12T15:15:07.13327Z","iopub.status.idle":"2022-03-12T15:15:07.140741Z","shell.execute_reply.started":"2022-03-12T15:15:07.133217Z","shell.execute_reply":"2022-03-12T15:15:07.13984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def compute_metrics(pred):\n    y_true = pred.label_ids\n    y_pred = pred.predictions.argmax(-1)\n    return {'f1_macro': f1_score(y_true, y_pred, average='macro')}","metadata":{"execution":{"iopub.status.busy":"2022-03-12T15:15:07.688948Z","iopub.execute_input":"2022-03-12T15:15:07.689183Z","iopub.status.idle":"2022-03-12T15:15:07.694079Z","shell.execute_reply.started":"2022-03-12T15:15:07.689154Z","shell.execute_reply":"2022-03-12T15:15:07.692786Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainer = Trainer(\n    model=model,\n    tokenizer=feature_extractor,\n    args=training_args,\n    compute_metrics=compute_metrics,\n    train_dataset=train_ds,\n    eval_dataset=val_ds,\n    data_collator=default_data_collator,\n)","metadata":{"execution":{"iopub.status.busy":"2022-03-12T15:15:08.104807Z","iopub.execute_input":"2022-03-12T15:15:08.105037Z","iopub.status.idle":"2022-03-12T15:15:08.119352Z","shell.execute_reply.started":"2022-03-12T15:15:08.10501Z","shell.execute_reply":"2022-03-12T15:15:08.118536Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train and predict from checkpoint because of the many images","metadata":{}},{"cell_type":"code","source":"trainer.train()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_ds = HerbariumDataset(test_df['directory'], [], feature_extractor)\ntest_dl = DataLoader(test_ds, batch_size=16, shuffle=False, num_workers=4)","metadata":{"execution":{"iopub.status.busy":"2022-03-12T15:22:31.113464Z","iopub.execute_input":"2022-03-12T15:22:31.11415Z","iopub.status.idle":"2022-03-12T15:22:31.142967Z","shell.execute_reply.started":"2022-03-12T15:22:31.114099Z","shell.execute_reply":"2022-03-12T15:22:31.142274Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = []\nwith torch.no_grad():\n    for inputs in tqdm(test_dl):\n        inputs['pixel_values'] = inputs['pixel_values'].to('cuda')\n        outputs = model(**inputs)\n        logits = outputs.logits\n        preds.extend([x.item() for x in logits.argmax(-1)])","metadata":{"execution":{"iopub.status.busy":"2022-03-12T15:24:55.763617Z","iopub.execute_input":"2022-03-12T15:24:55.763866Z","iopub.status.idle":"2022-03-12T16:18:22.643504Z","shell.execute_reply.started":"2022-03-12T15:24:55.763836Z","shell.execute_reply":"2022-03-12T16:18:22.64276Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit = pd.read_csv('../input/herbarium-2022-fgvc9/sample_submission.csv')\nsubmit['Predicted'] = preds\nsubmit.to_csv('beit.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-03-12T16:20:58.113087Z","iopub.execute_input":"2022-03-12T16:20:58.113496Z","iopub.status.idle":"2022-03-12T16:20:58.203583Z","shell.execute_reply.started":"2022-03-12T16:20:58.11346Z","shell.execute_reply":"2022-03-12T16:20:58.202799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}