462 lines
31 KiB
Plaintext
462 lines
31 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# بار بار اعصابی نیٹ ورکس\n",
|
||
"\n",
|
||
"پچھلے ماڈیول میں، ہم نے متن کی بھرپور معنوی نمائندگیوں کا جائزہ لیا۔ جو آرکیٹیکچر ہم استعمال کر رہے تھے وہ جملے میں الفاظ کے مجموعی معنی کو پکڑتا ہے، لیکن یہ الفاظ کی **ترتیب** کو مدنظر نہیں رکھتا، کیونکہ ایمبیڈنگ کے بعد جو ایگریگیشن آپریشن ہوتا ہے وہ اصل متن سے یہ معلومات ہٹا دیتا ہے۔ چونکہ یہ ماڈلز الفاظ کی ترتیب کو ظاہر کرنے سے قاصر ہیں، اس لیے وہ زیادہ پیچیدہ یا مبہم کاموں جیسے کہ متن کی تخلیق یا سوالات کے جوابات دینے میں ناکام رہتے ہیں۔\n",
|
||
"\n",
|
||
"متن کے سلسلے کے معنی کو سمجھنے کے لیے، ہم ایک اعصابی نیٹ ورک آرکیٹیکچر استعمال کریں گے جسے **ریکرنٹ نیورل نیٹ ورک** یا RNN کہا جاتا ہے۔ RNN استعمال کرتے وقت، ہم اپنے جملے کو نیٹ ورک کے ذریعے ایک وقت میں ایک ٹوکن پاس کرتے ہیں، اور نیٹ ورک کچھ **حالت** پیدا کرتا ہے، جسے ہم اگلے ٹوکن کے ساتھ دوبارہ نیٹ ورک میں پاس کرتے ہیں۔\n",
|
||
"\n",
|
||
"\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",
|
||
"> **نوٹ**: کچھ 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": [
|
||
"## سادہ آر این این کلاسیفائر\n",
|
||
"\n",
|
||
"سادہ آر این این کے معاملے میں، ہر ری کرنٹ یونٹ ایک سادہ لکیری نیٹ ورک ہوتا ہے، جو ایک ان پٹ ویکٹر اور اسٹیٹ ویکٹر لیتا ہے، اور ایک نیا اسٹیٹ ویکٹر پیدا کرتا ہے۔ Keras میں، اسے `SimpleRNN` لیئر کے ذریعے ظاہر کیا جا سکتا ہے۔\n",
|
||
"\n",
|
||
"اگرچہ ہم ون-ہاٹ انکوڈڈ ٹوکنز کو براہ راست آر این این لیئر میں بھیج سکتے ہیں، یہ ایک اچھا خیال نہیں ہے کیونکہ ان کی زیادہ ڈائمینشنلٹی ہوتی ہے۔ اس لیے، ہم ایک ایمبیڈنگ لیئر استعمال کریں گے تاکہ ورڈ ویکٹرز کی ڈائمینشنلٹی کو کم کیا جا سکے، اس کے بعد ایک آر این این لیئر اور آخر میں ایک `Dense` کلاسیفائر۔\n",
|
||
"\n",
|
||
"> **نوٹ**: ان صورتوں میں جہاں ڈائمینشنلٹی اتنی زیادہ نہ ہو، مثلاً جب کریکٹر لیول ٹوکنائزیشن استعمال کی جا رہی ہو، تو ون-ہاٹ انکوڈڈ ٹوکنز کو براہ راست آر این این سیل میں بھیجنا سمجھ میں آ سکتا ہے۔\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 کو تربیت دیں۔ عمومی طور پر RNNs کو تربیت دینا کافی مشکل ہوتا ہے، کیونکہ جب RNN سیلز کو سیکوئنس کی لمبائی کے ساتھ ان رول کیا جاتا ہے، تو بیک پروپیگیشن میں شامل لیئرز کی تعداد کافی زیادہ ہو جاتی ہے۔ اس لیے ہمیں ایک چھوٹا لرننگ ریٹ منتخب کرنا ہوگا اور نیٹ ورک کو ایک بڑے ڈیٹاسیٹ پر تربیت دینا ہوگا تاکہ اچھے نتائج حاصل کیے جا سکیں۔ یہ کافی وقت لے سکتا ہے، اس لیے GPU کا استعمال ترجیح دی جاتی ہے۔\n",
|
||
"\n",
|
||
"رفتار بڑھانے کے لیے، ہم صرف نیوز کے عنوانات پر RNN ماڈل کو تربیت دیں گے اور تفصیل کو چھوڑ دیں گے۔ آپ تفصیل کے ساتھ تربیت دینے کی کوشش کر سکتے ہیں اور دیکھ سکتے ہیں کہ آیا آپ ماڈل کو تربیت دینے میں کامیاب ہو سکتے ہیں۔\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Training vectorizer\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"def extract_title(x):\n",
|
||
" return x['title']\n",
|
||
"\n",
|
||
"def tupelize_title(x):\n",
|
||
" return (extract_title(x),x['label'])\n",
|
||
"\n",
|
||
"print('Training vectorizer')\n",
|
||
"vectorizer.adapt(ds_train.take(2000).map(extract_title))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"7500/7500 [==============================] - 82s 11ms/step - loss: 0.6629 - acc: 0.7623 - val_loss: 0.5559 - val_acc: 0.7995\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"<tensorflow.python.keras.callbacks.History at 0x7f3e0030d350>"
|
||
]
|
||
},
|
||
"execution_count": 6,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"model.compile(loss='sparse_categorical_crossentropy',metrics=['acc'], optimizer='adam')\n",
|
||
"model.fit(ds_train.map(tupelize_title).batch(batch_size),validation_data=ds_test.map(tupelize_title).batch(batch_size))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"nteract": {
|
||
"transient": {
|
||
"deleting": false
|
||
}
|
||
}
|
||
},
|
||
"source": [
|
||
"> **نوٹ** کہ یہاں درستگی ممکنہ طور پر کم ہوگی، کیونکہ ہم صرف خبریں کے عنوانات پر تربیت کر رہے ہیں۔\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## متغیر سلسلوں کا دوبارہ جائزہ\n",
|
||
"\n",
|
||
"یاد رکھیں کہ `TextVectorization` لیئر خود بخود متغیر لمبائی کی سلسلوں کو ایک منی بیچ میں پیڈ ٹوکنز کے ساتھ پیڈ کرے گی۔ یہ معلوم ہوا ہے کہ یہ ٹوکنز بھی تربیت میں حصہ لیتے ہیں، اور یہ ماڈل کے کنورجنس کو پیچیدہ بنا سکتے ہیں۔\n",
|
||
"\n",
|
||
"پیڈنگ کی مقدار کو کم کرنے کے لیے ہم کئی طریقے اختیار کر سکتے ہیں۔ ان میں سے ایک طریقہ یہ ہے کہ ڈیٹا سیٹ کو سلسلہ کی لمبائی کے لحاظ سے دوبارہ ترتیب دیں اور تمام سلسلوں کو سائز کے لحاظ سے گروپ کریں۔ یہ `tf.data.experimental.bucket_by_sequence_length` فنکشن کا استعمال کرتے ہوئے کیا جا سکتا ہے (دیکھیں [دستاویزات](https://www.tensorflow.org/api_docs/python/tf/data/experimental/bucket_by_sequence_length))۔\n",
|
||
"\n",
|
||
"ایک اور طریقہ **ماسکنگ** کا استعمال ہے۔ کیراس میں، کچھ لیئرز اضافی ان پٹ کو سپورٹ کرتی ہیں جو یہ ظاہر کرتی ہیں کہ تربیت کے دوران کون سے ٹوکنز کو مدنظر رکھا جانا چاہیے۔ ماسکنگ کو اپنے ماڈل میں شامل کرنے کے لیے، ہم یا تو ایک علیحدہ `Masking` لیئر شامل کر سکتے ہیں ([دستاویزات](https://keras.io/api/layers/core_layers/masking/))، یا ہم اپنے `Embedding` لیئر میں `mask_zero=True` پیرامیٹر کو مخصوص کر سکتے ہیں۔\n",
|
||
"\n",
|
||
"> **نوٹ**: اس تربیت کو پورے ڈیٹا سیٹ پر ایک ایپوک مکمل کرنے میں تقریباً 5 منٹ لگیں گے۔ اگر آپ کا صبر ختم ہو جائے تو تربیت کو کسی بھی وقت روکنے میں آزاد محسوس کریں۔ آپ یہ بھی کر سکتے ہیں کہ تربیت کے لیے استعمال ہونے والے ڈیٹا کی مقدار کو محدود کریں، `ds_train` اور `ds_test` ڈیٹا سیٹس کے بعد `.take(...)` کلاز شامل کر کے۔\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"7500/7500 [==============================] - 371s 49ms/step - loss: 0.5401 - acc: 0.8079 - val_loss: 0.3780 - val_acc: 0.8822\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"<tensorflow.python.keras.callbacks.History at 0x7f3dec118850>"
|
||
]
|
||
},
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"def extract_text(x):\n",
|
||
" return x['title']+' '+x['description']\n",
|
||
"\n",
|
||
"def tupelize(x):\n",
|
||
" return (extract_text(x),x['label'])\n",
|
||
"\n",
|
||
"model = keras.models.Sequential([\n",
|
||
" vectorizer,\n",
|
||
" keras.layers.Embedding(vocab_size,embed_size,mask_zero=True),\n",
|
||
" keras.layers.SimpleRNN(16),\n",
|
||
" keras.layers.Dense(4,activation='softmax')\n",
|
||
"])\n",
|
||
"\n",
|
||
"model.compile(loss='sparse_categorical_crossentropy',metrics=['acc'], optimizer='adam')\n",
|
||
"model.fit(ds_train.map(tupelize).batch(batch_size),validation_data=ds_test.map(tupelize).batch(batch_size))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"اب جب ہم ماسکنگ استعمال کر رہے ہیں، تو ہم ماڈل کو عنوانات اور تفصیلات کے پورے ڈیٹا سیٹ پر تربیت دے سکتے ہیں۔\n",
|
||
"\n",
|
||
"> **نوٹ**: کیا آپ نے غور کیا ہے کہ ہم نیوز کے عنوانات پر تربیت یافتہ ویکٹرائزر استعمال کر رہے ہیں، نہ کہ مضمون کے پورے متن پر؟ ممکن ہے کہ اس کی وجہ سے کچھ ٹوکنز نظرانداز ہو جائیں، اس لیے ویکٹرائزر کو دوبارہ تربیت دینا بہتر ہوگا۔ تاہم، اس کا اثر بہت معمولی ہو سکتا ہے، اس لیے ہم سادگی کے لیے پہلے سے تربیت یافتہ ویکٹرائزر پر قائم رہیں گے۔\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## ایل ایس ٹی ایم: طویل مدتی یادداشت\n",
|
||
"\n",
|
||
"آر این اینز کا ایک بڑا مسئلہ **غائب ہونے والے گریڈینٹس** ہیں۔ آر این اینز کافی لمبے ہو سکتے ہیں، اور بیک پروپیگیشن کے دوران نیٹ ورک کی پہلی پرت تک گریڈینٹس کو واپس لے جانے میں مشکل ہو سکتی ہے۔ جب ایسا ہوتا ہے، تو نیٹ ورک دور دراز ٹوکنز کے درمیان تعلقات سیکھنے سے قاصر ہوتا ہے۔ اس مسئلے سے بچنے کا ایک طریقہ **واضح حالت کا انتظام** متعارف کرانا ہے، جو **گیٹس** کے ذریعے کیا جاتا ہے۔ دو سب سے عام آرکیٹیکچرز جو گیٹس متعارف کراتے ہیں وہ ہیں **طویل مدتی یادداشت** (LSTM) اور **گیٹڈ ریلے یونٹ** (GRU)۔ یہاں ہم ایل ایس ٹی ایمز پر بات کریں گے۔\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"ایل ایس ٹی ایم نیٹ ورک آر این این کی طرح منظم ہوتا ہے، لیکن یہاں دو حالتیں ہیں جو پرت سے پرت تک منتقل ہوتی ہیں: اصل حالت $c$، اور چھپی ہوئی ویکٹر $h$۔ ہر یونٹ پر، چھپی ہوئی ویکٹر $h_{t-1}$ کو ان پٹ $x_t$ کے ساتھ ملایا جاتا ہے، اور یہ دونوں مل کر **گیٹس** کے ذریعے حالت $c_t$ اور آؤٹ پٹ $h_{t}$ پر قابو رکھتے ہیں۔ ہر گیٹ میں سگموئڈ ایکٹیویشن ہوتا ہے (آؤٹ پٹ کی حد $[0,1]$)، جسے حالت ویکٹر کے ساتھ ضرب کرنے پر بٹ وائز ماسک کے طور پر سمجھا جا سکتا ہے۔ ایل ایس ٹی ایمز میں درج ذیل گیٹس ہوتے ہیں (اوپر دی گئی تصویر میں بائیں سے دائیں):\n",
|
||
"* **فراموشی گیٹ** جو یہ طے کرتا ہے کہ ویکٹر $c_{t-1}$ کے کون سے اجزاء کو ہمیں بھولنا ہے، اور کون سے گزرنے دینے ہیں۔\n",
|
||
"* **ان پٹ گیٹ** جو یہ طے کرتا ہے کہ ان پٹ ویکٹر اور پچھلے چھپے ہوئے ویکٹر سے کتنی معلومات کو حالت ویکٹر میں شامل کرنا ہے۔\n",
|
||
"* **آؤٹ پٹ گیٹ** جو نئی حالت ویکٹر لیتا ہے اور فیصلہ کرتا ہے کہ اس کے کون سے اجزاء کو نیا چھپا ہوا ویکٹر $h_t$ پیدا کرنے کے لیے استعمال کیا جائے۔\n",
|
||
"\n",
|
||
"حالت $c$ کے اجزاء کو ایسے جھنڈے سمجھا جا سکتا ہے جنہیں آن اور آف کیا جا سکتا ہے۔ مثال کے طور پر، جب ہم سیکوئنس میں نام *ایلس* دیکھتے ہیں، تو ہم اندازہ لگاتے ہیں کہ یہ ایک عورت کا حوالہ دیتا ہے، اور حالت میں وہ جھنڈا اٹھاتے ہیں جو کہتا ہے کہ ہمارے پاس جملے میں ایک مؤنث اسم ہے۔ جب ہم مزید الفاظ *اور ٹام* دیکھتے ہیں، تو ہم وہ جھنڈا اٹھاتے ہیں جو کہتا ہے کہ ہمارے پاس جمع اسم ہے۔ اس طرح حالت کو جوڑ کر ہم جملے کی گرامر کی خصوصیات کا پتہ رکھ سکتے ہیں۔\n",
|
||
"\n",
|
||
"> **نوٹ**: ایل ایس ٹی ایمز کی اندرونی ساخت کو سمجھنے کے لیے یہاں ایک بہترین ذریعہ ہے: [Understanding LSTM Networks](https://colah.github.io/posts/2015-08-Understanding-LSTMs/) کرسٹوفر اولاہ کی طرف سے۔\n",
|
||
"\n",
|
||
"اگرچہ ایل ایس ٹی ایم سیل کی اندرونی ساخت پیچیدہ نظر آ سکتی ہے، کیراس اس نفاذ کو `LSTM` لیئر کے اندر چھپا دیتا ہے، لہذا اوپر دی گئی مثال میں ہمیں صرف ری کرنٹ لیئر کو تبدیل کرنا ہے۔\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 8,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"15000/15000 [==============================] - 188s 13ms/step - loss: 0.5692 - acc: 0.7916 - val_loss: 0.3441 - val_acc: 0.8870\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"<tensorflow.python.keras.callbacks.History at 0x7f3d6af5c350>"
|
||
]
|
||
},
|
||
"execution_count": 8,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"model = keras.models.Sequential([\n",
|
||
" vectorizer,\n",
|
||
" keras.layers.Embedding(vocab_size, embed_size),\n",
|
||
" keras.layers.LSTM(8),\n",
|
||
" keras.layers.Dense(4,activation='softmax')\n",
|
||
"])\n",
|
||
"\n",
|
||
"model.compile(loss='sparse_categorical_crossentropy',metrics=['acc'], optimizer='adam')\n",
|
||
"model.fit(ds_train.map(tupelize).batch(8),validation_data=ds_test.map(tupelize).batch(8))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"**نوٹ** کہ LSTMs کی تربیت بھی کافی سست ہوتی ہے، اور آپ کو تربیت کے آغاز میں درستگی میں زیادہ اضافہ نظر نہیں آ سکتا۔ اچھی درستگی حاصل کرنے کے لیے آپ کو کچھ وقت تک تربیت جاری رکھنے کی ضرورت ہو سکتی ہے۔\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## دو طرفہ اور کثیر پرت RNNs\n",
|
||
"\n",
|
||
"اب تک کے ہمارے مثالوں میں، ری کرنٹ نیٹ ورکس ایک ترتیب کے آغاز سے اختتام تک کام کرتے ہیں۔ یہ ہمیں قدرتی لگتا ہے کیونکہ یہ اسی سمت میں کام کرتا ہے جس میں ہم پڑھتے ہیں یا تقریر سنتے ہیں۔ تاہم، ایسے حالات کے لیے جہاں ان پٹ ترتیب کو بے ترتیب طور پر رسائی کی ضرورت ہو، دونوں سمتوں میں ری کرنٹ حساب چلانا زیادہ منطقی ہے۔ وہ RNNs جو دونوں سمتوں میں حسابات کی اجازت دیتے ہیں، **دو طرفہ** RNNs کہلاتے ہیں، اور انہیں ایک خاص `Bidirectional` لیئر کے ذریعے ری کرنٹ لیئر کو لپیٹ کر بنایا جا سکتا ہے۔\n",
|
||
"\n",
|
||
"> **نوٹ**: `Bidirectional` لیئر اس کے اندر لیئر کی دو کاپیاں بناتی ہے، اور ان میں سے ایک کی `go_backwards` پراپرٹی کو `True` پر سیٹ کرتی ہے، جس سے وہ ترتیب کے ساتھ مخالف سمت میں جاتی ہے۔\n",
|
||
"\n",
|
||
"ری کرنٹ نیٹ ورکس، چاہے یک طرفہ ہوں یا دو طرفہ، ترتیب کے اندر موجود پیٹرنز کو پکڑتے ہیں، اور انہیں اسٹیٹ ویکٹرز میں محفوظ کرتے ہیں یا آؤٹ پٹ کے طور پر واپس کرتے ہیں۔ جیسے کنوولوشنل نیٹ ورکس میں، ہم پہلے لیئر کے بعد ایک اور ری کرنٹ لیئر بنا سکتے ہیں تاکہ اعلیٰ سطح کے پیٹرنز کو پکڑا جا سکے، جو پہلے لیئر کے ذریعے نکالے گئے نچلے سطح کے پیٹرنز سے بنے ہوں۔ یہ ہمیں **کثیر پرت RNN** کے تصور تک لے جاتا ہے، جو دو یا زیادہ ری کرنٹ نیٹ ورکس پر مشتمل ہوتا ہے، جہاں پچھلی لیئر کا آؤٹ پٹ اگلی لیئر کو ان پٹ کے طور پر دیا جاتا ہے۔\n",
|
||
"\n",
|
||
"\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",
|
||
"> **نوٹ** یہ کوڈ دوبارہ مکمل ہونے میں کافی وقت لیتا ہے، لیکن یہ ہمیں اب تک کی سب سے زیادہ درستگی دیتا ہے۔ تو شاید انتظار کرنا اور نتیجہ دیکھنا فائدہ مند ہو۔\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-28T04:24:20+00:00",
|
||
"source_file": "lessons/5-NLP/16-RNN/RNNTF.ipynb",
|
||
"language_code": "ur"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 4
|
||
} |