pytorch to_device遇到数据迁移不成功的问题

pytorch中使用to(device)后数据未迁移成功

问题描述

调试模型时遇到报错:

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

内容说是要进行运算的两个数据没有在同一个设备上,在cpu和cuda:0两个设备上。
首先可以推断是有个别数据未迁移到同一设备上,这里我选择cuda:0作为实验的设备,以加快训练速度。

错误代码

主调代码:

print(f"self.device:{self.device}")   # cuda:0
event_ix = torch.LongTensor(self.lm.get_events_in_sentence(relpair))
event_ix.to(self.device)   # 数据迁移到GPU
print(f"exp_HGRU event_ix.device:{event_ix.device}")
time_anchor = self.timeAnchorModel(s, s_a_mask, event_ix, self.device)

被调代码:

event_1_ix, event_2_ix = event_ix.split(1, dim=-1)
print(f"event_1_ix.device:{event_1_ix.device}\nevent_2_ix.device:{event_2_ix.device}") # cpu cpu
event_1 = torch.gather(sequence_output, dim=1,
                               index=event_1_ix.expand(batch_size, hidden_size).unsqueeze(dim=1))  # index处发生报错
event_2 = torch.gather(sequence_output, dim=1,
                               index=event_2_ix.expand(batch_size, hidden_size).unsqueeze(dim=1))

我把device通过参数传进来了,但是event_1_ix.device和event_2_ix.device仍然是cpu

解决方法

其实很简单,就是data.to(device)后需要赋值给另一变量,可以是data本身,否者无法真正实现迁移。
可能是因为简单,网上没有针对性的解决方法,对pytorch略懂皮毛的人来说,有些简单的点,却最磨人。

正确代码

event_ix = torch.LongTensor(self.lm.get_events_in_sentence(relpair)).to(self.device)

或者

event_ix = torch.LongTensor(self.lm.get_events_in_sentence(relpair))
event_ix = event_ix.to(self.device)

!data = data.to(device) ------ 需要data来承接

  • 28
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
PyTorch是一个流行的深度学习框架,可以用于图像风格迁移。图像风格迁移是将一张图像的风格应用到另一张图像上的过程。以下是实现图像风格迁移的一些步骤: 1. 准备数据集:准备一组内容图像和一组风格图像。 2. 定义损失函数:定义内容损失和风格损失,用于衡量生成图像与内容图像和风格图像之间的差异。 3. 定义模型:定义一个卷积神经网络模型,用于将内容图像转换为风格图像。 4. 训练模型:使用数据集训练模型,以最小化损失函数。 5. 进行风格迁移:使用训练好的模型将内容图像转换为风格图像。 以下是一个简单的PyTorch图像风格迁移的例子: ```python import torch import torch.nn as nn import torch.optim as optim import torchvision.models as models import torchvision.transforms as transforms from PIL import Image # 载图像 def load_image(image_path, transform=None, max_size=None, shape=None): image = Image.open(image_path) if max_size: scale = max_size / max(image.size) size = np.array(image.size) * scale image = image.resize(size.astype(int), Image.ANTIALIAS) if shape: image = image.resize(shape, Image.LANCZOS) if transform: image = transform(image).unsqueeze(0) return image.to(device) # 定义损失函数 class ContentLoss(nn.Module): def __init__(self, target): super(ContentLoss, self).__init__() self.target = target.detach() def forward(self, input): self.loss = F.mse_loss(input, self.target) return input class StyleLoss(nn.Module): def __init__(self, target_feature): super(StyleLoss, self).__init__() self.target = gram_matrix(target_feature).detach() def forward(self, input): G = gram_matrix(input) self.loss = F.mse_loss(G, self.target) return input def gram_matrix(input): a, b, c, d = input.size() features = input.view(a * b, c * d) G = torch.mm(features, features.t()) return G.div(a * b * c * d) # 定义模型 class TransformerNet(nn.Module): def __init__(self): super(TransformerNet, self).__init__() self.conv1 = ConvLayer(3, 32, kernel_size=9, stride=1) self.in1 = nn.InstanceNorm2d(32, affine=True) self.conv2 = ConvLayer(32, 64, kernel_size=3, stride=2) self.in2 = nn.InstanceNorm2d(64, affine=True) self.conv3 = ConvLayer(64, 128, kernel_size=3, stride=2) self.in3 = nn.InstanceNorm2d(128, affine=True) self.res1 = ResidualBlock(128) self.res2 = ResidualBlock(128) self.res3 = ResidualBlock(128) self.res4 = ResidualBlock(128) self.res5 = ResidualBlock(128) self.conv4 = ConvLayer(128, 64, kernel_size=3, stride=1) self.in4 = nn.InstanceNorm2d(64, affine=True) self.conv5 = ConvLayer(64, 3, kernel_size=9, stride=1) def forward(self, input): x = F.relu(self.in1(self.conv1(input))) x = F.relu(self.in2(self.conv2(x))) x = F.relu(self.in3(self.conv3(x))) x = self.res1(x) x = self.res2(x) x = self.res3(x) x = self.res4(x) x = self.res5(x) x = F.relu(self.in4(self.conv4(x))) x = self.conv5(x) return x class ConvLayer(nn.Module): def __init__(self, in_channels, out_channels, kernel_size, stride): super(ConvLayer, self).__init__() reflection_padding = kernel_size // 2 self.reflection_pad = nn.ReflectionPad2d(reflection_padding) self.conv2d = nn.Conv2d(in_channels, out_channels, kernel_size, stride) def forward(self, x): out = self.reflection_pad(x) out = self.conv2d(out) return out class ResidualBlock(nn.Module): def __init__(self, channels): super(ResidualBlock, self).__init__() self.conv1 = ConvLayer(channels, channels, kernel_size=3, stride=1) self.in1 = nn.InstanceNorm2d(channels, affine=True) self.conv2 = ConvLayer(channels, channels, kernel_size=3, stride=1) self.in2 = nn.InstanceNorm2d(channels, affine=True) self.relu = nn.ReLU() def forward(self, x): residual = x out = self.relu(self.in1(self.conv1(x))) out = self.in2(self.conv2(out)) out = out + residual return out # 训练模型 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") transform = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(256), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])]) content = load_image("content.jpg", transform, max_size=400) style = load_image("style.jpg", transform, shape=[content.size(2), content.size(3)]) model = TransformerNet().to(device) optimizer = optim.Adam(model.parameters(), lr=0.001) style_features = models.vgg19(pretrained=True).features(style.to(device)) style_grams = [gram_matrix(feature) for feature in style_features] for i in range(1, 501): optimizer.zero_grad() content_features = model(content) content_loss = 0 style_loss = 0 for feature in content_features: content_loss += ContentLoss(feature).loss for j, feature in enumerate(model(style)): style_loss += StyleLoss(feature).loss total_loss = content_loss + style_loss total_loss.backward() optimizer.step() if i % 50 == 0: print("Iteration:", i, "Total loss:", total_loss.item()) # 进行风格迁移 with torch.no_grad(): output = model(content) output_image = output.cpu().clone() output_image = output_image.squeeze(0) output_image = transforms.ToPILImage()(output_image) output_image.save("output.jpg") ```
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值