Pytorch学习笔记——在GPU上进行训练

1. 环境准备

首先,确保PyTorch已经安装,且CUDA(NVIDIA的并行计算平台和编程模型)支持已经正确配置。可以通过以下代码检查CUDA是否可用:

print(torch.cuda.is_available())  # 如果返回True,则CUDA可用

配置PyTorch环境和CUDA支持,可以参考我写的这篇博客
Pytorch学习笔记——环境配置安装

2. 导入必要库

import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Linear, Flatten, Sequential
from torch.utils.data import DataLoader
  • torch 是PyTorch的核心库。
  • torchvision 提供了用于计算机视觉任务的工具,包括数据集和变换。
  • nn 包含了构建神经网络所需的各种模块。
  • DataLoader 用于加载数据集并进行批处理。

3. 加载数据集

使用CIFAR-10数据集进行训练,它是一个常用的小型图像数据集。加载数据集并创建数据加载器。

# 加载数据集
dataset = torchvision.datasets.CIFAR10(root="data1", train=False, transform=torchvision.transforms.ToTensor(), download=True)
# 创建数据加载器
dataloader = DataLoader(dataset, batch_size=64)
  • torchvision.datasets.CIFAR10:下载并加载CIFAR-10数据集。
  • DataLoader:将数据集划分为小批次,并进行数据加载。

4. 定义简单的神经网络模型

定义一个简单的卷积神经网络(CNN)模型:

self.model1 = Sequential(
            Conv2d(3, 32, 5, padding=2),  # 第一次卷积
            MaxPool2d(2),  # 第一次最大池化
            Conv2d(32, 32, 5, padding=2),  # 第二次卷积
            MaxPool2d(2),  # 第二次最大池化
            Conv2d(32, 64, 5, padding=2),  # 第三次卷积
            MaxPool2d(2),  # 第三次最大池化
            Flatten(),    # 展平层
            Linear(1024, 64),  # 第一个全连接层
            Linear(64, 10),  # 第二个全连接层
        )
def forward(self, x):
        x = self.model1(x)
        return x
  • Conv2d:二维卷积层,用于提取图像特征。
  • MaxPool2d:最大池化层,用于下采样。
  • Flatten:将多维输入展平为一维,用于全连接层的输入。
  • Linear:全连接层,用于分类任务。

5. 检查和设置GPU设备

需要检查是否有可用的GPU,并将模型和数据移动到GPU上。

# 检查是否有可用的GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# 将模型和数据转移到GPU上
mynn = NN().to(device)
print(mynn)
  • torch.device("cuda"):如果CUDA可用,则使用GPU;否则使用CPU。
  • to(device):将模型转移到指定的设备(CPU或GPU)。

6. 定义损失函数和优化器

定义损失函数和优化器来训练模型:

# 定义损失函数
loss = nn.CrossEntropyLoss().to(device)

# 定义优化器
optim = torch.optim.SGD(mynn.parameters(), lr=0.01)
  • nn.CrossEntropyLoss:适用于分类问题的损失函数。
  • torch.optim.SGD:随机梯度下降优化器。

7. 训练模型

通过多个epoch对模型进行训练。在每个epoch中,进行前向传播、计算损失、反向传播和参数更新:

# 多轮学习 0 - 20 20轮
for epoch in range(20):
    running_loss = 0.0
    for data in dataloader:
        # 确保数据也转移到GPU上
        imgs, targets = data[0].to(device), data[1].to(device)

        optim.zero_grad()  # 清零梯度缓存
        outputs = mynn(imgs)  # 前向传播
        loss_value = loss(outputs, targets)  # 计算损失
        loss_value.backward()  # 反向传播,计算梯度
        optim.step()  # 根据梯度更新权重

        running_loss += loss_value.item()  # 累加损失值

    print(f"Epoch {epoch + 1}, Loss: {running_loss / len(dataloader)}")
    print("------------------------------")
  • optim.zero_grad():清零之前计算的梯度。
  • outputs = mynn(imgs):进行前向传播。
  • loss_value.backward():进行反向传播,计算梯度。
  • optim.step():根据计算的梯度更新权重。
  • running_loss:累加损失值以计算平均损失。

8. 全部代码展示及运行结果

# -*- coding: utf-8 -*-
# @Author: kk
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Linear, Flatten, Sequential
from torch.utils.data import DataLoader

# 加载数据集
dataset = torchvision.datasets.CIFAR10(root="data1", train=False, transform=torchvision.transforms.ToTensor(), download=True)
# loader加载
dataloader = DataLoader(dataset, batch_size=64)

# 网络
class NN(nn.Module):
    def __init__(self):
        super(NN, self).__init__()
        self.model1 = Sequential(
            Conv2d(3, 32, 5, padding=2),  # 第一次卷积
            MaxPool2d(2),  # 第一次最大池化
            Conv2d(32, 32, 5, padding=2),  # 第二次卷积
            MaxPool2d(2),  # 第二次最大池化
            Conv2d(32, 64, 5, padding=2),  # 第三次卷积
            MaxPool2d(2),  # 第三次最大池化
            Flatten(),    # 展平层
            Linear(1024, 64),  # 第一个全连接层
            Linear(64, 10),  # 第二个全连接层
        )

    def forward(self, x):
        x = self.model1(x)
        return x

# 检查是否有可用的GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# 将模型和数据转移到GPU上
mynn = NN().to(device)
print(mynn)
loss = nn.CrossEntropyLoss().to(device)

# 优化器
optim = torch.optim.SGD(mynn.parameters(), lr=0.01)

# 多轮学习  0 - 20  20轮
for epoch in range(20):
    running_loss = 0.0
    for data in dataloader:
        # 确保数据也转移到GPU上
        imgs, targets = data[0].to(device), data[1].to(device)

        optim.zero_grad()  # 清零梯度缓存
        outputs = mynn(imgs)  # 前向传播
        loss_value = loss(outputs, targets)  # 计算损失
        loss_value.backward()  # 反向传播,计算梯度
        optim.step()  # 根据梯度更新权重

        running_loss += loss_value.item()  # 累加损失值

    print(f"Epoch {epoch + 1}, Loss: {running_loss / len(dataloader)}")
    print("------------------------------")

运行结果如下,发现在每一轮过后,Loss在逐渐减小:
在这里插入图片描述

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值