PyTorch Linear MINST模型训练错误

时间:2020-08-02 10:53:57

标签: python machine-learning pytorch mnist

我正在使用PyTorch基于MINST数据集创建一个二进制分类器。我希望我的分类器仅在0和1之间进行分类,但是,当我训练它时,错误不会减少并且损失会变为负数。 这是前几次迭代中的错误和损失:

enter image description here

我显然期望得到更好的结果。

这是我正在使用的代码:

# Loading the MNISR data reduced to  the 0/1 examples

from torchvision import datasets, transforms
from torch.utils.data import DataLoader

mnist_train = datasets.MNIST("./data", train=True, download=True, transform=transforms.ToTensor())
mnist_test = datasets.MNIST("./data", train=False, download=True, transform=transforms.ToTensor())

train_idx = mnist_train.train_labels <= 1
try:
    mnist_train.train_data = mnist_train.train_data[train_idx]
except AttributeError:
    mnist_train._train_data = mnist_train.train_data[train_idx]
try:
    mnist_train.train_labels = mnist_train.train_labels[train_idx]
except AttributeError:
    mnist_train._train_labels = mnist_train.train_labels[train_idx]

test_idx = mnist_test.test_labels <= 1
try:
    mnist_test.test_data = mnist_test.test_data[test_idx]
except AttributeError:
    mnist_test._test_data = mnist_test.test_data[test_idx]
try:
    mnist_test.test_labels = mnist_test.test_labels[test_idx]
except AttributeError:
    mnist_test._test_labels = mnist_test.test_labels[test_idx]
        
train_loader = DataLoader(mnist_train, batch_size = 100, shuffle=True)
test_loader = DataLoader(mnist_test, batch_size = 100, shuffle=False)


# Creating a simple linear classifier

import torch
import torch.nn as nn
import torch.optim as optim

# do a single pass over the data
def epoch(loader, model, opt=None):
    total_loss, total_err = 0.,0.
    for X,y in loader:
        yp = model(X.view(X.shape[0], -1))[:,0]
        loss = nn.BCEWithLogitsLoss()(yp, y.float())
        if opt:
            opt.zero_grad()
            loss.backward()
            opt.step()
        
        total_err += ((yp > 0) * (y==0) + (yp < 0) * (y==1)).sum().item()
        total_loss += loss.item() * X.shape[0]
    return total_err / len(loader.dataset), total_loss / len(loader.dataset)


model = nn.Linear(784, 1)
opt = optim.SGD(model.parameters(), lr=1)
print("Train Err", "Train Loss", "Test Err", "Test Loss", sep="\t")
for i in range(10):
    train_err, train_loss = epoch(train_loader, model, opt)
    test_err, test_loss = epoch(test_loader, model)
    print(*("{:.6f}".format(i) for i in (train_err, train_loss, test_err, test_loss)), sep="\t")

我不知道为什么我的错误不会减少,或者为什么我的损失会越来越负。有人发现错误了吗?

2 个答案:

答案 0 :(得分:0)

由于mnist数据由10个不同的输出组成,因此将模型更改为输出大小为10

model = nn.Linear(784, 10)

也将损失改为交叉熵损失,并将学习率降低到较小的值(0.001),并使用更深的模型。

可能上述更改可以解决您的问题

答案 1 :(得分:0)

我发现了错误。我从MNIST数据集中仅选择1和0的初始代码不起作用。显然,将BCELoss应用于非二进制数据集会使模型失败。