【机器学习】PyTorch、Cuda 的安装和示例代码

原文作者:我辈李想
版权声明:文章原创,转载时请务必加上原文超链接、作者信息和本声明。



前言

PyTorch是一个开源的Python深度学习框架,可以用于构建各种类型的神经网络模型。

一、Anaconda 中安装 PyTorch 和 CUDA (Ubuntu系统)

  1. 首先下载并安装适用于您系统的 Anaconda 版本。

Linux安装Anaconda教程

  1. 打开 Anaconda Prompt 或命令行工具,并创建一个名为“pytorch”或任何其他您喜欢的环境,此处假设您使用的是 Anaconda 4.5 或更高版本:
conda create -n pytorch python=3.7
  1. 激活新环境:
conda activate pytorch
  1. 查看cuda版本
nvidia-smi  # 显卡驱动(Driver Version: 535.113.01   CUDA Version: 12.2)
nvcc --version  # 显卡驱动  (V10.1.243)

cuda 的版本应该低于nvidia-smi 的Version,即低于12.2。

  1. 安装 PyTorch:
    这里使用的cuda是11.8,以下是安装命令,命令来源:https://pytorch.org/get-started/locally/
#在pytorch官方源中,conda根据cuda=11.8匹配pytorch torchvision和torchaudio版本
conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia 

实际上pytorch=1.12.1,torchvision=0.13.1,torchaudio=0.12.1。

二、检查PyTorch和CUDA版本

曹看连接:Ubuntu 安装 GPU 驱动、CUDA、cuDNN,以及是否安装成功的检测

  1. 通过python可以使用以下命令:
import torch

print(torch.__version__)
print(torch.version.cuda) # gpu
print(torch.backends.cudnn.version()) # cudnn 
print(torch.cuda.is_available())  # gpu
print(torch.cuda.device_count())
  1. 通过cmd命令行直接查看
python -c "import torch; print(torch.__version__)"
python -c "import torch; print(torch.version.cuda)"  # gpu
python -c "import torch; print(torch.cuda.is_available())"  # gpu
python -c "import torch; print(torch.cuda.device_count())"  # gpu

如果成功安装,这将打印 PyTorch 的版本号。

  1. 实时监测gpu
    nvidia-smi 相关命令
-h 查看帮助手册:nvidia-smi -h 
动态地观察 GPU 的状态:watch -n 0.5 nvidia-smi 
-i 查看指定GPU:nvidia-smi -i 0
-L 查看GPU列表及其UUID:nvidia-smi -L
-l 指定动态刷新时间,默认5秒刷新一次,通过Ctrl+C停止:nvidia-smi -l 5
-q 查询GPU详细信息:nvidia-smi -q
只列出某一GPU的详细信息,可使用 -i 选项指定:nvidia-smi -q -i 0
在所有 GPU 上启用持久性模式:nvidia-smi -pm 1
指定开启某个显卡的持久模式:nvidia-smi -pm 1 -i 0
以 1 秒的更新间隔监控整体 GPU 使用情况:nvidia-smi dmon
以 1 秒的更新间隔监控每个进程的 GPU 使用情况:nvidia-smi pmon

三、PyTorch调用cuda

在PyTorch中使用CUDA可以大大加速训练和推理过程。以下是使用CUDA的几个步骤:

  1. 检查CUDA是否可用:
import torch

if torch.cuda.is_available():
    device = torch.device("cuda")          # 如果GPU可用,则使用CUDA
else:
    device = torch.device("cpu")           # 如果GPU不可用,则使用CPU
  1. 将模型和数据加载到CUDA设备:
model.to(device)
inputs, labels = inputs.to(device), labels.to(device)
  1. 将数据转换为CUDA张量:
inputs = inputs.cuda()
labels = labels.cuda()
  1. 在训练过程中,使用CUDA加速计算:
for inputs, labels in dataloader:
    inputs, labels = inputs.to(device), labels.to(device)
    optimizer.zero_grad()
    outputs = model(inputs)
    loss = criterion(outputs, labels)
    loss.backward()
    optimizer.step()

