Example #1
0
        private Layer ConvertDepthwiseConv2d(tflite.Operator op)
        {
            var inputs   = op.GetInputsArray();
            var input    = _graph.Tensors(inputs[0]).Value;
            var options  = op.BuiltinOptions <tflite.DepthwiseConv2DOptions>().Value;
            var weights  = _graph.Tensors(inputs[1]).Value;
            var bias     = _graph.Tensors(inputs[2]).Value;
            var depthMul = options.DepthMultiplier;

            if (input.GetShapeArray().ToNCHW()[1] == 1 && depthMul != 1)
            {
                var layer = new Conv2d(input.GetShapeArray().ToNCHW(), _model.GetTensor <float>(weights).ToOIHW().Transpose(new[] { 1, 0, 2, 3 }), _model.GetTensor <float>(bias),
                                       options.Padding.ToPadding(), options.StrideW, options.StrideH, options.FusedActivationFunction.ToActivationFunction());
                _inputs.Add(layer.Input, inputs[0]);
                _outputs.Add(op.Outputs(0), layer.Output);
                return(layer);
            }
            else if (depthMul != 1)
            {
                throw new LayerNotSupportedException("DEPTHWISE_CONV_2D", "depth_multiplier must be 1");
            }

            {
                var layer = new DepthwiseConv2d(input.GetShapeArray().ToNCHW(), _model.GetTensor <float>(weights).ToOIHW(), _model.GetTensor <float>(bias),
                                                options.Padding.ToPadding(), options.StrideW, options.StrideH, options.FusedActivationFunction.ToActivationFunction());
                _inputs.Add(layer.Input, inputs[0]);
                _outputs.Add(op.Outputs(0), layer.Output);
                return(layer);
            }
        }
Example #2
0
        public override void Process(TransformContext context)
        {
            var space    = (SpaceToBatchNd)context.MatchedLayers[0];
            var dwConv2d = (DepthwiseConv2d)context.MatchedLayers[1];
            var conv2d   = (Conv2d)context.MatchedLayers[2];
            var input    = space.Input.Connection.From;
            var output   = conv2d.Output;

            space.Input.ClearConnection();
            var newDwConv2d = new DepthwiseConv2d(input.Dimensions, dwConv2d.Weights, dwConv2d.Bias, Padding.Same, 1, 1, dwConv2d.FusedActivationFunction);
            var quantize    = new Quantize(newDwConv2d.Output.Dimensions);
            var upload      = new K210Upload(quantize.Output.Dimensions);
            var newConv2d   = new K210Conv2d(upload.Output.Dimensions, K210Conv2dType.Conv2d, conv2d.Weights, conv2d.Bias, K210PoolType.LeftTop, conv2d.FusedActivationFunction, null);
            var dequantize  = new Dequantize(newConv2d.Output.Dimensions);

            newDwConv2d.Input.SetConnection(input);
            quantize.Input.SetConnection(newDwConv2d.Output);
            upload.Input.SetConnection(quantize.Output);
            newConv2d.Input.SetConnection(upload.Output);
            dequantize.Input.SetConnection(newConv2d.Output);
            var oldOuts = output.Connections.Select(o => o.To).ToList();

            foreach (var oldOut in oldOuts)
            {
                oldOut.SetConnection(dequantize.Output);
            }
        }
