Pytorch:RNN、LSTM、GRU

日萌社

人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新)


#模型中最后一层隐藏层的最后一个时间步(节点)的输出output可作为预测值,然后通过softmax把output输出转换为概率值
#for循环遍历出来的input可以是字符,也可以是单词,那么模型可以是字符输入版本,也可以是单词输入版本
for input in range(lines):
	output, hidden = RNN实例对象(input, hidden)
	output, hidden = GRU实例对象(input, hidden)
	output, (hidden, cn) = LSTM实例对象(input, (hidden, cn)) 
	encoder_output, encoder_hidden = encoder(encoder_input, encoder_hidden)
	decoder_output, decoder_hidden, decoder_attention = decoder(decoder_input, decoder_hidden, encoder_outputs)

# nn.RNN(输入数据的词嵌入维度input_size, 隐藏层中神经元数量hidden_size, 隐藏层层数num_layers)
rnn = nn.RNN(5, 6, 2)
gru = nn.GRU(5, 6, 2)
lstm = nn.LSTM(5, 6, 2)
	input_size: 每一个时步(time_step)输入到RNN/GRU/LSTM单元的维度,实际输入的数据shape为(当前批次的样本个数, 当前样本的序列长度(单词个数), 词嵌入维度)
	hidden_size: 确定了隐含状态hidden_state的维度,可以简单的看成构造了一个可学习输入隐藏权重的形状(hidden_size, input_size)

weight_ih: 
    可学习输入隐藏权重的形状(hidden_size, input_size)
    每个单词 的嵌入维度的 向量 作为 一个时间步 输入到 一个 RNN 节点,
    然后 会和 神经元数量维度的 向量 构成一个 可学习输入隐藏权重 这样的 形状 (hidden_size, input_size),
    就是 (神经元数量, 单词嵌入维度)。
    比如input输入数据为(当前批次的样本个数, 当前样本的序列长度(单词个数), 词嵌入维度),
    那么input_size即为input输入数据的最后一个维度即词嵌入维度,
    那么每个时间步的输入维度input_size(一个单词的词嵌入维度embedding_dim) 都要作用于 隐藏层的所有隐藏神经元hidden_size, 
    那么便会构建一个(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)
gru = nn.GRU(5, 6, 2)
lstm = 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))

LSTM输出API为:output,(h_n,c_n)=self.rnn(x)
	1.output: 如果num_layer为3,则output只记录最后一层(即第三层)的输出
		对应图中向上的各个time_step的ht,也即output。
		(seq_len, batch, num_directions * hidden_size):
			RNN是单向:(当前批次的样本个数, 当前样本的序列长度(单词个数), 隐藏层中神经元数量 * 1)	
			RNN是双向:(当前批次的样本个数, 当前样本的序列长度(单词个数), 隐藏层中神经元数量 * 2)		
 
	2.h_n: 各个层的最后一个时步的隐含状态h
		shape为[num_layers, batch_size, hidden_size]。
		(num_layers * num_directions, batch, hidden_size)
			RNN是单向:(隐藏层层数 * 1, 一个句子单词个数, 隐藏层中神经元数量)	
			RNN是双向:(隐藏层层数 * 2, 一个句子单词个数, 隐藏层中神经元数量)
 
	3.c_n: 各个层的最后一个时步的隐含状态C
		c_n可以看成另一个隐含状态,其shape和h_n的shape相同。
 		(num_layers * num_directions, batch, hidden_size)
			RNN是单向:(隐藏层层数 * 1, 一个句子单词个数, 隐藏层中神经元数量)	
			RNN是双向:(隐藏层层数 * 2, 一个句子单词个数, 隐藏层中神经元数量)

RNN

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]。


LSTM

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)的值。


GRU

  

发布了460 篇原创文章 · 获赞 163 · 访问量 24万+

猜你喜欢

转载自blog.csdn.net/zimiao552147572/article/details/105604107