{"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":"markdown","source":"After few EDA notebooks already submitted (Attaching them below!), let's get to a baseline to get started with.\n[Aditya's EDA](https://www.kaggle.com/code/adityaparikh668/know-your-data-eda)","metadata":{}},{"cell_type":"markdown","source":"# A simple CNN using PyTorch ! Best way to get started with your Deep Learning journey\n# Do UPVOTE! Will be sharing advance approaches and analysis as competition progresses!","metadata":{}},{"cell_type":"markdown","source":"**Import Stuffs**","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport os\nfrom PIL import Image\nfrom torch.utils.data import Dataset, DataLoader, random_split\nfrom torchvision import transforms\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torchvision.models as models\nfrom torchvision.datasets import ImageFolder\nfrom torchvision.utils import make_grid\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2023-10-07T18:35:55.782725Z","iopub.execute_input":"2023-10-07T18:35:55.78308Z","iopub.status.idle":"2023-10-07T18:35:55.789035Z","shell.execute_reply.started":"2023-10-07T18:35:55.783049Z","shell.execute_reply":"2023-10-07T18:35:55.787933Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Get your data ready for data loader**","metadata":{}},{"cell_type":"code","source":"train_df = pd.read_csv('/kaggle/input/UBC-OCEAN/train.csv')","metadata":{"execution":{"iopub.status.busy":"2023-10-07T18:28:31.242849Z","iopub.execute_input":"2023-10-07T18:28:31.243791Z","iopub.status.idle":"2023-10-07T18:28:31.268428Z","shell.execute_reply.started":"2023-10-07T18:28:31.243752Z","shell.execute_reply":"2023-10-07T18:28:31.267609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"target_labels = train_df.is_tma.astype('int') # True/False into 0/1\ntrain_ids = train_df.image_id\ntbn_images_list = os.listdir('/kaggle/input/UBC-OCEAN/train_thumbnails')","metadata":{"execution":{"iopub.status.busy":"2023-10-07T18:28:33.831978Z","iopub.execute_input":"2023-10-07T18:28:33.832392Z","iopub.status.idle":"2023-10-07T18:28:33.997369Z","shell.execute_reply.started":"2023-10-07T18:28:33.832357Z","shell.execute_reply":"2023-10-07T18:28:33.996472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"file_dict = {}\n\nfor file_name in tbn_images_list:\n    parts = file_name.split('_')\n    \n    file_id = parts[0]\n    file_dict[file_id] = file_name\n    \n# Made a dictionary with image id as key and image names as value\n# Print this dict and check!","metadata":{"execution":{"iopub.status.busy":"2023-10-07T18:28:35.647681Z","iopub.execute_input":"2023-10-07T18:28:35.648056Z","iopub.status.idle":"2023-10-07T18:28:35.65365Z","shell.execute_reply.started":"2023-10-07T18:28:35.648019Z","shell.execute_reply":"2023-10-07T18:28:35.652566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# I see some images are missing from thumbnails, no discard them from our scope for the timing\n\nunique_ids = set(train_df['image_id'])\n\n\nfiltered_dict = {key: value for key, value in file_dict.items() if int(key) in unique_ids}","metadata":{"execution":{"iopub.status.busy":"2023-10-07T18:28:37.309906Z","iopub.execute_input":"2023-10-07T18:28:37.310231Z","iopub.status.idle":"2023-10-07T18:28:37.316219Z","shell.execute_reply.started":"2023-10-07T18:28:37.310201Z","shell.execute_reply":"2023-10-07T18:28:37.315Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Just making sure\nlen(filtered_dict) == len(tbn_images_list)","metadata":{"execution":{"iopub.status.busy":"2023-10-07T18:28:38.809001Z","iopub.execute_input":"2023-10-07T18:28:38.809307Z","iopub.status.idle":"2023-10-07T18:28:38.815598Z","shell.execute_reply.started":"2023-10-07T18:28:38.809282Z","shell.execute_reply":"2023-10-07T18:28:38.814763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Setup your dataset for injection**","metadata":{}},{"cell_type":"code","source":"# Make your custom dataset loader\n\nclass UCBDataset(Dataset):\n    def __init__(self, data_dict, root_dir, labels, transform=None):\n        self.data_dict = data_dict\n        self.root_dir = root_dir\n        self.labels = labels\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.data_dict)\n\n    def __getitem__(self, idx):\n        image_id, image_path = list(self.data_dict.items())[idx]\n        image = Image.open(os.path.join(self.root_dir, image_path))\n\n        if self.transform:\n            image = self.transform(image)\n\n        label = self.labels[idx]\n\n        return image, label #Throws images with its target label","metadata":{"execution":{"iopub.status.busy":"2023-10-07T18:28:40.274507Z","iopub.execute_input":"2023-10-07T18:28:40.275107Z","iopub.status.idle":"2023-10-07T18:28:40.280948Z","shell.execute_reply.started":"2023-10-07T18:28:40.275078Z","shell.execute_reply":"2023-10-07T18:28:40.280098Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_root_dir = \"/kaggle/input/UBC-OCEAN/train_thumbnails\"\n\ntransform = transforms.Compose([\n    transforms.Resize((224, 224)),  # Baseline\n    transforms.ToTensor()\n])\n\ncustom_dataset = UCBDataset(data_dict=filtered_dict, root_dir=image_root_dir, labels = target_labels,transform=transform)\n\n# Making a validation split\nval_ratio = 0.2\ndataset_size = len(custom_dataset)\nval_size = int(val_ratio * dataset_size)\ntrain_size = dataset_size - val_size\ntrain_dataset, val_dataset = random_split(custom_dataset, [train_size, val_size])\n\n# Loading it into a dataloader\nbatch_size = 32\ntrain_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\nval_loader = DataLoader(val_dataset, batch_size=batch_size)","metadata":{"execution":{"iopub.status.busy":"2023-10-07T18:36:21.966187Z","iopub.execute_input":"2023-10-07T18:36:21.966529Z","iopub.status.idle":"2023-10-07T18:36:21.973772Z","shell.execute_reply.started":"2023-10-07T18:36:21.966501Z","shell.execute_reply":"2023-10-07T18:36:21.972876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Use a GPU to go BRrrrrrrrrrrrrrr**","metadata":{}},{"cell_type":"code","source":"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nprint(device)","metadata":{"execution":{"iopub.status.busy":"2023-10-07T18:36:26.804552Z","iopub.execute_input":"2023-10-07T18:36:26.804932Z","iopub.status.idle":"2023-10-07T18:36:26.810699Z","shell.execute_reply.started":"2023-10-07T18:36:26.804904Z","shell.execute_reply":"2023-10-07T18:36:26.809429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**A simple CNN to start with**","metadata":{}},{"cell_type":"code","source":"class SimpleCNN(nn.Module):\n    def __init__(self):\n        super(SimpleCNN, self).__init__()\n        self.conv1 = nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1)\n        self.relu1 = nn.ReLU()\n        self.maxpool1 = nn.MaxPool2d(kernel_size=2, stride=2)\n        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1)\n        self.relu2 = nn.ReLU()\n        self.maxpool2 = nn.MaxPool2d(kernel_size=2, stride=2)\n        self.fc1 = nn.Linear(32 * 56 * 56, 128)  \n        self.relu3 = nn.ReLU()\n        self.fc2 = nn.Linear(128, 2)  \n\n    def forward(self, x):\n        x = self.conv1(x)\n        x = self.relu1(x)\n        x = self.maxpool1(x)\n        x = self.conv2(x)\n        x = self.relu2(x)\n        x = self.maxpool2(x)\n        x = x.view(x.size(0), -1)\n        x = self.fc1(x)\n        x = self.relu3(x)\n        x = self.fc2(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2023-10-07T18:36:28.765138Z","iopub.execute_input":"2023-10-07T18:36:28.765459Z","iopub.status.idle":"2023-10-07T18:36:28.772575Z","shell.execute_reply.started":"2023-10-07T18:36:28.765432Z","shell.execute_reply":"2023-10-07T18:36:28.7717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = SimpleCNN().to(device) # Load model to GPU\n\ncriterion = nn.CrossEntropyLoss() # remember using a focal loss due to imbalanced and also augment it later\noptimizer = optim.Adam(model.parameters(), lr=0.001) # Will use a learning rate scheduler later","metadata":{"execution":{"iopub.status.busy":"2023-10-07T18:36:33.741019Z","iopub.execute_input":"2023-10-07T18:36:33.741345Z","iopub.status.idle":"2023-10-07T18:36:33.878286Z","shell.execute_reply.started":"2023-10-07T18:36:33.741318Z","shell.execute_reply":"2023-10-07T18:36:33.877362Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_epochs = 10 # Good to start with 10\n\n# Save losses for plot \ntrain_losses = []  \nval_losses = []    \nval_accuracies = []  \n\n# Standard forward-backward propagation\nfor epoch in range(num_epochs):\n    model.train()\n    running_loss = 0.0\n    for i, (images, labels) in enumerate(train_loader, 0):\n        images, labels = images.to(device), labels.to(device)\n        optimizer.zero_grad()\n        outputs = model(images)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n        running_loss += loss.item()\n\n    avg_train_loss = running_loss / len(train_loader)\n    train_losses.append(avg_train_loss)\n\n    # Validation\n    model.eval()\n    val_loss = 0.0\n    correct = 0\n    total = 0\n    with torch.no_grad():\n        for images, labels in val_loader:\n            images, labels = images.to(device), labels.to(device)\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n            val_loss += loss.item()\n\n            _, predicted = torch.max(outputs.data, 1)\n            total += labels.size(0)\n            correct += (predicted == labels).sum().item()\n\n    avg_val_loss = val_loss / len(val_loader)\n    val_losses.append(avg_val_loss)\n\n    accuracy = 100 * correct / total # Messed up accuracy metric, ignore accuracy in logs\n    val_accuracies.append(accuracy)\n\n    print(f'Epoch [{epoch + 1}/{num_epochs}], '\n          f'Train Loss: {avg_train_loss:.4f}, '\n          f'Validation Loss: {avg_val_loss:.4f}, '\n          f'Validation Accuracy: {accuracy:.2f}%')","metadata":{"execution":{"iopub.status.busy":"2023-10-07T18:37:47.263326Z","iopub.execute_input":"2023-10-07T18:37:47.263679Z","iopub.status.idle":"2023-10-07T18:53:35.76733Z","shell.execute_reply.started":"2023-10-07T18:37:47.26364Z","shell.execute_reply":"2023-10-07T18:53:35.766274Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(12, 6))\nplt.plot(train_losses, label='Training Loss', color='blue', linestyle='-', linewidth=1)\nplt.plot(val_losses, label='Validation Loss', color='red', linestyle='-', linewidth=1)\n\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend(loc='upper right')\n\nplt.title('Training and Validation Losses')\nplt.grid(True)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-10-07T18:53:41.243416Z","iopub.execute_input":"2023-10-07T18:53:41.243764Z","iopub.status.idle":"2023-10-07T18:53:41.59829Z","shell.execute_reply.started":"2023-10-07T18:53:41.243736Z","shell.execute_reply":"2023-10-07T18:53:41.597444Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"It did not generalize well, but good to start with.\nWe now know what to expect and how to!","metadata":{}},{"cell_type":"markdown","source":"# Do hit that upvote! Will start sharing advance approaches from now! Best Luck!","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}