网站后缀名wordpress 点赞 ajax
2026/4/6 4:02:58 网站建设 项目流程
网站后缀名,wordpress 点赞 ajax,人力资源公司名称大全简单大气,wordpress放tomcat浙大疏锦行 #x1f4d8; Day 34 实战作业#xff1a;GPU 加速与 Python 魔法方法 1. 作业综述 核心目标#xff1a; GPU 训练#xff1a;掌握 PyTorch 的 .to(device) 机制#xff0c;将模型和数据迁移到显卡上训练#xff0c;并对比 CPU 与 GPU 的速度差异。性能分…浙大疏锦行 Day 34 实战作业GPU 加速与 Python 魔法方法1. 作业综述核心目标GPU 训练掌握 PyTorch 的.to(device)机制将模型和数据迁移到显卡上训练并对比 CPU 与 GPU 的速度差异。性能分析理解为什么在小数据集上 GPU 反而比 CPU 慢数据传输开销 vs 计算开销。魔法方法深入理解__call__方法明白为什么我们用model(x)而不是model.forward(x)。涉及知识点Device Management:torch.device,.to(device),torch.cuda.is_available().Performance Tuning: 减少 CPU-GPU 通信频率 (减少.item()调用)。Python Magic Methods:__init__vs__call__.场景类比CPU: 像是一个全能的博士核心少但强大算简单的加减法小数据非常快。GPU: 像是一万个小学生核心多但简单算复杂的矩阵乘法大数据非常快。数据传输: 把题目从博士办公室内存搬到小学生教室显存是需要花时间的。如果题目太少搬运的时间比计算的时间还长。步骤 1环境检测与设备选择场景描述在开始训练前我们需要先确定电脑上是否有 N 卡NVIDIA GPU。代码应该具有通用性有显卡就用显卡没显卡就用 CPU。任务使用torch.cuda.is_available()检测环境。定义device对象。打印当前使用的设备名称。importtorchimporttorch.nnasnnimporttorch.optimasoptimfromsklearn.datasetsimportload_irisfromsklearn.model_selectionimporttrain_test_splitfromsklearn.preprocessingimportMinMaxScalerimporttimeimportmatplotlib.pyplotasplt# --- 1. 设备检测 ---# 这是 PyTorch 的标准写法保证代码在任何机器上都能跑devicetorch.device(cuda:0iftorch.cuda.is_available()elsecpu)print(f 当前运行设备:{device})ifdevice.typecuda:print(f 显卡型号:{torch.cuda.get_device_name(0)})print(f 显存信息:{torch.cuda.get_device_properties(0).total_memory/1024**3:.2f}GB)else:print( ⚠️ 未检测到 GPU将使用 CPU 进行训练。) 当前运行设备: cuda:0 显卡型号: NVIDIA GeForce RTX 3050 Laptop GPU 显存信息: 4.00 GB步骤 2数据与模型的“搬家”核心逻辑PyTorch 默认将所有数据和模型创建在CPU上。要使用 GPU必须显式地调用.to(device)方法将它们“搬运”到显存中。注意输入数据 (X)、标签 (y) 和 模型 (model) 必须在同一个设备上否则会报错。任务准备 Iris 数据。将 Tensor 移动到 GPU。实例化 MLP 模型并移动到 GPU。# --- 数据准备 ---irisload_iris()X,yiris.data,iris.target X_train,X_test,y_train,y_testtrain_test_split(X,y,test_size0.2,random_state42)# 归一化scalerMinMaxScaler()X_trainscaler.fit_transform(X_train)X_testscaler.transform(X_test)# --- 关键将数据移动到 Device ---# .to(device) 会返回一个新的 Tensor如果是 GPU则在显存中X_traintorch.FloatTensor(X_train).to(device)y_traintorch.LongTensor(y_train).to(device)# 测试集也要移动否则预测时会报错X_testtorch.FloatTensor(X_test).to(device)y_testtorch.LongTensor(y_test).to(device)print(f数据设备检测:{X_train.device})# --- 模型定义 ---classMLP(nn.Module):def__init__(self):super(MLP,self).__init__()self.fc1nn.Linear(4,10)self.relunn.ReLU()self.fc2nn.Linear(10,3)defforward(self,x):outself.fc1(x)outself.relu(out)outself.fc2(out)returnout# --- 关键将模型移动到 Device ---# 这一步会将模型的权重矩阵Weights和偏置Biases全部搬到显存modelMLP().to(device)数据设备检测: cuda:0步骤 3性能陷阱与优化思考题如果你直接运行训练可能会发现 GPU 居然比 CPU 慢原因数据量太小Iris 数据集太小GPU 启动核心Kernel Launch的开销比计算本身还大。通信频繁如果在循环中频繁使用.item()或打印 Loss会强制 CPU 等待 GPU 计算完成并把数据传回来Sync打断了 GPU 的流水线。优化策略减少loss.item()的调用频率例如每 200 轮记录一次。任务编写训练循环测量时间并尝试减少记录频率来优化速度。# 定义损失和优化器criterionnn.CrossEntropyLoss()optimizeroptim.SGD(model.parameters(),lr0.01)num_epochs20000losses[]print(f\n⏱️ 开始训练 (Total Epochs:{num_epochs})...)start_timetime.time()forepochinrange(num_epochs):# 1. 前向传播outputsmodel(X_train)losscriterion(outputs,y_train)# 2. 反向传播optimizer.zero_grad()loss.backward()optimizer.step()# --- 性能优化关键点 ---# 不要每个 epoch 都调用 loss.item()这会触发 GPU-CPU 的同步if(epoch1)%2000:# 只有在需要打印/记录时才从 GPU 取回数据curr_lossloss.item()losses.append(curr_loss)if(epoch1)%50000:print(fEpoch [{epoch1}/{num_epochs}], Loss:{curr_loss:.4f})end_timetime.time()print(f✅ 训练完成耗时:{end_time-start_time:.4f}秒)# 可视化plt.plot(range(0,num_epochs,200),losses)plt.title(Training Loss)plt.show()⏱️ 开始训练 (Total Epochs: 20000)... Epoch [5000/20000], Loss: 0.1506 Epoch [10000/20000], Loss: 0.0841 Epoch [15000/20000], Loss: 0.0675 Epoch [20000/20000], Loss: 0.0606 ✅ 训练完成耗时: 18.5502 秒步骤 4解密 Python 的魔法方法__call__核心疑问为什么我们训练时写的是outputs model(X_train)而不是outputs model.forward(X_train)这得益于 Python 的__call__机制。当一个对象被当作函数调用时即后面加括号()Python 会自动去执行它的__call__方法。PyTorch 的设计nn.Module定义了__call__。在__call__内部它不仅调用了你写的forward()还负责处理Hooks (钩子)等底层逻辑。结论永远直接调用model(x)不要显式调用forward(x)。任务编写一个简单的Counter类实现__call__方法模拟这种行为。# --- 自定义一个可调用的类 --- class Counter: def __init__(self): self.count 0 print(1. 对象已初始化 (__init__)) # 只要实现了这个方法对象就能像函数一样被调用 def __call__(self, name): self.count 1 print(f2. 对象被调用了 (__call__) - Hello, {name}! (第 {self.count} 次)) return self.count print(\n--- 测试 __call__ ---) # 1. 实例化 c Counter() # 2. 像函数一样调用对象 # 这实际上是在执行 c.__call__(PyTorch) num c(PyTorch) c(GPU) c(Deep Learning) print(f最终计数: {c.count}) # 3. 验证 PyTorch 模型 print(\n--- 验证 PyTorch 模型 ---) print(fmodel 是否可调用? {callable(model)}) # model(X) 等价于 model.__call__(X) - 内部调用 forward(X)--- 测试 __call__ --- 1. 对象已初始化 (__init__) 2. 对象被调用了 (__call__) - Hello, PyTorch! (第 1 次) 2. 对象被调用了 (__call__) - Hello, GPU! (第 2 次) 2. 对象被调用了 (__call__) - Hello, Deep Learning! (第 3 次) 最终计数: 3 --- 验证 PyTorch 模型 --- model 是否可调用? True Day 34 总结硬核内功今天我们跨越了两个维度的障碍硬件维度学会了如何驾驭 GPU。虽然在 Iris 这种小数据上 GPU 甚至更慢但当你面对 ResNet 处理 ImageNet 图片时GPU 将比 CPU 快 10-100 倍。记住核心口诀模型和数据统统.to(device)。软件维度理解了__call__魔法。这是 PyTorch 优雅设计的基石也是 Python 面向对象编程的高级技巧。Next Level:现在我们有了更快的计算设备GPU也有了模型。接下来我们需要解决**“怎么保存模型”和“怎么加载别人训练好的模型”**的问题。明天见

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询