{"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":"This is the inference notebook for a simple `tez` starter - training notebook can be found here: https://www.kaggle.com/code/konradb/tez-train\n\n","metadata":{}},{"cell_type":"code","source":"import sys\nsys.path.append(\"../input/tez-lib/\")\nsys.path.append(\"../input/timmmaster/\")","metadata":{"execution":{"iopub.status.busy":"2022-07-26T14:46:41.495724Z","iopub.execute_input":"2022-07-26T14:46:41.496188Z","iopub.status.idle":"2022-07-26T14:46:41.516824Z","shell.execute_reply.started":"2022-07-26T14:46:41.496102Z","shell.execute_reply":"2022-07-26T14:46:41.515866Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport albumentations as A\nimport pandas as pd\nimport numpy as np\n\nimport gc\nimport cv2\n\nfrom tez import Tez, TezConfig\nfrom tez.callbacks import EarlyStopping\nfrom tez.datasets import ImageDataset\n\nfrom tqdm.notebook import tqdm\nimport torch\nimport torch.nn as nn\nfrom torch.nn import functional as F\n\nfrom sklearn import metrics, model_selection, preprocessing\nimport timm\n\nfrom sklearn.model_selection import KFold\n\n# ignoring warnings\nimport warnings\nwarnings.simplefilter(\"ignore\")\n\nimport os, cv2, json\nfrom PIL import Image\n\nimport random\n\nimport tifffile\n","metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_kg_hide-input":true,"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","papermill":{"duration":4.973774,"end_time":"2022-03-23T17:33:31.007434","exception":false,"start_time":"2022-03-23T17:33:26.03366","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-07-26T14:46:41.51887Z","iopub.execute_input":"2022-07-26T14:46:41.519527Z","iopub.status.idle":"2022-07-26T14:46:47.548257Z","shell.execute_reply.started":"2022-07-26T14:46:41.519492Z","shell.execute_reply":"2022-07-26T14:46:47.547149Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CFG:    \n    # config\n    work_dir = '../input/mayo-clinic-strip-ai/'\n    img_folder = '../input/jpg-images-strip-ai/'\n    batch_size = 16\n    epochs = 10\n    img_size = 256\n    seed = 42\n    target_size = 2\n    model = 'efficientnet_b2' # efficientnetv2_rw_m\n    patience = 2 \n    nfolds = 5\n    model_folder = '../input/tez-train/'","metadata":{"papermill":{"duration":0.022459,"end_time":"2022-03-23T17:33:31.044561","exception":false,"start_time":"2022-03-23T17:33:31.022102","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-07-26T14:46:47.55014Z","iopub.execute_input":"2022-07-26T14:46:47.551169Z","iopub.status.idle":"2022-07-26T14:46:47.557162Z","shell.execute_reply.started":"2022-07-26T14:46:47.551125Z","shell.execute_reply":"2022-07-26T14:46:47.556169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def seed_everything(seed: int = 42) -> None:\n    random.seed(seed)\n    np.random.seed(seed)\n    os.environ[\"PYTHONHASHSEED\"] = str(seed)\n    \nseed_everything(CFG.seed)","metadata":{"papermill":{"duration":0.023903,"end_time":"2022-03-23T17:33:31.082591","exception":false,"start_time":"2022-03-23T17:33:31.058688","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-07-26T14:46:47.560863Z","iopub.execute_input":"2022-07-26T14:46:47.56125Z","iopub.status.idle":"2022-07-26T14:46:47.568507Z","shell.execute_reply.started":"2022-07-26T14:46:47.561215Z","shell.execute_reply":"2022-07-26T14:46:47.566799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Functions","metadata":{"papermill":{"duration":0.016304,"end_time":"2022-03-23T17:33:31.115341","exception":false,"start_time":"2022-03-23T17:33:31.099037","status":"completed"},"tags":[]}},{"cell_type":"code","source":"class SModel(nn.Module):\n    def __init__(self, num_classes):\n        super().__init__()\n        self.model = timm.create_model(CFG.model, pretrained = False, num_classes = 2)\n\n    def monitor_metrics(self, outputs, targets):\n        device = targets.get_device()\n        outputs = torch.argmax(outputs, dim=1).cpu().detach().numpy()\n        targets = targets.cpu().detach().numpy()\n        f1 = metrics.f1_score(targets, outputs, average=\"macro\")\n        accuracy = metrics.accuracy_score(targets, outputs)\n        return {\"acc\": torch.tensor(accuracy, device=device)}\n\n    def optimizer_scheduler(self):\n        opt = torch.optim.Adam(self.parameters(), lr=1e-3)\n        sch = torch.optim.lr_scheduler.ReduceLROnPlateau(\n            opt,\n            factor=0.5,\n            patience=2,\n            verbose=True,\n            mode=\"max\",\n            threshold=1e-4,\n        )\n        return opt, sch\n\n    def forward(self, image, targets=None):\n        outputs = self.model(image)\n        if targets is not None:\n            loss = nn.CrossEntropyLoss()(outputs, targets)\n            metrics = self.monitor_metrics(outputs, targets)\n            return outputs, loss, metrics\n        return outputs, 0, {}","metadata":{"papermill":{"duration":0.030872,"end_time":"2022-03-23T17:33:31.163023","exception":false,"start_time":"2022-03-23T17:33:31.132151","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-07-26T14:46:47.570525Z","iopub.execute_input":"2022-07-26T14:46:47.570866Z","iopub.status.idle":"2022-07-26T14:46:47.58416Z","shell.execute_reply.started":"2022-07-26T14:46:47.57083Z","shell.execute_reply":"2022-07-26T14:46:47.583082Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"aug = A.Compose([\n            A.Normalize(\n                mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225),\n                max_pixel_value=255.0, \n                p=1.0\n            ) ], p=1.)","metadata":{"papermill":{"duration":0.027294,"end_time":"2022-03-23T17:33:31.206732","exception":false,"start_time":"2022-03-23T17:33:31.179438","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-07-26T14:46:47.585727Z","iopub.execute_input":"2022-07-26T14:46:47.586132Z","iopub.status.idle":"2022-07-26T14:46:47.593098Z","shell.execute_reply.started":"2022-07-26T14:46:47.586083Z","shell.execute_reply":"2022-07-26T14:46:47.592047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data\n","metadata":{"papermill":{"duration":0.016306,"end_time":"2022-03-23T17:33:31.239751","exception":false,"start_time":"2022-03-23T17:33:31.223445","status":"completed"},"tags":[]}},{"cell_type":"code","source":"dfx = pd.read_csv('../input/prepare-folds/xfolds.csv')\ndfx['image_id'] = dfx['image_id'] + '.jpg'\ndfx['label'] = (dfx['label'] == 'CE') + 0\ndfx.head(3)","metadata":{"execution":{"iopub.status.busy":"2022-07-26T14:46:47.595122Z","iopub.execute_input":"2022-07-26T14:46:47.595552Z","iopub.status.idle":"2022-07-26T14:46:47.628743Z","shell.execute_reply.started":"2022-07-26T14:46:47.595509Z","shell.execute_reply":"2022-07-26T14:46:47.627946Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = pd.read_csv(\"../input/mayo-clinic-strip-ai/test.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-07-26T14:46:47.630009Z","iopub.execute_input":"2022-07-26T14:46:47.630397Z","iopub.status.idle":"2022-07-26T14:46:47.639844Z","shell.execute_reply.started":"2022-07-26T14:46:47.630359Z","shell.execute_reply":"2022-07-26T14:46:47.638837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df","metadata":{"execution":{"iopub.status.busy":"2022-07-26T14:46:47.641178Z","iopub.execute_input":"2022-07-26T14:46:47.641499Z","iopub.status.idle":"2022-07-26T14:46:47.651715Z","shell.execute_reply.started":"2022-07-26T14:46:47.641467Z","shell.execute_reply":"2022-07-26T14:46:47.650766Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dirs = [\"../input/mayo-clinic-strip-ai/train/\", \"../input/mayo-clinic-strip-ai/test/\"]\n\ntry:\n    os.mkdir(\"../test/\")\nexcept:\n    pass\nfor i in tqdm(range(test_df.shape[0])):\n    img_id = test_df.iloc[i].image_id\n    print(img_id)\n    try:\n        sz = os.path.getsize(dirs[1] + img_id + \".tif\")\n        print(sz)\n    except:\n        sz = 1000000000\n        \n    if(sz > 8e8):\n        img = np.zeros((512,512,3), np.uint8)\n        print('zeros')\n    else:\n        try:\n            img = cv2.resize(tifffile.imread(dirs[1] + img_id + \".tif\"), (512, 512))\n        except:\n            img = np.zeros((512,512,3), np.uint8)\n\n    cv2.imwrite(f\"../test/{img_id}.jpeg\", img)\n    del img\n    gc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-07-26T14:46:47.655401Z","iopub.execute_input":"2022-07-26T14:46:47.656253Z","iopub.status.idle":"2022-07-26T14:47:24.324775Z","shell.execute_reply.started":"2022-07-26T14:46:47.656218Z","shell.execute_reply":"2022-07-26T14:47:24.323809Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_image_paths = ['../test/' + x + '.jpeg' for x in test_df.image_id.values]\n\n# test_targets = test_df.image_num\ntest_dataset = ImageDataset(\n    image_paths=test_image_paths,\n    targets= [0] * len(test_image_paths),\n    augmentations = aug,\n)\n","metadata":{"execution":{"iopub.status.busy":"2022-07-26T14:47:24.326035Z","iopub.execute_input":"2022-07-26T14:47:24.326953Z","iopub.status.idle":"2022-07-26T14:47:24.333588Z","shell.execute_reply.started":"2022-07-26T14:47:24.326917Z","shell.execute_reply":"2022-07-26T14:47:24.332686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls -lh ../test/","metadata":{"execution":{"iopub.status.busy":"2022-07-26T14:47:24.334802Z","iopub.execute_input":"2022-07-26T14:47:24.335819Z","iopub.status.idle":"2022-07-26T14:47:25.011388Z","shell.execute_reply.started":"2022-07-26T14:47:24.335782Z","shell.execute_reply":"2022-07-26T14:47:25.01023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model","metadata":{"papermill":{"duration":0.014681,"end_time":"2022-03-23T17:33:31.361704","exception":false,"start_time":"2022-03-23T17:33:31.347023","status":"completed"},"tags":[]}},{"cell_type":"code","source":"prval = np.zeros((dfx.shape[0], CFG.target_size ))\nprfull = np.zeros(( len(test_image_paths), CFG.target_size))","metadata":{"execution":{"iopub.status.busy":"2022-07-26T14:47:25.013351Z","iopub.execute_input":"2022-07-26T14:47:25.013732Z","iopub.status.idle":"2022-07-26T14:47:25.019231Z","shell.execute_reply.started":"2022-07-26T14:47:25.013688Z","shell.execute_reply":"2022-07-26T14:47:25.018158Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for fold in range(0,CFG.nfolds):\n    \n    # split\n    trn_idx = dfx[dfx['fold'] != fold].index\n    val_idx = dfx[dfx['fold'] == fold].index\n    df_train = dfx.loc[trn_idx].reset_index(drop=True)\n    df_valid = dfx.loc[val_idx].reset_index(drop=True)\n    image_path = CFG.img_folder + 'train/'\n    train_image_paths = [os.path.join(image_path, x) for x in df_train.image_id.values]\n    valid_image_paths = [os.path.join(image_path, x) for x in df_valid.image_id.values]\n    train_targets = df_train.label.values\n    valid_targets = df_valid.label.values\n\n    # prepare datasets\n    train_dataset = ImageDataset(\n        image_paths=train_image_paths, targets=train_targets, \n        augmentations = aug)\n\n    valid_dataset = ImageDataset(\n        image_paths=valid_image_paths, targets=valid_targets,\n        augmentations = aug)\n    \n                \n    # fit model for this fold\n    model = SModel(num_classes = CFG.target_size) \n    model = Tez(model)\n    \n    es = EarlyStopping(\n        monitor=\"valid_acc\",\n        model_path = 'model_f' +str(fold) + '.bin',\n        patience = CFG.patience, mode=\"max\", save_weights_only=True,\n    )\n\n\n    config = TezConfig(\n        training_batch_size=CFG.batch_size, validation_batch_size=CFG.batch_size,\n        epochs=CFG.epochs, step_scheduler_after=\"epoch\",\n        step_scheduler_metric=\"valid_acc\",\n    )\n    \n    model.load(CFG.model_folder + 'model_f' + str(fold) + '.bin',\n               weights_only = True,\n              config = config)\n    \n    print(fold)\n    \n    # valid predictions\n    preds = model.predict(valid_dataset, batch_size=32, n_jobs=-1) #, device=\"cuda\")       \n    temp_preds = None\n    for p in preds:\n        if temp_preds is None:\n            temp_preds = p\n        else:\n            temp_preds = np.vstack((temp_preds, p))                                \n    prval[val_idx,:] = (1/(1 + np.exp(-temp_preds)) )\n        \n    # test predictions \n    preds = model.predict(test_dataset, batch_size = 16, n_jobs=-1)   \n    temp_preds = None\n    for p in preds:\n        if temp_preds is None:\n            temp_preds = p\n        else:\n            temp_preds = np.vstack((temp_preds, p)) \n            \n    temp_preds = (1/(1 + np.exp(-temp_preds)) )  \n    temp_preds /= CFG.nfolds\n    \n    prfull += temp_preds \n    \n\n    print('processed fold: ' + str(fold))\n    print('----------------------------')\n    \n","metadata":{"execution":{"iopub.status.busy":"2022-07-26T14:47:25.021377Z","iopub.execute_input":"2022-07-26T14:47:25.022289Z","iopub.status.idle":"2022-07-26T14:47:50.936807Z","shell.execute_reply.started":"2022-07-26T14:47:25.02225Z","shell.execute_reply":"2022-07-26T14:47:50.935191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# https://www.kaggle.com/code/muki2003/mayo-strip-ai-eda-lossfunction\n    \ndef weighted_mc_log_loss(y_true, y_pred, epsilon = 1e-10):\n    # Clipping the prediction value\n    y_pred_clipped = np.clip(y_pred, epsilon, 1-epsilon)  \n    #true labels weighted by weights and percent elements per class\n    y_true_weighted = (y_true * weights)/class_proportions\n    #multiply tensors element-wise and then sum\n    loss_num = (y_true_weighted * np.log(y_pred_clipped))\n    loss = -1*np.sum(loss_num)/np.sum(weights)\n    \n    return loss","metadata":{"execution":{"iopub.status.busy":"2022-07-26T14:52:01.128926Z","iopub.execute_input":"2022-07-26T14:52:01.129584Z","iopub.status.idle":"2022-07-26T14:52:01.141759Z","shell.execute_reply.started":"2022-07-26T14:52:01.129536Z","shell.execute_reply":"2022-07-26T14:52:01.14087Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import log_loss\n\nn_classes = 2 \nweights = np.ones(n_classes, dtype='float32')  \nclass_counts = dfx.groupby('label')['image_id'].count().values \nclass_proportions = class_counts/np.max(class_counts)\n\n\n# weighted_mc_log_loss(dfx['label'], prval[:,0])\nprint(log_loss(dfx['label'], prval[:,0]))\nprint(log_loss(dfx['label'], prval[:,1]))","metadata":{"execution":{"iopub.status.busy":"2022-07-26T14:52:14.64724Z","iopub.execute_input":"2022-07-26T14:52:14.647628Z","iopub.status.idle":"2022-07-26T14:52:14.661893Z","shell.execute_reply.started":"2022-07-26T14:52:14.647596Z","shell.execute_reply":"2022-07-26T14:52:14.660768Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub_df = pd.read_csv('../input/mayo-clinic-strip-ai/sample_submission.csv')\n\nsub_df['LAA'] = prfull[:,0]\nsub_df['CE'] = prfull[:,1]\n\nsub_df.drop_duplicates(inplace = True)\n\nsub_df.to_csv('submission.csv', index = False)","metadata":{"execution":{"iopub.status.busy":"2022-07-25T08:51:31.353445Z","iopub.execute_input":"2022-07-25T08:51:31.354029Z","iopub.status.idle":"2022-07-25T08:51:31.370338Z","shell.execute_reply.started":"2022-07-25T08:51:31.353992Z","shell.execute_reply":"2022-07-25T08:51:31.369394Z"},"trusted":true},"execution_count":null,"outputs":[]}]}