请注意,在使用CUDA时,您需要确保您的计算机具有兼容的GPU和正确的CUDA和cuDNN版本。您可以在PyTorch的官方文档中找到更多详细信息。

四、Matplotlib绘制Pytorch损失函数和准确率

在Pytorch中,我们可以使用Matplotlib来绘制训练过程中的损失函数曲线、准确率曲线等。下面是一个简单的示例:

import matplotlib.pyplot as plt

# 定义损失函数和准确率列表
train_losses = [0.1, 0.08, 0.05, 0.03, 0.02]
train_accs = [90, 92, 95, 97, 98]

# 绘制损失函数曲线
plt.plot(train_losses, label='Train Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()

# 绘制准确率曲线
plt.plot(train_accs, label='Train Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.show()

运行后会分别显示训练过程中的损失函数曲线和准确率曲线。我们可以根据自己的需要调整图表的样式和参数,例如修改线条颜色、线条宽度、坐标轴范围等。

五、tesorbrand显示图像

PyTorch下的Tensorboard 使用

六、PyTorch示例:nn.Module构建一个简单的全连接神经网络

示例代码:

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms

if torch.cuda.is_available():
    device = torch.device("cuda")  # 如果GPU可用,则使用CUDA
else:
    device = torch.device("cpu")  # 如果GPU不可用,则使用CPU

# 定义神经网络模型
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(784, 256)
        self.fc2 = nn.Linear(256, 10)

    def forward(self, x):
        x = x.view(-1, 784)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x


# 加载MNIST数据集的训练集
training_data = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=transforms.ToTensor(),
)
# 加载MNIST数据集的测试集
test_data = datasets.FashionMNIST(
    root="data",
    train=False,
    download=True,
    transform=transforms.ToTensor(),
)
 
# batch大小
batch_size = 64
 
# 创建dataloader
train_dataloader = torch.utils.data.DataLoader(training_data, batch_size=batch_size)
test_dataloader = torch.utils.data.DataLoader(test_data, batch_size=batch_size)

# 实例化模型并定义损失函数和优化器
net = Net().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.01)

# 加载数据并训练
for epoch in range(10):
    for inputs, labels in train_dataloader:
        inputs, labels = inputs.to(device), labels.to(device)
        optimizer.zero_grad()
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

# 加载模型并测试
correct = 0
total = 0
with torch.no_grad():
    for inputs, labels in test_dataloader:
        inputs, labels = inputs.to(device), labels.to(device)
        outputs = net(inputs)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()
        
# 结果评估
print('Accuracy: %d %%' % (100 * correct / total))

在这个例子中,我们定义了一个简单的全连接神经网络,使用MNIST数据集进行训练和测试。我们使用PyTorch内置的nn.Module类来定义神经网络模型,并在forward方法中定义正向传播的操作。我们使用交叉熵损失函数和随机梯度下降(SGD)优化器来训练模型。我们使用训练数据集中的数据来更新模型参数,并使用测试数据集来评估模型的准确性。

七、用Pytorch写一个卷积神经网络

下面是一个简单的卷积神经网络(CNN)的实现,用PyTorch框架来训练MNIST手写数字识别数据集。

首先,您需要导入所需的库和模块,如下所示:

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torchvision import datasets, transforms

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

接下来,您需要定义网络的架构。这个CNN有两个卷积层,一个最大池化层和两个全连接层。代码如下:

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        # 输入为28*28*1
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
        # 输入为24*24*10
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        # 输入为20*20*20
        self.mp = nn.MaxPool2d(2)
        # 输入为10*10*20
        self.fc1 = nn.Linear(320, 50)
        self.fc2 = nn.Linear(50, 10)

    def forward(self, x):
        x = F.relu(self.mp(self.conv1(x)))
        x = F.relu(self.mp(self.conv2(x)))
        x = x.view(-1, 320)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)

现在,您需要定义训练函数和测试函数。训练函数将会用来训练模型,而测试函数将会用来测试模型。代码如下:

def train(model, device, train_loader, optimizer, epoch):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = F.nll_loss(output, target)
        loss.backward()
        optimizer.step()
        if batch_idx % 100 == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_idx * len(data), len(train_loader.dataset),
                100. * batch_idx / len(train_loader), loss.item()))


