doanh25032004's picture
Upload folder using huggingface_hub
872b0a0 verified
Raw
History Blame Contribute Delete
7.56 kB
# -*- coding: utf-8 -*-
import os
from utils.tools import tools
import cv2
import numpy as np
from copy import deepcopy
import torch
import warnings # ignore warnings
import torch.nn.functional as F
import torch.optim as optim
from dataset.kitti_dataset import kitti_train, kitti_flow
from model.upflow import UPFlow_net
from torch.utils.data import DataLoader
import time
''' scripts for training:
1. simply using photo loss and smooth loss
2. add occlusion checking
3. add teacher-student loss(ARFlow)
'''
# save and log loss value during training
class Loss_manager():
def __init__(self):
self.error_meter = tools.Avg_meter_ls()
def fetch_loss(self, loss, loss_dict, name, batch_N, short_name=None):
if name not in loss_dict.keys():
pass
elif loss_dict[name] is None:
pass
else:
this_loss = loss_dict[name].mean()
self.error_meter.update(name=name, val=this_loss.item(), num=batch_N, short_name=short_name)
loss = loss + this_loss
return loss
def prepare_epoch(self):
self.error_meter.reset()
def log_info(self):
p_str = self.error_meter.print_all_losses()
return p_str
def compute_loss(self, loss_dict, batch_N):
loss = 0
loss = self.fetch_loss(loss=loss, loss_dict=loss_dict, name='photo_loss', short_name='ph', batch_N=batch_N)
loss = self.fetch_loss(loss=loss, loss_dict=loss_dict, name='smooth_loss', short_name='sm', batch_N=batch_N)
loss = self.fetch_loss(loss=loss, loss_dict=loss_dict, name='census_loss', short_name='cen', batch_N=batch_N)
# photo_loss, smooth_loss, census_loss = output_dict['photo_loss'].mean(), output_dict['smooth_loss'], output_dict['census_loss']
loss = self.fetch_loss(loss=loss, loss_dict=loss_dict, name='msd_loss', short_name='msd', batch_N=batch_N)
loss = self.fetch_loss(loss=loss, loss_dict=loss_dict, name='eq_loss', short_name='eq', batch_N=batch_N)
loss = self.fetch_loss(loss=loss, loss_dict=loss_dict, name='oi_loss', short_name='oi', batch_N=batch_N)
return loss
class Eval_model(tools.abs_test_model):
def __init__(self):
super(Eval_model, self).__init__()
self.net_work = None
def eval_forward(self, im1, im2, gt, *args):
if self.net_work is None:
raise ValueError('not network for evaluation')
# === network output
with torch.no_grad():
input_dict = {'im1': im1, 'im2': im2, 'if_loss': False}
output_dict = self.net_work(input_dict)
flow_fw, flow_bw = output_dict['flow_f_out'], output_dict['flow_b_out']
pred_flow = flow_fw
return pred_flow
def eval_save_result(self, save_name, predflow, *args, **kwargs):
# you can save flow results here
# print(save_name)
pass
def change_model(self, net):
net.eval()
self.net_work = net
class Trainer():
class Config(tools.abstract_config):
def __init__(self, **kwargs):
self.exp_dir = './demo_exp'
self.if_cuda = True
self.batchsize = 2
self.NUM_WORKERS = 4
self.n_epoch = 1000
self.batch_per_epoch = 500
self.batch_per_print = 20
self.lr = 1e-4
self.weight_decay = 1e-4
self.scheduler_gamma = 1
# init
self.update(kwargs)
def __call__(self, ):
t = Trainer(self)
return t
def __init__(self, conf: Config):
self.conf = conf
tools.check_dir(self.conf.exp_dir)
# load network
self.net = self.load_model()
# for evaluation
self.bench = self.load_eval_bench()
self.eval_model = Eval_model()
# load training dataset
self.train_set = self.load_training_dataset()
def training(self):
train_loader = tools.data_prefetcher(self.train_set, batch_size=self.conf.batchsize, shuffle=True, num_workers=self.conf.NUM_WORKERS, pin_memory=True, drop_last=True)
optimizer = optim.Adam(self.net.parameters(), lr=self.conf.lr, amsgrad=True, weight_decay=self.conf.weight_decay)
scheduler = optim.lr_scheduler.ExponentialLR(optimizer, gamma=self.conf.scheduler_gamma)
loss_manager = Loss_manager()
timer = tools.time_clock()
print("start training" + '=' * 10)
i_batch = 0
epoch = 0
loss_manager.prepare_epoch()
current_val, best_val, best_epoch = 0, 0, 0
timer.start()
while True:
# prepare batch data
batch_value = train_loader.next()
if batch_value is None:
batch_value = train_loader.next()
assert batch_value is not None
batchsize = batch_value['im1'].shape[0] # check if the im1 exists
i_batch += 1
# train batch
self.net.train()
optimizer.zero_grad()
out_data = self.net(batch_value) #
loss_dict = out_data['loss_dict']
loss = loss_manager.compute_loss(loss_dict=loss_dict, batch_N=batchsize)
loss.backward()
optimizer.step()
if i_batch % self.conf.batch_per_print == 0:
pass
if i_batch % self.conf.batch_per_epoch == 0:
# do eval and check if save model todo===
epoch+=1
timer.end()
print(' === epoch use time %.2f' % timer.get_during())
scheduler.step(epoch=epoch)
timer.start()
def evaluation(self):
self.eval_model.change_model(self.net)
epe_all, f1, epe_noc, epe_occ = self.bench(self.eval_model)
print('EPE All = %.2f, F1 = %.2f, EPE Noc = %.2f, EPE Occ = %.2f' % (epe_all, f1, epe_noc, epe_occ))
print_str = 'EPE_%.2f__F1_%.2f__Noc_%.2f__Occ_%.2f' % (epe_all, f1, epe_noc, epe_occ)
return epe_all, print_str
# ======
def load_model(self):
param_dict = {
# use cost volume norm
'if_norm_before_cost_volume': True,
'norm_moments_across_channels': False,
'norm_moments_across_images': False,
'if_froze_pwc': False,
'if_use_cor_pytorch': False, # speed is very slow, just for debug when cuda correlation is not compiled
'if_sgu_upsample': False, # 先把这个关掉跑通吧
}
pretrain_path = None # pretrain path
net_conf = UPFlow_net.config()
net_conf.update(param_dict)
net = net_conf() # .cuda()
if pretrain_path is not None:
net.load_model(pretrain_path, if_relax=True, if_print=False)
if self.conf.if_cuda:
net = net.cuda()
return net
def load_eval_bench(self):
bench = kitti_flow.Evaluation_bench(name='2015_train', if_gpu=self.conf.if_cuda, batch_size=1)
return bench
def load_training_dataset(self):
data_config = {
'crop_size': (256, 832),
'rho': 8,
'swap_images': True,
'normalize': True,
'horizontal_flip_aug': True,
}
data_conf = kitti_train.kitti_data_with_start_point.config(mv_type='2015', **data_config)
dataset = data_conf()
return dataset
if __name__ == '__main__':
training_param = {} # change param here
conf = Trainer.Config(**training_param)
trainer = conf()
trainer.training()