<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 如何開發時間序列預測的卷積神經網絡模型 > 原文: [https://machinelearningmastery.com/how-to-develop-convolutional-neural-network-models-for-time-series-forecasting/](https://machinelearningmastery.com/how-to-develop-convolutional-neural-network-models-for-time-series-forecasting/) 卷積神經網絡模型(簡稱 CNN)可以應用于時間序列預測。 有許多類型的 CNN 模型可用于每種特定類型的時間序列預測問題。 在本教程中,您將了解如何針對一系列標準時間序列預測問題開發一套 CNN 模型。 本教程的目的是為每種類型的時間序列問題提供每個模型的獨立示例,作為模板,您可以根據特定的時間序列預測問題進行復制和調整。 完成本教程后,您將了解: * 如何開發 CNN 模型進行單變量時間序列預測。 * 如何開發 CNN 模型進行多元時間序列預測。 * 如何開發 CNN 模型進行多步時間序列預測。 這是一個龐大而重要的職位;您可能希望將其加入書簽以供將來參考。 讓我們開始吧。 ![How to Develop Convolutional Neural Network Models for Time Series Forecasting](https://img.kancloud.cn/14/11/1411d20418c4240d761b9082aeb0ac85_640x457.jpg) 如何開發用于時間序列預測的卷積神經網絡模型 照片由[土地管理局](https://www.flickr.com/photos/blmoregon/35464087364/),保留一些權利。 ## 教程概述 在本教程中,我們將探討如何為時間序列預測開發一套不同類型的 CNN 模型。 這些模型在小型設計的時間序列問題上進行了演示,旨在解決時間序列問題類型的風格。所選擇的模型配置是任意的,并未針對每個問題進行優化;那不是目標。 本教程分為四個部分;他們是: 1. 單變量 CNN 模型 2. 多變量 CNN 模型 3. 多步 CNN 模型 4. 多變量多步 CNN 模型 ## 單變量 CNN 模型 雖然傳統上為二維圖像數據開發,但 CNN 可用于模擬單變量時間序列預測問題。 單變量時間序列是由具有時間排序的單個觀察序列組成的數據集,并且需要模型來從過去的一系列觀察中學習以預測序列中的下一個值。 本節分為兩部分;他們是: 1. 數據準備 2. CNN 模型 ### 數據準備 在對單變量系列進行建模之前,必須準備好它。 CNN 模型將學習將過去觀察序列作為輸入映射到輸出觀察的函數。因此,必須將觀察序列轉換為模型可以從中學習的多個示例。 考慮給定的單變量序列: ```py [10, 20, 30, 40, 50, 60, 70, 80, 90] ``` 我們可以將序列劃分為多個稱為樣本的輸入/輸出模式,其中三個時間步長用作輸入,一個時間步長用作正在學習的一步預測的輸出。 ```py X, y 10, 20, 30 40 20, 30, 40 50 30, 40, 50 60 ... ``` 下面的 _split_sequence()_ 函數實現了這種行為,并將給定的單變量序列分成多個樣本,其中每個樣本具有指定的時間步長,輸出是單個時間步長。 ```py # split a univariate sequence into samples def split_sequence(sequence, n_steps): X, y = list(), list() for i in range(len(sequence)): # find the end of this pattern end_ix = i + n_steps # check if we are beyond the sequence if end_ix > len(sequence)-1: break # gather input and output parts of the pattern seq_x, seq_y = sequence[i:end_ix], sequence[end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) ``` 我們可以在上面的小型人為數據集上演示這個功能。 下面列出了完整的示例。 ```py # univariate data preparation from numpy import array # split a univariate sequence into samples def split_sequence(sequence, n_steps): X, y = list(), list() for i in range(len(sequence)): # find the end of this pattern end_ix = i + n_steps # check if we are beyond the sequence if end_ix > len(sequence)-1: break # gather input and output parts of the pattern seq_x, seq_y = sequence[i:end_ix], sequence[end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) # define input sequence raw_seq = [10, 20, 30, 40, 50, 60, 70, 80, 90] # choose a number of time steps n_steps = 3 # split into samples X, y = split_sequence(raw_seq, n_steps) # summarize the data for i in range(len(X)): print(X[i], y[i]) ``` 運行該示例將單變量系列分成六個樣本,其中每個樣本具有三個輸入時間步長和一個輸出時間步長。 ```py [10 20 30] 40 [20 30 40] 50 [30 40 50] 60 [40 50 60] 70 [50 60 70] 80 [60 70 80] 90 ``` 現在我們知道如何準備一個單變量系列進行建模,讓我們看看開發一個可以學習輸入到輸出映射的 CNN 模型。 ### CNN 模型 一維 CNN 是 CNN 模型,其具有在 1D 序列上操作的卷積隱藏層。接下來可能在某些情況下可能是第二個卷積層,例如非常長的輸入序列,然后是池化層,其作用是將卷積層的輸出提取到最顯著的元素。 卷積和匯集層之后是密集的完全連接層,其解釋由模型的卷積部分提取的特征。在卷積層和密集層之間使用展平層以將特征映射減少為單個一維向量。 我們可以如下定義用于單變量時間序列預測的 1D CNN 模型。 ```py # define model model = Sequential() model.add(Conv1D(filters=64, kernel_size=2, activation='relu', input_shape=(n_steps, n_features))) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(50, activation='relu')) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') ``` 定義的關鍵是輸入的形狀;這就是模型期望的每個樣本的輸入,包括時間步數和特征數。 我們正在使用單變量系列,因此對于一個變量,要素的數量是一個。 輸入的時間步數是我們在準備數據集時選擇的數字,作為 _split_sequence()_ 函數的參數。 每個樣本的輸入形狀在第一個隱藏層定義的 _input_shape_ 參數中指定。 我們幾乎總是有多個樣本,因此,模型將期望訓練數據的輸入組件具有尺寸或形狀: ```py [samples, timesteps, features] ``` 我們在前一節中的 _split_sequence()_ 函數輸出具有[_ 樣本,時間步長 _]形狀??的 X,因此我們可以輕松地對其進行整形,以便為一個特征提供額外的維度。 ```py # reshape from [samples, timesteps] into [samples, timesteps, features] n_features = 1 X = X.reshape((X.shape[0], X.shape[1], n_features)) ``` CNN 實際上并不將數據視為具有時間步長,而是將其視為可以執行卷積讀取操作的序列,如一維圖像。 在這個例子中,我們定義了一個帶有 64 個濾波器映射和 2 的內核大小的卷積層。然后是最大池層和密集層來解釋輸入特征。指定輸出層以預測單個數值。 使用隨機梯度下降的有效 [Adam 版本擬合該模型,并使用均方誤差或' _mse_ ',損失函數進行優化。](https://machinelearningmastery.com/adam-optimization-algorithm-for-deep-learning/) 定義模型后,我們可以將其放在訓練數據集上。 ```py # fit model model.fit(X, y, epochs=1000, verbose=0) ``` 在模型擬合后,我們可以使用它來進行預測。 我們可以通過提供輸入來預測序列中的下一個值: ```py [70, 80, 90] ``` 并期望模型預測如下: ```py [100] ``` 該模型期望輸入形狀為[_ 樣本,時間步長,特征 _]三維,因此,我們必須在進行預測之前對單個輸入樣本進行整形。 ```py # demonstrate prediction x_input = array([70, 80, 90]) x_input = x_input.reshape((1, n_steps, n_features)) yhat = model.predict(x_input, verbose=0) ``` 我們可以將所有這些結合在一起并演示如何開發單變量時間序列預測的 1D CNN 模型并進行單一預測。 ```py # univariate cnn example from numpy import array from keras.models import Sequential from keras.layers import Dense from keras.layers import Flatten from keras.layers.convolutional import Conv1D from keras.layers.convolutional import MaxPooling1D # split a univariate sequence into samples def split_sequence(sequence, n_steps): X, y = list(), list() for i in range(len(sequence)): # find the end of this pattern end_ix = i + n_steps # check if we are beyond the sequence if end_ix > len(sequence)-1: break # gather input and output parts of the pattern seq_x, seq_y = sequence[i:end_ix], sequence[end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) # define input sequence raw_seq = [10, 20, 30, 40, 50, 60, 70, 80, 90] # choose a number of time steps n_steps = 3 # split into samples X, y = split_sequence(raw_seq, n_steps) # reshape from [samples, timesteps] into [samples, timesteps, features] n_features = 1 X = X.reshape((X.shape[0], X.shape[1], n_features)) # define model model = Sequential() model.add(Conv1D(filters=64, kernel_size=2, activation='relu', input_shape=(n_steps, n_features))) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(50, activation='relu')) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') # fit model model.fit(X, y, epochs=1000, verbose=0) # demonstrate prediction x_input = array([70, 80, 90]) x_input = x_input.reshape((1, n_steps, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) ``` 運行該示例準備數據,擬合模型并進行預測。 鑒于算法的隨機性,您的結果可能會有所不同;嘗試運行幾次這個例子。 我們可以看到模型預測序列中的下一個值。 ```py [[101.67965]] ``` ## 多變量 CNN 模型 多變量時間序列數據是指每個時間步長有多個觀察值的數據。 對于多變量時間序列數據,我們可能需要兩種主要模型;他們是: 1. 多輸入系列。 2. 多個并聯系列。 讓我們依次看看每一個。 ### 多輸入系列 問題可能有兩個或更多并行輸入時間序列和輸出時間序列,這取決于輸入時間序列。 輸入時間序列是平行的,因為每個系列都在同一時間步驟中進行觀察。 我們可以通過兩個并行輸入時間序列的簡單示例來演示這一點,其中輸出序列是輸入序列的簡單添加。 ```py # define input sequence in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) ``` 我們可以將這三個數據數組重新整形為單個數據集,其中每一行都是一個時間步,每列是一個單獨的時間序列。 這是將并行時間序列存儲在 CSV 文件中的標準方法。 ```py # convert to [rows, columns] structure in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # horizontally stack columns dataset = hstack((in_seq1, in_seq2, out_seq)) ``` 下面列出了完整的示例。 ```py # multivariate data preparation from numpy import array from numpy import hstack # define input sequence in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # convert to [rows, columns] structure in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # horizontally stack columns dataset = hstack((in_seq1, in_seq2, out_seq)) print(dataset) ``` 運行該示例將打印數據集,每個時間步長為一行,兩個輸入和一個輸出并行時間序列分別為一列。 ```py [[ 10 15 25] [ 20 25 45] [ 30 35 65] [ 40 45 85] [ 50 55 105] [ 60 65 125] [ 70 75 145] [ 80 85 165] [ 90 95 185]] ``` 與單變量時間序列一樣,我們必須將這些數據組織成具有輸入和輸出樣本的樣本。 1D CNN 模型需要足夠的上下文來學習從輸入序列到輸出值的映射。 CNN 可以支持并行輸入時間序列作為單獨的通道,如圖像的紅色,綠色和藍色分量。因此,我們需要將數據分成樣本,保持兩個輸入序列的觀察順序。 如果我們選擇三個輸入時間步長,那么第一個樣本將如下所示: 輸入: ```py 10, 15 20, 25 30, 35 ``` 輸出: ```py 65 ``` 也就是說,每個并行系列的前三個時間步長被提供作為模型的輸入,并且模型將其與第三時間步驟(在這種情況下為 65)的輸出系列中的值相關聯。 我們可以看到,在將時間序列轉換為輸入/輸出樣本以訓練模型時,我們將不得不從輸出時間序列中丟棄一些值,其中我們在先前時間步驟中沒有輸入時間序列中的值。反過來,選擇輸入時間步數的大小將對使用多少訓練數據產生重要影響。 我們可以定義一個名為 _split_sequences()_ 的函數,該函數將采用數據集,因為我們已經為時間步長和行定義了并行序列和返回輸入/輸出樣本的列。 ```py # split a multivariate sequence into samples def split_sequences(sequences, n_steps): X, y = list(), list() for i in range(len(sequences)): # find the end of this pattern end_ix = i + n_steps # check if we are beyond the dataset if end_ix > len(sequences): break # gather input and output parts of the pattern seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1, -1] X.append(seq_x) y.append(seq_y) return array(X), array(y) ``` 我們可以使用每個輸入時間序列的三個時間步長作為輸入在我們的數據集上測試此函數。 下面列出了完整的示例。 ```py # multivariate data preparation from numpy import array from numpy import hstack # split a multivariate sequence into samples def split_sequences(sequences, n_steps): X, y = list(), list() for i in range(len(sequences)): # find the end of this pattern end_ix = i + n_steps # check if we are beyond the dataset if end_ix > len(sequences): break # gather input and output parts of the pattern seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1, -1] X.append(seq_x) y.append(seq_y) return array(X), array(y) # define input sequence in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # convert to [rows, columns] structure in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # horizontally stack columns dataset = hstack((in_seq1, in_seq2, out_seq)) # choose a number of time steps n_steps = 3 # convert into input/output X, y = split_sequences(dataset, n_steps) print(X.shape, y.shape) # summarize the data for i in range(len(X)): print(X[i], y[i]) ``` 首先運行該示例打印 _X_ 和 _y_ 組件的形狀。 我們可以看到 _X_ 組件具有三維結構。 第一個維度是樣本數,在本例中為 7.第二個維度是每個樣本的時間步數,在這種情況下為 3,即為函數指定的值。最后,最后一個維度指定并行時間序列的數量或變量的數量,在這種情況下,兩個并行序列為 2。 這是 1D CNN 作為輸入所期望的精確三維結構。數據即可使用而無需進一步重塑。 然后我們可以看到每個樣本的輸入和輸出都被打印出來,顯示了兩個輸入序列中每個樣本的三個時間步長以及每個樣本的相關輸出。 ```py (7, 3, 2) (7,) [[10 15] [20 25] [30 35]] 65 [[20 25] [30 35] [40 45]] 85 [[30 35] [40 45] [50 55]] 105 [[40 45] [50 55] [60 65]] 125 [[50 55] [60 65] [70 75]] 145 [[60 65] [70 75] [80 85]] 165 [[70 75] [80 85] [90 95]] 185 ``` 我們現在準備在這個數據上安裝一維 CNN 模型,指定每個輸入樣本的預期時間步長和特征數,在這種情況下分別為 3 和 2。 ```py # define model model = Sequential() model.add(Conv1D(filters=64, kernel_size=2, activation='relu', input_shape=(n_steps, n_features))) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(50, activation='relu')) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') ``` 在進行預測時,模型需要兩個輸入時間序列的三個時間步長。 我們可以預測輸出系列中的下一個值,提供以下輸入值: ```py 80, 85 90, 95 100, 105 ``` 具有三個時間步長和兩個變量的一個樣本的形狀必須是[1,3,2]。 我們希望序列中的下一個值為 100 + 105 或 205。 ```py # demonstrate prediction x_input = array([[80, 85], [90, 95], [100, 105]]) x_input = x_input.reshape((1, n_steps, n_features)) yhat = model.predict(x_input, verbose=0) ``` 下面列出了完整的示例。 ```py # multivariate cnn example from numpy import array from numpy import hstack from keras.models import Sequential from keras.layers import Dense from keras.layers import Flatten from keras.layers.convolutional import Conv1D from keras.layers.convolutional import MaxPooling1D # split a multivariate sequence into samples def split_sequences(sequences, n_steps): X, y = list(), list() for i in range(len(sequences)): # find the end of this pattern end_ix = i + n_steps # check if we are beyond the dataset if end_ix > len(sequences): break # gather input and output parts of the pattern seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1, -1] X.append(seq_x) y.append(seq_y) return array(X), array(y) # define input sequence in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # convert to [rows, columns] structure in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # horizontally stack columns dataset = hstack((in_seq1, in_seq2, out_seq)) # choose a number of time steps n_steps = 3 # convert into input/output X, y = split_sequences(dataset, n_steps) # the dataset knows the number of features, e.g. 2 n_features = X.shape[2] # define model model = Sequential() model.add(Conv1D(filters=64, kernel_size=2, activation='relu', input_shape=(n_steps, n_features))) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(50, activation='relu')) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') # fit model model.fit(X, y, epochs=1000, verbose=0) # demonstrate prediction x_input = array([[80, 85], [90, 95], [100, 105]]) x_input = x_input.reshape((1, n_steps, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) ``` 運行該示例準備數據,擬合模型并進行預測。 ```py [[206.0161]] ``` 還有另一種更精細的方法來模擬問題。 每個輸入序列可以由單獨的 CNN 處理,并且可以在對輸出序列進行預測之前組合這些子模型中的每一個的輸出。 我們可以將其稱為多頭 CNN 模型。根據正在建模的問題的具體情況,它可以提供更大的靈活性或更好的表現。例如,它允許您為每個輸入系列配置不同的子模型,例如過濾器映射的數量和內核大小。 可以使用 [Keras 功能 API](https://machinelearningmastery.com/keras-functional-api-deep-learning/) 在 Keras 中定義此類型的模型。 首先,我們可以將第一個輸入模型定義為 1D CNN,其輸入層需要具有 _n_steps_ 和 1 個特征的向量。 ```py # first input model visible1 = Input(shape=(n_steps, n_features)) cnn1 = Conv1D(filters=64, kernel_size=2, activation='relu')(visible1) cnn1 = MaxPooling1D(pool_size=2)(cnn1) cnn1 = Flatten()(cnn1) ``` 我們可以以相同的方式定義第二個輸入子模型。 ```py # second input model visible2 = Input(shape=(n_steps, n_features)) cnn2 = Conv1D(filters=64, kernel_size=2, activation='relu')(visible2) cnn2 = MaxPooling1D(pool_size=2)(cnn2) cnn2 = Flatten()(cnn2) ``` 現在已經定義了兩個輸入子模型,我們可以將每個模型的輸出合并為一個長向量,可以在對輸出序列進行預測之前對其進行解釋。 ```py # merge input models merge = concatenate([cnn1, cnn2]) dense = Dense(50, activation='relu')(merge) output = Dense(1)(dense) ``` 然后我們可以將輸入和輸出聯系在一起。 ```py model = Model(inputs=[visible1, visible2], outputs=output) ``` 下圖提供了該模型外觀的示意圖,包括每層輸入和輸出的形狀。 ![Plot of Multi-Headed 1D CNN for Multivariate Time Series Forecasting](https://img.kancloud.cn/fd/cc/fdccb2d937f3525f27d379f972af6a93_992x737.jpg) 多頭 1D CNN 在多元時間序列預測中的應用 此模型要求輸入作為兩個元素的列表提供,其中列表中的每個元素包含一個子模型的數據。 為了實現這一點,我們可以將 3D 輸入數據分成兩個獨立的輸入數據陣列;這是從一個形狀為[7,3,2]的數組到兩個 3D 數組[7,3,1] ```py # one time series per head n_features = 1 # separate input data X1 = X[:, :, 0].reshape(X.shape[0], X.shape[1], n_features) X2 = X[:, :, 1].reshape(X.shape[0], X.shape[1], n_features) ``` 然后可以提供這些數據以適合模型。 ```py # fit model model.fit([X1, X2], y, epochs=1000, verbose=0) ``` 類似地,我們必須在進行單個一步預測時將單個樣本的數據準備為兩個單獨的二維數組。 ```py x_input = array([[80, 85], [90, 95], [100, 105]]) x1 = x_input[:, 0].reshape((1, n_steps, n_features)) x2 = x_input[:, 1].reshape((1, n_steps, n_features)) ``` 我們可以將所有這些結合在一起;下面列出了完整的示例。 ```py # multivariate multi-headed 1d cnn example from numpy import array from numpy import hstack from keras.models import Model from keras.layers import Input from keras.layers import Dense from keras.layers import Flatten from keras.layers.convolutional import Conv1D from keras.layers.convolutional import MaxPooling1D from keras.layers.merge import concatenate # split a multivariate sequence into samples def split_sequences(sequences, n_steps): X, y = list(), list() for i in range(len(sequences)): # find the end of this pattern end_ix = i + n_steps # check if we are beyond the dataset if end_ix > len(sequences): break # gather input and output parts of the pattern seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1, -1] X.append(seq_x) y.append(seq_y) return array(X), array(y) # define input sequence in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # convert to [rows, columns] structure in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # horizontally stack columns dataset = hstack((in_seq1, in_seq2, out_seq)) # choose a number of time steps n_steps = 3 # convert into input/output X, y = split_sequences(dataset, n_steps) # one time series per head n_features = 1 # separate input data X1 = X[:, :, 0].reshape(X.shape[0], X.shape[1], n_features) X2 = X[:, :, 1].reshape(X.shape[0], X.shape[1], n_features) # first input model visible1 = Input(shape=(n_steps, n_features)) cnn1 = Conv1D(filters=64, kernel_size=2, activation='relu')(visible1) cnn1 = MaxPooling1D(pool_size=2)(cnn1) cnn1 = Flatten()(cnn1) # second input model visible2 = Input(shape=(n_steps, n_features)) cnn2 = Conv1D(filters=64, kernel_size=2, activation='relu')(visible2) cnn2 = MaxPooling1D(pool_size=2)(cnn2) cnn2 = Flatten()(cnn2) # merge input models merge = concatenate([cnn1, cnn2]) dense = Dense(50, activation='relu')(merge) output = Dense(1)(dense) model = Model(inputs=[visible1, visible2], outputs=output) model.compile(optimizer='adam', loss='mse') # fit model model.fit([X1, X2], y, epochs=1000, verbose=0) # demonstrate prediction x_input = array([[80, 85], [90, 95], [100, 105]]) x1 = x_input[:, 0].reshape((1, n_steps, n_features)) x2 = x_input[:, 1].reshape((1, n_steps, n_features)) yhat = model.predict([x1, x2], verbose=0) print(yhat) ``` 運行該示例準備數據,擬合模型并進行預測。 ```py [[205.871]] ``` ### 多個并聯系列 另一個時間序列問題是存在多個并行時間序列并且必須為每個時間序列預測值的情況。 例如,給定上一節的數據: ```py [[ 10 15 25] [ 20 25 45] [ 30 35 65] [ 40 45 85] [ 50 55 105] [ 60 65 125] [ 70 75 145] [ 80 85 165] [ 90 95 185]] ``` 我們可能想要預測下一個時間步的三個時間序列中的每一個的值。 這可以稱為多變量預測。 同樣,必須將數據分成輸入/輸出樣本以訓練模型。 該數據集的第一個示例是: 輸入: ```py 10, 15, 25 20, 25, 45 30, 35, 65 ``` 輸出: ```py 40, 45, 85 ``` 下面的 _split_sequences()_ 函數將分割多個并行時間序列,其中時間步長為行,每列一個系列為所需的輸入/輸出形狀。 ```py # split a multivariate sequence into samples def split_sequences(sequences, n_steps): X, y = list(), list() for i in range(len(sequences)): # find the end of this pattern end_ix = i + n_steps # check if we are beyond the dataset if end_ix > len(sequences)-1: break # gather input and output parts of the pattern seq_x, seq_y = sequences[i:end_ix, :], sequences[end_ix, :] X.append(seq_x) y.append(seq_y) return array(X), array(y) ``` 我們可以在人為的問題上證明這一點;下面列出了完整的示例。 ```py # multivariate output data prep from numpy import array from numpy import hstack # split a multivariate sequence into samples def split_sequences(sequences, n_steps): X, y = list(), list() for i in range(len(sequences)): # find the end of this pattern end_ix = i + n_steps # check if we are beyond the dataset if end_ix > len(sequences)-1: break # gather input and output parts of the pattern seq_x, seq_y = sequences[i:end_ix, :], sequences[end_ix, :] X.append(seq_x) y.append(seq_y) return array(X), array(y) # define input sequence in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # convert to [rows, columns] structure in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # horizontally stack columns dataset = hstack((in_seq1, in_seq2, out_seq)) # choose a number of time steps n_steps = 3 # convert into input/output X, y = split_sequences(dataset, n_steps) print(X.shape, y.shape) # summarize the data for i in range(len(X)): print(X[i], y[i]) ``` 首先運行該示例打印準備好的 X 和 y 組件的形狀。 X 的形狀是三維的,包括樣品的數量(6),每個樣品選擇的時間步數(3),以及平行時間序列或特征的數量(3)。 y 的形狀是二維的,正如我們可能期望的樣本數量(6)和每個樣本的時間變量數量(3)。 該數據已準備好在 1D CNN 模型中使用,該模型期望每個樣本的 X 和 y 分量具有三維輸入和二維輸出形狀。 然后,打印每個樣本,顯示每個樣本的輸入和輸出分量。 ```py (6, 3, 3) (6, 3) [[10 15 25] [20 25 45] [30 35 65]] [40 45 85] [[20 25 45] [30 35 65] [40 45 85]] [ 50 55 105] [[ 30 35 65] [ 40 45 85] [ 50 55 105]] [ 60 65 125] [[ 40 45 85] [ 50 55 105] [ 60 65 125]] [ 70 75 145] [[ 50 55 105] [ 60 65 125] [ 70 75 145]] [ 80 85 165] [[ 60 65 125] [ 70 75 145] [ 80 85 165]] [ 90 95 185] ``` 我們現在準備在這些數據上安裝一維 CNN 模型。 在此模型中,通過 _input_shape_ 參數為輸入層指定時間步數和并行系列(特征)。 并行序列的數量也用于指定輸出層中模型預測的值的數量;再次,這是三個。 ```py # define model model = Sequential() model.add(Conv1D(filters=64, kernel_size=2, activation='relu', input_shape=(n_steps, n_features))) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(50, activation='relu')) model.add(Dense(n_features)) model.compile(optimizer='adam', loss='mse') ``` 我們可以通過為每個系列提供三個時間步長的輸入來預測三個并行系列中的每一個的下一個值。 ```py 70, 75, 145 80, 85, 165 90, 95, 185 ``` 用于進行單個預測的輸入的形狀必須是 1 個樣本,3 個時間步長和 3 個特征,或者[1,3,3]。 ```py # demonstrate prediction x_input = array([[70,75,145], [80,85,165], [90,95,185]]) x_input = x_input.reshape((1, n_steps, n_features)) yhat = model.predict(x_input, verbose=0) ``` 我們希望向量輸出為: ```py [100, 105, 205] ``` 我們可以將所有這些結合在一起并演示下面的多變量輸出時間序列預測的 1D CNN。 ```py # multivariate output 1d cnn example from numpy import array from numpy import hstack from keras.models import Sequential from keras.layers import Dense from keras.layers import Flatten from keras.layers.convolutional import Conv1D from keras.layers.convolutional import MaxPooling1D # split a multivariate sequence into samples def split_sequences(sequences, n_steps): X, y = list(), list() for i in range(len(sequences)): # find the end of this pattern end_ix = i + n_steps # check if we are beyond the dataset if end_ix > len(sequences)-1: break # gather input and output parts of the pattern seq_x, seq_y = sequences[i:end_ix, :], sequences[end_ix, :] X.append(seq_x) y.append(seq_y) return array(X), array(y) # define input sequence in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # convert to [rows, columns] structure in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # horizontally stack columns dataset = hstack((in_seq1, in_seq2, out_seq)) # choose a number of time steps n_steps = 3 # convert into input/output X, y = split_sequences(dataset, n_steps) # the dataset knows the number of features, e.g. 2 n_features = X.shape[2] # define model model = Sequential() model.add(Conv1D(filters=64, kernel_size=2, activation='relu', input_shape=(n_steps, n_features))) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(50, activation='relu')) model.add(Dense(n_features)) model.compile(optimizer='adam', loss='mse') # fit model model.fit(X, y, epochs=3000, verbose=0) # demonstrate prediction x_input = array([[70,75,145], [80,85,165], [90,95,185]]) x_input = x_input.reshape((1, n_steps, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) ``` 運行該示例準備數據,擬合模型并進行預測。 ```py [[100.11272 105.32213 205.53436]] ``` 與多輸入系列一樣,還有另一種更精細的方法來模擬問題。 每個輸出系列可以由單獨的輸出 CNN 模型處理。 我們可以將其稱為多輸出 CNN 模型。根據正在建模的問題的具體情況,它可以提供更大的靈活性或更好的表現。 可以使用 [Keras 功能 API](https://machinelearningmastery.com/keras-functional-api-deep-learning/) 在 Keras 中定義此類型的模型。 首先,我們可以將第一個輸入模型定義為 1D CNN 模型。 ```py # define model visible = Input(shape=(n_steps, n_features)) cnn = Conv1D(filters=64, kernel_size=2, activation='relu')(visible) cnn = MaxPooling1D(pool_size=2)(cnn) cnn = Flatten()(cnn) cnn = Dense(50, activation='relu')(cnn) ``` 然后,我們可以為我們希望預測的三個系列中的每一個定義一個輸出層,其中每個輸出子模型將預測單個時間步長。 ```py # define output 1 output1 = Dense(1)(cnn) # define output 2 output2 = Dense(1)(cnn) # define output 3 output3 = Dense(1)(cnn) ``` 然后,我們可以將輸入和輸出層組合到一個模型中。 ```py # tie together model = Model(inputs=visible, outputs=[output1, output2, output3]) model.compile(optimizer='adam', loss='mse') ``` 為了使模型架構清晰,下面的示意圖清楚地顯示了模型的三個獨立輸出層以及每個層的輸入和輸出形狀。 ![Plot of Multi-Output 1D CNN for Multivariate Time Series Forecasting](https://img.kancloud.cn/8c/b0/8cb084237f8cd09274d6ff9306f1f60a_1011x627.jpg) 多輸出 1D CNN 用于多元時間序列預測的圖 在訓練模型時,每個樣本需要三個獨立的輸出陣列。我們可以通過將具有形狀[7,3]的輸出訓練數據轉換為具有形狀[7,1]的三個陣列來實現這一點。 ```py # separate output y1 = y[:, 0].reshape((y.shape[0], 1)) y2 = y[:, 1].reshape((y.shape[0], 1)) y3 = y[:, 2].reshape((y.shape[0], 1)) ``` 可以在訓練期間將這些陣列提供給模型。 ```py # fit model model.fit(X, [y1,y2,y3], epochs=2000, verbose=0) ``` 將所有這些結合在一起,下面列出了完整的示例。 ```py # multivariate output 1d cnn example from numpy import array from numpy import hstack from keras.models import Model from keras.layers import Input from keras.layers import Dense from keras.layers import Flatten from keras.layers.convolutional import Conv1D from keras.layers.convolutional import MaxPooling1D # split a multivariate sequence into samples def split_sequences(sequences, n_steps): X, y = list(), list() for i in range(len(sequences)): # find the end of this pattern end_ix = i + n_steps # check if we are beyond the dataset if end_ix > len(sequences)-1: break # gather input and output parts of the pattern seq_x, seq_y = sequences[i:end_ix, :], sequences[end_ix, :] X.append(seq_x) y.append(seq_y) return array(X), array(y) # define input sequence in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # convert to [rows, columns] structure in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # horizontally stack columns dataset = hstack((in_seq1, in_seq2, out_seq)) # choose a number of time steps n_steps = 3 # convert into input/output X, y = split_sequences(dataset, n_steps) # the dataset knows the number of features, e.g. 2 n_features = X.shape[2] # separate output y1 = y[:, 0].reshape((y.shape[0], 1)) y2 = y[:, 1].reshape((y.shape[0], 1)) y3 = y[:, 2].reshape((y.shape[0], 1)) # define model visible = Input(shape=(n_steps, n_features)) cnn = Conv1D(filters=64, kernel_size=2, activation='relu')(visible) cnn = MaxPooling1D(pool_size=2)(cnn) cnn = Flatten()(cnn) cnn = Dense(50, activation='relu')(cnn) # define output 1 output1 = Dense(1)(cnn) # define output 2 output2 = Dense(1)(cnn) # define output 3 output3 = Dense(1)(cnn) # tie together model = Model(inputs=visible, outputs=[output1, output2, output3]) model.compile(optimizer='adam', loss='mse') # fit model model.fit(X, [y1,y2,y3], epochs=2000, verbose=0) # demonstrate prediction x_input = array([[70,75,145], [80,85,165], [90,95,185]]) x_input = x_input.reshape((1, n_steps, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) ``` 運行該示例準備數據,擬合模型并進行預測。 ```py [array([[100.96118]], dtype=float32), array([[105.502686]], dtype=float32), array([[205.98045]], dtype=float32)] ``` ## 多步 CNN 模型 在實踐中,1D CNN 模型在預測表示不同輸出變量的向量輸出(如在前面的示例中)或者表示一個變量的多個時間步長的向量輸出方面幾乎沒有差別。 然而,訓練數據的編制方式存在細微而重要的差異。在本節中,我們將演示使用向量模型開發多步預測模型的情況。 在我們查看模型的細節之前,讓我們首先看一下多步預測的數據準備。 ### 數據準備 與一步預測一樣,用于多步時間序列預測的時間序列必須分為帶有輸入和輸出組件的樣本。 輸入和輸出組件都將包含多個時間步長,并且可以具有或不具有相同數量的步驟。 例如,給定單變量時間序列: ```py [10, 20, 30, 40, 50, 60, 70, 80, 90] ``` 我們可以使用最后三個時間步作為輸入并預測接下來的兩個時間步。 第一個樣本如下: 輸入: ```py [10, 20, 30] ``` 輸出: ```py [40, 50] ``` 下面的 _split_sequence()_ 函數實現了這種行為,并將給定的單變量時間序列分割為具有指定數量的輸入和輸出時間步長的樣本。 ```py # split a univariate sequence into samples def split_sequence(sequence, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequence)): # find the end of this pattern end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out # check if we are beyond the sequence if out_end_ix > len(sequence): break # gather input and output parts of the pattern seq_x, seq_y = sequence[i:end_ix], sequence[end_ix:out_end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) ``` 我們可以在小型設計數據集上演示此功能。 下面列出了完整的示例。 ```py # multi-step data preparation from numpy import array # split a univariate sequence into samples def split_sequence(sequence, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequence)): # find the end of this pattern end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out # check if we are beyond the sequence if out_end_ix > len(sequence): break # gather input and output parts of the pattern seq_x, seq_y = sequence[i:end_ix], sequence[end_ix:out_end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) # define input sequence raw_seq = [10, 20, 30, 40, 50, 60, 70, 80, 90] # choose a number of time steps n_steps_in, n_steps_out = 3, 2 # split into samples X, y = split_sequence(raw_seq, n_steps_in, n_steps_out) # summarize the data for i in range(len(X)): print(X[i], y[i]) ``` 運行該示例將單變量系列拆分為輸入和輸出時間步驟,并打印每個系列的輸入和輸出組件。 ```py [10 20 30] [40 50] [20 30 40] [50 60] [30 40 50] [60 70] [40 50 60] [70 80] [50 60 70] [80 90] ``` 既然我們知道如何為多步預測準備數據,那么讓我們看一下可以學習這種映射的一維 CNN 模型。 ### 向量輸出模型 1D CNN 可以直接輸出向量,可以解釋為多步預測。 在前一節中看到這種方法是每個輸出時間序列的一個時間步驟被預測為向量。 與前一節中單變量數據的 1D CNN 模型一樣,必須首先對準備好的樣本進行重新整形。 CNN 希望數據具有[_ 樣本,時間步長,特征 _]的三維結構,在這種情況下,我們只有一個特征,因此重塑是直截了當的。 ```py # reshape from [samples, timesteps] into [samples, timesteps, features] n_features = 1 X = X.reshape((X.shape[0], X.shape[1], n_features)) ``` 通過 _n_steps_in_ 和 _n_steps_out_ 變量中指定的輸入和輸出步數,我們可以定義一個多步驟時間序列預測模型。 ```py # define model model = Sequential() model.add(Conv1D(filters=64, kernel_size=2, activation='relu', input_shape=(n_steps_in, n_features))) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(50, activation='relu')) model.add(Dense(n_steps_out)) model.compile(optimizer='adam', loss='mse') ``` 該模型可以對單個樣本進行預測。我們可以通過提供輸入來預測數據集末尾之后的下兩個步驟: ```py [70, 80, 90] ``` 我們希望預測的輸出為: ```py [100, 110] ``` 正如模型所預期的那樣,進行預測時輸入數據的單個樣本的形狀對于 1 個樣本,輸入的 3 個時間步長和單個特征必須是[1,3,1]。 ```py # demonstrate prediction x_input = array([70, 80, 90]) x_input = x_input.reshape((1, n_steps_in, n_features)) yhat = model.predict(x_input, verbose=0) ``` 將所有這些結合在一起,下面列出了具有單變量時間序列的 1D CNN 用于多步預測。 ```py # univariate multi-step vector-output 1d cnn example from numpy import array from keras.models import Sequential from keras.layers import Dense from keras.layers import Flatten from keras.layers.convolutional import Conv1D from keras.layers.convolutional import MaxPooling1D # split a univariate sequence into samples def split_sequence(sequence, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequence)): # find the end of this pattern end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out # check if we are beyond the sequence if out_end_ix > len(sequence): break # gather input and output parts of the pattern seq_x, seq_y = sequence[i:end_ix], sequence[end_ix:out_end_ix] X.append(seq_x) y.append(seq_y) return array(X), array(y) # define input sequence raw_seq = [10, 20, 30, 40, 50, 60, 70, 80, 90] # choose a number of time steps n_steps_in, n_steps_out = 3, 2 # split into samples X, y = split_sequence(raw_seq, n_steps_in, n_steps_out) # reshape from [samples, timesteps] into [samples, timesteps, features] n_features = 1 X = X.reshape((X.shape[0], X.shape[1], n_features)) # define model model = Sequential() model.add(Conv1D(filters=64, kernel_size=2, activation='relu', input_shape=(n_steps_in, n_features))) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(50, activation='relu')) model.add(Dense(n_steps_out)) model.compile(optimizer='adam', loss='mse') # fit model model.fit(X, y, epochs=2000, verbose=0) # demonstrate prediction x_input = array([70, 80, 90]) x_input = x_input.reshape((1, n_steps_in, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) ``` 運行示例預測并打印序列中的后兩個時間步驟。 ```py [[102.86651 115.08979]] ``` ## 多變量多步 CNN 模型 在前面的部分中,我們研究了單變量,多變量和多步驟時間序列預測。 對于不同的問題,可以混合和匹配到目前為止呈現的不同類型的 1D CNN 模型。這也適用于涉及多變量和多步預測的時間序列預測問題,但可能更具挑戰性。 在本節中,我們將探討多變量多步驟時間序列預測的數據準備和建模的簡短示例,作為模板來緩解這一挑戰,具體來說: 1. 多輸入多步輸出。 2. 多個并行輸入和多步輸出。 也許最大的絆腳石是準備數據,所以這是我們關注的重點。 ### 多輸入多步輸出 存在多變量時間序列預測問題,其中輸出序列是分開的但取決于輸入時間序列,并且輸出序列需要多個時間步長。 例如,考慮前一部分的多變量時間序列: ```py [[ 10 15 25] [ 20 25 45] [ 30 35 65] [ 40 45 85] [ 50 55 105] [ 60 65 125] [ 70 75 145] [ 80 85 165] [ 90 95 185]] ``` 我們可以使用兩個輸入時間序列中的每一個的三個先前時間步驟來預測輸出時間序列的兩個時間步長。 輸入: ```py 10, 15 20, 25 30, 35 ``` 輸出: ```py 65 85 ``` 下面的 _split_sequences()_ 函數實現了這種行為。 ```py # split a multivariate sequence into samples def split_sequences(sequences, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequences)): # find the end of this pattern end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out-1 # check if we are beyond the dataset if out_end_ix > len(sequences): break # gather input and output parts of the pattern seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1:out_end_ix, -1] X.append(seq_x) y.append(seq_y) return array(X), array(y) ``` 我們可以在我們設計的數據集上證明這一點。下面列出了完整的示例。 ```py # multivariate multi-step data preparation from numpy import array from numpy import hstack # split a multivariate sequence into samples def split_sequences(sequences, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequences)): # find the end of this pattern end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out-1 # check if we are beyond the dataset if out_end_ix > len(sequences): break # gather input and output parts of the pattern seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1:out_end_ix, -1] X.append(seq_x) y.append(seq_y) return array(X), array(y) # define input sequence in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # convert to [rows, columns] structure in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # horizontally stack columns dataset = hstack((in_seq1, in_seq2, out_seq)) # choose a number of time steps n_steps_in, n_steps_out = 3, 2 # convert into input/output X, y = split_sequences(dataset, n_steps_in, n_steps_out) print(X.shape, y.shape) # summarize the data for i in range(len(X)): print(X[i], y[i]) ``` 首先運行該示例打印準備好的訓練數據的形狀。 我們可以看到樣本的輸入部分的形狀是三維的,由六個樣本組成,具有三個時間步長和兩個輸入時間序列的兩個變量。 樣本的輸出部分對于六個樣本是二維的,并且每個樣本的兩個時間步長是預測的。 然后打印制備的樣品以確認數據是按照我們指定的方式制備的。 ```py (6, 3, 2) (6, 2) [[10 15] [20 25] [30 35]] [65 85] [[20 25] [30 35] [40 45]] [ 85 105] [[30 35] [40 45] [50 55]] [105 125] [[40 45] [50 55] [60 65]] [125 145] [[50 55] [60 65] [70 75]] [145 165] [[60 65] [70 75] [80 85]] [165 185] ``` 我們現在可以開發用于多步預測的 1D CNN 模型。 在這種情況下,我們將演示向量輸出模型。下面列出了完整的示例。 ```py # multivariate multi-step 1d cnn example from numpy import array from numpy import hstack from keras.models import Sequential from keras.layers import Dense from keras.layers import Flatten from keras.layers.convolutional import Conv1D from keras.layers.convolutional import MaxPooling1D # split a multivariate sequence into samples def split_sequences(sequences, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequences)): # find the end of this pattern end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out-1 # check if we are beyond the dataset if out_end_ix > len(sequences): break # gather input and output parts of the pattern seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1:out_end_ix, -1] X.append(seq_x) y.append(seq_y) return array(X), array(y) # define input sequence in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # convert to [rows, columns] structure in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # horizontally stack columns dataset = hstack((in_seq1, in_seq2, out_seq)) # choose a number of time steps n_steps_in, n_steps_out = 3, 2 # convert into input/output X, y = split_sequences(dataset, n_steps_in, n_steps_out) # the dataset knows the number of features, e.g. 2 n_features = X.shape[2] # define model model = Sequential() model.add(Conv1D(filters=64, kernel_size=2, activation='relu', input_shape=(n_steps_in, n_features))) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(50, activation='relu')) model.add(Dense(n_steps_out)) model.compile(optimizer='adam', loss='mse') # fit model model.fit(X, y, epochs=2000, verbose=0) # demonstrate prediction x_input = array([[70, 75], [80, 85], [90, 95]]) x_input = x_input.reshape((1, n_steps_in, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) ``` 運行該示例適合模型并預測輸出序列的下兩個時間步驟超出數據集。 我們希望接下來的兩個步驟是[185,205]。 這是一個具有挑戰性的問題框架,數據非常少,模型的任意配置版本也很接近。 ```py [[185.57011 207.77893]] ``` ### 多個并行輸入和多步輸出 并行時間序列的問題可能需要預測每個時間序列的多個時間步長。 例如,考慮前一部分的多變量時間序列: ```py [[ 10 15 25] [ 20 25 45] [ 30 35 65] [ 40 45 85] [ 50 55 105] [ 60 65 125] [ 70 75 145] [ 80 85 165] [ 90 95 185]] ``` 我們可以使用三個時間序列中的每一個的最后三個步驟作為模型的輸入,并預測三個時間序列中的每一個的下一個時間步長作為輸出。 訓練數據集中的第一個樣本如下。 輸入: ```py 10, 15, 25 20, 25, 45 30, 35, 65 ``` 輸出: ```py 40, 45, 85 50, 55, 105 ``` 下面的 _split_sequences()_ 函數實現了這種行為。 ```py # split a multivariate sequence into samples def split_sequences(sequences, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequences)): # find the end of this pattern end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out # check if we are beyond the dataset if out_end_ix > len(sequences): break # gather input and output parts of the pattern seq_x, seq_y = sequences[i:end_ix, :], sequences[end_ix:out_end_ix, :] X.append(seq_x) y.append(seq_y) return array(X), array(y) ``` 我們可以在小型設計數據集上演示此功能。 下面列出了完整的示例。 ```py # multivariate multi-step data preparation from numpy import array from numpy import hstack from keras.models import Sequential from keras.layers import LSTM from keras.layers import Dense from keras.layers import RepeatVector from keras.layers import TimeDistributed # split a multivariate sequence into samples def split_sequences(sequences, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequences)): # find the end of this pattern end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out # check if we are beyond the dataset if out_end_ix > len(sequences): break # gather input and output parts of the pattern seq_x, seq_y = sequences[i:end_ix, :], sequences[end_ix:out_end_ix, :] X.append(seq_x) y.append(seq_y) return array(X), array(y) # define input sequence in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # convert to [rows, columns] structure in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # horizontally stack columns dataset = hstack((in_seq1, in_seq2, out_seq)) # choose a number of time steps n_steps_in, n_steps_out = 3, 2 # convert into input/output X, y = split_sequences(dataset, n_steps_in, n_steps_out) print(X.shape, y.shape) # summarize the data for i in range(len(X)): print(X[i], y[i]) ``` 首先運行該示例打印準備好的訓練數據集的形狀。 我們可以看到數據集的輸入( _X_ )和輸出( _Y_ )元素分別對于樣本數,時間步長和變量或并行時間序列是三維的。 。 然后將每個系列的輸入和輸出元素并排打印,以便我們可以確認數據是按照我們的預期準備的。 ```py (5, 3, 3) (5, 2, 3) [[10 15 25] [20 25 45] [30 35 65]] [[ 40 45 85] [ 50 55 105]] [[20 25 45] [30 35 65] [40 45 85]] [[ 50 55 105] [ 60 65 125]] [[ 30 35 65] [ 40 45 85] [ 50 55 105]] [[ 60 65 125] [ 70 75 145]] [[ 40 45 85] [ 50 55 105] [ 60 65 125]] [[ 70 75 145] [ 80 85 165]] [[ 50 55 105] [ 60 65 125] [ 70 75 145]] [[ 80 85 165] [ 90 95 185]] ``` 我們現在可以為此數據集開發一維 CNN 模型。 在這種情況下,我們將使用向量輸出模型。因此,我們必須展平每個樣本的輸出部分的三維結構,以便訓練模型。這意味著,不是為每個系列預測兩個步驟,而是對模型進行訓練并預期直接預測六個數字的向量。 ```py # flatten output n_output = y.shape[1] * y.shape[2] y = y.reshape((y.shape[0], n_output)) ``` 下面列出了完整的示例。 ```py # multivariate output multi-step 1d cnn example from numpy import array from numpy import hstack from keras.models import Sequential from keras.layers import Dense from keras.layers import Flatten from keras.layers.convolutional import Conv1D from keras.layers.convolutional import MaxPooling1D # split a multivariate sequence into samples def split_sequences(sequences, n_steps_in, n_steps_out): X, y = list(), list() for i in range(len(sequences)): # find the end of this pattern end_ix = i + n_steps_in out_end_ix = end_ix + n_steps_out # check if we are beyond the dataset if out_end_ix > len(sequences): break # gather input and output parts of the pattern seq_x, seq_y = sequences[i:end_ix, :], sequences[end_ix:out_end_ix, :] X.append(seq_x) y.append(seq_y) return array(X), array(y) # define input sequence in_seq1 = array([10, 20, 30, 40, 50, 60, 70, 80, 90]) in_seq2 = array([15, 25, 35, 45, 55, 65, 75, 85, 95]) out_seq = array([in_seq1[i]+in_seq2[i] for i in range(len(in_seq1))]) # convert to [rows, columns] structure in_seq1 = in_seq1.reshape((len(in_seq1), 1)) in_seq2 = in_seq2.reshape((len(in_seq2), 1)) out_seq = out_seq.reshape((len(out_seq), 1)) # horizontally stack columns dataset = hstack((in_seq1, in_seq2, out_seq)) # choose a number of time steps n_steps_in, n_steps_out = 3, 2 # convert into input/output X, y = split_sequences(dataset, n_steps_in, n_steps_out) # flatten output n_output = y.shape[1] * y.shape[2] y = y.reshape((y.shape[0], n_output)) # the dataset knows the number of features, e.g. 2 n_features = X.shape[2] # define model model = Sequential() model.add(Conv1D(filters=64, kernel_size=2, activation='relu', input_shape=(n_steps_in, n_features))) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(50, activation='relu')) model.add(Dense(n_output)) model.compile(optimizer='adam', loss='mse') # fit model model.fit(X, y, epochs=7000, verbose=0) # demonstrate prediction x_input = array([[60, 65, 125], [70, 75, 145], [80, 85, 165]]) x_input = x_input.reshape((1, n_steps_in, n_features)) yhat = model.predict(x_input, verbose=0) print(yhat) ``` 運行該示例適合模型并預測超出數據集末尾的下兩個時間步的三個時間步中的每一個的值。 我們希望這些系列和時間步驟的值如下: ```py 90, 95, 185 100, 105, 205 ``` 我們可以看到模型預測合理地接近預期值。 ```py [[ 90.47855 95.621284 186.02629 100.48118 105.80815 206.52821 ]] ``` ## 摘要 在本教程中,您了解了如何針對一系列標準時間序列預測問題開發一套 CNN 模型。 具體來說,你學到了: * 如何開發 CNN 模型進行單變量時間序列預測。 * 如何開發 CNN 模型進行多元時間序列預測。 * 如何開發 CNN 模型進行多步時間序列預測。 你有任何問題嗎? 在下面的評論中提出您的問題,我會盡力回答。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看