如何在PyTorch中实现时间分布密集(TDD)层

时间:2020-04-22 18:38:33

标签: deep-learning pytorch

在一些分析时态数据(例如音频或视频)的深度学习模型中,我们使用“时间分布密集”(TDD)层。这样创建的是一个完全连接的(密集)层,该层分别应用于每个时间步。

在Keras中,可以使用TimeDistributed wrapper来完成此操作,实际上,它更为通用。在PyTorch中,an open feature request已经存在了两年。

我们如何在PyTorch中手动实现时间分布密集

2 个答案:

答案 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的单例尺寸。)