сомнения относительно размера партии и временных шагов в RNN

В учебнике Tensorflow по RNN: https://www.tensorflow.org/tutorials/recurrent. В нем упоминаются два параметра: размер партии и временные шаги. Меня смущают концепции. На мой взгляд, RNN вводит пакетную обработку потому, что последовательность для обучения может быть очень длинной, так что обратное распространение не может вычислить такую ​​длину (взрывные / исчезающие градиенты). Таким образом, мы разделяем длинную последовательность для обучения на более короткие последовательности, каждая из которых представляет собой мини-пакет, размер которого называется «размером пакета». Я здесь?

Что касается временных шагов, RNN состоит только из ячейки (ячейки LSTM или GRU, или другой ячейки), и эта ячейка является последовательной. Мы можем понять последовательную концепцию, развернув ее. Но разворачивание последовательной ячейки - это концепция, не реальная, что означает, что мы не реализуем ее в развернутом виде. Предположим, что последовательность для обучения - это корпус текста. Затем мы каждый раз подаем одно слово в ячейку RNN, а затем обновляем веса. Итак, почему у нас здесь временные шаги? Объединив свое понимание вышеупомянутого «размера партии», я еще больше запутался. Мы скармливаем ячейке одно слово или несколько слов (размер партии)?


person derek    schedule 06.06.2017    source источник


Ответы (3)


Размер пакета относится к количеству обучающих выборок, которые следует учитывать одновременно для обновления весов вашей сети. Итак, в сети с прямой связью, допустим, вы хотите обновить веса вашей сети на основе вычисления градиентов по одному слову за раз, ваш batch_size = 1. Поскольку градиенты вычисляются из одного образца, это очень дешево в вычислительном отношении. С другой стороны, это тоже очень беспорядочная тренировка.

Чтобы понять, что происходит во время обучения такой сети прямого распространения, я отсылаю вас к этому очень хороший наглядный пример обучения single_batch по сравнению с mini_batch и single_sample.

Однако вы хотите понять, что происходит с вашей переменной num_steps. Это не то же самое, что ваш batch_size. Как вы могли заметить, до сих пор я говорил о сетях прямого распространения. В сети с прямой связью выход определяется из входных данных сети, а отношение вход-выход отображается с помощью изученных сетевых отношений:

hidden_activations (t) = f (ввод (t))

output (t) = g (hidden_activations (t)) = g (f (input (t)))

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

Однако в рекуррентной нейронной сети (RNN) ваша сеть работает немного иначе:

hidden_activations (t) = f (input (t), hidden_activations (t-1))

output (t) = g (hidden_activations (t)) = g (f (input (t), hidden_activations (t-1)))

= g (f (ввод (t), f (ввод (t-1), hidden_activations (t-2)))) = g (f (inp (t), f (inp (t-1), ..., f (inp (t = 0), hidden_initial_state))))

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

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

Если это концептуальное обсуждение не было достаточно ясным, вы также можете взглянуть на более математическое описание вышеперечисленного.

person Uvar    schedule 15.06.2017
comment
Вместо вычисления всех состояний мы можем вычислить подмножество всех состояний, что означает, что нам просто нужно иметь последние ячейки памяти num_steps. Для реализации каждая память представляет собой массив. Итак, в этом случае нам нужна матрица num_steps x каждый размер памяти. Я правильно понимаю? - person derek; 15.06.2017
comment
Я до сих пор не понимаю, как именно работают обучающие примеры в каждой партии. Допустим, у нас есть 5 обучающих примеров в пакете. Означает ли это, что каждый обучающий пример будет загружен в скрытую нейронную клетку, так что у нас будет всего 5 ячеек в RNN? - person derek; 15.06.2017
comment
Предположим, у вас есть размер данных 100 и размер пакета 5 для 20 обновлений сетевых параметров в каждую эпоху. Сначала он распространяет первые 5 обучающих примеров, обновляет свои параметры на основе предоставленного вами метода оптимизации, затем выполняет следующие 5, пока не выполнит полный проход по данным. Num_steps определяет количество разворачиваемых ячеек и, следовательно, количество данных, используемых при вычислении градиента. Поскольку каждая ячейка / уровень имеют общие параметры, это не приводит к увеличению параметров для оптимизации, но позволяет изучать контекст, поэтому вам в первую очередь нужны RNN. - person Uvar; 19.06.2017
comment
Комментарий стал слишком длинным, поэтому продолжаем здесь: Предположим, вы хотели бы иметь возможность фиксировать в текстовом корпусе контекстные отношения, такие как облака в ... Мы все знаем, каким может быть сетевой вывод, независимо от его ввода. Для этого вам понадобится num_steps ›= 4, чтобы сеть могла изучить такие зависимости. Batch_size не имеет ничего общего с зависимостями, он просто определяет количество данных, используемых для каждого пакета обучения. Чем больше пакет, тем более репрезентативен вычисленный градиент для всего набора данных, но требуются большие объемы памяти. - person Uvar; 19.06.2017

