-
Notifications
You must be signed in to change notification settings - Fork 1
/
debug_har.py
164 lines (132 loc) · 6.99 KB
/
debug_har.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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import time
from torchvision import transforms
from data_utils import JointsActionDataLoader, CollateJointsSeqBatch, DepthJointsDataLoader, \
PersistentDataLoader
from models import BaselineHARModel
import torch
from torch.nn.utils.rnn import pack_sequence
import numpy as np
from contextlib import contextmanager
from timeit import default_timer
from tqdm import tqdm
## display elapsed time
@contextmanager
def elapsed_timer():
start = default_timer()
elapser = lambda: "%0.4fs" % (default_timer() - start)
yield lambda: elapser()
end = default_timer()
elapser = lambda: end-start
#@profile
def debug():
### fix for linux filesystem
torch.multiprocessing.set_sharing_strategy('file_system')
with elapsed_timer() as elapsed:
use_pca = False #True
load_depth = False
pad_seq = False
### note this stuff is meant to be wrapped by data loader class!!
train_loader = JointsActionDataLoader(
data_dir='datasets/hand_pose_action',
dataset_type='test',
batch_size=4,
shuffle=False,
validation_split=0.0,
num_workers=0,
debug=False,
reduce=True,
pad_sequence=pad_seq,# True
max_pad_length=120, #-1 # 100,
load_depth=load_depth, #False,
randomise_params=False,
use_pca=use_pca,
norm_keypt_dist=True,
)
lstm_baseline = BaselineHARModel(
in_frame_dim=63 if not use_pca else 30,#63 use 30 if using pca
out_dim=45,
num_lstm_units_per_layer=100,
num_hidden_layers=1,
lstm_dropout_prob=0.2,
use_unrolled_lstm=True, #False,#True#False#True
attention_type='v8' #'v5' #'v4' #'v3', #'cnn_v1', #'cnn_v1_k7',
)
print("\n[%s] Model Summary: " % elapsed())
print(lstm_baseline, "\n")
print("\n=> [%s] Debugging FWD+BKD Pass" % elapsed())
in_dim = 63 if not use_pca else 30
sample_input_seq = [
(np.random.randn(i, in_dim), j) for i,j in zip([3, 5, 10, 12, 7], [0,1,2,3,4])
]
# sample_input_seq = [
# (np.random.randn(i, in_dim), j) for i,j in zip([3, 3, 5, 5, 7], [0,1,2,3,4])
# ]
coll = CollateJointsSeqBatch(pad_sequence=pad_seq)
out, target = coll(sample_input_seq)
### unneeded now
# # this is for sorting in ascending order
# sample_input_seq = [torch.from_numpy(item[0]) for item in sample_input_seq]
# sample_input_seq.sort(key=lambda a: a.shape[0], reverse=True)
# sample_packed_seq, seq_idx_arr = out
# assert torch.allclose(sample_packed_seq[0][seq_idx_arr[0]], sample_input_seq[-1][-1])
# assert torch.allclose(sample_packed_seq[0][seq_idx_arr[1]], sample_input_seq[-2][-1])
# assert torch.allclose(sample_packed_seq[0][seq_idx_arr[len(seq_idx_arr)-1]], sample_input_seq[0][-1])
out = out.to(torch.device('cpu'), torch.float) if isinstance(out, torch.nn.utils.rnn.PackedSequence) else tuple(item.to(torch.device('cpu'), torch.float) for item in out)
outputs = lstm_baseline(out)
print("Output: ", outputs.shape)
## no need one-hot encoding, done automatically by torch!
## only supply action_class_idx!
targets = torch.tensor([1,0,44,15,13])#torch.randn(5, 45)
optimizer = torch.optim.Adam(lstm_baseline.parameters())
criterion = torch.nn.NLLLoss()
print("\n=> [%s] Debugging data loader(s) for first 10 batches" % elapsed())
tmp_item = None
max_num_batches = 99999
t = time.time()
# with tqdm(total=len(train_loader), desc="Loading max %d batches for HAR" % max_num_batches) as tqdm_pbar:
# t = time.time()
# for i, item in enumerate(train_loader):
# if i > max_num_batches:
# break
# # print("Got ", i, " Shape: ", item[0][0].data.shape)
# tmp_item = item # store running last item as the tmp_item
# tqdm_pbar.update(1)
print("HAR Data Loading Took: %0.2fs\n" % (time.time() - t) )
t = time.time()
with tqdm(total=len(train_loader), desc="Loading max %d batches for HAR" % max_num_batches) as tqdm_pbar:
for i, item in enumerate(train_loader):
if i > max_num_batches:
break
#print("Got ", i, " Shape: ", item[0][0].data.shape)
tmp_item = item # store running last item as the tmp_item
#print('\n',item[0].data[:4,:5])
tqdm_pbar.update(1)
print("HAR Data Loading Took: %0.2fs\n" % (time.time() - t) )
# for param in lstm_baseline.parameters():
# param.requires_grad = False
#print(list(lstm_baseline.parameters()))
#from copy import deepcopy
print("\n=> [%s] Debugging single batch training for HAR" % elapsed())
print("Overfitting HAR on 1 batch for 10 epochs...")
print("Info: Detected type is %s" % ('TUPLE' if isinstance(item[0], tuple) else \
'TORCH.TENSOR' if isinstance(item[0], torch.Tensor) else 'UNKNOWN'))
losses = []
(data, target) = tmp_item #deepcopy(tmp_item) # we need 'fresh new data' everytime! otherwise some errors in backprop
for _ in range(10):
#(data, target) = deepcopy(tmp_item) # tmp_item.copy()
if isinstance(data, torch.Tensor):
output = lstm_baseline(data) # direct invocation calls .forward() automatically
elif isinstance(data, tuple):
# if its not a tensor its probably a tuple
# we expect model to handle tuple
# we send it in similar fashion to *args
output = lstm_baseline(data)
loss = criterion(output, target)
loss.backward() # calc grads w.r.t weight/bias nodes
optimizer.step() # update weight/bias params
losses.append(loss.item())
print("10 Losses:\n", losses)
print("\n\n=> [%s] All debugging complete!\n" % elapsed())
#### for debugging
if __name__ == "__main__":
debug()