PyTorch中Conv2d导致输入维度缩减问题及解决咨询
文本CNN中Conv2d形状变化的原因与解决方法
形状变化的原因
你的输入张量x初始形状是[4, 39, 768],对应batch_size=4,句子长度=39,嵌入维度=768。执行x.unsqueeze(1)后,形状变为[4, 1, 39, 768],这是为了适配Conv2d的输入格式([batch_size, in_channels, height, width])。
再看你的Conv2d参数:kernel_size=(3, 768),意味着卷积核在句子长度维度(height)取3个词的窗口,在嵌入维度(width)完全覆盖。PyTorch的Conv2d默认padding=0、stride=1,输出维度的计算公式为:
输出维度 = (输入维度 - 核大小 + 2*padding) / stride + 1
代入句子长度维度的数值:
输出长度 = (39 - 3 + 0) / 1 + 1 = 37
嵌入维度的计算:
输出宽度 = (768 - 768 + 0) / 1 + 1 = 1
所以卷积后的张量形状是[4, 100, 37, 1],经过squeeze(3)去掉最后一维后变成[4, 100, 37],再通过permute(0,2,1)转置维度,最终得到[4, 37, 100]——这就是句子长度从39变成37的原因。
保持形状不变的解决方案
要保留原有的句子长度(39),只需要在Conv2d中设置合适的padding参数。针对你的卷积核大小,在句子长度维度(height)添加padding=1(首尾各补1个位置),嵌入维度(width)不需要补(padding=0),这样就能让卷积后句子长度保持不变。
修改后的初始化代码:
self.conv = nn.Conv2d(1, params.hidden_dim, kernel_size=(3, params.embedding_dim), padding=(1, 0)) nn.init.xavier_uniform_(self.conv.weight) nn.init.constant_(self.conv.bias, 0.0) self.fc = nn.Linear(params.hidden_dim, params.num_of_tags)
此时前向传播的形状变化:
x.unsqueeze(1)后形状:[4,1,39,768]- 卷积后形状:
[4,100,39,1](计算:(39-3+2*1)/1 +1=39) squeeze(3)后形状:[4,100,39]permute(0,2,1)后形状:[4,39,100]
这种方式不需要事后填充,而是通过卷积padding让模型覆盖到句子首尾的词,避免边缘信息丢失,比手动填充更合理。
内容的提问来源于stack exchange,提问作者jan.kowalski901
相关产品推荐
相关产品推荐

