{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":45867,"databundleVersionId":6924515,"sourceType":"competition"},{"sourceId":147716186,"sourceType":"kernelVersion"},{"sourceId":156101320,"sourceType":"kernelVersion"}],"dockerImageVersionId":30627,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!yes | dpkg -i --force-depends /kaggle/input/pip-pkg-pyvips-download-offline/linux_packages/archives/*.deb\n!pip install pyvips -f /kaggle/input/pip-pkg-pyvips-download-offline/python_packages/ --no-index","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2023-12-22T19:43:13.111895Z","iopub.execute_input":"2023-12-22T19:43:13.112137Z","iopub.status.idle":"2023-12-22T19:44:14.575225Z","shell.execute_reply.started":"2023-12-22T19:43:13.112113Z","shell.execute_reply":"2023-12-22T19:44:14.574116Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport torch","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:44:14.577172Z","iopub.execute_input":"2023-12-22T19:44:14.577476Z","iopub.status.idle":"2023-12-22T19:44:17.809522Z","shell.execute_reply.started":"2023-12-22T19:44:14.577448Z","shell.execute_reply":"2023-12-22T19:44:17.808783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if torch.cuda.is_available():\n    device = \"cuda\"\nelse:\n    device = \"cpu\"","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:44:17.810618Z","iopub.execute_input":"2023-12-22T19:44:17.811025Z","iopub.status.idle":"2023-12-22T19:44:17.835854Z","shell.execute_reply.started":"2023-12-22T19:44:17.810999Z","shell.execute_reply":"2023-12-22T19:44:17.834973Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_path = \"/kaggle/input/UBC-OCEAN/test_images\"\nlabel_csv_path = \"/kaggle/input/UBC-OCEAN/test.csv\"\n\nlabels = pd.read_csv(label_csv_path)\n\nclasslist = [\"CC\",\"EC\",\"HGSC\",\"LGSC\",\"MC\",\"Other\"]\n\nlabel2id = {k: v for v, k in enumerate(classlist) }\nid2label = {v: k for v, k in enumerate(classlist) }","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:44:17.838263Z","iopub.execute_input":"2023-12-22T19:44:17.838913Z","iopub.status.idle":"2023-12-22T19:44:17.871041Z","shell.execute_reply.started":"2023-12-22T19:44:17.838878Z","shell.execute_reply":"2023-12-22T19:44:17.870414Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from transformers import AutoImageProcessor\nfrom transformers import AutoModelForImageClassification, TrainingArguments, Trainer\n\ncheckpoint = \"/kaggle/input/ubc-model-test-pre-tiled-dataset-2048-512\"\n\nimage_processor = AutoImageProcessor.from_pretrained(checkpoint)\nsize = image_processor.size[\"shortest_edge\"] if \"shortest_edge\" in image_processor.size else (image_processor.size[\"height\"], image_processor.size[\"width\"])\nprint(size)\n\nmodel = AutoModelForImageClassification.from_pretrained(checkpoint)","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:44:17.872081Z","iopub.execute_input":"2023-12-22T19:44:17.87241Z","iopub.status.idle":"2023-12-22T19:44:33.098584Z","shell.execute_reply.started":"2023-12-22T19:44:17.872377Z","shell.execute_reply":"2023-12-22T19:44:33.097644Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torchvision.transforms.v2 as tvt\n\n_transforms = tvt.Compose([\n    tvt.Resize(size),\n    tvt.ToTensor(),\n    tvt.Normalize(mean=image_processor.image_mean, std=image_processor.image_std)\n])","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:44:33.100116Z","iopub.execute_input":"2023-12-22T19:44:33.100832Z","iopub.status.idle":"2023-12-22T19:44:33.390457Z","shell.execute_reply.started":"2023-12-22T19:44:33.100794Z","shell.execute_reply":"2023-12-22T19:44:33.389551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pyvips\n\ndef to_numpy(pyvips_img): \n    return np.ndarray(\n        buffer=pyvips_img.write_to_memory(),\n        dtype=np.uint8,\n        shape=[pyvips_img.height, pyvips_img.width, pyvips_img.bands]\n    )\n\ndef count_tiles(pyvips_img, tile_sz):\n    nx = pyvips_img.width // tile_sz \n    if pyvips_img.width % tile_sz != 0:\n        nx += 1\n    \n    ny = pyvips_img.height // tile_sz\n    if pyvips_img.height % tile_sz != 0:\n        ny += 1\n        \n    return nx, ny","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:44:33.391643Z","iopub.execute_input":"2023-12-22T19:44:33.391949Z","iopub.status.idle":"2023-12-22T19:44:33.642853Z","shell.execute_reply.started":"2023-12-22T19:44:33.391923Z","shell.execute_reply":"2023-12-22T19:44:33.642101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tile_sz = 2048","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:44:33.643938Z","iopub.execute_input":"2023-12-22T19:44:33.644202Z","iopub.status.idle":"2023-12-22T19:44:33.648063Z","shell.execute_reply.started":"2023-12-22T19:44:33.644178Z","shell.execute_reply":"2023-12-22T19:44:33.647187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch.nn.functional\n\npredicted_labels = []\n\nmodel = model.eval().to(device)\n\nfor _, row in labels.iterrows():\n    # initialize variables\n    add_probs = torch.zeros((len(classlist),) )\n    n = 0\n    \n    src_path = os.path.join(image_path, str(row[\"image_id\"])+\".png\")\n    \n    pyvips_img = pyvips.Image.new_from_file(src_path, access='sequential') \n    img_np = to_numpy(pyvips_img)\n    ntx, nty = count_tiles(pyvips_img, tile_sz)   \n    \n    for x in range(ntx):\n        for y in range(nty): \n            sx = min(tile_sz, abs(img_np.shape[1] - x * tile_sz))\n            sy = min(tile_sz, abs(img_np.shape[0] - y * tile_sz))\n            \n            left = x * tile_sz\n            top = y * tile_sz\n            right = left + sx\n            bottom = top + sy\n            \n            tile = img_np[top:bottom, left:right, :]\n            mask = tile.sum(-1) == 0\n            \n            # skip almost empty tile\n            if mask.sum() >= (np.prod(mask.shape) * 0.5):\n                continue\n            \n            tile = torch.from_numpy(tile).permute(2,0,1).to(torch.float32) / 255\n                  \n            with torch.no_grad():\n                tile = _transforms(tile.to(device))\n                output = model(tile.unsqueeze(0))    \n                probs = output.logits\n                #probs = torch.nn.functional.softmax(output.logits, dim=-1)\n\n                # add probabilities to sort-of correct wrong predictions\n                add_probs += probs.squeeze().cpu()\n                n += 1\n    \n    # end tile loop\n    pred = torch.nn.functional.sigmoid(add_probs / n)\n    if torch.all(pred <= 0.5):\n        predicted_labels.append(classlist[-1])\n    else:    \n        predicted_labels.append(id2label[torch.argmax(pred).item()])","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:44:33.649234Z","iopub.execute_input":"2023-12-22T19:44:33.6495Z","iopub.status.idle":"2023-12-22T19:45:15.472632Z","shell.execute_reply.started":"2023-12-22T19:44:33.649476Z","shell.execute_reply":"2023-12-22T19:45:15.471824Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.DataFrame(data={\"image_id\": labels[\"image_id\"].tolist(),\"label\": predicted_labels})\nsubmission.to_csv(\"/kaggle/working/submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2023-12-22T19:45:15.475403Z","iopub.execute_input":"2023-12-22T19:45:15.476206Z","iopub.status.idle":"2023-12-22T19:45:15.483969Z","shell.execute_reply.started":"2023-12-22T19:45:15.476168Z","shell.execute_reply":"2023-12-22T19:45:15.483232Z"},"trusted":true},"execution_count":null,"outputs":[]}]}