文章目录

一、张量创建和基本操作

1. 张量的创建

2. 张量的基本操作

二、自动求导

1. 张量的 requires_grad 属性

2. 张量操作和计算图

3. 计算梯度

4. 防止梯度追踪

5. 使用 with torch.autograd.set_grad_enabled(False): 控制梯度计算

6. 示例:使用自动求导进行优化

三、神经网络层

1. 创建一个简单的神经网络层

2. 构建更复杂的模型

3. 模块的嵌套和子模块

4. 访问模块的参数

5. 模型的保存和加载

6. 模型的设备移动

7. 自定义层和操作

四、优化器

1. SGD 优化器

2. Adam 优化器

3. RMSprop 优化器

4. 设置学习率

5. 梯度清零

6. 梯度更新

7. 动态调整学习率

8. 自定义优化器

五、损失函数

1. 均方误差损失(Mean Squared Error,MSE)

2. 交叉熵损失(Cross-Entropy Loss)

3. 二元交叉熵损失(Binary Cross-Entropy Loss)

4. 二元交叉熵损失(带权重)

5. K-L 散度损失(Kullback-Leibler Divergence Loss)

6. 三元组损失(Triplet Margin Loss)

7. 自定义损失函数

8. 使用损失函数进行训练


一、张量创建和基本操作

张量类似于 Numpy 的数组,但具有额外的功能,如自动求导(automatic differentiation)和 GPU加速。

张量创建和基本操作:

        ① 张量的创建

        ② 张量的基本操作

下面是在 PyTorch 中创建张量和进行基本操作的详细介绍。

1. 张量的创建

从 PyTorch 列表或 NumPy 数组创建张量:

import torch
import numpy as np

# 从列表创建张量
tensor_from_list = torch.tensor([1, 2, 3])

# 从 NumPy 数组创建张量
numpy_array = np.array([4, 5, 6])
tensor_from_numpy = torch.tensor(numpy_array)

使用特定值创建张量:

# 创建全零张量
zeros_tensor = torch.zeros((3, 4))

# 创建全一张量
ones_tensor = torch.ones((2, 2))

# 创建指定范围的张量
range_tensor = torch.arange(0, 10, 2)

# 创建均匀分布的张量
uniform_tensor = torch.rand((3, 3))

# 创建正态分布的张量
normal_tensor = torch.randn((2, 2))

使用特定形状的张量:

# 创建未初始化的张量
uninitialized_tensor = torch.empty((2, 2))

# 创建与现有张量相同形状的张量
like_tensor = torch.ones_like(zeros_tensor)

2. 张量的基本操作

索引和切片:

# 获取张量中的特定元素
element = tensor_from_list[1]

# 切片操作
sliced_tensor = tensor_from_list[1:3]

张量的形状操作:

# 获取张量的形状
shape = tensor_from_list.shape

# 改变张量的形状
reshaped_tensor = tensor_from_list.view(1, 3)

# 转置张量
transposed_tensor = tensor_from_list.t()

数学运算:

# 加法
sum_tensor = tensor_from_list + tensor_from_numpy

# 乘法
product_tensor = torch.matmul(zeros_tensor, ones_tensor)

# 广播操作
broadcasted_tensor = tensor_from_list * 2

这些功能使得 PyTorch 成为深度学习领域的一流选择,因为它提供了方便、灵活且高效的工具来处理张量和构建神经网络模型。

二、自动求导

PyTorch 中的自动求导(Autograd)允许用户自动计算张量的梯度,而无需手动编写反向传播算法。

Autograd的核心计算是计算图(computational graph),它记录了计算张量的操作,并在需要时能够生成梯度。

自动求导:

        ① 张量的 requires_grad 属性

        ② 张量操作和计算图

        ③ 计算梯度

        ④ 阻止梯度追踪

        ⑤ 使用 with torch.autograd.set_grad_enabled(False): 控制梯度计算

        ⑥ 示例:使用自动求导进行优化

