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

TensorFlow与PyTorch二分类准确率差异排查及代码修复问询

PyTorch二分类模型准确率异常(仅2.5%)的修复方案

问题描述

同一二分类任务中,TensorFlow实现的模型准确率约86%,但PyTorch版本准确率始终仅2.5%,相关代码如下:

PyTorch模型与训练代码

class SimpleClassifier(nn.Module):
    def __init__(self, input_size, hidden_size1, hidden_size2, output_size):
        super(SimpleClassifier, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size1)
        self.relu1 = nn.ReLU()
        self.fc2 = nn.Linear(hidden_size1, hidden_size2)
        self.relu2 = nn.ReLU()
        self.fc3 = nn.Linear(hidden_size2, output_size)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        x = self.relu1(self.fc1(x))
        x = self.relu2(self.fc2(x))
        x = self.sigmoid(self.fc3(x))
        return x

input_size = train_X.shape[1]
hidden_size1 = 64
hidden_size2 = 32
output_size = 1 
model = SimpleClassifier(input_size, hidden_size1, hidden_size2, output_size)

criterion = nn.BCELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)


num_epochs = 50
for epoch in range(num_epochs):
    for inputs, labels in train_dataloader:
        optimizer.zero_grad()
        outputs = model(inputs)
        
        # Reshape labels to match the shape of the outputs
        labels = labels.view(-1, 1)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
    # Evaluation on the test set
    with torch.no_grad():
        model.eval()
        predictions = model(test_X).squeeze()
        predictions_binary = (predictions.round()).float()
        accuracy = torch.sum(predictions_binary == test_Y) / (len(test_Y) * 100)
        if(epoch%25 == 0):
          print("Epoch " + str(epoch) + " passed. Test accuracy is {:.2f}%".format(accuracy))

TensorFlow对比代码

model = Sequential()
model.add(Dense(64, input_dim=len(train_X[0]), activation='relu'))
model.add(Dense(32, activation='relu'))
model.add(Dense(1, activation='sigmoid'))  # assuming binary classification

# Compile the model
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])


model.fit(train_X, train_Y, epochs=50, batch_size=64)

# Evaluate the model
loss, accuracy = model.evaluate(test_X, test_Y)
print(f"Loss: {loss}, Accuracy: {accuracy}")

PyTorch数据加载代码

train, test = train_test_split(data, test_size=0.056)

train_X = train[["A","B","C", "D"]].to_numpy()
test_X = test[["A","B", "C", "D"]].to_numpy()
train_Y = train[["label"]].to_numpy()
test_Y = test[["label"]].to_numpy()

train_X = torch.tensor(train_X, dtype=torch.float32)
test_X = torch.tensor(test_X, dtype=torch.float32)
train_Y = torch.tensor(train_Y, dtype=torch.float32)
test_Y = torch.tensor(test_Y, dtype=torch.float32)

train_dataset = TensorDataset(train_X, train_Y)
test_dataset = TensorDataset(test_X, test_Y)

train_dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_dataloader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)

错误定位与修复步骤

1. 准确率计算逻辑错误

原代码中错误地将准确率分母乘以100,导致数值被缩小100倍,同时test_Y是二维张量(形状(n,1)),需与一维的predictions_binary形状匹配:

# 错误代码
accuracy = torch.sum(predictions_binary == test_Y) / (len(test_Y) * 100)

# 修正后
correct = torch.sum(predictions_binary == test_Y.squeeze())
accuracy = correct / len(test_Y) * 100

2. 训练循环未切换回训练模式

评估阶段调用了model.eval(),会禁用梯度计算和部分层的训练行为,每个epoch的训练前需切换回训练模式:

for epoch in range(num_epochs):
    # 新增:切换为训练模式
    model.train()
    for inputs, labels in train_dataloader:
        # 训练逻辑...

3. 统一batch_size参数

TensorFlow代码使用batch_size=64,但PyTorch代码未明确定义该变量,需补充定义保证训练批次一致:

batch_size = 64

修正后的完整PyTorch训练代码

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import TensorDataset, DataLoader
from sklearn.model_selection import train_test_split

# 统一batch_size
batch_size = 64

# 数据加载
train, test = train_test_split(data, test_size=0.056)

train_X = train[["A","B","C", "D"]].to_numpy()
test_X = test[["A","B", "C", "D"]].to_numpy()
train_Y = train[["label"]].to_numpy()
test_Y = test[["label"]].to_numpy()

train_X = torch.tensor(train_X, dtype=torch.float32)
test_X = torch.tensor(test_X, dtype=torch.float32)
train_Y = torch.tensor(train_Y, dtype=torch.float32)
test_Y = torch.tensor(test_Y, dtype=torch.float32)

train_dataset = TensorDataset(train_X, train_Y)
test_dataset = TensorDataset(test_X, test_Y)

train_dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_dataloader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)

# 模型定义
class SimpleClassifier(nn.Module):
    def __init__(self, input_size, hidden_size1, hidden_size2, output_size):
        super(SimpleClassifier, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size1)
        self.relu1 = nn.ReLU()
        self.fc2 = nn.Linear(hidden_size1, hidden_size2)
        self.relu2 = nn.ReLU()
        self.fc3 = nn.Linear(hidden_size2, output_size)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        x = self.relu1(self.fc1(x))
        x = self.relu2(self.fc2(x))
        x = self.sigmoid(self.fc3(x))
        return x

input_size = train_X.shape[1]
hidden_size1 = 64
hidden_size2 = 32
output_size = 1 
model = SimpleClassifier(input_size, hidden_size1, hidden_size2, output_size)

criterion = nn.BCELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

num_epochs = 50
for epoch in range(num_epochs):
    model.train()
    total_train_loss = 0.0
    for inputs, labels in train_dataloader:
        optimizer.zero_grad()
        outputs = model(inputs)
        labels = labels.view(-1, 1)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        total_train_loss += loss.item() * inputs.size(0)
    
    avg_train_loss = total_train_loss / len(train_dataloader.dataset)
    
    with torch.no_grad():
        model.eval()
        predictions = model(test_X).squeeze()
        predictions_binary = (predictions.round()).float()
        correct = torch.sum(predictions_binary == test_Y.squeeze())
        accuracy = correct / len(test_Y) * 100
        
        if epoch % 25 == 0:
            print(f"Epoch {epoch} passed. Train Loss: {avg_train_loss:.4f}, Test Accuracy: {accuracy:.2f}%")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 06:35:00