{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"collapsed":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\nfor 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 20GB 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":{"trusted":true},"cell_type":"code","source":"os.listdir('../input/cassava-leaf-disease-classification')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_img_path = '../input/cassava-leaf-disease-classification/train_images'\nimages = os.listdir(train_img_path)\n\nprint(\"Training images:\", len(images))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import json\nfile = open('../input/cassava-leaf-disease-classification/label_num_to_disease_map.json')\n\nclass_map = json.load(file)\nprint(json.dumps(class_map,indent=1))\nlis = json.dumps(class_map)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"type(class_map)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\n\ntrain_file = '../input/cassava-leaf-disease-classification/train.csv'\n\ntrain = pd.read_csv(train_file)\ntrain.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from __future__ import print_function, division\n\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.optim import lr_scheduler\nimport numpy as np\nimport torchvision\nfrom torchvision import datasets, models, transforms\nimport matplotlib.pyplot as plt\nimport time\nimport os\nimport copy\n\nplt.ion()   # interactive mode","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_image = os.path.join(train_img_path, images[5])\nimg = cv2.imread(sample_image)\nimg.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.cuda.is_available()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class LeafDataset(torch.utils.data.Dataset):\n    def __init__(self, csv_path, images_folder, train, transform = None):\n        self.df = pd.read_csv(csv_path)\n        self.images_folder = images_folder\n        self.transform = transform\n        self.train = train\n        \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, index):\n        filename = self.df[\"image_id\"][index]\n        try:\n            label = self.df[\"label\"][index]\n        except:\n            label = ''\n        image = PIL.Image.open(os.path.join(self.images_folder, filename))\n        if self.transform is not None and self.train:\n            image = self.transform['train'](image)\n        elif self.transform is not None and not self.train:\n            image = self.transform['val'](image)\n        return image, label","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_transforms = {\n    'train': transforms.Compose([\n        transforms.RandomResizedCrop(224),\n        transforms.RandomHorizontalFlip(),\n        transforms.ToTensor(),\n        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n    ]),\n    'val': transforms.Compose([\n        transforms.Resize(256),\n        transforms.CenterCrop(224),\n        transforms.ToTensor(),\n        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n    ]),\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\nimport PIL\ntrain_file = '../input/cassava-leaf-disease-classification/train.csv'\n\ntrain = pd.read_csv(train_file)\ntrain.head()\n\nleaf_data_train = LeafDataset(train_file, train_img_path, True, data_transforms)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_size = int(0.8 * len(leaf_data_train))\nval_size = len(leaf_data_train) - train_size","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_size, val_size","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_dataset, val_dataset = torch.utils.data.random_split(leaf_data_train, [train_size, val_size])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 32\ntrain_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size)\nvalidation_loader = torch.utils.data.DataLoader(val_dataset, batch_size=batch_size)\ndataloaders = {}\ndataloaders['train'] = train_loader\ndataloaders['val'] = validation_loader\ndataset_sizes = {}\ndataset_sizes['train'] = len(train_dataset)\ndataset_sizes['val'] = len(val_dataset)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def imshow(inp, title=None):\n    \"\"\"Imshow for Tensor.\"\"\"\n    inp = inp.numpy().transpose((1, 2, 0))\n    mean = np.array([0.485, 0.456, 0.406])\n    std = np.array([0.229, 0.224, 0.225])\n    inp = std * inp + mean\n    inp = np.clip(inp, 0, 1)\n    plt.imshow(inp)\n    if title is not None:\n        plt.title(title)\n    plt.pause(0.001)  # pause a bit so that plots are updated\n\n\n# Get a batch of training data\ninputs, classes = next(iter(train_loader))\n\n# Make a grid from batch\nout = torchvision.utils.make_grid(inputs)\n\nimshow(out, title=[class_map[str(int(x))] for x in classes])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"classes.data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\ndevice","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(dataloaders['train'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def train_model(model, criterion, optimizer, scheduler, num_epochs=25):\n    since = time.time()\n\n    best_model_wts = copy.deepcopy(model.state_dict())\n    best_acc = 0.0\n\n    for epoch in range(num_epochs):\n        print('Epoch {}/{}'.format(epoch, num_epochs - 1))\n        print('-' * 10)\n\n        # Each epoch has a training and validation phase\n        for phase in ['train', 'val']:\n            if phase == 'train':\n                model.train()  # Set model to training mode\n            else:\n                model.eval()   # Set model to evaluate mode\n\n            running_loss = 0.0\n            running_corrects = 0\n\n            # Iterate over data.\n            mini_batch_no = 1\n            for inputs, labels in dataloaders[phase]:\n                \n                inputs = inputs.to(device)\n                labels = labels.to(device)\n\n                # zero the parameter gradients\n                optimizer.zero_grad()\n\n                # forward\n                # track history if only in train\n                with torch.set_grad_enabled(phase == 'train'):\n                    outputs = model(inputs)\n                    _, preds = torch.max(outputs, 1)\n                    loss = criterion(outputs, labels)\n\n                    # backward + optimize only if in training phase\n                    if phase == 'train':\n                        loss.backward()\n                        optimizer.step()\n\n                # statistics\n                running_loss += loss.item() * inputs.size(0)\n                running_corrects += torch.sum(preds == labels.data)\n                mini_batch_no += 1\n                if mini_batch_no%10 == 0:\n                    print('{} minibates done'.format(mini_batch_no))\n            if phase == 'train':\n                scheduler.step()\n\n            epoch_loss = running_loss / dataset_sizes[phase]\n            epoch_acc = running_corrects.double() / dataset_sizes[phase]\n\n            print('{} Loss: {:.4f} Acc: {:.4f}'.format(\n                phase, epoch_loss, epoch_acc))\n\n            # deep copy the model\n            if phase == 'val' and epoch_acc > best_acc:\n                best_acc = epoch_acc\n                best_model_wts = copy.deepcopy(model.state_dict())\n\n        print()\n\n    time_elapsed = time.time() - since\n    print('Training complete in {:.0f}m {:.0f}s'.format(\n        time_elapsed // 60, time_elapsed % 60))\n    print('Best val Acc: {:4f}'.format(best_acc))\n\n    # load best model weights\n    model.load_state_dict(best_model_wts)\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def visualize_model(model, num_images=6):\n    was_training = model.training\n    model.eval()\n    images_so_far = 0\n    fig = plt.figure()\n\n    with torch.no_grad():\n        for i, (inputs, labels) in enumerate(dataloaders['val']):\n            inputs = inputs.to(device)\n            labels = labels.to(device)\n\n            outputs = model(inputs)\n            _, preds = torch.max(outputs, 1)\n\n            for j in range(inputs.size()[0]):\n                images_so_far += 1\n                ax = plt.subplot(num_images//2, 2, images_so_far)\n                ax.axis('off')\n                ax.set_title('predicted: {}'.format(class_map[str(int(preds[j]))]))\n                imshow(inputs.cpu().data[j])\n\n                if images_so_far == num_images:\n                    model.train(mode=was_training)\n                    return\n        model.train(mode=was_training)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model_ft = models.resnet18(pretrained=True)\nmodel_path_download = '../input/resnet18/resnet18.pth'\nmodel_ft = models.resnet18(pretrained=False)\nmodel_ft.load_state_dict(torch.load(model_path_download))\n# model_ft = torch.load(model_path_download)\nnum_ftrs = model_ft.fc.in_features\n\n\nmodel_ft.fc = nn.Linear(num_ftrs, len(class_map))\n\nmodel_ft = model_ft.to(device)\n\ncriterion = nn.CrossEntropyLoss()\n\n# Observe that all parameters are being optimized\noptimizer_ft = optim.SGD(model_ft.parameters(), lr=0.001, momentum=0.9)\n\n# Decay LR by a factor of 0.1 every 7 epochs\nexp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model_ft = models.resnet18(pretrained=False)\n# model_ft.load_state_dict(torch.load(model_path_download))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# model_ft1 = train_model(model_ft, criterion, optimizer_ft, exp_lr_scheduler,\n#                        num_epochs=5)\n# PATH = os.path.join('../input/cassava-leaf-disease-classification', 'leaf_disease.pt')\ntorch.save(model_ft1.state_dict(), 'leaf_disease.pt')\n# model_ft.load_state_dict(best_model_wts)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# torch.save(model_ft.state_dict(), 'resnet18.pt')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"os.listdir('/kaggle/working')\n# print(os.getcwd())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"visualize_model(model_ft)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_img_path = '../input/cassava-leaf-disease-classification/test_images'\ntest_images = os.listdir(test_img_path)\n\nprint(\"Testing images:\", len(test_images))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_path_inf = '/kaggle/working/leaf_disease.pt'\nmodel_inf = models.resnet18(pretrained=False)\nnum_ftrs = model_inf.fc.in_features\nmodel_inf.fc = nn.Linear(num_ftrs, len(class_map))\nmodel_inf.load_state_dict(torch.load(model_path_inf))\n# model_inf = models.resnet18(pretrained=True)\n# num_ftrs = model_inf.fc.in_features\n\n\n# model_inf.fc = nn.Linear(num_ftrs, len(class_map))\n\nmodel_inf = model_inf.to(device)\n# PATH = os.path.join('/kaggle/working', 'resnet18.pt')\n# model_inf.load_state_dict(torch.load(PATH))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_file = \"../input/cassava-leaf-disease-classification/sample_submission.csv\"\ntest_df = pd.read_csv(\"../input/cassava-leaf-disease-classification/sample_submission.csv\")\nimage_path = \"../input/cassava-leaf-disease-classification/test_images/\"\n# fake targets\ntest_targets = test_df.label.values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 4\ntest_dataset = LeafDataset(test_file, image_path, False, data_transforms)\ntest_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predictions=[]\n\nfor imgs, _ in test_loader:\n    imgs = imgs.to(device)\n    with torch.no_grad():\n        model_inf = model_inf.to(device)\n        outputs = model_inf(imgs)\n        _, predicted = torch.max(outputs, dim=1)\n        predicted=predicted.to('cpu')\n        predictions.append(predicted)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predictions","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df['label'] = np.concatenate(predictions)\ntest_df.to_csv('submission.csv', index=False)","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":4}