Я работаю над оценкой 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. Я все еще ищу решение.
Вы можете получить размер партии из другого тензора пример
decoder_initial_state = cell.zero_state(array_ops.shape(attention_states)[0],
dtypes.float32).clone(cell_state=encoder_state)
Я использую разные размеры пакетов для обучения, оценки и вывода, он отлично работает без явного удаления размеров пакетов при загрузке контрольных точек.BTW я использую TensorFlow 1.11.0-rc0, вы можете использовать tf-nightly или tf-nightly-gpu, чтобы получить эту версию
Как инициализировать параметр initial_state?
Переход на 1.11 ничего не изменил. Начальное состояние сохраняется с заданным размером (который зависит от размера пакета) и ожидает того же размера при загрузке. Я делаю всю сеть зависимой от размера пакета. Очень назойливый. Кто-нибудь нашел решение?
посмотри на это: machinelearningmastery.com/…. Например, вам нужны разные графики для обучения, оценки и тестирования, когда вы используете тензорный поток, посмотрите здесь: github.com/tensorflow/…
Если у вас есть небольшой воспроизводимый код, я буду рад помочь
Спасибо за ваш ответ. Хитрость заключалась в том, чтобы создать оба начальных состояния, одно для обучения, а другое для прогнозирования с разными размерами пакетов, и сериализовать их оценщиком. Затем используйте условие is_training, чтобы использовать первую или вторую переменную.
Я нашел решение:
Он работает, поскольку обе эти переменные будут сериализованы и восстановлены кодом оценки, поэтому он не будет жаловаться. Недостатком является то, что размер пакета запроса (в моем случае 1) должен быть известен во время обучения (когда он создает обе переменные).
Спасибо, что ответили. Это не решает проблему, так как размеры пакетов будут разными во время обучения и прогнозирования. Таким образом, размер внутреннего состояния RNN будет сериализован с заданным размером, тогда при перезагрузке произойдет несоответствие размера. Вот почему я пытаюсь отфильтровать эту переменную 'H' при перезагрузке контрольной точки. Он будет инициализирован нулевым_состоянием на основе размера входного пакета и не будет перезаписан загрузкой контрольной точки.