简体   繁体   English

代码优化:Torch.Tensor中的计算

[英]Code Optimization: Computation in Torch.Tensor

I am currently implementing a function to compute Custom Cross Entropy Loss. 我目前正在实现一个计算自定义交叉熵损失的函数。 The definition of the function is a following image. 该函数的定义如下图。

引自Huan Fu等人的“用于单眼深度估计的深度序数回归网络”。 CVPR 2018

my codes are as following, 我的代码如下

output = output.permute(0, 2, 3, 1)
target = target.permute(0, 2, 3, 1)

batch, height, width, channel = output.size()

total_loss = 0.
for b in range(batch): # for each batch
    o = output[b]
    t = target[b]
    loss = 0.
    for w in range(width):
        for h in range(height): # for every pixel([h,w]) in the image
            sid_t = t[h][w][0]
            sid_o_candi = o[h][w]
            part1 = 0. # to store the first sigma 
            part2 = 0. # to store the second sigma

            for k in range(0, sid_t):
                p = torch.sum(sid_o_candi[k:]) # to get Pk(w,h)
                part1 += torch.log(p + 1e-12).item()

            for k in range(sid_t, intervals):
                p = torch.sum(sid_o_candi[k:]) # to get Pk(w,h)
                part2 += torch.log(1-p + 1e-12).item()

            loss += part1 + part2

    loss /= width * height * (-1)
    total_loss += loss
total_loss /= batch
return torch.tensor(total_loss, dtype=torch.float32)

I am wondering is there any optimization could be done with these code. 我想知道是否可以对这些代码进行任何优化。

I'm not sure sid_t = t[h][w][0] is the same for every pixel or not. 我不确定sid_t = t[h][w][0]是否对每个像素都相同。 If so, you can get rid of all for loop which boost the speed of computing loss. 如果是这样,您可以消除所有for loop ,从而提高计算损失的速度。

Don't use .item() because it will return a Python value which loses the grad_fn track. 不要使用.item()因为它将返回丢失grad_fn轨道的Python值。 Then you can't use loss.backward() to compute the gradients. 然后,您将无法使用loss.backward()计算梯度。

If sid_t = t[h][w][0] is not the same, here is some modification to help you get rid of at least 1 for-loop : 如果sid_t = t[h][w][0]不相同,请进行以下修改以帮助您摆脱至少1个for-loop



batch, height, width, channel = output.size()

total_loss = 0.
for b in range(batch): # for each batch
    o = output[b]
    t = target[b]
    loss = 0.
    for w in range(width):
        for h in range(height): # for every pixel([h,w]) in the image
            sid_t = t[h][w][0]
            sid_o_candi = o[h][w]
            part1 = 0. # to store the first sigma 
            part2 = 0. # to store the second sigma

            sid1_cumsum = sid_o_candi[:sid_t].flip(dim=(0,)).cumsum(dim=0).flip(dims=(0,)) 
            part1 = torch.sum(torch.log(sid1_cumsum + 1e-12))

            sid2_cumsum = sid_o_candi[sid_t:intervals].flip(dim=(0,)).cumsum(dim=0).flip(dims=(0,)) 
            part2 = torch.sum(torch.log(1 - sid2_cumsum + 1e-12))

            loss += part1 + part2

    loss /= width * height * (-1)
    total_loss += loss
total_loss /= batch
return torch.tensor(total_loss, dtype=torch.float32)

How it works: 这个怎么运作:

x = torch.arange(10); 
print(x)

x_flip = x.flip(dims=(0,)); 
print(x_flip)

x_inverse_cumsum = x_flip.cumsum(dim=0).flip(dims=(0,))
print(x_inverse_cumsum)

# output
tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
tensor([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
tensor([45, 45, 44, 42, 39, 35, 30, 24, 17,  9])

Hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM