首页 > 解决方案 > TensorFloat .netcore (CustomVision) 的问题

问题描述

好吧,我一直在做一些关于人工智能和对象检测的工作,最近我从 CustomVision 导出的模型遇到了一些问题。对于那些知道我在说什么的人,当您从 CustomVision 导出模型时,您会得到一个包含的 .cs 文件,该文件代表包含使用模型所需的一切的类。这开始了我所有的问题.. 第一个也是最重要的一个是在其中一种方法中,特别是在“ExtractBoxes”方法中接收一个 TensorFloat 对象和一个浮点数组的锚点。不管怎样.. 在这个方法里面有 4 个变量叫做“channels”、“height”和“width”,它们来自一个叫做“shape”的 TensorFloat 对象内部的列表。鉴于这一切.. 我的问题在于 TensorFloat 对象,

下面我将包含我正在谈论的 .cs 文件中的代码。提前致谢!

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);
}

标签: c#.net.net-coreartificial-intelligencemicrosoft-custom-vision

解决方案


推荐阅读