PyTorch AutoEncoder报错:mat1与mat2无法相乘(1x512和12x64)
解决AutoDecoder输入形状不匹配导致的矩阵相乘错误
我通过Hook提取CNN输出的特征并转换为张量:extracted_features = torch.tensor(rn_output),转换后张量尺寸为torch.Size([1014,512])。但AutoEncoder的decoder报出“无法相乘”错误,问题源于输入设置与形状逻辑错误。
原AutoEncoder代码
class AutoEncoder(nn.Module): def __init__(self): super(AutoEncoder, self).__init__() self.encoder = nn.Sequential( nn.Linear(in_features=512, out_features=256), nn.ReLU(), nn.Linear(in_features=256, out_features=128), nn.ReLU(), nn.Linear(in_features=128, out_features=64), nn.ReLU(), nn.Linear(in_features=64, out_features=12), ) self.decoder = nn.Sequential( nn.Linear(in_features=12, out_features=64), nn.ReLU(), nn.Linear(in_features=64, out_features=128), nn.Linear(in_features=128, out_features=256), nn.ReLU(), nn.Linear(in_features=256, out_features=512), nn.Tanh() ) def forward(self, x): encoded = self.encoder(x) decoded = self.decoder(x) return decoded
原调用代码
model = AutoEncoder() criterion = nn.MSELoss() optimiser = torch.optim.Adam(model.parameters(), lr=1e-3, weight_decay=1e-5) num_epochs = 10 outputs = [] for epoch in range(num_epochs): for (img) in extracted_features: recon = model(img) loss = criterion(recon, img) optimiser.zero_grad() loss.backward() optimiser.step() print(f'Epoch:{epoch+1}, Loss:{loss.item():.4f}') outputs.append((epoch, img, recon))
问题分析
- forward逻辑错误:解码器接收的是原始输入
x(维度512),但解码器第一层Linear(in_features=12)要求输入维度为12,直接导致矩阵维度不匹配,触发相乘错误。 - 单样本输入维度错误:遍历
extracted_features时,每个img是一维张量[512],PyTorch的Linear层默认处理二维批量输入[batch_size, feature_dim],单样本会被误判为[512, 1],进一步引发维度冲突。
修复方案
1. 修正forward方法逻辑
将编码器的输出传给解码器,而不是原始输入:
def forward(self, x): encoded = self.encoder(x) decoded = self.decoder(encoded) # 用编码后的特征作为解码器输入 return decoded
2. 调整输入维度为批量格式
直接使用二维张量批量输入,或用DataLoader包装:
from torch.utils.data import TensorDataset, DataLoader # 用DataLoader包装特征张量,按批次处理 dataset = TensorDataset(extracted_features) dataloader = DataLoader(dataset, batch_size=32, shuffle=True) num_epochs = 10 outputs = [] for epoch in range(num_epochs): total_loss = 0.0 for batch in dataloader: x = batch[0] # 取出批次特征,维度为[32, 512] recon = model(x) loss = criterion(recon, x) optimiser.zero_grad() loss.backward() optimiser.step() total_loss += loss.item() avg_loss = total_loss / len(dataloader) print(f'Epoch:{epoch+1}, Loss:{avg_loss:.4f}') outputs.append((epoch, x, recon))
3. 额外检查
确保extracted_features的数据类型(如float32)与模型参数一致,避免类型不匹配问题。
内容的提问来源于stack exchange,提问作者Mark McAllister
相关产品推荐
相关产品推荐

