def build_dataset_test(self): """ Create testing dataset """ # self.dataset_test = dataset_shapenet.ShapeNetSeg(mode="MEMORIZE", # class_choice=self.opt.cat, # npoints=self.opt.number_points) self.dataset_test = config.get_dataset('val', self.ddn_config) self.dataloader_test = torch.utils.data.DataLoader(self.dataset_test, batch_size=self.opt.batch_size, shuffle=False, num_workers=int(self.opt.workers), drop_last=True) self.len_dataset_test = len(self.dataset_test)
model_selection_metric = cfg['training']['model_selection_metric'] if cfg['training']['model_selection_mode'] == 'maximize': model_selection_sign = 1 elif cfg['training']['model_selection_mode'] == 'minimize': model_selection_sign = -1 else: raise ValueError('model_selection_mode must be ' 'either maximize or minimize.') # Output directory if not os.path.exists(out_dir): os.makedirs(out_dir) # Dataset train_dataset = config.get_dataset('train', cfg) val_dataset = config.get_dataset('val', cfg) train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, num_workers=4, shuffle=True, collate_fn=data.collate_remove_none, worker_init_fn=data.worker_init_fn) val_loader = torch.utils.data.DataLoader(val_dataset, batch_size=10, num_workers=4, shuffle=False, collate_fn=data.collate_remove_none, worker_init_fn=data.worker_init_fn)
occ_out = np.zeros((n_p, )) occ_out[inside_img & inside_mask] = 1. return occ_out # Shortcuts out_dir = cfg['training']['out_dir'] generation_dir = os.path.join(out_dir, cfg['generation']['generation_dir']) if not os.path.isdir(generation_dir): os.makedirs(generation_dir) # Dataset dataset = config.get_dataset(cfg, mode='render', return_idx=True) # Loader test_loader = torch.utils.data.DataLoader(dataset, batch_size=1, num_workers=0, shuffle=True) for it, data in enumerate(tqdm(test_loader)): idx = data['idx'].item() try: model_dict = dataset.get_model_dict(idx) except AttributeError: model_dict = {'model': str(idx), 'category': 'na', 'category_id': 0000} modelname = model_dict['model']
out_dir = cfg['training']['out_dir'] generation_dir = os.path.join(out_dir, cfg['generation']['generation_dir']) out_time_file = os.path.join(generation_dir, 'time_generation_full.pkl') out_time_file_class = os.path.join(generation_dir, 'time_generation.pkl') batch_size = cfg['generation']['batch_size'] input_type = cfg['data']['input_type'] vis_n_outputs = cfg['generation']['vis_n_outputs'] mesh_extension = cfg['generation']['mesh_extension'] # Dataset # This is for DTU when we parallelise over images # we do not want to treat different images from same object as # different objects cfg['data']['split_model_for_images'] = False dataset = config.get_dataset(cfg, mode='test', return_idx=True) # Model model = config.get_model(cfg, device=device, len_dataset=len(dataset)) checkpoint_io = CheckpointIO(out_dir, model=model) checkpoint_io.load(cfg['test']['model_file']) # Generator generator = config.get_generator(model, cfg, device=device) torch.manual_seed(0) # Loader test_loader = torch.utils.data.DataLoader(dataset, batch_size=1, num_workers=0,
elif cfg['training']['model_selection_mode'] == 'minimize': model_selection_sign = -1 else: raise ValueError('model_selection_mode must be ' 'either maximize or minimize.') # Output directory if not os.path.exists(out_dir): os.makedirs(out_dir) # Dataset # specify path train_dataset = config.get_dataset('train', cfg, batch_size=batch_size, shuffle=True, repeat_count=1, epoch=100) val_dataset = config.get_dataset('val', cfg, batch_size=10, shuffle=False, repeat_count=1, epoch=1) vis_dataset = config.get_dataset('val', cfg, batch_size=12, shuffle=False, repeat_count=1, epoch=1)
out_dir = cfg["training"]["out_dir"] generation_dir = os.path.join(out_dir, cfg["generation"]["generation_dir"]) out_time_file = os.path.join(generation_dir, "time_generation_full.pkl") out_time_file_class = os.path.join(generation_dir, "time_generation.pkl") batch_size = cfg["generation"]["batch_size"] input_type = cfg["data"]["input_type"] vis_n_outputs = cfg["generation"]["vis_n_outputs"] if vis_n_outputs is None: vis_n_outputs = -1 # Model # Dataset dataset = config.get_dataset('test', cfg, batch_size=1, shuffle=False, repeat_count=1, epoch=1) # Loader dataloader = dataset.loader() model = config.get_model(cfg, dataset=dataset) dummy_optimizer = tf.keras.optimizers.Adam(learning_rate=1e-4, epsilon=1e-08) checkpoint_io = CheckpointIO(model, dummy_optimizer, checkpoint_dir=out_dir) checkpoint_io.load(cfg['test']['model_file']) # Generator generator = config.get_generator(model, cfg)
is_cuda = (torch.cuda.is_available() and not args.no_cuda) device = torch.device("cuda" if is_cuda else "cpu") out_dir = cfg['training']['out_dir'] generation_dir = os.path.join(out_dir, cfg['generation']['generation_dir']) out_time_file = os.path.join(generation_dir, 'time_generation_full.pkl') out_time_file_class = os.path.join(generation_dir, 'time_generation.pkl') batch_size = cfg['generation']['batch_size'] input_type = cfg['data']['input_type'] vis_n_outputs = cfg['generation']['vis_n_outputs'] if vis_n_outputs is None: vis_n_outputs = -1 # Dataset dataset = config.get_dataset('test', cfg, return_idx=True) # Model model = config.get_model(cfg, device=device, dataset=dataset) checkpoint_io = CheckpointIO(out_dir, model=model) checkpoint_io.load(cfg['test']['model_file']) # Generator generator = config.get_generator(model, cfg, device=device) # Determine what to generate generate_mesh = cfg['generation']['generate_mesh'] generate_pointcloud = cfg['generation']['generate_pointcloud'] if generate_mesh and not hasattr(generator, 'generate_mesh'):
cfg['generation']['refinement_step'] = 0 model_selection_metric = cfg['training']['model_selection_metric'] if cfg['training']['model_selection_mode'] == 'maximize': model_selection_sign = 1 elif cfg['training']['model_selection_mode'] == 'minimize': model_selection_sign = -1 else: raise ValueError('model_selection_mode must be ' 'either maximize or minimize.') # Output directory if not os.path.exists(out_dir): os.makedirs(out_dir) train_dataset = config.get_dataset(cfg, mode='train') train_loader = torch.utils.data.DataLoader( train_dataset, batch_size=batch_size, num_workers=n_workers, shuffle=True, collate_fn=data.collate_remove_none, ) val_dataset = config.get_dataset(cfg, mode='val') val_loader = torch.utils.data.DataLoader( val_dataset, batch_size=batch_size_val, num_workers=int(n_workers / 2), shuffle=True, collate_fn=data.collate_remove_none, )
t0 = time.time() # Shorthands out_dir = cfg['training']['out_dir'] generation_dir = cfg['generation']['generation_dir'] batch_size = cfg['training']['batch_size'] # Out file generation_out_dir = os.path.join(out_dir, generation_dir) if not os.path.exists(generation_out_dir): os.makedirs(generation_out_dir) out_file_latent = os.path.join(generation_out_dir, 'latent_space.pkl') if not os.path.isfile(out_file_latent): # Dataset train_dataset = config.get_dataset('train', cfg, return_idx=True) train_loader = torch.utils.data.DataLoader( train_dataset, batch_size=batch_size, num_workers=4, shuffle=True, collate_fn=data.collate_remove_none, worker_init_fn=data.worker_init_fn) # Model model = config.get_model(cfg, device=device, dataset=train_dataset) kwargs = { 'model': model, } checkpoint_io = CheckpointIO( out_dir,
generation_dir = os.path.join(out_dir, cfg['generation']['generation_dir']) else: generation_dir = os.path.join(out_dir, args.generation_dir) out_time_file = os.path.join(generation_dir, 'time_generation_full.pkl') out_time_file_class = os.path.join(generation_dir, 'time_generation.pkl') batch_size = cfg['generation']['batch_size'] input_type = cfg['data']['input_type'] vis_n_outputs = cfg['generation']['vis_n_outputs'] if vis_n_outputs is None: vis_n_outputs = -1 # Dataset dataset = config.get_dataset('test', cfg, return_idx=True, use_target_domain=args.da) # Model model = config.get_model(cfg, device=device, dataset=dataset) checkpoint_io = CheckpointIO(out_dir, model=model) # load with 'cuda:0' because we set visible devices earlier checkpoint_io.load(cfg['test']['model_file'], 'cuda:0') # Generator generator = config.get_generator(model, cfg, device=device) # Determine what to generate generate_mesh = cfg['generation']['generate_mesh'] generate_pointcloud = cfg['generation']['generate_pointcloud']
model_selection_metric = cfg['training']['model_selection_metric'] if cfg['training']['model_selection_mode'] == 'maximize': model_selection_sign = 1 elif cfg['training']['model_selection_mode'] == 'minimize': model_selection_sign = -1 else: raise ValueError('model_selection_mode must be ' 'either maximize or minimize.') # Output directory if not os.path.exists(out_dir): os.makedirs(out_dir) # Dataset train_dataset = config.get_dataset('train', cfg, return_category=True) val_dataset = config.get_dataset('val', cfg) train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, num_workers=4, shuffle=True, collate_fn=data.collate_remove_none, worker_init_fn=data.worker_init_fn) val_loader = torch.utils.data.DataLoader(val_dataset, batch_size=10, num_workers=4, shuffle=False, collate_fn=data.collate_remove_none, worker_init_fn=data.worker_init_fn)
out_time_file = os.path.join(generation_dir, 'time_generation_full.pkl') out_time_file_class = os.path.join(generation_dir, 'time_generation.pkl') batch_size = cfg['generation']['batch_size'] input_type = cfg['data']['input_type'] vis_n_outputs = cfg['generation']['vis_n_outputs'] if vis_n_outputs is None: vis_n_outputs = -1 # Dataset if cfg['data']['input_type'] == 'img': cfg['model']['encoder_kwargs'].update({'pretrained': ''}) if args.subject_idx >= 0 and args.sequence_idx >= 0: dataset = config.get_dataset('test', cfg, subject_idx=args.subject_idx, sequence_idx=args.sequence_idx) else: dataset = config.get_dataset('test', cfg) # Model model = config.get_model(cfg, device=device, dataset=dataset) checkpoint_io = CheckpointIO(out_dir, model=model) checkpoint_io.load(cfg['test']['model_file']) # Generator generator = config.get_generator(model, cfg, device=device) # Determine what to generate generate_mesh = cfg['generation']['generate_mesh']
def SMPLD_register(args): cfg = config.load_config(args.config, 'configs/default.yaml') out_dir = cfg['training']['out_dir'] generation_dir = os.path.join(out_dir, cfg['generation']['generation_dir']) is_cuda = (torch.cuda.is_available() and not args.no_cuda) device = torch.device("cuda" if is_cuda else "cpu") if args.subject_idx >= 0 and args.sequence_idx >= 0: logger, _ = create_logger(generation_dir, phase='reg_subject{}_sequence{}'.format(args.subject_idx, args.sequence_idx), create_tf_logs=False) else: logger, _ = create_logger(generation_dir, phase='reg_all', create_tf_logs=False) # Get dataset if args.subject_idx >= 0 and args.sequence_idx >= 0: dataset = config.get_dataset('test', cfg, sequence_idx=args.sequence_idx, subject_idx=args.subject_idx) else: dataset = config.get_dataset('test', cfg) batch_size = cfg['generation']['batch_size'] # Loader test_loader = torch.utils.data.DataLoader( dataset, batch_size=batch_size, num_workers=1, shuffle=False) model_counter = defaultdict(int) # Set optimization hyper parameters iterations, pose_iterations, steps_per_iter, pose_steps_per_iter = 3, 2, 30, 30 inner_dists = [] outer_dists = [] for it, data in enumerate(tqdm(test_loader)): idxs = data['idx'].cpu().numpy() loc = data['points.loc'].cpu().numpy() batch_size = idxs.shape[0] # Directories to load corresponding informations mesh_dir = os.path.join(generation_dir, 'meshes') # directory for posed and (optionally) unposed implicit outer/inner meshes label_dir = os.path.join(generation_dir, 'labels') # directory for part labels register_dir = os.path.join(generation_dir, 'registrations') # directory for part labels if args.use_raw_scan: scan_dir = dataset.dataset_folder # this is the folder that contains CAPE raw scans else: scan_dir = None all_posed_minimal_meshes = [] all_posed_cloth_meshes = [] all_posed_vertices = [] all_unposed_vertices = [] scan_part_labels = [] for idx in idxs: model_dict = dataset.get_model_dict(idx) subset = model_dict['subset'] subject = model_dict['subject'] sequence = model_dict['sequence'] gender = model_dict['gender'] filebase = os.path.basename(model_dict['data_path'])[:-4] folder_name = os.path.join(subset, subject, sequence) # TODO: we assume batch size stays the same if one resumes the job # can be more flexible to support different batch sizes before and # after resume register_file = os.path.join(register_dir, folder_name, filebase + 'minimal.registered.ply') if os.path.exists(register_file): # batch already computed, break break # points_dict = np.load(model_dict['data_path']) # gender = str(points_dict['gender']) mesh_dir_ = os.path.join(mesh_dir, folder_name) label_dir_ = os.path.join(label_dir, folder_name) if scan_dir is not None: scan_dir_ = os.path.join(scan_dir, subject, sequence) # Load part labels and vertex translations label_file_name = filebase + '.minimal.npz' label_dict = dict(np.load(os.path.join(label_dir_, label_file_name))) labels = torch.tensor(label_dict['part_labels'].astype(np.int64)).to(device) # part labels for each vertex (14 or 24) scan_part_labels.append(labels) # Load minimal implicit surfaces mesh_file_name = filebase + '.minimal.posed.ply' # posed_mesh = Mesh(filename=os.path.join(mesh_dir_, mesh_file_name)) posed_mesh = trimesh.load(os.path.join(mesh_dir_, mesh_file_name), process=False) posed_vertices = np.array(posed_mesh.vertices) all_posed_vertices.append(posed_vertices) posed_mesh = tm.from_tensors(torch.tensor(posed_mesh.vertices.astype('float32'), requires_grad=False, device=device), torch.tensor(posed_mesh.faces.astype('int64'), requires_grad=False, device=device)) all_posed_minimal_meshes.append(posed_mesh) mesh_file_name = filebase + '.minimal.unposed.ply' if os.path.exists(os.path.join(mesh_dir_, mesh_file_name)) and args.init_pose: # unposed_mesh = Mesh(filename=os.path.join(mesh_dir_, mesh_file_name)) unposed_mesh = trimesh.load(os.path.join(mesh_dir_, mesh_file_name), process=False) unposed_vertices = np.array(unposed_mesh.vertices) all_unposed_vertices.append(unposed_vertices) if args.use_raw_scan: # Load raw scans mesh_file_name = filebase + '.ply' # posed_mesh = Mesh(filename=os.path.join(scan_dir_, mesh_file_name)) posed_mesh = trimesh.load(os.path.join(scan_dir_, mesh_file_name), process=False) posed_mesh = tm.from_tensors(torch.tensor(posed_mesh.vertices.astype('float32') / 1000, requires_grad=False, device=device), torch.tensor(posed_mesh.faces.astype('int64'), requires_grad=False, device=device)) all_posed_cloth_meshes.append(posed_mesh) else: # Load clothed implicit surfaces mesh_file_name = filebase + '.cloth.posed.ply' # posed_mesh = Mesh(filename=os.path.join(mesh_dir_, mesh_file_name)) posed_mesh = trimesh.load(os.path.join(mesh_dir_, mesh_file_name), process=False) posed_mesh = tm.from_tensors(torch.tensor(posed_mesh.vertices.astype('float32'), requires_grad=False, device=device), torch.tensor(posed_mesh.faces.astype('int64'), requires_grad=False, device=device)) all_posed_cloth_meshes.append(posed_mesh) if args.num_joints == 24: bm = BodyModel(bm_path='body_models/smpl/male/model.pkl', num_betas=10, batch_size=batch_size).to(device) parents = bm.kintree_table[0].detach().cpu().numpy() labels = bm.weights.argmax(1) # Convert 24 parts to 14 parts smpl2ipnet = torch.from_numpy(SMPL2IPNET_IDX).to(device) labels = smpl2ipnet[labels].clone().unsqueeze(0) del bm elif args.num_joints == 14: with open('body_models/misc/smpl_parts_dense.pkl', 'rb') as f: part_labels = pkl.load(f) labels = np.zeros((6890,), dtype=np.int64) for n, k in enumerate(part_labels): labels[part_labels[k]] = n labels = torch.tensor(labels).to(device).unsqueeze(0) else: raise ValueError('Got {} joints but umber of joints can only be either 14 or 24'.format(args.num_joints)) th_faces = torch.tensor(smpl_faces.astype('float32'), dtype=torch.long).to(device) # We assume loaded meshes are properly scaled and offsetted to the orignal SMPL space, if len(all_posed_minimal_meshes) > 0 and len(all_unposed_vertices) == 0: # IPNet optimization without vertex traslation # raise NotImplementedError('Optimization for IPNet is not implemented yet.') if args.num_joints == 24: for idx in range(len(scan_part_labels)): scan_part_labels[idx] = smpl2ipnet[scan_part_labels[idx]].clone() prior = get_prior(gender=gender, precomputed=True) pose_init = torch.zeros((batch_size, 72)) pose_init[:, 3:] = prior.mean betas, pose, trans = torch.zeros((batch_size, 10)), pose_init, torch.zeros((batch_size, 3)) # Init SMPL, pose with mean smpl pose, as in ch.registration smpl = th_batch_SMPL(batch_size, betas, pose, trans, faces=th_faces, gender=gender).to(device) smpl_part_labels = torch.cat([labels] * batch_size, axis=0) # Optimize pose first optimize_pose_only(all_posed_minimal_meshes, smpl, pose_iterations, pose_steps_per_iter, scan_part_labels, smpl_part_labels, None, args) # Optimize pose and shape optimize_pose_shape(all_posed_minimal_meshes, smpl, iterations, steps_per_iter, scan_part_labels, smpl_part_labels, None, args) inner_vertices, _, _, _ = smpl() # Optimize vertices for SMPLD init_smpl_meshes = [tm.from_tensors(vertices=v.clone().detach(), faces=smpl.faces) for v in inner_vertices] optimize_offsets(all_posed_cloth_meshes, smpl, init_smpl_meshes, 5, 10, args) outer_vertices, _, _, _ = smpl() elif len(all_posed_minimal_meshes) > 0: # NASA+PTFs optimization with vertex traslations # Compute poses from implicit surfaces and correspondences # TODO: we could also compute bone-lengths if we train PTFs to predict A-pose with a global translation # that equals to the centroid of the pointcloud poses = compute_poses(all_posed_vertices, all_unposed_vertices, scan_part_labels, parents, args) # Convert 24 parts to 14 parts for idx in range(len(scan_part_labels)): scan_part_labels[idx] = smpl2ipnet[scan_part_labels[idx]].clone() pose_init = torch.from_numpy(poses).float() betas, pose, trans = torch.zeros((batch_size, 10)), pose_init, torch.zeros((batch_size, 3)) # Init SMPL, pose with mean smpl pose, as in ch.registration smpl = th_batch_SMPL(batch_size, betas, pose, trans, faces=th_faces, gender=gender).to(device) smpl_part_labels = torch.cat([labels] * batch_size, axis=0) # Optimize pose first optimize_pose_only(all_posed_minimal_meshes, smpl, pose_iterations, pose_steps_per_iter, scan_part_labels, smpl_part_labels, None, args) # Optimize pose and shape optimize_pose_shape(all_posed_minimal_meshes, smpl, iterations, steps_per_iter, scan_part_labels, smpl_part_labels, None, args) inner_vertices, _, _, _ = smpl() # Optimize vertices for SMPLD init_smpl_meshes = [tm.from_tensors(vertices=v.clone().detach(), faces=smpl.faces) for v in inner_vertices] optimize_offsets(all_posed_cloth_meshes, smpl, init_smpl_meshes, 5, 10, args) outer_vertices, _, _, _ = smpl() else: inner_vertices = outer_vertices = None if args.use_raw_scan: for i, idx in enumerate(idxs): model_dict = dataset.get_model_dict(idx) subset = model_dict['subset'] subject = model_dict['subject'] sequence = model_dict['sequence'] filebase = os.path.basename(model_dict['data_path'])[:-4] folder_name = os.path.join(subset, subject, sequence) register_dir_ = os.path.join(register_dir, folder_name) if not os.path.exists(register_dir_): os.makedirs(register_dir_) if not os.path.exists(os.path.join(register_dir_, filebase + 'minimal.registered.ply')): registered_mesh = trimesh.Trimesh(inner_vertices[i].detach().cpu().numpy().astype(np.float64), smpl_faces, process=False) registered_mesh.export(os.path.join(register_dir_, filebase + 'minimal.registered.ply')) if not os.path.exists(os.path.join(register_dir_, filebase + 'cloth.registered.ply')): registered_mesh = trimesh.Trimesh(outer_vertices[i].detach().cpu().numpy().astype(np.float64), smpl_faces, process=False) registered_mesh.export(os.path.join(register_dir_, filebase + 'cloth.registered.ply')) else: # Evaluate registered mesh gt_smpl_mesh = data['points.minimal_smpl_vertices'].to(device) gt_smpld_mesh = data['points.smpl_vertices'].to(device) if inner_vertices is None: # if vertices are None, we assume they already exist due to previous runs inner_vertices = [] outer_vertices = [] for i, idx in enumerate(idxs): model_dict = dataset.get_model_dict(idx) subset = model_dict['subset'] subject = model_dict['subject'] sequence = model_dict['sequence'] filebase = os.path.basename(model_dict['data_path'])[:-4] folder_name = os.path.join(subset, subject, sequence) register_dir_ = os.path.join(register_dir, folder_name) # registered_mesh = Mesh(filename=os.path.join(register_dir_, filebase + 'minimal.registered.ply')) registered_mesh = trimesh.load(os.path.join(register_dir_, filebase + 'minimal.registered.ply'), process=False) registered_v = torch.tensor(registered_mesh.vertices.astype(np.float32), requires_grad=False, device=device) inner_vertices.append(registered_v) # registered_mesh = Mesh(filename=os.path.join(register_dir_, filebase + 'cloth.registered.ply')) registered_mesh = trimesh.load(os.path.join(register_dir_, filebase + 'cloth.registered.ply'), process=False) registered_v = torch.tensor(registered_mesh.vertices.astype(np.float32), requires_grad=False, device=device) outer_vertices.append(registered_v) inner_vertices = torch.stack(inner_vertices, dim=0) outer_vertices = torch.stack(outer_vertices, dim=0) inner_dist = torch.norm(gt_smpl_mesh - inner_vertices, dim=2).mean(-1) outer_dist = torch.norm(gt_smpld_mesh - outer_vertices, dim=2).mean(-1) for i, idx in enumerate(idxs): model_dict = dataset.get_model_dict(idx) subset = model_dict['subset'] subject = model_dict['subject'] sequence = model_dict['sequence'] filebase = os.path.basename(model_dict['data_path'])[:-4] folder_name = os.path.join(subset, subject, sequence) register_dir_ = os.path.join(register_dir, folder_name) if not os.path.exists(register_dir_): os.makedirs(register_dir_) logger.info('Inner distance for input {}: {} cm'.format(filebase, inner_dist[i].item())) logger.info('Outer distance for input {}: {} cm'.format(filebase, outer_dist[i].item())) if not os.path.exists(os.path.join(register_dir_, filebase + 'minimal.registered.ply')): registered_mesh = trimesh.Trimesh(inner_vertices[i].detach().cpu().numpy().astype(np.float64), smpl_faces, process=False) registered_mesh.export(os.path.join(register_dir_, filebase + 'minimal.registered.ply')) if not os.path.exists(os.path.join(register_dir_, filebase + 'cloth.registered.ply')): registered_mesh = trimesh.Trimesh(outer_vertices[i].detach().cpu().numpy().astype(np.float64), smpl_faces, process=False) registered_mesh.export(os.path.join(register_dir_, filebase + 'cloth.registered.ply')) inner_dists.extend(inner_dist.detach().cpu().numpy()) outer_dists.extend(outer_dist.detach().cpu().numpy()) logger.info('Mean inner distance: {} cm'.format(np.mean(inner_dists))) logger.info('Mean outer distance: {} cm'.format(np.mean(outer_dists)))
out_dir = cfg['training']['out_dir'] batch_size = cfg['training']['batch_size'] backup_every = cfg['training']['backup_every'] exit_after = args.exit_after model_selection_metric = cfg['training']['model_selection_metric'] if cfg['training']['model_selection_mode'] == 'maximize': model_selection_sign = 1 elif cfg['training']['model_selection_mode'] == 'minimize': model_selection_sign = -1 else: raise ValueError('model_selection_mode must be ' 'either maximize or minimize.') # Dataset train_dataset = config.get_dataset('train', cfg) val_dataset = config.get_dataset('val', cfg) uda_dataset = config.get_dataset( 'train', cfg) # for testing uda discriminator performance if args.benchmark_mode: num_workers = 0 else: num_workers = 24 train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, num_workers=num_workers, shuffle=True, collate_fn=data.collate_remove_none, worker_init_fn=data.worker_init_fn)