.. _sec_gru: Geçitli Yinelemeli Birimler (GRU) ================================= :numref:`sec_bptt` içinde, gradyanların RNN'lerde nasıl hesaplandığını tartıştık. Özellikle matrislerin uzun çarpımlarının kaybolan veya patlayan gradyanlara yol açabileceğini gördük. Bu tür gradyan sıradışılıklarının pratikte ne anlama geldiğini hakkında kısaca düşünelim: - Gelecekteki tüm gözlemleri tahmin etmek için erken bir gözlemin son derece önemli olduğu bir durumla karşılaşabiliriz. Biraz karmaşık bir durumu düşünün; ilk gözlem bir sağlama toplamı (checksum) içerir ve hedef de sağlama toplamının dizinin sonunda doğru olup olmadığını fark etmektir. Bu durumda, ilk andıcın etkisi hayati önem taşır. Hayati önem taşıyan erken bilgileri bir *bellek hücresinde* depolamak için bazı mekanizmalara sahip olmak isteriz. Böyle bir mekanizma olmadan, bu gözlemlere çok büyük bir gradyan atamak zorunda kalacağız, çünkü sonraki tüm gözlemleri etkilerler. - Bazı andıçların uygun gözlem taşımadığı durumlarla karşılaşabiliriz. Örneğin, bir web sayfasını ayrıştırırken, sayfada iletilen duygunun değerlendirilmesi amacıyla alakasız olan yardımcı HTML kodu olabilir. Gizli durum temsilinde bu tür andıçları *atlamak* için birtakım mekanizmaya sahip olmak isteriz. - Bir dizinin parçaları arasında mantıksal bir kırılma olduğu durumlarla karşılaşabiliriz. Örneğin, bir kitaptaki bölümler arasında bir geçiş veya menkul kıymetler piyasasında hisse değerleri arasında bir geçiş olabilir. Bu durumda iç durum temsilimizi *sıfırlamak* için bir araca sahip olmak güzel olurdu. Bunu ele almak için bir dizi yöntem önerilmiştir. İlk öncülerden biri :numref:`sec_lstm` içinde tartışacağımız uzun ömürlü kısa-dönem belleğidir :cite:`Hochreiter.Schmidhuber.1997`. Geçitli yinelemeli birim (GRU) :cite:`Cho.Van-Merrienboer.Bahdanau.ea.2014`, genellikle benzer performans sunan ve hesaplanmanın önemli ölçüde daha hızlı olduğu biraz daha elverişli bir türdür :cite:`Chung.Gulcehre.Cho.ea.2014`. Sadeliğinden dolayı, GRU ile başlayalım. Geçitli Gizli Durum ------------------- Sıradan RNN ve GRU'lar arasındaki anahtar ayrım, ikincisinin gizli durumu geçitlemeyi desteklemesidir. Bu, gizli bir durumun *güncellenmesi* gerektiği zamanlara ve ayrıca *sıfırlanması* gerektiği zamanlara yönelik özel mekanizmalarımız olduğu anlamına gelir. Bu mekanizmalar öğrenilir ve yukarıda listelenen kaygıları ele alır. Örneğin, ilk andıç büyük önem taşıyorsa, ilk gözlemden sonra gizli durumu güncellememeyi öğreneceğiz. Aynı şekilde, ilgisiz geçici gözlemleri atlamayı öğreneceğiz. Son olarak, gerektiğinde gizli durumu sıfırlamayı öğreneceğiz. Bunları aşağıda ayrıntılı olarak tartışıyoruz. Sıfırlama Geçidi ve Güncelleme Geçidi ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Tanışmamız gereken ilk kavramlar, *sıfırlama geçidi* ve *güncelleme geçidi*\ dir. Onları :math:`(0, 1)`'de girdileri olan vektörler olacak şekilde tasarlıyoruz, böylece dışbükey bileşimleri gerçekleştirebiliriz. Örneğin, bir sıfırlama geçidi, önceki durumun ne kadarını hala hatırlamak isteyebileceğimizi kontrol etmemizi sağlar. Aynı şekilde, bir güncelleme geçidi yeni durumun ne kadarının eski durumun bir kopyası olacağını kontrol etmemizi sağlayacaktır. Bu geçitleri işleyerek başlıyoruz. :numref:`fig_gru_1`, mevcut zaman adımının girdiyi ve önceki zaman adımının gizli durumu göz önüne alındığında, bir GRU'daki hem sıfırlama hem de güncelleme geçitleri için girdileri göstermektedir. İki geçidin çıktıları, sigmoid etkinleştirme işlevine sahip iki tam bağlı katman tarafından verilir. .. _fig_gru_1: .. figure:: ../img/gru-1.svg Bir GRU modelinde sıfırlama ve güncelleme geçitlerini hesaplama. Matematiksel olarak, belirli bir zaman adımı :math:`t` için, girdinin bir minigrubun :math:`\mathbf{X}_t \in \mathbb{R}^{n \times d}` (örnek sayısı: :math:`n`, girdi sayısı: :math:`d`) ve önceki zaman adımının gizli durumunun :math:`\mathbf{H}_{t-1} \in \mathbb{R}^{n \times h}` (gizli birimlerin sayısı: :math:`h`) olduğunu varsayalım. O zaman, sıfırlama geçidi :math:`\mathbf{R}_t \in \mathbb{R}^{n \times h}` ve güncelleştirme geçidi :math:`\mathbf{Z}_t \in \mathbb{R}^{n \times h}` aşağıdaki gibi hesaplanır: .. math:: \begin{aligned} \mathbf{R}_t = \sigma(\mathbf{X}_t \mathbf{W}_{xr} + \mathbf{H}_{t-1} \mathbf{W}_{hr} + \mathbf{b}_r),\\ \mathbf{Z}_t = \sigma(\mathbf{X}_t \mathbf{W}_{xz} + \mathbf{H}_{t-1} \mathbf{W}_{hz} + \mathbf{b}_z), \end{aligned} burada :math:`\mathbf{W}_{xr}, \mathbf{W}_{xz} \in \mathbb{R}^{d \times h}` ve :math:`\mathbf{W}_{hr}, \mathbf{W}_{hz} \in \mathbb{R}^{h \times h}` ağırlık parametreleridir ve :math:`\mathbf{b}_r, \mathbf{b}_z \in \mathbb{R}^{1 \times h}` ek girdilerdir. Yayınlamanın (bkz. :numref:`subsec_broadcasting`) toplama sırasında tetiklendiğini unutmayın. Girdi değerlerini :math:`(0, 1)` aralığına dönüştürmek için sigmoid işlevleri (:numref:`sec_mlp` içinde tanıtıldığı gibi) kullanırız. Aday Gizli Durum ~~~~~~~~~~~~~~~~ Ardından, :math:`\mathbf{R}_t`'i sıfırlama geçidini :eq:`rnn_h_with_state` denklemindeki normal gizli durum güncelleme mekanizmasıyla tümleştirelim. Bizi :math:`t` zaman adımında aşağıdaki *aday gizli durum* :math:`\tilde{\mathbf{H}}_t \in \mathbb{R}^{n \times h}`'ye yönlendirir: .. math:: \tilde{\mathbf{H}}_t = \tanh(\mathbf{X}_t \mathbf{W}_{xh} + \left(\mathbf{R}_t \odot \mathbf{H}_{t-1}\right) \mathbf{W}_{hh} + \mathbf{b}_h), :label: gru_tilde_H burada :math:`\mathbf{W}_{xh} \in \mathbb{R}^{d \times h}` ve :math:`\mathbf{W}_{hh} \in \mathbb{R}^{h \times h}` ağırlık parametreleridir, :math:`\mathbf{b}_h \in \mathbb{R}^{1 \times h}` ek girdi ve :math:`\odot` sembolü Hadamard (eleman yönlü) çarpım işlemidir. Burada, aday gizli durumdaki değerlerin :math:`(-1, 1)` aralığında kalmasını sağlamak için tanh şeklinde bir doğrusal olmayan bir işlev kullanıyoruz. Sonuç, hala güncelleme geçidinin eylemini dahil etmemiz gerektiğinden bir *adaydır*. :eq:`rnn_h_with_state` ile karşılaştırıldığında, önceki durumların etkisi :math:`\mathbf{R}_t` ve :math:`\mathbf{H}_{t-1}`'nin :eq:`gru_tilde_H` denkleminde eleman yönlü çarpımı ile azaltılabilir. Sıfırlama geçidi :math:`\mathbf{R}_t` girdileri 1'e yakın olduğunda, :eq:`rnn_h_with_state` denkleminde olduğu gibi sıradan bir RNN elde ederiz. Sıfırlama geçidi :math:`\mathbf{R}_t`'nın 0'a yakın olan tüm girdileri için, aday gizli durum, girdisi :math:`\mathbf{X}_t` olan bir MLP'nin sonucudur. Önceden var olan herhangi bir gizli durum böylece *sıfırlanarak* varsayılanlara döner. :numref:`fig_gru_2` sıfırlama geçidini uyguladıktan sonraki hesaplama akışını gösterir. .. _fig_gru_2: .. figure:: ../img/gru-2.svg GRU'de aday gizli durumu hesaplama. Gizli Durum ~~~~~~~~~~~ Son olarak, güncelleme geçidi :math:`\mathbf{Z}_t`'nin etkisini dahil etmemiz gerekiyor. Bu, yeni gizli durum :math:`\mathbf{H}_t \in \mathbb{R}^{n \times h}`'in sadece eski durum :math:`\mathbf{H}_{t-1}`'in ve yeni aday durum :math:`\tilde{\mathbf{H}}_t`'nin ne kadar kullanıldığını belirler. :math:`\mathbf{Z}_t` güncelleme geçidi bu amaçla kullanılabilir, basitçe hem :math:`\mathbf{H}_{t-1}` hem de :math:`\tilde{\mathbf{H}}_t` arasındaki eleman yönlü dışbükey birleşimler alarak kullanılabilir. Bu da, GRU için son güncelleştirme denklemine yol açar: .. math:: \mathbf{H}_t = \mathbf{Z}_t \odot \mathbf{H}_{t-1} + (1 - \mathbf{Z}_t) \odot \tilde{\mathbf{H}}_t. Güncelleme geçidi :math:`\mathbf{Z}_t` 1'e yakın olduğunda, sadece eski durumu koruruz. Bu durumda :math:`\mathbf{X}_t`'den gelen bilgiler esasen göz ardı edilir, bağlılık zincirinde :math:`t` zaman adımı etkin bir şekilde atlanır. Buna karşılık, :math:`\mathbf{Z}_t` 0'a yakın olduğunda, yeni gizli durum :math:`\mathbf{H}_t` aday gizli durum :math:`\tilde{\mathbf{H}}_t`'ye yaklaşır. Bu tasarımlar, RNN'lerdeki kaybolan gradyan sorunuyla başa çıkmamıza ve büyük zaman adım mesafeleri olan diziler için bağlılıkları daha iyi yakalamamıza yardımcı olabilirler. Örneğin, güncelleme geçidi tüm bir alt dizinin tüm zaman adımları için 1'e yakınsa, başlangıç zamanındaki eski gizli durum alt sıranın uzunluğuna bakılmaksızın kolayca korunur ve sonuna kadar geçirilir. :numref:`fig_gru_3` güncelleme geçidi harekete geçtikten sonra hesaplama akışını gösterir. .. _fig_gru_3: .. figure:: ../img/gru-3.svg GRU modelinde gizli durumu hesaplama. Özetle, GRU'lar aşağıdaki iki ayırt edici özelliğe sahiptir: - Sıfırlama geçitleri dizilerdeki kısa vadeli bağlılıkları yakalamaya yardımcı olur. - Güncelleme geçitleri dizilerdeki uzun vadeli bağlılıkları yakalamaya yardımcı olur. Sıfırdan Uygulama ----------------- GRU modelini daha iyi anlamak için sıfırdan uygulayalım. :numref:`sec_rnn_scratch` içinde kullandığımız zaman makinesi veri kümesini okuyarak başlıyoruz. Veri kümesini okuma kodu aşağıda verilmiştir. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python from d2l import mxnet as d2l from mxnet import np, npx from mxnet.gluon import rnn npx.set_np() batch_size, num_steps = 32, 35 train_iter, vocab = d2l.load_data_time_machine(batch_size, num_steps) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python import torch from torch import nn from d2l import torch as d2l batch_size, num_steps = 32, 35 train_iter, vocab = d2l.load_data_time_machine(batch_size, num_steps) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python import tensorflow as tf from d2l import tensorflow as d2l batch_size, num_steps = 32, 35 train_iter, vocab = d2l.load_data_time_machine(batch_size, num_steps) .. raw:: html
.. raw:: html
Model Parametrelerini İlkleme ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Bir sonraki adım model parametrelerini ilklemektir. Ağırlıkları standart sapması 0.01 olan bir Gauss dağılımından çekiyoruz ve ek girdiyi 0'a ayarlıyoruz. Hiper parametre ``num_hiddens``, gizli birimlerin sayısını tanımlar. Güncelleme geçidi, sıfırlama geçidi, aday gizli durumu ve çıktı katmanı ile ilgili tüm ağırlıkları ve ek girdileri ilkleyeceğiz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def get_params(vocab_size, num_hiddens, device): num_inputs = num_outputs = vocab_size def normal(shape): return np.random.normal(scale=0.01, size=shape, ctx=device) def three(): return (normal((num_inputs, num_hiddens)), normal((num_hiddens, num_hiddens)), np.zeros(num_hiddens, ctx=device)) W_xz, W_hz, b_z = three() # Geçit parametrelerini güncelle W_xr, W_hr, b_r = three() # Geçit parametrelerini sıfırla W_xh, W_hh, b_h = three() # Aday gizli durum parametreleri # Çıktı katmanı parametreleri W_hq = normal((num_hiddens, num_outputs)) b_q = np.zeros(num_outputs, ctx=device) # Gradyanları iliştir params = [W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q] for param in params: param.attach_grad() return params .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def get_params(vocab_size, num_hiddens, device): num_inputs = num_outputs = vocab_size def normal(shape): return torch.randn(size=shape, device=device)*0.01 def three(): return (normal((num_inputs, num_hiddens)), normal((num_hiddens, num_hiddens)), torch.zeros(num_hiddens, device=device)) W_xz, W_hz, b_z = three() # Geçit parametrelerini güncelle W_xr, W_hr, b_r = three() # Geçit parametrelerini sıfırla W_xh, W_hh, b_h = three() # Aday gizli durum parametreleri # Çıktı katmanı parametreleri W_hq = normal((num_hiddens, num_outputs)) b_q = torch.zeros(num_outputs, device=device) # Gradyanları iliştir params = [W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q] for param in params: param.requires_grad_(True) return params .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def get_params(vocab_size, num_hiddens): num_inputs = num_outputs = vocab_size def normal(shape): return tf.random.normal(shape=shape,stddev=0.01,mean=0,dtype=tf.float32) def three(): return (tf.Variable(normal((num_inputs, num_hiddens)), dtype=tf.float32), tf.Variable(normal((num_hiddens, num_hiddens)), dtype=tf.float32), tf.Variable(tf.zeros(num_hiddens), dtype=tf.float32)) W_xz, W_hz, b_z = three() # Geçit parametrelerini güncelle W_xr, W_hr, b_r = three() # Geçit parametrelerini sıfırla W_xh, W_hh, b_h = three() # Aday gizli durum parametreleri # Çıktı katmanı parametreleri W_hq = tf.Variable(normal((num_hiddens, num_outputs)), dtype=tf.float32) b_q = tf.Variable(tf.zeros(num_outputs), dtype=tf.float32) params = [W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q] return params .. raw:: html
.. raw:: html
Modelin Tanımlanması ~~~~~~~~~~~~~~~~~~~~ Şimdi gizli durum ilkleme işlevini tanımlayacağız ``init_gru_state``. :numref:`sec_rnn_scratch` içinde tanımlanan ``init_rnn_state`` işlevi gibi, bu işlev, değerleri sıfırlar olan (toplu boyut, gizli birim sayısı) şekline sahip bir tensör döndürür. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def init_gru_state(batch_size, num_hiddens, device): return (np.zeros(shape=(batch_size, num_hiddens), ctx=device), ) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def init_gru_state(batch_size, num_hiddens, device): return (torch.zeros((batch_size, num_hiddens), device=device), ) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def init_gru_state(batch_size, num_hiddens): return (tf.zeros((batch_size, num_hiddens)), ) .. raw:: html
.. raw:: html
Şimdi GRU modelini tanımlamaya hazırız. Yapısı, güncelleme denklemlerinin daha karmaşık olması dışında, temel RNN hücresinin yapısı ile aynıdır. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def gru(inputs, state, params): W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q = params H, = state outputs = [] for X in inputs: Z = npx.sigmoid(np.dot(X, W_xz) + np.dot(H, W_hz) + b_z) R = npx.sigmoid(np.dot(X, W_xr) + np.dot(H, W_hr) + b_r) H_tilda = np.tanh(np.dot(X, W_xh) + np.dot(R * H, W_hh) + b_h) H = Z * H + (1 - Z) * H_tilda Y = np.dot(H, W_hq) + b_q outputs.append(Y) return np.concatenate(outputs, axis=0), (H,) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def gru(inputs, state, params): W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q = params H, = state outputs = [] for X in inputs: Z = torch.sigmoid((X @ W_xz) + (H @ W_hz) + b_z) R = torch.sigmoid((X @ W_xr) + (H @ W_hr) + b_r) H_tilda = torch.tanh((X @ W_xh) + ((R * H) @ W_hh) + b_h) H = Z * H + (1 - Z) * H_tilda Y = H @ W_hq + b_q outputs.append(Y) return torch.cat(outputs, dim=0), (H,) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def gru(inputs, state, params): W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q = params H, = state outputs = [] for X in inputs: X = tf.reshape(X,[-1,W_xh.shape[0]]) Z = tf.sigmoid(tf.matmul(X, W_xz) + tf.matmul(H, W_hz) + b_z) R = tf.sigmoid(tf.matmul(X, W_xr) + tf.matmul(H, W_hr) + b_r) H_tilda = tf.tanh(tf.matmul(X, W_xh) + tf.matmul(R * H, W_hh) + b_h) H = Z * H + (1 - Z) * H_tilda Y = tf.matmul(H, W_hq) + b_q outputs.append(Y) return tf.concat(outputs, axis=0), (H,) .. raw:: html
.. raw:: html
Eğitme ve Tahmin Etme ~~~~~~~~~~~~~~~~~~~~~ Eğitim ve tahmin, tam olarak :numref:`sec_rnn_scratch` içindekiyle aynı şekilde çalışır. Eğitimden sonra, sırasıyla sağlanan “zaman yolcusu” ve “yolcusu” ön eklerini takip eden eğitim kümesindeki şaşkınlığı ve tahmin edilen diziyi yazdırırız. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python vocab_size, num_hiddens, device = len(vocab), 256, d2l.try_gpu() num_epochs, lr = 500, 1 model = d2l.RNNModelScratch(len(vocab), num_hiddens, device, get_params, init_gru_state, gru) d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output perplexity 1.1, 9994.0 tokens/sec on gpu(0) time traveller with a slight accession ofcheerfulness really thi traveller fimensions but how about up and down gravitation .. figure:: output_gru_b77a34_51_1.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python vocab_size, num_hiddens, device = len(vocab), 256, d2l.try_gpu() num_epochs, lr = 500, 1 model = d2l.RNNModelScratch(len(vocab), num_hiddens, device, get_params, init_gru_state, gru) d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output perplexity 1.1, 24069.9 tokens/sec on cuda:0 time traveller for so it will be convenient to speak of himwas e traveller aboutter new yarkmust of the ithed heldrea seamo .. figure:: output_gru_b77a34_54_1.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python vocab_size, num_hiddens, device_name = len(vocab), 256, d2l.try_gpu()._device_name # tensorflow eğitim stratejisini tanımlama strategy = tf.distribute.OneDeviceStrategy(device_name) num_epochs, lr = 500, 1 with strategy.scope(): model = d2l.RNNModelScratch(len(vocab), num_hiddens, init_gru_state, gru, get_params) d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, strategy) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output perplexity 1.1, 4763.0 tokens/sec on /GPU:0 time traveller for so it will be convenient to speak of himwas e travellerit would be remarkably convenient for the historia .. figure:: output_gru_b77a34_57_1.svg .. raw:: html
.. raw:: html
Kısa Uygulama ------------- Üst düzey API'lerde, doğrudan bir GPU modelini oluşturabiliriz. Bu, yukarıda açıkça yaptığımız tüm yapılandırma ayrıntılarını gizler. Kod, daha önce yazdığımız birçok ayrıntı için Python yerine derlenmiş operatörleri kullandığı için önemli ölçüde daha hızlıdır. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python gru_layer = rnn.GRU(num_hiddens) model = d2l.RNNModel(gru_layer, len(vocab)) d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output perplexity 1.1, 162532.0 tokens/sec on gpu(0) time traveller for so it will be convenient to speak of himwas e travelleryou can show black is white by argument said filby .. figure:: output_gru_b77a34_63_1.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python num_inputs = vocab_size gru_layer = nn.GRU(num_inputs, num_hiddens) model = d2l.RNNModel(gru_layer, len(vocab)) model = model.to(device) d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output perplexity 1.0, 325398.8 tokens/sec on cuda:0 time travelleryou can show black is white by argument said filby travelleryou can show black is white by argument said filby .. figure:: output_gru_b77a34_66_1.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python gru_cell = tf.keras.layers.GRUCell(num_hiddens, kernel_initializer='glorot_uniform') gru_layer = tf.keras.layers.RNN(gru_cell, time_major=True, return_sequences=True, return_state=True) device_name = d2l.try_gpu()._device_name strategy = tf.distribute.OneDeviceStrategy(device_name) with strategy.scope(): model = d2l.RNNModel(gru_layer, vocab_size=len(vocab)) d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, strategy) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output perplexity 1.0, 6936.2 tokens/sec on /GPU:0 time traveller for so it will be convenient to speak of himwas e travelleryou can show black is white by argument said filby .. figure:: output_gru_b77a34_69_1.svg .. raw:: html
.. raw:: html
Özet ---- - Geçitli RNN'ler, büyük zaman adım mesafeleri olan diziler için bağlılıkları daha iyi yakalayabilir. - Sıfırlama geçitleri dizilerdeki kısa vadeli bağlılıkları yakalamaya yardımcı olur. - Güncelleme geçitleri dizilerdeki uzun vadeli bağlılıkları yakalamaya yardımcı olur. - GRU'lar, sıfırlama geçidi açıldığında en uç durum olarak temel RNN'leri içerir. Ayrıca güncelleme geçidini açarak alt dizileri atlayabilirler. Alıştırmalar ------------ 1. Sadece :math:`t'` zaman adımını girdi olarak kullanarak :math:`t > t'` zaman adımlarındaki çıktıyı tahmin etmek için istediğimizi varsayalım. Her zaman adımında sıfırlama ve güncelleme geçitleri için en iyi değerler nelerdir? 2. Hiper parametreleri ayarlayın ve çalışma süresi, şaşkınlık ve çıktı dizisi üzerindeki etkilerini analiz edin. 3. ``rnn.RNN`` ve ``rnn.GRU`` uygulamaları için çalışma zamanı, şaşkınlık ve çıktı dizgilerini birbirleriyle karşılaştırın. 4. Yalnızca GRU'nun parçalarını, örneğin yalnızca bir sıfırlama geçidi veya yalnızca bir güncelleme geçidi, uygularsanız ne olur? .. raw:: html
mxnetpytorch
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html