.. _sec_rnn-concise: Yinelemeli Sinir Ağlarının Kısa Uygulaması ========================================== :numref:`sec_rnn_scratch` RNN'lerin nasıl uygulandığını görmek için öğretici olsa da, bu uygun veya hızlı değildir. Bu bölümde, derin öğrenme çerçevesinin üst düzey API'leri tarafından sağlanan işlevleri kullanarak aynı dil modelinin nasıl daha verimli bir şekilde uygulanacağı gösterilecektir. Daha önce olduğu gibi zaman makinesi veri kümesini okuyarak başlıyoruz. .. 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 nn, 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 torch.nn import functional as F 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
Modelin Tanımlanması -------------------- Üst seviye API'ler, yinelemeli sinir ağlarının uygulamalarını sağlar. Yinelemeli sinir ağı tabakası ``rnn_layer``'i tek bir gizli katman ve 256 gizli birimle inşa ediyoruz. Aslında, birden fazla katmana sahip olmanın ne anlama geldiğini henüz tartışmadık; onu :numref:`sec_deep_rnn` içinde göreceğiz. Şimdilik, birden çok katmanın, bir sonraki RNN katmanı için girdi olarak kullanılan bir RNN katmanının çıktısı anlamına geldiğini söylemek yeterlidir. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python num_hiddens = 256 rnn_layer = rnn.RNN(num_hiddens) rnn_layer.initialize() Gizli durumu ilklemek basittir. Üye fonksiyonu ``begin_state``'i çağırıyoruz . Bu, minigruptaki her örnek için (gizli katman sayısı, grup boyutu, gizli birim sayısı) şekilli bir ilk gizli durumu içeren liste (``state``) döndürür. Daha sonra tanıtılacak bazı modellerde (örneğin, uzun ömürlü kısa-dönem belleği), bu liste başka bilgiler de içerir. .. raw:: latex \diilbookstyleinputcell .. code:: python state = rnn_layer.begin_state(batch_size=batch_size) len(state), state[0].shape .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output (1, (1, 32, 256)) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python num_hiddens = 256 rnn_layer = nn.RNN(len(vocab), num_hiddens) Şekli (gizli katman sayısı, grup boyutu, gizli birim sayısı) olan bir tensörü gizli durumu ilklemek için kullanırız. .. raw:: latex \diilbookstyleinputcell .. code:: python state = torch.zeros((1, batch_size, num_hiddens)) state.shape .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output torch.Size([1, 32, 256]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python num_hiddens = 256 rnn_cell = tf.keras.layers.SimpleRNNCell(num_hiddens, kernel_initializer='glorot_uniform') rnn_layer = tf.keras.layers.RNN(rnn_cell, time_major=True, return_sequences=True, return_state=True) state = rnn_cell.get_initial_state(batch_size=batch_size, dtype=tf.float32) state.shape .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output TensorShape([32, 256]) .. raw:: html
.. raw:: html
Gizli bir durum ve bir girdi ile, çıktıyı güncellenmiş gizli durumla hesaplayabiliriz. ``rnn_layer``'in “çıktı”'nın (``Y``) çıktı katmanlarının hesaplanmasını *içermediği* vurgulanmalıdır: *Her bir* zaman adımındaki gizli durumu ifade eder ve sonraki çıktı katmanına girdi olarak kullanılabilir. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
Ayrıca, ``rnn_layer`` tarafından döndürülen güncelleştirilmiş gizli durum (``state_new``) minigrubun *son* zaman adımındaki gizli durumunu ifade eder. Sıralı bölümlemede bir dönem içinde sonraki minigrubun gizli durumunu ilklemede kullanılabilir. Birden çok gizli katman için, her katmanın gizli durumu bu değişkende saklanır (``state_new``). Daha sonra tanıtılacak bazı modellerde (örneğin, uzun ömürlü kısa-dönem belleği), bu değişken başka bilgiler de içerir. .. raw:: latex \diilbookstyleinputcell .. code:: python X = np.random.uniform(size=(num_steps, batch_size, len(vocab))) Y, state_new = rnn_layer(X, state) Y.shape, len(state_new), state_new[0].shape .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output ((35, 32, 256), 1, (1, 32, 256)) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python X = torch.rand(size=(num_steps, batch_size, len(vocab))) Y, state_new = rnn_layer(X, state) Y.shape, state_new.shape .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output (torch.Size([35, 32, 256]), torch.Size([1, 32, 256])) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python X = tf.random.uniform((num_steps, batch_size, len(vocab))) Y, state_new = rnn_layer(X, state) Y.shape, len(state_new), state_new[0].shape .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output (TensorShape([35, 32, 256]), 32, TensorShape([256])) .. raw:: html
.. raw:: html
:numref:`sec_rnn_scratch` içindekine benzer şekilde, tam bir RNN modeli için bir ``RNNModel`` sınıfı tanımlarız. ``rnn_layer``'in yalnızca gizli yinelemeli katmanları içerdiğini unutmayın, ayrı bir çıktı katmanı oluşturmamız gerekir. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python #@save class RNNModel(nn.Block): """RNN modeli.""" def __init__(self, rnn_layer, vocab_size, **kwargs): super(RNNModel, self).__init__(**kwargs) self.rnn = rnn_layer self.vocab_size = vocab_size self.dense = nn.Dense(vocab_size) def forward(self, inputs, state): X = npx.one_hot(inputs.T, self.vocab_size) Y, state = self.rnn(X, state) # Tam bağlı katman önce `Y`'nin şeklini # (`num_steps` * `batch_size`, `num_hiddens`) olarak değiştirir. # Çıktı (`num_steps` * `batch_size`, `vocab_size`) şeklindedir. output = self.dense(Y.reshape(-1, Y.shape[-1])) return output, state def begin_state(self, *args, **kwargs): return self.rnn.begin_state(*args, **kwargs) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python #@save class RNNModel(nn.Module): """RNN modeli.""" def __init__(self, rnn_layer, vocab_size, **kwargs): super(RNNModel, self).__init__(**kwargs) self.rnn = rnn_layer self.vocab_size = vocab_size self.num_hiddens = self.rnn.hidden_size # RNN çift yönlü ise (daha sonra tanıtılacaktır), # `num_directions` 2 olmalı, yoksa 1 olmalıdır. if not self.rnn.bidirectional: self.num_directions = 1 self.linear = nn.Linear(self.num_hiddens, self.vocab_size) else: self.num_directions = 2 self.linear = nn.Linear(self.num_hiddens * 2, self.vocab_size) def forward(self, inputs, state): X = F.one_hot(inputs.T.long(), self.vocab_size) X = X.to(torch.float32) Y, state = self.rnn(X, state) # Tam bağlı katman önce `Y`'nin şeklini # (`num_steps` * `batch_size`, `num_hiddens`) olarak değiştirir. # Çıktı (`num_steps` * `batch_size`, `vocab_size`) şeklindedir. output = self.linear(Y.reshape((-1, Y.shape[-1]))) return output, state def begin_state(self, device, batch_size=1): if not isinstance(self.rnn, nn.LSTM): # `nn.GRU` gizli durum olarak bir tensör alır return torch.zeros((self.num_directions * self.rnn.num_layers, batch_size, self.num_hiddens), device=device) else: # `nn.LSTM` bir gizli durum çokuzu alır return (torch.zeros(( self.num_directions * self.rnn.num_layers, batch_size, self.num_hiddens), device=device), torch.zeros(( self.num_directions * self.rnn.num_layers, batch_size, self.num_hiddens), device=device)) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python #@save class RNNModel(tf.keras.layers.Layer): def __init__(self, rnn_layer, vocab_size, **kwargs): super(RNNModel, self).__init__(**kwargs) self.rnn = rnn_layer self.vocab_size = vocab_size self.dense = tf.keras.layers.Dense(vocab_size) def call(self, inputs, state): X = tf.one_hot(tf.transpose(inputs), self.vocab_size) # Daha sonra `tf.keras.layers.LSTMCell` gibi RNN ikiden fazla değer döndürür Y, *state = self.rnn(X, state) output = self.dense(tf.reshape(Y, (-1, Y.shape[-1]))) return output, state def begin_state(self, *args, **kwargs): return self.rnn.cell.get_initial_state(*args, **kwargs) .. raw:: html
.. raw:: html
Eğitim ve Tahmin ---------------- Modeli eğitmeden önce, rastgele ağırlıklara sahip bir modelle bir tahmin yapalım. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python device = d2l.try_gpu() net = RNNModel(rnn_layer, len(vocab)) net.initialize(force_reinit=True, ctx=device) d2l.predict_ch8('time traveller', 10, net, vocab, device) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output 'time travellervmoopwrrrr' .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python device = d2l.try_gpu() net = RNNModel(rnn_layer, vocab_size=len(vocab)) net = net.to(device) d2l.predict_ch8('time traveller', 10, net, vocab, device) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output 'time travellerxxxxxxxxxx' .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python device_name = d2l.try_gpu()._device_name strategy = tf.distribute.OneDeviceStrategy(device_name) with strategy.scope(): net = RNNModel(rnn_layer, vocab_size=len(vocab)) d2l.predict_ch8('time traveller', 10, net, vocab) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output 'time travellergfqvpuhqh' .. raw:: html
.. raw:: html
Oldukça açık, bu model hiç çalışmıyor. Ardından, :numref:`sec_rnn_scratch` içinde tanımlanan aynı hiper parametrelerle ``train_ch8``'i çağırdık ve modelimizi üst düzey API'lerle eğitiyoruz. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python num_epochs, lr = 500, 1 d2l.train_ch8(net, train_iter, vocab, lr, num_epochs, device) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output perplexity 1.2, 132748.5 tokens/sec on gpu(0) time traveller but now you begin to srealle the time traveller b traveller for so it will be hove about in the other directi .. figure:: output_rnn-concise_eff2f4_68_1.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python num_epochs, lr = 500, 1 d2l.train_ch8(net, train_iter, vocab, lr, num_epochs, device) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output perplexity 1.3, 290440.5 tokens/sec on cuda:0 time traveller aptereave but lothe rak alyscthat arsthes than a travellerithe fore wescantwo snoweicalsiothroughi new yores .. figure:: output_rnn-concise_eff2f4_71_1.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python num_epochs, lr = 500, 1 d2l.train_ch8(net, train_iter, vocab, lr, num_epochs, strategy) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output perplexity 1.4, 15387.2 tokens/sec on /GPU:0 time traveller fficed for arellen yus ions ablit the rerele dire traveller mald existind fow ins al hing s all in tha rialli .. figure:: output_rnn-concise_eff2f4_74_1.svg .. raw:: html
.. raw:: html
Son bölümle karşılaştırıldığında, bu model, kodun derin öğrenme çerçevesinin üst düzey API'leriyle daha iyi hale getirilmesinden dolayı daha kısa bir süre içinde olsa da, benzer bir şaşkınlığa ulaşmaktadır. Özet ---- - Derin öğrenme çerçevesinin üst düzey API'leri RNN katmanının bir uygulanmasını sağlar. - Üst düzey API'lerin RNN katmanı, çıktının çıktı katmanı hesaplamasını içermediği bir çıktı ve güncellenmiş bir gizli durum döndürür. - Üst düzey API'lerin kullanılması, sıfırdan uygulama yaratmaktan daha hızlı RNN eğitimine yol açar. Alıştırmalar ------------ 1. RNN modelini üst düzey API'leri kullanarak aşırı eğitebilir misiniz? 2. RNN modelinde gizli katman sayısını artırırsanız ne olur? Modelin çalışmasını sağlayabilecek misiniz? 3. Bir RNN kullanarak :numref:`sec_sequence` içindeki özbağlanımlı modelini uygulayın. .. raw:: html
mxnetpytorchtensorflow
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html
`Tartışmalar `__ .. raw:: html
.. raw:: html