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

PyTorch含多BatchNorm1d层模型推理报错:期望2D/3D输入,得到1D输入

问题描述

我用PyTorch构建了带多个BatchNorm1d层的Discriminator模型,代码如下:

import torch.nn as nn

class Discriminator(nn.Module):
    def __init__(self, sequenceLength):
        super(Discriminator,self).__init__()
        self.batchnorm1 = nn.BatchNorm1d(sequenceLength)
        self.batchnorm2 = nn.BatchNorm1d(2*sequenceLength)
        self.linear1 = nn.Linear(sequenceLength, 2*sequenceLength)
        self.conv2 = nn.Conv1d(1, 1,kernel_size=3, stride=1, padding=1)
        self.conv3 = nn.Conv1d(1, 1,kernel_size=3, stride=1, padding=1)
        self.linear4 = nn.Linear(2*sequenceLength, 1)
        self.relu = nn.ReLU(0.01)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        out = self.batchnorm1(x)
        out = self.linear1(out)
        out = self.relu(out)
        out = self.batchnorm2(out)
        out = out.unsqueeze(1)
        out = self.conv2(out)
        out = self.sigmoid(out)
        out = self.conv3(out)
        out = self.relu(out)
        out = out.squeeze()
        out = self.batchnorm2(out)
        out = self.linear4(out)
        out = self.sigmoid(out)
        return out

推理代码如下:

import torch

Discriminator = torch.load('disc.pth', map_location=torch.device('cpu'))
Discriminator.eval()
embededSeq = Embedding.EmbedOne('sample data')
embededSeq = torch.tensor(embededSeq).float()
embededSeq = embededSeq.unsqueeze(0)
score = PosDiscriminator(embededSeq).detach().numpy()[0]

推理时在out = self.batchnorm2(out)行触发错误:expected 2D or 3D input (got 1D input)。怀疑是前一行out = out.squeeze()导致,但训练时代码运行正常,仅推理阶段出现问题,恳请帮忙排查错误原因。

问题原因与解决方案

核心原因

训练时输入的是批量数据(例如shape为(batch_size, seq_len)),经过卷积后的张量shape为(batch_size, 1, 2*seq_len),执行无参数squeeze()后会去掉维度为1的轴,得到(batch_size, 2*seq_len)的2D张量,符合BatchNorm1d对输入维度的要求。

但推理时输入的是单样本:embededSeq.unsqueeze(0)后shape为(1, seq_len),经过卷积后张量shape变为(1,1,2*seq_len),此时无参数squeeze()会把所有维度为1的轴全部移除,最终得到(2*seq_len,)的1D张量,而BatchNorm1d要求输入必须是2D((N, C))或3D((N, C, L))格式,因此触发错误。

解决方案

修改forward函数中的squeeze()调用,指定仅移除卷积添加的通道维度(第1维):

# 替换原代码中的 out = out.squeeze()
out = out.squeeze(1)

这样无论输入是单样本还是批量数据,只会去掉索引为1的维度,得到的张量shape为(N, 2*seq_len),完全符合BatchNorm1d的输入要求。

另外注意推理代码中的变量名问题:加载的模型变量名为Discriminator,但调用时使用了PosDiscriminator,需要统一变量名,避免出现"未定义对象"的错误。

内容的提问来源于stack exchange,提问作者Peter Phan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 01:23:26