{"cells":[{"metadata":{},"cell_type":"markdown","source":"<div><h1 style=\"font-size: 35px;\">🦴 RepVGG: ConvNets are Back Again. 🩺</h1></div>"},{"metadata":{},"cell_type":"markdown","source":"<p style=\"font-size: 20px; margin-right:50px\">In January 11th of 2021 a new paper on paperswithcode's <a href=\"paperswithcode.com\">website</a> was released.<br> It talked about <a href=\"https://paperswithcode.com/paper/repvgg-making-vgg-style-convnets-great-again\">Making VGG-style ConvNets Great Again</a>.<br><br>\nBefore we have this discussion, take a look at this:\n</p>\n<img src=\"https://i.pinimg.com/originals/eb/be/01/ebbe012dc393a88f1bd5c80017836e61.png\" style=\"width:30%; float:right;\">\n<h1 style=\"font-size: 30px; margin-right:50px\">What are transformers?</h1>\n<p style=\"font-size: 20px; margin-right:50px\">Transformers are a type of Deep Learning models that use encoders and decoders to do language modelling, later they can be trained to do specific NLP tasks such as Text Classification or Name Entity Recognition. These models have been used extensively in the field of NLP until recent times only.<br>\nUntil this bad boy comes in and says:<br><br>\"Yo, what if we used this model on pictures pixels to classify them?\"<br><br>\nThe Deep Learning Community went into a complete frenzy trying to figure out if this is the future.\nWell... The RepVGG is here to question it.\n<br><br>\n<h1 style=\"font-size: 30px; margin-right:50px\">RepVGG: Making ConvNets Great Again</h1>\n<img src=\"https://raw.githubusercontent.com/DingXiaoH/RepVGG/main/arch.PNG\" style=\"width:30%;float:right;display:inline-block\">\n<p style=\"font-size: 20px; margin-right:100px\">A simple but powerful architecture of convolutional neural network, which has a VGG-like inference-time body composed of nothing but a stack of 3x3 convolution and ReLU, while the training-time model has a multi-branch topology. Such decoupling of the training-time and inference-time architecture is realized by a structural re-parameterization technique so that the model is named RepVGG.\n<br><br><a href=\"https://github.com/DingXiaoH/RepVGG\">Check out the researcher's Repo!</a></p>\n\n<h1 style=\"font-size: 30px; margin-right:50px\">So, What was the Fuss about Again?</h1>\n<p style=\"font-size: 20px; margin-right:50px\">Nothing to be honest, just a bunch of ConvNets being insecure as they try regain their spot of being fast and efficient.</p>"},{"metadata":{},"cell_type":"markdown","source":"<center><p style=\"font-size: 14px;\">⁣✨✨✨✨✨✨✨✨✨☁️✨✨✨✨✨✨✨✨✨<br>\n✨✨✨✨✨✨✨✨✨☁️✨✨✨✨✨✨✨✨✨<br>\n✨✨✨✨✨✨✨✨✨☁️✨✨✨✨✨✨✨✨✨<br>\n✨✨✨✨✨✨✨✨✨☁️✨✨✨✨✨✨✨✨✨<br>\n✨✨✨✨✨✨✨✨✨☁️✨✨✨✨✨✨✨✨✨<br>\n✨✨✨✨✨✨✨✨✨☁️✨✨✨✨✨✨✨✨✨<br>\n✨✨✨✨✨✨✨✨✨☁️✨✨✨✨✨✨✨✨✨<br>\n✨✨✨✨✨✨✨✨✨☁️✨✨✨✨✨✨✨✨✨<br>\n✨✨✨✨✨✨✨⬛️⬛️☁️⬛️⬛️✨✨✨✨✨✨✨<br>\n✨✨✨✨✨✨✨⬛️🅰️☁️🅰️⬛️✨✨✨✨✨✨✨<br>\n✨✨✨✨✨✨⬛️🅰️🅰️☁️🅰️🅰️⬛️✨✨✨✨✨✨<br>\n✨✨✨⬛️⬛️⬛️🅰️🅰️🅰️☁️🅰️🅰️🅰️⬛️⬛️⬛️✨✨✨<br>\n✨⬛️⬛️🚹🚹🚹🚹🅰️🅰️☁️🅰️🅰️🚹🚹🚹🚹⬛️⬛️✨<br>\n⬛️🚹🚹🚹🚹🚹🚹⬛️⬛️☁️⬛️⬛️🚹🚹🚹🚹🚹🚹⬛️<br>\n⬛️🚹🚹🚹🚹🚹⬛️✨✨☁️✨✨⬛️🚹🚹🚹🚹🚹⬛️<br>\n✨⬛️🚹🚹🚹🚹🚹⬛️⬛️☁️⬛️⬛️🚹🚹🚹🚹🚹⬛️✨<br>\n✨✨⬛️🚹🚹🚹🚹🚹🚹☁️🚹🚹🚹🚹🚹🚹⬛️✨✨<br>\n✨✨✨⬛️🚹🚹🚹🚹🚹☁️🚹🚹🚹🚹🚹⬛️✨✨✨<br>\n✨✨✨✨⬛️⬛️⬛️⬛️⬛️☁️⬛️⬛️⬛️⬛️⬛️✨✨✨✨<br>\n✨✨✨✨⬛️🅰️🅰️🅰️⬛️☁️⬛️🅰️🅰️🅰️⬛️✨✨✨✨<br>\n✨✨✨⬛️🅰️🅰️🅰️🅰️⬛️🅰️⬛️🅰️🅰️🅰️🅰️⬛️✨✨✨<br>\n✨✨⬛️🅰️🅰️🅰️🅰️🅰️⬛️🅰️⬛️🅰️🅰️⁣🅰️🅰️🅰️⬛️✨✨<br>\n✨✨⬛️🅰️🅰️🅰️⬛️⬛️🅰️🅰️🅰️⬛️⬛️🅰️🅰️🅰️⬛️✨✨<br>\n✨⬛️🅰️🅰️🚹⬛️🚹🅰️🅰️🅰️🅰️🅰️🚹⬛️🚹🅰️🅰️⬛️✨<br>\n⬛️🅰️🅰️🚹⬛️🚹🅰️⬛️⬛️⬛️⬛️⬛️🅰️🚹⬛️🚹🅰️🅰️⬛️<br>\n⬛️🅰️🚹⬛️🅰️🅰️⬛️🅰️🅰️🅰️🅰️🅰️⬛️🅰️🅰️⬛️🚹🅰️⬛️<br>\n⬛️🅰️⬛️🅰️🅰️⬛️🅰️🅰️🅰️🅰️🅰️🅰️🅰️⬛️🅰️🅰️⬛️🅰️⬛️<br>\n⬛️🅰️⬛️🅰️⬛️🅰️🅰️🅰️🅰️🅰️🅰️🅰️🅰️🅰️⬛️🅰️⬛️🅰️⬛️<br>\n✨⬛️⬛️⬛️⬛️🅰️🅰️🅰️🅰️🅰️🅰️🅰️🅰️🅰️⬛️⬛️⬛️⬛️✨ <br>\n✨✨✨✨⬛️🅰️🅰️⬛️⬛️🅰️⬛️⬛️🅰️🅰️⬛️✨✨✨✨<br>\n✨✨✨✨⬛️🅰️⬛️☁️⬛️🅰️⬛️☁️⬛️🅰️⬛️✨✨✨✨<br>\n✨✨✨✨⬛️🅰️⬛️☁️⬛️🅰️⬛️☁️⬛️🅰️⬛️✨✨✨✨<br>\n✨✨✨✨⬛️🅰️⬛️⬛️⬛️🅰️⬛️⬛️⬛️🅰️⬛️✨✨✨✨<br>\n✨✨✨✨⬛️🅰️⬛️🅰️🅰️🅰️🅰️🅰️⬛️🅰️⬛️✨✨✨✨<br>\n✨✨✨✨⬛️🅰️🅰️🅰️🅰️🅰️🅰️🅰️🅰️🅰️⬛️✨✨✨✨<br>\n✨✨✨✨✨⬛️🅰️🅰️🅰️🅰️🅰️🅰️🅰️⬛️✨✨✨✨✨<br>\n✨✨✨✨✨✨⬛️⬛️🅰️🅰️🅰️⬛️⬛️✨✨✨✨✨✨<br>\n✨✨✨✨✨✨✨✨⬛️⬛️⬛️✨✨✨✨✨✨✨✨<br>\n✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨<br></p></center><br>\n<h1 style=\"font-size: 30px; margin-right:50px\">Spiderman is here to <br>Remind you to Upvote 👾</h1>"},{"metadata":{},"cell_type":"markdown","source":"# Importing Libraries\n<p style=\"font-size: 20px; margin-right:50px\"> Importing all the necessary libraries.</p>"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Cloning the Github Repo for the Model.\n!git clone https://github.com/DingXiaoH/RepVGG.git","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Some Native Python Tools.\nimport glob\nfrom itertools import chain\nimport os\nimport random\n\n# These ones are for dealing with our Data.\nimport matplotlib.pyplot as plt\nimport pandas as pd\nfrom PIL import Image\nimport numpy as np\n\n# PyTorch is like that one boss who actually does everything he can to help you.\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\nfrom torch.optim.lr_scheduler import StepLR\nfrom torch.utils.data import DataLoader, Dataset\nfrom torchvision import datasets, transforms\n\n# Keeping Time in check.\nfrom tqdm.notebook import tqdm\n\n# Tools for Preprocessing and stuff.\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import OrdinalEncoder\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Heading to the directory with model files.\ncd ./RepVGG","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# For Grabbing the RepVGG Model.\nfrom repvgg import repvgg_model_convert, create_RepVGG_A0","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Heading back to where the other data is stored.\ncd ../","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Setting up the Hyperparameters\n\nbatch_size = 64\nepochs = 15\nlr = 3e-4\ngamma= 0.7\nseed = 42","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h1 style=\"font-size: 27px; margin-right:50px\">Seeding Everything</h1>\n<p style=\"font-size: 20px; margin-right:50px\">Seeding makes things reproduceable so let's go!</p>"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Definign a function to seed everything.\ndef seed_it(seed):\n    random.seed(seed)\n    os.environ[\"PYTHONSEED\"] = str(seed)\n    np.random.seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed)\n    torch.backends.cudnn.deterministic = True\n    \n# Running the Function.\nseed_it(seed)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Moving stuff to the GPU.\ndevice = \"cuda\"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h1 style=\"font-size: 27px; margin-right:50px\">Preprocessing</h1>\n<p style=\"font-size: 20px; margin-right:50px\">Here, we will make a list of all images' paths and put them in a tuple along with thier labels. Also, let's gather all those tuples and put them into a list.</p>"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Defining the paths to files.\ntrainimages = \"../input/ranzcr-clip-catheter-line-classification\"\n\ntraindf = pd.read_csv(\"../input/ranzcr-clip-catheter-line-classification/train_annotations.csv\")\n\n\nord_enc = OrdinalEncoder()\ntraindf[\"label\"] = ord_enc.fit_transform(traindf[[\"label\"]])\ntraindf['label'] = traindf['label'].astype(\"int64\")\n\ntrain_list = []\n# Converting the Image IDs to their paths.\nfor i in traindf.index:\n    \n    a = traindf[\"StudyInstanceUID\"].loc[i]\n    \n    b = trainimages + \"/train/\" + a + \".jpg\"\n    \n    train_list.append((b, traindf['label'].loc[i]))\n\n# Taking a look.\ntrain_list[:3]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Visualizing the Data\n<p style=\"font-size: 20px; margin-right:50px\">Time to take a look at our Data!</p>\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"random_idx = np.random.randint(1, len(train_list), size=16)\nfig, axes = plt.subplots(6,6, figsize=(13,13))\n\nfor idx, ax in enumerate(axes.ravel()):\n    img = Image.open(train_list[idx][0])\n    ax.set_title(train_list[idx][1])\n    ax.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Dataloader\n<p style=\"font-size: 20px; margin-right:50px\">Time to set up a DataLoader with the resources we have.</p>"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Splitting the data into training and validation datasets.\ntrain, valid = train_test_split(train_list,\n                                test_size=0.2,\n                                random_state=42)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h1 style=\"font-size: 27px; margin-right:50px\">Transforms</h1>\n<p style=\"font-size: 20px; margin-right:50px\">Producing some transformations for our training and validation datasets.</p>"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_trans = transforms.Compose([\n                transforms.Resize((224, 224), interpolation=Image.NEAREST),\n                #transforms.RandomResizedCrop(224),\n                transforms.RandomHorizontalFlip(),\n                transforms.ToTensor(),\n                transforms.Normalize(mean=[0.485, 0.456, 0.406],\n                                         std=[0.229, 0.224, 0.225])\n            ])\n\nvalid_trans = transforms.Compose([\n                transforms.Resize((224, 224), interpolation=Image.NEAREST),\n                transforms.ToTensor(),\n                transforms.Normalize(mean=[0.485, 0.456, 0.406],\n                                         std=[0.229, 0.224, 0.225])\n            ])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h1 style=\"font-size: 27px; margin-right:50px\">Dataset Class</h1>\n<p style=\"font-size: 20px; margin-right:50px\">Defining the PyTorch Dataset Class.</p>"},{"metadata":{"trusted":true},"cell_type":"code","source":"class RANZCRDataset(Dataset):\n    \n    # Grabbing the transforms presets.\n    def __init__(self, file_list, transform=None):\n        self.file_list = file_list\n        self.transform = transform\n        \n    def __len__(self):\n        self.filelength = len(self.file_list)\n        return self.filelength\n    \n    def __getitem__(self, idx):\n        \n        img_path = self.file_list[idx][0]\n        img = Image.open(img_path).convert(\"RGB\")\n        img_transformed = self.transform(img)\n        \n        # The second item in the tuple is the label.\n        label = self.file_list[idx][1]\n        \n        return img_transformed, label","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<p style=\"font-size: 20px; margin-right:50px\">Finally collecting everthing into a two DataLoaders. One for the training data and another for the valid data.</p>\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data = RANZCRDataset(train, transform = train_trans)\nvalid_data = RANZCRDataset(valid, transform = valid_trans)\n\ntrain_loader = DataLoader(dataset = train_data, batch_size = batch_size, shuffle = True)\nvalid_loader = DataLoader(dataset = valid_data, batch_size = batch_size, shuffle = True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Model 🧠\n<p style=\"font-size: 20px; margin-right:50px\">Grabbing the Model.</p>"},{"metadata":{"trusted":true},"cell_type":"code","source":"model = create_RepVGG_A0(deploy=False).to(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Defining some presets.\n\ncriterion = nn.CrossEntropyLoss()\n\noptimizer = optim.Adam(model.parameters(), lr = lr)\n\nscheduler = StepLR(optimizer, step_size=1, gamma=gamma)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Training the Model 👟👟\n<p style=\"font-size: 20px; margin-right:50px\">Let's use everything that we have done above to finally train the model a few Epochs!</p>"},{"metadata":{"trusted":true},"cell_type":"code","source":"for epoch in range(epochs):\n    epoch_loss = 0.0\n    epoch_accuracy = 0.0\n    \n    for data, label in tqdm(train_loader):\n        data = data.to(device)\n        label = label.to(device)\n        \n        output = model(data)\n        \n        label = torch.nn.functional.one_hot(label, num_classes = 11)\n        label = label.squeeze_()\n        label = torch.argmax(label, axis=1)\n        \n        label = label.type_as(output)\n        \n        loss = criterion(output, label.long())\n        \n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n        \n        acc = (output.argmax(dim=1) == label).float().mean()\n        epoch_accuracy += acc / len(train_loader)\n        epoch_loss += loss / len(train_loader)\n\n        \n    with torch.no_grad():\n        epoch_val_accuracy = 0\n        epoch_val_loss = 0        \n        \n        for data, label in valid_loader:\n            data = data.to(device)\n            \n            label = label.to(device)\n            #label = label.squeeze_()\n            label = label.type_as(output)\n            \n            val_output = model(data)\n            val_loss = criterion(val_output, label.long())\n            \n            accc = (val_output.argmax(dim = 1) == label).float().mean()\n            epoch_val_accuracy += acc / len(valid_loader)\n            epoch_val_loss += val_loss / len(valid_loader)\n\n    print(\n        f\"Epoch: {epoch+1} - loss: {epoch_loss:.4f} - acc : {epoch_accuracy:.4f} - val_loss : {epoch_val_loss:.4f} - val_acc: {epoch_val_accuracy: .4f}\\n\"\n    )","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<h1 style=\"font-size: 30px; margin-right:50px\">Thank You for going through this notebook!</h1>\n<p style=\"font-size: 20px; margin-right:50px\">(Not releasing the accuracy due to the apparent Loss Function Fiasco)</p>"}],"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":4,"nbformat_minor":4}