Dosya Okuma/Yazma
=================
Ş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.
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.
.. raw:: html
.. raw:: html
.. code:: python
from mxnet import np, npx
from mxnet.gluon import nn
npx.set_np()
x = np.arange(4)
npx.save('x-file', x)
.. raw:: html
.. raw:: html
.. code:: python
import torch
from torch import nn
from torch.nn import functional as F
x = torch.arange(4)
torch.save(x, 'x-file')
.. raw:: html
.. raw:: html
.. code:: python
import numpy as np
import tensorflow as tf
x = tf.range(4)
np.save('x-file.npy', x)
.. raw:: html
.. raw:: html
Artık verileri kayıtlı dosyadan belleğe geri okuyabiliriz.
.. raw:: html
.. raw:: html
.. code:: python
x2 = npx.load('x-file')
x2
.. parsed-literal::
:class: output
[array([0., 1., 2., 3.])]
.. raw:: html
.. raw:: html
.. code:: python
x2 = torch.load('x-file')
x2
.. parsed-literal::
:class: output
tensor([0, 1, 2, 3])
.. raw:: html
.. raw:: html
.. code:: python
x2 = np.load('x-file.npy', allow_pickle=True)
x2
.. parsed-literal::
:class: output
array([0, 1, 2, 3], dtype=int32)
.. raw:: html
.. raw:: html
Tensörlerin bir listesini kaydedebilir ve bunları belleğe geri
okuyabiliriz.
.. raw:: html
.. raw:: html
.. code:: python
y = np.zeros(4)
npx.save('x-files', [x, y])
x2, y2 = npx.load('x-files')
(x2, y2)
.. parsed-literal::
:class: output
(array([0., 1., 2., 3.]), array([0., 0., 0., 0.]))
.. raw:: html
.. raw:: html
.. code:: python
y = torch.zeros(4)
torch.save([x, y],'x-files')
x2, y2 = torch.load('x-files')
(x2, y2)
.. parsed-literal::
:class: output
(tensor([0, 1, 2, 3]), tensor([0., 0., 0., 0.]))
.. raw:: html
.. raw:: html
.. code:: python
y = tf.zeros(4)
np.save('xy-files.npy', [x, y])
x2, y2 = np.load('xy-files.npy', allow_pickle=True)
(x2, y2)
.. parsed-literal::
:class: output
(array([0., 1., 2., 3.]), array([0., 0., 0., 0.]))
.. raw:: html
.. raw:: html
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.
.. raw:: html
.. raw:: html
.. code:: python
mydict = {'x': x, 'y': y}
npx.save('mydict', mydict)
mydict2 = npx.load('mydict')
mydict2
.. parsed-literal::
:class: output
{'x': array([0., 1., 2., 3.]), 'y': array([0., 0., 0., 0.])}
.. raw:: html
.. raw:: html
.. code:: python
mydict = {'x': x, 'y': y}
torch.save(mydict, 'mydict')
mydict2 = torch.load('mydict')
mydict2
.. parsed-literal::
:class: output
{'x': tensor([0, 1, 2, 3]), 'y': tensor([0., 0., 0., 0.])}
.. raw:: html
.. raw:: html
.. code:: python
mydict = {'x': x, 'y': y}
np.save('mydict.npy', mydict)
mydict2 = np.load('mydict.npy', allow_pickle=True)
mydict2
.. parsed-literal::
:class: output
array({'x': , 'y': },
dtype=object)
.. raw:: html
.. raw:: html
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.
.. raw:: html
.. raw:: html
.. code:: python
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)
.. raw:: html
.. raw:: html
.. code:: python
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)
.. raw:: html
.. raw:: html
.. code:: python
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)
.. raw:: html
.. raw:: html
Daha sonra modelin parametrelerini ``mlp.params`` adıyla bir dosya
olarak kaydediyoruz.
.. raw:: html
.. raw:: html
.. code:: python
net.save_parameters('mlp.params')
.. raw:: html
.. raw:: html
.. code:: python
torch.save(net.state_dict(), 'mlp.params')
.. raw:: html
.. raw:: html
.. code:: python
net.save_weights('mlp.params')
.. raw:: html
.. raw:: html
Modeli geri yüklemek için, orijinal MLP modelinin bir klonunu
örnekliyoruz. Model parametrelerini rastgele ilklemek yerine, dosyada
saklanan parametreleri doğrudan okuyoruz.
.. raw:: html
.. raw:: html
.. code:: python
clone = MLP()
clone.load_parameters('mlp.params')
.. raw:: html
.. raw:: html
.. code:: python
clone = MLP()
clone.load_state_dict(torch.load('mlp.params'))
clone.eval()
.. parsed-literal::
:class: output
MLP(
(hidden): Linear(in_features=20, out_features=256, bias=True)
(output): Linear(in_features=256, out_features=10, bias=True)
)
.. raw:: html
.. raw:: html
.. code:: python
clone = MLP()
clone.load_weights('mlp.params')
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Her iki örnek de aynı model parametrelerine sahip olduğundan, aynı ``X``
girdisinin hesaplamalı sonucu aynı olmalıdır. Bunu doğrulayalım.
.. raw:: html
.. raw:: html
.. code:: python
Y_clone = clone(X)
Y_clone == Y
.. parsed-literal::
:class: output
array([[ True, True, True, True, True, True, True, True, True,
True],
[ True, True, True, True, True, True, True, True, True,
True]])
.. raw:: html
.. raw:: html
.. code:: python
Y_clone = clone(X)
Y_clone == Y
.. parsed-literal::
:class: output
tensor([[True, True, True, True, True, True, True, True, True, True],
[True, True, True, True, True, True, True, True, True, True]])
.. raw:: html
.. raw:: html
.. code:: python
Y_clone = clone(X)
Y_clone == Y
.. parsed-literal::
:class: output
.. raw:: html
.. raw:: html
Özet
----
- ``save`` ve ``load`` 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.
Alıştırmalar
------------
1. Eğitilmiş modelleri farklı bir cihaza konuşlandırmaya gerek olmasa
bile, model parametrelerini saklamanın pratik faydaları nelerdir?
2. 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?
3. Ağ mimarisini ve parametrelerini kaydetmeye ne dersiniz? Mimariye ne
gibi kısıtlamalar uygularsınız?
.. raw:: html
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html
`Tartışmalar `__
.. raw:: html
.. raw:: html