從頭學pytorch(十二):模型保存和加載


模型讀取和存儲

總結下來,就是幾個函數

  1. torch.load()/torch.save()

通過python的pickle完成序列化與反序列化.完成內存<-->磁盤轉換.

  1. Module.state_dict()/Module.load_state_dict()

state_dict()獲取模型參數.load_state_dict()加載模型參數

讀寫Tensor

我們可以直接使用save函數和load函數分別存儲和讀取Tensorsave使用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列表並讀回內存。

y = torch.zeros(4)
torch.save([x, y], 'xy.pt')
xy_list = torch.load('xy.pt')
xy_list

輸出:

[tensor([1., 1., 1.]), tensor([0., 0., 0., 0.])]

存儲並讀取一個從字符串映射到Tensor的字典。

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.])}

state_dict

在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中保存和加載訓練模型有兩種常見的方法:

  1. 僅保存和加載模型參數(state_dict)
  2. 保存和加載整個模型

保存和加載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)

因為這netnet2都有同樣的模型參數,那么對同一個輸入X的計算結果將會是一樣的。上面的輸出也驗證了這一點。

此外,還有一些其他使用場景,例如GPU與CPU之間的模型保存與讀取、使用多塊GPU的模型的存儲等等,使用的時候可以參考官方文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM