我最近遇到了类似的情况,在这里我想链经常性和非经常性层。
我是否preceed我LSTM层用这种简单的层都传递给 tf.nn.dynamic_rnn()操作...
这是行不通的。该功能dynamic_rnn
预计细胞作为第一个参数。单元格是从tf.nn.rnn_cell.RNNCell
继承的类。此外,dynamic_rnn
的第二个输入参数应该是至少有三个维度的张量,其中前两个维度是批次和时间(time_major=False
)或时间和批次(time_major=True
)。
我是否使用函数tf.map_fn()两次(一个拆封批次,一个解包序列),其中,如果一个理解好,能解压我的序列并在每个特征线施加的层。
这可能行得通,但在我看来并不是一个高效而干净的解决方案。首先,不需要“解包批次”,因为您可能希望对批次的特征和时间步骤执行一些操作,批次中的每个观察都独立于其他批次。
我对这个问题的解决方案是创建一个tf.nn.rnn_cell.RNNCell
的子类。就我而言,我想这将遍历所有的时间步骤,并且可以在dynamic_rnn
可以使用一个简单的前馈层:
import tensorflow as tf
class FeedforwardCell(tf.nn.rnn_cell.RNNCell):
"""A stateless feedforward cell that can be used with MultiRNNCell
"""
def __init__(self, num_units, activation=tf.tanh, dtype=tf.float32):
self._num_units = num_units
self._activation = activation
# Store a dummy state to make dynamic_rnn happy.
self.dummy = tf.constant([[0.0]], dtype=dtype)
@property
def state_size(self):
return 1
@property
def output_size(self):
return self._num_units
def zero_state(self, batch_size, dtype):
return self.dummy
def __call__(self, inputs, state, scope=None):
"""Basic feedforward: output = activation(W * input)."""
with tf.variable_scope(scope or type(self).__name__): # "FeedforwardCell"
output = self._activation(tf.nn.rnn_cell._linear(
[inputs], self._num_units, True))
return output, self.dummy
这个类的一个实例可以通过,在列表中有“正常” RNN细胞,到tf.nn.rnn_cell.MultiRNNCell
初始值设定项。结果对象实例可以作为cell
输入参数传递给dynamic_rnn
。
重要提示:dynamic_rnn
预计复发性细胞在被调用时会返回一个状态。因此我在FeedforwardCell
中使用dummy
作为假状态变量。
我的解决方案可能不是最顺利或最好的方法来将循环和非循环图层链接在一起。我有兴趣从其他Tensorflow用户那里了解他们的建议。
编辑 如果您选择使用的dynamic_rnn
的sequence_length
输入参数,然后state_size
应该是self._num_units
和dummy
国家应该具有的形状[batch_size, self.state_size]
。换句话说,国家不可能是一个标量。请注意,bidirectional_dynamic_rnn
要求参数sequence_length
不是None
,而dynamic_rnn
不具有此要求。 (这在TF文档中记录得很少。)