a b/train_seg_patch.py
1
import cPickle as pickle
2
import string
3
import sys
4
import time
5
from itertools import izip
6
import lasagne as nn
7
import numpy as np
8
import theano
9
from datetime import datetime, timedelta
10
import utils
11
import logger
12
import theano.tensor as T
13
import buffering
14
from configuration import config, set_configuration
15
import pathfinder
16
17
# theano.config.warn_float64 = 'raise'
18
19
if len(sys.argv) < 2:
20
    sys.exit("Usage: train.py <configuration_name>")
21
22
config_name = sys.argv[1]
23
set_configuration('configs_seg_patch', config_name)
24
expid = utils.generate_expid(config_name)
25
print
26
print "Experiment ID: %s" % expid
27
print
28
29
# metadata
30
metadata_dir = utils.get_dir_path('models', pathfinder.METADATA_PATH)
31
metadata_path = metadata_dir + '/%s.pkl' % expid
32
33
# logs
34
logs_dir = utils.get_dir_path('logs', pathfinder.METADATA_PATH)
35
sys.stdout = logger.Logger(logs_dir + '/%s.log' % expid)
36
sys.stderr = sys.stdout
37
38
print 'Build model'
39
model = config().build_model()
40
all_layers = nn.layers.get_all_layers(model.l_out)
41
all_params = nn.layers.get_all_params(model.l_out)
42
num_params = nn.layers.count_params(model.l_out)
43
print '  number of parameters: %d' % num_params
44
print string.ljust('  layer output shapes:', 36),
45
print string.ljust('#params:', 10),
46
print 'output shape:'
47
for layer in all_layers:
48
    name = string.ljust(layer.__class__.__name__, 32)
49
    num_param = sum([np.prod(p.get_value().shape) for p in layer.get_params()])
50
    num_param = string.ljust(num_param.__str__(), 10)
51
    print '    %s %s %s' % (name, num_param, layer.output_shape)
52
53
train_loss = config().build_objective(model, deterministic=False)
54
valid_loss = config().build_objective(model, deterministic=True)
55
56
learning_rate_schedule = config().learning_rate_schedule
57
learning_rate = theano.shared(np.float32(learning_rate_schedule[0]))
58
updates = config().build_updates(train_loss, model, learning_rate)
59
60
x_shared = nn.utils.shared_empty(dim=len(model.l_in.shape))
61
y_shared = nn.utils.shared_empty(dim=len(model.l_target.shape))
62
63
idx = T.lscalar('idx')
64
givens_train = {}
65
givens_train[model.l_in.input_var] = x_shared[idx * config().batch_size:(idx + 1) * config().batch_size]
66
givens_train[model.l_target.input_var] = y_shared[idx * config().batch_size:(idx + 1) * config().batch_size]
67
68
givens_valid = {}
69
givens_valid[model.l_in.input_var] = x_shared
70
givens_valid[model.l_target.input_var] = y_shared
71
72
# theano functions
73
iter_train = theano.function([idx], train_loss, givens=givens_train, updates=updates)
74
iter_get_predictions = theano.function([idx], nn.layers.get_output(model.l_out), givens=givens_train,
75
                                       on_unused_input='ignore')
76
iter_get_targets = theano.function([idx], nn.layers.get_output(model.l_target), givens=givens_train,
77
                                   on_unused_input='ignore')
78
iter_get_inputs = theano.function([idx], nn.layers.get_output(model.l_in), givens=givens_train,
79
                                  on_unused_input='ignore')
80
iter_validate = theano.function([], valid_loss, givens=givens_valid)
81
82
if config().restart_from_save:
83
    print 'Load model parameters for resuming'
84
    resume_metadata = utils.load_pkl(config().restart_from_save)
85
    nn.layers.set_all_param_values(model.l_out, resume_metadata['param_values'])
86
    start_chunk_idx = resume_metadata['chunks_since_start'] + 1
87
    chunk_idxs = range(start_chunk_idx, config().max_nchunks)
88
89
    lr = np.float32(utils.current_learning_rate(learning_rate_schedule, start_chunk_idx))
90
    print '  setting learning rate to %.7f' % lr
91
    learning_rate.set_value(lr)
92
    losses_eval_train = resume_metadata['losses_eval_train']
93
    losses_eval_valid = resume_metadata['losses_eval_valid']
