简介
循环神经网络(Recurrent Neural Network, RNN)是一类以序列(sequence)数据为输入,在序列的演进方向进行递归(recursion)且所有节点(循环单元)按链式连接的递归神经网络(recursive neural network) [1] 。
对循环神经网络的研究始于二十世纪80-90年代,并在二十一世纪初发展为深度学习(deep learning)算法之一 [2] ,其中双向循环神经网络(Bidirectional RNN, Bi-RNN)和长短期记忆网络(Long Short-Term Memory networks,LSTM)是常见的循环神经网络 [3] 。
目录:
- 模型
- Forward
- Backward
- nn.RNN
- nn.RNNCell
一 模型
: t 时刻样本输入
: t 时刻样本隐藏状态
t时刻输出
: t时刻样本预测类别(只有分类算法才有)
: t 时刻损失函数
二 RNN 前向传播算法 Forward
2.1 t 时刻隐藏值 更新
其中激活函数通常用tanh
2.2 t 时刻输出
其中激活函数 为softmax
三 RNN 反向传播算法 BPTT(back-propagation through time)
3.1 输出层参数v,c梯度
3.2 隐藏层参数更新
定义
证明:
对于最后一个时刻T
3.3 计算权重系数U,W,b
四 nn.RNN
这里面介绍PyTorch 使用RNN 类
4.1 更新规则:
参数 | 说明 |
L | 时间序列长度T or 句子长度为 L |
N | batch_size |
d | 输入特征维度 |
# -*- coding: utf-8 -*-
"""
Created on Wed Jul 19 15:30:01 2023
@author: chengxf2
"""
import torch
import torch.nn as nn
rnn = nn.RNN(input_size=100, hidden_size=5)
param = rnn._parameters
print("\n 权重系数",param.keys())
print(rnn.weight_ih_l0.shape)
输出:
RNN参数说明:
参数 | 说明 |
input_size =d | 输入维度 |
hidden_size=h: | 隐藏层维度 |
num_layers | RNN默认是 1 层。该参数大于 1 时,会形成 Stacked RNN,又称多层RNN或深度RNN; |
nonlinearity | 非线性激活函数。可以选择 tanh 或 relu |
bias | 即偏置。默认启用 |
batch_first | 选择让 batch_size=N 作为输入的形状中的第一个参数。默认是 False,L × N × d 形状; 当 batch_first=True 时, N × L × d |
dropout | 即是否启用 dropout。如要启用,则应设置 dropout 的概率,此时除最后一层外,RNN的每一层后面都会加上一个dropout层。默认是 0,即不启用 |
bidirectional | 即是否启用双向RNN,默认关闭 |
4.2 单层例子
import torch.nn as nn
import torch
rnn = nn.RNN(input_size= 100, hidden_size=20, num_layers=1)
X = torch.randn(10,3,100)
h_0 = torch.zeros(1,3,20)
out,h = rnn(X,h_0)
print("\n out.shape",out.shape)
print("\n h.shape",h.shape)
out: 包含每个时刻的 隐藏值
h : 最后一个时刻的隐藏值
4.3 多层RNN
把当前的隐藏层输出,作为下一层的输入
第一个隐藏层输出:
第二个隐藏层输出
# -*- coding: utf-8 -*-
"""
Created on Mon Jul 24 11:43:30 2023
@author: chengxf2
"""
import torch.nn as nn
import torch
rnn = nn.RNN(input_size=100, hidden_size=20, num_layers=2)
print(rnn)
x = torch.randn(10,3,100) #默认是[L,N,d]结构
out,h =rnn(x)
print(out.shape, h.shape)
5 nn.RNNCell
nn.RNN封装了整个RNN实现的过程, PyTorch 还提供了 nn.RNNCell 可以
自己实现RNN
5.1 单层RNN
# -*- coding: utf-8 -*-
"""
Created on Mon Jul 24 11:43:30 2023
@author: chengxf2
"""
import torch
from torch import nn
def main():
model = nn.RNNCell(input_size=10, hidden_size=20)
h1= torch.zeros(3,20)
trainData = torch.randn(8,3,10)
for xt in trainData:
h1= model(xt,h1)
print(h1.shape)
if __name__ == "__main__":
main()
6.2 多层RNN
# -*- coding: utf-8 -*-
"""
Created on Mon Jul 24 11:43:30 2023
@author: chengxf2
"""
import torch
from torch import nn
def main():
layer1 = nn.RNNCell(input_size=40, hidden_size=30)
layer2 = nn.RNNCell(input_size=30, hidden_size=20)
h1= torch.zeros(3,30)
h2= torch.zeros(3,20)
trainData = torch.randn(8,3,40)
for xt in trainData:
h1= layer1(xt,h1)
h2 = layer2(h1,h2)
print(h1.shape)
print(h2.shape)
if __name__ == "__main__":
main()
参考:
Pytorch 循环神经网络 nn.RNN() nn.RNNCell() nn.Parameter()不同方法实现_老光头_ME2CS的博客-CSDN博客