{"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":"https://www.kaggle.com/rdizzl3/hpa-segmentation-masks-no-internet (No Internet Segmentation RDizzl3)\n","metadata":{}},{"cell_type":"code","source":"# !pip install \"../input/hpacellsegmentatormaster/HPA-Cell-Segmentation-master\"\n\n# segmentation tool\n# import hpacellseg.cellsegmentator as cellsegmentator\n# from hpacellseg.utils import label_cell, label_nuclei\n!pip install optuna\n!pip install plotly==4.14.3","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nfrom PIL import Image\nimport matplotlib.pyplot as plt\nfrom tqdm.notebook import tqdm\nimport glob\nimport math\nimport random\nimport cv2\n\n%matplotlib inline","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"DATA SETUP","metadata":{}},{"cell_type":"code","source":"'''HELPER FUNCTIONS'''\n\ndef grabMask(id):\n    return np.load(f'{cellMaskPath}/{id}.npz')['arr_0']\n\ndef grabImageLayers(id):\n    colors = ['red','green','blue']\n    img = [np.asarray(Image.open(os.path.join(trainingImageFolder, id+f\"_{c}.png\")), np.uint8) for c in colors]\n    return np.stack(img, axis=-1)\n    \ndef grabLabels(id):\n    data = train_df.loc[train_df['ID'] == id] \n    info = list(data['Label'])\n    info = info[0].split('|')\n    return [int(i) for i in info]\n\ndef showSituation(id, figsize=(20,6)):\n    mask = grabMask(id)\n    im = grabImageLayers(id)\n    lables = grabLabels(id)\n    \n    plt.figure(figsize=figsize)\n    plt.suptitle(f\"Image {id}'s Visual Information\", fontsize=22, fontweight=\"bold\")\n    \n    titles = [\"Red Channel – Microtubles\", \"Green Channel – Protein of Interest\", \"Blue - Nucleus\", \"Yellow – Endoplasmic Reticulum\", \"Mask\"]\n    \n    for i, c in enumerate(titles):\n        ch_arr = np.zeros_like(im[..., :-1])   \n        plt.subplot(1,5,i+1)\n        plt.title(f\"{c.title()}\", fontweight=\"bold\")\n        if c == 'Mask':\n            plt.imshow(mask)\n        else:\n            if c in [\"Red Channel – Microtubles\", \"Green Channel – Protein of Interest\", \"Blue - Nucleus\"]:\n                ch_arr[..., i] = im[..., i]\n            else:\n                ch_arr[..., 0] = im[..., i]\n                ch_arr[..., 1] = im[..., i]\n            plt.imshow(ch_arr)\n        plt.axis(False)\n    \n    plt.tight_layout(rect=[0, 0.2, 1, 0.97])\n    plt.show()\n    \ndef extract_bboxes(mask):\n    \"\"\"\n    https://discuss.pytorch.org/t/extracting-bounding-box-coordinates-from-mask/61179/3 (Qing_En)\n    Compute bounding boxes from masks.\n    mask: [height, width ]. Mask pixels are either 1 or 0.\n    Returns: bbox array [(y1, x1, y2, x2)].\n    \"\"\"\n    boxes = np.zeros([1, 4], dtype=np.int32)\n    m = mask[:, :]\n    # Bounding box.\n    horizontal_indicies = np.where(np.any(m, axis=0))[0]\n    vertical_indicies = np.where(np.any(m, axis=1))[0]\n    if horizontal_indicies.shape[0]:\n        x1, x2 = horizontal_indicies[[0, -1]]\n        y1, y2 = vertical_indicies[[0, -1]]\n        # x2 and y2 should not be part of the box. Increment by 1.\n        x2 += 1\n        y2 += 1\n    m = []\n    boxes = []\n    return np.array([y1, x1, y2, x2])\n    \ndef splitMasks(id, TOP, LABEL=None):\n    myImg = grabImageLayers(id)\n    myMask = np.array(grabMask(id))\n    layers =np.unique(myMask)\n    # print(id ,len(layers))\n    myMask = (myMask[np.newaxis] == layers[:, np.newaxis, np.newaxis, np.newaxis])\n    if len(myMask) > (TOP + 1):\n        extra = len(myMask) - (TOP + 1)\n    else:\n        extra = 0    \n    myMask = myMask[1:TOP + 1]\n    for i in range(len(myMask)):\n        myMask[i] = myMask[i][0]\n    output = []\n    for i in range(len(myMask)):   \n        mask = myMask[0][0]\n        bbox = extract_bboxes(mask)\n        y1, x1, y2, x2 = bbox\n        data = np.where(mask[...,None]==True, myImg,[0,0,0])\n        data = data[y1:y2, x1:x2]\n        myMask = myMask[1:]\n        if LABEL != None:\n            output.append([data, LABEL])\n        else:\n            output.append(data)\n        data = []\n    return output, extra\n\ndef idStrip(label):\n    if label > 17:\n        print('Nonexistant')\n        return []\n    df = train_df.loc[train_df[str(label)] == 1]\n    print('Total Labels: ', len(df))\n    return [id for id in df.ID.values]\n\ndef otherId(label, length):\n    if label > 17:\n        print('Nonexistant')\n        return []\n    df = train_df.loc[train_df[str(label)] != 1]\n    print('Total Other Labels: ', len(df))\n    data = [id for id in df.ID.values]\n    return data[:length]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataFolderPath = \"/kaggle/input/hpa-single-cell-image-classification/\"\ncellMaskPath = '../input/hpa-mask/hpa_cell_mask'   \ntrainingImageFolder = dataFolderPath + 'train/'\ntrain_df = pd.read_csv('../input/hpa-better-training-csv/betterTrain.csv')\ntrain_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"https://www.kaggle.com/dschettler8845/starter-on-how-to-load-rle-masks (Helper Function Help dschettler8845)","metadata":{}},{"cell_type":"markdown","source":"Sampling Dataset Size Crop Size","metadata":{}},{"cell_type":"code","source":"import time\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader\ntorch.cuda.empty_cache()\n\nif torch.cuda.is_available():\n    device = torch.device(\"cuda:0\") \n    print(\"Running on the GPU\")\nelse:\n    device = torch.device(\"cpu\")\n    print(\"Running on the CPU\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Setting up DataLoader","metadata":{}},{"cell_type":"code","source":"RESIZE_PIXEL = 500\nBATCH_SIZE = 10\nEPOCHS = 15","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def createData(label, testpct):\n    idList = idStrip(label)\n    otherList = otherId(label, len(idList))\n    \n    idList = [[id, 1] for id in idList]\n    otherList = [[id, 0] for id in otherList]\n    \n    val_size = int(len(idList)*testpct)\n    \n    train_X = idList[:-val_size]\n    train_y = otherList[:-val_size]\n\n    test_X = idList[-val_size:]\n    test_y = otherList[-val_size:]\n    \n    train = []\n    test = []\n    for i in range(len(train_X)):\n        train.append([train_X[i],train_y[i]])\n        if i < len(test_X):\n            test.append([test_X[i],test_y[i]])\n        \n    return train, test\n\ndef dataParser(data):\n    id = data[0][0] # id\n    label = data[0][1] #label\n    oid = data[1][0]\n    olabel = data[1][1]\n    \n    return id, label, oid, olabel\n\ndef createImageLoader(id, label, oid, olabel):\n    mask1, _ = splitMasks(id, BATCH_SIZE, LABEL=label)\n    mask2, _ = splitMasks(oid, BATCH_SIZE, LABEL=olabel)\n    minSize = min(len(mask1), len(mask2), BATCH_SIZE)\n    loader = mask1[:minSize] + mask2[:minSize]\n    np.random.shuffle(loader)\n    return loader\n\ndef createXy(testSet):\n    # [ [[id, label], [id,label]], [[id, label], [id,label]],... ]\n    id, label, oid, olabel = dataParser(testSet)\n    loader = createImageLoader(id, label, oid, olabel)\n    X = []\n    y = []\n    for data in loader:\n        array = np.array(data[0], dtype='uint8')\n        X.append(cv2.resize(array, (RESIZE_PIXEL, RESIZE_PIXEL)))\n        y.append(data[1])\n    X = torch.tensor(X).type(torch.FloatTensor)\n    y = torch.tensor(y).type(torch.FloatTensor)\n    return X,y","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainSet, testSet = createData(2, 0.05)\nprint(len(trainSet), len(testSet))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torchvision.models as models","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_checkpoint(filepath):\n    checkpoint = torch.load(filepath)\n    model = checkpoint['model']\n    num_ftrs = model.fc.in_features\n    model.fc = nn.Linear(num_ftrs, 2)\n    model.load_state_dict(checkpoint['state_dict'])\n    for parameter in model.parameters():\n        parameter.requires_grad = False\n    \n    model.eval()\n    \n    return model\n\nnet = load_checkpoint('../input/currentdata/checkpoint.pth').to(device)\nprint(net)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# net = models.resnext50_32x4d(pretrained=True)\n\n# num_ftrs = net.fc.in_features\n\n# net.fc = nn.Linear(num_ftrs, 2)\n\n# net.to(device)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch.optim as optim\n\noptimizer = optim.Adam(net.parameters(), lr=0.002981312675935298) \nloss_function = nn.MSELoss() ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def fwd_pass(X, y, train=False):\n\n    if train:\n        optimizer.zero_grad()\n        net.train()\n    else:\n        torch.no_grad()\n        net.eval()\n  \n    outputs = net(X)\n    \n    matches  = [torch.argmax(i) == j for i, j in zip(outputs, y)]\n#     print(matches)\n    acc = matches.count(True)/len(matches)\n    outputs = torch.Tensor([torch.argmax(i) for i in outputs]).to(device)\n#     print(outputs[0])\n#     print(outputs.shape, y.shape)\n    loss = loss_function(outputs, y)\n    \n    if train:\n        loss = loss.clone().detach().requires_grad_(True).to(device)\n        loss.backward()\n        optimizer.step()\n\n    return acc, loss","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def test(limit):\n    runningLoss = 0\n    runningAcc = 0\n    count = 0\n    rand = random.randint(0,len(testSet) - limit - 1)\n    print(f\"Testing: Random Int {rand}\")\n    for i in range(limit):\n        X, y = createXy(testSet[rand+i])\n        X = X.view(-1, 3, RESIZE_PIXEL, RESIZE_PIXEL)\n        val_acc, val_loss = fwd_pass(X.to(device), y.to(device))\n        count += 1\n        runningLoss += val_loss\n        runningAcc += val_acc\n#         print(runningAcc,count, runningLoss/count)\n    return runningAcc/count, runningLoss/count\n\nval_acc, val_loss = test(1)\nprint(val_acc, val_loss)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import time\n\nMODEL_NAME = f\"model-{int(time.time())}\"\n\nprint(MODEL_NAME)\n\ndef train(net, total):\n    count = 0\n    with open(\"model.log\", \"a\") as f:\n        for epoch in tqdm(range(EPOCHS), desc=\"Epochs Progress\"):\n            for i in tqdm(range(total), desc=\"Training Batch Progress\"):\n                count += 1\n                print(trainSet[i])\n                X, y = createXy(trainSet[i])\n                X = X.view(-1, 3, RESIZE_PIXEL, RESIZE_PIXEL) \n               \n                acc, loss = fwd_pass(X.to(device), y.to(device), train=True)\n                if i == 0 or count % 5 == 0:\n                    print(acc, loss)\n                    val_acc, val_loss = test(10)\n                    print(f\"Val Acc: {round(float(val_acc),4)}; Val Loss: {round(float(val_loss),4)}\")\n                    f.write(f\"{MODEL_NAME},{round(time.time(),2)},{round(float(acc),4)},{round(float(loss),4)},{round(float(val_acc),4)},{round(float(val_loss),4)}\\n\")\n\ntrain(net, 30)  ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"checkpoint = {'model': models.resnext50_32x4d(),\n              'state_dict': net.state_dict(),\n              'optimizer' : optimizer.state_dict()}\n\ntorch.save(checkpoint, 'checkpoint.pth')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}