94
else:
95
    chunk_idxs = range(config().max_nchunks)
96
    losses_eval_train = []
97
    losses_eval_valid = []
98
    start_chunk_idx = 0
99
100
train_data_iterator = config().train_data_iterator
101
valid_data_iterator = config().valid_data_iterator
102
103
print
104
print 'Data'
105
print 'n train: %d' % train_data_iterator.nsamples
106
print 'n validation: %d' % valid_data_iterator.nsamples
107
print 'n chunks per epoch', config().nchunks_per_epoch
108
109
print
110
print 'Train model'
111
chunk_idx = 0
112
start_time = time.time()
113
prev_time = start_time
114
tmp_losses_train = []
115
116
# use buffering.buffered_gen_threaded()
117
for chunk_idx, (x_chunk_train, y_chunk_train, id_train) in izip(chunk_idxs, buffering.buffered_gen_threaded(
118
        train_data_iterator.generate())):
119
    if chunk_idx in learning_rate_schedule:
120
        lr = np.float32(learning_rate_schedule[chunk_idx])
121
        print '  setting learning rate to %.7f' % lr
122
        print
123
        learning_rate.set_value(lr)
124
125
    # load chunk to GPU
126
    x_shared.set_value(x_chunk_train)
127
    y_shared.set_value(y_chunk_train)
128
129
    # make nbatches_chunk iterations
130
    chunk_train_losses = []
131
    for b in xrange(config().nbatches_chunk):
132
        loss = iter_train(b)
133
        chunk_train_losses.append(loss)
134
        tmp_losses_train.append(loss)
135
    print chunk_idx, np.mean(chunk_train_losses)
136
137
    if ((chunk_idx + 1) % config().validate_every) == 0:
138
        print
139
        print 'Chunk %d/%d' % (chunk_idx + 1, config().max_nchunks)
140
        # calculate mean train loss since the last validation phase
141
        mean_train_loss = np.mean(tmp_losses_train)
142
        print 'Mean train loss: %7f' % mean_train_loss
143
        losses_eval_train.append(mean_train_loss)
144
        tmp_losses_train = []
145
146
        # load validation data to GPU
147
        tmp_losses_valid = []
148
        for i, (x_chunk_valid, y_chunk_valid, ids_batch) in enumerate(
149
                buffering.buffered_gen_threaded(valid_data_iterator.generate(),
150
                                                buffer_size=2)):
151
            x_shared.set_value(x_chunk_valid)
152
            y_shared.set_value(y_chunk_valid)
153
            l_valid = iter_validate()
154
            print i, l_valid
155
            tmp_losses_valid.append(l_valid)
156
157
        # calculate validation loss across validation set
158
        valid_loss = np.mean(tmp_losses_valid)
159
        # TODO: taking mean is not correct if chunks have different sizes!!!
160
        print 'Validation loss: ', valid_loss
161
        losses_eval_valid.append(valid_loss)
162
163
        now = time.time()
164
        time_since_start = now - start_time
165
        time_since_prev = now - prev_time
166
        prev_time = now
167
        est_time_left = time_since_start * (config().max_nchunks - chunk_idx + 1.) / (chunk_idx + 1. - start_chunk_idx)
168
        eta = datetime.now() + timedelta(seconds=est_time_left)
169
        eta_str = eta.strftime("%c")
170
        print "  %s since start (%.2f s)" % (utils.hms(time_since_start), time_since_prev)
171
        print "  estimated %s to go (ETA: %s)" % (utils.hms(est_time_left), eta_str)
172
        print
173
174
    if ((chunk_idx + 1) % config().save_every) == 0:
175
        print
176
        print 'Chunk %d/%d' % (chunk_idx + 1, config().max_nchunks)
177
        print 'Saving metadata, parameters'
178
179
        with open(metadata_path, 'w') as f:
180
            pickle.dump({
181
                'configuration_file': config_name,
182
                'git_revision_hash': utils.get_git_revision_hash(),
183
                'experiment_id': expid,
184
                'chunks_since_start': chunk_idx,
185
                'losses_eval_train': losses_eval_train,
186
                'losses_eval_valid': losses_eval_valid,
187
                'param_values': nn.layers.get_all_param_values(model.l_out)
188
            }, f, pickle.HIGHEST_PROTOCOL)
189
            print '  saved to %s' % metadata_path
190
            print