2016-07-15 8 views
4

Keras에서 LSTM을 실행하고 출력에 상태를 더하고 싶습니다. TFKeras LSTM 상태

with tf.variable_scope("RNN"): 
     for time_step in range(num_steps): 
     if time_step > 0: tf.get_variable_scope().reuse_variables() 
     (cell_output, state) = cell(inputs[:, time_step, :], state) 
     outputs.append(cell_output) 

에서이 같은 일부 것은 내가 마지막 상태를 얻을 시퀀스의 아이폰에 거대한 때 새로운 입력에 공급할 수 Keras에서 그렇게 할 수있는 방법이있다. 나는 stateful = True를 알고 있지만 훈련도하는 동안 주에 대한 액세스 권한을 원합니다. 나는 for 루프를 사용하지 않고 기본적으로 상태를 저장하고 다음 실행시에 LSTM에 대한 시작 상태로 만들고 싶습니다. 요약하면 출력과 상태를 모두 얻으십시오.

답변

2

LSTM이 레이어이기 때문에 레이어가 하나의 케라 출력 만 가질 수 있습니다 (내가 틀렸다면 수정하십시오) 은 소스 코드를 수정하지 않고 두 개의 출력을 동시에 얻을 수 없습니다.

최근 몇 가지 진보 된 구조를 구현하기 위해 keras를 해킹하고 있습니다. 좋지 않을 수도있는 몇 가지 생각이 효과가있었습니다. 내가 뭘했는지는 케라 레이어을 오버라이드하여 숨겨진 상태를 나타내는 텐서에 액세스 할 수있게합니다.

첫째, 당신의 keras이 작업을 어떻게했는지에 대한 keras/layers/recurrent.pycall() 기능을 확인할 수 있습니다

import keras.backend as K 
from keras.layers import Input, LSTM 
class MyLSTM(LSTM): 
    def call(self, x, mask=None): 
    # .... blablabla, right before return 

    # we add this line to get access to states 
    self.extra_output = states 

    if self.return_sequences: 
    # .... blablabla, to the end 

    # you should copy **exactly the same code** from keras.layers.recurrent 

I = Input(shape=(...)) 
lstm = MyLSTM(20) 
output = lstm(I) # by calling, we actually call the `call()` and create `lstm.extra_output` 
extra_output = lstm.extra_output # refer to the target 

calculate_function = K.function(inputs=[I], outputs=extra_output+[output]) # use function to calculate them **simultaneously**. 
+0

그런데 우리가 우리의 레이어를 오버라이드 (override), 둘째

def call(self, x, mask=None): # input shape: (nb_samples, time (padded with zeros), input_dim) # note that the .build() method of subclasses MUST define # self.input_spec with a complete input shape. input_shape = self.input_spec[0].shape if K._BACKEND == 'tensorflow': if not input_shape[1]: raise Exception('When using TensorFlow, you should define ' 'explicitly the number of timesteps of ' 'your sequences.\n' 'If your first layer is an Embedding, ' 'make sure to pass it an "input_length" ' 'argument. Otherwise, make sure ' 'the first layer has ' 'an "input_shape" or "batch_input_shape" ' 'argument, including the time axis. ' 'Found input shape at layer ' + self.name + ': ' + str(input_shape)) if self.stateful: initial_states = self.states else: initial_states = self.get_initial_states(x) constants = self.get_constants(x) preprocessed_input = self.preprocess_input(x) last_output, outputs, states = K.rnn(self.step, preprocessed_input, initial_states, go_backwards=self.go_backwards, mask=mask, constants=constants, unroll=self.unroll, input_length=input_shape[1]) if self.stateful: self.updates = [] for i in range(len(states)): self.updates.append((self.states[i], states[i])) if self.return_sequences: return outputs else: return last_output 

을, 여기에 간단한 스크립트입니다 , 레이어를 커스터마이징하는 것은로드 할 때 케라가로드 할 때'MyLSTM'을 찾을 수 없기 때문에로드 및 저장시 약간의 에러를 일으 킵니다. model_from_json()을 호출 할 때'custom_object = { 'MyLSTM': MyLSTM}'을 호출하면됩니다. 그것은 간단해야합니다. – Van