Spaces:
Runtime error
Runtime error
| # Copyright 2016 The TensorFlow Authors All Rights Reserved. | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| # ============================================================================== | |
| import numpy as np | |
| import sys | |
| import tensorflow as tf | |
| import src.utils as utils | |
| import logging | |
| from tensorflow.contrib import slim | |
| from tensorflow.contrib.metrics.python.ops import confusion_matrix_ops | |
| from tensorflow.contrib.slim import arg_scope | |
| from tensorflow.contrib.slim.nets import resnet_v2 | |
| from tensorflow.python.framework import dtypes | |
| from tensorflow.python.ops import array_ops | |
| from tensorflow.python.ops import check_ops | |
| from tensorflow.python.ops import math_ops | |
| from tensorflow.python.ops import variable_scope | |
| sys.path.insert(0, '../slim') | |
| from preprocessing import inception_preprocessing as ip | |
| resnet_v2_50 = resnet_v2.resnet_v2_50 | |
| def custom_residual_block(x, neurons, kernel_size, stride, name, is_training, | |
| wt_decay=0.0001, use_residual=True, | |
| residual_stride_conv=True, conv_fn=slim.conv2d, | |
| batch_norm_param=None): | |
| # batch norm x and relu | |
| init_var = np.sqrt(2.0/(kernel_size**2)/neurons) | |
| with arg_scope([conv_fn], | |
| weights_regularizer=slim.l2_regularizer(wt_decay), | |
| weights_initializer=tf.random_normal_initializer(stddev=init_var), | |
| biases_initializer=tf.zeros_initializer()): | |
| if batch_norm_param is None: | |
| batch_norm_param = {'center': True, 'scale': False, | |
| 'activation_fn':tf.nn.relu, | |
| 'is_training': is_training} | |
| y = slim.batch_norm(x, scope=name+'_bn', **batch_norm_param) | |
| y = conv_fn(y, num_outputs=neurons, kernel_size=kernel_size, stride=stride, | |
| activation_fn=None, scope=name+'_1', | |
| normalizer_fn=slim.batch_norm, | |
| normalizer_params=batch_norm_param) | |
| y = conv_fn(y, num_outputs=neurons, kernel_size=kernel_size, | |
| stride=1, activation_fn=None, scope=name+'_2') | |
| if use_residual: | |
| if stride != 1 or x.get_shape().as_list()[-1] != neurons: | |
| batch_norm_param_ = dict(batch_norm_param) | |
| batch_norm_param_['activation_fn'] = None | |
| x = conv_fn(x, num_outputs=neurons, kernel_size=1, | |
| stride=stride if residual_stride_conv else 1, | |
| activation_fn=None, scope=name+'_0_1x1', | |
| normalizer_fn=slim.batch_norm, | |
| normalizer_params=batch_norm_param_) | |
| if not residual_stride_conv: | |
| x = slim.avg_pool2d(x, 1, stride=stride, scope=name+'_0_avg') | |
| y = tf.add(x, y, name=name+'_add') | |
| return y | |
| def step_gt_prob(step, step_number_op): | |
| # Change samping probability from 1 to -1 at step steps. | |
| with tf.name_scope('step_gt_prob'): | |
| out = tf.cond(tf.less(step_number_op, step), | |
| lambda: tf.constant(1.), lambda: tf.constant(-1.)) | |
| return out | |
| def inverse_sigmoid_decay(k, global_step_op): | |
| with tf.name_scope('inverse_sigmoid_decay'): | |
| k = tf.constant(k, dtype=tf.float32) | |
| tmp = k*tf.exp(-tf.cast(global_step_op, tf.float32)/k) | |
| tmp = tmp / (1. + tmp) | |
| return tmp | |
| def dense_resample(im, flow_im, output_valid_mask, name='dense_resample'): | |
| """ Resample reward at particular locations. | |
| Args: | |
| im: ...xHxWxC matrix to sample from. | |
| flow_im: ...xHxWx2 matrix, samples the image using absolute offsets as given | |
| by the flow_im. | |
| """ | |
| with tf.name_scope(name): | |
| valid_mask = None | |
| x, y = tf.unstack(flow_im, axis=-1) | |
| x = tf.cast(tf.reshape(x, [-1]), tf.float32) | |
| y = tf.cast(tf.reshape(y, [-1]), tf.float32) | |
| # constants | |
| shape = tf.unstack(tf.shape(im)) | |
| channels = shape[-1] | |
| width = shape[-2] | |
| height = shape[-3] | |
| num_batch = tf.cast(tf.reduce_prod(tf.stack(shape[:-3])), 'int32') | |
| zero = tf.constant(0, dtype=tf.int32) | |
| # Round up and down. | |
| x0 = tf.cast(tf.floor(x), 'int32'); x1 = x0 + 1; | |
| y0 = tf.cast(tf.floor(y), 'int32'); y1 = y0 + 1; | |
| if output_valid_mask: | |
| valid_mask = tf.logical_and( | |
| tf.logical_and(tf.less_equal(x, tf.cast(width, tf.float32)-1.), tf.greater_equal(x, 0.)), | |
| tf.logical_and(tf.less_equal(y, tf.cast(height, tf.float32)-1.), tf.greater_equal(y, 0.))) | |
| valid_mask = tf.reshape(valid_mask, shape=shape[:-1] + [1]) | |
| x0 = tf.clip_by_value(x0, zero, width-1) | |
| x1 = tf.clip_by_value(x1, zero, width-1) | |
| y0 = tf.clip_by_value(y0, zero, height-1) | |
| y1 = tf.clip_by_value(y1, zero, height-1) | |
| dim2 = width; dim1 = width * height; | |
| # Create base index | |
| base = tf.reshape(tf.range(num_batch) * dim1, shape=[-1,1]) | |
| base = tf.reshape(tf.tile(base, [1, height*width]), shape=[-1]) | |
| base_y0 = base + y0 * dim2 | |
| base_y1 = base + y1 * dim2 | |
| idx_a = base_y0 + x0 | |
| idx_b = base_y1 + x0 | |
| idx_c = base_y0 + x1 | |
| idx_d = base_y1 + x1 | |
| # use indices to lookup pixels in the flat image and restore channels dim | |
| sh = tf.stack([tf.constant(-1,dtype=tf.int32), channels]) | |
| im_flat = tf.cast(tf.reshape(im, sh), dtype=tf.float32) | |
| pixel_a = tf.gather(im_flat, idx_a) | |
| pixel_b = tf.gather(im_flat, idx_b) | |
| pixel_c = tf.gather(im_flat, idx_c) | |
| pixel_d = tf.gather(im_flat, idx_d) | |
| # and finally calculate interpolated values | |
| x1_f = tf.to_float(x1) | |
| y1_f = tf.to_float(y1) | |
| wa = tf.expand_dims(((x1_f - x) * (y1_f - y)), 1) | |
| wb = tf.expand_dims((x1_f - x) * (1.0 - (y1_f - y)), 1) | |
| wc = tf.expand_dims(((1.0 - (x1_f - x)) * (y1_f - y)), 1) | |
| wd = tf.expand_dims(((1.0 - (x1_f - x)) * (1.0 - (y1_f - y))), 1) | |
| output = tf.add_n([wa * pixel_a, wb * pixel_b, wc * pixel_c, wd * pixel_d]) | |
| output = tf.reshape(output, shape=tf.shape(im)) | |
| return output, valid_mask | |
| def get_flow(t, theta, map_size, name_scope='gen_flow'): | |
| """ | |
| Rotates the map by theta and translates the rotated map by t. | |
| Assume that the robot rotates by an angle theta and then moves forward by | |
| translation t. This function returns the flow field field. For every pixel in | |
| the new image it tells us which pixel in the original image it came from: | |
| NewI(x, y) = OldI(flow_x(x,y), flow_y(x,y)). | |
| Assume there is a point p in the original image. Robot rotates by R and moves | |
| forward by t. p1 = Rt*p; p2 = p1 - t; (the world moves in opposite direction. | |
| So, p2 = Rt*p - t, thus p2 came from R*(p2+t), which is what this function | |
| calculates. | |
| t: ... x 2 (translation for B batches of N motions each). | |
| theta: ... x 1 (rotation for B batches of N motions each). | |
| Output: ... x map_size x map_size x 2 | |
| """ | |
| with tf.name_scope(name_scope): | |
| tx, ty = tf.unstack(tf.reshape(t, shape=[-1, 1, 1, 1, 2]), axis=4) | |
| theta = tf.reshape(theta, shape=[-1, 1, 1, 1]) | |
| c = tf.constant((map_size-1.)/2., dtype=tf.float32) | |
| x, y = np.meshgrid(np.arange(map_size), np.arange(map_size)) | |
| x = tf.constant(x[np.newaxis, :, :, np.newaxis], dtype=tf.float32, name='x', | |
| shape=[1, map_size, map_size, 1]) | |
| y = tf.constant(y[np.newaxis, :, :, np.newaxis], dtype=tf.float32, name='y', | |
| shape=[1,map_size, map_size, 1]) | |
| x = x-(-tx+c) | |
| y = y-(-ty+c) | |
| sin_theta = tf.sin(theta) | |
| cos_theta = tf.cos(theta) | |
| xr = cos_theta*x - sin_theta*y | |
| yr = sin_theta*x + cos_theta*y | |
| xr = xr + c | |
| yr = yr + c | |
| flow = tf.stack([xr, yr], axis=-1) | |
| sh = tf.unstack(tf.shape(t), axis=0) | |
| sh = tf.stack(sh[:-1]+[tf.constant(_, dtype=tf.int32) for _ in [map_size, map_size, 2]]) | |
| flow = tf.reshape(flow, shape=sh) | |
| return flow | |
| def distort_image(im, fast_mode=False): | |
| # All images in the same batch are transformed the same way, but over | |
| # iterations you see different distortions. | |
| # im should be float with values between 0 and 1. | |
| im_ = tf.reshape(im, shape=(-1,1,3)) | |
| im_ = ip.apply_with_random_selector( | |
| im_, lambda x, ordering: ip.distort_color(x, ordering, fast_mode), | |
| num_cases=4) | |
| im_ = tf.reshape(im_, tf.shape(im)) | |
| return im_ | |
| def fc_network(x, neurons, wt_decay, name, num_pred=None, offset=0, | |
| batch_norm_param=None, dropout_ratio=0.0, is_training=None): | |
| if dropout_ratio > 0: | |
| assert(is_training is not None), \ | |
| 'is_training needs to be defined when trainnig with dropout.' | |
| repr = [] | |
| for i, neuron in enumerate(neurons): | |
| init_var = np.sqrt(2.0/neuron) | |
| if batch_norm_param is not None: | |
| x = slim.fully_connected(x, neuron, activation_fn=None, | |
| weights_initializer=tf.random_normal_initializer(stddev=init_var), | |
| weights_regularizer=slim.l2_regularizer(wt_decay), | |
| normalizer_fn=slim.batch_norm, | |
| normalizer_params=batch_norm_param, | |
| biases_initializer=tf.zeros_initializer(), | |
| scope='{:s}_{:d}'.format(name, offset+i)) | |
| else: | |
| x = slim.fully_connected(x, neuron, activation_fn=tf.nn.relu, | |
| weights_initializer=tf.random_normal_initializer(stddev=init_var), | |
| weights_regularizer=slim.l2_regularizer(wt_decay), | |
| biases_initializer=tf.zeros_initializer(), | |
| scope='{:s}_{:d}'.format(name, offset+i)) | |
| if dropout_ratio > 0: | |
| x = slim.dropout(x, keep_prob=1-dropout_ratio, is_training=is_training, | |
| scope='{:s}_{:d}'.format('dropout_'+name, offset+i)) | |
| repr.append(x) | |
| if num_pred is not None: | |
| init_var = np.sqrt(2.0/num_pred) | |
| x = slim.fully_connected(x, num_pred, | |
| weights_regularizer=slim.l2_regularizer(wt_decay), | |
| weights_initializer=tf.random_normal_initializer(stddev=init_var), | |
| biases_initializer=tf.zeros_initializer(), | |
| activation_fn=None, | |
| scope='{:s}_pred'.format(name)) | |
| return x, repr | |
| def concat_state_x_list(f, names): | |
| af = {} | |
| for i, k in enumerate(names): | |
| af[k] = np.concatenate([x[i] for x in f], axis=1) | |
| return af | |
| def concat_state_x(f, names): | |
| af = {} | |
| for k in names: | |
| af[k] = np.concatenate([x[k] for x in f], axis=1) | |
| # af[k] = np.swapaxes(af[k], 0, 1) | |
| return af | |
| def sample_action(rng, action_probs, optimal_action, sample_gt_prob, | |
| type='sample', combine_type='one_or_other'): | |
| optimal_action_ = optimal_action/np.sum(optimal_action+0., 1, keepdims=True) | |
| action_probs_ = action_probs/np.sum(action_probs+0.001, 1, keepdims=True) | |
| batch_size = action_probs_.shape[0] | |
| action = np.zeros((batch_size), dtype=np.int32) | |
| action_sample_wt = np.zeros((batch_size), dtype=np.float32) | |
| if combine_type == 'add': | |
| sample_gt_prob_ = np.minimum(np.maximum(sample_gt_prob, 0.), 1.) | |
| for i in range(batch_size): | |
| if combine_type == 'one_or_other': | |
| sample_gt = rng.rand() < sample_gt_prob | |
| if sample_gt: distr_ = optimal_action_[i,:]*1. | |
| else: distr_ = action_probs_[i,:]*1. | |
| elif combine_type == 'add': | |
| distr_ = optimal_action_[i,:]*sample_gt_prob_ + \ | |
| (1.-sample_gt_prob_)*action_probs_[i,:] | |
| distr_ = distr_ / np.sum(distr_) | |
| if type == 'sample': | |
| action[i] = np.argmax(rng.multinomial(1, distr_, size=1)) | |
| elif type == 'argmax': | |
| action[i] = np.argmax(distr_) | |
| action_sample_wt[i] = action_probs_[i, action[i]] / distr_[action[i]] | |
| return action, action_sample_wt | |
| def train_step_custom_online_sampling(sess, train_op, global_step, | |
| train_step_kwargs, mode='train'): | |
| m = train_step_kwargs['m'] | |
| obj = train_step_kwargs['obj'] | |
| rng_data = train_step_kwargs['rng_data'] | |
| rng_action = train_step_kwargs['rng_action'] | |
| writer = train_step_kwargs['writer'] | |
| iters = train_step_kwargs['iters'] | |
| num_steps = train_step_kwargs['num_steps'] | |
| logdir = train_step_kwargs['logdir'] | |
| dagger_sample_bn_false = train_step_kwargs['dagger_sample_bn_false'] | |
| train_display_interval = train_step_kwargs['train_display_interval'] | |
| if 'outputs' not in m.train_ops: | |
| m.train_ops['outputs'] = [] | |
| s_ops = m.summary_ops[mode] | |
| val_additional_ops = [] | |
| # Print all variables here. | |
| if False: | |
| v = tf.get_collection(tf.GraphKeys.VARIABLES) | |
| v_op = [_.value() for _ in v] | |
| v_op_value = sess.run(v_op) | |
| filter = lambda x, y: 'Adam' in x.name | |
| # filter = lambda x, y: np.is_any_nan(y) | |
| ind = [i for i, (_, __) in enumerate(zip(v, v_op_value)) if filter(_, __)] | |
| v = [v[i] for i in ind] | |
| v_op_value = [v_op_value[i] for i in ind] | |
| for i in range(len(v)): | |
| logging.info('XXXX: variable: %30s, is_any_nan: %5s, norm: %f.', | |
| v[i].name, np.any(np.isnan(v_op_value[i])), | |
| np.linalg.norm(v_op_value[i])) | |
| tt = utils.Timer() | |
| for i in range(iters): | |
| tt.tic() | |
| # Sample a room. | |
| e = obj.sample_env(rng_data) | |
| # Initialize the agent. | |
| init_env_state = e.reset(rng_data) | |
| # Get and process the common data. | |
| input = e.get_common_data() | |
| input = e.pre_common_data(input) | |
| feed_dict = prepare_feed_dict(m.input_tensors['common'], input) | |
| if dagger_sample_bn_false: | |
| feed_dict[m.train_ops['batch_norm_is_training_op']] = False | |
| common_data = sess.run(m.train_ops['common'], feed_dict=feed_dict) | |
| states = [] | |
| state_features = [] | |
| state_targets = [] | |
| net_state_to_input = [] | |
| step_data_cache = [] | |
| executed_actions = [] | |
| rewards = [] | |
| action_sample_wts = [] | |
| states.append(init_env_state) | |
| net_state = sess.run(m.train_ops['init_state'], feed_dict=feed_dict) | |
| net_state = dict(zip(m.train_ops['state_names'], net_state)) | |
| net_state_to_input.append(net_state) | |
| for j in range(num_steps): | |
| f = e.get_features(states[j], j) | |
| f = e.pre_features(f) | |
| f.update(net_state) | |
| f['step_number'] = np.ones((1,1,1), dtype=np.int32)*j | |
| state_features.append(f) | |
| feed_dict = prepare_feed_dict(m.input_tensors['step'], state_features[-1]) | |
| optimal_action = e.get_optimal_action(states[j], j) | |
| for x, v in zip(m.train_ops['common'], common_data): | |
| feed_dict[x] = v | |
| if dagger_sample_bn_false: | |
| feed_dict[m.train_ops['batch_norm_is_training_op']] = False | |
| outs = sess.run([m.train_ops['step'], m.sample_gt_prob_op, | |
| m.train_ops['step_data_cache'], | |
| m.train_ops['updated_state'], | |
| m.train_ops['outputs']], feed_dict=feed_dict) | |
| action_probs = outs[0] | |
| sample_gt_prob = outs[1] | |
| step_data_cache.append(dict(zip(m.train_ops['step_data_cache'], outs[2]))) | |
| net_state = outs[3] | |
| if hasattr(e, 'update_state'): | |
| outputs = outs[4] | |
| outputs = dict(zip(m.train_ops['output_names'], outputs)) | |
| e.update_state(outputs, j) | |
| state_targets.append(e.get_targets(states[j], j)) | |
| if j < num_steps-1: | |
| # Sample from action_probs and optimal action. | |
| action, action_sample_wt = sample_action( | |
| rng_action, action_probs, optimal_action, sample_gt_prob, | |
| m.sample_action_type, m.sample_action_combine_type) | |
| next_state, reward = e.take_action(states[j], action, j) | |
| executed_actions.append(action) | |
| states.append(next_state) | |
| rewards.append(reward) | |
| action_sample_wts.append(action_sample_wt) | |
| net_state = dict(zip(m.train_ops['state_names'], net_state)) | |
| net_state_to_input.append(net_state) | |
| # Concatenate things together for training. | |
| rewards = np.array(rewards).T | |
| action_sample_wts = np.array(action_sample_wts).T | |
| executed_actions = np.array(executed_actions).T | |
| all_state_targets = concat_state_x(state_targets, e.get_targets_name()) | |
| all_state_features = concat_state_x(state_features, | |
| e.get_features_name()+['step_number']) | |
| # all_state_net = concat_state_x(net_state_to_input, | |
| # m.train_ops['state_names']) | |
| all_step_data_cache = concat_state_x(step_data_cache, | |
| m.train_ops['step_data_cache']) | |
| dict_train = dict(input) | |
| dict_train.update(all_state_features) | |
| dict_train.update(all_state_targets) | |
| # dict_train.update(all_state_net) | |
| dict_train.update(net_state_to_input[0]) | |
| dict_train.update(all_step_data_cache) | |
| dict_train.update({'rewards': rewards, | |
| 'action_sample_wts': action_sample_wts, | |
| 'executed_actions': executed_actions}) | |
| feed_dict = prepare_feed_dict(m.input_tensors['train'], dict_train) | |
| for x in m.train_ops['step_data_cache']: | |
| feed_dict[x] = all_step_data_cache[x] | |
| if mode == 'train': | |
| n_step = sess.run(global_step) | |
| if np.mod(n_step, train_display_interval) == 0: | |
| total_loss, np_global_step, summary, print_summary = sess.run( | |
| [train_op, global_step, s_ops.summary_ops, s_ops.print_summary_ops], | |
| feed_dict=feed_dict) | |
| logging.error("") | |
| else: | |
| total_loss, np_global_step, summary = sess.run( | |
| [train_op, global_step, s_ops.summary_ops], feed_dict=feed_dict) | |
| if writer is not None and summary is not None: | |
| writer.add_summary(summary, np_global_step) | |
| should_stop = sess.run(m.should_stop_op) | |
| if mode != 'train': | |
| arop = [[] for j in range(len(s_ops.additional_return_ops))] | |
| for j in range(len(s_ops.additional_return_ops)): | |
| if s_ops.arop_summary_iters[j] < 0 or i < s_ops.arop_summary_iters[j]: | |
| arop[j] = s_ops.additional_return_ops[j] | |
| val = sess.run(arop, feed_dict=feed_dict) | |
| val_additional_ops.append(val) | |
| tt.toc(log_at=60, log_str='val timer {:d} / {:d}: '.format(i, iters), | |
| type='time') | |
| if mode != 'train': | |
| # Write the default val summaries. | |
| summary, print_summary, np_global_step = sess.run( | |
| [s_ops.summary_ops, s_ops.print_summary_ops, global_step]) | |
| if writer is not None and summary is not None: | |
| writer.add_summary(summary, np_global_step) | |
| # write custom validation ops | |
| val_summarys = [] | |
| val_additional_ops = zip(*val_additional_ops) | |
| if len(s_ops.arop_eval_fns) > 0: | |
| val_metric_summary = tf.summary.Summary() | |
| for i in range(len(s_ops.arop_eval_fns)): | |
| val_summary = None | |
| if s_ops.arop_eval_fns[i] is not None: | |
| val_summary = s_ops.arop_eval_fns[i](val_additional_ops[i], | |
| np_global_step, logdir, | |
| val_metric_summary, | |
| s_ops.arop_summary_iters[i]) | |
| val_summarys.append(val_summary) | |
| if writer is not None: | |
| writer.add_summary(val_metric_summary, np_global_step) | |
| # Return the additional val_ops | |
| total_loss = (val_additional_ops, val_summarys) | |
| should_stop = None | |
| return total_loss, should_stop | |
| def train_step_custom_v2(sess, train_op, global_step, train_step_kwargs, | |
| mode='train'): | |
| m = train_step_kwargs['m'] | |
| obj = train_step_kwargs['obj'] | |
| rng = train_step_kwargs['rng'] | |
| writer = train_step_kwargs['writer'] | |
| iters = train_step_kwargs['iters'] | |
| logdir = train_step_kwargs['logdir'] | |
| train_display_interval = train_step_kwargs['train_display_interval'] | |
| s_ops = m.summary_ops[mode] | |
| val_additional_ops = [] | |
| # Print all variables here. | |
| if False: | |
| v = tf.get_collection(tf.GraphKeys.VARIABLES) | |
| v_op = [_.value() for _ in v] | |
| v_op_value = sess.run(v_op) | |
| filter = lambda x, y: 'Adam' in x.name | |
| # filter = lambda x, y: np.is_any_nan(y) | |
| ind = [i for i, (_, __) in enumerate(zip(v, v_op_value)) if filter(_, __)] | |
| v = [v[i] for i in ind] | |
| v_op_value = [v_op_value[i] for i in ind] | |
| for i in range(len(v)): | |
| logging.info('XXXX: variable: %30s, is_any_nan: %5s, norm: %f.', | |
| v[i].name, np.any(np.isnan(v_op_value[i])), | |
| np.linalg.norm(v_op_value[i])) | |
| tt = utils.Timer() | |
| for i in range(iters): | |
| tt.tic() | |
| e = obj.sample_env(rng) | |
| rngs = e.gen_rng(rng) | |
| input_data = e.gen_data(*rngs) | |
| input_data = e.pre_data(input_data) | |
| feed_dict = prepare_feed_dict(m.input_tensors, input_data) | |
| if mode == 'train': | |
| n_step = sess.run(global_step) | |
| if np.mod(n_step, train_display_interval) == 0: | |
| total_loss, np_global_step, summary, print_summary = sess.run( | |
| [train_op, global_step, s_ops.summary_ops, s_ops.print_summary_ops], | |
| feed_dict=feed_dict) | |
| else: | |
| total_loss, np_global_step, summary = sess.run( | |
| [train_op, global_step, s_ops.summary_ops], | |
| feed_dict=feed_dict) | |
| if writer is not None and summary is not None: | |
| writer.add_summary(summary, np_global_step) | |
| should_stop = sess.run(m.should_stop_op) | |
| if mode != 'train': | |
| arop = [[] for j in range(len(s_ops.additional_return_ops))] | |
| for j in range(len(s_ops.additional_return_ops)): | |
| if s_ops.arop_summary_iters[j] < 0 or i < s_ops.arop_summary_iters[j]: | |
| arop[j] = s_ops.additional_return_ops[j] | |
| val = sess.run(arop, feed_dict=feed_dict) | |
| val_additional_ops.append(val) | |
| tt.toc(log_at=60, log_str='val timer {:d} / {:d}: '.format(i, iters), | |
| type='time') | |
| if mode != 'train': | |
| # Write the default val summaries. | |
| summary, print_summary, np_global_step = sess.run( | |
| [s_ops.summary_ops, s_ops.print_summary_ops, global_step]) | |
| if writer is not None and summary is not None: | |
| writer.add_summary(summary, np_global_step) | |
| # write custom validation ops | |
| val_summarys = [] | |
| val_additional_ops = zip(*val_additional_ops) | |
| if len(s_ops.arop_eval_fns) > 0: | |
| val_metric_summary = tf.summary.Summary() | |
| for i in range(len(s_ops.arop_eval_fns)): | |
| val_summary = None | |
| if s_ops.arop_eval_fns[i] is not None: | |
| val_summary = s_ops.arop_eval_fns[i](val_additional_ops[i], | |
| np_global_step, logdir, | |
| val_metric_summary, | |
| s_ops.arop_summary_iters[i]) | |
| val_summarys.append(val_summary) | |
| if writer is not None: | |
| writer.add_summary(val_metric_summary, np_global_step) | |
| # Return the additional val_ops | |
| total_loss = (val_additional_ops, val_summarys) | |
| should_stop = None | |
| return total_loss, should_stop | |
| def train_step_custom(sess, train_op, global_step, train_step_kwargs, | |
| mode='train'): | |
| m = train_step_kwargs['m'] | |
| params = train_step_kwargs['params'] | |
| rng = train_step_kwargs['rng'] | |
| writer = train_step_kwargs['writer'] | |
| iters = train_step_kwargs['iters'] | |
| gen_rng = train_step_kwargs['gen_rng'] | |
| logdir = train_step_kwargs['logdir'] | |
| gen_data = train_step_kwargs['gen_data'] | |
| pre_data = train_step_kwargs['pre_data'] | |
| train_display_interval = train_step_kwargs['train_display_interval'] | |
| val_additional_ops = [] | |
| # Print all variables here. | |
| if False: | |
| v = tf.get_collection(tf.GraphKeys.VARIABLES) | |
| for _ in v: | |
| val = sess.run(_.value()) | |
| logging.info('variable: %30s, is_any_nan: %5s, norm: %f.', _.name, | |
| np.any(np.isnan(val)), np.linalg.norm(val)) | |
| for i in range(iters): | |
| rngs = gen_rng(params, rng) | |
| input_data = gen_data(params, *rngs) | |
| input_data = pre_data(params, input_data) | |
| feed_dict = prepare_feed_dict(m.input_tensors, input_data) | |
| if mode == 'train': | |
| n_step = sess.run(global_step) | |
| if np.mod(n_step, train_display_interval) == 0: | |
| total_loss, np_global_step, summary, print_summary = sess.run( | |
| [train_op, global_step, m.summary_op[mode], m.print_summary_op[mode]], | |
| feed_dict=feed_dict) | |
| else: | |
| total_loss, np_global_step, summary = sess.run( | |
| [train_op, global_step, m.summary_op[mode]], | |
| feed_dict=feed_dict) | |
| if writer is not None: | |
| writer.add_summary(summary, np_global_step) | |
| should_stop = sess.run(m.should_stop_op) | |
| if mode == 'val': | |
| val = sess.run(m.agg_update_op[mode] + m.additional_return_op[mode], | |
| feed_dict=feed_dict) | |
| val_additional_ops.append(val[len(m.agg_update_op[mode]):]) | |
| if mode == 'val': | |
| summary, print_summary, np_global_step = sess.run( | |
| [m.summary_op[mode], m.print_summary_op[mode], global_step]) | |
| if writer is not None: | |
| writer.add_summary(summary, np_global_step) | |
| sess.run([m.agg_reset_op[mode]]) | |
| # write custom validation ops | |
| if m.eval_metrics_fn[mode] is not None: | |
| val_metric_summary = m.eval_metrics_fn[mode](val_additional_ops, | |
| np_global_step, logdir) | |
| if writer is not None: | |
| writer.add_summary(val_metric_summary, np_global_step) | |
| total_loss = val_additional_ops | |
| should_stop = None | |
| return total_loss, should_stop | |
| def setup_training(loss_op, initial_learning_rate, steps_per_decay, | |
| learning_rate_decay, momentum, max_steps, | |
| sync=False, adjust_lr_sync=True, | |
| num_workers=1, replica_id=0, vars_to_optimize=None, | |
| clip_gradient_norm=0, typ=None, momentum2=0.999, | |
| adam_eps=1e-8): | |
| if sync and adjust_lr_sync: | |
| initial_learning_rate = initial_learning_rate * num_workers | |
| max_steps = np.int(max_steps / num_workers) | |
| steps_per_decay = np.int(steps_per_decay / num_workers) | |
| global_step_op = slim.get_or_create_global_step() | |
| lr_op = tf.train.exponential_decay(initial_learning_rate, | |
| global_step_op, steps_per_decay, learning_rate_decay, staircase=True) | |
| if typ == 'sgd': | |
| optimizer = tf.train.MomentumOptimizer(lr_op, momentum) | |
| elif typ == 'adam': | |
| optimizer = tf.train.AdamOptimizer(learning_rate=lr_op, beta1=momentum, | |
| beta2=momentum2, epsilon=adam_eps) | |
| if sync: | |
| sync_optimizer = tf.train.SyncReplicasOptimizer(optimizer, | |
| replicas_to_aggregate=num_workers, | |
| replica_id=replica_id, | |
| total_num_replicas=num_workers) | |
| train_op = slim.learning.create_train_op(loss_op, sync_optimizer, | |
| variables_to_train=vars_to_optimize, | |
| clip_gradient_norm=clip_gradient_norm) | |
| else: | |
| sync_optimizer = None | |
| train_op = slim.learning.create_train_op(loss_op, optimizer, | |
| variables_to_train=vars_to_optimize, | |
| clip_gradient_norm=clip_gradient_norm) | |
| should_stop_op = tf.greater_equal(global_step_op, max_steps) | |
| return lr_op, global_step_op, train_op, should_stop_op, optimizer, sync_optimizer | |
| def add_value_to_summary(metric_summary, tag, val, log=True, tag_str=None): | |
| """Adds a scalar summary to the summary object. Optionally also logs to | |
| logging.""" | |
| new_value = metric_summary.value.add(); | |
| new_value.tag = tag | |
| new_value.simple_value = val | |
| if log: | |
| if tag_str is None: | |
| tag_str = tag + '%f' | |
| logging.info(tag_str, val) | |
| def add_scalar_summary_op(tensor, name=None, | |
| summary_key='summaries', print_summary_key='print_summaries', prefix=''): | |
| collections = [] | |
| op = tf.summary.scalar(name, tensor, collections=collections) | |
| if summary_key != print_summary_key: | |
| tf.add_to_collection(summary_key, op) | |
| op = tf.Print(op, [tensor], ' {:-<25s}: '.format(name) + prefix) | |
| tf.add_to_collection(print_summary_key, op) | |
| return op | |
| def setup_inputs(inputs): | |
| input_tensors = {} | |
| input_shapes = {} | |
| for (name, typ, sz) in inputs: | |
| _ = tf.placeholder(typ, shape=sz, name=name) | |
| input_tensors[name] = _ | |
| input_shapes[name] = sz | |
| return input_tensors, input_shapes | |
| def prepare_feed_dict(input_tensors, inputs): | |
| feed_dict = {} | |
| for n in input_tensors.keys(): | |
| feed_dict[input_tensors[n]] = inputs[n].astype(input_tensors[n].dtype.as_numpy_dtype) | |
| return feed_dict | |
| def simple_add_summaries(summarize_ops, summarize_names, | |
| summary_key='summaries', | |
| print_summary_key='print_summaries', prefix=''): | |
| for op, name, in zip(summarize_ops, summarize_names): | |
| add_scalar_summary_op(op, name, summary_key, print_summary_key, prefix) | |
| summary_op = tf.summary.merge_all(summary_key) | |
| print_summary_op = tf.summary.merge_all(print_summary_key) | |
| return summary_op, print_summary_op | |
| def add_summary_ops(m, summarize_ops, summarize_names, to_aggregate=None, | |
| summary_key='summaries', | |
| print_summary_key='print_summaries', prefix=''): | |
| if type(to_aggregate) != list: | |
| to_aggregate = [to_aggregate for _ in summarize_ops] | |
| # set up aggregating metrics | |
| if np.any(to_aggregate): | |
| agg_ops = [] | |
| for op, name, to_agg in zip(summarize_ops, summarize_names, to_aggregate): | |
| if to_agg: | |
| # agg_ops.append(slim.metrics.streaming_mean(op, return_reset_op=True)) | |
| agg_ops.append(tf.contrib.metrics.streaming_mean(op)) | |
| # agg_ops.append(tf.contrib.metrics.streaming_mean(op, return_reset_op=True)) | |
| else: | |
| agg_ops.append([None, None, None]) | |
| # agg_values_op, agg_update_op, agg_reset_op = zip(*agg_ops) | |
| # agg_update_op = [x for x in agg_update_op if x is not None] | |
| # agg_reset_op = [x for x in agg_reset_op if x is not None] | |
| agg_values_op, agg_update_op = zip(*agg_ops) | |
| agg_update_op = [x for x in agg_update_op if x is not None] | |
| agg_reset_op = [tf.no_op()] | |
| else: | |
| agg_values_op = [None for _ in to_aggregate] | |
| agg_update_op = [tf.no_op()] | |
| agg_reset_op = [tf.no_op()] | |
| for op, name, to_agg, agg_op in zip(summarize_ops, summarize_names, to_aggregate, agg_values_op): | |
| if to_agg: | |
| add_scalar_summary_op(agg_op, name, summary_key, print_summary_key, prefix) | |
| else: | |
| add_scalar_summary_op(op, name, summary_key, print_summary_key, prefix) | |
| summary_op = tf.summary.merge_all(summary_key) | |
| print_summary_op = tf.summary.merge_all(print_summary_key) | |
| return summary_op, print_summary_op, agg_update_op, agg_reset_op | |
| def accum_val_ops(outputs, names, global_step, output_dir, metric_summary, N): | |
| """Processes the collected outputs to compute AP for action prediction. | |
| Args: | |
| outputs : List of scalar ops to summarize. | |
| names : Name of the scalar ops. | |
| global_step : global_step. | |
| output_dir : where to store results. | |
| metric_summary : summary object to add summaries to. | |
| N : number of outputs to process. | |
| """ | |
| outs = [] | |
| if N >= 0: | |
| outputs = outputs[:N] | |
| for i in range(len(outputs[0])): | |
| scalar = np.array(map(lambda x: x[i], outputs)) | |
| assert(scalar.ndim == 1) | |
| add_value_to_summary(metric_summary, names[i], np.mean(scalar), | |
| tag_str='{:>27s}: [{:s}]: %f'.format(names[i], '')) | |
| outs.append(np.mean(scalar)) | |
| return outs | |
| def get_default_summary_ops(): | |
| return utils.Foo(summary_ops=None, print_summary_ops=None, | |
| additional_return_ops=[], arop_summary_iters=[], | |
| arop_eval_fns=[]) | |
| def simple_summaries(summarize_ops, summarize_names, mode, to_aggregate=False, | |
| scope_name='summary'): | |
| if type(to_aggregate) != list: | |
| to_aggregate = [to_aggregate for _ in summarize_ops] | |
| summary_key = '{:s}_summaries'.format(mode) | |
| print_summary_key = '{:s}_print_summaries'.format(mode) | |
| prefix=' [{:s}]: '.format(mode) | |
| # Default ops for things that dont need to be aggregated. | |
| if not np.all(to_aggregate): | |
| for op, name, to_agg in zip(summarize_ops, summarize_names, to_aggregate): | |
| if not to_agg: | |
| add_scalar_summary_op(op, name, summary_key, print_summary_key, prefix) | |
| summary_ops = tf.summary.merge_all(summary_key) | |
| print_summary_ops = tf.summary.merge_all(print_summary_key) | |
| else: | |
| summary_ops = tf.no_op() | |
| print_summary_ops = tf.no_op() | |
| # Default ops for things that dont need to be aggregated. | |
| if np.any(to_aggregate): | |
| additional_return_ops = [[summarize_ops[i] | |
| for i, x in enumerate(to_aggregate )if x]] | |
| arop_summary_iters = [-1] | |
| s_names = ['{:s}/{:s}'.format(scope_name, summarize_names[i]) | |
| for i, x in enumerate(to_aggregate) if x] | |
| fn = lambda outputs, global_step, output_dir, metric_summary, N: \ | |
| accum_val_ops(outputs, s_names, global_step, output_dir, metric_summary, | |
| N) | |
| arop_eval_fns = [fn] | |
| else: | |
| additional_return_ops = [] | |
| arop_summary_iters = [] | |
| arop_eval_fns = [] | |
| return summary_ops, print_summary_ops, additional_return_ops, \ | |
| arop_summary_iters, arop_eval_fns | |