Day 38 GPU训练及类的call方法

@浙大疏锦行

一、CPU 性能查看

系统级查看(Windows/Linux/Mac 通用)

(1)Windows 系统

  • 任务管理器 :按下 Ctrl+Shift+Esc → 切换到「性能」选项卡 → 查看 CPU 使用率、核心数、频率、缓存等;
  • 资源监视器:任务管理器「性能」→ 左下角「打开资源监视器」→ 可查看每个进程的 CPU 占用、线程数。

(2)Linux 系统(命令行)

复制代码
# 实时查看CPU整体使用率、核心数、负载(最常用)
top  # 按1显示每个核心,按q退出

# 查看CPU硬件信息(核心数、架构、频率)
lscpu

# 更直观的CPU监控(需安装)
apt install htop
htop

# 查看进程CPU占用(指定进程名/ID)
pidstat -p [进程ID] 1  # 每秒刷新1次

(3)Mac 系统

  • 「活动监视器」:启动台搜索「活动监视器」→ 「CPU」标签页 → 查看使用率、进程占用;

  • 终端命令:

    复制代码
    top  # 实时监控
    sysctl -n hw.ncpu  # 查看CPU核心数

二、GPU 性能查看

Python 代码中查看 GPU 性能

复制代码
import torch

# 1. 检查GPU是否可用
gpu_available = torch.cuda.is_available()
print(f"GPU是否可用:{gpu_available}")

# 2. 查看GPU数量、型号
if gpu_available:
    gpu_count = torch.cuda.device_count()
    gpu_name = torch.cuda.get_device_name(0)  # 查看第0块GPU名称
    print(f"GPU数量:{gpu_count},第0块GPU型号:{gpu_name}")
    
    # 3. 查看当前GPU显存使用(PyTorch视角)
    torch.cuda.empty_cache()  # 清空缓存
    allocated = torch.cuda.memory_allocated(0) / 1024**3  # 已分配显存(GB)
    cached = torch.cuda.memory_reserved(0) / 1024**3      # 缓存显存(GB)
    print(f"已分配显存:{allocated:.2f}GB,缓存显存:{cached:.2f}GB")
    
    # 4. 设置默认GPU
    torch.cuda.set_device(0)

三、GPU 训练方法

核心步骤:设备配置 → 模型 / 数据迁移 → 训练逻辑 → 显存优化

  • 设备配置:通过torch.cuda.is_available()判断 GPU 是否可用,将模型 / 数据移到 GPU(.to(device));

  • 数据 / 模型迁移:张量 / 模型必须和设备匹配(GPU 张量不能在 CPU 上计算,反之亦然);

  • 批量训练:避免 GPU 显存溢出,控制 batch_size;

  • 混合精度(可选):加速训练,减少显存占用。

    import torch
    import torch.nn as nn
    import torch.optim as optim
    from torch.utils.data import DataLoader, TensorDataset

    ===================== 1. 设备配置(核心) =====================

    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    print(f"训练设备:{device}")

    ===================== 2. 定义模型并迁移到GPU =====================

    class SimpleMLP(nn.Module):
    def init(self, input_dim=10, hidden_dim=64, output_dim=2):
    super().init()
    self.mlp = nn.Sequential(
    nn.Linear(input_dim, hidden_dim),
    nn.ReLU(),
    nn.Linear(hidden_dim, output_dim)
    )

    复制代码
      def forward(self, x):
          return self.mlp(x)

    初始化模型并移到GPU

    model = SimpleMLP(input_dim=10, output_dim=2).to(device)

    ===================== 3. 准备数据并迁移到GPU(批量) =====================

    模拟数据集

    batch_size = 64
    x = torch.randn(1000, 10) # CPU张量
    y = torch.randint(0, 2, (1000,)) # CPU张量
    dataset = TensorDataset(x, y)
    dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)

    ===================== 4. 定义优化器/损失函数 =====================

    criterion = nn.CrossEntropyLoss()
    optimizer = optim.Adam(model.parameters(), lr=1e-3)

    ===================== 5. GPU训练逻辑 =====================

    epochs = 5
    model.train() # 训练模式
    for epoch in range(epochs):
    epoch_loss = 0.0
    for x_batch, y_batch in dataloader:
    # 关键:将batch数据移到GPU(DataLoader默认生成CPU张量)
    x_batch = x_batch.to(device)
    y_batch = y_batch.to(device)

    复制代码
          # 前向传播
          outputs = model(x_batch)
          loss = criterion(outputs, y_batch)
          
          # 反向传播+优化
          optimizer.zero_grad()
          loss.backward()
          optimizer.step()
          
          epoch_loss += loss.item()
      
      avg_loss = epoch_loss / len(dataloader)
      print(f"Epoch [{epoch+1}/{epochs}], 平均损失:{avg_loss:.4f}")

    ===================== 6. GPU推理(验证) =====================

    model.eval()
    with torch.no_grad(): # 关闭梯度,节省显存
    test_x = torch.randn(10, 10).to(device) # 测试数据移到GPU
    pred = model(test_x)
    print(f"\nGPU推理结果(类别):{pred.argmax(dim=1).cpu().numpy()}") # 转回CPU便于打印