Example #3
0
        private Layer ConvertConv2d(paddle.OpDesc op)
        {
            var padding = GetAttr(op, "paddings").Ints;
            var strides = GetAttr(op, "strides").Ints.ToArray();
            var groups  = GetAttr(op, "groups").I;

            if (strides[0] == 0)
            {
                strides[0] = 1;
            }
            if (strides[1] == 0)
            {
                strides[1] = 1;
            }

            var input        = GetParameter(op.Inputs, "Input").Arguments[0];
            var weights      = GetParameter(op.Inputs, "Filter").Arguments[0];
            var weightsShape = GetVarShape(weights);
            var kernelWidth  = weightsShape[3];
            var kernelHeight = weightsShape[2];
            var output       = GetParameter(op.Outputs, "Output").Arguments[0];

            if (groups == 1)
            {
                Conv2d conv2d;
                if (padding[0] == 1 && padding[1] == 1 && strides[0] == 2 && strides[1] == 2 &&
                    kernelWidth == 3 && kernelHeight == 3)
                {
                    var space = new SpaceToBatchNd(GetVarShape(input), new[] { 1, 1 }.ToTensor(), new[, ] {
                        { 1, 1 }, { 1, 1, }
                    }.ToTensor());
                    conv2d = new Conv2d(space.Output.Dimensions, LoadVarData <float>(weights), null, Padding.Valid, strides[1], strides[0], ActivationFunctionType.Linear);
                    conv2d.Input.SetConnection(space.Output);
                    _inputs.Add(space.Input, input);
                }
                else
                {
                    if (padding[0] != padding[1] || (padding[0] != 0 && padding[0] != 1))
                    {
                        throw new NotSupportedException();
                    }

                    conv2d = new Conv2d(GetVarShape(input), LoadVarData <float>(weights), null, Padding.Same, strides[1], strides[0], ActivationFunctionType.Linear);
                    _inputs.Add(conv2d.Input, input);
                }

                _outputs.Add(output, conv2d.Output);
                return(conv2d);
            }
            else if (groups == weightsShape[0])
            {
                var             w = LoadVarData <float>(weights).Transpose(new[] { 1, 0, 2, 3 });
                DepthwiseConv2d dwConv2d;
                if (padding[0] == 1 && padding[1] == 1 && strides[0] == 2 && strides[1] == 2 &&
                    kernelWidth == 3 && kernelHeight == 3)
                {
                    var space = new SpaceToBatchNd(GetVarShape(input), new[] { 1, 1 }.ToTensor(), new[, ] {
                        { 1, 1 }, { 1, 1, }
                    }.ToTensor());
                    dwConv2d = new DepthwiseConv2d(space.Output.Dimensions, w, null, Padding.Valid, strides[1], strides[0], ActivationFunctionType.Linear);
                    dwConv2d.Input.SetConnection(space.Output);
                    _inputs.Add(space.Input, input);
                }
                else
                {
                    if (padding[0] != padding[1] || (padding[0] != 0 && padding[0] != 1))
                    {
                        throw new NotSupportedException();
                    }

                    dwConv2d = new DepthwiseConv2d(GetVarShape(input), w, null, Padding.Same, strides[1], strides[0], ActivationFunctionType.Linear);
                    _inputs.Add(dwConv2d.Input, input);
                }

                _outputs.Add(output, dwConv2d.Output);
                return(dwConv2d);
            }
            else
            {
                throw new NotSupportedException();
            }
        }
Example #4
0
        public override void Process(TransformContext context)
        {
            var space    = context.MatchedLayers[0];
            var dwConv2d = (DepthwiseConv2d)context.MatchedLayers[1];
            var conv2d   = (Conv2d)context.MatchedLayers.Last();
            var input    = space.InputConnectors[0].Connection.From;
            var output   = conv2d.Output;

            space.InputConnectors[0].ClearConnection();
            var newDwConv2d = new DepthwiseConv2d(input.Dimensions, dwConv2d.Weights, dwConv2d.Bias, Padding.Same, 1, 1, dwConv2d.FusedActivationFunction);
            var quantize    = new Quantize(newDwConv2d.Output.Dimensions);
            var upload      = new K210Upload(quantize.Output.Dimensions);
            var newConv2d   = new K210Conv2d(upload.Output.Dimensions, K210Conv2dType.Conv2d, conv2d.Weights, conv2d.Bias, K210PoolType.LeftTop, conv2d.FusedActivationFunction, null);
            var dequantize  = new Dequantize(newConv2d.Output.Dimensions);

            newDwConv2d.Input.SetConnection(input);
            quantize.Input.SetConnection(newDwConv2d.Output);
            upload.Input.SetConnection(quantize.Output);
            newConv2d.Input.SetConnection(upload.Output);
            dequantize.Input.SetConnection(newConv2d.Output);

            var oldOuts = output.Connections.Select(o => o.To).ToList();

            if (context.MatchedLayers.Count == 3)
            {
                foreach (var oldOut in oldOuts)
                {
                    oldOut.SetConnection(dequantize.Output);
                }
            }
            else
            {
                var newOutput = dequantize.Output;

                foreach (var middleLayer in context.MatchedLayers.Skip(2).Take(context.MatchedLayers.Count - 3))
                {
                    Layer newLayer;
                    switch (middleLayer)
                    {
                    case Quantize _:
                        newLayer = new Quantize(newOutput.Dimensions);
                        break;

                    case Dequantize _:
                        newLayer = new Dequantize(newOutput.Dimensions);
                        break;

                    case LeakyRelu l:
                        newLayer = new LeakyRelu(newOutput.Dimensions, l.Slope);
                        break;

                    default:
                        throw new NotImplementedException();
                    }

                    newLayer.InputConnectors[0].SetConnection(newOutput);
                    newOutput = newLayer.OutputConnectors[0];
                }

                foreach (var oldOut in oldOuts)
                {
                    oldOut.SetConnection(newOutput);
                }
            }
        }
