本文代码详解参考:

模型训练基础流程-CSDN博客


目录

为什么要用GPU训练模型

什么是CUDA

利用GPU训练—方式一(.cuda())

利用GPU训练—方式二 (.to())

Google Colaboratory


为什么要用GPU训练模型

用 GPU 训练模型的核心原因是GPU 的硬件架构和计算特性,能完美适配深度学习模型的计算需求,大幅提升训练效率

一、GPU 的核心优势:并行计算能力极强

深度学习模型的训练过程(如神经网络的前向传播、反向传播)本质上是大量重复的矩阵运算和向量运算(例如卷积层的卷积操作、全连接层的矩阵乘法)。

  • CPU 的设计侧重 “低延迟、串行计算”,核心数量少(通常 4-32 核),适合处理逻辑复杂、步骤连贯的任务(如系统调度、单线程指令),但面对成百上千万次的并行重复计算时效率极低。

  • GPU 的设计则侧重 “高吞吐、并行计算”,核心数量极多(主流 GPU 有数千个计算核心,如 RTX 4090 有 16384 个 CUDA 核心),这些核心可以同时处理大量相似的简单计算(比如同时对矩阵中不同位置的元素做乘法)。
    例如:一个 1000×1000 的矩阵乘法,CPU 可能需要逐个元素循环计算,而 GPU 可以同时启动上万次运算,将计算时间从 “小时级” 压缩到 “分钟级” 甚至 “秒级”。

二、适配深度学习的 “计算密集型” 需求

深度学习训练的两大核心特点,恰好被 GPU 针对性解决:

  1. 计算量极大:模型参数量从百万级(简单 CNN)到千亿级(大语言模型),每次迭代需要对所有参数计算梯度,涉及的运算次数按 “亿” 甚至 “万亿” 计。GPU 的并行核心能同时分摊这些计算,避免 CPU “逐个处理” 的低效。

  2. 数据吞吐量高:训练时需要频繁读取批量数据(如图像、文本特征),并在模型各层间传递。GPU 自带大容量高带宽显存(如 16GB-80GB GDDR6/HOF),配合专门的存储控制器,能快速读写数据,避免 “数据等待计算” 的瓶颈(而 CPU 的内存带宽通常仅为 GPU 的 1/10 左右)。

三、实际效果:训练效率提升数十倍甚至上百倍

  • 对于简单模型(如小型 CNN):GPU 训练速度通常是 CPU 的 10-30 倍。

  • 对于大型模型(如 Transformer、大语言模型):CPU 可能需要数周甚至数月才能完成训练,而 GPU(尤其是多 GPU 集群)可压缩到几天甚至几小时,且能支持更大的批量和更复杂的模型结构(否则 CPU 会因内存或速度限制无法运行)。


用后述代码展示速度差异:

利用GPU训练的时间:

 利用CPU训练的时间:

CPU训练百次需要2s左右 而GPU只要0.5s ! ! ! 


可以使用如图命令查看自己设备的GPU信息

若报错则是驱动没有正确安装,需要去英伟达官网下载 


什么是CUDA

CUDA(Compute Unified Device Architecture)是英伟达(NVIDIA)推出的一种并行计算平台和编程模型,旨在利用 NVIDIA GPU 的并行计算能力,加速计算密集型任务。

核心概念

  • 并行计算平台:CUDA 为开发者提供了一个环境,使得 GPU 可以作为一个高度并行的计算设备,和 CPU 协同工作。在传统计算中,CPU 处理任务是串行的,而 CUDA 允许将大量可以并行执行的计算任务分配到 GPU 上,极大地提高计算效率。

  • 编程模型:CUDA 定义了一套编程接口和语法规则,允许开发者使用类 C 语言(CUDA C/C++)编写并行计算程序,来充分发挥 GPU 的大规模并行计算能力。此外,像 PyTorch、TensorFlow 等深度学习框架也对 CUDA 进行了封装,使得深度学习开发者无需深入了解底层编程细节,就能轻松利用 GPU 加速模型训练。

