【问题标题】:Is it normal that accuracy decreases when advancing to the next epoch?进入下一个epoch时准确率下降是否正常?
【发布时间】:2020-07-31 14:46:19
【问题描述】:

我正在训练 CNN 以使用 MNIST 数据库预测数字。我正在做数据增强,由于某种原因,在进入下一个 epoch 时准确度急剧下降(图像中的迭代 60)

它与数据增强(代码中的转换 = my_transforms)有关,因为当我停用增强(转换 = 无)时,前进到下一个时代时准确性不会降低。但我无法解释为什么。有谁知道为什么会发生这种情况?

my_transforms = transforms.Compose([
    transforms.ToPILImage(),
    transforms.RandomCrop((25,25)),
    transforms.Resize((28,28)),
    transforms.RandomRotation(degrees=45, fill=255),
    transforms.RandomVerticalFlip(p=0.1),
    transforms.RandomHorizontalFlip(p=0.5),
    transforms.ToTensor()
    ])

dataset = MNISTDataset(transform = my_transforms)
train_loader = DataLoader(dataset = dataset, batch_size = 1000, shuffle=True)

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(1,10,kernel_size=5)
        self.pool = nn.MaxPool2d(kernel_size=2,stride=2)
        self.conv2 = nn.Conv2d(10,20,kernel_size=5)
        self.fc1 = nn.Linear(20*4*4, 64)
        self.fc2 = nn.Linear(64, 10)

def forward(self,x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1,20*4*4)
        x = F.relu(self.fc1(x))
        x = F.softmax(self.fc2(x), dim=1)

        return x

net = Net()

loss_function=nn.NLLLoss()
optimizer=optim.Adam(net.parameters())

EPOCHS=2
iteracion = 0

for epoch in range(EPOCHS):
    for data in train_loader:
        inputs, labels = data
        inputs = inputs.view(-1,1,28,28)

        net.zero_grad()

        probabilities=net(inputs)

        matches=[torch.argmax(i)==int(j) for i,j in zip(probabilities,labels)]

        in_batch_acc=matches.count(True)/len(matches)

        loss=loss_function(torch.log(probabilities), labels)

        print('Loss:', round(float(loss), 3))
        print('In-batch acc:', round(in_batch_acc, 2))

        iteracion += 1

        loss.backward()
        optimizer.step()

【问题讨论】:

    标签: pytorch conv-neural-network data-augmentation


    【解决方案1】:

    我通过数据增强复制了您的模型,并尝试绘制准确性和损失,似乎问题在于您绘制的方式。

    在以下几行中,我附上了我的代码以及损失和准确度图:

    代码

    # -- Imports -- #
    import torch
    
    from torch import nn, optim
    from torch.utils.data import DataLoader
    from torchvision import transforms, datasets
    import torch.nn.functional as F
    import matplotlib.pyplot as plt
    
    # -- Data Loader -- #
    my_transforms = transforms.Compose([
        transforms.ToPILImage(),
        transforms.RandomCrop((25,25)),
        transforms.Resize((28,28)),
        transforms.RandomRotation(degrees=45, fill=255),
        transforms.RandomVerticalFlip(p=0.1),
        transforms.RandomHorizontalFlip(p=0.5),
        transforms.ToTensor()
        ])
    dataset = datasets.MNIST('../data', train=True, download=True,
                             transform = transforms.Compose([
                                                transforms.RandomCrop((25,25)),
                                                transforms.Resize((28,28)),
                                                transforms.RandomRotation(degrees=45, fill=255),
                                                transforms.RandomVerticalFlip(p=0.1),
                                                transforms.RandomHorizontalFlip(p=0.5),
                                                transforms.ToTensor()
                                                ]))
    train_loader = DataLoader(dataset = dataset, batch_size = 1000, shuffle=True)
    
    
    # -- Define Model -- #
    class Net(nn.Module):
        def __init__(self):
            super().__init__()
            self.conv1 = nn.Conv2d(1,10,kernel_size=5)
            self.pool = nn.MaxPool2d(kernel_size=2,stride=2)
            self.conv2 = nn.Conv2d(10,20,kernel_size=5)
            self.fc1 = nn.Linear(20*4*4, 64)
            self.fc2 = nn.Linear(64, 10)
    
        def forward(self,x):
                x = self.pool(F.relu(self.conv1(x)))
                x = self.pool(F.relu(self.conv2(x)))
                x = x.view(-1,20*4*4)
                x = F.relu(self.fc1(x))
                x = F.softmax(self.fc2(x), dim=1)
    
                return x
    
    
    device = 'cuda'
    net = Net()
    net.to(device)
    
    loss_function=nn.NLLLoss()
    optimizer=optim.Adam(net.parameters())
    
    EPOCHS=2
    iteracion = 0
    accuracy = []
    loss_record = []
    for epoch in range(EPOCHS):
        for data in train_loader:
            inputs, labels = data
            inputs = inputs.view(-1,1,28,28)
            inputs, labels = inputs.to(device), labels.to(device)
    
            # -- Forward -- #
            net.zero_grad()
            probabilities=net(inputs)
            matches=[torch.argmax(i)==int(j) for i,j in zip(probabilities,labels)]
            in_batch_acc=matches.count(True)/len(matches)
            loss=loss_function(torch.log(probabilities), labels)
    
            # -- Statistics -- #
            accuracy.append(in_batch_acc)
            loss_record.append(loss)
            print('Loss:', round(float(loss), 3))
            print('In-batch acc:', round(in_batch_acc, 2))
    
            iteracion += 1
    
            loss.backward()
            optimizer.step()
    
    # -- Accuracy plot -- #
    iterations = range(0,120)
    plt.plot(iterations, accuracy, 'g', label='Accuracy')
    plt.title('Accuracy')
    plt.xlabel('Iterations')
    plt.ylabel('Accuracy')
    plt.legend()
    plt.show()
    
    # -- Loss plot -- #
    plt.plot(iterations, loss_record, label='Loss')
    plt.title('Loss')
    plt.xlabel('Iterations')
    plt.ylabel('Loss')
    plt.legend()
    plt.show()
    

    情节

    Accuracy plot

    Loss plot

    如你所见,(iteration = 61) -> Next epoch 时没有跳转

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-17
      • 2018-04-18
      • 1970-01-01
      • 1970-01-01
      • 2016-02-24
      • 1970-01-01
      • 1970-01-01
      • 2023-02-16
      相关资源
      最近更新 更多