def test(model, device, test_loader):
    model.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.to(device), target.to(device)
            output = model(data)
            test_loss += F.nll_loss(output, target, reduction='sum').item()
            pred = output.argmax(dim=1, keepdim=True)
            correct += pred.eq(target.view_as(pred)).sum().item()

    test_loss /= len(test_loader.dataset)

    print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset),
        100. * correct / len(test_loader.dataset)))

接下来,您需要加载数据集和定义训练和测试参数。代码如下:

batch_size = 64

train_transforms = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])

test_transforms = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])

train_dataset = datasets.MNIST('./data', train=True, download=True, transform=train_transforms)
test_dataset = datasets.MNIST('./data', train=False, transform=test_transforms)

train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False)


model = Net().to(device)
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)

最后,您需要在循环中训练和测试模型。代码如下:

epochs = 10

for epoch in range(1, epochs + 1):
    train(model, device, train_loader, optimizer, epoch)
    test(model, device, test_loader)

这是一个简单的CNN的实现,用PyTorch训练MNIST数据集。您可以调整模型的超参数,例如学习率、动量等,来提高模型的准确性和性能。

八、用Pytorch写一个目标检测模型

下面是一个基于PyTorch的目标检测模型的实现,使用Faster R-CNN网络,并使用COCO数据集进行训练和测试。

首先,您需要导入所需的库和模块,如下所示:

import torch
import torchvision
import torchvision.transforms as transforms
import torch.utils.data
import numpy as np
import matplotlib.pyplot as plt
import time
import os
import json
import torch.utils.data as data
from torchvision.datasets import CocoDetection
import torchvision.transforms.functional as F
import torch.nn as nn
import torch.optim as optim
from torchvision.models.detection import FasterRCNN
from torchvision.models.detection.rpn import AnchorGenerator
from torchvision.models.detection.backbone_utils import resnet_fpn_backbone
from torchvision.ops import MultiScaleRoIAlign

接下来,您需要定义数据转换和数据集类,以加载和预处理COCO数据集。代码如下:

class Compose(object):
    def __init__(self, transforms):
        self.transforms = transforms

    def __call__(self, img, target):
        for t in self.transforms:
            img, target = t(img, target)
        return img, target


class RandomHorizontalFlip(object):
    def __init__(self, probability=0.5):
        self.probability = probability

    def __call__(self, img, target):
        if np.random.rand() < self.probability:
            img = F.hflip(img)
            target["boxes"][:, [0, 2]] = img.width - target["boxes"][:, [2, 0]]
        return img, target


class Resize(object):
    def __init__(self, max_size=900, min_size=600):
        self.max_size = max_size
        self.min_size = min_size

    def __call__(self, img, target):
        w, h = img.size
        size = self.min_size
        if w < h and max(h, w * size / w) <= self.max_size:
            size = int(w * size / w)
        elif max(h, w * size / h) <= self.max_size:
            size = int(h * size / h)

        img = F.resize(img, (size, size))

        target["boxes"][:, :4] *= size / self.min_size

        return img, target


class ToTensor(object):
    def __call__(self, img, target):
        img = F.to_tensor(img)
        return img, target


class COCODataset(data.Dataset):
    def __init__(self, data_dir, set_name='train', transform=None):
        super().__init__()
        self.data_dir = data_dir
        self.images_dir = os.path.join(data_dir, set_name)
        self.set_name = set_name
        self.transform = transform

        self.coco = CocoDetection(self.images_dir, os.path.join(data_dir, f'{set_name}.json'))

    def __getitem__(self, index):
        image, target = self.coco[index]
        image_id = self.coco.ids[index]

        if self.transform is not None:
            image, target = self.transform(image, target)

        return image, target, image_id

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

接下来,您需要定义模型的架构。这个Faster R-CNN网络使用ResNet-50 FPN作为骨干网络。代码如下:

