【问题标题】:Skorch RuntimeError: Input type (torch.cuda.ByteTensor) and weight type (torch.cuda.FloatTensor) should be the sameSkorch RuntimeError:输入类型(torch.cuda.ByteTensor)和权重类型(torch.cuda.FloatTensor)应该相同
【发布时间】:2021-03-20 10:54:22
【问题描述】:

我正在尝试开发图像分割模型。在下面的代码中,我不断遇到 RuntimeError:输入类型 (torch.cuda.ByteTensor) 和权重类型 (torch.cuda.FloatTensor) 应该相同。我不知道为什么我试图使用 .cuda() 将我的数据和我的 UNet 模型加载到 GPU(虽然不是 skorch 模型——不知道该怎么做)。我正在使用一个用于主动学习的库,modAL,它封装了 skorch。

from modAL.models import ActiveLearner
import numpy as np
import torch

from torch import nn
from torch import Tensor
from torch.utils.data import DataLoader
from torch.utils.data import Dataset

from skorch.net import NeuralNet

from modAL.models import ActiveLearner
from modAL.uncertainty import classifier_uncertainty, classifier_margin
from modAL.utils.combination import make_linear_combination, make_product
from modAL.utils.selection import multi_argmax
from modAL.uncertainty import uncertainty_sampling

from model import UNet
from skorch.net import NeuralNet
from skorch.helper import predefined_split
from torch.optim import SGD

import cv2


# Map style dataset, 
class ImagesDataset(Dataset):
    """Constructs dataset of satellite images + masks"""
    def __init__(self, image_paths):
        super().__init__()
        self.image_paths = image_paths

    def __len__(self):
        return len(self.image_paths)

    def __getitem__(self, idx):  
        if torch.is_tensor(idx):
            idx = idx.tolist()
        print("idx:", idx)
        sample_dir = self.image_paths[idx]
        img_path = sample_dir +"/images/"+ Path(sample_dir).name +'.png'
        mask_path = sample_dir +'/mask.png'
        img, mask = cv2.imread(img_path), cv2.imread(mask_path)
        print("shape of img", img.shape)
        return img, mask

# turn data into dataset
train_ds = ImagesDataset(train_dirs)
val_ds = ImagesDataset(valid_dirs)

train_loader = torch.utils.data.DataLoader(train_ds, batch_size=3, shuffle=True, pin_memory=True)
val_loader = torch.utils.data.DataLoader(val_ds, batch_size=1, shuffle=True, pin_memory=True)

# make sure data loaded in cuda for train, validation
for i, (tr, val) in enumerate(train_loader):
    tr, val = tr.cuda(), val.cuda()

for i, (tr2, val2) in enumerate(val_loader):
    tr2, val2 = tr2.cuda(), val2.cuda()

X, y = next(iter(train_loader))
X_train = np.array(X.reshape(3,3,1024,1024))
y_train = np.array(y.reshape(3,3,1024,1024))

X2, y2 = next(iter(val_loader))
X_test = np.array(X2.reshape(1,3,1024,1024))
y_test = np.array(y2.reshape(1,3,1024,1024))


module = UNet(pretrained=True)
if torch.cuda.is_available():
    module = module.cuda()
    
# create the classifier

net = NeuralNet(
    module,
    criterion=torch.nn.NLLLoss,
    batch_size=32,
    max_epochs=20,
    optimizer=SGD,
    optimizer__momentum=0.9,
    iterator_train__shuffle=True,
    iterator_train__num_workers=4,
    iterator_valid__shuffle=False,
    iterator_valid__num_workers=4,
    train_split=predefined_split(val_ds),
    device='cuda',
)

# assemble initial data
n_initial = 1
initial_idx = np.random.choice(range(len(X_train)), size=n_initial, replace=False)
X_initial = X_train[initial_idx]
y_initial = y_train[initial_idx]

# generate the pool, remove the initial data from the training dataset
X_pool = np.delete(X_train, initial_idx, axis=0)
y_pool = np.delete(y_train, initial_idx, axis=0)

# train the activelearner
# shape of 4D matrix is 'batch', 'channel', 'width', 'height')
learner = ActiveLearner(
    estimator= net,
    X_training=X_initial, y_training=y_initial,
)

完整的错误跟踪是:

    ---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-83-0af6007b6b72> in <module>
      8 learner = ActiveLearner(
      9     estimator= net,
---> 10     X_training=X_initial, y_training=y_initial,
     11     # X_training=X_initial, y_training=y_initial,
     12 )

