private Layer ConvertMul(tflite.Operator op) { var inputs = op.GetInputsArray(); var inputA = _graph.Tensors(inputs[0]).Value; var inputB = _graph.Tensors(inputs[1]).Value; if (inputA.ShapeLength == 0) { var layer = new Mul(inputB.GetShapeArray().ToNCHW(), _model.GetScalar <float>(inputA)); _inputs.Add(layer.Input, inputs[1]); _outputs.Add(op.Outputs(0), layer.Output); return(layer); } else if (inputB.ShapeLength == 0) { var layer = new Mul(inputA.GetShapeArray().ToNCHW(), _model.GetScalar <float>(inputB)); _inputs.Add(layer.Input, inputs[0]); _outputs.Add(op.Outputs(0), layer.Output); return(layer); } else { throw new LayerNotSupportedException(op.ToString(), "Only scalar multiply is supported"); } }
private Layer ConvertFullyConnected(tflite.Operator op) { var inputs = op.GetInputsArray(); var input = _graph.Tensors(inputs[0]).Value; var options = op.BuiltinOptions <tflite.FullyConnectedOptions>().Value; var weights = _graph.Tensors(inputs[1]).Value; var bias = _graph.Tensors(inputs[2]).Value; if (input.ShapeLength == 4 && (input.Shape(1) != 1 || input.Shape(2) != 1)) { var flatten = new TensorflowFlatten(input.GetShapeArray().ToNCHW()); var layer = new FullyConnected(flatten.Output.Dimensions, _model.GetTensor <float>(weights), _model.GetTensor <float>(bias), options.FusedActivationFunction.ToActivationFunction()); layer.Input.SetConnection(flatten.Output); _inputs.Add(flatten.Input, inputs[0]); _outputs.Add(op.Outputs(0), layer.Output); return(layer); } else { var layer = new FullyConnected(input.GetShapeArray().ToNCHW(), _model.GetTensor <float>(weights), _model.GetTensor <float>(bias), options.FusedActivationFunction.ToActivationFunction()); _inputs.Add(layer.Input, inputs[0]); _outputs.Add(op.Outputs(0), layer.Output); return(layer); } }
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); } }
private Layer ConvertOperator(tflite.Operator op) { var opCode = _model.OperatorCodes((int)op.OpcodeIndex).Value; switch (opCode.BuiltinCode) { case tflite.BuiltinOperator.SPACE_TO_BATCH_ND: return(ConvertSpaceToBatchNd(op)); case tflite.BuiltinOperator.CONV_2D: return(ConvertConv2d(op)); case tflite.BuiltinOperator.DEPTHWISE_CONV_2D: return(ConvertDepthwiseConv2d(op)); case tflite.BuiltinOperator.AVERAGE_POOL_2D: return(ConvertAveragePool2d(op)); case tflite.BuiltinOperator.L2_NORMALIZATION: return(ConvertL2Normalization(op)); case tflite.BuiltinOperator.ADD: return(ConvertAdd(op)); case tflite.BuiltinOperator.MUL: return(ConvertMul(op)); case tflite.BuiltinOperator.FULLY_CONNECTED: return(ConvertFullyConnected(op)); case tflite.BuiltinOperator.MAX_POOL_2D: return(ConvertMaxPool2d(op)); case tflite.BuiltinOperator.SOFTMAX: return(ConvertSoftmax(op)); case tflite.BuiltinOperator.CONCATENATION: return(ConvertConcatenation(op)); case tflite.BuiltinOperator.MAXIMUM: return(ConvertMaximum(op)); case tflite.BuiltinOperator.RESIZE_NEAREST_NEIGHBOR: return(ConvertResizeNearestNeighbor(op)); case tflite.BuiltinOperator.LEAKY_RELU: return(ConvertLeakyRelu(op)); case tflite.BuiltinOperator.MEAN: return(ConvertMean(op)); case tflite.BuiltinOperator.RESHAPE: return(ConvertReshape(op)); default: throw new LayerNotSupportedException(opCode.BuiltinCode.ToString()); } }
private Layer ConvertLogistic(tflite.Operator op) { var inputs = op.GetInputsArray(); var input = _graph.Tensors(inputs[0]).Value; var layer = new Logistic(input.GetShapeArray().ToNCHW()); _inputs.Add(layer.Input, inputs[0]); _outputs.Add(op.Outputs(0), layer.Output); return(layer); }
private Layer ConvertLeakyRelu(tflite.Operator op) { var inputs = op.GetInputsArray(); var input = _graph.Tensors(inputs[0]).Value; var options = op.BuiltinOptions <tflite.LeakyReluOptions>().Value; var layer = new LeakyRelu(input.GetShapeArray().ToNCHW(), options.Alpha); _inputs.Add(layer.Input, inputs[0]); _outputs.Add(op.Outputs(0), layer.Output); return(layer); }
private Layer ConvertReshape(tflite.Operator op) { var inputs = op.GetInputsArray(); var input = _graph.Tensors(inputs[0]).Value; var options = op.BuiltinOptions <tflite.ReshapeOptions>().Value; var layer = new TensorflowReshape(input.GetShapeArray().ToNCHW(), options.GetNewShapeArray().ToNCHW()); _inputs.Add(layer.Input, inputs[0]); _outputs.Add(op.Outputs(0), layer.Output); return(layer); }
private Layer ConvertMaximum(tflite.Operator op) { var inputs = op.GetInputsArray(); var inputA = _graph.Tensors(inputs[0]).Value; var inputB = _graph.Tensors(inputs[1]).Value; var layer = new Maximum(inputA.GetShapeArray().ToNCHW(), inputB.GetShapeArray().ToNCHW()); _inputs.Add(layer.InputA, inputs[0]); _inputs.Add(layer.InputB, inputs[1]); _outputs.Add(op.Outputs(0), layer.Output); return(layer); }
private Layer ConvertMaxPool2d(tflite.Operator op) { var inputs = op.GetInputsArray(); var input = _graph.Tensors(inputs[0]).Value; var options = op.BuiltinOptions <tflite.Pool2DOptions>().Value; var layer = new MaxPool2d(input.GetShapeArray().ToNCHW(), options.Padding.ToPadding(), options.FilterWidth, options.FilterHeight, options.StrideW, options.StrideH, options.FusedActivationFunction.ToActivationFunction()); _inputs.Add(layer.Input, inputs[0]); _outputs.Add(op.Outputs(0), layer.Output); return(layer); }
private Layer ConvertSpaceToBatchNd(tflite.Operator op) { var inputs = op.GetInputsArray(); var input = _graph.Tensors(inputs[0]).Value; var blockShape = _graph.Tensors(inputs[1]).Value; var paddings = _graph.Tensors(inputs[2]).Value; var layer = new SpaceToBatchNd(input.GetShapeArray().ToNCHW(), _model.GetTensor <int>(blockShape), _model.GetTensor <int>(paddings)); _inputs.Add(layer.Input, inputs[0]); _outputs.Add(op.Outputs(0), layer.Output); return(layer); }
private Layer ConvertResizeNearestNeighbor(tflite.Operator op) { var inputs = op.GetInputsArray(); var input = _graph.Tensors(inputs[0]).Value; var newSize = _model.GetTensor <int>(_graph.Tensors(inputs[1]).Value); var options = op.BuiltinOptions <tflite.ResizeNearestNeighborOptions>().Value; var blockShape = _graph.Tensors(inputs[1]).Value; var layer = new ResizeNearestNeighbor(input.GetShapeArray().ToNCHW(), newSize[1], newSize[0], options.AlignCorners); _inputs.Add(layer.Input, inputs[0]); _outputs.Add(op.Outputs(0), layer.Output); return(layer); }
private Layer ConvertConv2d(tflite.Operator op) { var inputs = op.GetInputsArray(); var input = _graph.Tensors(inputs[0]).Value; var options = op.BuiltinOptions <tflite.Conv2DOptions>().Value; var weights = _graph.Tensors(inputs[1]).Value; var bias = _graph.Tensors(inputs[2]).Value; var layer = new Conv2d(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); }
private Layer ConvertPad(tflite.Operator op) { var inputs = op.GetInputsArray(); var input = _graph.Tensors(inputs[0]).Value; var paddings = _graph.Tensors(inputs[1]).Value; var layer = new Pad(input.GetShapeArray().ToNCHW(), _model.GetTensor <int>(paddings)); if (!layer.Paddings.ToArray().SequenceEqual(new[] { 0, 0, 1, 1, 1, 1, 0, 0 })) { throw new LayerNotSupportedException("Pad", "Only paddings of [[0,0],[1,1],[1,1],[0,0]] is supported"); } _inputs.Add(layer.Input, inputs[0]); _outputs.Add(op.Outputs(0), layer.Output); return(layer); }
private Layer ConvertConcatenation(tflite.Operator op) { var inputs = op.GetInputsArray(); var options = op.BuiltinOptions <tflite.ConcatenationOptions>().Value; if (options.Axis != 3) { throw new NotSupportedException("Axis of concatenation must be 3."); } var layer = new Concatenation(inputs.Select(x => new ReadOnlyMemory <int>(_graph.Tensors(x).Value.GetShapeArray().ToNCHW()))); for (int i = 0; i < inputs.Length; i++) { _inputs.Add(layer.Inputs[i], inputs[i]); } _outputs.Add(op.Outputs(0), layer.Output); return(layer); }
private Layer ConvertMean(tflite.Operator op) { var inputs = op.GetInputsArray(); var input = _graph.Tensors(inputs[0]).Value; var axes = _model.GetTensor <int>(_graph.Tensors(inputs[1]).Value); if (axes.ToArray().SequenceEqual(new[] { 1, 2 })) { var layer = new GlobalAveragePool(input.GetShapeArray().ToNCHW()); _inputs.Add(layer.Input, inputs[0]); var reshape = new Reshape(layer.Output.Dimensions, new[] { -1, layer.Output.Dimensions[1] }); reshape.Input.SetConnection(layer.Output); _outputs.Add(op.Outputs(0), layer.Output); return(reshape); } else { throw new LayerNotSupportedException(op.ToString(), "Only [1,2] axis mean is supported"); } }
private Layer ConvertL2Normalization(tflite.Operator op) { var inputs = op.GetInputsArray(); var input = _graph.Tensors(inputs[0]).Value; if (input.ShapeLength == 4 && (input.Shape(1) != 1 || input.Shape(2) != 1)) { var flatten = new TensorflowFlatten(input.GetShapeArray().ToNCHW()); var layer = new L2Normalization(flatten.Output.Dimensions); layer.Input.SetConnection(flatten.Output); _inputs.Add(flatten.Input, inputs[0]); _outputs.Add(op.Outputs(0), layer.Output); return(layer); } else { var layer = new L2Normalization(input.GetShapeArray().ToNCHW()); _inputs.Add(layer.Input, inputs[0]); _outputs.Add(op.Outputs(0), layer.Output); return(layer); } }