def build_layer(K): with arg_scope( [slim.fully_connected], trainable=False, normalizer_fn=None, normalizer_params=None, biases_initializer=None, biases_regularizer=None ): #make first layer clean, no BN no biases no activation func layer1_name = LayerName(layer_name + '_sep_K' + str(K)) net = slim.fully_connected(input_, K, weights_initializer=initializer, trainable=is_training, activation_fn=None, scope=layer1_name) layer2_name = LayerName(layer_name + '_K' + str(K)) with slim.arg_scope(resnet_arg_scope(is_training=False)): with arg_scope([slim.fully_connected], trainable=False, normalizer_fn=None, normalizer_params=None ): #make second layer no BN but with biases net = slim.fully_connected(net, num_outputs, weights_initializer=initializer, trainable=is_training, scope=layer2_name) return net
def build_layer(K): with arg_scope( [slim.conv2d], weights_regularizer=None, weights_initializer=None, trainable=False, activation_fn=None, normalizer_fn=None, normalizer_params=None, biases_initializer=None ): #make first layer clean, no BN no biases no activation func layer1_name = LayerName(layer_name + '_sep_K' + str(K)) net = conv2d_same(inputs, K, kernel_size=(kernel_size, 1), stride=[stride, 1], scope=layer1_name) layer2_name = LayerName(layer_name + '_K' + str(K)) with slim.arg_scope(resnet_arg_scope(is_training=False)): net = conv2d_same(net, num_output_channels, kernel_size=(1, kernel_size), stride=[1, stride], scope=layer2_name) return net
def fully_connected(self, input_, num_outputs, is_training, initializer, layer_name): if layer_name not in self._net_desc: return super(resnetv1_sep, self).fully_connected(input_, num_outputs, is_training, initializer, layer_name) K = self._net_desc[layer_name] layer1_name = LayerName(layer_name + '_sep_K'+str(K)) with arg_scope( [slim.fully_connected], trainable=False, normalizer_fn=None, normalizer_params=None, biases_initializer=None, biases_regularizer=None): #make first layer clean, no BN no biases no activation func net = slim.fully_connected(input_, K, weights_initializer=initializer, trainable=is_training, activation_fn=None, scope=layer1_name) layer2_name = LayerName(layer_name) # layer2_name = LayerName(layer_name + '_K'+str(K)) with slim.arg_scope(resnet_arg_scope(is_training=False)): with arg_scope( [slim.fully_connected], trainable=False, normalizer_fn=None, normalizer_params=None): #make second layer no BN but with biases net = slim.fully_connected(net, num_outputs, weights_initializer=initializer, trainable=is_training, scope=layer2_name) return net
def build_layer(K): with arg_scope( [slim.conv2d], trainable=False, normalizer_fn=None, normalizer_params=None, biases_initializer=None, biases_regularizer=None ): #make first layer clean, no BN no biases no activation func layer1_name = LayerName(layer_name + '_sep_K' + str(K)) net = slim.conv2d(net_conv4, K, [3, 1], trainable=is_training, weights_initializer=initializer, scope=layer1_name) layer2_name = LayerName(layer_name + '_K' + str(K)) with slim.arg_scope(resnet_arg_scope(is_training=False)): with arg_scope([slim.conv2d], trainable=False, normalizer_fn=None, normalizer_params=None ): #make second layer no BN but with biases net = slim.conv2d(net, 512, [1, 3], trainable=is_training, weights_initializer=initializer, scope=layer2_name) return net
def rpn_convolution(self, net_conv4, is_training, initializer): layer_name = 'rpn_conv/3x3' if layer_name not in self._net_desc: return super(resnetv1_sep, self).rpn_convolution(net_conv4, is_training, initializer) K = self._net_desc[layer_name] layer1_name = LayerName(layer_name + '_sep_K'+str(K)) with arg_scope( [slim.conv2d], trainable=False, normalizer_fn=None, normalizer_params=None, biases_initializer=None, biases_regularizer=None): #make first layer clean, no BN no biases no activation func net = slim.conv2d(net_conv4, K, [3, 1], trainable=is_training, weights_initializer=initializer, scope=layer1_name) layer2_name = LayerName(layer_name) # layer2_name = LayerName(layer_name + '_K'+str(K)) with slim.arg_scope(resnet_arg_scope(is_training=False)): with arg_scope( [slim.conv2d], trainable=False, normalizer_fn=None, normalizer_params=None): #make second layer no BN but with biases net = slim.conv2d(net, 512, [1, 3], trainable=is_training, weights_initializer=initializer, scope=layer2_name) return net
def _assign_trained_weights_to_separable_layers(self): all_ops = [] with tf.variable_scope(self._net_sep.get_scope(), reuse=True): for layer_name, K in self._net_desc.items(): source_weights = self._base_weights_dict[layer_name] layer1_name = LayerName(layer_name + '_sep_K%d/weights' % (K)) dest_weights_1 = tf.get_variable(layer1_name.layer_weights()) dest_weights_2 = tf.get_variable(layer_name.layer_weights()) ops = self._get_assign_ops(source_weights, dest_weights_1, dest_weights_2, K) all_ops.extend(ops) self._sess.run(all_ops)
def _assign_trained_weights_to_unchanged_layers(self): with tf.variable_scope(self._net_sep.get_scope(), reuse=True): restore_var_dict = {} for v in self._base_variables: name_full = v.op.name layer_name = LayerName(name_full, 'net_layer_weights') # if layer_name in self._net_desc: # continue #skip compressed layers and their BatchNorm params # print(name_full + ' ' + layer_name ) restore_var_dict[name_full] = tf.get_variable(layer_name.layer_weights()) saver = tf.train.Saver(restore_var_dict) saver.restore(self._sess, self._saved_model_path)
def separate_1x1_conv_layer(self, inputs, num_outputs, stride, layer_name, scope): # int_scope = scope + '_sep' with arg_scope( [layers.conv2d], trainable=False, normalizer_fn=None, normalizer_params=None, biases_initializer=None, biases_regularizer=None): #make first layer clean, no BN no biases no activation func K = self._net_desc[layer_name] layer1_name = LayerName(scope + '_sep_K'+str(K)) intermediate = layers.conv2d(inputs, K, [1, 1], stride=1, scope=layer1_name) layer2_name = LayerName(scope) # layer2_name = LayerName(scope + '_K'+str(K)) with arg_scope( [layers.conv2d], trainable=False): #make second layer with BN but with no biases net = layers.conv2d(intermediate, num_outputs, [1, 1], stride=stride, scope=layer2_name) return net
def filter_active_path(self, stats, print_results=True): self._active_children = [] self._inactive_children = [] for child in sorted(stats.children, key=lambda child: child.name): # print(child.name) try: profile_layer = LayerName(child.name, 'net_layer_weights') except ValueError as errno: print("{0}: ValueError error({1})".format(child.name, errno)) continue #is a non-layer e.g. Placeholder variable child_is_active = False if profile_layer.is_compressed(): profile_layer_uncomp = profile_layer.uncompressed_version() if profile_layer_uncomp in self._net_desc: profile_K = profile_layer.K() if profile_K == self._net_desc[profile_layer_uncomp][0]: child_is_active = True #this is a compressed layer in the active path else: profile_layer_no_bn = profile_layer.remove_batch_norm().remove_biases() if profile_layer_no_bn not in self._net_desc: child_is_active = True #this is an uncompressed layer in the active path if child_is_active: self._active_children.append(child) else: self._inactive_children.append(child) if print_results: print('\n%d Active layers:'%(len(self._active_children))) for child in sorted(self._active_children, key=lambda child: child.name): print(child.name) print('\n%d Inactive layers:'%(len(self._inactive_children))) for child in sorted(self._inactive_children, key=lambda child: child.name): print(child.name)
def print_comparison(self, base, statsname, attrname): try: if hasattr(self, '_active_children'): this_total = 0 base_total = 0 base_children = getattr( getattr(base, statsname), 'children') for child in sorted(self._active_children, key=lambda child: child.name): cn = LayerName(child.name, flag='net_layer') value = getattr(child, attrname) this_total += value base_value = -1 for i, bc in enumerate(base_children): try: bcn = LayerName(bc.name, flag='net_layer') except ValueError as errno: continue if bcn==cn: base_value = getattr(bc, attrname) base_total += base_value base_children.pop(i) break print('%d\t%d\t%d\t%s'%(base_value-value, value,base_value,cn)) print('Totals: %d\t%d'%(this_total,base_total)) print('\nUnmatched base nodes:') for i, bc in enumerate(base_children): base_value = getattr(bc, attrname) print('%d\t%s'%(base_value,bc.name)) else: this_total = getattr( getattr(self, statsname), attrname) base_total = getattr( getattr(base, statsname), attrname) return this_total - base_total, (this_total - base_total)/base_total except AttributeError as errno: print("AttributeError error({0})".format(errno)) return None
def build_base(self): layer_name = LayerName('conv1') if layer_name in self._net_desc: with tf.variable_scope(self._resnet_scope, self._resnet_scope): net = self.separate_conv_layer(self._image, 64, 7, 2, rate=None, layer_name=layer_name, full_layer_name=layer_name) end_points_collection = self._resnet_scope + '_end_points' utils.collect_named_outputs(end_points_collection, self._resnet_scope+'/conv1', net) net = tf.pad(net, [[0, 0], [1, 1], [1, 1], [0, 0]], name='Pad_1') net = slim.max_pool2d(net, [3, 3], stride=2, padding='VALID', scope='pool1') else: net = super(resnetv1_sep, self).build_base() return net
def separate_conv_layer(self, inputs, num_output_channels, kernel_size, stride, rate, layer_name, full_layer_name): with arg_scope( [slim.conv2d], weights_regularizer=None, weights_initializer=None, trainable=False, activation_fn=None, normalizer_fn=None, normalizer_params=None, biases_initializer=None): #make first layer clean, no BN no biases no activation func K = self._net_desc[full_layer_name] layer1_name = LayerName(layer_name + '_sep_K'+str(K)) net = conv2d_same(inputs, K, kernel_size=(kernel_size,1), stride=[stride,1], scope=layer1_name, pad_name='Pad_sep1') layer2_name = LayerName(layer_name) # layer2_name = LayerName(layer_name + '_K'+str(K)) with slim.arg_scope(resnet_arg_scope(is_training=False)): net = conv2d_same(net, num_output_channels, kernel_size=(1,kernel_size), stride=[1,stride], scope=layer2_name, pad_name='Pad_sep2') return net
def _assign_trained_weights_to_separable_layers(self): all_ops = [] with tf.variable_scope(self._net_sep.get_scope(), reuse=True): for layer_name, Ks in self._net_desc.items(): source_weights = self._base_weights_dict[layer_name] for K in Ks: layer1_name = LayerName(layer_name +'_sep_K' + str(K) + '/weights','layer_weights') layer2_name = LayerName(layer_name +'_K' + str(K) + '/weights','layer_weights') dest_weights_1 = tf.get_variable(layer1_name.layer_weights()) dest_weights_2 = tf.get_variable(layer2_name.layer_weights()) ops = self._get_assign_ops(source_weights, dest_weights_1, dest_weights_2, K) all_ops.extend(ops) for bn_type in ['beta','gamma','moving_mean','moving_variance']: try: dest_bn_var_name = layer_name+'_K' + str(K)+'/BatchNorm/'+bn_type dest_bn_var = tf.get_variable(dest_bn_var_name) source_bn_var_name = layer_name+'/BatchNorm/'+bn_type source_bn_var = self._comp_bn_vars_dict[source_bn_var_name] assign_op = tf.assign(dest_bn_var, source_bn_var) all_ops.append(assign_op) except ValueError: break #means this compressed layer doesn't have BatchNorm try: dest_bias_var_name = layer_name+'_K' + str(K)+'/biases' dest_bias_var = tf.get_variable(dest_bias_var_name) source_bias_var_name = layer_name+'/biases' source_bias_var = self._comp_bias_vars_dict[source_bias_var_name] assign_op = tf.assign(dest_bias_var, source_bias_var) all_ops.append(assign_op) except ValueError: continue #means this compressed layer doesn't have biases self._sess.run(all_ops)
def bottleneck(self, inputs, depth, depth_bottleneck, stride, rate=1, outputs_collections=None, scope=None): """Bottleneck residual unit variant with BN after convolutions. This is the original residual unit proposed in [1]. See Fig. 1(a) of [2] for its definition. Note that we use here the bottleneck variant which has an extra bottleneck layer. When putting together two consecutive ResNet blocks that use this unit, one should use stride = 2 in the last unit of the first block. Args: inputs: A tensor of size [batch, height, width, channels]. depth: The depth of the ResNet unit output. depth_bottleneck: The depth of the bottleneck layers. stride: The ResNet unit's stride. Determines the amount of downsampling of the units output compared to its input. rate: An integer, rate for atrous convolution. outputs_collections: Collection to add the ResNet unit output. scope: Optional variable_scope. Returns: The ResNet unit's output. """ with variable_scope.variable_scope(scope, 'bottleneck_v1', [inputs]) as sc: depth_in = utils.last_dimension(inputs.get_shape(), min_rank=4) if depth == depth_in: shortcut = resnet_utils.subsample(inputs, stride, 'shortcut') else: layer_name = LayerName(sc.name + '/shortcut', 'net_layer') if layer_name in self._net_desc: shortcut = self.separate_1x1_conv_layer(inputs, depth, stride, layer_name, scope='shortcut') else: shortcut = layers.conv2d(inputs, depth, [1, 1], stride=stride, activation_fn=None, scope='shortcut') layer_name = LayerName(sc.name + '/conv1', 'net_layer') if layer_name in self._net_desc: residual = self.separate_1x1_conv_layer(inputs, depth_bottleneck, 1, layer_name, scope='conv1') else: residual = layers.conv2d(inputs, depth_bottleneck, [1, 1], stride=1, scope='conv1') layer_name = LayerName(sc.name + '/conv2', 'net_layer') if layer_name in self._net_desc: residual = self.separate_conv_layer(residual, depth_bottleneck, 3, stride, rate=rate, layer_name='conv2', full_layer_name=layer_name) else: residual = resnet_utils.conv2d_same(residual, depth_bottleneck, 3, stride, rate=rate, scope='conv2') layer_name = LayerName(sc.name + '/conv3', 'net_layer') if layer_name in self._net_desc: residual = self.separate_1x1_conv_layer(residual, depth, 1, layer_name, scope='conv3') else: residual = layers.conv2d(residual, depth, [1, 1], stride=1, activation_fn=None, scope='conv3') output = nn_ops.relu(shortcut + residual) return utils.collect_named_outputs(outputs_collections, sc.name, output)