1. 张量的 requires_grad 属性

在创建张量时,可以通过设置 requires_grad 属性为 True 来指示 PyTorch 跟踪该张量的操作,从而构建计算图。

import torch

# 创建一个需要梯度的张量
x = torch.tensor([1.0, 2.0], requires_grad=True)

2. 张量操作和计算图

一旦设置了 requires_grad = True ,PyTorch 将自动追踪对该张量的所有操作,构建一个计算图。这个计算图记录了张量之间的关系和操作。

y = x + 2
z = y * y * 3
out = z.mean()

上述例子中,y、z 和 out 都是通过对 x 进行操作得到的新张量,这些操作构成了计算图。

3. 计算梯度

一旦有了计算图,可以调用 backward() 方法计算梯度。梯度计算完成后,可以通过张量的 grad 属性获取梯度值。

out.backward()  # 计算梯度

# 获取梯度
print(x.grad)

4. 防止梯度追踪

在某些情况下,可能需要阻止 PyTorch 对某些操作的梯度追踪,可以使用 torch.no_grad() 上下文管理器或者在张量上使用 .detach() 方法。

with torch.no_grad():
    # 不追踪梯度的操作
    y = x + 2

# 或者
z = y.detach()

5. 使用 with torch.autograd.set_grad_enabled(False): 控制梯度计算

在某些情况下,可能需要在一段代码中关闭梯度计算,可以使用上下文管理器 torch.autograd.set_grad_enabled。

with torch.autograd.set_grad_enabled(False):
    # 在此处的操作不会被追踪,也不会计算梯度
    y = x + 2

6. 示例:使用自动求导进行优化

import torch.optim as optim

# 定义一个变量并设置需要梯度
x = torch.tensor([1.0, 2.0], requires_grad=True)

# 定义一个优化器(例如梯度下降)
optimizer = optim.SGD([x], lr=0.01)

# 在循环中执行优化步骤
for _ in range(100):
    y = x + 2
    loss = y[0] * y[1]  # 这里定义了一个简单的损失函数

    optimizer.zero_grad()  # 清零梯度
    loss.backward()  # 计算梯度
    optimizer.step()  # 更新参数

# 查看优化后的结果
print(x)

这个例子演示了如何使用自动求导来执行优化步骤,通过反向传播计算梯度并使用优化器更新参数。

总体而言,PyTorch 中的自动求导提供了一个方便的工具,使得深度学习的模型训练变得更加简单和高效。

三、神经网络层

在 PyTorch 中,nn.Module 是构建神经网络模型的基础类。nn.Module 提供了一个模块化和灵活的方式来组织复杂的神经网络结构。通过继承 nn.Module 类,可以创建自定义的神经网络层、模型或整个神经网络。

神经网络层(nn.Module):

        ① 创建一个简单的神经网络层

        ② 构建更复杂的模型

        ③ 模块的嵌套和子模块

        ④ 访问模块的参数

        ⑤ 模型的保存和加载

        ⑥ 模型的设备移动

        ⑦ 自定义层和操作

1. 创建一个简单的神经网络层

import torch
import torch.nn as nn

class SimpleLayer(nn.Module):
    def __init__(self, input_size, output_size):
        super(SimpleLayer, self).__init__()
        self.linear = nn.Linear(input_size, output_size)
        self.relu = nn.ReLU()

    def forward(self, x):
        x = self.linear(x)
        x = self.relu(x)
        return x

上面的例子中,SimpleLayer 继承自 nn.Module,并定义了一个包含线性层(nn.Linear)和激活函数 ReLU 的简单神经网络层。forward 方法定义了前向传播的计算过程。

2. 构建更复杂的模型

可以通过将多个神经网络层组合在一起构建更复杂的模型。下面是一个简单的多层感知机(MLP)的例子:

class MLP(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(MLP, self).__init__()
        self.layer1 = SimpleLayer(input_size, hidden_size)
        self.layer2 = SimpleLayer(hidden_size, output_size)

    def forward(self, x):
        x = self.layer1(x)
        x = self.layer2(x)
        return x

3. 模块的嵌套和子模块

nn.Module 支持嵌套和包含其他 nn.Module 实例,这有助于构建更复杂的神经网络。子模块会自动跟踪其参数和梯度。

class ComplexModel(nn.Module):
    def __init__(self):
        super(ComplexModel, self).__init__()
        self.layer1 = SimpleLayer(10, 20)
        self.layer2 = MLP(20, 30, 5)

    def forward(self, x):
        x = self.layer1(x)
        x = self.layer2(x)
        return x

4. 访问模块的参数

通过 named_parameters() 或 parameters() 方法可以访问模块中的所有参数。

model = ComplexModel()
for name, param in model.named_parameters():
    print(f"{name}: {param.size()}")

5. 模型的保存和加载

可以使用 torch.save 保存模型的状态字典,并使用 torch.load 加载模型。

# 保存模型
torch.save(model.state_dict(), 'model.pth')

# 加载模型
loaded_model = ComplexModel()
loaded_model.load_state_dict(torch.load('model.pth'))

6. 模型的设备移动

可以使用 to 方法将模型移动到指定的设备,例如GPU。

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model.to(device)

7. 自定义层和操作

可以通过继承 nn.Module 类创建自定义的神经网络层和操作,例如自定义的激活函数、损失函数等。

这些功能使得 nn.Module 成为 PyTorch 中构建和组织神经网络的核心工具之一。通过模块化的设计,可以更灵活地搭建、训练和调整复杂的神经网络结构。

四、优化器

在 PyTorch 中,优化器(Optimizer)是用于更新神经网络模型参数的工具。优化器基于模型参数的梯度信息来调整参数,从而最小化或最大化某个损失函数。PyTorch 提供了多种优化器,包括随机梯度下降(SGD)、Adam、RMSprop等。

优化器:

        ① SGD 优化器

        ② Adam 优化器

        ③ RMSprop 优化器

        ④ 设置学习率

        ⑤ 梯度清零

        ⑥ 梯度更新

        ⑦ 动态调整学习率

        ⑧ 自定义优化器

1. SGD 优化器

随机梯度下降是最基本的优化算法之一。在 PyTorch 中,可以使用 torch.optim.SGD 类来创建SGD 优化器。

import torch
import torch.optim as optim

# 定义模型和损失函数
model = ...
criterion = ...

# 定义 SGD 优化器
optimizer = optim.SGD(model.parameters(), lr=0.01)

2. Adam 优化器

Adam 是一种自适应学习率的优化算法。它在训练深度学习模型时表现良好。在 PyTorch中,可以使用 torch.optim.Adam 类来创建 Adam 优化器。

# 定义 Adam 优化器
optimizer = optim.Adam(model.parameters(), lr=0.001)

3. RMSprop 优化器

RMSprop(Root Mean Square Propagation)是另一种自适应学习率的优化算法。在PyTorch中,可以使用 torch.optim.RMSprop 类来创建 RMSProp 优化器。

# 定义 RMSprop 优化器
optimizer = optim.RMSprop(model.parameters(), lr=0.001)

4. 设置学习率

可以通过 lr 参数来设置优化器的学习率。

optimizer = optim.SGD(model.parameters(), lr=0.01)

5. 梯度清零

在每个训练步骤之前,通常需要清零梯度。可以使用 zero_grad() 方法来实现。

optimizer.zero_grad()

6. 梯度更新

使用优化器的 step() 方法来更新模型参数。

loss.backward()  # 计算梯度
optimizer.step()  # 更新参数

7. 动态调整学习率

PyTorch 提供了一些学习率调整策略,如学习率衰减、余弦退火等。可以使用 torch.optim.lr_scheduler 模块来实现。

from torch.optim import lr_scheduler

# 创建学习率衰减策略
scheduler = lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.1)

