如何在PyTorch中将线性模型转换为Conv1d实现
PyTorch Conv1d维度规则与模型修正方案
核心规则:PyTorch nn.Conv1d 输入输出维度要求
PyTorch的一维卷积层nn.Conv1d要求输入固定为3维张量,格式为:(batch_size, in_channels, sequence_length)
其中:
batch_size:批量大小in_channels:输入的通道数,对应Conv1d初始化的第一个参数sequence_length:序列的长度,也就是每个样本特征在时序/维度方向的长度
输出维度格式和输入一致,为(batch_size, out_channels, sequence_length_out),序列长度的计算公式为:
sequence_length_out = (sequence_length_in + 2*padding - kernel_size) / stride + 1
注:Keras默认的Conv1D输入格式是(batch_size, sequence_length, in_channels),通道在最后一维,这是你两个框架概念混淆的核心原因。
原有问题的根因
你最初的报错是因为:
- Linear层输出的是2维张量
(batch_size, 64),缺少通道维度,不满足Conv1d的3维输入要求 - Conv1d的第一个参数设置为64,和实际输入的通道数不匹配
你后续添加的torch.unsqueeze(x,1)是正确的,作用是给输入新增通道维度,把(batch_size, 26)转为(batch_size, 1, 26),匹配Conv1d的3维输入要求。
符合需求的正确模型示例
你的需求是输入(N,26),输出(N,6),以下是无冗余逻辑的可运行版本:
import torch import torch.nn as nn class corrected_conv_model(nn.Module): def __init__(self, output_dim=6, activation=nn.ReLU): super(corrected_conv_model, self).__init__() self.net = nn.Sequential( # 输入形状:(N, 1, 26) nn.Conv1d(in_channels=1, out_channels=64, kernel_size=5, padding=2), activation(), nn.MaxPool1d(3, stride=1, padding=1), # 输出形状:(N,64,26) nn.Conv1d(in_channels=64, out_channels=32, kernel_size=3, padding=1, stride=2), activation(), nn.MaxPool1d(3, stride=1, padding=1), # 输出形状:(N,32,13) # 拉平特征用来接全连接层 nn.Flatten(), # 32*13 = 416 nn.Linear(416, 64), activation(), nn.Dropout(0.5), nn.Linear(64, output_dim) ) def forward(self, x): # 输入x原始形状:(N, 26),新增通道维度 x = torch.unsqueeze(x, 1) out = self.net(x) return out
调用时不需要额外做squeeze,直接计算损失即可:
model = corrected_conv_model() inputs = torch.randn(10, 26) # batch_size=10 outputs = model(inputs) print(outputs.shape) # 输出为torch.Size([10,6]),符合要求
层衔接注意事项
- 全连接层
nn.Linear作用在张量的最后一维,在Conv1d和Linear衔接时,如果不想保留序列结构,先调用nn.Flatten()把(N, C, L)的3维张量拉平为(N, C*L)的2维张量再喂给Linear - 如果需要在Conv1d之间衔接,只需要保证上一层的输出通道数等于下一层Conv1d的
in_channels参数即可
内容的提问来源于stack exchange,提问作者ALirezaSO
相关产品推荐
相关产品推荐

