做网站用什么版本系统,河南省建设信息网,广州市建设招标管理办公室网站,西部数码成品网站【深度学习】学习PyTorch基础 介绍PyTorch
深度学习框架是一种软件工具#xff0c;旨在简化和加速构建、训练和部署深度学习模型的过程。深度学习框架提供了一系列的函数、类和工具#xff0c;用于定义、优化和执行各种深度神经网络模型。这些框架帮助研究人员和开发人员专注…【深度学习】学习PyTorch基础 介绍PyTorch
深度学习框架是一种软件工具旨在简化和加速构建、训练和部署深度学习模型的过程。深度学习框架提供了一系列的函数、类和工具用于定义、优化和执行各种深度神经网络模型。这些框架帮助研究人员和开发人员专注于模型的设计和创新而无需过多关注底层的数值计算和优化。
主要的深度学习框架通常具有以下特点
图计算表示 深度学习框架通常使用图计算来表示神经网络模型其中节点表示操作边表示数据流向。这种表示方式有助于优化计算和自动求导。自动微分 深度学习框架提供自动微分功能允许用户计算模型中各个参数的梯度从而进行反向传播和优化。模块化设计 框架允许用户将神经网络分解为模块如层层、激活函数、优化器等从而可以灵活地构建和修改模型。优化器 深度学习框架提供了多种优化算法如随机梯度下降SGD、Adam 等用于在训练过程中调整模型参数以最小化损失函数。硬件加速 多数深度学习框架支持使用图形处理单元GPU进行加速这能够显著提升训练和推断性能。预训练模型 一些框架提供了预训练的模型这些模型在大型数据集上进行了训练可以用作迁移学习的起点。部署和推断 框架通常提供能够将训练好的模型部署到生产环境中的功能以进行推断和应用。
常见的深度学习框架包括 TensorFlow、PyTorch、Keras、Caffe、MXNet 等。
PyTorch 是一个备受欢迎的开源机器学习库由 Facebook 的人工智能研究小组开发并维护。它在深度学习领域中被广泛使用特别适合研究和开发新的神经网络模型以及进行实验和原型开发。其安装方式请参考官网教程。
张量操作
导入库
import torch创建张量
创建一个空的张量包含未初始化的随机值
empty_tensor torch.empty(3, 2) # 创建一个3行2列的空张量创建一个随机初始化的张量
random_tensor torch.rand(3, 2) # 创建一个3行2列的随机张量值在0到1之间创建一个全零的张量
zeros_tensor torch.zeros(3, 2) # 创建一个3行2列的全零张量创建一个全一的张量
ones_tensor torch.ones(3, 2) # 创建一个3行2列的全一张量从现有数据创建张量
data [[1, 2], [3, 4]]
tensor_from_data torch.tensor(data) # 从Python列表创建张量张量计算
tensor1 torch.tensor([[1, 2], [3, 4]])
tensor2 torch.tensor([[5, 6], [7, 8]])# 加法
result_add tensor1 tensor2
# tensor([[ 6, 8],
# [10, 12]])# 减法
result_sub tensor1 - tensor2
# tensor([[-4, -4],
# [-4, -4]])# 乘法逐元素相乘
result_mul tensor1 * tensor2
# tensor([[ 5, 12],
# [21, 32]])# 矩阵乘法
result_matmul torch.matmul(tensor1, tensor2)
# tensor([[19, 22],
# [43, 50]])张量索引和切片
tensor torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# 获取单个元素
element tensor[1, 2] # 获取第2行第3列的元素注意索引从0开始
# tensor(6)# 切片操作
slice tensor[0:2, 1:3] # 获取第1行和第2行第2列和第3列的切片
# tensor([[2, 3],
# [0, 6]])# 修改元素
tensor[1, 1] 0 # 将第2行第2列的元素设置为0
# tensor([[1, 2, 3],
# [4, 0, 6],
# [7, 8, 9]])张量形状操作
tensor torch.tensor([[1, 2, 3], [4, 5, 6]])# 获取张量的形状
shape tensor.shape # 返回一个元组表示张量的形状
# torch.Size([2, 3])# 改变张量的形状
reshaped_tensor tensor.view(3, 2) # 将原来的2行3列张量转换为3行2列
# tensor([[1, 2],
# [3, 4],
# [5, 6]])自动微分
PyTorch 的自动微分Automatic Differentiation是其在深度学习中的一大亮点它使得构建和训练神经网络变得更加便捷。自动微分允许你计算函数的导数特别适用于反向传播算法它是训练神经网络的核心。
梯度计算和反向传播
在 PyTorch 中你可以在需要求导的张量上调用 .requires_grad_() 方法将其标记为需要计算梯度。之后所有在这个张量上执行的操作都会被记录以便后续计算梯度。
import torch# 创建一个张量并标记为需要计算梯度
x torch.tensor([2.0], requires_gradTrue)# 执行一些操作
y x**2 3*x 1# 计算 y 对 x 的梯度
y.backward()# 输出梯度
print(x.grad) # 输出tensor([7.])即 y x**2 3*x 1 对 x 的导数在上述示例中我们创建了一个张量 x并标记它需要计算梯度。然后我们执行一些操作来计算 y并使用 y.backward() 计算关于 x 的梯度。最终我们使用 x.grad 获取梯度值。
上下文管理器 torch.no_grad()
有时候在进行推断不需要梯度计算时你可以使用 torch.no_grad() 上下文管理器从而避免不必要的梯度计算提高性能。
with torch.no_grad():# 在这个上下文中所有操作都不会计算梯度# 适用于不需要反向传播的情况如模型推断pass使用自动微分进行优化
自动微分在优化算法中的应用非常广泛。你可以使用优化器来自动地更新模型参数以最小化损失函数。
import torch.optim as optim# 创建一个需要优化的张量
weights torch.tensor([1.0], requires_gradTrue)# 定义损失函数
loss_fn torch.nn.MSELoss()# 创建优化器如随机梯度下降SGD
optimizer optim.SGD([weights], lr0.01)# 进行多轮优化
for _ in range(100):optimizer.zero_grad() # 清零梯度predictions weights * 3 # 假设的模型预测loss loss_fn(predictions, torch.tensor([10.0])) # 计算损失loss.backward() # 计算梯度optimizer.step() # 更新参数在上面的示例中我们首先创建了一个需要优化的权重张量并定义了损失函数和优化器。在每轮循环中我们将梯度清零计算预测计算损失然后通过调用 backward() 计算梯度。最后使用 optimizer.step() 来更新权重。
总之PyTorch 的自动微分使得计算梯度变得非常简便为神经网络的训练和优化提供了强大的支持。
利用自动微分梯度下降案例
首先需要计算函数关于自变量的梯度然后迭代更新自变量以逐步逼近最小值。
import torch
import math# 初始化自变量 x
x torch.tensor([0.0], requires_gradTrue)# 定义优化器使用随机梯度下降SGD
optimizer torch.optim.SGD([x], lr0.1)# 定义迭代次数
num_iterations 1000for i in range(num_iterations):optimizer.zero_grad() # 清零梯度y x**2 - torch.sin(x) # 定义函数 y x^2 - sin(x)y.backward() # 计算梯度optimizer.step() # 更新 x# 最终的 x 就是函数的最小值点
minimum x.item()# 计算最小值对应的 y
minimum_value minimum**2 - math.sin(minimum)print(f最小值点x {minimum:.4f}, y {minimum_value:.4f})
# 最小值点x 0.4502, y -0.2325在上述代码中我们首先初始化自变量 x并使用 SGD 优化器进行梯度下降。在每次迭代中我们计算函数值 y然后通过调用 backward() 计算梯度并使用 optimizer.step() 更新自变量 x。最终我们可以得到函数的最小值点和对应的最小值。
数据加载和预处理
数据加载
首先你需要将原始数据加载到内存中。数据可以是图像、文本、音频等类型。PyTorch 提供了 torch.utils.data.Dataset 类来帮助你自定义数据集。
torch.utils.data.Dataset 类 这个类是一个抽象类你可以通过继承它来创建自定义数据集。你需要实现 __len__ 方法和 __getitem__ 方法分别用于获取数据集大小和获取单个样本。
假设你有一组包含图像文件和对应标签的数据你可以按照以下步骤创建一个自定义的数据集类
import torch
from torch.utils.data import Dataset
from PIL import Image # 用于图像读取
import osclass CustomDataset(Dataset):def __init__(self, data_dir, transformNone):self.data_dir data_dirself.transform transformself.images, self.labels self.load_data()def load_data(self):# 获取图像文件列表和标签image_list sorted(os.listdir(os.path.join(self.data_dir, images)))label_list sorted(os.listdir(os.path.join(self.data_dir, labels)))images [os.path.join(self.data_dir, images, img) for img in image_list]labels [os.path.join(self.data_dir, labels, lbl) for lbl in label_list]return images, labelsdef __len__(self):return len(self.images)def __getitem__(self, idx):img_path self.images[idx]lbl_path self.labels[idx]image Image.open(img_path)label torch.load(lbl_path)if self.transform:image self.transform(image)return image, label数据预处理
一般来说原始数据需要经过一些预处理才能被用于模型训练。预处理可能包括图像缩放、剪裁、标准化、数据增强等。PyTorch 提供了各种转换函数可以在加载数据时对其进行预处理。
torchvision.transforms 模块 这个模块提供了许多用于图像预处理的函数比如图像缩放、剪裁、翻转、标准化等。你可以将这些函数应用于数据集的样本。
import torch
from torchvision import transforms
from PIL import Image# 定义数据预处理的转换
transform transforms.Compose([transforms.Resize((128, 128)), # 将图像缩放为 128x128transforms.RandomHorizontalFlip(), # 随机水平翻转transforms.ToTensor(), # 将图像转换为张量transforms.Normalize(mean[0.5, 0.5, 0.5], std[0.5, 0.5, 0.5]) # 标准化
])# 读取图像
image Image.open(path_to_image.jpg)# 应用预处理转换
transformed_image transform(image)在上面的代码示例中我们首先导入了 transforms 模块。然后我们定义了一个数据预处理的转换序列其中包括了图像缩放、随机水平翻转、转换为张量和标准化。接着我们使用 Image.open 从文件中读取了一个图像然后使用 transform 对图像进行预处理。
你可以根据需要组合不同的预处理操作以适应你的任务和数据集。torchvision.transforms 模块提供了多种函数如图像剪裁、色彩变换、随机增强等可以在数据加载前对图像进行灵活的处理。
数据加载器
为了高效地训练模型你可以使用 torch.utils.data.DataLoader 类它可以将预处理后的数据划分为小批次进行随机或顺序加载同时还可以提供多线程加载。
torch.utils.data.DataLoader 类 这个类将数据集包装成一个可迭代的对象每次返回一个小批次的数据。你可以设置批次大小、随机化、多线程等参数。
以下是一些 DataLoader 的常见参数和用法
pythonCopy codeimport torch
from torch.utils.data import DataLoader
from torchvision import datasets, transforms# 定义数据预处理的转换
transform transforms.Compose([transforms.Resize((128, 128)),transforms.ToTensor(),transforms.Normalize(mean[0.5, 0.5, 0.5], std[0.5, 0.5, 0.5])
])# 创建数据集
dataset datasets.ImageFolder(rootpath_to_dataset, transformtransform)# 创建数据加载器
dataloader DataLoader(dataset, batch_size32, shuffleTrue, num_workers4)在上面的示例中我们首先定义了数据预处理的转换。然后我们使用 datasets.ImageFolder 创建了一个图像数据集。接下来我们使用 DataLoader 创建了一个数据加载器。参数解释如下
dataset: 你想要加载的数据集。batch_size: 每个批次包含的样本数量。shuffle: 是否在每个 epoch 中随机化数据顺序。num_workers: 加载数据时使用的线程数。
接下来你可以通过迭代 dataloader 来获取每个批次的数据进行训练
for batch_images, batch_labels in dataloader:# 在这里进行模型训练pass在循环中每个 batch_images 和 batch_labels 都是一个批次的图像和对应的标签。
DataLoader 类在实际训练中非常有用可以帮助你有效地加载和处理数据使训练过程更加高效。
构建神经网络
PyTorch 提供了多种方法来构建神经网络以适应不同的需求和编程风格。
1.继承 nn.Module
这是创建自定义神经网络的常见方法。你可以创建一个类继承自 nn.Module然后在构造函数中定义网络的层和参数以及在 forward 方法中定义数据的前向传播过程。这种方法允许你自由地定义和组合各种层。
import torch
import torch.nn as nnclass CustomModel(nn.Module):def __init__(self):super(CustomModel, self).__init__()self.layer1 nn.Linear(in_features784, out_features128)self.layer2 nn.Linear(in_features128, out_features10)def forward(self, x):x self.layer1(x)x torch.relu(x)x self.layer2(x)return x2.使用 nn.Sequential
这是一种更简单的方法适用于顺序层的堆叠。你可以使用 nn.Sequential 来创建一个网络其中每个层按顺序连接。
import torch
import torch.nn as nnmodel nn.Sequential(nn.Linear(in_features784, out_features128),nn.ReLU(),nn.Linear(in_features128, out_features10)
)3.自定义层
除了使用 nn.Module 创建网络你还可以自定义层。你可以继承 nn.Module 并实现自己的层的前向传播。
import torch
import torch.nn as nnclass CustomLayer(nn.Module):def __init__(self, in_features, out_features):super(CustomLayer, self).__init__()self.weights nn.Parameter(torch.randn(in_features, out_features))self.bias nn.Parameter(torch.randn(out_features))def forward(self, x):return torch.matmul(x, self.weights) self.bias4.使用预训练模型
PyTorch 提供了许多预训练的模型如 VGG、ResNet、BERT 等。你可以使用这些模型作为基础进行微调或迁移学习。
import torch
import torchvision.models as modelsmodel models.resnet18(pretrainedTrue)
num_features model.fc.in_features
model.fc nn.Linear(num_features, 10)训练神经网络模型
模型训练的主要步骤
在 PyTorch 中训练神经网络模型涉及到以下主要步骤
选择网络架构 首先你需要选择适合你任务的神经网络架构。你可以使用 PyTorch 提供的预训练模型也可以自定义网络。定义损失函数 根据你的问题类型选择适当的损失函数如均方误差MSE、交叉熵损失CrossEntropyLoss等。选择优化器 选择一个优化算法如随机梯度下降SGD、Adam 等。你可以设置学习率和其他超参数。数据加载 使用 torch.utils.data.Dataset 和 torch.utils.data.DataLoader 加载和处理训练数据。训练循环 在训练循环中你需要进行以下操作 遍历数据加载器获取输入数据和对应标签。将数据送入网络得到预测结果。计算损失反向传播计算梯度。使用优化器更新网络参数。 验证 在训练过程中你可以定期使用验证数据集评估模型性能以避免过拟合。保存和加载模型 在训练完成后你可以保存模型的权重和参数以便在未来进行推断或继续训练。
以下是一个基本的训练循环示例
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms# 数据预处理和加载
transform transforms.Compose([transforms.ToTensor(),transforms.Normalize(mean[0.5, 0.5, 0.5], std[0.5, 0.5, 0.5])
])
train_dataset datasets.CIFAR10(rootdata, trainTrue, transformtransform, downloadTrue)
train_loader DataLoader(train_dataset, batch_size64, shuffleTrue)# 定义网络
class CustomModel(nn.Module):def __init__(self):super(CustomModel, self).__init__()# 定义网络结构# ...def forward(self, x):# 前向传播# ...model CustomModel()# 定义损失函数和优化器
criterion nn.CrossEntropyLoss()
optimizer optim.SGD(model.parameters(), lr0.01)# 训练循环
for epoch in range(num_epochs):for inputs, labels in train_loader:optimizer.zero_grad() # 清零梯度outputs model(inputs) # 前向传播loss criterion(outputs, labels) # 计算损失loss.backward() # 反向传播optimizer.step() # 更新参数# 在每个 epoch 结束后可以进行验证、保存模型等操作损失函数模块
在 PyTorch 中损失函数也称为目标函数用于度量模型预测与实际标签之间的差异。它是模型训练的关键部分通过优化损失函数来调整模型的参数使得模型的预测更加接近真实值。PyTorch 提供了许多常见的损失函数适用于不同类型的任务。
以下是一些常见的 PyTorch 损失函数 nn.MSELoss 均方误差损失函数适用于回归问题。它计算预测值与真实值之间的平方差。 criterion nn.MSELoss()
loss criterion(predictions, targets)nn.CrossEntropyLoss 交叉熵损失函数适用于多类别分类问题。通常用于分类问题的输出不经过 softmax 激活函数。 criterion nn.CrossEntropyLoss()
loss criterion(predictions, labels)nn.BCELoss 和 nn.BCEWithLogitsLoss 二元交叉熵损失函数用于二元分类问题。BCELoss 需要在预测值上手动应用 sigmoid 函数而 BCEWithLogitsLoss 同时包括 sigmoid 和交叉熵计算。 criterion nn.BCEWithLogitsLoss()
loss criterion(predictions, labels)nn.NLLLoss 负对数似然损失函数通常与 nn.LogSoftmax 结合使用适用于多类别分类问题。 criterion nn.NLLLoss()
log_probs nn.LogSoftmax(dim1)(predictions)
loss criterion(log_probs, labels)自定义损失函数 你也可以根据任务的特性定义自己的损失函数只需继承 nn.Module 并实现前向传播。
class CustomLoss(nn.Module):def __init__(self):super(CustomLoss, self).__init__()def forward(self, predictions, targets):# 自定义损失计算逻辑return loss_value注意选择正确的损失函数取决于任务的性质。不同的损失函数适用于不同的问题类型你需要根据问题的特点来选择合适的损失函数。
优化器模块
在 PyTorch 中优化器是用于更新神经网络模型参数以最小化损失函数的工具。PyTorch 提供了多种优化器每个优化器都使用不同的更新规则来调整模型的参数以使模型能够更好地拟合训练数据。以下是一些常见的 PyTorch 优化器
torch.optim.SGD 随机梯度下降SGD优化器是一种基本的优化算法。它在每次迭代中使用每个训练样本的梯度来更新模型参数。
import torch.optim as optim
optimizer optim.SGD(model.parameters(), lrlearning_rate)torch.optim.Adam Adam 优化器结合了自适应学习率和动量的特点适用于多种问题。它在许多情况下表现良好。
import torch.optim as optim
optimizer optim.Adam(model.parameters(), lrlearning_rate)torch.optim.RMSprop RMSprop 优化器使用移动平均的方式来调整学习率适用于非平稳目标。
import torch.optim as optim
optimizer optim.RMSprop(model.parameters(), lrlearning_rate)自定义优化器 你也可以根据需要定义自己的优化器只需继承 torch.optim.Optimizer 并实现必要的方法。
class CustomOptimizer(optim.Optimizer):def __init__(self, params, lr0.01):super(CustomOptimizer, self).__init__(params, defaults)# 自定义初始化逻辑def step(self, closureNone):# 自定义参数更新逻辑pass在训练循环中你需要执行以下操作来更新模型参数
optimizer.zero_grad() # 清零梯度
outputs model(inputs) # 前向传播
loss criterion(outputs, labels) # 计算损失
loss.backward() # 反向传播计算梯度
optimizer.step() # 更新参数在实际应用中选择正确的优化器取决于问题的性质不同的优化器可能会在不同的任务中表现更好。
保存和加载模型
在 PyTorch 中你可以使用 torch.save 函数来保存模型的权重、参数和其他相关信息以及使用 torch.load 函数来加载保存的模型。以下是保存和加载模型的示例代码
保存模型
import torch# 定义模型
class CustomModel(torch.nn.Module):def __init__(self):super(CustomModel, self).__init__()self.fc torch.nn.Linear(10, 2)def forward(self, x):return self.fc(x)model CustomModel()# 保存模型权重和参数
torch.save(model.state_dict(), model.pth)在上面的代码中我们定义了一个简单的模型 CustomModel然后使用 model.state_dict() 将模型的权重和参数保存到文件 model.pth 中。
加载模型
import torch# 定义模型
class CustomModel(torch.nn.Module):def __init__(self):super(CustomModel, self).__init__()self.fc torch.nn.Linear(10, 2)def forward(self, x):return self.fc(x)model CustomModel()# 加载模型权重和参数
model.load_state_dict(torch.load(model.pth))
model.eval() # 设置模型为评估模式在上面的代码中我们定义了相同的模型结构 CustomModel然后使用 torch.load 加载之前保存的权重和参数文件 model.pth。注意加载后的模型需要调用 .eval() 方法来将模型设置为评估模式以便在推断时使用。
请注意当你加载模型时模型的结构也需要保持一致。如果你的模型结构发生了变化可能需要手动调整或者重新定义模型的结构。
完整项目案例
MNIST数据集是一个经典的手写数字图像数据集包含了大量0到9的单个手写数字图像样本每个图像都有对应的标签表示其所代表的数字。这个数据集广泛用于测试和验证机器学习算法特别是图像分类算法的性能。每个图像都是28x28像素大小的灰度图像被展平成一维向量使其适用于各种机器学习模型。
使用卷积神经网络CNN来解决MNIST手写数字数据集分类问题的过程涉及数据预处理构建卷积层、池化层和全连接层的网络结构定义损失函数和优化器进行模型训练在训练集上通过梯度下降优化参数最终在测试集上评估模型性能以得出一个在数字分类上表现良好的卷积神经网络模型。 #mermaid-svg-pzXRfVMwgIef1Dfn {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-pzXRfVMwgIef1Dfn .error-icon{fill:#552222;}#mermaid-svg-pzXRfVMwgIef1Dfn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-pzXRfVMwgIef1Dfn .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-pzXRfVMwgIef1Dfn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-pzXRfVMwgIef1Dfn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-pzXRfVMwgIef1Dfn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-pzXRfVMwgIef1Dfn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-pzXRfVMwgIef1Dfn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-pzXRfVMwgIef1Dfn .marker.cross{stroke:#333333;}#mermaid-svg-pzXRfVMwgIef1Dfn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-pzXRfVMwgIef1Dfn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-pzXRfVMwgIef1Dfn .cluster-label text{fill:#333;}#mermaid-svg-pzXRfVMwgIef1Dfn .cluster-label span{color:#333;}#mermaid-svg-pzXRfVMwgIef1Dfn .label text,#mermaid-svg-pzXRfVMwgIef1Dfn span{fill:#333;color:#333;}#mermaid-svg-pzXRfVMwgIef1Dfn .node rect,#mermaid-svg-pzXRfVMwgIef1Dfn .node circle,#mermaid-svg-pzXRfVMwgIef1Dfn .node ellipse,#mermaid-svg-pzXRfVMwgIef1Dfn .node polygon,#mermaid-svg-pzXRfVMwgIef1Dfn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-pzXRfVMwgIef1Dfn .node .label{text-align:center;}#mermaid-svg-pzXRfVMwgIef1Dfn .node.clickable{cursor:pointer;}#mermaid-svg-pzXRfVMwgIef1Dfn .arrowheadPath{fill:#333333;}#mermaid-svg-pzXRfVMwgIef1Dfn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-pzXRfVMwgIef1Dfn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-pzXRfVMwgIef1Dfn .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-pzXRfVMwgIef1Dfn .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-pzXRfVMwgIef1Dfn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-pzXRfVMwgIef1Dfn .cluster text{fill:#333;}#mermaid-svg-pzXRfVMwgIef1Dfn .cluster span{color:#333;}#mermaid-svg-pzXRfVMwgIef1Dfn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-pzXRfVMwgIef1Dfn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 准备数据集 定义模型 定义损失函数和优化器 训练模型 测试模型 结束 下面是一个使用PyTorch的简单卷积神经网络CNN模型来解决MNIST手写数字数据集分类问题的基本步骤
步骤 1: 导入必要的库和模块
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms步骤 2: 准备数据集
# 定义数据预处理的转换
transform transforms.Compose([transforms.ToTensor(), # 将图像转换为Tensortransforms.Normalize((0.5,), (0.5,)) # 标准化将像素值映射到[-1, 1]
])# 下载并加载MNIST数据集
train_dataset torchvision.datasets.MNIST(root./data, trainTrue, transformtransform, downloadTrue)
train_loader torch.utils.data.DataLoader(datasettrain_dataset, batch_size64, shuffleTrue)test_dataset torchvision.datasets.MNIST(root./data, trainFalse, transformtransform, downloadTrue)
test_loader torch.utils.data.DataLoader(datasettest_dataset, batch_size64, shuffleFalse)步骤 3: 定义卷积神经网络模型
class SimpleCNN(nn.Module):def __init__(self):super(SimpleCNN, self).__init__()self.conv1 nn.Conv2d(1, 16, kernel_size3, padding1)self.pool nn.MaxPool2d(kernel_size2, stride2)self.fc1 nn.Linear(16 * 14 * 14, 128)self.fc2 nn.Linear(128, 10)def forward(self, x):x self.pool(nn.functional.relu(self.conv1(x)))x x.view(-1, 16 * 14 * 14)x nn.functional.relu(self.fc1(x))x self.fc2(x)return x# 创建模型实例
model SimpleCNN()步骤 4: 定义损失函数和优化器
criterion nn.CrossEntropyLoss() # 交叉熵损失函数
optimizer optim.Adam(model.parameters(), lr0.001) # Adam优化器步骤 5: 训练模型
num_epochs 10for epoch in range(num_epochs):for i, (images, labels) in enumerate(train_loader):optimizer.zero_grad() # 梯度清零outputs model(images)loss criterion(outputs, labels)loss.backward()optimizer.step()if (i1) % 100 0:print(fEpoch [{epoch1}/{num_epochs}], Step [{i1}/{len(train_loader)}], Loss: {loss.item():.4f})步骤 6: 测试模型
model.eval() # 将模型切换到评估模式
correct 0
total 0with torch.no_grad():for images, labels in test_loader:outputs model(images)_, predicted torch.max(outputs.data, 1)total labels.size(0)correct (predicted labels).sum().item()print(fAccuracy of the network on the 10000 test images: {100 * correct / total}%)这个简单的卷积神经网络模型将会在MNIST数据集上实现一个基本的手写数字分类器。你可以根据需要进行更多的调整、优化和改进例如增加更多的卷积层、调整超参数、添加正则化等来提升性能。
loss criterion(outputs, labels) loss.backward() optimizer.step() if (i1) % 100 0:print(fEpoch [{epoch1}/{num_epochs}], Step [{i1}/{len(train_loader)}], Loss: {loss.item():.4f})步骤 6: 测试模型python
model.eval() # 将模型切换到评估模式
correct 0
total 0with torch.no_grad():for images, labels in test_loader:outputs model(images)_, predicted torch.max(outputs.data, 1)total labels.size(0)correct (predicted labels).sum().item()print(fAccuracy of the network on the 10000 test images: {100 * correct / total}%)这个简单的卷积神经网络模型将会在MNIST数据集上实现一个基本的手写数字分类器。你可以根据需要进行更多的调整、优化和改进例如增加更多的卷积层、调整超参数、添加正则化等来提升性能。