{"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":"!pip install efficientnet_pytorch\n!pip install neptune-client","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:55:32.410424Z","iopub.execute_input":"2022-01-12T06:55:32.411110Z","iopub.status.idle":"2022-01-12T06:55:56.386499Z","shell.execute_reply.started":"2022-01-12T06:55:32.410998Z","shell.execute_reply":"2022-01-12T06:55:56.385700Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport time\nimport random\nimport yaml\n\nimport numpy as np\nimport cv2 as cv\nimport pandas as pd\nimport neptune.new as neptune\nimport matplotlib.pyplot as plt\n\nimport efficientnet_pytorch\n\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import DataLoader, Dataset\n\nfrom pathlib import Path\nfrom tqdm import tqdm\n\nfrom albumentations import (\n    Compose, Normalize, Transpose, HorizontalFlip,\n    VerticalFlip, RandomRotate90, RandomScale\n)\nfrom albumentations.pytorch import ToTensorV2","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:56:00.780449Z","iopub.execute_input":"2022-01-12T06:56:00.781202Z","iopub.status.idle":"2022-01-12T06:56:04.703124Z","shell.execute_reply.started":"2022-01-12T06:56:00.781155Z","shell.execute_reply":"2022-01-12T06:56:04.702348Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')\nprint(device)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:56:09.622164Z","iopub.execute_input":"2022-01-12T06:56:09.622420Z","iopub.status.idle":"2022-01-12T06:56:09.665502Z","shell.execute_reply.started":"2022-01-12T06:56:09.622390Z","shell.execute_reply":"2022-01-12T06:56:09.664565Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_dir = Path('/kaggle/input/cassava-leaf-disease-classification')\ncustom_data_base_dir = Path('/kaggle/input/cassava-dataset-splitted')\ntrain_img_dir = f'{base_dir}/train_images'\ntrain_df = pd.read_csv(f'{custom_data_base_dir}/cassava_splitted.csv')","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:56:11.478849Z","iopub.execute_input":"2022-01-12T06:56:11.479100Z","iopub.status.idle":"2022-01-12T06:56:11.530448Z","shell.execute_reply.started":"2022-01-12T06:56:11.479073Z","shell.execute_reply":"2022-01-12T06:56:11.529786Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:56:24.763493Z","iopub.execute_input":"2022-01-12T06:56:24.764070Z","iopub.status.idle":"2022-01-12T06:56:24.775365Z","shell.execute_reply.started":"2022-01-12T06:56:24.764031Z","shell.execute_reply":"2022-01-12T06:56:24.774615Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Config:\n    cfg = {\n        'seed': 42,\n        'validation_fold': 0,\n        'num_classes': 5,\n        'image_size': (512, 512),\n        'weight_decay': 1e-6,\n        'batch_size': 32,\n        'learning_rate': 0.001,\n        'criterion': 'cross_entropy',\n        'warm_restarts_T_0': 10,\n        'warm_restarts_eta_min': 1e-6,\n        'epochs': 10,\n        'patience': 10,\n        'num_workers': 8\n        \n    }\n    \n    neptune_settings = {\n        'active': True,\n        'log_artifacts': False\n    }","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:56:36.927043Z","iopub.execute_input":"2022-01-12T06:56:36.927303Z","iopub.status.idle":"2022-01-12T06:56:36.932600Z","shell.execute_reply.started":"2022-01-12T06:56:36.927272Z","shell.execute_reply":"2022-01-12T06:56:36.931905Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def seed_everything(seed):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = True\n    \nseed_everything(Config.cfg['seed'])","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:56:37.520771Z","iopub.execute_input":"2022-01-12T06:56:37.521006Z","iopub.status.idle":"2022-01-12T06:56:37.528761Z","shell.execute_reply.started":"2022-01-12T06:56:37.520978Z","shell.execute_reply":"2022-01-12T06:56:37.528083Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_neptune_config(config_path):\n    with open(config_path) as f:\n        neptune_config = yaml.load(f, Loader=yaml.FullLoader)\n    return neptune_config","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:56:38.240202Z","iopub.execute_input":"2022-01-12T06:56:38.240842Z","iopub.status.idle":"2022-01-12T06:56:38.244869Z","shell.execute_reply.started":"2022-01-12T06:56:38.240805Z","shell.execute_reply":"2022-01-12T06:56:38.244167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"neptune_config = get_neptune_config('/kaggle/input/neptune-configuration-file/neptune_config.yaml')","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:56:38.916136Z","iopub.execute_input":"2022-01-12T06:56:38.917065Z","iopub.status.idle":"2022-01-12T06:56:38.926837Z","shell.execute_reply.started":"2022-01-12T06:56:38.917011Z","shell.execute_reply":"2022-01-12T06:56:38.925765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if Config.neptune_settings['active']:\n    neptune_run = neptune.init(\n        project = neptune_config['project'],\n        api_token = neptune_config['api_token']\n    )\n    \n    neptune_run['my_params'] = Config.cfg","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:56:42.944809Z","iopub.execute_input":"2022-01-12T06:56:42.945072Z","iopub.status.idle":"2022-01-12T06:56:45.766558Z","shell.execute_reply.started":"2022-01-12T06:56:42.945041Z","shell.execute_reply":"2022-01-12T06:56:45.765835Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CassavaDataset(Dataset):\n    def __init__(self, df, image_size, augments=None):\n        self.df = df.image_id.tolist()\n        self.targets = df['label'].tolist()\n        self.image_size = image_size\n        self.augments = augments\n        \n    def __getitem__(self, idx):\n        image = cv.imread(os.path.join(train_img_dir, self.df[idx]))\n        image = cv.resize(image, self.image_size)\n        image = cv.cvtColor(image, cv.COLOR_BGR2RGB)\n        \n        if self.augments:\n            image = self.augments(image=image)['image']\n            \n        y = torch.tensor(self.targets[idx], dtype=torch.long)\n        \n        return {'X': image, 'y': y}\n    \n    def __len__(self):\n        return len(self.targets)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:56:45.936658Z","iopub.execute_input":"2022-01-12T06:56:45.936879Z","iopub.status.idle":"2022-01-12T06:56:45.946701Z","shell.execute_reply.started":"2022-01-12T06:56:45.936848Z","shell.execute_reply":"2022-01-12T06:56:45.946017Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Augments:\n    train_augments = Compose([\n        Transpose(p=.5),\n        HorizontalFlip(p=.5),\n        VerticalFlip(p=.5),\n        RandomRotate90(),\n        Normalize(mean=[.485, .456, .406],\n                  std=[.229, .224, .225],\n                  p=1.),\n        ToTensorV2(p=1.),\n    ],\n    p=1.,\n    )\n    \n    val_augments = Compose([\n        Normalize(mean=[.485, .456, .406],\n                  std=[.229, .224, .225],\n                  p=1.),\n        ToTensorV2(p=1.),\n    ],\n    p=1.,\n    )","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:56:53.418239Z","iopub.execute_input":"2022-01-12T06:56:53.418506Z","iopub.status.idle":"2022-01-12T06:56:53.424598Z","shell.execute_reply.started":"2022-01-12T06:56:53.418474Z","shell.execute_reply":"2022-01-12T06:56:53.423888Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def efficientnet_b0(num_classes):\n    model = efficientnet_pytorch.EfficientNet.from_pretrained('efficientnet-b0')\n    model._fc = nn.Linear(in_features=1280,\n                          out_features=num_classes,\n                          bias=True)\n    return model","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:56:54.557526Z","iopub.execute_input":"2022-01-12T06:56:54.558017Z","iopub.status.idle":"2022-01-12T06:56:54.563166Z","shell.execute_reply.started":"2022-01-12T06:56:54.557980Z","shell.execute_reply":"2022-01-12T06:56:54.562009Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def efficientnet_b4(num_classes):\n    model = efficientnet_pytorch.EfficientNet.from_pretrained('efficientnet-b4')\n    model._fc = nn.Linear(in_features=1792,\n                          out_features=num_classes,\n                          bias=True)\n    return model","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:56:57.385997Z","iopub.execute_input":"2022-01-12T06:56:57.386513Z","iopub.status.idle":"2022-01-12T06:56:57.391049Z","shell.execute_reply.started":"2022-01-12T06:56:57.386474Z","shell.execute_reply":"2022-01-12T06:56:57.390247Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def resnet_18(num_classes):\n    model = torch.hub.load('pytorch/vision:v0.10.1', 'resnet18', pretrained=True)\n    model.classifier = nn.Linear(in_features=512,\n                                 out_features=num_classes,\n                                 bias=True)\n    return model","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:56:57.979885Z","iopub.execute_input":"2022-01-12T06:56:57.980314Z","iopub.status.idle":"2022-01-12T06:56:57.986165Z","shell.execute_reply.started":"2022-01-12T06:56:57.980279Z","shell.execute_reply":"2022-01-12T06:56:57.983878Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def resnet_101(num_classes):\n    model = torch.hub.load('pytorch/vision:v0.10.1', 'resnet101', pretrained=True)\n    model.classifier = nn.Linear(in_features=2048,\n                                 out_features=num_classes,\n                                 bias=True)\n    return model","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:56:58.350080Z","iopub.execute_input":"2022-01-12T06:56:58.350398Z","iopub.status.idle":"2022-01-12T06:56:58.354950Z","shell.execute_reply.started":"2022-01-12T06:56:58.350367Z","shell.execute_reply":"2022-01-12T06:56:58.354258Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Trainer:\n    def __init__(self, model, optimizer, criterion, loss_metric, score_metric, scheduler, device='cuda:0'):\n        self.model = model\n        self.optimizer = optimizer\n        self.criterion = criterion\n        self.loss_metric = loss_metric\n        self.score_metric = score_metric\n        self.scheduler = scheduler\n        self.device = device\n        \n        self.best_valid_score = -np.inf\n        self.n_patience = 0\n        \n        self.messages = {\n            \"batch\": \"[{}: {}/{}] loss: {:.5f}, score: {:.5f}, time: {} s\",\n            \"epoch\": \"[Epoch {}: {}] loss: {:.5f}, score: {:.5f}, time: {} s\",\n            \"checkpoint\": \"The score improved from {:.5f} to {:.5f}. Save model to '{}'\",\n            \"patience\": \"\\nValid score didn't improve last {} epochs.\"\n        }\n        \n    \n    def fit(self, epochs, train_loader, valid_loader, save_path, patience):\n        history = {\n            \"train_loss\": [],\n            \"train_score\": [],\n            \"valid_loss\": [],\n            \"valid_score\": [],\n        }\n        \n        for num_epoch in range(1, epochs + 1):\n            self.info_message(f'Epoch: {num_epoch}')\n            \n            if Config.neptune_settings['active']:\n                neptune_run['lr'].log(self.optimizer.param_groups[0]['lr'])\n            \n            train_loss, train_score, train_time = self.train_epoch(train_loader, num_epoch)\n            valid_loss, valid_score, valid_time = self.valid_epoch(valid_loader)\n            \n            history[\"train_loss\"].append(train_loss)\n            history[\"train_score\"].append(train_score)\n            history[\"valid_loss\"].append(valid_loss)\n            history[\"valid_score\"].append(valid_score)\n            \n            self.info_message(\n                self.messages['epoch'], 'Train', num_epoch, train_loss, train_score, train_time\n            )\n            \n            if Config.neptune_settings['active']:\n                neptune_run['train_loss'].log(train_loss)\n                neptune_run['train_accuracy'].log(train_score)\n            \n            self.info_message(\n                self.messages['epoch'], 'Train', num_epoch, valid_loss, valid_score, valid_time\n            )\n            \n            if Config.neptune_settings['active']:\n                neptune_run['valid_loss'].log(valid_loss)\n                neptune_run['valid_accuracy'].log(valid_score)\n            \n            if self.best_valid_score < valid_score:\n                self.info_message(\n                    self.messages['checkpoint'], self.best_valid_score, valid_score, save_path\n                )\n                self.best_valid_score = valid_score\n                self.save_model(num_epoch, save_path)\n                self.n_patience = 0\n            else:\n                self.n_patience += 1\n                \n            if self.n_patience >= patience:\n                self.info_message(self.messages['patience'], patience)\n                break\n        \n        return history\n    \n    def train_epoch(self, train_loader, epoch):\n        self.model.train()\n        t = time.time()\n        train_loss = self.loss_metric()\n        train_score = self.score_metric()\n        \n        for step, batch in enumerate(train_loader, 1):\n            images = batch['X'].to(self.device)\n            targets = batch['y'].to(self.device)\n            \n            self.optimizer.zero_grad()\n            outputs = self.model(images)\n            \n            loss = self.criterion(outputs, targets)\n            loss.backward()\n            \n            train_loss.update(loss.detach().item())\n            train_score.update(targets, outputs.detach())\n            \n            self.optimizer.step()\n            \n            self.info_message(\n                self.messages['batch'], 'Train', step, len(train_loader),\n                train_loss.avg, train_score.avg, int(time.time() - t), end='\\r'\n            )\n            \n        self.scheduler.step()\n        \n        return train_loss.avg, train_score.avg, int(time.time() - t)\n    \n    def valid_epoch(self, valid_loader):\n        self.model.eval()\n        t = time.time()\n        valid_loss = self.loss_metric()\n        valid_score = self.score_metric()\n        \n        for step, batch in enumerate(valid_loader, 1):\n            with torch.no_grad():\n                images = batch['X'].to(self.device)\n                targets = batch['y'].to(self.device)\n                \n                outputs = self.model(images)\n                loss = self.criterion(outputs, targets)\n                \n                valid_loss.update(loss.detach().item())\n                valid_score.update(targets, outputs)\n                \n            self.info_message(\n                self.messages['batch'], 'Valid', step, len(valid_loader),\n                valid_loss.avg, valid_score.avg, int(time.time() - t), end='\\r'\n            )\n            \n        return valid_loss.avg, valid_score.avg, int(time.time() - t)\n    \n    def save_model(self, num_epoch, save_path):\n        torch.save(\n            {\n                'model_state_dict': self.model.state_dict(),\n                'optimizer_state_dict': self.optimizer.state_dict(),\n                'best_valid_score': self.best_valid_score,\n                'num_epoch': num_epoch\n            },\n            save_path\n        )\n        \n    @staticmethod\n    def info_message(message, *args, end='\\n'):\n        print(message.format(*args), end=end)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:57:00.360443Z","iopub.execute_input":"2022-01-12T06:57:00.360990Z","iopub.status.idle":"2022-01-12T06:57:00.387585Z","shell.execute_reply.started":"2022-01-12T06:57:00.360948Z","shell.execute_reply":"2022-01-12T06:57:00.386808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class LossMeter:\n    def __init__(self):\n        self.avg = 0\n        self.n = 0\n\n    def update(self, val):\n        self.n += 1\n        self.avg = val / self.n + (self.n - 1) / self.n * self.avg\n\n        \nclass AccMeter:\n    def __init__(self):\n        self.avg = 0\n        self.n = 0\n        \n    def update(self, y_true, y_pred):\n        y_true = y_true.cpu().numpy().astype(int)\n        y_pred = y_pred.cpu().numpy().argmax(axis=1).astype(int)\n        last_n = self.n\n        self.n += len(y_true)\n        true_count = np.sum(y_true == y_pred)\n        self.avg = true_count / self.n + last_n / self.n * self.avg","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:57:02.306343Z","iopub.execute_input":"2022-01-12T06:57:02.307116Z","iopub.status.idle":"2022-01-12T06:57:02.315407Z","shell.execute_reply.started":"2022-01-12T06:57:02.307063Z","shell.execute_reply":"2022-01-12T06:57:02.314624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_fold = train_df[train_df[\"fold\"] != Config.cfg['validation_fold']]\nvalid_fold = train_df[train_df[\"fold\"] == Config.cfg['validation_fold']]","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:57:05.424026Z","iopub.execute_input":"2022-01-12T06:57:05.424282Z","iopub.status.idle":"2022-01-12T06:57:05.437308Z","shell.execute_reply.started":"2022-01-12T06:57:05.424253Z","shell.execute_reply":"2022-01-12T06:57:05.436528Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_set = CassavaDataset(df=train_fold, image_size=Config.cfg['image_size'], augments=Augments.train_augments)\nvalid_set = CassavaDataset(df=valid_fold, image_size=Config.cfg['image_size'], augments=Augments.val_augments)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:57:06.537680Z","iopub.execute_input":"2022-01-12T06:57:06.538263Z","iopub.status.idle":"2022-01-12T06:57:06.544263Z","shell.execute_reply.started":"2022-01-12T06:57:06.538224Z","shell.execute_reply":"2022-01-12T06:57:06.543450Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataloader = DataLoader(\n    train_set,\n    batch_size=Config.cfg['batch_size'],\n    shuffle=True,\n    num_workers=Config.cfg['num_workers'],\n)\n\nvalid_dataloader = DataLoader(\n    valid_set,\n    batch_size=Config.cfg['batch_size'],\n    shuffle=False,\n    num_workers=Config.cfg['num_workers']\n)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:57:09.059081Z","iopub.execute_input":"2022-01-12T06:57:09.059872Z","iopub.status.idle":"2022-01-12T06:57:09.069348Z","shell.execute_reply.started":"2022-01-12T06:57:09.059820Z","shell.execute_reply":"2022-01-12T06:57:09.068595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = efficientnet_b0(Config.cfg['num_classes'])\nmodel.to(device)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:57:11.307532Z","iopub.execute_input":"2022-01-12T06:57:11.308233Z","iopub.status.idle":"2022-01-12T06:57:14.799153Z","shell.execute_reply.started":"2022-01-12T06:57:11.308194Z","shell.execute_reply":"2022-01-12T06:57:14.798396Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimizer = torch.optim.Adam(model.parameters(), lr=Config.cfg['learning_rate'], weight_decay=Config.cfg['weight_decay'],)\ncriterion = nn.CrossEntropyLoss()\nscheduler = torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(\n    optimizer,\n    T_0=Config.cfg['warm_restarts_T_0'],\n    eta_min=Config.cfg['warm_restarts_eta_min']\n)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:57:14.800921Z","iopub.execute_input":"2022-01-12T06:57:14.801425Z","iopub.status.idle":"2022-01-12T06:57:14.808962Z","shell.execute_reply.started":"2022-01-12T06:57:14.801386Z","shell.execute_reply":"2022-01-12T06:57:14.808058Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainer = Trainer(\n    model=model,\n    optimizer=optimizer,\n    criterion=criterion,\n    scheduler=scheduler,\n    loss_metric=LossMeter,\n    score_metric=AccMeter\n)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:57:21.403861Z","iopub.execute_input":"2022-01-12T06:57:21.404120Z","iopub.status.idle":"2022-01-12T06:57:21.410286Z","shell.execute_reply.started":"2022-01-12T06:57:21.404092Z","shell.execute_reply":"2022-01-12T06:57:21.407865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = trainer.fit(\n    epochs=Config.cfg['epochs'],\n    train_loader=train_dataloader,\n    valid_loader=valid_dataloader,\n    save_path=f'{Config.cfg[\"validation_fold\"]}_fold_model_effnetb0_best.torch.',\n    patience=Config.cfg['patience']\n)","metadata":{"execution":{"iopub.status.busy":"2022-01-12T06:57:39.056228Z","iopub.execute_input":"2022-01-12T06:57:39.056495Z","iopub.status.idle":"2022-01-12T08:19:09.361782Z","shell.execute_reply.started":"2022-01-12T06:57:39.056465Z","shell.execute_reply":"2022-01-12T08:19:09.360905Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(16, 6))\nplt.subplot(1, 2, 1)\nplt.plot(history['train_loss'], label='train loss')\nplt.plot(history['valid_loss'], label='valid loss')\nplt.xticks(fontsize=14)\nplt.xlabel(\"Epoch number\", fontsize=15)\nplt.yticks(fontsize=14)\nplt.ylabel(\"Loss value\", fontsize=15)\nplt.legend(fontsize=15)\nplt.grid()\n\nplt.subplot(1, 2, 2)\nplt.plot(history['train_score'], label='train acc')\nplt.plot(history['valid_score'], label='valid acc')\nplt.xticks(fontsize=14)\nplt.xlabel(\"Epoch number\", fontsize=15)\nplt.yticks(fontsize=14)\nplt.ylabel(\"Accuracy score\", fontsize=15)\nplt.legend(fontsize=15)\nplt.grid();","metadata":{"execution":{"iopub.status.busy":"2022-01-12T08:19:24.838787Z","iopub.execute_input":"2022-01-12T08:19:24.839173Z","iopub.status.idle":"2022-01-12T08:19:25.249590Z","shell.execute_reply.started":"2022-01-12T08:19:24.839117Z","shell.execute_reply":"2022-01-12T08:19:25.248915Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if Config.neptune_settings[\"active\"]:\n    neptune_run.stop()","metadata":{"execution":{"iopub.status.busy":"2022-01-12T08:22:24.144993Z","iopub.execute_input":"2022-01-12T08:22:24.145532Z","iopub.status.idle":"2022-01-12T08:22:24.552521Z","shell.execute_reply.started":"2022-01-12T08:22:24.145492Z","shell.execute_reply":"2022-01-12T08:22:24.551828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}