{"cells":[{"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":{},"cell_type":"markdown","source":"# Load data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train_csv = \"/kaggle/input/siim-isic-melanoma-classification/train.csv\"\nimage_dir = \"/kaggle/input/siim-isic-melanoma-classification/jpeg/train\"\ntrain_meta = pd.read_csv(train_csv)\ntest_csv = \"/kaggle/input/siim-isic-melanoma-classification/test.csv\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#print(train_meta)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch\n\n#Set device\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","collapsed":true,"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":false},"cell_type":"markdown","source":"# Data Loading","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2\nimport tensorflow as tf\n\nfrom torch.utils.data import DataLoader, Dataset #Create an efficient dataloader set to feed images to the model\nfrom torch.utils.data.sampler import SequentialSampler\nfrom torchvision import transforms\n\nimport albumentations as A #Package of transformations\nfrom albumentations.pytorch.transforms import ToTensorV2\n\ndef get_train_transform():\n    return A.Compose([\n        ToTensorV2(p=1.0)\n    ])\n\ndef get_valid_transforms():\n    return A.Compose([\n            A.Resize(height=512, width=512, p=1.0),\n            ToTensorV2(p=1.0),\n        ], p=1.0)\n\nclass TrainData(Dataset):\n\n    def __init__(self, dataframe, image_dir, labels, transforms):\n        super().__init__()\n        \n        self.df = dataframe\n        self.image_ids = dataframe['image_name'].unique()\n        self.image_dir = image_dir\n        self.labels = labels\n        self.transforms = transforms\n\n    def __getitem__(self, idx: int):\n        image_id = self.image_ids[idx]\n        image = cv2.imread(f'{self.image_dir}/{image_id}.jpg', cv2.IMREAD_COLOR)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)\n        image = image.astype(np.float32)/ 255\n        \n        target = torch.tensor(int(self.df.iloc[idx, 7]))\n        \n        if self.transforms:\n            sample = {'image': image}\n            sample = self.transforms(**sample)\n            image = sample['image']\n            \n        return image, target\n    \n    def __len__(self) -> int:\n        return self.image_ids.shape[0]\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\n#Split the training data into train and validate sets\ntrain_meta, valid_meta = train_test_split(train_meta,test_size=0.2)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(train_meta.shape)\nprint(valid_meta.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_dataset = TrainData(train_meta, image_dir, labels = train_meta[\"target\"].values, transforms = get_valid_transforms())\nvalid_dataset = TrainData(valid_meta, image_dir, labels = valid_meta[\"target\"].values, transforms = get_valid_transforms())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_loader = DataLoader(train_dataset, batch_size = 64, shuffle = True, num_workers = 0)\nvalid_loader = DataLoader(valid_dataset, batch_size = 64, shuffle = False, num_workers = 0)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Load Model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from torch import nn\nfrom torch.nn import functional as F\n\n!pip install efficientnet_pytorch\nfrom efficientnet_pytorch import EfficientNet\nmodel = EfficientNet.from_pretrained('efficientnet-b4', num_classes = 2) \nmodel","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Train Model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Freeze pretrained model parameters to avoid backpropogating through them\nfor parameter in model.parameters():\n    parameter.requires_grad = True\n\n    \n\"\"\"from collections import OrderedDict\n\n# Build custom classifier\nclassifier = nn.Sequential(OrderedDict([('fc1', nn.Linear(2048, 256)),\n                                        ('relu', nn.ReLU()),\n                                        ('drop', nn.Dropout(p=0.5)),\n                                        ('fc2', nn.Linear(256, 2)),\n                                        ('output', nn.LogSoftmax(dim=1))]))\n\nmodel.fc = classifier\nmodel.fc\n\nfor parameter in model.fc.parameters():\n    parameter.requires_grad = True\n\"\"\"\nmodel.to(device)\n#model.fc.to(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Function for the validation pass\ndef validation(model, valid_loader, criterion, device):\n    \n    val_loss = 0\n    accuracy = 0\n    \n    for images, labels in iter(valid_loader):\n        images, labels = images.cuda(), labels.cuda()\n\n        output = model.forward(images)\n        print(\"Output Valid\")\n        val_loss += criterion(output, labels).item()\n        print(\"val_loss\")\n\n        probabilities = torch.exp(output)\n        print(\"probabilities\")\n        \n        equality = (labels.data == probabilities.max(dim=1)[1])\n        print(\"equality\")\n        accuracy += equality.type(torch.FloatTensor).mean()\n    \n    return val_loss, accuracy","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Train the classifier\ndef train_classifier(model, optimizer, criterion,train_loader, valid_loader, epochs):\n\n    steps = 0\n    print_every = 50\n\n    for e in range(epochs):\n\n        model.train()\n\n        running_loss = 0\n\n        for images, labels in iter(train_loader):            \n            images, labels = images.cuda(), labels.cuda()\n    \n            steps += 1\n            print(\"Steps: \" + str(steps))\n\n            optimizer.zero_grad()\n        \n            output = model.forward(images)\n            #print(\"Output \" + str(output))\n            loss = criterion(output, labels)\n            #print(\"Loss: \" + str(loss))\n            loss.backward()\n            optimizer.step()\n\n            running_loss += loss.item()\n            print(\"Running loss: \" + str(running_loss))\n            \n            if steps % print_every == 0:\n\n                model.eval()\n\n                # Turn off gradients for validation, saves memory and computations\n                with torch.no_grad():\n                    validation_loss, accuracy = validation(model, valid_loader, criterion, device)\n\n                print(\"Epoch: {}/{}.. \".format(e+1, epochs),\n                      \"Training Loss: {:.3f}.. \".format(running_loss/print_every),\n                      \"Validation Loss: {:.3f}.. \".format(validation_loss/len(valid_loader)),\n                      \"Validation Accuracy: {:.3f}\".format(accuracy/len(valid_loader)))\n\n                running_loss = 0\n                model.train()\n                \n    model_path = \"/kaggle/working/model.pth\"\n    torch.save(model, model_path)\n                \n    \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from torch import optim\n\n#Loss function\ncriterion = nn.CrossEntropyLoss()\n\n# Gradient descent optimizer\noptimizer = optim.Adam(model.parameters(), lr=0.0001)\n    \ntrain_classifier(model, optimizer, criterion, train_loader, valid_loader, epochs = 1)\n\n","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}