AI-For-Beginners/translations/kn/lessons/5-NLP/17-GenerativeNetworks/GenerativePyTorch.ipynb

411 lines
33 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# ಜನರೇಟಿವ್ ನೆಟ್‌ವರ್ಕ್‌ಗಳು\n",
"\n",
"ರಿಕರೆಂಟ್ ನ್ಯೂರಲ್ ನೆಟ್‌ವರ್ಕ್‌ಗಳು (RNNಗಳು) ಮತ್ತು ಅವುಗಳ ಗೇಟೆಡ್ ಸೆಲ್ ರೂಪಾಂತರಗಳು, ಉದಾಹರಣೆಗೆ ಲಾಂಗ್ ಶಾರ್ಟ್ ಟರ್ಮ್ ಮೆಮೊರಿ ಸೆಲ್ಸ್ (LSTMs) ಮತ್ತು ಗೇಟೆಡ್ ರಿಕರೆಂಟ್ ಯುನಿಟ್ಸ್ (GRUs), ಭಾಷಾ ಮಾದರೀಕರಣಕ್ಕೆ ಒಂದು ಯಂತ್ರವಿಧಾನವನ್ನು ಒದಗಿಸುತ್ತವೆ, ಅಂದರೆ ಅವು ಪದಗಳ ಕ್ರಮವನ್ನು ಕಲಿಯಬಹುದು ಮತ್ತು ಸರಣಿಯಲ್ಲಿ ಮುಂದಿನ ಪದದ ಭವಿಷ್ಯವಾಣಿ ಮಾಡಬಹುದು. ಇದರಿಂದ ನಾವು RNNಗಳನ್ನು **ಜನರೇಟಿವ್ ಕಾರ್ಯಗಳಿಗೆ** ಬಳಸಬಹುದು, ಉದಾಹರಣೆಗೆ ಸಾಮಾನ್ಯ ಪಠ್ಯ ರಚನೆ, ಯಂತ್ರ ಅನುವಾದ ಮತ್ತು ಚಿತ್ರ ಶೀರ್ಷಿಕೆ ರಚನೆ.\n",
"\n",
"ನಾವು ಹಿಂದಿನ ಘಟಕದಲ್ಲಿ ಚರ್ಚಿಸಿದ RNN ವಾಸ್ತುಶಿಲ್ಪದಲ್ಲಿ, ಪ್ರತಿ RNN ಘಟಕವು ಮುಂದಿನ ಹಿಡನ್ ಸ್ಥಿತಿಯನ್ನು ಔಟ್‌ಪುಟ್ ಆಗಿ ನೀಡುತ್ತಿತ್ತು. ಆದರೆ, ನಾವು ಪ್ರತಿ ರಿಕರೆಂಟ್ ಘಟಕಕ್ಕೆ ಮತ್ತೊಂದು ಔಟ್‌ಪುಟ್ ಅನ್ನು ಸೇರಿಸಬಹುದು, ಇದು ನಮಗೆ **ಸರಣಿ** (ಮೂಲ ಸರಣಿಯ ಉದ್ದಕ್ಕೆ ಸಮಾನ) ಔಟ್‌ಪುಟ್ ಮಾಡಲು ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಜೊತೆಗೆ, ನಾವು ಪ್ರತಿ ಹಂತದಲ್ಲಿ ಇನ್‌ಪುಟ್ ಸ್ವೀಕರಿಸದ RNN ಘಟಕಗಳನ್ನು ಬಳಸಬಹುದು, ಮತ್ತು ಕೇವಲ ಕೆಲವು ಪ್ರಾರಂಭಿಕ ಸ್ಥಿತಿ ವೆಕ್ಟರ್ ತೆಗೆದುಕೊಂಡು, ನಂತರ ಔಟ್‌ಪುಟ್ ಸರಣಿಯನ್ನು ಉತ್ಪಾದಿಸಬಹುದು.\n",
"\n",
"ಈ ನೋಟ್ಬುಕ್‌ನಲ್ಲಿ, ನಾವು ಪಠ್ಯವನ್ನು ರಚಿಸಲು ಸಹಾಯ ಮಾಡುವ ಸರಳ ಜನರೇಟಿವ್ ಮಾದರಿಗಳ ಮೇಲೆ ಗಮನಹರಿಸುವೆವು. ಸರಳತೆಗೆ, ನಾವು **ಅಕ್ಷರ ಮಟ್ಟದ ನೆಟ್‌ವರ್ಕ್** ಅನ್ನು ನಿರ್ಮಿಸೋಣ, ಇದು ಅಕ್ಷರದಿಂದ ಅಕ್ಷರಕ್ಕೆ ಪಠ್ಯವನ್ನು ರಚಿಸುತ್ತದೆ. ತರಬೇತಿಯ ಸಮಯದಲ್ಲಿ, ನಮಗೆ ಕೆಲವು ಪಠ್ಯ ಸಂಗ್ರಹವನ್ನು ತೆಗೆದು, ಅದನ್ನು ಅಕ್ಷರ ಸರಣಿಗಳಾಗಿ ವಿಭಜಿಸಬೇಕಾಗುತ್ತದೆ.\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": [
"## ಅಕ್ಷರ ಶಬ್ದಕೋಶ ನಿರ್ಮಾಣ\n",
"\n",
"ಅಕ್ಷರ ಮಟ್ಟದ ಜನರೇಟಿವ್ ನೆಟ್‌ವರ್ಕ್ ನಿರ್ಮಿಸಲು, ನಾವು ಪಠ್ಯವನ್ನು ಪದಗಳ ಬದಲು ಪ್ರತ್ಯೇಕ ಅಕ್ಷರಗಳಾಗಿ ವಿಭಜಿಸಬೇಕು. ಇದನ್ನು ವಿಭಿನ್ನ ಟೋಕನೈಜರ್ ಅನ್ನು ನಿರ್ಧರಿಸುವ ಮೂಲಕ ಮಾಡಬಹುದು:\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": [
"ನಮ್ಮ ಡೇಟಾಸೆಟ್‌ನಿಂದ ಪಠ್ಯವನ್ನು ಎನ್‌ಕೋಡ್ ಮಾಡುವುದರ ಉದಾಹರಣೆಯನ್ನು ನೋಡೋಣ:\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": [
"## ಜನರೇಟಿವ್ RNN ತರಬೇತಿ\n",
"\n",
"ನಾವು RNN ಅನ್ನು ಪಠ್ಯವನ್ನು ರಚಿಸಲು ತರಬೇತಿಗೊಳಿಸುವ ವಿಧಾನ ಹೀಗಿದೆ. ಪ್ರತಿ ಹಂತದಲ್ಲಿ, ನಾವು `nchars` ಉದ್ದದ ಅಕ್ಷರಗಳ ಸರಣಿಯನ್ನು ತೆಗೆದು, ಪ್ರತಿಯೊಂದು ಇನ್‌ಪುಟ್ ಅಕ್ಷರಕ್ಕೆ ಮುಂದಿನ ಔಟ್‌ಪುಟ್ ಅಕ್ಷರವನ್ನು ನೆಟ್‌ವರ್ಕ್ ರಚಿಸಲು ಕೇಳುತ್ತೇವೆ:\n",
"\n",
"!['HELLO' ಎಂಬ ಪದದ ಉದಾಹರಣೆಯಾಗಿ RNN ರಚನೆಯನ್ನು ತೋರಿಸುವ ಚಿತ್ರ.](../../../../../translated_images/kn/rnn-generate.56c54afb52f9781d.webp)\n",
"\n",
"ವಾಸ್ತವಿಕ ಪರಿಸ್ಥಿತಿಯ ಮೇಲೆ ಅವಲಂಬಿಸಿ, ನಾವು ಕೆಲವು ವಿಶೇಷ ಅಕ್ಷರಗಳನ್ನು ಸೇರಿಸಲು ಬಯಸಬಹುದು, ಉದಾಹರಣೆಗೆ *end-of-sequence* `<eos>`. ನಮ್ಮ ಪ್ರಕರಣದಲ್ಲಿ, ನಾವು ನಿರಂತರ ಪಠ್ಯ ರಚನೆಗಾಗಿ ನೆಟ್‌ವರ್ಕ್ ಅನ್ನು ತರಬೇತಿಗೊಳಿಸಲು ಬಯಸುತ್ತೇವೆ, ಆದ್ದರಿಂದ ಪ್ರತಿ ಸರಣಿಯ ಗಾತ್ರವನ್ನು `nchars` ಟೋಕನ್‌ಗಳಿಗೆ ಸಮಾನವಾಗಿರಿಸುವೆವು. ಪರಿಣಾಮವಾಗಿ, ಪ್ರತಿ ತರಬೇತಿ ಉದಾಹರಣೆ `nchars` ಇನ್‌ಪುಟ್‌ಗಳು ಮತ್ತು `nchars` ಔಟ್‌ಪುಟ್‌ಗಳಿಂದ (ಇನ್‌ಪುಟ್ ಸರಣಿಯನ್ನು ಎಡಕ್ಕೆ ಒಂದು ಚಿಹ್ನೆ ಸರಿಸಿದವು) ಕೂಡಿರುತ್ತದೆ. ಮಿನಿಬ್ಯಾಚ್ ಹಲವಾರು ಇಂತಹ ಸರಣಿಗಳಿಂದ ಕೂಡಿರುತ್ತದೆ.\n",
"\n",
"ನಾವು ಮಿನಿಬ್ಯಾಚ್‌ಗಳನ್ನು ರಚಿಸುವ ವಿಧಾನವೆಂದರೆ, ಪ್ರತಿ ಸುದ್ದಿ ಪಠ್ಯದ ಉದ್ದ `l` ಅನ್ನು ತೆಗೆದು, ಅದರಿಂದ ಸಾಧ್ಯವಾದ ಎಲ್ಲಾ ಇನ್‌ಪುಟ್-ಔಟ್‌ಪುಟ್ ಸಂಯೋಜನೆಗಳನ್ನು ರಚಿಸುವುದು (ಅವುಗಳ ಸಂಖ್ಯೆ `l-nchars` ಇರುತ್ತದೆ). ಅವು ಒಂದು ಮಿನಿಬ್ಯಾಚ್ ಆಗಿ ರೂಪುಗೊಳ್ಳುತ್ತವೆ, ಮತ್ತು ಪ್ರತಿ ತರಬೇತಿ ಹಂತದಲ್ಲಿ ಮಿನಿಬ್ಯಾಚ್ ಗಾತ್ರ ವಿಭಿನ್ನವಾಗಿರುತ್ತದೆ.\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": [
"ಈಗ ಜನರೇಟರ್ ನೆಟ್‌ವರ್ಕ್ ಅನ್ನು ವ್ಯಾಖ್ಯಾನಿಸೋಣ. ಇದು ನಾವು ಹಿಂದಿನ ಘಟಕದಲ್ಲಿ ಚರ್ಚಿಸಿದ ಯಾವುದೇ ಪುನರಾವರ್ತಿತ ಸೆಲ್ ಆಧಾರಿತವಾಗಿರಬಹುದು (ಸರಳ, LSTM ಅಥವಾ GRU). ನಮ್ಮ ಉದಾಹರಣೆಯಲ್ಲಿ ನಾವು LSTM ಅನ್ನು ಬಳಸುತ್ತೇವೆ.\n",
"\n",
"ನೆಟ್‌ವರ್ಕ್ ಅಕ್ಷರಗಳನ್ನು ಇನ್‌ಪುಟ್ ಆಗಿ ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ ಮತ್ತು ಶಬ್ದಕೋಶದ ಗಾತ್ರ ತುಂಬಾ ಸಣ್ಣದಾಗಿರುವುದರಿಂದ, ನಮಗೆ ಎम्बೆಡ್ಡಿಂಗ್ ಲೇಯರ್ ಅಗತ್ಯವಿಲ್ಲ, ಒನ್-ಹಾಟ್-ಎನ್‌ಕೋಡ್ ಮಾಡಿದ ಇನ್‌ಪುಟ್ ನೇರವಾಗಿ LSTM ಸೆಲ್‌ಗೆ ಹೋಗಬಹುದು. ಆದರೆ, ನಾವು ಅಕ್ಷರ ಸಂಖ್ಯೆಗಳನ್ನೇ ಇನ್‌ಪುಟ್ ಆಗಿ ನೀಡುತ್ತಿರುವುದರಿಂದ, ಅವುಗಳನ್ನು LSTM ಗೆ ನೀಡುವ ಮೊದಲು ಒನ್-ಹಾಟ್-ಎನ್‌ಕೋಡ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ. ಇದನ್ನು `forward` ಪಾಸ್ ಸಮಯದಲ್ಲಿ `one_hot` ಫಂಕ್ಷನ್ ಅನ್ನು ಕರೆಸುವ ಮೂಲಕ ಮಾಡಲಾಗುತ್ತದೆ. ಔಟ್‌ಪುಟ್ ಎನ್‌ಕೋಡರ್ ಒಂದು ಲೀನಿಯರ್ ಲೇಯರ್ ಆಗಿದ್ದು, ಅದು ಹಿಡನ್ ಸ್ಟೇಟ್ ಅನ್ನು ಒನ್-ಹಾಟ್-ಎನ್‌ಕೋಡ್ ಮಾಡಿದ ಔಟ್‌ಪುಟ್ ಗೆ ಪರಿವರ್ತಿಸುತ್ತದೆ.\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": [
"ತರಬೇತಿನ ಸಮಯದಲ್ಲಿ, ನಾವು ರಚಿಸಿದ ಪಠ್ಯವನ್ನು ಮಾದರಿಯಾಗಿಸಲು ಬಯಸುತ್ತೇವೆ. ಅದಕ್ಕಾಗಿ, ನಾವು `generate` ಎಂಬ ಫಂಕ್ಷನ್ ಅನ್ನು ವ್ಯಾಖ್ಯಾನಿಸುವೆವು, ಇದು ಪ್ರಾರಂಭಿಕ ಸ್ಟ್ರಿಂಗ್ `start` ನಿಂದ ಪ್ರಾರಂಭಿಸಿ `size` ಉದ್ದದ ಔಟ್‌ಪುಟ್ ಸ್ಟ್ರಿಂಗ್ ಅನ್ನು ಉತ್ಪಾದಿಸುತ್ತದೆ.\n",
"\n",
"ಇದನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವ ವಿಧಾನ ಹೀಗಿದೆ. ಮೊದಲು, ನಾವು ಸಂಪೂರ್ಣ ಪ್ರಾರಂಭಿಕ ಸ್ಟ್ರಿಂಗ್ ಅನ್ನು ನೆಟ್‌ವರ್ಕ್ ಮೂಲಕ ಹಾದುಹೋಗಿಸುತ್ತೇವೆ, ಮತ್ತು ಔಟ್‌ಪುಟ್ ಸ್ಥಿತಿ `s` ಮತ್ತು ಮುಂದಿನ ಭವಿಷ್ಯವಾಣಿ ಅಕ್ಷರ `out` ಅನ್ನು ಪಡೆಯುತ್ತೇವೆ. `out` ಒಂದು-ಹಾಟ್ ಎನ್‌ಕೋಡ್ ಆಗಿರುವುದರಿಂದ, ನಾವು `argmax` ತೆಗೆದು ಅಕ್ಷರ `nc` ಯ ಸೂಚ್ಯಂಕವನ್ನು ಶಬ್ದಕೋಶದಲ್ಲಿ ಪಡೆಯುತ್ತೇವೆ, ಮತ್ತು `itos` ಬಳಸಿ ನಿಜವಾದ ಅಕ್ಷರವನ್ನು ಕಂಡುಹಿಡಿದು ಅದನ್ನು ಫಲಿತಾಂಶ ಅಕ್ಷರಗಳ ಪಟ್ಟಿಗೆ `chars` ಸೇರಿಸುತ್ತೇವೆ. ಈ ಒಂದು ಅಕ್ಷರವನ್ನು ರಚಿಸುವ ಪ್ರಕ್ರಿಯೆಯನ್ನು `size` ಬಾರಿ ಪುನರಾವರ್ತಿಸಿ ಅಗತ್ಯವಾದ ಅಕ್ಷರಗಳ ಸಂಖ್ಯೆಯನ್ನು ರಚಿಸಲಾಗುತ್ತದೆ.\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": [
"ಇಗೋ ತರಬೇತಿ ಪ್ರಾರಂಭಿಸೋಣ! ತರಬೇತಿ ಲೂಪ್ ನಮ್ಮ ಹಿಂದಿನ ಎಲ್ಲಾ ಉದಾಹರಣೆಗಳಂತೆಯೇ ಇದೆ, ಆದರೆ ನಿಖರತೆಯ ಬದಲು ಪ್ರತೀ 1000 ಎಪೋಕ್‌ಗಳಿಗೊಮ್ಮೆ ಮಾದರಿಯಾಗಿ ರಚಿಸಲಾದ ಪಠ್ಯವನ್ನು ಮುದ್ರಿಸುತ್ತೇವೆ.\n",
"\n",
"ನಷ್ಟವನ್ನು ಲೆಕ್ಕಿಸುವ ವಿಧಾನಕ್ಕೆ ವಿಶೇಷ ಗಮನ ನೀಡಬೇಕು. ನಾವು ಒಂದು-ಹಾಟ್-ಎನ್‌ಕೋಡ್ ಮಾಡಿದ ಔಟ್‌ಪುಟ್ `out` ಮತ್ತು ನಿರೀಕ್ಷಿತ ಪಠ್ಯ `text_out` (ಅಕ್ಷರ ಸೂಚ್ಯಂಕಗಳ ಪಟ್ಟಿ) ನೀಡಿದಾಗ ನಷ್ಟವನ್ನು ಲೆಕ್ಕಿಸಬೇಕು. ಭಾಗ್ಯವಶಾತ್, `cross_entropy` ಫಂಕ್ಷನ್ ಅಸಮಾನ್ಯೀಕೃತ ನೆಟ್‌ವರ್ಕ್ ಔಟ್‌ಪುಟ್ ಅನ್ನು ಮೊದಲ ಆರ್ಗ್ಯುಮೆಂಟ್ ಆಗಿ ಮತ್ತು ವರ್ಗ ಸಂಖ್ಯೆಯನ್ನು ಎರಡನೇ ಆರ್ಗ್ಯುಮೆಂಟ್ ಆಗಿ ನಿರೀಕ್ಷಿಸುತ್ತದೆ, ಇದು ನಿಜವಾಗಿಯೂ ನಮಗಿರುವುದು. ಇದು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಮಿನಿಬ್ಯಾಚ್ ಗಾತ್ರದ ಸರಾಸರಿಯನ್ನು ಕೂಡ ಮಾಡುತ್ತದೆ.\n",
"\n",
"ನಾವು ತರಬೇತಿಯನ್ನು `samples_to_train` ಮಾದರಿಗಳಿಂದ ಮಿತಿಗೊಳಿಸುತ್ತೇವೆ, ಬಹಳ ಸಮಯ ಕಾಯದಿರಲು. ನೀವು ಪ್ರಯೋಗ ಮಾಡಿ, ಹೆಚ್ಚು ಎಪೋಕ್‌ಗಳ ಕಾಲ (ಆಗ ಈ ಕೋಡ್ ಸುತ್ತಲೂ ಮತ್ತೊಂದು ಲೂಪ್ ರಚಿಸುವ ಅಗತ್ಯವಿರುತ್ತದೆ) ತರಬೇತಿ ನಡೆಸಲು ಪ್ರೋತ್ಸಾಹಿಸುತ್ತೇವೆ.\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": [
"ಈ ಉದಾಹರಣೆ ಈಗಾಗಲೇ ಕೆಲವು ಚೆನ್ನಾದ ಪಠ್ಯವನ್ನು ರಚಿಸುತ್ತದೆ, ಆದರೆ ಇದನ್ನು ಹಲವಾರು ರೀತಿಗಳಲ್ಲಿ ಇನ್ನಷ್ಟು ಸುಧಾರಿಸಬಹುದು:\n",
"* **ಮೆಚ್ಚಿನ ಮಿನಿಬ್ಯಾಚ್ ತಯಾರಿಕೆ**. ತರಬೇತಿಗಾಗಿ ನಾವು ಡೇಟಾವನ್ನು ತಯಾರಿಸಿದ ವಿಧಾನವು ಒಂದು ಮಾದರಿಯಿಂದ ಒಂದು ಮಿನಿಬ್ಯಾಚ್ ರಚಿಸುವುದು. ಇದು ಆದರ್ಶವಲ್ಲ, ಏಕೆಂದರೆ ಮಿನಿಬ್ಯಾಚ್‌ಗಳು ವಿಭಿನ್ನ ಗಾತ್ರಗಳಾಗಿವೆ ಮತ್ತು ಕೆಲವು ರಚಿಸಲಾಗುವುದಿಲ್ಲ, ಏಕೆಂದರೆ ಪಠ್ಯವು `nchars` ಗಿಂತ ಚಿಕ್ಕದಾಗಿದೆ. ಜೊತೆಗೆ, ಸಣ್ಣ ಮಿನಿಬ್ಯಾಚ್‌ಗಳು GPU ಅನ್ನು ಸಾಕಷ್ಟು ಲೋಡ್ ಮಾಡುತ್ತವೆಯೆಂದು ಹೇಳಲು ಆಗುವುದಿಲ್ಲ. ಎಲ್ಲಾ ಮಾದರಿಗಳಿಂದ ಒಂದು ದೊಡ್ಡ ಪಠ್ಯದ ತುಂಡನ್ನು ಪಡೆದು, ಎಲ್ಲಾ ಇನ್‌ಪುಟ್-ಔಟ್‌ಪುಟ್ ಜೋಡಿಗಳನ್ನು ರಚಿಸಿ, ಅವುಗಳನ್ನು ಮಿಶ್ರಣ ಮಾಡಿ, ಸಮಾನ ಗಾತ್ರದ ಮಿನಿಬ್ಯಾಚ್‌ಗಳನ್ನು ರಚಿಸುವುದು ಜ್ಞಾನವಂತಿಕೆಯಾಗಿದೆ.\n",
"* **ಬಹುಮಟ್ಟದ LSTM**. 2 ಅಥವಾ 3 LSTM ಸೆಲ್‌ಗಳ ಮಟ್ಟಗಳನ್ನು ಪ್ರಯತ್ನಿಸುವುದು ಅರ್ಥಪೂರ್ಣ. ಹಿಂದಿನ ಘಟಕದಲ್ಲಿ ನಾವು ಉಲ್ಲೇಖಿಸಿದಂತೆ, ಪ್ರತಿಯೊಂದು LSTM ಮಟ್ಟವು ಪಠ್ಯದಿಂದ ನಿರ್ದಿಷ್ಟ ಮಾದರಿಗಳನ್ನು ಹೊರತೆಗೆಯುತ್ತದೆ, ಮತ್ತು ಅಕ್ಷರ ಮಟ್ಟದ ಜನರೇಟರ್‌ನ ಸಂದರ್ಭದಲ್ಲಿ ಕೆಳಗಿನ LSTM ಮಟ್ಟವು ಸಿಲಬಲ್ಗಳನ್ನು ಹೊರತೆಗೆಯಲು ಹೊಣೆಗಾರರಾಗಿರಬಹುದು, ಮತ್ತು ಮೇಲಿನ ಮಟ್ಟಗಳು ಪದಗಳು ಮತ್ತು ಪದ ಸಂಯೋಜನೆಗಳಿಗೆ. ಇದನ್ನು LSTM ನಿರ್ಮಾಪಕಕ್ಕೆ ಮಟ್ಟಗಳ ಸಂಖ್ಯೆಯ ಪರಿಮಾಣವನ್ನು ನೀಡುವ ಮೂಲಕ ಸುಲಭವಾಗಿ ಅನುಷ್ಠಾನಗೊಳಿಸಬಹುದು.\n",
"* ನೀವು **GRU ಘಟಕಗಳ**ೊಂದಿಗೆ ಪ್ರಯೋಗ ಮಾಡಬಹುದು ಮತ್ತು ಯಾವವು ಉತ್ತಮ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತವೆ ಎಂದು ನೋಡಬಹುದು, ಮತ್ತು **ವಿಭಿನ್ನ ಗುಪ್ತ ಮಟ್ಟದ ಗಾತ್ರಗಳ**ೊಂದಿಗೆ ಕೂಡ ಪ್ರಯತ್ನಿಸಬಹುದು. ತುಂಬಾ ದೊಡ್ಡ ಗುಪ್ತ ಮಟ್ಟವು ಅತಿವೈಯಕ್ತೀಕರಣಕ್ಕೆ ಕಾರಣವಾಗಬಹುದು (ಉದಾ. ನೆಟ್‌ವರ್ಕ್ ನಿಖರ ಪಠ್ಯವನ್ನು ಕಲಿಯಬಹುದು), ಮತ್ತು ಚಿಕ್ಕ ಗಾತ್ರವು ಉತ್ತಮ ಫಲಿತಾಂಶ ನೀಡದಿರಬಹುದು.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## ಸಾಫ್ಟ್ ಪಠ್ಯ ಉತ್ಪಾದನೆ ಮತ್ತು ತಾಪಮಾನ\n",
"\n",
"ಹಿಂದಿನ `generate` ವ್ಯಾಖ್ಯಾನದಲ್ಲಿ, ನಾವು ಯಾವಾಗಲೂ ಅತ್ಯಧಿಕ ಸಾಧ್ಯತೆಯಿರುವ ಅಕ್ಷರವನ್ನು ಮುಂದಿನ ಅಕ್ಷರವಾಗಿ ತೆಗೆದುಕೊಂಡಿದ್ದೇವೆ. ಇದರಿಂದ ಪಠ್ಯವು ಬಹುಶಃ ಒಂದೇ ಅಕ್ಷರ ಸರಣಿಗಳನ್ನು ಮರುಕಳಿಸುವಂತೆ ಆಗುತ್ತಿತ್ತು, ಈ ಉದಾಹರಣೆಯಂತೆ:\n",
"```\n",
"today of the second the company and a second the company ...\n",
"```\n",
"\n",
"ಆದರೆ, ಮುಂದಿನ ಅಕ್ಷರದ ಸಾಧ್ಯತೆ ವಿತರಣೆಯನ್ನು ನೋಡಿದರೆ, ಕೆಲವು ಅತ್ಯಧಿಕ ಸಾಧ್ಯತೆಗಳ ನಡುವಿನ ವ್ಯತ್ಯಾಸ ದೊಡ್ಡದಾಗಿರದಿರಬಹುದು, ಉದಾಹರಣೆಗೆ ಒಂದು ಅಕ್ಷರಕ್ಕೆ 0.2 ಸಾಧ್ಯತೆ ಇದ್ದರೆ, ಇನ್ನೊಂದು ಅಕ್ಷರಕ್ಕೆ 0.19 ಸಾಧ್ಯತೆ ಇರಬಹುದು. ಉದಾಹರಣೆಗೆ, '*play*' ಸರಣಿಯಲ್ಲಿ ಮುಂದಿನ ಅಕ್ಷರವನ್ನು ಹುಡುಕುವಾಗ, ಮುಂದಿನ ಅಕ್ಷರವಾಗಿ ಸ್ಪೇಸ್ ಅಥವಾ **e** (ಪದ *player* ನಲ್ಲಿ ಇದ್ದಂತೆ) ಎರಡೂ ಸಮಾನವಾಗಿ ಸಾಧ್ಯವಾಗಬಹುದು.\n",
"\n",
"ಇದರಿಂದ ನಾವು ತಿಳಿಯಬಹುದು, ಯಾವಾಗಲೂ ಹೆಚ್ಚಿನ ಸಾಧ್ಯತೆಯ ಅಕ್ಷರವನ್ನು ಆಯ್ಕೆ ಮಾಡುವುದು \"ನ್ಯಾಯಸಮ್ಮತ\" ಅಲ್ಲ, ಏಕೆಂದರೆ ಎರಡನೇ ಅತ್ಯಧಿಕ ಅಕ್ಷರವನ್ನು ಆಯ್ಕೆ ಮಾಡುವುದು ಸಹ ಅರ್ಥಪೂರ್ಣ ಪಠ್ಯಕ್ಕೆ ದಾರಿ ಮಾಡಿಕೊಡಬಹುದು. ಆದ್ದರಿಂದ, ನೆಟ್‌ವರ್ಕ್ ಔಟ್‌ಪುಟ್ ನೀಡುವ ಸಾಧ್ಯತೆ ವಿತರಣೆಯಿಂದ ಅಕ್ಷರಗಳನ್ನು **ನಮೂದಿಸುವುದು** (sample) ಹೆಚ್ಚು ಜ್ಞಾನವಂತಿಕೆಯಾಗಿದೆ.\n",
"\n",
"ಈ ನಮೂದಿಸುವಿಕೆಯನ್ನು `multinomial` ಫಂಕ್ಷನ್ ಬಳಸಿ ಮಾಡಬಹುದು, ಇದು **ಮಲ್ಟಿನೋಮಿಯಲ್ ವಿತರಣೆಯನ್ನು** ಅನುಷ್ಠಾನಗೊಳಿಸುತ್ತದೆ. ಕೆಳಗಿನ ಕೋಡ್‌ನಲ್ಲಿ ಈ **ಸಾಫ್ಟ್** ಪಠ್ಯ ಉತ್ಪಾದನೆ ಕಾರ್ಯಾಚರಣೆ ವ್ಯಾಖ್ಯಾನಿಸಲಾಗಿದೆ:\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": [
"ನಾವು ಇನ್ನೊಂದು ಪರಿಮಾಣವನ್ನು ಪರಿಚಯಿಸಿದ್ದೇವೆ ಅದನ್ನು **ತಾಪಮಾನ** ಎಂದು ಕರೆಯಲಾಗುತ್ತದೆ, ಇದು ನಾವು ಎಷ್ಟು ಕಠಿಣವಾಗಿ ಅತ್ಯಧಿಕ ಸಾಧ್ಯತೆಯನ್ನು ಅನುಸರಿಸಬೇಕು ಎಂಬುದನ್ನು ಸೂಚಿಸಲು ಬಳಸಲಾಗುತ್ತದೆ. ತಾಪಮಾನ 1.0 ಆಗಿದ್ದರೆ, ನಾವು ನ್ಯಾಯಸಮ್ಮತ ಮಲ್ಟಿನೋಮಿಯಲ್ ಸ್ಯಾಂಪ್ಲಿಂಗ್ ಮಾಡುತ್ತೇವೆ, ಮತ್ತು ತಾಪಮಾನ ಅನಂತಕ್ಕೆ ಹೋಗುವಾಗ - ಎಲ್ಲಾ ಸಾಧ್ಯತೆಗಳು ಸಮಾನವಾಗುತ್ತವೆ, ಮತ್ತು ನಾವು ಯಾದೃಚ್ಛಿಕವಾಗಿ ಮುಂದಿನ ಅಕ್ಷರವನ್ನು ಆಯ್ಕೆಮಾಡುತ್ತೇವೆ. ಕೆಳಗಿನ ಉದಾಹರಣೆಯಲ್ಲಿ ನಾವು ಗಮನಿಸಬಹುದು, ತಾಪಮಾನವನ್ನು ತುಂಬಾ ಹೆಚ್ಚಿಸಿದಾಗ ಪಠ್ಯ ಅರ್ಥವಿಲ್ಲದಂತೆ ಆಗುತ್ತದೆ, ಮತ್ತು ಅದು 0ಕ್ಕೆ ಹತ್ತಿರವಾಗುವಾಗ \"ಸೈಕ್ಲ್ಡ್\" ಕಠಿಣ-ಉತ್ಪಾದಿತ ಪಠ್ಯವನ್ನು ಹೋಲುತ್ತದೆ.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n\n<!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**ಅಸ್ವೀಕರಣ**: \nಈ ದಸ್ತಾವೇಜು AI ಅನುವಾದ ಸೇವೆ [Co-op Translator](https://github.com/Azure/co-op-translator) ಬಳಸಿ ಅನುವಾದಿಸಲಾಗಿದೆ. ನಾವು ನಿಖರತೆಯಿಗಾಗಿ ಪ್ರಯತ್ನಿಸುತ್ತಿದ್ದರೂ, ಸ್ವಯಂಚಾಲಿತ ಅನುವಾದಗಳಲ್ಲಿ ತಪ್ಪುಗಳು ಅಥವಾ ಅಸತ್ಯತೆಗಳು ಇರಬಹುದು ಎಂದು ದಯವಿಟ್ಟು ಗಮನಿಸಿ. ಮೂಲ ಭಾಷೆಯಲ್ಲಿರುವ ಮೂಲ ದಸ್ತಾವೇಜನ್ನು ಅಧಿಕೃತ ಮೂಲವೆಂದು ಪರಿಗಣಿಸಬೇಕು. ಪ್ರಮುಖ ಮಾಹಿತಿಗಾಗಿ, ವೃತ್ತಿಪರ ಮಾನವ ಅನುವಾದವನ್ನು ಶಿಫಾರಸು ಮಾಡಲಾಗುತ್ತದೆ. ಈ ಅನುವಾದ ಬಳಕೆಯಿಂದ ಉಂಟಾಗುವ ಯಾವುದೇ ತಪ್ಪು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವಿಕೆ ಅಥವಾ ತಪ್ಪು ವಿವರಣೆಗಳಿಗೆ ನಾವು ಹೊಣೆಗಾರರಾಗುವುದಿಲ್ಲ.\n<!-- CO-OP TRANSLATOR DISCLAIMER END -->\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-11-26T02:13:10+00:00",
"source_file": "lessons/5-NLP/17-GenerativeNetworks/GenerativePyTorch.ipynb",
"language_code": "kn"
}
},
"nbformat": 4,
"nbformat_minor": 4
}