5.5. Dosya Okuma/Yazma¶ Open the notebook in SageMaker Studio Lab
Şu ana kadar verilerin nasıl işleneceğini ve derin öğrenme modellerinin nasıl oluşturulacağını, eğitileceğini ve test edileceğini tartıştık. Bununla birlikte, bir noktada, öğrenilmiş modellerden yeterince mutlu olacağımızı, öyle ki sonuçları daha sonra çeşitli bağlamlarda kullanmak için saklamak isteyeceğimiz umuyoruz (belki de konuşlandırmada tahminlerde bulunmak için). Ek olarak, uzun bir eğitim sürecini çalıştırırken, sunucumuzun güç kablosuna takılırsak birkaç günlük hesaplamayı kaybetmememiz için en iyi mesleki uygulama, periyodik olarak ara sonuçları kaydetmektir (kontrol noktası belirleme). Bu nedenle, hem bireysel ağırlık vektörlerini hem de tüm modelleri nasıl yükleyeceğimizi ve depolayacağımızı öğrenmenin zamanı geldi. Bu bölüm her iki sorunu da irdelemektedir.
5.5.1. Tensörleri Yükleme ve Kaydetme¶
Tek tensörler için, sırasıyla okumak ve yazmak için load
ve save
işlevlerini doğrudan çağırabiliriz. Her iki işleve de bir ad girmemiz
gerekir ve save
işlevi için kaydedilecek değişkeni de girdi olarak
girmemiz gerekir.
from mxnet import np, npx
from mxnet.gluon import nn
npx.set_np()
x = np.arange(4)
npx.save('x-file', x)
import torch
from torch import nn
from torch.nn import functional as F
x = torch.arange(4)
torch.save(x, 'x-file')
import numpy as np
import tensorflow as tf
x = tf.range(4)
np.save('x-file.npy', x)
Artık verileri kayıtlı dosyadan belleğe geri okuyabiliriz.
x2 = npx.load('x-file')
x2
[array([0., 1., 2., 3.])]
x2 = torch.load('x-file')
x2
tensor([0, 1, 2, 3])
x2 = np.load('x-file.npy', allow_pickle=True)
x2
array([0, 1, 2, 3], dtype=int32)
Tensörlerin bir listesini kaydedebilir ve bunları belleğe geri okuyabiliriz.
y = np.zeros(4)
npx.save('x-files', [x, y])
x2, y2 = npx.load('x-files')
(x2, y2)
(array([0., 1., 2., 3.]), array([0., 0., 0., 0.]))
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.]))
y = tf.zeros(4)
np.save('xy-files.npy', [x, y])
x2, y2 = np.load('xy-files.npy', allow_pickle=True)
(x2, y2)
(array([0., 1., 2., 3.]), array([0., 0., 0., 0.]))
Dizgilerden (string) tensörlere eşleşen bir sözlük bile yazabilir ve okuyabiliriz. Bu, bir modeldeki tüm ağırlıkları okumak veya yazmak istediğimizde kullanışlıdır.
mydict = {'x': x, 'y': y}
npx.save('mydict', mydict)
mydict2 = npx.load('mydict')
mydict2
{'x': array([0., 1., 2., 3.]), 'y': array([0., 0., 0., 0.])}
mydict = {'x': x, 'y': y}
torch.save(mydict, 'mydict')
mydict2 = torch.load('mydict')
mydict2
{'x': tensor([0, 1, 2, 3]), 'y': tensor([0., 0., 0., 0.])}
mydict = {'x': x, 'y': y}
np.save('mydict.npy', mydict)
mydict2 = np.load('mydict.npy', allow_pickle=True)
mydict2
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)
5.5.2. Model Parametrelerini Yükleme ve Kayıt Etme¶
Bireysel ağırlık vektörlerini (veya diğer tensörleri) kaydetmek faydalıdır, ancak tüm modeli kaydetmek (ve daha sonra yüklemek) istiyorsak bu çok bezdirici hale gelir. Sonuçta, her yere dağıtılmış yüzlerce parametre grubumuz olabilir. Bu nedenle derin öğrenme çerçevesi, tüm ağları yüklemek ve kaydetmek için yerleşik işlevsellikler sağlar. Farkında olunması gereken önemli bir ayrıntı, bunun tüm modeli değil, model parametrelerini kaydetmesidir. Örneğin, 3 katmanlı bir MLP’ye sahipsek, mimariyi ayrıca belirtmemiz gerekir. Bunun nedeni, modellerin kendilerinin keyfi kodlar içerebilmeleri, dolayısıyla doğal olarak serileştirilememeleridir. Bu nedenle, bir modeli eski haline getirmek için, kod içinde mimariyi oluşturmamız ve ardından parametreleri diskten yüklememiz gerekir. Tanıdık MLP’mizle başlayalım.
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 = np.random.uniform(size=(2, 20))
Y = net(X)
class MLP(nn.Module):
def __init__(self):
super().__init__()
self.hidden = nn.Linear(20, 256)
self.output = nn.Linear(256, 10)
def forward(self, x):
return self.output(F.relu(self.hidden(x)))
net = MLP()
X = torch.randn(size=(2, 20))
Y = net(X)
class MLP(tf.keras.Model):
def __init__(self):
super().__init__()
self.flatten = tf.keras.layers.Flatten()
self.hidden = tf.keras.layers.Dense(units=256, activation=tf.nn.relu)
self.out = tf.keras.layers.Dense(units=10)
def call(self, inputs):
x = self.flatten(inputs)
x = self.hidden(x)
return self.out(x)
net = MLP()
X = tf.random.uniform((2, 20))
Y = net(X)
Daha sonra modelin parametrelerini mlp.params
adıyla bir dosya
olarak kaydediyoruz.
net.save_parameters('mlp.params')
torch.save(net.state_dict(), 'mlp.params')
net.save_weights('mlp.params')
Modeli geri yüklemek için, orijinal MLP modelinin bir klonunu örnekliyoruz. Model parametrelerini rastgele ilklemek yerine, dosyada saklanan parametreleri doğrudan okuyoruz.
clone = MLP()
clone.load_parameters('mlp.params')
clone = MLP()
clone.load_state_dict(torch.load('mlp.params'))
clone.eval()
MLP(
(hidden): Linear(in_features=20, out_features=256, bias=True)
(output): Linear(in_features=256, out_features=10, bias=True)
)
clone = MLP()
clone.load_weights('mlp.params')
<tensorflow.python.training.tracking.util.CheckpointLoadStatus at 0x7fbfb05fcac0>
Her iki örnek de aynı model parametrelerine sahip olduğundan, aynı X
girdisinin hesaplamalı sonucu aynı olmalıdır. Bunu doğrulayalım.
Y_clone = clone(X)
Y_clone == Y
array([[ True, True, True, True, True, True, True, True, True,
True],
[ True, True, True, True, True, True, True, True, True,
True]])
Y_clone = clone(X)
Y_clone == Y
tensor([[True, True, True, True, True, True, True, True, True, True],
[True, True, True, True, True, True, True, True, True, True]])
Y_clone = clone(X)
Y_clone == Y
<tf.Tensor: shape=(2, 10), dtype=bool, numpy=
array([[ True, True, True, True, True, True, True, True, True,
True],
[ True, True, True, True, True, True, True, True, True,
True]])>
5.5.3. Özet¶
save
veload
fonksiyonları, tensör nesneler için dosya yazma/okuma gerçekleştirmek için kullanılabilir.Parametre sözlüğü aracılığıyla bir ağ için tüm parametre kümelerini kaydedebilir ve yükleyebiliriz.
Mimarinin kaydedilmesi parametreler yerine kodda yapılmalıdır.
5.5.4. Alıştırmalar¶
Eğitilmiş modelleri farklı bir cihaza konuşlandırmaya gerek olmasa bile, model parametrelerini saklamanın pratik faydaları nelerdir?
Bir ağın yalnızca belli bölümlerini farklı bir mimariye sahip bir ağa dahil edilecek şekilde yeniden kullanmak istediğimizi varsayalım. Yeni bir ağdaki eski bir ağdan ilk iki katmanı nasıl kullanmaya başlarsınız?
Ağ mimarisini ve parametrelerini kaydetmeye ne dersiniz? Mimariye ne gibi kısıtlamalar uygularsınız?