-
Notifications
You must be signed in to change notification settings - Fork 7
/
train_kinetics.py
172 lines (156 loc) · 7.01 KB
/
train_kinetics.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
165
166
167
168
169
170
171
172
'''
--- I M P O R T S T A T E M E N T S ---
'''
import os
import json
import socket
import logging
import argparse
import torch
import torch.nn.parallel
import dataset
from train_model import train_model
from network.symbol_builder import get_symbol
# Create main parser
parser = argparse.ArgumentParser(description="PyTorch Video Classification Parser")
# debug
parser.add_argument('--debug-mode', type=bool, default=True,
help="print all setting for debugging.")
parser.add_argument('--dataset', default='Kinetics',
help="path to dataset")
parser.add_argument('--clip-length', default=16,
help="define the length of each input sample.")
parser.add_argument('--clip-size', default=284,
help="define the size of each input sample.")
parser.add_argument('--train-frame-interval', type=int, default=[4,5,6],
help="define the sampling interval between frames.")
parser.add_argument('--val-frame-interval', type=int, default=5,
help="define the sampling interval between frames.")
parser.add_argument('--task-name', type=str, default='',
help="name of current task, leave it empty for using folder name")
parser.add_argument('--model-dir', type=str, default="./results/KINETICS-",
help="set logging file.")
parser.add_argument('--log-file', type=str, default="",
help="set logging file.")
# device
parser.add_argument('--gpus', type=str, default="0,1,2,3,4,5,6,7",
help="define gpu id")
# algorithm
parser.add_argument('--network', type=str, default='r3d_50',
help="chose the base network")
# initialization with priority (the next step will overwrite the previous step)
# - step 1: random initialize
# - step 2: load the 3D pretrained model if `pretrained_3d' is defined
# - step 3: resume if `resume_epoch' >= 0
parser.add_argument('--pretrained_3d', type=str, default=None,
help="load default 3D pretrained model.")
# optimization
parser.add_argument('--fine-tune', type=bool, default=False,
help="resume training and then fine tune the classifier")
parser.add_argument('--resume-epoch', type=int, default=-1,
help="resume train")
parser.add_argument('--batch-size', type=int, default=32,
help="batch size")
parser.add_argument('--long-cycles', type=bool, default=True,
help="Enebling long cycles for batches")
parser.add_argument('--short-cycles', type=bool, default=True,
help="Enebling short cycles for batches")
parser.add_argument('--lr-base', type=float, default=0.05,
help="learning rate")
parser.add_argument('--lr-steps', type=list, default=[40,70,95],
help="number of samples to pass before changing learning rate") # 1e6 million
parser.add_argument('--lr-factor', type=float, default=0.1,
help="reduce the learning with factor")
parser.add_argument('--save-frequency', type=float, default=1,
help="save once after N epochs")
parser.add_argument('--end-epoch', type=int, default=130,
help="maxmium number of training epoch")
parser.add_argument('--random-seed', type=int, default=1,
help='random seed (default: 1)')
parser.add_argument('--variant', default=700, type=int, choices=[200,400,600,700],
help='The kinetics dataset type to be used')
'''
--- S T A R T O F F U N C T I O N A U T O F I L L ---
[About]
Function for creating log directories based on the parser arguments
[Args]
- args: ArgumentParser object containg both the name of task (if empty a default folder is created) and the log file to be created.
[Returns]
- args: ArgumentParser object with additionally including the model directory and the model prefix.
'''
def autofill(args):
# customized
if not args.task_name:
args.task_name = os.path.basename(os.getcwd())
if not args.log_file:
if os.path.exists("./exps/logs"):
args.log_file = "./exps/logs/{}_at-{}.log".format(args.task_name, socket.gethostname())
else:
args.log_file = ".{}_at-{}.log".format(args.task_name, socket.gethostname())
# fixed
args.model_dir += str(args.variant)
args.model_dir = os.path.join(args.model_dir,args.network)
args.model_prefix = os.path.join(args.model_dir, args.network)
return args
'''
--- E N D O F F U N C T I O N A U T O F I L L ---
'''
'''
--- S T A R T O F F U N C T I O N S E T _ L O G G E R ---
[About]
Function for creating logger for displaying and storing all events.
[Args]
- log_file: String for the log file to store all session info through logging.
- debug_mode: Boolean for additional information while logging.
[Returns]
- None
'''
def set_logger(log_file='', debug_mode=False):
if log_file:
if not os.path.exists("./"+os.path.dirname(log_file)):
os.makedirs("./"+os.path.dirname(log_file))
handlers = [logging.FileHandler(log_file), logging.StreamHandler()]
else:
handlers = [logging.StreamHandler()]
'''add '%(filename)s:%(lineno)d %(levelname)s:' to format show source file'''
logging.basicConfig(level=logging.DEBUG if debug_mode else logging.INFO,
format='%(asctime)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
handlers = handlers)
'''
--- E N D O F F U N C T I O N S E T _ L O G G E R ---
'''
'''
--- S T A R T O F M A I N F U N C T I O N ---
'''
if __name__ == "__main__":
# set args
args = parser.parse_args()
args = autofill(args)
set_logger(log_file=args.log_file, debug_mode=args.debug_mode)
logging.info("Using pytorch {} ({})".format(torch.__version__, torch.__path__))
logging.info("Start training with args:\n" +
json.dumps(vars(args), indent=4, sort_keys=True))
# set device states
print('Can use cuda: '+str(torch.cuda.is_available()))
os.environ["CUDA_VISIBLE_DEVICES"] = args.gpus # before using torch
assert torch.cuda.is_available(), "CUDA is not available"
torch.manual_seed(args.random_seed)
torch.cuda.manual_seed(args.random_seed)
# load dataset related configuration
dataset_cfg = dataset.get_config(name=args.dataset,variant=int(args.variant))
# create model with all parameters initialised
assert (not args.fine_tune or not args.resume_epoch < 0), \
"args: `resume_epoch' must be defined for fine tuning"
net, input_conf = get_symbol(name=args.network,
print_net=False, # True if args.distributed else False,
**dataset_cfg)
# training
kwargs = {}
kwargs.update(dataset_cfg)
kwargs.update({'input_conf': input_conf})
kwargs.update(vars(args))
train_model(sym_net=net, name='KINETICS-'+str(args.variant),net_name=args.network, dataset_location=args.dataset, **kwargs)
'''
--- E N D O F M A I N F U N C T I O N ---
'''