我正在使用 u-net 对 N>1 个类进行语义分割。输入大小为 (128,128,3),输出大小为 (128,128,N)。将预测视为大小为 n1 x n2 x 1 的图像的正确方法是什么?
我的尝试:如果输出张量中的每个 (i,j) 向量(大小为 N),我取最大值以获得标量并绘制 128 x 128 图像。
我正在使用 u-net 对 N>1 个类进行语义分割。输入大小为 (128,128,3),输出大小为 (128,128,N)。将预测视为大小为 n1 x n2 x 1 的图像的正确方法是什么?
我的尝试:如果输出张量中的每个 (i,j) 向量(大小为 N),我取最大值以获得标量并绘制 128 x 128 图像。
如果您说您的模型为每个像素生成一个长度为 N 的向量(保存该像素的每个类别的概率),那么您选择最大值当然是正确的。
对于绘图,如果您将图像保留在 中128x128,您的输出将只是灰度,如果您正在绘制从每个向量中获取的原始最大值,我想图像会非常嘈杂。
您需要将每个像素的类别映射到预定义的颜色映射。例如,如果你有 classes: tree, car, building, sky,你应该为每一个决定一个颜色。例如,指定将每个类映射到颜色的字典:
colour_mappings = {
'tree': (255, 255, 255) # white
'car': (255, 0, 0) # red
'building': (0, 255, 0) # green
'sky': (0, 0, 255) # blue
}
不,当您有 size 的输出矩阵时128x128,您可以使用过滤将每个分类像素替换为您在上面映射中放置的颜色。
我使用上面的颜色映射以及像素分类结果的模拟矩阵(为简单起见,仅为 5x5,而不是 128x128),随机填充以下值[0, 1, 2, 3]:
classes = array([[0, 3, 3, 1, 0],
[2, 2, 0, 3, 2],
[3, 1, 0, 0, 1],
[1, 3, 2, 2, 2],
[1, 3, 1, 2, 1]])
现在创建一个具有三个通道的数组,我们将根据我们的结果对其进行填充。我只是用零初始化它,这将是黑色的,这没关系,因为我在上面的映射中的类都不是黑色的(只是为了避免混淆):
# initialise an empty (black) matrix to hold the image
segmented_image = np.ones((5, 5, 3)) # we require three channel dims for RGB colour
假设上面的类(以相同的顺序)具有数字0, 1, 2, 3- 然后您可以使用如下颜色填充空图像矩阵。
# fill the segmented image based on the class, using your mappings
segmented_image[classes == 0] = colour_mappings['tree']
这将产生以下图像,我们看到类“树”中的所有像素现在显示映射颜色,白色:
现在我们可以对剩下的类做同样的事情:
segmented_image[classes == 1] = colour_mappings['car']
segmented_image[classes == 2] = colour_mappings['building']
segmented_image[classes == 3] = colour_mappings['sky']
这将产生以下最终图像:
可以根据classes上面显示的矩阵进行检查。