【深度学习】PyTorch快速入门

news2024/12/22 23:58:37

【深度学习】学习PyTorch基础

image-20230812195050024

介绍PyTorch

深度学习框架是一种软件工具,旨在简化和加速构建、训练和部署深度学习模型的过程。深度学习框架提供了一系列的函数、类和工具,用于定义、优化和执行各种深度神经网络模型。这些框架帮助研究人员和开发人员专注于模型的设计和创新,而无需过多关注底层的数值计算和优化。

主要的深度学习框架通常具有以下特点:

  1. 图计算表示: 深度学习框架通常使用图计算来表示神经网络模型,其中节点表示操作,边表示数据流向。这种表示方式有助于优化计算和自动求导。
  2. 自动微分: 深度学习框架提供自动微分功能,允许用户计算模型中各个参数的梯度,从而进行反向传播和优化。
  3. 模块化设计: 框架允许用户将神经网络分解为模块,如层(层)、激活函数、优化器等,从而可以灵活地构建和修改模型。
  4. 优化器: 深度学习框架提供了多种优化算法,如随机梯度下降(SGD)、Adam 等,用于在训练过程中调整模型参数以最小化损失函数。
  5. 硬件加速: 多数深度学习框架支持使用图形处理单元(GPU)进行加速,这能够显著提升训练和推断性能。
  6. 预训练模型: 一些框架提供了预训练的模型,这些模型在大型数据集上进行了训练,可以用作迁移学习的起点。
  7. 部署和推断: 框架通常提供能够将训练好的模型部署到生产环境中的功能,以进行推断和应用。

常见的深度学习框架包括 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_grad=True)

# 执行一些操作
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_grad=True)

# 定义损失函数
loss_fn = torch.nn.MSELoss()

# 创建优化器,如随机梯度下降(SGD)
optimizer = optim.SGD([weights], lr=0.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_grad=True)

# 定义优化器,使用随机梯度下降(SGD)
optimizer = torch.optim.SGD([x], lr=0.1)

# 定义迭代次数
num_iterations = 1000

for 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 os

class CustomDataset(Dataset):
    def __init__(self, data_dir, transform=None):
        self.data_dir = data_dir
        self.transform = transform
        self.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, labels
    
    def __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)),  # 将图像缩放为 128x128
    transforms.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(root='path_to_dataset', transform=transform)

# 创建数据加载器
dataloader = DataLoader(dataset, batch_size=32, shuffle=True, num_workers=4)

在上面的示例中,我们首先定义了数据预处理的转换。然后,我们使用 datasets.ImageFolder 创建了一个图像数据集。接下来,我们使用 DataLoader 创建了一个数据加载器。参数解释如下:

  • dataset: 你想要加载的数据集。
  • batch_size: 每个批次包含的样本数量。
  • shuffle: 是否在每个 epoch 中随机化数据顺序。
  • num_workers: 加载数据时使用的线程数。

接下来,你可以通过迭代 dataloader 来获取每个批次的数据进行训练:

for batch_images, batch_labels in dataloader:
    # 在这里进行模型训练
    pass

在循环中,每个 batch_imagesbatch_labels 都是一个批次的图像和对应的标签。

DataLoader 类在实际训练中非常有用,可以帮助你有效地加载和处理数据,使训练过程更加高效。

构建神经网络

PyTorch 提供了多种方法来构建神经网络,以适应不同的需求和编程风格。

1.继承 nn.Module

这是创建自定义神经网络的常见方法。你可以创建一个类继承自 nn.Module,然后在构造函数中定义网络的层和参数,以及在 forward 方法中定义数据的前向传播过程。这种方法允许你自由地定义和组合各种层。

import torch
import torch.nn as nn

class CustomModel(nn.Module):
    def __init__(self):
        super(CustomModel, self).__init__()
        self.layer1 = nn.Linear(in_features=784, out_features=128)
        self.layer2 = nn.Linear(in_features=128, out_features=10)
    
    def forward(self, x):
        x = self.layer1(x)
        x = torch.relu(x)
        x = self.layer2(x)
        return x

2.使用 nn.Sequential

这是一种更简单的方法,适用于顺序层的堆叠。你可以使用 nn.Sequential 来创建一个网络,其中每个层按顺序连接。

import torch
import torch.nn as nn

model = nn.Sequential(
    nn.Linear(in_features=784, out_features=128),
    nn.ReLU(),
    nn.Linear(in_features=128, out_features=10)
)

3.自定义层

除了使用 nn.Module 创建网络,你还可以自定义层。你可以继承 nn.Module 并实现自己的层的前向传播。

import torch
import torch.nn as nn

class 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.bias

4.使用预训练模型