Example #5
0
        private Layer ConvertConvolution(LayerParameter layerParam)
        {
            var input = _outputs[layerParam.Bottom[0]];
            var param = layerParam.ConvolutionParam;

            uint[] GetDefault(Google.Protobuf.Collections.RepeatedField <uint> field)
            {
                if (field.Count == 0)
                {
                    return new uint[] { 1, 1 }
                }
                ;
                else if (field.Count == 1)
                {
                    return new[] { field[0], field[0] }
                }
                ;
                else
                {
                    return(field.ToArray());
                }
            }

            var padding    = GetDefault(param.Pad);
            var strides    = GetDefault(param.Stride);
            var kernelSize = param.KernelSize.Count == 1 ? new[] { param.KernelSize[0], param.KernelSize[0] }
                : (param.KernelSize.Count == 0 ? new[] { param.KernelH, param.KernelW } : param.KernelSize.ToArray());
            var group = param.Group == 0 ? 1 : param.Group;

            if (group == 1)
            {
                var    weights = LoadBlob(layerParam.Blobs[0]);
                Conv2d conv2d;
                if (padding[0] != 0 || padding[1] != 0)
                {
                    if (padding[0] == 1 && padding[1] == 1 && strides[0] == 1 && strides[1] == 1)
                    {
                        conv2d = new Conv2d(input.Dimensions, weights, null, Padding.Same, 1, 1, ActivationFunctionType.Linear);
                        conv2d.Input.SetConnection(input);
                    }
                    else
                    {
                        var space = new SpaceToBatchNd(input.Dimensions, new[] { 1, 1 }.ToTensor(), new[, ] {
                            { (int)padding[0], (int)padding[0] }, { (int)padding[1], (int)padding[1], }
                        }.ToTensor());
                        conv2d = new Conv2d(space.Output.Dimensions, weights, null, Padding.Valid, (int)strides[1], (int)strides[0], ActivationFunctionType.Linear);
                        space.Input.SetConnection(input);
                        conv2d.Input.SetConnection(space.Output);
                    }
                }
                else
                {
                    conv2d = new Conv2d(input.Dimensions, weights, null, Padding.Valid, (int)strides[1], (int)strides[0], ActivationFunctionType.Linear);
                    conv2d.Input.SetConnection(input);
                }

                _outputs.Add(layerParam.Top[0], conv2d.Output);
                return(conv2d);
            }
            else if (group == param.NumOutput)
            {
                var             weights = LoadBlob(layerParam.Blobs[0]).Transpose(new[] { 1, 0, 2, 3 });
                DepthwiseConv2d dwConv2d;

                if (padding[0] != 0 || padding[1] != 0)
                {
                    if (padding[0] == 1 && padding[1] == 1 && strides[0] == 1 && strides[1] == 1)
                    {
                        dwConv2d = new DepthwiseConv2d(input.Dimensions, weights, null, Padding.Same, 1, 1, ActivationFunctionType.Linear);
                        dwConv2d.Input.SetConnection(input);
                    }
                    else
                    {
                        var space = new SpaceToBatchNd(input.Dimensions, new[] { 1, 1 }.ToTensor(), new[, ] {
                            { (int)padding[0], (int)padding[0] }, { (int)padding[1], (int)padding[1], }
                        }.ToTensor());
                        dwConv2d = new DepthwiseConv2d(space.Output.Dimensions, weights, null, Padding.Valid, (int)strides[1], (int)strides[0], ActivationFunctionType.Linear);
                        space.Input.SetConnection(input);
                        dwConv2d.Input.SetConnection(space.Output);
                    }
                }
                else
                {
                    dwConv2d = new DepthwiseConv2d(input.Dimensions, weights, null, Padding.Valid, (int)strides[1], (int)strides[0], ActivationFunctionType.Linear);
                    dwConv2d.Input.SetConnection(input);
                }

                _outputs.Add(layerParam.Top[0], dwConv2d.Output);
                return(dwConv2d);
            }
            else
            {
                throw new NotSupportedException("Grouped conv2d is not supported.");
            }
        }