-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.py
executable file
·132 lines (110 loc) · 5.42 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import argparse
import os
import random
import numpy as np
import torch
from scipy.interpolate import interp1d
from torch.backends import cudnn
def parse_args():
description = 'Pytorch Implementation of \'Weakly-supervised Temporal Action Localization by Uncertainty Modeling\''
parser = argparse.ArgumentParser(description=description)
parser.add_argument('--data_path', type=str, default='/data')
parser.add_argument('--save_path', type=str, default='result')
parser.add_argument('--alpha', type=float, default=0.0005)
parser.add_argument('--beta', type=float, default=1.0)
parser.add_argument('--magnitude', type=int, default=100)
parser.add_argument('--r_act', type=int, default=9)
parser.add_argument('--r_bkg', type=int, default=4)
parser.add_argument('--act_th', type=float, default=0.2, help='threshold for action score')
parser.add_argument('--iou_th', type=float, default=0.6, help='threshold for NMS IoU')
parser.add_argument('--seg_th', type=str, default='np.arange(0.0, 0.25, 0.025)',
help='threshold for candidate segments')
parser.add_argument('--mag_th', type=str, default='np.arange(0.4, 0.625, 0.025)',
help='threshold for candidate actions')
parser.add_argument('--data_name', type=str, default='thumos14',
choices=['thumos14', 'activitynet1.2', 'activitynet1.3'])
parser.add_argument('--num_segments', type=int, default=750)
parser.add_argument('--scale', type=int, default=24)
parser.add_argument('--fps', type=int, default=16)
parser.add_argument('--sampling_frames', type=int, default=25)
parser.add_argument('--lr', type=float, default=0.0001)
parser.add_argument('--decay', type=float, default=0.0005, help='weight decay value for Adam')
parser.add_argument('--num_iter', type=int, default=10000)
parser.add_argument('--eval_iter', type=int, default=100)
parser.add_argument('--batch_size', type=int, default=16)
parser.add_argument('--num_workers', type=int, default=8)
parser.add_argument('--seed', type=int, default=-1, help='random seed (-1 for no manual seed)')
parser.add_argument('--model_file', type=str, default=None, help='the path of pre-trained model file')
return init_args(parser.parse_args())
def init_args(args):
if not os.path.exists(args.save_path):
os.makedirs(args.save_path)
if args.seed >= 0:
torch.manual_seed(args.seed)
np.random.seed(args.seed)
torch.cuda.manual_seed_all(args.seed)
random.seed(args.seed)
cudnn.deterministic = True
cudnn.benchmark = False
args.worker_init_fn = np.random.seed(args.seed)
else:
args.worker_init_fn = None
args.seg_th = eval(args.seg_th)
args.mag_th = eval(args.mag_th)
args.map_th = np.linspace(0.1, 0.7, 7) if args.data_name == 'thumos14' else np.linspace(0.5, 0.95, 10)
return args
def upgrade_resolution(arr, scale):
x = np.arange(0, arr.shape[0])
f = interp1d(x, arr, kind='linear', axis=0, fill_value='extrapolate')
scale_x = np.arange(0, arr.shape[0], 1 / scale)
up_scale = f(scale_x)
return up_scale
def get_proposal(seg_list, seg_score, act_score, c_pred, scale, v_len, fps, sampling_frames, num_segments,
_lambda=0.25, gamma=0.2):
t_factor = (fps * v_len) / (scale * num_segments * sampling_frames)
temp = []
for i in range(len(seg_list)):
c_temp = []
temp_list = np.array(seg_list[i])[0]
if temp_list.any():
# obtain the multi action temporal regions
temp_regions = grouping(temp_list)
for j in range(len(temp_regions)):
len_proposal = len(temp_regions[j])
# omit single frame
if len_proposal < 2:
continue
inner_score = np.mean(seg_score[temp_regions[j], i])
outer_s = max(0, int(temp_regions[j][0] - _lambda * len_proposal))
outer_e = min(int(seg_score.shape[0] - 1), int(temp_regions[j][-1] + _lambda * len_proposal))
outer_temp_list = list(range(outer_s, int(temp_regions[j][0]))) + list(
range(int(temp_regions[j][-1] + 1), outer_e + 1))
if len(outer_temp_list) == 0:
outer_score = 0
else:
outer_score = np.mean(seg_score[outer_temp_list, i])
# obtain the proposal
c_score = inner_score - outer_score + gamma * act_score[c_pred[i]]
t_start = temp_regions[j][0] * t_factor
t_end = (temp_regions[j][-1] + 1) * t_factor
c_temp.append([c_pred[i], t_start, t_end, c_score])
temp.append(c_temp)
return temp
def result2json(result, class_dict):
result_file = []
for key, value in result.items():
for line in value:
result_file.append({'label': class_dict[key], 'score': line[-1], 'segment': [line[0], line[1]]})
return result_file
def grouping(arr):
return np.split(arr, np.where(np.diff(arr) != 1)[0] + 1)
def minmax_norm(act_map, min_val=None, max_val=None):
if min_val is None or max_val is None:
min_val, max_val = torch.aminmax(act_map, dim=0, keepdim=True)
min_val, max_val = torch.relu(min_val), torch.relu(max_val)
delta = max_val - min_val
delta[delta <= 0] = 1
ret = (act_map - min_val) / delta
ret[ret > 1] = 1
ret[ret < 0] = 0
return ret