--- a +++ b/old/covidtesting_notebook.ipynb @@ -0,0 +1,228 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "covidtesting notebook.ipynb", + "provenance": [], + "collapsed_sections": [], + "toc_visible": true, + "mount_file_id": "1LK7pcqyeGafFPUjp_1ld_vAp6ortxV9k", + "authorship_tag": "ABX9TyNrMW/nJjb2vdqOvLx5Te+c", + "include_colab_link": true + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "view-in-github", + "colab_type": "text" + }, + "source": [ + "<a href=\"https://colab.research.google.com/github/ajsanjoaquin/COVID-19-Scanner/blob/master/covidtesting_notebook.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "syNJC42pUjl9", + "colab_type": "text" + }, + "source": [ + "This model is provided as-is, and not meant to diagnose COVID-19. This model has no clinical approval, nor endorsements from any health organizations. At the moment, this model is a proof of concept. In no way is the author responsible for any damages resulting from using this model. License: MIT " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "fDTcYzSMDucn", + "colab_type": "text" + }, + "source": [ + "#PURE PYTORCH IMPLEMENTATION\n", + "\n", + "Model instantiation" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "kxVuivn32TCY", + "colab_type": "code", + "colab": {} + }, + "source": [ + "#download model\n", + "!wget -O corona_V2.pth https://www.dropbox.com/s/hovi7vc0edv8fxt/corona_V2.pth?dl=0" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "GZHgM1-Z8Oqb", + "colab_type": "code", + "colab": {} + }, + "source": [ + "## The code below gives you Flatten and the double Adaptive Pooling (from fastai), plus\n", + "## a viable head. You must fill the number of FC's nodes manually through the myhead function\n", + "from torch import Tensor\n", + "from torch import nn\n", + "from torchvision import transforms\n", + "from torch.autograd import Variable\n", + "import PIL.Image\n", + "import torch\n", + "import torchvision\n", + "import logging as log\n", + "from typing import Optional # required for \"Optional[type]\"\n", + "import os,re\n", + "#if using CPU; else, comment out\n", + "torch.cuda.device(\"cuda\")\n", + "\n", + "#put test images in test folder\n", + "if not os.path.isdir('test'):\n", + " os.makedirs('test')\n", + "\n", + "class Flatten(nn.Module):\n", + " \"Flatten `x` to a single dimension, often used at the end of a model. `full` for rank-1 tensor\"\n", + " def __init__(self, full:bool=False):\n", + " super().__init__()\n", + " self.full = full\n", + "\n", + " def forward(self, x):\n", + " return x.view(-1) if self.full else x.view(x.size(0), -1)\n", + "\n", + "class AdaptiveConcatPool2d(nn.Module):\n", + " \"Layer that concats `AdaptiveAvgPool2d` and `AdaptiveMaxPool2d`.\" # from pytorch\n", + " def __init__(self, sz:Optional[int]=None): \n", + " \"Output will be 2*sz or 2 if sz is None\"\n", + " super().__init__()\n", + " self.output_size = sz or 1\n", + " self.ap = nn.AdaptiveAvgPool2d(self.output_size)\n", + " self.mp = nn.AdaptiveMaxPool2d(self.output_size)\n", + " def forward(self, x): return torch.cat([self.mp(x), self.ap(x)], 1)\n", + " \n", + "def myhead(nf, nc):\n", + " return \\\n", + " nn.Sequential( # the dropout is needed otherwise you cannot load the weights\n", + " AdaptiveConcatPool2d(),\n", + " Flatten(),\n", + " nn.BatchNorm1d(nf,eps=1e-05,momentum=0.1,affine=True,track_running_stats=True),\n", + " nn.Dropout(p=0.25,inplace=False),\n", + " nn.Linear(nf, 512,bias=True),\n", + " nn.ReLU(True),\n", + " nn.BatchNorm1d(512,eps=1e-05,momentum=0.1,affine=True,track_running_stats=True),\n", + " nn.Dropout(p=0.5,inplace=False),\n", + " nn.Linear(512, nc,bias=True),\n", + " )\n", + "\n", + "\n", + "my_model=torchvision.models.resnet50() \n", + "modules=list(my_model.children())\n", + "modules.pop(-1) \n", + "modules.pop(-1) \n", + "temp=nn.Sequential(nn.Sequential(*modules))\n", + "tempchildren=list(temp.children()) \n", + "#append the special fastai head\n", + "#Configured according to Model Architecture\n", + "\n", + "tempchildren.append(myhead(4096,2))\n", + "model_r50=nn.Sequential(*tempchildren)\n", + "\n", + "#LOAD MODEL\n", + "state = torch.load('corona_V2.pth')\n", + "model_r50.load_state_dict(state['model'])\n", + "\n", + "\n", + "#important to set to evaluation mode\n", + "model_r50.eval()\n", + "\n", + "\n", + "test_transforms = transforms.Compose([\n", + " transforms.Resize(512),\n", + " transforms.ToTensor(),\n", + " transforms.Normalize(mean=[0.485, 0.456, 0.406],\n", + " std=[0.229, 0.224, 0.225])\n", + "])\n", + "\n", + "def predict_image(model,image):\n", + " softmaxer = torch.nn.Softmax(dim=1)\n", + " image_tensor = PIL.Image.open(image)\n", + " image_tensor = image_tensor.convert('RGB')\n", + " image_tensor = test_transforms(image_tensor).float()\n", + " image_tensor = Variable(image_tensor,requires_grad=True)\n", + " image_tensor=image_tensor.unsqueeze(0)\n", + " image_tensor.cuda() #assuming using GPU w/ CUDA\n", + "\n", + " #convert evaluation to probabilities with softmax\n", + " with torch.no_grad(): #turn off backpropagation\n", + " processed=softmaxer(model(image_tensor))\n", + " return processed[0] #return probabilities\n" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "bEe1PH4dwYix", + "colab_type": "text" + }, + "source": [ + "##Before running the code below, put the test images in the test folder that was just created." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "K8r9AL6X_F_F", + "colab_type": "code", + "colab": {} + }, + "source": [ + "reg = re.compile('^.ipynb*')\n", + "test_files=[file for file in sorted(os.listdir('test'))if not reg.match(file)]\n", + "pytorch_results={filename:predict_image(model_r50,'test/'+filename) for filename in test_files}\n" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FuRl6NDtw5-o", + "colab_type": "text" + }, + "source": [ + "###Results are saved in a .csv file in the colab workspace." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "t7YqjQQw_STi", + "colab_type": "code", + "colab": {} + }, + "source": [ + "import pandas as pd\n", + "final_df=pd.DataFrame.from_dict(pytorch_results,orient='index',columns=['corona','other']).rename_axis('filename').reset_index()\n", + "final_df['corona']=final_df['corona'].apply(lambda x: x.item())\n", + "final_df['other']=final_df['other'].apply(lambda x: x.item())\n", + "final_df.loc[final_df['corona'] > final_df['other'], 'Predicted Label'] = \"Corona\"\n", + "final_df.loc[final_df['corona'] < final_df['other'], 'Predicted Label'] = \"Other\"\n", + "final_df.to_csv('results.csv', header=True)" + ], + "execution_count": 0, + "outputs": [] + } + ] +}