美文网首页
tf教程4: 因果卷积+LSTM预测时序数据

tf教程4: 因果卷积+LSTM预测时序数据

作者: poteman | 来源:发表于2019-08-10 17:42 被阅读0次
    • 导入所需的包
    !pip install tf-nightly-2.0-preview
    import tensorflow as tf
    import numpy as np
    import matplotlib.pyplot as plt
    print(tf.__version__)
    
    • 构造人工时序数据
    def plot_series(time, series, format="-", start=0, end=None):
        plt.plot(time[start:end], series[start:end], format)
        plt.xlabel("Time")
        plt.ylabel("Value")
        plt.grid(True)
    
    def trend(time, slope=0):
        return slope * time
    
    def seasonal_pattern(season_time):
        """Just an arbitrary pattern, you can change it if you wish"""
        return np.where(season_time < 0.4,
                        np.cos(season_time * 2 * np.pi),
                        1 / np.exp(3 * season_time))
    
    def seasonality(time, period, amplitude=1, phase=0):
        """Repeats the same pattern at each period"""
        season_time = ((time + phase) % period) / period
        return amplitude * seasonal_pattern(season_time)
    
    def noise(time, noise_level=1, seed=None):
        rnd = np.random.RandomState(seed)
        return rnd.randn(len(time)) * noise_level
    
    time = np.arange(4 * 365 + 1, dtype="float32")
    baseline = 10
    series = trend(time, 0.1)  
    baseline = 10
    amplitude = 40
    slope = 0.05
    noise_level = 5
    
    # Create the series
    series = baseline + trend(time, slope) + seasonality(time, period=365, amplitude=amplitude)
    # Update with noise
    series += noise(time, noise_level, seed=42)
    
    split_time = 1000
    time_train = time[:split_time]
    x_train = series[:split_time]
    time_valid = time[split_time:]
    x_valid = series[split_time:]
    
    window_size = 20
    batch_size = 32
    shuffle_buffer_size = 1000
    
    • 辅助函数
    def windowed_dataset(series, window_size, batch_size, shuffle_buffer):
        series = tf.expand_dims(series, axis=-1)
        ds = tf.data.Dataset.from_tensor_slices(series)
        ds = ds.window(window_size + 1, shift=1, drop_remainder=True)
        ds = ds.flat_map(lambda w: w.batch(window_size + 1))
        ds = ds.shuffle(shuffle_buffer)
        ds = ds.map(lambda w: (w[:-1], w[1:]))
        return ds.batch(batch_size).prefetch(1)
    
    def model_forecast(model, series, window_size):
        ds = tf.data.Dataset.from_tensor_slices(series)
        ds = ds.window(window_size, shift=1, drop_remainder=True)
        ds = ds.flat_map(lambda w: w.batch(window_size))
        ds = ds.batch(32).prefetch(1)
        forecast = model.predict(ds)
        return forecast
    
    • 创建模型并训练
    tf.keras.backend.clear_session()
    tf.random.set_seed(51)
    np.random.seed(51)
    
    window_size = 30
    train_set = windowed_dataset(x_train, window_size, batch_size=128, shuffle_buffer=shuffle_buffer_size)
    
    model = tf.keras.models.Sequential([
        tf.keras.layers.Conv1D(filters=32, kernel_size=5,
                              strides=1, padding="causal", # padding='causal'表示因果卷积,output[t] 不依赖于 input[t+1:]
                              activation="relu",
                              input_shape=[None, 1]),
        tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(32, return_sequences=True)),
        tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(32, return_sequences=True)),
        tf.keras.layers.Dense(1),
        tf.keras.layers.Lambda(lambda x: x*200)
    ])
    
    
    lr_schedule = tf.keras.callbacks.LearningRateScheduler(
        lambda epoch: 1e-8 * 10**(epoch / 20))
    optimizer = tf.keras.optimizers.SGD(lr=1e-8, momentum=0.9)
    model.compile(loss=tf.keras.losses.Huber(),
                  optimizer=optimizer,
                  metrics=["mae"])
    history = model.fit(train_set, epochs=100, callbacks=[lr_schedule])
    
    • 选择合适的学习率
    plt.semilogx(history.history["lr"], history.history["loss"])
    plt.axis([1e-8, 1e-4, 0, 30])
    
    • 使用优化后的学习率重新训练
    tf.keras.backend.clear_session()
    tf.random.set_seed(51)
    np.random.seed(51)
    #batch_size = 16
    dataset = windowed_dataset(x_train, window_size, batch_size, shuffle_buffer_size)
    
    model = tf.keras.models.Sequential([
      tf.keras.layers.Conv1D(filters=32, kernel_size=3,
                          strides=1, padding="causal",
                          activation="relu",
                          input_shape=[None, 1]),
      tf.keras.layers.LSTM(32, return_sequences=True),
      tf.keras.layers.LSTM(32, return_sequences=True),
      tf.keras.layers.Dense(1),
      tf.keras.layers.Lambda(lambda x: x * 200)
    ])
    
    optimizer = tf.keras.optimizers.SGD(lr=1e-5, momentum=0.9)
    model.compile(loss=tf.keras.losses.Huber(),
                  optimizer=optimizer,
                  metrics=["mae"])
    history = model.fit(dataset,epochs=500)
    
    • 使用模型预测
    rnn_forecast = model_forecast(model, series[..., np.newaxis], window_size)
    rnn_forecast = rnn_forecast[split_time - window_size:-1, -1, 0]
    
    • 查看预测结果及指标
    plt.figure(figsize=(10, 6))
    plot_series(time_valid, x_valid)
    plot_series(time_valid, rnn_forecast)
    
    tf.keras.metrics.mean_absolute_error(x_valid, rnn_forecast).numpy()
    
    • 查看训练曲线
    import matplotlib.image  as mpimg
    import matplotlib.pyplot as plt
    
    #-----------------------------------------------------------
    # Retrieve a list of list results on training and test data
    # sets for each training epoch
    #-----------------------------------------------------------
    mae=history.history['mae']
    loss=history.history['loss']
    
    epochs=range(len(loss)) # Get number of epochs
    
    #------------------------------------------------
    # Plot MAE and Loss
    #------------------------------------------------
    plt.plot(epochs, mae, 'r')
    plt.plot(epochs, loss, 'b')
    plt.title('MAE and Loss')
    plt.xlabel("Epochs")
    plt.ylabel("Accuracy")
    plt.legend(["MAE", "Loss"])
    
    plt.figure()
    
    epochs_zoom = epochs[200:]
    mae_zoom = mae[200:]
    loss_zoom = loss[200:]
    
    #------------------------------------------------
    # Plot Zoomed MAE and Loss
    #------------------------------------------------
    plt.plot(epochs_zoom, mae_zoom, 'r')
    plt.plot(epochs_zoom, loss_zoom, 'b')
    plt.title('MAE and Loss')
    plt.xlabel("Epochs")
    plt.ylabel("Accuracy")
    plt.legend(["MAE", "Loss"])
    
    plt.figure()
    

    【参考文献】
    1.google colab

    相关文章

      网友评论

          本文标题:tf教程4: 因果卷积+LSTM预测时序数据

          本文链接:https://www.haomeiwen.com/subject/phnrjctx.html