Skip to content

Commit d754cba

Browse files
committed
yeehaw
1 parent 032a50a commit d754cba

8 files changed

+182
-47
lines changed

eval2.py

+74-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import numpy as np
22
import pandas as pd
3+
import matplotlib.pyplot as plt
34
from scipy.interpolate import interp1d
45
import os
56

@@ -119,13 +120,13 @@ def average_recall_vs_nr_proposals(proposals,
119120
recall[ridx, :] = matches.sum(axis=0) / positives.sum()
120121

121122
# Recall is averaged.
122-
recall = recall.mean(axis=0)
123+
avg_recall = recall.mean(axis=0)
123124

124125
# Get the average number of proposals per video.
125126
proposals_per_video = pcn_lst * (
126127
float(proposals.shape[0]) / video_lst.shape[0])
127128

128-
return recall, proposals_per_video
129+
return recall, avg_recall, proposals_per_video
129130

130131

131132
def recall_vs_tiou_thresholds(proposals,
@@ -210,14 +211,80 @@ def recall_vs_tiou_thresholds(proposals,
210211
return recall, tiou_thresholds
211212

212213

214+
def plot_metric(opt,
215+
average_nr_proposals,
216+
average_recall,
217+
recall,
218+
tiou_thresholds=np.linspace(0.5, 1.0, 11)):
219+
220+
fn_size = 14
221+
plt.figure(num=None, figsize=(12, 8))
222+
ax = plt.subplot(1, 1, 1)
223+
224+
colors = [
225+
'k', 'r', 'yellow', 'b', 'c', 'm', 'b', 'pink', 'lawngreen', 'indigo'
226+
]
227+
area_under_curve = np.zeros_like(tiou_thresholds)
228+
for i in range(recall.shape[0]):
229+
area_under_curve[i] = np.trapz(recall[i], average_nr_proposals)
230+
231+
for idx, tiou in enumerate(tiou_thresholds[::2]):
232+
ax.plot(average_nr_proposals,
233+
recall[2 * idx, :],
234+
color=colors[idx + 1],
235+
label="tiou=[" + str(tiou) + "], area=" +
236+
str(int(area_under_curve[2 * idx] * 100) / 100.),
237+
linewidth=4,
238+
linestyle='--',
239+
marker=None)
240+
# Plots Average Recall vs Average number of proposals.
241+
ax.plot(
242+
average_nr_proposals,
243+
average_recall,
244+
color=colors[0],
245+
label="tiou = 0.5:0.05:1.0," + " area=" +
246+
str(int(np.trapz(average_recall, average_nr_proposals) * 100) / 100.),
247+
linewidth=4,
248+
linestyle='-',
249+
marker=None)
250+
251+
handles, labels = ax.get_legend_handles_labels()
252+
ax.legend([handles[-1]] + handles[:-1], [labels[-1]] + labels[:-1],
253+
loc='best')
254+
255+
plt.ylabel('Average Recall', fontsize=fn_size)
256+
plt.xlabel('Average Number of Proposals per Video', fontsize=fn_size)
257+
plt.grid(b=True, which="both")
258+
plt.ylim([0, 1.0])
259+
plt.setp(plt.axes().get_xticklabels(), fontsize=fn_size)
260+
plt.setp(plt.axes().get_yticklabels(), fontsize=fn_size)
261+
#plt.show()
262+
save_path = os.path.join(opt['postprocessed_results_dir'], 'evaluation_result.jpg')
263+
plt.savefig(save_path)
264+
265+
213266
def evaluation_proposal(opt):
214-
bsn_results = pd.read_csv(os.path.join(opt['postprocessed_results_dir'], 'thumos14_results.csv'))
267+
if 'thumos' in opt['dataset']:
268+
bsn_results = pd.read_csv(os.path.join(opt['postprocessed_results_dir'], 'thumos14_results.csv'))
269+
elif 'gymnastics' in opt['dataset']:
270+
bsn_results = pd.read_csv(os.path.join(opt['postprocessed_results_dir'], 'gym_results.csv'))
215271
ground_truth = pd.read_csv(opt['video_info'])
216272

217273
# Computes average recall vs average number of proposals.
218-
average_recall, average_nr_proposals = average_recall_vs_nr_proposals(
274+
recall, average_recall, average_nr_proposals = average_recall_vs_nr_proposals(
219275
bsn_results, ground_truth)
220-
221-
print(average_nr_proposals.shape)
276+
area_under_curve = np.trapz(average_recall, average_nr_proposals)
222277
f = interp1d(average_nr_proposals, average_recall, axis=0)
223-
print(f(50), f(100), f(200), f(500), f(1000))
278+
interp_results = [(k, f(k)) for k in [50, 100, 200, 500, 1000]]
279+
interp_str = ', '.join(['%d: %.4f' % (k, v) for k, v in interp_results])
280+
281+
with open(os.path.join(opt['postprocessed_results_dir'], 'output.txt'), 'w') as f:
282+
f.write('[RESULTS] Performance on %s proposal task.\n' % opt['dataset'])
283+
f.write('\tArea Under the AR vs AN curve: {}%\n'.format(
284+
100. * float(area_under_curve) / average_nr_proposals[-1]))
285+
f.write('Interpolation results: %s\n' % interp_str)
286+
287+
plot_metric(opt, average_nr_proposals, average_recall, recall)
288+
289+
290+

gen_postprocessed_results_jobs.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,21 @@
2727
for pem_results_subdir in os.listdir(pem_results_dir):
2828
counter = int(regex.match(pem_results_subdir).groups()[0])
2929
job = pemrun(find_counter=counter)
30+
job['do_eval_after_postprocessing'] = True
31+
job['num_gpus'] = num_gpus
32+
job['num_cpus'] = 48
33+
job['gb'] = 64
34+
job['time'] = 1
35+
job['module'] = 'Post_processing'
3036

3137
name = job['name']
3238
for ckpt_subdir in os.listdir(os.path.join(pem_results_dir, pem_results_subdir)):
3339
_job = deepcopy(job)
34-
_job['module'] = 'Post_processing'
3540
dirkey = '%s/%s' % (pem_results_subdir, ckpt_subdir)
3641
_job['postprocessed_results_dir'] = os.path.join(postprocessed_results_dir, dirkey)
3742
_job['pem_inference_results_dir'] = os.path.join(pem_results_dir, dirkey)
3843
if 'thumos' in _job['dataset']:
3944
_job['video_info'] = _job['video_info'].replace('Full_Annotation.csv', 'thumos14_test_groundtruth.csv')
4045
_job['name'] = '2019.09.18.%s.%s' % (pem_results_subdir, ckpt_subdir)
41-
_job['num_gpus'] = num_gpus
42-
_job['num_cpus'] = 48
43-
_job['gb'] = 64
44-
_job['time'] = 4
4546

4647
func(_job, counter, email, code_directory)

gen_tem_results_jobs.py

+1-8
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525

2626
for ckpt_subdir in os.listdir(ckpt_directory):
2727
counter = int(regex.match(ckpt_subdir).groups()[0])
28-
if counter not in [195]:
29-
continue
3028

3129
_job = run(find_counter=counter)
3230
_job['num_gpus'] = 8
@@ -39,12 +37,7 @@
3937
_job['checkpoint_path'] = os.path.join(ckpt_directory, ckpt_subdir)
4038
_job['tem_results_subset'] = 'full'
4139
name = _job['name']
42-
for ckpt_epoch in [5, 15, 20]:
43-
if counter == 195:
44-
if ckpt_epoch < 20:
45-
continue
46-
ckpt_epoch = 19
47-
40+
for ckpt_epoch in [5, 8]:
4841
_job['checkpoint_epoch'] = ckpt_epoch
4942
_job['name'] = '%s.ckpt%d' % (name, ckpt_epoch)
5043
print(ckpt_subdir, counter)

opts.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,21 @@ def parse_opt():
4040
# TEM model settings
4141
parser.add_argument('--tem_feat_dim', type=int, default=400)
4242
parser.add_argument('--tem_hidden_dim', type=int, default=512)
43-
parser.add_argument('--tem_nonlinear_factor', type=int, default=0.01)
43+
parser.add_argument('--tem_nonlinear_factor', type=float, default=0.01)
44+
parser.add_argument('--tem_reset_params', action='store_true')
4445

4546
# PEM model settings
4647
parser.add_argument('--pem_feat_dim', type=int, default=32)
4748
parser.add_argument('--pem_hidden_dim', type=int, default=256)
4849

4950
# TEM Training settings
5051
parser.add_argument('--tem_training_lr', type=float, default=0.001)
51-
parser.add_argument('--tem_weight_decay', type=float, default=0.0001)
52-
parser.add_argument('--tem_lr_penalty', type=float, default=0.0)
52+
parser.add_argument('--tem_weight_decay', type=float, default=0.0)
53+
parser.add_argument('--tem_l2_loss', type=float, default=0.005)
5354
parser.add_argument('--tem_epoch', type=int, default=30) # NOTE: was 20
5455
parser.add_argument('--tem_step_size', type=int, default=7)
5556
parser.add_argument('--tem_step_gamma', type=float, default=0.1) # 0.1
57+
parser.add_argument('--tem_lr_milestones', type=str, default='5')
5658
parser.add_argument('--tem_batch_size', type=int, default=16)
5759
parser.add_argument('--tem_match_thres', type=float, default=0.5)
5860
parser.add_argument('--tem_compute_loss_interval', type=float, default=20)
@@ -64,6 +66,7 @@ def parse_opt():
6466
parser.add_argument('--pem_nonlinear_factor', type=int, default=0.1)
6567
parser.add_argument('--pem_training_lr', type=float, default=0.01)
6668
parser.add_argument('--pem_weight_decay', type=float, default=0.00001)
69+
parser.add_argument('--pem_l2_loss', type=float, default=0.000025)
6770
parser.add_argument('--pem_epoch', type=int, default=20)
6871
parser.add_argument('--pem_step_size', type=int, default=10)
6972
parser.add_argument('--pem_step_gamma', type=float, default=0.1)
@@ -100,6 +103,7 @@ def parse_opt():
100103
# Post processing
101104
parser.add_argument('--post_process_top_K', type=int, default=100)
102105
parser.add_argument('--post_process_thread', type=int, default=8)
106+
parser.add_argument('--do_eval_after_postprocessing', action='store_true')
103107
parser.add_argument('--soft_nms_alpha', type=float, default=0.75)
104108
parser.add_argument('--soft_nms_low_thres', type=float, default=0.65)
105109
parser.add_argument('--soft_nms_high_thres', type=float, default=0.9)

pgm.py

+35-20
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,16 @@ def generate_proposals(opt, video_list, video_data):
6565
print('Skipping %s because %s is not a path.' % (video_name, results_path))
6666
skipped_paths.append(results_path)
6767
continue
68+
69+
anno_df_ = anno_df[anno_df.video == video_name]
6870

6971
tdf = pd.read_csv(results_path)
7072
start_scores = tdf.start.values[:]
7173
end_scores = tdf.end.values[:]
72-
frame_list = tdf.frames.values[:]
74+
try:
75+
frame_list = tdf.frames.values[:]
76+
except Exception as e:
77+
frame_list = tdf.frame.values[:]
7378

7479
start_bins = np.zeros(len(start_scores))
7580
start_bins[[0, -1]] = 1
@@ -95,15 +100,14 @@ def generate_proposals(opt, video_list, video_data):
95100
xmin_score_list = []
96101
xmax_list = []
97102
xmax_score_list = []
98-
for index in range(len(start_bins)):
103+
for index in range(len(start_scores)):
99104
if start_bins[index] == 1:
100105
xmin_list.append(int(frame_list[index]))
101106
xmin_score_list.append(start_scores[index])
102107
if end_bins[index] == 1:
103108
xmax_list.append(int(frame_list[index]))
104109
xmax_score_list.append(end_scores[index])
105110

106-
print('Doing new_props')
107111
new_props = []
108112
for ii in range(len(xmax_list)):
109113
if ii % 5000 == 0:
@@ -133,7 +137,6 @@ def generate_proposals(opt, video_list, video_data):
133137
# print('saving preliminary to %s' % path)
134138
# new_df.to_csv(path, index=False)
135139

136-
print('Doing gt max')
137140
if video_dict is not None:
138141
video_info = video_dict[video_name]
139142
video_fps = video_info['fps']
@@ -146,25 +149,29 @@ def generate_proposals(opt, video_list, video_data):
146149

147150
gt_xmins.append(annos[idx]["segment"][0] * video_fps)
148151
gt_xmaxs.append(annos[idx]["segment"][1] * video_fps)
149-
elif anno_df is not None:
150-
gt_xmins = anno_df.startFrame.values[:]
151-
gt_xmaxs = anno_df.endFrame.values[:]
152-
153-
print('GT Xmins and Xmaxs')
152+
elif anno_df_ is not None:
153+
gt_xmins = anno_df_.startFrame.values[:]
154+
gt_xmaxs = anno_df_.endFrame.values[:]
155+
156+
# Ok, so all of these gt_xmins and gt_xmaxs are the same ...
157+
# ... As are the xmin and xmax values in the DFs.
158+
154159
new_iou_list = []
155160
match_xmin_list = []
156161
match_xmax_list = []
157-
print('Doing iou and xmin lists.')
158162
for j in range(len(new_df)):
159163
tmp_new_iou = list(
160-
iou_with_anchors(new_df.xmin.values[j],
161-
new_df.xmax.values[j], gt_xmins, gt_xmaxs))
164+
iou_with_anchors(
165+
new_df.xmin.values[j],
166+
new_df.xmax.values[j],
167+
gt_xmins,
168+
gt_xmaxs)
169+
)
162170
new_iou_list.append(max(tmp_new_iou))
163171
match_xmin_list.append(gt_xmins[tmp_new_iou.index(max(tmp_new_iou))])
164172
match_xmax_list.append(gt_xmaxs[tmp_new_iou.index(max(tmp_new_iou))])
165173

166174
new_ioa_list = []
167-
print('Doing ioa max')
168175
for j in range(len(new_df)):
169176
tmp_new_ioa = max(
170177
ioa_with_anchors(new_df.xmin.values[j],
@@ -179,8 +186,7 @@ def generate_proposals(opt, video_list, video_data):
179186
print('saving to %s' % path)
180187
new_df.to_csv(path, index=False)
181188
print('Video %s took %.4f time' % (video_name, time.time() - start_time))
182-
print('Total time was %.4f' % (time.time() - start_time))
183-
print(skipped_paths)
189+
print('Total time was %.4f' % (time.time() - start_time), skipped_paths)
184190

185191

186192
def getDatasetDict(opt):
@@ -211,11 +217,10 @@ def bookend_zeros(arr, num):
211217
return np.concatenate([np.zeros([num]), arr, np.zeros([num])])
212218

213219

214-
def generate_features_repr(opt, video_list, video_dict):
220+
def generate_features(opt, video_list, video_dict):
215221
num_sample_start = opt["num_sample_start"]
216222
num_sample_end = opt["num_sample_end"]
217223
num_sample_action = opt["num_sample_action"]
218-
num_sample_interpld = opt["num_sample_interpld"]
219224
num_videoframes = opt["num_videoframes"]
220225
skip_videoframes = opt["skip_videoframes"]
221226
bookend_num = int(num_videoframes / skip_videoframes)
@@ -234,6 +239,10 @@ def generate_features_repr(opt, video_list, video_dict):
234239
print("NOT generating features for %s because features don't exist." % video_name)
235240
continue
236241
adf = pd.read_csv(tem_path)
242+
try:
243+
adf_frames = adf.frames.values[:]
244+
except Exception as e:
245+
adf_frames = adf.frame.values[:]
237246

238247
proposals_path = os.path.join(proposals_dir, '%s.proposals.csv' % video_name)
239248
if not os.path.exists(proposals_path):
@@ -247,7 +256,7 @@ def generate_features_repr(opt, video_list, video_dict):
247256
score_end = bookend_zeros(adf.end.values[:], bookend_num)
248257
score_start = bookend_zeros(adf.start.values[:], bookend_num)
249258
#
250-
snippets = [skip_videoframes*i - normalizer for i in range(bookend_num)] + list(adf.frames.values[:]) + [skip_videoframes*i + skip_videoframes + adf.frames.values[:][-1] for i in range(bookend_num)]
259+
snippets = [skip_videoframes*i - normalizer for i in range(bookend_num)] + list(adf_frames) + [skip_videoframes*i + skip_videoframes + adf_frames[-1] for i in range(bookend_num)]
251260
print('Computing the interp1ds')
252261
f_action = interp1d(snippets, score_action, axis=0)
253262
f_start = interp1d(snippets, score_start, axis=0)
@@ -282,7 +291,11 @@ def generate_features_repr(opt, video_list, video_dict):
282291

283292
#action
284293
plen_action = (xmax - xmin) / (num_sample_action - 1)
285-
tmp_x_new = [xmin_0 + plen_action * ii for ii in range(num_sample_action)]
294+
295+
# I originall had the following (see xmin_0)
296+
# tmp_x_new = [xmin_0 + plen_action * ii for ii in range(num_sample_action)]
297+
# But they have this:
298+
tmp_x_new = [xmin + plen_action * ii for ii in range(num_sample_action)]
286299
tmp_y_new_action = f_action(tmp_x_new)
287300
tmp_y_new_action = np.reshape(tmp_y_new_action, [-1])
288301

@@ -303,6 +316,8 @@ def PGM_proposal_generation(opt):
303316
if 'thumos' in opt['dataset']:
304317
video_data = pd.read_csv(os.path.join(opt["video_info"], 'Full_Annotation.csv'))
305318
video_list = sorted(list(set(video_data.video.values[:])))
319+
# video_list = [k for k in video_list if 'video_validation_0000053' in k]
320+
# print(video_list)
306321
else:
307322
video_data = load_json(opt["video_anno"])
308323
video_list = sorted(video_data.keys()) #[:199]
@@ -348,7 +363,7 @@ def PGM_feature_generation(opt):
348363
# NOTE: change this back.
349364
# video_list = [k for k in video_list if '12.18.18' in k or '12.5.18' in k]
350365

351-
func = generate_features_repr
366+
func = generate_features
352367
num_videos = len(video_list)
353368
num_threads = min(num_videos, opt['pgm_thread'])
354369
num_videos_per_thread = int(num_videos / opt["pgm_thread"])

post_processing.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def video_post_process(opt, video_list, video_dict):
107107
df = df.sort_values(by="score", ascending=False)
108108
video_info = video_dict[video_name]
109109
video_duration = float(
110-
video_info["duration_frame"] / 16 *
110+
video_intfo["duration_frame"] / 16 *
111111
16) / video_info["duration_frame"] * video_info["duration_second"]
112112
proposal_list = []
113113

post_processing2.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def BSN_post_processing(opt):
102102
pem_inference_results = opt['pem_inference_results_dir']
103103
for num, video_name in enumerate(videoNameList):
104104
if num % 25 == 0:
105-
print(num, len(videoNameList), name)
105+
print(num, len(videoNameList), video_name)
106106
videoAnno = annoDf[annoDf["video-name"] == video_name]
107107
videoFrame = videoAnno["video-frames"].values[0]
108108
try:
@@ -130,5 +130,9 @@ def BSN_post_processing(opt):
130130
output_dir = opt['postprocessed_results_dir']
131131
if not os.path.exists(output_dir):
132132
os.makedirs(output_dir)
133-
outfile = os.path.join(output_dir, 'thumos14_results.csv')
133+
134+
if 'thumos' in opt['dataset']:
135+
outfile = os.path.join(output_dir, 'thumos14_results.csv')
136+
elif 'gymnastics' in opt['dataset']:
137+
outfile = os.path.join(output_dir, 'gym_results.csv')
134138
outDf.to_csv(outfile, index=False)

0 commit comments

Comments
 (0)