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
mxnetpytorchtensorflow
.. 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
mxnetpytorchtensorflow
.. 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
mxnetpytorchtensorflow
.. 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
mxnetpytorchtensorflow
.. 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
mxnetpytorchtensorflow
.. 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
mxnetpytorchtensorflow
.. 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
mxnetpytorchtensorflow
.. 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
mxnetpytorchtensorflow
.. 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
mxnetpytorchtensorflow
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html