代码之家  ›  专栏  ›  技术社区  ›  blue-sky

在mnist数据集上很少出现时间段后,测试集的精度非常高。

  •  0
  • blue-sky  · 技术社区  · 6 年前

    在很少的时间段内,这个模型非常快地学会了对1和0的分类,这导致我认为有些事情是错误的。

    下面的代码下载mnist数据集,提取仅包含1或0的mnist图像。从mnist图像的子集中选择大小为200的随机样本。这个随机样本是模型所训练的数据集。只需2个周期,模型就可以达到90%以上的测试集精度,这是预期的行为吗?我希望需要更多的时间来训练模型以达到这个测试集精度水平。

    型号代码:

    %reset -f
    
    import torch
    import torch.nn as nn
    import torchvision
    import torchvision.transforms as transforms
    import torch
    import torch.nn as nn
    import torchvision
    import torchvision.transforms as transforms
    import torch.utils.data as data_utils
    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn.datasets import make_moons
    from matplotlib import pyplot
    from pandas import DataFrame
    import torchvision.datasets as dset
    import os
    import torch.nn.functional as F
    import time
    import random
    import pickle
    from sklearn.metrics import confusion_matrix
    import pandas as pd
    import sklearn
    
    
    trans = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (1.0,))])
    
    root = './data'
    if not os.path.exists(root):
        os.mkdir(root)
    train_set = dset.MNIST(root=root, train=True, transform=trans, download=True)
    test_set = dset.MNIST(root=root, train=False, transform=trans, download=True)
    
    batch_size = 64
    
    train_loader = torch.utils.data.DataLoader(
                     dataset=train_set,
                     batch_size=batch_size,
                     shuffle=True)
    test_loader = torch.utils.data.DataLoader(
                    dataset=test_set,
                    batch_size=batch_size,
    shuffle=True)
    
    class NeuralNet(nn.Module):
        def __init__(self):
            super(NeuralNet, self).__init__()
            self.fc1 = nn.Linear(28*28, 500)
            self.fc2 = nn.Linear(500, 256)
            self.fc3 = nn.Linear(256, 2)
        def forward(self, x):
            x = x.view(-1, 28*28)
            x = F.relu(self.fc1(x))
            x = F.relu(self.fc2(x))
            x = self.fc3(x)
            return x
    
    num_epochs = 2
    random_sample_size = 200
    
    values_0_or_1 = [t for t in train_set if (int(t[1]) == 0 or int(t[1]) == 1)]
    values_0_or_1_testset = [t for t in test_set if (int(t[1]) == 0 or int(t[1]) == 1)]
    
    print(len(values_0_or_1))
    print(len(values_0_or_1_testset))
    
    train_loader_subset = torch.utils.data.DataLoader(
                     dataset=values_0_or_1,
                     batch_size=batch_size,
                     shuffle=True)
    
    test_loader_subset = torch.utils.data.DataLoader(
                     dataset=values_0_or_1_testset,
                     batch_size=batch_size,
                     shuffle=False)
    
    train_loader = train_loader_subset
    
    # Hyper-parameters 
    input_size = 100
    hidden_size = 100
    num_classes = 2
    # learning_rate = 0.00001
    learning_rate = .0001
    # Device configuration
    device = 'cpu'
    print_progress_every_n_epochs = 1
    
    model = NeuralNet().to(device)
    
    # Loss and optimizer
    criterion = nn.CrossEntropyLoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)  
    
    N = len(train_loader)
    # Train the model
    total_step = len(train_loader)
    
    most_recent_prediction = []
    test_actual_predicted_dict = {}
    
    rm = random.sample(list(values_0_or_1), random_sample_size)
    train_loader_subset = data_utils.DataLoader(rm, batch_size=4)
    
    for epoch in range(num_epochs):
        for i, (images, labels) in enumerate(train_loader_subset):  
            # Move tensors to the configured device
            images = images.reshape(-1, 2).to(device)
            labels = labels.to(device)
    
            # Forward pass
            outputs = model(images)
            loss = criterion(outputs, labels)
    
            # Backward and optimize
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
    
        if (epoch) % print_progress_every_n_epochs == 0:
            print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, i+1, total_step, loss.item()))
    
    
    predicted_test = []
    model.eval()  # eval mode (batchnorm uses moving mean/variance instead of mini-batch mean/variance)
    probs_l = []
    
    predicted_values = []
    actual_values = []
    labels_l = []
    
    with torch.no_grad():
        for images, labels in test_loader_subset:
            images = images.to(device)
            labels = labels.to(device)
            outputs = model(images)
            _, predicted = torch.max(outputs.data, 1)
            predicted_test.append(predicted.cpu().numpy())
    
            sm = torch.nn.Softmax()
            probabilities = sm(outputs) 
            probs_l.append(probabilities)  
            labels_l.append(labels.cpu().numpy())
    
        predicted_values.append(np.concatenate(predicted_test).ravel())
        actual_values.append(np.concatenate(labels_l).ravel())
    
    if (epoch) % 1 == 0:
        print('test accuracy : ', 100 * len((np.where(np.array(predicted_values[0])==(np.array(actual_values[0])))[0])) / len(actual_values[0]))
    

    模型输出(12665和2115代表培训和测试集大小):

    12665
    2115
    Epoch [1/2], Step [50/198], Loss: 0.1256
    Epoch [2/2], Step [50/198], Loss: 0.0151
    test accuracy :  99.76359338061465
    
    /anaconda3/envs/pytorch/lib/python3.7/site-packages/ipykernel_launcher.py:143: UserWarning: Implicit dimension choice for softmax has been deprecated. Change the call to include dim=X as an argument.
    
    2 回复  |  直到 6 年前
        1
  •  0
  •   Rex Low    6 年前

    这是我给你的二元实验的2分。

    似乎你已经严重地降低了数据集的复杂性,并且随着中间层中神经元数量的增加,你的模型将很快收敛。

    请注意,mnist数据集的通道为1,这使得任务非常简单。

    你可以试着玩cifar10,看看你是否仍然在2个时期内获得高精度。

        2
  •  0
  •   Jatentaki    6 年前

    这不是一个很好的问题,因为预期的完全是主观的。也就是说, 我并不惊讶,因为 0 1 是非常不同的数字。例如, 背景被前景包围,而 不是-那几乎是区分这两者的绝对可靠的测试。作为一张健全的支票,我要换掉 对于 7 ,类似于 . 我预计成功率会显著降低。也就是说,这是一个健全性检查——即使通过了检查,您的方法中仍然可能存在错误或错误。