在 PyTorch 中创建具有多个通道的简单 1D CNN

Posted

技术标签:

【中文标题】在 PyTorch 中创建具有多个通道的简单 1D CNN【英文标题】:Creating a Simple 1D CNN in PyTorch with Multiple Channels 【发布时间】:2019-09-07 06:46:14 【问题描述】:

PyTorch 输入的维度不是模型所期望的,我不确定为什么。

据我了解...

in_channels 首先是我们想要传递给模型的一维输入的数量,并且是所有后续层的前一个 out_channel。

out_channels 是所需的内核(过滤器)数量。

kernel_size 是每个过滤器的参数数量。

因此,作为传递给转发的数据,我们希望数据集具有 7 个 1D 通道(即 2D 输入)。

但是,下面的代码抛出了一个与我预期不一致的错误,这里代码:

import numpy
import torch

X = numpy.random.uniform(-10, 10, 70).reshape(-1, 7)
# Y = np.random.randint(0, 9, 10).reshape(-1, 1)

class Simple1DCNN(torch.nn.Module):
    def __init__(self):
        super(Simple1DCNN, self).__init__()
        self.layer1 = torch.nn.Conv1d(in_channels=7, out_channels=20, kernel_size=5, stride=2)
        self.act1 = torch.nn.ReLU()
        self.layer2 = torch.nn.Conv1d(in_channels=20, out_channels=10, kernel_size=1)
    def forward(self, x):
        x = self.layer1(x)
        x = self.act1(x)
        x = self.layer2(x)

        log_probs = torch.nn.functional.log_softmax(x, dim=1)

        return log_probs

model = Simple1DCNN()
print(model(torch.tensor(X)).size)

抛出以下错误:

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-5-eca5856a2314> in <module>()
     21 
     22 model = Simple1DCNN()
---> 23 print(model(torch.tensor(X)).size)

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    487             result = self._slow_forward(*input, **kwargs)
    488         else:
--> 489             result = self.forward(*input, **kwargs)
    490         for hook in self._forward_hooks.values():
    491             hook_result = hook(self, input, result)

<ipython-input-5-eca5856a2314> in forward(self, x)
     12         self.layer2 = torch.nn.Conv1d(in_channels=20, out_channels=10, kernel_size=1)
     13     def forward(self, x):
---> 14         x = self.layer1(x)
     15         x = self.act1(x)
     16         x = self.layer2(x)

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    487             result = self._slow_forward(*input, **kwargs)
    488         else:
--> 489             result = self.forward(*input, **kwargs)
    490         for hook in self._forward_hooks.values():
    491             hook_result = hook(self, input, result)

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/torch/nn/modules/conv.py in forward(self, input)
    185     def forward(self, input):
    186         return F.conv1d(input, self.weight, self.bias, self.stride,
--> 187                         self.padding, self.dilation, self.groups)
    188 
    189 

RuntimeError: Expected 3-dimensional input for 3-dimensional weight [20, 7, 5], but got 2-dimensional input of size [10, 7] instead

编辑:由 Shai 推动的解决方案见下文。

import numpy
import torch

X = numpy.random.uniform(-10, 10, 70).reshape(1, 7, -1)
# Y = np.random.randint(0, 9, 10).reshape(1, 1, -1)

class Simple1DCNN(torch.nn.Module):
    def __init__(self):
        super(Simple1DCNN, self).__init__()
        self.layer1 = torch.nn.Conv1d(in_channels=7, out_channels=20, kernel_size=5, stride=2)
        self.act1 = torch.nn.ReLU()
        self.layer2 = torch.nn.Conv1d(in_channels=20, out_channels=10, kernel_size=1)
    def forward(self, x):
        x = self.layer1(x)
        x = self.act1(x)
        x = self.layer2(x)

        log_probs = torch.nn.functional.log_softmax(x, dim=1)

        return log_probs

model = Simple1DCNN().double()
print(model(torch.tensor(X)).shape)

【问题讨论】:

你应该批量规范 【参考方案1】:

您忘记了“小批量维度”,每个“一维”样本确实有两个维度:通道数(在您的示例中为 7)和长度(在您的示例中为 10)。但是,pytorch 期望的输入不是单个样本,而是沿“小批量维度”堆叠在一起的 B 小批量样本。 因此,pytorch 中的“1D”CNN 需要一个 3D 张量作为输入:BxCxT。如果你只有一个信号,你可以添加一个单一的维度:

 out = model(torch.tensor(X)[None, ...])

【讨论】:

以上是关于在 PyTorch 中创建具有多个通道的简单 1D CNN的主要内容,如果未能解决你的问题,请参考以下文章

我是否需要在PyTorch中创建多个神经网络实例来测试多个损失函数?

具有多个工作人员的可迭代 pytorch 数据集

具有多个值的张量的布尔值在 Pytorch 中不明确

我不明白 conv1d、conv2d 的 pytorch 输入大小

如何在 Dataloader 类之外的 pytorch 中创建数据预处理管道?

在 pytorch 中创建数据集时如何关闭某些类?