496 lines
44 KiB
Plaintext
496 lines
44 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Generative networks\n",
|
|
"\n",
|
|
"Recurrent Neural Networks (RNNs) နှင့် Long Short Term Memory Cells (LSTMs) နှင့် Gated Recurrent Units (GRUs) ကဲ့သို့သော gated cell မျိုးကွဲများသည် ဘာသာစကားမော်ဒယ်တစ်ခုအတွက် စနစ်တစ်ခုကို ပံ့ပိုးပေးခဲ့သည်။ အဆိုပါစနစ်သည် စကားလုံးများ၏ အစီအစဉ်ကို သင်ယူနိုင်ပြီး အစီအစဉ်အတွင်း နောက်တစ်ခုထွက်မည့် စကားလုံးကို ခန့်မှန်းပေးနိုင်သည်။ ၎င်းသည် RNNs ကို **ထုတ်လုပ်မှုဆိုင်ရာ လုပ်ငန်းများ** (ဥပမာ - ပုံမှန်စာသားထုတ်လုပ်မှု၊ စက်ဘာသာပြန်ခြင်း၊ ပုံဖော်ပြချက်ရေးခြင်း) အတွက် အသုံးပြုနိုင်စေသည်။\n",
|
|
"\n",
|
|
"ယခင်ယူနစ်တွင် ဆွေးနွေးခဲ့သည့် RNN architecture တွင် RNN unit တစ်ခုစီသည် နောက်ထွက်မည့် hidden state ကို output အဖြစ် ထုတ်ပေးသည်။ သို့သော်လည်း, RNN unit တစ်ခုစီတွင် output တစ်ခုထပ်မံထည့်သွင်းနိုင်ပြီး, ၎င်းသည် **sequence** (မူရင်း sequence နှင့် အရှည်တူ) ကို output အဖြစ် ထုတ်ပေးနိုင်သည်။ ထို့အပြင်, RNN units များကို အဆင့်တစ်ခုစီတွင် input မလိုအပ်ဘဲ, စတင်အခြေအနေ vector တစ်ခုသာ လက်ခံပြီး, ထို့နောက် output များ၏ sequence တစ်ခုကို ထုတ်ပေးစေနိုင်သည်။\n",
|
|
"\n",
|
|
"ဒီ notebook တွင်, စာသားထုတ်လုပ်ရန် ကူညီပေးသည့် ရိုးရှင်းသော generative models များကို အဓိကထား၍ လေ့လာသွားမည်ဖြစ်သည်။ ရိုးရှင်းစွာပြောရမည်ဆိုပါက, **character-level network** တစ်ခုကို တည်ဆောက်ကြမည်ဖြစ်ပြီး, ၎င်းသည် စာလုံးတစ်လုံးချင်းစီဖြင့် စာသားကို ထုတ်လုပ်ပေးမည်ဖြစ်သည်။ သင်ကြားမှုအတွင်း, စာသား corpus တစ်ခုကို ယူပြီး, ၎င်းကို စာလုံးအစီအစဉ်များအဖြစ် ခွဲထုတ်ရန် လိုအပ်မည်။\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` layer သည် အဲဒီလိုလုပ်ဆောင်နိုင်မည်မဟုတ်သောကြောင့် အောက်ပါရွေးချယ်စရာနှစ်ခုရှိသည်-\n",
|
|
"\n",
|
|
"* [ဒီ Keras ရဲ့ တရားဝင် ဥပမာ](https://keras.io/examples/generative/lstm_character_level_text_generation/) တွင်ဖော်ပြထားသည့်အတိုင်း စာသားကို ကိုယ်တိုင်တင်သွင်းပြီး 'ကိုယ်တိုင်' tokenization ပြုလုပ်ရန်\n",
|
|
"* `Tokenizer` class ကို အသုံးပြု၍ အက္ခရာအဆင့် tokenization ပြုလုပ်ရန်။\n",
|
|
"\n",
|
|
"ကျွန်ုပ်တို့သည် ဒုတိယရွေးချယ်စရာကို အသုံးပြုမည်ဖြစ်သည်။ `Tokenizer` သည် စကားလုံးများအဖြစ်လည်း tokenize ပြုလုပ်နိုင်သည့်အတွက် အက္ခရာအဆင့်မှ စကားလုံးအဆင့် tokenization သို့ အလွယ်တကူ ပြောင်းလဲနိုင်သည်။\n",
|
|
"\n",
|
|
"အက္ခရာအဆင့် tokenization ပြုလုပ်ရန် `char_level=True` parameter ကို ပေးသွင်းရမည်-\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>` token ကို ဖန်တီးရန် ကွန်ယက်ကို မေးမြန်းပါမည်။\n",
|
|
"\n",
|
|
"ဒီနေရာမှာ အသုံးပြုမည့် generative RNN နှင့် အခြား RNN များ၏ အဓိကကွာခြားချက်မှာ RNN ၏ နောက်ဆုံး cell မှသာမက၊ အဆင့်တစ်ခုချင်းစီမှ ထွက်လာသော output ကိုလည်း အသုံးပြုမည်ဖြစ်သည်။ ဒါကို RNN cell တွင် `return_sequences` parameter ကို သတ်မှတ်ခြင်းဖြင့် ပြုလုပ်နိုင်ပါသည်။\n",
|
|
"\n",
|
|
"ထို့ကြောင့် သင်ကြားမှုအတွင်းမှာ ကွန်ယက်သို့ ထည့်မည့် အင်ပွတ်မှာ အချို့အရှည်ရှိသော အက္ခရာများကို encode လုပ်ထားသော အစီအစဉ်ဖြစ်ပြီး၊ output မှာ အတူတူရှည်သော အစီအစဉ်ဖြစ်သော်လည်း တစ်ခုချင်းစီကို တစ်ခုအဆင့်ရွှေ့ထားပြီး `<eos>` ဖြင့် အဆုံးသတ်ထားမည်ဖြစ်သည်။ Minibatch မှာ အစီအစဉ်များစွာ ပါဝင်မည်ဖြစ်ပြီး၊ အားလုံးကို alignment ပြုလုပ်ရန် **padding** ကို အသုံးပြုရမည်ဖြစ်သည်။\n",
|
|
"\n",
|
|
"အခုတော့ dataset ကို ပြောင်းလဲပေးမည့် function များကို ဖန်တီးကြစို့။ Minibatch အဆင့်မှာ sequence များကို padding ပြုလုပ်လိုသောကြောင့် dataset ကို `.batch()` ခေါ်ပြီး batch လုပ်ပြီးနောက် `map` ကို အသုံးပြု၍ ပြောင်းလဲမှုကို ပြုလုပ်မည်ဖြစ်သည်။ ထို့ကြောင့် ပြောင်းလဲမှု function မှာ minibatch တစ်ခုလုံးကို parameter အဖြစ် လက်ခံမည်:\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",
|
|
"* ပထမဦးဆုံး ကျွန်တော်တို့ string tensor ထဲက အမှန်တကယ် text ကို extract လုပ်ပါတယ်။\n",
|
|
"* `text_to_sequences` က string တွေကို integer tensor တွေဖြစ်အောင် ပြောင်းပေးပါတယ်။\n",
|
|
"* `pad_sequences` က အဲ့ဒီ tensor တွေကို အများဆုံးအရှည်အတိုင်း pad လုပ်ပေးပါတယ်။\n",
|
|
"* နောက်ဆုံးမှာ character တွေကို one-hot encode လုပ်ပြီး shifting နဲ့ `<eos>` ကို ထည့်ပေးပါတယ်။ အဲ့ဒီ character တွေကို one-hot encode လုပ်ရတဲ့ အကြောင်းကို မကြာခင်မှာ ရှင်းပြပေးပါမယ်။\n",
|
|
"\n",
|
|
"ဒါပေမယ့် ဒီ function က **Pythonic** ဖြစ်ပါတယ်၊ ဒါကြောင့် Tensorflow computational graph အဖြစ် အလိုအလျောက် ပြောင်းလို့မရပါဘူး။ ဒီ function ကို `Dataset.map` function ထဲမှာ တိုက်ရိုက် အသုံးပြုမယ်ဆိုရင် error တွေ ရှိလာနိုင်ပါတယ်။ ဒီ 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 ပြောင်းလဲမှုလုပ်ဆောင်မှုများကို ခွဲခြားဖို့ အလွန်ရှုပ်ထွေးတယ်လို့ ခံစားရနိုင်ပြီး၊ dataset ကို `fit` မှာ ပေးပို့မယ့်အခါမှာ သာမန် Python function တွေကို သုံးပြီး ပြောင်းလဲမှုလုပ်ဆောင်မှုကို မလုပ်တာ ဘာကြောင့်လဲဆိုတာကို မေးမြန်းချင်ဖြစ်နိုင်ပါတယ်။ ဒါကို လုပ်နိုင်တာ သေချာပေမယ့်၊ `Dataset.map` ကို သုံးခြင်းက အလွန်ကြီးမားတဲ့ အကျိုးကျေးဇူးရှိပါတယ်၊ အကြောင်းကတော့ data ပြောင်းလဲမှုလုပ်ဆောင်မှု pipeline ကို Tensorflow computational graph ကို အသုံးပြုပြီး အကောင်အထည်ဖော်တာကြောင့် GPU တွေကို အသုံးချနိုင်ပြီး CPU/GPU အကြား data ပေးပို့မှု လိုအပ်ချက်ကို လျှော့ချနိုင်ပါတယ်။\n",
|
|
"\n",
|
|
"အခုတော့ generator network ကို တည်ဆောက်ပြီး training စတင်နိုင်ပါပြီ။ ဒါကို အရင် unit မှာ ဆွေးနွေးခဲ့တဲ့ recurrent cell မည်သည့်အမျိုးအစား (simple, LSTM, GRU) ကိုမဆို အခြေခံပြီး တည်ဆောက်နိုင်ပါတယ်။ ဥပမာအနေနဲ့ LSTM ကို အသုံးပြုပါမယ်။\n",
|
|
"\n",
|
|
"Network က အထိမ်းအမှတ်အဖြစ် character တွေကို input အနေနဲ့ ယူပြီး၊ vocabulary size က အတော်လေးသေးတဲ့အတွက် embedding layer မလိုအပ်ပါဘူး၊ one-hot-encoded input ကို တိုက်ရိုက် LSTM cell ထဲကို ပေးပို့နိုင်ပါတယ်။ Output layer ကတော့ LSTM output ကို one-hot-encoded token number တွေ အဖြစ် ပြောင်းလဲပေးမယ့် `Dense` classifier ဖြစ်ပါတယ်။\n",
|
|
"\n",
|
|
"ထို့အပြင်၊ variable-length sequences တွေကို ကိုင်တွယ်နေရတဲ့အတွက် `Masking` layer ကို အသုံးပြုပြီး string ရဲ့ padded အပိုင်းကို မထည့်သွင်းဖို့ mask တစ်ခု ဖန်တီးနိုင်ပါတယ်။ ဒါဟာ မဖြစ်မနေလိုအပ်တာ မဟုတ်ပါဘူး၊ အကြောင်းကတော့ `<eos>` token ကို ကျော်လွန်သွားတဲ့ အပိုင်းအားလုံးကို အလွန်စိတ်ဝင်စားနေရတာ မဟုတ်ပေမယ့်၊ layer အမျိုးအစားကို အသုံးပြုတဲ့ အတွေ့အကြုံရဖို့အတွက် သုံးပါမယ်။ `input_shape` က `(None, vocab_size)` ဖြစ်ပြီး၊ `None` က variable length sequence ကို ရည်ညွှန်းပါတယ်၊ output shape ကလည်း `(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",
|
|
"အခုတော့ မော်ဒယ်ကို လေ့ကျင့်ပြီးဖြစ်တာကြောင့် အထွက်တစ်ခုခုကို ဖန်တီးဖို့လိုပါတယ်။ ပထမဆုံးအနေနဲ့ token နံပါတ်များစဉ်လိုက်ကိုယ်စားပြုထားတဲ့ စာသားကို ပြန်လည်ဖော်ထုတ်နိုင်တဲ့ နည်းလမ်းတစ်ခုလိုအပ်ပါတယ်။ ဒီအတွက် `tokenizer.sequences_to_texts` function ကို အသုံးပြုနိုင်ပေမယ့် character-level tokenization နဲ့ အလုပ်မလုပ်ကောင်းပါဘူး။ ဒါကြောင့် `word_index` လို့ခေါ်တဲ့ tokenizer ထဲက token တွေရဲ့ dictionary ကိုယူပြီး၊ reverse map တစ်ခုတည်ဆောက်ကာ၊ ကိုယ့်ရဲ့ decoding function ကိုရေးဖို့လိုပါတယ်။\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` ဆိုတဲ့ string တစ်ခုရှိပြီး၊ အဲဒါကို `inp` sequence အဖြစ် encode လုပ်ပါမည်။ ထို့နောက် တစ်ဆင့်ချင်းစီမှာ ကျွန်ုပ်တို့၏ network ကိုခေါ်ပြီး နောက် character ကို ခန့်မှန်းပါမည်။\n",
|
|
"\n",
|
|
"Network ရဲ့ output `out` က `vocab_size` elements ရှိတဲ့ vector ဖြစ်ပြီး၊ token တစ်ခုချင်းစီရဲ့ probability ကို ကိုယ်စားပြုထားသည်။ အများဆုံးဖြစ်နိုင်သော token နံပါတ်ကို `argmax` အသုံးပြု၍ ရှာနိုင်ပြီး၊ ဒီ character ကို generated token list ထဲသို့ ထည့်သွင်းပါမည်။ ထို့နောက် generation ကို ဆက်လက်လုပ်ဆောင်ပါမည်။ Character တစ်ခု generate လုပ်တဲ့ ဒီလုပ်ငန်းစဉ်ကို `size` ကြိမ် ထပ်လုပ်ပြီး လိုအပ်သော character အရေအတွက်ကို generate လုပ်ပါမည်။ `eos_token` ကို တွေ့ရှိသောအခါမှာတော့ အစောပိုင်းတွင် generation ကို ရပ်တန့်ပါမည်။\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` function သို့ ပေးပို့နိုင်သော function များဖြစ်ပြီး၊ လေ့ကျင့်မှုအတွင်း အချိန်ကာလအလိုက် ခေါ်သုံးမည်ဖြစ်သည်။\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": [
|
|
"ဤဥပမာသည် အတော်လေးကောင်းမွန်သောစာသားကို ရAlready ထုတ်ပေးနိုင်ပြီးဖြစ်သော်လည်း အချို့နည်းလမ်းများဖြင့် ထပ်မံတိုးတက်စေနိုင်ပါသည်။\n",
|
|
"\n",
|
|
"* **ပိုမိုသောစာသား**။ ကျွန်ုပ်တို့၏လုပ်ငန်းအတွက် ခေါင်းစဉ်များကိုသာ အသုံးပြုထားသော်လည်း အပြည့်အစုံသောစာသားများဖြင့် စမ်းသပ်ကြည့်လိုစိတ်ရှိနိုင်ပါသည်။ သတိပြုရန်မှာ RNN များသည် ရှည်လျားသောအကြောင်းအရာများကို ကိုင်တွယ်ရာတွင် အလွန်ကောင်းမွန်သည်မဟုတ်ပါ၊ ထို့ကြောင့် စာကြောင်းတိုများအဖြစ် ခွဲထုတ်ခြင်း သို့မဟုတ် သတ်မှတ်ထားသော `num_chars` (ဥပမာ 256) တန်ဖိုးဖြင့် အမြဲတမ်းတည်ဆောက်ထားသော အတိုင်းအတာအရှည်ဖြင့် လေ့ကျင့်ခြင်းတို့ကို စဉ်းစားသင့်ပါသည်။ အထက်ပါဥပမာကို [အတည်ပြု Keras လေ့ကျင့်ရေးလမ်းညွှန်](https://keras.io/examples/generative/lstm_character_level_text_generation/) ကို အားထား၍ ထိုကဲ့သို့သောဖွဲ့စည်းမှုအဖြစ် ပြောင်းလဲကြည့်နိုင်ပါသည်။\n",
|
|
"\n",
|
|
"* **Multilayer LSTM**။ LSTM cells 2 သို့မဟုတ် 3 အလွှာကို စမ်းသပ်ကြည့်ရန် make sense ဖြစ်ပါသည်။ ယခင်ယူနစ်တွင် ပြောခဲ့သည့်အတိုင်း LSTM ၏ အလွှာတစ်ခုစီသည် စာသားမှ အချို့သောပုံစံများကို ထုတ်ယူပေးပြီး၊ character-level generator ၏အနေဖြင့် အနိမ့်ဆုံး LSTM အလွှာသည် သရော်အသံများကို ထုတ်ယူရန် တာဝန်ရှိပြီး၊ အမြင့်ဆုံးအလွှာများသည် စကားလုံးများနှင့် စကားလုံးပေါင်းများကို ထုတ်ယူရန် တာဝန်ရှိသည်ဟု မျှော်လင့်နိုင်ပါသည်။ ၎င်းကို LSTM constructor သို့ အလွှာအရေအတွက် parameter ကို ပေးပို့ခြင်းဖြင့် ရိုးရှင်းစွာ အကောင်အထည်ဖော်နိုင်ပါသည်။\n",
|
|
"\n",
|
|
"* **GRU units** ဖြင့်လည်း စမ်းသပ်ကြည့်လိုစိတ်ရှိနိုင်ပြီး၊ **hidden layer sizes များကို မတူညီစွာ** စမ်းသပ်ကြည့်နိုင်ပါသည်။ Hidden layer အရွယ်အစား အလွန်ကြီးလွန်းပါက overfitting ဖြစ်စေနိုင်ပြီး (ဥပမာ network သည် စာသားကို တိတိကျကျ သင်ယူသွားမည်ဖြစ်သည်)၊ အရွယ်အစား သေးလွန်းပါက ကောင်းမွန်သောရလဒ် မထုတ်ပေးနိုင်ပါ။\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Soft text generation and temperature\n",
|
|
"\n",
|
|
"ယခင် `generate` ကိုဖော်ပြထားသော အဓိပ္ပါယ်အရ၊ ကျွန်ုပ်တို့သည် အမြဲတမ်း အမြင့်ဆုံး probability ရှိသော အက္ခရာကို ရွေးပြီး ထုတ်လုပ်ထားသော စာသားတွင် နောက်ထပ် အက္ခရာအဖြစ် အသုံးပြုခဲ့သည်။ ဒီနည်းလမ်းကြောင့် စာသားသည် အချို့သော အက္ခရာအလှည့်အပြောင်းများကို ထပ်တလဲလဲ ဖြစ်စေခဲ့သည်။ ဥပမာအားဖြင့်:\n",
|
|
"```\n",
|
|
"today of the second the company and a second the company ...\n",
|
|
"```\n",
|
|
"\n",
|
|
"သို့သော်၊ နောက်ထပ် အက္ခရာအတွက် probability distribution ကိုကြည့်မယ်ဆိုရင်၊ အမြင့်ဆုံး probability ရှိသော အက္ခရာများအကြား ကွာဟချက်သည် များစွာ မကြီးမားနိုင်ပါ။ ဥပမာအားဖြင့် အက္ခရာတစ်ခုမှာ probability 0.2 ရှိနိုင်ပြီး၊ နောက်တစ်ခုမှာ 0.19 ရှိနိုင်သည်။ ဥပမာအားဖြင့် '*play*' ဆိုသော စာကြောင်းတွင် နောက်ထပ် အက္ခရာသည် space ဖြစ်နိုင်သလို၊ **e** (ဥပမာ player ဆိုသော စကားလုံးတွင်) ဖြစ်နိုင်ပါသည်။\n",
|
|
"\n",
|
|
"ဒီအခြေအနေကြောင့် အမြင့်ဆုံး probability ရှိသော အက္ခရာကိုသာ ရွေးချယ်ခြင်းသည် အမြဲတမ်း \"တရားမျှတ\" မဖြစ်နိုင်ပါ။ ဒုတိယမြင့်ဆုံး probability ရှိသော အက္ခရာကို ရွေးချယ်ခြင်းသည်လည်း အဓိပ္ပါယ်ရှိသော စာသားကို ရရှိစေနိုင်ပါသည်။ ထို့ကြောင့် network output မှပေးသော probability distribution ကို အသုံးပြု၍ **sample** လုပ်ခြင်းသည် ပိုပြီး ဉာဏ်ရှိသော နည်းလမ်းဖြစ်သည်။\n",
|
|
"\n",
|
|
"ဒီ sampling ကို **multinomial distribution** ဟုခေါ်သော နည်းလမ်းကို အကောင်အထည်ဖော်ပေးသော `np.multinomial` function ကို အသုံးပြု၍ ပြုလုပ်နိုင်ပါသည်။ **soft** text generation ကို အကောင်အထည်ဖော်ပေးသော function ကို အောက်တွင် ဖော်ပြထားသည်:\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 ဖြစ်ပါက၊ ကျွန်ုပ်တို့သည် တရားမျှတသော multinomial sampling ကို ပြုလုပ်ပြီး၊ အပူချိန်သည် အဆုံးမရှိအထိ မြင့်တက်သွားသောအခါ - ဖြစ်နိုင်မှုအားလုံးသည် တူညီသွားပြီး၊ နောက်တစ်ခုသော အက္ခရာကို ကျပန်းရွေးချယ်သည်။ အောက်တွင်ပေးထားသော ဥပမာတွင် ကျွန်ုပ်တို့သည် အပူချိန်ကို အလွန်များစွာမြှင့်တင်သောအခါ၊ စာသားသည် အဓိပ္ပါယ်မရှိသွားကြောင်းကို တွေ့နိုင်ပြီး၊ အပူချိန်သည် 0 အနီးသို့ ရောက်လာသောအခါ \"cycled\" အခက်အခဲဖြင့် ဖန်တီးထားသော စာသားနှင့် ဆင်တူသည်ကို တွေ့နိုင်သည်။\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-30T10:11:54+00:00",
|
|
"source_file": "lessons/5-NLP/17-GenerativeNetworks/GenerativeTF.ipynb",
|
|
"language_code": "my"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
} |