網(wǎng)絡(luò)的高大平房倉(cāng)溫度場(chǎng)預(yù)測(cè)實(shí)戰(zhàn)指南)
簡(jiǎn)介《基于BP神經(jīng)網(wǎng)絡(luò)方法的高大平房倉(cāng)溫度場(chǎng)預(yù)測(cè)研究》是一份學(xué)術(shù)論文PDF內(nèi)容圍繞國(guó)家糧食儲(chǔ)備倉(cāng)型——高大平房倉(cāng)的溫度場(chǎng)預(yù)測(cè)展開(kāi)面向糧油倉(cāng)儲(chǔ)安全監(jiān)測(cè)、機(jī)器學(xué)習(xí)算法應(yīng)用以及數(shù)據(jù)建模方向的科研人員、工程師與學(xué)生。該研究以BP神經(jīng)網(wǎng)絡(luò)為核心結(jié)合實(shí)際糧情監(jiān)測(cè)數(shù)據(jù)來(lái)自江蘇省某糧庫(kù)192個(gè)溫度監(jiān)測(cè)點(diǎn)、3萬(wàn)多組樣本在MATLAB平臺(tái)構(gòu)建并訓(xùn)練溫度場(chǎng)預(yù)測(cè)模型夏季糧堆容易因外界持續(xù)傳熱和微生物繁殖而發(fā)熱利用該模型可提前預(yù)判倉(cāng)內(nèi)溫度變化為通風(fēng)控溫決策提供依據(jù)。文檔不僅分析了溫度、濕度、氣流速率、糧種和儲(chǔ)藏時(shí)間等因素對(duì)溫度場(chǎng)的影響還借助SPSS統(tǒng)計(jì)學(xué)軟件量化各影響因素權(quán)重并通過(guò)神經(jīng)網(wǎng)絡(luò)驗(yàn)證主成分分析結(jié)論方法鏈條完整對(duì)農(nóng)業(yè)場(chǎng)景中的非線性建模有較強(qiáng)參考價(jià)值。資源包共1個(gè)PDF文件大小315KB目前已有188人學(xué)習(xí)/下載適合正在研究糧情預(yù)測(cè)、儲(chǔ)糧信息化或BP神經(jīng)網(wǎng)絡(luò)應(yīng)用的讀者直接借鑒。1. 基于BP神經(jīng)網(wǎng)絡(luò)預(yù)測(cè)高大平房倉(cāng)溫度場(chǎng)先回答明天哪里會(huì)先熱每年七月最悶熱的那幾天我經(jīng)常對(duì)著測(cè)溫屏幕發(fā)呆八十多個(gè)測(cè)點(diǎn)都在 28℃ 附近來(lái)回跳動(dòng)表面看起來(lái)一切正常但誰(shuí)也說(shuō)不準(zhǔn)第二天東北角第六根電纜中層會(huì)不會(huì)一個(gè)猛子沖上 30℃。高大平房倉(cāng)的溫度場(chǎng)預(yù)測(cè)解決的就是這種數(shù)據(jù)全在眼前卻沒(méi)人敢打包票的難題?;贐P神經(jīng)網(wǎng)絡(luò)的做法是把過(guò)去幾天的各點(diǎn)溫度序列、空間位置和外部氣溫一起喂進(jìn)網(wǎng)絡(luò)讓它自己學(xué)出從歷史到未來(lái)的非線性映射輸出未來(lái) 24 到 72 小時(shí)的溫度場(chǎng)。它不需要你推導(dǎo)糧堆的熱傳導(dǎo)微分方程也不用給倉(cāng)壁和糧面設(shè)定一堆邊界條件對(duì)糧庫(kù)信息化工程師、儲(chǔ)糧技術(shù)員和設(shè)備廠商的算法崗來(lái)說(shuō)是一條能直接落地的實(shí)用路線。2. 為什么溫度場(chǎng)預(yù)測(cè)要選 BP滯后、非線性和那張結(jié)構(gòu)圖2.1 平房倉(cāng)溫度場(chǎng)的滯后和非線性讓線性模型先出局高大平房倉(cāng)的糧堆體積動(dòng)輒幾千立方米導(dǎo)熱系數(shù)跟木材一個(gè)量級(jí)比混凝土低得多熱量在糧堆里走得極慢。外界氣溫對(duì)糧堆的影響要滯后幾十天才能滲透到中心層與此同時(shí)糧堆本身還是個(gè)發(fā)熱體糧食呼吸和微生物代謝的熱量在局部積累形成溫差和熱濕遷移。這幾個(gè)效應(yīng)疊加在一起讓每個(gè)測(cè)點(diǎn)的溫度序列表現(xiàn)出強(qiáng)烈的自相關(guān)和明顯的非線性。自相關(guān)強(qiáng)意味著今天的溫度對(duì)預(yù)測(cè)明天很重要非線性強(qiáng)意味著溫度增量不等于外溫增量乘一個(gè)固定系數(shù)。糧庫(kù)里最常見(jiàn)的傳統(tǒng)做法是拿上一時(shí)段溫度加外溫修正做預(yù)報(bào)本質(zhì)上假設(shè)溫度增量與外溫線性相關(guān)。這個(gè)假設(shè)在倉(cāng)壁附近勉強(qiáng)成立因?yàn)槟且粠芡鉁貍鲗?dǎo)主導(dǎo)可一旦到了糧堆中心呼吸熱和熱濕耦合占上風(fēng)線性修正就徹底失準(zhǔn)。更麻煩的是通風(fēng)作業(yè)冷鋒從通風(fēng)口往糧堆里推進(jìn)局部溫度能在十幾個(gè)小時(shí)內(nèi)急速下降這不是一個(gè)線性系數(shù)能描述的現(xiàn)象。線性模型出局之后就得找一個(gè)能擬合任意非線性映射的工具BP 神經(jīng)網(wǎng)絡(luò)正好在這個(gè)位置上。2.2 先畫一張 BP 神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)圖輸入層、隱層、輸出層怎么連在做任何訓(xùn)練之前我習(xí)慣先把預(yù)測(cè)任務(wù)翻譯成一張 BP 神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)圖。對(duì)于一個(gè)具體的測(cè)點(diǎn)任務(wù)可以寫成已知該點(diǎn)過(guò)去 7 天每隔 6 小時(shí)的溫度值疊加位置特征和外部氣溫求它未來(lái) 72 小時(shí)后的溫度。這是一個(gè)從高維輸入到單點(diǎn)輸出的連續(xù)映射BP 網(wǎng)絡(luò)能逼近它靠的是萬(wàn)能逼近定理——只要隱層節(jié)點(diǎn)足夠多三層前饋網(wǎng)絡(luò)就能以任意精度逼近任意連續(xù)函數(shù)。具體到這張結(jié)構(gòu)圖輸入層放過(guò)去 7 天每天 4 個(gè)時(shí)刻的溫度也就是 28 個(gè)神經(jīng)元再拼上測(cè)點(diǎn)的層位、行列坐標(biāo)和未來(lái)一段的外部氣溫總共 32 到 36 個(gè)輸入神經(jīng)元。第一隱層用 16 個(gè) tanh 節(jié)點(diǎn)第二隱層用 8 個(gè)輸出層只有 1 個(gè)神經(jīng)元輸出未來(lái)溫度。這個(gè)規(guī)??雌饋?lái)很小但很合適平房倉(cāng)一個(gè)倉(cāng)的可用歷史數(shù)據(jù)通常只有幾萬(wàn)條量級(jí)把網(wǎng)絡(luò)堆到上百個(gè)節(jié)點(diǎn)學(xué)到的就不是規(guī)律而是噪聲。記住先畫結(jié)構(gòu)圖再寫代碼輸入維度和隱層寬度都從這張圖里定下來(lái)。2.3 為什么不用 LSTM數(shù)據(jù)量、可解釋性和工程維護(hù)的現(xiàn)實(shí)權(quán)衡聊到溫度場(chǎng)預(yù)測(cè)很多人第一反應(yīng)是為什么不用 LSTM。LSTM 在長(zhǎng)序列建模上確實(shí)更優(yōu)雅但工程上有個(gè)很現(xiàn)實(shí)的問(wèn)題糧庫(kù)測(cè)溫系統(tǒng)的歷史數(shù)據(jù)量、質(zhì)量和記錄連續(xù)性普遍撐不起深度學(xué)習(xí)時(shí)序模型的訓(xùn)練。BP 網(wǎng)絡(luò)把時(shí)間序列問(wèn)題轉(zhuǎn)成靜態(tài)映射只要構(gòu)造好滑動(dòng)窗口就能用成熟穩(wěn)定的訓(xùn)練方式去擬合權(quán)重固定后甚至可以導(dǎo)出為矩陣乘法部署到倉(cāng)庫(kù)的工控機(jī)上毫無(wú)壓力。LSTM 的時(shí)序狀態(tài)在糧庫(kù)這種低采樣頻率、多缺測(cè)的數(shù)據(jù)環(huán)境里優(yōu)勢(shì)未必能發(fā)揮出來(lái)反而讓排查模型出錯(cuò)點(diǎn)變成猜謎。如果哪天業(yè)務(wù)真的需要逐小時(shí)滾動(dòng)更新、在線學(xué)習(xí)再升級(jí)到 GRU 或 LSTM 也不遲第一版用 BP 跑通預(yù)測(cè)流程是更務(wù)實(shí)的起點(diǎn)。3. 從測(cè)溫系統(tǒng)到訓(xùn)練樣本數(shù)據(jù)準(zhǔn)備決定模型上限3.1 導(dǎo)出數(shù)據(jù)整理成位置-時(shí)間-溫度長(zhǎng)表做預(yù)測(cè)模型數(shù)據(jù)準(zhǔn)備占掉整個(gè)工作量的大頭這一點(diǎn)在糧庫(kù)場(chǎng)景里尤其明顯。常見(jiàn)測(cè)溫系統(tǒng)導(dǎo)出的結(jié)果是一張大寬表每一行是一條記錄包含記錄時(shí)間、電纜編號(hào)、電纜內(nèi)的測(cè)點(diǎn)序號(hào)和溫度值配合另一張配置表能查到每根電纜的行列位置和層位。第一步是把這些表關(guān)聯(lián)起來(lái)整理成長(zhǎng)表格式一列時(shí)間一列位置標(biāo)識(shí)一列溫度值。位置標(biāo)識(shí)不需要很精確用層位加行列坐標(biāo)就能讓模型區(qū)分倉(cāng)壁邊的點(diǎn)和糧堆中心的點(diǎn)。3.2 清洗與插值壞值、停測(cè)和通風(fēng)擾動(dòng)測(cè)溫傳感器常年泡在糧堆里壞值是常態(tài)。我見(jiàn)過(guò)某根電纜中層測(cè)點(diǎn)連續(xù)三天輸出 45℃ 的假發(fā)熱如果這種值混進(jìn)訓(xùn)練集模型會(huì)在那個(gè)位置學(xué)到一條根本不存在的升溫規(guī)律。清洗的做法分兩步先用物理范圍初篩糧堆溫度正常情況下不可能低于 -20℃ 或高于 50℃超出直接標(biāo)記為缺失再做橫向?qū)Ρ韧粫r(shí)刻同一層位相鄰測(cè)點(diǎn)的中位數(shù)應(yīng)當(dāng)接近偏離超過(guò) 5℃ 的判為可疑。下面這段是我常用清洗流程的簡(jiǎn)化版。import pandas as pd import numpy as np # 長(zhǎng)表time, cable_id(電纜編號(hào)), layer(層位), temp(溫度) df pd.read_csv(granary_temp.csv, parse_dates[time]) # 1. 物理范圍初篩超出糧堆溫度合理區(qū)間直接置為缺失 df.loc[(df[temp] -20) | (df[temp] 50), temp] np.nan # 2. 橫向?qū)Ρ韧粫r(shí)刻同一層位看中位數(shù)偏離5度以上判為可疑 df[layer_median] df.groupby([time, layer])[temp].transform(median) df.loc[(df[temp] - df[layer_median]).abs() 5, temp] np.nan # 3. 按電纜分組線性插值缺測(cè)兩端用鄰近值補(bǔ)齊 df df.sort_values([cable_id, time]) df[temp] ( df.groupby(cable_id)[temp] .transform(lambda s: s.interpolate(methodlinear, limit_directionboth)) ) # 丟棄整段缺失超過(guò)3天以上的電纜數(shù)據(jù)避免插值造出假曲線 valid_counts df.groupby(cable_id)[temp].apply(lambda s: s.notna().sum()) keep_cables valid_counts[valid_counts 20].index df df[df[cable_id].isin(keep_cables)]這段代碼的邏輯要點(diǎn)先做整體范圍粗篩再做組內(nèi)橫向比對(duì)最后按電纜分組插值。參數(shù)上最值得留意的是橫向?qū)Ρ鹊拈撝?5℃這是經(jīng)驗(yàn)值南方夏季倉(cāng)溫和北方冬季倉(cāng)溫差異很大如果整體溫差本來(lái)就大可以把閾值放寬到 6℃閾值太小會(huì)把正常梯度誤判成壞值閾值太大又漏掉真故障。插值用線性就夠糧溫變化慢局部插值不會(huì)引入太大誤差真正危險(xiǎn)的是連續(xù)缺測(cè)幾天后的憑空拼接所以保留條件設(shè)成至少 20 個(gè)有效記錄寧可少樣本也不要假樣本。3.3 滑動(dòng)窗口構(gòu)造訓(xùn)練樣本特征和標(biāo)簽怎么對(duì)齊清洗完成后要把時(shí)序數(shù)據(jù)變成監(jiān)督學(xué)習(xí)的特征矩陣。常見(jiàn)做法是滑動(dòng)窗口以每個(gè)測(cè)點(diǎn)為單位取它過(guò)去若干天的溫度序列做特征未來(lái)某個(gè)時(shí)刻的溫度做標(biāo)簽。窗口長(zhǎng)度和預(yù)測(cè)步長(zhǎng)是兩個(gè)必須明確的參數(shù)我一般用過(guò)去 7 天每小時(shí) 6 個(gè)采樣點(diǎn)、預(yù)測(cè)未來(lái) 72 小時(shí)。窗口太短學(xué)不到趨勢(shì)慣性窗口太長(zhǎng)則特征冗余模型訓(xùn)練變慢還可能過(guò)擬合。構(gòu)造樣本的代碼如下。features, labels [], [] # 窗口大小7天 * 每天4個(gè)時(shí)刻 28個(gè)特征步 window_steps 28 # 預(yù)測(cè)目標(biāo)未來(lái)72小時(shí)按6小時(shí)一步折算成12步 future_steps 12 for (cable, layer), grp in df.groupby([cable_id, layer]): grp grp.sort_values(time).set_index(time) # 重采樣到6小時(shí)間隔取平均值保證時(shí)刻對(duì)齊 ser grp[temp].resample(6h).mean() values ser.values for i in range(len(values) - window_steps - future_steps): feat values[i : i window_steps] label values[i window_steps future_steps] features.append(feat) labels.append(label) X np.array(features) y np.array(labels) # 丟棄任何包含NaN的樣本保證訓(xùn)練集干凈 valid ~(np.isnan(X).any(axis1) | np.isnan(y)) X, y X[valid], y[valid]這里有個(gè)容易忽視的細(xì)節(jié)重采樣到 6 小時(shí)會(huì)引入 NaN 空檔直接喂給網(wǎng)絡(luò)會(huì)訓(xùn)練失敗所以我統(tǒng)一放在最后用掩碼丟棄。窗口和預(yù)測(cè)步長(zhǎng)的選擇直接決定樣本量一個(gè) 200 測(cè)點(diǎn)的倉(cāng)、90 天歷史數(shù)據(jù)大約能產(chǎn)生 40000 條左右的樣本完全夠一個(gè)小 BP 網(wǎng)絡(luò)訓(xùn)練。如果你想預(yù)測(cè) 24 小時(shí)而不是 72 小時(shí)把future_steps改成 4 就行其余不用動(dòng)。4. 模型搭建與訓(xùn)練平臺(tái)選擇、參數(shù)配置和收斂調(diào)優(yōu)4.1 平臺(tái)選型MATLAB 做驗(yàn)證Python 做部署論文復(fù)現(xiàn)和工程落地往往需要兩套平臺(tái)。復(fù)現(xiàn)這類研究時(shí)MATLAB 神經(jīng)網(wǎng)絡(luò)工具箱里的newff加trainlm是經(jīng)典組合交互直觀trainlm自帶的 Levenberg-Marquardt 算法對(duì)中小樣本收斂很快非常適合快速驗(yàn)證結(jié)構(gòu)和參數(shù)是否合理。但真要把模型接到測(cè)溫系統(tǒng)上做每日預(yù)測(cè)我一般會(huì)換 Python 重寫用 Keras 或 scikit-learn 的 MLPRegressor理由很實(shí)際免費(fèi)生態(tài)、便于自動(dòng)化驗(yàn)證模型導(dǎo)出和服務(wù)器部署都更方便。平臺(tái)選擇可以這樣權(quán)衡場(chǎng)景常用平臺(tái)優(yōu)點(diǎn)短板論文復(fù)現(xiàn)、參數(shù)試驗(yàn)MATLAB 神經(jīng)網(wǎng)絡(luò)工具箱收斂快、交互直觀授權(quán)成本高部署受限工程部署、沉淀系統(tǒng)Python Keras / scikit-learn免費(fèi)、易集成、可回歸參數(shù)需自己摸索訓(xùn)練函數(shù)不如 trainlm 省心先說(shuō)明一點(diǎn)平臺(tái)切換不影響網(wǎng)絡(luò)結(jié)構(gòu)和效果兩次實(shí)現(xiàn)我用同樣的結(jié)構(gòu)參數(shù)得到的結(jié)果基本一致。MATLAB 適合把模型跑通、確認(rèn)思路Python 適合把模型變成 7×24 小時(shí)運(yùn)行的服務(wù)。4.2 網(wǎng)絡(luò)結(jié)構(gòu)與初始化參數(shù)表回到那張 BP 神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)圖落地參數(shù)是這樣的層神經(jīng)元數(shù)激活函數(shù)說(shuō)明輸入層28 至 36無(wú)歷史溫度窗口加位置特征、外部氣溫隱層 116tanh學(xué)習(xí)溫度場(chǎng)非線性組合隱層 28tanh提取更高層抽象特征輸出層1linear輸出未來(lái)溫度回歸任務(wù)不用 sigmoid輸入層寬度對(duì)應(yīng) 3.3 節(jié)的特征設(shè)計(jì)。隱層激活選 tanh 而不是 ReLU是因?yàn)闇囟葦?shù)據(jù)歸一化后分布相對(duì)對(duì)稱tanh 在零附近梯度更穩(wěn)收斂不容易震蕩。輸出層必須是線性激活這是踩過(guò)坑的地方有人把輸出層也套上 sigmoid溫度被壓在 0 到 1 之間反歸一化后稍微超出區(qū)間就變成平臺(tái)值誤差直接爆炸。4.3 訓(xùn)練配置學(xué)習(xí)率、早停和驗(yàn)證集訓(xùn)練配置有三個(gè)關(guān)鍵點(diǎn)。第一樣本劃分不能用隨機(jī)打散必須按時(shí)間先后切分前 70% 做訓(xùn)練集后 15% 做驗(yàn)證集再往后 15% 做測(cè)試集。第二學(xué)習(xí)率從 0.01 起步配合自適應(yīng)優(yōu)化器前幾個(gè) epoch 觀察損失曲線如果震蕩就把學(xué)習(xí)率降一半。第三早停耐心值設(shè)置在 20 個(gè) epoch驗(yàn)證集損失連續(xù)不降就停下來(lái)防止后期過(guò)擬合。下面是 Keras 的完整訓(xùn)練配置。from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Input from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau # 輸入維度由訓(xùn)練樣本特征列數(shù)決定對(duì)應(yīng)結(jié)構(gòu)圖的輸入層寬度 model Sequential([ Input(shape(X_train.shape[1],)), Dense(16, activationtanh), Dense(8, activationtanh), Dense(1, activationlinear), ]) model.compile(optimizeradam, lossmse, metrics[mae]) early_stop EarlyStopping( monitorval_loss, patience20, restore_best_weightsTrue ) reduce_lr ReduceLROnPlateau( monitorval_loss, factor0.5, patience8, min_lr1e-5 ) history model.fit( X_train, y_train, validation_data(X_val, y_val), epochs500, # 上限500實(shí)際由早停決定 batch_size256, callbacks[early_stop, reduce_lr], verbose0, )參數(shù)說(shuō)明patience20表示驗(yàn)證損失連續(xù) 20 個(gè) epoch 不改善就停restore_best_weightsTrue會(huì)在訓(xùn)練結(jié)束后把權(quán)重回滾到驗(yàn)證集最好的那一步相當(dāng)于自動(dòng)保存最佳模型。ReduceLROnPlateau在驗(yàn)證損失停滯 8 個(gè) epoch 后把學(xué)習(xí)率減半避免后期在小范圍內(nèi)來(lái)回震蕩。batch_size256對(duì)幾萬(wàn)條樣本適中太小會(huì)讓梯度更新方向抖動(dòng)太大則內(nèi)存開(kāi)銷高且收斂慢。訓(xùn)練完先用訓(xùn)練集和驗(yàn)證集的誤差差判斷是否過(guò)擬合兩者差距在 15% 以內(nèi)結(jié)構(gòu)基本合理差距過(guò)大就回到結(jié)構(gòu)圖把隱層節(jié)點(diǎn)數(shù)減下來(lái)。5. 溫度場(chǎng)預(yù)測(cè)的避坑指南五個(gè)翻車現(xiàn)場(chǎng)和對(duì)應(yīng)的解法5.1 傳感器壞值混進(jìn)訓(xùn)練集預(yù)測(cè)曲線出現(xiàn)釘子現(xiàn)象某個(gè)測(cè)點(diǎn)的預(yù)測(cè)溫度曲線在持續(xù)平滑段里突然出現(xiàn)一個(gè)尖峰形狀像一根釘子。原因訓(xùn)練數(shù)據(jù)里包含了該傳感器某個(gè)時(shí)段輸出的跳變壞值網(wǎng)絡(luò)為了擬合這個(gè)假點(diǎn)把隱層的一部分權(quán)重專門用在了異常位置導(dǎo)致預(yù)測(cè)在對(duì)應(yīng)時(shí)段跟著學(xué)壞。解決清洗階段做橫向?qū)Ρ扔猛瑢游恢形粩?shù)做基準(zhǔn)偏離過(guò)大一律剔除模型上線后還要持續(xù)做數(shù)據(jù)質(zhì)量監(jiān)控發(fā)現(xiàn)新的壞值要及時(shí)補(bǔ)入清洗流程再重訓(xùn)。5.2 歸一化用全樣本統(tǒng)計(jì)測(cè)試集誤差被嚴(yán)重低估現(xiàn)象訓(xùn)練集驗(yàn)證集誤差都很好可一上真實(shí)業(yè)務(wù)就預(yù)測(cè)偏差明顯增大。原因歸一化時(shí)用全樣本計(jì)算最小值和最大值測(cè)試集的信息提前泄漏給了訓(xùn)練過(guò)程更隱蔽的是夏季訓(xùn)練的數(shù)據(jù)范圍窄冬季氣溫變成零下時(shí)新數(shù)據(jù)落到訓(xùn)練集范圍之外反歸一化后預(yù)測(cè)值被截?cái)嘣谶吔?。解決只用訓(xùn)練集統(tǒng)計(jì) min 和 max保存這兩個(gè)數(shù)預(yù)測(cè)新數(shù)據(jù)時(shí)沿用每個(gè)季度重訓(xùn)時(shí)重新統(tǒng)計(jì)范圍給模型的歸一化參數(shù)留出隨季節(jié)變化的余量。5.3 隱層節(jié)點(diǎn)堆過(guò)頭訓(xùn)練誤差降到零點(diǎn)幾測(cè)試誤差卻失控現(xiàn)象訓(xùn)練集 RMSE 一路降到 0.2℃驗(yàn)證集卻在 50 個(gè) epoch 后開(kāi)始回升測(cè)試集誤差達(dá)到 1.5℃。原因隱層節(jié)點(diǎn)太多網(wǎng)絡(luò)把訓(xùn)練集的噪聲也背下來(lái)了這是過(guò)擬合的典型表現(xiàn)。解決從 8 個(gè)節(jié)點(diǎn)開(kāi)始逐步加寬每加一次記錄驗(yàn)證集誤差找到驗(yàn)證誤差開(kāi)始回升的拐點(diǎn)訓(xùn)練時(shí)開(kāi) L2 正則把 alpha 設(shè)在 0.001 量級(jí)。記住平房倉(cāng)溫度場(chǎng)本身變化平緩模型參數(shù)越少泛化反而越好。5.4 用遞歸方式做 7 天預(yù)測(cè)誤差像雪球一樣滾大現(xiàn)象預(yù)測(cè)未來(lái) 24 小時(shí)誤差還行一預(yù)測(cè)第 5、第 7 天偏差大到不可用。原因有人把模型設(shè)計(jì)成滾動(dòng)預(yù)測(cè)第一次用歷史窗口預(yù)測(cè)出 6 小時(shí)后的溫度再把預(yù)測(cè)值塞回輸入當(dāng)作歷史繼續(xù)預(yù)測(cè)下一個(gè) 6 小時(shí)。每一步的誤差都會(huì)累積到第 7 天誤差已經(jīng)滾成好幾攝氏度。解決把預(yù)測(cè)目標(biāo)改成未來(lái) 72 小時(shí)后的溫度的直接映射也就是說(shuō)訓(xùn)練時(shí)標(biāo)簽就是 72 小時(shí)后的實(shí)測(cè)值模型一步到位不做多步遞歸如果業(yè)務(wù)要求多個(gè)預(yù)報(bào)時(shí)刻就為每個(gè)預(yù)報(bào)時(shí)刻單獨(dú)訓(xùn)練一個(gè)模型互相獨(dú)立、互不傳染誤差。5.5 只看整體 RMSE 好看熱點(diǎn)位置的漏報(bào)全被平均掉現(xiàn)象全倉(cāng)預(yù)測(cè) RMSE 只有 0.6℃挺漂亮但東北角第六根電纜中層的實(shí)測(cè)溫度已經(jīng)逼近預(yù)警線模型預(yù)測(cè)卻低了 2℃ 多。原因RMSE 是一個(gè)平均值大量正常測(cè)點(diǎn)的誤差把少數(shù)熱點(diǎn)的誤差稀釋了模型的平均表現(xiàn)掩蓋了局部失準(zhǔn)。解決評(píng)估指標(biāo)加一個(gè)逐測(cè)點(diǎn)最大誤差也就是每個(gè)測(cè)點(diǎn)分別統(tǒng)計(jì)預(yù)測(cè)誤差的最大值用這個(gè)值去卡預(yù)警閾值糧庫(kù)管理最關(guān)心的不是全倉(cāng)平均準(zhǔn)而是別漏掉任何一個(gè)可能發(fā)熱的局部點(diǎn)位。6. 驗(yàn)證模型值不值得上線時(shí)序交叉驗(yàn)證、基線對(duì)比和逐點(diǎn)誤差6.1 時(shí)序交叉驗(yàn)證隨機(jī)打散是最大的偽命題很多人剛接觸機(jī)器學(xué)習(xí)時(shí)習(xí)慣把數(shù)據(jù)集隨機(jī)分成訓(xùn)練和測(cè)試但在溫度預(yù)測(cè)這個(gè)任務(wù)里隨機(jī)打散會(huì)讓訓(xùn)練集里混入測(cè)試時(shí)間之后的樣本等于偷看了未來(lái)測(cè)試誤差虛假好看。正確做法是嚴(yán)格按時(shí)間切用 sklearn 的 TimeSeriesSplit 做順序交叉驗(yàn)證。from sklearn.model_selection import TimeSeriesSplit tscv TimeSeriesSplit(n_splits5) for train_idx, test_idx in tscv.split(X): X_train, X_test X[train_idx], X[test_idx] y_train, y_test y[train_idx], y[test_idx] # 每次劃分都保證訓(xùn)練數(shù)據(jù)全部早于測(cè)試數(shù)據(jù) model.fit(X_train, y_train) score model.evaluate(X_test, y_test, verbose0)這段代碼的意義在于模擬上線后的真實(shí)環(huán)境模型永遠(yuǎn)只能看到過(guò)去不能看到未來(lái)。糧庫(kù)業(yè)務(wù)每天新增一批數(shù)據(jù)模型在舊數(shù)據(jù)上訓(xùn)練、在新數(shù)據(jù)上預(yù)測(cè)TimeSeriesSplit 的每一次切分都對(duì)應(yīng)一次模擬上線跑完 5 次如果誤差波動(dòng)不大模型才有上線價(jià)值。6.2 與昨天等于今天比BP 贏多少才值得上線基線對(duì)比是判斷模型價(jià)值的硬標(biāo)準(zhǔn)。溫度場(chǎng)的自相關(guān)很強(qiáng)所以最簡(jiǎn)單的基線就是持久性預(yù)測(cè)用當(dāng)前時(shí)刻的溫度當(dāng)作未來(lái)溫度也就是說(shuō)今天多少度明天就多少度。如果 BP 模型的 RMSE 比這個(gè)基線改進(jìn)不到 15%先別急著上線回頭看數(shù)據(jù)清洗和特征設(shè)計(jì)哪里出了問(wèn)題。我自己的經(jīng)驗(yàn)是次日最高糧溫預(yù)測(cè)的 RMSE 能做到 0.8℃ 上下MAE 在 0.6℃ 左右72 小時(shí)預(yù)測(cè)的 MAE 放寬到 1.5℃ 以內(nèi)也可以接受。這個(gè)精度給保管員當(dāng)明天重點(diǎn)盯哪一排的參考是夠用的但如果要拿它做超溫報(bào)警觸發(fā)誤差還得再壓到 0.5℃ 以下。6.3 逐點(diǎn)誤差與殘差找出模型學(xué)不到的規(guī)律除了整體指標(biāo)我習(xí)慣把每個(gè)測(cè)點(diǎn)的殘差畫出來(lái)也就是實(shí)際溫度減預(yù)測(cè)溫度序列。殘差如果隨機(jī)散布在零附近說(shuō)明模型已經(jīng)學(xué)干凈了剩下的誤差是溫度場(chǎng)本身隨機(jī)波動(dòng)造成的殘差如果呈現(xiàn)出明顯的季節(jié)趨勢(shì)或通風(fēng)前后系統(tǒng)性偏大說(shuō)明模型漏掉了一個(gè)重要輸入。這時(shí)候回去把通風(fēng)記錄加進(jìn)特征或者把通風(fēng)時(shí)段單獨(dú)建模往往比盲目加深網(wǎng)絡(luò)更有效。我吃過(guò)一次虧當(dāng)時(shí)只看整體 RMSE 就上了線結(jié)果東北角局部熱點(diǎn)連續(xù)兩天被低估市里抽查差點(diǎn)出問(wèn)題。后來(lái)的教訓(xùn)是評(píng)估指標(biāo)必須和報(bào)警業(yè)務(wù)指標(biāo)保持一致逐點(diǎn)最大誤差才是這條線的生命線。希望幫到你祝這套預(yù)測(cè)模型少翻車、多省心。本文還有配套的精品資源點(diǎn)擊獲取