493 lines
42 KiB
Plaintext
493 lines
42 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# जेनेरेटिभ नेटवर्कहरू\n",
|
||
"\n",
|
||
"Recurrent Neural Networks (RNNs) र तिनका गेटेड सेल भेरियन्टहरू जस्तै Long Short Term Memory Cells (LSTMs) र Gated Recurrent Units (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": [
|
||
"हामीले **sequence को अन्त्य** जनाउनको लागि एउटा विशेष टोकन प्रयोग गर्न चाहन्छौं, जसलाई हामी `<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 को प्रत्येक चरणबाट आउटपुट लिनेछौं, न कि केवल अन्तिम सेलबाट। यो `return_sequences` प्यारामिटरलाई RNN सेलमा निर्दिष्ट गरेर हासिल गर्न सकिन्छ।\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",
|
||
"* पहिलोमा, हामी स्ट्रिङ टेन्सरबाट वास्तविक पाठ निकाल्छौं।\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": [
|
||
"> **नोट**: Pythonic र Tensorflow रूपान्तरण कार्यहरू बीचको भिन्नता बुझ्न अलि जटिल लाग्न सक्छ, र तपाईं सोच्न सक्नुहुन्छ कि किन हामीले डेटासेटलाई `fit` मा पठाउनु अघि सामान्य Python कार्यहरू प्रयोग गरेर रूपान्तरण गर्दैनौं। यद्यपि यो पक्कै गर्न सकिन्छ, `Dataset.map` प्रयोग गर्दा ठूलो फाइदा हुन्छ, किनभने डेटा रूपान्तरण पाइपलाइन Tensorflow को गणनात्मक ग्राफ प्रयोग गरेर कार्यान्वयन गरिन्छ, जसले GPU गणनाको फाइदा लिन्छ, र CPU/GPU बीच डेटा पास गर्नुपर्ने आवश्यकता कम गर्दछ।\n",
|
||
"\n",
|
||
"अब हामी हाम्रो generator नेटवर्क निर्माण गर्न सक्छौं र प्रशिक्षण सुरु गर्न सक्छौं। यो कुनै पनि पुनरावर्ती सेलमा आधारित हुन सक्छ जुन हामीले अघिल्लो इकाईमा छलफल गरेका थियौं (जस्तै, simple, LSTM वा GRU)। हाम्रो उदाहरणमा हामी LSTM प्रयोग गर्नेछौं।\n",
|
||
"\n",
|
||
"किनभने नेटवर्कले अक्षरहरूलाई इनपुटको रूपमा लिन्छ, र शब्दकोशको आकार धेरै सानो छ, हामीलाई embedding layer को आवश्यकता पर्दैन, one-hot-encoded इनपुट सिधै LSTM सेलमा जान सक्छ। आउटपुट लेयर `Dense` classifier हुनेछ, जसले LSTM को आउटपुटलाई one-hot-encoded टोकन नम्बरहरूमा रूपान्तरण गर्नेछ।\n",
|
||
"\n",
|
||
"यसका अतिरिक्त, किनभने हामी variable-length sequences संग काम गरिरहेका छौं, हामी `Masking` लेयर प्रयोग गर्न सक्छौं जसले स्ट्रिङको padded भागलाई बेवास्ता गर्ने मास्क सिर्जना गर्दछ। यो अनिवार्य रूपमा आवश्यक छैन, किनभने `<eos>` टोकन भन्दा परको सबै कुरामा हामी धेरै रुचि राख्दैनौं, तर हामी यस प्रकारको लेयरसँग अनुभव प्राप्त गर्नको लागि यसलाई प्रयोग गर्नेछौं। `input_shape` `(None, vocab_size)` हुनेछ, जहाँ `None` ले variable length को sequence संकेत गर्दछ, र आउटपुट आकार पनि `(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",
|
||
"* **अधिक पाठ**। हामीले हाम्रो कार्यका लागि केवल शीर्षकहरू प्रयोग गरेका छौं, तर तपाईं पूर्ण पाठसँग प्रयोग गर्न चाहनुहुन्छ। याद गर्नुहोस् कि RNNs लामो अनुक्रमहरू ह्यान्डल गर्न धेरै राम्रो छैनन्, त्यसैले तिनीहरूलाई छोटो वाक्यहरूमा विभाजन गर्नु वा निश्चित अनुक्रम लम्बाइ `num_chars` (जस्तै, 256) को पूर्वनिर्धारित मानमा सधैं प्रशिक्षण गर्नु उपयुक्त हुन्छ। तपाईं माथिको उदाहरणलाई यस्तो वास्तुकलामा परिवर्तन गर्न प्रयास गर्न सक्नुहुन्छ, [आधिकारिक Keras ट्यूटोरियल](https://keras.io/examples/generative/lstm_character_level_text_generation/) लाई प्रेरणाको रूपमा प्रयोग गर्दै।\n",
|
||
"* **बहु-स्तरीय LSTM**। LSTM को 2 वा 3 तह कोशिकाहरू प्रयास गर्नु उपयुक्त हुन्छ। जस्तै हामीले अघिल्लो इकाईमा उल्लेख गर्यौं, प्रत्येक LSTM तहले पाठबाट निश्चित ढाँचाहरू निकाल्छ, र क्यारेक्टर-स्तरको जेनेरेटरको अवस्थामा हामी अपेक्षा गर्न सक्छौं कि तल्लो LSTM तहले अक्षरहरू निकाल्ने जिम्मेवारी लिन्छ, र माथिल्लो तहहरूले शब्द र शब्द संयोजनहरू। यो सरल रूपमा LSTM कन्स्ट्रक्टरमा तहहरूको संख्या पार गरेर कार्यान्वयन गर्न सकिन्छ।\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",
|
||
"तर, यदि हामी अर्को अक्षरको सम्भावना वितरणलाई हेर्छौं भने, केही उच्चतम सम्भावनाहरूको बीचको अन्तर ठूलो नहुन सक्छ, जस्तै एउटा अक्षरको सम्भावना ०.२ हुन सक्छ भने अर्कोको ०.१९। उदाहरणका लागि, '*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": [
|
||
"हामीले **तापक्रम** नामक अर्को प्यारामिटर प्रस्तुत गरेका छौं, जसले उच्च सम्भावनामा कति दृढताका साथ टाँसिनुपर्छ भनेर संकेत गर्न प्रयोग गरिन्छ। यदि तापक्रम १.० छ भने, हामी निष्पक्ष बहुपद नमूना लिन्छौं, र जब तापक्रम अनन्ततिर जान्छ - सबै सम्भावनाहरू समान हुन्छन्, र हामीले अर्को अक्षर अनियमित रूपमा चयन गर्छौं। तलको उदाहरणमा, हामीले देख्न सक्छौं कि जब हामी तापक्रम धेरै बढाउँछौं, पाठ अर्थहीन बन्छ, र जब यो ० नजिक जान्छ, यो \"चक्रित\" कडा-उत्पन्न पाठ जस्तो देखिन्छ।\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-28T09:12:58+00:00",
|
||
"source_file": "lessons/5-NLP/17-GenerativeNetworks/GenerativeTF.ipynb",
|
||
"language_code": "ne"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 4
|
||
} |