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") | |