Почему точность тренировки падает после достижения идеальной формы тренировки? - PullRequest
1 голос
/ 14 июня 2019

Я тренирую NN в pytorch на данных MNIST. Модель хорошо запускается, совершенствуется, достигает хорошей точности как для обучения, так и для данных тестирования, стабилизируется некоторое время, а затем и тест, и точность обучения снижаются, как показано на следующем базовом графике результатов .

Что касается MNIST, я использую 60000 тренировочных образов, 10000 тестов, размер тренировочной партии 100 и скорость обучения 0,01. Нейронная сеть состоит из двух полностью связанных скрытых слоев, каждый из которых содержит 100 узлов, а узлы имеют функции активации ReLU. F.cross_entropy используется для потерь и SGD для расчета градиентов.

Это не проблема переоснащения, так как падает точность обучения и тестирования. Я подозревал, что это связано со слишком большой скоростью обучения. В базовом случае я использовал 0,01, но когда я опускаю его до 0,001, весь шаблон повторяется, чуть позже, как показано на на следующем графике (обратите внимание, изменение масштаба по оси X, шаблон происходит примерно 10 времена спустя, что интуитивно понятно). Аналогичные результаты были получены при использовании еще более низких показателей обучения.

Я пробовал модульное тестирование, проверял отдельные детали и делал модель меньше. Здесь - это результаты, когда я использую только 6 точек данных в обучающем наборе, размер партии 2. Идеальная подгонка к тренировочным данным (здесь они явно отличаются от точности теста, как и ожидалось), что неудивительно достигается, но все же падает от 100% до 1/6, так что не лучше, чем случайный выбор. Кто-нибудь может мне сказать, что должно произойти для того, чтобы сеть развернулась в идеальном положении на тренировочном наборе?

Вот структура сети (соответствующие библиотеки добавляются ранее), хотя я надеюсь, что вышеупомянутых симптомов будет достаточно, чтобы вы могли распознать, в чем проблема без нее:

class Network(nn.Module):
def __init__(self):
    # call to the super class Module from nn
    super(Network, self).__init__()

    # fc strand for 'fully connected'
    self.fc1 = nn.Linear(in_features=28*28, out_features=100)
    self.fc2 = nn.Linear(in_features=100, out_features=100)
    self.out = nn.Linear(in_features=100, out_features=10)

def forward(self, t):

    # (1) input layer (redundant)
    t = t

    # (2) hidden linear layer
    # As my t consists of 28*28 bit pictures, I need to flatten them:
    t = t.reshape(-1, 28*28)
    # Now having this reshaped input, add it to the linear layer
    t = self.fc1(t)
    # Again, apply ReLU as the activation function
    t = F.relu(t)

    # (3) hidden linear layer
    # As above, but reshaping is not needed now
    t = self.fc2(t)
    t = F.relu(t)

    # (4) output layer
    t = self.out(t)
    t = F.softmax(t, dim=1)

    return t

Основное исполнение кода:

for b in range(epochs):
print('***** EPOCH NO. ', b+1)
# getting a batch iterator
batch_iterator = iter(batch_train_loader)
# For loop for a single epoch, based on the length of the training set and the batch size
for a in range(round(train_size/b_size)):
    print(a+1)
    # get one batch for the iteration
    batch = next(batch_iterator)
    # decomposing a batch
    images, labels = batch[0].to(device), batch[1].to(device)
    # to get a prediction, as with individual layers, we need to equate it to the network with the samples as input:
    preds = network(images)
    # with the predictions, we will use F to get the loss as cross_entropy
    loss = F.cross_entropy(preds, labels)
    # function for counting the number of correct predictions
    get_num_correct(preds, labels))
    # calculate the gradients needed for update of weights
    loss.backward()
    # with the known gradients, we will update the weights according to stochastic gradient descent
    optimizer = optim.SGD(network.parameters(), lr=learning_rate)
    # with the known weights, step in the direction of correct estimation
    optimizer.step()
    # check if the whole data check should be performed (for taking full training/test data checks only in evenly spaced intervals on the log scale, pre-calculated later)
    if counter in X_log:
        # get the result on the whole train data and record them
        full_train_preds = network(full_train_images)
        full_train_loss = F.cross_entropy(full_train_preds, full_train_labels)
        # Record train loss
        a_train_loss.append(full_train_loss.item())
        # Get a proportion of correct estimates, to make them comparable between train and test data
        full_train_num_correct = get_num_correct(full_train_preds, full_train_labels)/train_size
        # Record train accuracy
        a_train_num_correct.append(full_train_num_correct)
        print('Correct predictions of the dataset:', full_train_num_correct)
        # Repeat for test predictions
        # get the results for the whole test data
        full_test_preds = network(full_test_images)
        full_test_loss = F.cross_entropy(full_test_preds, full_test_labels)
        a_test_loss.append(full_test_loss.item())
        full_test_num_correct = get_num_correct(full_test_preds, full_test_labels)/test_size
        a_test_num_correct.append(full_test_num_correct)
    # update counter
    counter = counter + 1

Я гуглил и проверил здесь ответы на эти вопросы, но люди либо спрашивают о переоснащении, либо их NN вообще не повышают точность в тренировочном наборе (то есть они просто не работают), а не о поиске хорошего тренировки подходят, а затем полностью теряют его, также на тренировочном наборе. Я надеюсь, что я не опубликовал что-то очевидное, я относительно новичок в NN, но я приложил все усилия, чтобы изучить эту тему, прежде чем публиковать ее здесь, спасибо за вашу помощь и понимание!

Ответы [ 2 ]

0 голосов
/ 15 июня 2019

Причина - ошибка в коде. Нам нужно добавить optimizator.zero_grad() в начале цикла обучения и создать оптимизатор перед внешним циклом обучения, т.е.

optimizator = optim.SGD(...)
for b in range(epochs):

Почему мы должны вызывать zero_grad () в PyTorch? объясняет почему.

0 голосов
/ 14 июня 2019

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

Я бы порекомендовал проверить это https://machinelearningmastery.com/early-stopping-to-avoid-overtraining-neural-network-models/, чтобы увидеть, соответствует ли оно тому, что вы видите, так как это было первое, о чем я подумал.

Также, возможно, посмотрите на этот пост. https://stats.stackexchange.com/questions/198629/difference-between-overtraining-and-overfitting (не говоря, что это дубликат)

И эта публикация: Перетренированность в обратном распространении Нейронные сети: цвет ЭЛТ Пример калибровки https://onlinelibrary.wiley.com/doi/pdf/10.1002/col.10027

...