internal static HybridSequential Conv2d(int channel, int kernel, int padding, int stride, string norm_layer = "BatchNorm", FuncArgs norm_kwargs = null) { var cell = new HybridSequential(prefix: ""); cell.Add(new Conv2D(channel, kernel_size: (kernel, kernel), strides: (stride, stride), padding: (padding, stride), use_bias: false)); cell.Add(LayerUtils.NormLayer(norm_layer, norm_kwargs)); cell.Add(new LeakyReLU(0.1f)); return(cell); }
public HybridSequential BNRelu(int channels, string norm_layer = "BatchNorm", FuncArgs norm_kwargs = null) { var @out = new HybridSequential(prefix: ""); var bn = LayerUtils.NormLayer(norm_layer, norm_kwargs); @out.Add(LayerUtils.NormLayer(norm_layer, norm_kwargs)); @out.Add(new Activation(ActivationType.Relu)); return(@out); }
internal static HybridSequential Conv2d(int channel, int kernel, int padding, int stride, string norm_layer = "BatchNorm", FuncArgs norm_kwargs = null) { var cell = new HybridSequential(); cell.Add(new Conv2D(channel, kernel_size: (kernel, kernel), strides: (stride, stride), padding: (padding, padding), use_bias: false)); if (norm_kwargs == null) { norm_kwargs = new FuncArgs(); } norm_kwargs["epsilon"] = 1e-5f; norm_kwargs["momentum"] = 0.9f; cell.Add(LayerUtils.NormLayer(norm_layer, norm_kwargs)); cell.Add(new LeakyReLU(0.1f)); return(cell); }
private void Construct(SymbolList outputs, SymbolList inputs, ParameterDict @params, int[] num_filters, bool use_1x1 = true, bool use_upsample = true, bool use_elewadd = true, bool use_p6 = false, bool p6_conv = true, bool no_bias = true, bool pretrained = false, string norm_layer = null, FuncArgs norm_kwargs = null, Context ctx = null) { Symbol y_p6 = null; // e.g. For ResNet50, the feature is : // outputs = ['stage1_activation2', 'stage2_activation3', // 'stage3_activation5', 'stage4_activation2'] // with regard to [conv2, conv3, conv4, conv5] -> [C2, C3, C4, C5] // append more layers with reversed order : [P5, P4, P3, P2] var y = outputs.Last(); var base_features = outputs.Take(outputs.Length - 1).ToArray(); var num_stages = num_filters.Length + 1; var weight_init = new Xavier(rnd_type: "uniform", factor_type: "in", magnitude: 1); var tmp_outputs = new List <Symbol>(); // num_filter is 256 in ori paper for (int i = 0; i < base_features.Length; i++) { var bf = base_features[i]; var f = num_filters[i]; if (i == 0) { if (use_1x1) { y = sym.Convolution(y, weight_init.InitWeight("weight"), null, num_filter: f, kernel: new Shape(1, 1), pad: new Shape(0, 0), stride: new Shape(1, 1), no_bias: no_bias, symbol_name: $"P{num_stages - i}_conv_lat"); if (norm_layer != null) { if (norm_layer == "SyncBatchNorm") { norm_kwargs["key"] = $"P{num_stages - i}_lat_bn"; norm_kwargs["name"] = $"P{num_stages - i}_lat_bn"; } var bn = LayerUtils.NormLayer(norm_layer, norm_kwargs); y = bn.Call(y); } } if (use_p6 && p6_conv) { // method 2 : use conv (Deformable use this) y_p6 = sym.Convolution(y, weight_init.InitWeight("weight"), null, num_filter: f, kernel: new Shape(3, 3), pad: new Shape(1, 1), stride: new Shape(2, 2), no_bias: no_bias, symbol_name: $"P{num_stages + 1}_conv1"); if (norm_layer != null) { if (norm_layer == "SyncBatchNorm") { norm_kwargs["key"] = $"P{num_stages - i}_pre_bn"; norm_kwargs["name"] = $"P{num_stages - i}_pre_bn"; } var bn = LayerUtils.NormLayer(norm_layer, norm_kwargs); y_p6 = bn.Call(y_p6); } } } else { if (use_1x1) { bf = sym.Convolution(bf, weight_init.InitWeight("weight"), null, num_filter: f, kernel: new Shape(1, 1), pad: new Shape(0, 0), stride: new Shape(1, 1), no_bias: no_bias, symbol_name: $"P{num_stages - i}_conv_lat"); if (norm_layer != null) { if (norm_layer == "SyncBatchNorm") { norm_kwargs["key"] = $"P{num_stages - i}_conv1_bn"; norm_kwargs["name"] = $"P{num_stages - i}_conv1_bn"; } var bn = LayerUtils.NormLayer(norm_layer, norm_kwargs); bf = bn.Call(bf); } } if (use_upsample) { y = sym.UpSampling(y, scale: 2, num_args: 1, sample_type: UpsamplingSampleType.Nearest, symbol_name: $"P{num_stages - i}_upsp"); } if (use_elewadd) { // make two symbol alignment // method 1 : mx.sym.Crop // y = mx.sym.Crop(*[y, bf], name="P{}_clip".format(num_stages-i)) // method 2 : mx.sym.slice_like y = sym.SliceLike(y, bf, axes: new Shape(2, 3), symbol_name: $"P{num_stages - i}_clip"); y = sym.ElemwiseAdd(bf, y, symbol_name: $"P{num_stages - i}_sum"); } } // Reduce the aliasing effect of upsampling described in ori paper var @out = sym.Convolution(y, weight_init.InitWeight("weight"), null, num_filter: f, kernel: new Shape(3, 3), pad: new Shape(1, 1), stride: new Shape(1, 1), no_bias: no_bias, symbol_name: $"P{num_stages - i}_conv1"); if (i == 0 && use_p6 && !p6_conv) { // method 2 : use max pool (Detectron use this) y_p6 = sym.Pooling(@out, pool_type: PoolingType.Max, kernel: new Shape(1, 1), pad: new Shape(0, 0), stride: new Shape(2, 2), symbol_name: $"P{num_stages + 1}_pre"); } if (norm_layer != null) { if (norm_layer == "SyncBatchNorm") { norm_kwargs["key"] = $"P{num_stages - i}_bn"; norm_kwargs["name"] = $"P{num_stages - i}_bn"; } var bn = LayerUtils.NormLayer(norm_layer, norm_kwargs); @out = bn.Call(@out); } tmp_outputs.Add(@out); } if (use_p6) { outputs = tmp_outputs.Take(tmp_outputs.Count - 1).ToList(); outputs.Add(y_p6); } else { outputs = tmp_outputs.Take(tmp_outputs.Count - 1).ToList(); } base.Construct(outputs, inputs, @params); }