
1. 卷積不只是神經網絡里的那個框框聊到卷積很多做控制、做嵌入式、做工業自動化的人第一反應是那不是搞深度學習的人天天掛在嘴邊的玩意兒嗎。我最早其實也是這么認為的直到在一家做運動控制系統的公司調試伺服驅動器被電流環噪聲逼得沒辦法才真正開始系統看卷積。那年我花了兩周時間把一個困擾了很久的高頻振蕩問題最終歸結為一句話系統的輸出不是獨立于輸入的而是系統對歷史輸入的一種加權記憶。這句話繞來繞去其實說的就是卷積。搞清楚這件事之后我才意識到卷積在數字控制里的地位遠比大多數人以為的重要得多。它不是一個只有AI工程師才需要理解的數學操作也不是信號處理課本里一個需要背下來的積分公式。它本質上描述了一個非常樸素的物理事實任何一個線性時不變系統在當前時刻的輸出都是它對過去所有輸入的記憶的疊加。而這個記憶的具體權重就是系統的脈沖響應——也就是你在輸入端打一個非常短的脈沖系統會如何記住它、如何回放它。這篇內容沒有任何AI相關的模型推理不聊圖像識別也不聊特征圖。我打算把純物理意義上的卷積掰開揉碎再把數字控制里的采樣、濾波、PID、前饋、觀測器這些高頻場景逐一映射上去。我想用一種比較適合工程師的方式來寫不是給數學系同學看的證明推導而是給每天要跟波形、跟時序打交道的人看的實操總結。讀了之后你能直接看懂一個FIR濾波器為什么就是一個離散卷積一個PID控制器為什么也能被寫成一個殘缺版的卷積核。2. 卷積的三種理解視角2.1 加權疊加從每筆賬都要翻歷史說起你可以把任何一個線性離散系統想象成一家很嚴謹的記賬公司。每一時刻進入系統的輸入信號并不是用完就消失了而是會被系統記錄在案并且按照一定的規則在未來的多個時刻持續產生影響。比如你在 t0 時刻給系統一個大小為 x[0] 的輸入那么它在 t0 時刻產生的影響是 h[0] 乘以 x[0]在 t1 時刻產生的影響是 h[1] 乘以 x[0]在 t2 時刻產生的影響是 h[2] 乘以 x[0]。這里的 h[k] 就是這個系統的記憶曲線學名叫脈沖響應。如果這個系統是時不變的那么同一筆輸入在不同時刻進入系統被記住的方式完全一樣只是產生影響的起點不同。假設系統在第0時刻接收到輸入 x[0]在第1時刻接收到 x[1]那么在第 n 時刻系統的總輸出就是所有歷史輸入在第 n 時刻產生的殘余影響的疊加y[n] x[0]·h[n] x[1]·h[n-1] ... x[n]·h[0]寫成通式就是那個經典的離散卷積和y[n] Σ x[k]·h[n-k]這是理解卷積的第一層也是最貼近物理直覺的一層。我覺得很多人對卷積公式感到害怕是因為教材上來就丟出這個翻轉版的求和公式卻沒說清楚為什么要把 h[n-k] 寫成反著走的樣子。其實你換到記賬視角就很好理解第 k 時刻的那筆輸入 x[k]到了第 n 時刻它已經被系統記了 n-k 個周期所以它對應的權重應該是 h[n-k]也就是脈沖響應在賬齡為 n-k 時的值。卷積里的翻轉本質上是把脈沖響應的坐標軸反過來從事件發生后經過的時間變成從當前時刻回看事件發生的時刻。2.2 疊加積分連續世界的極限記賬上面說的是離散采樣的情況。如果信號是連續的比如模擬電路里的電壓、電流、力、溫度那就要把逐筆記賬升級為無限多筆記賬。連續時間卷積的定義是y(t) ∫ x(τ)·h(t-τ) dτ這其實就是把求和變成了積分把每一筆輸入換成了每一個瞬間的輸入。在連續域里脈沖響應 h(t) 描述的是系統在受到一個狄拉克脈沖之后的自然衰減過程。任何輸入信號都可以看作是無窮多個、幅度分別為 x(τ)dτ 的微脈沖拼接而成的系統對每個微脈沖做出同樣的記憶衰減反應最后在 t 時刻把它們全部疊加起來。我最早做模擬調理電路的時候不太理解為什么運放電路的階躍響應能跟RC時間常數掛鉤。后來才明白一個一階RC低通濾波器的脈沖響應是 h(t) (1/RC)·e^(-t/RC)它的卷積運算就是在對輸入的歷史做指數衰減的加權平均。這個加權平均的窗口長度、遺忘速度完全由 RC 決定。這讓卷積的物理意義變得非常具體它不神秘它就是一個帶遺忘機制的加權歷史累加器。2.3 頻域相乘卷積在傅里葉變換下的偷懶辦法第三層視角也就是最實用的工程視角時域里做卷積等價于頻域里做乘法。也就是說如果你對輸入信號和脈沖響應分別做傅里葉變換把它們的頻譜相乘再做逆變換得到的結果和直接在時域做卷積完全一樣。這一性質被稱為卷積定理。可能有人會覺得這是多此一舉但實際工程里頻域視角能幫助你迅速判斷這個系統對哪些頻率敏感、對哪些頻率衰減。比如你設計一個二階低通濾波器你在時域里看到的是它的脈沖響應在振蕩衰減但在頻域里你一眼就能看出它的截止頻率在哪個位置、阻尼比多大、高頻衰減斜率是-40dB/dec。控制系統的分析與校正很大程度上依賴的就是這個切換視角的能力。頻域相乘告訴我們一個系統的頻率特性就是它對不同頻率輸入信號的放大倍數和相位移動。而這恰恰是經典控制理論里波特圖的核心思想。3. 數字控制場景中的卷積映射3.1 PID控制器你天天在用的最簡卷積核如果你看PID控制器的離散表達式u[n] Kp·e[n] Ki·Σ e[i]·Ts Kd·(e[n] - e[n-1]) / Ts從卷積的角度看它的每一項都是一種有限長度的卷積操作。比例項只看當前時刻的誤差相當于卷積核只在第0個位置上有值其他位置全為0。積分項是對從開始到當前時刻的全部誤差做等權重的累加相當于卷積核是一個從0時刻到當前時刻的所有位置上系數都為 Ki·Ts 的均勻柱狀窗口。微分項則是取當前誤差與上一時刻誤差的差分相當于卷積核的兩個非零系數分別是 Kd/Ts 和 -Kd/Ts位于當前位置和前一個位置。這個視角有意思在哪它告訴你PID本質上是一個極其簡單的三抽頭或者長條積分核的濾波器它沒有能力區分最近的誤差和很久以前的誤差在質量上的差別。積分項把所有歷史誤差一視同仁所以會出現積分飽和微分項只放大了相鄰兩個采樣周期的差值所以對測量噪聲極度敏感。想明白了這一點你再去理解抗積分飽和、微分先行、不完全微分這些PID變體就順理成章了。抗積分飽和的本質就是改變積分項那個均勻卷積核的結構讓它在誤差很大時不再無腦累加不完全微分則是給純微分項串了一個一階低通實質上就是把那個兩抽頭卷積核拉長成了一個衰減更慢的脈沖響應。3.2 數字濾波器控制回路里的標準卷積操作你可能沒意識到但你每次在控制環里加一個低通濾波器、一個陷波器、一個移動平均你都在做離散卷積。就拿工業伺服里最常見的二階巴特沃斯低通濾波器來說y[n] b0·x[n] b1·x[n-1] b2·x[n-2] - a1·y[n-1] - a2·y[n-2]這個式子從結構上看跟卷積公式非常接近。前一項是輸入信號在當前和過去兩個時刻的加權和后一項是輸出信號自身的歷史反饋。這個叫IIR濾波器因為輸出不僅依賴輸入還依賴過去的輸出所以它的脈沖響應是無限長的。而FIR濾波器則更純粹它的輸出只是輸入的有限長度加權和不帶輸出反饋脈沖響應本身就只有有限個非零點。我實際工作中最常用的是移動平均濾波和二階陷波器。移動平均本質上是一個矩形窗卷積y[n] (1/N)·(x[n] x[n-1] ... x[n-N1])它的幅頻響應是存在旁瓣的也就是說它對高頻噪聲的衰減并不是平滑的在某些頻率會有漏網之魚同時在通帶內也有衰減和相位滯后。很多人只知道移動平均能平滑波形但不知道為什么平滑后的波形會比原始信號慢半拍。答案就在卷積里矩形窗卷積的群延遲是 (N-1)/2 個采樣周期。你把N設得越大噪聲衰減越強但信號延遲也越大反饋環路的相位裕度就損失得越多。3.3 系統響應計算傳遞函數的時域原貌數字控制里我們描述被控對象常用Z傳遞函數 G(z)。比如一個典型的一階慣性環節加上零階保持器離散化后是G(z) K·(1 - e^(-T/τ)) / (z - e^(-T/τ))這個傳遞函數對應的時域行為完全可以用卷積來計算。對于一個任意的輸入序列 u[n]系統輸出 y[n] 就是 u[n] 與系統脈沖響應 g[n] 的卷積。脈沖響應 g[n] 可以由傳遞函數做Z反變換求得也可以直接在仿真軟件里對單位脈沖輸入進行仿真得到。有了 g[n]你可以用卷積算出任意輸入下的系統響應不需要反復做Z變換也不需要解差分方程。這一點在做控制參數調整前的預演時特別有用。比如我想知道一個經過整定的PID控制器在給定目標速度曲線下實際的位置跟蹤效果是什么樣的。傳統做法是搭Simulink模型或者在代碼里跑一段時間仿真。但如果你把整個閉環回路的閉環脈沖響應求出來那么目標曲線一次卷積就能得到輸出位置曲線時間復雜度極低非常適合在嵌入式平臺上做實時的軌跡預演。這種方法我印象中在一些高精度運動控制芯片里確實有類似的應用本質就是查表卷積。3.4 狀態觀測器與前饋補償中的卷積視角狀態觀測器尤其是龍伯格觀測器它做的事情是利用控制輸入 u[k] 和測量輸出 y[k] 的歷史數據重構出系統的內部狀態。重構的過程本質上是在運行一個與被控對象模型相同的仿真器然后不停地用輸出誤差做修正。這個修正量從卷積的視角看就是誤差信號 e[k] y[k] - ?[k] 與一個校正增益序列的卷積。觀測器的極點配置決定的就是這個校正卷積核的形狀。而前饋補償就更明顯了。如果你想讓系統完美跟蹤一條軌跡你希望控制輸入是目標軌跡經過被控對象逆模型的輸出。逆模型的核心就是利用已知的脈沖響應去反卷出需要的輸入。在實際工程里完全反卷通常不穩定因為系統的零點會變成逆模型的極點所以更常用的方案是近似逆超前校正預先設計一個有限長度的卷積核FIR讓目標軌跡與這個卷積核卷積得到的輸出能最大程度抵消被控對象的動態滯后。這就是前饋控制在時域里的全部秘密。4. 從卷積到控制一次完整的手算實操4.1 一個被控對象的脈沖響應為了讓上面的內容落下來我決定用一個簡單的實際例子完整走一遍。假設被控對象是一個直流電機的速度環簡化模型從PWM占空比到轉速的連續傳遞函數為G(s) 10 / (0.1s 1)也就是說這是一個增益為10、時間常數為0.1秒的一階慣性系統。控制器采樣周期取 Ts 0.02秒。加上零階保持器后離散化先求脈沖傳遞函數G(z) K·(1 - e^(-Ts/τ)) / (z - e^(-Ts/τ))這里 K10τ0.1Ts0.02所以e^(-Ts/τ) e^(-0.2) ≈ 0.8187 K·(1 - e^(-0.2)) 10 × (1 - 0.8187) 1.813所以G(z) 1.813 / (z - 0.8187)把這個傳遞函數轉換成脈沖響應 h[n]可以這樣想對系統輸入一個單位脈沖即 u[0]1u[1]0u[2]0……由差分方程 y[n] - 0.8187·y[n-1] 1.813·u[n-1]可以推得y[0]0 y[1]1.813 y[2]0.8187×1.813 ≈ 1.485 y[3]0.8187×1.485 ≈ 1.216 y[4]0.8187×1.216 ≈ 0.996也就是說脈沖響應是一個從1.813開始、以0.8187為公比逐漸衰減的等比數列。這個衰減速度對應的就是時間常數0.1秒。有了這個 h[n]我就能用卷積預測任意輸入下的輸出。4.2 用卷積手算階躍響應如果我們給系統一個幅度為5的階躍輸入即 u[0]5u[1]5u[2]5……那么輸出就是輸入序列與 h[n] 的卷積。按卷積和公式逐個時刻算y[0] u[0]·h[0] 5×0 0 y[1] u[0]·h[1] u[1]·h[0] 5×1.813 5×0 9.065 y[2] u[0]·h[2] u[1]·h[1] u[2]·h[0] 5×1.485 5×1.813 5×0 16.49 y[3] 5×1.216 5×1.485 5×1.813 5×0 22.57 y[4] 5×0.996 5×1.216 5×1.485 5×1.813 27.55可以看出 y[n] 逐漸趨近于穩態值 50因為增益10乘以階躍幅度5等于50。在前幾個周期輸出逐步爬升沒有超調符合一階慣性系統的特性。你把這個手算過程和示波器測得的轉速波形放一起對比會發現五個采樣點內的趨勢完全一致。用卷積算響應一點也不虛擬它跟實際系統幾乎是嚴絲合縫的。4.3 編寫一個通用卷積函數在實際工程里你不可能每次都手算。我在嵌入式代碼里經常寫一個極簡的離散卷積函數。假設輸入緩存在數組 u[] 中脈沖響應緩存在 h[] 中兩者長度分別為 Nu 和 Nh輸出長度為 N Nu Nh - 1C語言實現如下void conv(float *u, int Nu, float *h, int Nh, float *y) { for (int i 0; i Nu Nh - 1; i) { y[i] 0.0f; for (int j 0; j Nh; j) { int idx i - j; if (idx 0 idx Nu) { y[i] u[idx] * h[j]; } } } }這個實現是典型的 O(N^2) 算法。如果輸入和脈沖響應都很短比如幾十個點那么它可以在微秒級完成。但如果輸入很長比如持續采集了10萬個采樣點脈沖響應也有1000個點那這個雙重循環就會跑得很吃力。此時可以改用快速卷積對輸入和脈沖響應分別做FFT、頻域相乘、再做IFFT。這種方法的計算復雜度降為 O(N log N)在長序列場景下能快兩三個數量級。5. 卷積變體在控制場景里的對照與啟發5.1 轉置卷積與執行器重構問題轉置卷積也叫反卷積經常用于神經網絡的上采樣。它的核心操作是從較小的特征圖恢復出較大的特征圖。在控制場景里我們有一個高度類似的映射如果系統的執行器數量比被控變量少欠驅動系統或者傳感器采樣率低于執行器更新率你就需要根據低維的測量信息重構出高維的控制指令序列。轉置卷積的思路在這里可以直接遷移它本質上是在做一種有學習能力的插值而不是簡單的線性插值。傳統做法是零階保持或一階保持它們本質上是使用固定卷積核的上采樣而轉置卷積則是讓這個上采樣卷積核從數據中學習得到。5.2 空洞卷積與多速率控制空洞卷積通過在卷積核的元素之間插入空洞來擴大感受野適用于需要捕獲長期依賴的序列建模。我在做多速率采樣控制時發現這跟它非常像電流環的采樣頻率可能跑到10kHz以上而速度環只需1kHz位置環可能只有100Hz。多速率控制的本質就是每一層控制環都在以不同的時間尺度觀察系統。用空洞卷積的思路設計觀測器或控制器可以讓你在不降低控制周期的情況下看到更長時間窗口內的系統行為。這在處理大慣性負載時非常有效相當于在不犧牲帶寬的前提下增加相位超前信息。5.3 可變形卷積與自適應增益調度可變形卷積在特征圖每個位置學習一個偏移量讓卷積核變形到最需要的位置。實際控制工程中有一個非常相似的需求增益調度。比如一個隨角度變化而動力學特性劇烈變化的機械臂固定的一組PID參數在某個角度范圍內表現很好在其他角度就可能振蕩甚至發散。傳統增益調度做法是把工作區間分成若干段每段用一組PID參數相鄰段之間做線性過渡或模糊邏輯過渡。這實際上就是讓控制器卷積核的形狀隨著工況改變而改變。可變形卷積給你的啟發是沒有必要把整個狀態空間離散步你可以設計一個連續的函數把當前的狀態映射為控制器系數的增量讓控制器的卷積核連續變形。5.4 圖卷積與多變量解耦圖卷積處理的是非規則結構上的信號。多變量控制系統特別是存在強耦合的MIMO系統比如溫濕度耦合環境箱、多軸同步運動平臺從信號流圖的角度看它們就是一個典型的圖結構每個控制通道是一個節點通道之間的耦合是邊。傳統解耦控制需要精確知道耦合傳遞函數矩陣然后設計解耦補償器。圖卷積的思想則允許你從數據中直接學習這些邊上的權重和傳播規律。當然直接上神經網絡來實時控制目前還不現實但理解圖卷積可以幫助你用更系統化的方式梳理多變量耦合矩陣設計解耦前的信號預處理網絡。我把這些變體與控制算法的對應關系整理成了一個表方便日常討論時說同一種語言卷積變體核心特點控制場景映射轉置卷積低維恢復到高維欠驅動重構、執行器上采樣空洞卷積擴大感受野不增參數多速率采樣、長期預測觀測器可變形卷積核的位置動態調整增益調度、非線性自適應控制圖卷積非規則結構信息傳遞MIMO解耦、網絡化控制系統深度可分離卷積空間與通道解耦串級控制、分層控制結構分解3D卷積時空聯合特征提取時空軌跡預測、視覺伺服6. 實操中的常見問題與排查筆記6.1 邊界效應卷積算出的開頭幾個點總是不對很多人在用卷積做信號濾波時發現輸出的前幾個點跟預期不太一致。原因在于卷積的邊界處理。拿一個長度為 M 的濾波器卷積長度為 N 的信號輸出總長度為 MN-1。前面的 M-1 個點里卷積核有一部分還是空的懸在輸入信號范圍之外。這些點的值取決于你如何補齊邊界。常見的補齊策略有零填充、重復邊界值、鏡像填充、周期填充。控制環里處理實時采樣數據時我習慣用當前值填充或者零填充的組合并且把前 M-1 個點丟棄只保留有效卷積區的輸出。你要是做FIR濾波一定記得把初始化階段的數據跳過去否則系統啟動時會看到一段明顯的斜坡過渡。6.2 濾波延遲與相位裕度的矛盾這是數字控制里最經典的一個坑。你為了抑制傳感器噪聲在反饋通道上加了一個二階低通濾波器結果發現系統在某個增益下開始振蕩。原因就是濾波器的相位滯后吃掉了相位裕度。以截止頻率為 fn 的二階巴特沃斯低通為例在截止頻率處的相位滯后大約是90度。如果你的速度環在200Hz處穿越而這個低通濾波器的截止頻率恰好也設在200Hz那它在穿越頻率處的額外相移會直接從-180度變成-270度系統必振無疑。解決方法有幾種濾波器截止頻率設為穿越頻率的3到5倍以上使用相位滯后更小的貝塞爾濾波器或者在濾波器后面串聯一個相位超前補償器。6.3 實時卷積的計算成本控制在嵌入式上跑卷積最大的瓶頸是乘加運算的次數。一次長度為100的卷積對每1個輸出點要做100次乘加。如果你的采樣率是10kHz那每秒就是100萬次乘加。多數中端MCU帶FPU或DSP指令的話這還能接受但如果你用的是低端Cortex-M0只靠軟件循環跑主頻又只有48MHz那就可能撐不住。我的經驗是先算一下每秒鐘需要的乘加次數再估算一下芯片在這個頻率下能否完成。如果超了優先考慮降低濾波器階數、用級聯二階節SOS結構替代直接型結構、或者把一部分濾波任務放到DMA中斷里錯峰執行而不是一味提升主頻或者換芯片。6.4 有限字長效應定點卷積越算越偏如果用定點MCU做卷積會遇到有限字長效應。每次乘累加后都要做截斷或舍入誤差會隨著濾波階數和運算次數累積。現象就是零輸入時的輸出不完全為零或者信號幅度很小時卷積結果出現明顯臺階。排查思路也很直接用高精度浮點模型算一遍理想輸出再用定點模型的輸出對比找出誤差隨采樣點增加的規律。如果誤差呈線性增長多半是累加器沒有做足夠位寬的擴展保護如果誤差呈周期性波動很可能是正弦查找表或系數表的量化精度不夠。另外系數本身也要仔細檢查濾波器的系數在經過定點化之后極點位置可能偏離設計值導致實際幅頻響應跟理論不一致。7. 這些思路還能延伸到哪里寫到這里我突然想起來一個很有意思的事。去年我幫一位朋友排查一個自動化產線上的溫度控制問題那個系統用了很傳統的PID加前饋但總有大遲延溫度波動特別大。我們嘗試過史密斯預估器效果有改善但還是不夠。后來我發現問題的核心在于那個系統的過程對象其實是一個分布參數系統溫度在長管道里沿程傳遞每個截面都有不同的時間常數。用單個傳遞函數去描述它本身就是勉強的。后來我們換了一個思路把管道的長度方向離散成多個小段每一段用一個一階慣性模型描述整個管道的輸入輸出關系就是一個多段卷積的級聯。用這個思路重新做了前饋補償效果比史密斯預估器好得多。這件事給我的觸動很大卷積這種工具它不只是一個公式它是一種分析系統的方式。你把它當成在時間和空間上的加權傳播來理解就能在很廣泛的場景里找到它的影子。后面我還想專門整理一下卷積在做軌跡規劃中的應用比如S形速度規劃本質上也能寫成輸入序列與被控對象脈沖響應的卷積然后用預先計算的卷積結果做實時查表這樣可以把軌跡規劃的計算開銷降到幾乎可以忽略。8. 寫在最后的幾句心里話我做控制這么多年有一個特別深的體會很多理論上很漂亮的方法落到工程現場都會因為各種細節變形。卷積也是一樣課本上講卷積是用兩個無限長連續函數做積分但在工程里你面對的是有限長數組、定點數、DMA中斷、濾波延遲、傳感器噪聲。學會在不同抽象層次之間切換是工程師的核心能力。你需要在腦子里隨時能把這幾個視角串起來時域的加權疊加、頻域的相乘、Z域的多項式運算、C語言數組里的雙重循環。它們描述的是同一個東西只是在不同場景下各有側重。如果你想真正掌握卷積我建議你找一組真實的系統響應數據自己動手寫一個卷積函數把輸出波形和示波器測到的波形對比。不用多跑通一個例子就夠了。那之后你會發現神經網絡里的卷積、控制環路里的濾波、信號分析里的相關運算在你眼里都不再是孤立的公式而是同一棵樹上的不同枝杈。