494 lines
45 KiB
Plaintext
494 lines
45 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# ஜெனரேட்டிவ் நெட்வொர்க்கள்\n",
|
|
"\n",
|
|
"மீண்டும் மீண்டும் செயல்படும் நரம்பியல் நெட்வொர்க்கள் (Recurrent Neural Networks - RNNs) மற்றும் அவற்றின் கதவுகள் கொண்ட செல்கள் போன்ற Long Short Term Memory Cells (LSTMs) மற்றும் Gated Recurrent Units (GRUs) மொழி மாதிரியாக்கத்திற்கான ஒரு முறைமையை வழங்கின. அதாவது, அவை சொற்களின் வரிசையை கற்றுக்கொண்டு, ஒரு வரிசையில் அடுத்த சொல் என்னவென்று கணிக்க முடியும். இதன் மூலம், RNNகளை **ஜெனரேட்டிவ் பணிகளுக்கு** பயன்படுத்த முடியும், உதாரணமாக சாதாரண உரை உருவாக்கம், இயந்திர மொழிபெயர்ப்பு, மற்றும் பட விளக்க உரை உருவாக்கம் போன்றவை.\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",
|
|
"எழுத்து மட்டத்திலான உருவாக்க வலையமைப்பை உருவாக்க, உரையை சொற்களாக değil, தனிப்பட்ட எழுத்துகளாகப் பிரிக்க வேண்டும். `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": [
|
|
"இப்போது, உரையை எண்களின் வரிசைகளாக குறியாக்க, நாம் பயன்படுத்தலாம்:\n"
|
|
]
|
|
},
|
|
{
|
|
"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>`-இன் மூலம் முடிவடையும். மினிபேட்ச் பல வரிசைகளைக் கொண்டிருக்கும், மேலும் அனைத்து வரிசைகளையும் ஒழுங்குபடுத்த **padding** பயன்படுத்த வேண்டும்.\n",
|
|
"\n",
|
|
"நமக்கு தரவுத்தொகுப்பை மாற்றும் செயல்பாடுகளை உருவாக்க வேண்டும். மினிபேட்ச் அளவில் வரிசைகளை padding செய்ய விரும்புவதால், முதலில் `.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",
|
|
"* முதலில், string tensor-இலிருந்து உண்மையான உரையை எடுக்கிறோம்\n",
|
|
"* `text_to_sequences` string-களின் பட்டியலை integer tensor-களின் பட்டியலாக மாற்றுகிறது\n",
|
|
"* `pad_sequences` அந்த tensor-களை அவற்றின் அதிகபட்ச நீளத்திற்கு pad செய்கிறது\n",
|
|
"* இறுதியாக, அனைத்து எழுத்துக்களையும் one-hot encode செய்கிறோம், மேலும் shifting மற்றும் `<eos>` சேர்த்தல் செய்கிறோம். ஏன் one-hot-encoded எழுத்துக்கள் தேவையென விரைவில் பார்க்கப்போவோம்\n",
|
|
"\n",
|
|
"ஆனால், இந்த function **Pythonic** ஆக உள்ளது, அதாவது இது Tensorflow கணினி graph-இல் தானாக மாற்ற முடியாது. இந்த function-ஐ நேரடியாக `Dataset.map` function-இல் பயன்படுத்த முயற்சித்தால் பிழைகள் ஏற்படும். இந்த Pythonic call-ஐ `py_function` wrapper-ஐ பயன்படுத்தி மூட வேண்டும்:\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**: Pythonic மற்றும் Tensorflow மாற்ற செயல்பாடுகளுக்கு இடையிலான வேறுபாட்டை புரிந்து கொள்வது கொஞ்சம் சிக்கலாக தோன்றலாம், மேலும் ஏன் தரவுத்தொகுப்பை `fit`க்கு அனுப்புவதற்கு முன் Python செயல்பாடுகளைப் பயன்படுத்தி மாற்றம் செய்யவில்லை என்று நீங்கள் கேள்வி எழுப்பலாம். இது நிச்சயமாக செய்யக்கூடியது, ஆனால் `Dataset.map` பயன்படுத்துவதற்கு பெரிய நன்மை உள்ளது, ஏனெனில் தரவுமாற்ற குழாய் Tensorflow கணினி கிராஃபைப் பயன்படுத்தி செயல்படுத்தப்படுகிறது, இது GPU கணக்கீடுகளைப் பயன்படுத்துகிறது மற்றும் CPU/GPU இடையே தரவை மாற்றுவதற்கான தேவையை குறைக்கிறது.\n",
|
|
"\n",
|
|
"இப்போது நாங்கள் எங்கள் ஜெனரேட்டர் நெட்வொர்க்கை உருவாக்கி பயிற்சி தொடங்கலாம். இது முந்தைய அலகில் நாம் விவாதித்த எந்தவொரு மீள்நினைவுச் செல்களையும் (எளிமையானது, LSTM அல்லது GRU) அடிப்படையாகக் கொண்டிருக்கலாம். எங்கள் எடுத்துக்காட்டில், நாம் LSTM ஐப் பயன்படுத்துவோம்.\n",
|
|
"\n",
|
|
"நெட்வொர்க் எழுத்துக்களை உள்ளீடாக எடுக்கும் காரணமாக, அகராதி அளவு மிகவும் சிறியதாக உள்ளது, எனவே எம்பெட்டிங் லேயர் தேவையில்லை, ஒரே-ஹாட்-என்கோடட் உள்ளீடு நேரடியாக LSTM செலுக்கு செல்லலாம். வெளியீட்டு லேயர் `Dense` வகைப்பாட்டாளராக இருக்கும், இது LSTM வெளியீட்டை ஒரே-ஹாட்-என்கோடட் டோக்கன் எண்களாக மாற்றும்.\n",
|
|
"\n",
|
|
"மேலும், மாறுபட்ட நீளமான வரிசைகளுடன் நாம் செயல்படுவதால், `Masking` லேயரைப் பயன்படுத்தி ஒரு மாஸ்கை உருவாக்கலாம், இது சரத்தின் பூர்த்தி செய்யப்பட்ட பகுதியை புறக்கணிக்கும். இது கண்டிப்பாக தேவையில்லை, ஏனெனில் `<eos>` டோக்கனைத் தாண்டி உள்ள அனைத்திலும் நாங்கள் அதிகம் ஆர்வமாக இல்லை, ஆனால் இந்த லேயர் வகையைப் பயன்படுத்துவதில் அனுபவம் பெறுவதற்காக இதைப் பயன்படுத்துவோம். `input_shape` `(None, vocab_size)` ஆக இருக்கும், இதில் `None` மாறுபட்ட நீள வரிசையை குறிக்கிறது, மேலும் `summary`யில் காணக்கூடியபடி, வெளியீட்டு வடிவம் `(None, vocab_size)` ஆகவும் இருக்கும்:\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": [
|
|
"இப்போது, நாம் உருவாக்கத்தை செய்யலாம். முதலில், சில string `start`-இல் தொடங்குவோம், அதை ஒரு வரிசையாக `inp`-ஆக குறியாக்கம் செய்து, ஒவ்வொரு படியிலும் நமது network-ஐ அழைத்து அடுத்த எழுத்தை கண்டறிவோம்.\n",
|
|
"\n",
|
|
"Network-இன் output `out` என்பது `vocab_size` கூறுகளின் ஒரு வெக்டராக இருக்கும், இது ஒவ்வொரு token-இன் probability-களை பிரதிநிதித்துவப்படுத்தும். `argmax`-ஐ பயன்படுத்தி மிக அதிக probability கொண்ட token எண்ணை கண்டறியலாம். பின்னர், இந்த எழுத்தை உருவாக்கப்பட்ட token-களின் பட்டியலில் சேர்த்து, உருவாக்கத்தை தொடர்கிறோம். தேவையான எழுத்துக்களின் எண்ணிக்கையை உருவாக்க, இந்த ஒரு எழுத்தை உருவாக்கும் செயல்முறை `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",
|
|
"*துல்லியம்* போன்ற பயனுள்ள அளவுகோல்கள் எதுவும் இல்லாததால், எங்கள் மாதிரி மேம்படுகிறது என்பதை காண ஒரே வழி பயிற்சியின் போது உருவாக்கப்பட்ட சரங்களை **மாதிரி எடுப்பது** தான். இதற்காக, **callbacks** எனப்படும் செயல்பாடுகளை பயன்படுத்துவோம், அதாவது `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",
|
|
"* **மேலும் உரை**. நாங்கள் எங்கள் பணிக்காக தலைப்புகளை மட்டுமே பயன்படுத்தியுள்ளோம், ஆனால் முழு உரையுடன் பரிசோதிக்க விரும்பலாம். RNNகள் நீண்ட வரிசைகளை கையாளுவதில் சிறந்தவை அல்ல, எனவே அவற்றை குறுகிய வாக்கியங்களாகப் பிரிக்கவோ அல்லது ஒரு நிர்ணயிக்கப்பட்ட மதிப்பின் `num_chars` (உதாரணமாக, 256) நிலையான வரிசை நீளத்தில் எப்போதும் பயிற்சி செய்யவோ பொருத்தமாக இருக்கும். மேலே உள்ள எடுத்துக்காட்டை அப்படிப்பட்ட கட்டமைப்பாக மாற்ற முயற்சிக்கலாம், [அதிகாரப்பூர்வ Keras வழிகாட்டி](https://keras.io/examples/generative/lstm_character_level_text_generation/)யை ஒரு ஊக்கமாகக் கொண்டு. \n",
|
|
"* **பல அடுக்கு LSTM**. 2 அல்லது 3 அடுக்கு LSTM செல்களை முயற்சிக்கலாம். முந்தைய அலகில் குறிப்பிட்டதுபோல, ஒவ்வொரு LSTM அடுக்கும் உரையிலிருந்து குறிப்பிட்ட மாதிரிகளை எடுக்கிறது, மற்றும் எழுத்து-மட்ட அளவிலான ஜெனரேட்டரின் வழக்கில், கீழ் நிலை LSTM சில்லபிள்களை (syllables) எடுப்பதற்குப் பொறுப்பாக இருக்கும், மேலும் மேல்நிலைகள் சொற்கள் மற்றும் சொற்களின் இணைப்புகளுக்குப் பொறுப்பாக இருக்கும். இதை எளிதாக LSTM கட்டுமானத்தில் அடுக்குகளின் எண்ணிக்கையை குறிப்பிடுவதன் மூலம் செயல்படுத்தலாம். \n",
|
|
"* நீங்கள் **GRU யூனிட்கள்** உடன் பரிசோதிக்கவும், எவை சிறப்பாக செயல்படுகின்றன என்பதைப் பார்க்கவும், மற்றும் **வித்தியாசமான மறைமுக அடுக்கு அளவுகள்** உடன் முயற்சிக்கவும் விரும்பலாம். மிகப் பெரிய மறைமுக அடுக்கு அளவு overfitting (உதாரணமாக, நெட்வொர்க் சரியான உரையை கற்றுக்கொள்ளும்) ஏற்படுத்தக்கூடும், மற்றும் சிறிய அளவு நல்ல முடிவுகளை உருவாக்காமல் இருக்கலாம். \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இந்த ஆவணம் [Co-op Translator](https://github.com/Azure/co-op-translator) என்ற AI மொழிபெயர்ப்பு சேவையைப் பயன்படுத்தி மொழிபெயர்க்கப்பட்டுள்ளது. நாங்கள் துல்லியத்திற்காக முயற்சிக்கின்றோம், ஆனால் தானியங்கி மொழிபெயர்ப்புகளில் பிழைகள் அல்லது தவறுகள் இருக்கக்கூடும் என்பதை தயவுசெய்து கவனத்தில் கொள்ளுங்கள். அதன் தாய்மொழியில் உள்ள மூல ஆவணம் அதிகாரப்பூர்வ ஆதாரமாக கருதப்பட வேண்டும். முக்கியமான தகவல்களுக்கு, தொழில்முறை மனித மொழிபெயர்ப்பு பரிந்துரைக்கப்படுகிறது. இந்த மொழிபெயர்ப்பைப் பயன்படுத்துவதால் ஏற்படும் எந்த தவறான புரிதல்கள் அல்லது தவறான விளக்கங்களுக்கு நாங்கள் பொறுப்பல்ல.\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-10-11T12:52:02+00:00",
|
|
"source_file": "lessons/5-NLP/17-GenerativeNetworks/GenerativeTF.ipynb",
|
|
"language_code": "ta"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
} |