{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"pre_path = '../input/pytorch-image-models/pytorch-image-models-master'\n\nimport sys; sys.path.append(pre_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# at the top of the file, before other imports\nimport warnings\n\nwarnings.filterwarnings('ignore')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns;# sns.set()\n\nfrom tqdm import tqdm\n\nimport cv2\n\nfrom glob import glob","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('../input/recursion-cellular-image-classification/train.csv')\ntrain_control = pd.read_csv('../input/recursion-cellular-image-classification/train_controls.csv')\n\ntest_df = pd.read_csv('../input/recursion-cellular-image-classification/test.csv')\ntest_control = pd.read_csv('../input/recursion-cellular-image-classification/test_controls.csv')\n\nsub = pd.read_csv('../input/recursion-cellular-image-classification/sample_submission.csv')\npix = pd.read_csv('../input/recursion-cellular-image-classification/pixel_stats.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df['category'] = train_df['experiment'].apply(lambda x: x.split('-')[0])\ntrain_df['branch'] = train_df['experiment'].apply(lambda x: x.split('-')[1])\n\ntest_df['category'] = test_df['experiment'].apply(lambda x: x.split('-')[0])\ntest_df['branch'] = test_df['experiment'].apply(lambda x: x.split('-')[1])\n\n\ntrain_df['sirna'] = train_df['sirna'].apply(lambda x: x.split('_')[1]).astype('int')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# work on 2 train sites\nsite1 = train_df[['id_code','category', 'sirna']]\nsite2 = train_df[['id_code','category', 'sirna']]\n\nsite1['site'] = site1['id_code'] + '_s1'\nsite2['site'] = site2['id_code'] + '_s2'\n\ntrain = pd.concat([site1, site2], ignore_index=True)\nn_classes = train['sirna'].nunique()\n\nprint(train.shape)\ntrain.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# work on 2 test site\ntest_site1 = test_df[['id_code', 'category']]\ntest_site2 = test_df[['id_code', 'category']]\n\ntest_site1['site'] = test_site1['id_code'] + '_s1'\ntest_site2['site'] = test_site2['id_code'] + '_s2'\n\ntest = pd.concat([test_site1, test_site2], ignore_index=True)\nprint(test_site1.shape)\nprint(test_site2.shape)\n\ntest.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_img(path):\n    im_bgr = cv2.imread(path)\n    im_rgb = im_bgr[:, :, ::-1]\n    return im_rgb","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"i = 150\npath = '../input/recursion-cellular-image-classification-224-jpg/train/train/'\nimpath = path+train['site'][i]+'.jpeg'\n\nimg = get_img(impath)\nplt.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset,DataLoader\nfrom torch.cuda.amp import autocast, GradScaler\n\nimport timm\n\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\n\n\nfrom sklearn.metrics import log_loss\nfrom sklearn.model_selection import StratifiedKFold, train_test_split","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"config = {\n    'num_fold': 5,\n    'epoch': 10,\n    'seed': 42,\n    'img_size': 244,\n    'lr': 1e-3,\n    'weight_decay':1e-5,\n    'batch_size':32,\n    'model_arc': 'tf_efficientnet_b3_ns'   \n}\n\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class RecursionDataset(Dataset):\n    def __init__(self, df, path, labels=True, transform=None):\n        super().__init__()\n        self.df = df\n        self.path = path\n        self.labels = labels\n        self.transform = transform\n        \n        self.targets = df.sirna.values\n        self.site = df.site.values\n        self.cat = df.category.values\n        \n    def __len__(self):\n        return self.df.shape[0]\n    \n    def __getitem__(self, idx):\n        category = self.cat[idx]\n        img_path = self.path + self.site[idx] + '.jpeg'\n        \n        #print(img_path)\n        image = get_img(img_path)\n        \n        if self.transform != None:\n            image = self.transform(image=image)['image']\n            \n        \n        if self.labels:\n            target = self.targets[idx]\n            data = (image, target)\n        else:\n            data = (image)\n        \n        \n        return data\n\ndef get_train_transforms():\n    return A.Compose([\n            A.RandomResizedCrop(config['img_size'], config['img_size']),\n            A.Transpose(p=0.5),\n            A.HorizontalFlip(p=0.5),\n            A.VerticalFlip(p=0.5),\n            A.ShiftScaleRotate(p=0.5),\n            A.HueSaturationValue(hue_shift_limit=0.2, sat_shift_limit=0.2, val_shift_limit=0.2, p=0.5),\n            A.RandomBrightnessContrast(brightness_limit=(-0.1,0.1), contrast_limit=(-0.1, 0.1), p=0.5),\n            A.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], max_pixel_value=255.0, p=1.0),\n            A.CoarseDropout(p=0.5),\n            A.Cutout(p=0.5),\n            ToTensorV2(p=1.0),\n        ], p=1.)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"trn_idx, val_idx = train_test_split(train.index, test_size=0.2, random_state=config['seed'])\ntrain_set, valid_set = RecursionDataset(train.iloc[trn_idx], path, True, transform=get_train_transforms()), RecursionDataset(train.iloc[val_idx], path, True, transform=get_train_transforms())\n\nsite1set = RecursionDataset(site1, path, True, transform=get_train_transforms())\nsite2set = RecursionDataset(site2, path, True, transform=get_train_transforms())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_loader = DataLoader(train_set, batch_size=config['batch_size'], shuffle=True, num_workers=2)\nvalid_loader = DataLoader(valid_set, batch_size=config['batch_size'], shuffle=False, num_workers=2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class RecursionModel(nn.Module):\n    def __init__(self, model_arc, pretrained=False, n_class=n_classes):\n        super().__init__()\n        self.backbone = timm.create_model(model_arc, pretrained)\n        n_features = self.backbone.classifier.in_features\n        \n        self.backbone.classifier = nn.Sequential(\n            nn.Dropout(0.25),\n            nn.Linear(n_features, n_class)\n        )\n        \n    def forward(self, x):\n        return self.backbone(x)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def train_loop(epoch, loader, model, loss_fn, opt, scheduler=None, device=device):\n    model.train()\n    \n    running_loss = None\n    pbar = tqdm(enumerate(loader), len(loader))\n    \n    for i, (image, label) in pbar:\n        image, label = image.to(device).float(), label.to(device).long()\n        \n        opt.zero_grad()\n        y_pred = model(image)\n        loss = loss_fn(y_pred, label)\n        loss.backward()\n        \n        if running_loss is None:\n            running_loss = loss.item()\n        else:\n            running_loss = running_loss * .9 + loss.item() * .1\n        \n        opt.step()\n        scheduler.step()\n        \n        if (i+1) % 2 == 0 or (i+1) == len(loader):\n            description = f'epoch {epoch}, loss: {running_loss:.4f}'\n            pbar.set_description(description)\n\ndef valid_loop(epoch, val_loader, model, loss_fn, scheduler=None, device=device):\n    model.eval()\n    \n    pbar = tqdm(enumerate(val_loader), total=len(val_loader))\n    \n    for step, (imgs, image_labels) in pbar:\n        imgs = imgs.to(device).float()\n        image_labels = image_labels.to(device).long()\n        \n        image_preds = model(imgs)\n        image_preds_all += [torch.argmax(image_preds, 1).detach().cpu().numpy()]\n        image_targets_all += [image_labels.detach().cpu().numpy()]\n        \n        loss = loss_fn(image_preds, image_labels)\n        \n        loss_sum += loss.item()*image_labels.shape[0]\n        sample_num += image_labels.shape[0]  \n\n        if ((step + 1) % 2 == 0) or ((step + 1) == len(val_loader)):\n            description = f'epoch {epoch} loss: {loss_sum/sample_num:.4f}'\n            pbar.set_description(description)\n    \n    image_preds_all = np.concatenate(image_preds_all)\n    image_targets_all = np.concatenate(image_targets_all)\n    valid_acc = (image_preds_all==image_targets_all).mean()\n    print('validation multi-class accuracy = {:.4f}'.format(valid_acc))\n    \n    scheduler.step()\n            \n    return valid_acc","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Code still under modification, stay tuned."},{"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}