如何解决Conv1d CNN模型输入尺寸不匹配引发的Runtime Error?
问题描述
我正在使用包含4000个半简单随机点的合成数据集训练CNN模型,每个样本有2个特征,每类对应一个聚类。输入数据x的形状为[4000,2],标签y的形状为[4000]。
我清楚原始输入张量形状为[4000,2](4000为样本总数,2为特征数),Conv1d层需要输入[batch_size,1,2]的3D张量(1为输入通道数,2为序列长度),但经过DataLoader和训练函数处理后,输入变为[1,50,2],引发维度不匹配问题。
CNN模型定义
import torch import torch.nn as nn from torch.utils.data import DataLoader class Net(nn.Module): def __init__(self, Bias): super(Net, self).__init__() self.conv1 = nn.Conv1d(1, 1, kernel_size=1, stride=1) self.relu = nn.ReLU() self.fc1 = nn.Linear(2, 20, bias = False) self.fc2 = nn.Linear(20, 2, bias = False) def forward(self, x): x = self.relu(self.conv1(x)) x = x.reshape(x.size(0), -1) x = self.relu(self.fc1(x)) x = self.fc2(x) return x epochs = 50 alpha = 1e-2 batch_size = 50 criterion = nn.CrossEntropyLoss() # 假设biases是已定义的变量 model = Net(biases).to(device) model = train(model.to(device),criterion,x,y,alpha,epochs,batch_size)
训练函数
def train(model,criterion, x, y, alpha, epochs, batchsize): costs = [] optimizer = torch.optim.SGD(model.parameters(), lr=alpha) trainx, trainy, testx, testy= dataloader(x,y) x=trainx.float() y=trainy.float() data_train = torch.cat((x, y), dim=1) data_train_loader = DataLoader(data_train, batch_size=batchsize, shuffle=True) model.train() j = 0 for i in range(epochs): for index,samples in enumerate(data_train_loader): j += 1 x1 = samples[:,0:2] y1 = samples[:,2].long().reshape(-1,1) if (j%50 == 0): model.eval() acc = accuracy(model,testx,testy) print(f'Test accuracy is #{acc:.2f} , Iteration number is = {j}') model.train() cost = criterion(model(x1), y1.squeeze()) optimizer.zero_grad() cost.backward() optimizer.step() costs.append(float(cost)) return model
错误信息
RuntimeError Traceback (most recent call last) Cell In[17], line 7 5 criterion = nn.CrossEntropyLoss() 6 model = Net(biases).to(device) ----> 7 model=train(model.to(device),criterion,x,y,alpha,epochs,batch_size) Cell In[15], line 40, in train(model, criterion, x, y, alpha, epochs, batchsize) 38 print(f'Test accuracy is #{acc:.2f} , Iteration number is = {j}') 39 model.train() ---> 40 cost = criterion(model(x1), y1.squeeze()) Cell In[16], line 11, in Net.forward(self, x) 10 def forward(self, x): ---> 11 x = self.relu(self.conv1(x)) RuntimeError: Given groups=1, weight of size [1, 1, 1], expected input[1, 50, 2] to have 1 channels, but got 50 channels instead
解决方案
错误核心是Conv1d的输入维度不匹配:PyTorch中Conv1d要求输入格式为[batch_size, in_channels, sequence_length],但当前传入的x1形状是[batch_size, 2](或错误的[1,50,2],本质是通道维度缺失/位置错误),可以通过以下两种方式修复:
方法1:在训练函数中调整输入维度
在获取x1后,添加通道维度,将形状从[batch_size, 2]转为[batch_size, 1, 2]:
x1 = samples[:,0:2] # 添加这一行 x1 = x1.unsqueeze(1) # 形状变为[50,1,2],符合Conv1d要求
方法2:在模型forward方法中调整输入维度
如果不想修改训练函数,可在模型的forward开头添加维度调整,确保输入符合要求:
def forward(self, x): # 添加这一行:如果输入是[batch_size,2],转为[batch_size,1,2] x = x.unsqueeze(1) x = self.relu(self.conv1(x)) x = x.reshape(x.size(0), -1) x = self.relu(self.fc1(x)) x = self.fc2(x) return x
额外说明
- 你的模型中
fc1层的输入维度设置正确:Conv1d输出形状为[batch_size,1,2],经过reshape(x.size(0), -1)后变为[batch_size,2],与fc1(in_features=2)匹配。 - 注意代码中
biases变量需要提前定义,否则会引发未定义错误。
内容的提问来源于stack exchange,提问作者jerry gill
相关产品推荐
相关产品推荐

