一、導言
激活函數在目標檢測中的作用至關重要,它們主要服務于以下幾個關鍵目的:
-
引入非線性:神經網絡的基本構建塊(如卷積層、全連接層等)本質上是線性變換,而激活函數通過引入非線性,使得網絡能夠學習和表達更復雜、更豐富的數據特征。這對于目標檢測任務尤為重要,因為目標可能出現在圖像中的任何位置、大小和姿態,且彼此之間可能有重疊或遮擋,非線性表達能力可以幫助模型更好地理解和區分這些復雜的場景。
-
控制梯度流:激活函數的形狀影響著反向傳播過程中的梯度傳遞,這對于權重更新和學習過程至關重要。例如,ReLU及其變體(如Leaky ReLU、PReLU、FReLU等)通過在負值區域保持非零斜率,解決了傳統ReLU可能導致的“神經元死亡”問題,從而促進了深層網絡中的梯度流動。
-
增強模型表達能力:特定的激活函數能夠提升模型在特定任務上的表現。例如,FReLU(Funnel Activation Function)通過在激活階段整合空間信息,提高了模型的空間理解能力,這對于目標檢測這種需要精確定位的任務非常有利。
-
影響計算效率:不同的激活函數具有不同的計算復雜度。在實時目標檢測系統如YOLO系列中,選擇計算成本低且效果好的激活函數(如ReLU)對于保證模型的運行速度和資源效率是必要的。
-
輸出范圍調整:某些激活函數(如Sigmoid和Softmax)能夠將輸出限制在特定范圍內,這在輸出層特別有用,比如將網絡輸出轉化為概率值,便于進行目標類別預測。
綜上所述,激活函數不僅決定了神經網絡的學習能力,還在很大程度上影響了目標檢測模型的精度、訓練效率以及最終的檢測性能。因此,在設計目標檢測網絡時,精心選擇和設計激活函數是一個重要環節。
二、YOLO訓練中常見且有效的激活函數
-
SiLU (Sigmoid Linear Unit): 也稱為Swish,是一種自適應激活函數。SiLU嘗試結合了線性變換和sigmoid函數的優點,能夠提升模型的非線性表達能力,同時緩解梯度消失問題。
-
ReLU (Rectified Linear Unit): 是最常用的激活函數之一,當輸入為正時,輸出等于輸入;為負時,輸出為0。ReLU解決了sigmoid和tanh函數的梯度飽和問題,加速了神經網絡的訓練,但在負值區域梯度為0,可能導致“死亡ReLU”現象。
-
Leaky ReLU: 為了解決ReLU在負值區域梯度消失的問題而提出,即使負輸入時函數也有非零斜率,幫助梯度流動。
-
FReLU (Fractional ReLU): 是ReLU的一個變種,它引入了一個可學習的參數來調整負輸入部分的斜率,提供了比Leaky ReLU更靈活的調整能力。
-
PReLU (Parametric ReLU): 類似于Leaky ReLU,適用于不同層可能需要不同負斜率的情況。
-
Hardswish: 是MobileNetV3中引入的一種激活函數,試圖模仿Swish但計算成本更低。它在移動端設備上表現高效且性能良好。
-
Mish: 由D. Misra提出,Mish結合了自我門控的性質和ReLU的簡單性,被發現能在多種任務上提高模型性能。
-
ELU (Exponential Linear Unit): 目的是減少ReLU的偏差移位問題并加速學習過程。
-
CELU (Continuously Differentiable Exponential Linear Unit): 是ELU的一個連續可微分版本,旨在保持ELU的優點同時確保所有點的導數存在,適合需要嚴格平滑性的應用。
-
GELU (Gaussian Error Linear Unit): 形式較為復雜,與高斯分布的累積分布函數有關。GELU在Transformer等模型中表現優秀,因為它能更好地匹配神經網絡中權重初始化的分布。
-
SELU (Scaled Exponential Linear Unit): 設計用于自歸一化神經網絡,SELU旨在確保網絡的輸出具有零均值和單位方差,從而簡化訓練過程中的歸一化需求。
需要注意的是,YOLOv7、YOLOv5項目采用的默認激活函數為SiLU,而YOLOv7-tiny項目采用的激活函數為LeakyReLU,ResNet系列采用的激活函數則為ReLU,選擇何種激活函數為自己的Baseline需要先查閱相關論文再下判斷,以此為改進的對照方可得出結果。
同時,YOLOv5/v7的激活函數一般在models/activations.py下
三、YOLOv7-tiny改進工作
了解二后,在YOLOv7項目文件下的models文件夾下的common.py,采用ctrl+F搜索如下代碼。
self.act = nn.SiLU() if act is True else (act if isinstance(act, nn.Module) else nn.Identity())
將其替換為二的激活函數即可。
四、YOLOv7改進工作
了解二后,在YOLOv7項目文件下的models文件夾下的common.py,采用ctrl+F搜索如下代碼。
self.act = nn.SiLU() if act is True else (act if isinstance(act, nn.Module) else nn.Identity())
將其替換為二的激活函數即可。
五、YOLOv5改進工作
了解二后,在YOLOv5項目文件下的models文件夾下的common.py,采用ctrl+F搜索如下代碼。
self.act = nn.SiLU() if act is True else (act if isinstance(act, nn.Module) else nn.Identity())
將其替換為二的激活函數即可。
更多文章產出中,主打簡潔和準確,歡迎關注我,共同探討!