首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何改变张量的形状?

如何改变张量的形状?
EN

Stack Overflow用户
提问于 2020-06-15 07:44:15
回答 2查看 1.6K关注 0票数 1

问题定义:

我不得不用MSELoss函数来定义损失分类问题。因此,它一直在说关于张量形状的错误信息。

完整错误消息:

torch.Size(32,10)跟踪(最近一次调用)在53输出=模型中的torch.Size(32).forward(图像) 54打印(output.shape,labels.shape) -> 55损失=标准(输出,标签) 56 loss.backward() 57 optimizer.step()

/opt/conda/lib/python3.7/site-packages/torch/nn/modules/module.py in call(self,*input,**kwargs) 530结果=self._slow_forward(*输入,**kwargs) 531其他:-> 532 =self.forward(*输入,**kwargs) 533用于self._forward_hooks.values()中的钩子: 534 hook_result =钩子(self,input,result)

/opt/conda/lib/python3.7/site-packages/torch/nn/modules/loss.py在前进(自我,输入,目标)429430前进(自我,输入,目标):-> 431返回F.mse_loss(输入,目标,reduction=self.reduction) 432 433

/opt/conda/lib/python3.7/site-packages/torch/nn/functional.py in mse_loss(输入、目标、size_average、缩减、缩减) 2213

ret = torch.mean(ret)如果还原==‘意味着’其他torch.sum(ret)

其它:-> 2215 expanded_input,expanded_target =torch.broadcast_tensors(输入,目标) 2216 ret = torch._C._nn.mse_loss(expanded_input,expanded_target,_Reduction.get_enum(还原))

/opt/conda/lib/python3.7/site-packages/torch/functional.py in broadcast_tensors(*张量) 50 0,1,2]) 51“”--> 52返回torch._C._VariableFunctions.broadcast_tensors(tensors) 53 54

> RuntimeError:张量a (10)的大小必须与非单例维的张量b (32)的大小相匹配。

我如何重塑张量,我应该改变哪一个张量(输出或标签)来计算损失?

整个代码附在下面。

代码语言:javascript
运行
复制
import numpy as np
import torch

# Loading the Fashion-MNIST dataset
from torchvision import datasets, transforms

# Get GPU Device
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

transform = transforms.Compose([transforms.ToTensor(),
                                    transforms.Normalize((0.5,), (0.5,))])
# Download and load the training data
trainset = datasets.FashionMNIST('MNIST_data/', download = True, train = True, transform = transform)
testset = datasets.FashionMNIST('MNIST_data/', download = True, train = False, transform = transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size = 32, shuffle = True, num_workers=4)
testloader = torch.utils.data.DataLoader(testset, batch_size = 32, shuffle = True, num_workers=4)

# Examine a sample
dataiter = iter(trainloader)
images, labels = dataiter.next()

# Define the network architecture
from torch import nn, optim
import torch.nn.functional as F

model = nn.Sequential(nn.Linear(784, 128),
                      nn.ReLU(),
                      nn.Linear(128, 10),
                      nn.LogSoftmax(dim = 1))
model.to(device)

# Define the loss
criterion = nn.MSELoss()

# Define the optimizer
optimizer = optim.Adam(model.parameters(), lr = 0.001)

# Define the epochs
epochs = 5

train_losses, test_losses = [], []

for e in range(epochs):
  running_loss = 0
  for images, labels in trainloader:
    # Flatten Fashion-MNIST images into a 784 long vector
    images = images.to(device)
    labels = labels.to(device)
    images = images.view(images.shape[0], -1)

    # Training pass
    optimizer.zero_grad()
    output = model.forward(images)
    print(output.shape, labels.shape)
    loss = criterion(output, labels)
    loss.backward()
    optimizer.step()

    running_loss += loss.item()
  else:
    test_loss = 0
    accuracy = 0

    # Turn off gradients for validation, saves memory and computation
    with torch.no_grad():
      # Set the model to evaluation mode
      model.eval()

      # Validation pass
      for images, labels in testloader:
        images = images.to(device)
        labels = labels.to(device)
        images = images.view(images.shape[0], -1)
        ps = model(images)
        test_loss += criterion(ps, labels)
        top_p, top_class = ps.topk(1, dim = 1)
        equals = top_class == labels.view(*top_class.shape)
        accuracy += torch.mean(equals.type(torch.FloatTensor))

    model.train()

    print("Epoch: {}/{}..".format(e+1, epochs),
          "Training loss: {:.3f}..".format(running_loss/len(trainloader)),
          "Test loss: {:.3f}..".format(test_loss/len(testloader)),
          "Test Accuracy: {:.3f}".format(accuracy/len(testloader)))
EN

回答 2

Stack Overflow用户

发布于 2020-06-15 08:00:36

从您在其错误之前打印的输出,torch.Size([32, 10]) torch.Size([32])

左边的是模型给你的,右边的是trainloader的,通常你用它来做nn.CrossEntropyLoss之类的事情。

从完整的错误日志中,错误来自以下一行

代码语言:javascript
运行
复制
loss = criterion(output, labels)

做这个工作的方法叫做“一热编码”,如果是因为我的懒惰,我会写成这样。

代码语言:javascript
运行
复制
ones = torch.sparse.torch.eye(10).to(device)  # number of class class
labels = ones.index_select(0, labels)
票数 2
EN

Stack Overflow用户

发布于 2021-09-22 22:34:09

或者,您可以将丢失函数从nn.MSELoss()更改为nn.CrossEntropyLoss()。交叉熵损失通常比MSE更适合于这类分类任务,而且在PyTorch的实现中,这个丢失函数负责遮罩下的许多形状转换,因此您可以为它提供一个类概率向量和一个类标签。

从根本上说,您的模型试图通过计算每个可能的类的分数(您可以称之为“信任分数”)来预测输入属于哪个类。因此,如果有10个类,模型的输出将是一个10维列表(在PyTorch中是张量形状的[10]),预测将是得分最高的指标。通常情况下,人们会应用softmax (https://en.wikipedia.org/wiki/Softmax_function)函数将这些分数转换为概率分布,所以所有分数都在0到1之间,所有的元素都等于1。

然后,交叉熵是此任务损失函数的一个常见选择:它将预测列表与单一热编码标签进行比较。例如,如果您有3个类,标签将类似于[1, 0, 0]来表示第一个类。这也被称为“一热编码”。同时,一个预测可能看起来像[0.7, 0.1, 0.2]。在PyTorch中,nn.CrossEntropyLoss()期望标签作为单个值张量出现,其值表示类标签,因为不需要在内存中移动长而稀疏的向量。因此,这个丢失函数完成了您想要做的比较,我猜它的实现比实际创建一个热编码更有效。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62383595

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档