public MobileNetV2(float multiplier = 1, int classes = 1000, string prefix = "", ParameterDict @params = null) : base(prefix, @params) { Features = new HybridSequential(""); MobileNet.AddConv(Features, Convert.ToInt32(32 * multiplier), 3, pad: 1, stride: 2); for (var i = 0; i < in_channels_group.Length; i++) { var in_c = Convert.ToInt32(multiplier * in_channels_group[i]); var c = Convert.ToInt32(multiplier * channels_group[i]); var s = strides[i]; var t = ts[i]; Features.Add(new LinearBottleneck(in_c, c, t, s)); } var last_channel = multiplier > 1 ? Convert.ToInt32(1280 * multiplier) : 1280; MobileNet.AddConv(Features, last_channel, relu6: true); Features.Add(new GlobalAvgPool2D()); Output = new HybridSequential("output_"); Output.Add(new Conv2D(classes, (1, 1), use_bias: false, prefix: "pred_")); Output.Add(new Flatten()); }
public LinearBottleneck(int in_channels, int channels, int t, int stride, string prefix = null, ParameterDict @params = null) : base(prefix, @params) { use_shortcut = stride == 1 && in_channels == channels; output = new HybridSequential(); MobileNet.AddConv(output, in_channels * t, relu6: true); MobileNet.AddConv(output, in_channels * t, 3, stride, 1, in_channels, relu6: true); MobileNet.AddConv(output, channels, active: false, relu6: true); }