{"cells":[{"metadata":{},"cell_type":"markdown","source":"Os passos são:\n* Carregar e tratar os datasets de treinamento e teste do Histopathologic Cancer usando albumentations e o torchvision\n* Definir uma Rede Convolucional\n* Definir uma função de custo (loss)\n* Testar a rede em dados de teste"},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install albumentations > /dev/null 2>&1","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport time\n\nimport os\nimport cv2\n\nimport albumentations\nfrom albumentations import torch as AT\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import roc_auc_score\n\nimport torch\nfrom torch import Tensor\n\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nimport torchvision\nfrom torchvision import models\n\nimport torch.optim as optim\n\nfrom torch.utils.data import DataLoader, Dataset\nfrom torch.utils.data.sampler import SubsetRandomSampler","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 1. Preparando os Dados"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Constantes\ndata_dir = '../input/histopathologic-cancer-detection'\n\nseed=42\n\nimg_size = 32\nbatch_size = 32\nepochs = 100\nnum_workers = 4\n\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_transforms = {\n    'train' : albumentations.Compose([\n        albumentations.Resize(img_size, img_size),\n        albumentations.HorizontalFlip(),\n        albumentations.RandomBrightness(),\n        albumentations.ShiftScaleRotate(rotate_limit=15, scale_limit=0.10),\n        albumentations.JpegCompression(80),\n        albumentations.HueSaturationValue(),\n        albumentations.Normalize(),\n        AT.ToTensor()\n    ]),\n    \n    'valid' : albumentations.Compose([\n    albumentations.Resize(img_size, img_size),\n    albumentations.Normalize(),\n    AT.ToTensor()\n    ]),\n    \n    'test' : albumentations.Compose([\n    albumentations.Resize(img_size, img_size),\n    albumentations.Normalize(),\n    AT.ToTensor()\n    ])\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"classes = ('no cancer', 'cancer')\n\ndf_labels = pd.read_csv(f'{data_dir}/train_labels.csv')\ndf_labels.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dic_labels = {k:v for k, v in zip(df_labels.id, df_labels.label)}\nlist(dic_labels.items())[:10]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class CancerDataset(Dataset):\n    def __init__(self, datafolder,\n                 datatype='train',\n                 transform = albumentations.Compose([albumentations.Resize(224, 224), albumentations.Normalize(), AT.ToTensor()]),\n                 labels_dict={}\n                ):\n        self.datafolder = datafolder\n        self.datatype = datatype\n        self.image_files_list = [s for s in os.listdir(datafolder)]\n        self.transform = transform\n        self.labels_dict = labels_dict\n\n    def __len__(self):\n        return len(self.image_files_list)\n\n    def __getitem__(self, idx):\n        img_name = os.path.join(self.datafolder, self.image_files_list[idx])\n        img = cv2.imread(img_name)\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        image = self.transform(image=img)\n        image = image['image']\n\n        img_name_short = self.image_files_list[idx].split('.')[0]\n\n        if self.datatype == 'train':\n            label = self.labels_dict[img_name_short]\n        else:\n            label = 0\n        return image, label","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# indices for validation\ntr, val= train_test_split(df_labels.id, stratify=(df_labels.label), test_size=0.1, random_state=seed)\n#tr[:10], val[:10], len(tr), len(val)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_datasets = {x[0] : CancerDataset(datafolder=f'{data_dir}/{x[1]}/', datatype=f'{x[1]}', transform=data_transforms[x[0]], labels_dict=dic_labels)\n                  for x in [\n                      #dataset-name, dataset-dir\n                      ('train', 'train'),\n                      ('valid', 'train'),\n                      ('test',  'test')]}\n\nindexes = {'train' : tr.index,\n           'valid' : val.index}\n\nsampler = {x : SubsetRandomSampler(list(indexes[x]))\n           for x in ['train', 'valid']}\n\ndataset_sizes = {x: len(indexes[x])\n                 for x in ['train', 'valid']}\n\nloader = {'train' : torch.utils.data.DataLoader(image_datasets['train'], batch_size=batch_size, num_workers=num_workers, sampler=sampler['train']),\n          'valid' : torch.utils.data.DataLoader(image_datasets['valid'], batch_size=batch_size, num_workers=num_workers, sampler=sampler['valid']),\n          'test'  : torch.utils.data.DataLoader(image_datasets['test'],  batch_size=batch_size, num_workers=num_workers)}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def imshow(img):\n    #img = img / 2 + 0.5     # unnormalize\n    npimg = img.numpy()\n    plt.imshow(np.transpose(npimg, (1, 2, 0)))\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# get some random training images\ndataiter = iter(loader['train'])\nimages, labels = dataiter.next()\n\n# show images\nimshow(torchvision.utils.make_grid(images))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# print labels\nprint(' '.join('%s,' % labels[j].numpy() for j in range(batch_size)))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 2. Definindo uma Rede Convolucional"},{"metadata":{"trusted":true},"cell_type":"code","source":"def Net(output_dim=2):\n    model_ft = models.resnet18(pretrained=True)\n\n    #for i, param in model_ft.named_parameters():\n    #    param.requires_grad = False\n\n    num_ftrs = model_ft.fc.in_features\n    model_ft.fc = nn.Linear(num_ftrs, output_dim)\n        \n    model_ft = model_ft.to(device)\n\n    return model_ft","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"net = Net()\nnet = net.to(device)\nnet","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 3. Definindo uma Função de Custo e um Otimizador"},{"metadata":{"trusted":true},"cell_type":"code","source":"criterion = nn.CrossEntropyLoss()\n\n#optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)\noptimizer = optim.AdamW(net.parameters(), lr=0.01)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 4. Treinando a Rede"},{"metadata":{"trusted":true},"cell_type":"code","source":"def train(net, criterion, optimizer):\n    since = time.time()\n\n    for epoch in range(epochs):  # loop over the dataset multiple times\n\n        running_loss = 0.0\n        for i, data in enumerate(loader['train'], 0):\n            # get the inputs; data is a list of [inputs, labels]\n            #inputs, labels = data\n            inputs, labels = data[0].to(device), data[1].to(device)\n\n            # zero the parameter gradients\n            optimizer.zero_grad()\n\n            # forward + backward + optimize\n            outputs = net(inputs)\n            loss = criterion(outputs, labels)\n            loss.backward()\n            optimizer.step()\n\n            # print statistics\n            running_loss += loss.item()\n            if i % 1000 == 999:    # print every 100 mini-batches\n                print('[%d, %5d] loss: %.5f - time: %.2f' % (epoch + 1, i + 1, running_loss / 2000, time.time() - since))\n                running_loss = 0.0\n\n    time_elapsed = time.time() - since\n    print('Training complete in {:.0f}m {:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))\n\ntrain(net, criterion, optimizer)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 5. Testando a Rede nos Dados de Teste"},{"metadata":{"trusted":true},"cell_type":"code","source":"dataiter = iter(loader['valid'])\nimages, labels = dataiter.next()\n\n# print images\nimshow(torchvision.utils.make_grid(images))\n\n# print labels\nprint(' '.join('%s,' % labels[j].numpy() for j in range(batch_size)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"outputs = net(images.to(device))\n_, predicted = torch.max(outputs.cpu(), 1)\n\nprint('Predicted: ', ' '.join('%5s' % predicted[j].numpy() for j in range(batch_size)))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 5.1 Qual foi a Performance nos dados de Teste?"},{"metadata":{"trusted":true},"cell_type":"code","source":"correct = 0\ntotal = 0\nwith torch.no_grad():\n    for data in loader['valid']:\n        images, labels = data\n        outputs = net(images.to(device))\n        _, predicted = torch.max(outputs.data, 1)\n        total += labels.size(0)\n        correct += (predicted.cpu() == labels).sum().item()\n\nprint('Accuracy of the network on the validation images: %d %%' % (100 * correct / total))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 5.2 Qual foi a Performance em Cada Classe?"},{"metadata":{"trusted":true},"cell_type":"code","source":"def eval_net(net):\n    class_correct = list(0. for i in range(10))\n    class_total = list(0. for i in range(10))\n    with torch.no_grad():\n        for data in loader['valid']:\n            images, labels = data\n            outputs = net(images.to(device))\n            _, predicted = torch.max(outputs, 1)\n            c = (predicted.cpu() == labels).squeeze()\n            for i in range(len(c)):\n                label = labels[i]\n                class_correct[label] += c[i].item()\n                class_total[label] += 1\n\n    for i in range(len(classes)):\n        print('Accuracy of %5s : %2d %%' % (classes[i], 100 * class_correct[i] / class_total[i]))\n        \neval_net(net)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# referencias\n# https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html#sphx-glr-beginner-blitz-cifar10-tutorial-py","execution_count":null,"outputs":[]},{"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":1}