Darknsu commited on
Commit
e0e832b
·
verified ·
1 Parent(s): e0fde25

Upload 14 files

Browse files
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ data/Poppins[[:space:]]Black[[:space:]]Italic[[:space:]]900.ttf filter=lfs diff=lfs merge=lfs -text
37
+ data/Poppins[[:space:]]ExtraBold[[:space:]]Italic[[:space:]]800.ttf filter=lfs diff=lfs merge=lfs -text
Evaluation/__pycache__/eval_detection_gentime.cpython-310.pyc ADDED
Binary file (7.8 kB). View file
 
Evaluation/__pycache__/utils.cpython-310.pyc ADDED
Binary file (2.49 kB). View file
 
Evaluation/eval_detection_gentime.py ADDED
@@ -0,0 +1,566 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ #import urllib.request, urllib.error, urllib.parse
3
+
4
+ import numpy as np
5
+ import pandas as pd
6
+
7
+ from utils import get_blocked_videos
8
+ from utils import interpolated_prec_rec
9
+ from utils import segment_iou
10
+
11
+ class ANETdetection(object):
12
+
13
+ GROUND_TRUTH_FIELDS = ['database']#, 'taxonomy', 'version']
14
+ PREDICTION_FIELDS = ['results', 'version', 'external_data']
15
+
16
+ def __init__(self, opt, ground_truth_filename=None, prediction_filename=None,
17
+ ground_truth_fields=GROUND_TRUTH_FIELDS,
18
+ prediction_fields=PREDICTION_FIELDS,
19
+ tiou_thresholds=np.linspace(0.5, 0.95, 10),
20
+ subset='validation', verbose=False,
21
+ check_status=True):
22
+ if not ground_truth_filename:
23
+ raise IOError('Please input a valid ground truth file.')
24
+ if not prediction_filename:
25
+ raise IOError('Please input a valid prediction file.')
26
+ self.subset = subset
27
+ self.tiou_thresholds = tiou_thresholds
28
+ self.verbose = verbose
29
+ self.gt_fields = ground_truth_fields
30
+ self.pred_fields = prediction_fields
31
+ self.ap = None
32
+ self.tdiff = None
33
+ self.check_status = check_status
34
+ self.num_class = opt["num_of_class"]
35
+ # Retrieve blocked videos from server.
36
+ if self.check_status:
37
+ self.blocked_videos = get_blocked_videos()
38
+ else:
39
+ self.blocked_videos = list()
40
+ # Import ground truth and predictions.
41
+ self.ground_truth, self.activity_index, cidx = self._import_ground_truth(
42
+ ground_truth_filename)
43
+ self.prediction = self._import_prediction(prediction_filename, cidx)
44
+
45
+ if self.verbose:
46
+ print('[INIT] Loaded annotations from {} subset.'.format(subset))
47
+ nr_gt = len(self.ground_truth)
48
+ print('\tNumber of ground truth instances: {}'.format(nr_gt))
49
+ nr_pred = len(self.prediction)
50
+ print('\tNumber of predictions: {}'.format(nr_pred))
51
+ print('\tFixed threshold for tiou score: {}'.format(self.tiou_thresholds))
52
+
53
+ def _import_ground_truth(self, ground_truth_filename):
54
+ """Reads ground truth file, checks if it is well formatted, and returns
55
+ the ground truth instances and the activity classes.
56
+
57
+ Parameters
58
+ ----------
59
+ ground_truth_filename : str
60
+ Full path to the ground truth json file.
61
+
62
+ Outputs
63
+ -------
64
+ ground_truth : df
65
+ Data frame containing the ground truth instances.
66
+ activity_index : dict
67
+ Dictionary containing class index.
68
+ """
69
+ with open(ground_truth_filename, 'r') as fobj:
70
+ data = json.load(fobj)
71
+ # Checking format
72
+ if not all([field in list(data.keys()) for field in self.gt_fields]):
73
+ raise IOError('Please input a valid ground truth file.')
74
+
75
+ # Read ground truth data.
76
+ activity_index, cidx = {}, 0
77
+
78
+ video_lst, t_start_lst, t_end_lst, label_lst = [], [], [], []
79
+ for videoid, v in data['database'].items():
80
+ if self.subset not in v['subset']:
81
+ continue
82
+
83
+ for ann in v['annotations']:
84
+ if ann['label'] not in activity_index:
85
+ activity_index[ann['label']] = cidx
86
+ cidx += 1
87
+ video_lst.append(videoid)
88
+ t_start_lst.append(ann['segment'][0])
89
+ t_end_lst.append(ann['segment'][1])
90
+ label_lst.append(activity_index[ann['label']])
91
+
92
+ ground_truth = pd.DataFrame({'video-id': video_lst,
93
+ 't-start': t_start_lst,
94
+ 't-end': t_end_lst,
95
+ 'label': label_lst})
96
+
97
+ return ground_truth, activity_index, cidx
98
+
99
+ def _import_prediction(self, prediction_filename, cidx):
100
+ """Reads prediction file, checks if it is well formatted, and returns
101
+ the prediction instances.
102
+
103
+ Parameters
104
+ ----------
105
+ prediction_filename : str
106
+ Full path to the prediction json file.
107
+
108
+ Outputs
109
+ -------
110
+ prediction : df
111
+ Data frame containing the prediction instances.
112
+ """
113
+ with open(prediction_filename, 'r') as fobj:
114
+ data = json.load(fobj)
115
+ # Checking format...
116
+ if not all([field in list(data.keys()) for field in self.pred_fields]):
117
+ raise IOError('Please input a valid prediction file.')
118
+
119
+ # Read predicitons.
120
+ video_lst, t_start_lst, t_end_lst = [], [], []
121
+ label_lst, score_lst = [], []
122
+ gentime_lst = []
123
+ for videoid, v in data['results'].items():
124
+ if videoid in self.blocked_videos:
125
+ continue
126
+ for result in v:
127
+ if result['label'] not in self.activity_index.keys():
128
+ continue
129
+
130
+ label = self.activity_index[result['label']]
131
+ video_lst.append(videoid)
132
+ t_start_lst.append(result['segment'][0])
133
+ t_end_lst.append(result['segment'][1])
134
+ label_lst.append(label)
135
+ score_lst.append(result['score'])
136
+ gentime_lst.append(result['gentime'])
137
+
138
+ prediction = pd.DataFrame({'video-id': video_lst,
139
+ 't-start': t_start_lst,
140
+ 't-end': t_end_lst,
141
+ 'label': label_lst,
142
+ 'score': score_lst,
143
+ 'gentime': gentime_lst})
144
+ return prediction
145
+
146
+ def wrapper_compute_average_precision(self):
147
+ """Computes average precision for each class in the subset.
148
+ """
149
+ ap = np.zeros((len(self.tiou_thresholds), len(list(self.activity_index.items()))))
150
+ tdiff = np.zeros((len(self.tiou_thresholds), len(list(self.activity_index.items()))))
151
+ cnt_tp = np.zeros((len(self.tiou_thresholds), len(list(self.activity_index.items()))))
152
+ for activity, cidx in self.activity_index.items():
153
+ gt_idx = self.ground_truth['label'] == cidx
154
+ pred_idx = self.prediction['label'] == cidx
155
+ ap[:,cidx], tdiff[:,cidx], cnt_tp[:,cidx] = compute_average_precision_detection(
156
+ self.ground_truth.loc[gt_idx].reset_index(drop=True),
157
+ self.prediction.loc[pred_idx].reset_index(drop=True),
158
+ tiou_thresholds=self.tiou_thresholds)
159
+
160
+ sum_tdiff = np.sum(tdiff, axis=1)
161
+ total_tp = np.sum(cnt_tp, axis=1)
162
+ final_tdiff = sum_tdiff/total_tp
163
+
164
+ return ap, final_tdiff
165
+
166
+ def evaluate(self):
167
+ """Evaluates a prediction file. For the detection task we measure the
168
+ interpolated mean average precision to measure the performance of a
169
+ method.
170
+ """
171
+ self.ap, self.tdiff = self.wrapper_compute_average_precision()
172
+ self.mAP = self.ap.mean(axis=1)
173
+ if self.verbose:
174
+ print('[RESULTS] Performance on ActivityNet detection task.')
175
+ print('\tAverage-mAP: {}'.format(self.mAP.mean()))
176
+ print('\tAverage-time diff: {}'.format(self.tdiff.mean()))
177
+
178
+ def compute_average_precision_detection(ground_truth, prediction, tiou_thresholds=np.linspace(0.5, 0.95, 10)):
179
+ """Compute average precision (detection task) between ground truth and
180
+ predictions data frames. If multiple predictions occurs for the same
181
+ predicted segment, only the one with highest score is matches as
182
+ true positive. This code is greatly inspired by Pascal VOC devkit.
183
+
184
+ Parameters
185
+ ----------
186
+ ground_truth : df
187
+ Data frame containing the ground truth instances.
188
+ Required fields: ['video-id', 't-start', 't-end']
189
+ prediction : df
190
+ Data frame containing the prediction instances.
191
+ Required fields: ['video-id, 't-start', 't-end', 'score']
192
+ tiou_thresholds : 1darray, optional
193
+ Temporal intersection over union threshold.
194
+
195
+ Outputs
196
+ -------
197
+ ap : float
198
+ Average precision score.
199
+ """
200
+ npos = float(len(ground_truth))
201
+ lock_gt = np.ones((len(tiou_thresholds),len(ground_truth))) * -1
202
+
203
+ # Sort predictions by decreasing score order.
204
+ sort_idx = prediction['score'].values.argsort()[::-1]
205
+ prediction = prediction.loc[sort_idx].reset_index(drop=True)
206
+
207
+ # Initialize true positive and false positive vectors.
208
+ tp = np.zeros((len(tiou_thresholds), len(prediction)))
209
+ fp = np.zeros((len(tiou_thresholds), len(prediction)))
210
+ timediff = np.zeros((len(tiou_thresholds), len(prediction)))
211
+
212
+ # Adaptation to query faster
213
+ ground_truth_gbvn = ground_truth.groupby('video-id')
214
+
215
+ # Assigning true positive to truly grount truth instances.
216
+ for idx, this_pred in prediction.iterrows():
217
+
218
+ try:
219
+ # Check if there is at least one ground truth in the video associated.
220
+ ground_truth_videoid = ground_truth_gbvn.get_group(this_pred['video-id'])
221
+ except Exception as e:
222
+ fp[:, idx] = 1
223
+ continue
224
+
225
+ this_gt = ground_truth_videoid.reset_index()
226
+ tiou_arr = segment_iou(this_pred[['t-start', 't-end']].values,
227
+ this_gt[['t-start', 't-end']].values)
228
+ gentime_pred_arr= this_pred['gentime']
229
+ gentime_gt_arr = this_gt['t-end'].values
230
+ tiou_sorted_idx = tiou_arr.argsort()[::-1]
231
+ for tidx, tiou_thr in enumerate(tiou_thresholds):
232
+ for jdx in tiou_sorted_idx:
233
+ if tiou_arr[jdx] < tiou_thr:
234
+ fp[tidx, idx] = 1
235
+ break
236
+ if lock_gt[tidx, this_gt.loc[jdx]['index']] >= 0:
237
+ continue
238
+ # Assign as true positive after the filters above.
239
+ tp[tidx, idx] = 1
240
+ timediff[tidx, idx]=(gentime_pred_arr-gentime_gt_arr[jdx])#/len_gt_arr[jdx]
241
+ lock_gt[tidx, this_gt.loc[jdx]['index']] = idx
242
+ break
243
+
244
+ if fp[tidx, idx] == 0 and tp[tidx, idx] == 0:
245
+ fp[tidx, idx] = 1
246
+
247
+ ap = np.zeros(len(tiou_thresholds))
248
+ tdiff = np.zeros(len(tiou_thresholds))
249
+ cnt_tp = np.zeros(len(tiou_thresholds))
250
+
251
+ for tidx in range(len(tiou_thresholds)):
252
+ # Computing prec-rec
253
+ this_tp = np.cumsum(tp[tidx,:]).astype(float)
254
+ this_fp = np.cumsum(fp[tidx,:]).astype(float)
255
+
256
+ # print(this_tp, npos)
257
+ rec = this_tp / npos
258
+ prec = this_tp / (this_tp + this_fp)
259
+ # print('###', rec, prec)
260
+ ap[tidx] = interpolated_prec_rec(prec, rec)
261
+ this_tdiff=np.cumsum(timediff[tidx,:]).astype(float)
262
+ if len(this_tdiff)==0:
263
+ continue
264
+ tdiff[tidx]=this_tdiff[-1]# / max(1,this_tp[-1])
265
+ cnt_tp[tidx]=this_tp[-1]
266
+
267
+ return ap,tdiff, cnt_tp
268
+
269
+
270
+
271
+
272
+
273
+ # import json
274
+ # #import urllib.request, urllib.error, urllib.parse
275
+
276
+ # import numpy as np
277
+ # import pandas as pd
278
+
279
+ # from utils import get_blocked_videos
280
+ # from utils import interpolated_prec_rec
281
+ # from utils import segment_iou
282
+
283
+ # class ANETdetection(object):
284
+
285
+ # GROUND_TRUTH_FIELDS = ['database']#, 'taxonomy', 'version']
286
+ # PREDICTION_FIELDS = ['results', 'version', 'external_data']
287
+
288
+ # def __init__(self, opt, ground_truth_filename=None, prediction_filename=None,
289
+ # ground_truth_fields=GROUND_TRUTH_FIELDS,
290
+ # prediction_fields=PREDICTION_FIELDS,
291
+ # tiou_thresholds=np.linspace(0.5, 0.95, 10),
292
+ # subset='validation', verbose=False,
293
+ # check_status=True):
294
+ # if not ground_truth_filename:
295
+ # raise IOError('Please input a valid ground truth file.')
296
+ # if not prediction_filename:
297
+ # raise IOError('Please input a valid prediction file.')
298
+ # self.subset = subset
299
+ # self.tiou_thresholds = tiou_thresholds
300
+ # self.verbose = verbose
301
+ # self.gt_fields = ground_truth_fields
302
+ # self.pred_fields = prediction_fields
303
+ # self.ap = None
304
+ # self.tdiff = None
305
+ # self.check_status = check_status
306
+ # self.num_class = opt["num_of_class"]
307
+ # # Retrieve blocked videos from server.
308
+ # if self.check_status:
309
+ # self.blocked_videos = get_blocked_videos()
310
+ # else:
311
+ # self.blocked_videos = list()
312
+ # # Import ground truth and predictions.
313
+ # self.ground_truth, self.activity_index, cidx = self._import_ground_truth(
314
+ # ground_truth_filename)
315
+ # self.prediction = self._import_prediction(prediction_filename, cidx)
316
+
317
+ # if self.verbose:
318
+ # print('[INIT] Loaded annotations from {} subset.'.format(subset))
319
+ # nr_gt = len(self.ground_truth)
320
+ # print('\tNumber of ground truth instances: {}'.format(nr_gt))
321
+ # nr_pred = len(self.prediction)
322
+ # print('\tNumber of predictions: {}'.format(nr_pred))
323
+ # print('\tFixed threshold for tiou score: {}'.format(self.tiou_thresholds))
324
+
325
+ # def _import_ground_truth(self, ground_truth_filename):
326
+ # """Reads ground truth file, checks if it is well formatted, and returns
327
+ # the ground truth instances and the activity classes.
328
+
329
+ # Parameters
330
+ # ----------
331
+ # ground_truth_filename : str
332
+ # Full path to the ground truth json file.
333
+
334
+ # Outputs
335
+ # -------
336
+ # ground_truth : df
337
+ # Data frame containing the ground truth instances.
338
+ # activity_index : dict
339
+ # Dictionary containing class index.
340
+ # """
341
+ # with open(ground_truth_filename, 'r') as fobj:
342
+ # data = json.load(fobj)
343
+ # # Checking format
344
+ # if not all([field in list(data.keys()) for field in self.gt_fields]):
345
+ # raise IOError('Please input a valid ground truth file.')
346
+
347
+ # # Read ground truth data.
348
+ # activity_index, cidx = {}, 0
349
+
350
+ # video_lst, t_start_lst, t_end_lst, label_lst = [], [], [], []
351
+ # for videoid, v in data['database'].items():
352
+ # if self.subset not in v['subset']:
353
+ # continue
354
+
355
+ # for ann in v['annotations']:
356
+ # if ann['label'] not in activity_index:
357
+ # activity_index[ann['label']] = cidx
358
+ # cidx += 1
359
+ # video_lst.append(videoid)
360
+ # t_start_lst.append(ann['segment'][0])
361
+ # t_end_lst.append(ann['segment'][1])
362
+ # label_lst.append(activity_index[ann['label']])
363
+
364
+ # ground_truth = pd.DataFrame({'video-id': video_lst,
365
+ # 't-start': t_start_lst,
366
+ # 't-end': t_end_lst,
367
+ # 'label': label_lst})
368
+
369
+ # return ground_truth, activity_index, cidx
370
+
371
+ # def _import_prediction(self, prediction_filename, cidx):
372
+ # """Reads prediction file, checks if it is well formatted, and returns
373
+ # the prediction instances.
374
+
375
+ # Parameters
376
+ # ----------
377
+ # prediction_filename : str
378
+ # Full path to the prediction json file.
379
+
380
+ # Outputs
381
+ # -------
382
+ # prediction : df
383
+ # Data frame containing the prediction instances.
384
+ # """
385
+ # with open(prediction_filename, 'r') as fobj:
386
+ # data = json.load(fobj)
387
+ # # Checking format...
388
+ # if not all([field in list(data.keys()) for field in self.pred_fields]):
389
+ # raise IOError('Please input a valid prediction file.')
390
+
391
+ # # Read predicitons.
392
+ # video_lst, t_start_lst, t_end_lst = [], [], []
393
+ # label_lst, score_lst = [], []
394
+ # gentime_lst = []
395
+ # for videoid, v in data['results'].items():
396
+ # if videoid in self.blocked_videos:
397
+ # continue
398
+ # for result in v:
399
+ # if result['label'] not in self.activity_index.keys():
400
+ # continue
401
+
402
+ # label = self.activity_index[result['label']]
403
+ # video_lst.append(videoid)
404
+ # t_start_lst.append(result['segment'][0])
405
+ # t_end_lst.append(result['segment'][1])
406
+ # label_lst.append(label)
407
+ # score_lst.append(result['score'])
408
+ # gentime_lst.append(result['gentime'])
409
+
410
+ # prediction = pd.DataFrame({'video-id': video_lst,
411
+ # 't-start': t_start_lst,
412
+ # 't-end': t_end_lst,
413
+ # 'label': label_lst,
414
+ # 'score': score_lst,
415
+ # 'gentime': gentime_lst})
416
+ # return prediction
417
+
418
+ # def wrapper_compute_average_precision(self):
419
+ # """Computes average precision for each class in the subset.
420
+ # """
421
+ # ap = np.zeros((len(self.tiou_thresholds), len(list(self.activity_index.items()))))
422
+ # tdiff = np.zeros((len(self.tiou_thresholds), len(list(self.activity_index.items()))))
423
+ # cnt_tp = np.zeros((len(self.tiou_thresholds), len(list(self.activity_index.items()))))
424
+
425
+ # for activity, cidx in self.activity_index.items():
426
+ # gt_idx = self.ground_truth['label'] == cidx
427
+ # pred_idx = self.prediction['label'] == cidx
428
+ # ap[:,cidx], tdiff[:,cidx], cnt_tp[:,cidx] = compute_average_precision_detection(
429
+ # self.ground_truth.loc[gt_idx].reset_index(drop=True),
430
+ # self.prediction.loc[pred_idx].reset_index(drop=True),
431
+ # tiou_thresholds=self.tiou_thresholds)
432
+
433
+ # sum_tdiff = np.sum(tdiff, axis=1)
434
+ # total_tp = np.sum(cnt_tp, axis=1)
435
+
436
+ # # FIX: Handle division by zero
437
+ # final_tdiff = np.zeros_like(total_tp)
438
+ # valid_mask = total_tp > 0
439
+ # final_tdiff[valid_mask] = sum_tdiff[valid_mask] / total_tp[valid_mask]
440
+ # # For cases where total_tp is 0, keep final_tdiff as 0
441
+
442
+ # return ap, final_tdiff
443
+
444
+ # def evaluate(self):
445
+ # """Evaluates a prediction file. For the detection task we measure the
446
+ # interpolated mean average precision to measure the performance of a
447
+ # method.
448
+ # """
449
+ # self.ap, self.tdiff = self.wrapper_compute_average_precision()
450
+ # self.mAP = self.ap.mean(axis=1)
451
+ # if self.verbose:
452
+ # print('[RESULTS] Performance on ActivityNet detection task.')
453
+ # print('\tAverage-mAP: {}'.format(self.mAP.mean()))
454
+ # print('\tAverage-time diff: {}'.format(self.tdiff.mean()))
455
+
456
+ # def compute_average_precision_detection(ground_truth, prediction, tiou_thresholds=np.linspace(0.5, 0.95, 10)):
457
+ # """Compute average precision (detection task) between ground truth and
458
+ # predictions data frames. If multiple predictions occurs for the same
459
+ # predicted segment, only the one with highest score is matches as
460
+ # true positive. This code is greatly inspired by Pascal VOC devkit.
461
+
462
+ # Parameters
463
+ # ----------
464
+ # ground_truth : df
465
+ # Data frame containing the ground truth instances.
466
+ # Required fields: ['video-id', 't-start', 't-end']
467
+ # prediction : df
468
+ # Data frame containing the prediction instances.
469
+ # Required fields: ['video-id, 't-start', 't-end', 'score']
470
+ # tiou_thresholds : 1darray, optional
471
+ # Temporal intersection over union threshold.
472
+
473
+ # Outputs
474
+ # -------
475
+ # ap : float
476
+ # Average precision score.
477
+ # """
478
+ # npos = float(len(ground_truth))
479
+ # lock_gt = np.ones((len(tiou_thresholds),len(ground_truth))) * -1
480
+
481
+ # # Sort predictions by decreasing score order.
482
+ # sort_idx = prediction['score'].values.argsort()[::-1]
483
+ # prediction = prediction.loc[sort_idx].reset_index(drop=True)
484
+
485
+ # # Initialize true positive and false positive vectors.
486
+ # tp = np.zeros((len(tiou_thresholds), len(prediction)))
487
+ # fp = np.zeros((len(tiou_thresholds), len(prediction)))
488
+ # timediff = np.zeros((len(tiou_thresholds), len(prediction)))
489
+
490
+ # # Adaptation to query faster
491
+ # ground_truth_gbvn = ground_truth.groupby('video-id')
492
+
493
+ # # Assigning true positive to truly grount truth instances.
494
+ # for idx, this_pred in prediction.iterrows():
495
+
496
+ # try:
497
+ # # Check if there is at least one ground truth in the video associated.
498
+ # ground_truth_videoid = ground_truth_gbvn.get_group(this_pred['video-id'])
499
+ # except Exception as e:
500
+ # fp[:, idx] = 1
501
+ # continue
502
+
503
+ # this_gt = ground_truth_videoid.reset_index()
504
+ # tiou_arr = segment_iou(this_pred[['t-start', 't-end']].values,
505
+ # this_gt[['t-start', 't-end']].values)
506
+ # gentime_pred_arr= this_pred['gentime']
507
+ # gentime_gt_arr = this_gt['t-end'].values
508
+ # tiou_sorted_idx = tiou_arr.argsort()[::-1]
509
+ # for tidx, tiou_thr in enumerate(tiou_thresholds):
510
+ # for jdx in tiou_sorted_idx:
511
+ # if tiou_arr[jdx] < tiou_thr:
512
+ # fp[tidx, idx] = 1
513
+ # break
514
+ # if lock_gt[tidx, this_gt.loc[jdx]['index']] >= 0:
515
+ # continue
516
+ # # Assign as true positive after the filters above.
517
+ # tp[tidx, idx] = 1
518
+
519
+ # # FIX: Add safety check for NaN/Inf values
520
+ # time_diff = gentime_pred_arr - gentime_gt_arr[jdx]
521
+ # if np.isfinite(time_diff):
522
+ # timediff[tidx, idx] = time_diff
523
+ # else:
524
+ # timediff[tidx, idx] = 0.0 # Default value for invalid time differences
525
+
526
+ # lock_gt[tidx, this_gt.loc[jdx]['index']] = idx
527
+ # break
528
+
529
+ # if fp[tidx, idx] == 0 and tp[tidx, idx] == 0:
530
+ # fp[tidx, idx] = 1
531
+
532
+ # ap = np.zeros(len(tiou_thresholds))
533
+ # tdiff = np.zeros(len(tiou_thresholds))
534
+ # cnt_tp = np.zeros(len(tiou_thresholds))
535
+
536
+ # for tidx in range(len(tiou_thresholds)):
537
+ # # Computing prec-rec
538
+ # this_tp = np.cumsum(tp[tidx,:]).astype(float)
539
+ # this_fp = np.cumsum(fp[tidx,:]).astype(float)
540
+
541
+ # # Handle edge cases
542
+ # if npos == 0:
543
+ # ap[tidx] = 0.0
544
+ # tdiff[tidx] = 0.0
545
+ # cnt_tp[tidx] = 0.0
546
+ # continue
547
+
548
+ # rec = this_tp / npos
549
+
550
+ # # FIX: Handle division by zero in precision calculation
551
+ # denominator = this_tp + this_fp
552
+ # prec = np.zeros_like(this_tp)
553
+ # valid_mask = denominator > 0
554
+ # prec[valid_mask] = this_tp[valid_mask] / denominator[valid_mask]
555
+
556
+ # ap[tidx] = interpolated_prec_rec(prec, rec)
557
+
558
+ # # FIX: Handle time difference calculation more safely
559
+ # this_tdiff = np.cumsum(timediff[tidx,:]).astype(float)
560
+ # if len(this_tdiff) == 0 or this_tp[-1] == 0:
561
+ # tdiff[tidx] = 0.0
562
+ # else:
563
+ # tdiff[tidx] = this_tdiff[-1]
564
+ # cnt_tp[tidx] = this_tp[-1] if len(this_tp) > 0 else 0.0
565
+
566
+ # return ap, tdiff, cnt_tp
Evaluation/utils.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ #import urllib.request, urllib.error, urllib.parse
3
+
4
+ import numpy as np
5
+
6
+ API = 'http://ec2-52-11-11-89.us-west-2.compute.amazonaws.com/challenge17/api.py'
7
+
8
+ def get_blocked_videos(api=API):
9
+ # api_url = '{}?action=get_blocked'.format(api)
10
+ # req = urllib.request.Request(api_url)
11
+ # response = urllib.request.urlopen(req)
12
+ # return json.loads(response.read())
13
+ return list()
14
+
15
+ def interpolated_prec_rec(prec, rec):
16
+ """Interpolated AP - VOCdevkit from VOC 2011.
17
+ """
18
+ mprec = np.hstack([[0], prec, [0]])
19
+ mrec = np.hstack([[0], rec, [1]])
20
+ for i in range(len(mprec) - 1)[::-1]:
21
+ mprec[i] = max(mprec[i], mprec[i + 1])
22
+ idx = np.where(mrec[1::] != mrec[0:-1])[0] + 1
23
+ ap = np.sum((mrec[idx] - mrec[idx - 1]) * mprec[idx])
24
+ return ap
25
+
26
+ def segment_iou(target_segment, candidate_segments):
27
+ """Compute the temporal intersection over union between a
28
+ target segment and all the test segments.
29
+
30
+ Parameters
31
+ ----------
32
+ target_segment : 1d array
33
+ Temporal target segment containing [starting, ending] times.
34
+ candidate_segments : 2d array
35
+ Temporal candidate segments containing N x [starting, ending] times.
36
+
37
+ Outputs
38
+ -------
39
+ tiou : 1d array
40
+ Temporal intersection over union score of the N's candidate segments.
41
+ """
42
+ tt1 = np.maximum(target_segment[0], candidate_segments[:, 0])
43
+ tt2 = np.minimum(target_segment[1], candidate_segments[:, 1])
44
+ # Intersection including Non-negative overlap score.
45
+ segments_intersection = (tt2 - tt1).clip(0)
46
+ # Segment union.
47
+ segments_union = (candidate_segments[:, 1] - candidate_segments[:, 0]) \
48
+ + (target_segment[1] - target_segment[0]) - segments_intersection
49
+ # Compute overlap as the ratio of the intersection
50
+ # over union of two segments.
51
+ tIoU = segments_intersection.astype(float) / segments_union
52
+ return tIoU
53
+
54
+ def wrapper_segment_iou(target_segments, candidate_segments):
55
+ """Compute intersection over union btw segments
56
+ Parameters
57
+ ----------
58
+ target_segments : ndarray
59
+ 2-dim array in format [m x 2:=[init, end]]
60
+ candidate_segments : ndarray
61
+ 2-dim array in format [n x 2:=[init, end]]
62
+ Outputs
63
+ -------
64
+ tiou : ndarray
65
+ 2-dim array [n x m] with IOU ratio.
66
+ Note: It assumes that candidate-segments are more scarce that target-segments
67
+ """
68
+ if candidate_segments.ndim != 2 or target_segments.ndim != 2:
69
+ raise ValueError('Dimension of arguments is incorrect')
70
+
71
+ n, m = candidate_segments.shape[0], target_segments.shape[0]
72
+ tiou = np.empty((n, m))
73
+ for i in range(m):
74
+ tiou[:, i] = segment_iou(target_segments[i,:], candidate_segments)
75
+
76
+ return tiou
checkpoint/README.md ADDED
@@ -0,0 +1 @@
 
 
1
+ Please put the model files in this folder.
data/Poppins Black Italic 900.ttf ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d56d2b8ff884cfae1b637e73a71f3caf1d16cdb5b4acc123d9cd0b5864ca2567
3
+ size 156916
data/Poppins ExtraBold Italic 800.ttf ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:db8f803d5aaf8e646fd868d0a897ed9997985b88c931bfae3e08c7c8dc2556be
3
+ size 158896
data/egtea_annotations_split1.json ADDED
The diff for this file is too large to render. See raw diff
 
data/egtea_annotations_split2.json ADDED
The diff for this file is too large to render. See raw diff
 
data/egtea_annotations_split3.json ADDED
The diff for this file is too large to render. See raw diff
 
data/egtea_annotations_split4.json ADDED
The diff for this file is too large to render. See raw diff
 
data/test_video_annotations.json ADDED
The diff for this file is too large to render. See raw diff
 
data/thumos14_v2.json ADDED
The diff for this file is too large to render. See raw diff
 
data/thumos14_v2_small.json ADDED
The diff for this file is too large to render. See raw diff