{"cells":[{"metadata":{},"cell_type":"markdown","source":"## Fastai end to end\n\n\nBased on notebook at : https://www.kaggle.com/tanlikesmath/rcic-fastai-starter","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# You can write up to 5GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import os\nos.environ['CUDA_LAUNCH_BLOCKING'] = '1'\n\n\nfrom fastai.vision import *\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# deterministic, are we ?\ndef seed_everything(seed):\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 = 42\nseed_everything(SEED)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Loading and formatting data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('../input/recursion-cellular-image-classification/train.csv')\ntrain_df.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def generate_df(train_df,sample_num=1):\n    train_df['path'] = train_df['experiment'].str.cat(train_df['plate'].astype(str).str.cat(train_df['well'],sep='/'),sep='/Plate') + '_s'+str(sample_num) + '_w'\n    train_df = train_df.drop(columns=['id_code','experiment','plate','well']).reindex(columns=['path','sirna'])\n    return train_df\nproc_train_df = generate_df(train_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"proc_train_df.head(10)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Looking at an example image","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2\nimg = cv2.imread(\"../input/recursion-cellular-image-classification/train/HEPG2-01/Plate1/B02_s1_w1.png\")\nplt.imshow(img)\ngray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)\nplt.imshow(gray_img)\ngray_img.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Defining a new ImageList class redifining the loading function","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"\ndef open_rcic_image(fn):\n    images = []\n    for i in range(6):\n        file_name = fn+str(i+1)+'.png'\n        im = cv2.imread(file_name)\n        im = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY)\n        images.append(im)\n    image = np.dstack(images)\n    #print(pil2tensor(image, np.float32).shape)#.div_(255).shape)\n    return Image(pil2tensor(image, np.float32).div_(255))\n  \nclass MultiChannelImageList(ImageList):\n    def open(self, fn):\n        return open_rcic_image(fn)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"il = MultiChannelImageList.from_df(df=proc_train_df, path=\"../input/recursion-cellular-image-classification/train/\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def image2np(image:Tensor)->np.ndarray:\n    \"Convert from torch style `image` to numpy/matplotlib style.\"\n    res = image.cpu().permute(1,2,0).numpy()\n    if res.shape[2]==1:\n        return res[...,0]  \n    elif res.shape[2]>3:\n        #print(res.shape)\n        #print(res[...,:3].shape)\n        return res[...,:3]\n    else:\n        return res\n\nvision.image.image2np = image2np","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"il[0]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Creating databunch","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# creating a stratified split of data and getting the indices\nfrom sklearn.model_selection import StratifiedKFold\n#train_idx, val_idx = next(iter(StratifiedKFold(n_splits=int(1/0.035),random_state=42).split(proc_train_df, proc_train_df.sirna)))\nfrom sklearn.model_selection import train_test_split\ntrain_df,val_df = train_test_split(proc_train_df,test_size=0.035, stratify = proc_train_df.sirna, random_state=42)\n_proc_train_df = pd.concat([train_df,val_df])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# creating databunch\ndata = (MultiChannelImageList.from_df(df=_proc_train_df,path='../input/recursion-cellular-image-classification/train')\n        .split_by_idx(list(range(len(train_df),len(_proc_train_df))))\n        .label_from_df()\n        .transform(get_transforms(),size=256)\n        .databunch(bs=128,num_workers=4)\n        .normalize()\n       )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data.show_batch()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Creating and training a model\n\nwe use a pretrained EfficeintNet","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install efficientnet_pytorch\n#!pip install cv2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from efficientnet_pytorch import *","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torchvision\nRESNET_MODELS = {\n    18: torchvision.models.resnet18,\n    34: torchvision.models.resnet34,\n    50: torchvision.models.resnet50,\n    101: torchvision.models.resnet101,\n    \n    152: torchvision.models.resnet152,\n}\n\ndef resnet_multichannel(depth=50,pretrained=True,num_classes=1108,num_channels=6):\n        model = RESNET_MODELS[depth](pretrained=pretrained)\n        w = model.conv1.weight\n        model.conv1 = nn.Conv2d(num_channels, 64, kernel_size=7, stride=2, padding=3,\n                               bias=False)\n        model.conv1.weight = nn.Parameter(torch.stack([torch.mean(w, 1)]*num_channels, dim=1))\n        return model\n\n    \nDENSENET_MODELS = {\n    121: torchvision.models.densenet121,\n    161: torchvision.models.densenet161,\n    169: torchvision.models.densenet169,\n    201: torchvision.models.densenet201,\n}\n\ndef densenet_multichannel(depth=121,pretrained=True,num_classes=1108,num_channels=6):\n        model = DENSENET_MODELS[depth](pretrained=pretrained)\n        w = model.features.conv0.weight\n        model.features.conv0 = nn.Conv2d(num_channels, 64, kernel_size=7, stride=2, padding=3,\n                               bias=False)\n        model.features.conv0.weight = nn.Parameter(torch.stack([torch.mean(w, 1)]*num_channels, dim=1))\n        return model\n        \n        \n#EFFICIENTNET_MODELS = {\n#    'b0': '../input/efficientnet-pytorch/efficientnet-b0-08094119.pth',\n#    'b1': '../input/efficientnet-pytorch/efficientnet-b1-dbc7070a.pth',\n#    'b2': '../input/efficientnet-pytorch/efficientnet-b2-27687264.pth',\n#    'b3': '../input/efficientnet-pytorch/efficientnet-b3-c8376fa2.pth',\n#    'b4': '../input/efficientnet-pytorch/efficientnet-b4-e116e8b3.pth',\n#    'b5': '../input/efficientnet-pytorch/efficientnet-b5-586e6cc6.pth'\n#}\n\n\ndef efficientnet_multichannel(pretrained=True,name='b0',num_classes=1108,num_channels=6,image_size=256):\n    model = EfficientNet.from_pretrained('efficientnet-'+name,num_classes=num_classes)\n    #model.load_state_dict(torch.load(EFFICIENTNET_MODELS[name]))\n    w = model._conv_stem.weight\n    #s = model._conv_stem.static_padding\n    model._conv_stem = utils.Conv2dStaticSamePadding(num_channels,32,kernel_size=(3, 3), stride=(2, 2), bias=False, image_size = image_size)\n    model._conv_stem.weight = nn.Parameter(torch.stack([torch.mean(w, 1)]*num_channels, dim=1))\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def resnet1(pretrained, num_channels=6):\n    return resnet_multichannel(depth=18, pretrained=pretrained, num_channels=num_channels)\ndef _resnet_split(m):\n    return (m[0][6], m[1])\n\ndef densenet161(pretrained, num_channels=6):\n    return densenet_multichannel(depth=161, pretrained=pretrained, num_channels=num_channels)\ndef _densenet_split(m:nn.Module):\n    return (m[0][0][7], m[1])\n\ndef efficientnetb0(pretrained=True, num_channels=6):\n    return efficientnet_multichannel(pretrained=pretrained, name='b0', num_channels=num_channels)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Creating the learner","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from fastai.metrics import *\nlearn = Learner(data, efficientnetb0(), metrics=[accuracy]).to_fp16()\nlearn.path = Path('../')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Let us unfreexe and train the entire model\nlearn.unfreeze()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.fit_one_cycle(5, 1e-3)]\n\n# this error comes ecause the data is not loading correctly\n# need to find out more out it","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.recorder.plot_losses()\nlearn.recorder.plot_metrics()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.save('stage-2')\nlearn.export()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### making submission","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.read_csv(\"../input/recursion-cellular-image-classification/test\")\nproc_test_df = generate_df(test_df.copy())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_test = MultiChannelImageList.from_df(df=proc_test_df, path='../input/recursion-cellular-image-classification/test')\nlearn.data.add_test(data_test)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### getting predictions","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"preds, _ = learn.get_preds(DatasetType.Test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds_ = preds.argmax(dim=-1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df = pd.read_csv('../input/recursion-cellular-image-classification/submission.csv')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df.sirna = preds_.numpy().astype(int)\nsubmission_df.head(10)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df.to_csv('submission.csv', index=False)","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}