python - 用于对 2d 点进行二元分类的深度神经网络模型的训练和测试准确率达到 50%

标签 python pytorch neural-network

我有一个带有 2 个隐藏层的深度神经网络。我正在尝试使用神经网络将 2d 数据点分类为 0 或 1。我生成的数据如下所示:

enter image description here

我想做的也看起来像这样 tensorflow classification .

import random
import torch.optim
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from torch import nn
from sklearn.datasets import make_circles

def accuracy_fn(y_true, y_pred):
    correct = torch.eq(y_true, y_pred).sum().item() # torch.eq() calculates where two tensors are equal
    acc = (correct / len(y_pred)) * 100
    return acc


n_samples = 1000

X, y = make_circles(n_samples, noise=0.03, random_state=42)

X = torch.from_numpy(X).type(torch.float)
y = torch.from_numpy(y).type(torch.float).unsqueeze(1)

X_train, X_test, y_train, y_test = train_test_split(X,
                                                    y,
                                                    test_size=0.2, # 20% test, 80% train
                                                    random_state=42)

model = nn.Sequential(
    nn.Linear(2, 8),
    nn.ReLU(),
    nn.Linear(8, 8),
    nn.ReLU(),
    nn.Linear(8, 1),
)

print(model.state_dict())

criterion = nn.BCEWithLogitsLoss()

optimizer = torch.optim.SGD(model.parameters(), lr=0.1)

Loss = []
epochs = 500

for epoch in range(epochs):
    y_logit = model(X_train)
    loss = criterion(y_logit, y_train)
    y_pred = torch.round(torch.sigmoid(y_logit))
    acc = accuracy_fn(y_true=y_train,
                      y_pred=y_pred)

    if epoch % 100 == 0:
        Loss.append(loss.item())

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    model.eval()
    with torch.inference_mode():
        # 1. Forward pass
        test_logits = model(X_test)
        test_pred = torch.round(torch.sigmoid(test_logits))  # logits -> prediction probabilities -> prediction labels
        # 2. Calcuate loss and accuracy
        test_loss = criterion(test_logits, y_test)
        test_acc = accuracy_fn(y_true=y_test,
                               y_pred=test_pred)

    # Print out what's happening
    if epoch % 100 == 0:
        print(
            f"Epoch: {epoch} | Loss: {loss:.5f}, Accuracy: {acc:.2f}% | Test Loss: {test_loss:.5f}, Test Accuracy: {test_acc:.2f}%")

我不太确定我在这里做错了什么。我尝试了各种学习率和时期,但我的最终模型通常具有 50% 的准确率,并且损失永远不会下降。有时,如果我重新运行程序足够多次,准确度会达到 50 秒甚至 60 秒。我有点引用this link为了了解我应该获得的数据,作者的准确度在 70 多岁左右。他的损失也大幅缩小。

我没有完全复制他的代码,但我也看了其他类似的例子,我的代码似乎并没有太大的不同。

最佳答案

for epoch in range(epochs):
################################################################
    optimizer.zero_grad()
################################################################
    y_logit = model(X_train)
    loss = criterion(y_logit, y_train)
    y_pred = torch.round(torch.sigmoid(y_logit))
    acc = accuracy_fn(y_true=y_train,
                      y_pred=y_pred)

    if epoch % 100 == 0:
        Loss.append(loss.item())

    
    loss.backward()
    optimizer.step()

    model.eval()
    with torch.inference_mode():
        # 1. Forward pass
        test_logits = model(X_test)
        test_pred = torch.round(torch.sigmoid(test_logits))  # logits -> prediction probabilities -> prediction labels
        # 2. Calcuate loss and accuracy
        test_loss = criterion(test_logits, y_test)
        test_acc = accuracy_fn(y_true=y_test,
                               y_pred=test_pred)

    # Print out what's happening
    if epoch % 100 == 0:
        print(
            f"Epoch: {epoch} | Loss: {loss:.5f}, Accuracy: {acc:.2f}% | Test Loss: {test_loss:.5f}, Test Accuracy: {test_acc:.2f}%")

你必须将zero_grad放在循环的顶部。当您将 Optimizer.zero_grad() 放在训练循环的底部时,在计算当前批处理的梯度之前,您不会清除梯度。这可能会导致梯度在多个批处理中累积,从而导致模型参数的更新不正确且不一致。

关于python - 用于对 2d 点进行二元分类的深度神经网络模型的训练和测试准确率达到 50%,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76844362/

相关文章:

Python,打印字典中每种可能组合的元素和的键

ipython 并行的 Python namespace 问题

deep-learning - Pytorch 中 LSTM 的可变大小输入

deep-learning - Pytorch:经过一些迭代后测试损失变为 nan

python - Keras神经网络输出函数参数/如何构造损失函数?

machine-learning - 迁移学习和线性分类器

python - Keras GRU 模型仅预测 [-0., -0., -0., -0., -0.]

python - 如何使用 Django ORM 按时间戳字段中的日期进行分组?

Python - 在 for 循环中使用 frozenset 条目列表的问题

matrix - PyTorch - nn.Linear 权重的形状