卷积融合操作遇IndexError与RuntimeError问题求助
问题描述
执行卷积融合时先后遇到两个错误:
- 初始报错:
IndexError: too many indices for tensor of dimension 2 - 修改索引后报错:
RuntimeError: shape '[10, 1024, 1, 7, 7]' is invalid for input of size 2020
相关代码如下:
class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.spat_feature = spat_model # 预期输出维度:Nx512x7x7 self.temp_feature = temp_model # 预期输出维度:Nx512x7x7 self.layer1 = nn.Sequential(nn.Conv3d(1024, 512, 1, stride=1, padding=1, dilation=1,bias=True), nn.ReLU(),nn.MaxPool3d(kernel_size=2,stride=2)) self.fc = nn.Sequential(nn.Linear(8192,2048), nn.ReLU(), nn.Dropout(p=0.85), nn.Linear(2048, 512), nn.ReLU(), nn.Dropout(p=0.85), nn.Linear(512, 101)) def forward(self,spat_data,temp_data): x1 = self.spat_feature(spat_data) x2 = self.temp_feature(temp_data) y = torch.cat((x1,x2), dim= 1) for i in range(x1.size(1)): #y[i] = self.m[i](y[i]) y[:,(2*i),:,:] = x1[:,i,:,:] # 尝试过把四个冒号改成两个 y[:,(2*i+1)] = x2[:,i,:,:] # 尝试过把四个冒号改成两个 y = y.view(y.size(0), 1024, 1, 7, 7) cnn_out = self.layer1(y) cnn_out = cnn_out.view(cnn_out.size(0),-1) out = self.fc(cnn_out) return out
报错详情
第一个错误Traceback
Traceback (most recent call last): File "conv_fusion.py", line 345, in model = train_model(model, criterion, optimizer,scheduler, num_epochs=20) File "conv_fusion.py", line 167, in train_model outputs = model(spat_data, temp_data) File "/home/el304/.local/lib/python3.6/site-packages/torch/nn/modules/module.py", line 1102, in _call_impl return forward_call(input, **kwargs) File "conv_fusion.py", line 263, in forward y[:,(2i),:,:] = x1[:,i,:,:] IndexError: too many indices for tensor of dimension 2
修改索引后的错误
RuntimeError: shape '[10, 1024, 1, 7, 7]' is invalid for input of size 2020
错误原因及修复方案
1. 第一个错误的核心原因
- 你假设
spat_model和temp_model输出是[N,512,7,7],但实际它们的输出是2维张量(比如[N, 512*7*7]),导致torch.cat后的y也是2维,此时用4个索引访问2维张量自然报错。 - 另外,你已经通过
torch.cat((x1,x2), dim=1)完成了通道维度的拼接,后续的循环赋值完全是冗余操作,毫无意义。
2. 第二个错误的核心原因
- 当你移除索引后,
y的总元素数只有2020,但你试图将其reshape为[10,1024,1,7,7](总元素数为10*1024*7*7=491520),两者大小完全不匹配,本质还是spat_model/temp_model的输出维度和预期不符。
修复步骤
步骤1:验证特征提取模型的输出维度
在forward函数中添加打印语句,确认x1和x2的实际shape:
def forward(self,spat_data,temp_data): x1 = self.spat_feature(spat_data) x2 = self.temp_feature(temp_data) # 打印实际维度,确认是否符合预期[N,512,7,7] print("x1 shape:", x1.shape) print("x2 shape:", x2.shape) # ... 后续代码
如果输出是2维,检查spat_model和temp_model的结构,看是否不小心添加了flatten或全连接层将张量拉平,需要调整模型输出为4维特征图。
步骤2:删除冗余的循环赋值代码
直接删掉这段无意义的循环,保留torch.cat的拼接逻辑即可:
# 移除以下错误且冗余的代码块 # for i in range(x1.size(1)): # y[:,(2*i),:,:] = x1[:,i,:,:] # y[:,(2*i+1)] = x2[:,i,:,:]
步骤3:正确转换为3D卷积所需维度
用unsqueeze添加depth维度(比view更安全,避免张量不连续的问题):
# 替换原来的view语句 y = y.unsqueeze(2) # 将[N,1024,7,7]转换为[N,1024,1,7,7]
步骤4:验证全连接层输入维度
经过layer1的3D卷积和池化后,输出shape应为[N,512,1,4,4],展开后元素数为512*1*4*4=8192,与你定义的全连接层输入一致,这部分无需修改。
内容的提问来源于stack exchange,提问作者方耀廷

