def ConvNormLayer(net, from_layer, out_layer, ks, p, s, num_output, no_relu=False, drop_conv=False, drop_bn=False): net[out_layer] = L.Convolution(net[from_layer], num_output=num_output, kernel_size=ks, stride=s, pad=p, weight_filler=dict(type='xavier'), bias_term=False, mirror_stage=drop_conv) net[out_layer + '_bn'] = L.BN(net[out_layer], in_place=True, mirror_stage=drop_bn, param=bn_params, batch_norm_param={'use_global_stats': True}) if not no_relu: net[out_layer + '_relu'] = L.ReLU(net[out_layer + '_bn'], in_place=True)
def ResBody(net, from_layer, block_name, out2a, out2b, out2c, stride, use_branch1, dilation=1, **bn_param): # ResBody(net, 'pool1', '2a', 64, 64, 256, 1, True) conv_prefix = 'res{}_'.format(block_name) conv_postfix = '' bn_prefix = 'bn{}_'.format(block_name) bn_postfix = '' scale_prefix = 'scale{}_'.format(block_name) scale_postfix = '' use_scale = True if use_branch1: branch_name = 'branch1' ConvBNLayer(net, from_layer, branch_name, use_bn=True, use_relu=False, num_output=out2c, kernel_size=1, pad=0, stride=stride, use_scale=use_scale, conv_prefix=conv_prefix, conv_postfix=conv_postfix, bn_prefix=bn_prefix, bn_postfix=bn_postfix, scale_prefix=scale_prefix, scale_postfix=scale_postfix, **bn_param) branch1 = '{}{}'.format(conv_prefix, branch_name) else: branch1 = from_layer branch_name = 'branch2a' ConvBNLayer(net, from_layer, branch_name, use_bn=True, use_relu=True, num_output=out2a, kernel_size=1, pad=0, stride=stride, use_scale=use_scale, conv_prefix=conv_prefix, conv_postfix=conv_postfix, bn_prefix=bn_prefix, bn_postfix=bn_postfix, scale_prefix=scale_prefix, scale_postfix=scale_postfix, **bn_param) out_name = '{}{}'.format(conv_prefix, branch_name) branch_name = 'branch2b' if dilation == 1: ConvBNLayer(net, out_name, branch_name, use_bn=True, use_relu=True, num_output=out2b, kernel_size=3, pad=1, stride=1, use_scale=use_scale, conv_prefix=conv_prefix, conv_postfix=conv_postfix, bn_prefix=bn_prefix, bn_postfix=bn_postfix, scale_prefix=scale_prefix, scale_postfix=scale_postfix, **bn_param) else: pad = int((3 + (dilation - 1) * 2) - 1) / 2 ConvBNLayer(net, out_name, branch_name, use_bn=True, use_relu=True, num_output=out2b, kernel_size=3, pad=pad, stride=1, use_scale=use_scale, dilation=dilation, conv_prefix=conv_prefix, conv_postfix=conv_postfix, bn_prefix=bn_prefix, bn_postfix=bn_postfix, scale_prefix=scale_prefix, scale_postfix=scale_postfix, **bn_param) out_name = '{}{}'.format(conv_prefix, branch_name) branch_name = 'branch2c' ConvBNLayer(net, out_name, branch_name, use_bn=True, use_relu=False, num_output=out2c, kernel_size=1, pad=0, stride=1, use_scale=use_scale, conv_prefix=conv_prefix, conv_postfix=conv_postfix, bn_prefix=bn_prefix, bn_postfix=bn_postfix, scale_prefix=scale_prefix, scale_postfix=scale_postfix, **bn_param) branch2 = '{}{}'.format(conv_prefix, branch_name) res_name = 'res{}'.format(block_name) net[res_name] = L.Eltwise(net[branch1], net[branch2]) relu_name = '{}_relu'.format(res_name) net[relu_name] = L.ReLU(net[res_name], in_place=True)
def conv_relu(bottom, nout, ks=3, stride=1, pad=1): conv = L.Convolution( bottom, kernel_size=ks, stride=stride, num_output=nout, pad=pad, param=[dict(lr_mult=1, decay_mult=1), dict(lr_mult=2, decay_mult=0)]) return conv, L.ReLU(conv, in_place=True)
def InceptionResBlock(net, from_layer, out_layer, num_output): ConvNormLayer(net, from_layer=from_layer, ks=1, p=0, s=1, num_output=num_output, out_layer=out_layer + '_1x1') ConvNormLayer(net, from_layer=out_layer + '_1x1', ks=3, p=1, s=1, num_output=num_output / 2, out_layer=out_layer + '_3x3_reduce') ConvNormLayer(net, from_layer=out_layer + '_3x3_reduce', ks=3, p=1, s=1, num_output=num_output, out_layer=out_layer + '_3x3_a') ConvNormLayer(net, from_layer=out_layer + '_1x1', ks=3, p=1, s=1, num_output=num_output, out_layer=out_layer + '_3x3_b') net[out_layer + '_concat'] = L.Concat(net[out_layer + '_1x1'], net[out_layer + '_3x3_a'], net[out_layer + '_3x3_b'], axis=1) ConvNormLayer(net, from_layer=out_layer + '_concat', ks=3, p=1, s=1, num_output=num_output, out_layer=out_layer + '_reduce', no_relu=True) net[out_layer] = L.Add(net[out_layer + '_reduce'], net[from_layer]) net[out_layer + '_relu'] = L.ReLU(net[out_layer], in_place=True)
def ResBlock(net, from_layer, out_layer, num_output, stride=1, force_branch1=False, use_memonger=True): ConvNormLayer(net, from_layer, out_layer + '_branch2a', 3, 1, stride, num_output, drop_bn=use_memonger) ConvNormLayer(net, out_layer + '_branch2a', out_layer + '_branch2b', 3, 1, 1, num_output, no_relu=True, drop_conv=use_memonger, drop_bn=use_memonger) shortcut = from_layer if stride != 1 or force_branch1: ConvNormLayer(net, from_layer, out_layer + '_branch1', 1, 0, stride, num_output, no_relu=True) shortcut = out_layer + '_branch1' net[out_layer] = L.Add(net[out_layer + '_branch2b'], net[shortcut]) net[out_layer + '_relu'] = L.ReLU(net[out_layer], in_place=True)
def ConvBNLayer(net, from_layer, out_layer, use_bn, use_relu, num_output, kernel_size, pad, stride, dilation=1, use_scale=True, lr_mult=1, conv_prefix='', conv_postfix='', bn_prefix='', bn_postfix='_bn', scale_prefix='', scale_postfix='_scale', bias_prefix='', bias_postfix='_bias', **bn_params): if use_bn: # parameters for convolution layer with batchnorm. kwargs = { 'param': [dict(lr_mult=lr_mult, decay_mult=1)], 'weight_filler': dict(type='gaussian', std=0.01), 'bias_term': False, } eps = bn_params.get('eps', 1e-3) moving_average_fraction = bn_params.get('moving_average_fraction', 0.9) use_global_stats = bn_params.get('use_global_stats', False) # parameters for batchnorm layer. bn_kwargs = { 'param': [ dict(lr_mult=0, decay_mult=0), dict(lr_mult=0, decay_mult=0), dict(lr_mult=0, decay_mult=0)], } bn_lr_mult = lr_mult if use_global_stats: # only specify if use_global_stats is explicitly provided; # otherwise, use_global_stats_ = this->phase_ == TEST; bn_kwargs = { 'param': [ dict(lr_mult=0, decay_mult=0), dict(lr_mult=0, decay_mult=0), dict(lr_mult=0, decay_mult=0)], 'eps': eps, 'use_global_stats': use_global_stats, } # not updating scale/bias parameters bn_lr_mult = 0 # parameters for scale bias layer after batchnorm. if use_scale: sb_kwargs = { 'bias_term': True} else: kwargs = { 'param': [ dict(lr_mult=lr_mult, decay_mult=1), dict(lr_mult=2 * lr_mult, decay_mult=0)], 'weight_filler': dict(type='xavier'), 'bias_filler': dict(type='constant', value=0) } conv_name = '{}{}{}'.format(conv_prefix, out_layer, conv_postfix) [kernel_h, kernel_w] = UnpackVariable(kernel_size, 2) [pad_h, pad_w] = UnpackVariable(pad, 2) [stride_h, stride_w] = UnpackVariable(stride, 2) if kernel_h == kernel_w: net[conv_name] = L.Convolution(net[from_layer], num_output=num_output, kernel_size=kernel_h, pad=pad_h, stride=stride_h, **kwargs) else: net[conv_name] = L.Convolution(net[from_layer], num_output=num_output, kernel_h=kernel_h, kernel_w=kernel_w, pad_h=pad_h, pad_w=pad_w, stride_h=stride_h, stride_w=stride_w, **kwargs) if dilation > 1: net.update(conv_name, {'dilation': dilation}) if use_bn: bn_name = '{}{}{}'.format(bn_prefix, out_layer, bn_postfix) net[bn_name] = L.BatchNorm(net[conv_name], in_place=True, **bn_kwargs) if use_scale: sb_name = '{}{}{}'.format(scale_prefix, out_layer, scale_postfix) net[sb_name] = L.Scale(net[bn_name], in_place=True, **sb_kwargs) else: bias_name = '{}{}{}'.format(bias_prefix, out_layer, bias_postfix) net[bias_name] = L.Bias(net[bn_name], in_place=True, **bias_kwargs) if use_relu: relu_name = '{}_relu'.format(conv_name) net[relu_name] = L.ReLU(net[conv_name], in_place=True)
def VGGNetBody(net, from_layer, need_fc=True, fully_conv=False, reduced=False, dilated=False, nopool=False, dropout=True, freeze_layers=[], dilate_pool4=False): kwargs = { 'param': [dict(lr_mult=1, decay_mult=1), dict(lr_mult=2, decay_mult=0)], 'weight_filler': dict(type='xavier'), 'bias_filler': dict(type='constant', value=0)} assert from_layer in net.keys() net.conv1_1 = L.Convolution(net[from_layer], num_output=64, pad=1, kernel_size=3, **kwargs) net.relu1_1 = L.ReLU(net.conv1_1, in_place=True) net.conv1_2 = L.Convolution(net.relu1_1, num_output=64, pad=1, kernel_size=3, **kwargs) net.relu1_2 = L.ReLU(net.conv1_2, in_place=True) if nopool: name = 'conv1_3' net[name] = L.Convolution(net.relu1_2, num_output=64, pad=1, kernel_size=3, stride=2, **kwargs) else: name = 'pool1' net.pool1 = L.Pooling(net.relu1_2, pool=P.Pooling.MAX, kernel_size=2, stride=2) net.conv2_1 = L.Convolution(net[name], num_output=128, pad=1, kernel_size=3, **kwargs) net.relu2_1 = L.ReLU(net.conv2_1, in_place=True) net.conv2_2 = L.Convolution(net.relu2_1, num_output=128, pad=1, kernel_size=3, **kwargs) net.relu2_2 = L.ReLU(net.conv2_2, in_place=True) if nopool: name = 'conv2_3' net[name] = L.Convolution(net.relu2_2, num_output=128, pad=1, kernel_size=3, stride=2, **kwargs) else: name = 'pool2' net[name] = L.Pooling(net.relu2_2, pool=P.Pooling.MAX, kernel_size=2, stride=2) net.conv3_1 = L.Convolution(net[name], num_output=256, pad=1, kernel_size=3, **kwargs) net.relu3_1 = L.ReLU(net.conv3_1, in_place=True) net.conv3_2 = L.Convolution(net.relu3_1, num_output=256, pad=1, kernel_size=3, **kwargs) net.relu3_2 = L.ReLU(net.conv3_2, in_place=True) net.conv3_3 = L.Convolution(net.relu3_2, num_output=256, pad=1, kernel_size=3, **kwargs) net.relu3_3 = L.ReLU(net.conv3_3, in_place=True) if nopool: name = 'conv3_4' net[name] = L.Convolution(net.relu3_3, num_output=256, pad=1, kernel_size=3, stride=2, **kwargs) else: name = 'pool3' net[name] = L.Pooling(net.relu3_3, pool=P.Pooling.MAX, kernel_size=2, stride=2) net.conv4_1 = L.Convolution(net[name], num_output=512, pad=1, kernel_size=3, **kwargs) net.relu4_1 = L.ReLU(net.conv4_1, in_place=True) net.conv4_2 = L.Convolution(net.relu4_1, num_output=512, pad=1, kernel_size=3, **kwargs) net.relu4_2 = L.ReLU(net.conv4_2, in_place=True) net.conv4_3 = L.Convolution(net.relu4_2, num_output=512, pad=1, kernel_size=3, **kwargs) net.relu4_3 = L.ReLU(net.conv4_3, in_place=True) if nopool: name = 'conv4_4' net[name] = L.Convolution(net.relu4_3, num_output=512, pad=1, kernel_size=3, stride=2, **kwargs) else: name = 'pool4' if dilate_pool4: net[name] = L.Pooling(net.relu4_3, pool=P.Pooling.MAX, kernel_size=3, stride=1, pad=1) dilation = 2 else: net[name] = L.Pooling(net.relu4_3, pool=P.Pooling.MAX, kernel_size=2, stride=2) dilation = 1 kernel_size = 3 pad = int(int((kernel_size + (dilation - 1) * (kernel_size - 1)) - 1) / 2) net.conv5_1 = L.Convolution(net[name], num_output=512, pad=pad, kernel_size=kernel_size, dilation=dilation, **kwargs) net.relu5_1 = L.ReLU(net.conv5_1, in_place=True) net.conv5_2 = L.Convolution(net.relu5_1, num_output=512, pad=pad, kernel_size=kernel_size, dilation=dilation, **kwargs) net.relu5_2 = L.ReLU(net.conv5_2, in_place=True) net.conv5_3 = L.Convolution(net.relu5_2, num_output=512, pad=pad, kernel_size=kernel_size, dilation=dilation, **kwargs) net.relu5_3 = L.ReLU(net.conv5_3, in_place=True) if need_fc: if dilated: if nopool: name = 'conv5_4' net[name] = L.Convolution(net.relu5_3, num_output=512, pad=1, kernel_size=3, stride=1, **kwargs) else: name = 'pool5' net[name] = L.Pooling(net.relu5_3, pool=P.Pooling.MAX, pad=1, kernel_size=3, stride=1) else: if nopool: name = 'conv5_4' net[name] = L.Convolution(net.relu5_3, num_output=512, pad=1, kernel_size=3, stride=2, **kwargs) else: name = 'pool5' net[name] = L.Pooling(net.relu5_3, pool=P.Pooling.MAX, kernel_size=2, stride=2) if fully_conv: if dilated: if reduced: dilation = dilation * 6 kernel_size = 3 num_output = 1024 else: dilation = dilation * 2 kernel_size = 7 num_output = 4096 else: if reduced: dilation = dilation * 3 kernel_size = 3 num_output = 1024 else: kernel_size = 7 num_output = 4096 pad = int(int((kernel_size + (dilation - 1) * (kernel_size - 1)) - 1) / 2) net.fc6 = L.Convolution(net[name], num_output=num_output, pad=pad, kernel_size=kernel_size, dilation=dilation, **kwargs) net.relu6 = L.ReLU(net.fc6, in_place=True) if dropout: net.drop6 = L.Dropout(net.relu6, dropout_ratio=0.5, in_place=True) if reduced: net.fc7 = L.Convolution(net.relu6, num_output=1024, kernel_size=1, **kwargs) else: net.fc7 = L.Convolution(net.relu6, num_output=4096, kernel_size=1, **kwargs) net.relu7 = L.ReLU(net.fc7, in_place=True) if dropout: net.drop7 = L.Dropout(net.relu7, dropout_ratio=0.5, in_place=True) else: net.fc6 = L.InnerProduct(net.pool5, num_output=4096) net.relu6 = L.ReLU(net.fc6, in_place=True) if dropout: net.drop6 = L.Dropout(net.relu6, dropout_ratio=0.5, in_place=True) net.fc7 = L.InnerProduct(net.relu6, num_output=4096) net.relu7 = L.ReLU(net.fc7, in_place=True) if dropout: net.drop7 = L.Dropout(net.relu7, dropout_ratio=0.5, in_place=True) # Update freeze layers. kwargs['param'] = [dict(lr_mult=0, decay_mult=0), dict(lr_mult=0, decay_mult=0)] layers = net.keys() for freeze_layer in freeze_layers: if freeze_layer in layers: net.update(freeze_layer, kwargs) return net