{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"}],"dockerImageVersionId":30776,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"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/working'):\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","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-09-30T07:20:20.322630Z","iopub.execute_input":"2024-09-30T07:20:20.322980Z","iopub.status.idle":"2024-09-30T07:20:21.305153Z","shell.execute_reply.started":"2024-09-30T07:20:20.322940Z","shell.execute_reply":"2024-09-30T07:20:21.304179Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import zipfile\nimport os\nimport shutil\n\nimport tensorflow as tf\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# PyTorch imports\nimport torch\nimport torchvision.transforms as transforms\nimport torchvision.datasets as datasets\nfrom torch.utils.data import random_split\n\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import datasets, transforms\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nfrom torch.autograd import Variable\nimport torch.optim.optimizer as optimizer\nimport torch.optim as optim","metadata":{"execution":{"iopub.status.busy":"2024-09-30T07:20:21.307204Z","iopub.execute_input":"2024-09-30T07:20:21.307754Z","iopub.status.idle":"2024-09-30T07:20:38.308271Z","shell.execute_reply.started":"2024-09-30T07:20:21.307707Z","shell.execute_reply":"2024-09-30T07:20:38.307320Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define paths\ninput_dir = '/kaggle/input/dogs-vs-cats/'\noutput_dir = '/kaggle/working/dogs-vs-cats/'\n\n# Unzip the train and test datasets\nwith zipfile.ZipFile(input_dir + 'train.zip', 'r') as zip_ref:\n    zip_ref.extractall(output_dir)\n\nwith zipfile.ZipFile(input_dir + 'test1.zip', 'r') as zip_ref:\n    zip_ref.extractall(output_dir)","metadata":{"execution":{"iopub.status.busy":"2024-09-30T07:20:38.309740Z","iopub.execute_input":"2024-09-30T07:20:38.310475Z","iopub.status.idle":"2024-09-30T07:20:53.192729Z","shell.execute_reply.started":"2024-09-30T07:20:38.310428Z","shell.execute_reply":"2024-09-30T07:20:53.191710Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Organize the train dataset\ntrain_dir = output_dir + 'train/'\ncat_dir = train_dir + 'cat/'\ndog_dir = train_dir + 'dog/'","metadata":{"execution":{"iopub.status.busy":"2024-09-30T07:20:53.194790Z","iopub.execute_input":"2024-09-30T07:20:53.195142Z","iopub.status.idle":"2024-09-30T07:20:53.200112Z","shell.execute_reply.started":"2024-09-30T07:20:53.195108Z","shell.execute_reply":"2024-09-30T07:20:53.199049Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create directories for cats and dogs\nos.makedirs(cat_dir, exist_ok=True)\nos.makedirs(dog_dir, exist_ok=True)\n\n# Move only image files to respective folders\nfor filename in os.listdir(train_dir):\n    if filename.lower().endswith('.jpg'):  # Check if it's an image file\n        if 'cat' in filename.lower():\n            shutil.move(os.path.join(train_dir, filename), os.path.join(cat_dir, filename))\n        elif 'dog' in filename.lower():\n            shutil.move(os.path.join(train_dir, filename), os.path.join(dog_dir, filename))\n\nprint(\"Images have been organized into cat and dog folders.\")","metadata":{"execution":{"iopub.status.busy":"2024-09-30T07:20:53.201477Z","iopub.execute_input":"2024-09-30T07:20:53.201812Z","iopub.status.idle":"2024-09-30T07:20:54.082195Z","shell.execute_reply.started":"2024-09-30T07:20:53.201779Z","shell.execute_reply":"2024-09-30T07:20:54.081250Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_dir = '/kaggle/working/dogs-vs-cats/'\n\n#Define transformations\ntrain_transforms = transforms.Compose([\n    transforms.Resize(299),  # Resize to 299x299\n    transforms.CenterCrop(299),  # Center crop\n    transforms.RandomRotation(45),\n    transforms.GaussianBlur(3),\n    transforms.RandomHorizontalFlip(),\n    transforms.ToTensor()\n])","metadata":{"execution":{"iopub.status.busy":"2024-09-30T07:20:54.083311Z","iopub.execute_input":"2024-09-30T07:20:54.083633Z","iopub.status.idle":"2024-09-30T07:20:54.089064Z","shell.execute_reply.started":"2024-09-30T07:20:54.083599Z","shell.execute_reply":"2024-09-30T07:20:54.088065Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load the dataset using ImageFolder\ntrain_data = datasets.ImageFolder(data_dir + 'train', transform=train_transforms)","metadata":{"execution":{"iopub.status.busy":"2024-09-30T07:20:54.090207Z","iopub.execute_input":"2024-09-30T07:20:54.090581Z","iopub.status.idle":"2024-09-30T07:20:54.209587Z","shell.execute_reply.started":"2024-09-30T07:20:54.090539Z","shell.execute_reply":"2024-09-30T07:20:54.208902Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train-validation split (80-20)\ntrain_size = int(0.8 * len(train_data))  # 80% for training\nval_size = len(train_data) - train_size   # 20% for validation\n\ntrain_dataset, val_dataset = random_split(train_data, [train_size, val_size])","metadata":{"execution":{"iopub.status.busy":"2024-09-30T07:20:54.210627Z","iopub.execute_input":"2024-09-30T07:20:54.211003Z","iopub.status.idle":"2024-09-30T07:20:54.239368Z","shell.execute_reply.started":"2024-09-30T07:20:54.210961Z","shell.execute_reply":"2024-09-30T07:20:54.238625Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create DataLoaders\ntrainloader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)\nvalloader = torch.utils.data.DataLoader(val_dataset, batch_size=64)","metadata":{"execution":{"iopub.status.busy":"2024-09-30T07:20:54.240440Z","iopub.execute_input":"2024-09-30T07:20:54.240795Z","iopub.status.idle":"2024-09-30T07:20:54.246024Z","shell.execute_reply.started":"2024-09-30T07:20:54.240754Z","shell.execute_reply":"2024-09-30T07:20:54.245148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torchvision import models\n\nvgg = models.vgg16_bn(pretrained=True)","metadata":{"execution":{"iopub.status.busy":"2024-09-30T07:57:10.679767Z","iopub.execute_input":"2024-09-30T07:57:10.680644Z","iopub.status.idle":"2024-09-30T07:57:14.722085Z","shell.execute_reply.started":"2024-09-30T07:57:10.680600Z","shell.execute_reply":"2024-09-30T07:57:14.721227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vgg","metadata":{"execution":{"iopub.status.busy":"2024-09-30T07:57:20.184886Z","iopub.execute_input":"2024-09-30T07:57:20.185726Z","iopub.status.idle":"2024-09-30T07:57:20.192299Z","shell.execute_reply.started":"2024-09-30T07:57:20.185687Z","shell.execute_reply":"2024-09-30T07:57:20.191343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for param in vgg.parameters():\n    param.requires_grad = False","metadata":{"execution":{"iopub.status.busy":"2024-09-30T08:00:25.649549Z","iopub.execute_input":"2024-09-30T08:00:25.650470Z","iopub.status.idle":"2024-09-30T08:00:25.655407Z","shell.execute_reply.started":"2024-09-30T08:00:25.650425Z","shell.execute_reply":"2024-09-30T08:00:25.654353Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vgg.classifier[6].out_features = 2","metadata":{"execution":{"iopub.status.busy":"2024-09-30T08:00:27.476994Z","iopub.execute_input":"2024-09-30T08:00:27.477357Z","iopub.status.idle":"2024-09-30T08:00:27.481759Z","shell.execute_reply.started":"2024-09-30T08:00:27.477323Z","shell.execute_reply":"2024-09-30T08:00:27.480817Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Make sure classifier layers require gradient\nfor param in vgg.classifier.parameters():\n    param.requires_grad = True","metadata":{"execution":{"iopub.status.busy":"2024-09-30T08:00:37.703655Z","iopub.execute_input":"2024-09-30T08:00:37.704074Z","iopub.status.idle":"2024-09-30T08:00:37.709080Z","shell.execute_reply.started":"2024-09-30T08:00:37.704035Z","shell.execute_reply":"2024-09-30T08:00:37.708038Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.nn.init.xavier_uniform_(vgg.classifier[6].weight)\nvgg.classifier[6].bias.data.fill_(0)","metadata":{"execution":{"iopub.status.busy":"2024-09-30T07:58:42.606442Z","iopub.execute_input":"2024-09-30T07:58:42.606901Z","iopub.status.idle":"2024-09-30T07:58:42.641390Z","shell.execute_reply.started":"2024-09-30T07:58:42.606851Z","shell.execute_reply":"2024-09-30T07:58:42.640521Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimizer = optim.Adam(vgg.parameters(), lr=1e-5, weight_decay=1e-4)","metadata":{"execution":{"iopub.status.busy":"2024-09-30T08:01:00.815956Z","iopub.execute_input":"2024-09-30T08:01:00.816972Z","iopub.status.idle":"2024-09-30T08:01:00.822153Z","shell.execute_reply.started":"2024-09-30T08:01:00.816915Z","shell.execute_reply":"2024-09-30T08:01:00.821244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if torch.cuda.is_available():\n    vgg = vgg.cuda()\n    \ndef fit(epoch, model, data_loader, phase='training'):\n    if phase == 'training':\n        model.train()  # Mengaktifkan mode training\n    elif phase == 'validation':\n        model.eval()  # Mengaktifkan mode evaluasi\n\n    running_loss = 0.0\n    running_correct = 0\n\n    for batch_idx, (data, target) in enumerate(data_loader):\n        if torch.cuda.is_available():\n            data, target = data.cuda(), target.cuda()\n            \n        # Check for NaN or inf in input data or target\n        if torch.isnan(data).any() or torch.isinf(data).any():\n            print(f\"NaN or Inf detected in input data at batch {batch_idx}\")\n        if torch.isnan(target).any() or torch.isinf(target).any():\n            print(f\"NaN or Inf detected in target data at batch {batch_idx}\")\n\n        # Hanya aktifkan gradien pada fase training\n        with torch.set_grad_enabled(phase == 'training'):\n            output = model(data)\n             # Use CrossEntropyLoss (includes softmax + log + nll_loss)\n            loss = F.cross_entropy(output, target)\n\n            running_loss += loss.item() * data.size(0)\n            preds = output.argmax(dim=1, keepdim=True)\n            running_correct += preds.eq(target.view_as(preds)).sum().item()\n\n            if phase == 'training':\n                optimizer.zero_grad()  # Reset gradien\n                loss.backward()  # Backpropagation\n                \n                # Check for NaN gradients\n                for name, param in model.named_parameters():\n                    if param.grad is not None and torch.isnan(param.grad).any():\n                        print(f\"NaN in gradients at layer {name}\")\n                        \n                # Clip gradients to prevent explosion\n                torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=0.5)\n                \n                optimizer.step()  # Update weights\n\n    loss = running_loss / len(data_loader.dataset)\n    accuracy = 100. * running_correct / len(data_loader.dataset)\n    \n     # Print the current epoch along with loss and accuracy\n    print(f'Epoch {epoch} | {phase.capitalize()} loss: {loss:.4f}, {phase.capitalize()} accuracy: {accuracy:.2f}%')\n    return loss, accuracy","metadata":{"execution":{"iopub.status.busy":"2024-09-30T08:01:02.523585Z","iopub.execute_input":"2024-09-30T08:01:02.524224Z","iopub.status.idle":"2024-09-30T08:01:02.539557Z","shell.execute_reply.started":"2024-09-30T08:01:02.524185Z","shell.execute_reply":"2024-09-30T08:01:02.538783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for batch_idx, (data, target) in enumerate(trainloader):\n    print(f'Batch {batch_idx} - Label type: {target.dtype}')\n    break","metadata":{"execution":{"iopub.status.busy":"2024-09-30T07:21:01.510018Z","iopub.execute_input":"2024-09-30T07:21:01.510334Z","iopub.status.idle":"2024-09-30T07:21:02.260820Z","shell.execute_reply.started":"2024-09-30T07:21:01.510300Z","shell.execute_reply":"2024-09-30T07:21:02.259846Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_labels = []\nfor _, target in trainloader:\n    all_labels.extend(target.tolist())\nprint(f\"Unique labels in the dataset: {set(all_labels)}\")","metadata":{"execution":{"iopub.status.busy":"2024-09-30T07:21:02.262262Z","iopub.execute_input":"2024-09-30T07:21:02.262754Z","iopub.status.idle":"2024-09-30T07:21:02.267009Z","shell.execute_reply.started":"2024-09-30T07:21:02.262706Z","shell.execute_reply":"2024-09-30T07:21:02.265980Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_losses, train_accuracy = [], []\nval_losses, val_accuracy = [], []\n\nfor epoch in range(1, 3):  # Change epoch range if needed\n    epoch_loss, epoch_accuracy = fit(epoch, vgg, trainloader, phase='training')\n    val_epoch_loss, val_epoch_accuracy = fit(epoch, vgg, valloader, phase='validation')\n\n    train_losses.append(epoch_loss)\n    train_accuracy.append(epoch_accuracy)\n    val_losses.append(val_epoch_loss)\n    val_accuracy.append(val_epoch_accuracy)","metadata":{"execution":{"iopub.status.busy":"2024-09-30T08:01:06.831466Z","iopub.execute_input":"2024-09-30T08:01:06.831869Z","iopub.status.idle":"2024-09-30T08:13:16.018734Z","shell.execute_reply.started":"2024-09-30T08:01:06.831810Z","shell.execute_reply":"2024-09-30T08:13:16.017752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plot the training and validation loss over epochs\nplt.plot(range(1, len(train_losses)+1), train_losses, 'bo', label='Training Loss')\nplt.plot(range(1, len(val_losses)+1), val_losses, 'r', label='Validation Loss')\nplt.title('Training and Validation Loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-09-30T08:16:59.665028Z","iopub.execute_input":"2024-09-30T08:16:59.665631Z","iopub.status.idle":"2024-09-30T08:16:59.889137Z","shell.execute_reply.started":"2024-09-30T08:16:59.665590Z","shell.execute_reply":"2024-09-30T08:16:59.888244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plot the training and validation accuracy over epochs\nplt.plot(range(1, len(train_accuracy)+1), train_accuracy, 'bo', label='Training Accuracy')\nplt.plot(range(1, len(val_accuracy)+1), val_accuracy, 'r', label='Validation Accuracy')\nplt.title('Training and Validation Accuracy')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-09-30T08:17:17.537550Z","iopub.execute_input":"2024-09-30T08:17:17.538567Z","iopub.status.idle":"2024-09-30T08:17:17.831810Z","shell.execute_reply.started":"2024-09-30T08:17:17.538522Z","shell.execute_reply":"2024-09-30T08:17:17.830771Z"},"trusted":true},"execution_count":null,"outputs":[]}]}