PyTorch 提供了许多预训练的模型,如 VGG、ResNet、BERT 等。你可以使用这些模型作为基础,进行微调或迁移学习。

import torch
import torchvision.models as models

model = models.resnet18(pretrained=True)
num_features = model.fc.in_features
model.fc = nn.Linear(num_features, 10)

训练神经网络模型

模型训练的主要步骤

在 PyTorch 中训练神经网络模型涉及到以下主要步骤:

  1. 选择网络架构: 首先,你需要选择适合你任务的神经网络架构。你可以使用 PyTorch 提供的预训练模型,也可以自定义网络。
  2. 定义损失函数: 根据你的问题类型,选择适当的损失函数,如均方误差(MSE)、交叉熵损失(CrossEntropyLoss)等。
  3. 选择优化器: 选择一个优化算法,如随机梯度下降(SGD)、Adam 等。你可以设置学习率和其他超参数。
  4. 数据加载: 使用 torch.utils.data.Datasettorch.utils.data.DataLoader 加载和处理训练数据。
  5. 训练循环: 在训练循环中,你需要进行以下操作:
    • 遍历数据加载器,获取输入数据和对应标签。
    • 将数据送入网络,得到预测结果。
    • 计算损失,反向传播计算梯度。
    • 使用优化器更新网络参数。
  6. 验证: 在训练过程中,你可以定期使用验证数据集评估模型性能,以避免过拟合。
  7. 保存和加载模型: 在训练完成后,你可以保存模型的权重和参数,以便在未来进行推断或继续训练。

以下是一个基本的训练循环示例:

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(root='data', train=True, transform=transform, download=True)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)

# 定义网络
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(), lr=0.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 损失函数:

  1. nn.MSELoss 均方误差损失函数,适用于回归问题。它计算预测值与真实值之间的平方差。

    criterion = nn.MSELoss()
    loss = criterion(predictions, targets)
    
  2. nn.CrossEntropyLoss 交叉熵损失函数,适用于多类别分类问题。通常用于分类问题的输出不经过 softmax 激活函数。

    criterion = nn.CrossEntropyLoss()
    loss = criterion(predictions, labels)
    
  3. nn.BCELossnn.BCEWithLogitsLoss 二元交叉熵损失函数,用于二元分类问题。BCELoss 需要在预测值上手动应用 sigmoid 函数,而 BCEWithLogitsLoss 同时包括 sigmoid 和交叉熵计算。

    criterion = nn.BCEWithLogitsLoss()
    loss = criterion(predictions, labels)
    
  4. nn.NLLLoss 负对数似然损失函数,通常与 nn.LogSoftmax 结合使用,适用于多类别分类问题。

    criterion = nn.NLLLoss()
    log_probs = nn.LogSoftmax(dim=1)(predictions)
    loss = criterion(log_probs, labels)
    
  5. 自定义损失函数: 你也可以根据任务的特性定义自己的损失函数,只需继承 nn.Module 并实现前向传播。

class CustomLoss(nn.Module):
   def __init__(self):
       super(CustomLoss, self).__init__()

   def forward(self, predictions, targets):
       # 自定义损失计算逻辑
       return loss_value

注意,选择正确的损失函数取决于任务的性质。不同的损失函数适用于不同的问题类型,你需要根据问题的特点来选择合适的损失函数。

优化器模块

在 PyTorch 中,优化器是用于更新神经网络模型参数以最小化损失函数的工具。PyTorch 提供了多种优化器,每个优化器都使用不同的更新规则来调整模型的参数,以使模型能够更好地拟合训练数据。以下是一些常见的 PyTorch 优化器:

  1. torch.optim.SGD 随机梯度下降(SGD)优化器是一种基本的优化算法。它在每次迭代中使用每个训练样本的梯度来更新模型参数。
import torch.optim as optim
optimizer = optim.SGD(model.parameters(), lr=learning_rate)
  1. torch.optim.Adam Adam 优化器结合了自适应学习率和动量的特点,适用于多种问题。它在许多情况下表现良好。
import torch.optim as optim
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
  1. torch.optim.RMSprop RMSprop 优化器使用移动平均的方式来调整学习率,适用于非平稳目标。
import torch.optim as optim
optimizer = optim.RMSprop(model.parameters(), lr=learning_rate)
  1. 自定义优化器: 你也可以根据需要定义自己的优化器,只需继承 torch.optim.Optimizer 并实现必要的方法。
class CustomOptimizer(optim.Optimizer):
	def __init__(self, params, lr=0.01):
		super(CustomOptimizer, self).__init__(params, defaults)
       	# 自定义初始化逻辑

   	def step(self, closure=None):
       # 自定义参数更新逻辑
       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手写数字数据集分类问题的过程涉及数据预处理,构建卷积层、池化层和全连接层的网络结构,定义损失函数和优化器进行模型训练,在训练集上通过梯度下降优化参数,最终在测试集上评估模型性能,以得出一个在数字分类上表现良好的卷积神经网络模型。