Я нашел эту диаграмму, которая помогла мне визуализировать структуру данных.

Структура данных

На изображении «размер партии» - это количество примеров последовательности, с которой вы хотите обучить свою RNN для этой партии. «Значения на временной шаг» - это ваши входные данные ». (в моем случае моя RNN принимает 6 входов) и, наконец, ваши временные шаги - это, так сказать, `` длина '' последовательности, которую вы тренируете.

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

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

Надеюсь это поможет.

person Nate Smith    schedule 11.01.2018
comment
Я встроил изображение для вас. Вы должны сделать все возможное, чтобы обобщить, как изображение отвечает на вопрос OP. Ответ только по ссылке считается низким качеством при переполнении стека. - person Joey Harwood; 12.01.2018
comment
Похоже, мое редактирование для встраивания изображения было отклонено, когда вы сделали свое редактирование. Я могу сделать это снова, если хочешь. - person Joey Harwood; 12.01.2018
comment
@JoeyHarwood Пожалуйста. Спасибо - person derek; 21.01.2018

  1. «Размер пакета» RNN предназначен для ускорения вычислений (поскольку есть несколько полос в параллельных вычислительных модулях); это не мини-пакет для обратного распространения ошибки. Простой способ доказать это - поиграть с разными значениями размера пакета, ячейка RNN с размером пакета = 4 может быть примерно в 4 раза быстрее, чем ячейка с размером пакета = 1, и их потери обычно очень близки.

  2. Что касается «временных шагов» RNN, давайте рассмотрим следующие фрагменты кода из rnn.py. static_rnn () вызывает ячейку для каждого input_ за раз, а BasicRNNCell :: call () реализует свою логику прямой части. В случае предсказания текста, скажем, размер пакета = 8, мы можем думать, что input_ here - это 8 слов из разных предложений в большом текстовом корпусе, а не 8 последовательных слов в предложении. По моему опыту, мы определяем ценность временных шагов в зависимости от того, насколько глубоко мы хотели бы моделировать «во времени» или «последовательной зависимости». Опять же, чтобы предсказать следующее слово в текстовом корпусе с помощью BasicRNNCell, небольшие временные шаги могут работать. С другой стороны, большой размер временного шага может вызвать проблему взрыва градиента.

    def static_rnn(cell,
           inputs,
           initial_state=None,
           dtype=None,
           sequence_length=None,
           scope=None):
    """Creates a recurrent neural network specified by RNNCell `cell`.
       The simplest form of RNN network generated is:
    
       state = cell.zero_state(...)
       outputs = []
       for input_ in inputs:
           output, state = cell(input_, state)
       outputs.append(output)
       return (outputs, state)
    """
    
    class BasicRNNCell(_LayerRNNCell):
    def call(self, inputs, state):
    """Most basic RNN: output = new_state = 
       act(W * input + U * state + B).
    """
        gate_inputs = math_ops.matmul(
            array_ops.concat([inputs, state], 1), self._kernel)
        gate_inputs = nn_ops.bias_add(gate_inputs, self._bias)
        output = self._activation(gate_inputs)
        return output, output
    
  3. Чтобы наглядно представить, как эти два параметра связаны с набором данных и весами, Эрика Халлстрёма стоит прочитать. Из этой диаграммы и приведенных выше фрагментов кода очевидно, что "размер пакета" RNN не будет влияют на веса (wa, wb и b), но влияют на "временные шаги". Таким образом, можно определить «временные шаги» RNN на основе их проблемы и сетевой модели, а также «размера пакета» RNN на основе вычислительной платформы и набора данных.

person rcnjko    schedule 22.03.2018