赞
踩
人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新)
什么是RNN模型:
RNN模型的分类:
按照输入和输出的结构进行分类:
按照RNN的内部构造进行分类:
小节总结:
Pytorch中传统RNN工具的使用:
- >>> import torch
- >>> import torch.nn as nn
- >>> rnn = nn.RNN(5, 6, 1)
- >>> input = torch.randn(1, 3, 5)
- >>> h0 = torch.randn(1, 3, 6)
- >>> output, hn = rnn(input, h0)
- >>> output
- tensor([[[ 0.4282, -0.8475, -0.0685, -0.4601, -0.8357, 0.1252],
- [ 0.5758, -0.2823, 0.4822, -0.4485, -0.7362, 0.0084],
- [ 0.9224, -0.7479, -0.3682, -0.5662, -0.9637, 0.4938]]],
- grad_fn=<StackBackward>)
-
- >>> hn
- tensor([[[ 0.4282, -0.8475, -0.0685, -0.4601, -0.8357, 0.1252],
- [ 0.5758, -0.2823, 0.4822, -0.4485, -0.7362, 0.0084],
- [ 0.9224, -0.7479, -0.3682, -0.5662, -0.9637, 0.4938]]],
- grad_fn=<StackBackward>)
梯度消失或爆炸的危害:
小节总结:
- >>> import torch.nn as nn
- >>> import torch
- >>> rnn = nn.LSTM(5, 6, 2)
- >>> input = torch.randn(1, 3, 5)
- >>> h0 = torch.randn(2, 3, 6)
- >>> c0 = torch.randn(2, 3, 6)
- >>> output, (hn, cn) = rnn(input, (h0, c0))
- >>> output
- tensor([[[ 0.0447, -0.0335, 0.1454, 0.0438, 0.0865, 0.0416],
- [ 0.0105, 0.1923, 0.5507, -0.1742, 0.1569, -0.0548],
- [-0.1186, 0.1835, -0.0022, -0.1388, -0.0877, -0.4007]]],
- grad_fn=<StackBackward>)
- >>> hn
- tensor([[[ 0.4647, -0.2364, 0.0645, -0.3996, -0.0500, -0.0152],
- [ 0.3852, 0.0704, 0.2103, -0.2524, 0.0243, 0.0477],
- [ 0.2571, 0.0608, 0.2322, 0.1815, -0.0513, -0.0291]],
-
- [[ 0.0447, -0.0335, 0.1454, 0.0438, 0.0865, 0.0416],
- [ 0.0105, 0.1923, 0.5507, -0.1742, 0.1569, -0.0548],
- [-0.1186, 0.1835, -0.0022, -0.1388, -0.0877, -0.4007]]],
- grad_fn=<StackBackward>)
- >>> cn
- tensor([[[ 0.8083, -0.5500, 0.1009, -0.5806, -0.0668, -0.1161],
- [ 0.7438, 0.0957, 0.5509, -0.7725, 0.0824, 0.0626],
- [ 0.3131, 0.0920, 0.8359, 0.9187, -0.4826, -0.0717]],
-
- [[ 0.1240, -0.0526, 0.3035, 0.1099, 0.5915, 0.0828],
- [ 0.0203, 0.8367, 0.9832, -0.4454, 0.3917, -0.1983],
- [-0.2976, 0.7764, -0.0074, -0.1965, -0.1343, -0.6683]]],
- grad_fn=<StackBackward>)
小节总结:
- >>> import torch
- >>> import torch.nn as nn
- >>> rnn = nn.GRU(5, 6, 2)
- >>> input = torch.randn(1, 3, 5)
- >>> h0 = torch.randn(2, 3, 6)
- >>> output, hn = rnn(input, h0)
- >>> output
- tensor([[[-0.2097, -2.2225, 0.6204, -0.1745, -0.1749, -0.0460],
- [-0.3820, 0.0465, -0.4798, 0.6837, -0.7894, 0.5173],
- [-0.0184, -0.2758, 1.2482, 0.5514, -0.9165, -0.6667]]],
- grad_fn=<StackBackward>)
- >>> hn
- tensor([[[ 0.6578, -0.4226, -0.2129, -0.3785, 0.5070, 0.4338],
- [-0.5072, 0.5948, 0.8083, 0.4618, 0.1629, -0.1591],
- [ 0.2430, -0.4981, 0.3846, -0.4252, 0.7191, 0.5420]],
-
- [[-0.2097, -2.2225, 0.6204, -0.1745, -0.1749, -0.0460],
- [-0.3820, 0.0465, -0.4798, 0.6837, -0.7894, 0.5173],
- [-0.0184, -0.2758, 1.2482, 0.5514, -0.9165, -0.6667]]],
- grad_fn=<StackBackward>)
小节总结:
- weight_ih_l[k]
- 第k层的可学习输入隐藏权重的形状 (hidden_size, input_size)
- 对于“k=0”。否则,形状是 (hidden_size, num_directions * hidden_size)
-
- weight_ih:
- 可学习输入隐藏权重的形状(hidden_size, input_size)
- 每个单词 的嵌入维度的 向量 作为 一个时间步 输入到 一个 RNN 节点,
- 然后 会和 神经元数量维度的 向量 构成一个 可学习输入隐藏权重 这样的 形状 (hidden_size, input_size),
- 就是 (神经元数量, 单词嵌入维度)。
-
- def __init__(self, mode, input_size, hidden_size,
- num_layers=1, bias=True, batch_first=False, dropout=0.,
- bidirectional=False):
- #默认值bidirectional=False:那么“2 if False else 1”返回1,“2 if True else 1”返回2。
- #如果RNN是双向的,num_directions应该是2,否则应该是1。
- num_directions = 2 if bidirectional else 1
-
- ========================================================================
- # nn.RNN(输入数据的词嵌入维度, 隐藏层中神经元数量, 隐藏层层数)
- rnn = nn.RNN(5, 6, 2)
- rnn = nn.GRU(5, 6, 2)
- rnn = nn.LSTM(5, 6, 2)
-
- # input of shape (seq_len, batch, input_size):(当前批次的样本个数, 当前样本的序列长度(单词个数), 词嵌入维度)
- # input输入数据,torch.randn(当前批次的样本个数, 当前样本的序列长度(单词个数), 词嵌入维度)
- input = torch.randn(4, 3, 5)
-
- # h_0 of shape (num_layers * num_directions, batch, hidden_size):
- # RNN是单向:(隐藏层层数 * 1, 一个句子单词个数, 隐藏层中神经元数量)
- # RNN是双向:(隐藏层层数 * 2, 一个句子单词个数, 隐藏层中神经元数量)
- # hn隐藏层数据,torch.randn(隐藏层层数, 当前样本的序列长度(单词个数), 隐藏层中神经元数量)
- h0 = torch.randn(2, 3, 6)
-
- # c_0 of shape (num_layers * num_directions, batch, hidden_size)
- # RNN是单向:(隐藏层层数 * 1, 一个句子单词个数, 隐藏层中神经元数量)
- # RNN是双向:(隐藏层层数 * 2, 一个句子单词个数, 隐藏层中神经元数量)
- c0 = torch.randn(2, 3, 6)
-
- output, hn = rnn(input, h0)
- output, (hn, cn) = rnn(input, (h0, c0))
-
- # output of shape (seq_len, batch, num_directions * hidden_size):
- # RNN是单向:(当前批次的样本个数, 当前样本的序列长度(单词个数), 隐藏层中神经元数量 * 1)
- # RNN是双向:(当前批次的样本个数, 当前样本的序列长度(单词个数), 隐藏层中神经元数量 * 2)
- output.shape #torch.Size([4, 3, 6])
-
- # h_n of shape (num_layers * num_directions, batch, hidden_size)
- # RNN是单向:(隐藏层层数 * 1, 一个句子单词个数, 隐藏层中神经元数量)
- # RNN是双向:(隐藏层层数 * 2, 一个句子单词个数, 隐藏层中神经元数量)
- hn.shape #torch.Size([2, 3, 6])
-
- # c_n of shape (num_layers * num_directions, batch, hidden_size)
- # RNN是单向:(隐藏层层数 * 1, 一个句子单词个数, 隐藏层中神经元数量)
- # RNN是双向:(隐藏层层数 * 2, 一个句子单词个数, 隐藏层中神经元数量)
- hn.shape #torch.Size([2, 3, 6])
- ========================================================================
-
- Examples::
- #nn.LSTM(输入数据的词嵌入维度 10, 隐藏层中神经元数量 20, 隐藏层层数 2)
- >>> rnn = nn.LSTM(10, 20, 2)
- #input输入数据,torch.randn(当前批次的样本个数 5, 当前样本的序列长度(单词个数) 3, 词嵌入维度 10)
- >>> input = torch.randn(5, 3, 10)
- #h0/hn隐藏层数据,torch.randn(隐藏层层数 2, 当前样本的序列长度(单词个数) 3, 隐藏层中神经元数量 20)
- >>> h0 = torch.randn(2, 3, 20)
- #c0/cn细胞状态数据,torch.randn(隐藏层层数 2, 当前样本的序列长度(单词个数) 3, 隐藏层中神经元数量 20)
- >>> c0 = torch.randn(2, 3, 20)
- >>> output, (hn, cn) = rnn(input, (h0, c0))
- weight_ih:
- 可学习输入隐藏权重的形状(hidden_size, input_size)
- 每个单词 的嵌入维度的 向量 作为 一个时间步 输入到 一个 RNN 节点,
- 然后 会和 神经元数量维度的 向量 构成一个 可学习输入隐藏权重 这样的 形状 (hidden_size, input_size),
- 就是 (神经元数量, 单词嵌入维度)。
- nn.RNN(输入数据的词嵌入维度, 隐藏层中神经元数量, 隐藏层层数)
- Xt:输入数据,shape为(当前批次的样本个数, 当前样本的序列长度(单词个数), 词嵌入维度影),比如[1,3,5]。
- h0:隐藏层数据,shape为(隐藏层层数, 当前样本的序列长度(单词个数), 隐藏层中神经元数量),比如[1,3,6]。
- [Xt,ht-1]:通过concat(Xt,ht-1)把[1,3,5]和[1,3,6]进行列维度(最后一个维度)的拼接变成[1,3,11]。
- Wt[Xt,ht-1]:concat拼接后的[1,3,11]乘以Wt的[11,6]变成[1,3,6]。
- output是hn隐藏层中的最后一层输出,比如:
- 当隐藏层只有一层时,rnn的输出output和隐藏层数据hn 两者完全相同,shape均为[1,3,6]。
- 当隐藏层有多层时,rnn的输出output为隐藏层数据hn中的最后一个二维矩阵,比如hn为[2,3,6],output的数据实际为hn中最后一个二维矩阵[1,3,6]。
- 1.激活函数sigmiod的作用:用于帮助调节流经网络的值, sigmoid函数将值压缩在0和1之间的小数值(相当于一个百分比值)。
- 只要是sigmiod输出的百分比值(比如ft/it/ot) 都可作为控制阈值(保留信息比例值),用于控制流经的数据保留多少。
- 2.比如此处的遗忘门中的通过sigmiod输出的ft便是一个0和1之间的小数值,ft用作在“细胞状态更新公式”中的ft*Ct-1,
- 因为ft本身就是一个0和1之间的小数值(相当于一个百分比值),那么ft*Ct-1表示使用ft这个百分值保留多少Ct-1的值。
- 1.激活函数sigmiod的作用:用于帮助调节流经网络的值, sigmoid函数将值压缩在0和1之间的小数值(相当于一个百分比值)。
- 只要是sigmiod输出的百分比值(比如ft/it/ot) 都可作为控制阈值(保留信息比例值),用于控制流经的数据保留多少。
- 2.比如此处输入门中的通过sigmiod输出的it便是一个0和1之间的小数值,it用作在“细胞状态更新公式”中的it*Ct~,
- 因为it本身就是一个0和1之间的小数值(相当于一个百分比值),那么it*Ct~表示使用it这个百分值保留多少Ct~的值。
- 1.激活函数sigmiod的作用:用于帮助调节流经网络的值, sigmoid函数将值压缩在0和1之间的小数值(相当于一个百分比值)。
- 只要是sigmiod输出的百分比值(比如ft/it/ot) 都可作为控制阈值(保留信息比例值),用于控制流经的数据保留多少。
- 2.比如输入门中的通过sigmiod输出的it便是一个0和1之间的小数值,it用作在“细胞状态更新公式”中的it*Ct~,
- 因为it本身就是一个0和1之间的小数值(相当于一个百分比值),那么it*Ct~表示使用it这个百分值保留多少Ct~的值。
- 3.比如遗忘门中的通过sigmiod输出的ft便是一个0和1之间的小数值,ft用作在“细胞状态更新公式”中的ft*Ct-1,
- 因为ft本身就是一个0和1之间的小数值(相当于一个百分比值),那么ft*Ct-1表示使用ft这个百分值保留多少Ct-1的值。
- 1.激活函数sigmiod的作用:用于帮助调节流经网络的值, sigmoid函数将值压缩在0和1之间的小数值(相当于一个百分比值)。
- 只要是sigmiod输出的百分比值(比如ft/it/ot) 都可作为控制阈值(保留信息比例值),用于控制流经的数据保留多少。
- 2.比如此处输出门中的通过sigmiod输出的ot便是一个0和1之间的小数值,ot用作在“输出门更新公式”中的ot*tanh(Ct),
- 因为ot本身就是一个0和1之间的小数值(相当于一个百分比值),那么ot*tanh(Ct)表示使用ot这个百分值保留多少tanh(Ct)的值。
- import torch
- import torch.nn as nn
-
- #nn.RNN(输入数据的词嵌入维度, 隐藏层中神经元数量, 隐藏层层数)
- # rnn = nn.RNN(5, 6, 2)
- rnn = nn.GRU(5, 6, 2)
- #input输入数据,torch.randn(当前批次的样本个数, 当前样本的序列长度(单词个数), 词嵌入维度影)
- input = torch.randn(4, 3, 5)
- #hn隐藏层数据,torch.randn(隐藏层层数, 当前样本的序列长度(单词个数), 隐藏层中神经元数量)
- h0 = torch.randn(2, 3, 6)
- """
- nn.GRU 和 nn.LSTM 和 nn.RNN中,output是hn隐藏层中的最后一层输出,有如下情况:
- 1.当前批量数据只有一个样本的情况:
- 1.当隐藏层只有一层时,rnn的输出output和隐藏层数据hn 两者完全相同,shape均为[1,3,6]。
- 比如output的shape均为[1,3,6],[1,3,6]中的1表示一个样本,3表示样本的序列长度(单词个数),6表示隐藏层中神经元数量。
- 2.当隐藏层有多层时,rnn的输出output实际为多层隐藏层数据hn中的最后一层数据。
- 比如隐藏层有4层,那么hn为[4,3,6],output为[1,3,6],hn的[4,3,6]中的4表示4层的隐藏层数据,
- output的[1,3,6]实际为4层隐藏层中最后一层隐藏层的数据,即output的[1,3,6]中的[3,6]实际和hn中最后一个二维矩阵数据相同。
- 2.当前批量数据有多个样本的情况:
- 1.当隐藏层只有一层,批量数据有4个样本时,比如output.shape为[4, 3, 6],hn.shape为[1, 3, 6],
- output的[4, 3, 6]中的4表示4个样本的输出数据,hn的[1, 3, 6]实际是批量数据样本中最后一个样本的输出数据,
- 即hn的[1, 3, 6]中的[3,6]实际和output中最后一个二维矩阵数据相同。
- 2.当隐藏层有多层时,比如有2层隐藏层,批量数据有4个样本时,output.shape为[4, 3, 6],hn.shape为[2, 3, 6]。
- output的[4, 3, 6]中的4表示4个样本的输出数据,hn的[2, 3, 6]中的2表示2层隐藏层数据,
- 只有output中的最后一个二维矩阵和hn中的最后一个二维矩阵相同,因为output是hn隐藏层中的最后一层输出的关系,
- 那么批量样本输出数据output中最后一个样本的输出数据和hn隐藏层中的最后一层的隐藏层数据相同。
- """
- output, hn = rnn(input, h0)
-
- print("output.shape",output.shape)
- print("hn.shape",hn.shape)
- print("output",output)
- print("hn",hn)
- import torch.nn as nn
- import torch
- #nn.LSTM(输入数据的词嵌入维度, 隐藏层中神经元数量, 隐藏层层数)
- rnn = nn.LSTM(5, 6, 2)
- #input输入数据,torch.randn(当前批次的样本个数, 当前样本的序列长度(单词个数), 词嵌入维度影)
- input = torch.randn(4, 3, 5)
- #hn隐藏层数据,torch.randn(隐藏层层数, 当前样本的序列长度(单词个数), 隐藏层中神经元数量)
- h0 = torch.randn(2, 3, 6)
- #cn细胞状态数据,torch.randn(隐藏层层数, 当前样本的序列长度(单词个数), 隐藏层中神经元数量)
- c0 = torch.randn(2, 3, 6)
-
- """
- nn.GRU 和 nn.LSTM 和 nn.RNN中,output是hn隐藏层中的最后一层输出,有如下情况:
- 1.当前批量数据只有一个样本的情况:
- 1.当隐藏层只有一层时,rnn的输出output和隐藏层数据hn 两者完全相同,shape均为[1,3,6]。
- 比如output的shape均为[1,3,6],[1,3,6]中的1表示一个样本,3表示样本的序列长度(单词个数),6表示隐藏层中神经元数量。
- 2.当隐藏层有多层时,rnn的输出output实际为多层隐藏层数据hn中的最后一层数据。
- 比如隐藏层有4层,那么hn为[4,3,6],output为[1,3,6],hn的[4,3,6]中的4表示4层的隐藏层数据,
- output的[1,3,6]实际为4层隐藏层中最后一层隐藏层的数据,即output的[1,3,6]中的[3,6]实际和hn中最后一个二维矩阵数据相同。
- 2.当前批量数据有多个样本的情况:
- 1.当隐藏层只有一层,批量数据有4个样本时,比如output.shape为[4, 3, 6],hn.shape为[1, 3, 6],
- output的[4, 3, 6]中的4表示4个样本的输出数据,hn的[1, 3, 6]实际是批量数据样本中最后一个样本的输出数据,
- 即hn的[1, 3, 6]中的[3,6]实际和output中最后一个二维矩阵数据相同。
- 2.当隐藏层有多层时,比如有2层隐藏层,批量数据有4个样本时,output.shape为[4, 3, 6],hn.shape为[2, 3, 6]。
- output的[4, 3, 6]中的4表示4个样本的输出数据,hn的[2, 3, 6]中的2表示2层隐藏层数据,
- 只有output中的最后一个二维矩阵和hn中的最后一个二维矩阵相同,因为output是hn隐藏层中的最后一层输出的关系,
- 那么批量样本输出数据output中最后一个样本的输出数据和hn隐藏层中的最后一层的隐藏层数据相同。
- """
- output, (hn, cn) = rnn(input, (h0, c0))
-
- print("output.shape",output.shape)
- print("hn.shape",hn.shape)
- print("cn.shape",cn.shape)
- print("output",output)
- print("hn",hn)
- print("cn",cn)
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。