【问题标题】:Best input size of a the first layer 1D CNN第一层 1D CNN 的最佳输入大小
【发布时间】:2021-05-10 22:27:07
【问题描述】:

我正在尝试构建具有时间序列的一维 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)

据我了解,这迫使我将输入分成 50 个时间点的 10 个片段。我理解错了吗?用 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 秒的单导 ECG(心电图)信号。这是对听觉电信号的记录。这是样本的外观(绘制在 2D 图表上)的想法,其中 x 轴上有时间,y 轴上有电压/幅度

【问题讨论】:

    标签: python machine-learning pytorch conv-neural-network


    【解决方案1】:

    试试

        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 = 自然语言处理?酷!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多