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

460 lines
24 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Rangkaian Neural Berulang\n",
"\n",
"Dalam modul sebelumnya, kita telah membincangkan representasi semantik teks yang kaya. Seni bina yang kita gunakan menangkap makna agregat perkataan dalam ayat, tetapi ia tidak mengambil kira **susunan** perkataan, kerana operasi agregasi yang mengikuti embedding menghapuskan maklumat ini daripada teks asal. Oleh kerana model-model ini tidak dapat mewakili susunan perkataan, mereka tidak dapat menyelesaikan tugas yang lebih kompleks atau samar seperti penjanaan teks atau menjawab soalan.\n",
"\n",
"Untuk menangkap makna urutan teks, kita akan menggunakan seni bina rangkaian neural yang dipanggil **rangkaian neural berulang**, atau RNN. Apabila menggunakan RNN, kita menghantar ayat kita melalui rangkaian satu token pada satu masa, dan rangkaian menghasilkan beberapa **keadaan**, yang kemudian kita hantar semula ke rangkaian bersama token seterusnya.\n",
"\n",
"![Imej menunjukkan contoh penjanaan rangkaian neural berulang.](../../../../../translated_images/ms/rnn.27f5c29c53d727b5.webp)\n",
"\n",
"Diberikan urutan input token $X_0,\\dots,X_n$, RNN mencipta urutan blok rangkaian neural, dan melatih urutan ini secara hujung ke hujung menggunakan backpropagation. Setiap blok rangkaian mengambil pasangan $(X_i,S_i)$ sebagai input, dan menghasilkan $S_{i+1}$ sebagai hasil. Keadaan akhir $S_n$ atau output $Y_n$ dimasukkan ke dalam pengelas linear untuk menghasilkan keputusan. Semua blok rangkaian berkongsi berat yang sama, dan dilatih secara hujung ke hujung menggunakan satu laluan backpropagation.\n",
"\n",
"> Rajah di atas menunjukkan rangkaian neural berulang dalam bentuk yang tidak digulung (di sebelah kiri), dan dalam representasi berulang yang lebih padat (di sebelah kanan). Adalah penting untuk menyedari bahawa semua Sel RNN mempunyai **berat yang boleh dikongsi**.\n",
"\n",
"Oleh kerana vektor keadaan $S_0,\\dots,S_n$ dihantar melalui rangkaian, RNN dapat mempelajari kebergantungan berurutan antara perkataan. Sebagai contoh, apabila perkataan *tidak* muncul di suatu tempat dalam urutan, ia dapat belajar untuk menafikan elemen tertentu dalam vektor keadaan.\n",
"\n",
"Di dalamnya, setiap sel RNN mengandungi dua matriks berat: $W_H$ dan $W_I$, serta bias $b$. Pada setiap langkah RNN, diberikan input $X_i$ dan keadaan input $S_i$, keadaan output dikira sebagai $S_{i+1} = f(W_H\\times S_i + W_I\\times X_i+b)$, di mana $f$ adalah fungsi pengaktifan (sering $\\tanh$).\n",
"\n",
"> Untuk masalah seperti penjanaan teks (yang akan kita bincangkan dalam unit seterusnya) atau terjemahan mesin, kita juga ingin mendapatkan beberapa nilai output pada setiap langkah RNN. Dalam kes ini, terdapat juga matriks lain $W_O$, dan output dikira sebagai $Y_i=f(W_O\\times S_i+b_O)$.\n",
"\n",
"Mari kita lihat bagaimana rangkaian neural berulang dapat membantu kita mengklasifikasikan set data berita kita.\n",
"\n",
"> Untuk persekitaran sandbox, kita perlu menjalankan sel berikut untuk memastikan perpustakaan yang diperlukan dipasang, dan data telah dimuatkan terlebih dahulu. Jika anda menjalankan secara tempatan, anda boleh melangkau sel berikut.\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": [
"Apabila melatih model berskala besar, peruntukan memori GPU mungkin menjadi masalah. Kita juga mungkin perlu mencuba saiz minibatch yang berbeza, supaya data dapat dimuatkan ke dalam memori GPU kita, namun latihan tetap cukup pantas. Jika anda menjalankan kod ini pada mesin GPU anda sendiri, anda boleh mencuba melaraskan saiz minibatch untuk mempercepatkan proses latihan.\n",
"\n",
"> **Nota**: Versi tertentu pemacu NVidia diketahui tidak melepaskan memori selepas melatih model. Kami menjalankan beberapa contoh dalam buku nota ini, dan ia mungkin menyebabkan memori habis dalam sesetengah konfigurasi, terutamanya jika anda melakukan eksperimen anda sendiri dalam buku nota yang sama. Jika anda menghadapi ralat pelik semasa memulakan latihan model, anda mungkin mahu memulakan semula kernel buku nota.\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": [
"## Pengelas RNN Ringkas\n",
"\n",
"Dalam kes RNN ringkas, setiap unit berulang adalah rangkaian linear mudah, yang menerima vektor input dan vektor keadaan, dan menghasilkan vektor keadaan baharu. Dalam Keras, ini boleh diwakili oleh lapisan `SimpleRNN`.\n",
"\n",
"Walaupun kita boleh menghantar token yang dikodkan satu-panas terus ke lapisan RNN, ini bukan idea yang baik kerana dimensi mereka yang tinggi. Oleh itu, kita akan menggunakan lapisan embedding untuk mengurangkan dimensi vektor perkataan, diikuti oleh lapisan RNN, dan akhirnya pengelas `Dense`.\n",
"\n",
"> **Nota**: Dalam kes di mana dimensi tidak begitu tinggi, contohnya apabila menggunakan tokenisasi peringkat aksara, mungkin masuk akal untuk menghantar token yang dikodkan satu-panas terus ke sel RNN.\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": [
"> **Nota:** Kami menggunakan lapisan embedding yang tidak dilatih di sini untuk kesederhanaan, tetapi untuk hasil yang lebih baik, kami boleh menggunakan lapisan embedding yang telah dilatih menggunakan Word2Vec, seperti yang diterangkan dalam unit sebelumnya. Ia akan menjadi latihan yang baik untuk anda menyesuaikan kod ini agar berfungsi dengan embedding yang telah dilatih.\n",
"\n",
"Sekarang mari kita latih RNN kita. Secara umum, RNN agak sukar untuk dilatih, kerana apabila sel RNN diurai sepanjang panjang urutan, bilangan lapisan yang terlibat dalam backpropagation menjadi sangat besar. Oleh itu, kita perlu memilih kadar pembelajaran yang lebih kecil, dan melatih rangkaian pada dataset yang lebih besar untuk menghasilkan keputusan yang baik. Ini boleh mengambil masa yang agak lama, jadi penggunaan GPU adalah lebih disarankan.\n",
"\n",
"Untuk mempercepatkan proses, kita hanya akan melatih model RNN pada tajuk berita, dengan mengabaikan deskripsi. Anda boleh mencuba melatih dengan deskripsi dan melihat sama ada anda boleh membuat model tersebut dilatih.\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": [
"> **Nota** bahawa ketepatan mungkin lebih rendah di sini, kerana kami hanya melatih pada tajuk berita.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Meninjau semula urutan pembolehubah\n",
"\n",
"Ingat bahawa lapisan `TextVectorization` secara automatik akan menambah pad pada urutan panjang berubah dalam satu minibatch dengan token pad. Ternyata token tersebut juga terlibat dalam latihan, dan ini boleh menyulitkan penumpuan model.\n",
"\n",
"Terdapat beberapa pendekatan yang boleh kita ambil untuk mengurangkan jumlah padding. Salah satunya adalah dengan menyusun semula dataset mengikut panjang urutan dan mengelompokkan semua urutan mengikut saiz. Ini boleh dilakukan menggunakan fungsi `tf.data.experimental.bucket_by_sequence_length` (lihat [dokumentasi](https://www.tensorflow.org/api_docs/python/tf/data/experimental/bucket_by_sequence_length)).\n",
"\n",
"Pendekatan lain adalah dengan menggunakan **masking**. Dalam Keras, beberapa lapisan menyokong input tambahan yang menunjukkan token mana yang perlu diambil kira semasa latihan. Untuk memasukkan masking ke dalam model kita, kita boleh menambah lapisan `Masking` yang berasingan ([docs](https://keras.io/api/layers/core_layers/masking/)), atau kita boleh menetapkan parameter `mask_zero=True` pada lapisan `Embedding` kita.\n",
"\n",
"> **Note**: Latihan ini akan mengambil masa sekitar 5 minit untuk melengkapkan satu epoch pada keseluruhan dataset. Anda boleh menghentikan latihan pada bila-bila masa jika anda kehilangan kesabaran. Apa yang juga boleh dilakukan adalah menghadkan jumlah data yang digunakan untuk latihan, dengan menambah klausa `.take(...)` selepas dataset `ds_train` dan `ds_test`.\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": [
"Sekarang kita menggunakan penutupan, kita boleh melatih model pada keseluruhan dataset tajuk dan deskripsi.\n",
"\n",
"> **Note**: Adakah anda perasan bahawa kita telah menggunakan vectorizer yang dilatih pada tajuk berita, dan bukan keseluruhan isi artikel? Kemungkinan, ini boleh menyebabkan beberapa token diabaikan, jadi adalah lebih baik untuk melatih semula vectorizer. Walau bagaimanapun, kesannya mungkin sangat kecil, jadi kita akan kekal menggunakan vectorizer yang telah dilatih sebelumnya demi kesederhanaan.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## LSTM: Memori jangka panjang pendek\n",
"\n",
"Salah satu masalah utama RNN ialah **kecerunan yang hilang**. RNN boleh menjadi agak panjang, dan mungkin sukar untuk menyebarkan kecerunan kembali ke lapisan pertama rangkaian semasa backpropagation. Apabila ini berlaku, rangkaian tidak dapat mempelajari hubungan antara token yang jauh. Salah satu cara untuk mengelakkan masalah ini ialah dengan memperkenalkan **pengurusan keadaan secara eksplisit** menggunakan **pintu kawalan**. Dua seni bina yang paling biasa yang memperkenalkan pintu kawalan ialah **memori jangka panjang pendek** (LSTM) dan **unit relay berpintu** (GRU). Kita akan membincangkan LSTM di sini.\n",
"\n",
"![Imej menunjukkan contoh sel memori jangka panjang pendek](../../../../../lessons/5-NLP/16-RNN/images/long-short-term-memory-cell.svg)\n",
"\n",
"Rangkaian LSTM disusun dengan cara yang serupa dengan RNN, tetapi terdapat dua keadaan yang dihantar dari lapisan ke lapisan: keadaan sebenar $c$, dan vektor tersembunyi $h$. Pada setiap unit, vektor tersembunyi $h_{t-1}$ digabungkan dengan input $x_t$, dan bersama-sama mereka mengawal apa yang berlaku kepada keadaan $c_t$ dan output $h_{t}$ melalui **pintu kawalan**. Setiap pintu kawalan mempunyai pengaktifan sigmoid (output dalam julat $[0,1]$), yang boleh dianggap sebagai topeng bitwise apabila didarabkan dengan vektor keadaan. LSTM mempunyai pintu kawalan berikut (dari kiri ke kanan pada gambar di atas):\n",
"* **pintu lupa** yang menentukan komponen mana dalam vektor $c_{t-1}$ yang perlu kita lupakan, dan mana yang perlu diteruskan.\n",
"* **pintu input** yang menentukan berapa banyak maklumat daripada vektor input dan vektor tersembunyi sebelumnya yang harus dimasukkan ke dalam vektor keadaan.\n",
"* **pintu output** yang mengambil vektor keadaan baru dan memutuskan komponen mana yang akan digunakan untuk menghasilkan vektor tersembunyi baru $h_t$.\n",
"\n",
"Komponen keadaan $c$ boleh dianggap sebagai bendera yang boleh dihidupkan dan dimatikan. Sebagai contoh, apabila kita menemui nama *Alice* dalam urutan, kita menganggap ia merujuk kepada seorang wanita, dan menaikkan bendera dalam keadaan yang mengatakan kita mempunyai kata nama perempuan dalam ayat. Apabila kita seterusnya menemui perkataan *dan Tom*, kita akan menaikkan bendera yang mengatakan kita mempunyai kata nama jamak. Oleh itu, dengan memanipulasi keadaan, kita boleh menjejaki sifat tatabahasa ayat.\n",
"\n",
"> **Note**: Berikut adalah sumber yang hebat untuk memahami struktur dalaman LSTM: [Understanding LSTM Networks](https://colah.github.io/posts/2015-08-Understanding-LSTMs/) oleh Christopher Olah.\n",
"\n",
"Walaupun struktur dalaman sel LSTM mungkin kelihatan kompleks, Keras menyembunyikan pelaksanaannya di dalam lapisan `LSTM`, jadi satu-satunya perkara yang perlu kita lakukan dalam contoh di atas ialah menggantikan lapisan berulang:\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": [
"## RNN Dwihala dan Berlapis\n",
"\n",
"Dalam contoh kita sebelum ini, rangkaian berulang beroperasi dari permulaan urutan hingga ke penghujung. Ini terasa semula jadi bagi kita kerana ia mengikuti arah yang sama seperti kita membaca atau mendengar ucapan. Walau bagaimanapun, untuk senario yang memerlukan akses rawak kepada urutan input, lebih masuk akal untuk menjalankan pengiraan berulang dalam kedua-dua arah. RNN yang membenarkan pengiraan dalam kedua-dua arah dipanggil **RNN dwihala**, dan ia boleh dicipta dengan membungkus lapisan berulang dengan lapisan khas `Bidirectional`.\n",
"\n",
"> **Note**: Lapisan `Bidirectional` membuat dua salinan lapisan di dalamnya, dan menetapkan sifat `go_backwards` pada salah satu salinan tersebut kepada `True`, menjadikannya bergerak dalam arah bertentangan sepanjang urutan.\n",
"\n",
"Rangkaian berulang, sama ada sehala atau dwihala, menangkap corak dalam urutan, dan menyimpannya ke dalam vektor keadaan atau mengembalikannya sebagai output. Seperti rangkaian konvolusi, kita boleh membina lapisan berulang lain selepas yang pertama untuk menangkap corak tahap lebih tinggi, yang dibina daripada corak tahap lebih rendah yang diekstrak oleh lapisan pertama. Ini membawa kita kepada konsep **RNN berlapis**, yang terdiri daripada dua atau lebih rangkaian berulang, di mana output lapisan sebelumnya dihantar ke lapisan seterusnya sebagai input.\n",
"\n",
"![Imej menunjukkan RNN LSTM berlapis panjang-pendek](../../../../../translated_images/ms/multi-layer-lstm.dd975e29bb2a59fe.webp)\n",
"\n",
"*Gambar daripada [post yang hebat ini](https://towardsdatascience.com/from-a-lstm-cell-to-a-multilayer-lstm-network-with-pytorch-2899eb5696f3) oleh Fernando López.*\n",
"\n",
"Keras memudahkan pembinaan rangkaian ini, kerana anda hanya perlu menambah lebih banyak lapisan berulang ke model. Untuk semua lapisan kecuali yang terakhir, kita perlu menentukan parameter `return_sequences=True`, kerana kita memerlukan lapisan untuk mengembalikan semua keadaan perantaraan, dan bukan hanya keadaan akhir pengiraan berulang.\n",
"\n",
"Mari kita bina LSTM dwihala dua lapisan untuk masalah klasifikasi kita.\n",
"\n",
"> **Note** kod ini sekali lagi mengambil masa yang agak lama untuk diselesaikan, tetapi ia memberikan ketepatan tertinggi yang pernah kita lihat setakat ini. Jadi mungkin ia berbaloi untuk menunggu dan melihat hasilnya.\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": [
"## RNN untuk tugas lain\n",
"\n",
"Sehingga kini, kita telah memberi tumpuan kepada penggunaan RNN untuk mengklasifikasikan urutan teks. Namun, ia boleh menangani banyak lagi tugas, seperti penjanaan teks dan terjemahan mesin — kita akan membincangkan tugas-tugas tersebut dalam unit seterusnya.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Penafian**: \nDokumen ini telah diterjemahkan menggunakan perkhidmatan terjemahan AI [Co-op Translator](https://github.com/Azure/co-op-translator). Walaupun kami berusaha untuk memastikan ketepatan, sila ambil perhatian bahawa terjemahan automatik mungkin mengandungi kesilapan atau ketidaktepatan. Dokumen asal dalam bahasa asalnya harus dianggap sebagai sumber yang berwibawa. Untuk maklumat penting, terjemahan manusia profesional adalah disyorkan. Kami tidak bertanggungjawab atas sebarang salah faham atau salah tafsir yang timbul daripada penggunaan terjemahan ini.\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-29T16:13:11+00:00",
"source_file": "lessons/5-NLP/16-RNN/RNNTF.ipynb",
"language_code": "ms"
}
},
"nbformat": 4,
"nbformat_minor": 4
}