{"cells":[{"metadata":{},"cell_type":"markdown","source":"# RANZCR CLiP - Catheter and Line Position\n\n![](https://storage.googleapis.com/kaggle-competitions/kaggle/23870/logos/header.png?t=2020-12-01-04-28-05)\n\nEvaluation\nTimeline\nPrizes\nCode Requirements\nRANZCR 2021\nAcknowledgements\nSerious complications can occur as a result of malpositioned lines and tubes in patients. Doctors and nurses frequently use checklists for placement of lifesaving equipment to ensure they follow protocol in managing patients. Yet, these steps can be time consuming and are still prone to human error, especially in stressful situations when hospitals are at capacity.\n\nHospital patients can have catheters and lines inserted during the course of their admission and serious complications can arise if they are positioned incorrectly. Nasogastric tube malpositioning into the airways has been reported in up to 3% of cases, with up to 40% of these cases demonstrating complications [1-3]. Airway tube malposition in adult patients intubated outside the operating room is seen in up to 25% of cases [4,5]. The likelihood of complication is directly related to both the experience level and specialty of the proceduralist. Early recognition of malpositioned tubes is the key to preventing risky complications (even death), even more so now that millions of COVID-19 patients are in need of these tubes and lines."},{"metadata":{"trusted":true},"cell_type":"markdown","source":"<a id=\"top\"></a>\n\n<div class=\"list-group\" id=\"list-tab\" role=\"tablist\">\n<h3 class=\"list-group-item list-group-item-action active\" data-toggle=\"list\" style='color:white; background:#FFCD46; border:0' role=\"tab\" aria-controls=\"home\"><center>Quick Navigation</center></h3>\n\n* [Overview](#1)\n* [Annotations](#2)\n    \n    \n    \n* [ETT - Abnormal](#4)\n* [ETT - Borderline](#5)\n* [ETT - Normal](#6)\n* [NGT - Abnormal](#7)\n* [NGT - Borderline](#8)\n* [NGT - Incompletely Imaged](#9)\n* [NGT - Normal](#10)\n* [CVC - Abnormal](#11)\n* [CVC - Borderline](#12)\n* [CVC - Normal](#13)\n* [Swan Ganz Catheter Present](#14)\n    \n    \n* [About The Solution](#15)\n* [Directory Settings](#16)\n* [Context-Free Grammar (CFG)](#17)\n* [Library Using on The Datasets](#18)\n* [Utils](#19)\n* [Data Loading](#20)\n* [Dataset](#21)\n* [Transforms](#22)\n* [Model](#23)"},{"metadata":{"trusted":true},"cell_type":"markdown","source":"<a id=\"1\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Overview<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport ast\nimport random\n\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport matplotlib.pyplot as plt\nimport seaborn as sns","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"BASE_DIR = \"../input/ranzcr-clip-catheter-line-classification/\"\nprint(os.listdir(BASE_DIR))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train = pd.read_csv(os.path.join(BASE_DIR, \"train.csv\"), index_col=0)\ndf_train.head(10)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**StudyInstanceUID** - unique ID for each image   \n**ETT - Abnormal** - endotracheal tube placement abnormal   \n**ETT - Borderline** - endotracheal tube placement borderline abnormal   \n**ETT - Normal** - endotracheal tube placement normal   \n**NGT - Abnormal** - nasogastric tube placement abnormal   \n**NGT - Borderline** - nasogastric tube placement borderline abnormal   \n**NGT - Incompletely Imaged** - nasogastric tube placement inconclusive due to imaging   \n**NGT - Normal** - nasogastric tube placement borderline normal   \n**CVC - Abnormal** - central venous catheter placement abnormal   \n**CVC - Borderline** - central venous catheter placement borderline abnormal   \n**CVC - Normal** - central venous catheter placement normal   \n**Swan Ganz Catheter Present**   \n**PatientID** - unique ID for each patient in the dataset  "},{"metadata":{"trusted":true},"cell_type":"code","source":"! pip install seaborn","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.set_style(\"dark\")\nplt.figure(figsize=(10, 10))\ndf_tmp = df_train.iloc[:, :-1].sum()\nsns.barplot(x=df_tmp.values, y=df_tmp.index)\nplt.xticks(fontsize=14)\nplt.yticks(fontsize=14)\nplt.xlabel(\"Number of images\", fontsize=15)\nplt.title(\"Distribution of labels\", fontsize=16)\nplt.grid(True)\nplt.minorticks_on()\nplt.grid(b=True, which='minor', color='#999999', linestyle='-', alpha=0.2);","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Number of unique patients: {}\".format(df_train[\"PatientID\"].unique().shape[0]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(16, 8))\ndf_tmp = df_train[\"PatientID\"].value_counts()\nsns.countplot(x=df_tmp.values)\nplt.xticks(fontsize=12, rotation=90)\nplt.yticks(fontsize=14)\nplt.xlabel(\"Number of observations\", fontsize=15)\nplt.ylabel(\"Number of patients\", fontsize=15)\nplt.title(\"Distribution of observations by PatientID\", fontsize=16)\nplt.grid(True)\nplt.minorticks_on()\nplt.grid(b=True, which='minor', color='#999999', linestyle='-', alpha=0.2);","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"2\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Annotations<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"df_annot = pd.read_csv(os.path.join(BASE_DIR, \"train_annotations.csv\"))\ndf_annot.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_image_with_annotations(row_ind):\n    row = df_annot.iloc[row_ind]\n    image_path = os.path.join(BASE_DIR, \"train\", row[\"StudyInstanceUID\"] + \".jpg\")\n    label = row[\"label\"]\n    data = np.array(ast.literal_eval(row[\"data\"]))\n    \n    plt.figure(figsize=(10, 5))\n    image = cv2.imread(image_path)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    plt.subplot(1, 2, 1)\n    plt.imshow(image)\n    plt.subplot(1, 2, 2)\n    plt.imshow(image)\n    plt.scatter(data[:, 0], data[:, 1])\n    \n    plt.suptitle(label, fontsize=15)\n\n# Example -->\nplot_image_with_annotations(3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def visualize_annotations(file_id):\n    plt.figure(figsize=(8, 8))\n    \n    image = cv2.imread(os.path.join(BASE_DIR, \"train\", file_id + \".jpg\"))\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    plt.imshow(image)\n    \n    df_patient = df_annot.loc[df_annot[\"StudyInstanceUID\"] == file_id]\n    \n    if df_patient.shape[0]:        \n        labels = df_patient[\"label\"].values.tolist()\n        lines = df_patient[\"data\"].apply(ast.literal_eval).values.tolist()\n\n        for line, label in zip(lines, labels):         \n            line = np.asarray(line)\n            plt.scatter(line[:, 0], line[:, 1], s=40, label=label)\n        \n        plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0, prop={'size': 20})\n        \n    plt.tick_params(axis=\"x\", labelsize=15)\n    plt.tick_params(axis=\"y\", labelsize=15)\n    \n    plt.show()\n    \n    \nvisualize_annotations(\"1.2.826.0.1.3680043.8.498.83331936392921199432218327504041001669\")\nvisualize_annotations(\"1.2.826.0.1.3680043.8.498.11693509889426445054876979814173446281\")\nvisualize_annotations(\"1.2.826.0.1.3680043.8.498.15159015355212130418020059688126994534\")\nvisualize_annotations(\"1.2.826.0.1.3680043.8.498.92067938763801985117661596637576203997\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def visualize_batch(image_ids):\n    plt.figure(figsize=(16, 10))\n    \n    for ind, image_id in enumerate(image_ids):\n        plt.subplot(2, 3, ind + 1)\n        image = cv2.imread(os.path.join(BASE_DIR, \"train\", f\"{image_id}.jpg\"))\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\n        plt.imshow(image)\n        plt.axis(\"off\")\n    \n    plt.show()\n\n    \ndef plot_statistics(df, col):\n    plt.figure(figsize=(16, 2))\n    sns.countplot(y=df[col])\n    \n    plt.xticks(fontsize=12)\n    plt.yticks(fontsize=12)\n    plt.xlabel(\"Number of observations\", fontsize=15)\n    plt.ylabel(col, fontsize=15)\n    plt.title(f\"Distribution of {col}\", fontsize=16)\n    plt.xlim(0, 30000)\n    plt.grid(True)\n    plt.minorticks_on()\n    plt.grid(b=True, which='minor', color='#999999', linestyle='-', alpha=0.2);\n    \n    plt.show()\n    \n\ndef process_class(col_name):\n    plot_statistics(df_train, col_name)\n    tmp_df = df_train[df_train[col_name] == 1]\n    visualize_batch(random.sample(tmp_df.index.tolist(), 6))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"4\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>ETT - Abnormal<center><h2>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Endotracheal Tube Placement Abnormal<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"process_class(\"ETT - Abnormal\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"visualize_annotations(\"1.2.826.0.1.3680043.8.498.45114171511781107649527256548033785190\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"5\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>ETT - Borderline<center><h2>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Endotracheal Tube Placement Borderline Abnormal<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"process_class(\"ETT - Borderline\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"6\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>ETT - Normal<center><h2>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Endotracheal Tube Placement Normal<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"process_class(\"ETT - Normal\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"7\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>NGT - Abnormal<center><h2>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Nasogastric Tube Placement Abnormal<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"process_class(\"NGT - Abnormal\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"8\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>NGT - Borderline<center><h2>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Nasogastric Tube Placement Borderline Abnormal<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"process_class(\"NGT - Borderline\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"9\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>NGT - Incompletely Imaged<center><h2>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Nasogastric Tube Placement Inconclusive Due To Imaging<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"process_class(\"NGT - Incompletely Imaged\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"10\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>NGT - Normal<center><h2>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Nasogastric Tube Placement Borderline Normal<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"process_class(\"NGT - Normal\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"11\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>CVC - Abnormal<center><h2>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Central Venous Catheter Placement Abnormal<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"process_class(\"CVC - Abnormal\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"12\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>CVC - Borderline<center><h2>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Central Venous Catheter Placement Borderline Abnormal<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"process_class(\"CVC - Borderline\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"13\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>CVC - Normal<center><h2>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Central Venous Catheter Placement Normal<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"process_class(\"CVC - Normal\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"14\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Swan Ganz Catheter Present<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"process_class(\"Swan Ganz Catheter Present\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"15\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>About The Solution<center><h2>"},{"metadata":{},"cell_type":"markdown","source":"![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfcAAABkCAMAAACsLolMAAAAyVBMVEX///8lJSXuTCwAAAAhISEcHBwVFRXy8vIRERE/Pz+bm5uhoaHn5+eIiIgYGBhlZWUxMTHZ2dmSkpIrKyt+fn6srKzT09P5+fkLCwvuRyXtQBjk5OTHx8e3t7djY2NWVlb4u7Rvb2/tPRE5OTm+vr5OTk784NtFRUWMjIynp6d4eHhubm5aWlrtRCDvVzrwX0T719H0koL5ycH97er2qJv1npDtOADzg3D3sKXxblfzi3v98O71mor4ua/608zyeGPxclzwZEz5xb8IGFZeAAAQLElEQVR4nO2dCXfavBKG7Uhe2JcANnuBEAKBJM3StF/S9rb//0ddrJF3azGGxEn9nnPP/Qq2YvxY0sxoNFaUQoUK5Uytca1Ufu+LkNPD3/e+gs8iY4qQrdsfg/vD7st7X8JnkVHCqqqaH4L7w9n8y3tfw2fRB+L+cNYffHnvi/gs+jjc99jPCu7H0ofh/nDTP8vGfTxpRDTbdNrri6pxeJujbbRNsSYbK8OvOJI+CvdLB3s27hWkRVWv6yZCzUa5dyCKcbxNofRVwV1WgD0jd1NNFtZMtGoPD2lzbDPa5AgvC+6SothPxJ3AMHHnAPIF91PKxX5C7nvpaiV1mwX3E8rDfvbtV4ZmKHfTdmWapq7hABB7Uk3Z5hjVk6RBg5qdJFQquMvIxz5/9D607u4eUrYD3M8rXVfrSvlqs9SQ6bHXFynB9zadJG1Ii9qkm6hxygs/hfLPPYD91fvw7nYwOHtK1xDlHvHaLKNXXqI6Ba810/b4RFVJe/rVMdo6jXLPPYD9q/fhQ78f7v4ySuZO1Nogd2g+yuRb1Qn32hGaOpHyzj0Ru/I0gM9e0jTF4b4nv6QWmn0MWAX3jLo8S8KuPMOn31JN8VzuilJDAB61Dr9cVwX3bApgfw1+/t8OPjxef9/rCnq8tj30an0V3DOJhV359c35cPecqjURd6VRP1aHL7hn0WWfgV1RHr8NdvPbVN1dzN04x0cywwvuGcTBvv/y8fVLyvaE3JUyRHbqKRuOq+B+uALYUzrqDIm5D6lld9ASTVAF94PlYx+IsL/KmfVi7sqWePF25oBaKu7VUbdcbpcr3Z44EWAYeCSt4ejignOONbyolNtOw6P4QYncjd7oYtTKkI6QXQ9n0ti/zuX8eAnubXIIvRsGiN+olXiQNHfrorNAyDZN3TRthFa1HvPQVvdqq6G1+8/RBu9P3J/T7IwSQk3VdUMj7ULD6mwdDkTGuBtj50rQ/li0SGzxTWTdymMfnPVvZdqU4H5BXDntmvyjgYhG3EZL5JjzyKeS3KtXGqoHFoZUrKPSOvkCq3Vb11Sbch/5oWVcR4tKhFPv2rY1NdiwZqPJOHBUhHurE7iSfYuld1pDeN6lwL4/Ssajk+DeMwMefI8EcuozXps98qDY68jHUtyNmq2rMWG7mXjPq00CCv5SDYWpotCPak3CX1NpQZoh7q0ZilwJRpP3GO5/zl3sohD8V4jYyiRYy3AnnQgv4V/k1uBz3kpNh5xgHjLOXzQZ+QD7e57wJwPcrW1k1V9rBI8sm0nUoeWp23KAu9X2xo6A9EVm6za1HqR7OwRwnBiOeIqX4a4HuVeSO3NAxsK5e/VN9HMJ7jXbG1Y1nWQD+CN+/Tw+uQS4T6MPjBlIGDEmyOeskWQAP8cAq+6v97m3Su5ThB35D1PzzXu8O8oPvgoP/U5XaHb/CQ+VH+cn8K8q/GvKPh7SbVDMGBNyt67dm72fna+vuuOLcXmzrLuZANi+iDXpcZ8B9v2Mre3/53TuQITRWLgjtmbXV41Np7O53i7c2d4fGDzuXZ18tZ/T9cVquizVPcNAb0Sv4cS6o51491vi4P/cZ+RSdKS8XedO6TNw69hx24ZzAF7FPhdxtya0y9b1je+JWcPyio4COGZOetzXYHbo191hdTgclSd120/gMZqa23BjPHQ/Nobdmeq07HuowF0vV5Dz/9rekxgNDWvvngzHE3ckQrGH77T6TW35Gxm/3PoDR/eFpp2MH0d4eVbuCPHxDbXoKEsl4r6h2NF1ZBK1uucw12I98g3l3oVBKHjisO3/nZVGx4tN9GE1ukuENe8s4K4uNEK9EXLcRvThwQvW9Z9El7S7D35KHX7njvSiDp8+bmOBZbdgnQJxXTNuhQm4g+GgYjPBcq826LJg5Ka73J0hBkciSx40dwpoJjmf1njht0m5k2doGp2nhgv4Mj6BnVKvMHL3f0geT0f6ncgGFHOvnsPP9XoFgGWNd9YSB2eFYENc7j3anc6TJ5AagDfDZwN3PMUOdkZMYQwmXX3JcEEM/zyPOzYT7Fbwa9R6J7md08idsO8lj7+EDt+/ERwn5t6lXc37gFp2DAMHHPykwA6f+xQsKY1lN3TMyONHmiTcVczphhZY49pKwhB3udcXiVfRAesw+wqVvH6B797/I30Gzb7Z3fEPE3KHYT30lF8TRNG5loo47zgpK5rLnebccwKBE9LdXLeCNtl0B2bEiqVdkR+IsUxqKOWuLxlpZzQV4ShZpnJ6gv4++C59xv1AKsYj5N42Y7MaWHbJy1awXJ/4HY+7tSJ33Oas8hvQcUMJIB53PRYtcI+grKSscOCuTVmBeLhIQZD6qHITKYV+mS9qEPyPf5SI+wWMbbgU+Ixadok7GaHf2kldgsf9gjxKeMFb+oAJJzS9utwxZp1Y5k5KEVH/nblDCAKR2VcmpWV9SzvMewP9DX8VScB9RMNa4WccxoDEGXWiMW8zjzvx+VXU5V4rGNRa4Ae53NndGQ6QTB4Qrb/DQ51k851IlzC978ShOl8/qWXHHyL43Ls0WhFJqxzGe17om2QMHO5VMOqa/GeUjiWBR5ByZ2d9hmONIom4j2z2BHcS/aWT9ZcU5/yi5/B3z/G4t6Y0qo3tyPfQPbX4WWQkYAzXHO4whOtt7qUqFhlmg4F/yp2d9FnTo48KTyLusFIhuswj6rsUw7AeYIwY8KucsblfbL2Fy5glA9OxHRuWYeY3k28Mh/umzsdHRULEwYAZcOfM3mCg24J2XYm4t7Q35v64kxmzI5rLjBGUe7iDGqP1te1Rx3EfCZbc4osz4LzbybMpmztY84nOX0h0pcA3GoE7O4JWVdMM8/njTqN1acx5jzvf9aPcy5VyuXxV62xmk+mijlBgtVozE2Zr8IpjHZQYvKzbzOYOkaD4ym1UYD2Y/uhDuTPHiZGZyhDLHfevJ+au6qaz71131qWDm9+du1BK6k1Dclo0qd4Aq5zh57C5tzgBgZBgpcB/DkXc45YgV7nj/nTicZ4pXbtKHnyJv4Yj8wMxz5grNmzuFI/YL15FuIi4w1Ki9F6f3HGndp0o6BrSC3Cf8yP6PO6arTLL24yTHDaycsdccGNzLyfPGnGRCHHdb0HEfQMDkGyOTO64fxnI2OZh3dH+zn9WWNyxZtenFXYkmlp218HPhjBcsyiwudNuKQ6u1Bz7IWAHiLjTcJCwXarccafLMsJV1aCoz3/Gz9Og3HGgfJ1u2khdzdb87geecWiNgjjv7BgKm/tVvK1kkQck8LCJuG8/OPeXb1LB9pCoLShYiAXueHtN60Zezzq1yrhVFe4RaEEWTiCWbZEhIO7Uuzoad39t/7NzV9wkqxSbXW/gURGk41Vkp9aYyD0NrteQZTrMTjg9wjhP/MRAfFhynJfd6JI/7jR9JsUETxMvRCu3FfYSi0CxtNlNBEpUQrtO7G4Ruy7gPYq4Qw6o9IJ5/rhTw07UewOioR5Rgt3h3A1yz33OBsRI2C0J/Tj+apyjVWQmEXGnE4jsr8sfd7oQK+/BWzShVrRJ7nDuNO3IdgdR4rxrS/bxbO4Q3pW4n7D+LR+vkw4MgPLH3UubEu+EAD3Kpdtk4Q6rU17vWzo3hbePRhSnFSdH0PVfH7MwTstcME5UDrnfgycnG7p5oYbgTpRtn4E7kHZ7OHHeufvm2NwNSGDCovgK6b44sM9WxH0I7TYF7XrXkT/uCt0DLZlITTdViYeHLNxh1Zya4cQm5+6T5azDUvtLZNgR8zwYIBBxpyk6srU68sj9L+3wwl2Rjmiuzdlccp/UYdwhh5Ka1ySZmbsCwuG+hvFYsCBnhCcWRYI7ZMTJksojd7fDy/hyl3T5Tnpf5IF7QCBdguSTg/Me3xQXEC/PCrI3EzbZBLWO7cQRcocJHmNuu55yyd3dGCnOunlwq+AMxAGLTNx7/s4Z4lnb3Fr1vLxKCKyZ/GJpZHgJeQxC7pYKCTdyK/C55O5WMxBumvEKG84lojyZuIM/7eRZGJCJx51HedzpZibuRAzRndBmaCF36sGrdakluXxyt/xqxLzNkfc715aXr3NyKHeYl5EB/yFwxHjc6U4V3rZ6SPUI2+Zi7uD6qXWpBPp8cndDrw74Z2ag/onaf6nqGh3KHfLXzArkLwryWrj7pOguPJt5T62S5k0qfpNC7tQGUaVe+ppT7p4Tv+/L/eQu/+vWfTb6/RR1zA7e2zsju+Ga4LyX+MdyuVtLyOhjbp2YkLMj8UAJ7lWaYCARBc4td7+00b7L3/6MWm3W/Y9538Oepm7hwdzpvoQp/36BBPugaSkSlGgbGg26TS9s8Utwp6Uw2D3e8DHmlrtXucYhO+h/vX/x2L/cv9541PeWnWQgPyN3mqAOk7MgOiKoe9CmxW3QLG6D9VZ64mggw13Z0sJUdiPhAo2y5hfeyi935cvOY7sf7efzP8+vT49Pr89/dvNd4Itb2ZcPZOXu52kJs9RFdU6uaVO6ug6PZNUaTetG0XOluFteeRvtKjxcWL2aZmJ/CTHH3JW7mwBfZzzfOer3gx8O2GZfVFm5V71E+3i1qeihorpGWwoe280rt7CRZVxsNHcKiJdGk+G+tz7dizTNxrplGJZlGUar2ymRGnX+zJ9n7srL8yAEOaZdX36XfGbutAiCeFOjTB2ziVc0Tkfn202n1pktsVc/MNbbZbnvD/NqEGomUlfL6bKEkU1r4/l5W7nmrih/bwds6v3B7zRZ9pm5jygr8YsJUtUtdMsLYh9YgsEnyV0xtn7dQidsqwVKEaqaFxLIOXfl5fGG0ef78x+yFXBAmbnTHeaqLrz5MnVKx4vkvG6MlkmXKMtdUcpaQtlR0rJ9/jHGeaKX7z/muyj6/mD3nPadoRXk1OHMwr0iLGBJJVeX+AqbOMpGs5vr5K3V0tyV4czWYw3vWz5v++6DHHfGdt83knX59GMwH+wtOqLdYH72+3vat4QqSne13KuU4a1B4MJL5DJVoYS5KPml2l4hM1A9dj8jT7usrVcaaVLu6lu1BQq++hbXbbQNtWw0kfOqWibXFvyC937jpfVy//j1948/t3/+9/z6/S7dC4W8RogyXAVsoGAWmAmo6ryMoCpeIbF67ck5ghcI2ItZhYOVvN9Aur6UMWpv3YYRXnbGkTOtsaMu8+9Zsr/gTZQNW+a/robTao8kw3m9h/N+j2P/Ntpwr3r0lv8tQS0C+02LdxZ6f22jtUcK/Qui1affrrRXoVyIbnHKialT6K20EBSUKvQpBVHat6zYWigPglWZt6zMXSgHquL3D1wWentRq+7tX6pW6D0FlU3YFW0KfU6tC6vuXxR0d+ldxoU+iejrByQS0wt9IvXoywLe+zoKvamqK24V4kKfR8bWX24dLuG9XpxCRoU+ibrIXrZ7w6pRbbXP6VaGDBlahT6ItpqKTaQ2S0335dzo7d6xU+i9ZLivGfKyz81r8VmFPrq67nYWV/a2yFH7B7SyQwnoGM0K7P+Chlcq8vYeaEgtPLh/Rr32CvYOmJNx0dn/LVVbvVaRT1eokIz+DwTRNphnDsEpAAAAAElFTkSuQmCC)"},{"metadata":{},"cell_type":"markdown","source":"<a id=\"16\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Directory Settings<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\n\nMODEL_DIR = '../input/ranzcr-resnext50-32x4d-starter-training/'\nOUTPUT_DIR = './'\nif not os.path.exists(OUTPUT_DIR):\n    os.makedirs(OUTPUT_DIR)\n\nTEST_PATH = '../input/ranzcr-clip-catheter-line-classification/test'","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"17\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Context-Free Grammar (CFG)<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"class CFG:\n    debug=False\n    num_workers=4\n    model_name='resnext50_32x4d'\n    size=600\n    batch_size=64\n    seed=42\n    target_size=11\n    target_cols=['ETT - Abnormal', \n                 'ETT - Borderline', \n                 'ETT - Normal',\n                 'NGT - Abnormal',\n                 'NGT - Borderline', \n                 'NGT - Incompletely Imaged',\n                 'NGT - Normal', \n                 'CVC - Abnormal', \n                 'CVC - Borderline',\n                 'CVC - Normal',\n                 'Swan Ganz Catheter Present']\n    n_fold=4\n    trn_fold=[0, 1, 2, 3]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"18\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Library Using on The Datasets<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"import sys\n\nsys.path.append('../input/pytorch-image-models/pytorch-image-models-master')\n\nimport math\nimport time\nimport random\nimport shutil\nfrom pathlib import Path\nfrom contextlib import contextmanager\nfrom collections import (defaultdict,\n                         Counter)\n\nimport scipy as sp\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport matplotlib.pyplot as plt\n\nfrom sklearn import preprocessing\nfrom sklearn.metrics import roc_auc_score\nfrom sklearn.model_selection import (StratifiedKFold, \n                                     GroupKFold, \n                                     KFold)\n\nfrom tqdm.auto import tqdm\nfrom functools import partial\n\nfrom PIL import Image\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.optim import Adam, SGD\nimport torchvision.models as models\nfrom torch.nn.parameter import Parameter\nfrom torch.utils.data import (DataLoader,\n                              Dataset)\nfrom torch.optim.lr_scheduler import (CosineAnnealingWarmRestarts, \n                                      CosineAnnealingLR,\n                                      ReduceLROnPlateau)\n\nfrom albumentations import (Compose,\n                            OneOf,\n                            Normalize,\n                            Resize,\n                            RandomResizedCrop,\n                            RandomCrop,\n                            HorizontalFlip,\n                            VerticalFlip, \n                            RandomBrightness,\n                            RandomContrast,\n                            RandomBrightnessContrast,\n                            Rotate,\n                            ShiftScaleRotate,\n                            Cutout,\n                            IAAAdditiveGaussianNoise,\n                            Transpose)\n\nfrom albumentations.pytorch import ToTensorV2\nfrom albumentations import ImageOnlyTransform\n\n# import timm\n\nfrom torch.cuda.amp import (autocast, \n                            GradScaler)\n\nimport warnings \nwarnings.filterwarnings('ignore')\n\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"19\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Utils<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_score(y_true, y_pred):\n    scores = []\n    for i in range(y_true.shape[1]):\n        score = roc_auc_score(y_true[:,i], y_pred[:,i])\n        scores.append(score)\n    avg_score = np.mean(scores)\n    return avg_score, scores\n\n\ndef get_result(result_df):\n    preds = result_df[[f'pred_{c}' for c in CFG.target_cols]].values\n    labels = result_df[CFG.target_cols].values\n    score, scores = get_score(labels, preds)\n    LOGGER.info(f'Score: {score:<.4f}  Scores: {np.round(scores, decimals=4)}')\n\n\n@contextmanager\ndef timer(name):\n    t0 = time.time()\n    LOGGER.info(f'[{name}] start')\n    yield\n    LOGGER.info(f'[{name}] done in {time.time() - t0:.0f} s.')\n\n\ndef init_logger(log_file=OUTPUT_DIR+'inference.log'):\n    from logging import getLogger, INFO, FileHandler,  Formatter,  StreamHandler\n    logger = getLogger(__name__)\n    logger.setLevel(INFO)\n    handler1 = StreamHandler()\n    handler1.setFormatter(Formatter(\"%(message)s\"))\n    handler2 = FileHandler(filename=log_file)\n    handler2.setFormatter(Formatter(\"%(message)s\"))\n    logger.addHandler(handler1)\n    logger.addHandler(handler2)\n    return logger\n\nLOGGER = init_logger()\n\n\ndef seed_torch(seed=42):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n\nseed_torch(seed=CFG.seed)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"20\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Data Loading<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"train = pd.read_csv('../input/ranzcr-clip-catheter-line-classification/train.csv')\nfolds = train.copy()\nFold = GroupKFold(n_splits=CFG.n_fold)\ngroups = folds['PatientID'].values\nfor n, (train_index, val_index) in enumerate(Fold.split(folds, folds[CFG.target_cols], groups)):\n    folds.loc[val_index, 'fold'] = int(n)\nfolds['fold'] = folds['fold'].astype(int)\ndisplay(folds.groupby('fold').size())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"oof_df = pd.DataFrame()\nfor fold in CFG.trn_fold:\n    valid_folds = folds[folds['fold']==fold].reset_index(drop=True)\n    check_point = torch.load(MODEL_DIR+f'{CFG.model_name}_fold{fold}_best.pth', map_location=device)\n    for c in [f'pred_{c}' for c in CFG.target_cols]:\n        valid_folds[c] = np.nan\n    valid_folds[[f'pred_{c}' for c in CFG.target_cols]] = check_point['preds']\n    LOGGER.info(f\"========== fold: {fold} result ==========\")\n    get_result(valid_folds)\n    oof_df = pd.concat([oof_df, valid_folds])\noof_df = oof_df.reset_index(drop=True)\nLOGGER.info(f\"========== CV ==========\")\nget_result(oof_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test = pd.read_csv('../input/ranzcr-clip-catheter-line-classification/sample_submission.csv')\nprint(test.shape)\ntest.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test.isnull()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test.isnull().sum()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def testing():\n    if CFG.debug:\n        test = test.head()\n    else:\n        return ':)'\n    \ntesting()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"21\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Dataset<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"class TestDataset(Dataset):\n    def __init__(self, df, transform=None):\n        self.df = df\n        self.file_names = df['StudyInstanceUID'].values\n        self.transform = transform\n        \n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        file_name = self.file_names[idx]\n        file_path = f'{TEST_PATH}/{file_name}.jpg'\n        image = cv2.imread(file_path)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        if self.transform:\n            augmented = self.transform(image=image)\n            image = augmented['image']\n        return image\n\ntrain_dataset = TestDataset(test, transform=None)\n\nfor i in range(5):\n    image = train_dataset[i]\n    plt.imshow(image)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"22\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Transforms<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_transforms(*, data):\n    \n    if data == 'train':\n        return Compose([\n            Resize(CFG.size, CFG.size),\n            Normalize(\n                mean=[0.485, 0.456, 0.406],\n                std=[0.229, 0.224, 0.225],\n            ),\n            ToTensorV2(),\n        ])\n\n    elif data == 'valid':\n        return Compose([\n            Resize(CFG.size, CFG.size),\n            Normalize(\n                mean=[0.485, 0.456, 0.406],\n                std=[0.229, 0.224, 0.225],\n            ),\n            ToTensorV2(),\n        ])\n    \ntrain_dataset = TestDataset(test, transform=get_transforms(data='valid'))\n\nfor i in range(5):\n    image = train_dataset[i]\n    plt.imshow(image[0])\n    plt.show() ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"23\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>MODEL<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"class CustomResNext(nn.Module):\n    def __init__(self, model_name='resnext50_32x4d', pretrained=False):\n        super().__init__()\n        self.model = timm.create_model(model_name, pretrained=pretrained)\n        n_features = self.model.fc.in_features\n        self.model.fc = nn.Linear(n_features, CFG.target_size)\n\n    def forward(self, x):\n        x = self.model(x)\n        return x","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"24\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Helper Function<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"def inference(model, states, test_loader, device):\n    model.to(device)\n    tk0 = tqdm(enumerate(test_loader), total=len(test_loader))\n    probs = []\n    for i, (images) in tk0:\n        images = images.to(device)\n        avg_preds = []\n        for state in states:\n            model.load_state_dict(state['model'])\n            model.eval()\n            with torch.no_grad():\n                y_preds = model(images)\n            avg_preds.append(y_preds.sigmoid().to('cpu').numpy())\n        avg_preds = np.mean(avg_preds, axis=0)\n        probs.append(avg_preds)\n    probs = np.concatenate(probs)\n    return probs","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id=\"25\"></a>\n<h2 style='background:#FFCD46; border:0; color:white'><center>Result<center><h2>"},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install timm","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import timm\n\nmodel = CustomResNext(CFG.model_name, pretrained=False)\nstates = [torch.load(MODEL_DIR+f'{CFG.model_name}_fold{fold}_best.pth') for fold in CFG.trn_fold]\ntest_dataset = TestDataset(test, transform=get_transforms(data='valid'))\ntest_loader = DataLoader(test_dataset, batch_size=CFG.batch_size, shuffle=False, \n                         num_workers=CFG.num_workers, pin_memory=True)\npredictions = inference(model, states, test_loader, device)\n# submission\ntest[CFG.target_cols] = predictions\ntest[['StudyInstanceUID'] + CFG.target_cols].to_csv(OUTPUT_DIR+'submission.csv', index=False)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}