{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":6799,"databundleVersionId":4225553,"sourceType":"competition"},{"sourceId":109264,"sourceType":"datasetVersion","datasetId":56828},{"sourceId":6938289,"sourceType":"datasetVersion","datasetId":3984462}],"dockerImageVersionId":30559,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import torch\nimport torchvision\nimport torchvision.transforms as transforms\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\nimport torchvision.models as models\nimport cv2\nfrom matplotlib import pyplot as plt\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nimport random\nimport os\nimport shutil","metadata":{"execution":{"iopub.status.busy":"2023-11-10T14:49:49.78169Z","iopub.execute_input":"2023-11-10T14:49:49.782574Z","iopub.status.idle":"2023-11-10T14:49:49.788895Z","shell.execute_reply.started":"2023-11-10T14:49:49.782543Z","shell.execute_reply":"2023-11-10T14:49:49.787696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 128","metadata":{"execution":{"iopub.status.busy":"2023-11-10T14:49:49.792744Z","iopub.execute_input":"2023-11-10T14:49:49.792997Z","iopub.status.idle":"2023-11-10T14:49:49.800423Z","shell.execute_reply.started":"2023-11-10T14:49:49.792975Z","shell.execute_reply":"2023-11-10T14:49:49.79951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def select_random_samples(dataset_path, output_path, num_classes, samples_per_class):\n    # Get a list of all classes in the dataset\n    all_classes = os.listdir(dataset_path)\n\n    # Randomly select a specified number of classes\n    selected_classes = random.sample(all_classes, num_classes)\n\n    # Create the output directory if it doesn't exist\n    if not os.path.exists(output_path):\n        os.makedirs(output_path)\n\n    # Copy a specified number of samples from each selected class to the output directory\n    for class_label in selected_classes:\n        class_path = os.path.join(dataset_path, class_label)\n        output_class_path = os.path.join(output_path, class_label)\n\n        # Create the output class directory\n        os.makedirs(output_class_path, exist_ok=True)\n\n        # Get a list of all images in the class\n        all_images = os.listdir(class_path)\n\n        # Randomly select a specified number of samples\n        selected_samples = random.sample(all_images, samples_per_class)\n\n        # Copy selected samples to the output class directory\n        for sample in selected_samples:\n            sample_path = os.path.join(class_path, sample)\n            output_sample_path = os.path.join(output_class_path, sample)\n            shutil.copyfile(sample_path, output_sample_path)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-10T14:49:49.801892Z","iopub.execute_input":"2023-11-10T14:49:49.802153Z","iopub.status.idle":"2023-11-10T14:49:49.811609Z","shell.execute_reply.started":"2023-11-10T14:49:49.80213Z","shell.execute_reply":"2023-11-10T14:49:49.810651Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_train = '/kaggle/input/tiny-imagenet-200-zip/tiny-imagenet-200/train'\ntemp_dir_tr = 'kaggle/temp/temp_dataset_tr'\nos.makedirs(temp_dir_tr, exist_ok=True)\n\ntry:\n    shutil.copytree(dataset_train, temp_dir_tr)\nexcept FileExistsError:\n    print('The directory already exists')","metadata":{"execution":{"iopub.status.busy":"2023-11-10T14:49:49.813263Z","iopub.execute_input":"2023-11-10T14:49:49.813554Z","iopub.status.idle":"2023-11-10T14:49:49.829302Z","shell.execute_reply.started":"2023-11-10T14:49:49.813524Z","shell.execute_reply":"2023-11-10T14:49:49.82834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_test = '/kaggle/input/tiny-imagenet-200-zip/tiny-imagenet-200/test'\ntemp_dir_ts = 'kaggle/temp/temp_dataset_ts'\nos.makedirs(temp_dir_ts, exist_ok=True)\n\ntry:\n    shutil.copytree(dataset_test, temp_dir_ts)\nexcept FileExistsError:\n    print('The directory already exists')\n    ","metadata":{"execution":{"iopub.status.busy":"2023-11-10T14:49:49.830405Z","iopub.execute_input":"2023-11-10T14:49:49.830704Z","iopub.status.idle":"2023-11-10T14:49:49.837207Z","shell.execute_reply.started":"2023-11-10T14:49:49.830681Z","shell.execute_reply":"2023-11-10T14:49:49.836307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transform = transforms.Compose(\n    [transforms.ToTensor()])","metadata":{"execution":{"iopub.status.busy":"2023-11-10T14:49:49.838887Z","iopub.execute_input":"2023-11-10T14:49:49.839248Z","iopub.status.idle":"2023-11-10T14:49:49.846262Z","shell.execute_reply.started":"2023-11-10T14:49:49.839224Z","shell.execute_reply":"2023-11-10T14:49:49.845359Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainset = torchvision.datasets.ImageNet(root= '/kaggle/input/tiny-imagenet-200-zip/tiny-imagenet-200/train', train=True,\n                                        download=True, transform=transform)\ntrain_loader = torch.utils.data.DataLoader(trainset, batch_size=batch_size,\n                                          shuffle=True, num_workers=4)\n\ntestset = torchvision.datasets.ImageNet(root= '/kaggle/input/tiny-imagenet-200-zip/tiny-imagenet-200/test', train=False,\n                                       download=True, transform=transform)\ntest_loader = torch.utils.data.DataLoader(testset, batch_size=batch_size,\n                                         shuffle=False, num_workers=4)\n\n# /kaggle/input/imagenet-object-localization-challenge/ILSVRC/Data/CLS-LOC/train\n# /kaggle/input/imagenet-object-localization-challenge/ILSVRC/Data/CLS-LOC/test\n\n# Sub-datasets::\n# (10 - 10)       # (30 - 10)\n# (10 - 100)      # (30 - 100)\n# (10 - 300)      # (30 - 300)\n\n#usage:\ndataset_path = '/kaggle/input/tiny-imagenet-200-zip/tiny-imagenet-200/train'\noutput_path = '/kaggle/working/'\nnum_classes = 10\nsamples_per_class = 10\n\nselect_random_samples(dataset_path, output_path, num_classes, samples_per_class)","metadata":{"execution":{"iopub.status.busy":"2023-11-10T14:49:49.847406Z","iopub.execute_input":"2023-11-10T14:49:49.847675Z","iopub.status.idle":"2023-11-10T14:49:49.931812Z","shell.execute_reply.started":"2023-11-10T14:49:49.847652Z","shell.execute_reply":"2023-11-10T14:49:49.930037Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class ResNet50CustomInput(nn.Module):\n    def __init__(self, num_classes, input_channels):\n        super(ResNet50CustomInput, self).__init__()\n\n        # Load the pre-trained ResNet-50 model without the final classification layer\n        self.resnet = models.resnet50(pretrained=True)\n        # Remove the original fully connected layer\n        self.resnet = nn.Sequential(*list(self.resnet.children())[:-2])\n\n        # Modify the first convolution layer to accept smaller input\n        self.resnet[0] = nn.Conv2d(input_channels, 64, kernel_size=3, stride=1, padding=1, bias=False)\n\n        # Adaptive average pooling layer to adapt to different input sizes\n        self.avgpool = nn.AdaptiveAvgPool2d(1)\n\n        # New fully connected layer for your specific number of classes\n        self.fc = nn.Linear(2048, num_classes)\n\n    def forward(self, x):\n        x = self.resnet(x)\n        x = self.avgpool(x)\n        x = x.view(x.size(0), -1)\n        x = self.fc(x)\n        return x\n\n# Instantiate the modified ResNet-50 model\nnum_classes = 10  # Adjust to your specific number of classes\ninput_channels = 3  # Adjust to match your input data channels\nmodel = ResNet50CustomInput(num_classes, input_channels)\nmodel = model.to(device)","metadata":{"execution":{"iopub.status.busy":"2023-11-10T14:49:49.932574Z","iopub.status.idle":"2023-11-10T14:49:49.93291Z","shell.execute_reply.started":"2023-11-10T14:49:49.932742Z","shell.execute_reply":"2023-11-10T14:49:49.932759Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"criterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=0.001)","metadata":{"execution":{"iopub.status.busy":"2023-11-10T14:49:49.934507Z","iopub.status.idle":"2023-11-10T14:49:49.934962Z","shell.execute_reply.started":"2023-11-10T14:49:49.93472Z","shell.execute_reply":"2023-11-10T14:49:49.934741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train(model, train_loader, optimizer, criterion, epoch):\n    model.train()\n    for batch_idx, data in enumerate(train_loader):\n        inputs, labels = data\n        inputs, labels = inputs.to(device), labels.to(device)\n        optimizer.zero_grad()\n        output = model(inputs)\n        loss = criterion(output, labels)\n        loss.backward()\n        optimizer.step()\n        if batch_idx % 100 == 0:\n            print('Train Epoch: {} [{}/{} ({:.0f}%)]\\tLoss: {:.6f}'.format(\n                epoch, batch_idx * len(inputs), len(train_loader.dataset),\n                100. * batch_idx / len(train_loader), loss.item()))\n","metadata":{"execution":{"iopub.status.busy":"2023-11-10T14:49:49.93676Z","iopub.status.idle":"2023-11-10T14:49:49.937091Z","shell.execute_reply.started":"2023-11-10T14:49:49.936929Z","shell.execute_reply":"2023-11-10T14:49:49.936945Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def test(model, test_loader):\n    model.eval()\n    test_loss = 0\n    correct = 0\n    with torch.no_grad():\n        for data in test_loader:\n            inputs, labels = data\n            inputs, labels = inputs.to(device), labels.to(device)\n            output = model(inputs)\n            test_loss += criterion(output, labels).item()\n            pred = output.argmax(dim=1, keepdim=True)\n            correct += pred.eq(labels.view_as(pred)).sum().item()\n\n    test_loss /= len(test_loader.dataset)\n    accuracy = 100. * correct / len(test_loader.dataset)\n    print('\\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.2f}%)\\n'.format(\n        test_loss, correct, len(test_loader.dataset), accuracy))\n","metadata":{"execution":{"iopub.status.busy":"2023-11-10T14:49:49.938195Z","iopub.status.idle":"2023-11-10T14:49:49.938528Z","shell.execute_reply.started":"2023-11-10T14:49:49.938366Z","shell.execute_reply":"2023-11-10T14:49:49.938381Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = 10 #50\nfor epoch in range(1, epochs + 1):\n    train(model, train_loader, optimizer, criterion, epoch)\n    test(model, test_loader)\n    torch.save(model.state_dict(), 'cifar_resnet50_model.pth')\n    print('model saved')","metadata":{"execution":{"iopub.status.busy":"2023-11-10T14:49:49.939979Z","iopub.status.idle":"2023-11-10T14:49:49.940279Z","shell.execute_reply.started":"2023-11-10T14:49:49.940128Z","shell.execute_reply":"2023-11-10T14:49:49.940141Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loaded_net = ResNet50CustomInput(num_classes, input_channels)\ncheckpoint = torch.load('cifar_resnet50_model.pth')\nloaded_net.load_state_dict(checkpoint)\nloaded_net = loaded_net.to(device)'","metadata":{"execution":{"iopub.status.busy":"2023-11-10T14:49:49.941809Z","iopub.status.idle":"2023-11-10T14:49:49.94218Z","shell.execute_reply.started":"2023-11-10T14:49:49.941993Z","shell.execute_reply":"2023-11-10T14:49:49.94201Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"------------------\n","metadata":{}},{"cell_type":"code","source":"## old code\n\nimport torch\nimport torchvision\nimport torchvision.transforms as transforms\nimport torch.nn as nn\nimport torch.optim as optim\nimport torchvision.models as models\nimport cv2\nfrom matplotlib import pyplot as plt\nfrom torch.utils.data import DataLoader, Subset\nimport numpy as np\n\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nbatch_size = 128\n\ntransform = transforms.Compose([transforms.ToTensor()])\n\n# Define the number of samples you want per class\n\n# Sub-datasets::\n# (10 - 10)       # (30 - 10)\n# (10 - 100)      # (30 - 100)\n# (10 - 300)      # (30 - 300)\n\nsamples_per_class = 10  # Change this to your desired number\n\n\n# Load CIFAR-10 dataset\ntrainset = torchvision.datasets.CIFAR10(root='./cifar', train=True, download=True, transform=transform)\n\n# Select the desired number of samples per class\nselected_indices = []\nfor class_label in range(10):\n    class_indices = np.where(np.array(trainset.targets) == class_label)[0]\n    selected_indices.extend(class_indices[:samples_per_class])\n\n# Create a custom dataset with the selected samples\ncustom_trainset = Subset(trainset, selected_indices)\n\n# Create a data loader with your custom dataset\ntrain_loader = DataLoader(custom_trainset, batch_size=batch_size, shuffle=True, num_workers=4)\n\n#testset = torchvision.datasets.CIFAR10(root='./cifar', train=False, download=True, transform=transform)\n#testset = torchvision.datasets.ImageNet('path/to/imagenet_root/')\n\ntestset = torchvision.datasets.ImageNet(root='/kaggle/input/imagenet-object-localization-challenge', train=False, download=True, transform=transform)\ntest_loader = DataLoader(testset, batch_size=batch_size, shuffle=False, num_workers=4)\n\nclasses = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')\n\nclass ResNet50CustomInput(nn.Module):\n    def __init__(self, num_classes, input_channels):\n        super(ResNet50CustomInput, self).__init()\n\n        # Load the pre-trained ResNet-50 model without the final classification layer\n        self.resnet = models.resnet50(pretrained=True)\n        # Remove the original fully connected layer\n        self.resnet = nn.Sequential(*list(self.resnet.children())[:-2])\n\n        # Modify the first convolution layer to accept smaller input\n        self.resnet[0] = nn.Conv2d(input_channels, 64, kernel_size=3, stride=1, padding=1, bias=False)\n\n        # Adaptive average pooling layer to adapt to different input sizes\n        self.avgpool = nn.AdaptiveAvgPool2d(1)\n\n        # New fully connected layer for your specific number of classes\n        self.fc = nn.Linear(2048, num_classes)\n\n    def forward(self, x):\n        x = self.resnet(x)\n        x = self.avgpool(x)\n        x = x.view(x.size(0), -1)\n        x = self.fc(x)\n        return x\n\n# Instantiate the modified ResNet-50 model\nnum_classes = 10  # Adjust to your specific number of classes\ninput_channels = 3  # Adjust to match your input data channels\nmodel = ResNet50CustomInput(num_classes, input_channels)\nmodel = model.to(device)\n\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=0.001)\n\ndef train(model, train_loader, optimizer, criterion, epoch):\n    model.train()\n    for batch_idx, data in enumerate(train_loader):\n        inputs, labels = data\n        inputs, labels = inputs.to(device), labels.to(device)\n        optimizer.zero_grad()\n        output = model(inputs)\n        loss = criterion(output, labels)\n        loss.backward()\n        optimizer.step()\n        if batch_idx % 100 == 0:\n            print('Train Epoch: {} [{}/{} ({:.0f}%)]\\tLoss: {:.6f}'.format(\n                epoch, batch_idx * len(inputs), len(train_loader.dataset),\n                100. * batch_idx / len(train_loader), loss.item()))\n\ndef test(model, test_loader):\n    model.eval()\n    test_loss = 0\n    correct = 0\n    with torch.no_grad():\n        for data in test_loader:\n            inputs, labels = data\n            inputs, labels = inputs.to(device), labels to(device)\n            output = model(inputs)\n            test_loss += criterion(output, labels).item()\n            pred = output.argmax(dim=1, keepdim=True)\n            correct += pred.eq(labels.view_as(pred)).sum().item()\n\n    test_loss /= len(test_loader.dataset)\n    accuracy = 100. * correct / len(test_loader.dataset)\n    print('\\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.2f}%)\\n'.format(\n        test_loss, correct, len(test_loader.dataset), accuracy))\n\nepochs = 50\nfor epoch in range(1, epochs + 1):\n    train(model, train_loader, optimizer, criterion, epoch)\n    test(model, test_loader)\n    torch.save(model.state_dict(), 'cifar_resnet50_model.pth')\n    print('Model saved')\n","metadata":{"execution":{"iopub.status.busy":"2023-11-10T14:49:49.943873Z","iopub.status.idle":"2023-11-10T14:49:49.944206Z","shell.execute_reply.started":"2023-11-10T14:49:49.944037Z","shell.execute_reply":"2023-11-10T14:49:49.944052Z"},"trusted":true},"execution_count":null,"outputs":[]}]}