{"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":"code","source":"from __future__ import print_function\nfrom __future__ import division\nimport argparse\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\nimport random\nimport pandas as pd\nimport os, fnmatch, copy, time\nimport numpy as np\nimport math\nimport torchvision\nimport matplotlib.pyplot as plt\nfrom torchvision import datasets, models\nfrom torchvision import transforms as T\nfrom torch.optim.lr_scheduler import StepLR\nfrom datetime import datetime\nfrom PIL import Image\nfrom torch.utils.data import DataLoader","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-06-13T12:19:33.090718Z","iopub.execute_input":"2021-06-13T12:19:33.091090Z","iopub.status.idle":"2021-06-13T12:19:33.100126Z","shell.execute_reply.started":"2021-06-13T12:19:33.091058Z","shell.execute_reply":"2021-06-13T12:19:33.098770Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torchvision import transforms as T\nfrom torch.utils import data\n\nrandom.seed(1)\n\ndef get_filepath(dir_root):\n    file_paths = []\n    for root, dirs, files in os.walk(dir_root):\n        for file in files:\n            file_paths.append(os.path.join(root, file))\n    return file_paths\n\nclass DriverDatasetTrain(data.Dataset):\n    def __init__(self, data_root, transforms=None, train=True):\n        self.train = train\n        imgs_in = get_filepath(data_root)\n        random.shuffle(imgs_in)\n        imgs_num = len(imgs_in)\n\n        if transforms is None:\n            self.transforms = T.Compose([\n                                         T.Resize(size = (224, 224)),\n                                         T.ToTensor(),\n                                         T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n                                         ])\n\n        if self.train:\n            self.imgs = imgs_in[:int(0.7 * imgs_num)]\n        else:\n            self.imgs = imgs_in[int(0.7 * imgs_num):]\n\n    def __getitem__(self, index):\n        img_path = self.imgs[index]\n\n        label = int(img_path.split('/')[-2][1])\n        data = Image.open(img_path)\n        data = self.transforms(data)\n        return data, label\n\n    def __len__(self):\n        return len(self.imgs)\n\nclass DriverDatasetTest(data.Dataset):\n    def __init__(self, data_root, transforms=None):\n\n        self.imgs_in = get_filepath(data_root)\n\n        if transforms is None:\n            self.transforms = T.Compose([T.Resize(size=(224,224)),\n                                         T.ToTensor(),\n                                         T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n                                         ])\n\n    def __getitem__(self, index):\n        img_path = self.imgs_in[index]\n\n        data = Image.open(img_path)\n        data = self.transforms(data)\n        return data, img_path\n\n    def __len__(self):\n        return len(self.imgs_in)","metadata":{"execution":{"iopub.status.busy":"2021-06-13T12:19:33.102419Z","iopub.execute_input":"2021-06-13T12:19:33.103118Z","iopub.status.idle":"2021-06-13T12:19:33.123378Z","shell.execute_reply.started":"2021-06-13T12:19:33.103060Z","shell.execute_reply":"2021-06-13T12:19:33.122097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train(model, device, train_loader, optimizer, epoch, train_losses):\n    model.train()\n    for batch_idx, (data, target) in enumerate(train_loader):\n        data, target = data.to(device), target.to(device)\n        optimizer.zero_grad()\n        output = model(data)\n        loss = torch.nn.CrossEntropyLoss()(output, target)\n        loss.backward()\n        optimizer.step()\n\n        if batch_idx % 50 ==0:\n            print('Train Epoch: {} [{}/{} ({:.0f}%)]\\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset),100. * batch_idx / len(train_loader), loss.item()))\n        \n    train_losses.append(loss.item())","metadata":{"execution":{"iopub.status.busy":"2021-06-13T12:19:33.128376Z","iopub.execute_input":"2021-06-13T12:19:33.128714Z","iopub.status.idle":"2021-06-13T12:19:33.140628Z","shell.execute_reply.started":"2021-06-13T12:19:33.128683Z","shell.execute_reply":"2021-06-13T12:19:33.139238Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def validation(model, device, test_loader, test_losses):\n    model.eval()\n    test_loss = 0\n    correct = 0\n    with torch.no_grad():\n        for data, target in test_loader:\n            data, target = data.to(device), target.to(device)\n            output = model(data)\n            test_loss += F.cross_entropy(output, target, reduction = 'sum').item()\n            pred = output.argmax(dim = 1, keepdim = True)\n            correct += pred.eq(target.view_as(pred)).sum().item()\n    test_loss/=len(test_loader.dataset)\n    print('\\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\\n'.format(\n        test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset)))\n    \n    test_losses.append(test_loss)","metadata":{"execution":{"iopub.status.busy":"2021-06-13T12:19:33.145208Z","iopub.execute_input":"2021-06-13T12:19:33.145633Z","iopub.status.idle":"2021-06-13T12:19:33.158089Z","shell.execute_reply.started":"2021-06-13T12:19:33.145559Z","shell.execute_reply":"2021-06-13T12:19:33.156684Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def set_parameter_requires_grad(model, feature_extracting):\n    if feature_extracting:\n        for param in model.parameters():\n            param.requires_grad = False","metadata":{"execution":{"iopub.status.busy":"2021-06-13T12:19:33.160068Z","iopub.execute_input":"2021-06-13T12:19:33.160684Z","iopub.status.idle":"2021-06-13T12:19:33.170099Z","shell.execute_reply.started":"2021-06-13T12:19:33.160632Z","shell.execute_reply":"2021-06-13T12:19:33.168929Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_name = \"\"\nnum_classes=10\nfeature_extract=True\nuse_pretrained=False\ndef initialize_model(model_name, num_classes=10, feature_extract=True, use_pretrained=False):\n    # Initialize these variables which will be set in this if statement. Each of these\n    #   variables is model specific.\n    model_ft = None\n    input_size = 0\n    \n    if model_name == \"resnet50\":\n        \"\"\" Resnet50\n        \"\"\"\n        model_ft = models.resnet50(pretrained=use_pretrained)\n        set_parameter_requires_grad(model_ft, feature_extract)\n        num_ftrs = model_ft.fc.in_features\n        model_ft.fc = nn.Linear(num_ftrs, num_classes)\n        input_size = 224\n        \n    elif model_name == \"resnet152\":\n        \"\"\" Resnet152\n        \"\"\"\n        model_ft = models.resnet152(pretrained=use_pretrained)\n        set_parameter_requires_grad(model_ft, feature_extract)\n        num_ftrs = model_ft.fc.in_features\n        model_ft.fc = nn.Linear(num_ftrs, num_classes)\n        input_size = 224\n        \n    elif model_name == \"resnext101_32x8d\":\n        \"\"\" Resnext101_32x8d\n        \"\"\"\n        model_ft = models.resnext101_32x8d(pretrained=use_pretrained)\n        set_parameter_requires_grad(model_ft, feature_extract)\n        num_ftrs = model_ft.fc.in_features\n        model_ft.fc = nn.Linear(num_ftrs, num_classes)\n        input_size = 224\n        \n    elif model_name == \"wide_resnet101_2\":\n        \"\"\" Wide_resnet101_2\n        \"\"\"\n        model_ft = models.wide_resnet101_2(pretrained=use_pretrained)\n        set_parameter_requires_grad(model_ft, feature_extract)\n        num_ftrs = model_ft.fc.in_features\n        model_ft.fc = nn.Linear(num_ftrs, num_classes)\n        input_size = 224\n        \n    elif model_name == \"densenet\":\n        \"\"\" Densenet161\n        \"\"\"\n        model_ft = models.densenet161()\n        set_parameter_requires_grad(model_ft, feature_extract)\n        num_ftrs = model_ft.classifier.in_features\n        model_ft.classifier = nn.Linear(num_ftrs, num_classes)\n        input_size = 224\n    \n    elif model_name == \"squeezenet\":\n        \"\"\" Squeezenet1_1\n        \"\"\"\n        model_ft = models.squeezenet1_1(pretrained=use_pretrained)\n        set_parameter_requires_grad(model_ft, feature_extract)\n        model_ft.classifier[1] = nn.Conv2d(512, num_classes, kernel_size=(1,1), stride=(1,1))\n        model_ft.num_classes = num_classes\n        input_size = 224\n        \n    else:\n        print(\"Invalid model name, exiting...\")\n        exit()\n    \n    return model_ft, input_size\n    \n# Initialize the model for this run\n# model_ft, input_size = initialize_model(model_name, num_classes, feature_extract, use_pretrained=False)\n\n# Print the model we just instantiated\n# print(model_ft)","metadata":{"execution":{"iopub.status.busy":"2021-06-13T12:19:33.343748Z","iopub.execute_input":"2021-06-13T12:19:33.344177Z","iopub.status.idle":"2021-06-13T12:19:33.358963Z","shell.execute_reply.started":"2021-06-13T12:19:33.344130Z","shell.execute_reply":"2021-06-13T12:19:33.357561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Hyperparameters\nmax_epoch = 1 #max_epoch             200\nalpha = 0.01 #learning rate           0.001 0.005 0.01 0.05 0.1\nbth_size = 64 #batch size             32 64 128 256 512 1024\ngam = 0.9 #gamma(discount factor)    0.1 0.5 0.9","metadata":{"execution":{"iopub.status.busy":"2021-06-13T12:19:33.361716Z","iopub.execute_input":"2021-06-13T12:19:33.362603Z","iopub.status.idle":"2021-06-13T12:19:33.377396Z","shell.execute_reply.started":"2021-06-13T12:19:33.362552Z","shell.execute_reply":"2021-06-13T12:19:33.376303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data_path = '../input/state-farm-distracted-driver-detection/imgs/train'\ntest_data_path = '../input/state-farm-distracted-driver-detection/imgs/test'\n\ntrain_data = DriverDatasetTrain(train_data_path, train=True)\ntrain_loader = DataLoader(dataset=train_data, shuffle=True, batch_size=bth_size, num_workers=4)\n\nvali_data = DriverDatasetTrain(train_data_path, train=False)\nvali_loader = DataLoader(dataset=vali_data, shuffle=False, batch_size=bth_size, num_workers=4)\n\ntest_data = DriverDatasetTest(test_data_path)\ntest_loader = DataLoader(dataset = test_data, shuffle=False, batch_size=1, num_workers=1)\n","metadata":{"execution":{"iopub.status.busy":"2021-06-13T12:19:33.382768Z","iopub.execute_input":"2021-06-13T12:19:33.383198Z","iopub.status.idle":"2021-06-13T12:23:53.495745Z","shell.execute_reply.started":"2021-06-13T12:19:33.383150Z","shell.execute_reply":"2021-06-13T12:23:53.494583Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_list = [\"resnet50\", \"resnet152\", \"resnext101_32x8d\", \"wide_resnet101_2\", \"densenet\", \"squeezenet\"]\nmodel_name = model_list[4]\nmodel_ft, input_size = initialize_model(model_name, num_classes=10)    # input_size = 224\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\nmodel = model_ft.to(device)\noptimizer = optim.Adam(model.parameters(), lr = alpha)\nscheduler = StepLR(optimizer, step_size = 1, gamma = gam)\n\ntrain_losses = []\nvalidation_losses = []\nfor epoch in range(max_epoch):\n    print(\"======== Epoch: {} ========\".format(epoch + 1))\n    train(model, device, train_loader, optimizer, epoch, train_losses)\n    validation(model, device, vali_loader, validation_losses)\n    \nplt.plot(train_losses, label='train loss')\nplt.plot(validation_losses, label='validation loss')\nplt.legend()\nplt.title(model_name)\nplt.show()\n#print('Best accuracy of '+model_name+' during training: {:.4f}'.format(test_best_acc))\n\ntorch.save(model.state_dict(), \"trained.model\")","metadata":{"execution":{"iopub.status.busy":"2021-06-13T12:23:53.497763Z","iopub.execute_input":"2021-06-13T12:23:53.498239Z","iopub.status.idle":"2021-06-13T12:27:09.346745Z","shell.execute_reply.started":"2021-06-13T12:23:53.498181Z","shell.execute_reply":"2021-06-13T12:27:09.345656Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def predict(model, device, test_loader):\n    model.eval()\n    result = []\n    for (data, path) in test_loader:\n        path = path[0].split('/')\n        with torch.no_grad():\n            data = data.to(device)\n            y = model(data)\n            output = nn.Softmax(dim = 1)(y)[0].cpu().numpy()\n            temp = []\n            temp.append(path[-1])\n            for j in range(10):\n                temp.append(output[j])\n            result.append(temp)\n    \n    df_ = pd.DataFrame(result, columns = ['img', 'c0', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9'])\n    df_.to_csv(\"result.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2021-06-13T12:33:23.976408Z","iopub.execute_input":"2021-06-13T12:33:23.976872Z","iopub.status.idle":"2021-06-13T12:33:23.987331Z","shell.execute_reply.started":"2021-06-13T12:33:23.976835Z","shell.execute_reply":"2021-06-13T12:33:23.985947Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#model, input_size = initialize_model(\"densenet\", num_classes=10)\n#model = model_ft.to(device)\n#model.load_state_dict(torch.load(\"trained.model\"))\npredict(model, device, test_loader)","metadata":{"execution":{"iopub.status.busy":"2021-06-13T12:33:25.560135Z","iopub.execute_input":"2021-06-13T12:33:25.560581Z","iopub.status.idle":"2021-06-13T12:33:25.830638Z","shell.execute_reply.started":"2021-06-13T12:33:25.560532Z","shell.execute_reply":"2021-06-13T12:33:25.829344Z"},"trusted":true},"execution_count":null,"outputs":[]}]}