TensorFlow转PyTorch模型后无法学习的问题排查请求
核心错误:卷积层缺失ReLU激活
原TensorFlow的Conv1D层自带activation='relu',卷积后直接进行非线性激活;但你的PyTorch代码中,Conv1d层输出后没有添加ReLU激活,直接进入池化层。这导致模型缺乏非线性表达能力,无法学习到有效特征,训练陷入随机猜测状态。
次要问题及修复建议
1. 数据类型冗余转换
你的CustomDataset中将文本序列转为torch.Tensor(默认float类型),又在forward中转为LongTensor,可以直接在Dataset中转为LongTensor,减少冗余操作:
class CustomDataset(Dataset): def __init__(self, x, y): self.x = torch.LongTensor(x) # 直接转为LongTensor self.y = torch.FloatTensor(y) def __len__(self): return len(self.y) def __getitem__(self, idx): return self.x[idx], self.y[idx]
同时删除forward中的类型转换:
def forward(self, x): x = self.dropout1(self.embedding(x)) # 无需再转类型 # ... 后续代码不变
2. Dataloader遍历逻辑错误
手动固定steps_per_epoch并调用next(it)会导致超出数据集范围(IMDB训练集25000样本,batch_size=32时实际步数为781),应直接遍历dataloader:
修改fit和predict_proba中的循环逻辑:
# fit方法中的训练循环 for x, y in tqdm(train_dataloader): opt.zero_grad() y_pred = self.model(x).view(-1) loss = crit(y_pred, y) epoch_loss += loss.item() # 准确率计算修改为numpy格式 epoch_acc += accuracy_score(y.cpu().numpy(), (y_pred > 0.5).cpu().numpy()) loss.backward() opt.step() # 计算平均损失和准确率时用len(train_dataloader) avg_loss = epoch_loss / len(train_dataloader) avg_acc = epoch_acc / len(train_dataloader) # predict_proba方法同理 for x, y in tqdm(test_dataloader): with torch.no_grad(): y_pred = self.model(x).view(-1) batch_loss = crit(y_pred, y) val_loss += batch_loss.item() val_acc += accuracy_score(y.cpu().numpy(), (y_pred > 0.5).cpu().numpy()) avg_val_loss = val_loss / len(test_dataloader) avg_val_acc = val_acc / len(test_dataloader)
3. 准确率计算的设备兼容性
使用sklearn.metrics.accuracy_score时,需将Tensor转为numpy数组,避免GPU张量与CPU计算的冲突,如上代码所示。
修改后的完整模型forward方法
def forward(self, x): x = self.dropout1(self.embedding(x)) x = self.conv1d(x.transpose(1, 2)) # 用transpose更安全,替代view x = F.relu(x) # 添加ReLU激活,对应原TensorFlow的Conv1D自带激活 x = self.pool(x) x = self.activation(self.dropout2(self.linear1(x.view(-1, x.size()[1])))) x = self.activation2(self.output(x)) return x
这里用x.transpose(1,2)替代view,将Embedding输出的(batch, seq_len, embed_dim)转为(batch, embed_dim, seq_len),比view更鲁棒(避免batch_size变化时的维度错误)。
验证修改效果
修复上述问题后,PyTorch模型的训练曲线应与原TensorFlow模型趋势一致,训练准确率会快速上升至80%以上,最终接近原模型的98%训练准确率。
内容的提问来源于stack exchange,提问作者lrthistlethwaite

