在Tensorflow 1.9中的LSTM中设置初始状态



我尝试制作一个简单的LSTM网络,其中堆叠了2层。为此,我使用MultiRNNCell。我学习了教程和其他堆栈主题,但我仍然有一个问题来运行我的网络。下面可以找到我在堆栈上找到的初始状态声明。

cell_count = 10 # timesteps
num_hidden = 4 # hidden layer num of features
num_classes = 1 
num_layers = 2
state_size = 4
init_c = tf.Variable(tf.zeros([batch_size, cell_count]), trainable=False)
init_h = tf.Variable(tf.zeros([batch_size, cell_count]), trainable=False)
initial_state = rnn.LSTMStateTuple(init_c, init_h) #[num_layers, 2, batch_size, state_size])

下面你可以找到我的模型是什么样子的:

def generate_model_graph(self, data):
L1 = self.generate_layer(self.cell_count)
L2 = self.generate_layer(self.cell_count)
#outputs from L1
L1_outs, _ = L1(data, self.initial_state)
#reverse output array
L2_inputs = L1_outs[::-1]
L2_outs, _ = L2(L2_inputs, self.initial_state)
predicted_vals = tf.add(tf.matmul(self.weights["out"], L2_outs), self.biases["out"])
L2_out = tf.nn.sigmoid(predicted_vals)
return L2_out

def generate_layer(self, size):
cells = [rnn.BasicLSTMCell(self.num_hidden) for _ in range(size)]
return rnn.MultiRNNCell(cells)

并运行会话:

def train_model(self, generator):
tr, cost = self.define_model()
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for _ in range(self.n_epochs):
batch_x, batch_y = self._prepare_data(generator)
init_state = tf.zeros((self.cell_count, self.num_hidden))
t, c = sess.run([tr, cost], feed_dict={self.X: batch_x, self.Y:batch_y, self.initial_state:init_state})
print(c)

不幸的是,我仍然在说'Variable' object is not iterable时出错。

File "detector_lstm_v2.py", line 104, in <module>
c.train_model(data_gen)
File "detector_lstm_v2.py", line 38, in train_model
tr, cost = self.define_model()
File "detector_lstm_v2.py", line 51, in define_model
predicted_vals = self.generate_model_graph(self.X)
File "detector_lstm_v2.py", line 65, in generate_model_graph
L1_outs, _ = L1(data, self.initial_state)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/rnn_cell_impl.py", line 232, in __call__
return super(RNNCell, self).__call__(inputs, state)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/layers/base.py", line 329, in __call__
outputs = super(Layer, self).__call__(inputs, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/base_layer.py", line 703, in __call__
outputs = self.call(inputs, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/rnn_cell_impl.py", line 1325, in call
cur_inp, new_state = cell(cur_inp, cur_state)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/rnn_cell_impl.py", line 339, in __call__
*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/layers/base.py", line 329, in __call__
outputs = super(Layer, self).__call__(inputs, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/base_layer.py", line 703, in __call__
outputs = self.call(inputs, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/rnn_cell_impl.py", line 633, in call
c, h = state
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/variables.py", line 491, in __iter__
raise TypeError("'Variable' object is not iterable.")
TypeError: 'Variable' object is not iterable.

有人知道如何解决这个问题吗?

您正在创建一个多层rnn单元,但您正在传递一个状态。

使用此创建您的状态:

initial_state = L1.zero_state()

或者,如果您需要一个变量,可以使用它来初始化该变量。

你的代码中有一些"命名"问题,这让我认为你误解了这里的一些内容

有不同的参数:

  1. 层的隐藏大小:它是RNNCell构造函数的units属性。你的细胞的所有状态都必须有一个形状[bacth_size,hidden_size](而不是细胞计数(
  2. 代码中的cell_count不是决定序列的长度,而是决定网络的"深度">
  3. 序列的长度是根据您传递给模型的输入序列(需要是张量列表(自动确定的

我建议你在这里看一看关于递归神经网络的TF教程,也许在这里看这个答案,以了解什么是RNNCell w.r.t.RNN文献(它是一层而不是单个细胞(。

最新更新