【pytorch基础】神经网络学习

概述

最近在研究Llama的源码,有很多pytorch相关的函数,由于对pytorch不是很熟悉,阅读源码有些困难,所以本文主要记录了自己在阅读llama源码过程中遇到的pytorch相关函数,通过查阅资料将自己不熟悉的函数作用和理解进行了说明。

通过本文的学习,你将对pytorch的一些函数有比较深入的了解并且对大模型的学习打下基础,后续将会介绍一下llama源码相关的内容。

pytorch函数说明

nn.Module

nn.Module的作用

在PyTorch中,nn.Module是构建神经网络模型的基类,它的作用是提供了一个模型组件的基本结构,使得用户可以方便地定义和管理神经网络模型。nn.Module的存在使得神经网络模型的构建更加模块化和易于组织,提供了许多方法和属性来方便地管理模型的参数、子模块等。

理解nn.Module

理解nn.Module可以看作是神经网络模型的基本组成单元,它可以包含模型的参数、定义前向传播方法等。通过继承nn.Module,用户可以定义自己的神经网络模型,并使用PyTorch提供的许多功能来管理模型。同时,nn.Module还提供了一种递归的方式来管理模型的子模块,使得复杂的神经网络结构可以被方便地构建和管理。

示例

以下是一个简单的示例,说明如何使用nn.Module来定义一个简单的神经网络模型:

python 复制代码
import torch
import torch.nn as nn
import torch.nn.functional as F

# 创建一个简单的全连接神经网络模型
class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        self.fc1 = nn.Linear(10, 5)
        self.fc2 = nn.Linear(5, 2)

    def forward(self, x):
        x = F.relu(self.fc1(x))  # 使用激活函数
        print('使用relu激活函数:')
        print(x)
        x = self.fc2(x)
        return x

# 创建模型实例
model = MyModel()

# 使用模型进行前向传播
input_data = torch.rand(1, 10)  # 一个样本,10个特征
output = model(input_data)
print('输出内容:')
print(output)

# 输出结果如下:
# 使用relu激活函数:
# tensor([[0.5010, 0.4212, 0.0000, 0.0000, 0.3532]], grad_fn=<ReluBackward0>)
# 输出内容:
# tensor([[0.1825, 0.0719]], grad_fn=<AddmmBackward0>)

在这个示例中,我们创建了一个简单的全连接神经网络模型,并使用nn.Module定义了模型的结构和前向传播的方法。通过继承nn.Module,我们可以方便地管理模型的参数、定义前向传播方法,并使用PyTorch提供的许多功能来管理模型。

forward 方法

forward 方法是在 PyTorch 中用于定义模型的前向传播过程的方法。当我们构建一个自定义的神经网络模型时,需要继承 nn.Module 类并且实现 forward 方法。在这个方法中,我们定义了输入数据的传播过程,包括输入数据经过各个层的变换、激活函数的应用等。

理解 forward 方法的概念可以看作是定义了模型的计算流程。在 forward 方法中,我们描述了模型的结构以及如何将输入数据按照这个结构进行传递和变换,最终得到输出结果。在模型实例被调用时,PyTorch 将自动调用 forward 方法来执行模型的前向传播。

nn.Linear

nn.Linear的作用

在PyTorch中,nn.Linear是一个用于定义线性变换的模块,它通常用于构建神经网络的全连接层(也称为密集连接层或线性层)。

nn.Linear的作用是将输入数据进行线性变换,具体来说,对输入的每一行进行线性变换,将输入的特征值与权重相乘,再加上偏置项。其数学表达式为:y = xA^T + b

[{output} = {input} * {weight}^T + {bias} ]

其中,input为输入数据,weight为权重矩阵,bias为偏置项。在神经网络中,这个操作可以表示为将输入数据映射到输出空间的线性变换。

理解nn.Linear

在理解nn.Linear时,可以将其视为一个简单的模型,该模型接收输入数据,对输入数据进行加权求和,然后加上偏置项,最终得到输出。这个操作通常用于连接神经网络中的不同层,以便实现特征提取和变换。

示例

以下是一个示例,说明如何使用nn.Linear定义一个简单的全连接层:

python 复制代码
import torch
import torch.nn as nn

# 定义输入特征维度为5,输出特征维度为3的线性层
linear_layer = nn.Linear(5, 3)
print(linear_layer)
# 定义一个随机输入数据
input_data = torch.rand(2, 5)  # 2个样本,每个样本有5个特征
print(input_data)
# 将输入数据传入线性层进行线性变换
output = linear_layer(input_data)
print(output)