# 在训练循环中使用
for epoch in range(num_epochs):
    # 训练模型
    ...

    # 更新学习率
    scheduler.step()

8. 自定义优化器

可以通过继承 torch.optim.Optimizer 类来创建自定义的优化器。

class CustomOptimizer(optim.Optimizer):
    def __init__(self, params, lr=0.01):
        defaults = dict(lr=lr)
        super(CustomOptimizer, self).__init__(params, defaults)

    def step(self, closure=None):
        # 自定义的优化步骤
        ...

优化器是深度学习训练过程中关键的组件之一,选择适当的优化器和学习率策略对于模型的性能至关重要。PyTorch 提供了丰富的优化器和学习率调整工具,使得用户能够根据具体问题选择合适的训练策略。

五、损失函数

损失函数(Loss Function)用于度量模型输出与真实标签之间的差异,是训练神经网络时优化的目标。

PyTorch 提供了多种损失函数,适用于不同类型的任务,如分类、回归等。

损失函数:

        ① 均方误差损失(Mean Squared Error,MSE)

        ② 交叉熵损失(Cross-Entropy Loss)

        ③ 二元交叉熵损失(Binary Cross-Entropy Loss)

        ④ 二元交叉熵损失(带权重)

        ⑤ K-L 散度损失(Kullback-Leibler Divergence Loss)

        ⑥ 三元组损失(Triplet Margin Loss)

        ⑦ 自定义损失函数

        ⑧ 使用损失函数进行训练

1. 均方误差损失(Mean Squared Error,MSE)

均方误差是回归任务中常用的损失函数,计算模型输出与真实标签之间的平方差的平均值。

import torch.nn as nn

criterion = nn.MSELoss()

2. 交叉熵损失(Cross-Entropy Loss)

交叉熵损失是分类任务中常用的损失函数,适用于多类别分类问题。

criterion = nn.CrossEntropyLoss()

3. 二元交叉熵损失(Binary Cross-Entropy Loss)

二元交叉熵损失通常用于二分类问题,其中每个样本属于两个类别之一。

criterion = nn.BCELoss()

4. 二元交叉熵损失(带权重)

可以为每个类别设置不同的权重,以处理类别不平衡的问题。

weights = torch.tensor([weight_class_0, weight_class_1])
criterion = nn.BCEWithLogitsLoss(pos_weight=weights)

5. K-L 散度损失(Kullback-Leibler Divergence Loss)

适用于度量两个概率分布之间的差异,通常用于生成对抗网络(GANs)。

criterion = nn.KLDivLoss()

6. 三元组损失(Triplet Margin Loss)

在训练人脸识别等任务时,可以使用三元组损失来确保相同类别样本之间的距离小于不同类别样本之间的距离。

from torch.nn.functional import triplet_margin_loss

criterion = triplet_margin_loss

7. 自定义损失函数

可以通过继承 nn.Module 类创建自定义的损失函数,实现自定义的损失计算逻辑。

import torch

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

    def forward(self, output, target):
        loss = torch.mean((output - target) ** 2)
        return self.weight * loss

8. 使用损失函数进行训练

在训练循环中,通过计算模型输出与真实标签的损失,并调用反向传播和优化器更新参数来训练模型。

output = model(inputs)
loss = criterion(output, labels)

optimizer.zero_grad()
loss.backward()
optimizer.step()

选择适当的损失函数取决于任务类型和数据特性。通常,可以根据任务的性质和输出的特点选择合适的损失函数。

Logo

脑启社区是一个专注类脑智能领域的开发者社区。欢迎加入社区,共建类脑智能生态。社区为开发者提供了丰富的开源类脑工具软件、类脑算法模型及数据集、类脑知识库、类脑技术培训课程以及类脑应用案例等资源。

更多推荐