工作原理

  • 任务拆分:在 CUDA 编程中,开发者需要将计算任务分解成大量可以并行执行的小任务。例如,在深度学习的矩阵乘法中,矩阵的不同元素运算可以并行执行,CUDA 可以将这些运算分配到 GPU 的众多计算核心上。

  • 线程管理:CUDA 将 GPU 的计算资源组织成线程层次结构,包括线程块(block)和线程网格(grid)。每个线程执行相同的内核函数(kernel function),但处理不同的数据,通过线程 ID 来区分和操作不同的数据。

  • 协同计算:CPU 负责处理逻辑性强、计算量小的任务,如程序的流程控制、数据的预处理和后处理等;GPU 则专注于执行高度并行的计算任务,两者相互协作,共同完成复杂的计算任务。

应用场景

  • 深度学习:是 CUDA 最广泛的应用领域之一。在训练神经网络模型(如卷积神经网络 CNN、循环神经网络 RNN 及其变体 LSTM、GRU,还有 Transformer 等)时,大量的矩阵运算(如前向传播、反向传播)可以利用 CUDA 在 GPU 上并行加速,大幅缩短训练时间。

  • 科学计算:在物理模拟、流体动力学计算、分子动力学模拟等科学领域,存在大量的数值计算,CUDA 能够显著提升这些计算的效率,加速科研进程。

  • 图形渲染:虽然 GPU 最初是为图形渲染设计的,但 CUDA 进一步拓展了其应用。在实时渲染、光线追踪等图形处理任务中,CUDA 可以加速图形算法的执行,提升渲染质量和速度。


利用GPU训练—方式一(.cuda())

把如图所示的三个 加上cuda方法即可

运行后GPU确实跑起来了:

代码:

import torchimport torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
import timetrain_data = torchvision.datasets.CIFAR10(root="D:\\Python\\learn_pytorch\\torchvision_dataset", train=True,transform=torchvision.transforms.ToTensor(),download=True)test_data = torchvision.datasets.CIFAR10(root="D:\\Python\\learn_pytorch\\torchvision_dataset", train=True,transform=torchvision.transforms.ToTensor(),download=False)# 数据集长度
train_data_size = len(train_data)
test_data_size = len(test_data)
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))# 利用DataLoader来加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)# 创建网络模型
class MyModule(nn.Module):def __init__(self):super().__init__()self.module = nn.Sequential(nn.Conv2d(3, 32, 5, 1, 2),nn.MaxPool2d(2),nn.Conv2d(32, 32, 5, 1, 2),nn.MaxPool2d(2),nn.Conv2d(32, 64, 5, 1, 2),nn.MaxPool2d(2),nn.Flatten(),nn.Linear(64 * 4 * 4, 64),nn.Linear(64, 10))def forward(self, x):x = self.module(x)return xmodel = MyModule()
# 网络模型转移到GPU
if torch.cuda.is_available():model = model.cuda()# 损失函数
loss_fn = nn.CrossEntropyLoss()
# 损失函数转移到GPU
if torch.cuda.is_available():loss_fn = loss_fn.cuda()
# 优化器
learning_rate = 1e-2
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)# 设置训练网络的一些参数
# 训练次数
total_train_step = 0
# 测试次数
total_test_step = 0
# 训练轮数
epoch = 10# 添加tensorboard
writer = SummaryWriter("logs_test16")# 计时比较CPU和GPU的训练速度差异
# 开始时间
start_time=time.time()
for i in range(epoch):print("---------第{}轮训练开始---------".format(i + 1))# 训练model.train()for data in train_dataloader:imgs, targets = data# 训练数据转移到GPUif torch.cuda.is_available():imgs = imgs.cuda()targets = targets.cuda()outputs = model(imgs)loss = loss_fn(outputs, targets)# 优化器优化模型optimizer.zero_grad()loss.backward()optimizer.step()total_train_step = total_train_step + 1if total_train_step % 100 == 0:# 到当前的训练总时间end_time=time.time()print("训练所花时间:{}秒".format(end_time-start_time))print("训练次数:{},Loss:{}".format(total_train_step, loss.item()))writer.add_scalar("train_loss", loss.item(), total_train_step)# 评估模型训练效果 - 跑一个测试数据查看正确率# 测试过程中,参数不需要调整了,临时把梯度去除model.eval()total_test_loss = 0total_accuracy = 0with torch.no_grad():for data in test_dataloader:imgs, targets = data# 测试数据转移到GPUif torch.cuda.is_available():imgs = imgs.cuda()targets = targets.cuda()outputs = model(imgs)loss = loss_fn(outputs, targets)total_test_loss = total_test_loss + loss.item()accuracy = (outputs.argmax(1) == targets).sum()total_accuracy = total_accuracy + accuracy  # 预测对的总数量print("整体测试集上的loss:{}", format(total_test_loss))print("整体测试集上的准确率:{}", format(total_accuracy / test_data_size))  # 准确率writer.add_scalar("test_sum_loss", total_test_loss, total_test_step)writer.add_scalar("test_accuracy", total_accuracy / test_data_size, total_test_step)total_test_step = total_test_step + 1# 保存每一次训练的结果torch.save(model, "model_{}.pth".format(i))print("模型已保存")writer.close()

