逐行理解LSTM代码

由于我还没有学习过python,所以会很基础的理解 ,首先大概了解有关的知识

相关学习代码的链接:

https://zhuanlan.zhihu.com/p/39191116

学习笔记:

 

 

 

 

 

 

具体代码解释:

导入模块: 

import torch
import torch.nn as nn

使用pytorch搭建神经网络的时候,有两个最常用的包:torch.nn和torch.optim。

torch.nn包中主要包含了用来搭建各个层的模块(Modules),比如全连接、二维卷积、池化等;torch.nn包中还包含了一系列有用的loss函数,比如CrossEntropyLoss、MSELoss等;另外,torch.nn.functional子包中包含了常用的激活函数,如relu、leaky_relu、prelu、sigmoid等。

torch.optim包则主要包含了用来更新参数的优化算法,比如SGD、AdaGrad、RMSProp、 Adam等。

python语句:import as 后续对torch.optim的引用可以直接使用optim,但是需要注意使用as语法之后,只能通过as后面的名字来访问导入的moudle

定义数据维度:

# 定义输入数据维度和超参数
input_size = 10
hidden_size = 20
num_layers = 2
output_size = 1
  • input_size – 输入数据的大小,也就是前面例子中每个单词向量的长度(输入特征的维数)
  • hidden_size – 隐藏层的大小(即隐藏层节点数量),输出向量的维度等于隐藏节点数(每个LSTM单元或者时间步的输出的ht的维度,单元内部有权重与偏差计算)
  • num_layers – recurrent layer的数量,默认等于1(构建多层的LSTM进行堆叠)
  • bias – If False, then the layer does not use bias weights b_ih and b_hh. Default: True
  • batch_first – 默认为False,也就是说官方不推荐我们把batch放在第一维,这个与常见的CNN输入有点不同,此时输入输出的各个维度含义为 (seq_length,batch,feature)。当然如果你想和CNN一样把batch放在第一维,可将该参数设置为True,即 (batch,seq_length,feature),习惯上将batch_first 设置为True。
  • dropout – 如果非0,就在除了最后一层的其它层都插入Dropout层,默认为0。
  • bidirectional – 如果设置为 True, 则表示双向 LSTM,默认为 False
  • output:output保存了最后一层,每个time step的输出h,如果是双向LSTM,每个time step的输出h = [h正向, h逆向] (同一个time step的正向和逆向的h连接起来)。
  • output是一个三维的张量,第一维表示序列长度,第二维表示一批的样本数(batch),第三维是 hidden_size(隐藏层大小) * num_directions ,num_directions根据是“否为双向”取值为1或2。因此,output第三个维度的尺寸根据是否为双向而变化,如果不是双向,第三个维度等于我们定义的隐藏层大小;如果是双向的,第三个维度的大小等于2倍的隐藏层大小。为什么使用2倍的隐藏层大小?因为它把每个time step的前向和后向的输出连接起来了
  • learning_rate:控制 模型的学习进度
  • epoch: 所有的数据送入网络中, 完成了一次前向计算 + 反向传播的过程

创建模型:

# 创建模型实例
model = LSTMModel(input_size, hidden_size, num_layers, output_size)

定义多层LSTM: 

# 定义多层LSTM模型
class LSTMModel(nn.Module):
    def __init__(self, input_size, hidden_size, num_layers, output_size):
        super(LSTMModel, self).__init__()
        self.hidden_size = hidden_size
        self.num_layers = num_layers

 # 创建LSTM层和linear层,LSTM层提取特征,linear层用作最后的预测
 # LSTM算法接受三个输入:先前的隐藏状态,先前的单元状态和当前输入。
        self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
        self.fc = nn.Linear(hidden_size, output_size)

# forward函数的任务需要把输入层、网络层、输出层链接起来,实现信息的前向传导。
# forward该函数的参数一般为输入数据,返回值是输出数据。
    def forward(self, x):
