当前位置:   article > 正文

解决RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cp

runtimeerror: expected all tensors to be on the same device, but found at le

今天在把.pt文件转ONNX文件时,遇到此错误。

报错

RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cpu and cuda:0! (when checking argument for argument mat2 in method wrapper_mm)
  • 1

原因

代码中的Tensor**,一会在CPU中运行,一会在GPU中运行**,所以最好是都放在同一个device中执行。

pytorch有两种模型保存方式

一、保存整个神经网络的的结构信息和模型参数信息,save的对象是网络net

二、只保存神经网络的训练模型参数,save的对象是net.state_dict()

对应两种保存模型的方式,pytorch也有两种加载模型的方式。对应第一种保存方式,加载模型时通过torch.load(‘.pth’)直接初始化新的神经网络对象;对应第二种保存方式,需要首先导入对应的网络,再通过net.load_state_dict(torch.load(‘.pth’))完成模型参数的加载。

解决方案

在报错中寻找错误的哪一行,通过Print语句查看相关参数到底在那里运行

print(参数a.is_cuda,参数a.is_cuda)
  • 1

然后把它们统一都放在CPU/GPU上就可以。

解决案例

案例1

在这里插入图片描述
报错提示在utils.py 这个文件的问题

index = idx_ range.index_ select(0, reverse_ mapping )
  • 1

使用print语句检查

print(index .is_cuda,idx_ range.is_cuda)
  • 1

经过验证发现idx_range在cpu上,index在GPU上,把idx_range放在GPU即可。

  idx_range.to(device)
  • 1

如果遇到下面问题

NameError: name 'device' is not defined
  • 1

请在开始加入语句

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
  • 1

案例2

错误代码

if __name__ == '__main__':
    model = Perception(2, 3, 2).cuda()

    input = torch.randn(4, 2).cuda()
    output = model(input)
    # output = output.cuda()

    label = torch.Tensor([0, 1, 1, 0]).long()
    criterion = nn.CrossEntropyLoss()
    loss_nn = criterion(output, label)
    print(loss_nn)
    loss_functional = F.cross_entropy(output, label)
    print(loss_functional)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

解决方案

将用到的Tensor都改为同一个device:Tensor.to(device)

if __name__ == '__main__':
	#添加语句 device = torch.device('cuda:0')以及.to(device)
    device = torch.device('cuda:0')
    model = Perception(2, 3, 2).to(device)

    input = torch.randn(4, 2).to(device)
    output = model(input).to(device)

    label = torch.Tensor([0, 1, 1, 0]).long().to(device)
    criterion = nn.CrossEntropyLoss()
    loss_nn = criterion(output, label).to(device)
    print(loss_nn)
    loss_functional = F.cross_entropy(output, label)
    print(loss_functional)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

完整代码:

import torch
from torch import nn
import torch.nn.functional as F

from torch.nn import Linear


class linear(nn.Module):  # 继承nn.Module
    def __init__(self, in_dim, out_dim):
        super(Linear, self).__init__()  # 调用nn.Module的构造函数

        # 使用nn.Parameter来构造需要学习的参数
        self.w = nn.Parameter(torch.randn(in_dim, out_dim))
        self.b = nn.Parameter(torch.randn(out_dim))

    # 在forward中实现前向传播过程
    def forward(self, x):
        x = x.matmul(self.w)
        y = x + self.b.expand_as(x)  # expand_as保证矩阵形状一致

        return y

class Perception(nn.Module):
    def __init__(self, in_dim, hid_dim, out_dim):
        super(Perception, self).__init__()
        self.layer = nn.Sequential(
            nn.Linear(in_dim, hid_dim),
            nn.Sigmoid(),
            nn.Linear(hid_dim, out_dim),
            nn.Sigmoid()
        )
        # self.layer1 = Linear(in_dim, hid_dim)
        # self.layer2 = Linear(hid_dim, out_dim)

    def forward(self, x):
        # x = self.layer1(x)
        # y = torch.sigmoid(x)
        # y = self.layer2(y)
        # y = torch.sigmoid(y)
        y = self.layer(x)
        return y


if __name__ == '__main__':
    device = torch.device('cuda:0')
    model = Perception(2, 3, 2).to(device)

    input = torch.randn(4, 2).to(device)
    output = model(input).to(device)
    # output = output.cuda()

    label = torch.Tensor([0, 1, 1, 0]).long().to(device)
    criterion = nn.CrossEntropyLoss()
    loss_nn = criterion(output, label).to(device)
    print(loss_nn)
    loss_functional = F.cross_entropy(output, label)
    print(loss_functional)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

补充

如果遇到错误:Tensor for argument #2 ‘mat1’ is on CPU, but expected it to be on GPU (while checking arguments for addmm)

代表着模型在GPU上进行计算,需要将变量和模型都增加.to(device),都搬到GPU上。

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
 
g = g.to(device)
 
model=model.to(device)
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

更多Ai资讯:公主号AiCharm
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/149483
推荐阅读
相关标签
  

闽ICP备14008679号