Parametre Yönetimi ================== Bir mimari seçip hiper parametrelerimizi belirledikten sonra, hedefimiz yitim işlevimizi en aza indiren parametre değerlerini bulmak olduğu eğitim döngüsüne geçiyoruz. Eğitimden sonra, gelecekteki tahminlerde bulunmak için bu parametrelere ihtiyacımız olacak. Ek olarak, bazen parametreleri başka bir bağlamda yeniden kullanmak, modelimizi başka bir yazılımda yürütülebilmesi için diske kaydetmek veya bilimsel anlayış kazanma umuduyla incelemek için ayıklamak isteyeceğiz. Çoğu zaman, ağır işlerin üstesinden gelmek için derin öğrenme çerçevelerine dayanarak, parametrelerin nasıl beyan edildiğine ve değiştirildiğine dair işin esas ayrıntıları görmezden gelebileceğiz. Bununla birlikte, standart katmanlara sahip yığılmış mimarilerden uzaklaştığımızda, bazen parametreleri bildirme ve onların üstünde oynama yabani otlarına girmemizi gerekecektir. Bu bölümde aşağıdakileri ele alıyoruz: - Hata ayıklama, teşhis ve görselleştirmeler için parametrelere erişim. - Parametre ilkletme. - Parametreleri farklı model bileşenleri arasında paylaşma. Tek bir gizli katmana sahip bir MLP'ye odaklanarak başlıyoruz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python from mxnet import init, np, npx from mxnet.gluon import nn npx.set_np() net = nn.Sequential() net.add(nn.Dense(8, activation='relu')) net.add(nn.Dense(1)) net.initialize() # Varsayılan ilkleme yöntemini kullan X = np.random.uniform(size=(2, 4)) net(X) # İleri hesaplama .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[0.0054572 ], [0.00488594]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python import torch from torch import nn net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 1)) X = torch.rand(size=(2, 4)) net(X) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[-0.4043], [-0.3974]], grad_fn=) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python import tensorflow as tf net = tf.keras.models.Sequential([ tf.keras.layers.Flatten(), tf.keras.layers.Dense(4, activation=tf.nn.relu), tf.keras.layers.Dense(1), ]) X = tf.random.uniform((2, 4)) net(X) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Parametre Erişimi ----------------- Zaten bildiğiniz modellerden parametrelere nasıl erişileceğiyle başlayalım. Bir model ``Sequential`` sınıfı aracılığıyla tanımlandığında, ilk olarak herhangi bir katmana, bir listeymiş gibi modelde üzerinden indeksleme ile erişebiliriz. Her katmanın parametreleri, özelliklerinde uygun bir şekilde bulunur. Tam bağlı ikinci katmanın parametrelerini aşağıdaki gibi irdeleyebiliriz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print(net[1].params) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output dense1_ ( Parameter dense1_weight (shape=(1, 8), dtype=float32) Parameter dense1_bias (shape=(1,), dtype=float32) ) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print(net[2].state_dict()) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output OrderedDict([('weight', tensor([[ 0.0882, -0.0851, -0.0998, -0.0520, 0.1348, 0.3360, -0.1585, -0.1034]])), ('bias', tensor([-0.3121]))]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print(net.layers[2].weights) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output [, ] .. raw:: html
.. raw:: html
Çıktı bize birkaç önemli şey gösteriyor. İlk olarak, bu tam bağlı katman, sırasıyla o katmanın ağırlıklarına ve ek girdilerine karşılık gelen iki parametre içerir. Her ikisi de tek hassas basamaklı kayan virgüllü sayı (float32) olarak saklanır. Parametrelerin adlarının, yüzlerce katman içeren bir ağda bile, her katmanın parametrelerini benzersiz şekilde tanımlamamıza izin verdiğini unutmayın. Hedeflenen Parametreler ~~~~~~~~~~~~~~~~~~~~~~~ Her parametrenin, parametre sınıfının bir örneği olarak temsil edildiğine dikkat edin. Parametrelerle yararlı herhangi bir şey yapmak için önce altta yatan sayısal değerlere erişmemiz gerekir. Bunu yapmanın birkaç yolu var. Bazıları daha basitken diğerleri daha geneldir. Aşağıdaki kod, bir parametre sınıfı örneği döndüren ikinci sinir ağı katmanından ek girdiyi dışarı çıkarır ve dahası bu parametrenin değerine erişim sağlar. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print(type(net[1].bias)) print(net[1].bias) print(net[1].bias.data()) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output Parameter dense1_bias (shape=(1,), dtype=float32) [0.] Parametreler; değer, gradyanlar ve ek bilgiler içeren karmaşık nesnelerdir. Bu nedenle değerleri açıkça talep etmemiz gerekiyor. Değere ek olarak, her parametre gradyana erişmemize de izin verir. Henüz bu ağ için geri yaymayı çağırmadığımız için, ağ ilk durumundadır. .. raw:: latex \diilbookstyleinputcell .. code:: python net[1].weight.grad() .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[0., 0., 0., 0., 0., 0., 0., 0.]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print(type(net[2].bias)) print(net[2].bias) print(net[2].bias.data) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output Parameter containing: tensor([-0.3121], requires_grad=True) tensor([-0.3121]) Parametreler; değer, gradyanlar ve ek bilgiler içeren karmaşık nesnelerdir. Bu nedenle değerleri açıkça talep etmemiz gerekiyor. Değere ek olarak, her parametre gradyana erişmemize de izin verir. Henüz bu ağ için geri yaymayı çağırmadığımız için, ağ ilk durumundadır. .. raw:: latex \diilbookstyleinputcell .. code:: python net[2].weight.grad == None .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output True .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print(type(net.layers[2].weights[1])) print(net.layers[2].weights[1]) print(tf.convert_to_tensor(net.layers[2].weights[1])) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tf.Tensor([0.], shape=(1,), dtype=float32) .. raw:: html
.. raw:: html
Bütün Parametrelere Bir Kerede Erişim ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Tüm parametrelerde işlem yapmamız gerektiğinde, bunlara tek tek erişmek bıktırıcı olabilir. Her bir alt bloğun parametrelerini dışarı çıkarmayı tüm ağaç boyunca tekrarlamamız gerekeceğinden, daha karmaşık bloklarla (örneğin, iç içe geçmiş bloklarla) çalıştığımızda durum özellikle kullanışsızca büyüyebilir. Aşağıda, ilk tam bağlı katmanın parametrelerine erişmeye karşılık tüm katmanlara erişmeyi gösteriyoruz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print(net[0].collect_params()) print(net.collect_params()) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output dense0_ ( Parameter dense0_weight (shape=(8, 4), dtype=float32) Parameter dense0_bias (shape=(8,), dtype=float32) ) sequential0_ ( Parameter dense0_weight (shape=(8, 4), dtype=float32) Parameter dense0_bias (shape=(8,), dtype=float32) Parameter dense1_weight (shape=(1, 8), dtype=float32) Parameter dense1_bias (shape=(1,), dtype=float32) ) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print(*[(name, param.shape) for name, param in net[0].named_parameters()]) print(*[(name, param.shape) for name, param in net.named_parameters()]) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output ('weight', torch.Size([8, 4])) ('bias', torch.Size([8])) ('0.weight', torch.Size([8, 4])) ('0.bias', torch.Size([8])) ('2.weight', torch.Size([1, 8])) ('2.bias', torch.Size([1])) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print(net.layers[1].weights) print(net.get_weights()) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output [, ] [array([[ 0.31354207, -0.2002306 , 0.04489189, 0.65902776], [-0.3884784 , -0.41679087, -0.8219113 , -0.44252217], [-0.6896628 , -0.19932956, 0.6800088 , 0.0731557 ], [-0.27203923, -0.7259777 , -0.19643682, 0.3815747 ]], dtype=float32), array([0., 0., 0., 0.], dtype=float32), array([[ 0.34046865], [-0.7770064 ], [-0.46259564], [-0.86495763]], dtype=float32), array([0.], dtype=float32)] .. raw:: html
.. raw:: html
Bu bize ağın parametrelerine erişmenin aşağıdaki gibi başka bir yolunu sağlar: .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python net.collect_params()['dense1_bias'].data() .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([0.]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python net.state_dict()['2.bias'].data .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([-0.3121]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python net.get_weights()[1] .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([0., 0., 0., 0.], dtype=float32) .. raw:: html
.. raw:: html
İçiçe Bloklardan Parametreleri Toplama ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Birden çok bloğu iç içe yerleştirirsek, parametre adlandırma kurallarının nasıl çalıştığını görelim. Bunun için önce blok üreten bir fonksiyon tanımlıyoruz (tabiri caizse bir blok fabrikası) ve sonra bunları daha büyük bloklar içinde birleştiriyoruz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def block1(): net = nn.Sequential() net.add(nn.Dense(32, activation='relu')) net.add(nn.Dense(16, activation='relu')) return net def block2(): net = nn.Sequential() for _ in range(4): # Burada iç içe konuyor net.add(block1()) return net rgnet = nn.Sequential() rgnet.add(block2()) rgnet.add(nn.Dense(10)) rgnet.initialize() rgnet(X) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[-6.3465846e-09, -1.1096752e-09, 6.4161787e-09, 6.6354140e-09, -1.1265507e-09, 1.3284951e-10, 9.3619388e-09, 3.2229084e-09, 5.9429879e-09, 8.8181435e-09], [-8.6219423e-09, -7.5150686e-10, 8.3133251e-09, 8.9321128e-09, -1.6740003e-09, 3.2405989e-10, 1.2115976e-08, 4.4926449e-09, 8.0741742e-09, 1.2075874e-08]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def block1(): return nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 4), nn.ReLU()) def block2(): net = nn.Sequential() for i in range(4): # Burada iç içe konuyor net.add_module(f'block {i}', block1()) return net rgnet = nn.Sequential(block2(), nn.Linear(4, 1)) rgnet(X) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[0.3051], [0.3051]], grad_fn=) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def block1(name): return tf.keras.Sequential([ tf.keras.layers.Flatten(), tf.keras.layers.Dense(4, activation=tf.nn.relu)], name=name) def block2(): net = tf.keras.Sequential() for i in range(4): # Burada iç içe konuyor net.add(block1(name=f'block-{i}')) return net rgnet = tf.keras.Sequential() rgnet.add(block2()) rgnet.add(tf.keras.layers.Dense(1)) rgnet(X) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Ağı tasarladığımıza göre, şimdi nasıl düzenlendiğini görelim. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print(rgnet.collect_params) print(rgnet.collect_params()) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output 32, Activation(relu)) (1): Dense(32 -> 16, Activation(relu)) ) (1): Sequential( (0): Dense(16 -> 32, Activation(relu)) (1): Dense(32 -> 16, Activation(relu)) ) (2): Sequential( (0): Dense(16 -> 32, Activation(relu)) (1): Dense(32 -> 16, Activation(relu)) ) (3): Sequential( (0): Dense(16 -> 32, Activation(relu)) (1): Dense(32 -> 16, Activation(relu)) ) ) (1): Dense(16 -> 10, linear) )> sequential1_ ( Parameter dense2_weight (shape=(32, 4), dtype=float32) Parameter dense2_bias (shape=(32,), dtype=float32) Parameter dense3_weight (shape=(16, 32), dtype=float32) Parameter dense3_bias (shape=(16,), dtype=float32) Parameter dense4_weight (shape=(32, 16), dtype=float32) Parameter dense4_bias (shape=(32,), dtype=float32) Parameter dense5_weight (shape=(16, 32), dtype=float32) Parameter dense5_bias (shape=(16,), dtype=float32) Parameter dense6_weight (shape=(32, 16), dtype=float32) Parameter dense6_bias (shape=(32,), dtype=float32) Parameter dense7_weight (shape=(16, 32), dtype=float32) Parameter dense7_bias (shape=(16,), dtype=float32) Parameter dense8_weight (shape=(32, 16), dtype=float32) Parameter dense8_bias (shape=(32,), dtype=float32) Parameter dense9_weight (shape=(16, 32), dtype=float32) Parameter dense9_bias (shape=(16,), dtype=float32) Parameter dense10_weight (shape=(10, 16), dtype=float32) Parameter dense10_bias (shape=(10,), dtype=float32) ) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print(rgnet) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output Sequential( (0): Sequential( (block 0): Sequential( (0): Linear(in_features=4, out_features=8, bias=True) (1): ReLU() (2): Linear(in_features=8, out_features=4, bias=True) (3): ReLU() ) (block 1): Sequential( (0): Linear(in_features=4, out_features=8, bias=True) (1): ReLU() (2): Linear(in_features=8, out_features=4, bias=True) (3): ReLU() ) (block 2): Sequential( (0): Linear(in_features=4, out_features=8, bias=True) (1): ReLU() (2): Linear(in_features=8, out_features=4, bias=True) (3): ReLU() ) (block 3): Sequential( (0): Linear(in_features=4, out_features=8, bias=True) (1): ReLU() (2): Linear(in_features=8, out_features=4, bias=True) (3): ReLU() ) ) (1): Linear(in_features=4, out_features=1, bias=True) ) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python print(rgnet.summary()) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output Model: "sequential_1" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= sequential_2 (Sequential) (2, 4) 80 dense_6 (Dense) (2, 1) 5 ================================================================= Total params: 85 Trainable params: 85 Non-trainable params: 0 _________________________________________________________________ None .. raw:: html
.. raw:: html
Katmanlar hiyerarşik olarak iç içe olduğundan, iç içe geçmiş listeler aracılığıyla dizinlenmiş gibi bunlara da erişebiliriz. Örneğin, birinci ana bloğa, içindeki ikinci alt bloğa ve bunun içindeki ilk katmanın ek girdisine aşağıdaki şekilde erişebiliriz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python rgnet[0][1][0].bias.data() .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python rgnet[0][1][0].bias.data .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([-0.2715, 0.3849, 0.4326, 0.4178, 0.4517, -0.2524, 0.2472, -0.1414]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python rgnet.layers[0].layers[1].layers[1].weights[1] .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Parametre İlkleme ----------------- Artık parametrelere nasıl erişeceğimizi bildiğimize göre, onları nasıl doğru şekilde ilkleteceğimize bakalım. Uygun ilkleme ihtiyacını :numref:`sec_numerical_stability` içinde tartıştık. Derin öğrenme çerçevesi katmanlarına varsayılan rastgele ilklemeler sağlar. Bununla birlikte, ağırlıklarımızı öteki farklı protokollere göre ilkletmek istiyoruz. Çerçeve, en sık kullanılan protokolleri sağlar ve ayrıca özelleştirilmiş bir ilkletici oluşturmaya izin verir. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
Varsayılan olarak, MXNet ağırlık parametrelerini :math:`U[-0.07, 0.07]` tekdüze dağılımdan rasgele çekerek ilkler ve ek girdileri sıfırlar. MXNet'in ``init`` modülü önceden ayarlı çeşitli ilkleme yöntemleri sağlar. .. raw:: html
.. raw:: html
Varsayılan olarak PyTorch, girdi ve çıktı boyutuna göre hesaplanan bir aralıktan çekerek ağırlık ve ek girdi matrislerini tekdüze olarak başlatır. PyTorch'un ``nn.init`` modülü önceden ayarlı çeşitli ilkleme yöntemleri sağlar. .. raw:: html
.. raw:: html
Varsayılan olarak Keras, girdi ve çıktı boyutuna göre hesaplanan bir aralıktan çekerek ağırlık matrislerini tekdüze olarak ilkletir ve ek girdi parametrelerinin tümü sıfır olarak atanır. TensorFlow, hem kök modülde hem de ``keras.initializers`` modülünde çeşitli ilkleme yöntemleri sağlar. .. raw:: html
.. raw:: html
Yerleşik İlkletme ~~~~~~~~~~~~~~~~~ Yerleşik ilkleticileri çağırarak ilkleyelim. Aşağıdaki kod, tüm ağırlık parametrelerini standart sapması 0.01 olan Gauss rastgele değişkenler olarak ilkletirken ek girdi parametreleri de 0 olarak atanır. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Burada 'force_reinit', daha önce ilklenmiş olsalar bile parametrelerin # yeniden ilklenmesini sağlar net.initialize(init=init.Normal(sigma=0.01), force_reinit=True) net[0].weight.data()[0] .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([-0.00324057, -0.00895028, -0.00698632, 0.01030831]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def init_normal(m): if type(m) == nn.Linear: nn.init.normal_(m.weight, mean=0, std=0.01) nn.init.zeros_(m.bias) net.apply(init_normal) net[0].weight.data[0], net[0].bias.data[0] .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output (tensor([ 0.0006, -0.0043, 0.0077, -0.0008]), tensor(0.)) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python net = tf.keras.models.Sequential([ tf.keras.layers.Flatten(), tf.keras.layers.Dense( 4, activation=tf.nn.relu, kernel_initializer=tf.random_normal_initializer(mean=0, stddev=0.01), bias_initializer=tf.zeros_initializer()), tf.keras.layers.Dense(1)]) net(X) net.weights[0], net.weights[1] .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output (, ) .. raw:: html
.. raw:: html
Ayrıca tüm parametreleri belirli bir sabit değere ilkleyebiliriz (örneğin, 1 gibi). .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python net.initialize(init=init.Constant(1), force_reinit=True) net[0].weight.data()[0] .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([1., 1., 1., 1.]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def init_constant(m): if type(m) == nn.Linear: nn.init.constant_(m.weight, 1) nn.init.zeros_(m.bias) net.apply(init_constant) net[0].weight.data[0], net[0].bias.data[0] .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output (tensor([1., 1., 1., 1.]), tensor(0.)) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python net = tf.keras.models.Sequential([ tf.keras.layers.Flatten(), tf.keras.layers.Dense( 4, activation=tf.nn.relu, kernel_initializer=tf.keras.initializers.Constant(1), bias_initializer=tf.zeros_initializer()), tf.keras.layers.Dense(1), ]) net(X) net.weights[0], net.weights[1] .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output (, ) .. raw:: html
.. raw:: html
Ayrıca belirli bloklar için farklı ilkleyiciler uygulayabiliriz. Örneğin, aşağıda ilk katmanı Xavier ilkleyicisi ile ilkliyoruz ve ikinci katmanı sabit 42 değeri ile ilkliyoruz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python net[0].weight.initialize(init=init.Xavier(), force_reinit=True) net[1].initialize(init=init.Constant(42), force_reinit=True) print(net[0].weight.data()[0]) print(net[1].weight.data()) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output [-0.17594433 0.02314097 -0.1992535 0.09509248] [[42. 42. 42. 42. 42. 42. 42. 42.]] .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def xavier(m): if type(m) == nn.Linear: nn.init.xavier_uniform_(m.weight) def init_42(m): if type(m) == nn.Linear: nn.init.constant_(m.weight, 42) net[0].apply(xavier) net[2].apply(init_42) print(net[0].weight.data[0]) print(net[2].weight.data) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([-0.0983, 0.5310, -0.2538, 0.6591]) tensor([[42., 42., 42., 42., 42., 42., 42., 42.]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python net = tf.keras.models.Sequential([ tf.keras.layers.Flatten(), tf.keras.layers.Dense( 4, activation=tf.nn.relu, kernel_initializer=tf.keras.initializers.GlorotUniform()), tf.keras.layers.Dense( 1, kernel_initializer=tf.keras.initializers.Constant(42)), ]) net(X) print(net.layers[1].weights[0]) print(net.layers[2].weights[0]) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Özelleştirilmiş İlkleme ~~~~~~~~~~~~~~~~~~~~~~~ Bazen, ihtiyaç duyduğumuz ilkletme yöntemleri derin öğrenme çerçevesi tarafından sağlanmayabilir. Aşağıdaki örnekte, herhangi bir ağırlık parametresi :math:`w` için aşağıdaki garip dağılımı kullanarak bir ilkleyici tanımlıyoruz: .. math:: \begin{aligned} w \sim \begin{cases} U(5, 10) & \text{ olasılık değeri } \frac{1}{4} \\ 0 & \text{ olasılık değeri } \frac{1}{2} \\ U(-10, -5) & \text{ olasılık değeri } \frac{1}{4} \end{cases} \end{aligned} .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
Burada ``Initializer`` sınıfının bir alt sınıfını tanımlıyoruz. Genellikle, yalnızca bir tensör bağımsız değişkeni (``data``) alan ve ona istenen ilkletilmiş değerleri atayan ``_init_weight`` işlevini uygulamamız gerekir. .. raw:: latex \diilbookstyleinputcell .. code:: python class MyInit(init.Initializer): def _init_weight(self, name, data): print('Init', name, data.shape) data[:] = np.random.uniform(-10, 10, data.shape) data *= np.abs(data) >= 5 net.initialize(MyInit(), force_reinit=True) net[0].weight.data()[:2] .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output Init dense0_weight (8, 4) Init dense1_weight (1, 8) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[ 0. , -0. , -0. , 8.522827 ], [ 0. , -8.828651 , -0. , -5.6012006]]) .. raw:: html
.. raw:: html
Yine, ``net``'e uygulamak için bir ``my_init`` işlevi uyguluyoruz. .. raw:: latex \diilbookstyleinputcell .. code:: python def my_init(m): if type(m) == nn.Linear: print("Init", *[(name, param.shape) for name, param in m.named_parameters()][0]) nn.init.uniform_(m.weight, -10, 10) m.weight.data *= m.weight.data.abs() >= 5 net.apply(my_init) net[0].weight[:2] .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output Init weight torch.Size([8, 4]) Init weight torch.Size([1, 8]) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[ 0.0000, -8.7999, 9.7935, 8.7815], [-0.0000, 0.0000, -0.0000, 5.8831]], grad_fn=) .. raw:: html
.. raw:: html
Burada ``Initializer``'ın bir alt sınıfını tanımlıyoruz ve şekil ve veri türüne göre istenen bir tensörü döndüren ``__call__`` işlevini uyguluyoruz. .. raw:: latex \diilbookstyleinputcell .. code:: python class MyInit(tf.keras.initializers.Initializer): def __call__(self, shape, dtype=None): data=tf.random.uniform(shape, -10, 10, dtype=dtype) factor=(tf.abs(data) >= 5) factor=tf.cast(factor, tf.float32) return data * factor net = tf.keras.models.Sequential([ tf.keras.layers.Flatten(), tf.keras.layers.Dense( 4, activation=tf.nn.relu, kernel_initializer=MyInit()), tf.keras.layers.Dense(1), ]) net(X) print(net.layers[1].weights[0]) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Her zaman parametreleri doğrudan ayarlama seçeneğimiz olduğunu unutmayın. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python net[0].weight.data()[:] += 1 net[0].weight.data()[0, 0] = 42 net[0].weight.data()[0] .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([42. , 1. , 1. , 9.522827]) İleri düzey kullanıcılar için bir hatırlatma: Parametreleri bir ``autograd`` (otomatik türev) kapsamında ayarlamak istiyorsanız, otomatik türev alma mekanizmalarının karıştırılmasını önlemek için ``set_data``'yı kullanmanız gerekir. .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python net[0].weight.data[:] += 1 net[0].weight.data[0, 0] = 42 net[0].weight.data[0] .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([42.0000, -7.7999, 10.7935, 9.7815]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python net.layers[1].weights[0][:].assign(net.layers[1].weights[0] + 1) net.layers[1].weights[0][0, 0].assign(42) net.layers[1].weights[0] .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Bağlı Parametreler ------------------ Genellikle, parametreleri birden çok katmanda paylaşmak isteriz. Bunu biraz daha zekice bir şekilde nasıl yapacağımızı görelim. Aşağıda yoğun (dense) bir katman ayırıyoruz ve ardından onun parametrelerini de özellikle başka bir katmanınkileri ayarlamak için kullanıyoruz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python net = nn.Sequential() # Parametrelerine atıfta bulunabilmemiz için paylaşılan katmana bir ad # vermemiz gerekiyor shared = nn.Dense(8, activation='relu') net.add(nn.Dense(8, activation='relu'), shared, nn.Dense(8, activation='relu', params=shared.params), nn.Dense(10)) net.initialize() X = np.random.uniform(size=(2, 20)) net(X) # Parametrelerin aynı olup olmadığını kontrol edin print(net[1].weight.data()[0] == net[2].weight.data()[0]) net[1].weight.data()[0, 0] = 100 # Aynı değere sahip olmak yerine aslında aynı nesne olduklarından emin olun print(net[1].weight.data()[0] == net[2].weight.data()[0]) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output [ True True True True True True True True] [ True True True True True True True True] Bu örnek, ikinci ve üçüncü katmanın parametrelerinin birbirine bağlı olduğunu göstermektedir. Sadece eşit değiller, tamamen aynı tensörle temsil ediliyorlar. Bu yüzden parametrelerden birini değiştirirsek diğeri de değişir. Merak edebilirsiniz, parametreler bağlı olduğunda gradyanlara ne olur? Model parametreleri gradyanlar içerdiğinden, ikinci ve üçüncü gizli katmanların gradyanları geri yayma sırasında birbiriyle toplanır. .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # Parametrelerine atıfta bulunabilmemiz için paylaşılan katmana bir ad # vermemiz gerekiyor shared = nn.Linear(8, 8) net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), shared, nn.ReLU(), shared, nn.ReLU(), nn.Linear(8, 1)) net(X) # Parametrelerin aynı olup olmadığını kontrol edin print(net[2].weight.data[0] == net[4].weight.data[0]) net[2].weight.data[0, 0] = 100 # Aynı değere sahip olmak yerine aslında aynı nesne olduklarından emin olun print(net[2].weight.data[0] == net[4].weight.data[0]) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([True, True, True, True, True, True, True, True]) tensor([True, True, True, True, True, True, True, True]) Bu örnek, ikinci ve üçüncü katmanın parametrelerinin birbirine bağlı olduğunu göstermektedir. Sadece eşit değiller, tamamen aynı tensörle temsil ediliyorlar. Bu yüzden parametrelerden birini değiştirirsek diğeri de değişir. Merak edebilirsiniz, parametreler bağlı olduğunda gradyanlara ne olur? Model parametreleri gradyanlar içerdiğinden, ikinci ve üçüncü gizli katmanların gradyanları geri yayma sırasında birbiriyle toplanır. .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python # tf.keras biraz farklı davranır. Yinelenen katmanı otomatik olarak kaldırır. shared = tf.keras.layers.Dense(4, activation=tf.nn.relu) net = tf.keras.models.Sequential([ tf.keras.layers.Flatten(), shared, shared, tf.keras.layers.Dense(1), ]) net(X) # Parametrelerin farklı olup olmadığını kontrol edin print(len(net.layers) == 3) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output True .. raw:: html
.. raw:: html
Özet ---- - Model parametrelerine erişmek, ilklemek ve onları bağlamak için birkaç farklı yol var. - Özelleştirilmiş ilkleme kullanabiliriz. Alıştırmalar ------------ 1. :numref:`sec_model_construction` içinde tanımlanan ``FancyMLP`` modelini kullanınız ve çeşitli katmanların parametrelerine erişiniz. 2. Farklı ilkleyicileri keşfetmek için ilkleme modülü dökümanına bakınız. 3. Paylaşılan bir parametre katmanı içeren bir MLP oluşturunuz ve onu eğitiniz. Eğitim sürecinde, her katmanın model parametrelerini ve gradyanlarını gözlemleyiniz. 4. Parametreleri paylaşmak neden iyi bir fikirdir? .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html