Потери при проверке увеличиваются через несколько эпох

#python #neural-network #pytorch #conv-neural-network

#python #нейронная сеть #pytorch #conv-нейронная сеть

Вопрос:

Я создаю небольшую модель CNN для прогнозирования болезней растений с помощью набора данных Plant Village. Он состоит из 39 классов различных видов с заболеваниями и без них.

Модель CNN

 class CropDetectCNN(nn.Module):
    # initialize the class and the parameters
    def __init__(self):
        super(CropDetectCNN, self).__init__()

        # convolutional layer 1 amp; max pool layer 1
        self.layer1 = nn.Sequential(
            nn.Conv2d(3, 16, kernel_size=3),
            nn.MaxPool2d(kernel_size=2))

        # convolutional layer 2 amp; max pool layer 2
        self.layer2 = nn.Sequential(
            nn.Conv2d(16, 32, kernel_size=3, padding=1, stride=2),
            nn.MaxPool2d(kernel_size=2))

        #Fully connected layer
        self.fc = nn.Linear(32*28*28, 39)
        
        

    # Feed forward the network
    def forward(self, x):
        out = self.layer1(x)
        out = self.layer2(out)
        out = out.reshape(out.size(0), -1)
        out = self.fc(out)
        return out


model = CropDetectCNN()
 

Обучение

 criterion = nn.CrossEntropyLoss()  # this include softmax   cross entropy loss
optimizer = torch.optim.Adam(model.parameters())

def batch_gd(model, criterion, train_loader, validation_loader, epochs):
    train_losses = np.zeros(epochs)
    test_losses = np.zeros(epochs)
    validation_losses = np.zeros(epochs)
    
    for e in range(epochs):
        t0 = datetime.now()
        train_loss = []
        model.train()
        for inputs, targets in train_loader:
            inputs, targets = inputs.to(device), targets.to(device)

            optimizer.zero_grad()

            output = model(inputs)

            loss = criterion(output, targets)

            train_loss.append(loss.item())  # torch to numpy world

            loss.backward()
            optimizer.step()
            
        
        train_loss = np.mean(train_loss)

        validation_loss = []

        for inputs, targets in validation_loader:
            
            model.eval()

            inputs, targets = inputs.to(device), targets.to(device)

            output = model(inputs)

            loss = criterion(output, targets)

            validation_loss.append(loss.item())  # torch to numpy world
        
        
        
        validation_loss = np.mean(validation_loss)

        train_losses[e] = train_loss
        validation_losses[e] = validation_loss

        dt = datetime.now() - t0

        print(
            f"Epoch : {e 1}/{epochs} Train_loss: {train_loss:.3f} Validation_loss: {validation_loss:.3f} Duration: {dt}"
        )

    return train_losses, validation_losses

# Running the function
train_losses, validation_losses = batch_gd(
    model, criterion, train_loader, validation_loader, 5
)

# And theses are results:
Epoch : 1/5 Train_loss: 1.164 Validation_loss: 0.861 Duration: 0:10:59.968168
Epoch : 2/5 Train_loss: 0.515 Validation_loss: 0.816 Duration: 0:10:49.199842
Epoch : 3/5 Train_loss: 0.241 Validation_loss: 1.007 Duration: 0:09:56.334155
Epoch : 4/5 Train_loss: 0.156 Validation_loss: 1.147 Duration: 0:10:12.625819
Epoch : 5/5 Train_loss: 0.135 Validation_loss: 1.603 Duration: 0:09:56.746308
 

Разве потери при проверке не должны уменьшаться с эпохами? Так почему же он сначала уменьшается, а затем увеличивается?

Как я должен установить количество эпох и почему?

Любая помощь действительно ценится!

Комментарии:

1. похоже, у вас есть несколько вопросов в рамках одного поста — пожалуйста, задавайте каждый вопрос в отдельном кратком посте. не стесняйтесь связывать вопросы для контекста

2. Хорошо, я постараюсь это исправить, спасибо!

Ответ №1:

Вы сталкиваетесь с явлением «переобучения», когда ваши потери при проверке увеличиваются после уменьшения. На этом этапе вам следует прекратить обучение и попытаться использовать некоторые приемы, чтобы избежать переобучения.

Получение разных прогнозов может произойти, когда ваши градиенты продолжают обновляться во время вывода, поэтому попробуйте явно «остановить» их обновление с помощью torch.no_grad()

Комментарии:

1. Хорошо, да, я понимаю. Итак, я должен уменьшить количество эпох до 2, потому что оно начинает увеличиваться после? Что касается прогнозов, добавление a with torch.no_grad(): перед проверкой может разрешить? Но я создам еще один пост для своего второго вопроса по истечении 90 минут.

2. So I have to reduce the number of epochs to 2 — Я бы лучше уменьшил скорость обучения и посмотрел, может ли ошибка снизиться, прежде чем прерывать процесс обучения

3. Я понимаю, что я использую адаптивную скорость обучения с оптимизатором Adam : optimizer = torch.optim.Adam(model.parameters()) . Как мне уменьшить скорость обучения?

4. Установите lr= 1e-4 или lr= 3e-4 в torch.optim. Адам pytorch.org/docs/stable/generated/torch.optim.Adam.html