gpt4 book ai didi

machine-learning - Pytorch 中 GRU 单元的隐藏和输出是否相同?

转载 作者:行者123 更新时间:2023-11-30 09:04:13 27 4
gpt4 key购买 nike

我确实从概念上理解 LSTM 或 GRU 应该做什么(感谢这个问题 What's the difference between "hidden" and "output" in PyTorch LSTM? )但是当我检查 GRU 的输出时 h_noutput 不是相同,而他们应该...

(Pdb) rnn_output
tensor([[[ 0.2663, 0.3429, -0.0415, ..., 0.1275, 0.0719, 0.1011],
[-0.1272, 0.3096, -0.0403, ..., 0.0589, -0.0556, -0.3039],
[ 0.1064, 0.2810, -0.1858, ..., 0.3308, 0.1150, -0.3348],
...,
[-0.0929, 0.2826, -0.0554, ..., 0.0176, -0.1552, -0.0427],
[-0.0849, 0.3395, -0.0477, ..., 0.0172, -0.1429, 0.0153],
[-0.0212, 0.1257, -0.2670, ..., -0.0432, 0.2122, -0.1797]]],
grad_fn=<StackBackward>)
(Pdb) hidden
tensor([[[ 0.1700, 0.2388, -0.4159, ..., -0.1949, 0.0692, -0.0630],
[ 0.1304, 0.0426, -0.2874, ..., 0.0882, 0.1394, -0.1899],
[-0.0071, 0.1512, -0.1558, ..., -0.1578, 0.1990, -0.2468],
...,
[ 0.0856, 0.0962, -0.0985, ..., 0.0081, 0.0906, -0.1234],
[ 0.1773, 0.2808, -0.0300, ..., -0.0415, -0.0650, -0.0010],
[ 0.2207, 0.3573, -0.2493, ..., -0.2371, 0.1349, -0.2982]],

[[ 0.2663, 0.3429, -0.0415, ..., 0.1275, 0.0719, 0.1011],
[-0.1272, 0.3096, -0.0403, ..., 0.0589, -0.0556, -0.3039],
[ 0.1064, 0.2810, -0.1858, ..., 0.3308, 0.1150, -0.3348],
...,
[-0.0929, 0.2826, -0.0554, ..., 0.0176, -0.1552, -0.0427],
[-0.0849, 0.3395, -0.0477, ..., 0.0172, -0.1429, 0.0153],
[-0.0212, 0.1257, -0.2670, ..., -0.0432, 0.2122, -0.1797]]],
grad_fn=<StackBackward>)

它们是彼此的转置...为什么?

最佳答案

它们实际上并不相同。考虑我们有以下单向 GRU 模型:

import torch.nn as nn
import torch

gru = nn.GRU(input_size = 8, hidden_size = 50, num_layers = 3, batch_first = True)

请确保仔细观察输入形状。

inp = torch.randn(1024, 112, 8)
out, hn = gru(inp)

当然,

torch.equal(out, hn)
False

帮助我理解输出与隐藏状态的最有效方法之一是将 hn 查看为 hn.view(num_layers, num_directions, batch, hide_size) 其中 num_directions = 2 用于双向循环网络(以及其他 1 个,即我们的情况)。因此,

hn_conceptual_view = hn.view(3, 1, 1024, 50)

正如文档所述(注意斜体粗体):

h_n of shape (num_layers * num_directions, batch, hidden_size): tensor containing the hidden state for t = seq_len (i.e., for the last timestep)

在我们的例子中,它包含时间步长 t = 112 的隐藏向量,其中:

output of shape (seq_len, batch, num_directions * hidden_size): tensor containing the output features h_t from the last layer of the GRU, for each t. If a torch.nn.utils.rnn.PackedSequence has been given as the input, the output will also be a packed sequence. For the unpacked case, the directions can be separated using output.view(seq_len, batch, num_directions, hidden_size), with forward and backward being direction 0 and 1 respectively.

因此,人们可以这样做:

torch.equal(out[:, -1], hn_conceptual_view[-1, 0, :, :])
True

解释:我将 out[:, -1] 中所有批处理的最后一个序列与 hn[-1, 0,:,:]

<小时/>

对于双向 GRU(需要先读取单向):

gru = nn.GRU(input_size = 8, hidden_size = 50, num_layers = 3, batch_first = True bidirectional = True)
inp = torch.randn(1024, 112, 8)
out, hn = gru(inp)

View 更改为(因为我们有两个方向):

hn_conceptual_view = hn.view(3, 2, 1024, 50)

如果您尝试确切的代码:

torch.equal(out[:, -1], hn_conceptual_view[-1, 0, :, :])
False

解释:这是因为我们甚至比较了错误的形状;

out[:, 0].shape
torch.Size([1024, 100])
hn_conceptual_view[-1, 0, :, :].shape
torch.Size([1024, 50])

请记住,对于双向网络,隐藏状态会在第一个 hidden_​​state 大小(即 out[:, 0, :50])是前向网络的隐藏状态,其他 hidden_​​state 大小用于后向网络(即 out[:, 0, 50:])。 前向网络的正确比较是:

torch.equal(out[:, -1, :50], hn_conceptual_view[-1, 0, :, :])
True

如果您想要后向网络的隐藏状态,并且 since a backward network processes the sequence from time step n ... 1 。您比较序列的第一个时间步和最后一个 hidden_​​state 大小,并将 hn_conceptual_view 方向更改为 1:

torch.equal(out[:, -1, :50], hn_conceptual_view[-1, 1, :, :])
True
<小时/>

简而言之,一般来说:

单向:

rnn_module = nn.RECURRENT_MODULE(num_layers = X, hidden_state = H, batch_first = True)
inp = torch.rand(B, S, E)
output, hn = rnn_module(inp)
hn_conceptual_view = hn.view(X, 1, B, H)

其中 RECURRENT_MODULE 是 GRU 或 LSTM(在撰写本文时),B 是批量大小,S 序列长度和 E 嵌入大小。

torch.equal(output[:, S, :], hn_conceptual_view[-1, 0, :, :])
True

我们再次使用S,因为rnn_module是正向的(即单向),并且最后一个时间步存储在序列长度S处。

双向:

rnn_module = nn.RECURRENT_MODULE(num_layers = X, hidden_state = H, batch_first = True, bidirectional = True)
inp = torch.rand(B, S, E)
output, hn = rnn_module(inp)
hn_conceptual_view = hn.view(X, 2, B, H)

比较

torch.equal(output[:, S, :H], hn_conceptual_view[-1, 0, :, :])
True

上面是前向网络比较,我们使用 :H 因为前向将其隐藏向量存储在每个时间步的第一个 H 元素中。

对于后向网络:

torch.equal(output[:, 0, H:], hn_conceptual_view[-1, 1, :, :])
True

我们将 hn_conceptual_view 中的方向更改为 1 以获取后向网络的隐藏向量。

<小时/>

对于所有示例,我们都使用 hn_conceptual_view[-1, ...],因为我们只对最后一层感兴趣。

关于machine-learning - Pytorch 中 GRU 单元的隐藏和输出是否相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56677052/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com