# 输出结果如下:
# Linear(in_features=5, out_features=3, bias=True)
# tensor([[0.2396, 0.1651, 0.2020, 0.6231, 0.2183],
#         [0.3458, 0.7107, 0.8589, 0.3148, 0.3530]])
# tensor([[-0.4772, -0.5004, -0.4116],
#         [-0.1266, -0.3313, -0.6919]], grad_fn=<AddmmBackward0>)

nn.Parameter

nn.Parameter的作用

在PyTorch中,nn.Parameter是Tensor的一个特殊类型,它被用于在神经网络的参数中进行标识。通常情况下,当在模型中定义需要学习的参数时,我们会使用nn.Parameter来创建可学习的张量。

nn.Parameter的主要作用是将张量包装成一个可训练的参数,并将其注册到模型参数中。这意味着,当使用优化器进行模型参数的优化时,nn.Parameter所包装的张量将被自动识别为需要学习的参数,并且会被优化器所更新。

理解nn.Parameter

理解nn.Parameter的概念可以看作是将张量包装成模型参数的一种约定和标识,这有助于将需要学习的参数与其他张量区分开来,更方便地进行参数优化和更新。

示例

下面是一个简单的示例,说明如何使用nn.Parameter定义一个可学习的参数:

python 复制代码
import torch
import torch.nn as nn

# 创建一个简单的模型
class SimpleModel(nn.Module):
    def __init__(self):
        super(SimpleModel, self).__init__()
        # 在模型中使用nn.Parameter定义可学习的权重参数
        self.weight = nn.Parameter(torch.rand(3, 3))  

    def forward(self, x):
        return torch.matmul(x, self.weight)

# 创建模型实例
model = SimpleModel()

# 输出模型参数
print(model.weight)

# 输出结果如下:
# Parameter containing:
# tensor([[0.5604, 0.1497, 0.5703],
#         [0.9534, 0.0289, 0.9364],
#         [0.3786, 0.0865, 0.2071]], requires_grad=True)

在上述示例中,我们使用nn.Parameter定义了一个可学习的权重参数,然后将其包装到一个简单的神经网络模型中。当优化器对模型进行参数优化时,模型中的nn.Parameter所包装的参数将被自动识别并更新。

nn.Dropout

nn.Dropout 的作用

在PyTorch中,nn.Dropout是一个用于防止过拟合的正则化技术,通常用于深度学习模型中。

它的作用是在模型训练过程中以一定的概率随机地将部分神经元的输出设置为0,从而减少神经元之间的依赖关系,防止过拟合。

理解nn.Dropout

理解nn.Dropout的概念可以看作是在训练过程中实施随机失活(dropout)操作,即在每个训练步骤中,以一定的概率随机地将部分神经元的输出置为0。这有助于模型对某些特定特征的依赖性降低,增加模型的泛化能力,减少过拟合的风险。

示例

下面是一个简单的示例,说明如何使用nn.Dropout将dropout层添加到一个神经网络模型中:

python 复制代码
import torch
import torch.nn as nn

# 创建一个带有dropout层的神经网络模型
class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        self.fc1 = nn.Linear(10, 5)
        self.dropout = nn.Dropout(p=0.5)  # 添加一个dropout层,以概率0.5随机失活
        self.fc2 = nn.Linear(5, 2)

    def forward(self, x):
        x = self.fc1(x)
        x = self.dropout(x)  # 在全连接层的输出上应用dropout
        print('在全连接层的输出上应用dropout后的结果如下:')
        print(x)
        x = self.fc2(x)
        return x

# 创建模型实例
model = MyModel()

# 在模型中使用dropout层
input_data = torch.rand(1, 10)  # 一个样本,10个特征
output = model(input_data)
print('最后的结果:')
print(output)


# 输出结果如下:
# 在全连接层的输出上应用dropout后的结果如下:
# tensor([[ 0.8835, -0.3673,  0.0000, -0.0000,  0.0000]], grad_fn=<MulBackward0>)
# 最后的结果:
# tensor([[-0.8057,  0.3372]], grad_fn=<AddmmBackward0>)

在这个示例中,我们创建了一个简单的神经网络模型,并在模型中使用了nn.Dropout层,将dropout应用到全连接层的输出上。在模型训练过程中,dropout层将以概率0.5随机地将部分神经元的输出置为0,从而实现随机失活的效果。

