{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":5048,"databundleVersionId":868335,"sourceType":"competition"}],"dockerImageVersionId":31041,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import torch\nimport numpy as np\nimport pandas as pd\nimport torch.nn as nn\nfrom torch import optim\nfrom torchvision.datasets import ImageFolder\nfrom torchvision import transforms, models\nfrom torch.utils.data import random_split, DataLoader\nfrom tqdm import tqdm\nfrom sklearn.metrics import f1_score","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-06-22T10:08:34.261470Z","iopub.execute_input":"2025-06-22T10:08:34.261707Z","iopub.status.idle":"2025-06-22T10:08:38.338521Z","shell.execute_reply.started":"2025-06-22T10:08:34.261687Z","shell.execute_reply":"2025-06-22T10:08:38.337668Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"root_dir = '/kaggle/input/state-farm-distracted-driver-detection/imgs/train'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-22T10:08:38.339292Z","iopub.execute_input":"2025-06-22T10:08:38.339616Z","iopub.status.idle":"2025-06-22T10:08:38.343120Z","shell.execute_reply.started":"2025-06-22T10:08:38.339599Z","shell.execute_reply":"2025-06-22T10:08:38.342504Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.Resize((320, 320)),\n    transforms.ToTensor(),\n    transforms.Normalize(\n        mean=[0.485, 0.456, 0.406],\n        std=[0.229, 0.224, 0.225]\n    )\n])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-22T10:08:38.344828Z","iopub.execute_input":"2025-06-22T10:08:38.345020Z","iopub.status.idle":"2025-06-22T10:08:38.361162Z","shell.execute_reply.started":"2025-06-22T10:08:38.345006Z","shell.execute_reply":"2025-06-22T10:08:38.360489Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dataset = ImageFolder(root = root_dir, transform = transform)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-22T10:08:38.361883Z","iopub.execute_input":"2025-06-22T10:08:38.362301Z","iopub.status.idle":"2025-06-22T10:08:58.781063Z","shell.execute_reply.started":"2025-06-22T10:08:38.362280Z","shell.execute_reply":"2025-06-22T10:08:58.780263Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_dataset, test_dataset = random_split(dataset, [round(0.8*(len(dataset))), round(0.2*(len(dataset)))])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-22T10:08:58.781940Z","iopub.execute_input":"2025-06-22T10:08:58.782199Z","iopub.status.idle":"2025-06-22T10:08:58.787708Z","shell.execute_reply.started":"2025-06-22T10:08:58.782176Z","shell.execute_reply":"2025-06-22T10:08:58.786992Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_loader = DataLoader(train_dataset, batch_size=8, shuffle = True)\ntest_loader = DataLoader(test_dataset, batch_size=8, shuffle = False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-22T10:08:58.788459Z","iopub.execute_input":"2025-06-22T10:08:58.789133Z","iopub.status.idle":"2025-06-22T10:08:58.804082Z","shell.execute_reply.started":"2025-06-22T10:08:58.789115Z","shell.execute_reply":"2025-06-22T10:08:58.803366Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class EfficientNetClassifier(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.aboba = models.efficientnet_b3(pretrained=True)\n        self.MLP = nn.Sequential(\n            nn.Linear(1000, 512),\n            nn.ReLU(),\n            nn.Dropout(0.2),\n            nn.Linear(512, 128),\n            nn.ReLU(),\n            nn.Dropout(0.2),\n            nn.Linear(128, 64),\n            nn.ReLU(),\n            nn.Dropout(0.2),\n            nn.Linear(64, 10),\n        )\n\n    def forward(self, x):\n        x = self.aboba(x)\n        x = self.MLP(x)\n        return x","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-22T10:08:58.804845Z","iopub.execute_input":"2025-06-22T10:08:58.805311Z","iopub.status.idle":"2025-06-22T10:08:58.820643Z","shell.execute_reply.started":"2025-06-22T10:08:58.805287Z","shell.execute_reply":"2025-06-22T10:08:58.819939Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = EfficientNetClassifier()\noptimizer = optim.Adam(model.parameters(), lr=0.001)\ncriterion = nn.CrossEntropyLoss()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-22T10:08:58.821222Z","iopub.execute_input":"2025-06-22T10:08:58.821452Z","iopub.status.idle":"2025-06-22T10:08:59.144061Z","shell.execute_reply.started":"2025-06-22T10:08:58.821428Z","shell.execute_reply":"2025-06-22T10:08:59.143297Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device = torch.device('cuda')\nmodel = model.to(device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-22T10:08:59.145894Z","iopub.execute_input":"2025-06-22T10:08:59.146110Z","iopub.status.idle":"2025-06-22T10:08:59.312346Z","shell.execute_reply.started":"2025-06-22T10:08:59.146093Z","shell.execute_reply":"2025-06-22T10:08:59.311809Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"losses = []\nfs = []\nvalid = []\n\nfor epoch in range(10):\n    model.train()\n    \n    running_loss = 0.0\n    running_f1 = 0.0\n\n    num_batches = 0\n    for inputs, labels in (bar := tqdm(train_loader)):\n        inputs = inputs.to(device)\n        labels = labels.to(device)\n        \n        optimizer.zero_grad()\n        outputs = model(inputs)\n\n        loss = criterion(outputs, labels.long())\n        loss.backward()\n        optimizer.step()\n        running_loss += loss.item()\n        num_batches += 1\n        \n        \n        score = f1_score(labels.detach().cpu().numpy(), np.argmax(outputs.detach().cpu().numpy(), axis=1), average='macro')\n        running_f1 += score\n        bar.set_description(f\"Epoch: {epoch + 1}, Loss by batch: {loss.item():.4f}, F1 by epoch: {score:.4f}\")\n\n\n    all_preds = []\n    all_labels = []\n\n    model.eval()\n    with torch.no_grad():\n        for inputs, labels in test_loader:\n            inputs = inputs.to(device)\n            labels = labels.to(device)\n    \n            outputs = model(inputs)\n            preds = np.argmax(outputs.cpu(), axis=1)\n    \n            all_preds.extend(preds.cpu().numpy())\n            all_labels.extend(labels.cpu().numpy())\n            \n    f1_valid = f1_score(all_labels, all_preds, average='macro')\n    print(f\"Epoch: {epoch + 1}, mean loss on epoch: {running_loss / num_batches}, mean F1: {running_f1 / num_batches}, F1 valid: {f1_valid}\")\n    valid.append(f1_valid)\n    losses.append(running_loss / num_batches)\n    fs.append(running_f1 / num_batches)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-22T10:08:59.313161Z","iopub.execute_input":"2025-06-22T10:08:59.313436Z","iopub.status.idle":"2025-06-22T11:20:33.233023Z","shell.execute_reply.started":"2025-06-22T10:08:59.313414Z","shell.execute_reply":"2025-06-22T11:20:33.232403Z"}},"outputs":[],"execution_count":null}]}