准备数据集
定义模型
定义损失函数和优化器
训练模型
测试模型
结束

下面是一个使用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(),  # 将图像转换为Tensor
    transforms.Normalize((0.5,), (0.5,))  # 标准化,将像素值映射到[-1, 1]
])

# 下载并加载MNIST数据集
train_dataset = torchvision.datasets.MNIST(root='./data', train=True, transform=transform, download=True)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=64, shuffle=True)

test_dataset = torchvision.datasets.MNIST(root='./data', train=False, transform=transform, download=True)
test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=64, shuffle=False)

步骤 3: 定义卷积神经网络模型

class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 16, kernel_size=3, padding=1)
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
        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(), lr=0.001)  # Adam优化器

步骤 5: 训练模型

num_epochs = 10

for 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 (i+1) % 100 == 0:
            print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {loss.item():.4f}')

步骤 6: 测试模型

model.eval()  # 将模型切换到评估模式
correct = 0
total = 0

with 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(f'Accuracy of the network on the 10000 test images: {100 * correct / total}%')

这个简单的卷积神经网络模型将会在MNIST数据集上实现一个基本的手写数字分类器。你可以根据需要进行更多的调整、优化和改进,例如增加更多的卷积层、调整超参数、添加正则化等来提升性能。

loss = criterion(outputs, labels)
loss.backward()
optimizer.step()

    if (i+1) % 100 == 0:
        print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {loss.item():.4f}')

步骤 6: 测试模型

