495 lines
42 KiB
Plaintext
495 lines
42 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# जनरेटिव नेटवर्क्स\n",
|
|
"\n",
|
|
"रिकरंट न्यूरल नेटवर्क्स (RNNs) और उनके गेटेड सेल वेरिएंट्स जैसे लॉन्ग शॉर्ट टर्म मेमोरी सेल्स (LSTMs) और गेटेड रिकारंट यूनिट्स (GRUs) ने भाषा मॉडलिंग के लिए एक तंत्र प्रदान किया है, यानी वे शब्दों के क्रम को सीख सकते हैं और अनुक्रम में अगले शब्द की भविष्यवाणी कर सकते हैं। यह हमें RNNs का उपयोग **जनरेटिव कार्यों** के लिए करने की अनुमति देता है, जैसे साधारण टेक्स्ट जनरेशन, मशीन ट्रांसलेशन, और यहां तक कि इमेज कैप्शनिंग।\n",
|
|
"\n",
|
|
"पिछली यूनिट में हमने जिस RNN आर्किटेक्चर पर चर्चा की थी, उसमें प्रत्येक RNN यूनिट ने अगले हिडन स्टेट को आउटपुट के रूप में उत्पन्न किया। हालांकि, हम प्रत्येक रिकारंट यूनिट में एक और आउटपुट जोड़ सकते हैं, जो हमें एक **अनुक्रम** आउटपुट करने की अनुमति देगा (जो मूल अनुक्रम की लंबाई के बराबर होगा)। इसके अलावा, हम ऐसे RNN यूनिट्स का उपयोग कर सकते हैं जो प्रत्येक चरण में इनपुट स्वीकार नहीं करते, बल्कि केवल एक प्रारंभिक स्टेट वेक्टर लेते हैं और फिर आउटपुट का एक अनुक्रम उत्पन्न करते हैं।\n",
|
|
"\n",
|
|
"इस नोटबुक में, हम सरल जनरेटिव मॉडलों पर ध्यान केंद्रित करेंगे जो हमें टेक्स्ट जनरेट करने में मदद करते हैं। सरलता के लिए, चलिए एक **कैरेक्टर-लेवल नेटवर्क** बनाते हैं, जो अक्षर दर अक्षर टेक्स्ट जनरेट करता है। प्रशिक्षण के दौरान, हमें कुछ टेक्स्ट कॉर्पस लेना होगा और उसे अक्षर अनुक्रमों में विभाजित करना होगा।\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"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",
|
|
"ds_train, ds_test = tfds.load('ag_news_subset').values()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## वर्णमाला शब्दावली बनाना\n",
|
|
"\n",
|
|
"वर्ण-स्तरीय जनरेटिव नेटवर्क बनाने के लिए, हमें टेक्स्ट को शब्दों के बजाय व्यक्तिगत अक्षरों में विभाजित करना होगा। `TextVectorization` लेयर, जिसे हमने पहले उपयोग किया था, ऐसा नहीं कर सकती, इसलिए हमारे पास दो विकल्प हैं:\n",
|
|
"\n",
|
|
"* टेक्स्ट को मैन्युअली लोड करें और 'हाथ से' टोकनाइज़ेशन करें, जैसा कि [इस आधिकारिक Keras उदाहरण](https://keras.io/examples/generative/lstm_character_level_text_generation/) में दिखाया गया है।\n",
|
|
"* वर्ण-स्तरीय टोकनाइज़ेशन के लिए `Tokenizer` क्लास का उपयोग करें।\n",
|
|
"\n",
|
|
"हम दूसरे विकल्प को चुनेंगे। `Tokenizer` का उपयोग शब्दों में टोकनाइज़ करने के लिए भी किया जा सकता है, इसलिए कोई आसानी से वर्ण-स्तरीय से शब्द-स्तरीय टोकनाइज़ेशन में स्विच कर सकता है।\n",
|
|
"\n",
|
|
"वर्ण-स्तरीय टोकनाइज़ेशन करने के लिए, हमें `char_level=True` पैरामीटर पास करना होगा:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"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",
|
|
"tokenizer = keras.preprocessing.text.Tokenizer(char_level=True,lower=False)\n",
|
|
"tokenizer.fit_on_texts([x['title'].numpy().decode('utf-8') for x in ds_train])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"हम एक विशेष टोकन का उपयोग करना चाहते हैं ताकि **अनुक्रम के अंत** को दर्शाया जा सके, जिसे हम `<eos>` कहेंगे। आइए इसे मैन्युअल रूप से शब्दावली में जोड़ें:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"eos_token = len(tokenizer.word_index)+1\n",
|
|
"tokenizer.word_index['<eos>'] = eos_token\n",
|
|
"\n",
|
|
"vocab_size = eos_token + 1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[[48, 2, 10, 10, 5, 44, 1, 25, 5, 8, 10, 13, 78]]"
|
|
]
|
|
},
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"tokenizer.texts_to_sequences(['Hello, world!'])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## शीर्षक उत्पन्न करने के लिए एक जनरेटिव RNN को प्रशिक्षित करना\n",
|
|
"\n",
|
|
"हम RNN को समाचार शीर्षक उत्पन्न करने के लिए इस प्रकार प्रशिक्षित करेंगे। प्रत्येक चरण में, हम एक शीर्षक लेंगे, जिसे RNN में दिया जाएगा, और प्रत्येक इनपुट अक्षर के लिए हम नेटवर्क से अगला आउटपुट अक्षर उत्पन्न करने के लिए कहेंगे:\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"हमारे अनुक्रम के अंतिम अक्षर के लिए, हम नेटवर्क से `<eos>` टोकन उत्पन्न करने के लिए कहेंगे।\n",
|
|
"\n",
|
|
"यहां उपयोग किए जा रहे जनरेटिव RNN का मुख्य अंतर यह है कि हम RNN के प्रत्येक चरण से आउटपुट लेंगे, न कि केवल अंतिम सेल से। इसे RNN सेल में `return_sequences` पैरामीटर निर्दिष्ट करके प्राप्त किया जा सकता है।\n",
|
|
"\n",
|
|
"इस प्रकार, प्रशिक्षण के दौरान, नेटवर्क में इनपुट कुछ लंबाई के एन्कोडेड अक्षरों का अनुक्रम होगा, और आउटपुट उसी लंबाई का अनुक्रम होगा, लेकिन एक तत्व द्वारा शिफ्ट किया गया और `<eos>` से समाप्त किया गया। मिनीबैच में कई ऐसे अनुक्रम शामिल होंगे, और हमें सभी अनुक्रमों को संरेखित करने के लिए **पैडिंग** का उपयोग करना होगा।\n",
|
|
"\n",
|
|
"आइए ऐसी फ़ंक्शन बनाएं जो हमारे लिए डेटासेट को परिवर्तित करें। क्योंकि हम मिनीबैच स्तर पर अनुक्रमों को पैड करना चाहते हैं, हम पहले `.batch()` कॉल करके डेटासेट को बैच करेंगे, और फिर इसे `map` करेंगे ताकि परिवर्तन किया जा सके। इसलिए, परिवर्तन फ़ंक्शन पूरे मिनीबैच को एक पैरामीटर के रूप में लेगा:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def title_batch(x):\n",
|
|
" x = [t.numpy().decode('utf-8') for t in x]\n",
|
|
" z = tokenizer.texts_to_sequences(x)\n",
|
|
" z = tf.keras.preprocessing.sequence.pad_sequences(z)\n",
|
|
" return tf.one_hot(z,vocab_size), tf.one_hot(tf.concat([z[:,1:],tf.constant(eos_token,shape=(len(z),1))],axis=1),vocab_size)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"कुछ महत्वपूर्ण बातें जो हम यहाँ करते हैं:\n",
|
|
"* सबसे पहले हम स्ट्रिंग टेंसर से वास्तविक टेक्स्ट को निकालते हैं\n",
|
|
"* `text_to_sequences` स्ट्रिंग्स की सूची को पूर्णांक टेंसर की सूची में बदल देता है\n",
|
|
"* `pad_sequences` उन टेंसर को उनकी अधिकतम लंबाई तक पैड करता है\n",
|
|
"* अंत में हम सभी अक्षरों को वन-हॉट एन्कोड करते हैं, और साथ ही शिफ्टिंग और `<eos>` जोड़ने का काम भी करते हैं। हम जल्द ही देखेंगे कि हमें वन-हॉट-एन्कोडेड अक्षरों की आवश्यकता क्यों है\n",
|
|
"\n",
|
|
"हालांकि, यह फ़ंक्शन **Pythonic** है, यानी इसे Tensorflow के कम्प्यूटेशनल ग्राफ में स्वचालित रूप से अनुवादित नहीं किया जा सकता। अगर हम इस फ़ंक्शन को सीधे `Dataset.map` फ़ंक्शन में उपयोग करने की कोशिश करेंगे, तो हमें त्रुटियाँ मिलेंगी। हमें इस Pythonic कॉल को `py_function` रैपर का उपयोग करके संलग्न करना होगा:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def title_batch_fn(x):\n",
|
|
" x = x['title']\n",
|
|
" a,b = tf.py_function(title_batch,inp=[x],Tout=(tf.float32,tf.float32))\n",
|
|
" return a,b"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"> **Note**: पायथनिक और टेन्सरफ्लो ट्रांसफॉर्मेशन फंक्शन्स के बीच अंतर करना थोड़ा जटिल लग सकता है, और आप सोच सकते हैं कि हम डेटा सेट को `fit` में पास करने से पहले मानक पायथन फंक्शन्स का उपयोग करके क्यों नहीं बदलते। हालांकि यह निश्चित रूप से किया जा सकता है, `Dataset.map` का उपयोग करने का एक बड़ा लाभ है, क्योंकि डेटा ट्रांसफॉर्मेशन पाइपलाइन टेन्सरफ्लो कम्प्यूटेशनल ग्राफ का उपयोग करके निष्पादित होती है, जो GPU कम्प्यूटेशन का लाभ उठाती है और CPU/GPU के बीच डेटा पास करने की आवश्यकता को कम करती है।\n",
|
|
"\n",
|
|
"अब हम अपना जनरेटर नेटवर्क बना सकते हैं और प्रशिक्षण शुरू कर सकते हैं। इसे किसी भी पुनरावर्ती सेल पर आधारित किया जा सकता है जिसे हमने पिछले यूनिट में चर्चा की थी (सिंपल, LSTM या GRU)। हमारे उदाहरण में हम LSTM का उपयोग करेंगे।\n",
|
|
"\n",
|
|
"चूंकि नेटवर्क इनपुट के रूप में अक्षरों को लेता है, और शब्दावली का आकार काफी छोटा है, हमें एम्बेडिंग लेयर की आवश्यकता नहीं है। वन-हॉट-एनकोडेड इनपुट सीधे LSTM सेल में जा सकता है। आउटपुट लेयर एक `Dense` क्लासिफायर होगी जो LSTM आउटपुट को वन-हॉट-एनकोडेड टोकन नंबरों में बदल देगी।\n",
|
|
"\n",
|
|
"इसके अलावा, चूंकि हम वेरिएबल-लेंथ सीक्वेंस के साथ काम कर रहे हैं, हम `Masking` लेयर का उपयोग कर सकते हैं ताकि एक मास्क बनाया जा सके जो स्ट्रिंग के पैडेड हिस्से को अनदेखा कर दे। यह सख्ती से आवश्यक नहीं है, क्योंकि हम `<eos>` टोकन से आगे की चीजों में बहुत अधिक रुचि नहीं रखते हैं, लेकिन हम इस लेयर प्रकार के साथ कुछ अनुभव प्राप्त करने के लिए इसका उपयोग करेंगे। `input_shape` `(None, vocab_size)` होगा, जहां `None` वेरिएबल लंबाई की सीक्वेंस को इंगित करता है, और आउटपुट आकार भी `(None, vocab_size)` होगा, जैसा कि आप `summary` से देख सकते हैं:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Model: \"sequential\"\n",
|
|
"_________________________________________________________________\n",
|
|
"Layer (type) Output Shape Param # \n",
|
|
"=================================================================\n",
|
|
"masking (Masking) (None, None, 84) 0 \n",
|
|
"_________________________________________________________________\n",
|
|
"lstm (LSTM) (None, None, 128) 109056 \n",
|
|
"_________________________________________________________________\n",
|
|
"dense (Dense) (None, None, 84) 10836 \n",
|
|
"=================================================================\n",
|
|
"Total params: 119,892\n",
|
|
"Trainable params: 119,892\n",
|
|
"Non-trainable params: 0\n",
|
|
"_________________________________________________________________\n",
|
|
"15000/15000 [==============================] - 229s 15ms/step - loss: 1.5385\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"<tensorflow.python.keras.callbacks.History at 0x7fa40c1245e0>"
|
|
]
|
|
},
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"model = keras.models.Sequential([\n",
|
|
" keras.layers.Masking(input_shape=(None,vocab_size)),\n",
|
|
" keras.layers.LSTM(128,return_sequences=True),\n",
|
|
" keras.layers.Dense(vocab_size,activation='softmax')\n",
|
|
"])\n",
|
|
"\n",
|
|
"model.summary()\n",
|
|
"model.compile(loss='categorical_crossentropy')\n",
|
|
"\n",
|
|
"model.fit(ds_train.batch(8).map(title_batch_fn))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## आउटपुट उत्पन्न करना\n",
|
|
"\n",
|
|
"अब जब हमने मॉडल को प्रशिक्षित कर लिया है, तो हम इसे कुछ आउटपुट उत्पन्न करने के लिए उपयोग करना चाहते हैं। सबसे पहले, हमें टोकन नंबरों की एक श्रृंखला द्वारा दर्शाए गए टेक्स्ट को डिकोड करने का एक तरीका चाहिए। इसके लिए, हम `tokenizer.sequences_to_texts` फ़ंक्शन का उपयोग कर सकते हैं; हालांकि, यह कैरेक्टर-लेवल टोकनाइजेशन के साथ अच्छी तरह से काम नहीं करता। इसलिए, हम टोकनाइज़र से टोकन की एक डिक्शनरी (जिसे `word_index` कहा जाता है) लेंगे, एक रिवर्स मैप बनाएंगे, और अपना खुद का डिकोडिंग फ़ंक्शन लिखेंगे:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"reverse_map = {val:key for key, val in tokenizer.word_index.items()}\n",
|
|
"\n",
|
|
"def decode(x):\n",
|
|
" return ''.join([reverse_map[t] for t in x])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"अब, चलिए जनरेशन करते हैं। हम किसी स्ट्रिंग `start` से शुरुआत करेंगे, इसे एक अनुक्रम `inp` में एन्कोड करेंगे, और फिर हर चरण में हम अपने नेटवर्क को कॉल करेंगे ताकि अगला कैरेक्टर अनुमानित किया जा सके।\n",
|
|
"\n",
|
|
"नेटवर्क का आउटपुट `out` एक वेक्टर होता है जिसमें `vocab_size` तत्व होते हैं, जो प्रत्येक टोकन की संभावनाओं का प्रतिनिधित्व करते हैं। हम `argmax` का उपयोग करके सबसे संभावित टोकन नंबर ढूंढ सकते हैं। इसके बाद हम इस कैरेक्टर को जनरेट किए गए टोकन्स की सूची में जोड़ते हैं और जनरेशन की प्रक्रिया जारी रखते हैं। इस प्रक्रिया में एक कैरेक्टर जनरेट करने की प्रक्रिया को `size` बार दोहराया जाता है ताकि आवश्यक संख्या में कैरेक्टर्स जनरेट किए जा सकें, और हम जल्दी समाप्त कर देते हैं जब `eos_token` मिल जाता है।\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"'Today #39;s lead to strike for the strike for the strike for the strike (AFP)'"
|
|
]
|
|
},
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"def generate(model,size=100,start='Today '):\n",
|
|
" inp = tokenizer.texts_to_sequences([start])[0]\n",
|
|
" chars = inp\n",
|
|
" for i in range(size):\n",
|
|
" out = model(tf.expand_dims(tf.one_hot(inp,vocab_size),0))[0][-1]\n",
|
|
" nc = tf.argmax(out)\n",
|
|
" if nc==eos_token:\n",
|
|
" break\n",
|
|
" chars.append(nc.numpy())\n",
|
|
" inp = inp+[nc]\n",
|
|
" return decode(chars)\n",
|
|
" \n",
|
|
"generate(model)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## प्रशिक्षण के दौरान आउटपुट का नमूना लेना\n",
|
|
"\n",
|
|
"चूंकि हमारे पास *सटीकता* जैसे कोई उपयोगी मेट्रिक्स नहीं हैं, इसलिए यह देखने का एकमात्र तरीका कि हमारा मॉडल बेहतर हो रहा है, **प्रशिक्षण के दौरान उत्पन्न स्ट्रिंग का नमूना लेना** है। इसे करने के लिए, हम **कॉलबैक्स** का उपयोग करेंगे, यानी ऐसी फ़ंक्शन्स जिन्हें हम `fit` फ़ंक्शन में पास कर सकते हैं, और जो प्रशिक्षण के दौरान समय-समय पर कॉल की जाएंगी।\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Epoch 1/3\n",
|
|
"15000/15000 [==============================] - 226s 15ms/step - loss: 1.2703\n",
|
|
"Today #39;s a lead in the company for the strike\n",
|
|
"Epoch 2/3\n",
|
|
"15000/15000 [==============================] - 227s 15ms/step - loss: 1.2057\n",
|
|
"Today #39;s the Market Service on Security Start (AP)\n",
|
|
"Epoch 3/3\n",
|
|
"15000/15000 [==============================] - 226s 15ms/step - loss: 1.1752\n",
|
|
"Today #39;s a line on the strike to start for the start\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"<tensorflow.python.keras.callbacks.History at 0x7fa40c74e3d0>"
|
|
]
|
|
},
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"sampling_callback = keras.callbacks.LambdaCallback(\n",
|
|
" on_epoch_end = lambda batch, logs: print(generate(model))\n",
|
|
")\n",
|
|
"\n",
|
|
"model.fit(ds_train.batch(8).map(title_batch_fn),callbacks=[sampling_callback],epochs=3)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"यह उदाहरण पहले से ही काफी अच्छा पाठ उत्पन्न करता है, लेकिन इसे कई तरीकों से और बेहतर बनाया जा सकता है:\n",
|
|
"\n",
|
|
"* **अधिक पाठ**। हमने अपने कार्य के लिए केवल शीर्षकों का उपयोग किया है, लेकिन आप पूरे पाठ के साथ प्रयोग करना चाह सकते हैं। याद रखें कि RNNs लंबे अनुक्रमों को संभालने में बहुत अच्छे नहीं होते हैं, इसलिए उन्हें छोटे वाक्यों में विभाजित करना या हमेशा किसी पूर्वनिर्धारित मान `num_chars` (जैसे, 256) की निश्चित अनुक्रम लंबाई पर प्रशिक्षण देना समझदारी हो सकती है। आप ऊपर दिए गए उदाहरण को ऐसी संरचना में बदलने की कोशिश कर सकते हैं, [आधिकारिक Keras ट्यूटोरियल](https://keras.io/examples/generative/lstm_character_level_text_generation/) को प्रेरणा के रूप में उपयोग करते हुए।\n",
|
|
"\n",
|
|
"* **मल्टीलेयर LSTM**। LSTM कोशिकाओं की 2 या 3 परतों को आज़माना समझदारी हो सकता है। जैसा कि हमने पिछले यूनिट में उल्लेख किया था, LSTM की प्रत्येक परत पाठ से कुछ पैटर्न निकालती है, और कैरेक्टर-लेवल जनरेटर के मामले में हम उम्मीद कर सकते हैं कि निचली LSTM परत अक्षरों को निकालने के लिए जिम्मेदार होगी, और ऊपरी परतें - शब्द और शब्द संयोजन के लिए। इसे LSTM कंस्ट्रक्टर में परतों की संख्या का पैरामीटर पास करके आसानी से लागू किया जा सकता है।\n",
|
|
"\n",
|
|
"* आप **GRU यूनिट्स** के साथ भी प्रयोग करना चाह सकते हैं और देख सकते हैं कि कौन सा बेहतर प्रदर्शन करता है, और **विभिन्न छिपी परत के आकार** के साथ भी। बहुत बड़ी छिपी परत ओवरफिटिंग का कारण बन सकती है (जैसे, नेटवर्क सटीक पाठ सीख लेगा), और छोटा आकार अच्छा परिणाम उत्पन्न नहीं कर सकता।\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## सॉफ्ट टेक्स्ट जनरेशन और टेम्परेचर\n",
|
|
"\n",
|
|
"`generate` की पिछली परिभाषा में, हम हमेशा उस अक्षर को अगला अक्षर चुनते थे जिसकी संभावना सबसे अधिक होती थी। इसका परिणाम यह होता था कि टेक्स्ट अक्सर बार-बार एक ही अक्षर अनुक्रम में \"चक्रित\" हो जाता था, जैसे इस उदाहरण में:\n",
|
|
"```\n",
|
|
"today of the second the company and a second the company ...\n",
|
|
"```\n",
|
|
"\n",
|
|
"हालांकि, अगर हम अगले अक्षर के लिए संभावना वितरण को देखें, तो यह हो सकता है कि कुछ उच्चतम संभावनाओं के बीच का अंतर बहुत बड़ा न हो, जैसे कि एक अक्षर की संभावना 0.2 हो, और दूसरे की 0.19। उदाहरण के लिए, जब अनुक्रम '*play*' में अगले अक्षर की तलाश की जाती है, तो अगला अक्षर समान रूप से स्पेस या **e** (जैसे शब्द *player* में) हो सकता है।\n",
|
|
"\n",
|
|
"इससे यह निष्कर्ष निकलता है कि हमेशा उच्चतम संभावना वाले अक्षर को चुनना \"न्यायसंगत\" नहीं है, क्योंकि दूसरे उच्चतम को चुनना भी हमें सार्थक टेक्स्ट की ओर ले जा सकता है। यह अधिक समझदारी होगी कि नेटवर्क आउटपुट द्वारा दी गई संभावना वितरण से अक्षरों को **सैंपल** किया जाए।\n",
|
|
"\n",
|
|
"यह सैंपलिंग `np.multinomial` फंक्शन का उपयोग करके की जा सकती है, जो तथाकथित **मल्टिनोमियल वितरण** को लागू करता है। एक फंक्शन जो इस **सॉफ्ट** टेक्स्ट जनरेशन को लागू करता है, नीचे परिभाषित है:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 33,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"--- Temperature = 0.3\n",
|
|
"Today #39;s strike #39; to start at the store return\n",
|
|
"On Sunday PO to Be Data Profit Up (Reuters)\n",
|
|
"Moscow, SP wins straight to the Microsoft #39;s control of the space start\n",
|
|
"President olding of the blast start for the strike to pay <b>...</b>\n",
|
|
"Little red riding hood ficed to the spam countered in European <b>...</b>\n",
|
|
"\n",
|
|
"--- Temperature = 0.8\n",
|
|
"Today countie strikes ryder missile faces food market blut\n",
|
|
"On Sunday collores lose-toppy of sale of Bullment in <b>...</b>\n",
|
|
"Moscow, IBM Diffeiting in Afghan Software Hotels (Reuters)\n",
|
|
"President Ol Luster for Profit Peaced Raised (AP)\n",
|
|
"Little red riding hood dace on depart talks #39; bank up\n",
|
|
"\n",
|
|
"--- Temperature = 1.0\n",
|
|
"Today wits House buiting debate fixes #39; supervice stake again\n",
|
|
"On Sunday arling digital poaching In for level\n",
|
|
"Moscow, DS Up 7, Top Proble Protest Caprey Mamarian Strike\n",
|
|
"President teps help of roubler stepted lessabul-Dhalitics (AFP)\n",
|
|
"Little red riding hood signs on cash in Carter-youb\n",
|
|
"\n",
|
|
"--- Temperature = 1.3\n",
|
|
"Today wits flawer ro, pSIA figat's co DroftwavesIs Talo up\n",
|
|
"On Sunday hround elitwing wint EU Powerburlinetien\n",
|
|
"Moscow, Bazz #39;s sentries olymen winnelds' next for Olympite Huc?\n",
|
|
"President lost securitys from power Elections in Smiltrials\n",
|
|
"Little red riding hood vides profit, exponituity, profitmainalist-at said listers\n",
|
|
"\n",
|
|
"--- Temperature = 1.8\n",
|
|
"Today #39;It: He deat: N.KA Asside\n",
|
|
"On Sunday i arry Par aldeup patient Wo stele1\n"
|
|
]
|
|
},
|
|
{
|
|
"ename": "KeyError",
|
|
"evalue": "0",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)",
|
|
"\u001b[0;32m<ipython-input-33-db32367a0feb>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 18\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"\\n--- Temperature = {i}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mj\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 20\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgenerate_soft\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0msize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m300\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mstart\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mwords\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mj\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mtemperature\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
|
|
"\u001b[0;32m<ipython-input-33-db32367a0feb>\u001b[0m in \u001b[0;36mgenerate_soft\u001b[0;34m(model, size, start, temperature)\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0mchars\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0minp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0minp\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mnc\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 13\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mdecode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mchars\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 14\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0mwords\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m'Today '\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'On Sunday '\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'Moscow, '\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'President '\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'Little red riding hood '\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
|
"\u001b[0;32m<ipython-input-10-3f5fa6130b1d>\u001b[0m in \u001b[0;36mdecode\u001b[0;34m(x)\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mdecode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0;34m''\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjoin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mreverse_map\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mt\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mt\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
|
|
"\u001b[0;32m<ipython-input-10-3f5fa6130b1d>\u001b[0m in \u001b[0;36m<listcomp>\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mdecode\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0;34m''\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjoin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mreverse_map\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mt\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mt\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
|
|
"\u001b[0;31mKeyError\u001b[0m: 0"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def generate_soft(model,size=100,start='Today ',temperature=1.0):\n",
|
|
" inp = tokenizer.texts_to_sequences([start])[0]\n",
|
|
" chars = inp\n",
|
|
" for i in range(size):\n",
|
|
" out = model(tf.expand_dims(tf.one_hot(inp,vocab_size),0))[0][-1]\n",
|
|
" probs = tf.exp(tf.math.log(out)/temperature).numpy().astype(np.float64)\n",
|
|
" probs = probs/np.sum(probs)\n",
|
|
" nc = np.argmax(np.random.multinomial(1,probs,1))\n",
|
|
" if nc==eos_token:\n",
|
|
" break\n",
|
|
" chars.append(nc)\n",
|
|
" inp = inp+[nc]\n",
|
|
" return decode(chars)\n",
|
|
"\n",
|
|
"words = ['Today ','On Sunday ','Moscow, ','President ','Little red riding hood ']\n",
|
|
" \n",
|
|
"for i in [0.3,0.8,1.0,1.3,1.8]:\n",
|
|
" print(f\"\\n--- Temperature = {i}\")\n",
|
|
" for j in range(5):\n",
|
|
" print(generate_soft(model,size=300,start=words[j],temperature=i))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"हमने एक और पैरामीटर **तापमान** पेश किया है, जिसका उपयोग यह संकेत देने के लिए किया जाता है कि हमें उच्चतम संभावना से कितनी दृढ़ता से चिपकना चाहिए। यदि तापमान 1.0 है, तो हम निष्पक्ष बहुपद नमूना लेते हैं, और जब तापमान अनंत तक जाता है - सभी संभावनाएँ समान हो जाती हैं, और हम अगला वर्ण यादृच्छिक रूप से चुनते हैं। नीचे दिए गए उदाहरण में हम देख सकते हैं कि जब हम तापमान को बहुत अधिक बढ़ाते हैं तो पाठ अर्थहीन हो जाता है, और जब यह 0 के करीब होता है तो यह \"चक्रित\" कठोर-जनित पाठ जैसा दिखता है।\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n---\n\n**अस्वीकरण**: \nयह दस्तावेज़ AI अनुवाद सेवा [Co-op Translator](https://github.com/Azure/co-op-translator) का उपयोग करके अनुवादित किया गया है। जबकि हम सटीकता सुनिश्चित करने का प्रयास करते हैं, कृपया ध्यान दें कि स्वचालित अनुवाद में त्रुटियां या अशुद्धियां हो सकती हैं। मूल भाषा में उपलब्ध मूल दस्तावेज़ को प्रामाणिक स्रोत माना जाना चाहिए। महत्वपूर्ण जानकारी के लिए, पेशेवर मानव अनुवाद की सिफारिश की जाती है। इस अनुवाद के उपयोग से उत्पन्न किसी भी गलतफहमी या गलत व्याख्या के लिए हम जिम्मेदार नहीं हैं।\n"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"interpreter": {
|
|
"hash": "16af2a8bbb083ea23e5e41c7f5787656b2ce26968575d8763f2c4b17f9cd711f"
|
|
},
|
|
"kernelspec": {
|
|
"display_name": "Python 3.8.12 ('py38')",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"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.8.12"
|
|
},
|
|
"coopTranslator": {
|
|
"original_hash": "9fbb7d5fda708537649f71f5f646fcde",
|
|
"translation_date": "2025-08-31T15:12:26+00:00",
|
|
"source_file": "lessons/5-NLP/17-GenerativeNetworks/GenerativeTF.ipynb",
|
|
"language_code": "hi"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
} |