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

460 lines
39 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# पुनरावृत्ती तंत्रिका नेटवर्क\n",
"\n",
"मागील विभागात, आपण मजकूराच्या समृद्ध अर्थपूर्ण प्रतिनिधित्वांबद्दल चर्चा केली. आपण वापरत असलेली आर्किटेक्चर वाक्यातील शब्दांचा एकत्रित अर्थ पकडते, परंतु ती शब्दांच्या **क्रम** विचारात घेत नाही, कारण एम्बेडिंगनंतर होणारी एकत्रीकरण प्रक्रिया मूळ मजकूरातील ही माहिती काढून टाकते. या मॉडेल्सना शब्द क्रमवारीचे प्रतिनिधित्व करता येत नसल्यामुळे, ते मजकूर निर्मिती किंवा प्रश्नोत्तर यांसारख्या अधिक जटिल किंवा संदिग्ध कार्ये सोडवू शकत नाहीत.\n",
"\n",
"मजकूर अनुक्रमाचा अर्थ पकडण्यासाठी, आपण **पुनरावृत्ती तंत्रिका नेटवर्क** किंवा RNN नावाची तंत्रिका नेटवर्क आर्किटेक्चर वापरणार आहोत. RNN वापरताना, आपण आपले वाक्य नेटवर्कमधून एकावेळी एक टोकन पास करतो, आणि नेटवर्क काही **स्थिती** तयार करते, जी आपण पुढील टोकनसह पुन्हा नेटवर्कमध्ये पास करतो.\n",
"\n",
"![पुनरावृत्ती तंत्रिका नेटवर्क निर्मितीचे उदाहरण दर्शवणारी प्रतिमा.](../../../../../translated_images/mr/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": [
"> **टीप:** येथे आपण साधेपणासाठी एक अप्रशिक्षित एम्बेडिंग लेयर वापरतो, परंतु चांगल्या परिणामांसाठी आपण Word2Vec वापरून प्रीट्रेन केलेला एम्बेडिंग लेयर वापरू शकतो, जसे की मागील युनिटमध्ये वर्णन केले आहे. हा कोड प्रीट्रेन एम्बेडिंगसह कार्य करण्यासाठी अनुकूलित करणे हे तुमच्यासाठी एक चांगले व्यायाम ठरू शकते.\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",
"दुसरी पद्धत म्हणजे **मास्किंग** वापरणे. Keras मध्ये, काही लेयर्स अतिरिक्त इनपुटला समर्थन देतात जे दाखवते की प्रशिक्षण करताना कोणते टोकन्स विचारात घ्यावेत. आपल्या मॉडेलमध्ये मास्किंग समाविष्ट करण्यासाठी, आपण `Masking` लेयर ([डॉक्स](https://keras.io/api/layers/core_layers/masking/)) स्वतंत्रपणे समाविष्ट करू शकतो, किंवा आपण `Embedding` लेयरच्या `mask_zero=True` पॅरामीटरला निर्दिष्ट करू शकतो.\n",
"\n",
"> **Note**: संपूर्ण डेटासेटवर एक epoch पूर्ण करण्यासाठी हे प्रशिक्षण सुमारे 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",
"> **टीप**: तुम्ही लक्षात घेतले आहे का की आपण बातम्यांच्या शीर्षकांवर प्रशिक्षित केलेला व्हेक्टरायझर वापरत आहोत, आणि लेखाच्या संपूर्ण मजकुरावर नाही? संभाव्यतः, यामुळे काही टोकन्स दुर्लक्षित होऊ शकतात, त्यामुळे व्हेक्टरायझर पुन्हा प्रशिक्षण देणे चांगले आहे. मात्र, याचा परिणाम फारच कमी होऊ शकतो, त्यामुळे साधेपणासाठी आपण पूर्व-प्रशिक्षित व्हेक्टरायझरच वापरणार आहोत.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## LSTM: लाँग शॉर्ट-टर्म मेमरी\n",
"\n",
"RNNs च्या मुख्य समस्यांपैकी एक म्हणजे **vanishing gradients**. RNNs खूप लांब असू शकतात आणि बॅकप्रोपोगेशन दरम्यान नेटवर्कच्या पहिल्या लेयरपर्यंत ग्रेडियंट्स पोहोचवणे कठीण होऊ शकते. जेव्हा असे होते, तेव्हा नेटवर्क दूरच्या टोकनमधील संबंध शिकू शकत नाही. ही समस्या टाळण्यासाठी **explicit state management** वापरणे एक उपाय आहे, ज्यामध्ये **gates** चा वापर केला जातो. **लाँग शॉर्ट-टर्म मेमरी** (LSTM) आणि **gated relay unit** (GRU) या दोन सर्वात सामान्य आर्किटेक्चर आहेत ज्यामध्ये gates असतात. येथे आपण LSTMs बद्दल चर्चा करू.\n",
"\n",
"![लाँग शॉर्ट-टर्म मेमरी सेलचे उदाहरण दाखवणारी प्रतिमा](../../../../../lessons/5-NLP/16-RNN/images/long-short-term-memory-cell.svg)\n",
"\n",
"LSTM नेटवर्क RNN प्रमाणेच आयोजित केले जाते, परंतु दोन states लेयरपासून लेयरपर्यंत पास होतात: actual state $c$, आणि hidden vector $h$. प्रत्येक युनिटवर, hidden vector $h_{t-1}$ input $x_t$ सोबत एकत्रित केला जातो, आणि एकत्रितपणे ते state $c_t$ आणि output $h_{t}$ वर **gates** च्या माध्यमातून नियंत्रण ठेवतात. प्रत्येक gate ला sigmoid activation असते (output $[0,1]$ च्या रेंजमध्ये), ज्याला state vector सोबत गुणाकार केल्यावर bitwise mask म्हणून विचार करता येतो. LSTMs मध्ये खालील gates असतात (वर दिलेल्या चित्रात डावीकडून उजवीकडे):\n",
"* **forget gate** जो ठरवतो की vector $c_{t-1}$ च्या कोणत्या घटकांना विसरायचे आहे आणि कोणते पास करायचे आहेत.\n",
"* **input gate** जो ठरवतो की input vector आणि previous hidden vector मधील किती माहिती state vector मध्ये समाविष्ट करायची आहे.\n",
"* **output gate** जो नवीन state vector घेतो आणि त्याच्या कोणत्या घटकांचा उपयोग नवीन hidden vector $h_t$ तयार करण्यासाठी करायचा आहे हे ठरवतो.\n",
"\n",
"State $c$ चे घटक flags म्हणून विचार करता येऊ शकतात जे ऑन आणि ऑफ केले जाऊ शकतात. उदाहरणार्थ, जेव्हा आपण sequence मध्ये *Alice* हे नाव पाहतो, तेव्हा आपण अंदाज लावतो की ते एका स्त्रीला संदर्भित करते, आणि state मध्ये एक flag उचलतो जो सांगतो की वाक्यात एक स्त्रीलिंगी नाम आहे. जेव्हा आपण पुढे *and Tom* शब्द पाहतो, तेव्हा आपण एक flag उचलतो जो सांगतो की वाक्यात एक बहुवचन नाम आहे. अशा प्रकारे state manipulate करून आपण वाक्याच्या व्याकरणात्मक गुणधर्मांचा मागोवा ठेवू शकतो.\n",
"\n",
"> **Note**: LSTMs च्या अंतर्गत रचना समजून घेण्यासाठी येथे एक उत्कृष्ट स्रोत आहे: [Understanding LSTM Networks](https://colah.github.io/posts/2015-08-Understanding-LSTMs/) क्रिस्टोफर ओलाह यांनी लिहिलेले.\n",
"\n",
"LSTM सेलची अंतर्गत रचना जरी क्लिष्ट दिसत असली तरी Keras ही अंमलबजावणी `LSTM` लेयरमध्ये लपवते, त्यामुळे वर दिलेल्या उदाहरणात आपल्याला फक्त recurrent लेयर बदलणे आवश्यक आहे:\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": [
"## द्विदिशात्मक आणि बहुपरत RNNs\n",
"\n",
"आत्तापर्यंतच्या उदाहरणांमध्ये, पुनरावृत्ती नेटवर्क्स अनुक्रमाच्या सुरुवातीपासून शेवटपर्यंत कार्य करतात. हे आपल्याला नैसर्गिक वाटते कारण हे त्याच दिशेने कार्य करते ज्या दिशेने आपण वाचतो किंवा भाषण ऐकतो. परंतु, अशा परिस्थितीसाठी जिथे इनपुट अनुक्रमाचा यादृच्छिक प्रवेश आवश्यक असतो, तिथे पुनरावृत्ती गणना दोन्ही दिशांनी चालवणे अधिक अर्थपूर्ण ठरते. अशा RNNs ज्यामध्ये दोन्ही दिशांनी गणना करण्याची परवानगी असते त्यांना **द्विदिशात्मक** RNNs म्हणतात, आणि त्यांना `Bidirectional` लेयरने पुनरावृत्ती लेयरला वेढून तयार करता येते.\n",
"\n",
"> **Note**: `Bidirectional` लेयर त्यामधील लेयरची दोन प्रत बनवते आणि त्या प्रतांपैकी एका प्रताचे `go_backwards` गुणधर्म `True` सेट करते, ज्यामुळे ती अनुक्रमाच्या विरुद्ध दिशेने जाते.\n",
"\n",
"पुनरावृत्ती नेटवर्क्स, एकदिशात्मक किंवा द्विदिशात्मक, अनुक्रमातील नमुने पकडतात आणि त्यांना स्टेट व्हेक्टरमध्ये साठवतात किंवा आउटपुट म्हणून परत करतात. जसे कॉनव्होल्यूशन नेटवर्क्समध्ये होते, तसेच आपण पहिल्या लेयरने काढलेल्या कमी स्तरातील नमुन्यांमधून उच्च स्तराचे नमुने पकडण्यासाठी पहिल्या लेयरनंतर आणखी एक पुनरावृत्ती लेयर तयार करू शकतो. यामुळे **बहुपरत RNN** ची संकल्पना तयार होते, ज्यामध्ये दोन किंवा अधिक पुनरावृत्ती नेटवर्क्स असतात, जिथे मागील लेयरचे आउटपुट पुढील लेयरला इनपुट म्हणून दिले जाते.\n",
"\n",
"![मल्टीलेयर लाँग-शॉर्ट-टर्म-मेमरी RNN दर्शवणारी प्रतिमा](../../../../../translated_images/mr/multi-layer-lstm.dd975e29bb2a59fe.webp)\n",
"\n",
"*फर्नांडो लोपेझ यांनी लिहिलेल्या [या अप्रतिम पोस्टमधून](https://towardsdatascience.com/from-a-lstm-cell-to-a-multilayer-lstm-network-with-pytorch-2899eb5696f3) घेतलेली प्रतिमा.*\n",
"\n",
"Keras या नेटवर्क्स तयार करणे सोपे बनवते, कारण तुम्हाला फक्त मॉडेलमध्ये अधिक पुनरावृत्ती लेयर्स जोडायच्या असतात. शेवटच्या लेयर वगळता सर्व लेयर्ससाठी, आपल्याला `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": [
"## इतर कार्यांसाठी RNNs\n",
"\n",
"आत्तापर्यंत, आपण RNNs चा वापर मजकूराच्या अनुक्रमांचे वर्गीकरण करण्यासाठी कसा करायचा यावर लक्ष केंद्रित केले आहे. पण ते यापेक्षा बरेच कार्य हाताळू शकतात, जसे की मजकूर निर्मिती आणि भाषांतर — आपण पुढील युनिटमध्ये ही कार्ये विचारात घेऊ.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**अस्वीकरण**: \nहा दस्तऐवज AI भाषांतर सेवा [Co-op Translator](https://github.com/Azure/co-op-translator) चा वापर करून भाषांतरित करण्यात आला आहे. आम्ही अचूकतेसाठी प्रयत्नशील असलो तरी, कृपया लक्षात घ्या की स्वयंचलित भाषांतरांमध्ये त्रुटी किंवा अचूकतेचा अभाव असू शकतो. मूळ भाषेतील दस्तऐवज हा अधिकृत स्रोत मानला जावा. महत्त्वाच्या माहितीसाठी व्यावसायिक मानवी भाषांतराची शिफारस केली जाते. या भाषांतराचा वापर केल्यामुळे उद्भवणाऱ्या कोणत्याही गैरसमज किंवा चुकीच्या अर्थासाठी आम्ही जबाबदार राहणार नाही.\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-28T09:33:46+00:00",
"source_file": "lessons/5-NLP/16-RNN/RNNTF.ipynb",
"language_code": "mr"
}
},
"nbformat": 4,
"nbformat_minor": 4
}