pytorch实现焦点丢失的两种方式小结

  

<强>我就废话不多说了,直接上代码吧!

        进口火炬   进口torch.nn。功能和F   进口numpy np   从火炬。autograd导入变量   “‘   pytorch实现焦点丢失的两种方式(现在讨论的是基于分割任务)   在计算损失函数的过程中考虑到类别不平衡的问题,假设加上背景类别共有6个类别   “‘   def compute_class_weights(柱状图):   classWeights=np。(6,dtype=np.float32)   normHist=直方图/np.sum(柱状图)   因为我在范围(6):   classWeights[我]=1/(np.log (1.10 + normHist[我]))   返回classWeights   def focal_loss_my(输入,目标):   “‘   参数输入:形状(batch_size num_classes, H, W)仅仅经过卷积操作后的输出,并没有经过任何激活函数的作用   :param目标:形状(batch_size H, W)   返回:   “‘   n、c, h, w=input.size ()      目标=target.long ()   输入=V?1、2).transpose (2、3) .contiguous ()。视图(1 c)   目标=target.contiguous () .view (1)      number_0=火炬。和(目标==0).item ()   number_1=火炬。总和(目标==1).item ()   number_2=火炬。总和(目标==2).item ()   number_3=火炬。总和(目标==3).item ()   number_4=火炬。总和(目标==4).item ()   number_5=火炬。总和(目标==5).item ()      频率=火炬。张量((number_0 number_1、number_2 number_3, number_4, number_5), dtype=torch.float32)   频率=frequency.numpy ()   classWeights=compute_class_weights(频率)   “‘   根据当前给出的地面实况标签计算出每个类别所占据的权重   “‘      #权重=torch.from_numpy (classWeights) .float () .cuda ()   重量=torch.from_numpy (classWeights) .float ()   focal_frequency=F.nll_loss (F。softmax(输入,昏暗的=1),目标,减少='没有')   “‘   上面一篇博文讲过   F.nll_loss (torch.log (F。softmax(输入,昏暗的=1),目标)的函数功能与F.cross_entropy相同   可见F。nll_loss中实现了对于目标的一个炎热的编码编码功能,将其编码成与输入形状相同的张量   然后与前面那一项(即F。nll_loss输入的第一项)进行element-wise生产   相当于取出了日志(p_gt)即当前样本点被分类为正确类别的概率   现在去掉取对数的操作,相当于focal_frequency形状(num_samples)   即取出地面实况类别的概率数值,并取了负号   “‘      focal_frequency +=1.0 #形状(num_samples) 1 - p (gt_classes)      focal_frequency=火炬。战俘(focal_frequency, 2) # torch.Size ([75])   focal_frequency=focal_frequency。重复(c, 1)   “‘   进行重复操作后,focal_frequency形状(num_classes, num_samples)   “‘   focal_frequency=focal_frequency。置(1,0)   损失=F。nll_loss (focal_frequency * (torch.log (F。softmax(输入,昏暗的=1))),目标,重量=没有   减少=癳lementwise_mean”)   回波损耗         def focal_loss_zhihu(输入,目标):   “‘   参数输入:使用知乎上面大神给出的方案https://zhuanlan.zhihu.com/p/28527749   :param目标:   返回:   “‘   n、c, h, w=input.size ()      目标=target.long ()   输入=输入。置(1、2).transpose (2、3) .contiguous ()。视图(1 c)   目标=target.contiguous () .view (1)      N=inputs.size (0)   C=inputs.size (1)      number_0=火炬。和(目标==0).item ()   number_1=火炬。总和(目标==1).item ()   number_2=火炬。总和(目标==2).item ()   number_3=火炬。总和(目标==3).item ()   number_4=火炬。总和(目标==4).item ()   number_5=火炬。总和(目标==5).item ()      频率=火炬。张量((number_0 number_1、number_2 number_3, number_4, number_5), dtype=torch.float32)   频率=frequency.numpy ()   classWeights=compute_class_weights(频率)      重量=torch.from_numpy (classWeights) .float ()   重量=重量(target.view(1)] #这行代码非常重要      γ=2      P=F。softmax(输入,昏暗的=1)#形状(num_samples, num_classes)      class_mask=inputs.data。新(N、C) .fill_ (0)   class_mask=变量(class_mask)   id=目标。视图(1,1)   class_mask。scatter_ (id。数据,1)#形状(num_samples num_classes]一个炎热的编码      聚合氯化铝=(P * class_mask) .sum (1)。视图(1,1)#形状(num_samples,)   log_p=probs.log ()      打印(在计算batch_loss, weights.shape、probs.shape log_p.shape)      # batch_loss=重量*(火炬。战俘((1 -聚合氯化铝)γ))* log_p   batch_loss=-(火炬。战俘((1 -聚合氯化铝)γ))* log_p      打印(batch_loss.shape)      损失=batch_loss.mean ()   回波损耗      if __name__==癬_main__”:   pred=torch.rand ((2、6、5、5))   y=torch.from_numpy (np.random.randint (0 6 (2、5、5)))   loss1=focal_loss_my (pred, y)   loss2=focal_loss_zhihu (pred, y)      打印(loss1, loss1)   打印(loss2, loss2)   “‘   在计算batch_loss torch.Size火炬([50])。大小([50,1])火炬。大小([50,1])   火炬。大小([50,1])   loss1张量(1.3166)   loss2张量(1.3166)   “‘   

pytorch实现焦点丢失的两种方式小结