欢迎来到《深度学习保姆教程》系列的第九篇!在前面的几篇中,我们已经介绍了Python、numpy及pytorch的基本使用,进行了梯度及神经网络的实践并学习了激活函数和激活函数,在上一个教程中我们学习了优化算法。今天,我们将开始使用pytorch构建我们自己的神经网络。
欢迎订阅专栏进行系统学习:
深度学习保姆教程_tRNA做科研的博客-CSDN博客
目录
1.理解nn模块:
(1)使用 nn.Sequential 创建神经网络
(2)自定义神经网络
2 创建神经网络层
(1)线性层(全连接层)
(2)卷积层
(3)池化层
(4)循环层
(5)其他层类型
(6)将层组合成神经网络
3 构建顺序模型
(1)循环神经网络(RNNs)
(2)长短期记忆网络(LSTMs)
(3)门控循环单元(GRUs)
4 自定义神经网络模块
(1)理解自定义模块的需求
创建自定义模块
将自定义模块纳入神经网络
总结
PyTorch 的 nn 模块提供了构建神经网络的高级接口。它封装了层、损失函数和优化算法,使得构建和训练复杂模型变得更加容易。
nn 模块提供了一系列类和函数,用于构建各种神经网络组件:
nn.Sequential 容器是一种创建前馈神经网络的简单方法。它定义了一个模块的线性堆栈。
import torch
import torch.nn as nn
# 定义一个简单的神经网络
model = nn.Sequential(
nn.Linear(input_size, hidden_size),
nn.ReLU(),
nn.Linear(hidden_size, output_size)
)
虽然 nn.Sequential 很方便,但您可以通过继承 nn.Module 来创建更复杂的架构。这允许您自定义前向传播逻辑,并对模型结构拥有更多控制权。
import torch
import torch.nn as nn
# 定义一个名为MyModel的神经网络模型类,继承自nn.Module
class MyModel(nn.Module):
# 构造函数,初始化模型参数
def __init__(self, input_size, hidden_size, output_size):
# 调用父类nn.Module的构造函数进行初始化
super(MyModel, self).__init__()
# 定义第一个全连接层(线性层),输入大小为input_size,输出大小为hidden_size
self.fc1 = nn.Linear(input_size, hidden_size)
# 定义第二个全连接层(线性层),输入大小为hidden_size,输出大小为output_size
self.fc2 = nn.Linear(hidden_size, output_size)
# 前向传播函数,定义数据如何通过网络
def forward(self, x):
# 对第一个全连接层的输出应用ReLU激活函数
x = torch.relu(self.fc1(x))
# 将经过激活后的输出传递给第二个全连接层
x = self.fc2(x)
# 返回最终的输出
return x
# 实例化MyModel模型,传入输入层、隐藏层和输出层的大小
model = MyModel(input_size, hidden_size, output_size)
神经网络层是处理信息的基本组件。它们对输入数据执行计算,将其转换为适合后续层的表示形式。让我们探索一些常见的层类型。
线性层,也称为全连接层,将一层中的每个神经元连接到下一层中的每个神经元。它们执行矩阵乘法后加上偏置。
import torch.nn as nn
linear_layer = nn.Linear(in_features=10, out_features=20)
卷积层对于处理网格状数据(如图像)至关重要。它们应用滤波器来提取特征。
import torch.nn as nn
conv_layer = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, stride=1, padding=1)
池化层降低输入的维度,同时保留重要信息。
import torch.nn as nn
max_pool = nn.MaxPool2d(kernel_size=2, stride=2)
avg_pool = nn.AvgPool2d(kernel_size=2, stride=2)
循环层处理序列数据。它们维护内部状态以捕捉来自先前步骤的信息。
import torch.nn as nn
rnn = nn.RNN(input_size=10, hidden_size=20, num_layers=1)
lstm = nn.LSTM(input_size=10, hidden_size=20, num_layers=1)
gru = nn.GRU(input_size=10, hidden_size=20, num_layers=1)
多个层组合在一起可以创建复杂的架构。例如,卷积神经网络通常由卷积层、池化层和全连接层组成。
import torch.nn as nn
# 定义一个名为MyCNN的神经网络模型类,继承自nn.Module
class MyCNN(nn.Module):
def __init__(self):
super(MyCNN, self).__init__()
# 定义第一个卷积层
self.conv1 = nn.Conv2d(3, 16, 3, padding=1)
# 定义最大池化层
self.pool = nn.MaxPool2d(2, 2)
# 定义第一个全连接层
self.fc1 = nn.Linear(16 * 7 * 7, 120)
# 定义第二个全连接层
self.fc2 = nn.Linear(120, 84)
# 定义第三个全连接层
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
# 应用卷积、ReLU激活函数和池化
x = self.pool(torch.relu(self.conv1(x)))
# 将特征图展平成一维向量
x = torch.flatten(x, 1)
# 应用第一个全连接层和ReLU激活函数
x = torch.relu(self.fc1(x))
# 应用第二个全连接层和ReLU激活函数
x = torch.relu(self.fc2(x))
# 应用第三个全连接层
x = self.fc3(x)
return x
关键考虑因素
顺序模型旨在处理具有时间或空间顺序的数据,例如时间序列数据、文本和音频。它们捕捉序列中元素之间的依赖关系。
理解顺序数据
RNNs 是处理顺序数据的基础架构。它们在网络中引入循环,允许信息跨时间步长持续存在。
import torch.nn as nn
# 简单的 RNN
rnn = nn.RNN(input_size=10, hidden_size=20, num_layers=1)
LSTMs 通过引入记忆单元和门来解决梯度消失问题。
import torch.nn as nn
lstm = nn.LSTM(input_size=10, hidden_size=20, num_layers=1)
GRUs 是 LSTMs 的简化版本,参数更少。
import torch.nn as nn
gru = nn.GRU(input_size=10, hidden_size=20, num_layers=1)
挑战和注意事项
虽然 PyTorch 的 nn 模块提供了一套丰富的预建层,但在某些情况下,需要创建针对特定问题域或架构创新的自定义组件。
要创建自定义模块,您需要继承 torch.nn.Module
并实现 forward
方法。该方法定义了对输入张量执行的计算。
import torch
import torch.nn as nn
# 定义一个名为MyCustomLayer的自定义神经网络层类,继承自nn.Module
class MyCustomLayer(nn.Module):
def __init__(self, in_features, out_features):
super().__init__()
# 初始化权重参数,使用标准正态分布随机初始化
self.weight = nn.Parameter(torch.randn(in_features, out_features))
# 初始化偏置参数,使用零初始化
self.bias = nn.Parameter(torch.zeros(out_features))
def forward(self, x):
# 执行线性变换:x @ weight + bias
return x @ self.weight + self.bias
一旦定义了自定义模块,您就可以像使用其他层一样在神经网络架构中使用它。
model = nn.Sequential(
MyCustomLayer(10, 20),
nn.ReLU(),
nn.Linear(20, 5)
)
高级自定义
通过掌握自定义模块的创建,您可以解锁设计高度专业化和创新的神经网络架构的潜力。nn 模块是一个强大的工具,但将其与对神经网络概念的理解相结合,才能构建有效的模型。