{"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":"code","source":"%matplotlib inline\nimport glob\nimport time\nimport random\nimport numpy as np\nimport pandas as pd\nimport datetime as dt\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nfrom mpl_toolkits.axes_grid1 import ImageGrid\nfrom os import listdir, makedirs, getcwd, remove\nfrom os.path import isfile, join, abspath, exists, isdir, expanduser\nfrom PIL import Image\nimport torch\nfrom torch.optim import lr_scheduler\nfrom torch.autograd import Variable\nfrom torch.utils.data import Dataset, DataLoader\nimport torchvision\nfrom torchvision import transforms, datasets, models\n\nnp.random.seed(42) ","metadata":{"execution":{"iopub.status.busy":"2023-09-22T07:14:41.411616Z","iopub.execute_input":"2023-09-22T07:14:41.412012Z","iopub.status.idle":"2023-09-22T07:14:43.474849Z","shell.execute_reply.started":"2023-09-22T07:14:41.411973Z","shell.execute_reply":"2023-09-22T07:14:43.473328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"competition = \"dog-breed-identification\"\nsubmission_path = \"sample_submission.csv\"\n\nlabels_path = f\"/kaggle/input/{competition}/labels.csv\"\nsubmission_path = f\"/kaggle/input/{competition}/sample_submission.csv\"\n\nlabels = pd.read_csv(labels_path)\nsubmission_df = pd.read_csv(submission_path)","metadata":{"execution":{"iopub.status.busy":"2023-09-22T07:14:43.477279Z","iopub.execute_input":"2023-09-22T07:14:43.477748Z","iopub.status.idle":"2023-09-22T07:14:43.919279Z","shell.execute_reply.started":"2023-09-22T07:14:43.477719Z","shell.execute_reply":"2023-09-22T07:14:43.918171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create a dictionary to map index to breed\nindex_to_breed = dict(zip(labels.index, labels['breed']))\n# Create a set of unique values from the values of the index_to_breed dictionary\nunique_values = set(index_to_breed.values())\n# Sort the unique values and store them in a list\nsorted_unique_values = sorted(unique_values)\nlabels_dic=dict(enumerate(sorted_unique_values))\nlen(labels_dic)","metadata":{"execution":{"iopub.status.busy":"2023-09-22T07:14:43.920531Z","iopub.execute_input":"2023-09-22T07:14:43.920850Z","iopub.status.idle":"2023-09-22T07:14:43.936097Z","shell.execute_reply.started":"2023-09-22T07:14:43.920789Z","shell.execute_reply":"2023-09-22T07:14:43.935076Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Assuming you have defined your index_to_breed dictionary\nw = 'kelpie'\nif w in labels_dic.values():\n    print(f\"Cong! The label {w} is found in index_to_breed.\")\nelse:\n    print(f\"Sorry! The label {w} is not found in index_to_breed.\")","metadata":{"execution":{"iopub.status.busy":"2023-09-22T07:14:43.938321Z","iopub.execute_input":"2023-09-22T07:14:43.938616Z","iopub.status.idle":"2023-09-22T07:14:43.945727Z","shell.execute_reply.started":"2023-09-22T07:14:43.938593Z","shell.execute_reply":"2023-09-22T07:14:43.943985Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class DogsDataset(Dataset):\n    \n    def __init__(self, labels, root_dir, class_to_idx, transform=None):\n        self.labels = labels\n        self.root_dir = root_dir\n        self.transform = transform\n        self.class_to_idx = class_to_idx  # Mapping from class names to indices\n        \n    def __len__(self):\n        return len(self.labels)\n    \n    def __getitem__(self, idx):\n        img_name = '{}.jpg'.format(self.labels.iloc[idx, 0])\n        fullname = join(self.root_dir, img_name)\n        img = Image.open(fullname)\n        label = self.labels.iloc[idx, 1]  # Get the string label\n        label_idx = self.class_to_idx[label]  # Convert the label to class index\n        if self.transform:\n            img = self.transform(img)\n        return img, label_idx  # Return class index instead of string label","metadata":{"execution":{"iopub.status.busy":"2023-09-22T07:14:43.947627Z","iopub.execute_input":"2023-09-22T07:14:43.948472Z","iopub.status.idle":"2023-09-22T07:14:43.958678Z","shell.execute_reply.started":"2023-09-22T07:14:43.948417Z","shell.execute_reply":"2023-09-22T07:14:43.957340Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Image Transform\nimg_transform = {\n    'train' : transforms.Compose([\n        #Image Augmentation \n        transforms.RandomResizedCrop(size = 256),#Merkezi korumadan random image kirpar.Random sekilde yapilmasi,modele aynı görüntünün biraz farklı görünümlerini göstererek eğitim verilerinde çeşitlilik sağlamaya yardımcı olur.\n        transforms.RandomRotation(degrees = 30),#Bu dönüşüm, image'i max 30 derece rastgele döndürür. Bu islem, modelin oryantasyondaki değişikliklere karşı daha dayanıklı olmasına yardımcı olur\n        transforms.ColorJitter(), #Parlaklık, kontrast, doygunluk ve renk tonundaki değişiklikler de dahil olmak üzere image'de rastgele renk ayarlamaları. Bu, renk görünümünde değişkenliğe neden olur.\n        transforms.RandomHorizontalFlip(),#Bu dönüşüm image'i %50 olasılıkla yatay olarak çevirir. Eğitim verilerinin çeşitliliğini artıran yaygın bir büyütme tekniğidir.\n        transforms.CenterCrop(size=224),#Çeşitli random islemler uygulandıktan sonra,bu dönüşüm 224x224 piksel boyutunda merkezi bir kırpma alır.Bu adım, islenmis görüntünün modele gelmeden önce boyutunun tutarlı olmasını sağlar.\n        transforms.ToTensor(),\n        transforms.Normalize([0.485, 0.456, 0.406],\n                             [0.229, 0.224, 0.225])#ImageNet veri kümesi için tipik olan değerler. Bu, giriş verilerinin, modeli önceden eğitmek için kullanılan verilerle benzer ölçeğe sahip olmasını sağlamak için önemlidir.\n    ]),\n    'valid':transforms.Compose([\n        transforms.Resize(size = 256),\n        transforms.CenterCrop(size = 224),\n        transforms.ToTensor(),\n        transforms.Normalize([0.485, 0.456, 0.406],\n                             [0.229, 0.224, 0.225])\n    ])}","metadata":{"execution":{"iopub.status.busy":"2023-09-22T07:14:43.961033Z","iopub.execute_input":"2023-09-22T07:14:43.961445Z","iopub.status.idle":"2023-09-22T07:14:43.977361Z","shell.execute_reply.started":"2023-09-22T07:14:43.961411Z","shell.execute_reply":"2023-09-22T07:14:43.976182Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"unique_labels = labels['breed'].unique()\nclass_to_idx = {label: idx for idx, label in enumerate(unique_labels)}\n\nlabels = pd.read_csv('../input/dog-breed-identification/labels.csv')\n#Split data into train and valid\ntrain = labels.sample(frac=0.8)\nvalid = labels[~labels['id'].isin(train['id'])]\n\ntrain_dir = '../input/dog-breed-identification/train/'\n\ntrain_ds = DogsDataset(labels, train_dir, class_to_idx, transform=img_transform['train'])\nvalid_ds = DogsDataset(valid, train_dir, class_to_idx, transform=img_transform['valid'])\n\ntrain_dl = DataLoader(train_ds, batch_size = 4, shuffle = True, num_workers = 4)\nvalid_dl = DataLoader(valid_ds, batch_size = 4, shuffle = True, num_workers = 4)","metadata":{"execution":{"iopub.status.busy":"2023-09-22T07:14:43.978818Z","iopub.execute_input":"2023-09-22T07:14:43.979406Z","iopub.status.idle":"2023-09-22T07:14:44.027066Z","shell.execute_reply.started":"2023-09-22T07:14:43.979374Z","shell.execute_reply":"2023-09-22T07:14:44.025540Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from mpl_toolkits.axes_grid1 import ImageGrid\nimport matplotlib.pyplot as plt\nimport numpy as np\n\ndef imshow(axis, inp, label):\n    \"\"\"Denormalize and show\"\"\"\n    inp = inp.numpy().transpose((1, 2, 0))\n    mean = np.array([0.485, 0.456, 0.406])\n    std = np.array([0.229, 0.224, 0.225])\n    inp = std * inp + mean\n    axis.imshow(inp)\n    axis.set_title(label) \n\nimg, label = next(iter(train_dl))\nprint(len(img), len(label))\nfig = plt.figure(1, figsize=(16, 4))\ngrid = ImageGrid(fig, 111, nrows_ncols=(1, 4), axes_pad=0.05)    \nfor i in range(len(img)):\n    ax = grid[i]\n    imshow(ax, img[i], label[i])  # Pass the label for the current image\nplt.show()  # Show the entire figure","metadata":{"execution":{"iopub.status.busy":"2023-09-22T07:14:44.028411Z","iopub.execute_input":"2023-09-22T07:14:44.028707Z","iopub.status.idle":"2023-09-22T07:14:46.227673Z","shell.execute_reply.started":"2023-09-22T07:14:44.028678Z","shell.execute_reply":"2023-09-22T07:14:46.225831Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### NOTE: Validation ile Test verisetleri icin ayni islemler uygulanirken, train seti icin cesitlilik saglanmaya calisilmistir.","metadata":{}},{"cell_type":"markdown","source":"### Build A Model","metadata":{}},{"cell_type":"code","source":"use_gpu = torch.cuda.is_available()\nresnet = models.resnet50(pretrained=True)\ninputs, labels = next(iter(train_dl))\nif use_gpu:\n    resnet = resnet.cuda()\n    inputs, labels = inputs.cuda(), labels.cuda()   \nelse:\n    inputs, labels = inputs, labels\noutputs = resnet(inputs)\noutputs.size()","metadata":{"execution":{"iopub.status.busy":"2023-09-22T07:14:46.228717Z","iopub.status.idle":"2023-09-22T07:14:46.229105Z","shell.execute_reply.started":"2023-09-22T07:14:46.228918Z","shell.execute_reply":"2023-09-22T07:14:46.228938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_model(dataloaders, model, criterion, optimizer, scheduler, num_epochs=5, patience=2):\n    since = time.time()\n    use_gpu = torch.cuda.is_available()\n    best_model = model.state_dict()\n    dataset_sizes = {'train': len(dataloaders['train'].dataset),\n                     'valid': len(dataloaders['valid'].dataset)}\n    \n    # Define early stopping parameters\n    best_validation_loss = float('inf')\n    current_patience = 0\n    \n    for epoch in range(num_epochs):\n        for phase in ['train', 'valid']:\n            if phase == 'train':\n                scheduler.step()  # Adjust the learning rate according to the scheduler\n                model.train(True)  # Set the model to training mode\n            else:\n                model.train(False)  # Set the model to evaluation mode\n            \n            running_loss = 0.0\n            running_corrects = 0\n            for inputs, labels in dataloaders[phase]:\n                if use_gpu:\n                    inputs, labels = inputs.cuda(), labels.cuda()\n                else:\n                    inputs, labels = inputs, labels\n                \n                optimizer.zero_grad()  # Zero out gradients in the optimizer\n                outputs = model(inputs)  # Forward pass through the model\n                _, preds = torch.max(outputs.data, 1)  # Get the class predictions\n                loss = criterion(outputs, labels)  # Compute the loss\n                \n                if phase == 'train':\n                    loss.backward()  # Backpropagate gradients\n                    optimizer.step()  # Update model weights\n                \n                running_loss += loss.item()  # Accumulate the loss\n                running_corrects += torch.sum(preds == labels.data)  # Count correct predictions\n            \n            # Training\n            if phase == 'train':\n                train_epoch_loss = running_loss / dataset_sizes[phase]  # Average loss per sample\n                train_epoch_acc = running_corrects.double() / dataset_sizes[phase]  # Accuracy\n            \n            # Validation\n            else:\n                valid_epoch_loss = running_loss / dataset_sizes[phase]  # Average loss per sample\n                valid_epoch_acc = running_corrects.double() / dataset_sizes[phase]  # Accuracy\n                \n                # Check if validation loss improved\n                if valid_epoch_loss < best_validation_loss:\n                    best_validation_loss = valid_epoch_loss\n                    current_patience = 0  # Reset patience counter\n                    best_model_wts = model.state_dict()  # Save the best model weights\n                else:\n                    current_patience += 1  # Increment patience if no improvement\n        \n        # Print training and validation metrics for the epoch\n        print('Epoch [{}/{}] train loss: {:.4f} acc: {:.4f} ' \n              'valid loss: {:.4f} acc: {:.4f}'.format(\n                epoch, num_epochs - 1,\n                train_epoch_loss, train_epoch_acc, \n                valid_epoch_loss, valid_epoch_acc))\n            \n        # Check for early stopping\n        if current_patience >= patience:\n            print('Early stopping triggered. Training stopped.')\n            break\n            \n    # Print the best validation loss and accuracy achieved during training\n    print('Best val loss: {:.4f} Best val Acc: {:.4f}'.format(best_validation_loss, best_validation_acc))\n\n    # Load the best model weights\n    model.load_state_dict(best_model_wts)\n    return model","metadata":{"execution":{"iopub.status.busy":"2023-09-22T07:14:46.230682Z","iopub.status.idle":"2023-09-22T07:14:46.231001Z","shell.execute_reply.started":"2023-09-22T07:14:46.230854Z","shell.execute_reply":"2023-09-22T07:14:46.230868Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### ResNet","metadata":{}},{"cell_type":"code","source":"resnet = models.resnet50(pretrained=True)\n# freeze all model parameters\nfor param in resnet.parameters():\n    param.requires_grad = False\n\n# new final layer with 120 classes\nnum_ftrs = resnet.fc.in_features\nresnet.fc = torch.nn.Linear(num_ftrs, 120)\nif use_gpu:\n    \n    resnet = resnet.cuda()\n\ncriterion = torch.nn.CrossEntropyLoss()\noptimizer = torch.optim.SGD(resnet.fc.parameters(), lr=0.001, momentum=0.9)\nexp_lr_scheduler = lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)\n\ndloaders = {'train':train_dl, 'valid':valid_dl}\nstart_time = time.time()\n#model = train_model(dloaders, resnet, criterion, optimizer, exp_lr_scheduler, num_epochs=30, patience=2)\nprint('Training time: {:.4f} minutes'.format((time.time() - start_time) / 60))","metadata":{"execution":{"iopub.status.busy":"2023-09-22T07:14:46.232331Z","iopub.status.idle":"2023-09-22T07:14:46.232660Z","shell.execute_reply.started":"2023-09-22T07:14:46.232522Z","shell.execute_reply":"2023-09-22T07:14:46.232536Z"},"trusted":true},"execution_count":null,"outputs":[]}]}