import torch

import torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
import time

train_data = torchvision.datasets.CIFAR10(root="D:\\Python\\learn_pytorch\\torchvision_dataset", train=True,
                                          transform=torchvision.transforms.ToTensor(),
                                          download=True)

test_data = torchvision.datasets.CIFAR10(root="D:\\Python\\learn_pytorch\\torchvision_dataset", train=True,
                                         transform=torchvision.transforms.ToTensor(),
                                         download=False)

# 数据集长度
train_data_size = len(train_data)
test_data_size = len(test_data)
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))

# 利用DataLoader来加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)

# 创建网络模型
class MyModule(nn.Module):
    def __init__(self):
        super().__init__()
        self.module = nn.Sequential(
            nn.Conv2d(3, 32, 5, 1, 2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 32, 5, 1, 2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 64, 5, 1, 2),
            nn.MaxPool2d(2),
            nn.Flatten(),
            nn.Linear(64 * 4 * 4, 64),
            nn.Linear(64, 10)
        )

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

model = MyModule()
# 网络模型转移到GPU
if torch.cuda.is_available():
    model = model.cuda()

# 损失函数
loss_fn = nn.CrossEntropyLoss()
# 损失函数转移到GPU
if torch.cuda.is_available():
    loss_fn = loss_fn.cuda()

# 优化器
learning_rate = 1e-2
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

# 设置训练网络的一些参数
# 训练次数
total_train_step = 0
# 测试次数
total_test_step = 0
# 训练轮数
epoch = 10

# 添加tensorboard
writer = SummaryWriter("logs_test16")

# 计时比较CPU和GPU的训练速度差异
# 开始时间
start_time=time.time()
for i in range(epoch):
    print("---------第{}轮训练开始---------".format(i + 1))

    # 训练
    model.train()
    for data in train_dataloader:
        imgs, targets = data

        # 训练数据转移到GPU
        if torch.cuda.is_available():
            imgs = imgs.cuda()
            targets = targets.cuda()


        outputs = model(imgs)
        loss = loss_fn(outputs, targets)

        # 优化器优化模型
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        total_train_step = total_train_step + 1
        if total_train_step % 100 == 0:
            # 到当前的训练总时间
            end_time=time.time()
            print("训练所花时间:{}秒".format(end_time-start_time))
            print("训练次数:{},Loss:{}".format(total_train_step, loss.item()))
            writer.add_scalar("train_loss", loss.item(), total_train_step)
    # 评估模型训练效果 - 跑一个测试数据查看正确率

    # 测试过程中,参数不需要调整了,临时把梯度去除
    model.eval()
    total_test_loss = 0
    total_accuracy = 0
    with torch.no_grad():
        for data in test_dataloader:
            imgs, targets = data

           # 测试数据转移到GPU
            if torch.cuda.is_available():
                imgs = imgs.cuda()
                targets = targets.cuda()

            outputs = model(imgs)
            loss = loss_fn(outputs, targets)
            total_test_loss = total_test_loss + loss.item()
            accuracy = (outputs.argmax(1) == targets).sum()
            total_accuracy = total_accuracy + accuracy  # 预测对的总数量

    print("整体测试集上的loss:{}", format(total_test_loss))
    print("整体测试集上的准确率:{}", format(total_accuracy / test_data_size))  # 准确率
    writer.add_scalar("test_sum_loss", total_test_loss, total_test_step)
    writer.add_scalar("test_accuracy", total_accuracy / test_data_size, total_test_step)
    total_test_step = total_test_step + 1

    # 保存每一次训练的结果
    torch.save(model, "model_{}.pth".format(i))
    print("模型已保存")

