Spaces:
Sleeping
Sleeping
| # -*- coding: utf-8 -*- | |
| """Training_with_lr_A4000.ipynb | |
| Automatically generated by Colaboratory. | |
| Original file is located at | |
| https://colab.research.google.com/drive/1gtGnp5dp_W4rB-Kz7uMsbPGYUuNPmVtu | |
| """ | |
| import torch | |
| import torch.optim as optim | |
| from src.model_yolov3 import YOLOv3 | |
| from tqdm import tqdm | |
| import src.config as config | |
| from src.utils_rh import ( | |
| mean_average_precision, | |
| cells_to_bboxes, | |
| get_evaluation_bboxes, | |
| save_checkpoint, | |
| load_checkpoint, | |
| check_class_accuracy, | |
| get_loaders, | |
| plot_couple_examples | |
| ) | |
| from src.loss import YoloLoss | |
| import warnings | |
| warnings.filterwarnings("ignore") | |
| import torch | |
| from pytorch_lightning import LightningModule, Trainer | |
| from torch import nn | |
| from torch.nn import functional as F | |
| from torch.utils.data import DataLoader, random_split | |
| import torchvision | |
| from pytorch_lightning.callbacks import LearningRateMonitor | |
| from pytorch_lightning.callbacks.progress import TQDMProgressBar | |
| from pytorch_lightning.loggers import CSVLogger | |
| from pytorch_lightning.callbacks import ModelCheckpoint | |
| import pandas as pd | |
| from torch.optim.lr_scheduler import OneCycleLR | |
| import seaborn as sn | |
| class Assignment13(LightningModule): | |
| def __init__(self): | |
| super().__init__() | |
| self.save_hyperparameters() | |
| self.epoch_number = 0 | |
| self.config = config | |
| self.train_csv_path = self.config.DATASET + "/train.csv" | |
| self.test_csv_path = self.config.DATASET + "/test.csv" | |
| self.train_loader, self.test_loader, self.train_eval_loader = get_loaders( | |
| train_csv_path=self.train_csv_path, test_csv_path=self.test_csv_path) | |
| self.check_class_accuracy = check_class_accuracy | |
| self.model = YOLOv3(num_classes=self.config.NUM_CLASSES) | |
| self.loss_fn = YoloLoss() | |
| self.check_class_accuracy = check_class_accuracy | |
| self.get_evaluation_bboxes = get_evaluation_bboxes | |
| self.scaled_anchors = (torch.tensor(self.config.ANCHORS) * torch.tensor(self.config.S).unsqueeze(1).unsqueeze(1).repeat(1, 3, 2)) | |
| self.losses = [] | |
| self.plot_couple_examples = plot_couple_examples | |
| self.mean_average_precision = mean_average_precision | |
| self.EPOCHS = self.config.NUM_EPOCHS * 2 // 5 | |
| def forward(self, x): | |
| out = self.model(x) | |
| return out | |
| def training_step(self, batch, batch_idx): | |
| x, y = batch | |
| out = self(x) | |
| y0, y1, y2 = (y[0],y[1],y[2]) | |
| loss = ( | |
| self.loss_fn(out[0], y0, self.scaled_anchors[0].to(y0)) | |
| + self.loss_fn(out[1], y1, self.scaled_anchors[1].to(y1)) | |
| + self.loss_fn(out[2], y2, self.scaled_anchors[2].to(y2)) | |
| ) | |
| self.losses.append(loss.item()) | |
| mean_loss = sum(self.losses) / len(self.losses) | |
| self.log("train_loss", mean_loss, on_step=True, on_epoch=True, prog_bar=True, logger=True) | |
| #self.log("train_loss", mean_loss) | |
| return loss | |
| def on_train_epoch_start(self): | |
| self.epoch_number += 1 | |
| self.losses = [] | |
| #self.plot_couple_examples(self.model,self.test_loader,0.6,0.5,self.scaled_anchors) | |
| if self.epoch_number > 1 and self.epoch_number % 10 == 0: | |
| self.plot_couple_examples(self.model,self.test_loader,0.6,0.5,self.scaled_anchors) | |
| def on_train_epoch_end(self): | |
| print(f"Currently epoch {self.epoch_number}") | |
| print("On Train Eval loader:") | |
| print("On Train loader:") | |
| self.check_class_accuracy(self.model, self.train_loader, threshold=self.config.CONF_THRESHOLD) | |
| if self.epoch_number == self.EPOCHS: | |
| #if self.epoch_number > 1 and self.epoch_number % 3 == 0: | |
| self.check_class_accuracy(self.model, self.test_loader, threshold=self.config.CONF_THRESHOLD) | |
| pred_boxes, true_boxes = self.get_evaluation_bboxes( self.test_loader,self.model,iou_threshold=self.config.NMS_IOU_THRESH, | |
| anchors=self.config.ANCHORS, | |
| threshold=self.config.CONF_THRESHOLD,) | |
| mapval = self.mean_average_precision( | |
| pred_boxes, | |
| true_boxes, | |
| iou_threshold=self.config.MAP_IOU_THRESH, | |
| box_format="midpoint", | |
| num_classes=self.config.NUM_CLASSES, | |
| ) | |
| print(f"MAP: {mapval.item()}") | |
| self.model.train() | |
| pass | |
| def configure_optimizers(self): | |
| optimizer = optimizer = optim.Adam( | |
| model.parameters(), lr=config.LEARNING_RATE, weight_decay=config.WEIGHT_DECAY) | |
| #EPOCHS = config.NUM_EPOCHS * 2 // 5 | |
| scheduler = OneCycleLR( | |
| optimizer, | |
| max_lr=1E-3, | |
| steps_per_epoch=len(self.train_loader), | |
| epochs=self.EPOCHS, | |
| pct_start=5/self.EPOCHS, | |
| div_factor=100, | |
| three_phase=False, | |
| final_div_factor=100, | |
| anneal_strategy='linear' | |
| ) | |
| return {"optimizer": optimizer, "lr_scheduler":scheduler} | |
| #################### | |
| # DATA RELATED HOOKS | |
| #################### | |
| def train_dataloader(self): | |
| return self.train_loader | |
| def test_dataloader(self): | |
| return self.test_loader | |
| #finding maximum learning rate | |
| model = Assignment13() | |
| #trainer = Trainer(precision=16,accelerator='cpu',callbacks=[TQDMProgressBar(refresh_rate=0)]) | |
| # Run learning rate finder | |
| #lr_finder = trainer.tuner.lr_find(model,max_lr=2, num_training=200,mode="exponential") | |
| # Inspect results | |
| #fig = lr_finder.plot(); fig.show() | |
| #suggested_lr = lr_finder.suggestion() | |
| #print(suggested_lr) | |
| # Overwrite lr and create new model | |
| #hparams.lr = suggested_lr | |
| #model = MyModelClass(hparams) | |
| class Assignment13(LightningModule): | |
| def __init__(self): | |
| super().__init__() | |
| self.save_hyperparameters() | |
| self.epoch_number = 0 | |
| self.config = config | |
| self.train_csv_path = self.config.DATASET + "/train.csv" | |
| self.test_csv_path = self.config.DATASET + "/test.csv" | |
| self.train_loader, self.test_loader, self.train_eval_loader = get_loaders( | |
| train_csv_path=self.train_csv_path, test_csv_path=self.test_csv_path) | |
| self.check_class_accuracy = check_class_accuracy | |
| self.model = YOLOv3(num_classes=self.config.NUM_CLASSES) | |
| self.loss_fn = YoloLoss() | |
| self.check_class_accuracy = check_class_accuracy | |
| self.get_evaluation_bboxes = get_evaluation_bboxes | |
| self.scaled_anchors = (torch.tensor(self.config.ANCHORS) * torch.tensor(self.config.S).unsqueeze(1).unsqueeze(1).repeat(1, 3, 2)) | |
| self.losses = [] | |
| self.plot_couple_examples = plot_couple_examples | |
| self.mean_average_precision = mean_average_precision | |
| self.EPOCHS = self.config.NUM_EPOCHS * 2 // 5 | |
| def forward(self, x): | |
| out = self.model(x) | |
| return out | |
| def training_step(self, batch, batch_idx): | |
| x, y = batch | |
| out = self(x) | |
| y0, y1, y2 = (y[0],y[1],y[2]) | |
| loss = ( | |
| self.loss_fn(out[0], y0, self.scaled_anchors[0].to(y0)) | |
| + self.loss_fn(out[1], y1, self.scaled_anchors[1].to(y1)) | |
| + self.loss_fn(out[2], y2, self.scaled_anchors[2].to(y2)) | |
| ) | |
| self.losses.append(loss.item()) | |
| mean_loss = sum(self.losses) / len(self.losses) | |
| self.log("train_loss", mean_loss, on_step=True, on_epoch=True, prog_bar=True, logger=True) | |
| #self.log("train_loss", mean_loss) | |
| return loss | |
| def on_train_epoch_start(self): | |
| self.epoch_number += 1 | |
| self.losses = [] | |
| #self.plot_couple_examples(self.model,self.test_loader,0.6,0.5,self.scaled_anchors) | |
| if self.epoch_number > 1 and self.epoch_number % 10 == 0: | |
| self.plot_couple_examples(self.model,self.test_loader,0.6,0.5,self.scaled_anchors) | |
| def on_train_epoch_end(self): | |
| print(f"Currently epoch {self.epoch_number}") | |
| print("On Train Eval loader:") | |
| print("On Train loader:") | |
| self.check_class_accuracy(self.model, self.train_loader, threshold=self.config.CONF_THRESHOLD) | |
| if self.epoch_number == self.EPOCHS: | |
| #if self.epoch_number > 1 and self.epoch_number % 3 == 0: | |
| self.check_class_accuracy(self.model, self.test_loader, threshold=self.config.CONF_THRESHOLD) | |
| pred_boxes, true_boxes = self.get_evaluation_bboxes( self.test_loader,self.model,iou_threshold=self.config.NMS_IOU_THRESH, | |
| anchors=self.config.ANCHORS, | |
| threshold=self.config.CONF_THRESHOLD,) | |
| mapval = self.mean_average_precision( | |
| pred_boxes, | |
| true_boxes, | |
| iou_threshold=self.config.MAP_IOU_THRESH, | |
| box_format="midpoint", | |
| num_classes=self.config.NUM_CLASSES, | |
| ) | |
| print(f"MAP: {mapval.item()}") | |
| self.model.train() | |
| pass | |
| def configure_optimizers(self): | |
| optimizer = optimizer = optim.Adam( | |
| model.parameters(), lr=config.LEARNING_RATE, weight_decay=config.WEIGHT_DECAY) | |
| #EPOCHS = config.NUM_EPOCHS * 2 // 5 | |
| scheduler = OneCycleLR( | |
| optimizer, | |
| max_lr=8E-4, | |
| steps_per_epoch=len(self.train_loader), | |
| epochs=self.EPOCHS, | |
| pct_start=5/self.EPOCHS, | |
| div_factor=100, | |
| three_phase=False, | |
| final_div_factor=100, | |
| anneal_strategy='linear' | |
| ) | |
| return {"optimizer": optimizer, "lr_scheduler":scheduler} | |
| #################### | |
| # DATA RELATED HOOKS | |
| #################### | |
| def train_dataloader(self): | |
| return self.train_loader | |
| def test_dataloader(self): | |
| return self.test_loader | |
| model = Assignment13() | |
| checkpoint_callback = ModelCheckpoint( | |
| monitor='train_loss', # Metric to monitor for saving the best model | |
| mode='min', # 'min' to save the model with the lowest value of the monitored metric | |
| dirpath='/storage/', | |
| filename='assignment13_final{epoch:02d}-train_loss_min_A400{train_loss:.2f}', | |
| save_top_k=1 # Save only the best model | |
| ) | |
| #trainer = Trainer( | |
| #max_epochs=config.NUM_EPOCHS * 2 // 5, | |
| #accelerator="cpu", | |
| #precision=16, # limiting got iPython runs | |
| #logger=CSVLogger(save_dir="logs/"), | |
| #callbacks=[LearningRateMonitor(logging_interval="step"),TQDMProgressBar(refresh_rate=0),checkpoint_callback], | |
| #) | |
| #trainer.fit(model) | |
| #metrics = pd.read_csv(f"{trainer.logger.log_dir}/metrics.csv") | |
| #del metrics["step"] | |
| #metrics.set_index("epoch", inplace=True) | |
| #display(metrics.dropna(axis=1, how="all").head()) | |
| #sn.relplot(data=metrics, kind="line") | |