~/.local/lib/python3.7/site-packages/modAL/models/learners.py in __init__(self, estimator, query_strategy, X_training, y_training, bootstrap_init, on_transformed, **fit_kwargs)
     80                  ) -> None:
     81         super().__init__(estimator, query_strategy,
---> 82                          X_training, y_training, bootstrap_init, on_transformed, **fit_kwargs)
     83 
     84     def teach(self, X: modALinput, y: modALinput, bootstrap: bool = False, only_new: bool = False, **fit_kwargs) -> None:

~/.local/lib/python3.7/site-packages/modAL/models/base.py in __init__(self, estimator, query_strategy, X_training, y_training, bootstrap_init, on_transformed, force_all_finite, **fit_kwargs)
     70         self.y_training = y_training
     71         if X_training is not None:
---> 72             self._fit_to_known(bootstrap=bootstrap_init, **fit_kwargs)
     73             self.Xt_training = self.transform_without_estimating(self.X_training) if self.on_transformed else None
     74 

~/.local/lib/python3.7/site-packages/modAL/models/base.py in _fit_to_known(self, bootstrap, **fit_kwargs)
    160         """
    161         if not bootstrap:
--> 162             self.estimator.fit(self.X_training, self.y_training, **fit_kwargs)
    163         else:
    164             n_instances = self.X_training.shape[0]

~/.local/lib/python3.7/site-packages/skorch/net.py in fit(self, X, y, **fit_params)
    901             self.initialize()
    902 
--> 903         self.partial_fit(X, y, **fit_params)
    904         return self
    905 

~/.local/lib/python3.7/site-packages/skorch/net.py in partial_fit(self, X, y, classes, **fit_params)
    860         self.notify('on_train_begin', X=X, y=y)
    861         try:
--> 862             self.fit_loop(X, y, **fit_params)
    863         except KeyboardInterrupt:
    864             pass

~/.local/lib/python3.7/site-packages/skorch/net.py in fit_loop(self, X, y, epochs, **fit_params)
    774 
    775             self.run_single_epoch(dataset_train, training=True, prefix="train",
--> 776                                   step_fn=self.train_step, **fit_params)
    777 
    778             if dataset_valid is not None:

~/.local/lib/python3.7/site-packages/skorch/net.py in run_single_epoch(self, dataset, training, prefix, step_fn, **fit_params)
    810             yi_res = yi if not is_placeholder_y else None
    811             self.notify("on_batch_begin", X=Xi, y=yi_res, training=training)
--> 812             step = step_fn(Xi, yi, **fit_params)
    813             self.history.record_batch(prefix + "_loss", step["loss"].item())
    814             self.history.record_batch(prefix + "_batch_size", get_len(Xi))

~/.local/lib/python3.7/site-packages/skorch/net.py in train_step(self, Xi, yi, **fit_params)
    707             return step['loss']
    708 
--> 709         self.optimizer_.step(step_fn)
    710         return step_accumulator.get_step()
    711 

~/.local/lib/python3.7/site-packages/torch/autograd/grad_mode.py in decorate_context(*args, **kwargs)
     24         def decorate_context(*args, **kwargs):
     25             with self.__class__():
---> 26                 return func(*args, **kwargs)
     27         return cast(F, decorate_context)
     28 

~/.local/lib/python3.7/site-packages/torch/optim/sgd.py in step(self, closure)
     84         if closure is not None:
     85             with torch.enable_grad():
---> 86                 loss = closure()
     87 
     88         for group in self.param_groups:

~/.local/lib/python3.7/site-packages/skorch/net.py in step_fn()
    703         def step_fn():
    704             self.optimizer_.zero_grad()
--> 705             step = self.train_step_single(Xi, yi, **fit_params)
    706             step_accumulator.store_step(step)
    707             return step['loss']

~/.local/lib/python3.7/site-packages/skorch/net.py in train_step_single(self, Xi, yi, **fit_params)
    643         """
    644         self.module_.train()
--> 645         y_pred = self.infer(Xi, **fit_params)
    646         loss = self.get_loss(y_pred, yi, X=Xi, training=True)
    647         loss.backward()

~/.local/lib/python3.7/site-packages/skorch/net.py in infer(self, x, **fit_params)
   1046             x_dict = self._merge_x_and_fit_params(x, fit_params)
   1047             return self.module_(**x_dict)
-> 1048         return self.module_(x, **fit_params)
   1049 
   1050     def _get_predict_nonlinearity(self):

~/.local/lib/python3.7/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
    725             result = self._slow_forward(*input, **kwargs)
    726         else:
--> 727             result = self.forward(*input, **kwargs)
    728         for hook in itertools.chain(
    729                 _global_forward_hooks.values(),

~/al/model.py in forward(self, x)
     51 
     52     def forward(self, x):
---> 53         conv1 = self.conv1(x)
     54         conv2 = self.conv2(conv1)
     55         conv3 = self.conv3(conv2)

~/.local/lib/python3.7/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
    725             result = self._slow_forward(*input, **kwargs)
    726         else:
--> 727             result = self.forward(*input, **kwargs)
    728         for hook in itertools.chain(
    729                 _global_forward_hooks.values(),

~/.local/lib/python3.7/site-packages/torch/nn/modules/container.py in forward(self, input)
    115     def forward(self, input):
    116         for module in self:
--> 117             input = module(input)
    118         return input
    119 

~/.local/lib/python3.7/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
    725             result = self._slow_forward(*input, **kwargs)
    726         else:
--> 727             result = self.forward(*input, **kwargs)
    728         for hook in itertools.chain(
    729                 _global_forward_hooks.values(),

~/.local/lib/python3.7/site-packages/torch/nn/modules/conv.py in forward(self, input)
    421 
    422     def forward(self, input: Tensor) -> Tensor:
--> 423         return self._conv_forward(input, self.weight)
    424 
    425 class Conv3d(_ConvNd):

~/.local/lib/python3.7/site-packages/torch/nn/modules/conv.py in _conv_forward(self, input, weight)
    418                             _pair(0), self.dilation, self.groups)
    419         return F.conv2d(input, weight, self.bias, self.stride,
--> 420                         self.padding, self.dilation, self.groups)
    421 
    422     def forward(self, input: Tensor) -> Tensor:

RuntimeError: Input type (torch.cuda.ByteTensor) and weight type (torch.cuda.FloatTensor) should be the same

如果有人能提供帮助,那将非常感激!尽管搜索了所有内容,但我真的被困住了——将我的 UNet 模型转换为浮点数并没有帮助,我想我已经在我应该调用的地方调用了 .cuda()。

我尝试过的具体事情:

【问题讨论】:

  • 请尽量减少标签垃圾邮件。这显然不是一个 CUDA 编程问题,不应该被标记为一个
  • @talonmies 对不起!不,这不是 CUDA 编程——感谢您指出这一点!下次会记住的。

标签: pytorch image-segmentation torchvision dataloader skorch


【解决方案1】:

cv2.imread 为您提供np.uint8 数据类型,它将被转换为 PyTorch 的字节。 byte 类型不能与 float 类型一起使用(您的模型很可能使用它)。

您需要通过修改数据集将字节类型转换为浮点类型(和张量)

import torchvision.transforms as transforms
class ImagesDataset(Dataset):
    """Constructs dataset of satellite images + masks"""
    def __init__(self, image_paths):
        super().__init__()
        self.image_paths = image_paths
        self.transform = transforms.Compose([transforms.ToTensor()])

    def __len__(self):
        return len(self.image_paths)

    def __getitem__(self, idx):  
        if torch.is_tensor(idx):
            idx = idx.tolist()
        print("idx:", idx)
        sample_dir = self.image_paths[idx]
        img_path = sample_dir +"/images/"+ Path(sample_dir).name +'.png'
        mask_path = sample_dir +'/mask.png'
        img, mask = cv2.imread(img_path), cv2.imread(mask_path)
        img = self.transform(img)
        mask = self.transform(mask)
        print("shape of img", img.shape)
        return img, mask

【讨论】:

  • 非常感谢您的回复!当我使用您的示例进行投射时,我得到了 AttributeError: 'numpy.ndarray' object has no attribute 'float' b/c X_initial 似乎是一个 numpy 数组。我还更改了 DataLoader 的 getitem 方法以返回 img.astype(float)、mask.astype(float),这产生了不同版本的运行时错误:RuntimeError: Input type (torch.cuda.DoubleTensor) 和 weight type ( torch.cuda.FloatTensor) 应该是一样的。 imread 不应该返回一个 np 数组吗?
  • @mwpqz 啊,我忽略了它。请检查更新。
  • 非常感谢@hkchengrex——这解决了我的问题!下次我将不得不使用 ToTensor 在数据类型之间转换以进行 imread 输出。谢谢你,我真的很感激!
猜你喜欢
  • 2020-04-22
  • 2023-03-27
  • 2021-07-18
  • 2021-07-19
  • 1970-01-01
  • 2022-08-10
  • 2020-09-29
  • 2021-01-03
  • 2022-11-11
相关资源
最近更新 更多