writer.close()


 利用GPU训练—方式二 (.to())

更常用和推荐

import torchimport torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
import time# 定义训练的设备
device1 = torch.device("cpu")
device2 = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# device2 = torch.device("cuda") 在确保有GPU的情况下也可以train_data = torchvision.datasets.CIFAR10(root="D:\\Python\\learn_pytorch\\torchvision_dataset", train=True,transform=torchvision.transforms.ToTensor(),download=True)test_data = torchvision.datasets.CIFAR10(root="D:\\Python\\learn_pytorch\\torchvision_dataset", train=True,transform=torchvision.transforms.ToTensor(),download=False)# 数据集长度
train_data_size = len(train_data)
test_data_size = len(test_data)
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))# 利用DataLoader来加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)# 创建网络模型
class MyModule(nn.Module):def __init__(self):super().__init__()self.module = nn.Sequential(nn.Conv2d(3, 32, 5, 1, 2),nn.MaxPool2d(2),nn.Conv2d(32, 32, 5, 1, 2),nn.MaxPool2d(2),nn.Conv2d(32, 64, 5, 1, 2),nn.MaxPool2d(2),nn.Flatten(),nn.Linear(64 * 4 * 4, 64),nn.Linear(64, 10))def forward(self, x):x = self.module(x)return xmodel = MyModule()
# 网络模型转移到GPU
model = model.to(device2)# 损失函数
loss_fn = nn.CrossEntropyLoss()
# 损失函数转移到GPU
loss_fn = loss_fn.to(device2)
# 优化器
learning_rate = 1e-2
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)# 设置训练网络的一些参数
# 训练次数
total_train_step = 0
# 测试次数
total_test_step = 0
# 训练轮数
epoch = 10# 添加tensorboard
writer = SummaryWriter("logs_test17")# 计时比较CPU和GPU的训练速度差异
# 开始时间
start_time = time.time()
for i in range(epoch):print("---------第{}轮训练开始---------".format(i + 1))# 训练model.train()for data in train_dataloader:imgs, targets = data# 训练数据转移到GPUimgs = imgs.to(device2)targets = targets.to(device2)outputs = model(imgs)loss = loss_fn(outputs, targets)# 优化器优化模型optimizer.zero_grad()loss.backward()optimizer.step()total_train_step = total_train_step + 1if total_train_step % 100 == 0:# 到当前的训练总时间end_time = time.time()print("训练所花时间:{}秒".format(end_time - start_time))print("训练次数:{},Loss:{}".format(total_train_step, loss.item()))writer.add_scalar("train_loss", loss.item(), total_train_step)# 评估模型训练效果 - 跑一个测试数据查看正确率# 测试过程中,参数不需要调整了,临时把梯度去除model.eval()total_test_loss = 0total_accuracy = 0with torch.no_grad():for data in test_dataloader:imgs, targets = data# 测试数据转移到GPUimgs = imgs.to(device2)targets = targets.to(device2)outputs = model(imgs)loss = loss_fn(outputs, targets)total_test_loss = total_test_loss + loss.item()accuracy = (outputs.argmax(1) == targets).sum()total_accuracy = total_accuracy + accuracy  # 预测对的总数量print("整体测试集上的loss:{}", format(total_test_loss))print("整体测试集上的准确率:{}", format(total_accuracy / test_data_size))  # 准确率writer.add_scalar("test_sum_loss", total_test_loss, total_test_step)writer.add_scalar("test_accuracy", total_accuracy / test_data_size, total_test_step)total_test_step = total_test_step + 1# 保存每一次训练的结果torch.save(model, "model_{}.pth".format(i))print("模型已保存")writer.close()
import torchimport torchvision
from torch import nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
import time# 定义训练的设备
device1 = torch.device("cpu")
device2 = torch.device("cuda" if torch.cuda.is_available() else "cpu")
train_data = torchvision.datasets.CIFAR10(root="D:\\Python\\learn_pytorch\\torchvision_dataset", train=True,transform=torchvision.transforms.ToTensor(),download=True)test_data = torchvision.datasets.CIFAR10(root="D:\\Python\\learn_pytorch\\torchvision_dataset", train=True,transform=torchvision.transforms.ToTensor(),download=False)# 数据集长度
train_data_size = len(train_data)
test_data_size = len(test_data)
print("训练数据集的长度为:{}".format(train_data_size))
print("测试数据集的长度为:{}".format(test_data_size))# 利用DataLoader来加载数据集
train_dataloader = DataLoader(train_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)# 创建网络模型
class MyModule(nn.Module):def __init__(self):super().__init__()self.module = nn.Sequential(nn.Conv2d(3, 32, 5, 1, 2),nn.MaxPool2d(2),nn.Conv2d(32, 32, 5, 1, 2),nn.MaxPool2d(2),nn.Conv2d(32, 64, 5, 1, 2),nn.MaxPool2d(2),nn.Flatten(),nn.Linear(64 * 4 * 4, 64),nn.Linear(64, 10))def forward(self, x):x = self.module(x)return xmodel = MyModule()
# 网络模型转移到GPU
model = model.to(device2)# 损失函数
loss_fn = nn.CrossEntropyLoss()
# 损失函数转移到GPU
loss_fn = loss_fn.to(device2)
# 优化器
learning_rate = 1e-2
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)# 设置训练网络的一些参数
# 训练次数
total_train_step = 0
# 测试次数
total_test_step = 0
# 训练轮数
epoch = 10# 添加tensorboard
writer = SummaryWriter("logs_test17")# 计时比较CPU和GPU的训练速度差异
# 开始时间
start_time = time.time()
for i in range(epoch):print("---------第{}轮训练开始---------".format(i + 1))# 训练model.train()for data in train_dataloader:imgs, targets = data# 训练数据转移到GPUimgs = imgs.to(device2)targets = targets.to(device2)outputs = model(imgs)loss = loss_fn(outputs, targets)# 优化器优化模型optimizer.zero_grad()loss.backward()optimizer.step()total_train_step = total_train_step + 1if total_train_step % 100 == 0:# 到当前的训练总时间end_time = time.time()print("训练所花时间:{}秒".format(end_time - start_time))print("训练次数:{},Loss:{}".format(total_train_step, loss.item()))writer.add_scalar("train_loss", loss.item(), total_train_step)# 评估模型训练效果 - 跑一个测试数据查看正确率# 测试过程中,参数不需要调整了,临时把梯度去除model.eval()total_test_loss = 0total_accuracy = 0with torch.no_grad():for data in test_dataloader:imgs, targets = data
# 测试数据转移到GPUimgs = imgs.to(device2)targets = targets.to(device2)outputs = model(imgs)loss = loss_fn(outputs, targets)total_test_loss = total_test_loss + loss.item()accuracy = (outputs.argmax(1) == targets).sum()total_accuracy = total_accuracy + accuracy  # 预测对的总数量print("整体测试集上的loss:{}", format(total_test_loss))print("整体测试集上的准确率:{}", format(total_accuracy / test_data_size))  # 准确率writer.add_scalar("test_sum_loss", total_test_loss, total_test_step)writer.add_scalar("test_accuracy", total_accuracy / test_data_size, total_test_step)total_test_step = total_test_step + 1# 保存每一次训练的结果torch.save(model, "model_{}.pth".format(i))print("模型已保存")writer.close()


