You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于PyTorch的时序数据二分类CNN:输入张量与展平问题咨询

问题解答

1. 输入张量维度

PyTorch中nn.Conv1d要求输入张量形状为(batch_size, in_channels, sequence_length):

  • batch_size:批次内样本数量
  • in_channels:输入的通道数,这里每个样本是单序列(30个传感器测量值组成的时序序列),所以设为1
  • sequence_length:序列长度,即30个测量值的数量

你当前使用的(num_of_samples, 1, 30)是完全正确的,无需调整。之前转成(38,30,1)的步骤是多余的,可以直接从原始的(38,30)一步转成目标形状:

X_train = X_train.reshape(len(X_train), 1, 30)

2. 卷积后展平的问题

你遇到的RuntimeError: mat1 and mat2 shapes cannot be multiplied,核心原因是手动计算的卷积输出维度与实际输出不匹配,导致全连接层输入维度错误。

解决方法:

不要手动计算conv_linear_out,而是用自适应展平:

  • 在forward方法中,用x = x.flatten(1)或者x = x.view(x.size(0), -1)自动展平除了batch维度之外的所有维度,这样不管卷积层怎么调整,都不会出现维度不匹配的问题。

你的代码中的其他问题:

  • 卷积层的nn.Sequential里已经包含了nn.ReLU(),但forward里又叠加了F.leaky_relu,属于重复激活,会导致梯度消失或输出异常,二选一即可(推荐保留leaky_relu,去掉卷积层里的ReLU)。
  • nn.Linear(self.conv_linear_out, self.FN_1, nn.Dropout(0.2))写法错误,nn.Linear的第三个参数不是dropout层,需要把dropout单独作为一层添加到模型中。
  • F.logsigmoid搭配CrossEntropyLoss不合理,CrossEntropyLoss要求最后一层是原始logits,不需要额外激活。

修改后的CNN类示例:

import torch
import torch.nn as nn
import torch.nn.functional as F

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        # 简化卷积层参数,避免冗余操作
        self.conv1 = nn.Sequential(
            nn.Conv1d(1, 16, kernel_size=3, padding=1),
            nn.LeakyReLU(),
            nn.MaxPool1d(kernel_size=2)
        )
        self.conv2 = nn.Sequential(
            nn.Conv1d(16, 32, kernel_size=3, padding=1),
            nn.LeakyReLU(),
            nn.MaxPool1d(kernel_size=2)
        )
        self.dropout = nn.Dropout(0.2)
        # 30经过两次池化(2*2)后长度为30//2//2=7,通道数32,所以输入维度是32*7
        self.fc1 = nn.Linear(32 * 7, 50)
        self.fc2 = nn.Linear(50, 2)

    def forward(self, x):
        x = x.float()
        x = self.conv1(x)
        x = self.conv2(x)
        x = x.flatten(1)  # 自适应展平,batch维度保留,其余维度合并
        x = self.dropout(x)
        x = F.leaky_relu(self.fc1(x))
        x = self.fc2(x)  # CrossEntropyLoss不需要额外激活
        return x

3. CNN结构合理性建议

你的原始模型存在几个冗余或不合理的点:

  • kernel_size=1的卷积层没有提取序列局部特征的作用,相当于线性变换,建议换成kernel_size=2/3,更适合捕捉时序数据的局部模式。
  • MaxPool1d(kernel_size=1)完全没有池化效果,无法降低序列长度和计算量,建议设置为2或3,逐步压缩序列长度。
  • 训练集只有38个样本,模型层数过多(4个卷积层)容易过拟合,建议简化为2-3个卷积层,同时添加dropout层抑制过拟合。
  • 可以尝试调整通道数(比如16、32,不要用17、18这种非2的幂次值,硬件计算更高效)。

额外优化点

  • 数据预处理:对传感器测量值做标准化(比如用sklearn.preprocessing.StandardScaler),让输入数据分布更稳定,加快模型收敛。
  • 损失函数:如果样本不平衡(故障样本少),可以用nn.BCELoss搭配sigmoid激活,或者给CrossEntropyLoss加类别权重。
  • 优化器:SGD的收敛速度较慢,可以尝试Adam优化器,学习率可以调到0.0001-0.001。

内容的提问来源于stack exchange,提问作者Rory Majule

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 07:20:48