def __init__(self, args: argparse.Namespace = None): super().__init__() self.num_classes = args.num_classes self.latent_dim = args.latent_dim self.feature_dim = args.feature_dim self.batch_size = args.batch_size self.lr = args.lr self.class_noise_convertor = nn.ModuleDict({ str(k): nn.Sequential(nn.Linear(self.feature_dim, self.latent_dim), nn.ReLU(), nn.Linear(self.latent_dim, self.latent_dim)).to(self.device) for k in range(self.num_classes) }) self.generator = Generator(ngpu=1) self.generator.load_state_dict(torch.load(args.gen_weights)) self.class_identifier = SiameseNet() self.class_identifier.load_state_dict(torch.load(args.siamese_weights)) if args.generator_pre_train: self.generator.to(self.device).freeze() if args.siamese_pre_train: self.class_identifier.to(self.device).freeze() # self.class_similarity = nn.Linear(4096, 1) self.creterion = ContrastiveLoss(1) self.threshold = args.threshold self.train_acc = Accuracy() self.val_acc = Accuracy() self.test_acc = Accuracy()
def __init__(self, model_path, *args, **kwargs): """ - Load model from model_path - Load state to the model """ self.model = SiameseNet().cuda() self.ckpt = torch.load(model_path) self.model.load_state_dict(self.ckpt['model_state'])
def train_step(): model = SiameseNet.SiameseNet() train_data = DataSet(mode='train', batch_size=4) img1, img2, labels = next(train_data) loss, pred_label, acc = model(img1, img2, labels) print(labels) print('loss: ', loss) print('predict_label:', pred_label) print('acc: ', acc)
def haha(): a = tf.random.normal([1,164,164,3]) b = tf.random.normal([1,164,164,3]) label = tf.constant([1, 0]) net = SiameseNet.SiameseNet() loss = net(a, b, label) seq = net.encoder seq(a) print(seq.summary()) pprint(net.layers) print('\033[1;32mLoss is\033[0m') print(loss)
def putCharacters(image, db="database"): dbs = os.listdir(db) right = np.array( [np.expand_dims(cv2.imread(os.path.join(db, x), 0), -1) for x in dbs]) names = [os.path.splitext(x)[0] for x in dbs] for face, x, y, w, h in giveAllFaces(image): face = cv2.resize(face, (100, 100), interpolation=cv2.INTER_AREA) face = np.expand_dims(face, -1) left = np.array([face for _ in range(len(dbs))]) probs = np.squeeze(SiameseNet.predict([left, right])) index = np.argmax(probs) prob = probs[index] name = "Unknown" if prob > 0.5: name = names[index] putBoxText(image, x, y, w, h, text=name + "({:.2f})".format(prob))
def test(self): # Load best model model = SiameseNet() _, _, _, model_state, _ = self.load_checkpoint(best=self.config.best) model.load_state_dict(model_state) if self.config.use_gpu: model.cuda() test_loader = get_test_loader(self.config.data_dir, self.config.way, self.config.test_trials, self.config.seed, self.config.num_workers, self.config.pin_memory) correct_sum = 0 num_test = test_loader.dataset.trials print(f"[*] Test on {num_test} pairs.") pbar = tqdm(enumerate(test_loader), total=num_test, desc="Test") with torch.no_grad(): for i, (x1, x2, _) in pbar: if self.config.use_gpu: x1, x2 = x1.to(self.device), x2.to(self.device) # compute log probabilities out = model(x1, x2) y_pred = torch.sigmoid(out) y_pred = torch.argmax(y_pred) if y_pred == 0: correct_sum += 1 pbar.set_postfix_str(f"accuracy: {correct_sum / num_test}") test_acc = (100. * correct_sum) / num_test print(f"Test Acc: {correct_sum}/{num_test} ({test_acc:.2f}%)")
camera_id.append(int(camera[0])) return camera_id, labels gallery_path = image_datasets['gallery'].imgs query_path = image_datasets['query'].imgs gallery_cam, gallery_label = get_id(gallery_path) query_cam, query_label = get_id(query_path) ###################################################################### # Load Collected data Trained model print('-------test-----------') embedding_net = ft_net_dense(751) model_siamese = SiameseNet(embedding_net) model_siamese = load_network_easy(model_siamese, name) model_siamese = model_siamese.eval() if use_gpu: model = model_siamese.cuda() # Extract feature with torch.no_grad(): gallery_feature = extract_feature(model, dataloaders['gallery']) query_feature = extract_feature(model, dataloaders['query']) result = {'gallery_f': gallery_feature.numpy(), 'gallery_label': gallery_label, 'gallery_cam': gallery_cam, 'query_f': query_feature.numpy(), 'query_label': query_label, 'query_cam': query_cam} scipy.io.savemat('pytorch_result.mat', result)
output = (np.squeeze(probs) > 0.5) * 1 percent_correct = (output == targets).sum() * 100 / N if verbose: print("Got an average of {}% {} way one-shot learning accuracy".format( percent_correct, N)) return percent_correct if __name__ == "__main__": evaluate_every = 7000 loss_every = 500 batch_size = 32 N = 1000 best = 0 loss_history = [] for i in range(0, 200000): (inputs, targets) = getMiniBatch(batch_size, path="train") loss = SiameseNet.train_on_batch(inputs, targets) loss_history.append(loss) if i % loss_every == 0: vloss = SiameseNet.test_on_batch( *getMiniBatch(batch_size, path="eval")) print( "iteration {}, training loss: {:.7f}, validation loss : {:.7f}" .format(i, np.mean(loss_history), vloss)) loss_history.clear() val_acc = test_oneshot(SiameseNet, N, verbose=True) if val_acc >= best: print("saving") SiameseNet.save('saved_best') best = val_acc
gflags.DEFINE_float ("lr", 0.001, "learning rate") gflags.DEFINE_integer("valid_every", 1, "valid model after each test_every iter.") gflags.DEFINE_integer("max_iter", 40, "number of iteration - n epoch are max_iter/batch_size") gflags.DEFINE_string("gpu_ids", "0", "gpu ids used to train") Flags(sys.argv) trainSet = Dataset(Flags.train_path,Flags.test_path,Flags.valid_path,Flags.max_iter,"train") trainLoader = DataLoader(trainSet, batch_size=Flags.batch_size, shuffle=False, num_workers=Flags.workers) validSet = Dataset(Flags.valid_path,Flags.test_path,Flags.valid_path,Flags.max_iter,"valid") validLoader = DataLoader(validSet, batch_size=Flags.batch_size, shuffle=False, num_workers=Flags.workers) loss_BCE = torch.nn.BCEWithLogitsLoss(size_average=True) net = SiameseNet() save_path = os.path.join(Flags.save_folder,"save_data") makeFolder(save_path) makeFolder(os.path.join(save_path,"models")) # multi gpu if Flags.cuda: os.environ["CUDA_VISIBLE_DEVICES"] = Flags.gpu_ids if len(Flags.gpu_ids.split(",")) > 1: net = torch.nn.DataParallel(net) net.cuda() optimizer = torch.optim.Adam(net.parameters(),lr = Flags.lr ) optimizer.zero_grad() loss_val = 0 valid_list = []
class QueryModel(): """ Get the confidence score for two PIL images Args :param model_path str: path to the model to be loaded Properties :param self.model nn.Module: Model Type to be used for inference. :param self.ckpt: Loaded model information """ def __init__(self, model_path, *args, **kwargs): """ - Load model from model_path - Load state to the model """ self.model = SiameseNet().cuda() self.ckpt = torch.load(model_path) self.model.load_state_dict(self.ckpt['model_state']) @staticmethod def resizeImage(image): """ resize image to model parameters. Args :param image PIL.Image: PIL Image Return :param image PIL.Image: resized image """ return image.resize((120, 80), Image.ANTIALIAS) # return image.resize((96, 64), Image.ANTIALIAS) def ImageToTensor(self, image): """ resize and transform PIL image to tensor Args :param image PIL.Image: PIL Image Return :param tensor torch.Tesnor: PyTorch Tensor """ image = self.resizeImage(image) transform = transforms.Compose([transforms.ToTensor()]) return torch.reshape(transform(image), [1, 1, 80, 120]) def getConfidence(self, tensor0, tensor1): """ get confidence on the two tensors from the model and apply sigmoid. Args :param tensor0 torch.Tensor: transformed image tensor to be used for inference :param tensor1 torch.Tensor: transformed image tensor to be used for inference Return :param output torch.Tensor: confidence tensor """ x0, x1 = Variable(tensor0).cuda(), Variable(tensor1).cuda() output = self.model(x0, x1) output = F.sigmoid(output) return output def predict(self, img0, img1): """ Infer confidence on the two images from the model and return it. Args :param img0 PIL.Image: first image to be compared :param img1 PIL.Image: second image to be compared Return :param output torch.Tensor: confidence tensor confidence > 0.5, Similar Pairs confidence < 0.5, Dissimilar Pairs """ img0_tensor = self.ImageToTensor(img0) img1_tensor = self.ImageToTensor(img1) output = self.getConfidence(img0_tensor, img1_tensor) return output
def print_parameters(): count_parameters(SiameseNet())
def loadModel(path): model = SiameseNet() model.load_state_dict(torch.load(path, map_location=torch.device('cuda'))) model.cuda() model.eval() return model
def __init__(self, config, data_loader, layer_hyperparams): """ Construct a new Trainer instance. Args ---- - config: object containing command line arguments. - data_loader: data iterator. - layer_hyperparams: dict containing layer-wise hyperparameters such as the initial learning rate, the end momentum, and the l2 regularization strength. """ self.config = config self.layer_hyperparams = layer_hyperparams if config.is_train: self.train_loader = data_loader[0] self.valid_loader = data_loader[1] self.num_train = len(self.train_loader.dataset) self.num_valid = self.valid_loader.dataset.trials else: self.test_loader = data_loader self.num_test = self.test_loader.dataset.trials self.model = SiameseNet() if config.use_gpu: self.model.cuda() # model params self.num_params = sum( [p.data.nelement() for p in self.model.parameters()]) self.num_model = get_num_model(config) self.num_layers = len(list(self.model.children())) print('[*] Number of model parameters: {:,}'.format(self.num_params)) # path params self.ckpt_dir = os.path.join(config.ckpt_dir, self.num_model) self.logs_dir = os.path.join(config.logs_dir, self.num_model) # misc params self.resume = config.resume self.use_gpu = config.use_gpu self.dtype = (torch.cuda.FloatTensor if self.use_gpu else torch.FloatTensor) # optimization params self.best = config.best self.best_valid_acc = 0. self.epochs = config.epochs self.start_epoch = 0 self.lr_patience = config.lr_patience self.train_patience = config.train_patience self.counter = 0 # grab layer-wise hyperparams self.init_lrs = self.layer_hyperparams['layer_init_lrs'] self.init_momentums = [config.init_momentum] * self.num_layers self.end_momentums = self.layer_hyperparams['layer_end_momentums'] self.l2_regs = self.layer_hyperparams['layer_l2_regs'] # compute temper rate for momentum if self.epochs == 1: f = lambda max, min: min else: f = lambda max, min: (max - min) / (self.epochs - 1) self.momentum_temper_rates = [ f(x, y) for x, y in zip(self.end_momentums, self.init_momentums) ] # set global learning rates and momentums self.lrs = self.init_lrs self.momentums = self.init_momentums # # initialize optimizer # optim_dict = [] # for i, layer in enumerate(self.model.children()): # group = {} # group['params'] = layer.parameters() # group['lr'] = self.lrs[i] # group['momentum'] = self.momentums[i] # group['weight_decay'] = self.l2_regs[i] # optim_dict.append(group) # self.optimizer = optim.SGD(optim_dict) # self.optimizer = optim.SGD( # self.model.parameters(), lr=1e-3, momentum=0.9, weight_decay=4e-4, # ) self.optimizer = optim.Adam( self.model.parameters(), lr=3e-4, weight_decay=6e-5, )
required=True) parser.add_argument("-m", "--model", dest="model", help="Saved Model", required=True) parser.add_argument("-i", "--image", nargs='+', dest="images", help="Image Paths", required=True) args = parser.parse_args() print("############ Please wait while model is loading. ###############") val_acc = None while val_acc == None: try: SiameseNet.load_weights(args.model) val_acc = test_oneshot(SiameseNet, 1000, verbose=0, path="../eval") print("Model loaded with Accuracy: {}".format(val_acc)) except: print("Exception Occured: Ignoring") for image in args.images: im = cv2.imread(image, 1) putCharacters( im, db=args.database, ) plt.imshow(im) plt.show()
+ list(map(id, model.classifier.parameters())) stage_1_base_id = list(map(id, model.embedding_net.parameters())) stage_1_base_params = filter(lambda p: id(p) in stage_1_base_id, model.parameters()) stage_1_classifier_params = filter(lambda p: id(p) in stage_1_id and id(p) not in stage_1_base_id, model.parameters()) return stage_1_base_params, stage_1_classifier_params stage_1 = False stage_2 = True if stage_1: margin = 1. embedding_net = ft_net_dense() model = SiameseNet(embedding_net) # model = Sggnn(SiameseNet(embedding_net)) if use_gpu: model.cuda() # save_whole_network(model, 'best') # exit() loss_fn = ContrastiveLoss(margin) # loss_fn = SigmoidLoss() # loss_fn = nn.CrossEntropyLoss() lr = 1e-3 step = 8 # stage_1_base_params, stage_1_classifier_params = stage_1_params(model) # optimizer = optim.Adam([ # {'params': stage_1_base_params, 'lr': 1 * lr},
import paddle from paddle.io import Dataset, DataLoader from data_reader import MyDataset from model import SiameseNet from paddle.vision.transforms import functional as F import paddle.nn as nn from PIL import Image net = SiameseNet() net.eval() paddle.set_device("gpu:0") layer_state_dict = paddle.load("basic_acc38.pdparams") net.set_state_dict(layer_state_dict) dist = nn.PairwiseDistance(keepdim=True) def load_img(path1, path2): img1 = Image.open(path1) img2 = Image.open(path2) img1 = img1.convert("L") img2 = img2.convert("L") img1 = img1.resize((100, 100)) img2 = img2.resize((100, 100)) return F.to_tensor(img1), F.to_tensor(img2) with open("train_list.txt", "r") as r: lines = r.readlines() index = 0 for line in lines:
from model import ResNet try: src_path = sys.argv[1] except: print("请输入需要匹配的图片路径!") exit(-1) model = "basic" if model == "resnet": size = 100 net = ResNet() elif model == "basic": size = 100 net = SiameseNet() net.eval() paddle.set_device("gpu:0") layer_state_dict = paddle.load(model + "_acc38.pdparams") net.set_state_dict(layer_state_dict) dist = nn.PairwiseDistance(keepdim=True) def load_img(path1, path2): img1 = Image.open(path1) img2 = Image.open(path2) img1 = img1.convert("L") img2 = img2.convert("L") img1 = img1.resize((size, size))
siamese_train_dataset = SiameseMarket(train_dataset, train=True) siamese_test_dataset = SiameseMarket(test_dataset, train=False) print(len(siamese_test_dataset)) print(len(siamese_train_dataset)) # a,b = siamese_test_dataset[0] # print(b) # print(type(a)) trainloader_l, trainloader_u, valloader, testloader = get_dataloaders( siamese_train_dataset, siamese_test_dataset, args.train_size, args.val_size, args.batch_size) device = torch.device("cuda:0") net = SiameseNet(10, False) net = net.to(device) criterion = nn.BCEWithLogitsLoss() optimizer = optim.Adam(net.parameters(), lr=args.lr) model_name = 'reid_pl' + str(args.train_size) alpha = 0.0 val_min_acc = 0.0 test_acc = 0.0 flag = False for epoch in range(args.epochs): if (epoch > args.T1 and epoch <= args.T2): alpha = (epoch - args.T1) / (args.T2 - args.T1)
class Trainer(object): """ Trainer encapsulates all the logic necessary for training the Siamese Network model. All hyperparameters are provided by the user in the config file. """ def __init__(self, config, data_loader, layer_hyperparams): """ Construct a new Trainer instance. Args ---- - config: object containing command line arguments. - data_loader: data iterator. - layer_hyperparams: dict containing layer-wise hyperparameters such as the initial learning rate, the end momentum, and the l2 regularization strength. """ self.config = config self.layer_hyperparams = layer_hyperparams if config.is_train: self.train_loader = data_loader[0] self.valid_loader = data_loader[1] self.num_train = len(self.train_loader.dataset) self.num_valid = self.valid_loader.dataset.trials else: self.test_loader = data_loader self.num_test = self.test_loader.dataset.trials self.model = SiameseNet() if config.use_gpu: self.model.cuda() # model params self.num_params = sum( [p.data.nelement() for p in self.model.parameters()]) self.num_model = get_num_model(config) self.num_layers = len(list(self.model.children())) print('[*] Number of model parameters: {:,}'.format(self.num_params)) # path params self.ckpt_dir = os.path.join(config.ckpt_dir, self.num_model) self.logs_dir = os.path.join(config.logs_dir, self.num_model) # misc params self.resume = config.resume self.use_gpu = config.use_gpu self.dtype = (torch.cuda.FloatTensor if self.use_gpu else torch.FloatTensor) # optimization params self.best = config.best self.best_valid_acc = 0. self.epochs = config.epochs self.start_epoch = 0 self.lr_patience = config.lr_patience self.train_patience = config.train_patience self.counter = 0 # grab layer-wise hyperparams self.init_lrs = self.layer_hyperparams['layer_init_lrs'] self.init_momentums = [config.init_momentum] * self.num_layers self.end_momentums = self.layer_hyperparams['layer_end_momentums'] self.l2_regs = self.layer_hyperparams['layer_l2_regs'] # compute temper rate for momentum if self.epochs == 1: f = lambda max, min: min else: f = lambda max, min: (max - min) / (self.epochs - 1) self.momentum_temper_rates = [ f(x, y) for x, y in zip(self.end_momentums, self.init_momentums) ] # set global learning rates and momentums self.lrs = self.init_lrs self.momentums = self.init_momentums # # initialize optimizer # optim_dict = [] # for i, layer in enumerate(self.model.children()): # group = {} # group['params'] = layer.parameters() # group['lr'] = self.lrs[i] # group['momentum'] = self.momentums[i] # group['weight_decay'] = self.l2_regs[i] # optim_dict.append(group) # self.optimizer = optim.SGD(optim_dict) # self.optimizer = optim.SGD( # self.model.parameters(), lr=1e-3, momentum=0.9, weight_decay=4e-4, # ) self.optimizer = optim.Adam( self.model.parameters(), lr=3e-4, weight_decay=6e-5, ) # # learning rate scheduler # self.scheduler = StepLR( # self.optimizer, step_size=self.lr_patience, gamma=0.99, # ) def train(self): if self.resume: self.load_checkpoint(best=False) # switch to train mode self.model.train() # create train and validation log files optim_file = open(os.path.join(self.logs_dir, 'optim.csv'), 'w') train_file = open(os.path.join(self.logs_dir, 'train.csv'), 'w') valid_file = open(os.path.join(self.logs_dir, 'valid.csv'), 'w') print("\n[*] Train on {} sample pairs, validate on {} trials".format( self.num_train, self.num_valid)) for epoch in range(self.start_epoch, self.epochs): # self.decay_lr() # self.temper_momentum(epoch) # # # log lrs and momentums # n = self.num_layers # msg = ( # "{}, " + ", ".join(["{}"] * n) + ", " + ", ".join(["{}"] * n) # ) # optim_file.write(msg.format( # epoch, *self.momentums, *self.lrs) # ) print('\nEpoch: {}/{}'.format(epoch + 1, self.epochs)) train_loss = self.train_one_epoch(epoch, train_file) valid_acc = self.validate(epoch, valid_file) # check for improvement is_best = valid_acc > self.best_valid_acc msg = "train loss: {:.3f} - val acc: {:.3f}" if is_best: msg += " [*]" self.counter = 0 print(msg.format(train_loss, valid_acc)) # checkpoint the model if not is_best: self.counter += 1 if self.counter > self.train_patience: print("[!] No improvement in a while, stopping training.") return self.best_valid_acc = max(valid_acc, self.best_valid_acc) self.save_checkpoint( { 'epoch': epoch + 1, 'model_state': self.model.state_dict(), 'optim_state': self.optimizer.state_dict(), 'best_valid_acc': self.best_valid_acc, }, is_best) # release resources optim_file.close() train_file.close() valid_file.close() def train_one_epoch(self, epoch, file): train_batch_time = AverageMeter() train_losses = AverageMeter() tic = time.time() with tqdm(total=self.num_train) as pbar: for i, (x1, x2, y) in enumerate(self.train_loader): if self.use_gpu: x1, x2, y = x1.cuda(), x2.cuda(), y.cuda() x1, x2, y = Variable(x1), Variable(x2), Variable(y) # split input pairs along the batch dimension batch_size = x1.shape[0] out = self.model(x1, x2) loss = F.binary_cross_entropy_with_logits(out, y) # compute gradients and update self.optimizer.zero_grad() loss.backward() self.optimizer.step() # store batch statistics toc = time.time() train_losses.update(loss.data[0], batch_size) train_batch_time.update(toc - tic) tic = time.time() pbar.set_description(("{:.1f}s - loss: {:.3f}".format( train_batch_time.val, train_losses.val, ))) pbar.update(batch_size) # log loss iter = (epoch * len(self.train_loader)) + i file.write('{},{}\n'.format(iter, train_losses.val)) return train_losses.avg def validate(self, epoch, file): # switch to evaluate mode self.model.eval() correct = 0 for i, (x1, x2) in enumerate(self.valid_loader): if self.use_gpu: x1, x2 = x1.cuda(), x2.cuda() x1, x2 = Variable(x1, volatile=True), Variable(x2, volatile=True) batch_size = x1.shape[0] # compute log probabilities out = self.model(x1, x2) log_probas = F.sigmoid(out) # get index of max log prob pred = log_probas.data.max(0)[1][0] if pred == 0: correct += 1 # compute acc and log valid_acc = (100. * correct) / self.num_valid iter = epoch file.write('{},{}\n'.format(iter, valid_acc)) return valid_acc def test(self): # load best model self.load_checkpoint(best=self.best) # switch to evaluate mode self.model.eval() correct = 0 for i, (x1, x2) in enumerate(self.test_loader): if self.use_gpu: x1, x2 = x1.cuda(), x2.cuda() x1, x2 = Variable(x1, volatile=True), Variable(x2, volatile=True) batch_size = x1.shape[0] # compute log probabilities out = self.model(x1, x2) log_probas = F.sigmoid(out) # get index of max log prob pred = log_probas.data.max(0)[1][0] if pred == 0: correct += 1 test_acc = (100. * correct) / self.num_test print("[*] Test Acc: {}/{} ({:.2f}%)".format(correct, self.num_test, test_acc)) def temper_momentum(self, epoch): """ This function linearly increases the per-layer momentum to a predefined ceiling over a set amount of epochs. """ if epoch == 0: return self.momentums = [ x + y for x, y in zip(self.momentums, self.momentum_temper_rates) ] for i, param_group in enumerate(self.optimizer.param_groups): param_group['momentum'] = self.momentums[i] def decay_lr(self): """ This function linearly decays the per-layer lr over a set amount of epochs. """ self.scheduler.step() for i, param_group in enumerate(self.optimizer.param_groups): self.lrs[i] = param_group['lr'] def save_checkpoint(self, state, is_best): filename = 'model_ckpt.tar' ckpt_path = os.path.join(self.ckpt_dir, filename) torch.save(state, ckpt_path) if is_best: filename = 'best_model_ckpt.tar' shutil.copyfile(ckpt_path, os.path.join(self.ckpt_dir, filename)) def load_checkpoint(self, best=False): print("[*] Loading model from {}".format(self.ckpt_dir)) filename = 'model_ckpt.tar' if best: filename = 'best_model_ckpt.tar' ckpt_path = os.path.join(self.ckpt_dir, filename) ckpt = torch.load(ckpt_path) # load variables from checkpoint self.start_epoch = ckpt['epoch'] self.best_valid_acc = ckpt['best_valid_acc'] self.model.load_state_dict(ckpt['model_state']) self.optimizer.load_state_dict(ckpt['optim_state']) if best: print("[*] Loaded {} checkpoint @ epoch {} " "with best valid acc of {:.3f}".format( filename, ckpt['epoch'], ckpt['best_valid_acc'])) else: print("[*] Loaded {} checkpoint @ epoch {}".format( filename, ckpt['epoch']))
def train(self): # Dataloader train_loader, valid_loader = get_train_validation_loader( self.config.data_dir, self.config.batch_size, self.config.num_train, self.config.augment, self.config.way, self.config.valid_trials, self.config.shuffle, self.config.seed, self.config.num_workers, self.config.pin_memory) # Model, Optimizer, criterion model = SiameseNet() if self.config.optimizer == "SGD": optimizer = optim.SGD(model.parameters(), lr=self.config.lr) else: optimizer = optim.Adam(model.parameters()) criterion = torch.nn.BCEWithLogitsLoss() if self.config.use_gpu: model.cuda() # Load check point if self.config.resume: start_epoch, best_epoch, best_valid_acc, model_state, optim_state = self.load_checkpoint( best=False) model.load_state_dict(model_state) optimizer.load_state_dict(optim_state) one_cycle = OneCyclePolicy(optimizer, self.config.lr, (self.config.epochs - start_epoch) * len(train_loader), momentum_rng=[0.85, 0.95]) else: best_epoch = 0 start_epoch = 0 best_valid_acc = 0 one_cycle = OneCyclePolicy(optimizer, self.config.lr, self.config.epochs * len(train_loader), momentum_rng=[0.85, 0.95]) # create tensorboard summary and add model structure. writer = SummaryWriter(os.path.join(self.config.logs_dir, 'logs'), filename_suffix=self.config.num_model) im1, im2, _ = next(iter(valid_loader)) writer.add_graph(model, [im1.to(self.device), im2.to(self.device)]) counter = 0 num_train = len(train_loader) num_valid = len(valid_loader) print( f"[*] Train on {len(train_loader.dataset)} sample pairs, validate on {valid_loader.dataset.trials} trials" ) # Train & Validation main_pbar = tqdm(range(start_epoch, self.config.epochs), initial=start_epoch, position=0, total=self.config.epochs, desc="Process") for epoch in main_pbar: train_losses = AverageMeter() valid_losses = AverageMeter() # TRAIN model.train() train_pbar = tqdm(enumerate(train_loader), total=num_train, desc="Train", position=1, leave=False) for i, (x1, x2, y) in train_pbar: if self.config.use_gpu: x1, x2, y = x1.to(self.device), x2.to(self.device), y.to( self.device) out = model(x1, x2) loss = criterion(out, y.unsqueeze(1)) # compute gradients and update optimizer.zero_grad() loss.backward() optimizer.step() one_cycle.step() # store batch statistics train_losses.update(loss.item(), x1.shape[0]) # log loss writer.add_scalar("Loss/Train", train_losses.val, epoch * len(train_loader) + i) train_pbar.set_postfix_str(f"loss: {train_losses.val:0.3f}") # VALIDATION model.eval() valid_acc = 0 correct_sum = 0 valid_pbar = tqdm(enumerate(valid_loader), total=num_valid, desc="Valid", position=1, leave=False) with torch.no_grad(): for i, (x1, x2, y) in valid_pbar: if self.config.use_gpu: x1, x2, y = x1.to(self.device), x2.to( self.device), y.to(self.device) # compute log probabilities out = model(x1, x2) loss = criterion(out, y.unsqueeze(1)) y_pred = torch.sigmoid(out) y_pred = torch.argmax(y_pred) if y_pred == 0: correct_sum += 1 # store batch statistics valid_losses.update(loss.item(), x1.shape[0]) # compute acc and log valid_acc = correct_sum / num_valid writer.add_scalar("Loss/Valid", valid_losses.val, epoch * len(valid_loader) + i) valid_pbar.set_postfix_str(f"accuracy: {valid_acc:0.3f}") writer.add_scalar("Acc/Valid", valid_acc, epoch) # check for improvement if valid_acc > best_valid_acc: is_best = True best_valid_acc = valid_acc best_epoch = epoch counter = 0 else: is_best = False counter += 1 # checkpoint the model if counter > self.config.train_patience: print("[!] No improvement in a while, stopping training.") return if is_best or epoch % 5 == 0 or epoch == self.config.epochs: self.save_checkpoint( { 'epoch': epoch, 'model_state': model.state_dict(), 'optim_state': optimizer.state_dict(), 'best_valid_acc': best_valid_acc, 'best_epoch': best_epoch, }, is_best) main_pbar.set_postfix_str( f"best acc: {best_valid_acc:.3f} best epoch: {best_epoch} ") tqdm.write( f"[{epoch}] train loss: {train_losses.avg:.3f} - valid loss: {valid_losses.avg:.3f} - valid acc: {valid_acc:.3f} {'[BEST]' if is_best else ''}" ) # release resources writer.close()
num_workers=8) #========================================================================================================= #================================ 2. BUILDING MODEL device = 'cuda' # Hyperparameters LEARNING_RATE = 1e-3 HIDDEN_LAYER = 100 M = 10 # Model model = SiameseNet(100).to(device) optimizer = optim.Adam(model.parameters(), lr=LEARNING_RATE) criterion = SinkhornDivergenceLoss(lbda=0.1, max_iter=100, p=2, reduction='none') # Count the number of parameters in the network model_parameters = filter(lambda p: p.requires_grad, model.parameters()) params = sum([np.prod(p.size()) for p in model_parameters]) print('\n>> Learning: {} parameters\n'.format(params)) #========================================================================================================= #================================ 3. MAIN D = 4 # Training procedure
class RobustClassifier(LightningModule): def __init__(self, args: argparse.Namespace = None): super().__init__() self.num_classes = args.num_classes self.latent_dim = args.latent_dim self.feature_dim = args.feature_dim self.batch_size = args.batch_size self.lr = args.lr self.class_noise_convertor = nn.ModuleDict({ str(k): nn.Sequential(nn.Linear(self.feature_dim, self.latent_dim), nn.ReLU(), nn.Linear(self.latent_dim, self.latent_dim)).to(self.device) for k in range(self.num_classes) }) self.generator = Generator(ngpu=1) self.generator.load_state_dict(torch.load(args.gen_weights)) self.class_identifier = SiameseNet() self.class_identifier.load_state_dict(torch.load(args.siamese_weights)) if args.generator_pre_train: self.generator.to(self.device).freeze() if args.siamese_pre_train: self.class_identifier.to(self.device).freeze() # self.class_similarity = nn.Linear(4096, 1) self.creterion = ContrastiveLoss(1) self.threshold = args.threshold self.train_acc = Accuracy() self.val_acc = Accuracy() self.test_acc = Accuracy() @staticmethod def add_to_argparse(parser): parser.add_argument("--num_classes", type=int, default=10, help="Number of Classes") parser.add_argument("--lr", type=float, default=3e-4) parser.add_argument("--threshold", type=float, default=0.5) parser.add_argument("--batch_size", type=int, default=16) parser.add_argument("--latent_dim", type=int, default=100) parser.add_argument("--feature_dim", type=int, default=100) parser.add_argument("--gen_weights", type=str, default="weights/gen_weights.pth") parser.add_argument("--siamese_weights", type=str, default="weights/siamese_weights.pth") parser.add_argument("--generator_pre_train", dest='generator_pre_train', default=True, action='store_true') parser.add_argument("--no_generator_pre_train", dest='generator_pre_train', default=True, action='store_false') parser.set_defaults(generator_pre_train=True) parser.add_argument("--siamese_pre_train", dest='siamese_pre_train', default=True, action='store_true') parser.add_argument("--no_siamese_pre_train", dest='siamese_pre_train', default=True, action='store_false') parser.set_defaults(siamese_pre_train=True) return parser def forward(self, x): batch_size = x.size(0) embeddings1, embeddings2 = torch.Tensor([]), torch.Tensor([]) scores = torch.ones(self.num_classes, batch_size) noise = torch.rand(batch_size, self.feature_dim, device=self.device) for class_idx, model in self.class_noise_convertor.items(): class_noise = model(noise).view(batch_size, -1, 1, 1) gen_imgs = self.generator(class_noise) embed1, embed2 = self.class_identifier(gen_imgs, x) embeddings1 = torch.cat( (embeddings1.to(self.device), embed1.to(self.device)), dim=0) embeddings2 = torch.cat( (embeddings2.to(self.device), embed2.to(self.device)), dim=0) scores[int(class_idx)] = nn.functional.cosine_similarity(embed1, embed2, dim=1) self.register_buffer("embeddings_1", embeddings1.view(-1, 4096)) self.register_buffer("embeddings_2", embeddings2.view(-1, 4096)) scores = torch.softmax(scores[scores > 0].view(batch_size, -1), dim=1) pred = torch.argmax(scores, dim=1).to( self.device ) #torch.Tensor([torch.argmax(img_score) if (img_score.max()-img_score.min())>0.5 else -1 for img_score in scores]).to(self.device) return pred def calculate_loss(self, y_true): siamese_labels = torch.Tensor([]) for class_idx in range(self.num_classes): temp = torch.from_numpy( np.where(y_true.cpu().numpy() == class_idx, 1, 0)) siamese_labels = torch.cat( (siamese_labels.to(self.device), temp.to(self.device)), dim=0) result = self.creterion(self.embeddings_1, self.embeddings_2, siamese_labels) return result def training_step(self, batch, batch_idx): img, y_true = batch img, y_true = img.to(self.device), y_true.to(self.device) y_pred = self(img) result = self.calculate_loss(y_true) self.train_acc(y_pred, y_true) self.log('train_acc', self.train_acc, on_epoch=True, on_step=False) self.log('train_loss', result, on_step=True) return result def validation_step(self, batch, batch_idx): img, y_true = batch img, y_true = img.to(self.device), y_true.to(self.device) y_pred = self(img) val_loss = self.calculate_loss(y_true) self.log('val_loss', val_loss, prog_bar=True) self.val_acc(y_pred, y_true) self.log('val_acc', self.val_acc, on_epoch=True, on_step=False) def test_step(self, batch, batch_idx): img, y_true = batch img, y_true = img.to(self.device), y_true.to(self.device) y_pred = self(img) self.test_acc(y_pred, y_true) self.log('test_acc', self.test_acc, on_epoch=True, on_step=False) def configure_optimizers(self): optimizer = optim.Adam(filter(lambda p: p.requires_grad_, self.parameters()), lr=self.lr) return [optimizer], []
dataset_path.append(image_datasets[dataset_list[i]].imgs) dataset_cam = [] dataset_label = [] dataset_filename = [] for i in range(len(dataset_list)): cam, label, filename = get_id(dataset_path[i]) dataset_cam.append(cam) dataset_label.append(label) dataset_filename.append(filename) ###################################################################### # Load Collected data Trained model print('-------test-----------') class_num = len(os.listdir(os.path.join(data_dir, 'train_all'))) embedding_net = ft_net(class_num) model = SiameseNet(embedding_net) if use_gpu: model.cuda() model = load_whole_network(model, name, opt.which_epoch + '_' + str(opt.net_loss_model)) model = model.eval() if use_gpu: model = model.cuda() # Extract feature dataset_feature = [] with torch.no_grad(): for i in range(len(dataset_list)): dataset_feature.append( extract_feature(model, dataloaders[dataset_list[i]]))
camera_id.append(int(camera[0])) files.append(filename) return camera_id, labels, files gallery_path = image_datasets['gallery'].imgs query_path = image_datasets['query'].imgs gallery_cam, gallery_label, gallery_files = get_id(gallery_path) query_cam, query_label, query_files = get_id(query_path) ###################################################################### # Load Collected data Trained model print('-------test-----------') if opt.use_dense: embedding_net = ft_net_dense() model_structure = SiameseNet(embedding_net) else: model_structure = ft_net(751) # model = load_network(model_structure) model = load_network_easy(model_structure) model.bn = nn.Sequential() model.fc = nn.Sequential() model.classifier = nn.Sequential() # Change to test mode model = model.eval() if use_gpu: model = model.cuda() # Extract feature
def main(): ckpt_dir = './ckpt/exp_1/' model = SiameseNet() model.cuda() load_checkpoint(model, ckpt_dir, best=False)
gflags.DEFINE_bool ("retrain", True, "use cuda") gflags.DEFINE_string ("retrain_path", "path-to-retrain-model", 'path retrain') Flags(sys.argv) ############################################# trainSet = Dataset(Flags.train_path,Flags.test_path,Flags.valid_path,Flags.max_iter_train,"train") trainLoader = DataLoader(trainSet, batch_size=Flags.batch_size, shuffle=False, num_workers=Flags.workers) ############################################# validSet = Dataset(Flags.valid_path,Flags.test_path,Flags.valid_path,Flags.max_iter_valid,"valid") validLoader = DataLoader(validSet, batch_size=Flags.batch_size, shuffle=False, num_workers=Flags.workers) ############################################# loss_MSE = torch.nn.MSELoss() if Flags.retrain: print("\n ... Retrain model") net = loadModel(Flags.retrain_path) else: net = SiameseNet() ############################################# save_path = os.path.join(Flags.save_folder,"save_data") model_path = os.path.join(save_path,"models") ############################################# makeFolder(save_path) makeFolder(model_path) # multi gpu if Flags.cuda: os.environ["CUDA_VISIBLE_DEVICES"] = Flags.gpu_ids if len(Flags.gpu_ids.split(",")) > 1: net = torch.nn.DataParallel(net) net.cuda() optimizer = torch.optim.SGD(net.parameters(),lr = Flags.lr, momentum=0.9, nesterov=True) sensitivity_list = [] loss_list = []
def train(config): np.random.seed(2019) tf.random.set_seed(2019) # Cteate model's folder model_dir = config['model_dir'] if not os.path.exists(model_dir): os.makedirs(model_dir) # Create log's folder log_dir = config['train_log_dir'] if not os.path.exists(log_dir): os.makedirs(log_dir) log_name = f"SiameseNet_{datetime.datetime.now():%Y_%m_%d-%H:%M}.log" log_name = os.path.join(log_dir, log_name) print(f"\033[1;32mAll Infomations can be found in {log_name}\033[0m") # Initialize data loader data_dir = config['dataset_path'] train_dataset = DataSet(mode='train', batch_size=config['train_batch_size']) val_dataset = DataSet(mode='val', batch_size=config['eval_batch_size']) train_engine = TrainEngine.TranEngine() # Training options # Build model and load pretrained weights model = SiameseNet.SiameseNet() if config['checkpoint'] is not None: model.load_weights(config['checkpoint']) lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay( initial_learning_rate=config['learning_rate'], decay_steps=5000, decay_rate=0.9, ) optimizer = tf.keras.optimizers.Adagrad(learning_rate=lr_schedule) # Metrics to gather results train_loss = tf.metrics.Mean(name='train_loss') train_acc = tf.metrics.Mean(name='train_acc') val_loss = tf.metrics.Mean(name='val_loss') val_acc = tf.metrics.Mean(name='val_acc') # Summary writers current_time = datetime.datetime.now().strftime('%Y_%m_%d-%H:%M:%S') train_summary_writer = tf.summary.create_file_writer(config['tensorboard_dir']) def loss(img1, img2, label): return model(img1, img2, label) # Forward and upgrade gradients def train_step(state): img1, img2, labels = next(state['train_dataset']) with tf.GradientTape() as tape: loss, label_predict, acc = model(img1, img2, labels) gradient = tape.gradient(loss, model.trainable_variables) optimizer.apply_gradients(zip(gradient, model.trainable_variables)) # show_result(img1, img2, labels) # print(f"\033[1;32mLoss: {loss.numpy()} | Label: {labels.numpy()} | Prediction: {label_predict.numpy()} | Acc: {acc.numpy()}\033[0m") train_loss(loss) train_acc(acc) # if state['total_steps'] % 100 ==0: # logging.info(f"Step: {state['total_steps']} | Loss: {loss.numpy()} | Loss-avg: {train_loss.result().numpy()}") def val_step(state): img1, img2, labels = next(state['val_dataset']) # print(type(img1)) loss,_ , acc = model(img1, img2, labels) loss = tf.reduce_mean(loss) acc = tf.reduce_mean(acc) val_loss(loss) val_acc(acc) def start(state): logging.info("\033[1;31m************** Start Training **************\033[0m") def end(state): logging.info("\033[1;31m************** End Training **************\033[0m") def end_epoch(state): epoch = state['current_epoch'] + 1 val_step(state) logging.info(f"\033[1;32m************** End Epoch {epoch} **************\033[0m") template = 'Epoch {} | Loss: {:.6f} | Accuracy: {:.3%} | ' \ 'Val Loss: {:.6f} | Val Accuracy: {:.3%}' logging.info(template.format(epoch, train_loss.result(), train_acc.result(), val_loss.result(), val_acc.result())) current_loss = val_loss.result().numpy() if current_loss < state['best_val_loss']: logging.info("\033[1;32m************** Saving the best model with loss: " "{:.6f} **************\033[0m".format(current_loss)) state['best_val_loss'] = current_loss # model.save(save_dir=config['model_dir'], model=model) model.save_weights(os.path.join(config['model_dir'], 'my_model'), overwrite=True) #TODO: Early stopping with train_summary_writer.as_default(): tf.summary.scalar('loss', train_loss.result(), step=epoch*config['step_per_epoch']) tf.summary.scalar('accuracy', train_acc.result(), step=epoch*config['step_per_epoch']) # Reset metrics train_loss.reset_states() train_acc.reset_states() val_loss.reset_states() val_acc.reset_states() train_engine.hooks['start'] = start train_engine.hooks['end'] = end train_engine.hooks['end_epoch'] = end_epoch train_engine.hooks['train_step'] = train_step time_start = time.time() # with tf.device('/gpu:0'): train_engine.train(loss_func=loss, train_dataset=train_dataset, val_dataset=val_dataset, epochs=config['epochs'], step_per_epoch=config['step_per_epoch']) time_end = time.time() total_time = time_end - time_start h, m, s = total_time//3600, total_time%3600//60, total_time%3600%60 logging.info(f"\033[1;31m************** Totally used {h}hour {m}minute {s}second **************\033[0m") copyfile(real_log, log_name)
[VAL_SPLIT_SIZE, TEST_SPLIT_SIZE]) vdl = DataLoader(val_set, batch_size=VALIDATE_BATCH_SIZE, collate_fn=collate_fn) tdl = DataLoader(test_set, batch_size=TEST_BATCH_SIZE, collate_fn=collate_fn) VOCAB_SIZE = len(vocab) + 1 EMB_DIM = 100 HIDDEN_SIZE = 128 LR = 0.001 N_EPOCH = 10 print("Creating network") net = SiameseNet(VOCAB_SIZE, EMB_DIM, HIDDEN_SIZE) opt = optim.Adam(net.parameters(), lr=LR) net = net.cuda() sim = nn.CosineSimilarity() print(net) print("Running training loop") cost_book = [] val_acc_book = [] for j in range(N_EPOCH): cost = 0 pbar = tqdm(dl) for i, b in enumerate(pbar): opt.zero_grad()
stage_1 = False stage_2 = True stage_3 = False if stage_0: print('train_model_siamese_with_two_model structure') print(model) print(model_verif) # train_model = train_model_triplet train_model = train_model_siamese_with_two_model model = train_model(model, model_verif, criterion, optimizer_ft, exp_lr_scheduler, num_epochs=60) if stage_1: embedding_net = ft_net_dense(len(class_names)) model_siamese = SiameseNet(embedding_net) if use_gpu: model_siamese.cuda() print('model_siamese structure') # print(model_siamese) # stage_1_classifier_id = list(map(id, model_siamese.embedding_net.classifier.parameters())) \ # + list(map(id, model_siamese.embedding_net.model.fc.parameters())) \ # + list(map(id, model_siamese.classifier.parameters())) # stage_1_classifier_params = filter(lambda p: id(p) in stage_1_classifier_id, model_siamese.parameters()) # stage_1_base_params = filter(lambda p: id(p) not in stage_1_classifier_id, model_siamese.parameters()) # This manner's effect is worse than SGD # optimizer_ft = optim.Adam([ # {'params': stage_1_base_params, 'lr': 0.1 * opt.lr}, # {'params': stage_1_classifier_params, 'lr': 1 * opt.lr},
return model ###################################################################### # Train and evaluate # ^^^^^^^^^^^^^^^^^^ # # It should take around 1-2 hours on GPU. # dir_name = os.path.join('./model', name) if not os.path.exists('model'): os.mkdir('model') print('class_num = %d' % (class_num)) embedding_net = ft_net(class_num) model = SiameseNet(embedding_net) if use_gpu: model.cuda() # print('model structure') # print(model) criterion_contrastive = ContrastiveLoss() criterion_verify = nn.CrossEntropyLoss() classifier_id = list(map(id, model.embedding_net.classifier.parameters())) \ + list(map(id, model.classifier.parameters())) classifier_params = filter(lambda p: id(p) in classifier_id, model.parameters()) base_params = filter(lambda p: id(p) not in classifier_id, model.parameters())