在用写的分割模型dice计算公式时,需要先对分割mask进行one-hot编码,以和输出的分割相匹配。以分割mask大小为[1,3,3,2],pred_mask 为[1,4,3,3,2]为例子,假设分割目标区域有三个,加上背景一共4个。
class_num=4
label=torch.tensor([[[[0,1],[0,2],[3,1]],[[0,0],[1,2],[2,1]],[[2,2],[1,1],[3,3]]]])
#print(label.shape) #[1,3,3,2] 第一个1是batch数
label.unsqueeze_(1)#带横杠就表示直接在x上修改,不用写x=x....这种格式
print(label.shape)
print(label)
y=torch.zeros(1,class_num,3,3,2) # 生成全0的[1,4,3,3,2],要与编码后维度相同
y=y.scatter(1,label,1 ) # scatter(dim , label ,1 )
print(y.shape)
print(y)
scatter(dim, label, 1)中,dim指想填充进y的哪个维度,1代表第二个维度,label指要进行one-hot编码的mask,注意,要把这个label的维度数先变得和y相同,所以用了unsqueeze_(1)在dim=1的地方加1维,scatter()中最后一个参数指要填入进去的数,我们用one-hot就是填入1就好。最后的输出y就是one-hot编码后的结果。
结果如下:
#before one-hot
torch.Size([1, 1, 3, 3, 2])
tensor([[[[[0, 1],
[0, 2],
[3, 1]],[[0, 0],
[1, 2],
[2, 1]],[[2, 2],
[1, 1],
[3, 3]]]]])#after one-hot
torch.Size([1, 4, 3, 3, 2])
tensor([[[[[1., 0.],
[1., 0.],
[0., 0.]],[[1., 1.],
[0., 0.],
[0., 0.]],[[0., 0.],
[0., 0.],
[0., 0.]]],
[[[0., 1.],
[0., 0.],
[0., 1.]],[[0., 0.],
[1., 0.],
[0., 1.]],[[0., 0.],
[1., 1.],
[0., 0.]]],
[[[0., 0.],
[0., 1.],
[0., 0.]],[[0., 0.],
[0., 1.],
[1., 0.]],[[1., 1.],
[0., 0.],
[0., 0.]]],
[[[0., 0.],
[0., 0.],
[1., 0.]],[[0., 0.],
[0., 0.],
[0., 0.]],[[0., 0.],
[0., 0.],
[1., 1.]]]]])
如上,在看结果时一定要从dim=1的维度上看,这个维度的大小是4,说明有4块[3,3,2]大小的tensor, 那么把 原来[3,3,2]大小的label内的每一个位置的数都对应到4个通道,如图,0对应下面的[1,0,0,0], 1对应[0,1,0,0], 2对应[0,0,1,0], 3对应[0,0,0,1]。 编码完成。
注意:按照惯例编码的位置都是如上最小在第一个位置,然后由小到大排序,所以不必担心与调用pytorch库里包含独热编码的loss函数一起用时会出问题。