{"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":34426,"databundleVersionId":3218632,"sourceType":"competition"}],"dockerImageVersionId":30787,"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\n# for dirname, _, filenames in os.walk('/kaggle/input'):\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","_kg_hide-output":false,"execution":{"iopub.status.busy":"2024-11-13T12:38:11.154563Z","iopub.execute_input":"2024-11-13T12:38:11.155249Z","iopub.status.idle":"2024-11-13T12:38:11.163749Z","shell.execute_reply.started":"2024-11-13T12:38:11.155194Z","shell.execute_reply":"2024-11-13T12:38:11.161826Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nfor dirname in os.listdir('/kaggle/input/dog-vs-cat-classification'):\n    print(dirname)","metadata":{"execution":{"iopub.status.busy":"2024-11-13T13:56:54.523354Z","iopub.execute_input":"2024-11-13T13:56:54.524319Z","iopub.status.idle":"2024-11-13T13:56:54.878855Z","shell.execute_reply.started":"2024-11-13T13:56:54.524271Z","shell.execute_reply":"2024-11-13T13:56:54.877953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Import PyTorch libraries\nimport torch\nimport torchvision\nimport torchvision.transforms as transforms\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.autograd import Variable\nimport torch.nn.functional as F\n\n# Other libraries we'll use\nimport numpy as np\nimport os\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\n%matplotlib inline\n\nprint(\"Libraries imported - ready to use PyTorch\", torch.__version__)","metadata":{"execution":{"iopub.status.busy":"2024-11-13T13:56:56.611032Z","iopub.execute_input":"2024-11-13T13:56:56.611871Z","iopub.status.idle":"2024-11-13T13:57:01.009489Z","shell.execute_reply.started":"2024-11-13T13:56:56.611823Z","shell.execute_reply":"2024-11-13T13:57:01.008607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls /kaggle/input/dog-vs-cat-classification/train/train","metadata":{"execution":{"iopub.status.busy":"2024-11-13T14:31:42.019254Z","iopub.execute_input":"2024-11-13T14:31:42.019658Z","iopub.status.idle":"2024-11-13T14:31:43.050795Z","shell.execute_reply.started":"2024-11-13T14:31:42.019622Z","shell.execute_reply":"2024-11-13T14:31:43.049788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# The images are in the data/shapes folder\ndata_path = '/kaggle/input/dog-vs-cat-classification/train/train/'\n\n# Get the class names\nclasses = os.listdir(data_path)\nclasses.sort()\nprint(len(classes), 'classes:')\nprint(classes)\n\n# Show the first image in each folder\nfig = plt.figure(figsize=(8, 12))\ni = 0\nfor sub_dir in os.listdir(data_path):\n    i+=1\n    img_file = os.listdir(os.path.join(data_path,sub_dir))[0]\n    img_path = os.path.join(data_path, sub_dir, img_file)\n    img = mpimg.imread(img_path)\n    a=fig.add_subplot(1, len(classes),i)\n    a.axis('off')\n    imgplot = plt.imshow(img)\n    a.set_title(img_file)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-11-13T14:42:14.759808Z","iopub.execute_input":"2024-11-13T14:42:14.760789Z","iopub.status.idle":"2024-11-13T14:42:15.055173Z","shell.execute_reply.started":"2024-11-13T14:42:14.760745Z","shell.execute_reply":"2024-11-13T14:42:15.054272Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Function to ingest data using training and test loaders\ndef load_dataset(data_path):\n    # Load all of the images\n    transformation = transforms.Compose(\n        [\n        \n        #.......\n        transforms.RandomHorizontalFlip(p=0.2),\n        transforms.RandomVerticalFlip(p=0.2),\n#         transforms.RandomRotation(degrees=30),\n        transforms.Resize((64,64)),\n        # transform to tensors\n        transforms.ToTensor(),\n        # Normalize the pixel values (in R, G, and B channels)\n        transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])\n      ]\n        )\n\n    # Load all of the images, transforming them\n    full_dataset = torchvision.datasets.ImageFolder(\n        root=data_path,\n        transform=transformation\n    )\n\n\n    # Split into training (70% and testing (30%) datasets)\n    train_size = int(0.8 * len(full_dataset))\n    test_size = len(full_dataset) - train_size\n    train_dataset, test_dataset = torch.utils.data.random_split(full_dataset, [train_size, test_size])\n\n    train_loader = torch.utils.data.DataLoader(\n        train_dataset,\n        batch_size=32,  # 8 16 32 64 128\n        num_workers=0,\n        shuffle=False\n    )\n\n    test_loader = torch.utils.data.DataLoader(\n        test_dataset,\n        batch_size=32,\n        num_workers=0,\n        shuffle=False\n    )\n\n    return train_loader, test_loader\n\n# Get the iterative dataloaders for test and training data\ntrain_loader, test_loader = load_dataset(data_path)\nprint('Data loaders ready')","metadata":{"execution":{"iopub.status.busy":"2024-11-13T14:42:15.775933Z","iopub.execute_input":"2024-11-13T14:42:15.776798Z","iopub.status.idle":"2024-11-13T14:42:20.355853Z","shell.execute_reply.started":"2024-11-13T14:42:15.776758Z","shell.execute_reply":"2024-11-13T14:42:20.354761Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch.nn as nn\nimport torch.nn.functional as F\n\n\n# Create a neural net class\nclass Net(nn.Module):\n    # Constructor\n    def __init__(self, num_classes=3):\n      # khởi tạo các layer\n        super(Net, self).__init__()\n\n        # CNN: convolution layer, max pooling,  FC: Linear\n\n        # Our images are RGB, so input channels = 3. We'll apply 12 filters in the first convolutional layer\n        self.conv1 = nn.Conv2d(in_channels=3, out_channels=12, kernel_size=3, stride=1, padding=1)\n\n        # We'll apply max pooling with a kernel size of 2\n        self.pool = nn.MaxPool2d(kernel_size=2)\n\n        # A second convolutional layer takes 12 input channels, and generates 12 outputs\n        self.conv2 = nn.Conv2d(in_channels=12, out_channels=12, kernel_size=3, stride=1, padding=1)\n\n        # A third convolutional layer takes 12 inputs and generates 24 outputs\n        self.conv3 = nn.Conv2d(in_channels=12, out_channels=24, kernel_size=3, stride=1, padding=1)\n\n        self.fc = nn.Linear(in_features=8* 8 * 24, out_features=num_classes)\n\n    def forward(self, x):\n      # xác định đường đi của input ảnh\n        x = F.relu(self.pool(self.conv1(x)))\n\n        # Use a relu activation function after layer 2 (convolution 2 and pool)\n        x = F.relu(self.pool(self.conv2(x)))\n\n        # Select some features to drop after the 3rd convolution to prevent overfitting\n        x = F.relu(self.pool(self.conv3(x)))\n\n        # Flatten\n#         x = x.view(-1, 32* 32 * 24)\n        x= x.view(x.size(0),-1)\n        # Feed to fully-connected layer to predict class\n        x = self.fc(x)\n        # Return log_softmax tensor\n        return F.log_softmax(x, dim=1)\n\nprint(\"CNN model class defined!\")","metadata":{"execution":{"iopub.status.busy":"2024-11-13T14:42:20.357580Z","iopub.execute_input":"2024-11-13T14:42:20.357915Z","iopub.status.idle":"2024-11-13T14:42:20.368779Z","shell.execute_reply.started":"2024-11-13T14:42:20.357880Z","shell.execute_reply":"2024-11-13T14:42:20.367896Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install torchsummary","metadata":{"execution":{"iopub.status.busy":"2024-11-13T14:42:20.369881Z","iopub.execute_input":"2024-11-13T14:42:20.370165Z","iopub.status.idle":"2024-11-13T14:42:31.909075Z","shell.execute_reply.started":"2024-11-13T14:42:20.370134Z","shell.execute_reply":"2024-11-13T14:42:31.907807Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nfrom torchsummary import summary\nmodel=Net(num_classes=2)\nmodel.to('cuda')\nsummary(model,(3,64,64),device='cuda')","metadata":{"execution":{"iopub.status.busy":"2024-11-13T14:42:31.912376Z","iopub.execute_input":"2024-11-13T14:42:31.913170Z","iopub.status.idle":"2024-11-13T14:42:31.927377Z","shell.execute_reply.started":"2024-11-13T14:42:31.913124Z","shell.execute_reply":"2024-11-13T14:42:31.926445Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = Net(num_classes=2)\nprint(model)","metadata":{"execution":{"iopub.status.busy":"2024-11-13T14:42:31.928435Z","iopub.execute_input":"2024-11-13T14:42:31.928719Z","iopub.status.idle":"2024-11-13T14:42:31.935455Z","shell.execute_reply.started":"2024-11-13T14:42:31.928689Z","shell.execute_reply":"2024-11-13T14:42:31.934400Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train(model, device, train_loader, optimizer, epoch):\n    # Set the model to training mode\n    model.train()\n    train_loss = 0\n    print(\"Epoch:\", epoch)\n    for batch_idx, (data, target) in enumerate(train_loader):\n        # Use the CPU or GPU as appropriate\n        data, target = data.to(device), target.to(device)\n\n        # Reset the optimizer\n        # reset gradient về 0 trước mỗi vòng lặp\n        optimizer.zero_grad()\n\n        # Push the data forward through the model layers\n        output = model(data)\n\n        # Get the loss\n        loss = loss_criteria(output, target)\n\n        # Keep a running total\n        train_loss += loss.item()\n\n        # Backpropagate\n        loss.backward()\n        optimizer.step()\n\n        # Print metrics for every 10 batches so we see some progress\n        if batch_idx % 10 == 0:\n            print('Training set [{}/{} ({:.0f}%)] Loss: {:.6f}'.format(\n                batch_idx * len(data), len(train_loader.dataset),\n                100. * batch_idx / len(train_loader), loss.item()))\n\n    # return average loss for the epoch\n    avg_loss = train_loss / (batch_idx+1)\n    print('Training set: Average loss: {:.6f}'.format(avg_loss))\n    return avg_loss\n\n\ndef test(model, device, test_loader):\n    # Switch the model to evaluation mode (so we don't backpropagate or drop)\n    model.eval()\n    test_loss = 0\n    correct = 0\n    with torch.no_grad():\n        batch_count = 0\n        for data, target in test_loader:\n            batch_count += 1\n            data, target = data.to(device), target.to(device)\n\n            # Get the predicted classes for this batch\n            output = model(data)\n\n            # Calculate the loss for this batch\n            test_loss += loss_criteria(output, target).item()\n\n            # Calculate the accuracy for this batch\n            # Lấy ra nhãn model đã dự đoán.  Ví dụ output (0.8, 0.2, 0.2). --> nhãn= 0\n                                                  #output (0.1, 0.85, 0.05). --> nhãn= 1\n            _, predicted = torch.max(output.data, 1)\n\n            # đếm xem có bao nhiêu ảnh đúng nhãn thực tế\n            correct += torch.sum(target==predicted).item()\n\n    # Calculate the average loss and total accuracy for this epoch\n    avg_loss = test_loss/batch_count\n    print('Validation set: Average loss: {:.6f}, Accuracy: {}/{} ({:.0f}%)\\n'.format(\n        avg_loss,\n        correct,\n        len(test_loader.dataset),\n        100. * correct / len(test_loader.dataset)))\n\n    # return average loss for the epoch\n    return avg_loss, 100. * correct / len(test_loader.dataset)\n\n\n# Now use the train and test functions to train and test the model\n\ndevice = \"cpu\"\nif (torch.cuda.is_available()):\n    # if GPU available, use cuda (on a cpu, training will take a considerable length of time!)\n    device = \"cuda\"\nprint('Training on', device)\n\n# Create an instance of the model class and allocate it to the device\n# model = Net(num_classes=2).to(device)\n\n# from torchvision.models import resnet18\n# model = resnet18(pretrained = True)\n# # Modifying Head - classifier\n# model.fc = nn.Sequential(\n#     nn.Linear(512, 2, bias = True),\n#     nn.Softmax(dim=1)\n# )\n# model.to(device)\n\nfrom torchvision.models import mobilenet_v2\nmodel = mobilenet_v2(pretrained = True)\nmodel.classifier = nn.Sequential(\n    nn.Linear(1280, 2, bias = True),\n    nn.Softmax(dim=1)\n)\nmodel.to(device)\n\n\n#data\ntrain_loader, test_loader = load_dataset(data_path)\n\n\n# Use an \"Adam\" optimizer to adjust weights\n# (see https://pytorch.org/docs/stable/optim.html#algorithms for details of supported algorithms)\noptimizer = optim.Adam(model.parameters(), lr=0.001)\n\n# Specify the loss criteria\nloss_criteria = nn.CrossEntropyLoss()\n\n# Track metrics in these arrays\nepoch_nums = []\ntraining_loss = []\nvalidation_loss = []\nacc_list= []\n\n# Train over 5 epochs (in a real scenario, you'd likely use many more)\nepochs = 3\nfor epoch in range(1, epochs + 1):\n        train_loss = train(model, device, train_loader, optimizer, epoch)\n        test_loss, acc = test(model, device, test_loader)\n        epoch_nums.append(epoch)\n        training_loss.append(train_loss)\n        validation_loss.append(test_loss)\n        acc_list.append(acc)\n\n        # Save the model weights\n        model_file = f'dog_cat_classifier_e{epoch}.pt'\n        torch.save(model.state_dict(), model_file)\n        print('model saved as', model_file)","metadata":{"execution":{"iopub.status.busy":"2024-11-13T14:42:31.936977Z","iopub.execute_input":"2024-11-13T14:42:31.937277Z","iopub.status.idle":"2024-11-13T14:47:25.156458Z","shell.execute_reply.started":"2024-11-13T14:42:31.937247Z","shell.execute_reply":"2024-11-13T14:47:25.155457Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"86","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%matplotlib inline\nfrom matplotlib import pyplot as plt\n\nplt.plot(epoch_nums, training_loss)\nplt.plot(epoch_nums, validation_loss)\nplt.xlabel('epoch')\nplt.ylabel('loss')\nplt.legend(['training', 'validation'], loc='upper right')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-11-13T14:06:58.574909Z","iopub.execute_input":"2024-11-13T14:06:58.575315Z","iopub.status.idle":"2024-11-13T14:06:58.821340Z","shell.execute_reply.started":"2024-11-13T14:06:58.575278Z","shell.execute_reply":"2024-11-13T14:06:58.820438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%matplotlib inline\nfrom matplotlib import pyplot as plt\n\nplt.plot(epoch_nums, acc_list)\nplt.xlabel('epoch')\nplt.ylabel('acc')\nplt.legend(['acc_test'], loc='upper right')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-11-13T14:07:46.154143Z","iopub.execute_input":"2024-11-13T14:07:46.154885Z","iopub.status.idle":"2024-11-13T14:07:46.404899Z","shell.execute_reply.started":"2024-11-13T14:07:46.154843Z","shell.execute_reply":"2024-11-13T14:07:46.403899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Pytorch doesn't have a built-in confusion matrix metric, so we'll use SciKit-Learn\nfrom sklearn.metrics import confusion_matrix\n\n# Set the model to evaluate mode\nmodel.eval()\n\n# Get predictions for the test data and convert to numpy arrays for use with SciKit-Learn\nprint(\"Getting predictions from test set...\")\ntruelabels = []\npredictions = []\nfor data, target in test_loader:\n    for label in target.cpu().data.numpy():\n        truelabels.append(label)\n    for prediction in model.cpu()(data).data.numpy().argmax(1):\n        predictions.append(prediction)\n\n# Plot the confusion matrix\ncm = confusion_matrix(truelabels, predictions)\nplt.imshow(cm, interpolation=\"nearest\", cmap=plt.cm.Blues)\nplt.colorbar()\ntick_marks = np.arange(len(classes))\nplt.xticks(tick_marks, classes, rotation=45)\nplt.yticks(tick_marks, classes)\nplt.xlabel(\"Predicted Shape\")\nplt.ylabel(\"Actual Shape\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-11-13T14:12:29.246527Z","iopub.execute_input":"2024-11-13T14:12:29.247251Z","iopub.status.idle":"2024-11-13T14:12:58.050032Z","shell.execute_reply.started":"2024-11-13T14:12:29.247215Z","shell.execute_reply":"2024-11-13T14:12:58.049096Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Save the model weights\nmodel_file = 'dogs_cats_classifier.pt'\ntorch.save(model.state_dict(), model_file)\ndel model\nprint('model saved as', model_file)","metadata":{"execution":{"iopub.status.busy":"2024-11-13T14:17:54.802042Z","iopub.execute_input":"2024-11-13T14:17:54.802818Z","iopub.status.idle":"2024-11-13T14:17:54.841090Z","shell.execute_reply.started":"2024-11-13T14:17:54.802778Z","shell.execute_reply":"2024-11-13T14:17:54.840188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls","metadata":{"execution":{"iopub.status.busy":"2024-11-13T14:17:57.508606Z","iopub.execute_input":"2024-11-13T14:17:57.508967Z","iopub.status.idle":"2024-11-13T14:17:58.529266Z","shell.execute_reply.started":"2024-11-13T14:17:57.508935Z","shell.execute_reply":"2024-11-13T14:17:58.527694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport os\nimport numpy\nfrom random import randint\n%matplotlib inline\nimport cv2\n\n# Function to predict the class of an image\ndef predict_image(model, image):\n\n    # Set the classifer model to evaluation mode\n    model.eval()\n\n    # Apply the same transformations as we did for the training images\n    transformation = transforms.Compose([\n        transforms.ToTensor(),\n        transforms.Resize((64,64)),\n        transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])\n    ])\n\n    # Preprocess the image\n    image_tensor = transformation(image).float()\n\n    # Add an extra batch dimension since pytorch treats all inputs as batches\n    image_tensor = image_tensor.unsqueeze_(0) #  (224x224x3) -->(1x224x224x3)\n\n    # Turn the input into a Variable\n    input_features = Variable(image_tensor)\n\n    # Predict the class of the image\n    output = model(input_features) # (0.8, 0.1).\n    print(output)\n    index = output.data.numpy().argmax() #--> index=0\n    return index\n\n\nimg= cv2.imread(\"/kaggle/input/dog-vs-cat-classification/test/test/001336.jpg\")\n\n# Display the image\nplt.axis('off')\nplt.imshow(img)\n\n\nmodel_file=\"dogs_cats_classifier.pt\"\n# Create a new model class and load the saved weights\nfrom torchvision.models import mobilenet_v2\nmodel = mobilenet_v2(pretrained = True)\nmodel.classifier = nn.Sequential(\n    nn.Linear(1280, 2, bias = True),\n    nn.Softmax(dim=1)\n)\n# model.to(device)\nmodel.load_state_dict(torch.load(model_file))\n\n# Call the predction function\nindex = predict_image(model, img)\nprint(index)","metadata":{"execution":{"iopub.status.busy":"2024-11-13T14:25:52.555627Z","iopub.execute_input":"2024-11-13T14:25:52.556475Z","iopub.status.idle":"2024-11-13T14:25:52.980065Z","shell.execute_reply.started":"2024-11-13T14:25:52.556436Z","shell.execute_reply":"2024-11-13T14:25:52.979076Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls /kaggle/input/dog-vs-cat-classification/test/test/001334.jpg","metadata":{"execution":{"iopub.status.busy":"2024-11-13T14:20:32.291451Z","iopub.execute_input":"2024-11-13T14:20:32.292401Z","iopub.status.idle":"2024-11-13T14:20:33.795005Z","shell.execute_reply.started":"2024-11-13T14:20:32.292357Z","shell.execute_reply":"2024-11-13T14:20:33.793794Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}