def main():
    print('\nCurrent time is \x1b[91m{}\x1b[0m.'.format(str(time.asctime())))
    print('Parsed options: {}'.format(vars(args)))
    print('Number of Speakers: {}.\n'.format(train_dir.num_spks))
    kernel_size = args.kernel_size.split(',')
    kernel_size = [int(x) for x in kernel_size]
    padding = [int(((x - 1) / 2)) for x in kernel_size]
    kernel_size = tuple(kernel_size)
    padding = tuple(padding)
    channels = args.channels.split(',')
    channels = [int(x) for x in channels]
    model_kwargs = {'embedding_size_a': args.embedding_size_a, 'embedding_size_b': args.embedding_size_b, 'embedding_size_o': args.embedding_size_o, 'inst_norm': args.inst_norm, 'resnet_size': args.resnet_size, 'num_classes_a': train_dir.num_spks, 'num_classes_b': train_dir.num_doms, 'channels': channels, 'avg_size': args.avg_size, 'alpha': args.alpha, 'kernel_size': kernel_size, 'padding': padding, 'dropout_p': args.dropout_p}
    print('Model options: {}'.format(model_kwargs))
    model = create_model(args.model, **model_kwargs)
    start_epoch = 0
    if (args.save_init and (not args.finetune)):
        check_path = '{}/checkpoint_{}.pth'.format(args.check_path, start_epoch)
        torch.save(model, check_path)
    if args.resume:
        if os.path.isfile(args.resume):
            print('=> loading checkpoint {}'.format(args.resume))
            checkpoint = torch.load(args.resume)
            start_epoch = checkpoint['epoch']
            filtered = {k: v for (k, v) in checkpoint['state_dict'].items() if ('num_batches_tracked' not in k)}
            model_dict = model.state_dict()
            model_dict.update(filtered)
            model.load_state_dict(model_dict)
        else:
            print('=> no checkpoint found at {}'.format(args.resume))
    ce_criterion = nn.CrossEntropyLoss()
    if (args.loss_type == 'soft'):
        xe_criterion = None
    elif (args.loss_type == 'asoft'):
        ce_criterion = None
        model.classifier_spk = AngleLinear(in_features=args.embedding_size, out_features=train_dir.num_spks, m=args.m)
        xe_criterion = AngleSoftmaxLoss(lambda_min=args.lambda_min, lambda_max=args.lambda_max)
    elif (args.loss_type == 'center'):
        xe_criterion = CenterLoss(num_classes=train_dir.num_spks, feat_dim=args.embedding_size)
    elif (args.loss_type == 'amsoft'):
        ce_criterion = None
        model.classifier_spk = AdditiveMarginLinear(feat_dim=args.embedding_size, n_classes=train_dir.num_spks)
        xe_criterion = AMSoftmaxLoss(margin=args.margin, s=args.s)
    optimizer = create_optimizer(model.parameters(), args.optimizer, **opt_kwargs)
    if (args.loss_type == 'center'):
        optimizer = torch.optim.SGD([{'params': xe_criterion.parameters(), 'lr': (args.lr * 5)}, {'params': model.parameters()}], lr=args.lr, weight_decay=args.weight_decay, momentum=args.momentum)
    if args.finetune:
        if ((args.loss_type == 'asoft') or (args.loss_type == 'amsoft')):
            classifier_params = list(map(id, model.classifier.parameters()))
            rest_params = filter((lambda p: (id(p) not in classifier_params)), model.parameters())
            optimizer = torch.optim.SGD([{'params': model.classifier.parameters(), 'lr': (args.lr * 5)}, {'params': rest_params}], lr=args.lr, weight_decay=args.weight_decay, momentum=args.momentum)
    if (args.scheduler == 'exp'):
        scheduler = ExponentialLR(optimizer, gamma=args.gamma)
    else:
        milestones = args.milestones.split(',')
        milestones = [int(x) for x in milestones]
        milestones.sort()
        scheduler = MultiStepLR(optimizer, milestones=milestones, gamma=0.1)
    ce = [ce_criterion, xe_criterion]
    start = (args.start_epoch + start_epoch)
    print(('Start epoch is : ' + str(start)))
    end = (start + args.epochs)
    train_loader = torch.utils.data.DataLoader(train_dir, batch_size=args.batch_size, shuffle=False, **kwargs)
    valid_loader = torch.utils.data.DataLoader(valid_dir, batch_size=int((args.batch_size / 2)), shuffle=False, **kwargs)
    test_loader = torch.utils.data.DataLoader(test_dir, batch_size=args.test_batch_size, shuffle=False, **kwargs)
    if args.cuda:
        model = model.cuda()
        for i in range(len(ce)):
            if (ce[i] != None):
                ce[i] = ce[i].cuda()
        print('Dropout is {}.'.format(model.dropout_p))
    for epoch in range(start, end):
        print("\n\x1b[1;34m Current '{}' learning rate is ".format(args.optimizer), end='')
        for param_group in optimizer.param_groups:
            print('{:.5f} '.format(param_group['lr']), end='')
        print(' \x1b[0m')
        if (((epoch % 2) == 1) and (epoch != (end - 1))):
            test(test_loader, valid_loader, model, epoch)
        train(train_loader, model, ce, optimizer, epoch)
        if (((epoch % 4) == 1) or (epoch == (end - 1))):
            check_path = '{}/checkpoint_{}.pth'.format(args.check_path, epoch)
            torch.save({'epoch': epoch, 'state_dict': model.state_dict(), 'criterion': ce}, check_path)
        scheduler.step()
    extract_dir = KaldiExtractDataset(dir=args.test_dir, transform=transform_V, filer_loader=np.load)
    extract_loader = torch.utils.data.DataLoader(extract_dir, batch_size=1, shuffle=False, **kwargs)
    xvector_dir = args.check_path
    xvector_dir = xvector_dir.replace('checkpoint', 'xvector')
    verification_extract(extract_loader, model, xvector_dir)
    verify_dir = ScriptVerifyDataset(dir=args.test_dir, trials_file=args.trials, xvectors_dir=xvector_dir, loader=read_vec_flt)
    verify_loader = torch.utils.data.DataLoader(verify_dir, batch_size=64, shuffle=False, **kwargs)
    verification_test(test_loader=verify_loader, dist_type=('cos' if args.cos_sim else 'l2'), log_interval=args.log_interval)
    writer.close()
