Tensorflow: как использовать начальное состояние rnn в оценщике с разным размером пакета для обучения и тестирования?

Я работаю над оценкой Tensorflow с использованием RNN (GRUCell). Я использую zero_state для инициализации первого состояния, он требует фиксированного размера. Моя проблема в том, что я хочу иметь возможность использовать оценщик для прогнозирования с помощью одной выборки (размер партии = 1). Когда он загружает сериализованный оценщик, он жалуется, что размер пакета, который я использую для прогнозирования, не соответствует размеру обучающего пакета.

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

Есть ли элегантный способ использовать zero_state в оценщике? Я видел некоторые решения с использованием переменной для хранения размера партии, но с использованием метода feed_dict. Я не могу найти, как заставить его работать в контексте оценщика.

Вот суть моей простой тестовой RNN в оценщике:

cells = [  tf.nn.rnn_cell.GRUCell(self.getNSize()) for _ in range(self.getNLayers())]


multicell = tf.nn.rnn_cell.MultiRNNCell(cells, state_is_tuple=False)
H_init = tf.Variable( multicell.zero_state( batchsize, dtype=tf.float32 ), trainable=False)
H = tf.Variable( H_init )

Yr, state = tf.nn.dynamic_rnn(multicell, Xo, dtype=tf.float32, initial_state=H)

Кто-нибудь знает об этом?

Обновлено:

Хорошо, я пробую разные способы решения этой проблемы. Теперь я пытаюсь отфильтровать переменные, которые я загружаю из контрольной точки, чтобы удалить «H», которое используется как внутреннее состояние повторяющихся ячеек. Для предсказания я могу оставить все 0 значений.

Пока что я сделал это: Сначала я определяю крючок:

class RestoreHook(tf.train.SessionRunHook):
    def __init__(self, init_fn):
        self.init_fn = init_fn

    def after_create_session(self, session, coord=None):
        print("--------------->After create session.")
        self.init_fn(session)

Затем в моей model_fn:

if mode == tf.estimator.ModeKeys.PREDICT:
        logits = tf.nn.softmax(logits)

        # Do not restore H as it's batch size might be different.
        vlist = tf.contrib.framework.get_variables_to_restore()
        vlist = [ x for x in vlist if x.name.split(':')[0] != 'architecture/H']
        init_fn = tf.contrib.framework.assign_from_checkpoint_fn(tf.train.latest_checkpoint(self.modelDir), vlist, ignore_missing_vars=True)
        spec = tf.estimator.EstimatorSpec(mode=mode,
                                          predictions = {
                                              'logits': logits,
                                          },
                                          export_outputs={
                                              'prediction': tf.estimator.export.PredictOutput( logits )
                                          },
                                          prediction_hooks=[RestoreHook(init_fn)])

Я взял этот фрагмент кода из https://github.com/tensorflow/tensorflow/issues/14713

Но пока не работает. Вроде все еще пытается загрузить H из файла ... Проверил, что его нет в vlist. Я все еще ищу решение.

0
0
388
2

Ответы 2

Вы можете получить размер партии из другого тензора пример

decoder_initial_state = cell.zero_state(array_ops.shape(attention_states)[0], dtypes.float32).clone(cell_state=encoder_state)

Спасибо, что ответили. Это не решает проблему, так как размеры пакетов будут разными во время обучения и прогнозирования. Таким образом, размер внутреннего состояния RNN будет сериализован с заданным размером, тогда при перезагрузке произойдет несоответствие размера. Вот почему я пытаюсь отфильтровать эту переменную 'H' при перезагрузке контрольной точки. Он будет инициализирован нулевым_состоянием на основе размера входного пакета и не будет перезаписан загрузкой контрольной точки.

Guillaume 13.09.2018 12:12

Я использую разные размеры пакетов для обучения, оценки и вывода, он отлично работает без явного удаления размеров пакетов при загрузке контрольных точек.BTW я использую TensorFlow 1.11.0-rc0, вы можете использовать tf-nightly или tf-nightly-gpu, чтобы получить эту версию

sam 14.09.2018 09:21

Как инициализировать параметр initial_state?

Guillaume 14.09.2018 11:56

Переход на 1.11 ничего не изменил. Начальное состояние сохраняется с заданным размером (который зависит от размера пакета) и ожидает того же размера при загрузке. Я делаю всю сеть зависимой от размера пакета. Очень назойливый. Кто-нибудь нашел решение?

Guillaume 01.10.2018 15:00

посмотри на это: machinelearningmastery.com/…. Например, вам нужны разные графики для обучения, оценки и тестирования, когда вы используете тензорный поток, посмотрите здесь: github.com/tensorflow/…

sam 02.10.2018 08:34

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

sam 02.10.2018 08:39

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

Guillaume 02.10.2018 15:21

Я нашел решение:

  • Я создаю переменные для начального состояния как для размера партии = 64, так и для размера партии = 1.
  • На тренировке я использую первый для инициализации RNN.
  • В Predict time я использую второй.

Он работает, поскольку обе эти переменные будут сериализованы и восстановлены кодом оценки, поэтому он не будет жаловаться. Недостатком является то, что размер пакета запроса (в моем случае 1) должен быть известен во время обучения (когда он создает обе переменные).

Другие вопросы по теме