四、类的call方法

  1. 语法规则

    class 类名:
    def call(self, *args, **kwargs):
    # 自定义逻辑(可接收参数、返回结果)
    执行操作
    return 结果

  • 当实例被调用(实例()实例(参数))时,Python 会自动执行 __call__ 方法;
  • self 指向实例本身,可访问实例的所有属性(状态);
  • 支持任意参数(*args/**kwargs)和返回值,和普通函数完全一致。
  1. 本质:可调用对象(Callable)

Python 中「可调用对象」包括:函数、方法、类、带 __call__ 的实例。可通过 callable() 验证:

复制代码
class Counter:
    def __call__(self):
        pass

counter = Counter()
print(callable(counter))  # True(实例可调用)
print(callable(Counter))  # True(类本身可调用,调用后创建实例)
print(callable(lambda x: x+1))  # True(函数可调用)

3.基础示例:带状态的调用

最典型的场景是「保存状态的函数」(区别于普通函数的局部变量):

复制代码
class Accumulator:
    """累加器:每次调用传入一个数,累加并返回总和"""
    def __init__(self):
        self.total = 0  # 实例属性保存累加状态
    
    def __call__(self, num):
        self.total += num
        return self.total

# 使用示例
acc = Accumulator()
print(acc(10))  # 执行__call__,total=0+10 → 输出10
print(acc(20))  # total=10+20 → 输出30
print(acc(5))   # total=30+5 → 输出35
print(acc.total)# 直接访问状态 → 输出35
相关推荐
猷咪20 分钟前
C++基础
开发语言·c++
IT·小灰灰22 分钟前
30行PHP,利用硅基流动API,网页客服瞬间上线
开发语言·人工智能·aigc·php
快点好好学习吧23 分钟前
phpize 依赖 php-config 获取 PHP 信息的庖丁解牛
android·开发语言·php
秦老师Q24 分钟前
php入门教程(超详细,一篇就够了!!!)
开发语言·mysql·php·db
烟锁池塘柳024 分钟前
解决Google Scholar “We‘re sorry... but your computer or network may be sending automated queries.”的问题
开发语言
是誰萆微了承諾24 分钟前
php 对接deepseek
android·开发语言·php
vx_BS8133028 分钟前
【直接可用源码免费送】计算机毕业设计精选项目03574基于Python的网上商城管理系统设计与实现:Java/PHP/Python/C#小程序、单片机、成品+文档源码支持定制
java·python·课程设计
2601_9498683628 分钟前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
gzxx2007sddx35 分钟前
windows vnpy运行过程及问题记录
python·量化·vnpy
星火开发设计42 分钟前
类型别名 typedef:让复杂类型更简洁
开发语言·c++·学习·算法·函数·知识