<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 如何網格搜索深度學習模型進行時間序列預測 > 原文: [https://machinelearningmastery.com/how-to-grid-search-deep-learning-models-for-time-series-forecasting/](https://machinelearningmastery.com/how-to-grid-search-deep-learning-models-for-time-series-forecasting/) 網格搜索通常不是我們可以使用深度學習方法執行的操作。 這是因為深度學習方法通??常需要大量數據和大型模型,因此需要花費數小時,數天或數周才能訓練的模型。 在數據集較小的情況下,例如單變量時間序列,可以使用網格搜索來調整深度學習模型的超參數。 在本教程中,您將了解如何為深度學習模型開發網格搜索超參數框架。 完成本教程后,您將了解: * 如何開發用于調整模型超參數的通用網格搜索框架。 * 如何在航空公司乘客單變量時間序列預測問題上對多層感知器模型進行網格搜索超參數。 * 如何使框架適應卷積和長期短期記憶神經網絡的網格搜索超參數。 讓我們開始吧。 ![How to Grid Search Deep Learning Models for Time Series Forecasting](https://img.kancloud.cn/65/b3/65b3c77963fb96d9cc5fa79ec67325dc_640x360.jpg) 如何網格搜索時間序列預測的深度學習模型 照片由 [Hannes Flo](https://www.flickr.com/photos/hannesflo/40192605640/) ,保留一些權利。 ## 教程概述 本教程分為五個部分;他們是: 1. 時間序列問題 2. 網格搜索框架 3. 網格搜索多層感知器 4. 網格搜索卷積神經網絡 5. 網格搜索長短期記憶網絡 ## 時間序列問題 '_ 月度航空公司乘客 _'數據集總結了 1949 年至 1960 年期間航空公司每月數千人的國際旅客總數。 直接從這里下載數據集: * [monthly-airline-passengers.csv](https://raw.githubusercontent.com/jbrownlee/Datasets/master/airline-passengers.csv) 在當前工作目錄中使用文件名“ _monthly-airline-passengers.csv_ ”保存文件。 我們可以使用函數 _read_csv()_ 將此數據集作為 Pandas 系列加載。 ```py # load series = read_csv('monthly-airline-passengers.csv', header=0, index_col=0) ``` 加載后,我們可以總結數據集的形狀,以確定觀察的數量。 ```py # summarize shape print(series.shape) ``` 然后我們可以創建該系列的線圖,以了解該系列的結構。 ```py # plot pyplot.plot(series) pyplot.show() ``` 我們可以將所有這些結合在一起;下面列出了完整的示例。 ```py # load and plot dataset from pandas import read_csv from matplotlib import pyplot # load series = read_csv('monthly-airline-passengers.csv', header=0, index_col=0) # summarize shape print(series.shape) # plot pyplot.plot(series) pyplot.show() ``` 首先運行該示例將打印數據集的形狀。 ```py (144, 1) ``` 該數據集是每月一次,有 12 年或 144 次觀測。在我們的測試中,我們將使用去年或 12 個觀測值作為測試集。 創建線圖。數據集具有明顯的趨勢和季節性成分。季節性成分的期限為 12 個月。 ![Line Plot of Monthly International Airline Passengers](https://img.kancloud.cn/e9/7f/e97f0c216f9a1f72ab7ed7e9f6b5d36b_1280x960.jpg) 每月國際航空公司乘客的線路情節 在本教程中,我們將介紹用于網格搜索的工具,但我們不會針對此問題優化模型超參數。相反,我們將演示如何通常網格搜索深度學習模型超參數,并找到與樸素模型相比具有一定技巧的模型。 從之前的實驗中,一個樸素的模型可以通過持續 12 個月前的值(相對指數-12)來實現 50.70 的均方根誤差或 RMSE(記住單位是數千名乘客)。 這個樸素模型的表現提供了一個被認為適合這個問題的模型的約束。任何在過去 12 個月內達到低于 50.70 的預測表現的模型都具有技巧。 應該注意的是,調諧的 ETS 模型可以實現 17.09 的 RMSE,并且調諧的 SARIMA 可以實現 13.89 的 RMSE。這些為這個問題提供了一個調整良好的深度學習模型的預期的下限。 現在我們已經定義了模型技能的問題和期望,我們可以看看定義網格搜索測試工具。 ## 網格搜索框架 在本節中,我們將開發一個網格搜索測試工具,可用于評估不同神經網絡模型的一系列超參數,例如 MLP,CNN 和 LSTM。 本節分為以下幾部分: 1. 訓練 - 測試分裂 2. 系列作為監督學習 3. 前瞻性驗證 4. 重復評估 5. 總結表現 6. 工作示例 ### 訓練 - 測試分裂 第一步是將加載的系列分成訓練和測試集。 我們將使用前 11 年(132 個觀測值)進行訓練,最后 12 個用于測試集。 下面的 _train_test_split()_ 函數將拆分系列,將原始觀察值和在測試集中使用的觀察數作為參數。 ```py # split a univariate dataset into train/test sets def train_test_split(data, n_test): return data[:-n_test], data[-n_test:] ``` ### 系列作為監督學習 接下來,我們需要能夠將單變量觀測系列框架化為監督學習問題,以便我們可以訓練神經網絡模型。 系列的監督學習框架意味著數據需要分成模型從中學習和概括的多個示例。 每個樣本必須同時具有輸入組件和輸出組件。 輸入組件將是一些先前的觀察,例如三年或 36 個時間步驟。 輸出組件將是下個月的總銷售額,因為我們有興趣開發一個模型來進行一步預測。 我們可以使用 pandas DataFrame 上的 [shift()函數](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.shift.html)來實現它。它允許我們向下移動一列(向前移動)或向后移動(向后移動)。我們可以將該系列作為一列數據,然后創建列的多個副本,向前或向后移動,以便使用我們需要的輸入和輸出元素創建樣本。 當一個系列向下移動時,會引入 NaN 值,因為我們沒有超出系列開頭的值。 例如,系列定義為列: ```py (t) 1 2 3 4 ``` 此列可以預先移位并作為列插入: ```py (t-1), (t) Nan, 1 1, 2 2, 3 3, 4 4 NaN ``` 我們可以看到,在第二行,值 1 作為輸入提供,作為前一時間步的觀察,2 是系列中可以預測的下一個值,或者當 1 是預測模型時要學習的值作為輸入呈現。 可以刪除具有 NaN 值的行。 下面的 _series_to_supervised()_ 函數實現了這種行為,允許您指定輸入中使用的滯后觀察數和每個樣本的輸出中使用的數。它還將刪除具有 NaN 值的行,因為它們不能用于訓練或測試模型。 ```py # transform list into supervised learning format def series_to_supervised(data, n_in=1, n_out=1): df = DataFrame(data) cols = list() # input sequence (t-n, ... t-1) for i in range(n_in, 0, -1): cols.append(df.shift(i)) # forecast sequence (t, t+1, ... t+n) for i in range(0, n_out): cols.append(df.shift(-i)) # put it all together agg = concat(cols, axis=1) # drop rows with NaN values agg.dropna(inplace=True) return agg.values ``` ### 前瞻性驗證 可以使用前向驗證在測試集上評估時間序列預測模型。 前瞻性驗證是一種方法,其中模型一次一個地對測試數據集中的每個觀察進行預測。在對測試數據集中的時間步長進行每個預測之后,將預測的真實觀察結果添加到測試數據集并使其可用于模型。 在進行后續預測之前,可以使用觀察結果更簡單的模型。考慮到更高的計算成本,更復雜的模型,例如神經網絡,不會被改裝。 然而,時間步驟的真實觀察可以用作輸入的一部分,用于在下一個時間步驟上進行預測。 首先,數據集分為訓練集和測試集。我們將調用 _train_test_split()_ 函數來執行此拆分并傳入預先指定數量的觀察值以用作測試數據。 對于給定配置,模型將適合訓練數據集一次。 我們將定義一個通用的 _model_fit()_ 函數來執行此操作,可以為我們稍后可能感興趣的給定類型的神經網絡填充該操作。該函數獲取訓練數據集和模型配置,并返回準備好進行預測的擬合模型。 ```py # fit a model def model_fit(train, config): return None ``` 枚舉測試數據集的每個時間步。使用擬合模型進行預測。 同樣,我們將定義一個名為 _model_predict()_ 的通用函數,它采用擬合模型,歷史和模型配置,并進行單個一步預測。 ```py # forecast with a pre-fit model def model_predict(model, history, config): return 0.0 ``` 將預測添加到預測列表中,并將來自測試集的真實觀察結果添加到用訓練數據集中的所有觀察結果播種的觀察列表中。此列表在前向驗證的每個步驟中構建,允許模型使用最新歷史記錄進行一步預測。 然后可以將所有預測與測試集中的真實值進行比較,并計算誤差測量值。 我們將計算預測和真實值之間的均方根誤差或 RMSE。 RMSE 計算為預測值與實際值之間的平方差的平均值的平方根。 _measure_rmse()_ 使用 [mean_squared_error()scikit-learn](http://scikit-learn.org/stable/modules/generated/sklearn.metrics.mean_squared_error.html) 函數在計算平方根之前首先計算均方誤差或 MSE。 ```py # root mean squared error or rmse def measure_rmse(actual, predicted): return sqrt(mean_squared_error(actual, predicted)) ``` 下面列出了將所有這些聯系在一起的完整 _walk_forward_validation()_ 函數。 它采用數據集,用作測試集的觀察數量以及模型的配置,并返回測試集上模型表現的 RMSE。 ```py # walk-forward validation for univariate data def walk_forward_validation(data, n_test, cfg): predictions = list() # split dataset train, test = train_test_split(data, n_test) # fit model model = model_fit(train, cfg) # seed history with training dataset history = [x for x in train] # step over each time-step in the test set for i in range(len(test)): # fit model and make forecast for history yhat = model_predict(model, history, cfg) # store forecast in list of predictions predictions.append(yhat) # add actual observation to history for the next loop history.append(test[i]) # estimate prediction error error = measure_rmse(test, predictions) print(' > %.3f' % error) return error ``` ### 重復評估 神經網絡模型是隨機的。 這意味著,在給定相同的模型配置和相同的訓練數據集的情況下,每次訓練模型時將產生不同的內部權重集,這反過來將具有不同的表現。 這是一個好處,允許模型自適應并找到復雜問題的高表現配置。 在評估模型的表現和選擇用于進行預測的最終模型時,這也是一個問題。 為了解決模型評估問題,我們將通過[前進驗證](https://machinelearningmastery.com/backtest-machine-learning-models-time-series-forecasting/)多次評估模型配置,并將錯誤報告為每次評估的平均誤差。 對于大型神經網絡而言,這并不總是可行的,并且可能僅適用于能夠在幾分鐘或幾小時內完成的小型網絡。 下面的 _repeat_evaluate()_ 函數實現了這一點,并允許將重復次數指定為默認為 10 的可選參數,并返回所有重復的平均 RMSE 分數。 ```py # score a model, return None on failure def repeat_evaluate(data, config, n_test, n_repeats=10): # convert config to a key key = str(config) # fit and evaluate the model n times scores = [walk_forward_validation(data, n_test, config) for _ in range(n_repeats)] # summarize score result = mean(scores) print('> Model[%s] %.3f' % (key, result)) return (key, result) ``` ### 網格搜索 我們現在擁有框架的所有部分。 剩下的就是驅動搜索的功能。我們可以定義 _grid_search()_ 函數,該函數獲取數據集,要搜索的配置列表以及用作測試集的觀察數量并執行搜索。 一旦為每個配置計算平均分數,配置列表將按升序排序,以便首先列出最佳分數。 完整的功能如下所列。 ```py # grid search configs def grid_search(data, cfg_list, n_test): # evaluate configs scores = scores = [score_model(data, n_test, cfg) for cfg in cfg_list] # sort configs by error, asc scores.sort(key=lambda tup: tup[1]) return scores ``` ### 工作示例 現在我們已經定義了測試工具的元素,我們可以將它們綁定在一起并定義一個簡單的持久性模型。 我們不需要擬合模型,因此 _model_fit()_ 函數將被實現為簡單地返回 None。 ```py # fit a model def model_fit(train, config): return None ``` 我們將使用配置來定義先前觀察中的索引偏移列表,該列表相對于將被用作預測的預測時間。例如,12 將使用 12 個月前(-12)相對于預測時間的觀察。 ```py # define config cfg_list = [1, 6, 12, 24, 36] ``` 可以實現 _model_predict()_ 函數以使用此配置將值保持在負相對偏移處。 ```py # forecast with a pre-fit model def model_predict(model, history, offset): history[-offset] ``` 下面列出了使用簡單持久性模型使用框架的完整示例。 ```py # grid search persistence models for airline passengers from math import sqrt from numpy import mean from pandas import read_csv from sklearn.metrics import mean_squared_error # split a univariate dataset into train/test sets def train_test_split(data, n_test): return data[:-n_test], data[-n_test:] # root mean squared error or rmse def measure_rmse(actual, predicted): return sqrt(mean_squared_error(actual, predicted)) # fit a model def model_fit(train, config): return None # forecast with a pre-fit model def model_predict(model, history, offset): return history[-offset] # walk-forward validation for univariate data def walk_forward_validation(data, n_test, cfg): predictions = list() # split dataset train, test = train_test_split(data, n_test) # fit model model = model_fit(train, cfg) # seed history with training dataset history = [x for x in train] # step over each time-step in the test set for i in range(len(test)): # fit model and make forecast for history yhat = model_predict(model, history, cfg) # store forecast in list of predictions predictions.append(yhat) # add actual observation to history for the next loop history.append(test[i]) # estimate prediction error error = measure_rmse(test, predictions) print(' > %.3f' % error) return error # score a model, return None on failure def repeat_evaluate(data, config, n_test, n_repeats=10): # convert config to a key key = str(config) # fit and evaluate the model n times scores = [walk_forward_validation(data, n_test, config) for _ in range(n_repeats)] # summarize score result = mean(scores) print('> Model[%s] %.3f' % (key, result)) return (key, result) # grid search configs def grid_search(data, cfg_list, n_test): # evaluate configs scores = scores = [repeat_evaluate(data, cfg, n_test) for cfg in cfg_list] # sort configs by error, asc scores.sort(key=lambda tup: tup[1]) return scores # define dataset series = read_csv('monthly-airline-passengers.csv', header=0, index_col=0) data = series.values # data split n_test = 12 # model configs cfg_list = [1, 6, 12, 24, 36] # grid search scores = grid_search(data, cfg_list, n_test) print('done') # list top 10 configs for cfg, error in scores[:10]: print(cfg, error) ``` 運行該示例將打印在最近 12 個月的數據中使用前向驗證評估的模型的 RMSE。 每個模型配置被評估 10 次,但是,因為模型沒有隨機元素,所以每次得分都相同。 在運行結束時,將報告前三個執行模型配置的配置和 RMSE。 我們可以看到,正如我們可能預期的那樣,持續一年前的值(相對偏移-12)導致持久性模型的最佳表現。 ```py ... > 110.274 > 110.274 > 110.274 > Model[36] 110.274 done 12 50.708316214732804 1 53.1515129919491 24 97.10990337413241 36 110.27352356753639 6 126.73495965991387 ``` 現在我們有一個強大的網格搜索模型超參數測試工具,我們可以用它來評估一套神經網絡模型。 ## 網格搜索多層感知器 我們可能希望調整 MLP 的許多方面。 我們將定義一個非常簡單的模型,其中包含一個隱藏層,并定義五個超參數進行調整。他們是: * **n_input** :用作模型輸入的先前輸入數(例如 12 個月)。 * **n_nodes** :隱藏層中使用的節點數(例如 50)。 * **n_epochs** :訓練時期的數量(例如 1000)。 * **n_batch** :每個小批量中包含的樣本數(例如 32)。 * **n_diff** :差分順序(例如 0 或 12)。 現代神經網絡可以通過很少的預處理來處理原始數據,例如縮放和差分。然而,當涉及時間序列數據時,有時差異系列可以使問題更容易建模。 回想一下,[差分](https://machinelearningmastery.com/remove-trends-seasonality-difference-transform-python/)是數據的變換,使得從當前觀察中減去先前觀察的值,去除趨勢或季節性結構。 我們將為網格搜索測試工具添加差異支持,以防它為您的特定問題增加價值。它確實為內部航空公司乘客數據集增加了價值。 下面的 _ 差異()_ 函數將計算數據集的給定順序的差異。 ```py # difference dataset def difference(data, order): return [data[i] - data[i - order] for i in range(order, len(data))] ``` 差異將是可選的,其中 0 的順序表示沒有差異,而 1 階或 12 階將要求在擬合模型之前差異數據并且模型的預測需要在返回預測之前反轉差分。 我們現在可以定義在測試工具中安裝 MLP 模型所需的元素。 首先,我們必須解壓縮超參數列表。 ```py # unpack config n_input, n_nodes, n_epochs, n_batch, n_diff = config ``` 接下來,我們必須準備數據,包括差分,將數據轉換為監督格式,并分離出數據樣本的輸入和輸出方面。 ```py # prepare data if n_diff > 0: train = difference(train, n_diff) # transform series into supervised format data = series_to_supervised(train, n_in=n_input) # separate inputs and outputs train_x, train_y = data[:, :-1], data[:, -1] ``` 我們現在可以使用提供的配置定義和擬合模型。 ```py # define model model = Sequential() model.add(Dense(n_nodes, activation='relu', input_dim=n_input)) model.add(Dense(1)) model.compile(loss='mse', optimizer='adam') # fit model model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0) ``` 下面列出了 _model_fit()_ 函數的完整實現。 ```py # fit a model def model_fit(train, config): # unpack config n_input, n_nodes, n_epochs, n_batch, n_diff = config # prepare data if n_diff > 0: train = difference(train, n_diff) # transform series into supervised format data = series_to_supervised(train, n_in=n_input) # separate inputs and outputs train_x, train_y = data[:, :-1], data[:, -1] # define model model = Sequential() model.add(Dense(n_nodes, activation='relu', input_dim=n_input)) model.add(Dense(1)) model.compile(loss='mse', optimizer='adam') # fit model model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0) return model ``` 五個選擇的超參數絕不是要調整的模型的唯一或最佳超參數。您可以修改該功能以調整其他參數,例如更多隱藏層的添加和大小等等。 一旦模型適合,我們就可以使用它來進行預測。 如果數據差異,則必須反轉差異以預測模型。這涉及將歷史的相對偏移處的值添加回模型預測的值。 ```py # invert difference correction = 0.0 if n_diff > 0: correction = history[-n_diff] ... # correct forecast if it was differenced return correction + yhat[0] ``` 這也意味著必須區分歷史記錄,以便用于進行預測的輸入數據具有預期的形式。 ```py # calculate difference history = difference(history, n_diff) ``` 準備好之后,我們可以使用歷史數據創建單個樣本作為模型的輸入,以進行一步預測。 一個樣本的形狀必須是[1,n_input],其中 _n_input_ 是要使用的滯后觀察數的選定數量。 ```py # shape input for model x_input = array(history[-n_input:]).reshape((1, n_input)) ``` 最后,可以進行預測。 ```py # make forecast yhat = model.predict(x_input, verbose=0) ``` 下面列出了 _model_predict()_ 函數的完整實現。 接下來,我們必須定義要為每個超參數嘗試的值范圍。 我們可以定義 _model_configs()_ 函數,該函數創建要嘗試的不同參數組合的列表。 我們將定義一小部分配置作為示例,包括 12 個月的差異,我們預計這將是必需的。建議您嘗試使用獨立模型,查看學習曲線診斷圖,并使用有關域的信息來設置超參數值到網格搜索的范圍。 我們還鼓勵您重復網格搜索以縮小顯示更好表現的值范圍。 下面列出了 _model_configs()_ 函數的實現。 ```py # create a list of configs to try def model_configs(): # define scope of configs n_input = [12] n_nodes = [50, 100] n_epochs = [100] n_batch = [1, 150] n_diff = [0, 12] # create configs configs = list() for i in n_input: for j in n_nodes: for k in n_epochs: for l in n_batch: for m in n_diff: cfg = [i, j, k, l, m] configs.append(cfg) print('Total configs: %d' % len(configs)) return configs ``` 我們現在擁有網格搜索 MLP 模型所需的所有部分,用于單變量時間序列預測問題。 下面列出了完整的示例。 ```py # grid search mlps for airline passengers from math import sqrt from numpy import array from numpy import mean from pandas import DataFrame from pandas import concat from pandas import read_csv from sklearn.metrics import mean_squared_error from keras.models import Sequential from keras.layers import Dense # split a univariate dataset into train/test sets def train_test_split(data, n_test): return data[:-n_test], data[-n_test:] # transform list into supervised learning format def series_to_supervised(data, n_in=1, n_out=1): df = DataFrame(data) cols = list() # input sequence (t-n, ... t-1) for i in range(n_in, 0, -1): cols.append(df.shift(i)) # forecast sequence (t, t+1, ... t+n) for i in range(0, n_out): cols.append(df.shift(-i)) # put it all together agg = concat(cols, axis=1) # drop rows with NaN values agg.dropna(inplace=True) return agg.values # root mean squared error or rmse def measure_rmse(actual, predicted): return sqrt(mean_squared_error(actual, predicted)) # difference dataset def difference(data, order): return [data[i] - data[i - order] for i in range(order, len(data))] # fit a model def model_fit(train, config): # unpack config n_input, n_nodes, n_epochs, n_batch, n_diff = config # prepare data if n_diff > 0: train = difference(train, n_diff) # transform series into supervised format data = series_to_supervised(train, n_in=n_input) # separate inputs and outputs train_x, train_y = data[:, :-1], data[:, -1] # define model model = Sequential() model.add(Dense(n_nodes, activation='relu', input_dim=n_input)) model.add(Dense(1)) model.compile(loss='mse', optimizer='adam') # fit model model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0) return model # forecast with the fit model def model_predict(model, history, config): # unpack config n_input, _, _, _, n_diff = config # prepare data correction = 0.0 if n_diff > 0: correction = history[-n_diff] history = difference(history, n_diff) # shape input for model x_input = array(history[-n_input:]).reshape((1, n_input)) # make forecast yhat = model.predict(x_input, verbose=0) # correct forecast if it was differenced return correction + yhat[0] # walk-forward validation for univariate data def walk_forward_validation(data, n_test, cfg): predictions = list() # split dataset train, test = train_test_split(data, n_test) # fit model model = model_fit(train, cfg) # seed history with training dataset history = [x for x in train] # step over each time-step in the test set for i in range(len(test)): # fit model and make forecast for history yhat = model_predict(model, history, cfg) # store forecast in list of predictions predictions.append(yhat) # add actual observation to history for the next loop history.append(test[i]) # estimate prediction error error = measure_rmse(test, predictions) print(' > %.3f' % error) return error # score a model, return None on failure def repeat_evaluate(data, config, n_test, n_repeats=10): # convert config to a key key = str(config) # fit and evaluate the model n times scores = [walk_forward_validation(data, n_test, config) for _ in range(n_repeats)] # summarize score result = mean(scores) print('> Model[%s] %.3f' % (key, result)) return (key, result) # grid search configs def grid_search(data, cfg_list, n_test): # evaluate configs scores = scores = [repeat_evaluate(data, cfg, n_test) for cfg in cfg_list] # sort configs by error, asc scores.sort(key=lambda tup: tup[1]) return scores # create a list of configs to try def model_configs(): # define scope of configs n_input = [12] n_nodes = [50, 100] n_epochs = [100] n_batch = [1, 150] n_diff = [0, 12] # create configs configs = list() for i in n_input: for j in n_nodes: for k in n_epochs: for l in n_batch: for m in n_diff: cfg = [i, j, k, l, m] configs.append(cfg) print('Total configs: %d' % len(configs)) return configs # define dataset series = read_csv('monthly-airline-passengers.csv', header=0, index_col=0) data = series.values # data split n_test = 12 # model configs cfg_list = model_configs() # grid search scores = grid_search(data, cfg_list, n_test) print('done') # list top 3 configs for cfg, error in scores[:3]: print(cfg, error) ``` 運行該示例,我們可以看到框架總共要評估八種配置。 每個配置將被評估 10 次;這意味著將使用前向驗證創建和評估 10 個模型,以在報告這 10 個分數的平均值并用于對配置進行評分之前計算 RMSE 分數。 然后對得分進行排序,最后報告具有最低 RMSE 的前 3 個配置。與報告 RMSE 為 50.70 的幼稚模型相比,發現了一種熟練的模型配置。 我們可以看到 18.98 的最佳 RMSE 是通過[12,100,100,1,12]的配置實現的,我們知道可以解釋為: * **n_input** :12 * **n_nodes** :100 * **n_epochs** :100 * **n_batch** :1 * **n_diff** :12 下面列出了網格搜索的截斷示例輸出。 鑒于算法的隨機性,您的具體分數可能會有所不同。 ```py Total configs: 8 > 20.707 > 29.111 > 17.499 > 18.918 > 28.817 ... > 21.015 > 20.208 > 18.503 > Model[[12, 100, 100, 150, 12]] 19.674 done [12, 100, 100, 1, 12] 18.982720013625606 [12, 50, 100, 150, 12] 19.33004059448595 [12, 100, 100, 1, 0] 19.5389405532858 ``` ## 網格搜索卷積神經網絡 我們現在可以將框架調整為網格搜索 CNN 模型。 可以像使用 MLP 模型一樣搜索大量相同的超參數集,除了隱藏層中的節點數可以由卷積層中的濾波器映射數和內核大小替換。 在 CNN 模型中選擇的網格搜索超參數集如下: * **n_input** :用作模型輸入的先前輸入數(例如 12 個月)。 * **n_filters** :卷積層中的濾波器映射的數量(例如 32)。 * **n_kernel** :卷積層中的內核大小(例如 3)。 * **n_epochs** :訓練時期的數量(例如 1000)。 * **n_batch** :每個小批量中包含的樣本數(例如 32)。 * **n_diff** :差分順序(例如 0 或 12)。 您可能希望研究的一些額外的超參數是在池化層之前使用兩個卷積層,重復卷積和池化層模式,使用丟失等等。 我們將定義一個非常簡單的 CNN 模型,其中包含一個卷積層和一個最大池池。 ```py # define model model = Sequential() model.add(Conv1D(filters=n_filters, kernel_size=n_kernel, activation='relu', input_shape=(n_input, n_features))) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(1)) model.compile(loss='mse', optimizer='adam') ``` 必須以與 MLP 相同的方式準備數據。 與期望輸入數據具有[樣本,特征]形狀的 MLP 不同,1D CNN 模型期望數據具有[_ 樣本,時間步長,特征 _]的形狀,其中特征映射到通道上并且在此案例 1 是我們每個月測量的一個變量。 ```py # reshape input data into [samples, timesteps, features] n_features = 1 train_x = train_x.reshape((train_x.shape[0], train_x.shape[1], n_features)) ``` 下面列出了 _model_fit()_ 函數的完整實現。 ```py # fit a model def model_fit(train, config): # unpack config n_input, n_filters, n_kernel, n_epochs, n_batch, n_diff = config # prepare data if n_diff > 0: train = difference(train, n_diff) # transform series into supervised format data = series_to_supervised(train, n_in=n_input) # separate inputs and outputs train_x, train_y = data[:, :-1], data[:, -1] # reshape input data into [samples, timesteps, features] n_features = 1 train_x = train_x.reshape((train_x.shape[0], train_x.shape[1], n_features)) # define model model = Sequential() model.add(Conv1D(filters=n_filters, kernel_size=n_kernel, activation='relu', input_shape=(n_input, n_features))) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(1)) model.compile(loss='mse', optimizer='adam') # fit model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0) return model ``` 使用擬合 CNN 模型進行預測非常類似于使用擬合 MLP 進行預測。 同樣,唯一的區別是一個樣本值的輸入數據必須具有三維形狀。 ```py x_input = array(history[-n_input:]).reshape((1, n_input, 1)) ``` 下面列出了 _model_predict()_ 函數的完整實現。 ```py # forecast with the fit model def model_predict(model, history, config): # unpack config n_input, _, _, _, _, n_diff = config # prepare data correction = 0.0 if n_diff > 0: correction = history[-n_diff] history = difference(history, n_diff) x_input = array(history[-n_input:]).reshape((1, n_input, 1)) # forecast yhat = model.predict(x_input, verbose=0) return correction + yhat[0] ``` 最后,我們可以定義要評估的模型的配置列表。和以前一樣,我們可以通過定義超參數值列表來嘗試將它們組合成一個列表。我們將嘗試少量配置以確保示例在合理的時間內執行。 完整的 _model_configs()_ 功能如下所示。 ```py # create a list of configs to try def model_configs(): # define scope of configs n_input = [12] n_filters = [64] n_kernels = [3, 5] n_epochs = [100] n_batch = [1, 150] n_diff = [0, 12] # create configs configs = list() for a in n_input: for b in n_filters: for c in n_kernels: for d in n_epochs: for e in n_batch: for f in n_diff: cfg = [a,b,c,d,e,f] configs.append(cfg) print('Total configs: %d' % len(configs)) return configs ``` 我們現在擁有網格搜索卷積神經網絡的超參數所需的所有元素,用于單變量時間序列預測。 下面列出了完整的示例。 ```py # grid search cnn for airline passengers from math import sqrt from numpy import array from numpy import mean from pandas import DataFrame from pandas import concat from pandas import read_csv from sklearn.metrics import mean_squared_error 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 dataset into train/test sets def train_test_split(data, n_test): return data[:-n_test], data[-n_test:] # transform list into supervised learning format def series_to_supervised(data, n_in=1, n_out=1): df = DataFrame(data) cols = list() # input sequence (t-n, ... t-1) for i in range(n_in, 0, -1): cols.append(df.shift(i)) # forecast sequence (t, t+1, ... t+n) for i in range(0, n_out): cols.append(df.shift(-i)) # put it all together agg = concat(cols, axis=1) # drop rows with NaN values agg.dropna(inplace=True) return agg.values # root mean squared error or rmse def measure_rmse(actual, predicted): return sqrt(mean_squared_error(actual, predicted)) # difference dataset def difference(data, order): return [data[i] - data[i - order] for i in range(order, len(data))] # fit a model def model_fit(train, config): # unpack config n_input, n_filters, n_kernel, n_epochs, n_batch, n_diff = config # prepare data if n_diff > 0: train = difference(train, n_diff) # transform series into supervised format data = series_to_supervised(train, n_in=n_input) # separate inputs and outputs train_x, train_y = data[:, :-1], data[:, -1] # reshape input data into [samples, timesteps, features] n_features = 1 train_x = train_x.reshape((train_x.shape[0], train_x.shape[1], n_features)) # define model model = Sequential() model.add(Conv1D(filters=n_filters, kernel_size=n_kernel, activation='relu', input_shape=(n_input, n_features))) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(1)) model.compile(loss='mse', optimizer='adam') # fit model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0) return model # forecast with the fit model def model_predict(model, history, config): # unpack config n_input, _, _, _, _, n_diff = config # prepare data correction = 0.0 if n_diff > 0: correction = history[-n_diff] history = difference(history, n_diff) x_input = array(history[-n_input:]).reshape((1, n_input, 1)) # forecast yhat = model.predict(x_input, verbose=0) return correction + yhat[0] # walk-forward validation for univariate data def walk_forward_validation(data, n_test, cfg): predictions = list() # split dataset train, test = train_test_split(data, n_test) # fit model model = model_fit(train, cfg) # seed history with training dataset history = [x for x in train] # step over each time-step in the test set for i in range(len(test)): # fit model and make forecast for history yhat = model_predict(model, history, cfg) # store forecast in list of predictions predictions.append(yhat) # add actual observation to history for the next loop history.append(test[i]) # estimate prediction error error = measure_rmse(test, predictions) print(' > %.3f' % error) return error # score a model, return None on failure def repeat_evaluate(data, config, n_test, n_repeats=10): # convert config to a key key = str(config) # fit and evaluate the model n times scores = [walk_forward_validation(data, n_test, config) for _ in range(n_repeats)] # summarize score result = mean(scores) print('> Model[%s] %.3f' % (key, result)) return (key, result) # grid search configs def grid_search(data, cfg_list, n_test): # evaluate configs scores = scores = [repeat_evaluate(data, cfg, n_test) for cfg in cfg_list] # sort configs by error, asc scores.sort(key=lambda tup: tup[1]) return scores # create a list of configs to try def model_configs(): # define scope of configs n_input = [12] n_filters = [64] n_kernels = [3, 5] n_epochs = [100] n_batch = [1, 150] n_diff = [0, 12] # create configs configs = list() for a in n_input: for b in n_filters: for c in n_kernels: for d in n_epochs: for e in n_batch: for f in n_diff: cfg = [a,b,c,d,e,f] configs.append(cfg) print('Total configs: %d' % len(configs)) return configs # define dataset series = read_csv('monthly-airline-passengers.csv', header=0, index_col=0) data = series.values # data split n_test = 12 # model configs cfg_list = model_configs() # grid search scores = grid_search(data, cfg_list, n_test) print('done') # list top 10 configs for cfg, error in scores[:3]: print(cfg, error) ``` 運行該示例,我們可以看到只評估了八種不同的配置。 我們可以看到[12,64,5,100,1,12]的配置實現了 18.89 的 RMSE,與實現 50.70 的樸素預測模型相比,這是巧妙的。 我們可以將此配置解壓縮為: * **n_input** :12 * **n_filters** :64 * **n_kernel** :5 * **n_epochs** :100 * **n_batch** :1 * **n_diff** :12 下面列出了網格搜索的截斷示例輸出。 鑒于算法的隨機性,您的具體分數可能會有所不同。 ```py Total configs: 8 > 23.372 > 28.317 > 31.070 ... > 20.923 > 18.700 > 18.210 > Model[[12, 64, 5, 100, 150, 12]] 19.152 done [12, 64, 5, 100, 1, 12] 18.89593462072732 [12, 64, 5, 100, 150, 12] 19.152486150334234 [12, 64, 3, 100, 150, 12] 19.44680151564605 ``` ## 網格搜索長短期記憶網絡 我們現在可以采用網格搜索 LSTM 模型的超參數。 LSTM 模型的超參數將與 MLP 相同;他們是: * **n_input** :用作模型輸入的先前輸入數(例如 12 個月)。 * **n_nodes** :隱藏層中使用的節點數(例如 50)。 * **n_epochs** :訓練時期的數量(例如 1000)。 * **n_batch** :每個小批量中包含的樣本數(例如 32)。 * **n_diff** :差分順序(例如 0 或 12)。 我們將定義一個簡單的 LSTM 模型,該模型具有單個隱藏的 LSTM 層和指定該層中單元數的節點數。 ```py # define model model = Sequential() model.add(LSTM(n_nodes, activation='relu', input_shape=(n_input, n_features))) model.add(Dense(n_nodes, activation='relu')) model.add(Dense(1)) model.compile(loss='mse', optimizer='adam') # fit model model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0) ``` 探索調整其他配置(例如使用雙向輸入層,堆疊 LSTM 層,甚至是具有 CNN 或 ConvLSTM 輸入模型的混合模型)可能會很有趣。 與 CNN 模型一樣,LSTM 模型期望輸入數據具有樣本,時間步長和特征的三維形狀。 ```py # reshape input data into [samples, timesteps, features] n_features = 1 train_x = train_x.reshape((train_x.shape[0], train_x.shape[1], n_features)) ``` 下面列出了 _model_fit()_ 函數的完整實現。 ```py # fit a model def model_fit(train, config): # unpack config n_input, n_nodes, n_epochs, n_batch, n_diff = config # prepare data if n_diff > 0: train = difference(train, n_diff) # transform series into supervised format data = series_to_supervised(train, n_in=n_input) # separate inputs and outputs train_x, train_y = data[:, :-1], data[:, -1] # reshape input data into [samples, timesteps, features] n_features = 1 train_x = train_x.reshape((train_x.shape[0], train_x.shape[1], n_features)) # define model model = Sequential() model.add(LSTM(n_nodes, activation='relu', input_shape=(n_input, n_features))) model.add(Dense(n_nodes, activation='relu')) model.add(Dense(1)) model.compile(loss='mse', optimizer='adam') # fit model model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0) return model ``` 與 CNN 一樣,用于進行預測的單個輸入樣本也必須重新形成預期的三維結構。 ```py # reshape sample into [samples, timesteps, features] x_input = array(history[-n_input:]).reshape((1, n_input, 1)) ``` 完整的 _model_predict()_ 功能如下所示。 ```py # forecast with the fit model def model_predict(model, history, config): # unpack config n_input, _, _, _, n_diff = config # prepare data correction = 0.0 if n_diff > 0: correction = history[-n_diff] history = difference(history, n_diff) # reshape sample into [samples, timesteps, features] x_input = array(history[-n_input:]).reshape((1, n_input, 1)) # forecast yhat = model.predict(x_input, verbose=0) return correction + yhat[0] ``` 我們現在可以定義用于創建要評估的模型配置列表的函數。 訓練的 LSTM 模型比 MLP 和 CNN 模型慢得多;因此,您可能希望評估每次運行的配置更少。 我們將定義一組非常簡單的兩種配置來探索:隨機和批量梯度下降。 ```py # create a list of configs to try def model_configs(): # define scope of configs n_input = [12] n_nodes = [100] n_epochs = [50] n_batch = [1, 150] n_diff = [12] # create configs configs = list() for i in n_input: for j in n_nodes: for k in n_epochs: for l in n_batch: for m in n_diff: cfg = [i, j, k, l, m] configs.append(cfg) print('Total configs: %d' % len(configs)) return configs ``` 我們現在擁有了針對 LSTM 模型的網格搜索超參數所需的一切,用于單變量時間序列預測。 下面列出了完整的示例。 ```py # grid search lstm for airline passengers from math import sqrt from numpy import array from numpy import mean from pandas import DataFrame from pandas import concat from pandas import read_csv from sklearn.metrics import mean_squared_error from keras.models import Sequential from keras.layers import Dense from keras.layers import LSTM # split a univariate dataset into train/test sets def train_test_split(data, n_test): return data[:-n_test], data[-n_test:] # transform list into supervised learning format def series_to_supervised(data, n_in=1, n_out=1): df = DataFrame(data) cols = list() # input sequence (t-n, ... t-1) for i in range(n_in, 0, -1): cols.append(df.shift(i)) # forecast sequence (t, t+1, ... t+n) for i in range(0, n_out): cols.append(df.shift(-i)) # put it all together agg = concat(cols, axis=1) # drop rows with NaN values agg.dropna(inplace=True) return agg.values # root mean squared error or rmse def measure_rmse(actual, predicted): return sqrt(mean_squared_error(actual, predicted)) # difference dataset def difference(data, order): return [data[i] - data[i - order] for i in range(order, len(data))] # fit a model def model_fit(train, config): # unpack config n_input, n_nodes, n_epochs, n_batch, n_diff = config # prepare data if n_diff > 0: train = difference(train, n_diff) # transform series into supervised format data = series_to_supervised(train, n_in=n_input) # separate inputs and outputs train_x, train_y = data[:, :-1], data[:, -1] # reshape input data into [samples, timesteps, features] n_features = 1 train_x = train_x.reshape((train_x.shape[0], train_x.shape[1], n_features)) # define model model = Sequential() model.add(LSTM(n_nodes, activation='relu', input_shape=(n_input, n_features))) model.add(Dense(n_nodes, activation='relu')) model.add(Dense(1)) model.compile(loss='mse', optimizer='adam') # fit model model.fit(train_x, train_y, epochs=n_epochs, batch_size=n_batch, verbose=0) return model # forecast with the fit model def model_predict(model, history, config): # unpack config n_input, _, _, _, n_diff = config # prepare data correction = 0.0 if n_diff > 0: correction = history[-n_diff] history = difference(history, n_diff) # reshape sample into [samples, timesteps, features] x_input = array(history[-n_input:]).reshape((1, n_input, 1)) # forecast yhat = model.predict(x_input, verbose=0) return correction + yhat[0] # walk-forward validation for univariate data def walk_forward_validation(data, n_test, cfg): predictions = list() # split dataset train, test = train_test_split(data, n_test) # fit model model = model_fit(train, cfg) # seed history with training dataset history = [x for x in train] # step over each time-step in the test set for i in range(len(test)): # fit model and make forecast for history yhat = model_predict(model, history, cfg) # store forecast in list of predictions predictions.append(yhat) # add actual observation to history for the next loop history.append(test[i]) # estimate prediction error error = measure_rmse(test, predictions) print(' > %.3f' % error) return error # score a model, return None on failure def repeat_evaluate(data, config, n_test, n_repeats=10): # convert config to a key key = str(config) # fit and evaluate the model n times scores = [walk_forward_validation(data, n_test, config) for _ in range(n_repeats)] # summarize score result = mean(scores) print('> Model[%s] %.3f' % (key, result)) return (key, result) # grid search configs def grid_search(data, cfg_list, n_test): # evaluate configs scores = scores = [repeat_evaluate(data, cfg, n_test) for cfg in cfg_list] # sort configs by error, asc scores.sort(key=lambda tup: tup[1]) return scores # create a list of configs to try def model_configs(): # define scope of configs n_input = [12] n_nodes = [100] n_epochs = [50] n_batch = [1, 150] n_diff = [12] # create configs configs = list() for i in n_input: for j in n_nodes: for k in n_epochs: for l in n_batch: for m in n_diff: cfg = [i, j, k, l, m] configs.append(cfg) print('Total configs: %d' % len(configs)) return configs # define dataset series = read_csv('monthly-airline-passengers.csv', header=0, index_col=0) data = series.values # data split n_test = 12 # model configs cfg_list = model_configs() # grid search scores = grid_search(data, cfg_list, n_test) print('done') # list top 10 configs for cfg, error in scores[:3]: print(cfg, error) ``` 運行該示例,我們可以看到只評估了兩個不同的配置。 我們可以看到[12,100,50,1,12]的配置實現了 21.24 的 RMSE,與實現 50.70 的樸素預測模型相比,這是巧妙的。 該模型需要更多的調整,并且可以使用混合配置做得更好,例如將 CNN 模型作為輸入。 我們可以將此配置解壓縮為: * **n_input** :12 * **n_nodes** :100 * **n_epochs** :50 * **n_batch** :1 * **n_diff** :12 下面列出了網格搜索的截斷示例輸出。 鑒于算法的隨機性,您的具體分數可能會有所不同。 ```py Total configs: 2 > 20.488 > 17.718 > 21.213 ... > 22.300 > 20.311 > 21.322 > Model[[12, 100, 50, 150, 12]] 21.260 done [12, 100, 50, 1, 12] 21.243775750634093 [12, 100, 50, 150, 12] 21.259553398553606 ``` ## 擴展 本節列出了一些擴展您可能希望探索的教程的想法。 * **更多配置**。探索其中一個模型的大型配置套件,看看您是否能找到能夠提高表現的配置。 * **數據縮放**。更新網格搜索框架以在擬合模型和反轉變換以進行預測之前還支持數據的縮放(標準化和/或標準化)。 * **網絡架構**。探索網格搜索給定模型的更大架構更改,例如添加更多隱藏層。 * **新數據集**。在新的單變量時間序列數據集中探索給定模型的網格搜索。 * **多變量**。更新網格搜索框架以支持小的多變量時間序列數據集,例如具有多個輸入變量的數據集。 如果你探索任何這些擴展,我很想知道。 ## 進一步閱讀 如果您希望深入了解,本節將提供有關該主題的更多資源。 * [如何使用 Keras 網格搜索 Python 中的深度學習模型的超參數](https://machinelearningmastery.com/grid-search-hyperparameters-deep-learning-models-python-keras/) * [Keras 核心層 API](https://keras.io/layers/core/) * [Keras 卷積層 API](https://keras.io/layers/convolutional/) * [Keras Recurrent Layers API](https://keras.io/layers/recurrent/) ## 摘要 在本教程中,您了解了如何為深度學習模型開發網格搜索超參數框架。 具體來說,你學到了: * 如何開發用于調整模型超參數的通用網格搜索框架。 * 如何在航空公司乘客單變量時間序列預測問題上對多層感知器模型進行網格搜索超參數。 * 如何使框架適應卷積和長期短期記憶神經網絡的網格搜索超參數。 你有任何問題嗎? 在下面的評論中提出您的問題,我會盡力回答。
                  <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>

                              哎呀哎呀视频在线观看