обучение партиями приводит к большему переоснащению - PullRequest
1 голос
/ 09 апреля 2020

Я тренирую модель последовательности в последовательность (seq2seq), и у меня есть различные значения для тренировки для input_sequence_length.

Для значений 10 и 15 я получаю приемлемые результаты, но когда я пытаюсь тренироваться с 20, я получаю ошибок памяти , поэтому я переключил тренировку на тренировку партиями но модель с избыточной аппроксимацией и потери при проверке взрываются, и даже при накопленном градиенте я получаю то же поведение, поэтому я ищу подсказки и приводит к более точным способам обновления.


Вот моя функция тренировки (только с секцией партии):

    if batch_size is not None:
        k=len(list(np.arange(0,(X_train_tensor_1.size()[0]//batch_size-1), batch_size )))
        for epoch in range(num_epochs):
            optimizer.zero_grad()
            epoch_loss=0
            for i in list(np.arange(0,(X_train_tensor_1.size()[0]//batch_size-1), batch_size )): # by using equidistant batch till the last one it becomes much faster than using the X.size()[0] directly
                sequence = X_train_tensor[i:i+batch_size,:,:].reshape(-1, sequence_length, input_size).to(device)
                labels = y_train_tensor[i:i+batch_size,:,:].reshape(-1, sequence_length, output_size).to(device)
                # Forward pass
                outputs = model(sequence)
                loss = criterion(outputs, labels)
                epoch_loss+=loss.item()
                # Backward and optimize
                loss.backward() 

            optimizer.step()    
            epoch_loss=epoch_loss/k
            model.eval
            validation_loss,_= evaluate(model,X_test_hard_tensor_1,y_test_hard_tensor_1)
            model.train()
            training_loss_log.append(epoch_loss)
            print ('Epoch [{}/{}], Train MSELoss: {}, Validation : {} {}'.format(epoch+1, num_epochs,epoch_loss,validation_loss))

РЕДАКТИРОВАТЬ: вот параметры, с которыми я тренируюсь:

batch_size = 1024 
num_epochs = 25000
learning_rate = 10e-04

optimizer=torch.optim.Adam(model.parameters(), lr=learning_rate)
criterion = nn.MSELoss(reduction='mean')

1 Ответ

2 голосов
/ 15 апреля 2020

Размер партии влияет на регуляризацию. Тренировки на одном примере за раз довольно шумные, что затрудняет их переобучение. Тренировка в партиях сглаживает все, что облегчает переодевание. Перевод обратно на регуляризацию:

  • Меньшие партии добавляют регуляризацию.
  • Большие партии уменьшают регуляризацию.

Мне также интересно узнать о вашей скорости обучения. Каждый вызов loss.backward() будет накапливать градиент. Если вы установили, что ваша скорость обучения рассчитана на один пример за раз, а не уменьшаете его для учета накопления партии, то произойдет одно из двух:

  1. Скорость обучения будет быть слишком высоким для накопленного в настоящее время градиента, обучение будет расходиться, а ошибки обучения и проверки будут взрываться.

  2. Скорость обучения не будет слишком высокой, и ничто не будет расходиться. Модель просто будет тренироваться быстрее и эффективнее. Если модель слишком велика для подгонки данных, то ошибка обучения изменится с go на 0, но ошибка проверки взорвется из-за переоснащения.


Обновление

Вот немного больше деталей относительно накопления градиента.

Каждый вызов loss.backward() будет накапливать градиент, пока вы не сбросите его с помощью optimizer.zero_grad(). Он будет действовать, когда вы звоните optimizer.step(), исходя из того, что он накопил.

При написании кода вы вызываете loss.backward() для каждого прохода через внутренний l oop, затем вы вызовите optimizer.step() во внешнем l oop перед сбросом. Таким образом, градиент был накоплен, который суммируется по всем примерам в серии, а не только по одному примеру за раз.

При большинстве допущений это сделает градиент, накопленный в партии, больше, чем градиент для один пример. Если все градиенты выровнены, для партий B он будет больше в B раз. Если градиенты равны iid , то это будет больше в 1040 * раз больше.

Если вы не учитываете это, то вы эффективно увеличили скорость обучения на этот коэффициент. Часть этого будет смягчена эффектом сглаживания больших партий, которые затем могут выдержать более высокую скорость обучения. Большие партии уменьшают регуляризацию, более высокая скорость обучения добавляет это обратно. Но это не будет идеальным соответствием для компенсации, поэтому вы все равно захотите откорректировать соответствующим образом.

В общем, всякий раз, когда вы изменяете размер своей партии, вы также хотите перенастроить свою скорость обучения для компенсации.


Lesl ie N. Smith написал несколько отличных работ по методическому подходу к настройке гиперпараметров. Отличное место для начала - Дисциплинированный подход к гиперпараметрам нейронной сети: Часть 1 - скорость обучения, размер партии, импульс и снижение веса . Он рекомендует начать с чтения диаграмм, которые очень хорошо сделаны.

...