1

我正在尝试在 iOS 上运行分段模型,我对如何正确使用输出张量有几个问题。

这里是我正在使用的模型的链接: https ://www.tensorflow.org/lite/models/segmentation/overview

当我运行这个模型时,我得到了尺寸为:1 x 257 x 257 x 21 的输出张量。为什么我得到 21 作为最后一个维度?看起来我们正在获得每个像素的类分数。我们是否需要在这里找到 argmax 才能得到正确的类值?

但为什么只有 21 节课?我在想它应该包含更多。在哪里我可以找到哪个值对应于某个类的信息。在 ImageClassification 示例中,我们有一个包含 1001 个类的 label.txt。

基于 ImageClassification 示例,我尝试解析张量:首先将其转换为大小为 1 387 029 (21 x 257 x 257) 的浮点数组,然后使用以下代码逐像素创建图像:

    // size = 257
    // depth = 21
    // array - float array of size 1 387 029
    for i in 0..<size {
        for j in 0..<size {
            var scores: [Float] = []
            for k in 0..<depth {
                let index = i * size * depth + j * depth + k
                let score = array[index]
                scores.append(score)
            }
            if let maxScore = scores.max(),
                let maxClass = scores.firstIndex(of: maxScore) {
                let index = i * size + j

                if maxClass == 0 {
                    pixelBuffer[index] = .blue
                } else if maxClass == 12 {
                    pixelBuffer[index] = .black
                } else {
                    pixelBuffer[index] = .green
                }
            }
        }
    }

这是我得到的结果:

在此处输入图像描述

你可以看到质量不是很好。我错过了什么?

CoreML 的分割模型(https://developer.apple.com/machine-learning/models/)在同一个例子中效果更好:

在此处输入图像描述

4

2 回答 2

3

看起来您的模型是在PASCAL VOC数据上训练的,该数据有 21 个用于分割的类。您可以在此处
找到课程列表:

背景
飞机
自行车



总线
汽车

椅子

餐桌


摩托车

盆栽

沙发
火车
tvmonitor

于 2019-07-23T11:51:51.653 回答
1

除了 Shai 的答案之外,您还可以使用像Netron这样的工具来可视化您的网络并更深入地了解输入和输出,例如您的输入将是大小为 257x257x3 的图像: 在此处输入图像描述

而且你已经知道你的输出大小,对于分割模型,你得到了 21,因为这是 Shai 提到的模型支持的类的数量,然后为所有类取每个像素的 argmax,这应该会给你一个更体面的输出,无需调整任何大小,尝试类似(在伪代码中):

output = [rows][cols]
for i in rows:
  for j in cols:
    argmax = -1
    for c in classes:
      if tensor_out[i][j][c] > argmax:
        argmax = tensor_out[i][j][c]
    output[i][j] = c

然后输出将是您的分割图像。

于 2019-07-25T10:21:42.037 回答