Google Colaboratory

Google Colab(Colaboratory)是谷歌开发的基于云端的交互式笔记本环境。

  • 核心功能:无需本地配置环境,可直接在浏览器中编写和运行 Python 代码,支持深度学习、数据分析等任务。
  • 硬件支持:免费提供 CPU、GPU(如 Tesla K80、T4)甚至 TPU(张量处理单元)资源,方便运行大型模型(如训练神经网络)。
  • 优势
    • 与 Google Drive 无缝集成,可直接读取 / 保存云端文件;
    • 支持实时协作(多人共同编辑同一笔记本);
    • 预装了 PyTorch、TensorFlow、NumPy 等主流库,开箱即用。
  • 适用场景:快速原型开发、学习深度学习、资源有限时的模型训练等。

简单说,它是一个 “云端免费 GPU 编程工具”,对初学者和需要临时算力的开发者非常友好。 

前提:能使用谷歌  (-_-)

 

 在上方导航栏   修改-笔记本设置 里可以启用GPU/TPU

查看硬件参数 

Tesla T4 是一款面向数据中心的推理加速 GPU,基于 Turing 架构,具备不错的计算能力,支持多种计算精度,在深度学习推理任务中有出色表现。

用 Colaboratory 跑上述代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/90716.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/90716.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/90716.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Matlab学习笔记:自定义函数

