Skip to content

Instantly share code, notes, and snippets.

@nymwa
Created December 3, 2020 04:07
Show Gist options
  • Select an option

  • Save nymwa/c65c9847f8294b55013fe9d189e89d30 to your computer and use it in GitHub Desktop.

Select an option

Save nymwa/c65c9847f8294b55013fe9d189e89d30 to your computer and use it in GitHub Desktop.
soweli_RDAE.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "soweli_RDAE.ipynb",
"provenance": [],
"authorship_tag": "ABX9TyO5ANXKxHz/LiHm+j66M88i",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/nymwa/c65c9847f8294b55013fe9d189e89d30/soweli_rdae.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "-68Ck3l3qlL9"
},
"source": [
"Download dataset"
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "iYAQhAF7qoTJ",
"outputId": "6b71b494-17e8-440d-a753-12c31fa077fc"
},
"source": [
"! wget https://downloads.tatoeba.org/exports/per_language/toki/toki_sentences.tsv.bz2\n",
"! bunzip2 toki_sentences.tsv.bz2\n",
"! cut -f 3 toki_sentences.tsv | perl -MList::Util -e 'srand 0; print List::Util::shuffle <>' > cut.txt"
],
"execution_count": 1,
"outputs": [
{
"output_type": "stream",
"text": [
"--2020-12-03 03:52:02-- https://downloads.tatoeba.org/exports/per_language/toki/toki_sentences.tsv.bz2\n",
"Resolving downloads.tatoeba.org (downloads.tatoeba.org)... 94.130.77.194\n",
"Connecting to downloads.tatoeba.org (downloads.tatoeba.org)|94.130.77.194|:443... connected.\n",
"HTTP request sent, awaiting response... 200 OK\n",
"Length: 408307 (399K) [application/octet-stream]\n",
"Saving to: ‘toki_sentences.tsv.bz2’\n",
"\n",
"toki_sentences.tsv. 100%[===================>] 398.74K 1.43MB/s in 0.3s \n",
"\n",
"2020-12-03 03:52:03 (1.43 MB/s) - ‘toki_sentences.tsv.bz2’ saved [408307/408307]\n",
"\n",
"bunzip2: Output file toki_sentences.tsv already exists.\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "q0j7JrPatG_e"
},
"source": [
"Install library to use"
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "G8T7m_EhtGgH",
"outputId": "3fd82df1-2a8b-4f88-ce37-f26c7869549b"
},
"source": [
"! pip install livelossplot"
],
"execution_count": 2,
"outputs": [
{
"output_type": "stream",
"text": [
"Requirement already satisfied: livelossplot in /usr/local/lib/python3.6/dist-packages (0.5.3)\n",
"Requirement already satisfied: matplotlib; python_version >= \"3.6\" in /usr/local/lib/python3.6/dist-packages (from livelossplot) (3.2.2)\n",
"Requirement already satisfied: ipython in /usr/local/lib/python3.6/dist-packages (from livelossplot) (5.5.0)\n",
"Requirement already satisfied: bokeh; python_version >= \"3.6\" in /usr/local/lib/python3.6/dist-packages (from livelossplot) (2.1.1)\n",
"Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib; python_version >= \"3.6\"->livelossplot) (2.4.7)\n",
"Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib; python_version >= \"3.6\"->livelossplot) (2.8.1)\n",
"Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.6/dist-packages (from matplotlib; python_version >= \"3.6\"->livelossplot) (0.10.0)\n",
"Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib; python_version >= \"3.6\"->livelossplot) (1.3.1)\n",
"Requirement already satisfied: numpy>=1.11 in /usr/local/lib/python3.6/dist-packages (from matplotlib; python_version >= \"3.6\"->livelossplot) (1.18.5)\n",
"Requirement already satisfied: decorator in /usr/local/lib/python3.6/dist-packages (from ipython->livelossplot) (4.4.2)\n",
"Requirement already satisfied: traitlets>=4.2 in /usr/local/lib/python3.6/dist-packages (from ipython->livelossplot) (4.3.3)\n",
"Requirement already satisfied: prompt-toolkit<2.0.0,>=1.0.4 in /usr/local/lib/python3.6/dist-packages (from ipython->livelossplot) (1.0.18)\n",
"Requirement already satisfied: setuptools>=18.5 in /usr/local/lib/python3.6/dist-packages (from ipython->livelossplot) (50.3.2)\n",
"Requirement already satisfied: pexpect; sys_platform != \"win32\" in /usr/local/lib/python3.6/dist-packages (from ipython->livelossplot) (4.8.0)\n",
"Requirement already satisfied: simplegeneric>0.8 in /usr/local/lib/python3.6/dist-packages (from ipython->livelossplot) (0.8.1)\n",
"Requirement already satisfied: pickleshare in /usr/local/lib/python3.6/dist-packages (from ipython->livelossplot) (0.7.5)\n",
"Requirement already satisfied: pygments in /usr/local/lib/python3.6/dist-packages (from ipython->livelossplot) (2.6.1)\n",
"Requirement already satisfied: typing-extensions>=3.7.4 in /usr/local/lib/python3.6/dist-packages (from bokeh; python_version >= \"3.6\"->livelossplot) (3.7.4.3)\n",
"Requirement already satisfied: packaging>=16.8 in /usr/local/lib/python3.6/dist-packages (from bokeh; python_version >= \"3.6\"->livelossplot) (20.4)\n",
"Requirement already satisfied: PyYAML>=3.10 in /usr/local/lib/python3.6/dist-packages (from bokeh; python_version >= \"3.6\"->livelossplot) (3.13)\n",
"Requirement already satisfied: Jinja2>=2.7 in /usr/local/lib/python3.6/dist-packages (from bokeh; python_version >= \"3.6\"->livelossplot) (2.11.2)\n",
"Requirement already satisfied: tornado>=5.1 in /usr/local/lib/python3.6/dist-packages (from bokeh; python_version >= \"3.6\"->livelossplot) (5.1.1)\n",
"Requirement already satisfied: pillow>=4.0 in /usr/local/lib/python3.6/dist-packages (from bokeh; python_version >= \"3.6\"->livelossplot) (7.0.0)\n",
"Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.6/dist-packages (from python-dateutil>=2.1->matplotlib; python_version >= \"3.6\"->livelossplot) (1.15.0)\n",
"Requirement already satisfied: ipython-genutils in /usr/local/lib/python3.6/dist-packages (from traitlets>=4.2->ipython->livelossplot) (0.2.0)\n",
"Requirement already satisfied: wcwidth in /usr/local/lib/python3.6/dist-packages (from prompt-toolkit<2.0.0,>=1.0.4->ipython->livelossplot) (0.2.5)\n",
"Requirement already satisfied: ptyprocess>=0.5 in /usr/local/lib/python3.6/dist-packages (from pexpect; sys_platform != \"win32\"->ipython->livelossplot) (0.6.0)\n",
"Requirement already satisfied: MarkupSafe>=0.23 in /usr/local/lib/python3.6/dist-packages (from Jinja2>=2.7->bokeh; python_version >= \"3.6\"->livelossplot) (1.1.1)\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "KuhV-KjTqlOc"
},
"source": [
"Building vocabulary and tokenizer"
]
},
{
"cell_type": "code",
"metadata": {
"id": "aW8Jak9Gq2lZ"
},
"source": [
"class Vocabulary(list):\n",
" def __init__(self, word_list, comma_split_special_tokens = None):\n",
"\n",
" if comma_split_special_tokens is None:\n",
" comma_split_special_tokens = 'pad:bos:sep:eos:unk:num:prp'\n",
"\n",
" special_tokens = []\n",
" for token_id, token in enumerate(comma_split_special_tokens.split(':')):\n",
" special_tokens.append(f'<{token}>')\n",
" setattr(self, token, f'<{token}>')\n",
" setattr(self, f'{token}_id', token_id)\n",
"\n",
" super().__init__(special_tokens + word_list)\n",
" self.dictionary = {word : index for index, word in enumerate(self) if word not in special_tokens}"
],
"execution_count": 3,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "3oPshUltrLoB"
},
"source": [
"class TokiPonaVocabulary(Vocabulary):\n",
" def __init__(self, comma_split_special_tokens = None):\n",
" all_words = 'a akesi ala alasa ali anpa ante anu awen e en esun ijo ike ilo insa jaki jan jelo jo kala kalama kama kasi ken kepeken kili kin kiwen ko kon kule kulupu kute la lape laso lawa len lete li lili linja lipu loje lon luka lukin lupa ma mama mani meli mi mije moku moli monsi mu mun musi mute namako nanpa nasa nasin nena ni nimi noka o oko olin ona open pakala pali palisa pan pana pi pilin pimeja pini pipi poka pona pu sama seli selo seme sewi sijelo sike sin sina sinpin sitelen sona soweli suli suno supa suwi tan taso tawa telo tenpo toki tomo tu unpa uta utala walo wan waso wawa weka wile'\n",
" super().__init__(all_words.split())\n",
" self.dictionary['ale'] = self.dictionary['ali']"
],
"execution_count": 4,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "wWv5Z4YtrroZ"
},
"source": [
"import re\n",
"\n",
"class IloTunimi:\n",
" def __init__(self):\n",
" self.vocab = TokiPonaVocabulary()\n",
"\n",
" def convert(self, x):\n",
" if x in {'║', '.', '!', '?', ':'}:\n",
" return self.vocab.sep_id\n",
"\n",
" x = re.sub('[^0-9A-Za-z]', '', x)\n",
" if x in self.vocab.dictionary:\n",
" return self.vocab.dictionary[x]\n",
" elif x.isdecimal():\n",
" return self.vocab.num_id\n",
" elif re.match(r'^([AIUEO]|[KSNPML][aiueo]|[TJ][aueo]|W[aie])n?(([ksnpml][aiueo]|[tj][aueo]|w[aie])n?)*$', x):\n",
" return self.vocab.prp_id\n",
" else:\n",
" return self.vocab.unk_id\n",
"\n",
" def __call__(self, xs):\n",
" xs = xs.strip()\n",
" xs = re.sub(r'([.!?:])', ' \\\\1 ', xs)\n",
" xs = xs.split()\n",
" ys = [self.convert(x) for x in xs]\n",
" return ys"
],
"execution_count": 5,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "bxAsHqM2qlQx"
},
"source": [
"Preprocess the dataset"
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "PKV4phI4rYwb",
"outputId": "58609cf7-d2e8-4a9a-84b0-c8a598deede7"
},
"source": [
"from tqdm import tqdm\n",
"\n",
"tokenizer = IloTunimi()\n",
"\n",
"data = []\n",
"with open('cut.txt') as f:\n",
" for x in tqdm(f):\n",
" x = tokenizer(x)\n",
" if x not in data:\n",
" data.append(x)"
],
"execution_count": 6,
"outputs": [
{
"output_type": "stream",
"text": [
"42235it [00:13, 3228.37it/s]\n"
],
"name": "stderr"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "HvkkpPCDqlTI"
},
"source": [
"Build classes for dataset"
]
},
{
"cell_type": "code",
"metadata": {
"id": "XLB3TbGPsEPs"
},
"source": [
"import random as rd\n",
"import numpy as np\n",
"from collections import deque\n",
"\n",
"class Sampler:\n",
" def __init__(self, buffer_size = None):\n",
" self.queue = deque()\n",
" if buffer_size is not None:\n",
" self.buffer_size = buffer_size\n",
" else:\n",
" self.buffer_size = 10000\n",
"\n",
" def __call__(self):\n",
" if not self.queue:\n",
" self.queue.extend(self.sampler())\n",
" return self.queue.pop()\n",
"\n",
"class GeometricSampler(Sampler):\n",
" def __init__(self, p, buffer_size = None):\n",
" super().__init__(buffer_size = buffer_size)\n",
" self.p = p\n",
"\n",
" def sampler(self):\n",
" return np.random.geometric(self.p, self.buffer_size)\n",
"\n",
"class ChoiceSampler(Sampler):\n",
" def __init__(self, cands, p = None, buffer_size = None):\n",
" super().__init__(buffer_size = buffer_size)\n",
" self.cands = cands\n",
" self.p = p\n",
"\n",
" def sampler(self):\n",
" return np.random.choice(self.cands, size = self.buffer_size, p = self.p)\n",
"\n",
"class BoolSampler(Sampler):\n",
" def __init__(self, p, buffer_size = None):\n",
" super().__init__(buffer_size = buffer_size)\n",
" self.p = p\n",
"\n",
" def sampler(self):\n",
" return np.random.rand(self.buffer_size) < self.p"
],
"execution_count": 7,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "KLO8OxaQsERu"
},
"source": [
"class SentenceNoiser:\n",
" def __init__(self, vocab_size, mask_id, p, r):\n",
" self.vocab_size = vocab_size\n",
" self.mask_id = mask_id\n",
" self.num_edit_sampler = GeometricSampler(p)\n",
" self.mask_ratio_sampler = BoolSampler(r)\n",
"\n",
" def sample_word(self):\n",
" if self.mask_ratio_sampler():\n",
" word = self.mask_id\n",
" else:\n",
" word = rd.randrange(self.vocab_size)\n",
" return word\n",
"\n",
" def delete(self, sent):\n",
" if len(sent) <= 1:\n",
" return sent\n",
" pos = rd.randrange(len(sent))\n",
" return sent[:pos] + sent[pos+1:]\n",
"\n",
" def swap(self, sent):\n",
" if len(sent) <= 1:\n",
" return sent\n",
" pos = rd.randrange(len(sent) - 1)\n",
" return sent[:pos] + [sent[pos], sent[pos+1]] + sent[pos+2:]\n",
"\n",
" def insert(self, sent):\n",
" pos = rd.randrange(len(sent) + 1)\n",
" return sent[:pos] + [self.sample_word()] + sent[pos:]\n",
"\n",
" def replace(self, sent):\n",
" if len(sent) <= 0:\n",
" return sent\n",
" pos = rd.randrange(len(sent))\n",
" return sent[:pos] + [self.sample_word()] + sent[pos+1:]\n",
"\n",
" def __call__(self, sent):\n",
" for _ in range(self.num_edit_sampler()):\n",
" noise_fn = self.operation_sampler()\n",
" sent = noise_fn(sent)\n",
" return sent\n",
"\n",
"class EncoderSentenceNoiser(SentenceNoiser):\n",
" def __init__(self, vocab_size, mask_id, p, r):\n",
" super().__init__(vocab_size, mask_id, p, r)\n",
" self.operation_sampler = ChoiceSampler(\n",
" [self.delete, self.swap, self.insert, self.replace],\n",
" p=[0.33, 0.01, 0.33, 0.33])\n",
"\n",
"class DecoderSentenceNoiser(SentenceNoiser):\n",
" def __init__(self, vocab_size, mask_id, p, r):\n",
" super().__init__(vocab_size, mask_id, p, r)\n",
" self.operation_sampler = ChoiceSampler([self.swap, self.replace], p=[0.05, 0.95])"
],
"execution_count": 8,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "0G5ff6xvsET8"
},
"source": [
"import contextlib\n",
"from livelossplot import PlotLosses\n",
"import torch\n",
"import torch.nn as nn\n",
"import torch.optim as optim\n",
"from torch.utils.data import Dataset, DataLoader\n",
"from torch.nn.utils.rnn import pad_sequence as pad\n",
"from torch.nn.utils.rnn import pack_padded_sequence as pack\n",
"from torch.nn.utils.rnn import pad_packed_sequence as unpack"
],
"execution_count": 18,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "kP0DriivsB1B"
},
"source": [
"class DAEBatch:\n",
" def __init__(self, ei, di, do, el, dl):\n",
" self.encoder_inputs = ei\n",
" self.decoder_inputs = di\n",
" self.decoder_outputs = do\n",
" self.encoder_lengths = el\n",
" self.decoder_lengths = dl\n",
"\n",
" def __len__(self):\n",
" return len(self.encoder_lengths)\n",
"\n",
" def cuda(self):\n",
" self.encoder_inputs = self.encoder_inputs.cuda()\n",
" self.decoder_inputs = self.decoder_inputs.cuda()\n",
" self.decoder_outputs = self.decoder_outputs.cuda()\n",
" return self"
],
"execution_count": 10,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "NfJvutB0s3W1"
},
"source": [
"class DAEDataset(Dataset):\n",
" def __init__(self, sents, vocab):\n",
" self.sents = sents\n",
" self.vocab = vocab\n",
" self.pad = self.vocab.pad_id\n",
" self.bos = self.vocab.bos_id\n",
" self.eos = self.vocab.eos_id\n",
"\n",
" def __len__(self):\n",
" return len(self.sents)\n",
"\n",
" def __getitem__(self, index):\n",
" return self.sents[index]\n",
"\n",
" def collate(self, batch):\n",
" ei = [torch.tensor(sent) for sent in batch]\n",
" di = [torch.tensor([self.bos] + sent) for sent in batch]\n",
" do = [torch.tensor(sent + [self.eos]) for sent in batch]\n",
" el = torch.tensor([len(sent) for sent in batch])\n",
" dl = torch.tensor([len(sent) + 1 for sent in batch])\n",
" return DAEBatch(\n",
" pad(ei, padding_value = self.pad),\n",
" pad(di, padding_value = self.pad),\n",
" pad(do, padding_value = self.pad),\n",
" el, dl)\n",
"\n",
"class NoisingDAEDataset(DAEDataset):\n",
" def __init__(self, sents, vocab, ep, er, dp, dr):\n",
" super().__init__(sents, vocab)\n",
" self.encoder_noiser = EncoderSentenceNoiser(len(vocab), vocab.pad_id, ep, er)\n",
" self.decoder_noiser = DecoderSentenceNoiser(len(vocab), vocab.pad_id, dp, dr)\n",
"\n",
" def collate(self, batch):\n",
" ei = [self.encoder_noiser(sent) for sent in batch]\n",
" di = [[self.bos] + self.decoder_noiser(sent) for sent in batch]\n",
" do = [sent + [self.eos] for sent in batch]\n",
" el = torch.tensor([len(sent) for sent in ei])\n",
" dL = torch.tensor([len(sent) for sent in di])\n",
" dl = torch.tensor([len(sent) for sent in do])\n",
" ei = [torch.tensor(sent) for sent in ei]\n",
" di = [torch.tensor(sent) for sent in di]\n",
" do = [torch.tensor(sent) for sent in do]\n",
" return DAEBatch(\n",
" pad(ei, padding_value = self.pad),\n",
" pad(di, padding_value = self.pad),\n",
" pad(do, padding_value = self.pad),\n",
" el, dl)"
],
"execution_count": 11,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "2-wmRircqlVd"
},
"source": [
"Build class for model"
]
},
{
"cell_type": "code",
"metadata": {
"id": "vYMop1ErtBCJ"
},
"source": [
"class RDAEEncoder(nn.Module):\n",
" def __init__(self, d_vocab, d_embed, d_hidden, num_layers):\n",
" super().__init__()\n",
" self.embeddings = nn.Embedding(d_vocab, d_embed)\n",
" self.rnn = nn.GRU(d_embed, d_hidden, bidirectional=True, num_layers = num_layers)\n",
"\n",
" def forward(self, batch):\n",
" x = self.embeddings(batch.encoder_inputs)\n",
" packed = pack(x, batch.encoder_lengths, enforce_sorted=False)\n",
" _, h = self.rnn(packed)\n",
" return h\n",
"\n",
"class RDAEDecoder(nn.Module):\n",
" def __init__(self, d_vocab, d_embed, d_hidden, dropout):\n",
" super().__init__()\n",
" self.embeddings = nn.Embedding(d_vocab, d_embed)\n",
" self.rnn = nn.GRU(d_embed, d_hidden)\n",
" self.dropout = nn.Dropout(p=dropout)\n",
" self.proj = nn.Linear(d_hidden, d_vocab)\n",
"\n",
" def forward(self, batch, hidden):\n",
" x = self.embeddings(batch.decoder_inputs)\n",
" packed = pack(x, batch.decoder_lengths, enforce_sorted=False)\n",
" x, _ = self.rnn(packed, hidden)\n",
" x, _ = unpack(x)\n",
" x = self.dropout(x)\n",
" x = self.proj(x)\n",
" return x\n",
"\n",
"class RDAE(nn.Module):\n",
" def __init__(self, d_vocab, d_embed, d_hidden, num_layers, dropout=0.2):\n",
" super().__init__()\n",
" self.encoder = RDAEEncoder(d_vocab, d_embed, d_hidden, num_layers)\n",
" self.decoder = RDAEDecoder(d_vocab, d_embed, d_hidden, dropout)\n",
" self.proj = nn.Linear(d_hidden * num_layers * 2, d_hidden)\n",
"\n",
" def encode(self, batch):\n",
" h = self.encoder(batch)\n",
" h = h.transpose(0, 1).flatten(1).unsqueeze(0)\n",
" h = self.proj(h)\n",
" return h\n",
"\n",
" def forward(self, batch):\n",
" h = self.encode(batch)\n",
" x = self.decoder(batch, h)\n",
" return x"
],
"execution_count": 12,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "aecqASLwqlXn"
},
"source": [
"Train the model"
]
},
{
"cell_type": "code",
"metadata": {
"id": "a2VLjV2DtDxB"
},
"source": [
"class WarmupScheduler(optim.lr_scheduler.LambdaLR):\n",
" def __init__(self, optimizer, warmup_steps, last_epoch=-1):\n",
" def lr_lambda(step):\n",
" r = max(1e-8, step / warmup_steps)\n",
" return min(r, r ** -0.5)\n",
" super().__init__(optimizer, lr_lambda, last_epoch=last_epoch)"
],
"execution_count": 13,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "sjOZI4IatQ5o"
},
"source": [
"def calculate_loss(model, batch, criterion, requires_grad=True):\n",
" batch.cuda()\n",
" context = contextlib.suppress if requires_grad else torch.no_grad\n",
" with context():\n",
" pred = model(batch)\n",
" pred = pred.view(-1, pred.size(-1))\n",
" loss = criterion(pred, batch.decoder_outputs.view(-1))\n",
" return loss"
],
"execution_count": 14,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "ljXrDhhXtQ8A",
"outputId": "e42a72b8-f103-4be7-cf78-0bde8dd9c65b"
},
"source": [
"valid_size = 1000\n",
"train_data = data[:-valid_size]\n",
"valid_data = data[-valid_size:]\n",
"encoder_noiser_p = 0.9\n",
"encoder_noiser_r = 0.9\n",
"decoder_noiser_p = 0.7\n",
"decoder_noiser_r = 0.7\n",
"train_dataset = NoisingDAEDataset(train_data, tokenizer.vocab,\n",
" encoder_noiser_p, encoder_noiser_r, \n",
" decoder_noiser_p, decoder_noiser_r)\n",
"valid_dataset = DAEDataset(valid_data, tokenizer.vocab)\n",
"\n",
"batch_size = 256\n",
"train_loader = DataLoader(train_dataset, batch_size, shuffle=True, collate_fn=train_dataset.collate)\n",
"valid_loader = DataLoader(valid_dataset, batch_size, shuffle=False, collate_fn=valid_dataset.collate)\n",
"\n",
"embed_size = 32\n",
"hidden_size = 128\n",
"num_layers = 1\n",
"dropout = 0.2\n",
"model = RDAE(len(tokenizer.vocab), embed_size, hidden_size, num_layers, dropout)\n",
"model = model.cuda()\n",
"\n",
"lr = 0.002\n",
"warmup_steps = 2000\n",
"criterion = nn.CrossEntropyLoss(ignore_index=tokenizer.vocab.pad_id)\n",
"optimizer = optim.AdamW(model.parameters(), lr=lr)\n",
"scheduler = WarmupScheduler(optimizer, warmup_steps)\n",
"print('#params: {}'.format(sum(p.numel() for p in model.parameters() if p.requires_grad)))"
],
"execution_count": 15,
"outputs": [
{
"output_type": "stream",
"text": [
"#params: 244417\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000
},
"id": "PHEKDLNCtQ-k",
"outputId": "fa2ea189-4eef-4945-841b-308e4ac1bb3e"
},
"source": [
"liveloss = PlotLosses()\n",
"\n",
"clip_norm = 0.1\n",
"num_steps = 0\n",
"for epoch in range(50):\n",
" model.train()\n",
" train_accum = 0.0\n",
" train_example = 0\n",
" for batch in train_loader:\n",
" loss = calculate_loss(model, batch, criterion, requires_grad=True)\n",
" train_accum += loss.item() * len(batch)\n",
" train_example += len(batch)\n",
" optimizer.zero_grad()\n",
" loss.backward()\n",
" nn.utils.clip_grad_norm_(model.parameters(), clip_norm)\n",
" optimizer.step()\n",
" scheduler.step()\n",
" num_steps += 1\n",
"\n",
" model.eval()\n",
" valid_accum = 0.0\n",
" valid_example = 0\n",
" for batch in valid_loader:\n",
" loss = calculate_loss(model, batch, criterion, requires_grad=False)\n",
" valid_accum += loss.item() * len(batch)\n",
" valid_example += len(batch)\n",
"\n",
" train_loss = train_accum / train_example\n",
" valid_loss = valid_accum / valid_example\n",
" lr = scheduler.get_last_lr()[0]\n",
" liveloss.update({\n",
" 'train_log_loss': train_loss,\n",
" 'valid_log_loss': valid_loss,\n",
" 'lr': lr,\n",
" 'steps': num_steps,\n",
" })\n",
" liveloss.draw()"
],
"execution_count": 20,
"outputs": [
{
"output_type": "display_data",
"data": {
"image/png": "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d7Jz2549e9zAgQMP/284dC5q7vzUnFM5F3EFK0LOHZCtugan+etKfEcBEHDjxo07ajPDe++9VyNGjNCECRO0ZcuWZq/05Ofna+TIkZKkMWPGaOPGjSf9O59++qny8/M1cOBASdJ1112nd999V6tWrVK/fv0OZ7jyyitbnX3+/Pm66qqrJEnXXnut3nvvPUnSpEmTdP311+uhhx5SfX29JGnixIn6z//8T919993atGmTkpKSWv132oNzbodzblHT83JJKyXlHHPYDEmPN51bF0hKN7NOtZbu/MHdtLu8hvuGgSgyatQo7d69W9u3b9eSJUvUtWtX9ejRQ//2b/+m4cOH64ILLtC2bdu0a9euFj/j3Xff1TXXXCNJGj58uIYPH96qv/3ee+/p0ksvVTgcVkpKir70pS9p3rx5ev/99zVjxgwlJiaqS5cuuuSSS1r1eS2d29LS0pSYmKgbbrhBL7zwgpKTkyU1f346UxSsCBmT11VJoVjNYzoTgJMIh8OHn7/99tv661//qvnz52vJkiUaNWpUs5sdJiQkHH4eGxururq6iGRtrQceeEA//vGPtWXLFo0ZM0YlJSW66qqr9PLLLyspKUkXXnih3nzzTd8xDzOzPEmjJC085q0cSVuO+Hmrji9hMrPZZlZkZkXFxR1refi5A7NlJr2xquX/kALQ+cycOVPPP/+8nn32WV1++eV66qmnVFxcrI8//liLFy9W9+7dO/TG73Fxcfrwww912WWXae7cuZo2bZqk5s9PZ4qCFSEJcbGa2D9T77K/CIBjdOnSReXl5c2+V1ZWpq5duyo5OVmrVq3SggUL2uzvDho0SBs3btTatWslSU888YTOPfdcDRo0SOvXrz98FezZZ59t9Weec845euaZZyRJTz31lCZPnixJWrduncaPH6+77rpL2dnZ2rJli9avX69+/frp1ltv1YwZM7R06dI2+992JswsRdIfJH3HOXdal3Gcc3Occ2Odc2Ozs7PbNmA7y0xJ0Kje6XpzFfdhAdHk8ssv1zPPPKPnn39eM2fOVFlZmbp166ZQKKS33npLmzZtOuHvT5kyRb/73e8kScuWLWv1v9MnT56sF198UZWVlTpw4ID++Mc/avLkyZo0aZL+9Kc/qbq6WhUVFZo7d26rPq+lc1tFRYXKysp04YUX6p577tGSJUskNX9+OlNMEYygKQOy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\n",
"text/plain": [
"<Figure size 864x864 with 4 Axes>"
]
},
"metadata": {
"tags": [],
"needs_background": "light"
}
},
{
"output_type": "stream",
"text": [
"lr\n",
"\tlr \t (min: 0.000, max: 0.002, cur: 0.001)\n",
"steps\n",
"\tsteps \t (min: 159.000, max: 7950.000, cur: 7950.000)\n",
"train_log_loss\n",
"\ttrain_log_loss \t (min: 0.577, max: 4.606, cur: 0.578)\n",
"valid_log_loss\n",
"\tvalid_log_loss \t (min: 0.256, max: 3.779, cur: 0.256)\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ZF9ifdYyqlZo"
},
"source": [
"Generate denonised sentence"
]
},
{
"cell_type": "code",
"metadata": {
"id": "oYpTqqqStREb"
},
"source": [
"class ScoredSentence:\n",
" def __init__(self, log_probs, sent, hidden):\n",
" self.log_probs = log_probs\n",
" self.sent = sent\n",
" self.hidden = hidden\n",
"\n",
" def last(self):\n",
" return self.sent[-1]\n",
"\n",
" def score(self):\n",
" return sum(self.log_probs) / len(self.log_probs)\n",
"\n",
" def get_new_sent(self, log_prob, token, hidden):\n",
" log_probs = self.log_probs + [log_prob]\n",
" sent = self.sent + [token]\n",
" return ScoredSentence(log_probs, sent, hidden)\n",
"\n",
"def calc_scores(model, beam):\n",
" decoder_inputs = torch.tensor([[sent.last() for sent in beam]]).cuda()\n",
" hidden_states = torch.cat([sent.hidden for sent in beam], dim=-2).cuda()\n",
" lengths = [1 for _ in range(len(beam))]\n",
" with torch.no_grad():\n",
" x = model.decoder.embeddings(decoder_inputs)\n",
" packed = pack(x, lengths, enforce_sorted=False)\n",
" x, hidden_states = model.decoder.rnn(packed, hidden_states)\n",
" x, _ = unpack(x)\n",
" x = model.decoder.proj(x)\n",
" score = torch.log_softmax(x, dim=-1)\n",
" return score, hidden_states\n",
"\n",
"def update_beam(old_beam, scores, hidden_states, width):\n",
" new_beam = []\n",
" for n in range(len(old_beam)):\n",
" values, indices = scores[0, n].topk(width)\n",
" for v, i in zip(values, indices):\n",
" sent = old_beam[n].get_new_sent(v.item(), i.item(), hidden_states[:,n:n+1,:])\n",
" new_beam.append(sent)\n",
" new_beam.sort(key = lambda sent:-sent.score())\n",
" new_beam = new_beam[:width]\n",
" return new_beam\n",
"\n",
"def split_beam(vocab, old_beam):\n",
" new_beam = []\n",
" ended = []\n",
" for sent in old_beam:\n",
" if sent.last() == vocab.eos_id:\n",
" ended.append(sent)\n",
" else:\n",
" new_beam.append(sent)\n",
" return new_beam, ended\n",
"\n",
"def beam_search(model, vocab, hidden, width, max_len = 128):\n",
" model.eval()\n",
" beam = [ScoredSentence(log_probs = [], sent = [vocab.bos_id], hidden = hidden)]\n",
" output = []\n",
" for i in range(max_len):\n",
" if len(beam) == 0:\n",
" break\n",
" scores, hidden_states = calc_scores(model, beam)\n",
" beam = update_beam(beam, scores, hidden_states, width - len(output))\n",
" beam, ended = split_beam(vocab, beam)\n",
" output += ended\n",
" output.sort(key = lambda sent:-sent.score())\n",
" return output"
],
"execution_count": 21,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "GL3LgHf0w6_u"
},
"source": [
"def encode(model, tokenizer, sent):\n",
" x = tokenizer(sent)\n",
" encoder_inputs = torch.tensor([x]).cuda()\n",
" batch = DAEBatch(\n",
" pad(encoder_inputs, padding_value = tokenizer.vocab.pad_id),\n",
" None, None, torch.tensor([len(x)]), None)\n",
" with torch.no_grad():\n",
" h = model.encode(batch)\n",
" return h"
],
"execution_count": 22,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "wtx1xhI_w-SW"
},
"source": [
"def denoise(sent, beam_size=5, max_len=128):\n",
" h = encode(model, tokenizer, sent)\n",
" beam = beam_search(model, tokenizer.vocab, h, beam_size, max_len)\n",
" for sent in beam:\n",
" score = np.exp(sent.score())\n",
" print(' '.join([tokenizer.vocab[n] for n in sent.sent]) + '\\t' + str(score))"
],
"execution_count": 25,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "8dnLRyPcxZ2M",
"outputId": "652381c5-0950-4140-bad8-3b93b9b10804"
},
"source": [
"denoise('toki pona li pona.')"
],
"execution_count": 26,
"outputs": [
{
"output_type": "stream",
"text": [
"<bos> toki pona li pona <sep> <eos>\t0.9602100566038698\n",
"<bos> toki pona li kama <sep> <eos>\t0.6168163541045165\n",
"<bos> toki pona li pona ala <sep> <eos>\t0.538016617486722\n",
"<bos> toki musi li pona <sep> <eos>\t0.4962341315446067\n",
"<bos> toki pona li pona ala <eos>\t0.4453851306025853\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "hnOcKETzxiVO",
"outputId": "632f5cbd-fd3c-4fa2-d01b-daf580f76393"
},
"source": [
"denoise('mi moku e soweli.')"
],
"execution_count": 27,
"outputs": [
{
"output_type": "stream",
"text": [
"<bos> mi moku e soweli <sep> <eos>\t0.873192273500337\n",
"<bos> mi moku e soweli <unk> <sep> <eos>\t0.7090508112513239\n",
"<bos> mi moku e soweli <prp> <sep> <eos>\t0.6052923052951552\n",
"<bos> mi moku e soweli mute <sep> <eos>\t0.5918776299807577\n",
"<bos> mi moku e soweli lili <sep> <eos>\t0.5519345455800279\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "mHvvc9MqxiXi",
"outputId": "a8918142-c958-41d5-c662-85551359fbab"
},
"source": [
"denoise('mi li moku e soweli.')"
],
"execution_count": 28,
"outputs": [
{
"output_type": "stream",
"text": [
"<bos> mi mute li moku e soweli <sep> <eos>\t0.9382321932582245\n",
"<bos> mi mute li moku e soweli <prp> <sep> <eos>\t0.7230858882356526\n",
"<bos> mi mute li moku e soweli <unk> <sep> <eos>\t0.6577222089734941\n",
"<bos> jan mute li moku e soweli <sep> <eos>\t0.621702277383898\n",
"<bos> jan ali li moku e soweli <sep> <eos>\t0.6093385091711904\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "9EbqF8gLxidd",
"outputId": "6cf81159-a952-4836-be7e-b94ad239a38a"
},
"source": [
"denoise('ona li toki e ni.')"
],
"execution_count": 29,
"outputs": [
{
"output_type": "stream",
"text": [
"<bos> ona li toki e ni <sep> <eos>\t0.9594348112659932\n",
"<bos> ona li toki ala e ni <sep> <eos>\t0.6484826114620437\n",
"<bos> ona li wile toki e ni <sep> <eos>\t0.6153196331193732\n",
"<bos> ona li toki e ijo ni <sep> <eos>\t0.5993120629623885\n",
"<bos> ona li toki e seme <sep> <eos>\t0.5271209277469302\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "ID4vMt7-xify",
"outputId": "8353fd4c-075e-472f-ca15-40118a0bed4f"
},
"source": [
"denoise('ona toki e ni.')"
],
"execution_count": 30,
"outputs": [
{
"output_type": "stream",
"text": [
"<bos> ona li toki e ni <sep> <eos>\t0.9904916720548973\n",
"<bos> ona li toki e seme <sep> <eos>\t0.6004794934120553\n",
"<bos> ona o toki e ni <sep> <eos>\t0.4841754472753993\n",
"<bos> ona li toki e ijo <sep> <eos>\t0.43191650670698983\n",
"<bos> ona li toki e sewi <sep> <eos>\t0.41773600416921963\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "O7a2RwyrxikL",
"outputId": "2986cf6a-d608-40dc-cf90-3ee1ff096cef"
},
"source": [
"denoise('tenpo ni la mi wile moku ala e kili.')"
],
"execution_count": 33,
"outputs": [
{
"output_type": "stream",
"text": [
"<bos> tenpo ni la mi wile ala moku e kili <sep> <eos>\t0.9575241861112094\n",
"<bos> tenpo ni la mi wile moku ala e kili <sep> <eos>\t0.8759633175544083\n",
"<bos> tenpo ni la mi wile ala moku e telo <sep> <eos>\t0.6682083869593419\n",
"<bos> tenpo suno ni la mi wile ala moku e kili <sep> <eos>\t0.662143229361594\n",
"<bos> tenpo ni la mi wile ala moku e soweli <sep> <eos>\t0.6354420223515982\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "7r2AAnB2xiiS",
"outputId": "a07e7005-4445-4cd1-f57b-11d281021a74"
},
"source": [
"denoise('jan lili ni li lukin pona.')"
],
"execution_count": 36,
"outputs": [
{
"output_type": "stream",
"text": [
"<bos> jan lili ni li lukin pona <sep> <eos>\t0.9681033323752564\n",
"<bos> jan lili ni li pona lukin <sep> <eos>\t0.6790848388869116\n",
"<bos> jan lili ni li ken lukin pona <sep> <eos>\t0.6244324694247788\n",
"<bos> jan lili ni li sona pona <sep> <eos>\t0.587818588934063\n",
"<bos> jan lili ni li sitelen pona <sep> <eos>\t0.5350942833725847\n"
],
"name": "stdout"
}
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment