本書基于 C++編寫,旨在帶領(lǐng)讀者動手打造出一個深度學(xué)習(xí)框架。本書首先介紹 C++模板元編程的基礎(chǔ)技術(shù),然后在此基礎(chǔ)上剖析深度學(xué)習(xí)框架的內(nèi)部結(jié)構(gòu),逐一實現(xiàn)深度學(xué)習(xí)框架中的各個組件和功能,包括基本數(shù)據(jù)結(jié)構(gòu)、運算與表達模板、基本層、復(fù)合層、循環(huán)層、求值與優(yōu)化等,最終打造出一個深度學(xué)習(xí)框架。本書將深度學(xué)習(xí)框架與 C++模板元編程有機結(jié)合,更利于讀者學(xué)習(xí)和掌握使用 C++開發(fā)大型項目的方法。
本書適合對 C++有一定了解,希望深入了解深度學(xué)習(xí)框架內(nèi)部實現(xiàn)細節(jié),以及提升 C++程序設(shè)計水平的讀者閱讀。
1.實戰(zhàn)導(dǎo)向,分析核心代碼與邏輯,并提供源代碼
2.結(jié)構(gòu)合理,從元編程技術(shù)到逐步打造深度學(xué)習(xí)框架
3.鞏固學(xué)習(xí),每章都配有練習(xí)題,方便讀者檢測學(xué)習(xí)效果
4.全程視頻講解,理解更清晰
李偉,畢業(yè)于清華大學(xué),曾負(fù)責(zé)百度公司自然語言處理部深度學(xué)習(xí)機器翻譯系統(tǒng)線上預(yù)測部分的開發(fā)與維護,目前就職于微軟。主要研究方向為 C++,擁有 10 余年相關(guān)開發(fā)經(jīng)驗,對 C++ 模板元編程與編譯期計算有著濃厚的興趣。喜歡嘗試新技術(shù)。著有《C++ 模板元編程實戰(zhàn)》。
第 1 部分 元編程基礎(chǔ)技術(shù)
第 1 章 元編程基本方法 2
1.1 元函數(shù)與 type_traits 2
1.1.1 元函數(shù)簡介 2
1.1.2 類型元函數(shù) 3
1.1.3 各式各樣的元函數(shù) 5
1.1.4 type_traits 6
1.1.5 元函數(shù)與宏 6
1.1.6 本書中元函數(shù)的命名方式 7
1.2 模板型模板參數(shù)與容器模板 7
1.2.1 模板作為元函數(shù)的輸入 8
1.2.2 模板作為元函數(shù)的輸出 .8
1.2.3 容器模板 9
1.3 從元函數(shù)到元對象 10
1.3.1 元對象與元數(shù)據(jù)域 11
1.3.2 元方法 12
1.4 順序、分支與循環(huán)代碼的編寫 13
1.4.1 順序執(zhí)行的代碼 13
1.4.2 分支執(zhí)行的代碼 14
1.4.3 循環(huán)執(zhí)行的代碼 21
1.4.4 小心:實例化爆炸與編譯崩潰 27
1.4.5 分支選擇與短路邏輯 29
1.5 奇特的遞歸模板式 30
1.6 小結(jié) 32
1.7 練習(xí) 32
第 2 章 元數(shù)據(jù)結(jié)構(gòu)與算法 34
2.1 基本數(shù)據(jù)結(jié)構(gòu)與算法 34
2.1.1 數(shù)據(jù)結(jié)構(gòu)的表示方法 34
2.1.2 基本算法 36
2.1.3 算法的復(fù)雜度 38
2.2 基于包展開與折疊表達式的優(yōu)化 41
2.2.1 基于包展開的優(yōu)化 41
2.2.2 基于折疊表達式的優(yōu)化 42
2.3 基于操作合并的優(yōu)化 43
2.4 基于函數(shù)重載的索引算法 46
2.4.1 分?jǐn)倧?fù)雜度 46
2.4.2 容器的重載結(jié)構(gòu)映射 46
2.4.3 構(gòu)造重載結(jié)構(gòu) 47
2.4.4 索引元函數(shù) 48
2.4.5 允許重復(fù)鍵 48
2.4.6 集合與順序表的索引操作 51
2.5 順序表的索引算法 52
2.5.1 構(gòu)造索引序列 52
2.5.2 索引順序表的元函數(shù) 54
2.6 小結(jié) 55
2.7 練習(xí) 56
第 3 章 異類詞典與 policy 模板 57
3.1 具名參數(shù)簡介 57
3.2 異類詞典 59
3.2.1 模塊的使用方式 59
3.2.2 鍵的表示 61
3.2.3 異類詞典的實現(xiàn) 63
3.2.4 VarTypeDict 的性能簡析 69
3.2.5 將 std::tuple 作為緩存 70
3.3 policy 模板 70
3.3.1 policy 介紹 71
3.3.2 定義 policy 與 policy 對象(模板) 73
3.3.3 使用 policy 76
3.3.4 背景知識-支配與虛繼承 78
3.3.5 policy 對象與 policy 支配結(jié)構(gòu) 79
3.3.6 policy 選擇元函數(shù) 80
3.3.7 使用宏簡化 policy 對象的聲明 85
3.3.8 特殊的 policy 類型 86
3.3.9 其他與 policy 相關(guān)的元函數(shù) 89
3.4 小結(jié) 89
3.5 練習(xí) 90
第 2 部分 深度學(xué)習(xí)框架
第 4 章 深度學(xué)習(xí)概述 92
4.1 深度學(xué)習(xí)簡介 92
4.1.1 從機器學(xué)習(xí)到深度學(xué)習(xí) 93
4.1.2 各式各樣的人工神經(jīng)網(wǎng)絡(luò) 94
4.1.3 深度學(xué)習(xí)系統(tǒng)的組織與訓(xùn)練 96
4.2 本書所實現(xiàn)的框架--MetaNN 98
4.2.1 從矩陣運算工具到深度學(xué)習(xí)框架 98
4.2.2 MetaNN 概述 99
4.2.3 本書將要討論的內(nèi)容 101
4.3 小結(jié) 104
第 5 章 類型體系與基本數(shù)據(jù)類型 105
5.1 設(shè)計理念 106
5.1.1 編譯期的職責(zé)劃分 106
5.1.2 使用類型體系管理不同的數(shù)據(jù)類型 106
5.1.3 支持不同的計算設(shè)備與計算單元 107
5.1.4 存儲空間的分配與維護 107
5.1.5 淺拷貝與寫操作檢測 110
5.1.6 底層接口擴展 112
5.1.7 類型轉(zhuǎn)換與求值 113
5.1.8 數(shù)據(jù)接口規(guī)范 114
5.2 類型體系 114
5.2.1 類型體系概述 114
5.2.2 迭代器分類體系 116
5.2.3 將標(biāo)簽作為模板參數(shù) 117
5.2.4 MetaNN 的類型體系 119
5.2.5 類別標(biāo)簽與數(shù)據(jù)類型的關(guān)聯(lián) 120
5.2.6 與類型體系相關(guān)的元函數(shù) 121
5.3 Shape 類與形狀信息 123
5.3.1 模板定義與基本操作 124
5.3.2 索引與偏移量的變換 125
5.3.3 維度為 0 時的特化 127
5.3.4 Shape 的模板推導(dǎo) 127
5.4 Tensor 類模板 128
5.4.1 模板定義 128
5.4.2 底層訪問接口 131
5.4.3 模板特化與類型別名 132
5.4.4 主體類型的相關(guān)元函數(shù) 133
5.5 TrivialTensor 134
5.6 MetaNN 所提供的其他數(shù)據(jù)類型 135
5.7 DynamicData 135
5.7.1 基類模板 DynamicBase 136
5.7.2 派生類模板DynamicWrapper 137
5.7.3 使用 DynamicData 封裝指針行為 138
5.7.4 輔助函數(shù)與輔助元函數(shù) 139
5.7.5 DynamicData 與動態(tài)類型體系 139
5.8 小結(jié) 140
5.9 練習(xí) 141
第 6 章 運算與表達式模板 143
6.1 表達式模板概述 143
6.2 MetaNN 運算模板的設(shè)計思想 145
6.2.1 Add 類模板的問題 145
6.2.2 運算模板的行為分析 146
6.3 輔助元函數(shù)與輔助類模板 150
6.3.1 IsValidOper 150
6.3.2 輔助類模板 OperElementType_/ OperDeviceType_ 150
6.3.3 輔助類模板 OperCateCal 151
6.3.4 輔助類模板 OperAuxParams 152
6.3.5 輔助類模板 OperShapeInfo 153
6.3.6 輔助類模板 OperSeq_ 155
6.4 運算模板的框架 155
6.5 運算實現(xiàn)示例 157
6.5.1 Sigmoid 運算 157
6.5.2 加法運算 159
6.5.3 點乘運算 163
6.6 其他運算 167
6.6.1 四則運算 168
6.6.2 Slice 運算 168
6.6.3 Permute 運算及其相關(guān)運算 169
6.6.4 ReduceSum 運算 170
6.6.5 非線性變換與相應(yīng)的梯度計算 170
6.7 運算的折中與局限性 171
6.7.1 運算的折中 171
6.7.2 運算的局限性 171
6.8 小結(jié) 172
6.9 練習(xí) 172
第 7 章 基本層 174
7.1 層的設(shè)計理念 174
7.1.1 概述 174
7.1.2 層對象的構(gòu)造 176
7.1.3 參數(shù)的初始化與加載 178
7.1.4 正向傳播 178
7.1.5 存儲中間結(jié)果 180
7.1.6 反向傳播 182
7.1.7 輸出梯度的形狀檢測 183
7.1.8 更新參數(shù) 183
7.1.9 導(dǎo)出參數(shù) 184
7.1.10 層的中性檢測 184
7.2 層的輔助邏輯 184
7.2.1 初始化模塊 184
7.2.2 接口相關(guān)輔助邏輯 192
7.2.3 GradPolicy 195
7.2.4 MakeInferLayer 與MakeTrainLayer 196
7.2.5 通用操作函數(shù) 197
7.2.6 其他輔助邏輯 198
7.3 層的具體實現(xiàn) 201
7.3.1 AddLayer 202
7.3.2 MultiplyLayer 206
7.3.3 ParamSourceLayer 208
7.4 小結(jié) 214
7.5 練習(xí) 214
第 8 章 復(fù)合層 215
8.1 復(fù)合層的接口與設(shè)計理念 216
8.1.1 基本結(jié)構(gòu) 216
8.1.2 結(jié)構(gòu)描述語法 217
8.1.3 policy 的繼承 218
8.1.4 policy 的修正 219
8.1.5 輸入類型映射表的推導(dǎo) 219
8.1.6 復(fù)合層的構(gòu)造函數(shù) 220
8.1.7 一個完整的復(fù)合層構(gòu)造示例 220
8.2 policy 繼承與修正邏輯的實現(xiàn) 222
8.2.1 policy 繼承邏輯的實現(xiàn) 222
8.2.2 policy 修正邏輯的實現(xiàn) 225
8.3 ComposeTopology 的實現(xiàn) 225
8.3.1 功能簡述 225
8.3.2 拓?fù)渑判蛩惴ǜ攀觥?26
8.3.3 ComposeTopology 包含的主要步驟 227
8.3.4 結(jié)構(gòu)描述子句與其劃分 227
8.3.5 結(jié)構(gòu)合法性檢查 229
8.3.6 拓?fù)渑判虻膶崿F(xiàn) 230
8.3.7 子層實例化元函數(shù) 233
8.4 ComposeKernel 的實現(xiàn) 239
8.4.1 類模板的聲明 239
8.4.2 子層對象管理 240
8.4.3 參數(shù)初始化、參數(shù)獲取、參數(shù)梯度收集與中性檢測 242
8.4.4 正向傳播 244
8.4.5 反向傳播 248
8.5 復(fù)合層實現(xiàn)示例 250
8.6 小結(jié) 251
8.7 練習(xí) 252
第 9 章 循環(huán)層 253
9.1 設(shè)計理念 253
9.1.1 子層的容器接口 253
9.1.2 確定序列所在維度 254
9.1.3 正向傳播與反向傳播 255
9.2 循環(huán)層的實現(xiàn) 256
9.2.1 主體框架 256
9.2.2。ㄔ⿺(shù)據(jù)域 256
9.2.3 KernelGenerator_的實現(xiàn) 257
9.2.4 ShapeDictHelper 259
9.2.5 構(gòu)造函數(shù)、參數(shù)初始化等接口 260
9.2.6 正向傳播 261
9.2.7 反向傳播 263
9.3 循環(huán)層應(yīng)用示例 265
9.3.1 以 AddLayer 作為內(nèi)核的循環(huán)層 265
9.3.2 GRU 266
9.4 小結(jié) 268
9.5 練習(xí) 268
第 10 章 求值與優(yōu)化 269
10.1 MetaNN 的求值模型 270
10.1.1 運算的層次結(jié)構(gòu) 270
10.1.2 求值子系統(tǒng)的類劃分 271
10.2 基本求值邏輯 280
10.2.1 主體類型的求值接口 280
10.2.2 非主體基本數(shù)據(jù)類型的求值 281
10.2.3 運算模板的求值 284
10.2.4 DynamicData 與求值 286
10.3 求值過程的優(yōu)化 287
10.3.1 避免重復(fù)計算 287
10.3.2 針對運算特性的優(yōu)化 289
10.3.3 同類計算合并 290
10.3.4 多運算協(xié)同優(yōu)化 291
10.4 小結(jié) 297
10.5 練習(xí) 298
后記 299