0

我正在尝试实现一个简单的循环神经网络架构,并注意tf.keras在 Tensorflow 2.1 中使用的序列到序列任务。我大部分时间都在关注Tensorflow 教程,到目前为止,它正在工作。

但是,该指南使用自写的培训功能,我想使用各种tf.keras.Model功能,例如fit,所以我尝试调整代码以允许我使用这些功能。问题点如下:在解码器部分,由于注意力架构,必须手动迭代时间步长,进行注意力计算并将结果提供给下一步。我的解码器模型如下所示:

class MyDecoderModel(tf.keras.Model):
    def __init__(self, **kwargs):
        ...

    def call(self, x):
        seq_in, state_in = x
        batch_size, seq_len = seq_in.shape
        for step in range(seq_len):
            do_stuff()

最重要的是,必须定义输入的序列长度,而不是None. 但我想使用可变序列长度。据我了解,这使得我通常会使用的 Keras 功能 API 无法使用这个模型,因为编写了类似的东西

x = tf.keras.Input(shape=(None,))
x = MyDecoderModel()(x)

将反馈None到通话中。所以我决定只使用模型子类化,编写一个主模型

class MyMainModel(tf.keras.Model):
    ...
    def call(self, x):
        enc_in, dec_in = x
        state = self.my_encoder(enc_in)
        dec_out = self.my_decoder((dec_in, state))
        return dec_out

这似乎在原则上有效,使用输入数据调用这个主模型成功地产生了结果。但是,当fit()在这个模型上使用该方法时,会发生一些我不明白的事情:首先,模型以未知的批量大小被调用,但指定的序列长度。随后,仅以指定的批量大小调用它,但序列长度未知。因此None通过并且迭代失败。

现在为什么会发生这种情况?训练时,batch的序列长度肯定是已知的,为什么不传给我的模型呢?如果没有自定义培训方法,是否有机会解决这个问题?如果有人能解释那里发生了什么,我会很高兴...

4

1 回答 1

0

第一件事:如果您的输入数据是一个序列,则输入的形状Input必须具有两个值: ( timesteps, features).timesteps可以是None,但features必须具有固定形状。如果您只有一个特征,请执行以下操作:

x = tf.keras.Input(shape=(None, 1))

其次,您可以在模型中使用可变时间步长,只需进行一些更改;tf.unstack你的朋友在这里吗:

class MyDecoderModel(tf.keras.Model):
    def __init__(self, **kwargs):
        ...

    def call(self, x):
        seq_in, state_in = x
        step_number = 0
        steps_in = tf.unstack(seq_in, axis=SEQUENCE_AXIS)
        steps_out = []
        for step in batches_in:
            steps_out.append(do_stuff())
            step_number += 1
        return tf.stack(steps_out, axis=SEQUENCE_AXIS)
于 2020-04-30T17:45:16.220 回答