def main():
    print('\nCurrent time is \x1b[91m{}\x1b[0m.'.format(str(time.asctime())))
    print('Parsed options: {}'.format(vars(args)))
    print('Number of Speakers: {}.\n'.format(train_dir.num_spks))
    kernel_size = args.kernel_size.split(',')
    kernel_size = [int(x) for x in kernel_size]
    padding = [int(((x - 1) / 2)) for x in kernel_size]
    kernel_size = tuple(kernel_size)
    padding = tuple(padding)
    channels = args.channels.split(',')
    channels = [int(x) for x in channels]
    model_kwargs = {'embedding_size_a': args.embedding_size_a, 'embedding_size_b': args.embedding_size_b, 'embedding_size_o': args.embedding_size_o, 'inst_norm': args.inst_norm, 'resnet_size': args.resnet_size, 'num_classes_a': train_dir.num_spks, 'num_classes_b': train_dir.num_doms, 'channels': channels, 'avg_size': args.avg_size, 'alpha': args.alpha, 'kernel_size': kernel_size, 'padding': padding, 'dropout_p': args.dropout_p}
    print('Model options: {}'.format(model_kwargs))
    model = create_model(args.model, **model_kwargs)
    start_epoch = 0
    if (args.save_init and (not args.finetune)):
        check_path = '{}/checkpoint_{}.pth'.format(args.check_path, start_epoch)
        torch.save(model, check_path)
    if args.resume:
        if os.path.isfile(args.resume):
            print('=> loading checkpoint {}'.format(args.resume))
            checkpoint = torch.load(args.resume)
            start_epoch = checkpoint['epoch']
            filtered = {k: v for (k, v) in checkpoint['state_dict'].items() if ('num_batches_tracked' not in k)}
            model_dict = model.state_dict()
            model_dict.update(filtered)
            model.load_state_dict(model_dict)
        else:
            print('=> no checkpoint found at {}'.format(args.resume))
    ce_criterion = nn.CrossEntropyLoss()
    if (args.loss_type == 'soft'):
        xe_criterion = None
    elif (args.loss_type == 'asoft'):
        ce_criterion = None
        model.classifier_spk = AngleLinear(in_features=args.embedding_size, out_features=train_dir.num_spks, m=args.m)
        xe_criterion = AngleSoftmaxLoss(lambda_min=args.lambda_min, lambda_max=args.lambda_max)
    elif (args.loss_type == 'center'):
        xe_criterion = CenterLoss(num_classes=train_dir.num_spks, feat_dim=args.embedding_size)
    elif (args.loss_type == 'amsoft'):
        ce_criterion = None
        model.classifier_spk = AdditiveMarginLinear(feat_dim=args.embedding_size, n_classes=train_dir.num_spks)
        xe_criterion = AMSoftmaxLoss(margin=args.margin, s=args.s)
    optimizer = create_optimizer(model.parameters(), args.optimizer, **opt_kwargs)
    if (args.loss_type == 'center'):
        optimizer = torch.optim.SGD([{'params': xe_criterion.parameters(), 'lr': (args.lr * 5)}, {'params': model.parameters()}], lr=args.lr, weight_decay=args.weight_decay, momentum=args.momentum)
    if args.finetune:
        if ((args.loss_type == 'asoft') or (args.loss_type == 'amsoft')):
            classifier_params = list(map(id, model.classifier.parameters()))
            rest_params = filter((lambda p: (id(p) not in classifier_params)), model.parameters())
            optimizer = torch.optim.SGD([{'params': model.classifier.parameters(), 'lr': (args.lr * 5)}, {'params': rest_params}], lr=args.lr, weight_decay=args.weight_decay, momentum=args.momentum)
    if (args.scheduler == 'exp'):
        scheduler = ExponentialLR(optimizer, gamma=args.gamma)
    else:
        milestones = args.milestones.split(',')
        milestones = [int(x) for x in milestones]
        milestones.sort()
        scheduler = MultiStepLR(optimizer, milestones=milestones, gamma=0.1)
    ce = [ce_criterion, xe_criterion]
    start = (args.start_epoch + start_epoch)
    print(('Start epoch is : ' + str(start)))
    end = (start + args.epochs)
    train_loader = torch.utils.data.DataLoader(train_dir, batch_size=args.batch_size, shuffle=False, **kwargs)
    valid_loader = torch.utils.data.DataLoader(valid_dir, batch_size=int((args.batch_size / 2)), shuffle=False, **kwargs)
    test_loader = torch.utils.data.DataLoader(test_dir, batch_size=args.test_batch_size, shuffle=False, **kwargs)
    if args.cuda:
        model = model.cuda()
        for i in range(len(ce)):
            if (ce[i] != None):
                ce[i] = ce[i].cuda()
        print('Dropout is {}.'.format(model.dropout_p))
    for epoch in range(start, end):
        print("\n\x1b[1;34m Current '{}' learning rate is ".format(args.optimizer), end=)
        for param_group in optimizer.param_groups:
            print('{:.5f} '.format(param_group['lr']), end=)
        print(' \x1b[0m')
        if (((epoch % 2) == 1) and (epoch != (end - 1))):
            test(test_loader, valid_loader, model, epoch)
        train(train_loader, model, ce, optimizer, epoch)
        if (((epoch % 4) == 1) or (epoch == (end - 1))):
            check_path = '{}/checkpoint_{}.pth'.format(args.check_path, epoch)
            torch.save({'epoch': epoch, 'state_dict': model.state_dict(), 'criterion': ce}, check_path)
        scheduler.step()
    extract_dir = KaldiExtractDataset(dir=args.test_dir, transform=transform_V, filer_loader=np.load)
    extract_loader = torch.utils.data.DataLoader(extract_dir, batch_size=1, shuffle=False, **kwargs)
    xvector_dir = args.check_path
    xvector_dir = xvector_dir.replace('checkpoint', 'xvector')
    verification_extract(extract_loader, model, xvector_dir)
    verify_dir = ScriptVerifyDataset(dir=args.test_dir, trials_file=args.trials, xvectors_dir=xvector_dir, loader=read_vec_flt)
    verify_loader = torch.utils.data.DataLoader(verify_dir, batch_size=64, shuffle=False, **kwargs)
    verification_test(test_loader=verify_loader, dist_type=('cos' if args.cos_sim else 'l2'), log_interval=args.log_interval)
    writer.close()