2017-01-19 3 views
1

This ответ указывает на разницу между эпохой и итерацией во время обучения нейронной сети. Однако, когда я смотрю на исходный код API-интерфейса Solver в курсе Stanford CS231n (и я предполагаю, что это так для большинства библиотек), во время каждой итерации число экземпляров batch_size равно случайно с заменой. Таким образом, нет никакой гарантии, что все примеры будут видны в каждую эпоху?Разъяснение между эпохой и итерацией

Существует ли эпоха, что все примеры будут видны в ожидании? Или я понимаю это неправильно?

Соответствующий Исходный код:

def _step(self): 
    """ 
    Make a single gradient update. This is called by train() and should not 
    be called manually. 
    """ 
    # Make a minibatch of training data 
    num_train = self.X_train.shape[0] 
    batch_mask = np.random.choice(num_train, self.batch_size) 
    X_batch = self.X_train[batch_mask] 
    y_batch = self.y_train[batch_mask] 

    # Compute loss and gradient 
    loss, grads = self.model.loss(X_batch, y_batch) 
    self.loss_history.append(loss) 

    # Perform a parameter update 
    for p, w in self.model.params.iteritems(): 
     dw = grads[p] 
     config = self.optim_configs[p] 
     next_w, next_config = self.update_rule(w, dw, config) 
     self.model.params[p] = next_w 
     self.optim_configs[p] = next_config 

    def train(self): 
    """ 
    Run optimization to train the model. 
    """ 
    num_train = self.X_train.shape[0] 
    iterations_per_epoch = max(num_train/self.batch_size, 1) 
    num_iterations = self.num_epochs * iterations_per_epoch 

    for t in xrange(num_iterations): 
     self._step() 

     # Maybe print training loss 
     if self.verbose and t % self.print_every == 0: 
     print '(Iteration %d/%d) loss: %f' % (
       t + 1, num_iterations, self.loss_history[-1]) 

     # At the end of every epoch, increment the epoch counter and decay the 
     # learning rate. 
     epoch_end = (t + 1) % iterations_per_epoch == 0 
     if epoch_end: 
     self.epoch += 1 
     for k in self.optim_configs: 
      self.optim_configs[k]['learning_rate'] *= self.lr_decay 

     # Check train and val accuracy on the first iteration, the last 
     # iteration, and at the end of each epoch. 
     first_it = (t == 0) 
     last_it = (t == num_iterations + 1) 
     if first_it or last_it or epoch_end: 
     train_acc = self.check_accuracy(self.X_train, self.y_train, 
             num_samples=1000) 
     val_acc = self.check_accuracy(self.X_val, self.y_val) 
     self.train_acc_history.append(train_acc) 
     self.val_acc_history.append(val_acc) 

     if self.verbose: 
      print '(Epoch %d/%d) train acc: %f; val_acc: %f' % (
       self.epoch, self.num_epochs, train_acc, val_acc) 

     # Keep track of the best model 
     if val_acc > self.best_val_acc: 
      self.best_val_acc = val_acc 
      self.best_params = {} 
      for k, v in self.model.params.iteritems(): 
      self.best_params[k] = v.copy() 

    # At the end of training swap the best params into the model 
    self.model.params = self.best_params 

Спасибо.

+0

Можете ли вы дать ссылку на исходный код, который вы упомянули? – jdehesa

+0

Добавлен исходный код. – shaun

ответ

0

Я считаю, как вы говорите, что в курсе Стэнфорда они эффективно используют «эпоху» с менее строгим значением «ожидаемое количество раз, когда каждый пример рассматривается во время обучения». Однако, по моему опыту, большинство реализаций рассматривают эпоху как прохождение каждого примера в учебном наборе один раз, и я бы сказал, что они просто выбрали выборку с заменой для простоты. Если у вас есть хороший объем данных, есть вероятность, что вы не увидите разницы, но тем не менее, правильнее пробовать без замены, пока не будет примеров.

Вы можете проверить, к примеру, как Keras выполняет тренировки в своем source code; это немного сложно, но важно то, что make_batches призван разбивать (возможно, перетасованные) примеры на партии, что соответствует вашей первоначальной идее «эпохи».

+0

Это имеет смысл. Если мое понимание верное, каждый пример в каждой партии, возвращаемой функцией make_batch, различен. Таким образом, если вы суммируете все примеры во всех партиях, которые составляют все ваши данные обучения. Это также означает, что между партиями нет перекрытия. Это верно? На стороне заметки, даже если мы перейдем к np.random.choice (num_train, self.batch_size, replacement = False), мы не увидим все примеры. Потому что при каждом вызове _step мы забываем то, что мы видели раньше. Однако внутри каждого _step-вызова batch_mask будет содержать уникальные примеры. Я прав? – shaun

+0

@shaun Да, это правильно. Как вы сказали, использование 'replacement = True' в коде, который вы отправили, будет гарантировать, что каждая партия не будет иметь повторяющихся элементов, но это не гарантирует, что каждый пример будет отображаться в каждую эпоху. То, что я имел в виду с «образцом без замены», было, как и упомянутый вами код Keras, брать * n * образцы 'batch_size' без замены. – jdehesa