学习深度学习入门门槛!PyTorch真的不难,常见的用法就这么多!研一、一定要先看在学,理论和实践相结合!
PyTorch以其灵活性和强大的功能脱颖而出,成为研究者和开发者的首选工具。它不仅能够支持复杂神经网络的构建,还能在数据处理上展现出卓越的效率。本文将带你深入了解PyTorch的核心技巧,让你在构建、训练和优化神经网络模型的过程中游刃有余,同时掌握数据处理的高级技巧,以便将深度学习的理论快速转化为实际应用。
·
自我介绍:
您好,我们是一群热情洋溢的探索者,致力于深耕于知识图谱和大型语言模型(LLM)领域。我们的目标是挖掘、分析并分享那些能够启迪思维、推动科学进步的优质学术论文。我们坚信,知识的传播和交流是促进创新和社会发展的关键力量。
引言
PyTorch以其灵活性和强大的功能脱颖而出,成为研究者和开发者的首选工具。它不仅能够支持复杂神经网络的构建,还能在数据处理上展现出卓越的效率。本文将带你深入了解PyTorch的核心技巧,让你在构建、训练和优化神经网络模型的过程中游刃有余,同时掌握数据处理的高级技巧,以便将深度学习的理论快速转化为实际应用。
所有内容来源于:https://mp.weixin.qq.com/s/ydlzsZ3wuZt-0CRHeYy3GQ
一、导入Pytorch
# 导入PyTorch库,用于构建和训练神经网络
import torch
# 导入神经网络模块,用于定义神经网络结构
import torch.nn as nn
# 导入优化器模块,用于定义模型的优化算法
import torch.optim as optim
# 导入函数al模块,用于使用各种激活函数和损失函数
import torch.nn.functional as F
# 导入数据加载和数据集模块,用于处理和加载训练数据
from torch.utils.data import DataLoader, Dataset
# 导入变换模块,用于对图像数据进行预处理
from torchvision import transforms
二、检查 GPU 支持
# 根据环境选择合适的计算设备
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
三、创建自定义数据集:
class CustomDataset(Dataset):
"""
自定义数据集类,继承自torch.utils.data.Dataset。
用于封装任意数据和其对应的标签,方便在神经网络模型中使用。
参数:
- data: 数据集,可以是任意形式,如numpy数组或Pandas DataFrame。
- labels: 数据集的标签,通常是一个一维数组或列表。
- transform: 可选的数据转换函数,用于在获取数据项时对其进行转换。
"""
def __init__(self, data, labels, transform=None):
"""
初始化自定义数据集类。
"""
self.data = data
self.labels = labels
self.transform = transform
def __len__(self):
"""
返回数据集的大小。
返回:
- 数据集的样本数量。
"""
return len(self.data)
def __getitem__(self, index):
"""
根据索引获取数据项。
参数:
- index: 索引值,用于获取数据集中的特定样本。
返回:
- x: 数据项。
- y: 数据项的标签。
"""
x = self.data[index]
y = self.labels[index]
# 如果提供了数据转换函数,则应用该函数对数据项进行转换
if self.transform:
x = self.transform(x)
return x, y
四、使用数据增强:
# 定义一个转换器,用于将图像转换为一系列预处理步骤的组合
transform = transforms.Compose([
# 随机水平翻转图像,增加数据集的多样性
transforms.RandomHorizontalFlip(),
# 随机旋转图像,旋转角度在(-10, 10)之间,以增强模型的泛化能力
transforms.RandomRotation(10),
# 将图像转换为Tensor,以便于在PyTorch模型中使用
transforms.ToTensor(),
])
五、数据加载:
# 创建训练数据集实例
# 参数:
# - train_data: 训练数据输入
# - train_labels: 训练数据标签
# - transform: 数据转换函数
train_dataset = CustomDataset(train_data, train_labels, transform=transform)
# 创建数据加载器
# 参数:
# - train_dataset: 训练数据集实例
# - batch_size: 每个批次的数据大小
# - shuffle: 是否在每个epoch开始时打乱数据顺序
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
六、定义神经网络模型:
class Net(nn.Module):
"""
定义一个神经网络模型。继承自torch.nn.Module。
该模型包括一个卷积层和两个全连接层。
"""
def __init__(self):
"""
初始化模型并定义各层。
"""
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 32, kernel_size=3) # 卷积层:输入通道数1,输出通道数32,卷积核大小3x3
self.fc1 = nn.Linear(32 * 28 * 28, 128) # 全连接层:输入大小32*28*28,输出大小128
self.fc2 = nn.Linear(128, 10) # 全连接层:输入大小128,输出大小10
def forward(self, x):
"""
定义模型的前向传播过程。
:param x: 输入数据,一个张量
:return: 模型输出,一个张量
"""
x = F.relu(self.conv1(x)) # 经过卷积层后使用ReLU激活函数
x = x.view(x.size(0), -1) # 将张量展平
x = F.relu(self.fc1(x)) # 经过第一个全连接层后使用ReLU激活函数
x = self.fc2(x) # 第二个全连接层的输出,此处不使用激活函数
return x
七、实例化模型和优化器:
#实例化神经网络模型并转移到指定设备上
model = Net().to(device)
#初始化优化器,使用Adam算法优化模型参数
#学习率设置为0.001,以适应大多数深度学习模型的训练需求
optimizer = optim.Adam(model.parameters(), lr=0.001)
八、定义损失函数:
# 定义损失函数为交叉熵损失,用于分类任务中
criterion = nn.CrossEntropyLoss()
九、训练模型:
# 迭代训练模型,共进行num_epochs轮
for epoch in range(num_epochs):
# 遍历训练数据加载器,获取批次索引、数据和目标标签
for batch_idx, (data, target) in enumerate(train_loader):
# 将数据和目标标签移动到指定设备(如GPU)
data, target = data.to(device), target.to(device)
# 清空梯度,避免累积
optimizer.zero_grad()
# 前向传播,获取模型输出
output = model(data)
# 计算模型输出与目标标签之间的损失
loss = criterion(output, target)
# 反向传播,计算梯度
loss.backward()
# 更新模型权重
optimizer.step()
# 按照日志间隔打印训练信息
if batch_idx % log_interval == 0:
print(f"Train Epoch: {epoch} [{batch_idx * len(data)}/{len(train_loader.dataset)} ({100. * batch_idx / len(train_loader):.0f}%)]\tLoss: {loss.item():.6f}")
十、评估模型:
model.eval() # 将模型设置为评估模式,以禁用dropout等仅在训练时需要的特性
test_loss = 0 # 初始化测试损失为0
correct = 0 # 初始化正确预测的数量为0
with torch.no_grad(): # 在不需要计算梯度的上下文中进行评估,以减少内存消耗
for data, target in test_loader: # 遍历测试数据集
data, target = data.to(device), target.to(device) # 将数据和目标移动到指定设备
output = model(data) # 前向传播,获取模型的输出
test_loss += criterion(output, target).item() # 计算并累加测试损失
pred = output.argmax(dim=1, keepdim=True) # 获取预测的类别索引
correct += pred.eq(target.view_as(pred)).sum().item() # 计算并累加正确预测的数量
test_loss /= len(test_loader.dataset) # 计算平均测试损失
test_accuracy = 100. * correct / len(test_loader.dataset) # 计算测试准确率
# 打印测试集的平均损失和准确率
print(f'Test set: Average loss: {test_loss:.4f}, Accuracy: {correct}/{len(test_loader.dataset)} ({test_accuracy:.0f}%)')
十一、保存和加载模型:
# 保存模型的参数状态
torch.save(model.state_dict(), 'model.pth')
# 实例化一个新的模型对象
model = Net()
# 加载保存的模型参数状态到新的模型对象中
model.load_state_dict(torch.load('model.pth'))
# 将模型移动到指定的设备上,例如CPU或GPU
model.to(device)
十二、使用 GPU 加速:
# 将模型移动到指定设备上,以适应不同硬件环境(如GPU或CPU)
model = model.to(device)
# 将数据移动到指定设备上,确保数据与模型在同一硬件环境
data = data.to(device)
# 将目标值移动到指定设备上,保证目标与数据、模型一致
target = target.to(device)
十三、使用 TensorBoard 进行可视化:
from torch.utils.tensorboard import SummaryWriter
# 创建一个SummaryWriter对象,用于将训练过程中的损失和准确率等数据写入TensorBoard日志文件
writer = SummaryWriter()
# 遍历训练的每个周期(epoch)
for epoch in range(num_epochs):
# 进行训练和记录...
# 记录当前周期的训练损失
writer.add_scalar('Loss/train', loss.item(), epoch)
# 记录当前周期的训练准确率
writer.add_scalar('Accuracy/train', accuracy, epoch)
# ...
# 关闭SummaryWriter对象,确保所有数据被正确写入日志文件
writer.close()
十四、调整学习率:
# 初始化学习率调度器,以便在训练过程中按策略调整学习率
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)
# 开始训练过程,迭代指定的轮次
for epoch in range(num_epochs):
# 更新学习率调度器,根据当前轮次调整学习率
scheduler.step() # 更新学习率
# 进行训练...
十五、使用预训练模型:
# 导入torchvision中的models模块,用于访问预定义的模型架构和预训练模型
import torchvision.models as models
# 初始化一个预训练的ResNet-18模型
# ResNet-18是一个深度卷积神经网络,具有18层,广泛应用于图像分类任务中
# 参数pretrained=True表示使用ImageNet数据集预训练的模型权重
model = models.resnet18(pretrained=True)
十六、迁移学习:
# 遍历模型的所有参数
for param in model.parameters():
param.requires_grad = False # 冻结模型参数,防止在训练过程中更新这些参数
# 替换最后的全连接层以适应新的类别数
model.fc = nn.Linear(model.fc.in_features, num_classes)
PS:整理的PPT和资料稍后上传到公众号,直接回复论文名字,即可获取!
关注我们
欢迎大家关注我们的公众号,我们将会分享更多有关知识图谱和LLM方向的论文:

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)