414 lines
21 KiB
Plaintext
414 lines
21 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Generatiiviset verkot\n",
|
|
"\n",
|
|
"Toistuvat neuroverkot (Recurrent Neural Networks, RNN) ja niiden portilliset solumuunnelmat, kuten Long Short Term Memory Cells (LSTM) ja Gated Recurrent Units (GRU), tarjoavat mekanismin kielen mallintamiseen, eli ne voivat oppia sanojen järjestyksen ja ennustaa seuraavan sanan sekvenssissä. Tämä mahdollistaa RNN:ien käytön **generatiivisissa tehtävissä**, kuten tavallisessa tekstin generoinnissa, konekäännöksessä ja jopa kuvatekstien luomisessa.\n",
|
|
"\n",
|
|
"RNN-arkkitehtuurissa, jota käsittelimme edellisessä osiossa, jokainen RNN-yksikkö tuotti seuraavan piilotilan ulostulona. Voimme kuitenkin lisätä jokaiselle toistuvalle yksikölle toisen ulostulon, mikä mahdollistaa **sekvenssin** tuottamisen (joka on yhtä pitkä kuin alkuperäinen sekvenssi). Lisäksi voimme käyttää RNN-yksiköitä, jotka eivät ota syötettä jokaisessa vaiheessa, vaan ainoastaan jonkin alkuperäisen tilavektorin, ja tuottavat sitten ulostulosekvenssin.\n",
|
|
"\n",
|
|
"Tässä muistikirjassa keskitymme yksinkertaisiin generatiivisiin malleihin, jotka auttavat meitä tuottamaan tekstiä. Yksinkertaisuuden vuoksi rakennetaan **merkki-tason verkko**, joka generoi tekstiä kirjain kerrallaan. Koulutuksen aikana meidän täytyy ottaa jokin tekstikorpus ja jakaa se kirjainsekvensseihin.\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": [
|
|
"## Rakennetaan merkkisanasto\n",
|
|
"\n",
|
|
"Merkkitason generatiivisen verkon rakentamiseksi meidän täytyy jakaa teksti yksittäisiin merkkeihin sanojen sijaan. Tämä voidaan tehdä määrittelemällä erilainen tokenisaattori:\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": [
|
|
"Katsotaan esimerkki siitä, miten voimme koodata tekstin aineistostamme:\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": [
|
|
"## Generatiivisen RNN:n kouluttaminen\n",
|
|
"\n",
|
|
"Tapa, jolla koulutamme RNN:n tuottamaan tekstiä, on seuraava. Jokaisella askeleella otamme `nchars` merkin pituisen merkkijonon ja pyydämme verkkoa tuottamaan seuraavan ulostulomerkin jokaiselle syötemerkille:\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"Riippuen todellisesta tilanteesta, saatamme haluta sisällyttää myös joitakin erikoismerkkejä, kuten *sekvenssin loppu* `<eos>`. Meidän tapauksessamme haluamme vain kouluttaa verkon loputtomaan tekstin tuottamiseen, joten kiinnitämme jokaisen sekvenssin koon `nchars`-merkkien pituiseksi. Näin ollen jokainen koulutusesimerkki koostuu `nchars` syötteistä ja `nchars` ulostuloista (jotka ovat syötesekvenssi siirrettynä yhden symbolin verran vasemmalle). Minibatch koostuu useista tällaisista sekvensseistä.\n",
|
|
"\n",
|
|
"Tapa, jolla luomme minibatchit, on ottaa jokainen uutisteksti, jonka pituus on `l`, ja luoda siitä kaikki mahdolliset syöte-ulostulo-yhdistelmät (näitä yhdistelmiä on `l-nchars`). Ne muodostavat yhden minibatchin, ja minibatchien koko vaihtelee jokaisella koulutusaskeleella.\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": [
|
|
"Nyt määritellään generaattoriverkko. Se voi perustua mihin tahansa rekursiiviseen soluun, joita käsiteltiin edellisessä osiossa (yksinkertainen, LSTM tai GRU). Esimerkissämme käytämme LSTM:ää.\n",
|
|
"\n",
|
|
"Koska verkko ottaa syötteenä merkkejä ja sanaston koko on melko pieni, emme tarvitse upotuskerrosta; yksi-hot-koodattu syöte voi mennä suoraan LSTM-soluun. Kuitenkin, koska syötteenä annetaan merkkien numerot, ne täytyy yksi-hot-koodata ennen kuin ne välitetään LSTM:lle. Tämä tehdään kutsumalla `one_hot`-funktiota `forward`-kulkuprosessin aikana. Ulostulon kooderi olisi lineaarinen kerros, joka muuntaa piilotilan yksi-hot-koodatuksi ulostuloksi.\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": [
|
|
"Harjoittelun aikana haluamme pystyä näytteistämään generoituja tekstejä. Tätä varten määrittelemme `generate`-funktion, joka tuottaa merkkijonon, jonka pituus on `size`, alkaen alkuperäisestä merkkijonosta `start`.\n",
|
|
"\n",
|
|
"Näin se toimii. Ensin syötämme koko `start`-merkkijonon verkkoon ja otamme ulostulotilan `s` sekä seuraavan ennustetun merkin `out`. Koska `out` on one-hot-koodattu, käytämme `argmax`-funktiota saadaksemme merkin `nc` indeksin sanastossa, ja käytämme `itos`-funktiota selvittääksemme todellisen merkin, jonka lisäämme tuloksena olevaan merkkilistaan `chars`. Tämä yhden merkin generointiprosessi toistetaan `size` kertaa, jotta saadaan tarvittava määrä merkkejä.\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": [
|
|
"Aloitetaan harjoittelu! Harjoittelusilmukka on lähes sama kuin kaikissa aiemmissa esimerkeissämme, mutta tarkkuuden sijaan tulostamme satunnaisesti generoituja tekstejä joka 1000. epookin kohdalla.\n",
|
|
"\n",
|
|
"Erityistä huomiota on kiinnitettävä siihen, miten laskemme häviön. Meidän täytyy laskea häviö annetun one-hot-koodatun tulosteen `out` ja odotetun tekstin `text_out` perusteella, joka on merkkien indeksien lista. Onneksi `cross_entropy`-funktio odottaa ensimmäisenä argumenttina normalisoimatonta verkon tulostetta ja toisena argumenttina luokan numeroa, mikä on juuri se, mitä meillä on. Se myös suorittaa automaattisen keskiarvon laskemisen minibatchin koon perusteella.\n",
|
|
"\n",
|
|
"Rajoitamme harjoittelun myös `samples_to_train`-näytteisiin, jotta emme joudu odottamaan liian kauan. Kannustamme sinua kokeilemaan ja testaamaan pidempää harjoittelua, mahdollisesti useiden epookkien ajan (tässä tapauksessa sinun täytyisi luoda toinen silmukka tämän koodin ympärille).\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": [
|
|
"Tämä esimerkki tuottaa jo varsin hyvää tekstiä, mutta sitä voidaan parantaa useilla tavoilla:\n",
|
|
"\n",
|
|
"* **Parempi minibatchien luonti**. Tapa, jolla valmistelimme dataa koulutusta varten, oli luoda yksi minibatch yhdestä näytteestä. Tämä ei ole ihanteellista, koska minibatchit ovat kaikki erikokoisia, ja joitakin niistä ei voida edes luoda, koska teksti on pienempi kuin `nchars`. Lisäksi pienet minibatchit eivät kuormita GPU:ta riittävästi. Olisi viisaampaa ottaa yksi suuri tekstikappale kaikista näytteistä, luoda sitten kaikki syöte-tulos-parit, sekoittaa ne ja luoda samankokoisia minibatcheja.\n",
|
|
"\n",
|
|
"* **Monikerroksinen LSTM**. On järkevää kokeilla 2 tai 3 kerrosta LSTM-soluja. Kuten mainitsimme edellisessä osiossa, jokainen LSTM-kerros poimii tiettyjä kuvioita tekstistä, ja merkkitason generaattorin tapauksessa voimme odottaa alemman LSTM-tason vastaavan tavujen poimimisesta ja ylempien tasojen - sanoista ja sanayhdistelmistä. Tämä voidaan toteuttaa yksinkertaisesti antamalla kerrosten lukumäärä -parametri LSTM-rakentajalle.\n",
|
|
"\n",
|
|
"* Voit myös haluta kokeilla **GRU-yksiköitä** ja nähdä, mitkä toimivat paremmin, sekä **erilaisia piilokerroksen kokoja**. Liian suuri piilokerros voi johtaa ylisovittamiseen (esim. verkko oppii tarkan tekstin), ja pienempi koko ei välttämättä tuota hyvää tulosta.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Pehmeä tekstin generointi ja lämpötila\n",
|
|
"\n",
|
|
"Aiemmassa `generate`-määritelmässä valitsimme aina seuraavaksi merkiksi sen, jolla oli korkein todennäköisyys. Tämä johti usein siihen, että teksti \"kiersi\" samoja merkkijonoja uudelleen ja uudelleen, kuten tässä esimerkissä:\n",
|
|
"```\n",
|
|
"today of the second the company and a second the company ...\n",
|
|
"```\n",
|
|
"\n",
|
|
"Jos kuitenkin tarkastelemme seuraavan merkin todennäköisyysjakaumaa, voi olla, että muutaman korkeimman todennäköisyyden ero ei ole suuri, esimerkiksi yksi merkki voi olla todennäköisyydellä 0.2 ja toinen 0.19, jne. Esimerkiksi, kun etsitään seuraavaa merkkiä jaksossa '*play*', seuraava merkki voi yhtä hyvin olla joko välilyönti tai **e** (kuten sanassa *player*).\n",
|
|
"\n",
|
|
"Tämä johtaa siihen päätelmään, että ei ole aina \"reilua\" valita merkkiä, jolla on korkein todennäköisyys, koska toisen korkein todennäköisyys voi silti johtaa merkitykselliseen tekstiin. Viisaampaa on **näytteistää** merkkejä verkon tuottaman todennäköisyysjakauman perusteella.\n",
|
|
"\n",
|
|
"Tämä näytteistäminen voidaan tehdä `multinomial`-funktiolla, joka toteuttaa niin kutsutun **multinomiaalisen jakauman**. Alla on määritelty funktio, joka toteuttaa tämän **pehmeän** tekstin generoinnin:\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": [
|
|
"Olemme ottaneet käyttöön yhden lisäparametrin nimeltä **lämpötila**, jota käytetään osoittamaan, kuinka tiukasti meidän tulisi pitäytyä korkeimmassa todennäköisyydessä. Jos lämpötila on 1.0, teemme reilua multinomiaalisia otantoja, ja kun lämpötila kasvaa äärettömyyteen - kaikki todennäköisyydet muuttuvat yhtä suuriksi, ja valitsemme seuraavan merkin satunnaisesti. Alla olevassa esimerkissä voimme havaita, että teksti muuttuu merkityksettömäksi, kun nostamme lämpötilaa liikaa, ja se muistuttaa \"kierrätettyä\" tiukasti generoituvaa tekstiä, kun lämpötila lähestyy arvoa 0.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n---\n\n**Vastuuvapauslauseke**: \nTämä asiakirja on käännetty käyttämällä tekoälypohjaista käännöspalvelua [Co-op Translator](https://github.com/Azure/co-op-translator). Vaikka pyrimme tarkkuuteen, huomioithan, että automaattiset käännökset voivat sisältää virheitä tai epätarkkuuksia. Alkuperäistä asiakirjaa sen alkuperäisellä kielellä tulisi pitää ensisijaisena lähteenä. Kriittisen tiedon osalta suositellaan ammattimaista ihmiskäännöstä. Emme ole vastuussa väärinkäsityksistä tai virhetulkinnoista, jotka johtuvat tämän käännöksen käytöstä.\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-28T21:33:29+00:00",
|
|
"source_file": "lessons/5-NLP/17-GenerativeNetworks/GenerativePyTorch.ipynb",
|
|
"language_code": "fi"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
} |