到目前為止,我們討論了如何處理數(shù)據(jù)以及如何構(gòu)建、訓(xùn)練和測試深度學(xué)習(xí)模型。然而,在某些時候,我們希望對學(xué)習(xí)的模型感到滿意,我們希望保存結(jié)果以供以后在各種情況下使用(甚至可能在部署中進行預(yù)測)。此外,在運行較長的訓(xùn)練過程時,最佳做法是定期保存中間結(jié)果(檢查點),以確保如果我們被服務(wù)器的電源線絆倒,我們不會損失幾天的計算量。因此,是時候?qū)W習(xí)如何加載和存儲單個權(quán)重向量和整個模型了。本節(jié)解決這兩個問題。
import torch
from torch import nn
from torch.nn import functional as F
import flax
import jax
from flax import linen as nn
from flax.training import checkpoints
from jax import numpy as jnp
from d2l import jax as d2l
import numpy as np
import tensorflow as tf
6.6.1. 加載和保存張量
對于單個張量,我們可以直接調(diào)用load
和save
函數(shù)分別進行讀寫。這兩個函數(shù)都需要我們提供一個名稱,并且save
需要將要保存的變量作為輸入。
我們現(xiàn)在可以將存儲文件中的數(shù)據(jù)讀回內(nèi)存。
tensor([0, 1, 2, 3])
x2 = jnp.load('x-file.npy', allow_pickle=True)
x2
Array([0, 1, 2, 3], dtype=int32)
我們可以存儲張量列表并將它們讀回內(nèi)存。
y = torch.zeros(4)
torch.save([x, y],'x-files')
x2, y2 = torch.load('x-files')
(x2, y2)
(tensor([0, 1, 2, 3]), tensor([0., 0., 0., 0.]))
(array([0., 1., 2., 3.]), array([0., 0., 0., 0.]))
(Array([0., 1., 2., 3.], dtype=float32),
Array([0., 0., 0., 0.], dtype=float32))
我們甚至可以編寫和讀取從字符串映射到張量的字典。當(dāng)我們想要讀取或?qū)懭肽P椭械乃袡?quán)重時,這很方便。
{'x': tensor([0, 1, 2, 3]), 'y': tensor([0., 0., 0., 0.])}
{'x': array([0., 1., 2., 3.]), 'y': array([0., 0., 0., 0.])}
array({'x': Array([0, 1, 2, 3], dtype=int32), 'y': Array([0., 0., 0., 0.], dtype=float32)},
dtype=object)
array({'x': <tf.Tensor: shape=(4,), dtype=int32, numpy=array([0, 1, 2, 3], dtype=int32)>, 'y': <tf.Tensor: shape=(4,), dtype=float32, numpy=array([0., 0., 0., 0.], dtype=float32)>},
dtype=object)
6.6.2. 加載和保存模型參數(shù)
保存單個權(quán)重向量(或其他張量)很有用,但如果我們想保存(并稍后加載)整個模型,它會變得非常乏味。畢竟,我們可能散布著數(shù)百個參數(shù)組。出于這個原因,深度學(xué)習(xí)框架提供了內(nèi)置功能來加載和保存整個網(wǎng)絡(luò)。需要注意的一個重要細(xì)節(jié)是,這會保存模型參數(shù)而不是整個模型。例如,如果我們有一個 3 層的 MLP,我們需要單獨指定架構(gòu)。這樣做的原因是模型本身可以包含任意代碼,因此它們不能自然地序列化。因此,為了恢復(fù)模型,我們需要用代碼生成架構(gòu),然后從磁盤加載參數(shù)。讓我們從我們熟悉的 MLP 開始。
class MLP(nn.Module):
def __init__(self):
super().__init__()
self.hidden = nn.LazyLinear(256)
self.output = nn.LazyLinear(10)
def forward(self, x):
return self.output(F.relu(self.hidden(x)))
net = MLP()
X = torch.randn(size=(2, 20))
Y = net(X)
評論
查看更多