class FasterRCNNResNetFPN(nn.Module):
    def __init__(self, num_classes):
        super(FasterRCNNResNetFPN, self).__init__()

        self.num_classes = num_classes

        backbone = resnet_fpn_backbone('resnet50', pretrained=True)
        anchor_generator = AnchorGenerator(sizes=((32, 64, 128, 256, 512),),
                                            aspect_ratios=((0.5, 1.0, 2.0),))
        roi_pooler = MultiScaleRoIAlign(featmap_names=['0', '1', '2', '3'],
                                        output_size=7,
                                        sampling_ratio=2)

        self.model = FasterRCNN(backbone,
                                num_classes=num_classes + 1,
                                rpn_anchor_generator=anchor_generator,
                                box_roi_pool=roi_pooler)

    def forward(self, x, targets=None):
        if self.training and targets is None:
            raise ValueError("In training mode, targets should be passed")
        elif not self.training and targets is not None:
            raise ValueError("In inference mode, targets should not be passed")
        else:
            return self.model(x, targets)

现在,您需要设置训练和测试的超参数并进行模型训练。代码如下:

batch_size = 2
num_workers = 2
num_epochs = 10

data_dir = '/path/to/coco'

train_transforms = Compose([Resize(min_size=600, max_size=900),
                            RandomHorizontalFlip(),
                            ToTensor()])
test_transforms = Compose([Resize(min_size=800, max_size=1333),
                           ToTensor()])

train_dataset = COCODataset(data_dir, set_name='train', transform=train_transforms)
test_dataset = COCODataset(data_dir, set_name='val', transform=test_transforms)

train_loader = data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=num_workers, collate_fn=lambda x: tuple(zip(*x)))
test_loader = data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False, num_workers=num_workers, collate_fn=lambda x: tuple(zip(*x)))

num_classes = 80

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

model = FasterRCNNResNetFPN(num_classes=num_classes).to(device)

optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9, weight_decay=0.0005)

def train_one_epoch(model, optimizer, data_loader, device, epoch):
    model.train()
    train_loss = 0.0
    start_time = time.time()
    for step, (images, targets, image_ids) in enumerate(data_loader):
        images = [img.to(device) for img in images]
        targets = [{k: v.to(device) for k, v in t.items()} for t in targets]

        loss_dict = model(images, targets)

        losses = sum(loss_dict.values())
        train_loss += losses.item()

        optimizer.zero_grad()
        losses.backward()
        optimizer.step()

        if step % 10 == 0:
            print(f'Epoch: [{epoch}/{num_epochs}] Step: [{step}/{len(data_loader)}] Loss: {losses.item()}')

    train_loss /= len(data_loader)
    end_time = time.time()
    print(f'Training Loss: {train_loss} Time: {end_time - start_time}')

def evaluate(model, data_loader, device):
    model.eval()
    results = []
    for images, targets, image_ids in data_loader:
        images = [img.to(device) for img in images]
        targets = [{k: v.to(device) for k, v in t.items()} for t in targets]

        with torch.no_grad():
            outputs = model(images)

        for i, (output, target) in enumerate(zip(outputs, targets)):
            result = {
                'image_id': image_ids[i],
                'boxes': output['boxes'].detach().cpu().numpy(),
                'scores': output['scores'].detach().cpu().numpy(),
                'labels': output['labels'].detach().cpu().numpy(),
            }
            target = {
                'image_id': image_ids[i],
                'boxes': target['boxes'].cpu().numpy(),
                'labels': target['labels'].cpu().numpy(),
            }
            results.append((result, target))

    return results

for epoch in range(num_epochs):
    train_one_epoch(model, optimizer, train_loader, device, epoch)
    results = evaluate(model, test_loader, device)

这是一个使用PyTorch实现的目标检测模型的示例,使用Faster R-CNN网络和COCO数据集进行训练和测试。您可以根据需要调整模型的超参数,以提高模型的准确性和性能。

九、多标签分类识别

1.构建自定义数据集识别多标签

在是一个实例中,有一个COCODataset类,里面实现了 initgetitem__和__len,如果要实现多标签识别,需要重写getitem。使用二进制交叉熵损失函数。
参考连接:Pytorch基础知识(15)基于PyTorch的多标签图像分类

  • 6
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我辈李想

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值