總結下來,就是幾個函數html
經過python的pickle完成序列化與反序列化.完成內存<-->磁盤轉換.python
state_dict()獲取模型參數.load_state_dict()加載模型參數函數
咱們能夠直接使用save
函數和load
函數分別存儲和讀取Tensor
。save
使用Python的pickle實用程序將對象進行序列化,而後將序列化的對象保存到disk,使用save
能夠保存各類對象,包括模型、張量和字典等。而laod
使用pickle unpickle工具將pickle的對象文件反序列化爲內存。
下面的例子建立了Tensor
變量x
,並將其存在文件名同爲x.pt
的文件裏。工具
import torch from torch import nn x = torch.ones(3) torch.save(x, 'x.pt')
而後咱們將數據從存儲的文件讀回內存。學習
x2 = torch.load('x.pt') x2
輸出:優化
tensor([1., 1., 1.])
咱們還能夠存儲一個Tensor
列表並讀回內存。ui
y = torch.zeros(4) torch.save([x, y], 'xy.pt') xy_list = torch.load('xy.pt') xy_list
輸出:code
[tensor([1., 1., 1.]), tensor([0., 0., 0., 0.])]
存儲並讀取一個從字符串映射到Tensor
的字典。htm
torch.save({'x': x, 'y': y}, 'xy_dict.pt') xy = torch.load('xy_dict.pt') xy
輸出:對象
{'x': tensor([1., 1., 1.]), 'y': tensor([0., 0., 0., 0.])}
在PyTorch中,Module
的可學習參數(即權重和誤差),模塊模型包含在參數中(經過model.parameters()
訪問)。state_dict
是一個從參數名稱隱射到參數Tesnor
的字典對象。
class MLP(nn.Module): def __init__(self): super(MLP, self).__init__() self.hidden = nn.Linear(3, 2) self.act = nn.ReLU() self.output = nn.Linear(2, 1) def forward(self, x): a = self.act(self.hidden(x)) return self.output(a) net = MLP() net.state_dict()
輸出:
OrderedDict([('hidden.weight', tensor([[ 0.2448, 0.1856, -0.5678], [ 0.2030, -0.2073, -0.0104]])), ('hidden.bias', tensor([-0.3117, -0.4232])), ('output.weight', tensor([[-0.4556, 0.4084]])), ('output.bias', tensor([-0.3573]))])
注意,只有具備可學習參數的層(卷積層、線性層等)纔有state_dict
中的條目優化器(optim
)也有一個state_dict
,其中包含關於優化器狀態以及所使用的超參數的信息。
optimizer = torch.optim.SGD(net.parameters(), lr=0.001, momentum=0.9) optimizer.state_dict()
輸出:
{'state': {}, 'param_groups': [{'lr': 0.001, 'momentum': 0.9, 'dampening': 0, 'weight_decay': 0, 'nesterov': False, 'params': [139952370292992, 139952370293784, 139952370294144, 139952370293496]}]}
PyTorch中保存和加載訓練模型有兩種常見的方法:
state_dict
)state_dict
(推薦方式)保存:
torch.save(model.state_dict(), PATH) # 推薦的文件後綴名是pt或pth
加載:
model = TheModelClass(*args, **kwargs) model.load_state_dict(torch.load(PATH))
保存:
torch.save(model, PATH)
加載:
model = torch.load(PATH)
咱們採用推薦的方法一來實驗一下:
X = torch.randn(2, 3) Y = net(X) PATH = "./net.pt" torch.save(net.state_dict(), PATH) net2 = MLP() net2.load_state_dict(torch.load(PATH)) Y2 = net2(X) Y2 == Y
輸出:
tensor([[1], [1]], dtype=torch.uint8)
由於這net
和net2
都有一樣的模型參數,那麼對同一個輸入X
的計算結果將會是同樣的。上面的輸出也驗證了這一點。
此外,還有一些其餘使用場景,例如GPU與CPU之間的模型保存與讀取、使用多塊GPU的模型的存儲等等,使用的時候能夠參考官方文檔。