当前位置: 首页 > article >正文

Pytorch深度学习教程_9_nn模块构建神经网络

欢迎来到《深度学习保姆教程》系列的第九篇!在前面的几篇中,我们已经介绍了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 模块提供了构建神经网络的高级接口。它封装了层、损失函数和优化算法,使得构建和训练复杂模型变得更加容易。

 1.理解nn模块:

nn 模块提供了一系列类和函数,用于构建各种神经网络组件:

  • 层(Layers)‌:定义对输入数据执行的计算操作(例如,Linear、Conv2d、RNN)。
  • 损失函数(Loss functions)‌:量化预测输出和实际输出之间的差异(例如,CrossEntropyLoss、MSELoss)。
  • 容器(Containers)‌:将层组织成顺序、并行或更复杂的结构(例如,Sequential、ModuleList、ModuleDict)。
  • 初始化(Initialization)‌:初始化模型参数(例如,kaiming_normal_、xavier_uniform_)。

(1)使用 nn.Sequential 创建神经网络

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)
)

(2)自定义神经网络

虽然 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)

 

2 创建神经网络层

神经网络层是处理信息的基本组件。它们对输入数据执行计算,将其转换为适合后续层的表示形式。让我们探索一些常见的层类型。

(1)线性层(全连接层)

线性层,也称为全连接层,将一层中的每个神经元连接到下一层中的每个神经元。它们执行矩阵乘法后加上偏置。

import torch.nn as nn

linear_layer = nn.Linear(in_features=10, out_features=20)

(2)卷积层

卷积层对于处理网格状数据(如图像)至关重要。它们应用滤波器来提取特征。

import torch.nn as nn

conv_layer = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, stride=1, padding=1)

(3)池化层

池化层降低输入的维度,同时保留重要信息。

import torch.nn as nn

max_pool = nn.MaxPool2d(kernel_size=2, stride=2)
avg_pool = nn.AvgPool2d(kernel_size=2, stride=2)

(4)循环层

循环层处理序列数据。它们维护内部状态以捕捉来自先前步骤的信息。

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)

(5)其他层类型

  • 归一化层(Normalization layers)‌:归一化输入数据(例如,BatchNorm、LayerNorm)。
  • Dropout 层(Dropout layers)‌:通过随机丢弃神经元来防止过拟合。
  • 嵌入层(Embedding layers)‌:将分类数据转换为密集向量。

(6)将层组合成神经网络

多个层组合在一起可以创建复杂的架构。例如,卷积神经网络通常由卷积层、池化层和全连接层组成。

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

关键考虑因素

  • 层的深度和宽度(Layer depth and width)‌:尝试不同数量的层和神经元。
  • 超参数调整(Hyperparameter tuning)‌:优化诸如核大小、步幅和填充等参数。
  • 计算效率(Computational efficiency)‌:考虑不同层的计算成本。

 

3 构建顺序模型

顺序模型旨在处理具有时间或空间顺序的数据,例如时间序列数据、文本和音频。它们捕捉序列中元素之间的依赖关系。

理解顺序数据

  • 时间序列数据(Time series data)‌:在特定时间点记录的观测值。
  • 文本数据(Text data)‌:单词或字符的序列。
  • 音频数据(Audio data)‌:音频样本的序列。

(1)循环神经网络(RNNs)

RNNs 是处理顺序数据的基础架构。它们在网络中引入循环,允许信息跨时间步长持续存在。

  • 隐藏状态(Hidden state)‌:维护关于过去输入的信息。
  • 梯度消失问题(Vanishing gradient problem)‌:难以学习长期依赖关系。
import torch.nn as nn

# 简单的 RNN
rnn = nn.RNN(input_size=10, hidden_size=20, num_layers=1)

(2)长短期记忆网络(LSTMs)

LSTMs 通过引入记忆单元和门来解决梯度消失问题。

  • 记忆单元(Memory cell)‌:存储长时间的信息。
  • 门(Gates)‌:控制信息流入和流出记忆单元的流动。
import torch.nn as nn

lstm = nn.LSTM(input_size=10, hidden_size=20, num_layers=1)

(3)门控循环单元(GRUs)

GRUs 是 LSTMs 的简化版本,参数更少。

  • 更新门(Update gate)‌:控制保留多少之前的隐藏状态。
  • 重置门(Reset gate)‌:控制忘记多少过去的信息。
import torch.nn as nn

gru = nn.GRU(input_size=10, hidden_size=20, num_layers=1)

挑战和注意事项

  • 梯度消失/爆炸(Vanishing/exploding gradients)‌:可能阻碍训练,特别是对于长序列。
  • 计算成本(Computational cost)‌:RNNs 训练起来可能计算成本较高。
  • 过拟合(Overfitting)‌:防止模型记住训练数据。

 

4 自定义神经网络模块

虽然 PyTorch 的 nn 模块提供了一套丰富的预建层,但在某些情况下,需要创建针对特定问题域或架构创新的自定义组件。

(1)理解自定义模块的需求

  • 特定问题的操作(Problem-specific operations)‌:某些任务可能需要标准层未涵盖的操作。
  • 架构实验(Architectural experimentation)‌:自定义模块允许灵活地探索新架构。
  • 性能优化(Performance optimization)‌:手工实现有时可能更高效。

创建自定义模块

要创建自定义模块,您需要继承 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)
)

高级自定义

  • 参数共享(Parameter sharing)‌:创建在不同层之间共享参数的模块。
  • 动态架构(Dynamic architectures)‌:根据输入数据构建具有可变结构的模型。
  • 混合模型(Hybrid models)‌:结合自定义模块与预训练层。

 总结

通过掌握自定义模块的创建,您可以解锁设计高度专业化和创新的神经网络架构的潜力。nn 模块是一个强大的工具,但将其与对神经网络概念的理解相结合,才能构建有效的模型。


http://www.kler.cn/a/598026.html

相关文章:

  • 数据建模流程: 概念模型>>逻辑模型>>物理模型
  • 大数据驱动:UI设计如何更懂用户
  • 数据结构与算法:宽度优先遍历
  • [node] 4 http模块
  • 【C++教程】break语句
  • MOE框架详解与实现
  • hackmyvm-lookup
  • 数组,指针 易混题解析(二)
  • golang Error的一些坑
  • 唯品会商品详情页架构设计与实现:高并发场景下的技术实践‌
  • 乘法逆元(快速幂,费马小定理)
  • 常见前端安全问题及解决方案
  • PyJSON5:高效、安全的JSON5处理库
  • Linux-数据结构-哈夫曼树-哈希表-内核链表
  • 【STL】string类
  • 死锁:当程序 “卡住“ 时,发生了什么?
  • wordpress主题使用中常见错误汇总
  • OpenGL实现摄像机(根据鼠标位置放大缩小视图)
  • How to install visual studio code on Linux mint 22
  • 详解内联容器标签<span>的用法