Spaces:
Running
Running
# 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. | |
# ============================================================================== | |
"""Utility functions for setting up the CMP graph. | |
""" | |
import os, numpy as np | |
import matplotlib.pyplot as plt | |
import tensorflow as tf | |
from tensorflow.contrib import slim | |
from tensorflow.contrib.slim import arg_scope | |
import logging | |
from src import utils | |
import src.file_utils as fu | |
from tfcode import tf_utils | |
resnet_v2 = tf_utils.resnet_v2 | |
custom_residual_block = tf_utils.custom_residual_block | |
def value_iteration_network( | |
fr, num_iters, val_neurons, action_neurons, kernel_size, share_wts=False, | |
name='vin', wt_decay=0.0001, activation_fn=None, shape_aware=False): | |
""" | |
Constructs a Value Iteration Network, convolutions and max pooling across | |
channels. | |
Input: | |
fr: NxWxHxC | |
val_neurons: Number of channels for maintaining the value. | |
action_neurons: Computes action_neurons * val_neurons at each iteration to | |
max pool over. | |
Output: | |
value image: NxHxWx(val_neurons) | |
""" | |
init_var = np.sqrt(2.0/(kernel_size**2)/(val_neurons*action_neurons)) | |
vals = [] | |
with tf.variable_scope(name) as varscope: | |
if shape_aware == False: | |
fr_shape = tf.unstack(tf.shape(fr)) | |
val_shape = tf.stack(fr_shape[:-1] + [val_neurons]) | |
val = tf.zeros(val_shape, name='val_init') | |
else: | |
val = tf.expand_dims(tf.zeros_like(fr[:,:,:,0]), dim=-1) * \ | |
tf.constant(0., dtype=tf.float32, shape=[1,1,1,val_neurons]) | |
val_shape = tf.shape(val) | |
vals.append(val) | |
for i in range(num_iters): | |
if share_wts: | |
# The first Value Iteration maybe special, so it can have its own | |
# paramterss. | |
scope = 'conv' | |
if i == 0: scope = 'conv_0' | |
if i > 1: varscope.reuse_variables() | |
else: | |
scope = 'conv_{:d}'.format(i) | |
val = slim.conv2d(tf.concat([val, fr], 3, name='concat_{:d}'.format(i)), | |
num_outputs=action_neurons*val_neurons, | |
kernel_size=kernel_size, stride=1, activation_fn=activation_fn, | |
scope=scope, normalizer_fn=None, | |
weights_regularizer=slim.l2_regularizer(wt_decay), | |
weights_initializer=tf.random_normal_initializer(stddev=init_var), | |
biases_initializer=tf.zeros_initializer()) | |
val = tf.reshape(val, [-1, action_neurons*val_neurons, 1, 1], | |
name='re_{:d}'.format(i)) | |
val = slim.max_pool2d(val, kernel_size=[action_neurons,1], | |
stride=[action_neurons,1], padding='VALID', | |
scope='val_{:d}'.format(i)) | |
val = tf.reshape(val, val_shape, name='unre_{:d}'.format(i)) | |
vals.append(val) | |
return val, vals | |
def rotate_preds(loc_on_map, relative_theta, map_size, preds, | |
output_valid_mask): | |
with tf.name_scope('rotate'): | |
flow_op = tf_utils.get_flow(loc_on_map, relative_theta, map_size=map_size) | |
if type(preds) != list: | |
rotated_preds, valid_mask_warps = tf_utils.dense_resample(preds, flow_op, | |
output_valid_mask) | |
else: | |
rotated_preds = [] ;valid_mask_warps = [] | |
for pred in preds: | |
rotated_pred, valid_mask_warp = tf_utils.dense_resample(pred, flow_op, | |
output_valid_mask) | |
rotated_preds.append(rotated_pred) | |
valid_mask_warps.append(valid_mask_warp) | |
return rotated_preds, valid_mask_warps | |
def get_visual_frustum(map_size, shape_like, expand_dims=[0,0]): | |
with tf.name_scope('visual_frustum'): | |
l = np.tril(np.ones(map_size)) ;l = l + l[:,::-1] | |
l = (l == 2).astype(np.float32) | |
for e in expand_dims: | |
l = np.expand_dims(l, axis=e) | |
confs_probs = tf.constant(l, dtype=tf.float32) | |
confs_probs = tf.ones_like(shape_like, dtype=tf.float32) * confs_probs | |
return confs_probs | |
def deconv(x, is_training, wt_decay, neurons, strides, layers_per_block, | |
kernel_size, conv_fn, name, offset=0): | |
"""Generates a up sampling network with residual connections. | |
""" | |
batch_norm_param = {'center': True, 'scale': True, | |
'activation_fn': tf.nn.relu, | |
'is_training': is_training} | |
outs = [] | |
for i, (neuron, stride) in enumerate(zip(neurons, strides)): | |
for s in range(layers_per_block): | |
scope = '{:s}_{:d}_{:d}'.format(name, i+1+offset,s+1) | |
x = custom_residual_block(x, neuron, kernel_size, stride, scope, | |
is_training, wt_decay, use_residual=True, | |
residual_stride_conv=True, conv_fn=conv_fn, | |
batch_norm_param=batch_norm_param) | |
stride = 1 | |
outs.append((x,True)) | |
return x, outs | |
def fr_v2(x, output_neurons, inside_neurons, is_training, name='fr', | |
wt_decay=0.0001, stride=1, updates_collections=tf.GraphKeys.UPDATE_OPS): | |
"""Performs fusion of information between the map and the reward map. | |
Inputs | |
x: NxHxWxC1 | |
Outputs | |
fr map: NxHxWx(output_neurons) | |
""" | |
if type(stride) != list: | |
stride = [stride] | |
with slim.arg_scope(resnet_v2.resnet_utils.resnet_arg_scope( | |
is_training=is_training, weight_decay=wt_decay)): | |
with slim.arg_scope([slim.batch_norm], updates_collections=updates_collections) as arg_sc: | |
# Change the updates_collections for the conv normalizer_params to None | |
for i in range(len(arg_sc.keys())): | |
if 'convolution' in arg_sc.keys()[i]: | |
arg_sc.values()[i]['normalizer_params']['updates_collections'] = updates_collections | |
with slim.arg_scope(arg_sc): | |
bottleneck = resnet_v2.bottleneck | |
blocks = [] | |
for i, s in enumerate(stride): | |
b = resnet_v2.resnet_utils.Block( | |
'block{:d}'.format(i + 1), bottleneck, [{ | |
'depth': output_neurons, | |
'depth_bottleneck': inside_neurons, | |
'stride': stride[i] | |
}]) | |
blocks.append(b) | |
x, outs = resnet_v2.resnet_v2(x, blocks, num_classes=None, global_pool=False, | |
output_stride=None, include_root_block=False, | |
reuse=False, scope=name) | |
return x, outs | |