Problem with TensorFloat .netcore (CustomVision)

78 Views Asked by At

Well i've been doing some work with AI and object detection and have recently encounter somewhat of a problem with a model that i exported from CustomVision. For the ones who know what i'm talking about, when you export a model from CustomVision you get a .cs file included that represents the class with everything you need to use the model. And there starts all my problems.. first and most important one is that in one of the methods, specifically in the "ExtractBoxes" method receives a TensorFloat object and a float array of anchors. Anyways.. inside this method there's 4 variables called "channels", "height" and "width" that come from a list inside of the TensorFloat object called "shape". Given all this.. my question resides in the TensorFloat object, more specifically in how can i get the values for the variables "channels", "height" and "width" without having a TensorFloat object.

Below im going to include the code from the .cs file that im talking about. Thanks in advance!

public async Task<IList<PredictionModel>> PredictImageAsync(VideoFrame image)
{
    var imageWidth = image.SoftwareBitmap.PixelWidth;
    var imageHeight = image.SoftwareBitmap.PixelHeight;

    double ratio = Math.Sqrt((double)imageInputSize / (double)imageWidth / (double)imageHeight);
    int targetWidth = 32 * (int)Math.Round(imageWidth * ratio / 32);
    int targetHeight = 32 * (int)Math.Round(imageHeight * ratio / 32);

    using (var resizedBitmap = await ResizeBitmap(image.SoftwareBitmap, targetWidth, targetHeight))
    using (VideoFrame resizedVideoFrame = VideoFrame.CreateWithSoftwareBitmap(resizedBitmap))
    {
        var imageFeature = ImageFeatureValue.CreateFromVideoFrame(resizedVideoFrame);
        var bindings = new LearningModelBinding(this.session);
        bindings.Bind("input", imageFeature);

        var result = await this.session.EvaluateAsync(bindings, "");

        return Postprocess(result.Outputs["output"] as TensorFloat);
    }
}

private List<PredictionModel> Postprocess(TensorFloat predictionOutputs)
{
    var extractedBoxes = this.ExtractBoxes(predictionOutputs, ObjectDetection.Anchors);
    return this.SuppressNonMaximum(extractedBoxes);
}

private ExtractedBoxes ExtractBoxes(TensorFloat predictionOutput, float[] anchors)
{
            var shape = predictionOutput.Shape;
            Debug.Assert(shape.Count == 4, "The model output has unexpected shape");
            Debug.Assert(shape[0] == 1, "The batch size must be 1");

            IReadOnlyList<float> outputs = predictionOutput.GetAsVectorView();

            var numAnchor = anchors.Length / 2;
            var channels = shape[1];
            var height = shape[2];
            var width = shape[3];

            Debug.Assert(channels % numAnchor == 0);
            var numClass = (channels / numAnchor) - 5;

            Debug.Assert(numClass == this.labels.Count);

            var boxes = new List<BoundingBox>();
            var probs = new List<float[]>();
            for (int gridY = 0; gridY < height; gridY++)
            {
                for (int gridX = 0; gridX < width; gridX++)
                {
                    int offset = 0;
                    int stride = (int)(height * width);
                    int baseOffset = gridX + gridY * (int)width;

                    for (int i = 0; i < numAnchor; i++)
                    {
                        var x = (Logistic(outputs[baseOffset + (offset++ * stride)]) + gridX) / width;
                        var y = (Logistic(outputs[baseOffset + (offset++ * stride)]) + gridY) / height;
                        var w = (float)Math.Exp(outputs[baseOffset + (offset++ * stride)]) * anchors[i * 2] / width;
                        var h = (float)Math.Exp(outputs[baseOffset + (offset++ * stride)]) * anchors[i * 2 + 1] / height;

                        x = x - (w / 2);
                        y = y - (h / 2);

                        var objectness = Logistic(outputs[baseOffset + (offset++ * stride)]);

                        var classProbabilities = new float[numClass];
                        for (int j = 0; j < numClass; j++)
                        {
                            classProbabilities[j] = outputs[baseOffset + (offset++ * stride)];
                        }
                        var max = classProbabilities.Max();
                        for (int j = 0; j < numClass; j++)
                        {
                            classProbabilities[j] = (float)Math.Exp(classProbabilities[j] - max);
                        }
                        var sum = classProbabilities.Sum();
                        for (int j = 0; j < numClass; j++)
                        {
                            classProbabilities[j] *= objectness / sum;
                        }

                        if (classProbabilities.Max() > this.probabilityThreshold)
                        {
                            boxes.Add(new BoundingBox(x, y, w, h));
                            probs.Add(classProbabilities);
                        }
                    }
                    Debug.Assert(offset == channels);
                }
            }

            Debug.Assert(boxes.Count == probs.Count);
            return new ExtractedBoxes(boxes, probs);
}
0

There are 0 best solutions below