{"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":"markdown","source":"<br>\n<h2 style = \"font-size:60px; font-family:Garamond ; font-weight : normal; background-color: #f6f5f5 ; color : #fe346e; text-align: center; border-radius: 100px 100px;\">Wikipedia Image/Caption Starter</h2>\n<br>","metadata":{}},{"cell_type":"markdown","source":"# <span><h1 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color: #f6f5f5; color :#fe346e; border-radius: 100px 100px; text-align:center\">Install Required Libraries</h1></span>","metadata":{}},{"cell_type":"code","source":"!pip install git+https://github.com/rwightman/pytorch-image-models\n!pip install --upgrade wandb","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport gc\nimport cv2\nimport copy\nimport time\nimport random\nfrom PIL import Image\nfrom PIL import ImageFile\nImageFile.LOAD_TRUNCATED_IMAGES = True\n\nimport base64\nimport pickle\n\n# For downloading images\nfrom io import BytesIO\n\n# For data manipulation\nimport numpy as np\nimport pandas as pd\n\n# Pytorch Imports\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.optim import lr_scheduler\nfrom torch.utils.data import Dataset, DataLoader\nfrom torch.cuda import amp\n\n# Utils\nimport joblib\nfrom tqdm import tqdm\nfrom collections import defaultdict\n\n# Sklearn Imports\nfrom sklearn.metrics import mean_squared_error\nfrom sklearn.model_selection import StratifiedKFold, KFold\n\n# For Image Models\nimport timm\n\n# For Transformer Models\nfrom transformers import AutoTokenizer, AutoModel\n\n# Albumentations for augmentations\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\n\n# For colored terminal text\nfrom colorama import Fore, Back, Style\nb_ = Fore.BLUE\nsr_ = Style.RESET_ALL\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\n# For descriptive error messages\nos.environ['CUDA_LAUNCH_BLOCKING'] = \"1\"","metadata":{"execution":{"iopub.status.busy":"2021-12-23T13:58:06.061583Z","iopub.execute_input":"2021-12-23T13:58:06.061852Z","iopub.status.idle":"2021-12-23T13:58:17.251159Z","shell.execute_reply.started":"2021-12-23T13:58:06.061817Z","shell.execute_reply":"2021-12-23T13:58:17.250263Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<img src=\"https://i.imgur.com/gb6B4ig.png\" width=\"400\" alt=\"Weights & Biases\" />\n\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.2em; font-weight: 300;\"> Weights & Biases (W&B) is a set of machine learning tools that helps you build better models faster. <strong>Kaggle competitions require fast-paced model development and evaluation</strong>. There are a lot of components: exploring the training data, training different models, combining trained models in different combinations (ensembling), and so on.</span>\n\n> <span style=\"color: #000508; font-family: Segoe UI; font-size: 1.2em; font-weight: 300;\">⏳ Lots of components = Lots of places to go wrong = Lots of time spent debugging</span>\n\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.2em; font-weight: 300;\">W&B can be useful for Kaggle competition with it's lightweight and interoperable tools:</span>\n\n* <span style=\"color: #000508; font-family: Segoe UI; font-size: 1.2em; font-weight: 300;\">Quickly track experiments,<br></span>\n* <span style=\"color: #000508; font-family: Segoe UI; font-size: 1.2em; font-weight: 300;\">Version and iterate on datasets, <br></span>\n* <span style=\"color: #000508; font-family: Segoe UI; font-size: 1.2em; font-weight: 300;\">Evaluate model performance,<br></span>\n* <span style=\"color: #000508; font-family: Segoe UI; font-size: 1.2em; font-weight: 300;\">Reproduce models,<br></span>\n* <span style=\"color: #000508; font-family: Segoe UI; font-size: 1.2em; font-weight: 300;\">Visualize results and spot regressions,<br></span>\n* <span style=\"color: #000508; font-family: Segoe UI; font-size: 1.2em; font-weight: 300;\">Share findings with colleagues.</span>\n\n<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.2em; font-weight: 300;\">To learn more about Weights and Biases check out this <strong><a href=\"https://www.kaggle.com/ayuraj/experiment-tracking-with-weights-and-biases\">kernel</a></strong>.</span>","metadata":{}},{"cell_type":"code","source":"import wandb\n\ntry:\n    from kaggle_secrets import UserSecretsClient\n    user_secrets = UserSecretsClient()\n    api_key = user_secrets.get_secret('wandb_api')\n    wandb.login(key=api_key)\n    anony = None\nexcept:\n    anony = \"must\"\n    print('If you want to use your W&B account, go to Add-ons -> Secrets and provide your W&B access token. Use the Label name as wandb_api. \\nGet your W&B access token from here: https://wandb.ai/authorize')","metadata":{"execution":{"iopub.status.busy":"2021-12-23T13:58:17.252899Z","iopub.execute_input":"2021-12-23T13:58:17.253226Z","iopub.status.idle":"2021-12-23T13:58:18.983532Z","shell.execute_reply.started":"2021-12-23T13:58:17.253165Z","shell.execute_reply":"2021-12-23T13:58:18.982885Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <span><h1 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color: #f6f5f5; color :#fe346e; border-radius: 100px 100px; text-align:center\">Training Configuration ⚙️</h1></span>","metadata":{}},{"cell_type":"code","source":"CONFIG = {\"seed\": 2021,\n          \"epochs\": 5,\n          \"img_size\": 256,\n          \"image_model_name\": \"tf_efficientnet_b0\",\n          \"text_model_name\": \"xlm-roberta-base\",\n          \"embedding_size\": 256,\n          \"train_batch_size\": 32,\n          \"valid_batch_size\": 64,\n          \"learning_rate\": 1e-4,\n          \"scheduler\": 'CosineAnnealingLR',\n          \"min_lr\": 1e-6,\n          \"T_max\": 500,\n          \"weight_decay\": 1e-6,\n          \"max_length\": 32,\n          \"n_accumulate\": 1,\n          \"device\": torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n          }\n\nCONFIG[\"tokenizer\"] = AutoTokenizer.from_pretrained(CONFIG['text_model_name'])","metadata":{"execution":{"iopub.status.busy":"2021-12-23T13:58:18.984504Z","iopub.execute_input":"2021-12-23T13:58:18.985055Z","iopub.status.idle":"2021-12-23T13:58:27.15659Z","shell.execute_reply.started":"2021-12-23T13:58:18.985017Z","shell.execute_reply":"2021-12-23T13:58:27.15563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"CONFIG","metadata":{"execution":{"iopub.status.busy":"2021-12-23T13:58:27.158586Z","iopub.execute_input":"2021-12-23T13:58:27.158826Z","iopub.status.idle":"2021-12-23T13:58:27.167381Z","shell.execute_reply.started":"2021-12-23T13:58:27.158795Z","shell.execute_reply":"2021-12-23T13:58:27.166546Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <span><h1 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color: #f6f5f5; color :#fe346e; border-radius: 100px 100px; text-align:center\">Set Seed for Reproducibility</h1></span>","metadata":{}},{"cell_type":"code","source":"\n\ndef set_seed(seed=42):\n    '''Sets the seed of the entire notebook so results are the same every time we run.\n    This is for REPRODUCIBILITY.'''\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    # When running on the CuDNN backend, two further options must be set\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n    # Set a fixed value for the hash seed\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    \nset_seed(CONFIG['seed'])\n\n","metadata":{"execution":{"iopub.status.busy":"2021-12-23T13:58:27.168683Z","iopub.execute_input":"2021-12-23T13:58:27.168887Z","iopub.status.idle":"2021-12-23T13:58:27.186929Z","shell.execute_reply.started":"2021-12-23T13:58:27.168861Z","shell.execute_reply":"2021-12-23T13:58:27.186344Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <span><h1 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color: #f6f5f5; color :#fe346e; border-radius: 100px 100px; text-align:center\">Download Dataset</h1></span>","metadata":{}},{"cell_type":"code","source":"run = wandb.init(project=\"Wikipedia\", \n                 anonymous=\"must\")\nartifact = run.use_artifact('dchanda/Wikipedia/Wiki-data:latest', type='dataset')\nartifact_dir = artifact.download()\nrun.finish()\n\nfor file in os.listdir(artifact_dir):\n    filepath = os.path.join(artifact_dir, file)\n    with open(filepath, \"rb\") as fp:\n        data = pickle.load(fp)\n","metadata":{"execution":{"iopub.status.busy":"2021-12-23T13:58:27.188483Z","iopub.execute_input":"2021-12-23T13:58:27.188752Z","iopub.status.idle":"2021-12-23T13:59:19.93071Z","shell.execute_reply.started":"2021-12-23T13:58:27.188711Z","shell.execute_reply":"2021-12-23T13:59:19.930026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.5em; font-weight: 300;\">Dataset Structure</span>\n<blockquote>\n<ul>\n    <li><span style=\"color: #000508; font-family: Segoe UI; font-size: 1.3em; font-weight: 300;\"><code>data</code>: list of dictionaries</span>\n    </li>\n    <ul>\n        <li><code>b64_bytes</code>: base64 encoded bytes of the image file at a 300px resolution</li>\n        <li><code>caption_title_and_reference_description</code>: list of captions</li>\n        <li><code>target</code>: 1 for positive samples and -1 for negative samples</li>\n    </ul>","metadata":{}},{"cell_type":"code","source":"\n\nrandom.shuffle(data)\nprint(len(data))\ntrain_data = data[:5000]\nvalid_data = data[5001:8000]\nprint(f\"Number of training samples: {len(train_data)}\")\nprint(f\"Number of validation samples: {len(valid_data)}\")\n\n","metadata":{"execution":{"iopub.status.busy":"2021-12-23T13:59:19.932134Z","iopub.execute_input":"2021-12-23T13:59:19.932594Z","iopub.status.idle":"2021-12-23T13:59:20.062406Z","shell.execute_reply.started":"2021-12-23T13:59:19.932561Z","shell.execute_reply":"2021-12-23T13:59:20.061562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <span><h1 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color: #f6f5f5; color :#fe346e; border-radius: 100px 100px; text-align:center\">Visualize Images</h1></span>","metadata":{}},{"cell_type":"markdown","source":"![](https://i.imgur.com/Uebq4gp.gif)","metadata":{}},{"cell_type":"markdown","source":"# <span><h1 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color: #f6f5f5; color :#fe346e; border-radius: 100px 100px; text-align:center\">Dataset Class</h1></span>","metadata":{}},{"cell_type":"code","source":"class WikipediaDataset(Dataset):\n    def __init__(self, data, tokenizer, max_length, transforms=None):\n        self.data = data\n        self.max_len = max_length\n        self.tokenizer = tokenizer\n        self.transforms = transforms\n        \n    def __len__(self):\n        return len(self.data)\n    \n    def __getitem__(self, index):\n        image_bytes = base64.b64decode(self.data[index][\"b64_bytes\"])\n        img = np.asarray(Image.open(BytesIO(image_bytes)).convert(\"RGB\"))\n        caption = random.choice(self.data[index][\"caption_title_and_reference_description\"])\n        caption = caption.replace(\"[SEP]\", \"</s>\") # sep token for xlm-roberta\n        inputs = self.tokenizer.encode_plus(\n                caption,\n                truncation=True,\n                add_special_tokens=True,\n                max_length=self.max_len,\n                padding='max_length'\n            )\n        target = self.data[index]['target']\n        \n        ids = inputs['input_ids']\n        mask = inputs['attention_mask']\n        \n        if self.transforms:\n            img = self.transforms(image=img)[\"image\"]\n        \n        return {\n            'ids': torch.tensor(ids, dtype=torch.long),\n            'mask': torch.tensor(mask, dtype=torch.long),\n            'image': img,\n            'target': torch.tensor(target, dtype=torch.long)\n        }","metadata":{"execution":{"iopub.status.busy":"2021-12-23T13:59:20.063743Z","iopub.execute_input":"2021-12-23T13:59:20.063983Z","iopub.status.idle":"2021-12-23T13:59:25.568443Z","shell.execute_reply.started":"2021-12-23T13:59:20.063953Z","shell.execute_reply":"2021-12-23T13:59:25.567711Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <span><h1 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color: #f6f5f5; color :#fe346e; border-radius: 100px 100px; text-align:center\">Augmentations</h1></span>","metadata":{}},{"cell_type":"code","source":"data_transforms = {\n    \"train\": A.Compose([\n        A.Resize(CONFIG['img_size'], CONFIG['img_size']),\n        A.HorizontalFlip(p=0.5),\n        A.Normalize(\n                mean=[0.485, 0.456, 0.406], \n                std=[0.229, 0.224, 0.225], \n                max_pixel_value=255.0, \n                p=1.0\n            ),\n        ToTensorV2()], p=1.),\n    \n    \"valid\": A.Compose([\n        A.Resize(CONFIG['img_size'], CONFIG['img_size']),\n        A.Normalize(\n                mean=[0.485, 0.456, 0.406], \n                std=[0.229, 0.224, 0.225], \n                max_pixel_value=255.0, \n                p=1.0\n            ),\n        ToTensorV2()], p=1.)\n}","metadata":{"execution":{"iopub.status.busy":"2021-12-23T13:59:25.571561Z","iopub.execute_input":"2021-12-23T13:59:25.571859Z","iopub.status.idle":"2021-12-23T13:59:33.900304Z","shell.execute_reply.started":"2021-12-23T13:59:25.571825Z","shell.execute_reply":"2021-12-23T13:59:33.899217Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = WikipediaDataset(train_data, CONFIG[\"tokenizer\"], CONFIG[\"max_length\"], \n                                 transforms=data_transforms[\"train\"])\ntrain_loader = DataLoader(train_dataset, batch_size=CONFIG['train_batch_size'], \n                          num_workers=4, shuffle=True, pin_memory=True, drop_last=True)\n\nvalid_dataset = WikipediaDataset(valid_data, CONFIG[\"tokenizer\"], CONFIG[\"max_length\"], \n                                 transforms=data_transforms[\"valid\"])\nvalid_loader = DataLoader(valid_dataset, batch_size=CONFIG['valid_batch_size'], \n                          num_workers=4, shuffle=False, pin_memory=True)","metadata":{"execution":{"iopub.status.busy":"2021-12-23T13:59:33.901697Z","iopub.execute_input":"2021-12-23T13:59:33.901948Z","iopub.status.idle":"2021-12-23T13:59:38.84748Z","shell.execute_reply.started":"2021-12-23T13:59:33.901917Z","shell.execute_reply":"2021-12-23T13:59:38.846722Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <span><h1 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color: #f6f5f5; color :#fe346e; border-radius: 100px 100px; text-align:center\">Create Model</h1></span>","metadata":{}},{"cell_type":"markdown","source":"![](https://i.imgur.com/PzooBWU.png)","metadata":{}},{"cell_type":"code","source":"class WikipediaModel(nn.Module):\n    def __init__(self, image_model, text_model, embedding_size):\n        super(WikipediaModel, self).__init__()\n        self.image_model = timm.create_model(image_model, pretrained=True)\n        self.n_features = self.image_model.classifier.in_features\n        self.image_model.reset_classifier(0)\n        self.image_drop = nn.Dropout(p=0.2)\n        self.image_fc = nn.Linear(self.n_features, embedding_size)\n        \n        self.text_model = AutoModel.from_pretrained(text_model)\n        self.text_drop = nn.Dropout(p=0.2)\n        self.text_fc = nn.Linear(768, embedding_size)\n        \n        self.freeze_backbone()\n        \n    def forward(self, images, ids, mask):\n        image_features = self.image_model(images)\n        image_embeddings = self.image_fc(self.image_drop(image_features))\n        \n        out = self.text_model(input_ids=ids,attention_mask=mask,\n                              output_hidden_states=False)\n        out = self.text_drop(out[1])\n        text_embeddings = self.text_fc(out)\n\n        return image_embeddings, text_embeddings\n    \n    def freeze_backbone(self):\n        for params in self.image_model.parameters():\n            params.requires_grad = False\n        # Only finetune final layer\n        self.image_fc.weight.requires_grad = True\n        self.image_fc.bias.requires_grad = True\n        \n        for params in self.text_model.parameters():\n            params.requires_grad = False\n        # Only finetune final layer\n        self.text_fc.weight.requires_grad = True\n        self.text_fc.bias.requires_grad = True\n    \n\nmodel = WikipediaModel(CONFIG['image_model_name'], CONFIG['text_model_name'], CONFIG['embedding_size'])\nmodel.to(CONFIG['device']);","metadata":{"execution":{"iopub.status.busy":"2021-12-23T13:59:38.850769Z","iopub.execute_input":"2021-12-23T13:59:38.851105Z","iopub.status.idle":"2021-12-23T14:00:27.687683Z","shell.execute_reply.started":"2021-12-23T13:59:38.851065Z","shell.execute_reply":"2021-12-23T14:00:27.686773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <span><h1 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color: #f6f5f5; color :#fe346e; border-radius: 100px 100px; text-align:center\">Loss Function</h1></span>","metadata":{}},{"cell_type":"code","source":"\n\ndef criterion(outputs1, outputs2, targets):\n    return nn.CosineEmbeddingLoss()(outputs1, outputs2, targets)\n\n","metadata":{"execution":{"iopub.status.busy":"2021-12-23T14:00:27.689301Z","iopub.execute_input":"2021-12-23T14:00:27.690294Z","iopub.status.idle":"2021-12-23T14:00:27.695634Z","shell.execute_reply.started":"2021-12-23T14:00:27.69024Z","shell.execute_reply":"2021-12-23T14:00:27.694636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <span><h1 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color: #f6f5f5; color :#fe346e; border-radius: 100px 100px; text-align:center\">Training Function</h1></span>","metadata":{}},{"cell_type":"code","source":"def train_one_epoch(model, optimizer, scheduler, dataloader, device, epoch):\n    model.train()\n    \n    dataset_size = 0\n    running_loss = 0.0\n    \n    bar = tqdm(enumerate(dataloader), total=len(dataloader))\n    for step, data in bar:\n        ids = data['ids'].to(device, dtype = torch.long)\n        mask = data['mask'].to(device, dtype = torch.long)\n        images = data['image'].to(device, dtype=torch.float)\n        targets = data['target'].to(device, dtype=torch.long)\n        \n        batch_size = ids.size(0)\n\n        image_outputs, text_outputs = model(images, ids, mask)\n        loss = criterion(image_outputs, text_outputs, targets)\n        loss = loss / CONFIG['n_accumulate']\n        loss.backward()\n    \n        if (step + 1) % CONFIG['n_accumulate'] == 0:\n            optimizer.step()\n\n            # zero the parameter gradients\n            optimizer.zero_grad()\n\n            if scheduler is not None:\n                scheduler.step()\n                \n        running_loss += (loss.item() * batch_size)\n        dataset_size += batch_size\n        \n        epoch_loss = running_loss / dataset_size\n        \n        bar.set_postfix(Epoch=epoch, Train_Loss=epoch_loss,\n                        LR=optimizer.param_groups[0]['lr'])\n    gc.collect()\n    \n    return epoch_loss","metadata":{"execution":{"iopub.status.busy":"2021-12-23T14:00:27.699157Z","iopub.execute_input":"2021-12-23T14:00:27.699928Z","iopub.status.idle":"2021-12-23T14:00:27.711576Z","shell.execute_reply.started":"2021-12-23T14:00:27.699888Z","shell.execute_reply":"2021-12-23T14:00:27.710687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# def calAccuracy(outputs1, targets)","metadata":{"execution":{"iopub.status.busy":"2021-12-23T14:00:27.712772Z","iopub.execute_input":"2021-12-23T14:00:27.713024Z","iopub.status.idle":"2021-12-23T14:00:27.728372Z","shell.execute_reply.started":"2021-12-23T14:00:27.712984Z","shell.execute_reply":"2021-12-23T14:00:27.727056Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <span><h1 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color: #f6f5f5; color :#fe346e; border-radius: 100px 100px; text-align:center\">Validation Function</h1></span>","metadata":{}},{"cell_type":"code","source":"@torch.no_grad()\ndef valid_one_epoch(model, dataloader, device, epoch):\n    model.eval()\n    \n    dataset_size = 0\n    running_loss = 0.0\n    \n    bar = tqdm(enumerate(dataloader), total=len(dataloader))\n    for step, data in bar:        \n        ids = data['ids'].to(device, dtype = torch.long)\n        mask = data['mask'].to(device, dtype = torch.long)\n        images = data['image'].to(device, dtype=torch.float)\n        targets = data['target'].to(device, dtype=torch.long)\n        \n        batch_size = ids.size(0)\n        \n        image_outputs, text_outputs = model(images, ids, mask)\n        loss = criterion(image_outputs, text_outputs, targets)\n        print(\"trung tin\",image_outputs)\n        return \n        running_loss += (loss.item() * batch_size)\n        dataset_size += batch_size\n        \n        epoch_loss = running_loss / dataset_size\n        \n        bar.set_postfix(Epoch=epoch, Valid_Loss=epoch_loss,\n                        LR=optimizer.param_groups[0]['lr'])   \n    \n    gc.collect()\n    \n    return epoch_loss","metadata":{"execution":{"iopub.status.busy":"2021-12-23T14:00:27.73Z","iopub.status.idle":"2021-12-23T14:00:27.730743Z","shell.execute_reply.started":"2021-12-23T14:00:27.730505Z","shell.execute_reply":"2021-12-23T14:00:27.730541Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <span><h1 style = \"font-family: garamond; font-size: 40px; font-style: normal; letter-spcaing: 3px; background-color: #f6f5f5; color :#fe346e; border-radius: 100px 100px; text-align:center\">Run Training</h1></span>","metadata":{}},{"cell_type":"code","source":"def run_training(model, optimizer, scheduler, device, num_epochs):\n    # To automatically log gradients\n    wandb.watch(model, log_freq=100)\n    \n    if torch.cuda.is_available():\n        print(\"[INFO] Using GPU: {}\\n\".format(torch.cuda.get_device_name()))\n    \n    start = time.time()\n    best_model_wts = copy.deepcopy(model.state_dict())\n    best_epoch_loss = np.inf\n    history = defaultdict(list)\n    \n    for epoch in range(1, num_epochs + 1): \n        gc.collect()\n        train_epoch_loss = train_one_epoch(model, optimizer, scheduler, \n                                           dataloader=train_loader, \n                                           device=CONFIG['device'], epoch=epoch)\n        \n        val_epoch_loss = valid_one_epoch(model, valid_loader, device=CONFIG['device'], \n                                         epoch=epoch)\n    \n        history['Train Loss'].append(train_epoch_loss)\n        history['Valid Loss'].append(val_epoch_loss)\n        \n        # Log the metrics\n        wandb.log({\"Train Loss\": train_epoch_loss})\n        wandb.log({\"Valid Loss\": val_epoch_loss})\n        \n        # deep copy the model\n        if val_epoch_loss <= best_epoch_loss:\n            print(f\"{b_}Validation Loss Improved ({best_epoch_loss} ---> {val_epoch_loss})\")\n            best_epoch_loss = val_epoch_loss\n            run.summary[\"Best Loss\"] = best_epoch_loss\n            best_model_wts = copy.deepcopy(model.state_dict())\n            PATH = \"Loss{:.4f}_epoch{:.0f}.bin\".format(best_epoch_loss, epoch)\n            torch.save(model.state_dict(), PATH)\n            # Save a model file from the current directory\n            print(f\"Model Saved{sr_}\")\n            \n        print()\n    \n    end = time.time()\n    time_elapsed = end - start\n    print('Training complete in {:.0f}h {:.0f}m {:.0f}s'.format(\n        time_elapsed // 3600, (time_elapsed % 3600) // 60, (time_elapsed % 3600) % 60))\n    print(\"Best Loss: {:.4f}\".format(best_epoch_loss))\n    \n    # load best model weights\n    model.load_state_dict(best_model_wts)\n    \n    return model, history","metadata":{"execution":{"iopub.status.busy":"2021-12-23T14:00:27.731767Z","iopub.status.idle":"2021-12-23T14:00:27.732747Z","shell.execute_reply.started":"2021-12-23T14:00:27.73236Z","shell.execute_reply":"2021-12-23T14:00:27.732387Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.5em; font-weight: 300;\">Define Optimizer and Scheduler</span>","metadata":{}},{"cell_type":"code","source":"def fetch_scheduler(optimizer):\n    if CONFIG['scheduler'] == 'CosineAnnealingLR':\n        scheduler = lr_scheduler.CosineAnnealingLR(optimizer,T_max=CONFIG['T_max'], \n                                                   eta_min=CONFIG['min_lr'])\n    elif CONFIG['scheduler'] == 'CosineAnnealingWarmRestarts':\n        scheduler = lr_scheduler.CosineAnnealingWarmRestarts(optimizer,T_0=CONFIG['T_0'], \n                                                             eta_min=CONFIG['min_lr'])\n    elif CONFIG['scheduler'] == None:\n        return None\n        \n    return scheduler","metadata":{"execution":{"iopub.status.busy":"2021-12-23T14:00:27.733762Z","iopub.status.idle":"2021-12-23T14:00:27.734648Z","shell.execute_reply.started":"2021-12-23T14:00:27.734458Z","shell.execute_reply":"2021-12-23T14:00:27.73448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<span style=\"color: #000508; font-family: Segoe UI; font-size: 1.5em; font-weight: 300;\">Start Training</span>","metadata":{}},{"cell_type":"code","source":"optimizer = optim.Adam(model.parameters(), lr=CONFIG['learning_rate'], \n                       weight_decay=CONFIG['weight_decay'])\nscheduler = fetch_scheduler(optimizer)","metadata":{"execution":{"iopub.status.busy":"2021-12-23T14:00:27.736081Z","iopub.status.idle":"2021-12-23T14:00:27.736414Z","shell.execute_reply.started":"2021-12-23T14:00:27.736251Z","shell.execute_reply":"2021-12-23T14:00:27.736269Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n\nrun = wandb.init(project='Wikipedia', \n                 config=CONFIG,\n                 job_type='Train',\n                 anonymous='must')\n\n","metadata":{"execution":{"iopub.status.busy":"2021-12-23T14:00:27.737579Z","iopub.status.idle":"2021-12-23T14:00:27.737879Z","shell.execute_reply.started":"2021-12-23T14:00:27.737725Z","shell.execute_reply":"2021-12-23T14:00:27.73774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n\nmodel, history = run_training(model, optimizer, scheduler, \n                              device=CONFIG['device'],\n                              num_epochs=CONFIG['epochs'])\n\n","metadata":{"execution":{"iopub.status.busy":"2021-12-23T14:00:27.738988Z","iopub.status.idle":"2021-12-23T14:00:27.739518Z","shell.execute_reply.started":"2021-12-23T14:00:27.739337Z","shell.execute_reply":"2021-12-23T14:00:27.739357Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n\nrun.finish()\n\n","metadata":{"execution":{"iopub.status.busy":"2021-12-23T14:00:27.741129Z","iopub.status.idle":"2021-12-23T14:00:27.741493Z","shell.execute_reply.started":"2021-12-23T14:00:27.741331Z","shell.execute_reply":"2021-12-23T14:00:27.741349Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from IPython import display\n\n# we create an IFrame and set the width and height\niF = display.IFrame(run.url, width=1080, height=720)\niF","metadata":{"execution":{"iopub.status.busy":"2021-12-23T14:00:27.742631Z","iopub.status.idle":"2021-12-23T14:00:27.742929Z","shell.execute_reply.started":"2021-12-23T14:00:27.742774Z","shell.execute_reply":"2021-12-23T14:00:27.74279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.","metadata":{"execution":{"iopub.status.busy":"2021-12-23T14:00:27.744072Z","iopub.status.idle":"2021-12-23T14:00:27.744405Z","shell.execute_reply.started":"2021-12-23T14:00:27.74423Z","shell.execute_reply":"2021-12-23T14:00:27.744247Z"},"trusted":true},"execution_count":null,"outputs":[]}]}