【问题标题】:about torch.nn.CrossEntropyLoss parameter shape关于 torch.nn.CrossEntropyLoss 参数形状
【发布时间】:2017-09-10 10:15:42
【问题描述】:

我正在学习 pytorch,并参加了基于 tensorflow 的 anpr 项目 (https://github.com/matthewearl/deep-anpr, http://matthewearl.github.io/2016/05/06/cnn-anpr/) 作为练习,移植到pytorch平台。

有一个问题,我正在使用 nn.CrossEntropyLoss() 作为损失函数:

criterion=nn.CrossEntropyLoss()

模型的输出数据为:

  - 1.00000e-02 *
   - 2.5552 2.7582 2.5368 ... 5.6184 1.2288 -0.0076
   - 0.7033 1.3167 -1.0966 ... 4.7249 1.3217 1.8367
   - 0.7592 1.4777 1.8095 ... 0.8733 1.2417 1.1521
   - 0.1040 -0.7054 -3.4862 ... 4.7703 2.9595 1.4263 
   - [torch.FloatTensor of size 4x253]

targets.data 是:

 - 1 0 0 ... 0 0 0
 - 1 0 0 ... 0 0 0
 - 1 0 0 ... 0 0 0
 - 1 0 0 ... 0 0 0
 - [torch.DoubleTensor of size 4x253]

当我打电话时:

loss=criterion(output,targets)

发生错误,信息为:

TypeError: FloatClassNLLCriterion_updateOutput received an invalid combination of arguments - got (int, torch.FloatTensor, **torch.DoubleTensor**, torch.FloatTensor, bool, NoneType, torch.FloatTensor), but expected (int state, torch.FloatTensor input, **torch.LongTensor** target, torch.FloatTensor output, bool sizeAverage, [torch.FloatTensor weights or None], torch.FloatTensor total_weight)

'expected torch.LongTensor'......'got torch.DoubleTensor',but if i convert the targets into LongTensor:
torch.LongTensor(numpy.array(targets.data.numpy(),numpy.long))

调用loss=criterion(output,targets),错误为:

RuntimeError: multi-target not supported at /data/users/soumith/miniconda2/conda-bld/pytorch-0.1.10_1488752595704/work/torch/lib/THNN/generic/ClassNLLCriterion.c:20

我最后的练习是mnist,一个pytorch的例子,我做了一点修改,batch_size是4,损失函数:

loss = F.nll_loss(outputs, labels)

输出.数据:

 - -2.3220 -2.1229 -2.3395 -2.3391 -2.5270 -2.3269 -2.1055 -2.2321 -2.4943 -2.2996

   -2.3653 -2.2034 -2.4437 -2.2708 -2.5114 -2.3286 -2.1921 -2.1771 -2.3343 -2.2533

   -2.2809 -2.2119 -2.3872 -2.2190 -2.4610 -2.2946 -2.2053 -2.3192 -2.3674 -2.3100

   -2.3715 -2.1455 -2.4199 -2.4177 -2.4565 -2.2812 -2.2467 -2.1144 -2.3321 -2.3009

   [torch.FloatTensor of size 4x10]

标签.数据:

 - 8 
 - 6 
 - 0 
 - 1 
 - [torch.LongTensor of size 4]

标签,对于输入图像,必须是单个元素,在上例中,有 253 个数字,而在 'mnist' 中,只有一个数字,输出的形状与标签不同。

我查看了 tensorflow 手册,tf.nn.softmax_cross_entropy_with_logits, 'Logits 和标签必须具有相同的形状 [batch_size, num_classes] 和相同的 dtype(float32 或 float64)。'

pytorch 是否支持 tensorflow 中的相同功能?

很多想法

【问题讨论】:

    标签: loss pytorch


    【解决方案1】:

    您可以将您拥有的目标转换为分类表示。 在您提供的示例中,如果类为 0,则为 1 0 0 0.. 0,如果类为 1,则为 0 1 0 0 ...,如果类为 2,则为 0 0 1 0 0 0...等等。 我能想到的一种快速方法是首先将目标张量转换为 numpy 数组,然后将其从一个热转换为分类数组,然后将其转换回 pytorch 张量。像这样的:

    targetnp=targets.numpy()
    idxs=np.where(targetnp>0)[1]
    new_targets=torch.LongTensor(idxs)
    loss=criterion(output,new_targets)
    

    【讨论】:

      【解决方案2】:

      CrossEntropyLoss 等价于tf.nn.softmax_cross_entropy_with_logitsCrossEntropyLoss 的输入是一个形状为 [batch_size] 的分类向量。使用.view() 更改张量形状。

      labels = labels.view(-1) output = output.view(labels.size(0), -1) loss = criterion(output, loss)

      调用.view(x, y, -1) 会导致张量使用剩余的数据点来填充-1 维度,如果没有足够的维度来制作完整维度,则会导致错误

      labels.size(0) 给出了label 张量的第 0 维的大小

      附加

      要在张量类型之间进行转换,您可以调用张量上的类型,例如 'labels = labels.long()`

      第二次补充

      如果您从像 output.data 这样的变量中解压缩数据,那么您将丢失该输出的梯度,并且在时机成熟时无法进行反向传播

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-03-19
        • 2022-06-15
        • 2021-09-16
        • 2018-04-17
        • 2017-08-27
        • 2016-06-23
        • 1970-01-01
        相关资源
        最近更新 更多