Sequential
块的示例代码为
self._encoder = nn.Sequential(
# 1, 28, 28
nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, stride=3, padding=1),
# 32, 10, 10 = 16, (1//3)(28 + 2 * 1 - 3) + 1, (1//3)(28 + 2*1 - 3) + 1
nn.ReLU(True),
nn.MaxPool2d(kernel_size=2, stride=2),
# 32, 5, 5
nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, stride=2, padding=1),
# 64, 3, 3
nn.ReLU(True),
nn.MaxPool2d(kernel_size=2, stride=1),
# 64, 2, 2
)
有没有像nn.Sequential
这样的结构,把模块放在里面并行?
我现在想定义一下
self._mean_logvar_layers = nn.Parallel(
nn.Conv2d(in_channels=64, out_channels=64, kernel_size=2, stride=1, padding=0),
nn.Conv2d(in_channels=64, out_channels=64, kernel_size=2, stride=1, padding=0),
)
它的输出应该是两个数据管道-self._mean_logvar_layers
中的每个元素一个,然后可以馈送到网络的其余部分。有点像一个多头网络。
我目前的实现:
self._mean_layer = nn.Conv2d(in_channels=64, out_channels=64, kernel_size=2, stride=1, padding=0)
self._logvar_layer = nn.Conv2d(in_channels=64, out_channels=64, kernel_size=2, stride=1, padding=0)
和
def _encode(self, x: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
for i, layer in enumerate(self._encoder):
x = layer(x)
mean_output = self._mean_layer(x)
logvar_output = self._logvar_layer(x)
return mean_output, logvar_output
我想把平行结构作为一个层。
这在PyTorch中可行吗?
2条答案
按热度按时间qf9go6mv1#
顺序拆分
你可以做的是创建一个
Parallel
模块(尽管我会给它起不同的名字,因为它暗示了这段代码实际上是并行运行的,也许Split
会是一个好名字),像这样:现在你可以按照你想要的定义它:
然后像这样使用它:
一层一分
正如@xdurch0所建议的那样,我们可以使用一个单一的层,并使用这个模块在通道之间进行分割:
这在你的神经网络中(注意
128
通道,这些通道将被分成2
部分,每个部分的大小为64
):像以前一样使用它:
为什么要这样做?
一切都将在一个一举,而不是顺序,因此更快,但可能会太宽,如果你没有足够的GPU内存。
是否可以使用Sequential?
是的,它仍然是一层。但是下一层必须使用
tuple(torch.Tensor, torch.Tensor)
作为输入。Sequential
也是一个层,非常简单,让我们看看forward
:它只是将输出从前一个模型传递到下一个模型,仅此而已。
thtygnil2#
在@Szymon Maszke的伟大回答之后,这里是完整的相关代码,经过所有的增强:
使用方法:
现在允许子类化VAE并在init时定义不同的编码器。