def update(self, batch_id, data, outputs): """update metrics during each iter """ labels = data[2] clip_ids = data[3] # gather mulit card, results of following process in each card is the same. if self.world_size > 1: outputs = _all_gather(outputs, self.world_size) labels = _all_gather(labels, self.world_size) clip_ids = _all_gather(clip_ids, self.world_size) # to numpy preds = outputs.numpy() labels = labels.numpy().astype("int64") clip_ids = clip_ids.numpy() # preds ensemble for ind in range(preds.shape[0]): vid_id = int(clip_ids[ind]) // self.num_clips ts_idx = int(clip_ids[ind]) % self.num_clips if vid_id not in self.clip_count: self.clip_count[vid_id] = [] if ts_idx in self.clip_count[vid_id]: logger.info( "[TEST] Passed!! read video {} clip index {} / {} repeatedly." .format(vid_id, ts_idx, clip_ids[ind])) else: self.clip_count[vid_id].append(ts_idx) self.video_preds[vid_id] += preds[ind] # ensemble method: sum if self.video_labels[vid_id].sum() > 0: assert self.video_labels[vid_id] == labels[ind] self.video_labels[vid_id] = labels[ind] if batch_id % self.log_interval == 0: logger.info("[TEST] Processing batch {}/{} ...".format( batch_id, self.data_size // (self.batch_size * self.world_size)))
def test_slowfast(args): config = parse_config(args.config_file) test_config = merge_configs(config, 'test', vars(args)) print_configs(test_config, "Test") if not args.use_gpu: place = fluid.CPUPlace() elif not args.use_data_parallel: place = fluid.CUDAPlace(0) else: place = fluid.CUDAPlace(fluid.dygraph.parallel.Env().dev_id) _nranks = ParallelEnv().nranks # num gpu bs_single = int(test_config.TEST.batch_size / _nranks) # batch_size of each gpu with fluid.dygraph.guard(place): #build model slowfast = SlowFast(cfg=test_config, num_classes=400) if args.weights: assert os.path.exists(args.weights + '.pdparams'),\ "Given weight dir {} not exist.".format(args.weights) logger.info('load test weights from {}'.format(args.weights)) model_dict, _ = fluid.load_dygraph(args.weights) slowfast.set_dict(model_dict) if args.use_data_parallel: strategy = fluid.dygraph.parallel.prepare_context() slowfast = fluid.dygraph.parallel.DataParallel(slowfast, strategy) #create reader test_data = KineticsDataset(mode="test", cfg=test_config) test_sampler = DistributedBatchSampler(test_data, batch_size=bs_single, shuffle=False, drop_last=False) test_loader = DataLoader(test_data, batch_sampler=test_sampler, places=place, feed_list=None, num_workers=8, return_list=True) # start eval num_ensemble_views = test_config.TEST.num_ensemble_views num_spatial_crops = test_config.TEST.num_spatial_crops num_cls = test_config.MODEL.num_classes num_clips = num_ensemble_views * num_spatial_crops num_videos = len(test_data) // num_clips video_preds = np.zeros((num_videos, num_cls)) video_labels = np.zeros((num_videos, 1), dtype="int64") clip_count = {} print( "[EVAL] eval start, number of videos {}, total number of clips {}". format(num_videos, num_clips * num_videos)) slowfast.eval() for batch_id, data in enumerate(test_loader): # call net model_inputs = [data[0], data[1]] preds = slowfast(model_inputs, training=False) labels = data[2] clip_ids = data[3] # gather mulit card, results of following process in each card is the same. if _nranks > 1: preds = _all_gather(preds, _nranks) labels = _all_gather(labels, _nranks) clip_ids = _all_gather(clip_ids, _nranks) # to numpy preds = preds.numpy() labels = labels.numpy().astype("int64") clip_ids = clip_ids.numpy() # preds ensemble for ind in range(preds.shape[0]): vid_id = int(clip_ids[ind]) // num_clips ts_idx = int(clip_ids[ind]) % num_clips if vid_id not in clip_count: clip_count[vid_id] = [] if ts_idx in clip_count[vid_id]: print( "[EVAL] Passed!! read video {} clip index {} / {} repeatedly." .format(vid_id, ts_idx, clip_ids[ind])) else: clip_count[vid_id].append(ts_idx) video_preds[vid_id] += preds[ind] # ensemble method: sum if video_labels[vid_id].sum() > 0: assert video_labels[vid_id] == labels[ind] video_labels[vid_id] = labels[ind] if batch_id % args.log_interval == 0: print("[EVAL] Processing batch {}/{} ...".format( batch_id, len(test_data) // test_config.TEST.batch_size)) # check clip index of each video for key in clip_count.keys(): if len(clip_count[key]) != num_clips or sum( clip_count[key]) != num_clips * (num_clips - 1) / 2: print( "[EVAL] Warning!! video [{}] clip count [{}] not match number clips {}" .format(key, clip_count[key], num_clips)) video_preds = to_variable(video_preds) video_labels = to_variable(video_labels) acc_top1 = fluid.layers.accuracy(input=video_preds, label=video_labels, k=1) acc_top5 = fluid.layers.accuracy(input=video_preds, label=video_labels, k=5) print('[EVAL] eval finished, avg_acc1= {}, avg_acc5= {} '.format( acc_top1.numpy(), acc_top5.numpy()))
def infer_slowfast(args): config = parse_config(args.config_file) infer_config = merge_configs(config, 'infer', vars(args)) print_configs(infer_config, "Infer") if not os.path.isdir(infer_config.INFER.save_path): os.makedirs(infer_config.INFER.save_path) if not args.use_gpu: place = fluid.CPUPlace() elif not args.use_data_parallel: place = fluid.CUDAPlace(0) else: place = fluid.CUDAPlace(fluid.dygraph.parallel.Env().dev_id) _nranks = ParallelEnv().nranks # num gpu bs_single = int(infer_config.INFER.batch_size / _nranks) # batch_size of each gpu with fluid.dygraph.guard(place): #build model slowfast = SlowFast(cfg=infer_config, num_classes=400) if args.weights: assert os.path.exists(args.weights + '.pdparams'),\ "Given weight dir {} not exist.".format(args.weights) logger.info('load test weights from {}'.format(args.weights)) model_dict, _ = fluid.load_dygraph(args.weights) slowfast.set_dict(model_dict) if args.use_data_parallel: strategy = fluid.dygraph.parallel.prepare_context() slowfast = fluid.dygraph.parallel.DataParallel( slowfast, strategy, find_unused_parameters=False) #create reader infer_data = KineticsDataset(mode="infer", cfg=infer_config) infer_sampler = DistributedBatchSampler(infer_data, batch_size=bs_single, shuffle=False, drop_last=False) infer_loader = DataLoader(infer_data, batch_sampler=infer_sampler, places=place, feed_list=None, num_workers=0, return_list=True) # start infer num_ensemble_views = infer_config.INFER.num_ensemble_views num_spatial_crops = infer_config.INFER.num_spatial_crops num_cls = infer_config.MODEL.num_classes num_clips = num_ensemble_views * num_spatial_crops num_videos = len(infer_data) // num_clips video_preds = np.zeros((num_videos, num_cls)) clip_count = {} video_paths = [] with open(infer_config.INFER.filelist, "r") as f: for path in f.read().splitlines(): video_paths.append(path) print( "[INFER] infer start, number of videos {}, number of clips {}, total number of clips {}" .format(num_videos, num_clips, num_clips * num_videos)) slowfast.eval() for batch_id, data in enumerate(infer_loader): # call net model_inputs = [data[0], data[1]] preds = slowfast(model_inputs, training=False) clip_ids = data[3] # gather mulit card, results of following process in each card is the same. if _nranks > 1: preds = _all_gather(preds, _nranks) clip_ids = _all_gather(clip_ids, _nranks) # to numpy preds = preds.numpy() clip_ids = clip_ids.numpy() # preds ensemble for ind in range(preds.shape[0]): vid_id = int(clip_ids[ind]) // num_clips ts_idx = int(clip_ids[ind]) % num_clips if vid_id not in clip_count: clip_count[vid_id] = [] if ts_idx in clip_count[vid_id]: print( "[INFER] Passed!! read video {} clip index {} / {} repeatedly." .format(vid_id, ts_idx, clip_ids[ind])) else: clip_count[vid_id].append(ts_idx) video_preds[vid_id] += preds[ind] # ensemble method: sum if batch_id % args.log_interval == 0: print("[INFER] Processing batch {}/{} ...".format( batch_id, len(infer_data) // infer_config.INFER.batch_size)) # check clip index of each video for key in clip_count.keys(): if len(clip_count[key]) != num_clips or sum( clip_count[key]) != num_clips * (num_clips - 1) / 2: print( "[INFER] Warning!! video [{}] clip count [{}] not match number clips {}" .format(key, clip_count[key], num_clips)) res_list = [] for j in range(video_preds.shape[0]): pred = to_variable(video_preds[j] / num_clips) #mean prob video_path = video_paths[j] pred = to_variable(pred) top1_values, top1_indices = fluid.layers.topk(pred, k=1) top5_values, top5_indices = fluid.layers.topk(pred, k=5) top1_values = top1_values.numpy().astype("float64")[0] top1_indices = int(top1_indices.numpy()[0]) top5_values = list(top5_values.numpy().astype("float64")) top5_indices = [int(item) for item in top5_indices.numpy() ] #np.int is not JSON serializable print( "[INFER] video id [{}], top1 value {}, top1 indices {}".format( video_path, top1_values, top1_indices)) print( "[INFER] video id [{}], top5 value {}, top5 indices {}".format( video_path, top5_values, top5_indices)) save_dict = { 'video_id': video_path, 'top1_values': top1_values, 'top1_indices': top1_indices, 'top5_values': top5_values, 'top5_indices': top5_indices } res_list.append(save_dict) with open( os.path.join(infer_config.INFER.save_path, 'result' + '.json'), 'w') as f: json.dump(res_list, f) print('[INFER] infer finished, results saved in {}'.format( infer_config.INFER.save_path))