Tensorflow Keras model.summary() 在层上显示 0 个可训练参数

Tap*_*pio 7 python keras tensorflow tf.keras

我正在训练 LSTM 变体 PhasedLSTM 以进行回归。我正在使用 tensorflow.contrib.rnn.PhasedLSTMCell ,除了功能之外,它还需要一个时间戳向量。这是我的模型定义:

    from tensorflow.keras.layers import Dense, RNN, Input
    from tensorflow.keras.models import Model
    from tensorflow.keras.optimizers import Adam

    from tensorflow.contrib.rnn import PhasedLSTMCell

    hidden_size = 128
    num_features = 217
    num_timesteps = 2016

    input_layer_timestamps = Input(shape=(num_timesteps, 1), name='time_input')
    input_layer_features = Input(shape=(num_timesteps, num_features) name='data_input')

    timed_inputs = (input_layer_timestamps, input_layer_features)

    P_cell = PhasedLSTMCell(hidden_size)
    PLSTM_layer = RNN(P_cell, return_sequences=False, name='Phased_LSTM_1')(timed_inputs)

    output_layer = Dense(2, activation=None)(PLSTM_layer_1)

    model = Model(inputs  = [input_layer_timestamps, input_layer_features],
                  outputs = [output_layer])

    lstm_optimizer = Adam(lr=Adam_lr, clipnorm=5.)

    model.compile(optimizer=lstm_optimizer,
                  loss='mse')

    model.summary()
Run Code Online (Sandbox Code Playgroud)

该模型可以很好地编译和训练。验证结果似乎不错,但存在合理的错误。但是,上一个片段中 model.summary() 的输出是:

__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
================================================================================================== 
time_input (InputLayer)         (None, 2016, 1)      0                

__________________________________________________________________________________________________ 
data_input (InputLayer)         (None, 2016, 217)    0                

__________________________________________________________________________________________________ 
Phased_LSTM_1 (RNN)             (None, 128)           0           time_input[0][0]                 
                                                                 data_input[0][0]                 
__________________________________________________________________________________________________ 
dense_1 (Dense)                 (None, 2)            66          Phased_LSTM_1[0][0]              
==================================================================================================
Total params: 258 Trainable params: 258 Non-trainable params: 0
__________________________________________________________________________________________________
Run Code Online (Sandbox Code Playgroud)

值得注意的是 Phased_LSTM_1 的可训练参数数量为 0

如果 model.weights() 被调用,它根本不显示 LSTM 部分:

ipdb> NN.weights
[<tf.Variable 'scope/dense/kernel:0' shape=(128, 2) dtype=float32>, <tf.Variable 'scope/dense/bias:0' shape=(2,) dtype=float32>]
Run Code Online (Sandbox Code Playgroud)

此外,如果模型随后使用 model.save() 保存并使用 tensorflow.keras.models.load_model 或定义模型 -> model.load() 加载,则模型的行为将完全不同。相当好的验证精度将变成一个只预测噪声的模型,即看起来原来相当好的回归模型从一个 RNN 变成了一个看起来确实像一个 128 个神经元的单层 NN,线性激活训练错误事物。

我有三个问题:

1)发生了什么?这是一个错误还是只是我滥用了 Keras RNN API?

2) 我如何验证 LSTM 是否被正确训练?我想像通常使用 model.weights 和 model.get_weights() 一样检查图层

3) 如何在不破坏模型的情况下保存和加载该模型?我的输入和输出管道及其周围的模块是为 Keras 构建的,因此如果可能,我宁愿不将 NN 定义转换为“基本”张量流。

我正在使用 tensorflow-gpu 1.13.1 和 Keras 2.2.4-tf