AI-For-Beginners/translations/tr/lessons/5-NLP/16-RNN/RNNTF.ipynb

460 lines
24 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Tekrarlayan Sinir Ağları\n",
"\n",
"Önceki modülde, metnin zengin anlamsal temsillerini ele aldık. Kullandığımız mimari, bir cümledeki kelimelerin toplu anlamını yakalıyor, ancak kelimelerin **sırasını** dikkate almıyor, çünkü gömme işlemini takip eden toplama işlemi, bu bilgiyi orijinal metinden çıkarıyor. Bu modeller kelime sırasını temsil edemediği için, metin üretimi veya soru yanıtlama gibi daha karmaşık veya belirsiz görevleri çözemiyor.\n",
"\n",
"Bir metin dizisinin anlamını yakalamak için, **tekrarlayan sinir ağı** veya RNN adı verilen bir sinir ağı mimarisi kullanacağız. RNN kullanırken, cümlemizi ağı birer birer token olarak geçiririz ve ağ bir **durum** üretir, bu durumu bir sonraki token ile birlikte tekrar ağa iletiriz.\n",
"\n",
"![Tekrarlayan sinir ağı üretimine dair bir örnek gösteren görsel.](../../../../../translated_images/tr/rnn.27f5c29c53d727b5.webp)\n",
"\n",
"Token giriş dizisi $X_0,\\dots,X_n$ verildiğinde, RNN bir sinir ağı blokları dizisi oluşturur ve bu diziyi baştan sona geri yayılım kullanarak eğitir. Her ağ bloğu $(X_i,S_i)$ çiftini giriş olarak alır ve sonuç olarak $S_{i+1}$ üretir. Son durum $S_n$ veya çıktı $Y_n$, sonucu üretmek için doğrusal bir sınıflandırıcıya gider. Tüm ağ blokları aynıırlıkları paylaşır ve tek bir geri yayılım geçişiyle baştan sona eğitilir.\n",
"\n",
"> Yukarıdaki şekil, tekrarlayan sinir ağınıılmış formda (solda) ve daha kompakt tekrarlayan temsilde (sağda) göstermektedir. Tüm RNN hücrelerinin aynı **paylaşılabilir ağırlıklara** sahip olduğunu anlamak önemlidir.\n",
"\n",
"Durum vektörleri $S_0,\\dots,S_n$ ağ boyunca geçtiği için, RNN kelimeler arasındaki sıralı bağımlılıkları öğrenebilir. Örneğin, dizide bir yerde *not* kelimesi geçtiğinde, durum vektöründeki belirli öğeleri olumsuzlamayı öğrenebilir.\n",
"\n",
"Her bir RNN hücresinin içinde iki ağırlık matrisi bulunur: $W_H$ ve $W_I$, ve bir sapma $b$. Her bir RNN adımında, giriş $X_i$ ve giriş durumu $S_i$ verildiğinde, çıktı durumu şu şekilde hesaplanır: $S_{i+1} = f(W_H\\times S_i + W_I\\times X_i+b)$, burada $f$ bir aktivasyon fonksiyonudur (genellikle $\\tanh$).\n",
"\n",
"> Metin üretimi (bir sonraki birimde ele alacağız) veya makine çevirisi gibi problemler için, her RNN adımında bir çıktı değeri elde etmek de isteriz. Bu durumda, başka bir matris $W_O$ vardır ve çıktı şu şekilde hesaplanır: $Y_i=f(W_O\\times S_i+b_O)$.\n",
"\n",
"Şimdi, tekrarlayan sinir ağlarının haber veri setimizi sınıflandırmamıza nasıl yardımcı olabileceğini görelim.\n",
"\n",
"> Sandbox ortamı için, gerekli kütüphanenin yüklendiğinden ve verilerin önceden alındığından emin olmak için aşağıdaki hücreyi çalıştırmamız gerekiyor. Yerel olarak çalışıyorsanız, aşağıdaki hücreyi atlayabilirsiniz.\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"!{sys.executable} -m pip install --quiet tensorflow_datasets==4.4.0\n",
"!cd ~ && wget -q -O - https://mslearntensorflowlp.blob.core.windows.net/data/tfds-ag-news.tgz | tar xz"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import tensorflow as tf\n",
"from tensorflow import keras\n",
"import tensorflow_datasets as tfds\n",
"import numpy as np\n",
"\n",
"# We are going to be training pretty large models. In order not to face errors, we need\n",
"# to set tensorflow option to grow GPU memory allocation when required\n",
"physical_devices = tf.config.list_physical_devices('GPU') \n",
"if len(physical_devices)>0:\n",
" tf.config.experimental.set_memory_growth(physical_devices[0], True)\n",
"\n",
"ds_train, ds_test = tfds.load('ag_news_subset').values()"
]
},
{
"cell_type": "markdown",
"metadata": {
"nteract": {
"transient": {
"deleting": false
}
}
},
"source": [
"Büyük modelleri eğitirken, GPU bellek tahsisi bir sorun haline gelebilir. Ayrıca, verilerin GPU belleğine sığması ve eğitimin yeterince hızlı olması için farklı minibatch boyutlarını denememiz gerekebilir. Eğer bu kodu kendi GPU makinenizde çalıştırıyorsanız, eğitimi hızlandırmak için minibatch boyutunu ayarlamayı deneyebilirsiniz.\n",
"\n",
"> **Not**: NVidia sürücülerinin belirli sürümlerinin, modeli eğittikten sonra belleği serbest bırakmadığı bilinmektedir. Bu not defterinde birkaç örnek çalıştırıyoruz ve bu durum, özellikle aynı not defteri içinde kendi deneylerinizi yapıyorsanız, bazı kurulumlarda belleğin tükenmesine neden olabilir. Modeli eğitmeye başlarken garip hatalarla karşılaşırsanız, not defteri çekirdeğini yeniden başlatmayı düşünebilirsiniz.\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": true,
"jupyter": {
"outputs_hidden": false,
"source_hidden": false
},
"nteract": {
"transient": {
"deleting": false
}
}
},
"outputs": [],
"source": [
"batch_size = 16\n",
"embed_size = 64"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Basit RNN sınıflandırıcı\n",
"\n",
"Basit bir RNN durumunda, her bir yinelemeli birim, bir giriş vektörü ve durum vektörünü alarak yeni bir durum vektörü üreten basit bir doğrusal ağdır. Keras'ta bu, `SimpleRNN` katmanı ile temsil edilebilir.\n",
"\n",
"Her ne kadar tekil kodlanmış (one-hot encoded) tokenleri doğrudan RNN katmanına geçirebilsek de, yüksek boyutlulukları nedeniyle bu iyi bir fikir değildir. Bu nedenle, kelime vektörlerinin boyutunu düşürmek için bir gömme (embedding) katmanı kullanacağız, ardından bir RNN katmanı ve son olarak bir `Dense` sınıflandırıcı ekleyeceğiz.\n",
"\n",
"> **Not**: Boyutluluğun çok yüksek olmadığı durumlarda, örneğin karakter düzeyinde tokenizasyon kullanıldığında, tekil kodlanmış tokenleri doğrudan RNN hücresine geçirmek mantıklı olabilir.\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"sequential\"\n",
"_________________________________________________________________\n",
"Layer (type) Output Shape Param # \n",
"=================================================================\n",
"text_vectorization (TextVect (None, None) 0 \n",
"_________________________________________________________________\n",
"embedding (Embedding) (None, None, 64) 1280000 \n",
"_________________________________________________________________\n",
"simple_rnn (SimpleRNN) (None, 16) 1296 \n",
"_________________________________________________________________\n",
"dense (Dense) (None, 4) 68 \n",
"=================================================================\n",
"Total params: 1,281,364\n",
"Trainable params: 1,281,364\n",
"Non-trainable params: 0\n",
"_________________________________________________________________\n"
]
}
],
"source": [
"vocab_size = 20000\n",
"\n",
"vectorizer = keras.layers.experimental.preprocessing.TextVectorization(\n",
" max_tokens=vocab_size,\n",
" input_shape=(1,))\n",
"\n",
"model = keras.models.Sequential([\n",
" vectorizer,\n",
" keras.layers.Embedding(vocab_size, embed_size),\n",
" keras.layers.SimpleRNN(16),\n",
" keras.layers.Dense(4,activation='softmax')\n",
"])\n",
"\n",
"model.summary()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **Not:** Burada basitlik açısından eğitilmemiş bir gömme katmanı kullanıyoruz, ancak daha iyi sonuçlar için önceki bölümde açıklandığı gibi Word2Vec kullanarak önceden eğitilmiş bir gömme katmanı kullanabiliriz. Bu kodu önceden eğitilmiş gömmelerle çalışacak şekilde uyarlamak sizin için iyi bir egzersiz olacaktır.\n",
"\n",
"Şimdi RNN'mizi eğitelim. Genel olarak RNN'leri eğitmek oldukça zordur, çünkü RNN hücreleri dizinin uzunluğu boyunca açıldığında, geri yayılımda yer alan katmanların sayısı oldukça fazla olur. Bu nedenle daha küçük bir öğrenme oranı seçmemiz ve iyi sonuçlar elde etmek için ağı daha büyük bir veri kümesinde eğitmemiz gerekir. Bu oldukça uzun sürebilir, bu yüzden bir GPU kullanılması tercih edilir.\n",
"\n",
"Hızı artırmak için, RNN modelini yalnızca haber başlıkları üzerinde eğiteceğiz ve açıklamayı dışarıda bırakacağız. Açıklama ile eğitmeyi deneyebilir ve modeli eğitip eğitemeyeceğinizi görebilirsiniz.\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Training vectorizer\n"
]
}
],
"source": [
"def extract_title(x):\n",
" return x['title']\n",
"\n",
"def tupelize_title(x):\n",
" return (extract_title(x),x['label'])\n",
"\n",
"print('Training vectorizer')\n",
"vectorizer.adapt(ds_train.take(2000).map(extract_title))"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"7500/7500 [==============================] - 82s 11ms/step - loss: 0.6629 - acc: 0.7623 - val_loss: 0.5559 - val_acc: 0.7995\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n"
]
},
{
"data": {
"text/plain": [
"<tensorflow.python.keras.callbacks.History at 0x7f3e0030d350>"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model.compile(loss='sparse_categorical_crossentropy',metrics=['acc'], optimizer='adam')\n",
"model.fit(ds_train.map(tupelize_title).batch(batch_size),validation_data=ds_test.map(tupelize_title).batch(batch_size))"
]
},
{
"cell_type": "markdown",
"metadata": {
"nteract": {
"transient": {
"deleting": false
}
}
},
"source": [
"> **Not** burada doğruluğun daha düşük olma olasılığı olduğunu, çünkü yalnızca haber başlıkları üzerinde eğitim yaptığımızı unutmayın.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Değişken dizileri yeniden gözden geçirme\n",
"\n",
"`TextVectorization` katmanının, bir minibatch içindeki değişken uzunluktaki dizileri otomatik olarak dolgu (pad) tokenlarıyla doldurduğunu unutmayın. Bu tokenların da eğitim sürecine dahil olduğu ortaya çıkıyor ve bu durum modelin yakınsama sürecini zorlaştırabiliyor.\n",
"\n",
"Dolgu miktarını en aza indirmek için birkaç yaklaşım benimseyebiliriz. Bunlardan biri, veri kümesini dizi uzunluğuna göre yeniden sıralamak ve tüm dizileri boyutlarına göre gruplandırmaktır. Bu, `tf.data.experimental.bucket_by_sequence_length` fonksiyonu kullanılarak yapılabilir (bkz. [dokümantasyon](https://www.tensorflow.org/api_docs/python/tf/data/experimental/bucket_by_sequence_length)).\n",
"\n",
"Bir diğer yaklaşım ise **masking** kullanmaktır. Keras'ta bazı katmanlar, eğitim sırasında hangi tokenların dikkate alınması gerektiğini gösteren ek bir girdi desteği sunar. Modelimize masking eklemek için ya ayrı bir `Masking` katmanı ([dokümanlar](https://keras.io/api/layers/core_layers/masking/)) ekleyebiliriz ya da `Embedding` katmanımızın `mask_zero=True` parametresini belirtebiliriz.\n",
"\n",
"> **Note**: Bu eğitim, tüm veri kümesi üzerinde bir epoch tamamlamak için yaklaşık 5 dakika sürecektir. Sabırsızlanırsanız, eğitimi istediğiniz zaman durdurabilirsiniz. Ayrıca, eğitim için kullanılan veri miktarını sınırlayabilirsiniz; bunu `ds_train` ve `ds_test` veri kümelerinden sonra `.take(...)` ifadesini ekleyerek yapabilirsiniz.\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"7500/7500 [==============================] - 371s 49ms/step - loss: 0.5401 - acc: 0.8079 - val_loss: 0.3780 - val_acc: 0.8822\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n"
]
},
{
"data": {
"text/plain": [
"<tensorflow.python.keras.callbacks.History at 0x7f3dec118850>"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def extract_text(x):\n",
" return x['title']+' '+x['description']\n",
"\n",
"def tupelize(x):\n",
" return (extract_text(x),x['label'])\n",
"\n",
"model = keras.models.Sequential([\n",
" vectorizer,\n",
" keras.layers.Embedding(vocab_size,embed_size,mask_zero=True),\n",
" keras.layers.SimpleRNN(16),\n",
" keras.layers.Dense(4,activation='softmax')\n",
"])\n",
"\n",
"model.compile(loss='sparse_categorical_crossentropy',metrics=['acc'], optimizer='adam')\n",
"model.fit(ds_train.map(tupelize).batch(batch_size),validation_data=ds_test.map(tupelize).batch(batch_size))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Artık maskelamayı kullandığımız için modeli başlıklar ve açıklamalardan oluşan tüm veri seti üzerinde eğitebiliriz.\n",
"\n",
"> **Not**: Fark ettiniz mi, haber başlıkları üzerinde eğitilmiş bir vektörleştirici kullanıyoruz, makalenin tamamı üzerinde değil? Bu durum bazı tokenların göz ardı edilmesine neden olabilir, bu yüzden vektörleştiriciyi yeniden eğitmek daha iyi olabilir. Ancak, bunun etkisi çok küçük olabilir, bu yüzden basitlik adına önceki önceden eğitilmiş vektörleştiriciyi kullanmaya devam edeceğiz.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## LSTM: Uzun Kısa Süreli Bellek\n",
"\n",
"RNN'lerin (Tekrarlayan Sinir Ağları) en büyük problemlerinden biri **kaybolan gradyanlar**dır. RNN'ler oldukça uzun olabilir ve geri yayılım sırasında gradyanlarıın ilk katmanına kadar taşımakta zorlanabilir. Bu durum gerçekleştiğinde, ağ uzak tokenlar arasındaki ilişkileri öğrenemez. Bu sorunu önlemenin bir yolu, **kapılar** kullanarak **açık durum yönetimi** sağlamaktır. Kapıları tanıtan en yaygın iki mimari **uzun kısa süreli bellek** (LSTM) ve **kapılı röle birimi** (GRU) olarak bilinir. Burada LSTM'leri ele alacağız.\n",
"\n",
"![Uzun kısa süreli bellek hücresine örnek gösteren bir görsel](../../../../../lessons/5-NLP/16-RNN/images/long-short-term-memory-cell.svg)\n",
"\n",
"Bir LSTM ağı, RNN'e benzer bir şekilde organize edilir, ancak katmandan katmana iki durum aktarılır: gerçek durum $c$ ve gizli vektör $h$. Her birimde, gizli vektör $h_{t-1}$ giriş $x_t$ ile birleştirilir ve birlikte **kapılar** aracılığıyla durum $c_t$ ve çıktı $h_{t}$ üzerinde ne olacağını kontrol ederler. Her kapı sigmoid aktivasyonuna sahiptir (çıktı aralığı $[0,1]$), bu da durum vektörüyle çarpıldığında bit düzeyinde bir maske olarak düşünülebilir. LSTM'lerde aşağıdaki kapılar bulunur (yukarıdaki resimde soldan sağa doğru):\n",
"* **unutma kapısı**, vektör $c_{t-1}$'in hangi bileşenlerini unutmamız gerektiğini ve hangilerini geçirmemiz gerektiğini belirler.\n",
"* **giriş kapısı**, giriş vektöründen ve önceki gizli vektörden ne kadar bilginin durum vektörüne dahil edilmesi gerektiğini belirler.\n",
"* **çıkış kapısı**, yeni durum vektörünü alır ve bu vektörün hangi bileşenlerinin yeni gizli vektör $h_t$'yi üretmek için kullanılacağını belirler.\n",
"\n",
"Durum $c$'nin bileşenleri, açılıp kapatılabilen bayraklar olarak düşünülebilir. Örneğin, dizide *Alice* ismiyle karşılaştığımızda, bunun bir kadına atıfta bulunduğunu tahmin ederiz ve cümlede bir kadın ismi olduğunu belirten bayrağı kaldırırız. Daha sonra *ve Tom* kelimeleriyle karşılaştığımızda, çoğul bir isim olduğunu belirten bayrağı kaldırırız. Böylece durumu manipüle ederek cümlenin dilbilgisel özelliklerini takip edebiliriz.\n",
"\n",
"> **Note**: LSTM'lerin iç yapısını anlamak için harika bir kaynak: Christopher Olah tarafından yazılan [Understanding LSTM Networks](https://colah.github.io/posts/2015-08-Understanding-LSTMs/).\n",
"\n",
"Bir LSTM hücresinin iç yapısı karmaşık görünebilir, ancak Keras bu implementasyonu `LSTM` katmanı içinde gizler. Bu nedenle, yukarıdaki örnekte yapmamız gereken tek şey tekrarlayan katmanı değiştirmektir:\n"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"15000/15000 [==============================] - 188s 13ms/step - loss: 0.5692 - acc: 0.7916 - val_loss: 0.3441 - val_acc: 0.8870\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n"
]
},
{
"data": {
"text/plain": [
"<tensorflow.python.keras.callbacks.History at 0x7f3d6af5c350>"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model = keras.models.Sequential([\n",
" vectorizer,\n",
" keras.layers.Embedding(vocab_size, embed_size),\n",
" keras.layers.LSTM(8),\n",
" keras.layers.Dense(4,activation='softmax')\n",
"])\n",
"\n",
"model.compile(loss='sparse_categorical_crossentropy',metrics=['acc'], optimizer='adam')\n",
"model.fit(ds_train.map(tupelize).batch(8),validation_data=ds_test.map(tupelize).batch(8))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Çift Yönlü ve Çok Katmanlı RNN'ler\n",
"\n",
"Şimdiye kadar verdiğimiz örneklerde, tekrarlayan ağlar bir dizinin başından sonuna kadar işlem yapıyor. Bu bize doğal geliyor çünkü okuma veya konuşmayı dinleme yönümüzle aynı doğrultuda ilerliyor. Ancak, giriş dizisine rastgele erişim gerektiren senaryolar için, tekrarlayan hesaplamayı her iki yönde çalıştırmak daha mantıklı olabilir. Hesaplamaları her iki yönde yapabilen RNN'lere **çift yönlü** RNN'ler denir ve bu tür ağlar, tekrarlayan katmanı özel bir `Bidirectional` katmanla sarmalayarak oluşturulabilir.\n",
"\n",
"> **Not**: `Bidirectional` katmanı, içindeki katmanın iki kopyasını oluşturur ve bu kopyalardan birinin `go_backwards` özelliğini `True` olarak ayarlar, böylece dizinin ters yönünde ilerlemesini sağlar.\n",
"\n",
"Tek yönlü veya çift yönlü tekrarlayan ağlar, bir dizideki desenleri yakalar ve bunları durum vektörlerine kaydeder veya çıktı olarak döndürür. Konvolüsyonel ağlarda olduğu gibi, birinci katman tarafından çıkarılan alt düzey desenlerden daha yüksek düzey desenleri yakalamak için birinci katmanın ardından başka bir tekrarlayan katman ekleyebiliriz. Bu bizi **çok katmanlı RNN** kavramına götürür; bu, iki veya daha fazla tekrarlayan ağdan oluşur ve önceki katmanın çıktısı bir sonraki katmana giriş olarak aktarılır.\n",
"\n",
"![Çok katmanlı uzun-kısa süreli bellek RNN'yi gösteren bir resim](../../../../../translated_images/tr/multi-layer-lstm.dd975e29bb2a59fe.webp)\n",
"\n",
"*Fernando López'in [bu harika yazısından](https://towardsdatascience.com/from-a-lstm-cell-to-a-multilayer-lstm-network-with-pytorch-2899eb5696f3) alınmış bir resim.*\n",
"\n",
"Keras, bu tür ağları oluşturmayı oldukça kolaylaştırır, çünkü modele sadece daha fazla tekrarlayan katman eklemeniz yeterlidir. Son katman hariç tüm katmanlar için `return_sequences=True` parametresini belirtmemiz gerekir, çünkü katmanın yalnızca tekrarlayan hesaplamanın son durumunu değil, tüm ara durumları döndürmesini isteriz.\n",
"\n",
"Hadi sınıflandırma problemimiz için iki katmanlı çift yönlü bir LSTM oluşturalım.\n",
"\n",
"> **Not** Bu kodun tamamlanması yine oldukça uzun sürüyor, ancak şimdiye kadar gördüğümüz en yüksek doğruluğu sağlıyor. Bu yüzden beklemeye ve sonucu görmeye değer olabilir.\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"5044/7500 [===================>..........] - ETA: 2:33 - loss: 0.3709 - acc: 0.8706\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\r5045/7500 [===================>..........] - ETA: 2:33 - loss: 0.3709 - acc: 0.8706"
]
}
],
"source": [
"model = keras.models.Sequential([\n",
" vectorizer,\n",
" keras.layers.Embedding(vocab_size, 128, mask_zero=True),\n",
" keras.layers.Bidirectional(keras.layers.LSTM(64,return_sequences=True)),\n",
" keras.layers.Bidirectional(keras.layers.LSTM(64)), \n",
" keras.layers.Dense(4,activation='softmax')\n",
"])\n",
"\n",
"model.compile(loss='sparse_categorical_crossentropy',metrics=['acc'], optimizer='adam')\n",
"model.fit(ds_train.map(tupelize).batch(batch_size),\n",
" validation_data=ds_test.map(tupelize).batch(batch_size))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Diğer Görevler için RNN'ler\n",
"\n",
"Şimdiye kadar, RNN'leri metin dizilerini sınıflandırmak için kullanmaya odaklandık. Ancak, metin üretimi ve makine çevirisi gibi birçok başka görevi de yerine getirebilirler — bu görevleri bir sonraki birimde ele alacağız.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Feragatname**: \nBu belge, AI çeviri hizmeti [Co-op Translator](https://github.com/Azure/co-op-translator) kullanılarak çevrilmiştir. Doğruluk için çaba göstersek de, otomatik çevirilerin hata veya yanlışlıklar içerebileceğini lütfen unutmayın. Belgenin orijinal dili, yetkili kaynak olarak kabul edilmelidir. Kritik bilgiler için profesyonel insan çevirisi önerilir. Bu çevirinin kullanımından kaynaklanan yanlış anlamalar veya yanlış yorumlamalar için sorumluluk kabul etmiyoruz.\n"
]
}
],
"metadata": {
"kernel_info": {
"name": "conda-env-py37_tensorflow-py"
},
"kernelspec": {
"display_name": "py37_tensorflow",
"language": "python",
"name": "conda-env-py37_tensorflow-py"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.9"
},
"nteract": {
"version": "nteract-front-end@1.0.0"
},
"coopTranslator": {
"original_hash": "81351e61f619b432ff51010a4f993194",
"translation_date": "2025-08-28T14:22:08+00:00",
"source_file": "lessons/5-NLP/16-RNN/RNNTF.ipynb",
"language_code": "tr"
}
},
"nbformat": 4,
"nbformat_minor": 4
}