参数 #2 'mat1' 的张量在 CPU 上,但预计它在 GPU 上

Tensor for argument #2 'mat1' is on CPU, but expected it to be on GPU

继我之前的 之后,我编写了这段代码来训练自动编码器,然后提取特征。 (变量名称可能会有一些变化)

# Autoencoder class
#https://medium.com/pytorch/implementing-an-autoencoder-in-pytorch-19baa22647d1
class AE_class(nn.Module):
    def __init__(self, **kwargs):
        super().__init__()
        self.encoder_hidden_layer = nn.Linear(
            in_features=kwargs["input_shape"], out_features=128
        )
        self.encoder_output_layer = nn.Linear(
            in_features=128, out_features=128
        )
        self.decoder_hidden_layer = nn.Linear(
            in_features=128, out_features=128
        )
        self.decoder_output_layer = nn.Linear(
            in_features=128, out_features=kwargs["input_shape"]
        )

    def forward(self, features):
        #print("in forward")
        #print(type(features))
        activation = self.encoder_hidden_layer(features)
        activation = torch.relu(activation)
        code = self.encoder_output_layer(activation)
        code = torch.relu(code)
        activation = self.decoder_hidden_layer(code)
        activation = torch.relu(activation)
        activation = self.decoder_output_layer(activation)
        reconstructed = torch.relu(activation)
        return reconstructed
    
    def encode(self, features_h):
        activation_h = self.encoder_hidden_layer(features_h)
        activation_h = torch.relu(activation_h)
        code_h = self.encoder_output_layer(activation_h)
        code_h = torch.relu(code_h)
        return code_h
   

然后,进行训练:

def retrieve_AE_features(X_before, n_voxel_region):
    
        #  use gpu if available
    #https://discuss.pytorch.org/t/runtimeerror-tensor-for-out-is-on-cpu-tensor-for-argument-1-self-is-on-cpu-but-expected-them-to-be-on-gpu-while-checking-arguments-for-addmm/105453
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

    # create a model from `AE` autoencoder class
    # load it to the specified device, either gpu or cpu
    model_AE = AE_class(input_shape=n_voxel_region).to(device)

    # create an optimizer object
    # Adam optimizer with learning rate 1e-3
    optimizer = optim.Adam(model_AE.parameters(), lr=1e-3)

    # mean-squared error loss
    criterion = nn.MSELoss()

    
    
    
    X_tensor = torch.tensor(X_before, dtype=torch.float32)
    
    print(type(X_tensor))
                            
    
    train_loader = torch.utils.data.DataLoader(
        X_tensor, batch_size=64, shuffle=True, num_workers=2, pin_memory=True
    )
    
    test_loader = torch.utils.data.DataLoader(
        X_tensor, batch_size=32, shuffle=False, num_workers=2
    )
    
    print(type(train_loader))

    for epoch in range(epochs_AE):
        loss = 0
        
        for batch_features in train_loader:
            # reshape mini-batch data to [N, 784] matrix
            # load it to the active device
            #batch_features = batch_features.view(-1, 784).to(device)
            
            #print(batch_features.shape)

            # reset the gradients back to zero
            # PyTorch accumulates gradients on subsequent backward passes
            optimizer.zero_grad()

            # compute reconstructions
            outputs = model_AE(batch_features)

            # compute training reconstruction loss
            train_loss = criterion(outputs, batch_features)

            # compute accumulated gradients
            train_loss.backward()

            # perform parameter update based on current gradients
            optimizer.step()

            # add the mini-batch training loss to epoch loss
            loss += train_loss.item()

        # compute the epoch training loss
        loss = loss / len(train_loader)

        # display the epoch training loss
        
        print("AE, epoch : {}/{}, loss = {:.6f}".format(epoch + 1, epochs_AE, loss))
        
        
    #After training
    hidden_features = model_AE.encode(X_before)
    return hidden_features

但是,我收到以下错误:

Tensor for argument #2 'mat1' is on CPU, but expected it to be on GPU (while checking arguments for addmm)

似乎我的一些变量应该以其他方式定义才能在 GPU 上执行。

我的问题:

  1. 我如何了解哪些变量将在 GPU 上执行,哪些变量将在 CPU 上执行?
  2. 如何解决?也就是说,如何在GPU上定义一个可变的可执行文件?

提前致谢

我看到你的模型被移动到 device 这是由这条线决定的 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") 这可以是 cpucuda.

所以添加这一行 batch_features = batch_features.to(device) 实际上会将您的输入数据移动到 device
由于您的模型已移至设备,因此您还应该将输入移至设备。 下面的代码有那个变化

for epoch in range(epochs_AE):
    loss = 0
    
    for batch_features in train_loader:
        batch_features = batch_features.to(device)  #this will move inout to your device        
        optimizer.zero_grad()
        outputs = model_AE(batch_features)
        train_loss = criterion(outputs, batch_features)
        ...

来到你的问题:调用.to(device)可以直接将张量移动到你指定的设备
如果您希望它被硬编码,那么在您的 torch 张量

上执行 .to('cpu').to('cuda')