【问题标题】:pytorch isn't running on gpu while truepytorch 未在 gpu 上运行而为真
【发布时间】:2021-08-23 19:17:31
【问题描述】:

我想在本地 gpu 上训练,但它只在 cpu 上运行,而 torch.cuda.is_available() 实际上是真的,我可以看到我的 gpu 但它只在 cpu 上运行,所以如何修复它

我的 CNN 模型:

import torch.nn as nn
import torch.nn.functional as F
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
# define the CNN architecture

class Net(nn.Module):
    ### TODO: choose an architecture, and complete the class
    def __init__(self):
        super(Net, self).__init__()
        ## Define layers of a CNN
        self.conv1 = nn.Conv2d(3, 16, 3, padding=1)
        # convolutional layer (sees 16x16x16 tensor)
        self.conv2 = nn.Conv2d(16, 32, 3, padding=1)
        # convolutional layer (sees 8x8x32 tensor)
        self.conv3 = nn.Conv2d(32, 64, 3, padding=1)
        
        # max pooling layer
        self.pool = nn.MaxPool2d(2, 2)
        # linear layer (64 * 4 * 4 -> 500)
        self.fc1 = nn.Linear(64 * 28 * 28, 500)
        # linear layer (500 -> 10)
        self.fc2 = nn.Linear(500, 133)
        # dropout layer (p=0.25)
        self.dropout = nn.Dropout(0.25)
    
    def forward(self, x):
        ## Define forward behavior
        x = self.pool(F.relu(self.conv1(x)))
        #print(x.shape)
        x = self.pool(F.relu(self.conv2(x)))
        #print(x.shape)
        x = self.pool(F.relu(self.conv3(x)))
        #print(x.shape)
        
        #print(x.shape)
        # flatten image input
        x = x.view(-1, 64 * 28 * 28)
        # add dropout layer
        x = self.dropout(x)
        # add 1st hidden layer, with relu activation function
        x = F.relu(self.fc1(x))
        # add dropout layer
        x = self.dropout(x)
        # add 2nd hidden layer, with relu activation function
        x = self.fc2(x)
        
        return x

#-#-# You so NOT have to modify the code below this line. #-#-#

# instantiate the CNN
model_scratch = Net()

# move tensors to GPU if CUDA is available
if use_cuda:
    print("TRUE")
    model_scratch = model_scratch.cuda()

训练功能:

def train(n_epochs, loaders, model, optimizer, criterion, use_cuda, save_path):
    """returns trained model"""
    # initialize tracker for minimum validation loss
    valid_loss_min = np.Inf 

    loaders_scratch = {'train': train_loader,'valid': valid_loader,'test': test_loader}
    
    for epoch in range(1, n_epochs+1):
        # initialize variables to monitor training and validation loss
        train_loss = 0.0
        valid_loss = 0.0
        
        ###################
        # train the model #
        ###################
        model.train()
        for batch_idx, (data, target) in enumerate(loaders['train']):
            # move to GPU
            if use_cuda:
                data, target = data.cuda(), target.cuda()
            ## find the loss and update the model parameters accordingly
            ## record the average training loss, using something like
            ## train_loss = train_loss + ((1 / (batch_idx + 1)) * (loss.data - train_loss))
            # clear the gradients of all optimized variables
            optimizer.zero_grad()
            # forward pass: compute predicted outputs by passing inputs to the model
            output = model(data)
            # calculate the batch loss
            loss = criterion(output, target)
            # backward pass: compute gradient of the loss with respect to model parameters
            loss.backward()
            # perform a single optimization step (parameter update)
            optimizer.step()
            # update training loss
            train_loss += loss.item()*data.size(0)
            
        ######################    
        # validate the model #
        ######################
        model.eval()
        for batch_idx, (data, target) in enumerate(loaders['valid']):
            # move to GPU
            if use_cuda:
                data, target = data.cuda(), target.cuda()
            ## update the average validation loss
            output = model(data)
            # calculate the batch loss
            loss = criterion(output, target)
            # update average validation loss 
            valid_loss += loss.item()*data.size(0)

        # calculate average losses
        train_loss = train_loss/len(train_loader.dataset)
        valid_loss = valid_loss/len(valid_loader.dataset)

        # print training/validation statistics 
        print('Epoch: {} \tTraining Loss: {:.6f} \tValidation Loss: {:.6f}'.format(
            epoch, 
            train_loss,
            valid_loss
            ))
        
        ## TODO: save the model if validation loss has decreased
        if valid_loss <= valid_loss_min:
            print('Validation loss decreased ({:.6f} --> {:.6f}).  Saving model ...'.format(
            valid_loss_min,
            valid_loss))
            torch.save(model.state_dict(), save_path)
            valid_loss_min = valid_loss
        
    # return trained model
    return model

# train the model
loaders_scratch = {'train': train_loader,'valid': valid_loader,'test': test_loader}
model_scratch = train(100, loaders_scratch, model_scratch, optimizer_scratch, 
                      criterion_scratch, use_cuda, 'model_scratch.pt')

# load the model that got the best validation accuracy
model_scratch.load_state_dict(torch.load('model_scratch.pt'))

虽然我在torch.cuda.is_available() 中得到"TRUE",但仍未在GPU 上运行 我只在 CPU 上运行

下图显示我在 62% 的 cpu 上运行

【问题讨论】:

  • 您的nvidia-smi 显示了什么?要查找nvidia-smi,您可以查看here
  • 7% 的 CUDA 利用率并不意味着它没有使用 GPU。这是一个常见的误解,您的代码在 GPU 上运行。
  • nvidi-smi 显示 0% - 4% 正在运行
  • @ Snoopy 博士,如果我在 gpu 上运行,为什么我运行 train 函数后 cpu 会增加 65%

标签: tensorflow deep-learning pytorch gpu conv-neural-network


【解决方案1】:

要在 pytorch 中使用 cuda,您必须指定要在 gpu 设备上运行代码。

一行代码,如:

use_cuda = torch.cuda.is_available()
device = torch.device("cuda" if use_cuda else "cpu")

将确定您是否有可用的 cuda,如果有,您将把它作为您的设备。

稍后在代码中,您必须将张量和模型传递给此设备:

net = net.to(device)

并对需要转到 gpu 的其他张量执行相同的操作,例如测试和训练值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-26
    • 2021-10-19
    • 2021-03-08
    • 1970-01-01
    • 2017-12-03
    • 2019-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多