首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

tiny-cnn 源碼深度解析(十):layer_base 與 layer 類結構詳解

     編輯:關於C++

layer_base:網絡層基礎設施

layer_base 是所有層類型的公共基類,封裝了神經網絡層的通用屬性與操作。

核心成員變量

變量含義
in_size_, out_size_輸入/輸出特徵維度
parallelize_是否啟用 TBB 多線程加速(默認 true)
next_, prev_指向下一層/上一層指針,構建網絡拓撲鏈表
a_卷積/全連接運算的線性輸出(激活前)
output_經激活函數後的最終輸出特徵
prev_delta_反向傳播傳入的誤差靈敏度 (∂L/∂a)
W_, b_權重矩陣、偏置向量
dW_, db_權重/偏置梯度 (∂L/∂W, ∂L/∂b)
Whessian_, bhessian_海森矩陣相關(二階優化用,如 Levenberg-Marquardt)
prev_delta2_誤差對輸入的二階導數 (∂²L/∂x²),全連接層二階反向傳播用

構造與初始化

layer_base(layer_size_t in_dim, layer_size_t out_dim,
           size_t weight_dim, size_t bias_dim)
    : parallelize_(true), next_(nullptr), prev_(nullptr) {
    set_size(in_dim, out_dim, weight_dim, bias_dim);
}
void set_size(layer_size_t in_dim, layer_size_t out_dim,
              size_t weight_dim, size_t bias_dim) {
    in_size_ = in_dim; out_size_ = out_dim;
    W_.resize(weight_dim); b_.resize(bias_dim);
    Whessian_.resize(weight_dim); bhessian_.resize(bias_dim);
    prev_delta2_.resize(in_dim);
    for (auto& o : output_) o.resize(out_dim);
    for (auto& a : a_) a.resize(out_dim);
    for (auto& p : prev_delta_) p.resize(in_dim);
    for (auto& dw : dW_) dw.resize(weight_dim);
    for (auto& db : db_) db.resize(bias_dim);
}

大量使用 C++11 範圍 for 初始化向量容器,簡潔安全。

純虛函數:留給具體層實現

virtual activation::function& activation_function() = 0;
virtual const vec_t& forward_propagation(const vec_t& in, size_t worker_index) = 0;
virtual const vec_t& back_propagation(const vec_t& current_delta, size_t worker_index) = 0;
virtual const vec_t& back_propagation_2nd(const vec_t& current_delta2) = 0;
  • 激活函數:不同層可選不同激活(ReLU, Sigmoid, Tanh...)
  • 前向/反向傳播:核心計算邏輯,卷積層、池化層、全連接層完全不同
  • 二階反向傳播:支持二階優化算法

模型持久化

virtual void save(std::ostream& os) const {
    if (is_exploded()) throw nn_error("infinite weight");
    for (auto w : W_) os << w << ' ';
    for (auto b : b_) os << b << ' ';
}
virtual void load(std::istream& is) {
    for (auto& w : W_) is >> w;
    for (auto& b : b_) is >> b;
}

流式保存/加載權重偏置,支持斷點續訓。

權重更新

void update_weights(optimizer& opt) {
    opt.update(W_, dW_, Whessian_); // 權重更新
    opt.update(b_, db_, bhessian_); // 偏置更新
}

委託給優化器(SGD, Adam, LM 等)具體更新邏輯,解耦層與優化算法。

layer:具體化實例化模板

template class layer : public layer_base

三大職責

  1. 激活函數實例化:
    activation::function& activation_function() override { return Activation::function(); }
  2. 流操作符重載:
    operator<< / operator>> 調用 save/load,支持 cout << layer
  3. 錯誤提示靜態函數:
    connection_mismatch() — 輸出維度不匹配
    data_mismatch() — 輸入特徵維度不匹配
    pooling_size_mismatch() — 池化窗口不整除特徵圖尺寸

錯誤函數僅格式化輸出,具體檢查邏輯由調用方(如 network::add_layer)執行。

關鍵設計模式

  • 模板方法模式:layer_base 定義框架,layer 注入激活函数
  • 策略模式:優化器通過 optimizer 接口注入,層不關心具體更新規則
  • 組合模式:next_/prev_ 構建層鏈表,network 統一協調前向/反向傳播

注意事項

  1. 範圍 for 循環是 tiny-cnn 遍歷容器的標準寫法,建議熟練掌握
  2. layer_base 還有其他輔助函數(如可視化輸出 output_to_image),用到時再深入
  3. 激活函數 ≠ 優化算法:前者如 ReLU/Sigmoid,後者如 SGD/Adam,初學者易混淆
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved