带有自定义训练循环和 tf.data.dataset 的 tensorflow

问题描述 投票:0回答:0

我正在尝试构建一个带有自定义训练循环的张量流模型,以使用预测来提供下一个时间步长的输入。关于头部和输入集的模型。我无法找到如何传递我的 2 个输入并管理如何处理自定义调用函数。

我使用这个参考来构建我的代码: https://www.tensorflow.org/tutorials/structured_data/time_series#advanced_autoregressive_model 这是我的数据示例以及我想在每个时间步迭代中使用它的方式。

Input#1
|---input warm up/observed data---|--- forcast---------------------|
          t-5    t-4    t-3    t-2    t-1    t-0     t+1    t+2    t+3   
  var#1    3       2      1      5      4      2       1      3     4   
  var#2    1      -1     -3      1      0     -5      -11     0     1    
  var#3    66     67     69     71      73    75       ?      ?     ?   
 
Using this exemple, var1-2 are inputs, var3 inputs AND labels. Var3 is know on first times steps with a lag on 1 day (today we know last day value of var3) to start model.
First itteration I get these inputs and try forecaste a values that will be insert in var3 t+1 fore the next itteration:
          t-5    t-4    t-3    t-2    t-1    t-0     t+1 
  var#1    3       2      1      5      4      2          
  var#2    1      -1     -3      1      0     -5          
  var#3    66     67     69     71      73    75       ?  
if ? =88 the next inputs for next itteration will looklike this:
          t-5    t-4    t-3    t-2    t-1    t-0     t+1    t+2  
  var#1    3       2      1      5      4      2       1            
  var#2    1      -1     -3      1      0     -5      -11            
  var#3    66     67     69     71      73    75     ?=88     ?    

Input#2
Is just a seq of 3 values for the second head of model using only dense layer.
class FeedBack(tf.keras.Model):

    def __init__(self, num_timesteps_in, num_timesteps_out, nb_features, nb_attributs,
                 nb_lstm_units, nb_dense_units):
        super(FeedBack, self).__init__()
        self.num_timesteps_in = num_timesteps_in
        self.num_timesteps_out = num_timesteps_out
        self.nb_features = nb_features
        self.nb_attributs = nb_attributs
        self.nb_lstm_units = nb_lstm_units
        self.nb_dense_units = nb_dense_units

        self.lstm_cell = tf.keras.layers.LSTMCell(nb_lstm_units)
        self.dense = tf.keras.layers.Dense(nb_lstm_units)


def call(self, inputs, training=None):

    predictions = []
    inputs1 = tf.keras.Input(shape=(self.num_timesteps_in + self.num_timesteps_out, self.nb_features))
    inputs2 = tf.keras.Input(shape=(self.nb_attributs))

    # Run prediction steps by step with a rolling window on the inputs
    for i in range(0, self.num_timesteps_out):
        
        input_chunk = inputs1[i:i + self.num_timesteps_in, :]

        # Execute one step.
        extraction_info = self.lstm_cell(self.nb_lstm_units, 
                                         training=training,
                                         return_sequences=False, 
                                         stateful=False)(input_chunk)

        extraction_info = tf.keras.layers.Dropout(0.2)(extraction_info)

        
        # -------------- Merge les inputs météo/apports avec les attributs physiographiques --------------------

        merged_input = tf.keras.layers.Concatenate(axis=1, name='merged_head')([extraction_info, inputs2])

        merged_input = self.Dense(self.nb_dense_units)(merged_input)

        merged_input = tf.keras.layers.Dropout(0.2)(merged_input)

        prediction = self.Dense(1, activation='linear')(merged_input)

        # insert this forecast into the input1 on the next timestep
        inputs1[i + self.num_timesteps_in + 1, -1] = prediction
        # Add the prediction to the record for extracting at the end.
        predictions.append(prediction)

    return predictions

现在格式化为 tf.数据集训练模型

optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rates[1])

# inputs convertion to tf.data.dataset
inputs_hydro = tf.data.Dataset.from_tensor_slices((X1))
inputs_static = tf.data.Dataset.from_tensor_slices((X2))
output = tf.data.Dataset.from_tensor_slices((y))
combined_dataset = tf.data.Dataset.zip(((inputs_hydro, inputs_static), output))
input_dataset = combined_dataset.batch(5)

base_model = cr.FeedBack(10, 5, 2, 3, 50, 50)
base_model.call = cr.call
model.compile(optimizer=optimizer, loss=tf.keras.losses.MeanSquaredError())
history = model.fit(input_dataset,
                    verbose=0,
                    epochs=10)

At this point, I try a lot of thing and read many exemples and questions but still be unable to make it run.The actual version I got this error: 

File "E:\Anaconda3\envs\tf2.7_bigData\lib\site-packages\keras\engine\training.py", line 1160, in train_function  *
        return step_function(self, iterator)

    TypeError: tf__call() missing 1 required positional argument: 'inputs'

Any help will be realy welcom! It is my first use of tf.data.dataset and of custom layer/model, it is a hard step in my learning lol

python tensorflow tensorflow-datasets
© www.soinside.com 2019 - 2024. All rights reserved.