{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":5048,"databundleVersionId":868335,"sourceType":"competition"}],"dockerImageVersionId":30684,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"### Import Packages","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd \n\nimport os\nimport glob\nimport matplotlib.pyplot as plt\n\nfrom tqdm import tqdm\n\nfrom PIL import Image\n\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\n\nimport torchvision.io as io\nimport torchvision.models as models\nfrom torchvision import datasets, transforms\nfrom torch.utils.data import DataLoader, random_split","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-04-09T20:45:05.859529Z","iopub.execute_input":"2024-04-09T20:45:05.859904Z","iopub.status.idle":"2024-04-09T20:45:05.866236Z","shell.execute_reply.started":"2024-04-09T20:45:05.859877Z","shell.execute_reply":"2024-04-09T20:45:05.865158Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Import data & Display Some Images","metadata":{}},{"cell_type":"code","source":"train_path = '/kaggle/input/state-farm-distracted-driver-detection/imgs/train'\nfor folder in glob.glob(train_path+'/*'):\n    folder_name = folder.split('/')[-1]\n    print(f'{folder_name} : {len(os.listdir(folder))} images')","metadata":{"execution":{"iopub.status.busy":"2024-04-09T19:39:55.940024Z","iopub.execute_input":"2024-04-09T19:39:55.940449Z","iopub.status.idle":"2024-04-09T19:39:57.836234Z","shell.execute_reply.started":"2024-04-09T19:39:55.940413Z","shell.execute_reply":"2024-04-09T19:39:57.835161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> Data is almost balanced","metadata":{}},{"cell_type":"code","source":"classes = {\n    'c0': 'safe driving',\n    'c1': 'texting - right',\n    'c2': 'talking on the phone - right',\n    'c3': 'texting - left',\n    'c4': 'talking on the phone - left',\n    'c5': 'operating the radio',\n    'c6': 'drinking',\n    'c7': 'reaching behind',\n    'c8': 'hair and makeup',\n    'c9': 'talking to passenger'\n}\n","metadata":{"execution":{"iopub.status.busy":"2024-04-09T19:39:57.837446Z","iopub.execute_input":"2024-04-09T19:39:57.837782Z","iopub.status.idle":"2024-04-09T19:39:57.843393Z","shell.execute_reply.started":"2024-04-09T19:39:57.837754Z","shell.execute_reply":"2024-04-09T19:39:57.842399Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_images(folder_path, num):\n    \"\"\"\n    Description:\n        Display a random selection of images from the specified folder path.\n\n    Parameters:\n        - folder_path (str): The path to the folder containing the images.\n        - num (int): The number of images to display.\n\n    Returns:\n        None\n    \"\"\"\n    images = glob.glob(folder_path+'/*')\n    selected_images = np.random.choice(images, num, replace=False)\n    \n    fig = plt.figure(figsize=(10, 6))\n    columns = 3\n    rows = (len(selected_images) // columns) + 1\n    for i, image_file in enumerate(selected_images):\n        img = plt.imread(image_file)\n        ax = fig.add_subplot(rows, columns, i+1)\n        ax.imshow(img)\n        ax.axis('off')\n    class_ = folder_path.split('/')[-1]\n    plt.suptitle(classes[class_])\n    plt.show()\n\n# show some random images from each class \nfor folder in glob.glob(train_path+'/*'):\n    show_images(folder, 6)\n","metadata":{"execution":{"iopub.status.busy":"2024-04-09T19:39:57.845585Z","iopub.execute_input":"2024-04-09T19:39:57.845899Z","iopub.status.idle":"2024-04-09T19:40:04.567807Z","shell.execute_reply.started":"2024-04-09T19:39:57.845858Z","shell.execute_reply":"2024-04-09T19:40:04.566828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_path = '/kaggle/input/state-farm-distracted-driver-detection/imgs/train/c1/img_100021.jpg'\nimg = io.read_image(img_path)\nimg.shape","metadata":{"execution":{"iopub.status.busy":"2024-04-09T19:40:04.569092Z","iopub.execute_input":"2024-04-09T19:40:04.569448Z","iopub.status.idle":"2024-04-09T19:40:04.605727Z","shell.execute_reply.started":"2024-04-09T19:40:04.569416Z","shell.execute_reply":"2024-04-09T19:40:04.604519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### BaseLine Dense Model","metadata":{}},{"cell_type":"code","source":"class BaselineDenseModel(nn.Module):\n    def __init__(self, input_size, num_classes):\n        super(BaselineDenseModel, self).__init__()\n        self.fc1 = nn.Linear(input_size, 256)\n        self.fc2 = nn.Linear(256, 128)\n        self.fc3 = nn.Linear(128, 64)\n        self.fc4 = nn.Linear(64, 32)\n        self.fc5 = nn.Linear(32, num_classes)\n        self.relu = nn.ReLU()\n        self.softmax = nn.Softmax(dim=1)\n        \n    def forward(self, x):\n        x = x.view(x.size(0), -1) # flatten the input\n        x = self.relu(self.fc1(x))\n        x = self.relu(self.fc2(x))\n        x = self.relu(self.fc3(x))\n        x = self.relu(self.fc4(x))\n        x = self.fc5(x)\n        return self.softmax(x)\n\n\ninput_size = 480*640*3\nnum_classes = 10\n\nmodel = BaselineDenseModel(input_size, num_classes)\n\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters())","metadata":{"execution":{"iopub.status.busy":"2024-04-09T19:40:04.607061Z","iopub.execute_input":"2024-04-09T19:40:04.607458Z","iopub.status.idle":"2024-04-09T19:40:07.114006Z","shell.execute_reply.started":"2024-04-09T19:40:04.607421Z","shell.execute_reply":"2024-04-09T19:40:07.113207Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Data Augmentation","metadata":{}},{"cell_type":"code","source":"train_transform = transforms.Compose([\n    transforms.Resize((480, 640)),\n    transforms.RandomHorizontalFlip(),\n    transforms.RandomRotation(degrees=10),\n    transforms.RandomAffine(degrees=0, translate=(0.1,0.1), scale=(1.0, 1.2)),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\n])\n\ntest_transform = transforms.Compose([\n    transforms.Resize((480, 640)),  \n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\n])\n","metadata":{"execution":{"iopub.status.busy":"2024-04-09T19:40:07.115167Z","iopub.execute_input":"2024-04-09T19:40:07.115468Z","iopub.status.idle":"2024-04-09T19:40:07.122589Z","shell.execute_reply.started":"2024-04-09T19:40:07.115442Z","shell.execute_reply":"2024-04-09T19:40:07.121661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset = datasets.ImageFolder(root=train_path, transform=train_transform)","metadata":{"execution":{"iopub.status.busy":"2024-04-09T19:40:07.123726Z","iopub.execute_input":"2024-04-09T19:40:07.123993Z","iopub.status.idle":"2024-04-09T19:40:17.546185Z","shell.execute_reply.started":"2024-04-09T19:40:07.123969Z","shell.execute_reply":"2024-04-09T19:40:17.545405Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset","metadata":{"execution":{"iopub.status.busy":"2024-04-09T19:40:17.547294Z","iopub.execute_input":"2024-04-09T19:40:17.547608Z","iopub.status.idle":"2024-04-09T19:40:17.553979Z","shell.execute_reply.started":"2024-04-09T19:40:17.547581Z","shell.execute_reply":"2024-04-09T19:40:17.553123Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class2idx = dataset.class_to_idx\nclass_indices = {v:k for k, v in class2idx.items()}\nclass_indices","metadata":{"execution":{"iopub.status.busy":"2024-04-09T19:40:17.556910Z","iopub.execute_input":"2024-04-09T19:40:17.557170Z","iopub.status.idle":"2024-04-09T19:40:17.565904Z","shell.execute_reply.started":"2024-04-09T19:40:17.557147Z","shell.execute_reply":"2024-04-09T19:40:17.565117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_size = int(0.8 * len(dataset))\nval_size = len(dataset) - train_size","metadata":{"execution":{"iopub.status.busy":"2024-04-09T19:40:17.566854Z","iopub.execute_input":"2024-04-09T19:40:17.567087Z","iopub.status.idle":"2024-04-09T19:40:17.575359Z","shell.execute_reply.started":"2024-04-09T19:40:17.567066Z","shell.execute_reply":"2024-04-09T19:40:17.574562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Split the dataset into training and validation sets\ntrain_dataset, val_dataset = random_split(dataset, [train_size, val_size])","metadata":{"execution":{"iopub.status.busy":"2024-04-09T19:40:17.576369Z","iopub.execute_input":"2024-04-09T19:40:17.576726Z","iopub.status.idle":"2024-04-09T19:40:17.596080Z","shell.execute_reply.started":"2024-04-09T19:40:17.576693Z","shell.execute_reply":"2024-04-09T19:40:17.595068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset.dataset.transform = train_transform\nval_dataset.dataset.transform = test_transform","metadata":{"execution":{"iopub.status.busy":"2024-04-09T19:40:17.597118Z","iopub.execute_input":"2024-04-09T19:40:17.597387Z","iopub.status.idle":"2024-04-09T19:40:17.601924Z","shell.execute_reply.started":"2024-04-09T19:40:17.597364Z","shell.execute_reply":"2024-04-09T19:40:17.600927Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> The issue with this dataset is that we only have the train folder without a separate validation set. To address this, I utilized `random_split` to split the train data into train and validation subsets. However, a problem arose where the same data augmentation techniques, such as random rotation and horizontal flip, were applied to both the train and validation sets. To rectify this, I modified the transformation pipeline to apply specific augmentation to the train data and specific preprocessing to the validation or new data.","metadata":{}},{"cell_type":"code","source":"batch_size = 32\ntrain_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\nval_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2024-04-09T19:40:17.603113Z","iopub.execute_input":"2024-04-09T19:40:17.603381Z","iopub.status.idle":"2024-04-09T19:40:17.612692Z","shell.execute_reply.started":"2024-04-09T19:40:17.603357Z","shell.execute_reply":"2024-04-09T19:40:17.611669Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = 'cuda' if torch.cuda.is_available() else 'cpu'\ndevice","metadata":{"execution":{"iopub.status.busy":"2024-04-09T19:40:17.613857Z","iopub.execute_input":"2024-04-09T19:40:17.614164Z","iopub.status.idle":"2024-04-09T19:40:17.671716Z","shell.execute_reply.started":"2024-04-09T19:40:17.614138Z","shell.execute_reply":"2024-04-09T19:40:17.670724Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_model(model, train_loader, val_loader, criterion, optimizer, num_epochs=10, device='cuda'):\n    \"\"\"\n    Description:\n        Train the given model using the provided data loaders and optimization parameters.\n\n    Parameters:\n        - model (torch.nn.Module): The neural network model to train.\n        - train_loader (torch.utils.data.DataLoader): DataLoader for training data.\n        - val_loader (torch.utils.data.DataLoader): DataLoader for validation data.\n        - criterion (torch.nn.Module): The loss function.\n        - optimizer (torch.optim.Optimizer): The optimizer used for updating model parameters.\n        - num_epochs (int): Number of training epochs (default: 10).\n        - device (str): Device to run the training on (default: 'cuda').\n\n    Returns:\n        - model (torch.nn.Module): The trained model.\n        - history (dict): A dictionary containing training history with keys:\n            - 'train_loss': List of training losses for each epoch.\n            - 'train_acc': List of training accuracies for each epoch.\n            - 'val_loss': List of validation losses for each epoch.\n            - 'val_acc': List of validation accuracies for each epoch.\n\n    \"\"\"\n    \n    model.to(device)\n    history = {'train_loss': [], 'train_acc': [], 'val_loss': [], 'val_acc': []}\n    \n    for epoch in tqdm(range(num_epochs)):\n        # Training phase\n        model.train()\n        train_loss = 0.0\n        correct_train = 0\n        total_train_images = 0\n        for inputs, labels in train_loader:\n            inputs, labels = inputs.to(device), labels.to(device)\n            optimizer.zero_grad()\n            outputs = model(inputs)\n            loss = criterion(outputs, labels)\n            loss.backward()\n            optimizer.step()\n\n            train_loss += loss.item()\n            _, predicted = torch.max(outputs.data, dim=1)\n            correct_train += (predicted == labels).sum().item()\n            total_train_images += labels.size(0)\n            \n\n        train_accuracy = 100 * correct_train / total_train_images\n        avg_train_loss = train_loss / len(train_loader)\n\n        # Validation phase\n        model.eval()\n        val_loss = 0.0\n        correct_val = 0\n        total_val_images = 0\n        with torch.no_grad():\n            for inputs, labels in val_loader:\n                inputs, labels = inputs.to(device), labels.to(device)\n                outputs = model(inputs)\n                loss = criterion(outputs, labels)\n\n                val_loss += loss.item()\n                _, predicted = torch.max(outputs.data, 1)\n                correct_val += (predicted == labels).sum().item()\n                total_val_images += labels.size(0)\n                \n\n        val_accuracy = 100 * correct_val / total_val_images\n        avg_val_loss = val_loss / len(val_loader)\n\n        # Print epoch statistics\n        print(f\"Epoch [{epoch+1}/{num_epochs}]\\nTrain Loss: {avg_train_loss:.4f}, Train Acc: {train_accuracy:.2f}%, Val Loss: {avg_val_loss:.4f}, Val Acc: {val_accuracy:.2f}%\")\n\n        # Save history\n        history['train_loss'].append(avg_train_loss)\n        history['train_acc'].append(train_accuracy)\n        history['val_loss'].append(avg_val_loss)\n        history['val_acc'].append(val_accuracy)\n\n    return model, history\n","metadata":{"execution":{"iopub.status.busy":"2024-04-09T19:40:17.673194Z","iopub.execute_input":"2024-04-09T19:40:17.673539Z","iopub.status.idle":"2024-04-09T19:40:17.688724Z","shell.execute_reply.started":"2024-04-09T19:40:17.673507Z","shell.execute_reply":"2024-04-09T19:40:17.687821Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trained_model, history = train_model(model, train_loader, val_loader, criterion, optimizer, num_epochs=5)","metadata":{"execution":{"iopub.status.busy":"2024-04-09T19:40:17.689935Z","iopub.execute_input":"2024-04-09T19:40:17.690582Z","iopub.status.idle":"2024-04-09T20:00:13.320550Z","shell.execute_reply.started":"2024-04-09T19:40:17.690548Z","shell.execute_reply":"2024-04-09T20:00:13.319574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_performance(history):\n    \"\"\"\n    Description:\n        Plot the training and validation loss, as well as training and validation accuracy over epochs.\n\n    Parameters:\n        - history (dict): A dictionary containing training history with keys:\n        - 'train_loss': List of training losses for each epoch.\n        - 'train_acc': List of training accuracies for each epoch.\n        - 'val_loss': List of validation losses for each epoch.\n        - 'val_acc': List of validation accuracies for each epoch.\n\n    Returns:\n        None\n    \"\"\"\n    \n    epochs = range(1, len(history['train_loss']) + 1)\n\n    # Plot loss\n    plt.figure(figsize=(12, 5))\n    plt.subplot(1, 2, 1)\n    plt.plot(epochs, history['train_loss'], 'b-', label='Training Loss')\n    plt.plot(epochs, history['val_loss'], 'r-', label='Validation Loss')\n    plt.title('Training and Validation Loss')\n    plt.xlabel('Epochs')\n    plt.ylabel('Loss')\n    plt.legend()\n\n    # Plot accuracy\n    plt.subplot(1, 2, 2)\n    plt.plot(epochs, history['train_acc'], 'b-', label='Training Accuracy')\n    plt.plot(epochs, history['val_acc'], 'r-', label='Validation Accuracy')\n    plt.title('Training and Validation Accuracy')\n    plt.xlabel('Epochs')\n    plt.ylabel('Accuracy (%)')\n    plt.legend()\n\n    plt.tight_layout()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-04-09T20:00:44.520396Z","iopub.execute_input":"2024-04-09T20:00:44.520874Z","iopub.status.idle":"2024-04-09T20:00:44.529164Z","shell.execute_reply.started":"2024-04-09T20:00:44.520840Z","shell.execute_reply":"2024-04-09T20:00:44.528171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_performance(history)","metadata":{"execution":{"iopub.status.busy":"2024-04-09T20:00:45.231894Z","iopub.execute_input":"2024-04-09T20:00:45.232246Z","iopub.status.idle":"2024-04-09T20:00:46.001407Z","shell.execute_reply.started":"2024-04-09T20:00:45.232218Z","shell.execute_reply":"2024-04-09T20:00:46.000366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### BaseLine CNN","metadata":{}},{"cell_type":"code","source":"class BaselineCNN(nn.Module):\n    def __init__(self, num_classes):\n        super(BaselineCNN, self).__init__()\n        self.conv1 = nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3, stride=1, padding=1)\n        self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, stride=1, padding=1)\n        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)\n        self.fc1 = nn.Linear(64 * 37 * 37, 512)  # Adjusted input size based on the output of conv2\n        self.fc2 = nn.Linear(512, num_classes)\n\n    def forward(self, x):\n        x = self.pool(torch.relu(self.conv1(x)))\n        x = self.pool(torch.relu(self.conv2(x)))\n        x = x.view(-1, 64 * 37 * 37)  # Adjusted reshape based on the output size of conv2\n        x = torch.relu(self.fc1(x))\n        x = self.fc2(x)\n        return x\n\nmodel = BaselineCNN(num_classes=10)","metadata":{"execution":{"iopub.status.busy":"2024-04-09T20:01:05.138000Z","iopub.execute_input":"2024-04-09T20:01:05.138380Z","iopub.status.idle":"2024-04-09T20:01:05.597846Z","shell.execute_reply.started":"2024-04-09T20:01:05.138349Z","shell.execute_reply":"2024-04-09T20:01:05.596971Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_transform = transforms.Compose([\n    transforms.Resize((150, 150)),\n    transforms.RandomHorizontalFlip(),\n    transforms.RandomRotation(degrees=10),\n    transforms.RandomAffine(degrees=0, translate=(0.1,0.1), scale=(1.0, 1.2)),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\n])\n\ntest_transform = transforms.Compose([\n    transforms.Resize((150, 150)),  \n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\n])\n","metadata":{"execution":{"iopub.status.busy":"2024-04-09T20:01:08.824796Z","iopub.execute_input":"2024-04-09T20:01:08.825186Z","iopub.status.idle":"2024-04-09T20:01:08.833562Z","shell.execute_reply.started":"2024-04-09T20:01:08.825153Z","shell.execute_reply":"2024-04-09T20:01:08.832515Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset = datasets.ImageFolder(root=train_path, transform=train_transform)","metadata":{"execution":{"iopub.status.busy":"2024-04-09T20:01:11.255787Z","iopub.execute_input":"2024-04-09T20:01:11.256129Z","iopub.status.idle":"2024-04-09T20:01:17.538454Z","shell.execute_reply.started":"2024-04-09T20:01:11.256102Z","shell.execute_reply":"2024-04-09T20:01:17.537660Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset","metadata":{"execution":{"iopub.status.busy":"2024-04-09T20:01:17.540229Z","iopub.execute_input":"2024-04-09T20:01:17.540535Z","iopub.status.idle":"2024-04-09T20:01:17.546813Z","shell.execute_reply.started":"2024-04-09T20:01:17.540510Z","shell.execute_reply":"2024-04-09T20:01:17.545921Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class2idx = dataset.class_to_idx\nclass_indices = {v:k for k, v in class2idx.items()}\nclass_indices","metadata":{"execution":{"iopub.status.busy":"2024-04-09T20:01:17.548006Z","iopub.execute_input":"2024-04-09T20:01:17.548257Z","iopub.status.idle":"2024-04-09T20:01:17.557877Z","shell.execute_reply.started":"2024-04-09T20:01:17.548234Z","shell.execute_reply":"2024-04-09T20:01:17.556994Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_size = int(0.8 * len(dataset))\nval_size = len(dataset) - train_size","metadata":{"execution":{"iopub.status.busy":"2024-04-09T20:01:17.559868Z","iopub.execute_input":"2024-04-09T20:01:17.560217Z","iopub.status.idle":"2024-04-09T20:01:17.570482Z","shell.execute_reply.started":"2024-04-09T20:01:17.560184Z","shell.execute_reply":"2024-04-09T20:01:17.569398Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Split the dataset into training and validation sets\ntrain_dataset, val_dataset = random_split(dataset, [train_size, val_size])","metadata":{"execution":{"iopub.status.busy":"2024-04-09T20:01:18.886509Z","iopub.execute_input":"2024-04-09T20:01:18.886893Z","iopub.status.idle":"2024-04-09T20:01:18.892687Z","shell.execute_reply.started":"2024-04-09T20:01:18.886861Z","shell.execute_reply":"2024-04-09T20:01:18.891798Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset.dataset.transform = train_transform\nval_dataset.dataset.transform = test_transform","metadata":{"execution":{"iopub.status.busy":"2024-04-09T20:01:22.411163Z","iopub.execute_input":"2024-04-09T20:01:22.411798Z","iopub.status.idle":"2024-04-09T20:01:22.416042Z","shell.execute_reply.started":"2024-04-09T20:01:22.411763Z","shell.execute_reply":"2024-04-09T20:01:22.414992Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 32\ntrain_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\nval_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2024-04-09T20:01:23.547966Z","iopub.execute_input":"2024-04-09T20:01:23.548563Z","iopub.status.idle":"2024-04-09T20:01:23.554592Z","shell.execute_reply.started":"2024-04-09T20:01:23.548532Z","shell.execute_reply":"2024-04-09T20:01:23.553796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> The issue here appears to be memory crashes due to the large size of the images. I tried to solve this issue by reducing batch size and simplifying the model architecture, but the problem persisted. As a solution, resizing the images from (480, 640) to (150, 150) has resolved the problem.","metadata":{}},{"cell_type":"code","source":"criterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters())","metadata":{"execution":{"iopub.status.busy":"2024-04-09T20:01:24.195095Z","iopub.execute_input":"2024-04-09T20:01:24.195508Z","iopub.status.idle":"2024-04-09T20:01:24.201420Z","shell.execute_reply.started":"2024-04-09T20:01:24.195476Z","shell.execute_reply":"2024-04-09T20:01:24.200449Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trained_model, history = train_model(model, train_loader, val_loader, criterion, optimizer, num_epochs=6)","metadata":{"execution":{"iopub.status.busy":"2024-04-09T20:01:29.753477Z","iopub.execute_input":"2024-04-09T20:01:29.754367Z","iopub.status.idle":"2024-04-09T20:16:13.174684Z","shell.execute_reply.started":"2024-04-09T20:01:29.754331Z","shell.execute_reply":"2024-04-09T20:16:13.173595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_performance(history)","metadata":{"execution":{"iopub.status.busy":"2024-04-09T20:23:09.609980Z","iopub.execute_input":"2024-04-09T20:23:09.610808Z","iopub.status.idle":"2024-04-09T20:23:10.294013Z","shell.execute_reply.started":"2024-04-09T20:23:09.610769Z","shell.execute_reply":"2024-04-09T20:23:10.293054Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Test model on Test Data","metadata":{}},{"cell_type":"code","source":"def predict_folder(folder_path, model):\n    probabilities_per_image = []\n    images = []\n\n    for img_path in glob.glob(folder_path+'/*'):\n        image = Image.open(img_path)\n        image = test_transform(image).unsqueeze(0) # batch dimension\n        \n        model.eval()\n        with torch.no_grad():\n            image = image.to(device)\n            output = model(image)\n\n        # Apply softmax to obtain probabilities\n        probabilities = torch.softmax(output, dim=1)\n        probabilities = probabilities.squeeze(0).tolist()\n\n        images.append(img_path.split('/')[-1])\n        probabilities_per_image.append(probabilities)\n\n    return images, probabilities_per_image\n","metadata":{"execution":{"iopub.status.busy":"2024-04-09T20:46:10.331219Z","iopub.execute_input":"2024-04-09T20:46:10.331627Z","iopub.status.idle":"2024-04-09T20:46:10.339708Z","shell.execute_reply.started":"2024-04-09T20:46:10.331585Z","shell.execute_reply":"2024-04-09T20:46:10.338547Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Example usage\nfolder_path = '/kaggle/input/state-farm-distracted-driver-detection/imgs/test'\nimages, probabilities_per_image = predict_folder(folder_path, trained_model)","metadata":{"execution":{"iopub.status.busy":"2024-04-09T20:46:11.596694Z","iopub.execute_input":"2024-04-09T20:46:11.597063Z","iopub.status.idle":"2024-04-09T21:07:08.849089Z","shell.execute_reply.started":"2024-04-09T20:46:11.597035Z","shell.execute_reply":"2024-04-09T21:07:08.847955Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(probabilities_per_image)","metadata":{"execution":{"iopub.status.busy":"2024-04-09T21:07:52.891327Z","iopub.execute_input":"2024-04-09T21:07:52.891828Z","iopub.status.idle":"2024-04-09T21:07:52.898888Z","shell.execute_reply.started":"2024-04-09T21:07:52.891796Z","shell.execute_reply":"2024-04-09T21:07:52.897661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df1 = pd.DataFrame({'img': images})\ndf2 = pd.DataFrame(probabilities_per_image, columns = ['c0', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9'])\nfinal_sub = pd.concat((df1, df2), axis=1)\nfinal_sub","metadata":{"execution":{"iopub.status.busy":"2024-04-09T21:12:04.751489Z","iopub.execute_input":"2024-04-09T21:12:04.752374Z","iopub.status.idle":"2024-04-09T21:12:04.882031Z","shell.execute_reply.started":"2024-04-09T21:12:04.752338Z","shell.execute_reply":"2024-04-09T21:12:04.880951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"final_sub.isnull().sum()","metadata":{"execution":{"iopub.status.busy":"2024-04-09T21:12:24.239995Z","iopub.execute_input":"2024-04-09T21:12:24.240739Z","iopub.status.idle":"2024-04-09T21:12:24.259808Z","shell.execute_reply.started":"2024-04-09T21:12:24.240703Z","shell.execute_reply":"2024-04-09T21:12:24.258585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"final_sub.to_csv('final_sub.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-04-09T21:13:41.660321Z","iopub.execute_input":"2024-04-09T21:13:41.661223Z","iopub.status.idle":"2024-04-09T21:13:43.577231Z","shell.execute_reply.started":"2024-04-09T21:13:41.661184Z","shell.execute_reply":"2024-04-09T21:13:43.576343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Transfer Learning","metadata":{}},{"cell_type":"code","source":"transfer_model = models.resnet18(pretrained=True)\nnum = transfer_model.fc.in_features\ntransfer_model.fc = nn.Linear(num, 10)\n\ntrained_transfer_model, history = train_model(transfer_model, train_loader, val_loader, criterion, optimizer, num_epochs=6)","metadata":{"execution":{"iopub.status.busy":"2024-04-09T21:14:52.071771Z","iopub.execute_input":"2024-04-09T21:14:52.072438Z","iopub.status.idle":"2024-04-09T21:31:17.200994Z","shell.execute_reply.started":"2024-04-09T21:14:52.072406Z","shell.execute_reply":"2024-04-09T21:31:17.199837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> Now, We will ignore the previous accuracy and loss😂 and say that the best model for this problem is simple CNN.","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}