簡體   English   中英

Tensorflow在dynamic_rnn中保存LSTM的最終狀態以進行預測

[英]Tensorflow save final state of LSTM in dynamic_rnn for prediction

我想保存LSTM的最終狀態,以便在我恢復模型時將其包含在內並可用於預測。 如下所述,當我使用tf.assign時,Saver只知道最終狀態。 但是,這會引發錯誤(也在下面說明)。

在培訓過程中,我總是喂最終LSTM狀態回到網絡中,在解釋這個職位 以下是代碼的重要部分:

構建圖表時:

            self.init_state = tf.placeholder(tf.float32, [
                self.n_layers, 2, self.batch_size, self.n_hidden
            ])

            state_per_layer_list = tf.unstack(self.init_state, axis=0)

            rnn_tuple_state = tuple([
                tf.contrib.rnn.LSTMStateTuple(state_per_layer_list[idx][0],
                                              state_per_layer_list[idx][1])

                for idx in range(self.n_layers)
            ])

            outputs, self.final_state = tf.nn.dynamic_rnn(
                cell, inputs=self.inputs, initial_state=rnn_tuple_state)

在培訓期間:

        _current_state = np.zeros((self.n_layers, 2, self.batch_size,
                                   self.n_hidden))

            _train_step, _current_state, _loss, _acc, summary = self.sess.run(
                [
                    self.train_step, self.final_state,
                    self.merged
                ],
                feed_dict={self.inputs: _inputs,
                           self.labels:_labels, 
                           self.init_state: _current_state})

當我稍后從檢查點恢復我的模型時,最終狀態也不會恢復。 作為概括這篇文章的問題是,包裹沒有新狀態的知識。 該帖還提出了一個基於tf.assign的解決方案。 遺憾的是,我無法使用建議

            assign_op = tf.assign(self.init_state, _current_state)
            self.sess.run(assign_op)

因為self.init狀態不是Variable而是占位符。 我收到了錯誤

AttributeError:'Tensor'對象沒有屬性'assign'

我已經嘗試解決這個問題幾個小時了,但我無法讓它工作。

任何幫助表示贊賞!

編輯:

我已將self.init_state更改為

            self.init_state = tf.get_variable('saved_state', shape=
            [self.n_layers, 2, self.batch_size, self.n_hidden])

            state_per_layer_list = tf.unstack(self.init_state, axis=0)

            rnn_tuple_state = tuple([
                tf.contrib.rnn.LSTMStateTuple(state_per_layer_list[idx][0],
                                              state_per_layer_list[idx][1])

                for idx in range(self.n_layers)
            ])

            outputs, self.final_state = tf.nn.dynamic_rnn(
                cell, inputs=self.inputs, initial_state=rnn_tuple_state)

在訓練期間,我沒有為self.init_state提供值:

            _train_step, _current_state, _loss, _acc, summary = self.sess.run(
                [
                    self.train_step, self.final_state,
                    self.merged
                ],
                feed_dict={self.inputs: _inputs,
                           self.labels:_labels})

但是,我仍然無法運行賦值操作。 知道我明白了

TypeError:期望的float32傳遞給op'Disign'的參數'value',得到(LSTMStateTuple(c = array([[0.07291573,-0.06366599,-0.23425588,...,0.05307654,

為了保存最終狀態,您可以創建一個單獨的TF變量,然后在保存圖形之前,運行assign op將最新狀態分配給該變量,然后保存圖形。 您唯一需要記住的是在聲明Saver之前聲明該變量; 否則它將不會包含在圖表中。

這里將對此進行詳細討論,包括工作代碼: TF LSTM:稍后從訓練會話中保存狀態以進行預測會話

***更新:后續問題的答案:

看起來你正在使用BasicLSTMCellstate_is_tuple=True 之前的討論,我提到你使用GRUCellstate_is_tuple=False 兩者之間的細節有些不同,但總體方法可能類似,所以希望這對您有用:

在訓練期間,首先將零作為initial_statedynamic_rnn ,然后將其自身的輸出重新作為輸入返回到initial_state 因此,我們的dynamic_rnn調用的LAST輸出狀態是您想要保存以供日后使用的狀態。 因為它是由sess.run()調用產生的,所以基本上它是一個numpy數組(不是張量而不是占位符)。 所以這個問題相當於“如何將numpy數組保存為Tensorflow變量以及圖中的其余變量。” 這就是為什么你將最終狀態分配給一個唯一目的的變量。

所以,代碼是這樣的:

    # GRAPH DEFINITIONS:
    state_in = tf.placeholder(tf.float32, [LAYERS, 2, None, CELL_SIZE], name='state_in')
    l = tf.unstack(state_in, axis=0)
    state_tup = tuple(
        [tf.nn.rnn_cell.LSTMStateTuple(l[idx][0], l[idx][1])
        for idx in range(NLAYERS)])
    #multicell = your BasicLSTMCell / MultiRNN definitions
    output, state_out = tf.nn.dynamic_rnn(multicell, X, dtype=tf.float32, initial_state=state_tup)

    savedState = tf.get_variable('savedState', shape=[LAYERS, 2, BATCHSIZE, CELL_SIZE])
    saver = tf.train.Saver(max_to_keep=1)

    in_state = np.zeros((LAYERS, 2, BATCHSIZE, CELL_SIZE))

    # TRAINING LOOP:
    feed_dict = {X: x, Y_: y_, batchsize: BATCHSIZE, state_in:in_state}
    _, out_state = sess.run([training_step, state_out], feed_dict=feed_dict)
    in_state = out_state

    # ONCE TRAINING IS OVER:
    assignOp = tf.assign(savedState, out_state)
    sess.run(assignOp)
    saver.save(sess, pathModel + '/my_model.ckpt')

    # RECOVERING IN A DIFFERENT PROGRAM:

    gInit = tf.global_variables_initializer().run()
    lInit = tf.local_variables_initializer().run()
    new_saver = tf.train.import_meta_graph(pathModel + 'my_model.ckpt.meta')
    new_saver.restore(sess, pathModel + 'my_model.ckpt')
    # retrieve State and get its LAST batch (latest obervarions)
    savedState = sess.run('savedState:0') # this is FULL state from training
    state = savedState[:,:,-1,:]  # -1 gets only the LAST batch of the state (latest seen observations)
    state = np.reshape(state, [state.shape[0], 2, -1, state.shape[2]]) #[LAYERS, 2, 1 (BATCH), SELL_SIZE]
    #x = .... (YOUR INPUTS)
    feed_dict = {'X:0': x, 'state_in:0':state}
    #PREDICTION LOOP:
    preds, state = sess.run(['preds:0', 'state_out:0'], feed_dict = feed_dict)
    # so now state will be re-fed into feed_dict with the next loop iteration

如上所述,對於GRUCell來說,這是一個改進的方法,其中state_is_tuple = False 我適應它嘗試BasicLSTMCellstate_is_tuple=True 它有效,但不如原始方法准確。 我不知道它是否僅僅因為對我來說GRU比LSTM更好或者出於其他原因。 看看這對你有用嗎......

另外請記住,正如您可以看到的恢復和預測代碼,您的預測可能會基於不同的批量大小而不是您的訓練循環(我猜一批1?)所以你必須考慮如何處理你的恢復狀態 - 只需要最后一批? 或者是其他東西? 此代碼僅采用保存狀態的最后一層(即最近的培訓觀察結果),因為這與我的相關...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM