414 lines
22 KiB
Plaintext
414 lines
22 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Rangkaian Generatif\n",
|
|
"\n",
|
|
"Recurrent Neural Networks (RNNs) dan varian sel berpintunya seperti Long Short Term Memory Cells (LSTMs) dan Gated Recurrent Units (GRUs) menyediakan mekanisme untuk pemodelan bahasa, iaitu mereka boleh belajar susunan perkataan dan memberikan ramalan untuk perkataan seterusnya dalam satu urutan. Ini membolehkan kita menggunakan RNN untuk **tugas generatif**, seperti penjanaan teks biasa, terjemahan mesin, dan juga kapsyen imej.\n",
|
|
"\n",
|
|
"Dalam seni bina RNN yang kita bincangkan dalam unit sebelumnya, setiap unit RNN menghasilkan keadaan tersembunyi seterusnya sebagai output. Walau bagaimanapun, kita juga boleh menambah output lain kepada setiap unit berulang, yang membolehkan kita menghasilkan **urutan** (yang sama panjang dengan urutan asal). Selain itu, kita boleh menggunakan unit RNN yang tidak menerima input pada setiap langkah, dan hanya mengambil beberapa vektor keadaan awal, kemudian menghasilkan urutan output.\n",
|
|
"\n",
|
|
"Dalam notebook ini, kita akan memberi tumpuan kepada model generatif mudah yang membantu kita menjana teks. Untuk kesederhanaan, mari bina **rangkaian peringkat aksara**, yang menjana teks huruf demi huruf. Semasa latihan, kita perlu mengambil beberapa korpus teks, dan membahagikannya kepada urutan huruf.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Loading dataset...\n",
|
|
"Building vocab...\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"import torch\n",
|
|
"import torchtext\n",
|
|
"import numpy as np\n",
|
|
"from torchnlp import *\n",
|
|
"train_dataset,test_dataset,classes,vocab = load_dataset()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Membina perbendaharaan kata watak\n",
|
|
"\n",
|
|
"Untuk membina rangkaian generatif peringkat watak, kita perlu memecahkan teks kepada watak individu dan bukannya perkataan. Ini boleh dilakukan dengan mendefinisikan pengekod token yang berbeza:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Vocabulary size = 82\n",
|
|
"Encoding of 'a' is 1\n",
|
|
"Character with code 13 is c\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def char_tokenizer(words):\n",
|
|
" return list(words) #[word for word in words]\n",
|
|
"\n",
|
|
"counter = collections.Counter()\n",
|
|
"for (label, line) in train_dataset:\n",
|
|
" counter.update(char_tokenizer(line))\n",
|
|
"vocab = torchtext.vocab.vocab(counter)\n",
|
|
"\n",
|
|
"vocab_size = len(vocab)\n",
|
|
"print(f\"Vocabulary size = {vocab_size}\")\n",
|
|
"print(f\"Encoding of 'a' is {vocab.get_stoi()['a']}\")\n",
|
|
"print(f\"Character with code 13 is {vocab.get_itos()[13]}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Mari kita lihat contoh bagaimana kita boleh mengekod teks daripada set data kita:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"tensor([ 0, 1, 2, 2, 3, 4, 5, 6, 3, 7, 8, 1, 9, 10, 3, 11, 2, 1,\n",
|
|
" 12, 3, 7, 1, 13, 14, 3, 15, 16, 5, 17, 3, 5, 18, 8, 3, 7, 2,\n",
|
|
" 1, 13, 14, 3, 19, 20, 8, 21, 5, 8, 9, 10, 22, 3, 20, 8, 21, 5,\n",
|
|
" 8, 9, 10, 3, 23, 3, 4, 18, 17, 9, 5, 23, 10, 8, 2, 2, 8, 9,\n",
|
|
" 10, 24, 3, 0, 1, 2, 2, 3, 4, 5, 9, 8, 8, 5, 25, 10, 3, 26,\n",
|
|
" 12, 27, 16, 26, 2, 27, 16, 28, 29, 30, 1, 16, 26, 3, 17, 31, 3, 21,\n",
|
|
" 2, 5, 9, 1, 23, 13, 32, 16, 27, 13, 10, 24, 3, 1, 9, 8, 3, 10,\n",
|
|
" 8, 8, 27, 16, 28, 3, 28, 9, 8, 8, 16, 3, 1, 28, 1, 27, 16, 6])"
|
|
]
|
|
},
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"def enc(x):\n",
|
|
" return torch.LongTensor(encode(x,voc=vocab,tokenizer=char_tokenizer))\n",
|
|
"\n",
|
|
"enc(train_dataset[0][1])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Melatih RNN Generatif\n",
|
|
"\n",
|
|
"Cara kita akan melatih RNN untuk menghasilkan teks adalah seperti berikut. Pada setiap langkah, kita akan mengambil satu urutan watak dengan panjang `nchars`, dan meminta rangkaian untuk menghasilkan watak output seterusnya bagi setiap watak input:\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"Bergantung kepada senario sebenar, kita mungkin juga ingin memasukkan beberapa watak khas, seperti *end-of-sequence* `<eos>`. Dalam kes kita, kita hanya ingin melatih rangkaian untuk menghasilkan teks tanpa henti, oleh itu kita akan menetapkan saiz setiap urutan sama dengan token `nchars`. Akibatnya, setiap contoh latihan akan terdiri daripada `nchars` input dan `nchars` output (iaitu urutan input yang dialihkan satu simbol ke kiri). Minibatch akan terdiri daripada beberapa urutan seperti ini.\n",
|
|
"\n",
|
|
"Cara kita akan menghasilkan minibatch adalah dengan mengambil setiap teks berita dengan panjang `l`, dan menghasilkan semua kombinasi input-output yang mungkin daripadanya (akan ada `l-nchars` kombinasi seperti itu). Kombinasi ini akan membentuk satu minibatch, dan saiz minibatch akan berbeza pada setiap langkah latihan.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"(tensor([[ 0, 1, 2, ..., 28, 29, 30],\n",
|
|
" [ 1, 2, 2, ..., 29, 30, 1],\n",
|
|
" [ 2, 2, 3, ..., 30, 1, 16],\n",
|
|
" ...,\n",
|
|
" [20, 8, 21, ..., 1, 28, 1],\n",
|
|
" [ 8, 21, 5, ..., 28, 1, 27],\n",
|
|
" [21, 5, 8, ..., 1, 27, 16]]),\n",
|
|
" tensor([[ 1, 2, 2, ..., 29, 30, 1],\n",
|
|
" [ 2, 2, 3, ..., 30, 1, 16],\n",
|
|
" [ 2, 3, 4, ..., 1, 16, 26],\n",
|
|
" ...,\n",
|
|
" [ 8, 21, 5, ..., 28, 1, 27],\n",
|
|
" [21, 5, 8, ..., 1, 27, 16],\n",
|
|
" [ 5, 8, 9, ..., 27, 16, 6]]))"
|
|
]
|
|
},
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"nchars = 100\n",
|
|
"\n",
|
|
"def get_batch(s,nchars=nchars):\n",
|
|
" ins = torch.zeros(len(s)-nchars,nchars,dtype=torch.long,device=device)\n",
|
|
" outs = torch.zeros(len(s)-nchars,nchars,dtype=torch.long,device=device)\n",
|
|
" for i in range(len(s)-nchars):\n",
|
|
" ins[i] = enc(s[i:i+nchars])\n",
|
|
" outs[i] = enc(s[i+1:i+nchars+1])\n",
|
|
" return ins,outs\n",
|
|
"\n",
|
|
"get_batch(train_dataset[0][1])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Sekarang mari kita definisikan rangkaian penjana. Ia boleh berdasarkan mana-mana sel berulang yang telah kita bincangkan dalam unit sebelumnya (simple, LSTM atau GRU). Dalam contoh kita, kita akan menggunakan LSTM.\n",
|
|
"\n",
|
|
"Oleh kerana rangkaian ini mengambil aksara sebagai input, dan saiz kosa kata agak kecil, kita tidak memerlukan lapisan embedding, input yang dikodkan satu-panas (one-hot-encoded) boleh terus masuk ke dalam sel LSTM. Walau bagaimanapun, kerana kita menghantar nombor aksara sebagai input, kita perlu mengkodkan satu-panas (one-hot-encode) mereka sebelum menghantar ke LSTM. Ini dilakukan dengan memanggil fungsi `one_hot` semasa laluan `forward`. Pengekod output akan menjadi lapisan linear yang akan menukar keadaan tersembunyi kepada output yang dikodkan satu-panas.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class LSTMGenerator(torch.nn.Module):\n",
|
|
" def __init__(self, vocab_size, hidden_dim):\n",
|
|
" super().__init__()\n",
|
|
" self.rnn = torch.nn.LSTM(vocab_size,hidden_dim,batch_first=True)\n",
|
|
" self.fc = torch.nn.Linear(hidden_dim, vocab_size)\n",
|
|
"\n",
|
|
" def forward(self, x, s=None):\n",
|
|
" x = torch.nn.functional.one_hot(x,vocab_size).to(torch.float32)\n",
|
|
" x,s = self.rnn(x,s)\n",
|
|
" return self.fc(x),s"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Semasa latihan, kita ingin dapat mengambil sampel teks yang dihasilkan. Untuk melakukannya, kita akan mendefinisikan fungsi `generate` yang akan menghasilkan string output dengan panjang `size`, bermula dari string awal `start`.\n",
|
|
"\n",
|
|
"Cara ia berfungsi adalah seperti berikut. Pertama, kita akan menghantar keseluruhan string `start` melalui rangkaian, dan mengambil keadaan output `s` dan watak seterusnya yang diramalkan `out`. Oleh kerana `out` dikodkan satu-hot, kita mengambil `argmax` untuk mendapatkan indeks watak `nc` dalam perbendaharaan kata, dan menggunakan `itos` untuk menentukan watak sebenar dan menambahkannya ke senarai watak `chars` yang dihasilkan. Proses menghasilkan satu watak ini diulang sebanyak `size` kali untuk menghasilkan jumlah watak yang diperlukan.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def generate(net,size=100,start='today '):\n",
|
|
" chars = list(start)\n",
|
|
" out, s = net(enc(chars).view(1,-1).to(device))\n",
|
|
" for i in range(size):\n",
|
|
" nc = torch.argmax(out[0][-1])\n",
|
|
" chars.append(vocab.get_itos()[nc])\n",
|
|
" out, s = net(nc.view(1,-1),s)\n",
|
|
" return ''.join(chars)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Sekarang mari kita mulakan latihan! Gelung latihan hampir sama seperti dalam semua contoh sebelumnya, tetapi kali ini, bukannya ketepatan, kita cetak teks yang dijana setiap 1000 epoch.\n",
|
|
"\n",
|
|
"Perhatian khusus perlu diberikan kepada cara kita mengira kehilangan. Kita perlu mengira kehilangan berdasarkan output yang dikodkan satu-haba `out`, dan teks yang dijangka `text_out`, iaitu senarai indeks aksara. Nasib baik, fungsi `cross_entropy` mengharapkan output rangkaian yang tidak dinormalisasi sebagai argumen pertama, dan nombor kelas sebagai argumen kedua, yang mana tepat seperti yang kita ada. Ia juga melakukan purata automatik berdasarkan saiz minibatch.\n",
|
|
"\n",
|
|
"Kita juga menghadkan latihan kepada sampel `samples_to_train`, supaya tidak perlu menunggu terlalu lama. Kami menggalakkan anda untuk bereksperimen dan mencuba latihan yang lebih lama, mungkin untuk beberapa epoch (dalam kes ini, anda perlu mencipta gelung lain di sekitar kod ini).\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Current loss = 4.398899078369141\n",
|
|
"today sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr sr s\n",
|
|
"Current loss = 2.161320447921753\n",
|
|
"today and to the tor to to the tor to to the tor to to the tor to to the tor to to the tor to to the tor t\n",
|
|
"Current loss = 1.6722588539123535\n",
|
|
"today and the court to the could to the could to the could to the could to the could to the could to the c\n",
|
|
"Current loss = 2.423795223236084\n",
|
|
"today and a second to the conternation of the conternation of the conternation of the conternation of the \n",
|
|
"Current loss = 1.702607274055481\n",
|
|
"today and the company to the company to the company to the company to the company to the company to the co\n",
|
|
"Current loss = 1.692358136177063\n",
|
|
"today and the company to the company to the company to the company to the company to the company to the co\n",
|
|
"Current loss = 1.9722288846969604\n",
|
|
"today and the control the control the control the control the control the control the control the control \n",
|
|
"Current loss = 1.8705692291259766\n",
|
|
"today and the second to the second to the second to the second to the second to the second to the second t\n",
|
|
"Current loss = 1.7626899480819702\n",
|
|
"today and a security and a security and a security and a security and a security and a security and a secu\n",
|
|
"Current loss = 1.5574463605880737\n",
|
|
"today and the company and the company and the company and the company and the company and the company and \n",
|
|
"Current loss = 1.5620026588439941\n",
|
|
"today and the be that the be the be that the be the be that the be the be that the be the be that the be t\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"net = LSTMGenerator(vocab_size,64).to(device)\n",
|
|
"\n",
|
|
"samples_to_train = 10000\n",
|
|
"optimizer = torch.optim.Adam(net.parameters(),0.01)\n",
|
|
"loss_fn = torch.nn.CrossEntropyLoss()\n",
|
|
"net.train()\n",
|
|
"for i,x in enumerate(train_dataset):\n",
|
|
" # x[0] is class label, x[1] is text\n",
|
|
" if len(x[1])-nchars<10:\n",
|
|
" continue\n",
|
|
" samples_to_train-=1\n",
|
|
" if not samples_to_train: break\n",
|
|
" text_in, text_out = get_batch(x[1])\n",
|
|
" optimizer.zero_grad()\n",
|
|
" out,s = net(text_in)\n",
|
|
" loss = torch.nn.functional.cross_entropy(out.view(-1,vocab_size),text_out.flatten()) #cross_entropy(out,labels)\n",
|
|
" loss.backward()\n",
|
|
" optimizer.step()\n",
|
|
" if i%1000==0:\n",
|
|
" print(f\"Current loss = {loss.item()}\")\n",
|
|
" print(generate(net))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Contoh ini sudah menghasilkan teks yang agak baik, tetapi ia masih boleh diperbaiki dengan beberapa cara:\n",
|
|
"\n",
|
|
"* **Penjanaan minibatch yang lebih baik**. Cara kita menyediakan data untuk latihan adalah dengan menghasilkan satu minibatch daripada satu sampel. Ini tidak ideal kerana saiz minibatch berbeza-beza, dan ada yang tidak dapat dihasilkan kerana teks lebih kecil daripada `nchars`. Selain itu, minibatch kecil tidak memanfaatkan GPU dengan cukup baik. Adalah lebih bijak untuk mengambil satu bahagian besar teks daripada semua sampel, kemudian menghasilkan semua pasangan input-output, mengacakkannya, dan menghasilkan minibatch dengan saiz yang sama.\n",
|
|
"\n",
|
|
"* **LSTM berlapis-lapis**. Adalah masuk akal untuk mencuba 2 atau 3 lapisan sel LSTM. Seperti yang disebutkan dalam unit sebelumnya, setiap lapisan LSTM mengekstrak corak tertentu daripada teks, dan dalam kes penjana peringkat aksara, kita boleh menjangkakan lapisan LSTM yang lebih rendah bertanggungjawab untuk mengekstrak suku kata, manakala lapisan yang lebih tinggi - untuk perkataan dan kombinasi perkataan. Ini boleh dilaksanakan dengan mudah dengan memberikan parameter bilangan lapisan kepada pembina LSTM.\n",
|
|
"\n",
|
|
"* Anda juga mungkin ingin bereksperimen dengan **unit GRU** dan melihat mana yang memberikan prestasi lebih baik, serta dengan **saiz lapisan tersembunyi yang berbeza**. Lapisan tersembunyi yang terlalu besar mungkin menyebabkan overfitting (contohnya, rangkaian akan belajar teks secara tepat), manakala saiz yang lebih kecil mungkin tidak menghasilkan keputusan yang baik.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Penjanaan teks lembut dan suhu\n",
|
|
"\n",
|
|
"Dalam definisi `generate` sebelum ini, kita sentiasa memilih aksara dengan kebarangkalian tertinggi sebagai aksara seterusnya dalam teks yang dijana. Ini menyebabkan teks sering \"berulang\" antara urutan aksara yang sama berulang kali, seperti dalam contoh ini: \n",
|
|
"```\n",
|
|
"today of the second the company and a second the company ...\n",
|
|
"```\n",
|
|
"\n",
|
|
"Namun, jika kita melihat pada taburan kebarangkalian untuk aksara seterusnya, mungkin perbezaan antara beberapa kebarangkalian tertinggi tidak begitu besar, contohnya satu aksara boleh mempunyai kebarangkalian 0.2, manakala yang lain - 0.19, dan sebagainya. Sebagai contoh, apabila mencari aksara seterusnya dalam urutan '*play*', aksara seterusnya boleh jadi sama ada ruang, atau **e** (seperti dalam perkataan *player*).\n",
|
|
"\n",
|
|
"Ini membawa kita kepada kesimpulan bahawa tidak selalu \"adil\" untuk memilih aksara dengan kebarangkalian tertinggi, kerana memilih yang kedua tertinggi mungkin masih membawa kepada teks yang bermakna. Adalah lebih bijak untuk **sampel** aksara daripada taburan kebarangkalian yang diberikan oleh output rangkaian.\n",
|
|
"\n",
|
|
"Pensampelan ini boleh dilakukan menggunakan fungsi `multinomial` yang melaksanakan apa yang dipanggil **taburan multinomial**. Fungsi yang melaksanakan penjanaan teks **lembut** ini ditakrifkan di bawah:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"--- Temperature = 0.3\n",
|
|
"Today and a company and complete an all the land the restrational the as a security and has provers the pay to and a report and the computer in the stand has filities and working the law the stations for a company and with the company and the final the first company and refight of the state and and workin\n",
|
|
"\n",
|
|
"--- Temperature = 0.8\n",
|
|
"Today he oniis its first to Aus bomblaties the marmation a to manan boogot that pirate assaid a relaid their that goverfin the the Cappets Ecrotional Assonia Cition targets it annight the w scyments Blamity #39;s TVeer Diercheg Reserals fran envyuil that of ster said access what succers of Dour-provelith\n",
|
|
"\n",
|
|
"--- Temperature = 1.0\n",
|
|
"Today holy they a 11 will meda a toket subsuaties, engins for Chanos, they's has stainger past to opening orital his thempting new Nattona was al innerforder advan-than #36;s night year his religuled talitatian what the but with Wednesday to Justment will wemen of Mark CCC Camp as Timed Nae wome a leaders\n",
|
|
"\n",
|
|
"--- Temperature = 1.3\n",
|
|
"Today gpone 2.5 fech atcusion poor cocles toparsdorM.cht Line Pamage put 43 his calt lowed to the book, that has authh-the silia rruch ailing to'ory andhes beutirsimi- Aefffive heading offil an auf eacklets is charged evis, Gunymy oy) Mony has it after-sloythyor loveId out filme, the Natabl -Najuntaxiggs \n",
|
|
"\n",
|
|
"--- Temperature = 1.8\n",
|
|
"Today plary, P.slan chly\\401 mardregationly #39;t 8.1Mide) closes ,filtcon alfly playin roven!\\grea.-QFBEP: Iss onfarchQ/itilia CCf Zivesigntwasta orce.-Peul-aw.uicrin of fuglinfsut aftaningwo, MIEX awayew Aice Woiduar Corvagiugge oppo esig ThusBratourid canthly-RyI.co lagitems\\eexciaishes.conBabntusmor I\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def generate_soft(net,size=100,start='today ',temperature=1.0):\n",
|
|
" chars = list(start)\n",
|
|
" out, s = net(enc(chars).view(1,-1).to(device))\n",
|
|
" for i in range(size):\n",
|
|
" #nc = torch.argmax(out[0][-1])\n",
|
|
" out_dist = out[0][-1].div(temperature).exp()\n",
|
|
" nc = torch.multinomial(out_dist,1)[0]\n",
|
|
" chars.append(vocab.get_itos()[nc])\n",
|
|
" out, s = net(nc.view(1,-1),s)\n",
|
|
" return ''.join(chars)\n",
|
|
" \n",
|
|
"for i in [0.3,0.8,1.0,1.3,1.8]:\n",
|
|
" print(f\"--- Temperature = {i}\\n{generate_soft(net,size=300,start='Today ',temperature=i)}\\n\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Kami telah memperkenalkan satu lagi parameter yang dipanggil **temperature**, yang digunakan untuk menunjukkan sejauh mana kita harus berpegang kepada kebarangkalian tertinggi. Jika temperature adalah 1.0, kami melakukan pensampelan multinomial yang adil, dan apabila temperature meningkat ke infiniti - semua kebarangkalian menjadi sama, dan kami memilih aksara seterusnya secara rawak. Dalam contoh di bawah, kita dapat melihat bahawa teks menjadi tidak bermakna apabila kita meningkatkan temperature terlalu banyak, dan ia menyerupai teks \"berkitar\" yang dihasilkan secara keras apabila ia menjadi lebih dekat kepada 0.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n---\n\n**Penafian**: \nDokumen ini telah diterjemahkan menggunakan perkhidmatan terjemahan AI [Co-op Translator](https://github.com/Azure/co-op-translator). Walaupun kami berusaha untuk memastikan ketepatan, sila ambil perhatian bahawa terjemahan automatik mungkin mengandungi kesilapan atau ketidaktepatan. Dokumen asal dalam bahasa asalnya harus dianggap sebagai sumber yang berwibawa. Untuk maklumat yang kritikal, terjemahan manusia profesional adalah disyorkan. Kami tidak bertanggungjawab atas sebarang salah faham atau salah tafsir yang timbul daripada penggunaan terjemahan ini.\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": "7673cd150d96c74c6d6011460094efb4",
|
|
"translation_date": "2025-08-29T15:45:26+00:00",
|
|
"source_file": "lessons/5-NLP/17-GenerativeNetworks/GenerativePyTorch.ipynb",
|
|
"language_code": "ms"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
} |