def conv_dw(model, inputs, inp, oup, stride, name): W_dw = model.create_param(param_name=name + '_dw_w', shape=[inp, 1, 3, 3], initializer=initializers.update_initializer( None, None, ("XavierFill", {})), tags=ParameterTags.WEIGHT) h = inputs.Conv([W_dw], [name + '_dw'], kernel_h=3, kernel_w=3, stride_h=stride, stride_w=stride, pad_b=1, pad_l=1, pad_r=1, pad_t=1, order='NCHW', group=inp) h = brew.spatial_bn(model, h, name + '_dw_bn', inp, is_test=True) h = brew.relu(model, h, h) h = brew.conv(model, h, name + '_sep', dim_in=inp, dim_out=oup, kernel=1, pad=0, stride=1, no_bias=True) h = brew.spatial_bn(model, h, name + '_sep_bn', oup, is_test=True) h = brew.relu(model, h, h) return h
def testShapeInferenceConvNet(self): model = model_helper.ModelHelper(name="convtest") model.NHWC2NCHW("data", "data_nchw") brew.conv(model, "data_nchw", 'conv1', 3, 64, weight_init=("MSRAFill", {}), kernel=7, stride=2, pad=3, no_bias=0) brew.spatial_bn(model, 'conv1', 'conv1_spatbn_relu', 64, epsilon=1e-3, is_test=False) brew.relu(model, 'conv1_spatbn_relu', 'conv1_spatbn_relu') brew.max_pool(model, 'conv1_spatbn_relu', 'pool1', kernel=3, stride=2) brew.fc(model, 'pool1', 'fc', dim_in=(64 * 56 * 56), dim_out=100) brew.dropout(model, 'fc', 'fc_drop', is_test=False) model.Sigmoid('fc_drop', 'fc_sigm') brew.softmax(model, 'fc_sigm', 'softmax') model.LabelCrossEntropy(['softmax', 'label'], 'xent') loss = model.AveragedLoss('xent', 'loss') model.AddGradientOperators([loss]) LR = model.param_init_net.ConstantFill([], 'LR', shape=[1], value=0.1) for param in model.GetParams(): param_grad = model.param_to_grad[param] param_momentum = model.param_init_net.ConstantFill([param], param + '_momentum', value=0.0) model.net.MomentumSGDUpdate( [param_grad, param_momentum, LR, param], [param_grad, param_momentum, param], ) workspace.FeedBlob( "data", np.random.rand(16, 227, 227, 3).astype(np.float32), ) workspace.FeedBlob( "label", (100 * np.random.rand(16)).astype(np.int32), ) workspace.FeedBlob( "label", (100 * np.random.rand(16)).astype(np.int32), ) # Then do automatic comparison test: run the next once to # initialize everything self.InferTensorRunAndCompare(model)
def simple_cnn(): model = ModelHelper(name="r", arg_scope={"order": "NCHW", "is_test": True}) brew.conv( model, "data", 'conv1', 3, 16, kernel=3, stride=1 ) brew.spatial_bn( model, 'conv1', 'conv1_spatbn', 16, epsilon=1e-3 ) brew.relu(model, 'conv1_spatbn', 'relu1') return model, (1, 3, 32, 32)
def create_resnet( model, data, num_input_channels, num_groups, num_labels, device_opts, is_test=False, ): with core.DeviceScope(device_opts): filters = [16, 32, 64] brew.conv(model, data, 'conv1', num_input_channels, filters[0], no_bias=1, kernel=3, stride=1, pad=1) builder = ResNetBuilder(model, 'conv1', no_bias=1, is_test=is_test) # input: 32x32x16 output: 32x32x16 for _ in range(num_groups): builder.add_simple_block(filters[0], filters[0], down_sampling=False) # input: 32x32x16 output: 16x16x32 builder.add_simple_block(filters[0], filters[1], down_sampling=True) for _ in range(1, num_groups): builder.add_simple_block(filters[1], filters[1], down_sampling=False) # input: 16x16x32 output: 8x8x64 builder.add_simple_block(filters[1], filters[2], down_sampling=True) for _ in range(1, num_groups): builder.add_simple_block(filters[2], filters[2], down_sampling=False) brew.spatial_bn(model, builder.prev_blob, 'last_spatbn', filters[2], epsilon=1e-3, is_test=is_test) brew.relu(model, 'last_spatbn', 'last_relu') # Final layers brew.average_pool(model, 'last_relu', 'final_avg', kernel=8, stride=1) last_out = brew.fc(model, 'final_avg', 'last_out', 64, num_labels) return last_out
def AddMLP(model, data, batch_size): ''' Implement MLP model on MNIST ''' num_units = 4096 # number of nuerons in fc layer num_labels = 10 # for 10 classes in mnist drop1 = brew.dropout(model, data, 'drop1', ratio=0.5, is_test=0) fc2 = brew.fc(model, drop1, 'fc2', dim_in=1 * 28 * 28, dim_out=num_units) model.Reshape([fc2], [fc2, 'fc2_old_shape'], shape=(batch_size, num_units, 1, 1)) bn2 = brew.spatial_bn(model, fc2, 'bn2', num_units, epsilon=1e-4, momentum=0.9) relu2 = brew.relu(model, bn2, 'relu2') fc3 = brew.fc(model, relu2, 'fc3', dim_in=num_units, dim_out=num_units) model.Reshape([fc3], [fc3, 'fc3_old_shape'], shape=(batch_size, num_units, 1, 1)) bn3 = brew.spatial_bn(model, fc3, 'bn3', num_units, epsilon=1e-4, momentum=0.9) relu3 = brew.relu(model, bn3, 'relu3') fc4 = brew.fc(model, relu3, 'fc4', dim_in=num_units, dim_out=num_units) model.Reshape([fc4], [fc4, 'fc4_old_shape'], shape=(batch_size, num_units, 1, 1)) bn4 = brew.spatial_bn(model, fc4, 'bn4', num_units, epsilon=1e-4, momentum=0.9) relu4 = brew.relu(model, bn4, 'relu4') fc5 = brew.fc(model, relu4, 'fc5', dim_in=num_units, dim_out=num_labels) model.Reshape([fc5], [fc5, 'fc5_old_shape'], shape=(batch_size, num_labels, 1, 1)) bn5 = brew.spatial_bn(model, fc5, 'bn5', num_labels, epsilon=1e-4, momentum=0.9) softmax = brew.softmax(model, bn5, 'softmax') return softmax
def ConvBN( # args in the same order of Conv() self, blob_in, prefix, dim_in, dim_out, kernel, stride, pad, group=1, dilation=1, weight_init=None, bias_init=None, suffix='_bn' ): """ ConvBN adds a Conv op followed by a SpatialBN op. """ conv_blob = self.Conv( blob_in, prefix, dim_in, dim_out, kernel, stride=stride, pad=pad, group=group, dilation=dilation, weight_init=weight_init, bias_init=bias_init, no_bias=1 ) blob_out = brew.spatial_bn( self, conv_blob, prefix + suffix, dim_out, is_test= not self.train ) return blob_out
def conv_factory(self, model, v, num_in_channels, num_filters, kernel, stride=1, pad=0, relu=True, name='conv'): """Standard convolution block: Conv -> BatchNorm -> Activation """ if isinstance(pad, int): pad_t = pad_b = pad_l = pad_r = pad elif isinstance(pad, list) or isinstance(pad, tuple): if len(pad) == 2: pad_t = pad_b = pad[0] pad_l = pad_r = pad[1] elif len(pad) == 4: pad_t = pad[0] pad_b = pad[1] pad_l = pad[2] pad_r = pad[3] else: assert False, "Invalid length of pad array. Expecting 2 or 4 but have: " + str(pad) else: assert False, "Invalid type of padding: " + str(pad) v = brew.conv(model, v, name + '_conv', num_in_channels, num_filters, kernel=kernel, pad_t=pad_t, pad_l=pad_l, pad_b=pad_b, pad_r=pad_r, stride=stride) v = brew.spatial_bn(model, v, name+'_bn', num_filters, eps=2e-5, momentum=0.9, is_test=(self.phase == 'inference')) if relu is True: v = brew.relu(model, v, name + '_relu') return v
def create_resnet20(model, data, num_input_channels=3, num_labels=10, is_test=False): ''' Create residual net for cifar-10/100 num_groups = 3 ''' # conv1 + maxpool, input=32x32x3, output=32x32x16 brew.conv(model, data, 'conv1', num_input_channels, 16, kernel=3, stride=1) brew.spatial_bn(model, 'conv1', 'conv1_spatbn', 16, epsilon=1e-3, is_test=is_test) brew.relu(model, 'conv1_spatbn', 'relu1') builder = ResNet20Builder(model, 'relu1', is_test=is_test) # conv2, output=32x32x16 builder.add_simple_block(16, 16) builder.add_simple_block(16, 16) builder.add_simple_block(16, 16) #conv3, output=16x16x32 builder.add_simple_block(16, 32, down_sampling=True) builder.add_simple_block(32, 32) builder.add_simple_block(32, 32) #conv4, output=8x8x64 builder.add_simple_block(32, 64, down_sampling=True) builder.add_simple_block(64, 64) builder.add_simple_block(64, 64) # avg_pool output=1x1, 64 brew.average_pool(model, builder.prev_blob, 'final_avg', kernel=8, stride=1) # fc layer output=1x1x(num_labels) brew.fc(model, 'final_avg', 'last_out', 64, num_labels) softmax = brew.softmax(model, 'last_out', 'softmax') return softmax
def testShapeInferenceConvNet(self): model = model_helper.ModelHelper(name="convtest") model.NHWC2NCHW("data", "data_nchw") brew.conv(model, "data_nchw", 'conv1', 3, 64, weight_init=("MSRAFill", {}), kernel=7, stride=2, pad=3, no_bias=0) brew.spatial_bn(model, 'conv1', 'conv1_spatbn_relu', 64, epsilon=1e-3, is_test=False) brew.relu(model, 'conv1_spatbn_relu', 'conv1_spatbn_relu') brew.max_pool(model, 'conv1_spatbn_relu', 'pool1', kernel=3, stride=2) brew.fc(model, 'pool1', 'fc', dim_in=(64 * 56 * 56), dim_out=100) brew.dropout(model, 'fc', 'fc_drop', is_test=False) model.Sigmoid('fc_drop', 'fc_sigm') brew.softmax(model, 'fc_sigm', 'softmax') model.LabelCrossEntropy(['softmax', 'label'], 'xent') loss = model.AveragedLoss('xent', 'loss') model.AddGradientOperators([loss]) LR = model.param_init_net.ConstantFill( [], 'LR', shape=[1], value=0.1 ) for param in model.GetParams(): param_grad = model.param_to_grad[param] param_momentum = model.param_init_net.ConstantFill( [param], param + '_momentum', value=0.0 ) model.net.MomentumSGDUpdate( [param_grad, param_momentum, LR, param], [param_grad, param_momentum, param], ) workspace.FeedBlob( "data", np.random.rand(16, 227, 227, 3).astype(np.float32), ) workspace.FeedBlob( "label", (100 * np.random.rand(16)).astype(np.int32), ) workspace.FeedBlob( "label", (100 * np.random.rand(16)).astype(np.int32), ) # Then do automatic comparison test: run the next once to # initialize everything self.InferTensorRunAndCompare(model)
def add_simple_block( self, input_filters, num_filters, down_sampling=False, spatial_batch_norm=True ): self.comp_idx = 0 shortcut_blob = self.prev_blob # 3x3 self.add_conv( input_filters, num_filters, kernel=3, stride=(1 if down_sampling is False else 2), pad=1 ) if spatial_batch_norm: self.add_spatial_bn(num_filters) self.add_relu() last_conv = self.add_conv(num_filters, num_filters, kernel=3, pad=1) if spatial_batch_norm: last_conv = self.add_spatial_bn(num_filters) # Increase of dimensions, need a projection for the shortcut if (num_filters != input_filters): shortcut_blob = brew.conv( self.model, shortcut_blob, 'shortcut_projection_%d' % self.comp_count, input_filters, num_filters, weight_init=("MSRAFill", {}), kernel=1, stride=(1 if down_sampling is False else 2), no_bias=self.no_bias, ) if spatial_batch_norm: shortcut_blob = brew.spatial_bn( self.model, shortcut_blob, 'shortcut_projection_%d_spatbn' % self.comp_count, num_filters, epsilon=1e-3, is_test=self.is_test, ) self.prev_blob = brew.sum( self.model, [shortcut_blob, last_conv], 'comp_%d_sum_%d' % (self.comp_count, self.comp_idx) ) self.comp_idx += 1 self.add_relu() # Keep track of number of high level components if this ResNetBuilder self.comp_count += 1
def add_simple_block( self, input_filters, num_filters, down_sampling=False, spatial_batch_norm=True ): self.comp_idx = 0 shortcut_blob = self.prev_blob # 3x3 self.add_conv( input_filters, num_filters, kernel=3, stride=(1 if down_sampling is False else 2), pad=1 ) if spatial_batch_norm: self.add_spatial_bn(num_filters) self.add_relu() last_conv = self.add_conv(num_filters, num_filters, kernel=3, pad=1) if spatial_batch_norm: last_conv = self.add_spatial_bn(num_filters) # Increase of dimensions, need a projection for the shortcut if (num_filters != input_filters): shortcut_blob = brew.conv( self.model, shortcut_blob, 'shortcut_projection_%d' % self.comp_count, input_filters, num_filters, weight_init=("MSRAFill", {}), kernel=1, stride=(1 if down_sampling is False else 2), no_bias=self.no_bias, ) if spatial_batch_norm: shortcut_blob = brew.spatial_bn( self.model, shortcut_blob, 'shortcut_projection_%d_spatbn' % self.comp_count, num_filters, epsilon=1e-3, is_test=self.is_test, ) self.prev_blob = brew.sum( self.model, [shortcut_blob, last_conv], 'comp_%d_sum_%d' % (self.comp_count, self.comp_idx) ) self.comp_idx += 1 self.add_relu() # Keep track of number of high level components if this ResNetBuilder self.comp_count += 1
def input_block( model, inputs, dim_in, dim_out, kernel, pad, stride, no_bias=False, is_test=False, ): ''' add input conv module (separated out due to the name of predict.pbtxt) ''' # convolution layer conv = brew.conv( model, inputs, 'conv1', dim_in=dim_in, dim_out=dim_out, kernel=kernel, pad=pad, stride=stride, no_bias=no_bias ) # spaial batchnormalization layer bn = brew.spatial_bn( model, conv, 'res_conv1_bn', # conv, # in-place dim_in = dim_out, epsilon = 1e-05, is_test = is_test, ) # ReLU layer relu = brew.relu( model, bn, bn # in-place ) # max pool pool = brew.max_pool( model, relu, 'pool1', kernel=3, stride=2, pad=1, ) return pool
def add_spatial_bn(self, num_filters): self.prev_blob = brew.spatial_bn( self.model, self.prev_blob, 'comp_%d_spatbn_%d' % (self.comp_count, self.comp_idx), num_filters, epsilon=1e-3, is_test=self.is_test, ) return self.prev_blob
def create_resnet_32x32(model, data, num_input_channels, num_groups, num_labels, is_test=False): ''' Create residual net for smaller images (sec 4.2 of He et. al (2015)) num_groups = 'n' in the paper ''' # conv1 + maxpool brew.conv(model, data, 'conv1', num_input_channels, 16, kernel=3, stride=1) brew.spatial_bn(model, 'conv1', 'conv1_spatbn', 16, epsilon=1e-3, is_test=is_test) brew.relu(model, 'conv1_spatbn', 'relu1') # Number of blocks as described in sec 4.2 filters = [16, 32, 64] builder = ResNetBuilder(model, 'relu1', is_test=is_test) prev_filters = 16 for groupidx in range(0, 3): for blockidx in range(0, 2 * num_groups): builder.add_simple_block( prev_filters if blockidx == 0 else filters[groupidx], filters[groupidx], down_sampling=(True if blockidx == 0 and groupidx > 0 else False)) prev_filters = filters[groupidx] # Final layers brew.average_pool(model, builder.prev_blob, 'final_avg', kernel=8, stride=1) brew.fc(model, 'final_avg', 'last_out', 64, num_labels) softmax = brew.softmax(model, 'last_out', 'softmax') return softmax
def meta_conv( model, inputs, dim_in, dim_out, kernel, pad, stride, no_bias=False, is_test=False, has_relu=False, module_seq=None, # group seq sub_seq=None, # block seq branch_seq=None, conv_seq=None ): ''' add basic conv module of resnet 50 ''' # set projection branch if branch_seq == "2": # branch of 2 normal part conv_name = "conv{}".format(conv_seq) elif branch_seq == "1" : # branch of 1 projection part conv_name = "proj" # convolution layer conv = brew.conv( model, inputs, 'group{}_block{}_{}'.format(module_seq, sub_seq, conv_name), dim_in=dim_in, dim_out=dim_out, kernel=kernel, stride=stride, pad=pad, no_bias=no_bias, ) # spaial batchnormalization layer bn = brew.spatial_bn( model, conv, 'group{}_block{}_{}_bn'.format(module_seq, sub_seq, conv_name), # conv, # in-place dim_in = dim_out, epsilon = 1e-05, is_test = is_test, ) # ReLU layer if has_relu: relu = brew.relu(model, bn, bn) return relu else: return bn
def add_sp_batch_norm(self, filters): self.prev_blob = brew.spatial_bn( self.model, self.prev_blob, '%s_sp_batch_norm_%d' % (self.block_name, self.layer_num), filters, epsilon=1e-3, momentum=self.sp_batch_norm, is_test=self.is_test, ) return self.prev_blob
def add_spatial_bn(self, num_filters): self.prev_blob = brew.spatial_bn( self.model, self.prev_blob, 'comp_%d_spatbn_%d' % (self.comp_count, self.comp_idx), num_filters, epsilon=1e-3, momentum=self.spatial_bn_mom, is_test=self.is_test, ) return self.prev_blob
def test_spatialbn_brew_wrapper(self, size, input_channels, batch_size, seed, epsilon, engine, gc, dc): np.random.seed(seed) X = np.random.rand(batch_size, input_channels, size, size).astype(np.float32) workspace.FeedBlob('X', X) model = ModelHelper(name='test_spatialbn_brew_wrapper') brew.spatial_bn( model, 'X', 'Y', input_channels, epsilon=epsilon, is_test=False, ) workspace.RunNetOnce(model.param_init_net) workspace.RunNetOnce(model.net)
def add_spatial_bn(self, num_filters, suffix=''): self.prev_blob = brew.spatial_bn( self.model, self.prev_blob, '%scomp_%d_spatbn_%d%s' % (self.prefix, self.comp_count, self.comp_idx, suffix), num_filters, epsilon=1e-3, momentum=self.spatial_bn_mom, is_test=self.is_test, ) return self.prev_blob
def input_block_conv_topk( model, inputs, dim_in, dim_out, kernel, pad, stride, topk=5, no_bias=False, is_test=False, ): ''' add input conv module (separated out due to the name of predict.pbtxt) ''' # convolution layer conv = brew.conv( model, inputs, 'first_conv', dim_in=dim_in, dim_out=dim_out, kernel=kernel, pad=pad, stride=stride, no_bias=no_bias ) conv_hook = model.net.TopKGradHook( conv, 'first_conv_hook', k=topk, ) # spaial batchnormalization layer bn = brew.spatial_bn( model, conv_hook, 'first_conv_bn', # conv, # in-place dim_in = dim_out, epsilon = 1e-05, is_test = is_test, ) # ReLU layer relu = brew.relu( model, bn, bn # in-place ) return relu
def conv(self, model, name, inputs, input_depth, num_filters, kernel, stride, pad, is_inference): # Check padding if isinstance(pad, int): pad_t = pad_b = pad_l = pad_r = pad elif isinstance(pad, list) or isinstance(pad, tuple): if len(pad) == 2: pad_t = pad_b = pad[0] pad_l = pad_r = pad[1] elif len(pad) == 4: pad_t = pad[0] pad_b = pad[1] pad_l = pad[2] pad_r = pad[3] else: assert False, "Invalid length of pad array. Expecting 2 or 4 but have: " + str( pad) else: assert False, "Invalid type of padding: " + str(pad) # Check kernel if isinstance(kernel, int): kernel = [kernel, kernel] elif isinstance(kernel, tuple) or isinstance(kernel, list): assert len(kernel) == 2, "Kernel must have length 2" kernel = [kernel[0], kernel[1]] else: assert False, "Invalid type of kerne;: " + str(kernel) # self.counts[name] += 1 name = name + str(self.counts[name] - 1) # v = brew.conv(model, inputs, name + '_conv', input_depth, num_filters, kernel=kernel, stride=stride, pad_t=pad_t, pad_l=pad_l, pad_b=pad_b, pad_r=pad_r, no_bias=True) v = brew.spatial_bn(model, v, name + '_bn', num_filters, eps=2e-5, momentum=0.9, is_test=is_inference) v = brew.relu(model, v, name + '_relu') return v
def test_spatialbn_brew_wrapper( self, size, input_channels, batch_size, seed, epsilon, engine, gc, dc): np.random.seed(seed) X = np.random.rand( batch_size, input_channels, size, size).astype(np.float32) workspace.FeedBlob('X', X) model = ModelHelper(name='test_spatialbn_brew_wrapper') brew.spatial_bn( model, 'X', 'Y', input_channels, epsilon=epsilon, is_test=False, ) workspace.RunNetOnce(model.param_init_net) workspace.RunNetOnce(model.net)
def conv_bn(model, inputs, inp, oup, stride, name): h = brew.conv(model, inputs, name, dim_in=inp, dim_out=oup, kernel=3, pad=1, stride=stride, no_bias=True) h = brew.spatial_bn(model, h, name + '_bn', oup, is_test=True) h = brew.relu(model, h, h) return h
def add_simple_block(self, input_filters, num_filters, down_sampling=False, spatial_batch_norm=True): self.comp_idx = 0 shortcut_blob = self.prev_blob # 3x3 self.add_conv(input_filters, num_filters, kernel=3, stride=(1 if down_sampling is False else 2), pad=1) if spatial_batch_norm: self.add_spatial_bn(num_filters) self.add_relu() last_conv = self.add_conv(num_filters, num_filters, kernel=3, pad=1) if spatial_batch_norm: last_conv = self.add_spatial_bn(num_filters) if (num_filters != input_filters): shortcut_blob = brew.conv( self.model, shortcut_blob, 'shortcut_projection_%d' % self.comp_count, input_filters, num_filters, weight_init=("MSRAFill", {}), kernel=1, stride=(1 if down_sampling is False else 2), no_bias=self.no_bias, ) if spatial_batch_norm: shortcut_blob = brew.spatial_bn( self.model, shortcut_blob, 'shortcut_projection_%d_spatbn' % self.comp_count, num_filters, epsilon=1e-3, is_test=self.is_test, ) self.prev_blob = brew.sum( self.model, [shortcut_blob, last_conv], 'comp_%d_sum_%d' % (self.comp_count, self.comp_idx)) self.comp_idx += 1 self.add_relu() self.comp_count += 1
def create_resnet_32x32( model, data, num_input_channels, num_groups, num_labels, is_test=False ): ''' Create residual net for smaller images (sec 4.2 of He et. al (2015)) num_groups = 'n' in the paper ''' # conv1 + maxpool brew.conv( model, data, 'conv1', num_input_channels, 16, kernel=3, stride=1 ) brew.spatial_bn( model, 'conv1', 'conv1_spatbn', 16, epsilon=1e-3, is_test=is_test ) brew.relu(model, 'conv1_spatbn', 'relu1') # Number of blocks as described in sec 4.2 filters = [16, 32, 64] builder = ResNetBuilder(model, 'relu1', is_test=is_test) prev_filters = 16 for groupidx in range(0, 3): for blockidx in range(0, 2 * num_groups): builder.add_simple_block( prev_filters if blockidx == 0 else filters[groupidx], filters[groupidx], down_sampling=(True if blockidx == 0 and groupidx > 0 else False)) prev_filters = filters[groupidx] # Final layers brew.average_pool( model, builder.prev_blob, 'final_avg', kernel=8, stride=1 ) brew.fc(model, 'final_avg', 'last_out', 64, num_labels) softmax = brew.softmax(model, 'last_out', 'softmax') return softmax
def meta_conv( model, inputs, dim_in, dim_out, kernel, pad, stride, no_bias=False, is_test=False, has_relu=False, module_seq=None, sub_seq=None, branch_seq=None, conv_seq=None ): ''' add basic conv module of resnet 50 ''' # convolution layer conv = brew.conv( model, inputs, '{}_{}_branch{}{}'.format(module_seq, sub_seq, branch_seq, conv_seq), dim_in=dim_in, dim_out=dim_out, kernel=kernel, stride=stride, pad=pad, no_bias=no_bias, ) # spaial batchnormalization layer bn = brew.spatial_bn( model, conv, '{}_{}_branch{}{}_bn'.format(module_seq, sub_seq, branch_seq, conv_seq), # conv, # in-place dim_in = dim_out, epsilon = 1e-05, is_test = is_test, ) # ReLU layer if has_relu: relu = brew.relu(model, bn, bn) return relu else: return bn
def add_conv1x1_bn(self, prev_blob, blob, in_channels, out_channels): prev_blob = brew.conv(self.model, prev_blob, blob, in_channels, out_channels, kernel=1, weight_init=("MSRAFill", {})) prev_blob = brew.spatial_bn(self.model, prev_blob, prev_blob + '_bn', out_channels, epsilon=self.bn_epsilon, is_test=self.is_test) prev_blob = brew.relu(self.model, prev_blob, prev_blob) return prev_blob
def add_dwconv3x3_bn(self, prev_blob, blob, channels, stride): prev_blob = brew.conv(self.model, prev_blob, blob, channels, channels, kernel=3, weight_init=("MSRAFill", {}), stride=stride, group=channels, pad=1) prev_blob = brew.spatial_bn(self.model, prev_blob, prev_blob + '_bn', channels, epsilon=self.bn_epsilon, is_test=self.is_test) return prev_blob
def test_get_complete_net(self): model = model_helper.ModelHelper("test_orig") conv = brew.conv( model, "input", "conv", dim_in=3, dim_out=16, weight_init=("MSRAFill", {}), kernel=3, stride=1, pad=0, ) conv = brew.spatial_bn(model, conv, "conv_bn", 16, epsilon=1e-3, is_test=False) conv = brew.relu(model, conv, "conv_relu") pred = brew.fc(model, conv, "pred", dim_in=16 * 3 * 3, dim_out=10) brew.softmax(model, pred, "softmax") net = model.GetCompleteNet() model2 = model_helper.ModelHelper("test_new") model2.ConstructInitTrainNetfromNet(net) net = model.param_init_net net2 = model2.param_init_net for op1, op2 in zip(net.Proto().op, net2.Proto().op): op1.debug_info = op1.debug_info + "/param_init_net" self.assertEqual( op1, op2, "op mismatch between {}\n and {}\n".format(op1, op2)) net = model.net net2 = model2.net for op1, op2 in zip(net.Proto().op, net2.Proto().op): self.assertEqual( op1, op2, "op mismatch between {}\n and {}\n".format(op1, op2)) # this is not guaranteed in other situations where user define own net self.assertEqual( sorted(map(str, net.external_inputs)), sorted(map(str, net2.external_inputs)), )
def add_detection_unit(self, prev_blob, prefix, in_channels, out_channels, kernel=3, pad=1): out_blob = brew.conv(self.model, prev_blob, prefix + '_conv', in_channels, out_channels, kernel=kernel, weight_init=("MSRAFill", {}), group=in_channels, pad=pad) out_blob = brew.spatial_bn(self.model, out_blob, prefix + '_bn', out_channels, epsilon=self.bn_epsilon, is_test=self.is_test) return out_blob
def add_bottleneck( self, input_filters, # num of feature maps from preceding layer base_filters, # num of filters internally in the component output_filters, # num of feature maps to output down_sampling=False, spatial_batch_norm=True, ): self.comp_idx = 0 shortcut_blob = self.prev_blob # 1x1 self.add_conv(input_filters, base_filters, kernel=1, stride=1) if spatial_batch_norm: self.add_spatial_bn(base_filters) self.add_relu() # 3x3 (note the pad, required for keeping dimensions) self.add_conv(base_filters, base_filters, kernel=3, stride=(1 if down_sampling is False else 2), pad=1) if spatial_batch_norm: self.add_spatial_bn(base_filters) self.add_relu() # 1x1 last_conv = self.add_conv(base_filters, output_filters, kernel=1) if spatial_batch_norm: last_conv = self.add_spatial_bn(output_filters) # Summation with input signal (shortcut) # If we need to increase dimensions (feature maps), need to # do a projection for the short cut if (output_filters > input_filters): shortcut_blob = brew.conv( self.model, shortcut_blob, 'shortcut_projection_%d' % self.comp_count, input_filters, output_filters, weight_init=("MSRAFill", {}), kernel=1, stride=(1 if down_sampling is False else 2), no_bias=self.no_bias, ) if spatial_batch_norm: shortcut_blob = brew.spatial_bn( self.model, shortcut_blob, 'shortcut_projection_%d_spatbn' % self.comp_count, output_filters, epsilon=1e-3, momentum=self.spatial_bn_mom, is_test=self.is_test, ) self.prev_blob = brew.sum( self.model, [shortcut_blob, last_conv], 'comp_%d_sum_%d' % (self.comp_count, self.comp_idx)) self.comp_idx += 1 self.add_relu() # Keep track of number of high level components if this ResNetBuilder self.comp_count += 1
def create_mobilenet( model, data, num_input_channels, num_labels, label=None, is_test=False ): ''' Create residual net for smaller images (sec 4.2 of He et. al (2015)) num_groups = 'n' in the paper ''' # conv1 brew.conv( model, data, 'conv1', 3, 32, weight_init=("MSRAFill", {}), kernel=3, stride=2, pad=2, no_bias=False, ) brew.spatial_bn( model, 'conv1', 'conv1_spatbn', 32, epsilon=1e-3, is_test=is_test ) # brew.relu(model, 'conv1_spatbn', 'relu1') # builder = MobileNetBuilder(model, 'conv1_spatbn', is_test=is_test) builder = MobileNetBuilder(model, 'conv1_spatbn', no_bias=False, is_test=is_test) # block1 builder.add_simple_block(input_filters=32, output_filters=64, down_sampling=False, spatial_batch_norm=True) # block2 builder.add_simple_block(input_filters=64, output_filters=128, down_sampling=True, spatial_batch_norm=True) # block3 builder.add_simple_block(input_filters=128, output_filters=128, down_sampling=False, spatial_batch_norm=True) # block4 builder.add_simple_block(input_filters=128, output_filters=256, down_sampling=True, spatial_batch_norm=True) # block5 builder.add_simple_block(input_filters=256, output_filters=256, down_sampling=False, spatial_batch_norm=True) # block6 builder.add_simple_block(input_filters=256, output_filters=512, down_sampling=True, spatial_batch_norm=True) # block7-11 for i in xrange(7, 12): builder.add_simple_block(input_filters=512, output_filters=512, down_sampling=False, spatial_batch_norm=True) # block12 builder.add_simple_block(input_filters=512, output_filters=1024, down_sampling=True, spatial_batch_norm=True) # block13 builder.add_simple_block(input_filters=1024, output_filters=1024, down_sampling=False, spatial_batch_norm=True) # Final layers brew.average_pool( model, builder.prev_blob, 'final_avg', kernel=7, stride=7) last_out = brew.fc(model, 'final_avg', 'last_out', 1024, num_labels) if (label is not None): (softmax, loss) = model.SoftmaxWithLoss( [last_out, label], ['softmax', 'loss'], ) return (softmax, loss) else: return brew.softmax(model, 'last_out', 'softmax')
def SpatialBN(self, *args, **kwargs): return brew.spatial_bn(self, *args, order=self.order, **kwargs)
def create_resnet50( model, data, num_input_channels, num_labels, label=None, is_test=False, no_loss=False, no_bias=0, conv1_kernel=7, conv1_stride=2, final_avg_kernel=7, ): # conv1 + maxpool brew.conv( model, data, 'conv1', num_input_channels, 64, weight_init=("MSRAFill", {}), kernel=conv1_kernel, stride=conv1_stride, pad=3, no_bias=no_bias ) brew.spatial_bn( model, 'conv1', 'conv1_spatbn_relu', 64, epsilon=1e-3, momentum=0.1, is_test=is_test ) brew.relu(model, 'conv1_spatbn_relu', 'conv1_spatbn_relu') brew.max_pool(model, 'conv1_spatbn_relu', 'pool1', kernel=3, stride=2) # Residual blocks... builder = ResNetBuilder(model, 'pool1', no_bias=no_bias, is_test=is_test, spatial_bn_mom=0.1) # conv2_x (ref Table 1 in He et al. (2015)) builder.add_bottleneck(64, 64, 256) builder.add_bottleneck(256, 64, 256) builder.add_bottleneck(256, 64, 256) # conv3_x builder.add_bottleneck(256, 128, 512, down_sampling=True) for _ in range(1, 4): builder.add_bottleneck(512, 128, 512) # conv4_x builder.add_bottleneck(512, 256, 1024, down_sampling=True) for _ in range(1, 6): builder.add_bottleneck(1024, 256, 1024) # conv5_x builder.add_bottleneck(1024, 512, 2048, down_sampling=True) builder.add_bottleneck(2048, 512, 2048) builder.add_bottleneck(2048, 512, 2048) # Final layers final_avg = brew.average_pool( model, builder.prev_blob, 'final_avg', kernel=final_avg_kernel, stride=1, ) # Final dimension of the "image" is reduced to 7x7 last_out = brew.fc( model, final_avg, 'last_out_L{}'.format(num_labels), 2048, num_labels ) if no_loss: return last_out # If we create model for training, use softmax-with-loss if (label is not None): (softmax, loss) = model.SoftmaxWithLoss( [last_out, label], ["softmax", "loss"], ) return (softmax, loss) else: # For inference, we just return softmax return brew.softmax(model, last_out, "softmax")
def add_bottleneck( self, input_filters, # num of feature maps from preceding layer base_filters, # num of filters internally in the component output_filters, # num of feature maps to output down_sampling=False, spatial_batch_norm=True, ): self.comp_idx = 0 shortcut_blob = self.prev_blob # 1x1 self.add_conv( input_filters, base_filters, kernel=1, stride=1 ) if spatial_batch_norm: self.add_spatial_bn(base_filters) self.add_relu() # 3x3 (note the pad, required for keeping dimensions) self.add_conv( base_filters, base_filters, kernel=3, stride=(1 if down_sampling is False else 2), pad=1 ) if spatial_batch_norm: self.add_spatial_bn(base_filters) self.add_relu() # 1x1 last_conv = self.add_conv(base_filters, output_filters, kernel=1) if spatial_batch_norm: last_conv = self.add_spatial_bn(output_filters) # Summation with input signal (shortcut) # If we need to increase dimensions (feature maps), need to # do a projection for the short cut if (output_filters > input_filters): shortcut_blob = brew.conv( self.model, shortcut_blob, 'shortcut_projection_%d' % self.comp_count, input_filters, output_filters, weight_init=("MSRAFill", {}), kernel=1, stride=(1 if down_sampling is False else 2), no_bias=self.no_bias, ) if spatial_batch_norm: shortcut_blob = brew.spatial_bn( self.model, shortcut_blob, 'shortcut_projection_%d_spatbn' % self.comp_count, output_filters, epsilon=1e-3, momentum=self.spatial_bn_mom, is_test=self.is_test, ) self.prev_blob = brew.sum( self.model, [shortcut_blob, last_conv], 'comp_%d_sum_%d' % (self.comp_count, self.comp_idx) ) self.comp_idx += 1 self.add_relu() # Keep track of number of high level components if this ResNetBuilder self.comp_count += 1
def SpatialBN(self, *args, **kwargs): return brew.spatial_bn(self, *args, order=self.order, **kwargs)
def create_resnet152( model, data, num_input_channels, num_labels, label=None, is_test=False, no_loss=False, no_bias=0, conv1_kernel=7, conv1_stride=2, final_avg_kernel=7, ): # conv1 + maxpool brew.conv(model, data, 'conv1', num_input_channels, 64, weight_init=("MSRAFill", {}), kernel=conv1_kernel, stride=conv1_stride, pad=3, no_bias=no_bias) brew.spatial_bn(model, 'conv1', 'conv1_spatbn_relu', 64, epsilon=1e-3, momentum=0.1, is_test=is_test) brew.relu(model, 'conv1_spatbn_relu', 'conv1_spatbn_relu') brew.max_pool(model, 'conv1_spatbn_relu', 'pool1', kernel=3, stride=2) # Residual blocks... builder = ResNetBuilder(model, 'pool1', no_bias=no_bias, is_test=is_test, spatial_bn_mom=0.1) # conv2_x (ref Table 1 in He et al. (2015)) builder.add_bottleneck(64, 64, 256) builder.add_bottleneck(256, 64, 256) builder.add_bottleneck(256, 64, 256) # conv3_x builder.add_bottleneck(256, 128, 512, down_sampling=True) for _ in range(1, 8): builder.add_bottleneck(512, 128, 512) # conv4_x builder.add_bottleneck(512, 256, 1024, down_sampling=True) for _ in range(1, 36): builder.add_bottleneck(1024, 256, 1024) # conv5_x builder.add_bottleneck(1024, 512, 2048, down_sampling=True) builder.add_bottleneck(2048, 512, 2048) builder.add_bottleneck(2048, 512, 2048) # Final layers final_avg = brew.average_pool( model, builder.prev_blob, 'final_avg', kernel=final_avg_kernel, stride=1, ) # Final dimension of the "image" is reduced to 7x7 last_out = brew.fc(model, final_avg, 'last_out_L{}'.format(num_labels), 2048, num_labels) if no_loss: return last_out # If we create model for training, use softmax-with-loss if (label is not None): (softmax, loss) = model.SoftmaxWithLoss( [last_out, label], ["softmax", "loss"], ) return (softmax, loss) else: # For inference, we just return softmax return brew.softmax(model, last_out, "softmax")
def add_bottleneck( self, input_filters, # num of feature maps from preceding layer output_filters, # num of feature maps to output base_filters, # num of filters internally in the component down_sampling=False, spatial_batch_norm=True, ): self.comp_idx = 0 shortcut_blob = self.prev_blob # 1x1 self.add_conv( input_filters, base_filters, kernel=1, ) if spatial_batch_norm: self.add_spatial_bn(base_filters) self.add_relu() # 3x3 self.add_conv( base_filters, base_filters, kernel=3, stride=(2 if down_sampling else 1), pad=1, ) if spatial_batch_norm: self.add_spatial_bn(base_filters) self.add_relu() # 1x1 last_conv = self.add_conv( base_filters, output_filters, kernel=1, ) if spatial_batch_norm: last_conv = self.add_spatial_bn(output_filters) # Summation with input signal (shortcut) # If we need to increase dimensions (feature maps), need to # do do a projection for the short cut if (output_filters > input_filters or down_sampling): shortcut_blob = brew.conv( self.model, shortcut_blob, '%sshortcut_projection_%d' % (self.prefix, self.comp_count), input_filters, output_filters, kernel=1, weight_init=("MSRAFill", {}), stride=(2 if down_sampling else 1), no_bias=self.no_bias, ) if spatial_batch_norm: shortcut_blob = brew.spatial_bn( self.model, shortcut_blob, '%sshortcut_projection_%d_spatbn' % (self.prefix, self.comp_count), output_filters, epsilon=1e-3, momentum=self.spatial_bn_mom, is_test=self.is_test, ) self.prev_blob = brew.sum( self.model, [shortcut_blob, last_conv], '%scomp_%d_sum_%d' % (self.prefix, self.comp_count, self.comp_idx)) self.comp_idx += 1 self.add_relu() self.comp_count += 1