在我们实现网络训练或者自定义loss函数式,要计算预测图score和GT图target之间的loss时,score和target的shape需要保持一致,而标签数据label通常只是索引信息,我们需要将label数据通过onehot编码转化为向量(矩阵)target,在target中对应label索引的位置为1.0,其余为0.0,通常label类型为int,转化后的target为float
首先定义batch_szie,num_classes,H,W
bs=16
num_classes=5
H=128
W=128
2D Tensor:
label:shape:[bs] dtype:torch.int64===>target: shape:[bs,num_classes] dtype:torch.float32
score: shape:[bs,num_classes] dtype:torch.float32
KD Tensor:
label:shape:[bs,H,W] dtype:torch.int64===>target: shape:[bs,num_classes,H,W] dtype:torch.float32
score: shape:[bs,num_classes,H,W] dtype:torch.float32
根据index(LongTensor)中的索引值将value(float)或src(Tensor)中的所有值写入self(Tensor)中,写入位置在dim维度的索引由index确定
对于2D tensor,slef更新规则:
self[index[i][j]][j]=src[i][j]
self[i][index[i][j]]=src[i][j]
对于4D tensor,self更新规则:
self[index[i][j][h][w]][j][h][w]=src[i][j][h][w]
self[i][index[i][j][h][w]][h][w]=src[i][j][h][w]
self[i][j][index[i][j][h][w]][w]=src[i][j][h][w]
self[i][j][h][index[i][j][h][w]]=src[i][j][h][w]
可见self,index和src必须有相同的维度
参数:
1. 定义1D label和2D score
score=torch.rand(bs,num_classes)
label=torch.randint(low=0,high=num_classes,size=(bs,))
print("score shape:{},score dtype:{}".format(score.size(),score.dtype))
print("label shape:{},label dtype:{}".format(label.size(),label.dtype))
输出:
score shape:torch.Size([16, 5]),score dtype:torch.float32
label shape:torch.Size([16]),label dtype:torch.int64
2. 将1D label转化为one-hot矩阵2D target¶
label=torch.unsqueeze(label,dim=1)
print("label shape:{},label dtype:{}".format(label.size(),label.dtype))
target=torch.zeros_like(score).scatter_(1, label, torch.ones_like(label,dtype=torch.float32))
print("target shape:{},target dtype:{}".format(target.size(),target.dtype))
输出:
label shape:torch.Size([16, 1]),label dtype:torch.int64
target shape:torch.Size([16, 5]),target dtype:torch.float32
3.测试:
print(label[0:5,0])
print(target[0:5,:])
输出:
tensor([4, 3, 4, 0, 2])
tensor([[0., 0., 0., 0., 1.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.],
[1., 0., 0., 0., 0.],
[0., 0., 1., 0., 0.]])
1. 定义3D label和4D score
score=torch.rand(bs,num_classes,H,W)
label=torch.randint(low=0,high=num_classes,size=(bs,H,W))
print("score shape:{},score dtype:{}".format(score.size(),score.dtype))
print("label shape:{},label dtype:{}".format(label.size(),label.dtype))
输出:
score shape:torch.Size([16, 5, 128, 128]),score dtype:torch.float32
label shape:torch.Size([16, 128, 128]),label dtype:torch.int64
2. 将3D label转化为one-hot矩阵4D target¶
label=torch.unsqueeze(label,dim=1)
print("label shape:{},label dtype:{}".format(label.size(),label.dtype))
target=torch.zeros(bs,num_classes,H,W).scatter_(1, label, torch.ones_like(label,dtype=torch.float32))
print("target shape:{},target dtype:{}".format(target.size(),target.dtype))
输出:
label shape:torch.Size([16, 1, 128, 128]),label dtype:torch.int64
target shape:torch.Size([16, 5, 128, 128]),target dtype:torch.float32
3.测试
print(label[2:6,0,66,60])
print(target[2:6,:,66,60])
输出:
tensor([4, 1, 2, 3])
tensor([[0., 0., 0., 0., 1.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.]])
2D Tensor:
label:shape:[bs] dtype:tf.int32===>target: shape:[bs,num_classes] dtype:tf.float32
score: shape:[bs,num_classes] dtype:tf.float32
KD Tensor:
label:shape:[bs,H,W] dtype:tf.int32===>target: shape:[bs,H,W,num_classes] dtype:tf.float32
score: shape:[bs,H,W,num_classes] dtype:tf.float32
tf.one_hot(indices,depth,on_value=None,off_value=None,axis=None,dtype=None,name=None)
[bs,depth](axis=-1)
或者[depth,bs](axis=0)
参数:
1. 定义1D label和2D score
score=tf.random.uniform((bs,num_classes),0,1)
label_numpy=np.random.randint(low=0,high=num_classes,size=(bs,))
label=tf.convert_to_tensor(label_numpy)
print("score shape:{},score dtype:{}".format(score.shape,score.dtype))
print("label shape:{},label dtype:{}".format(label.shape,label.dtype))
输出:
score shape:(16, 5),score dtype:
label shape:(16,),label dtype:
2.将1D label转化为one-hot矩阵2D target
target=tf.one_hot(indices=label,depth=num_classes,on_value=1.0,off_value=0.0,axis=1,dtype=tf.float32)
print("target shape:{},target dtype:{}".format(target.shape,target.dtype))
输出:
target shape:(16, 5),target dtype:
3.测试
print(label[1:5,])
print(target[1:5,:])
输出:
tf.Tensor([3 2 4 4], shape=(4,), dtype=int32)
tf.Tensor(
[[0. 0. 0. 1. 0.]
[0. 0. 1. 0. 0.]
[0. 0. 0. 0. 1.]
[0. 0. 0. 0. 1.]], shape=(4, 5), dtype=float32)
1. 定义3D label和4D score
score=tf.random.uniform((bs,H,W,num_classes),0,1)
label_numpy=np.random.randint(low=0,high=num_classes,size=(bs,H,W))
label=tf.convert_to_tensor(label_numpy)
print("score shape:{},score dtype:{}".format(score.shape,score.dtype))
print("label shape:{},label dtype:{}".format(label.shape,label.dtype))
输出:
score shape:(16, 128, 128, 5),score dtype:
label shape:(16, 128, 128),label dtype:
2.将3D label转化为one-hot矩阵4D target
target=tf.one_hot(indices=label,depth=num_classes,on_value=1.0,off_value=0.,axis=3,dtype=tf.float32)
print("target shape:{},target dtype:{}".format(target.shape,target.dtype))
输出:
target shape:(16, 128, 128, 5),target dtype:
3. 测试
print(label[2:6,66,66])
print(target[2:6,66,66,:])
输出:
tf.Tensor([0 4 4 3], shape=(4,), dtype=int32)
tf.Tensor(
[[1. 0. 0. 0. 0.]
[0. 0. 0. 0. 1.]
[0. 0. 0. 0. 1.]
[0. 0. 0. 1. 0.]], shape=(4, 5), dtype=float32)