動手打造深度學習框架
內容描述
本書基於 C++編寫,旨在帶領讀者動手打造出一個深度學習框架。本書首先介紹 C++模板元編程的基礎技術,然後在此基礎上剖析深度學習框架的內部結構,逐一實現深度學習框架中的各個組件和功能,包括基本數據結構、運算與表達模板、基本層、復合層、循環層、求值與優化等,最終打造出一個深度學習框架。本書將深度學習框架與 C++模板元編程有機結合,更利於讀者學習和掌握使用 C++開發大型項目的方法。本書適合對 C++有一定瞭解,希望深入瞭解深度學習框架內部實現細節,以及提升 C++程序設計水平的讀者閱讀。
目錄大綱
第 1 部分 元編程基礎技術第 1 章 元編程基本方法 21.1 元函數與 type_traits 21.1.1 元函數簡介 21.1.2 類型元函數 31.1.3 各式各樣的元函數 51.1.4 typetraits 61.1.5 元函數與宏 61.1.6 本書中元函數的命名方式 71.2 模板型模板參數與容器模板 71.2.1 模板作為元函數的輸入 81.2.2 模板作為元函數的輸出 .81.2.3 容器模板 91.3 從元函數到元對象 101.3.1 元對象與元數據域 111.3.2 元方法 121.4 順序、分支與循環代碼的編寫 131.4.1 順序執行的代碼 131.4.2 分支執行的代碼 141.4.3 循環執行的代碼 211.4.4 小心:實例化爆炸與編譯崩潰 271.4.5 分支選擇與短路邏輯 291.5 奇特的遞歸模板式 301.6 小結 321.7 練習 32第 2 章 元數據結構與算法 342.1 基本數據結構與算法 342.1.1 數據結構的表示方法 342.1.2 基本算法 362.1.3 算法的復雜度 382.2 基於包展開與折疊表達式的優化 412.2.1 基於包展開的優化 412.2.2 基於折疊表達式的優化 422.3 基於操作合並的優化 432.4 基於函數重載的索引算法 462.4.1 分攤復雜度 462.4.2 容器的重載結構映射 462.4.3 構造重載結構 472.4.4 索引元函數 482.4.5 允許重復鍵 482.4.6 集合與順序表的索引操作 512.5 順序表的索引算法 522.5.1 構造索引序列 522.5.2 索引順序表的元函數 542.6 小結 552.7 練習 56第 3 章 異類詞典與 policy 模板 573.1 具名參數簡介 573.2 異類詞典 593.2.1 模塊的使用方式 593.2.2 鍵的表示 613.2.3 異類詞典的實現 633.2.4 VarTypeDict 的性能簡析 693.2.5 將 std::tuple 作為緩存 703.3 policy 模板 703.3.1 policy 介紹 713.3.2 定義 policy 與 policy 對象(模板) 733.3.3 使用 policy 763.3.4 背景知識-支配與虛繼承 783.3.5 policy 對象與 policy 支配結構 793.3.6 policy 選擇元函數 803.3.7 使用宏簡化 policy 對象的聲明 853.3.8 特殊的 policy 類型 863.3.9 其他與 policy 相關的元函數 893.4 小結 893.5 練習 90第 2 部分 深度學習框架第 4 章 深度學習概述 924.1 深度學習簡介 924.1.1 從機器學習到深度學習 934.1.2 各式各樣的人工神經網絡 944.1.3 深度學習系統的組織與訓練 964.2 本書所實現的框架--MetaNN 984.2.1 從矩陣運算工具到深度學習框架 984.2.2 MetaNN 概述 994.2.3 本書將要討論的內容 1014.3 小結 104第 5 章 類型體系與基本數據類型 1055.1 設計理念 1065.1.1 編譯期的職責劃分 1065.1.2 使用類型體系管理不同的數據類型 1065.1.3 支持不同的計算設備與計算單元 1075.1.4 存儲空間的分配與維護 1075.1.5 淺拷貝與寫操作檢測 1105.1.6 底層接口擴展 1125.1.7 類型轉換與求值 1135.1.8 數據接口規範 1145.2 類型體系 1145.2.1 類型體系概述 1145.2.2 迭代器分類體系 1165.2.3 將標簽作為模板參數 1175.2.4 MetaNN 的類型體系 1195.2.5 類別標簽與數據類型的關聯 1205.2.6 與類型體系相關的元函數 1215.3 Shape 類與形狀信息 1235.3.1 模板定義與基本操作 1245.3.2 索引與偏移量的變換 1255.3.3 維度為 0 時的特化 1275.3.4 Shape 的模板推導 1275.4 Tensor 類模板 1285.4.1 模板定義 1285.4.2 底層訪問接口 1315.4.3 模板特化與類型別名 1325.4.4 主體類型的相關元函數 1335.5 TrivialTensor 1345.6 MetaNN 所提供的其他數據類型 1355.7 DynamicData 1355.7.1 基類模板 DynamicBase 1365.7.2 派生類模板DynamicWrapper 1375.7.3 使用 DynamicData 封裝指針行為 1385.7.4 輔助函數與輔助元函數 1395.7.5 DynamicData 與動態類型體系 1395.8 小結 1405.9 練習 141第 6 章 運算與表達式模板 1436.1 表達式模板概述 1436.2 MetaNN 運算模板的設計思想 1456.2.1 Add 類模板的問題 1456.2.2 運算模板的行為分析 1466.3 輔助元函數與輔助類模板 1506.3.1 IsValidOper 1506.3.2 輔助類模板 OperElementType/ OperDeviceType 1506.3.3 輔助類模板 OperCateCal 1516.3.4 輔助類模板 OperAuxParams 1526.3.5 輔助類模板 OperShapeInfo 1536.3.6 輔助類模板 OperSeq 1556.4 運算模板的框架 1556.5 運算實現示例 1576.5.1 Sigmoid 運算 1576.5.2 加法運算 1596.5.3 點乘運算 1636.6 其他運算 1676.6.1 四則運算 1686.6.2 Slice 運算 1686.6.3 Permute 運算及其相關運算 1696.6.4 ReduceSum 運算 1706.6.5 非線性變換與相應的梯度計算 1706.7 運算的折中與局限性 1716.7.1 運算的折中 1716.7.2 運算的局限性 1716.8 小結 1726.9 練習 172第 7 章 基本層 1747.1 層的設計理念 1747.1.1 概述 1747.1.2 層對象的構造 1767.1.3 參數的初始化與加載 1787.1.4 正向傳播 1787.1.5 存儲中間結果 1807.1.6 反向傳播 1827.1.7 輸出梯度的形狀檢測 1837.1.8 更新參數 1837.1.9 導出參數 1847.1.10 層的中性檢測 1847.2 層的輔助邏輯 1847.2.1 初始化模塊 1847.2.2 接口相關輔助邏輯 1927.2.3 GradPolicy 1957.2.4 MakeInferLayer 與MakeTrainLayer 1967.2.5 通用操作函數 1977.2.6 其他輔助邏輯 1987.3 層的具體實現 2017.3.1 AddLayer 2027.3.2 MultiplyLayer 2067.3.3 ParamSourceLayer 2087.4 小結 2147.5 練習 214第 8 章 復合層 2158.1 復合層的接口與設計理念 2168.1.1 基本結構 2168.1.2 結構描述語法 2178.1.3 policy 的繼承 2188.1.4 policy 的修正 2198.1.5 輸入類型映射表的推導 2198.1.6 復合層的構造函數 2208.1.7 一個完整的復合層構造示例 2208.2 policy 繼承與修正邏輯的實現 2228.2.1 policy 繼承邏輯的實現 2228.2.2 policy 修正邏輯的實現 2258.3 ComposeTopology 的實現 2258.3.1 功能簡述 2258.3.2 拓撲排序算法概述 2268.3.3 ComposeTopology 包含的主要步驟 2278.3.4 結構描述子句與其劃分 2278.3.5 結構合法性檢查 2298.3.6 拓撲排序的實現 2308.3.7 子層實例化元函數 2338.4 ComposeKernel 的實現 2398.4.1 類模板的聲明 2398.4.2 子層對象管理 2408.4.3 參數初始化、參數獲取、參數梯度收集與中性檢測 2428.4.4 正向傳播 2448.4.5 反向傳播 2488.5 復合層實現示例 2508.6 小結 2518.7 練習 252第 9 章 循環層 2539.1 設計理念 2539.1.1 子層的容器接口 2539.1.2 確定序列所在維度 2549.1.3 正向傳播與反向傳播 2559.2 循環層的實現 2569.2.1 主體框架 2569.2.2 (元)數據域 2569.2.3 KernelGenerator_的實現 2579.2.4 ShapeDictHelper 2599.2.5 構造函數、參數初始化等接口 2609.2.6 正向傳播 2619.2.7 反向傳播 2639.3 循環層應用示例 2659.3.1 以 AddLayer 作為內核的循環層 2659.3.2 GRU 2669.4 小結 2689.5 練習 268第 10 章 求值與優化 26910.1 MetaNN 的求值模型 27010.1.1 運算的層次結構 27010.1.2 求值子系統的類劃分 27110.2 基本求值邏輯 28010.2.1 主體類型的求值接口 28010.2.2 非主體基本數據類型的求值 28110.2.3 運算模板的求值 28410.2.4 DynamicData 與求值 28610.3 求值過程的優化 28710.3.1 避免重復計算 28710.3.2 針對運算特性的優化 28910.3.3 同類計算合並 29010.3.4 多運算協同優化 29110.4 小結 29710.5 練習 298後記 299
作者介紹
李伟,毕业于清华大学,曾负责百度公司自然语言处理部深度学习机器翻译系统线上预测部分的开发与维护,目前就职于微软。主要研究方向为 C++,拥有 10 余年相关开发经验,对 C++ 模板元编程与编译期计算有着浓厚的兴趣。喜欢尝试新技术。著有《C++ 模板元编程实战》。