在一些分析时态数据(例如音频或视频)的深度学习模型中,我们使用“时间分布密集”(TDD)层。这样创建的是一个完全连接的(密集)层,该层分别应用于每个时间步。
在Keras中,可以使用TimeDistributed wrapper来完成此操作,实际上,它更为通用。在PyTorch中,an open feature request已经存在了两年。
我们如何在PyTorch中手动实现时间分布密集?
答案 0 :(得分:2)
正如您在 discussion 中所指出的:
<块引用>与此同时,这个 #1935 将使线性层不需要 TimeDistributed/Bottle。
对于 TDD 层,它将直接在具有时间片的输入上应用线性层。
In [1]: import torch
In [2]: m = torch.nn.Linear(20, 30)
In [3]: input = torch.randn(128, 5, 20)
In [4]: output = m(input)
In [5]: print(output.size())
torch.Size([128, 5, 30])
以下是计算结果的简短说明
In [1]: import torch
In [2]: m = torch.nn.Linear(2, 3, bias=False)
...:
...: for name, param in m.named_parameters():
...: print(name)
...: print(param)
...:
weight
Parameter containing:
tensor([[-0.3713, -0.1113],
[ 0.2938, 0.4709],
[ 0.2791, 0.5355]], requires_grad=True)
In [3]: input = torch.stack([torch.ones(3, 2), 2 * torch.ones(3, 2)], dim=0)
...: print(input)
tensor([[[1., 1.],
[1., 1.],
[1., 1.]],
[[2., 2.],
[2., 2.],
[2., 2.]]])
In [4]: m(input)
Out[4]:
tensor([[[-0.4826, 0.7647, 0.8145],
[-0.4826, 0.7647, 0.8145],
[-0.4826, 0.7647, 0.8145]],
[[-0.9652, 1.5294, 1.6291],
[-0.9652, 1.5294, 1.6291],
[-0.9652, 1.5294, 1.6291]]], grad_fn=<UnsafeViewBackward>)
nn.Linear
操作的更多细节可以从 torch.matmul
中看到。请注意,您可能需要添加另一个非线性函数,如 torch.tanh()
以获得与 Dense()
中的 Keras
完全相同的层,它们支持关键字参数 {{1} }.
对于带有例如 CNN 层的 Timedistributed,也许 PyTorch forum 中的片段可能有用。
答案 1 :(得分:1)
专门针对时间分布密集的(而不是时间分布其他),我们可以使用卷积层对其进行破解。
看一下您显示的TDD层图。我们可以将其重新想象为一个卷积层,其中卷积核的“宽度”(时间上)正好为1,并且“高度”与张量的整个高度匹配。如果这样做,同时还要确保我们的内核不允许移动超出张量的边缘,它应该可以工作:
self.tdd = nn.Conv2d(1, num_of_output_channels, (num_of_input_channels, 1))
您可能需要重新布置张量轴。这行代码的“输入通道”实际上来自张量的“频率”轴(“图像的y轴”),“输出通道”的确将布置在“通道”轴上。 (输出的“ y轴”将为高度为1的单例尺寸。)