《動手學深度學習》mxnet版/第四章學習筆記
阿新 • • 發佈:2020-08-21
第四章
概括深度學習計算的各個重要組成部分,如模型構造、引數的訪問和初始化等,自定義層,讀取、儲存和 使用GPU
- 模型構造
- 模型引數的訪問、初始化和共享
- 讀寫Gluon模型的引數
模型構造
Block類是nn模組裡提供的一個模型構造類,可以繼承它來定義我們想要的模型。
#這裡定義的MLP類過載了Block類的__init__函 數和forward函式。它們分別用於建立模型引數和定義前向計算 from mxnet import nd from mxnet.gluon import nn class MLP(nn.Block): # 宣告帶有模型引數的層,這裡聲明瞭兩個全連線層 def __init__(self, **kwargs): # 呼叫MLP父類Block的建構函式來進行必要的初始化。這樣在構造例項時還可以指定其他函式 # 引數,如“模型引數的訪問、初始化和共享”一節將介紹的模型引數 super(MLP, self).__init__(**kwargs) self.hidden = nn.Dense(256, activation='relu')# 隱藏層 self.output = nn.Dense(10) # 輸出層 # 定義模型的前向計算,即如何根據輸入x計算返回所需要的模型輸出 def forward(self, x): return self.output(self.hidden(x))
#實現一個與Sequential類有相同功能的MySequential類 class MySequential(nn.Block): def __init__(self, **kwargs): super(MySequential, self).__init__(**kwargs) def add(self, block): # block是一個Block子類例項,假設它有一個獨一無二的名字。我們將它儲存在Block類的 # 成員變數_children裡,其型別是OrderedDict。當MySequential例項呼叫 # initialize函式時,系統會自動對_children裡所有成員初始化 self._children[block.name] = block def forward(self, x): # OrderedDict保證會按照成員新增時的順序遍歷成員 for block in self._children.values(): x = block(x) return x # 使用起來與Sequential差不多 net = MySequential() net.add(nn.Dense(256, activation='relu')) net.add(nn.Dense(10)) net.initialize() net(X)
模型引數的訪問、初始化和共享
在有些情況下,我們希望在多個層之間共享模型引數
#讓模型的第二隱藏層(shared變數)和第三隱藏層共享模型引數 net = nn.Sequential() shared = nn.Dense(8, activation='relu') net.add(nn.Dense(8, activation='relu'), shared, nn.Dense(8, activation='relu', params=shared.params), nn.Dense(10)) net.initialize() #在構造第三隱藏層時通過params來指定它使用第二隱藏層的引數。因為模型引數裡包含了 梯度, 所以在反向傳播計算時, 第二隱藏層和第三隱藏層的梯度都會被累加在shared.params.grad()裡
讀寫Gluon模型的引數
Gluon的Block類提供了save_parameters函式和load_parameters函式來讀寫模型引數。
class MLP(nn.Block):
def __init__(self, **kwargs):
super(MLP, self).__init__(**kwargs)
self.hidden = nn.Dense(256, activation='relu')
self.output = nn.Dense(10)
def forward(self, x):
return self.output(self.hidden(x))
net = MLP()
net.initialize()
X = nd.random.uniform(shape=(2, 20))
Y = net(X)
#把該模型的引數存成檔案,檔名為mlp.params
filename = 'mlp.params' net.save_parameters(filename)
#再例項化一次定義好的多層感知機。與隨機初始化模型引數不同,我們在這裡直接 讀取儲存在檔案裡的引數
net2 = MLP()
net2.load_parameters(filename)
#因為這兩個例項都有同樣的模型引數,那麼對同一個輸入X的計算結果將會是一樣的
Y2 = net2(X)
Y2 == Y