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

462 lines
42 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# ಪುನರಾವರ್ತಿತ ನ್ಯೂರಲ್ ನೆಟ್‌ವರ್ಕ್‌ಗಳು\n",
"\n",
"ಹಿಂದಿನ ಘಟಕದಲ್ಲಿ, ನಾವು ಪಠ್ಯದ ಸಮೃದ್ಧ ಅರ್ಥಾತ್ಮಕ ಪ್ರತಿನಿಧಿಗಳನ್ನು ಆವರಿಸಿಕೊಂಡಿದ್ದೇವೆ. ನಾವು ಬಳಸುತ್ತಿರುವ ವಾಸ್ತುಶಿಲ್ಪವು ವಾಕ್ಯದ ಪದಗಳ ಸಂಗ್ರಹಿತ ಅರ್ಥವನ್ನು ಹಿಡಿದಿಡುತ್ತದೆ, ಆದರೆ ಅದು ಪದಗಳ **ಕ್ರಮ**ವನ್ನು ಪರಿಗಣಿಸುವುದಿಲ್ಲ, ಏಕೆಂದರೆ ಎम्बೆಡ್ಡಿಂಗ್‌ಗಳ ನಂತರದ ಸಂಗ್ರಹಣಾ ಕಾರ್ಯಾಚರಣೆ ಮೂಲ ಪಠ್ಯದಿಂದ ಈ ಮಾಹಿತಿಯನ್ನು ತೆಗೆದುಹಾಕುತ್ತದೆ. ಈ ಮಾದರಿಗಳು ಪದಗಳ ಕ್ರಮವನ್ನು ಪ್ರತಿನಿಧಿಸಲು ಸಾಧ್ಯವಾಗದ ಕಾರಣ, ಅವು ಪಠ್ಯ ರಚನೆ ಅಥವಾ ಪ್ರಶ್ನೋತ್ತರದಂತಹ ಹೆಚ್ಚು ಸಂಕೀರ್ಣ ಅಥವಾ ಅಸ್ಪಷ್ಟ ಕಾರ್ಯಗಳನ್ನು ಪರಿಹರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ.\n",
"\n",
"ಪಠ್ಯ ಕ್ರಮದ ಅರ್ಥವನ್ನು ಹಿಡಿಯಲು, ನಾವು **ಪುನರಾವರ್ತಿತ ನ್ಯೂರಲ್ ನೆಟ್‌ವರ್ಕ್** ಅಥವಾ RNN ಎಂದು ಕರೆಯುವ ನ್ಯೂರಲ್ ನೆಟ್‌ವರ್ಕ್ ವಾಸ್ತುಶಿಲ್ಪವನ್ನು ಬಳಸುತ್ತೇವೆ. RNN ಬಳಸುವಾಗ, ನಾವು ನಮ್ಮ ವಾಕ್ಯವನ್ನು ಒಂದು ಟೋಕನ್‌ವನ್ನೊಂದು ಸಮಯದಲ್ಲಿ ನೆಟ್‌ವರ್ಕ್ ಮೂಲಕ ಹಾದುಹೋಗಿಸುತ್ತೇವೆ, ಮತ್ತು ನೆಟ್‌ವರ್ಕ್ ಕೆಲವು **ಸ್ಥಿತಿ** ಅನ್ನು ಉತ್ಪಾದಿಸುತ್ತದೆ, ಅದನ್ನು ನಂತರ ಮುಂದಿನ ಟೋಕನ್ ಜೊತೆಗೆ ಮತ್ತೆ ನೆಟ್‌ವರ್ಕ್‌ಗೆ ನೀಡುತ್ತೇವೆ.\n",
"\n",
"![ಪುನರಾವರ್ತಿತ ನ್ಯೂರಲ್ ನೆಟ್‌ವರ್ಕ್ ರಚನೆಯ ಉದಾಹರಣೆಯನ್ನು ತೋರಿಸುವ ಚಿತ್ರ.](../../../../../translated_images/kn/rnn.27f5c29c53d727b5.webp)\n",
"\n",
"ನಮೂದಿಸಿದ ಟೋಕನ್ ಕ್ರಮ $X_0,\\dots,X_n$ ನೀಡಿದಾಗ, RNN ನ್ಯೂರಲ್ ನೆಟ್‌ವರ್ಕ್ ಬ್ಲಾಕ್‌ಗಳ ಸರಣಿಯನ್ನು ರಚಿಸುತ್ತದೆ ಮತ್ತು ಬ್ಯಾಕ್ಪ್ರೊಪಗೇಶನ್ ಬಳಸಿ ಈ ಸರಣಿಯನ್ನು ಅಂತ್ಯದಿಂದ ಅಂತ್ಯಕ್ಕೆ ತರಬೇತುಗೊಳಿಸುತ್ತದೆ. ಪ್ರತಿ ನೆಟ್‌ವರ್ಕ್ ಬ್ಲಾಕ್ ಒಂದು ಜೋಡಿ $(X_i,S_i)$ ಅನ್ನು ಇನ್ಪುಟ್ ಆಗಿ ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ ಮತ್ತು $S_{i+1}$ ಅನ್ನು ಫಲಿತಾಂಶವಾಗಿ ಉತ್ಪಾದಿಸುತ್ತದೆ. ಅಂತಿಮ ಸ್ಥಿತಿ $S_n$ ಅಥವಾ ಔಟ್‌ಪುಟ್ $Y_n$ ಅನ್ನು ಲೀನಿಯರ್ ವರ್ಗೀಕರಣಕಾರಿಗೆ ನೀಡಲಾಗುತ್ತದೆ ಫಲಿತಾಂಶವನ್ನು ಉತ್ಪಾದಿಸಲು. ಎಲ್ಲಾ ನೆಟ್‌ವರ್ಕ್ ಬ್ಲಾಕ್‌ಗಳು ಒಂದೇ ತೂಕಗಳನ್ನು ಹಂಚಿಕೊಳ್ಳುತ್ತವೆ ಮತ್ತು ಒಂದು ಬ್ಯಾಕ್ಪ್ರೊಪಗೇಶನ್ ಪಾಸ್ ಬಳಸಿ ಅಂತ್ಯದಿಂದ ಅಂತ್ಯಕ್ಕೆ ತರಬೇತುಗೊಳ್ಳುತ್ತವೆ.\n",
"\n",
"> ಮೇಲಿನ ಚಿತ್ರವು ಪುನರಾವರ್ತಿತ ನ್ಯೂರಲ್ ನೆಟ್‌ವರ್ಕ್ ಅನ್ನು ಅನರೋಲ್ಡ್ ರೂಪದಲ್ಲಿ (ಎಡಭಾಗದಲ್ಲಿ) ಮತ್ತು ಹೆಚ್ಚು ಸಂಕ್ಷಿಪ್ತ ಪುನರಾವರ್ತಿತ ಪ್ರತಿನಿಧಿಯಲ್ಲಿ (ಬಲಭಾಗದಲ್ಲಿ) ತೋರಿಸುತ್ತದೆ. ಎಲ್ಲಾ RNN ಸೆಲ್‌ಗಳಿಗೆ ಒಂದೇ **ಹಂಚಿಕೊಳ್ಳಬಹುದಾದ ತೂಕಗಳು** ಇರುವುದನ್ನು ತಿಳಿದುಕೊಳ್ಳುವುದು ಮುಖ್ಯ.\n",
"\n",
"ಸ್ಥಿತಿ ವೆಕ್ಟರ್‌ಗಳು $S_0,\\dots,S_n$ ನೆಟ್‌ವರ್ಕ್ ಮೂಲಕ ಹಾದುಹೋಗುವುದರಿಂದ, RNN ಪದಗಳ ನಡುವಿನ ಕ್ರಮಬದ್ಧ ಅವಲಂಬನೆಗಳನ್ನು ಕಲಿಯಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ. ಉದಾಹರಣೆಗೆ, ಕ್ರಮದಲ್ಲಿ *not* ಎಂಬ ಪದವು ಇದ್ದಾಗ, ಅದು ಸ್ಥಿತಿ ವೆಕ್ಟರ್‌ನ ಕೆಲವು ಅಂಶಗಳನ್ನು ನಿರಾಕರಿಸುವುದನ್ನು ಕಲಿಯಬಹುದು.\n",
"\n",
"ಒಳಗೆ, ಪ್ರತಿ RNN ಸೆಲ್ ಎರಡು ತೂಕ ಮ್ಯಾಟ್ರಿಕ್ಸ್‌ಗಳನ್ನು ಹೊಂದಿದೆ: $W_H$ ಮತ್ತು $W_I$, ಮತ್ತು ಬಯಾಸ್ $b$. ಪ್ರತಿ RNN ಹಂತದಲ್ಲಿ, ಇನ್ಪುಟ್ $X_i$ ಮತ್ತು ಇನ್ಪುಟ್ ಸ್ಥಿತಿ $S_i$ ನೀಡಿದಾಗ, ಔಟ್‌ಪುಟ್ ಸ್ಥಿತಿ $S_{i+1} = f(W_H\\times S_i + W_I\\times X_i+b)$ ಎಂದು ಲೆಕ್ಕಿಸಲಾಗುತ್ತದೆ, ಇಲ್ಲಿ $f$ ಒಂದು ಸಕ್ರಿಯತೆ ಕಾರ್ಯ (ಸಾಮಾನ್ಯವಾಗಿ $\\tanh$).\n",
"\n",
"> ಪಠ್ಯ ರಚನೆ (ಮುಂದಿನ ಘಟಕದಲ್ಲಿ ನಾವು ಆವರಿಸುವುದು) ಅಥವಾ ಯಂತ್ರ ಅನುವಾದದಂತಹ ಸಮಸ್ಯೆಗಳಿಗೆ, ನಾವು ಪ್ರತಿ RNN ಹಂತದಲ್ಲಿಯೂ ಕೆಲವು ಔಟ್‌ಪುಟ್ ಮೌಲ್ಯವನ್ನು ಪಡೆಯಲು ಬಯಸುತ್ತೇವೆ. ಈ ಸಂದರ್ಭದಲ್ಲಿ, ಇನ್ನೊಂದು ಮ್ಯಾಟ್ರಿಕ್ಸ್ $W_O$ ಇರುತ್ತದೆ ಮತ್ತು ಔಟ್‌ಪುಟ್ $Y_i=f(W_O\\times S_i+b_O)$ ಎಂದು ಲೆಕ್ಕಿಸಲಾಗುತ್ತದೆ.\n",
"\n",
"ಪುನರಾವರ್ತಿತ ನ್ಯೂರಲ್ ನೆಟ್‌ವರ್ಕ್‌ಗಳು ನಮ್ಮ ಸುದ್ದಿ ಡೇಟಾಸೆಟ್ ಅನ್ನು ವರ್ಗೀಕರಿಸಲು ಹೇಗೆ ಸಹಾಯ ಮಾಡಬಹುದು ಎಂದು ನೋಡೋಣ.\n",
"\n",
"> ಸ್ಯಾಂಡ್‌ಬಾಕ್ಸ್ ಪರಿಸರಕ್ಕಾಗಿ, ಅಗತ್ಯವಿರುವ ಗ್ರಂಥಾಲಯ ಸ್ಥಾಪಿತವಾಗಿರುವುದು ಮತ್ತು ಡೇಟಾ ಪೂರ್ವಪ್ರಾಪ್ತವಾಗಿರುವುದನ್ನು ಖಚಿತಪಡಿಸಲು ಕೆಳಗಿನ ಸೆಲ್ ಅನ್ನು ಚಾಲನೆ ಮಾಡಬೇಕಾಗುತ್ತದೆ. ನೀವು ಸ್ಥಳೀಯವಾಗಿ ಚಾಲನೆ ಮಾಡುತ್ತಿದ್ದರೆ, ಕೆಳಗಿನ ಸೆಲ್ ಅನ್ನು ಬಿಟ್ಟುಹೋಗಬಹುದು.\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": [
"ದೊಡ್ಡ ಮಾದರಿಗಳನ್ನು ತರಬೇತಿಗೊಳಿಸುವಾಗ, GPU ಮೆಮೊರಿ ಹಂಚಿಕೆ ಸಮಸ್ಯೆಯಾಗಬಹುದು. ನಾವು ವಿಭಿನ್ನ ಮಿನಿಬ್ಯಾಚ್ ಗಾತ್ರಗಳೊಂದಿಗೆ ಪ್ರಯೋಗ ಮಾಡಬೇಕಾಗಬಹುದು, ಹೀಗಾಗಿ ಡೇಟಾ ನಮ್ಮ GPU ಮೆಮೊರಿಯಲ್ಲಿ ಸರಿಯಾಗಿ ಹೊಂದಿಕೊಳ್ಳುತ್ತದೆ ಮತ್ತು ತರಬೇತಿ ವೇಗವಾಗಿ ನಡೆಯುತ್ತದೆ. ನೀವು ನಿಮ್ಮ ಸ್ವಂತ GPU ಯಂತ್ರದಲ್ಲಿ ಈ ಕೋಡ್ ಅನ್ನು ಚಲಾಯಿಸುತ್ತಿದ್ದರೆ, ತರಬೇತಿಯನ್ನು ವೇಗಗೊಳಿಸಲು ಮಿನಿಬ್ಯಾಚ್ ಗಾತ್ರವನ್ನು ಹೊಂದಿಸಿ ಪ್ರಯೋಗ ಮಾಡಬಹುದು.\n",
"\n",
"> **Note**: ಕೆಲವು NVidia ಡ್ರೈವರ್ ಆವೃತ್ತಿಗಳು ಮಾದರಿಯನ್ನು ತರಬೇತಿಗೊಳಿಸಿದ ನಂತರ ಮೆಮೊರಿಯನ್ನು ಬಿಡುಗಡೆ ಮಾಡದಿರುವುದು ತಿಳಿದುಬಂದಿದೆ. ನಾವು ಈ ನೋಟ್ಬುಕ್‌ನಲ್ಲಿ ಹಲವಾರು ಉದಾಹರಣೆಗಳನ್ನು ಚಲಾಯಿಸುತ್ತಿದ್ದೇವೆ, ಮತ್ತು ಇದು ಕೆಲವು ವ್ಯವಸ್ಥೆಗಳಲ್ಲಿ ಮೆಮೊರಿ ಮುಗಿಯುವ ಕಾರಣವಾಗಬಹುದು, ವಿಶೇಷವಾಗಿ ನೀವು ಅದೇ ನೋಟ್ಬುಕ್‌ನ ಭಾಗವಾಗಿ ನಿಮ್ಮ ಸ್ವಂತ ಪ್ರಯೋಗಗಳನ್ನು ಮಾಡುತ್ತಿದ್ದರೆ. ಮಾದರಿಯನ್ನು ತರಬೇತಿಗೊಳಿಸಲು ಪ್ರಾರಂಭಿಸಿದಾಗ ಕೆಲವು ವಿಚಿತ್ರ ದೋಷಗಳು ಎದುರಾಗಿದೆಯಾದರೆ, ನೀವು ನೋಟ್ಬುಕ್ ಕರ್ಣಲ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸುವುದು ಉತ್ತಮ.\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": [
"## ಸರಳ RNN ವರ್ಗೀಕರಣೆ\n",
"\n",
"ಸರಳ RNN ನಲ್ಲಿ, ಪ್ರತಿ ಪುನರಾವರ್ತಿತ ಘಟಕವು ಸರಳ ರೇಖೀಯ ಜಾಲವಾಗಿದ್ದು, ಇದು ಇನ್‌ಪುಟ್ ವೆಕ್ಟರ್ ಮತ್ತು ಸ್ಥಿತಿ ವೆಕ್ಟರ್ ಅನ್ನು ತೆಗೆದು ಹೊಸ ಸ್ಥಿತಿ ವೆಕ್ಟರ್ ಅನ್ನು ಉತ್ಪಾದಿಸುತ್ತದೆ. Keras ನಲ್ಲಿ, ಇದನ್ನು `SimpleRNN` ಲೇಯರ್ ಮೂಲಕ ಪ್ರತಿನಿಧಿಸಬಹುದು.\n",
"\n",
"ನಾವು RNN ಲೇಯರ್‌ಗೆ ನೇರವಾಗಿ ಒನ್-ಹಾಟ್ ಎನ್‌ಕೋಡ್ ಮಾಡಿದ ಟೋಕನ್‌ಗಳನ್ನು ನೀಡಬಹುದು, ಆದರೆ ಅವುಗಳ ಉನ್ನತ ಆಯಾಮಗಳ ಕಾರಣದಿಂದ ಇದು ಉತ್ತಮ ಆಯ್ಕೆ ಅಲ್ಲ. ಆದ್ದರಿಂದ, ನಾವು ಪದ ವೆಕ್ಟರ್‌ಗಳ ಆಯಾಮವನ್ನು ಕಡಿಮೆ ಮಾಡಲು ಎम्बೆಡ್ಡಿಂಗ್ ಲೇಯರ್ ಅನ್ನು ಬಳಸುತ್ತೇವೆ, ನಂತರ RNN ಲೇಯರ್ ಮತ್ತು ಕೊನೆಗೆ `Dense` ವರ್ಗೀಕರಣೆ ಲೇಯರ್ ಅನ್ನು ಬಳಸುತ್ತೇವೆ.\n",
"\n",
"> **Note**: ಆಯಾಮಗಳು ಅತಿ ಹೆಚ್ಚು ಇಲ್ಲದ ಸಂದರ್ಭಗಳಲ್ಲಿ, ಉದಾಹರಣೆಗೆ ಅಕ್ಷರ ಮಟ್ಟದ ಟೋಕನೈಜೆಶನ್ ಬಳಸುವಾಗ, ಒನ್-ಹಾಟ್ ಎನ್‌ಕೋಡ್ ಮಾಡಿದ ಟೋಕನ್‌ಗಳನ್ನು ನೇರವಾಗಿ 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": [
"> **ಗಮನಿಸಿ:** ಸರಳತೆಗೆ ನಾವು ಇಲ್ಲಿ ತರಬೇತಿಗೊಳ್ಳದ embedding ಲೇಯರ್ ಅನ್ನು ಬಳಸುತ್ತಿದ್ದೇವೆ, ಆದರೆ ಉತ್ತಮ ಫಲಿತಾಂಶಗಳಿಗಾಗಿ ನಾವು ಹಿಂದಿನ ಘಟಕದಲ್ಲಿ ವಿವರಿಸಿದಂತೆ Word2Vec ಬಳಸಿ pretrained embedding ಲೇಯರ್ ಅನ್ನು ಬಳಸಬಹುದು. pretrained embeddings ಜೊತೆಗೆ ಈ ಕೋಡ್ ಅನ್ನು ಹೊಂದಿಸುವುದು ನಿಮ್ಮಿಗೆ ಒಳ್ಳೆಯ ಅಭ್ಯಾಸವಾಗಿರುತ್ತದೆ.\n",
"\n",
"ಈಗ ನಮ್ಮ RNN ಅನ್ನು ತರಬೇತಿಗೊಳಿಸೋಣ. ಸಾಮಾನ್ಯವಾಗಿ RNNಗಳನ್ನು ತರಬೇತಿಗೊಳಿಸುವುದು ತುಂಬಾ ಕಷ್ಟಕರ, ಏಕೆಂದರೆ RNN ಸೆಲ್‌ಗಳನ್ನು ಕ್ರಮದ ಉದ್ದದಂತೆ ಅನ್ರೋಲ್ ಮಾಡಿದಾಗ, ಬ್ಯಾಕ್ಪ್ರೊಪಾಗೇಶನ್‌ನಲ್ಲಿ ಭಾಗವಹಿಸುವ ಲೇಯರ್‌ಗಳ ಸಂಖ್ಯೆ ತುಂಬಾ ಹೆಚ್ಚಾಗುತ್ತದೆ. ಆದ್ದರಿಂದ ನಾವು ಕಡಿಮೆ ಲರ್ನಿಂಗ್ ರೇಟ್ ಆಯ್ಕೆಮಾಡಬೇಕು ಮತ್ತು ಉತ್ತಮ ಫಲಿತಾಂಶಗಳಿಗಾಗಿ ದೊಡ್ಡ ಡೇಟಾಸೆಟ್ ಮೇಲೆ ನೆಟ್‌ವರ್ಕ್ ಅನ್ನು ತರಬೇತಿಗೊಳಿಸಬೇಕು. ಇದಕ್ಕೆ ಸಾಕಷ್ಟು ಸಮಯ ಬೇಕಾಗಬಹುದು, ಆದ್ದರಿಂದ GPU ಬಳಕೆ ಮಾಡುವುದು ಉತ್ತಮ.\n",
"\n",
"ವೇಗವರ್ಧನೆಗಾಗಿ, ನಾವು RNN ಮಾದರಿಯನ್ನು ಸುದ್ದಿ ಶೀರ್ಷಿಕೆಗಳ ಮೇಲೆ ಮಾತ್ರ ತರಬೇತಿಗೊಳಿಸುವೆವು, ವಿವರಣೆಯನ್ನು ಹೊರತುಪಡಿಸುತ್ತೇವೆ. ನೀವು ವಿವರಣೆಯೊಂದಿಗೆ ತರಬೇತಿಗೊಳಿಸಲು ಪ್ರಯತ್ನಿಸಿ, ಮಾದರಿಯನ್ನು ತರಬೇತಿಗೊಳಿಸಲು ಸಾಧ್ಯವೋ ನೋಡಬಹುದು.\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": [
"> **ಗಮನಿಸಿ** ಇಲ್ಲಿ ನಿಖರತೆ ಕಡಿಮೆಯಾಗಿರಬಹುದು, ಏಕೆಂದರೆ ನಾವು ಕೇವಲ ಸುದ್ದಿಯ ಶೀರ್ಷಿಕೆಗಳ ಮೇಲೆ ತರಬೇತಿ ನೀಡುತ್ತಿದ್ದೇವೆ.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## ಬದಲಾಗುವ ಕ್ರಮಗಳನ್ನು ಮರುಪರಿಶೀಲನೆ\n",
"\n",
"`TextVectorization` ಲೇಯರ್ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಮಿನಿಬ್ಯಾಚ್‌ನ ಬದಲಾಗುವ ಉದ್ದದ ಕ್ರಮಗಳನ್ನು ಪ್ಯಾಡ್ ಟೋಕನ್‌ಗಳೊಂದಿಗೆ ಪ್ಯಾಡ್ ಮಾಡುತ್ತದೆ ಎಂದು ನೆನಪಿಡಿ. ಆ ಟೋಕನ್‌ಗಳು ತರಬೇತಿಯಲ್ಲಿ ಭಾಗವಹಿಸುತ್ತವೆ ಮತ್ತು ಅವು ಮಾದರಿಯ ಸಮೀಕರಣವನ್ನು ಸಂಕೀರ್ಣಗೊಳಿಸಬಹುದು.\n",
"\n",
"ಪ್ಯಾಡಿಂಗ್ ಪ್ರಮಾಣವನ್ನು ಕಡಿಮೆ ಮಾಡಲು ನಾವು ಹಲವು ವಿಧಾನಗಳನ್ನು ಅನುಸರಿಸಬಹುದು. ಅವುಗಳಲ್ಲಿ ಒಂದು ಕ್ರಮದ ಉದ್ದದ ಪ್ರಕಾರ ಡೇಟಾಸೆಟ್ ಅನ್ನು ಮರುಕ್ರಮಗೊಳಿಸಿ ಎಲ್ಲಾ ಕ್ರಮಗಳನ್ನು ಗಾತ್ರದ ಪ್ರಕಾರ ಗುಂಪು ಮಾಡುವುದು. ಇದನ್ನು `tf.data.experimental.bucket_by_sequence_length` ಫಂಕ್ಷನ್ ಬಳಸಿ ಮಾಡಬಹುದು ([ಡಾಕ್ಯುಮೆಂಟೇಶನ್](https://www.tensorflow.org/api_docs/python/tf/data/experimental/bucket_by_sequence_length) ನೋಡಿ).\n",
"\n",
"ಮತ್ತೊಂದು ವಿಧಾನವೆಂದರೆ **ಮಾಸ್ಕಿಂಗ್** ಬಳಕೆ. ಕೇರಾಸ್‌ನಲ್ಲಿ, ಕೆಲವು ಲೇಯರ್‌ಗಳು ತರಬೇತಿಯಲ್ಲಿ ಯಾವ ಟೋಕನ್‌ಗಳನ್ನು ಪರಿಗಣಿಸಬೇಕು ಎಂಬುದನ್ನು ತೋರಿಸುವ ಹೆಚ್ಚುವರಿ ಇನ್‌ಪುಟ್ ಅನ್ನು ಬೆಂಬಲಿಸುತ್ತವೆ. ನಮ್ಮ ಮಾದರಿಯಲ್ಲಿ ಮಾಸ್ಕಿಂಗ್ ಸೇರಿಸಲು, ನಾವು ಪ್ರತ್ಯೇಕ `Masking` ಲೇಯರ್ ([ಡಾಕ್ಸ್](https://keras.io/api/layers/core_layers/masking/)) ಸೇರಿಸಬಹುದು ಅಥವಾ ನಮ್ಮ `Embedding` ಲೇಯರ್‌ನ `mask_zero=True` ಪರಿಮಾಣವನ್ನು ಸೂಚಿಸಬಹುದು.\n",
"\n",
"> **ಗಮನಿಸಿ**: ಈ ತರಬೇತಿ ಸಂಪೂರ್ಣ ಡೇಟಾಸೆಟ್ ಮೇಲೆ ಒಂದು ಎಪೋಕ್ ಪೂರ್ಣಗೊಳ್ಳಲು ಸುಮಾರು 5 ನಿಮಿಷ ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ. ನೀವು ಸಹನೆ ಕಳೆದುಕೊಂಡರೆ ಯಾವುದೇ ಸಮಯದಲ್ಲಿ ತರಬೇತಿಯನ್ನು ನಿಲ್ಲಿಸಬಹುದು. ನೀವು ಮಾಡಬಹುದಾದ ಮತ್ತೊಂದು ವಿಧಾನವೆಂದರೆ, `ds_train` ಮತ್ತು `ds_test` ಡೇಟಾಸೆಟ್‌ಗಳ ನಂತರ `.take(...)` ಕ್ಲಾಜ್ ಸೇರಿಸಿ ತರಬೇತಿಗೆ ಬಳಸುವ ಡೇಟಾ ಪ್ರಮಾಣವನ್ನು ಮಿತಿಗೊಳಿಸುವುದು.\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": [
"ಈಗ ನಾವು ಮಾಸ್ಕಿಂಗ್ ಬಳಸುತ್ತಿದ್ದೇವೆ, ನಾವು ಶೀರ್ಷಿಕೆಗಳು ಮತ್ತು ವಿವರಣೆಗಳ ಸಂಪೂರ್ಣ ಡೇಟಾಸೆಟ್ ಮೇಲೆ ಮಾದರಿಯನ್ನು ತರಬೇತಿಗೆ ಒಳಪಡಿಸಬಹುದು.\n",
"\n",
"> **Note**: ನಾವು ಸುದ್ದಿಯ ಶೀರ್ಷಿಕೆಗಳ ಮೇಲೆ ತರಬೇತಿಗೊಳಿಸಿದ ವೆಕ್ಟರೈಜರ್ ಅನ್ನು ಬಳಸುತ್ತಿದ್ದೇವೆ, ಸಂಪೂರ್ಣ ಲೇಖನದ ದೇಹವನ್ನು ಅಲ್ಲ, ಎಂದು ನೀವು ಗಮನಿಸಿದ್ದೀರಾ? ಸಾಧ್ಯತೆಯಾಗಿ, ಇದರಿಂದ ಕೆಲವು ಟೋಕನ್‌ಗಳನ್ನು ನಿರ್ಲಕ್ಷಿಸಲಾಗಬಹುದು, ಆದ್ದರಿಂದ ವೆಕ್ಟರೈಜರ್ ಅನ್ನು ಮರುತರಬೇತಿಗೊಳಿಸುವುದು ಉತ್ತಮ. ಆದರೆ, ಇದರ ಪರಿಣಾಮ ಬಹಳ ಸಣ್ಣದಾಗಿರಬಹುದು, ಆದ್ದರಿಂದ ಸರಳತೆಗೆ ನಾವು ಹಿಂದಿನ ಪೂರ್ವ-ತರಬೇತಿಗೊಳಿಸಿದ ವೆಕ್ಟರೈಜರ್ ಅನ್ನು ಬಳಸುತ್ತೇವೆ.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## LSTM: ದೀರ್ಘಕಾಲಿಕ ಮತ್ತು ಕ್ಷಣಿಕ ಸ್ಮೃತಿ\n",
"\n",
"RNNಗಳ ಪ್ರಮುಖ ಸಮಸ್ಯೆಗಳಲ್ಲಿ ಒಂದಾಗಿದೆ **ವ್ಯರ್ಥವಾಗುವ ಗ್ರೇಡಿಯಂಟ್‌ಗಳು**. RNNಗಳು ಬಹಳ ದೀರ್ಘವಾಗಿರಬಹುದು, ಮತ್ತು ಬ್ಯಾಕ್ಪ್ರೊಪಗೇಶನ್ ಸಮಯದಲ್ಲಿ ಗ್ರೇಡಿಯಂಟ್‌ಗಳನ್ನು ನೆಟ್‌ವರ್ಕ್‌ನ ಮೊದಲ ಲೇಯರ್‌ಗೆ ತಲುಪಿಸುವುದು ಕಷ್ಟವಾಗಬಹುದು. ಇದರಿಂದ ದೂರದ ಟೋಕನ್‌ಗಳ ನಡುವಿನ ಸಂಬಂಧಗಳನ್ನು ನೆಟ್‌ವರ್ಕ್ ಕಲಿಯಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ. ಈ ಸಮಸ್ಯೆಯನ್ನು ತಪ್ಪಿಸಲು ಒಂದು ಮಾರ್ಗವೆಂದರೆ **ಗೇಟುಗಳನ್ನು** ಬಳಸಿ **ಸ್ಪಷ್ಟ ಸ್ಥಿತಿ ನಿರ್ವಹಣೆಯನ್ನು** ಪರಿಚಯಿಸುವುದು. ಗೇಟುಗಳನ್ನು ಪರಿಚಯಿಸುವ ಎರಡು ಸಾಮಾನ್ಯ ವಾಸ್ತುಶಿಲ್ಪಗಳು **ದೀರ್ಘಕಾಲಿಕ ಮತ್ತು ಕ್ಷಣಿಕ ಸ್ಮೃತಿ** (LSTM) ಮತ್ತು **ಗೇಟೆಡ್ ರಿಲೇ ಯೂನಿಟ್** (GRU). ಇಲ್ಲಿ ನಾವು LSTMಗಳನ್ನು ನೋಡೋಣ.\n",
"\n",
"![ದೀರ್ಘಕಾಲಿಕ ಮತ್ತು ಕ್ಷಣಿಕ ಸ್ಮೃತಿ ಸೆಲ್ ಉದಾಹರಣೆಯನ್ನು ತೋರಿಸುವ ಚಿತ್ರ](../../../../../lessons/5-NLP/16-RNN/images/long-short-term-memory-cell.svg)\n",
"\n",
"LSTM ನೆಟ್‌ವರ್ಕ್ RNNಗೆ ಹೋಲುವ ರೀತಿಯಲ್ಲಿ ಸಂಘಟಿತವಾಗಿದೆ, ಆದರೆ ಎರಡು ಸ್ಥಿತಿಗಳನ್ನು ಲೇಯರ್‌ಗಳಿಂದ ಲೇಯರ್‌ಗೆ ಕಳುಹಿಸಲಾಗುತ್ತದೆ: ನಿಜವಾದ ಸ್ಥಿತಿ $c$, ಮತ್ತು ಹಿಡನ್ ವೆಕ್ಟರ್ $h$. ಪ್ರತಿ ಯೂನಿಟ್‌ನಲ್ಲಿ, ಹಿಡನ್ ವೆಕ್ಟರ್ $h_{t-1}$ ಅನ್ನು ಇನ್‌ಪುಟ್ $x_t$ ಜೊತೆಗೆ ಸಂಯೋಜಿಸಲಾಗುತ್ತದೆ, ಮತ್ತು ಅವುಗಳ ಮೂಲಕ **ಗೇಟುಗಳ** ಮೂಲಕ ಸ್ಥಿತಿ $c_t$ ಮತ್ತು ಔಟ್‌ಪುಟ್ $h_t$ ಮೇಲೆ ನಿಯಂತ್ರಣ ಇರುತ್ತದೆ. ಪ್ರತಿ ಗೇಟಿನಲ್ಲೂ ಸಿಗ್ಮಾಯ್ಡ್ ಸಕ್ರಿಯತೆ (ಔಟ್‌ಪುಟ್ $[0,1]$ ವ್ಯಾಪ್ತಿಯಲ್ಲಿ) ಇರುತ್ತದೆ, ಇದನ್ನು ಸ್ಥಿತಿ ವೆಕ್ಟರ್‌ಗೆ ಗುಣಿಸುವಾಗ ಬಿಟ್‌ವೈಸ್ ಮಾಸ್ಕ್ ಎಂದು ಭಾವಿಸಬಹುದು. LSTMಗಳಿಗೆ ಕೆಳಗಿನ ಗೇಟುಗಳಿವೆ (ಚಿತ್ರದಲ್ಲಿ ಎಡದಿಂದ ಬಲಕ್ಕೆ):\n",
"* **ಮರೆತುಹೋಗುವ ಗೇಟು** ಇದು ವೆಕ್ಟರ್ $c_{t-1}$ ರ ಯಾವ ಅಂಶಗಳನ್ನು ಮರೆತುಹೋಗಬೇಕೆಂದು ಮತ್ತು ಯಾವ ಅಂಶಗಳನ್ನು ಮುಂದುವರಿಸಲು ಎಂದು ನಿರ್ಧರಿಸುತ್ತದೆ.\n",
"* **ಇನ್‌ಪುಟ್ ಗೇಟು** ಇದು ಇನ್‌ಪುಟ್ ವೆಕ್ಟರ್ ಮತ್ತು ಹಿಂದಿನ ಹಿಡನ್ ವೆಕ್ಟರ್‌ನಿಂದ ಎಷ್ಟು ಮಾಹಿತಿ ಸ್ಥಿತಿ ವೆಕ್ಟರ್‌ಗೆ ಸೇರಿಸಬೇಕೆಂದು ನಿರ್ಧರಿಸುತ್ತದೆ.\n",
"* **ಔಟ್‌ಪುಟ್ ಗೇಟು** ಇದು ಹೊಸ ಸ್ಥಿತಿ ವೆಕ್ಟರ್ ತೆಗೆದುಕೊಂಡು ಅದರ ಯಾವ ಅಂಶಗಳನ್ನು ಹೊಸ ಹಿಡನ್ ವೆಕ್ಟರ್ $h_t$ ರಚಿಸಲು ಬಳಸಬೇಕೆಂದು ನಿರ್ಧರಿಸುತ್ತದೆ.\n",
"\n",
"ಸ್ಥಿತಿ $c$ ರ ಅಂಶಗಳನ್ನು ಆನ್ ಮತ್ತು ಆಫ್ ಮಾಡಬಹುದಾದ ಫ್ಲಾಗ್‌ಗಳಂತೆ ಭಾವಿಸಬಹುದು. ಉದಾಹರಣೆಗೆ, ಸರಣಿಯಲ್ಲಿ *Alice* ಎಂಬ ಹೆಸರನ್ನು ಕಂಡಾಗ, ಅದು ಮಹಿಳೆಯೊಬ್ಬಳನ್ನು ಸೂಚಿಸುತ್ತದೆ ಎಂದು ಊಹಿಸಿ, ವಾಕ್ಯದಲ್ಲಿ ಮಹಿಳಾ ನಾಮಪದವಿದೆ ಎಂದು ಸ್ಥಿತಿಯಲ್ಲಿ ಫ್ಲಾಗ್ ಎತ್ತುತ್ತೇವೆ. ನಂತರ *and Tom* ಎಂಬ ಪದಗಳನ್ನು ಕಂಡಾಗ, ಬಹುವಚನ ನಾಮಪದವಿದೆ ಎಂದು ಸೂಚಿಸುವ ಫ್ಲಾಗ್ ಎತ್ತುತ್ತೇವೆ. ಹೀಗಾಗಿ ಸ್ಥಿತಿಯನ್ನು ನಿಯಂತ್ರಿಸುವ ಮೂಲಕ ವಾಕ್ಯದ ವ್ಯಾಕರಣಾತ್ಮಕ ಗುಣಲಕ್ಷಣಗಳನ್ನು ಗಮನದಲ್ಲಿರಿಸಬಹುದು.\n",
"\n",
"> **Note**: LSTMಗಳ ಒಳಗಿನ ರಚನೆಯನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಇದು ಅತ್ಯುತ್ತಮ ಸಂಪನ್ಮೂಲ: [Understanding LSTM Networks](https://colah.github.io/posts/2015-08-Understanding-LSTMs/) ಕ್ರಿಸ್ಟೋಫರ್ ಓಲಾ ಅವರಿಂದ.\n",
"\n",
"LSTM ಸೆಲ್‌ನ ಒಳಗಿನ ರಚನೆ ಸಂಕೀರ್ಣವಾಗಿದ್ದರೂ, Keras ಇದನ್ನು `LSTM` ಲೇಯರ್ ಒಳಗೆ ಮರೆಮಾಡುತ್ತದೆ, ಆದ್ದರಿಂದ ಮೇಲಿನ ಉದಾಹರಣೆಯಲ್ಲಿ ನಾವು ಮಾಡಬೇಕಾದದ್ದು ಕೇವಲ ರಿಕರೆಂಟ್ ಲೇಯರ್ ಅನ್ನು ಬದಲಾಯಿಸುವುದಷ್ಟೇ:\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": [
"> **ಗಮನಿಸಿ** LSTMಗಳನ್ನು ತರಬೇತಿಗೊಳಿಸುವುದು ಕೂಡ ತುಂಬಾ ನಿಧಾನವಾಗಿರುತ್ತದೆ, ಮತ್ತು ತರಬೇತಿಯ ಆರಂಭದಲ್ಲಿ ನೀವು ಹೆಚ್ಚಿನ ನಿಖರತೆಯನ್ನು ಕಾಣದಿರಬಹುದು. ಉತ್ತಮ ನಿಖರತೆಯನ್ನು ಸಾಧಿಸಲು ನೀವು ಕೆಲವು ಸಮಯ ತರಬೇತಿ ಮುಂದುವರಿಸಬೇಕಾಗಬಹುದು.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## ದ್ವಿಮುಖ ಮತ್ತು ಬಹುಮಟ್ಟದ RNNಗಳು\n",
"\n",
"ನಮ್ಮ ಉದಾಹರಣೆಗಳಲ್ಲಿ ಇದುವರೆಗೆ, ಪುನರಾವರ್ತಿತ ಜಾಲಗಳು ಕ್ರಮದ ಆರಂಭದಿಂದ ಅಂತ್ಯವರೆಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತವೆ. ನಾವು ಓದುತ್ತಾ ಅಥವಾ ಮಾತು ಕೇಳುತ್ತಾ ಇರುವ ದಿಕ್ಕಿನಲ್ಲಿ ಇದು ಸಹಜವಾಗಿ ಅನಿಸುತ್ತದೆ. ಆದರೆ, ಇನ್ಪುಟ್ ಕ್ರಮದ ಯಾದೃಚ್ಛಿಕ ಪ್ರವೇಶ ಅಗತ್ಯವಿರುವ ಸಂದರ್ಭಗಳಲ್ಲಿ, ಪುನರಾವರ್ತಿತ ಗಣನೆಗಳನ್ನು ಎರಡೂ ದಿಕ್ಕಿನಲ್ಲಿ ನಡೆಸುವುದು ಹೆಚ್ಚು ಅರ್ಥಪೂರ್ಣ. ಎರಡೂ ದಿಕ್ಕಿನಲ್ಲಿ ಗಣನೆಗಳನ್ನು ಅನುಮತಿಸುವ RNNಗಳನ್ನು **ದ್ವಿಮುಖ** RNNಗಳು ಎಂದು ಕರೆಯುತ್ತಾರೆ, ಮತ್ತು ಅವುಗಳನ್ನು ವಿಶೇಷ `Bidirectional` ಲೇಯರ್‌ನೊಂದಿಗೆ ಪುನರಾವರ್ತಿತ ಲೇಯರ್ ಅನ್ನು ಮುಚ್ಚುವ ಮೂಲಕ ರಚಿಸಬಹುದು.\n",
"\n",
"> **Note**: `Bidirectional` ಲೇಯರ್ ಅದರೊಳಗಿನ ಲೇಯರ್‌ನ ಎರಡು ನಕಲುಗಳನ್ನು ಮಾಡುತ್ತದೆ, ಮತ್ತು ಅವುಗಳಲ್ಲಿ ಒಂದರ `go_backwards` ಗುಣಲಕ್ಷಣವನ್ನು `True` ಆಗಿ ಹೊಂದಿಸಿ, ಕ್ರಮದ ವಿರುದ್ಧ ದಿಕ್ಕಿನಲ್ಲಿ ಹೋಗುವಂತೆ ಮಾಡುತ್ತದೆ.\n",
"\n",
"ಪುನರಾವರ್ತಿತ ಜಾಲಗಳು, ಏಕದಿಕ್ಕಿ ಅಥವಾ ದ್ವಿಮುಖವಾಗಿರಲಿ, ಕ್ರಮದೊಳಗಿನ ಮಾದರಿಗಳನ್ನು ಹಿಡಿದುಕೊಳ್ಳುತ್ತವೆ ಮತ್ತು ಅವುಗಳನ್ನು ಸ್ಥಿತಿ ವೆಕ್ಟರ್‌ಗಳಲ್ಲಿ ಸಂಗ್ರಹಿಸುತ್ತವೆ ಅಥವಾ ಔಟ್‌ಪುಟ್ ಆಗಿ ನೀಡುತ್ತವೆ. ಸಂಯೋಜಕ ಜಾಲಗಳಂತೆ, ನಾವು ಮೊದಲ ಲೇಯರ್‌ನ ನಂತರ ಮತ್ತೊಂದು ಪುನರಾವರ್ತಿತ ಲೇಯರ್ ಅನ್ನು ನಿರ್ಮಿಸಿ, ಮೊದಲ ಲೇಯರ್ ತೆಗೆದುಕೊಂಡ ಕಡಿಮೆ ಮಟ್ಟದ ಮಾದರಿಗಳಿಂದ ನಿರ್ಮಿತ ಉನ್ನತ ಮಟ್ಟದ ಮಾದರಿಗಳನ್ನು ಹಿಡಿಯಬಹುದು. ಇದರಿಂದ ನಮಗೆ **ಬಹುಮಟ್ಟದ RNN** ಎಂಬ ಕಲ್ಪನೆ ಬರುತ್ತದೆ, ಇದು ಎರಡು ಅಥವಾ ಹೆಚ್ಚು ಪುನರಾವರ್ತಿತ ಜಾಲಗಳನ್ನು ಒಳಗೊಂಡಿದ್ದು, ಹಿಂದಿನ ಲೇಯರ್‌ನ ಔಟ್‌ಪುಟ್ ಮುಂದಿನ ಲೇಯರ್‌ಗೆ ಇನ್ಪುಟ್ ಆಗಿ ನೀಡಲಾಗುತ್ತದೆ.\n",
"\n",
"![ಬಹುಮಟ್ಟದ ದೀರ್ಘಕಾಲಿಕ-ಸ್ಮೃತಿ- RNN ಅನ್ನು ತೋರಿಸುವ ಚಿತ್ರ](../../../../../translated_images/kn/multi-layer-lstm.dd975e29bb2a59fe.webp)\n",
"\n",
"*ಚಿತ್ರ [ಈ ಅದ್ಭುತ ಪೋಸ್ಟ್](https://towardsdatascience.com/from-a-lstm-cell-to-a-multilayer-lstm-network-with-pytorch-2899eb5696f3) ನಿಂದ ಫೆರ್ನಾಂಡೋ ಲೋಪೆಜ್ ಅವರಿಂದ.*\n",
"\n",
"ಕೆರಾಸ್ ಈ ಜಾಲಗಳನ್ನು ರಚಿಸುವುದನ್ನು ಸುಲಭ ಮಾಡುತ್ತದೆ, ಏಕೆಂದರೆ ನೀವು ಕೇವಲ ಹೆಚ್ಚಿನ ಪುನರಾವರ್ತಿತ ಲೇಯರ್‌ಗಳನ್ನು ಮಾದರಿಯಲ್ಲಿ ಸೇರಿಸಬೇಕಾಗುತ್ತದೆ. ಕೊನೆಯ ಲೇಯರ್ ಹೊರತುಪಡಿಸಿ ಎಲ್ಲಾ ಲೇಯರ್‌ಗಳಿಗೆ `return_sequences=True` ಪರಿಮಾಣವನ್ನು ಸೂಚಿಸಬೇಕಾಗುತ್ತದೆ, ಏಕೆಂದರೆ ನಾವು ಲೇಯರ್ ಎಲ್ಲಾ ಮಧ್ಯಂತರ ಸ್ಥಿತಿಗಳನ್ನು ಹಿಂತಿರುಗಿಸಬೇಕಾಗುತ್ತದೆ, ಕೇವಲ ಪುನರಾವರ್ತಿತ ಗಣನೆಯ ಅಂತಿಮ ಸ್ಥಿತಿಯನ್ನು ಮಾತ್ರವಲ್ಲ.\n",
"\n",
"ನಮ್ಮ ವರ್ಗೀಕರಣ ಸಮಸ್ಯೆಗೆ ಎರಡು-ಮಟ್ಟದ ದ್ವಿಮುಖ LSTM ಅನ್ನು ನಿರ್ಮಿಸೋಣ.\n",
"\n",
"> **Note** ಈ ಕೋಡ್ ಮತ್ತೆ ತುಂಬಾ ಸಮಯ ತೆಗೆದುಕೊಳ್ಳಬಹುದು, ಆದರೆ ಇದುವರೆಗೆ ನಾವು ಕಂಡ ಅತ್ಯುತ್ತಮ ನಿಖರತೆಯನ್ನು ನೀಡುತ್ತದೆ. ಆದ್ದರಿಂದ ಫಲಿತಾಂಶವನ್ನು ನೋಡಲು ಕಾಯುವುದು ಮೌಲ್ಯವಿರಬಹುದು.\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ಗಳು\n",
"\n",
"ಈವರೆಗೆ, ನಾವು RNNಗಳನ್ನು ಪಠ್ಯದ ಕ್ರಮಗಳನ್ನು ವರ್ಗೀಕರಿಸಲು ಬಳಸುವುದರ ಮೇಲೆ ಗಮನಹರಿಸಿದ್ದೇವೆ. ಆದರೆ ಅವು ಇನ್ನೂ ಅನೇಕ ಕಾರ್ಯಗಳನ್ನು ನಿರ್ವಹಿಸಬಹುದು, ಉದಾಹರಣೆಗೆ ಪಠ್ಯ ರಚನೆ ಮತ್ತು ಯಂತ್ರ ಭಾಷಾಂತರ — ನಾವು ಆ ಕಾರ್ಯಗಳನ್ನು ಮುಂದಿನ ಘಟಕದಲ್ಲಿ ಪರಿಗಣಿಸುವೆವು.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n\n<!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**ಅಸ್ವೀಕರಣ**: \nಈ ದಸ್ತಾವೇಜು [Co-op Translator](https://github.com/Azure/co-op-translator) ಎಂಬ AI ಅನುವಾದ ಸೇವೆಯನ್ನು ಬಳಸಿ ಅನುವಾದಿಸಲಾಗಿದೆ. ನಾವು ಶುದ್ಧತೆಯತ್ತ ಪ್ರಯತ್ನಿಸುತ್ತಿದ್ದರೂ, ಸ್ವಯಂಚಾಲಿತ ಅನುವಾದಗಳಲ್ಲಿ ತಪ್ಪುಗಳು ಅಥವಾ ಅಸತ್ಯತೆಗಳು ಇರಬಹುದು ಎಂದು ದಯವಿಟ್ಟು ಗಮನಿಸಿ. ಮೂಲ ಭಾಷೆಯಲ್ಲಿರುವ ಮೂಲ ದಸ್ತಾವೇಜನ್ನು ಅಧಿಕೃತ ಮೂಲವೆಂದು ಪರಿಗಣಿಸಬೇಕು. ಮಹತ್ವದ ಮಾಹಿತಿಗಾಗಿ, ವೃತ್ತಿಪರ ಮಾನವ ಅನುವಾದವನ್ನು ಶಿಫಾರಸು ಮಾಡಲಾಗುತ್ತದೆ. ಈ ಅನುವಾದ ಬಳಕೆಯಿಂದ ಉಂಟಾಗುವ ಯಾವುದೇ ತಪ್ಪು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವಿಕೆ ಅಥವಾ ತಪ್ಪು ವಿವರಣೆಗಳಿಗೆ ನಾವು ಹೊಣೆಗಾರರಾಗುವುದಿಲ್ಲ.\n<!-- CO-OP TRANSLATOR DISCLAIMER END -->\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-11-26T02:09:01+00:00",
"source_file": "lessons/5-NLP/16-RNN/RNNTF.ipynb",
"language_code": "kn"
}
},
"nbformat": 4,
"nbformat_minor": 4
}