```python
model.eval()  # 将模型切换到评估模式
correct = 0
total = 0

with 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(f'Accuracy of the network on the 10000 test images: {100 * correct / total}%')

这个简单的卷积神经网络模型将会在MNIST数据集上实现一个基本的手写数字分类器。你可以根据需要进行更多的调整、优化和改进,例如增加更多的卷积层、调整超参数、添加正则化等来提升性能。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Autoware感知02—欧氏聚类(lidar_euclidean_cluster_detect)源码解析

文章目录 引言一、点云回调函数:二、预处理(1)裁剪距离雷达过于近的点云,消除车身的影响(2)点云降采样(体素滤波,默认也是不需要的)(3)裁剪雷达高…

linux shell快速入门

linux shell快速入门 0 、前置1、简单使用 0 、前置 一安装linux的虚拟环境 1、简单使用 1、新建/usr/shell目录 2、新建hello.sh 文件 3、编写脚本文件# !/bin/bashecho "hello world"查看是否具备执行权限 新增执行权限 chomd x hello.sh执行hello.sh文件 /b…

AI大模型自动生成PowerPoint(PPT)

1,使用现有开源大模型工具,生成markdown语言文件(我这里使用chatGLM2-6B) eg,请用Markdown语言生成一个大纲,主题是:给小白用户的第一课,如何快速的学好Python markdown语言文本如下…

[C++ 网络协议编程] UDP协议

目录 1. UDP和TCP的区别 2. UDP的工作原理 3. UDP存在数据边界 4. UDP的I/O函数 4.1 sendto函数 4.2 recvfrom函数 4. 已连接(connected)UDP套接字和未连接(unconnected)UDP套接字 5. UDP的通信流程 5.1 服务器端通信流程 5.2 客户端通信流程 1. UDP和TCP的区别 主要…

电脑系统重装日记

重装原因 电脑C盘几乎爆炸故重装系统一清二白 此片原因 记录重装过程,强调一些要注意的点,以防日后重装。 重装过程 1.清空电脑文件后重启,电脑冒蓝光,一直蓝屏反复重启,故只能重装系统以解难题。 2.准备一个U盘&…

英语翻译,纯人工翻译哪里比较专业?

我们知道,人类语言是复杂的,给定的单词或短语含义会根据上下文内容和目标受众的不同而有所不同。机器翻译的准确率比较低。而专业的人工翻译是保持原文真实、原意的唯一保证。那么,针对英语翻译,如何做好人工翻译,北京…

app专项测试(网络测试流程)

目录 一、网络测试的一般流程 二、背景介绍 三、弱网功能测试 四、弱网UI测试 五、无网状态测试 六、网络切换测试 七、用户体验关注 八、响应时间 九、异常测试 一、网络测试的一般流程 step1:首先要考虑网络正常的情况 ① 各个模块的功能正常可用 ②…

(十八)大数据实战——Hive的metastore元数据服务安装

前言 Hive的metastore服务作用是为Hive CLI或者Hiveserver2提供元数据访问接口。Hive的metastore 是Hive元数据的存储和管理组件,它负责管理 Hive 表、分区、列等元数据信息。元数据是描述数据的数据,它包含了关于表结构、存储位置、数据类型等信息。本…

i18n 配置vue项目中英文语言包(中英文转化)

一、实现效果 二、下载插件创建文件夹 2.1 下载cookie来存储 npm install --save js-cookienpm i vue-i18n -S 2.2 封装组件多页面应用 2.3 创建配置语言包字段 三、示例代码 3.1 main.js 引用 i18n.js import i18n from ./lang// 实现语言切换:i18n处理element&#xff0c…

AI 绘画Stable Diffusion 研究(八)sd采样方法详解

大家好,我是风雨无阻。 本文适合人群: 希望了解stable Diffusion WebUI中提供的Sampler究竟有什么不同,想知道如何选用合适采样器以进一步提高出图质量的朋友。 想要进一步了解AI绘图基本原理的朋友。 对stable diffusion AI绘图感兴趣的朋…

使用QT可视化设计对话框详细步骤与代码

一、创建对话框基本步骤 创建并初始化子窗口部件把子窗口部件放到布局中设置tab键顺序建立信号-槽之间的连接实现对话框中的自定义槽 首先前面三步在这里是通过ui文件里面直接进行的,剩下两步则是通过代码来实现 二、项目创建详细步骤 创建新项目 为项目命名 为…

提高 After Effects 效率的 40 个最佳快捷键

After Effects 是运动图形和视觉效果的强大工具,但它也可能让人不知所措。拥有如此多的特性和功能,很容易让人迷失在软件中。但是,有一种方法可以简化您的工作流程并提高工作效率 - 使用键盘快捷键。 After Effects素材文件巨大、占用电脑内…

Makefile从入门到上手

文章目录 前言一、Makefile 介绍二、示例源码1、hello.c2、add.c3、sub.c4、mul.c5、div.c6、head.h 三、Makefile 基础规则1、一个规则2、两个函数和 clean①、2 个函数&#xff1a;②、clean 3、三个自动变量和模式规则①、三个自动变量②、模式规则<1>、模式规则<2…

ARM【day2】

思维导图&#xff1a; 作业1&#xff1a; 作业2&#xff1a;

每日一题——圆圈中最后剩下的数字(约瑟夫环问题)

圆圈中最后剩下的数字&#xff08;约瑟夫环问题&#xff09; 题目链接 约瑟夫环 这是一道典型的约瑟夫环问题&#xff0c;而约瑟夫问题的一般形式是这样的&#xff1a; 约瑟夫问题是个有名的问题&#xff1a;N个人围成一圈&#xff0c;从第一个开始报数&#xff0c;第M个将被…

目前最流行的GenAI框架、工具和服务初创公司一览表

目前最流行的GenAI框架、工具和服务初创公司一览表 框架与相关技术&#xff08;Frameworks & Technologies) LangChain BerriAl Outerbounds DUST Llamalndex Pinecone chroma{eature{orm LanceDB activeloop drant Baseplate beam agenta pyq Meru griptape BentoML pyq 数…

实验二十八、三角波发生电路参数的确认

一、题目 利用 Multisim 确定图1所示电路中各元件的参数&#xff0c;使输出电压的频率为 500 Hz 500\,\textrm{Hz} 500Hz、幅值为 6 V 6\,\textrm{V} 6V 的三角波。 图 1 三角波发生电路 图1\,\,三角波发生电路 图1三角波发生电路 2、仿真电路 A 1 \textrm A_1 A1​ 采用…

qtcreator编译报错cannot find -lGL

编译报错cannot find -lGL 是因为找不到openGL的库。 打开终端&#xff0c;输入”locate libGL.so”查找系统中是否有openGL的库&#xff0c;没有的话先安装&#xff0c;有的话可以看到&#xff1a; #locate libGL.so 或 #find / -name libGL.so 系统中存在openGL库&#xff0…

黑马项目一阶段面试 项目介绍篇

我完成了一个外卖项目&#xff0c;名叫苍穹外卖&#xff0c;是跟着黑马程序员的课程来自己动手写的。 项目基本实现了外卖客户端、商家端的后端完整业务。 商家端分为员工管理、文件上传、菜品管理、分类管理、套餐管理、店铺营业状态、订单下单派送等的管理、数据统计等&…

提升车间生产效率,这些做法很关键!

生产效率是制造生产企业的重要属性&#xff0c;对于影响生产效率的问题点&#xff0c;应当引起重视并规避&#xff0c;积极协调资源去改善&#xff0c;让企业能够有序、有章地运行。 一、影响生产效率的因素 1、产品加工工艺变更频繁 产品的加工工艺标准应在一段时间内不变…