• nn.CrossEntropyLoss


    nn.CrossEntropyLoss

    pytorch中交叉熵计算方式为:

    \[H(p,q) = -\sum p(i)logq(i) \]

    其中,p为真实值矩阵,q为预测值矩阵
    当P使用one-hot embedding时,只有在分类正确时

    nn.CrossEntropyLoss()计算包括:
    Softmax --> log --> NLLoss

    1. softmax:将数值映射到01之间,故ln后的值为-inf0
    2. 对Softmax的结果取log,将乘法改为加法,减少计算量,同时保持函数的单调性
    3. NLLoss:将log结果中与label对应的值取出,去掉负号求均值。

    官方文档

    torch.nn.functional.cross_entropy(input, target, weight=None, size_average=True)
    
    

    input: [batch_size, num_class]
    target: [batch_size]

    参数 shape 注释
    input (N,C) C为类别数
    target N 0<= targets[i] <= C-1
    import torch
    import torch.nn as nn
    x_input=torch.randn(3,3)#随机生成输入 
    print('x_input:\n',x_input) 
    y_target=torch.tensor([1,2,0])#设置输出具体值 print('y_target\n',y_target)
    
    #计算输入softmax,此时可以看到每一行加到一起结果都是1
    softmax_func=nn.Softmax(dim=1)
    soft_output=softmax_func(x_input)
    print('soft_output:\n',soft_output)
    
    #在softmax的基础上取log
    log_output=torch.log(soft_output)
    print('log_output:\n',log_output)
    
    #对比softmax与log的结合与nn.LogSoftmaxloss(负对数似然损失)的输出结果,发现两者是一致的。
    logsoftmax_func=nn.LogSoftmax(dim=1)
    logsoftmax_output=logsoftmax_func(x_input)
    print('logsoftmax_output:\n',logsoftmax_output)
    
    #pytorch中关于NLLLoss的默认参数配置为:reducetion=True、size_average=True
    nllloss_func=nn.NLLLoss()
    nlloss_output=nllloss_func(logsoftmax_output,y_target)
    print('nlloss_output:\n',nlloss_output)
    
    #将结果与nn.CrossEntropyLoss()结果进行对比
    cross_entropyloss=nn.CrossEntropyLoss()
    cross_entropyloss_output=crossentropyloss(x_input,y_target)
    print('cross_entropyloss_output:\n',crossentropyloss_output)
    

    output:

    x_input:
     tensor([[ 2.8883,  0.1760,  1.0774],
            [ 1.1216, -0.0562,  0.0660],
            [-1.3939, -0.0967,  0.5853]])
    y_target
     tensor([1, 2, 0])
    soft_output:
     tensor([[0.8131, 0.0540, 0.1329],
            [0.6039, 0.1860, 0.2102],
            [0.0841, 0.3076, 0.6083]])
    log_output:
     tensor([[-0.2069, -2.9192, -2.0178],
            [-0.5044, -1.6822, -1.5599],
            [-2.4762, -1.1790, -0.4970]])
    logsoftmax_output:
     tensor([[-0.2069, -2.9192, -2.0178],
            [-0.5044, -1.6822, -1.5599],
            [-2.4762, -1.1790, -0.4970]])
    nlloss_output:
     tensor(2.3185)
    cross_entropyloss_output:
     tensor(2.3185)
    

    发现通过nn.CrossEntropyLoss()计算得到的结果与nn.LogSoftmax --> NLLLoss()结果相同。

    使用时遇到的问题:

    loss_id = self.IDLoss(id_preds, id_targets)
    
    "nll_loss_forward_reduce_cuda_kernel_2d_index" not implemented for 'Int'
    

    解决方法:

    数据类型转换

    id_targets = id_targets.to(torch.int64)     # TODO: ReID. [matched_anchor], float16 to int
    

    F.cross_entropy只是一个函数,nn.CrossEntropyLoss不仅可以计算还可以进行反向传播,是网络的一个层

    来源:
    https://blog.csdn.net/qq_41683065/article/details/122441927
    https://blog.csdn.net/wuliBob/article/details/104119616

  • 相关阅读:
    数据类型
    java基础
    Codeforces Round #655 (Div. 2) B. Omkar and Last Class of Math(数论)
    Codeforces Round #655 (Div. 2) A. Omkar and Completion(构造)
    LibreOJ
    QT入门-QMainWindow类
    WCF 请求与响应参数大小设置
    Python 代码性能优化技巧
    lists,tuples and sets of Python
    SQL Language
  • 原文地址:https://www.cnblogs.com/ArdenWang/p/15968481.html
Copyright © 2020-2023  润新知