Python 第一层1D CNN的最佳输入大小

Python 第一层1D CNN的最佳输入大小,python,machine-learning,pytorch,conv-neural-network,Python,Machine Learning,Pytorch,Conv Neural Network,我正试图用时间序列建立一个1D CNN。输入长度为500。有(只有)2个标签。到目前为止,我构建的架构如下:有3个卷积层,每个层后面都有一个激活层。第一个卷积层采用50个通道作为输入 import torch import torch.nn as nn import numpy as np import random class Simple1DCNN3(torch.nn.Module): def __init__(self): super(Simple1DCNN5,

我正试图用时间序列建立一个1D CNN。输入长度为500。有(只有)2个标签。到目前为止,我构建的架构如下:有3个卷积层,每个层后面都有一个激活层。第一个卷积层采用50个通道作为输入


import torch
import torch.nn as nn
import numpy as np
import random

class Simple1DCNN3(torch.nn.Module):
    def __init__(self):
        super(Simple1DCNN5, self).__init__()
        self.sequence = nn.Sequential(
            torch.nn.Conv1d(in_channels=50, 
                                          out_channels=64, 
                                          kernel_size=5, 
                                          stride=2),
            torch.nn.ReLU(),
            torch.nn.Conv1d(in_channels=64, 
                                          out_channels=128, 
                                          kernel_size=3),
            torch.nn.ReLU(),
            torch.nn.Conv1d(in_channels=128, 
                                          out_channels=256, 
                                          kernel_size=1),
            torch.nn.ReLU(),
        )
        self.fc1 = nn.Linear(256, 2)

        

    def forward(self, x):
        x = x.view(1, 50,-1)
        
        for layer in self.sequence:
            x = layer(x)
            print(x.size())
        x = x.view(1,-1)
        #print(x.size())
        x = self.fc1(x)
        #print(x.size())
        return x

net = Simple1DCNN3()

input_try = np.random.uniform(-10, 10, 500)
input_try = torch.from_numpy(input_try).float()
net(input_try)
print("input successfull passed to net")
input_try_modif = input_try.view(1, 50,-1)
print(input_try.shape)
print(input_try_modif.shape)

据我所知,这迫使我将输入分成10段50个时间点。我理解错了吗?用500个通道作为输入并使用滑动窗口内核构建第一层不是更明智吗?我在下面的其他脚本中尝试了它,但得到了以下错误消息


import torch
import torch.nn as nn
import numpy as np
import random

class Simple1DCNN4(torch.nn.Module):
    def __init__(self):
        super(Simple1DCNN5, self).__init__()
        self.sequence = nn.Sequential(
            torch.nn.Conv1d(in_channels=500, 
                                          out_channels=64, 
                                          kernel_size=5, 
                                          stride=2),
            torch.nn.ReLU(),
            torch.nn.Conv1d(in_channels=64, 
                                          out_channels=128, 
                                          kernel_size=3),
            torch.nn.ReLU(),
            torch.nn.Conv1d(in_channels=128, 
                                          out_channels=256, 
                                          kernel_size=1),
            torch.nn.ReLU(),
        )
        self.fc1 = nn.Linear(256, 2)

        

    def forward(self, x):
        x = x.view(1, 50,-1)
        
        for layer in self.sequence:
            x = layer(x)
            print(x.size())
        x = x.view(1,-1)
        #print(x.size())
        x = self.fc1(x)
        #print(x.size())
        return x

net = Simple1DCNN4()

input_try = np.random.uniform(-10, 10, 500)
input_try = torch.from_numpy(input_try).float()
net(input_try)
print("input successfull passed to net")
input_try_modif = input_try.view(1, 50,-1)
print(input_try.shape)
print(input_try_modif.shape)

错误消息:

RuntimeError: Given groups=1, weight of size [64, 500, 5], expected input[1, 50, 10] to have 500 channels, but got 50 channels instead
编辑

感谢@ghchoi的回答,这里是工作内核的代码。为此,我还必须将所有卷积层的内核大小更改为1

class Simple1DCNN5(torch.nn.Module):
    def __init__(self):
        super(Simple1DCNN5, self).__init__()
        self.sequence = nn.Sequential(
            torch.nn.Conv1d(in_channels=500, 
                                          out_channels=64, 
                                          kernel_size=1, 
                                          stride=2),
            torch.nn.ReLU(),
            torch.nn.Conv1d(in_channels=64, 
                                          out_channels=128, 
                                          kernel_size=1),
            torch.nn.ReLU(),
            torch.nn.Conv1d(in_channels=128, 
                                          out_channels=256, 
                                          kernel_size=1),
            torch.nn.ReLU(),
        )
        self.fc1 = nn.Linear(256, 2)

        

    def forward(self, x):
        x = x.view(1, 500,-1)
        
        for layer in self.sequence:
            x = layer(x)
            #print(x.size())
        x = x.view(1,-1)
        #print(x.size())
        x = self.fc1(x)
        #print(x.size())
        return x
我拥有的数据是2秒的单导心电图信号。这是hear的电信号记录。下面是一个示例的外观(绘制在2D图形上),其中时间在x轴上,电压/振幅在y轴上

试试看

    def forward(self, x):
        x = x.view(1, 500, -1) 

        ...

net = Simple1DCNN4()

input_try = np.random.uniform(-10, 10, 5000)

这样,第一个
Conv1d
的输入将有500个频道。

非常感谢@ghchoi。这解决了问题,尽管我必须将所有卷积层的内核大小设置为1。你对我如何改进神经网络还有什么特别的意见吗?@ecjb你必须从经验上改进你的模型。一个模型可以在一个基准数据集上使用SOTA,但是,它在其他数据集上的性能可能很差。使常用的流行模型适应您的数据通常需要大量的超参数调整。你的数据怎么样?谢谢@ghchoi的建议。我的数据是2秒钟的心电图样本。我在问题中添加了一个理论样本。这是否更清楚?何时是您想要捕获的重要信息?顺便说一句,我是一名NLP研究人员。当信号达到峰值时,我并不比信号的其他部分更感兴趣。事实上,我们并不确切地知道每种模式都有意义。我们更想看看是否有一些隐藏的模式。NLP=自然语言处理?酷!