MATLAB 学习笔记:自定义函数自定义函数是MATLAB编程的基础,它允许你将重复代码封装成可重用的模块,提高代码的可读性和效率。本笔记将覆盖所有重点知识点,包括语法细节、输入输出处理、函数文件管理、错误处理等。我会用自然易懂的…

【数学建模 | Matlab】二维绘图 和 三维绘图

- 第 115 篇 - Date: 2025 - 07 - 23 Author: 郑龙浩(仟墨) 续写上一篇,如下文章: 【数学建模|Matlab】Matlab「基础知识」和「基础操作」 五 二维绘图 1 举例 % 二维平面绘图(扩展至 -2π 到 2π) x …

MCP (Model Context Protocol) 与 HTTP API:大模型时代的通信新范式

MCP (Model Context Protocol) 与 HTTP API:大模型时代的通信新范式在数字世界的两端,API 扮演着不可或缺的桥梁角色。我们熟知的 HTTP API 是 Web 互联互通的基石,驱动着无数应用程序的交互。然而,随着大型语言模型(L…

CentOS 搭建 Docker 私有镜像仓库

CentOS 搭建 Docker 私有镜像仓库 搭建 Docker 私有镜像仓库能为团队提供高效、安全的镜像管理方案。下面将详细介绍每个步骤的操作细节,其中命令部分均用代码块展示。 一、环境准备 要搭建 Docker 私有镜像仓库,首先得确保服务器环境符合要求&#xff0…

Zookeeper的简单了解

Zookeeper的简单了解 Zookeeper是一个为分布式应用程序提供协调服务的中间件。 主要作用有三点:分布式锁、注册中心、配置管理、。 特点有读写速度快(内存存储)、有监听机制(用于发布订阅)、保证了顺序一致性&#xff…

Android Fragment 全解析

在 Android 开发中,Fragment 是构建灵活界面的核心组件 —— 它既能像 “迷你 Activity” 一样包含布局和逻辑,又能灵活地嵌入到不同 Activity 中复用。无论是平板的多面板布局,还是手机的单页切换,Fragment 都能让界面适配更高效…

0-1BFS(双端队列,洛谷P4667 [BalticOI 2011] Switch the Lamp On 电路维修 (Day1)题解)

对于权重为0或1的路径搜索中&#xff0c;使用双端队列可以对最短路问题进行时间复杂度的优化&#xff0c;由于优先队列的O(longn)级别的插入时间&#xff0c;对于双端队列O(1)插入可以将时间复杂度减少至O(M); https://www.luogu.com.cn/problem/P4667 #include<bits/stdc…

基于LNMP架构的分布式个人博客搭建

1.运行环境主机主机名系统服务192.168.75.154Server-WebLinuxWeb192.168.75.155Server-NFS-DNSLinuxNFS/DNS2.基础配置配置主机名&#xff0c;静态IP地址开启防火墙并配置部分开启SElinux并配置服务器之间使用同ntp.aliyun.com进行时间同步服务器之间使用用ntp.aliyun.com进行时…

基于开源AI智能名片链动2+1模式S2B2C商城小程序的人格品牌化实现路径研究

摘要&#xff1a;在数字化消费时代&#xff0c;人格品牌化已成为企业突破同质化竞争的核心策略。本文以开源AI智能名片、链动21模式与S2B2C商城小程序的融合为切入点&#xff0c;构建“技术赋能-关系重构-价值共生”的人格品牌化理论框架。通过分析用户触达、信任裂变与价值沉淀…

设计模式十一:享元模式(Flyweight Pattern)

享元模式是一种结构型设计模式&#xff0c;它通过共享对象来最小化内存使用或计算开销。这种模式适用于大量相似对象的情况&#xff0c;通过共享这些对象的公共部分来减少资源消耗。基本概念享元模式的核心思想是将对象的内在状态&#xff08;不变的部分&#xff09;和外在状态…

Webpack/Vite 终极指南:前端开发的“涡轮增压引擎“

开篇:当你的项目变成"俄罗斯套娃" "我的index.js怎么引入了87个文件?!" —— 这是每个前端开发者第一次面对复杂项目依赖时的真实反应。别担心,今天我要带你认识两位"打包侠":老牌劲旅Webpack和新锐黑马Vite 一、构建工具:前端世界的&qu…

Windows 下配置 GPU 用于深度学习(PyTorch)的完整流程

1. 安装 NVIDIA 显卡驱动 前往 NVIDIA官网 下载并安装适合你显卡型号&#xff08;如 5070Ti&#xff09;的最新版驱动。下载 NVIDIA 官方驱动 | NVIDIA安装完成后建议重启电脑。 2. 安装 CUDA Toolkit 前往 CUDA Toolkit 下载页。 选择 Windows、x86_64、你的系统版本&#…

详解力扣高频SQL50题之180. 连续出现的数字【困难】

传送门&#xff1a;180. 连续出现的数字 题目 表&#xff1a;Logs -------------------- | Column Name | Type | -------------------- | id | int | | num | varchar | -------------------- 在 SQL 中&#xff0c;id 是该表的主键。 id 是一个自增列。 找出所有至少连续…

VSCode 报错 Error: listen EACCES: permission denied 0.0.0.0:2288

使用 npm run dev 启动项目时报错&#xff1a;error when starting dev server: Error: listen EACCES: permission denied 0.0.0.0:2288at Server.setupListenHandle [as _listen2] (node:net:1881:21)at listenInCluster (node:net:1946:12)at Server.listen (node:net:2044:…

[2025CVPR-图象超分辨方向]DORNet:面向退化的正则化网络,用于盲深度超分辨率

1. ​问题背景与挑战​ 盲深度超分辨率&#xff08;Blind Depth Super-Resolution, DSR&#xff09;的目标是从低分辨率&#xff08;LR&#xff09;深度图中恢复高分辨率&#xff08;HR&#xff09;深度图&#xff0c;但现有方法在真实场景下面临显著挑战&#xff1a; ​已知…

关系与逻辑运算 —— 寄存器操作的 “入门钥匙”

前言 哈喽大家好&#xff0c;这里是 Hello_Embed 的新一篇学习笔记。在前文中&#xff0c;我们学习了如何用结构体指针操作硬件寄存器&#xff0c;而寄存器的配置往往离不开位运算和条件判断 —— 比如通过逻辑运算精准修改某几位的值&#xff0c;通过关系运算判断硬件状态。这…

使用 Python 将 CSV 文件转换为带格式的 Excel 文件

在日常的数据处理和报表生成工作中&#xff0c;CSV 格式因其简洁性而被广泛采用。但在展示数据时&#xff0c;CSV 文件往往缺乏格式和结构化样式&#xff0c;不利于阅读与分析。相比之下&#xff0c;Excel 格式&#xff08;如 .xlsx&#xff09;不仅支持丰富的样式设置&#xf…

每天读本书-《如何度过每天的24小时》

全景式书籍探索框架 1. “这本书是关于什么的&#xff1f;”——核心定位 一句话核心思想&#xff1a;这本书的核心并非教你如何高效地工作&#xff0c;而是倡导你将工作之外的“自由时间”视为一个“内在的另一天”&#xff0c;并投入智力与热情去经营它&#xff0c;从而获得精…

前端开发 React 状态优化

为了更深入地理解 React 状态管理的性能问题及其解决方案&#xff0c;本文将详细分析 React Context 和 State 的性能问题&#xff0c;配以示例代码说明优化策略。之后&#xff0c;讨论 Redux 作为不可变库的性能问题&#xff0c;并引出 Immer 作为优化解决方案。1. React Stat…

剑指offer第2版:双指针+排序+分治+滑动窗口

一、p129-JZ21使奇数位于偶数前面&#xff08;不考虑相对位置&#xff09;&#xff08;hoare快排双指针&#xff09; 调整数组顺序使奇数位于偶数前面(二)_牛客题霸_牛客网 如果不考虑相对位置的话&#xff0c;那么我们可以模仿hoare快排&#xff0c;使用双指针的思想&#xf…