#lstm的输出是当前时间步的隐藏状态ht和单元状态ct以及输出lstm_out
        h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)
        c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)
        out, _ = self.lstm(x, (h0, c0))
        out = self.fc(out[:, -1, :])
        return out

 nn.Module 是 PyTorch 体系下所有神经网络模块的基类

nn.Moudle的实现:

__init__ 函数:

在 nn.Module 的 __init__ 函数中,会首先被调用。super().__init__()。只有这样才能正确地初始化自定义的神经网络模块,否则会缺少上面代码中的成员变量而导致模块被调用时出错。实际上,如果没有提前调用 super().__init__(),在增加模块的 parameter 或者 buffer 的时候,被调用的 __setattr__ 函数也会检查出父类 nn.Module 没被正确地初始化并报错。

self.training = True  # 控制 training/testing 状态
self._parameters = OrderedDict()  # 在训练过程中会随着 BP 而更新的参数
self._buffers = OrderedDict()  # 在训练过程中不会随着 BP 而更新的参数
self._non_persistent_buffers_set = set()
self._backward_hooks = OrderedDict()  # Backward 完成后会被调用的 hook
self._forward_hooks = OrderedDict()  # Forward 完成后会被调用的 hook
self._forward_pre_hooks = OrderedDict()  # Forward 前会被调用的 hook
self._state_dict_hooks = OrderedDict()  # 得到 state_dict 以后会被调用的 hook
self._load_state_dict_pre_hooks = OrderedDict()  # load state_dict 前会被调用的 hook
self._modules = OrderedDict()  # 子神经网络模块

torch.zeros()函数

返回一个形状为为size,类型为torch.dtype,里面的每一个值都是0的tensor

torch.zeros(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor

参数说明
size: 定义tensor的shape ,这里可以是一个list 也可以是一个tuple

dtype:(可选)我不设置值 默认值就是torch.set_default_tensor_type制定的值,如果需要设置那就是torch.dtype的那几个。作用是指定返回tensor的数据类型

layout:(可选)值为 torch.layout。 torch.layout表示torch.Tensor内存布局的对象。有torch.strided(dense Tensors 默认)并为torch.sparse_coo(sparse COO Tensors)提供实验支持。
torch.strided代表密集张量,是最常用的内存布局。每个strided张量都会关联 一个torch.Storage,它保存着它的数据。这些张力提供了多维度, 存储的strided视图。Strides是一个整数型列表:k-th stride表示在张量的第k维从一个元素跳转到下一个元素所需的内存。关于这里的理解请看demo2

device:(可选)就是创建的tensor存放的device

requires_grad: (可选)是bool 类型的值,默认值是False 

定义输入数据:

# 定义输入数据
batch_size = 16
sequence_length = 5
input_data = torch.randn(batch_size, sequence_length, input_size)

前向传播输出: 

# 前向传播计算输出
output = model(input_data)

 打印输出结果的形状 :

# 打印输出结果的形状
print(output.shape)

代码:

import torch
import torch.nn as nn

# 定义多层LSTM模型
class LSTMModel(nn.Module):
    def __init__(self, input_size, hidden_size, num_layers, output_size):
        super(LSTMModel, self).__init__()
        self.hidden_size = hidden_size
        self.num_layers = num_layers
        self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
        self.fc = nn.Linear(hidden_size, output_size)

    def forward(self, x):
        h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)
        c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)
        out, _ = self.lstm(x, (h0, c0))
        out = self.fc(out[:, -1, :])
        return out

# 定义输入数据维度和超参数
input_size = 10
hidden_size = 20
num_layers = 2
output_size = 1

# 创建模型实例
model = LSTMModel(input_size, hidden_size, num_layers, output_size)

# 定义输入数据
batch_size = 16
sequence_length = 5
input_data = torch.randn(batch_size, sequence_length, input_size)

# 前向传播计算输出
output = model(input_data)

# 打印输出结果的形状
print(output.shape)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值