nn.CrossEntropyLoss

nn.CrossEntropyLoss的作用

在PyTorch中,nn.CrossEntropyLoss 是用于多分类问题的损失函数。它结合了 softmax 函数和负对数似然损失(negative log likelihood loss) ,用于计算多分类问题中的损失值。通常情况下,对于多分类问题,模型的最后一层会使用 softmax 激活函数,将输出转换为表示类别概率的形式,而交叉熵损失函数是用来衡量模型输出的概率分布与实际标签之间的差异。

理解nn.CrossEntropyLoss

理解nn.CrossEntropyLoss可以看作是衡量模型输出的概率分布和实际标签之间的差异。它通过最大化正确标签的对数概率来最小化负对数似然损失,从而使模型更加关注于正确类别的分类概率。

示例

下面是一个简单的示例,说明了如何使用 nn.CrossEntropyLoss 损失函数:

python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim

# 定义模型输出和实际标签
outputs = torch.tensor([[0.5, 0.1, 0.2], [0.3, 0.4, 0.3]])  # 模型输出,假设有3个类别
labels = torch.tensor([0, 2])  # 实际类别标签

# 使用 nn.CrossEntropyLoss 计算损失
crossEntropyLoss = nn.CrossEntropyLoss()
loss = crossEntropyLoss(outputs, labels)

print(loss)
# 输出结果:
# tensor(1.0066)

在这个示例中,我们创建了一个包含模型输出和实际标签的张量,并使用 nn.CrossEntropyLoss 计算了模型输出与实际标签之间的交叉熵损失。在训练神经网络时,通常会将这个损失值作为优化器的目标,并通过反向传播来更新模型参数,以便最小化损失值。

在实际计算中,nn.CrossEntropyLoss在内部会先进行softmax操作,然后计算负对数似然损失。如果模型的输出已经经过softmax操作,可以使用nn.NLLLoss(negative log likelihood loss)来计算负对数似然损失。

下面是一个简单的示例,说明了如何使用 nn.NLLLoss 损失函数来计算负对数似然损失:

python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim

# 定义模型输出和实际标签
outputs = torch.tensor([[0.5, 0.1, 0.2], [0.3, 0.4, 0.3]])  # 模型输出,假设有3个类别
labels = torch.tensor([0, 2])  # 实际类别标签

log_softmax = nn.LogSoftmax(dim=1)
probs = log_softmax(outputs)
# 使用 nn.NLLLoss 计算负对数似然损失
nllloss = nn.NLLLoss()
loss = nllloss(probs, labels)

print(loss)
# 输出结果:
# tensor(1.0066)

可以看到计算nn.NLLLoss 损失时,先对模型输出进行softmax,然后nn.NLLLoss计算的结果和直接使用nn.CrossEntropyLoss计算的结果是一样的。


相关推荐
进击的女IT3 分钟前
SpringBoot上传图片实现本地存储以及实现直接上传阿里云OSS
java·spring boot·后端
xiandong201 小时前
240929-CGAN条件生成对抗网络
图像处理·人工智能·深度学习·神经网络·生成对抗网络·计算机视觉
一 乐1 小时前
学籍管理平台|在线学籍管理平台系统|基于Springboot+VUE的在线学籍管理平台系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·学习
innutritious2 小时前
车辆重识别(2020NIPS去噪扩散概率模型)论文阅读2024/9/27
人工智能·深度学习·计算机视觉
橙子小哥的代码世界3 小时前
【深度学习】05-RNN循环神经网络-02- RNN循环神经网络的发展历史与演化趋势/LSTM/GRU/Transformer
人工智能·pytorch·rnn·深度学习·神经网络·lstm·transformer
艾伦~耶格尔4 小时前
Spring Boot 三层架构开发模式入门
java·spring boot·后端·架构·三层架构
985小水博一枚呀4 小时前
【深度学习基础模型】神经图灵机(Neural Turing Machines, NTM)详细理解并附实现代码。
人工智能·python·rnn·深度学习·lstm·ntm
man20174 小时前
基于spring boot的篮球论坛系统
java·spring boot·后端
攸攸太上5 小时前
Spring Gateway学习
java·后端·学习·spring·微服务·gateway
SEU-WYL5 小时前
基于深度学习的任务序列中的快速适应
人工智能·深度学习