495 lines
29 KiB
Plaintext
495 lines
29 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Mga Generative na Network\n",
|
|
"\n",
|
|
"Ang Recurrent Neural Networks (RNNs) at ang mga gated cell na variant nito tulad ng Long Short Term Memory Cells (LSTMs) at Gated Recurrent Units (GRUs) ay nagbibigay ng mekanismo para sa pagmomodelo ng wika, ibig sabihin, kaya nilang matutunan ang pagkakasunod-sunod ng mga salita at magbigay ng prediksyon para sa susunod na salita sa isang sequence. Dahil dito, magagamit natin ang RNNs para sa **mga generative na gawain**, tulad ng karaniwang pagbuo ng teksto, pagsasalin ng makina, at maging sa paglalagay ng caption sa mga imahe.\n",
|
|
"\n",
|
|
"Sa arkitektura ng RNN na tinalakay natin sa nakaraang unit, ang bawat RNN unit ay gumagawa ng susunod na hidden state bilang output. Gayunpaman, maaari rin tayong magdagdag ng isa pang output sa bawat recurrent unit, na magpapahintulot sa atin na mag-output ng isang **sequence** (na may parehong haba sa orihinal na sequence). Bukod dito, maaari tayong gumamit ng mga RNN unit na hindi tumatanggap ng input sa bawat hakbang, at sa halip ay gumagamit lamang ng isang initial state vector, at pagkatapos ay gumagawa ng isang sequence ng mga output.\n",
|
|
"\n",
|
|
"Sa notebook na ito, magpo-focus tayo sa mga simpleng generative na modelo na tumutulong sa atin na bumuo ng teksto. Para sa pagiging simple, magtatayo tayo ng **character-level network**, na bumubuo ng teksto letra kada letra. Sa panahon ng training, kailangan nating kumuha ng isang text corpus, at hatiin ito sa mga sequence ng letra.\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": [
|
|
"## Pagbuo ng Bokabularyo ng mga Karakter\n",
|
|
"\n",
|
|
"Upang makabuo ng character-level generative network, kailangan nating hatiin ang teksto sa mga indibidwal na karakter sa halip na mga salita. Ang `TextVectorization` layer na ginagamit natin dati ay hindi kayang gawin ito, kaya may dalawang opsyon tayo:\n",
|
|
"\n",
|
|
"* Manu-manong i-load ang teksto at gawin ang tokenization 'nang mano-mano', tulad ng nasa [opisyal na halimbawa ng Keras na ito](https://keras.io/examples/generative/lstm_character_level_text_generation/)\n",
|
|
"* Gamitin ang `Tokenizer` class para sa character-level tokenization.\n",
|
|
"\n",
|
|
"Pipiliin natin ang pangalawang opsyon. Ang `Tokenizer` ay maaari ring gamitin para sa tokenization ng mga salita, kaya madali kang makakapagpalit mula sa char-level patungo sa word-level tokenization.\n",
|
|
"\n",
|
|
"Upang gawin ang character-level tokenization, kailangan nating ipasa ang parameter na `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": [
|
|
"Gusto rin naming gumamit ng isang espesyal na token upang tukuyin ang **katapusan ng sequence**, na tatawagin naming `<eos>`. Idagdag natin ito nang manu-mano sa bokabularyo:\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": [
|
|
"## Pagsasanay ng isang generative RNN para lumikha ng mga pamagat\n",
|
|
"\n",
|
|
"Ang paraan ng pagsasanay natin sa RNN upang lumikha ng mga pamagat ng balita ay ganito. Sa bawat hakbang, kukuha tayo ng isang pamagat, na ipapasok sa isang RNN, at para sa bawat input na karakter, hihilingin natin sa network na lumikha ng susunod na output na karakter:\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"Para sa huling karakter ng ating sequence, hihilingin natin sa network na lumikha ng `<eos>` token.\n",
|
|
"\n",
|
|
"Ang pangunahing pagkakaiba ng generative RNN na ginagamit natin dito ay kukunin natin ang output mula sa bawat hakbang ng RNN, at hindi lamang mula sa huling cell. Magagawa ito sa pamamagitan ng pag-specify ng `return_sequences` na parameter sa RNN cell.\n",
|
|
"\n",
|
|
"Kaya, sa panahon ng pagsasanay, ang input sa network ay magiging isang sequence ng mga encoded na karakter na may tiyak na haba, at ang output ay magiging isang sequence na may parehong haba, ngunit naka-shift ng isang elemento at nagtatapos sa `<eos>`. Ang minibatch ay binubuo ng ilang ganitong mga sequence, at kakailanganin nating gumamit ng **padding** upang ma-align ang lahat ng mga sequence.\n",
|
|
"\n",
|
|
"Gumawa tayo ng mga function na magbabago sa dataset para sa atin. Dahil gusto nating magpad ng mga sequence sa antas ng minibatch, una nating ibabatch ang dataset sa pamamagitan ng pagtawag sa `.batch()`, at pagkatapos ay `map` ito upang gawin ang transformation. Kaya, ang transformation function ay kukuha ng isang buong minibatch bilang 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": [
|
|
"Ilang mahahalagang bagay na ginagawa natin dito: \n",
|
|
"* Una, kinukuha natin ang aktwal na teksto mula sa string tensor \n",
|
|
"* Ang `text_to_sequences` ay nagko-convert ng listahan ng mga string sa isang listahan ng mga integer tensor \n",
|
|
"* Ang `pad_sequences` ay nagdadagdag ng padding sa mga tensor na ito hanggang sa kanilang pinakamahabang haba \n",
|
|
"* Sa huli, ini-encode natin sa one-hot ang lahat ng mga karakter, at ginagawa rin ang shifting at pagdaragdag ng `<eos>`. Malalaman natin sa lalong madaling panahon kung bakit kailangan natin ng one-hot-encoded na mga karakter \n",
|
|
"\n",
|
|
"Gayunpaman, ang function na ito ay **Pythonic**, ibig sabihin, hindi ito maaaring awtomatikong ma-convert sa Tensorflow computational graph. Magkakaroon tayo ng mga error kung susubukan nating gamitin ang function na ito nang direkta sa `Dataset.map` function. Kailangan nating balutin ang tawag na ito gamit ang `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**: Ang pagkakaiba sa pagitan ng Pythonic at Tensorflow transformation functions ay maaaring mukhang masyadong komplikado, at maaaring iniisip mo kung bakit hindi natin ginagamit ang mga standard na Python functions para i-transform ang dataset bago ito ipasa sa `fit`. Bagama't posible itong gawin, ang paggamit ng `Dataset.map` ay may malaking bentahe, dahil ang data transformation pipeline ay isinasagawa gamit ang Tensorflow computational graph, na gumagamit ng GPU computations, at binabawasan ang pangangailangan na magpalipat-lipat ng data sa pagitan ng CPU/GPU.\n",
|
|
"\n",
|
|
"Ngayon, maaari na nating buuin ang ating generator network at simulan ang training. Maaari itong basehan ng anumang recurrent cell na tinalakay natin sa nakaraang unit (simple, LSTM o GRU). Sa ating halimbawa, gagamit tayo ng LSTM.\n",
|
|
"\n",
|
|
"Dahil ang network ay tumatanggap ng mga character bilang input, at maliit lang ang laki ng vocabulary, hindi natin kailangan ng embedding layer; ang one-hot-encoded input ay maaaring direktang ipasa sa LSTM cell. Ang output layer ay magiging isang `Dense` classifier na magko-convert ng LSTM output sa one-hot-encoded token numbers.\n",
|
|
"\n",
|
|
"Bukod pa rito, dahil ang ating tinatrabaho ay mga sequence na may variable na haba, maaari tayong gumamit ng `Masking` layer upang lumikha ng mask na magpapawalang-bisa sa padded na bahagi ng string. Hindi ito mahigpit na kinakailangan, dahil hindi naman tayo masyadong interesado sa anumang bahagi na lampas sa `<eos>` token, ngunit gagamitin natin ito para magkaroon ng karanasan sa ganitong uri ng layer. Ang `input_shape` ay magiging `(None, vocab_size)`, kung saan ang `None` ay nagpapahiwatig ng sequence na may variable na haba, at ang output shape ay `(None, vocab_size)` din, tulad ng makikita mo sa `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": [
|
|
"## Pagbuo ng Output\n",
|
|
"\n",
|
|
"Ngayon na natapos na natin ang pagsasanay sa modelo, gusto nating gamitin ito upang makabuo ng output. Una sa lahat, kailangan natin ng paraan upang i-decode ang teksto na kinakatawan ng isang sequence ng mga numero ng token. Para magawa ito, maaari nating gamitin ang function na `tokenizer.sequences_to_texts`; gayunpaman, hindi ito mahusay gumagana sa character-level tokenization. Kaya't gagamit tayo ng dictionary ng mga token mula sa tokenizer (tinatawag na `word_index`), gagawa ng reverse map, at isusulat ang sarili nating 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": [
|
|
"Ngayon, magsisimula tayo sa isang string na `start`, i-encode ito sa isang sequence na `inp`, at pagkatapos sa bawat hakbang ay tatawagin natin ang ating network upang mahinuha ang susunod na karakter.\n",
|
|
"\n",
|
|
"Ang output ng network na `out` ay isang vector na may `vocab_size` na mga elemento na kumakatawan sa mga probabilidad ng bawat token, at maaari nating mahanap ang pinaka-malamang na numero ng token gamit ang `argmax`. Pagkatapos, idinadagdag natin ang karakter na ito sa listahan ng mga na-generate na token, at nagpapatuloy sa pagbuo. Ang prosesong ito ng pagbuo ng isang karakter ay inuulit nang `size` na beses upang makabuo ng kinakailangang bilang ng mga karakter, at natatapos nang maaga kapag naabot ang `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": [
|
|
"## Pagkuha ng sample ng output habang nagsasanay\n",
|
|
"\n",
|
|
"Dahil wala tayong anumang kapaki-pakinabang na sukatan tulad ng *accuracy*, ang tanging paraan upang makita natin kung gumaganda ang ating modelo ay sa pamamagitan ng **pagkuha ng sample** ng mga nabuong string habang nagsasanay. Upang gawin ito, gagamit tayo ng **callbacks**, ibig sabihin, mga function na maaari nating ipasa sa `fit` function, at tatawagin ito nang pana-panahon habang nagsasanay.\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": [
|
|
"Ang halimbawang ito ay nakabubuo na ng medyo maayos na teksto, ngunit maaari pa itong mapahusay sa iba't ibang paraan:\n",
|
|
"\n",
|
|
"* **Mas maraming teksto**. Gumamit lamang tayo ng mga pamagat para sa ating gawain, ngunit maaari mong subukang gumamit ng buong teksto. Tandaan na hindi gaanong mahusay ang RNNs sa paghawak ng mahahabang mga sequence, kaya makatuwiran na hatiin ang mga ito sa mas maiikling pangungusap, o palaging magsanay gamit ang nakapirming haba ng sequence na may paunang itinakdang halaga `num_chars` (halimbawa, 256). Maaari mong subukang baguhin ang halimbawa sa itaas sa ganitong arkitektura, gamit ang [opisyal na tutorial ng Keras](https://keras.io/examples/generative/lstm_character_level_text_generation/) bilang inspirasyon.\n",
|
|
"\n",
|
|
"* **Multilayer LSTM**. Makatuwiran ding subukan ang 2 o 3 layer ng mga LSTM cell. Gaya ng nabanggit natin sa nakaraang yunit, ang bawat layer ng LSTM ay kumukuha ng partikular na mga pattern mula sa teksto, at sa kaso ng character-level generator, maaari nating asahan na ang mas mababang antas ng LSTM ay responsable sa pagkuha ng mga pantig, at ang mas mataas na antas - para sa mga salita at kombinasyon ng mga salita. Madali itong maipatupad sa pamamagitan ng pagpapasa ng bilang ng mga layer bilang parameter sa LSTM constructor.\n",
|
|
"\n",
|
|
"* Maaari mo ring subukang mag-eksperimento gamit ang **GRU units** at tingnan kung alin ang mas mahusay ang pagganap, pati na rin ang **iba't ibang laki ng hidden layer**. Ang sobrang laki ng hidden layer ay maaaring magresulta sa overfitting (halimbawa, matututunan ng network ang eksaktong teksto), at ang mas maliit na laki ay maaaring hindi makabuo ng magandang resulta.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Malambot na pagbuo ng teksto at temperatura\n",
|
|
"\n",
|
|
"Sa nakaraang depinisyon ng `generate`, palagi nating pinipili ang karakter na may pinakamataas na posibilidad bilang susunod na karakter sa nabubuong teksto. Dahil dito, madalas na \"umuulit\" ang teksto sa parehong mga sequence ng karakter nang paulit-ulit, tulad ng sa halimbawang ito:\n",
|
|
"```\n",
|
|
"today of the second the company and a second the company ...\n",
|
|
"```\n",
|
|
"\n",
|
|
"Gayunpaman, kung titingnan natin ang distribusyon ng posibilidad para sa susunod na karakter, maaaring ang pagkakaiba sa pagitan ng ilang pinakamataas na posibilidad ay hindi ganoon kalaki, halimbawa, ang isang karakter ay maaaring may posibilidad na 0.2, habang ang isa pa ay 0.19, at iba pa. Halimbawa, kapag hinahanap ang susunod na karakter sa sequence na '*play*', ang susunod na karakter ay maaaring maging space o **e** (tulad ng sa salitang *player*).\n",
|
|
"\n",
|
|
"Ito ay nagdadala sa atin sa konklusyon na hindi palaging \"makatarungan\" na piliin ang karakter na may mas mataas na posibilidad, dahil ang pagpili sa pangalawang pinakamataas ay maaari pa ring magresulta sa makabuluhang teksto. Mas matalino na **mag-sample** ng mga karakter mula sa distribusyon ng posibilidad na ibinigay ng output ng network.\n",
|
|
"\n",
|
|
"Ang pag-sample na ito ay maaaring gawin gamit ang `np.multinomial` na function na nag-iimplementa ng tinatawag na **multinomial distribution**. Ang isang function na nag-iimplementa ng ganitong **malambot** na pagbuo ng teksto ay nakasaad sa ibaba:\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": [
|
|
"Nagpakilala kami ng isa pang parameter na tinatawag na **temperature**, na ginagamit upang ipakita kung gaano kahigpit dapat tayong sumunod sa pinakamataas na posibilidad. Kung ang temperature ay 1.0, gumagawa tayo ng patas na multinomial sampling, at kapag ang temperature ay umabot sa infinity - nagiging pantay ang lahat ng posibilidad, at random nating pinipili ang susunod na karakter. Sa halimbawa sa ibaba, makikita natin na nagiging walang kahulugan ang teksto kapag masyadong tinaasan ang temperature, at nagiging katulad ng \"cycled\" na mahirap-generate na teksto kapag mas malapit ito sa 0.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n---\n\n**Paunawa**: \nAng dokumentong ito ay isinalin gamit ang AI translation service na [Co-op Translator](https://github.com/Azure/co-op-translator). Bagama't sinisikap naming maging tumpak, pakitandaan na ang mga awtomatikong pagsasalin ay maaaring maglaman ng mga pagkakamali o hindi pagkakatugma. Ang orihinal na dokumento sa kanyang katutubong wika ang dapat ituring na opisyal na sanggunian. Para sa mahalagang impormasyon, inirerekomenda ang propesyonal na pagsasalin ng tao. Hindi kami mananagot sa anumang hindi pagkakaunawaan o maling interpretasyon na maaaring magmula sa paggamit ng pagsasaling ito.\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-28T04:08:11+00:00",
|
|
"source_file": "lessons/5-NLP/17-GenerativeNetworks/GenerativeTF.ipynb",
|
|
"language_code": "tl"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
} |