網(wǎng)絡的自適應PID控制算法:原理、實現(xiàn)與工程落地)
簡介這份PDF文檔面向自動化、控制工程與人工智能方向的學習者和研究人員聚焦非線性系統(tǒng)難以用線性模型精確描述這一核心難題提出將DRNN神經(jīng)網(wǎng)絡與自適應控制相結(jié)合的算法思路。文檔系統(tǒng)梳理了非線性系統(tǒng)控制面臨的挑戰(zhàn)、DRNN神經(jīng)網(wǎng)絡在信息處理與非線性辨識上的優(yōu)勢并給出其輸入層、隱含層、輸出層三層回歸結(jié)構(gòu)及權(quán)值更新推導進而闡述基于該網(wǎng)絡的自適應PID控制算法如何完成系統(tǒng)辨識與參數(shù)整定仿真結(jié)果顯示其過渡過程短、魯棒性強、泛化能力良好可應用于機器人控制、過程控制、自動駕駛與智能家居等場景。資源包為1個PDF文件大小約1.14MB內(nèi)容完整、公式與結(jié)構(gòu)圖齊全便于直接閱讀與引用。目前已有129人學習下載適合希望深入理解神經(jīng)網(wǎng)絡自適應控制建模與仿真細節(jié)的讀者參考。1. 被控對象一非線性普通 PID 就開始“玄學抖動”了做過程控制或者運動控制的同行大概率都遇到過這種場景被控對象里帶點死區(qū)、飽和、摩擦或者時變參數(shù)用一組固定 PID 參數(shù)調(diào)得挺好工況一變超調(diào)直接飆上去穩(wěn)態(tài)誤差怎么都壓不下來。這時候很多人第一反應是重新整定 PID但整定完發(fā)現(xiàn)只是把震蕩點從一個工況挪到了另一個工況。根本原因在于線性 PID 的增益是定值而非線性系統(tǒng)的動態(tài)特性隨工作點漂移一套固定參數(shù)不可能在全工況下都最優(yōu)。這份《一種基于 DRNN 神經(jīng)網(wǎng)絡的自適應控制算法》給出的思路就是用對角回歸神經(jīng)網(wǎng)絡DRNN在線辨識被控對象的非線性動態(tài)再讓網(wǎng)絡輸出實時修正 PID 的三個增益。它解決的不是“PID 怎么調(diào)”的問題而是“PID 參數(shù)能不能自己跟著工況走”的問題。適合已經(jīng)懂 PID 基本結(jié)構(gòu)、想往自適應控制方向落地的工程師也適合做機器人關(guān)節(jié)控制、電機調(diào)速、溫度過程控制這類非線性明顯場景的從業(yè)者。下面我按“網(wǎng)絡結(jié)構(gòu)怎么理解 → 辨識器怎么搭 → 控制器怎么整定 → 仿真怎么復現(xiàn) → 坑在哪”的順序拆一遍。2. DRNN 網(wǎng)絡結(jié)構(gòu)與系統(tǒng)辨識回歸層到底回歸了什么2.1 為什么選 DRNN 而不是 BP 或普通 RNN普通 BP 網(wǎng)絡是靜態(tài)映射輸入到輸出沒有記憶處理帶慣性的非線性系統(tǒng)時辨識器本身就需要額外引入延遲輸入來構(gòu)造動態(tài)。而 DRNN 在隱含層加了回歸支路隱含層第 j 個神經(jīng)元在當前時刻的輸入總和里包含了自己上一時刻的輸出乘以一個回歸權(quán)值。這個結(jié)構(gòu)讓網(wǎng)絡天然具備對動態(tài)系統(tǒng)的記憶能力不需要在外層手動堆一堆延遲線。和標準 Elman 網(wǎng)絡相比DRNN 的“對角”體現(xiàn)在回歸權(quán)值矩陣是對角陣也就是每個回歸神經(jīng)元只把自己的上一時刻輸出回饋給自己不交叉回饋。這樣做的好處是參數(shù)量少、在線計算量小適合放在采樣周期比較短的控制回路里跑。常見做法是隱含層取 5 到 9 個回歸神經(jīng)元輸入層取被控對象的當前輸入和當前輸出輸出層就是辨識出的系統(tǒng)輸出。2.2 辨識器的前向計算與權(quán)值更新辨識器的輸入是系統(tǒng)實際輸入 u(k) 和實際輸出 y(k)輸出是網(wǎng)絡預測的 ym(k)。誤差 em(k) y(k) - ym(k)指標函數(shù)取二分之一誤差平方。權(quán)值更新用梯度下降回歸層、輸入層、輸出層三組權(quán)值分別沿各自偏導方向修正。下面這段 Python 把前向和更新寫清楚可以直接對照論文里的公式復現(xiàn)。import numpy as np class DRNNIdentifier: def __init__(self, n_input2, n_hidden7, lr0.05): # 輸入層權(quán)值 W1: (n_hidden, n_input) self.W1 np.random.randn(n_hidden, n_input) * 0.1 # 回歸層權(quán)值 Wr: (n_hidden,) 對角回歸每個神經(jīng)元只回饋自己 self.Wr np.random.randn(n_hidden) * 0.1 # 輸出層權(quán)值 Wo: (1, n_hidden) self.Wo np.random.randn(1, n_hidden) * 0.1 self.lr lr self.X np.zeros(n_hidden) # 隱含層當前輸出 self.X_prev np.zeros(n_hidden) # 隱含層上一時刻輸出 def forward(self, u): # u: 當前時刻輸入向量 [u(k), y(k)] S self.W1 u self.Wr * self.X_prev # 隱含層輸入總和 self.X np.tanh(S) # S 函數(shù)激活 ym self.Wo self.X # 網(wǎng)絡輸出 return ym def update(self, u, y, ym): em y - ym # 輸出層權(quán)值更新 dWo em * self.X # 隱含層誤差反傳tanh 導數(shù) 1 - X^2 dS (em * self.Wo) * (1 - self.X ** 2) dW1 np.outer(dS, u) dWr dS * self.X_prev # 梯度下降更新 self.Wo self.lr * dWo self.W1 self.lr * dW1 self.Wr self.lr * dWr self.X_prev self.X.copy() return em邏輯說明forward里S W1 u Wr * X_prev對應論文中隱含層輸入總和公式回歸項只乘自己上一時刻輸出這就是對角回歸的含義。update里先算輸出層梯度再把誤差按Wo反傳到隱含層乘 tanh 導數(shù)得到dS最后分別更新三組權(quán)值。參數(shù)方面lr是學習率辨識階段一般取 0.02 到 0.1太大權(quán)值震蕩太小收斂慢n_hidden取 5 到 9神經(jīng)元太少辨識精度不夠太多在線計算吃緊。X_prev必須在每次更新后同步否則回歸支路就斷了。2.3 辨識器的輸入輸出配對與采樣周期辨識器要能工作輸入向量必須同時包含被控對象的控制量和輸出量。常見做法是u [u(k), y(k)]網(wǎng)絡輸出ym(k)逼近y(k)。采樣周期 T 要和被控對象的主導時間常數(shù)匹配一般取主導時間常數(shù)的十分之一到二十分之一。T 太大回歸支路記憶的信息跨了好幾個動態(tài)過程辨識發(fā)散T 太小相鄰采樣點差異微弱梯度信號被噪聲淹沒。仿真里如果被控對象是連續(xù)模型記得先用零階保持器離散化再喂給辨識器。3. 自適應 PID 控制器三個增益怎么被網(wǎng)絡在線整定3.1 控制器結(jié)構(gòu)與誤差構(gòu)造論文里的控制器用兩個神經(jīng)網(wǎng)絡 NN1 和 NN2 分別整定兩路 PID 參數(shù)單路控制器的輸出是三個增益乘以三個誤差分量之和。三個誤差分量分別是當前誤差 e(k)、誤差累積、誤差差分。這里有個容易翻車的點誤差差分項要除以采樣時間 T如果 T 取得很小差分項會放大噪聲實際工程里通常再加一個一階低通濾波。class AdaptivePID: def __init__(self, kp01.0, ki00.1, kd00.05, lr0.02, T0.01): self.kp, self.ki, self.kd kp0, ki0, kd0 self.lr lr self.T T self.e_prev 0.0 self.e_sum 0.0 def control(self, r, y): e r - y self.e_sum e * self.T de (e - self.e_prev) / self.T # 三個誤差分量 x1, x2, x3 e, self.e_sum, de u self.kp * x1 self.ki * x2 self.kd * x3 # 增益在線修正梯度方向為誤差對增益的敏感度 self.kp self.lr * e * x1 self.ki self.lr * e * x2 self.kd self.lr * e * x3 self.e_prev e return u, (x1, x2, x3)邏輯說明control里先算三個誤差分量再合成控制量 u。增益修正項lr * e * x對應論文中增益沿誤差平方負梯度方向調(diào)整的思路誤差為正且分量也為正時增益增大加快響應。參數(shù)上lr是增益學習率一般比辨識器學習率小一個量級取 0.005 到 0.02太大增益會來回跳。T必須和辨識器采樣周期一致否則誤差差分和累積都對不上。初始增益可以先用一組手動整定的 PID 參數(shù)讓網(wǎng)絡從小范圍修正開始比從零起步穩(wěn)得多。3.2 辨識器與控制器的耦合關(guān)系辨識器和控制器不是各跑各的。辨識器輸出的系統(tǒng)雅可比信息也就是被控對象輸出對控制量的偏導會通過鏈式法則影響控制器增益的修正方向。論文里用 DRNN 的輸出對輸入的偏導來近似這個雅可比。實際實現(xiàn)時如果辨識器還沒收斂雅可比估計不準控制器增益修正就會亂走。常見做法是前若干百個采樣步只訓練辨識器凍結(jié)控制器增益等辨識誤差降到閾值以下再放開控制器在線修正。這個“先辨識后控制”的啟動順序是整套算法能不能穩(wěn)的關(guān)鍵。3.3 仿真被控對象與參數(shù)設置論文給的被控對象是一個二階非線性狀態(tài)方程狀態(tài)變量 x1、x2未知參數(shù) a110.3、a120.7、a21-5.3、a22 等。復現(xiàn)時用四階龍格庫塔離散化采樣周期取 0.01 秒仿真時長 10 秒左右就能看到收斂過程。下面是被控對象和主循環(huán)的骨架。def plant(x1, x2, u): a11, a12, a21, a22 0.3, 0.7, -5.3, -0.5 dx1 a11 * x1 a12 * x2 dx2 a21 * x1 a22 * x2 u return dx1, dx2 # 主循環(huán)骨架 ident DRNNIdentifier(n_input2, n_hidden7, lr0.05) pid AdaptivePID(kp01.0, ki00.1, kd00.05, lr0.01, T0.01) x1, x2 0.5, 0.0 for k in range(1000): r 1.0 # 階躍指令 u, _ pid.control(r, x1) dx1, dx2 plant(x1, x2, u) x1 dx1 * 0.01 x2 dx2 * 0.01 ym ident.forward(np.array([u, x1])) ident.update(np.array([u, x1]), x1, ym)邏輯說明plant是被控對象連續(xù)方程主循環(huán)里用歐拉法以 0.01 秒步長推進。辨識器輸入取[u, x1]輸出逼近 x1。參數(shù)上初始狀態(tài) x10.5、x20 是為了讓系統(tǒng)從非零初值收斂到指令值方便觀察過渡過程。仿真步數(shù) 1000 對應 10 秒足夠看到誤差收斂和增益穩(wěn)定。如果換成四階龍格庫塔把x1 dx1 * 0.01換成 RK4 更新即可精度更高但代碼略長。4. 復現(xiàn)時最容易翻車的幾個地方4.1 辨識器發(fā)散誤差越跑越大現(xiàn)象辨識誤差 em(k) 不收斂幾十步后直接沖到很大值。原因通常是學習率過大或者輸入向量沒有做歸一化被控對象輸出量綱遠大于控制量導致權(quán)值更新步長在某個方向上過大。解決先把學習率降到 0.01 量級再對輸入做歸一化讓 u 和 y 都落在 -1 到 1 之間網(wǎng)絡輸出再反歸一化回物理量。4.2 控制器增益來回震蕩不收斂現(xiàn)象kp、ki、kd 三個曲線在仿真圖里高頻抖動控制量也跟著抖。原因一般是控制器學習率相對辨識器學習率偏大或者辨識器還沒收斂就放開了控制器修正。解決控制器學習率取辨識器的五分之一到十分之一并且加一個啟動凍結(jié)期前 200 到 500 步只訓練辨識器辨識誤差小于 0.01 后再放開增益修正。4.3 誤差差分項把噪聲放大現(xiàn)象控制量里出現(xiàn)明顯的高頻毛刺執(zhí)行機構(gòu)跟著響。原因誤差差分 de (e - e_prev)/TT 很小時差分對測量噪聲極其敏感。解決在差分項后面串一個一階低通濾波濾波時間常數(shù)取 3 到 5 個采樣周期或者直接用不完全微分結(jié)構(gòu)把微分項乘一個小于 1 的濾波系數(shù)。4.4 采樣周期和對象時間常數(shù)不匹配現(xiàn)象辨識器怎么調(diào)都不收斂或者收斂后一換工況就崩。原因采樣周期 T 相對被控對象主導時間常數(shù)太大或太小。解決先測被控對象的階躍響應找到上升到 63% 的時間作為主導時間常數(shù)T 取它的十分之一到二十分之一。仿真里如果對象是連續(xù)模型務必先離散化再進循環(huán)不要混著連續(xù)和離散算。4.5 初始增益全設為零導致啟動死區(qū)現(xiàn)象仿真一開始控制量一直是零系統(tǒng)不動網(wǎng)絡也沒法從零誤差里學到東西。原因PID 初始增益設為零控制量為零被控對象沒有激勵辨識器輸入全是零梯度為零。解決初始增益用一組手動整定的值哪怕粗糙也行保證系統(tǒng)有初始激勵。常見做法是先跑一段開環(huán)或者固定 PID采集數(shù)據(jù)預訓練辨識器再切到自適應模式。5. 從仿真到落地驗證收斂性和魯棒性的幾個硬指標仿真跑通只是第一步判斷這套算法到底能不能用我一般盯四個指標。第一是辨識誤差的穩(wěn)態(tài)值收斂后 em 的絕對值應該小于被控對象輸出量程的 2%否則辨識器精度不夠后面增益修正就是建在沙子上。第二是增益收斂時間從放開控制器修正到三個增益波動小于 5%一般希望在 1 到 3 秒內(nèi)完成太慢說明學習率偏小或者網(wǎng)絡容量不夠。第三是階躍響應的超調(diào)量和調(diào)節(jié)時間和手動整定的最優(yōu) PID 比超調(diào)不應更差調(diào)節(jié)時間應縮短至少 20%。第四是魯棒性測試把被控對象參數(shù)改 20% 到 30%看增益能不能重新收斂、響應能不能恢復這一條最能區(qū)分“真自適應”和“仿真里碰巧調(diào)通”。驗證魯棒性時我習慣做一個參數(shù)攝動掃描表把關(guān)鍵參數(shù)按比例改記錄每次的調(diào)節(jié)時間和超調(diào)。下面這個表是我復現(xiàn)時用的記錄格式可以直接套。攝動項變化幅度調(diào)節(jié)時間(s)超調(diào)量(%)增益是否重新收斂a21-20%1.86.2是a2120%2.18.5是a12-30%2.411.0是a1230%2.613.4邊界收斂加輸出噪聲5% 量程2.29.1是從表里能看出參數(shù)往使系統(tǒng)阻尼變小的方向攝動時超調(diào)會明顯上升增益收斂也變慢。如果某個攝動下增益不收斂優(yōu)先查辨識器輸入歸一化有沒有跟著參數(shù)變化失效再查學習率是不是需要按攝動幅度自適應縮小。還有一個容易被忽略的點這套算法在線計算量集中在辨識器前向和反傳隱含層 7 個神經(jīng)元時單步計算量很小但如果你把采樣周期壓到 1 毫秒以下普通 MCU 可能跑不動。落地前先估算單步浮點運算次數(shù)留出至少 50% 的 CPU 余量否則控制回路會被計算拖垮。我自己的習慣是每次把這類自適應算法往真實控制器上搬之前先在仿真里把采樣周期、學習率、網(wǎng)絡規(guī)模三組參數(shù)各掃一遍找到收斂邊界再按邊界往保守方向退兩檔。從那以后凡是帶在線學習的控制算法我都強制先跑一遍參數(shù)攝動掃描確認收斂域覆蓋實際工況才敢往硬件上燒。希望幫到你。本文還有配套的精品資源點擊獲取