Skip to content

Instantly share code, notes, and snippets.

@CookieBox26
Created April 5, 2020 03:21
Show Gist options
  • Save CookieBox26/b48e347c4ece2fe9763aa72d54162bdc to your computer and use it in GitHub Desktop.
Save CookieBox26/b48e347c4ece2fe9763aa72d54162bdc to your computer and use it in GitHub Desktop.
PyTorch で Transformer を学習する
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# PyTorch で Transformer を学習する\n",
"\n",
"### 参考文献\n",
"\n",
"SEQUENCE-TO-SEQUENCE MODELING WITH NN.TRANSFORMER AND TORCHTEXT \n",
"https://pytorch.org/tutorials/beginner/transformer_tutorial.html\n",
"- [torchtext.datasets.WikiText2](https://torchtext.readthedocs.io/en/latest/datasets.html#torchtext.datasets.WikiText2)\n",
"- [torchtext.data.Field](https://torchtext.readthedocs.io/en/latest/data.html#field)\n",
"- [torchtext.data.get_tokenizer](https://pytorch.org/text/data.html#torchtext.data.get_tokenizer)\n",
"- [neural network - PyTorch - contiguous() - Stack Overflow](https://stackoverflow.com/questions/48915810/pytorch-contiguous)\n",
" - view() や transpose() はインデックスをふりかえるだけで新しいオブジェクトを生成しないが、これをつけると新しいインデックスに適切なメモリ上の配置で新しいオブジェクトを生成する。プレ処理中に転置などをするなら処理速度上 contiguous しておいた方がよい場合がありそう。\n",
"- [torch.triu](https://pytorch.org/docs/stable/torch.html#torch.triu)\n",
" - デフォルトで行列を広義上三角にしてくる。オプションで狭義上三角にもできるし逆に対角要素より何行下まで残すこともできる。\n",
"- [torch.nn.Embedding](https://pytorch.org/docs/master/nn.html#torch.nn.Embedding)\n",
"- [torch.nn.Transformer](https://pytorch.org/docs/master/nn.html?highlight=nn%20transformer#torch.nn.Transformer)\n",
" - 以下の論文にもとづいている.\n",
" - [Attention Is All You Need](https://arxiv.org/abs/1706.03762)\n",
"- [torch.nn.TransformerEncoder](https://pytorch.org/docs/master/nn.html?highlight=nn%20transformerencoder#torch.nn.TransformerEncoder)\n",
"- [torch.nn.TransformerEncoderLayer](https://pytorch.org/docs/master/nn.html?highlight=transformerencoderlayer#torch.nn.TransformerEncoderLayer)\n",
"- [torch.nn.MultiheadAttention](https://pytorch.org/docs/master/nn.html?highlight=multiheadattention#torch.nn.MultiheadAttention)\n",
" - 今回はこのモジュールを生でつかうことはしない。TransformerEncoderLayer を定義する。"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"◆ まず Wikitext-2 データを取得する\n",
"◇ 訓練データ語数: 2086708\n",
" 訓練データ冒頭: ['<eos>', '=', 'valkyria', 'chronicles', 'iii', '=', '<eos>', '<eos>', 'senjō', 'no', 'valkyria', '3', '<unk>', 'chronicles', '(', 'japanese', '戦場のヴァルキュリア3', ',', 'lit', '.', 'valkyria', 'of', 'the', 'battlefield', '3', ')', ',', 'commonly', 'referred', 'to', 'as', 'valkyria', 'chronicles', 'iii', 'outside', 'japan', ',', 'is', 'a', 'tactical']\n",
"◇ 評価データ語数: 218177\n",
" 評価データ冒頭: ['<eos>', '=', 'homarus', 'gammarus', '=', '<eos>', '<eos>', 'homarus', 'gammarus', ',', 'known', 'as', 'the', 'european', 'lobster', 'or', 'common', 'lobster', ',', 'is', 'a', 'species', 'of', '<unk>', 'lobster', 'from', 'the', 'eastern', 'atlantic', 'ocean', ',', 'mediterranean', 'sea', 'and', 'parts', 'of', 'the', 'black', 'sea', '.']\n",
"◇ テストデータ語数: 246217\n",
" テストデータ冒頭: ['<eos>', '=', 'robert', '<unk>', '=', '<eos>', '<eos>', 'robert', '<unk>', 'is', 'an', 'english', 'film', ',', 'television', 'and', 'theatre', 'actor', '.', 'he', 'had', 'a', 'guest', '@-@', 'starring', 'role', 'on', 'the', 'television', 'series', 'the', 'bill', 'in', '2000', '.', 'this', 'was', 'followed', 'by', 'a']\n",
"◇ 訓練データの語彙を取得する\n",
"語彙数: 28785\n",
"0 <unk>\n",
"1 <pad>\n",
"2 <sos>\n",
"3 <eos>\n",
"4 the\n",
"5 ,\n",
"6 .\n",
"7 of\n",
"8 and\n",
"9 in\n",
"10 to\n",
"11 a\n",
"12 =\n",
"13 was\n",
"14 '\n",
"15 @-@\n",
"16 on\n",
"17 as\n",
"18 s\n",
"19 that\n",
"20 for\n"
]
}
],
"source": [
"import torch\n",
"import torchtext\n",
"from torchtext.data.utils import get_tokenizer\n",
"\n",
"print('◆ まず Wikitext-2 データを取得する')\n",
"# torchtext.data.Field でテキストデータへの前処理を定義しておく\n",
"# トークナイザは今回は basic_english というのをつかう(これは空白で split するより先に正規化するらしい)\n",
"# > which normalize the string first and split by space.\n",
"# 今回は init_token と eos_token を定義しておく(全ての例文に文頭トークンと文末トークンが付加される;デフォルトは付加しない)\n",
"# 今回は小文字化 lower=True にしておく(デフォルトは False)\n",
"TEXT = torchtext.data.Field(tokenize=get_tokenizer(\"basic_english\"), init_token='<sos>', eos_token='<eos>', lower=True)\n",
"# 訓練データ、評価データ、テストデータを取得する\n",
"train_txt, val_txt, test_txt = torchtext.datasets.WikiText2.splits(TEXT)\n",
"print('◇ 訓練データ語数: {}'.format(len(train_txt.examples[0].text)))\n",
"print(' 訓練データ冒頭: ', train_txt.examples[0].text[:40])\n",
"print('◇ 評価データ語数: {}'.format(len(val_txt.examples[0].text)))\n",
"print(' 評価データ冒頭: ', val_txt.examples[0].text[:40])\n",
"print('◇ テストデータ語数: {}'.format(len(test_txt.examples[0].text)))\n",
"print(' テストデータ冒頭: ', test_txt.examples[0].text[:40])\n",
"\n",
"print('◇ 訓練データの語彙を取得する')\n",
"TEXT.build_vocab(train_txt) # 訓練データをもとに語彙を構成(これにもとづいて各単語を数字にする)\n",
"print('語彙数: {}'.format(len(TEXT.vocab.stoi)))\n",
"for token, i in TEXT.vocab.stoi.items():\n",
" print(i, token)\n",
" if i == 20:\n",
" break"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"◆ データを固定長ごとに区切って整形する\n",
"訓練データ torch.Size([104335, 20])\n",
"評価データ torch.Size([21817, 10])\n",
"テストデータ torch.Size([24621, 10])\n",
"\n",
"◇ 訓練データの 0, 1, 2, 33, 34, 35 個目の単語列(数字列版)\n",
"単語列0 tensor([ 3, 25, 1849, 570, 7, 5, 5, 9258, 4, 56, 0, 7,\n",
" 6, 6634, 4, 6603, 6, 5, 65, 30])\n",
"単語列1 tensor([ 12, 66, 13, 4889, 458, 8, 1045, 21, 19094, 34,\n",
" 147, 4, 0, 10, 2280, 2294, 58, 35, 2438, 4064])\n",
"単語列2 tensor([ 3852, 13667, 2962, 68, 6, 28374, 39, 417, 0, 2034,\n",
" 29, 88, 27804, 350, 7, 17, 4811, 902, 33, 20])\n",
"単語列33 tensor([ 884, 28, 27, 435, 12, 6, 63, 133, 6, 0, 13, 31,\n",
" 3, 43, 8, 2997, 78, 5977, 52, 181])\n",
"単語列34 tensor([ 632, 4, 127, 6, 3, 4775, 4, 4, 25, 23, 124, 5223,\n",
" 12, 194, 4, 8, 36, 2142, 139, 37])\n",
"単語列35 tensor([ 979, 725, 4, 10997, 3, 8, 677, 542, 112, 55,\n",
" 126, 11, 12, 6, 6962, 4113, 5196, 37, 27, 9177])\n",
"\n",
"◇ 訓練データの 0, 1, 2 個目の単語列(単語列に翻訳版)\n",
"単語列0 ['<eos>', '@', 'settlement', 'heavy', 'of', ',', ',', 'lined', 'the', 'she', '<unk>', 'of', '.', 'interception', 'the', 'dried', '.', ',', 'would', 'his']\n",
"単語列1 ['=', '1', 'was', 'rains', 'ireland', 'and', 'starting', 'with', 'hairy', 'had', 'found', 'the', '<unk>', 'to', 'possibility', 'heads', 'other', 'which', 'receive', 'gift']\n",
"単語列2 ['valkyria', 'rebounds', 'rapid', 'over', '.', 'truely', 'their', 'lead', '<unk>', 'recently', 'at', 'year', 'sharif', 'take', 'of', 'as', 'symptoms', 'usually', 'an', 'for']\n",
"\n",
"今回学習するモデルは、\n",
"Inputs として 単語列0 を入力したら 単語列1 っぽい確率分布が出てくる.\n",
"Inputs として 単語列1 を入力したら 単語列2 っぽい確率分布が出てくる.\n",
"任意の長さの単語列を入力したら、それに続きそうな同じ長さの単語列が出てくる.\n",
"たぶんそんなモデル.\n"
]
}
],
"source": [
"print('◆ データを固定長ごとに区切って整形する')\n",
"\n",
"def batchify(data, seq_len):\n",
" data = TEXT.numericalize([data.examples[0].text]) # データ内の単語列を数字列へ\n",
" # print(data.size()) # torch.Size([2086708, 1])\n",
" nbatch = data.size(0) // seq_len \n",
" data = data.narrow(0, 0, nbatch * seq_len) # 系列長で割り切れない単語は捨てる ヾ(;ω;) \n",
" # print(data.size()) # torch.Size([2086700, 1])\n",
" data = data.view(seq_len, -1).t().contiguous() # 次元を (ほげ, 系列長) にする\n",
" # print(data.size()) # torch.Size([104335, 20])\n",
" return data.to('cpu')\n",
"\n",
"seq_len = 20\n",
"eval_seq_len = 10\n",
"\n",
"train_data = batchify(train_txt, seq_len)\n",
"val_data = batchify(val_txt, eval_seq_len)\n",
"test_data = batchify(test_txt, eval_seq_len)\n",
"\n",
"print('訓練データ', train_data.size())\n",
"print('評価データ', val_data.size())\n",
"print('テストデータ', test_data.size())\n",
"\n",
"print('\\n◇ 訓練データの 0, 1, 2, 33, 34, 35 個目の単語列(数字列版)')\n",
"print('単語列0', train_data[0,:])\n",
"print('単語列1', train_data[1,:])\n",
"print('単語列2', train_data[2,:])\n",
"print('単語列33', train_data[33,:])\n",
"print('単語列34', train_data[34,:])\n",
"print('単語列35', train_data[35,:])\n",
"\n",
"print('\\n◇ 訓練データの 0, 1, 2 個目の単語列(単語列に翻訳版)')\n",
"print('単語列0', [TEXT.vocab.itos[i] for i in train_data[0,:]])\n",
"print('単語列1', [TEXT.vocab.itos[i] for i in train_data[1,:]])\n",
"print('単語列2', [TEXT.vocab.itos[i] for i in train_data[2,:]])\n",
"\n",
"print('\\n今回学習するモデルは、')\n",
"print('Inputs として 単語列0 を入力したら 単語列1 っぽい確率分布が出てくる.')\n",
"print('Inputs として 単語列1 を入力したら 単語列2 っぽい確率分布が出てくる.')\n",
"print('任意の長さの単語列を入力したら、それに続きそうな同じ長さの単語列が出てくる.')\n",
"print('たぶんそんなモデル.')"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"◆ 1バッチの学習に必要なデータを取得する関数を用意する\n",
"◇ data と targets が得られる\n",
"torch.Size([35, 20])\n",
"torch.Size([700])\n",
"◇ data には Inputs から入れる用に訓練データの 0~34 個目の単語列が入っている\n",
"tensor([ 3, 25, 1849, 570, 7]) 単語列0\n",
"tensor([632, 4, 127, 6, 3]) 単語列34\n",
"◇ targets には損失計算用に訓練データの 1~35 個目の単語列が入っている(損失計算時の便利用に1次元配列にしてある)\n",
"tensor([ 12, 66, 13, 4889, 458]) 単語列1\n",
"tensor([ 979, 725, 4, 10997, 3]) 単語列35\n"
]
}
],
"source": [
"print('◆ 1バッチの学習に必要なデータを取得する関数を用意する')\n",
"bptt = 35 # bptt 個の単語列を一度にモデルに流す\n",
"def get_batch(source, i):\n",
" seq_len = min(bptt, len(source) - 1 - i)\n",
" data = source[i:i+seq_len]\n",
" target = source[i+1:i+1+seq_len].view(-1)\n",
" return data, target\n",
"\n",
"data, targets = get_batch(train_data, 0) # 1バッチ目の学習に必要なデータ\n",
"print('◇ data と targets が得られる')\n",
"print(data.size())\n",
"print(targets.size())\n",
"\n",
"print('◇ data には Inputs から入れる用に訓練データの 0~34 個目の単語列が入っている')\n",
"print(data[0, :5], '単語列0')\n",
"print(data[34, :5], '単語列34')\n",
"print('◇ targets には損失計算用に訓練データの 1~35 個目の単語列が入っている(損失計算時の便利用に1次元配列にしてある)')\n",
"print(targets[:5], '単語列1')\n",
"print(targets[680:685], '単語列35')"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"◆ モデル本体より先に、PositionalEncoding という単語列を埋め込んだテンソルに少しプレ処理する機能を用意する\n",
"埋め込み次元数の半分の長さ(100)まで指数的に減衰する成分が用意される\n",
"tensor([1.0000, 0.9120, 0.8318, 0.7586, 0.6918, 0.6310])\n",
"tensor([0.0002, 0.0002, 0.0001, 0.0001, 0.0001, 0.0001])\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAhwAAAChCAYAAACMNWb+AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nO2dd5wdVfn/38/dXlLZNNI2pBIglAQEAUGaQoQAil8iCEEEG6jYqCogKoIIiCAiICAISIdf6NIEQyAhdBJI771uNtuf3x/PudnZyd2W7O7N7j7v1+u87swpM8+cOXPmM6ddUVUcx3Ecx3Fak0S6DXAcx3Ecp+PjgsNxHMdxnFbHBYfjOI7jOK2OCw7HcRzHcVodFxyO4ziO47Q6Ljgcx9lhRCSrI5/PcZwdxwWH4zg7hIj0Aj4VkUFtdL7LgZva4lyO47QcLjhaERE5T0ReiewvFxFN4RY34VjTReTYBsKvF5EfhO2iFOcY20DaDBHJjLlmlw0RyRKR80WkWyPxBtSTD6ncPpF0F4jIH8P2ehH5Sjjfc+EaForIuOba3YTrGiMiR0b2zxORdyP7B4nIcY0c42wR6R62/09EbmlpOyPnuqEJ+dq3CcfZT0R+2YRTXg18pqoLY+lPFJHZ9Rx7YngeqkTk2SBaouFHishcEakRkTdFZGgk+GHgbBE5tAnXUBgvRy2NiFwlIs+G7dNFZH4sPENEfiAi/SP794vIySKyT7CvMPhdLiKHisgsEclo4Jzni8jFMb8jReQOEZF60uwnIk+KSGEzr+8EEXmovjpBRF4Ukb+IyBsiMqIJx1stIic2x4ZI2tyQXy3+nDdwzsNDOT1SRJ6SBlrXRGR0sp4W434RObqtbN3ZccHR9nwL2CNsHwCcG48gIsNEZN/IvgBjgJQVSWAOcL2IjAbWAkMi7mOgoYrgI6Ay5p5u6CLERM01IpId8f4icCOQ31BaYCnQq4nug0i6tcBPRGS/pBnAJGAFMAgYCGxs5NxJYXSkiHxHRL4vIseJSEEDSW4A/lJfhQtcAFzawPm+BNwG9A5em4DviMieTbA1ISIHi8i3g9A5MSlcGuER6paBuFvVhGPkAb8SkXrvZxAKpwNXxfyzge/Xk+YA4B4sX78M7IKJiGT4IOBx4AngCGAd8IyI5ACo6ofh+i5pwjU0ioj0EZHiZriiJhxTRGSUiPwc+BS4Djg02F8NlAF/ofZZ6QNMABYCw4AuIV59nBDSxP3Gav2rOR4J7KWqJcHGzAauMXrsJeHY9ZZx7NmsAB5MvpBF5LQgRuo4oCtwRYqw+xs4frMQkbukfrF9VeNHSMkq4Gjg2gbi/JKQT+E+ZABX1ScCOxuZ6TagE7IJezjBKtJNKeJcCBQBJ4nIAOBA7F4Vi0gfVV2RIs0twA+Bb6nqz4D5yQARWQKMbMCmw4Coar8C6BJJnwcUqeqiSJzBwNnA3iLyFVWtxF7+bwFbUrwUa1R1I4Cq1gCrG7CnPp7HxNFemFjeB9gT+DWWR1VAjYgUR9IsDOdLXstE4E/hequCdzWQJyJXAH9OUWFfDLwJjAeeigaISD/geODHqQwOX6lXAE+o6qcAqvq0iLwD3CUiB4W8S5X2KOBWTHhtwO7JOqCviPwJuFxVq1KlbYTS6MtMrEWqR4p4q7C8+bpEWuqAKlVNtsqdCixS1dcixysG5oXdOSmO+3NgsqpeHeLPBWaLyBGq+hJwPjBbVS8I4TOARcBpwJ3hGHcAz4nIYFVdEJ6TRfETRZiRos7/oqq+AtyHvYybyl3AWeHeZmEvlYSI5IbtAUAJJibmAA8At8aen9uw5y4pOo/HyuPL2PO/IFaOK1R1qYgcBowGvgDMFJHvArOAV4GvAY/Gnr2qpMAIaV6MhA2g9j7F+Q9wFICqTheR64DvikiqrqxMIBu4DCsPedhHyxvYx0Ccq+s5ZxlYCygN30uAt2P3M3kvk1wcO09f4F/AGkzsbkMQyanEdbJFaCFwPVYPd1fV9bH0+2D34KsR798C07GPkj81fEmdAFV110oOOA94JbK/HDgLqzAU2B84B1gcS/dzrHC/gVX4i0P8j7GviAeAHinOtyeQEfPLxATOs82w+17g+sj+McCmFPGSrSl/xARNVbAzlVvUAvn5SgPHf6Ae/+6R9L8INv4MqyD/DfwZaymZiLWO3FrPuV8HHovc13fD9m+xSjunnnSXYS+fITH/MUA59uKRFOkmBluvBQqAa4AnQ9iXgGXA/4vf7xB+QwP5pMD/S2FjQ/Hjbn4k7UPxPAt5uw/wK0w4xO1bDZwV83sb+H3YngZcEQt/CLg/do4yYFLYzwCKU7jks3ZcirDcRspbV+zFNR979q7CWvHyQvikFHnzOibUjgUGxo71OrBr2K8vb6cBn6XwT5a324M9Dwc3DxNAE+s5XrT+WQx8Zzueu75AT2A4JlgaKx/x8nBqI/FficWv714WY/WMYgKtSfcSGIoJv3uA/AbipbqfDbncSNoC4D1MSMeP+3vsWT9iR+vA9u7SbkBHddhLphwTDCXAiZjgSFVw44LjT8H/r+FhOh5YG8IGAy8B7wCZTbDji+FYFURevo2keRM4L7J/ArCsnriHYN01U4JLAO8DX4rE+TfweNgWoHszXWbkWF/BXjQ12Av5BexLbSPwtxDn98CjMTuPCGnOifi9BlwW2T8s3K/jIn4C5AIHh8ouF2vNeC9s74IJx1y2FXs/DOecVE/enRPuzW1AVsR/d2AL8NuI3z3A7bE4JcD3Uxz3BuxlVFyP692McnxwyOf96gn/DPh2PWGTiAkOoBu1YvuryfsE/A14OGyvA04Jcd4OfhcD02LHmgrc0oj9heF8+zTz+T0Oe16fxURfVfB/GLgrci2jsOf0v2H7uyHdkFienxbKwi6Rc1wVyptiLQLXhjKowMQQZwrww0ia25Pnj+w/BMxl2zJ/NeFljj2XVcDhzcyHLExs3RuO8SLW6jYp4t7EWtvAPk66h+2ckP9nYgI5VVn8Y8i7QqCwEVt6Yy1xCoxrov37AgtogtBKVV6D/xeA6sh+Ziy8C/YxtBjonyJ9NlZnbwaObU7+dzSXdgM6qguVz2+wLoZRoVAux5rc+oaHZhim/hdH0h2HiYMK4OjgdxnwWiROfniAvxX2M7EumCKga8yOfwAzw/nObILdPbFunhMifmcD79cTP4E1VW4G9gx+pQTBgVW8VcnjYeKgOV8RChyONdP+FauYbwXWAz/AvvbmhXjTwzkmExESwW8K8HTMb148T4AHCS0ZYX9cM+y8KJIn/8ZeMFdE7k0qd3GI9xbhiwm4HxNtGRE7XgZ+HbP1D8CMFPekWS0cTSgTk7EWiG0EbrgPX6kn3SS2FRzJ+z8UK9efBf/fAs+H7Sqsi+N0oDL4nQN8GjvWE8Ajkf03m3GvljdwvV/DBN9ZYf9EUgiOSPyrCC2I2Dii+SnOVw78NcTZDese1HAPFRNfq4JTbMyHYM/iIZFzpRIcT2PjQXrH7IoKjj7huIO3oy4biT3TX8cEx9+xVr6kmwpcjpXnSuDLId2tzbgfCmg95z8Oq+8UqxebJDiwemMDJuqqwz2Yg3XH7VVPeZ1L3Y+dfOCgcM5EyIslQL+QZo9wv1dgwqS+53wIJqxqgJ819x50FOeDRlsJVZ2JFcJSVZ2pqsmxGvlY8yqYCIn3GV6Njcd4HmtZABuo9N/IsUuxyjY5+vlAaiurR5PxQl/oaVhz/BTgF5Ji5LuIFIjIhSIyD+vjLASeEJE1IvIYVgGnnG2gNj6iBjhZVT8MgwjzgBVhkOWdwAzC2AdVXayqknTY9MaHwnZeOOz+0ThqfbNl2IN/Hda/vBgbWLhHyItHsfEk/YDPYS1A0Xw4EPuaSvrlYgNNP41d0mRsMG+Sd7D7FHU/xQazxv2vi+TJs8BJQH9q700qtwyrUO9T1bLQj3wCcIPWHTQ4oh5b904O3BWR/qHfvysNDxo9LwwMbHTwqdhslkvCdaSaAVGAtbQ0leR4mirgE2oHBSe745JxqrCxCe+mCE+yichYIyy/49eaHKA9Pua/fyrjQp78Hfipqv6jGdfVTUS+B4xQ1eJY+RVVzVHV74W4ldg4pInYS+wprAwPx15ej2DP9hisfng3dq4zkwMgsY+Blap6HjBEbDZJqgGKyTE6m5txTQCo6ixswOvzwSsPe25vwkTjSqyF7wxsQHgy3qVYXv+Q2lafuLsOEyzJ/TqE+ure4AqxgbU1wMkN2SwiJ2PPYAk2xusYrLXuEqxlapqknvU3BGthS7pbqB1nV4i1YM1T1WXBbzZWD+2LtWLU95zPxVpZr8Ge285JuhVPR3akHsORStkvDuF7hv1RWMvHBqxiqsRewtFj/wp4MeZ3edQPGwy3EKsMTgzH/l4sTXes0v8YExZ/BZ7EXlpHYmMcSrEX4yRSjzcYDxSH7WPCeX4crmELsHcDefQoYbxIsLPerxds8GQR9oC/SO3XQ59wHe8Dj2HdK/kx+8qo221xcMjXwtg5jsZEYmP39d0mloFks/IXsa+sfmG/EPvamhSLv0fIg2j/f/9kuYjFHR78e4f92fWUr/rc5U2w//EQtyb8fjcWvhY4vp60k9i2hSPZxbF3zP8vwINhexUwIRb+M2BqzO8pTKw2ZH+zulSobf6Pti7tDdwcts8ltIqFcvUE9mFRhrV+HI+95OaG+5F0a4FfRI65ayi7q6jbCrYb1nVQHcpy/Bm/nbrdZQ9Q28WTrCu+E/avSabHXqQKFDQlH1Lky4+xj5YXsZe/YvXFcuBurM5YA1ycIm2zxnDE0iZbg/eN+C0jRcteJPxcTKDeTP1jq24FPon5fYtIK1rI67vC/VCsu6uE0PKc4pgFobzdHu5d8jk/mnpabzqb8xaO1iUP2FVEbhKRw1W1r9qXfL8QPlzt62dA2N8T2KjWOvIw9mC9AHykqm/Hjr0rDcz0EJFvAt8AfqKqZar6OKb4fy8iYyJRf4l9Ze2PVeAnAHer6kZV/Q/2RSBYC8utWAUbPc/+WBdAcmT2iVil90vgOWCMqr5Xj40ZWGvEJw1cR8/IF9tDhJcRJoaSXw/LsQrmnnD+h9VagZJ0w74Co7NBvg78R2tH8CfpjQm95Pm7iUj3qMPua0bcP7joNGFUtTyc4yjgQ1VdpqolwS9Z4UZJrmGyJGbrzFAu4rYqYSqwqg4L5etG7B4K1ipUARwU9g8FLgjl7vLIdU4QkZvZltOwrr+JWFP0E7HwVdhLoUmE616BiaUoe2HjQcCEWEPhSfqSYhaE2FTiPmLTaxudwhpjN+x529q6pKrvqeoPwvZtqnp3CCrFWsD+h700v4aV5QLgC+F+DFPVYZgYjpaNJVjeFWEfD8my/G9VXQk8g5XlVDMqSlR1vqrOJ9K6pKofYGNhrhRbayOXMPMj2ApQJJE1ZZrBWCz/87CuiSgzMaG1DpvFEecRrIXlEqxueAebVdMjuCdE5BFJvb7FCiyvfiQi+4rIj7H7npvKSBH5CVZPJbt7uqVq1cXqupEiEp2p2ZW6rXW5QHm4Hxuw8j9ZVV9IdW5V3YzlzZFYF3jyOd+SKn5nxAVHKyAivcNU1Guwyv5dICfSDJpsjvssMjf8kOBXAaA23fFW7Ov9ntjx87HKaEo95z8b68q4QVUfjgSdTpixIiKDg98XgTvCw/Jz7MF6PJIm2dIyEWs2/HM4h4jIWVj3xmTgT6E740ysy2Et8E9ST4tMMh5rtXikgTh/x76eUNXDsVacJVjl/XtgVnh5llDb5RCfUrca6JGseMQWkTo7eS0x4vm6hrpNrOuw+7pnCv91mMirg4iMBH6CfXFFSU4fjNsKli+ISE/svqSajngi1tJSliIMAFV9E/tKe1BEXsYGyh4j266t8Q3sqzqefrOqzlHVB1X121rblJzkHWycS3N4hdruwuQ02oMxcZ0qvCv2Qnsh4peDdTm8FfFLiMj1mABbjg0WnBeCbxJbfKtnI7atxLomGl03QVVfVtUrsKnacRZFnu3k13E0rYTrTHYn/g8b9JzMy/rKcmNcjwmXZGtgcr2V5Iv0CuABsTU4/iA2TbxBQtfoUdhzsRuWR2AfAFArZi4CBonISZG0ybrqGeB3WLfX4djg919jIuQabEDwNtPDVVWxj5ndsVl7P8G62ubF4waexJ7tO7BxTyuAEhG5MhZvAPZxF51WPgJYLCJdRGQU1rU6P4R9gomj5OKK9S0pcQk2Du7eiF+q57xzku4mlo7qsCbglF0JRAaNxvyTTeSnYOJgPdYlspLQ9I+NGr87hO0SS38d1hJxGlbxpOr+6I/1S+aH/WnY6PgLsUrpoEjcfOzBviTFcR4Ktt6ITWPLw75aFoV0h2Hi6WZST93sE+JGZ15s06WCvSBvDduZWD9pBVaRbAGuDmGDQj59iD3c0YF23cO1XYaNl5gD3JnCpvHYS/fwRu5tc7pU9sdefm9St5k+P1zH4bH4GVgldwsmBqdjzdiJWLz9wvVPSnHOG6g7sLArNrCwhjDQOEWaqcDPt6Ocfx+YU0/YJFKP+j8A+xK8AHuRvQ28GgkfFO7X70I5egb7us6JxDkmXM+giN8hIU+PwFoZElhrooYy/kbIs5sJg/7qeTY3YM9SVhPzIDpodFg43+BQXpPuVerOiBqBtQzUUDvINDnY8rhQDj/EnpFekXS3Y4O0k4Ma72HbQawZ4fcD6nbjJLt0r4zYXYq9RPvG7M2M5bViLW1JAbA4lKuTQp6XBNvOTZaHYGcFJgCfJgy8DWH7YM9wDfD1ZpS3LiG/Us6MSlE+dgvlYTO1XWHdMNFyZyzNp9i4k1ND/r8V7uNd4bqrsBbDXKwOidaVgrXqKvCD2HHPITKVvDO7tBvQGVx4SIojbn9q+wSTfv1D3OQMg83Y10gOcEAIGxselApskGby+HthsyJKsa//p7AvwkE0MtUU+HaoEN4CDo3ZfXt4sLaZroYNwvxC2P489qW7JWlr8D8zPKRPExkdj7WUfBCupTDinxkqiW+GPDkCaxI+JRKnAGuCrsb6yRX7QvoM+0rMxWbmrAGOiaT7GlZRrccGj0bHc/TBxEgZYS2IRu5no4Ij5PHfwvVPAbpFzjUEa51ZT4p1AbDR7p9glfg/sFUno8f9QUj7r1g6wbpZ7gnnvBZ70S0P5eiWkG+vhfs+JJL2amzA33fD+ffAXp7FMZcfO2fPcN8PS3Edk0ghOELYN7EXTnJqc3yGxTHhfiVn8AyPhT/ItuuJ7BGO952wPRxbRKyaIM6xlpQpmMDaRpBH8n8xtQs9nY59lY9L3sdI3MHYuKfJYb9JgiPE3RXrOlWsLJdjrQSbsKnxhdhz8h6wW+SZ1Ji7K3LMAeE+fTvk3R6RsP+E+CMj5eVXWMtc/JhKGPeCdcXOwATE4mS+Yc9MNVZnfSOk2ULtVOcvYR9PR2EfNFUhP18K1zUcE5vlWDmfQD3raWDi8UtYPfMyjSwJgK2/Uo2JgP2xVthXw/7CcP6iSPzkYNRhEb8TMRGyAqur/xvyKpmPY0K8g7APN6V2plpyLZG9Qt7dtj3vjo7m0m5AZ3BYJZ7qgY66mZH4RYTFhWLHycJaFPaN+Z+KNSXujr1wrse+nrY0cL5DGrH5x9gL74BG4r0Sjvde8gGMhX8Za9YtxwbDZmBdTG8AA1LEv4faGQmloSJKfrFdhbVelGEv7EzsxVWJjRcpCvGyscqxChjdgO2CiZ4a7EvyrIauNZKuKYIjG1vo6efUFTf/DNe2iHqmkzZwzBfDNa3GFjGLt3p8JRw7KcYewl64e0Xi7I8N1C0D7o34Z4Treg4b5LiB2imIUbdnCrtuxcbDtNXzNCbY9vkUYWeEslhK7TTI78TiCNCzkXPkYkLjHuyFsTrk2Vdj8RaF8vfDsJ8UHKncZZHzvxz8lmMva8GESw0mFBMh7oBwPQtCmfoJkZYowjiIyP7UcNw12EybqK03keJLm1qhOiDmsjCh+ggmch+Mnfu3WCuURI6/irqti0XBng3YOJZ/AT8itGJiQuIsrD5YRuqPmzexumwTNo24wQXbIukmYM/gunCPVmH11Y/ix8AGjN4e87sba93oE/Z7Ya1tm6i7MOLBmOA4NOKXE85ZHe51UVNs7uguWVAcpw5iy12P0G0Hq8bjHYtVBq9qPYVJRHpgi2ndF/Z7YwuZNWtZ7jD24kDgGVVdG/H/CvaFqbH4x6jq8zSAiJyKvTSmaGQJ9J0RETkee5G+pin6u8NYh92wcS0NDlQL9zdXUy+T31y7emIvjGO07vLdrYKIXIa1WFzQ2udqLcSWKC8EXlDViuBXAHxObXn3aNxCTMz/bwfPmUhHGZcUy4DXEy9XU4xHCs93CfaMxgesOu0IFxyO4+wwbf0yS9fL03Gc7ccFh+M4juM4rY5Pi3Ucx3Ecp9VxweE4juM4TqtT3+IlbUJRUZEWFxen0wTHcRzHcVqI6dOnr1bVXqnCmiw4RORQbNndfvWEn4tNWcrC/nfgwsaOWVxczLRp05pqguM4juM4OzEisqC+sCZ1qYjINdjiPCmX+xWRsdgaCQdhixp9SUTOab6pjuM4juN0RJokOFT1F9iiTfUxEfuzqJmqugoTH99qAfscx3Ecx+kAtNSg0VHADBE5XUQuxla7G91Cx24WHy/dyISb32DR2tLGIzuO4ziO0ya0lODIw/6Poxhb6XA99p8X2yAi54rINBGZtmrVqlRRdogeBVnMXLaR61/8tPHIjuM4juO0CS0lOEqwf+B7B/tjpB7YevPboKq3qeo4VR3Xq1fKgaw7RL9ueZz5+WIem7GEWctTmuA4juM4ThvTUoJjJrbW/9Oqeif299Mft9Cxm833DhtKYXYmf3x+VrpMcBzHcRwnQksJjgeBM0VkePhjrsuwf/lMCz0KsvnOYbvxwscrmL5gXbrMcBzHcRwnsN2CQ0QuEpH1AKr6DnAl8DYwD/sb7TtaxMLt5KyDh1BUmMM1z87E/y/GcRzHcdJLkwWHqs5X1b6R/atVtXtk/xZV7a6qBar6s/r+qrytKMjJ5IdHDmPqvLW89tnqdJriOI7jOJ2eDv1fKqfuP4iBPfO45tmZ1NR4K4fjOI7jpIsOLTiyMxP89OiRfLR0I5M/WJZucxzHcRyn09KhBQfACXvvyqi+Xbju+VlUVNWk2xzHcRzH6ZR0eMGRSAgXH7c789eU8o835qXbHMdxHMfplHR4wQFw2IheHLV7b256aTYrN5Wl2xzHcRzH6XR0CsEBcNn40ZRXVXPNs74YmOM4juO0NZ1GcBQXFfCtQ4bw8PTFvLtofbrNcRzHcZxORacRHADnHzGcXl1yuPzJj3yarOM4juO0IZ1KcBTmZHLhl0fx7qL1PDZjSbrNcRzHcZxOQ6cSHAAn79ufvQd25+pnZ1JSXpVucxzHcRynU9DpBEciIVx+/GhWbSrnxhc/Tbc5juM4jtMp6HSCA2DfQT2YeMBA7nh9Hh8u2ZBucxzHcRynw9MpBQfARcfuzi6FOVz4yPtUVfsKpI7jOI7TmnRawdEtL4srTtiDj5Zu5E5fgdRxHMdxWpVOKzgAjt2zL0eP7sOfXviUhWtK022O4ziO43RYOrXgEBF+M2FPMhMJLnnsA1R9bQ7HcRzHaQ06teAA6Nstlwu/PJLXZ6/m0Xd8bQ7HcRzHaQ06veAAOO1zgxk7uAe/mfyx/7mb4ziO47QCLjiwtTn+8NW92FJRzYUPv+9dK47jOI7TwrjgCAzr3YWLjx3Fy7NWcd/Uhek2x3Ecx3E6FC44IpxxUDGHDi/it5M/Ye6qknSb4ziO4zgdBhccERIJ4dqv7U12ZoILHnyXSl8QzHEcx3FaBBccMfp2y+V3J+3Fe4s3cNNLs9NtjuM4juN0CFxwpGD8mH6cvG9/bn55Nu8sXJducxzHcRyn3eOCox4un7AHfbvm8qMHZrChtDLd5jiO4zhOu8YFRz10zc3ipm/sy7L1Zfz0oXepqfGpso7jOI6zvbjgaID9BvXg0vG78+InK/nba3PTbY7jOI7jtFtccDTCpM8XM35MP659biZT5qxJtzmO4ziO0y5xwdEIIsIfvjqG4qICzr9/Bis3+tLnjuM4jtNcXHA0gcKcTP562lhKyis5//4ZVPn6HI7jOI7TLFxwNJGRfbvwu5P2Yuq8tVw1+ZN0m+M4juM47YrMdBvQnjh5vwF8uGQjd74xj2G9Czn9wMHpNslxHMdx2gXewtFMLh2/O18c2YtfP/kRr3+2Ot3mOI7jOE67wAVHM8lICH+euC/DehXy/fumM8f/5M1xHMdxGsUFx3bQJTeL288cR1ZGgrPvept1myvSbZLjOI7j7NS44NhOBvbM52/fHMvS9WV8597plFVWp9skx3Ecx9lpccGxA4wr7sm1p4zhrXlr+dEDPl3WcRzHcerDBccOMmGf/vzqK6N57qMVXPrYh6j6f644juM4ThyfFtsCfOuQIawrreCml2bToyCbi44dlW6THMdxHGenwgVHC/GTo0ewdnMFt746h54FWZz7haHpNslxHMdxdhqa1KUiIgeKyBwRKReRySLSLRY+SUQqRGR9xL3fOibvnIgIV07Yk/Fj+vG7p2fywFsL022S4ziO4+w0NCo4RCQfeBS4COgGLAduSRH1UVXtHnFjWtbUnZ+MhHD91/fhsBG9uOjRD7jfRYfjOI7jAE1r4TgCWKKqD6lqGXAJcLKIFLauae2T7MwEf/vmWL44shcXP/oB901dkG6THMdxHCftNEVwjAJmiMgQEZmsqiuApcDwWLyvhq6UD0Xk5yKS8tgicq6ITBORaatWrdpB83dOcrMyuPWbYzlyVG8ufexD/jllfrpNchzHcZy00hTBkQdsBPoDI4LfeqAgEucJoCfQAzgZmABcmOpgqnqbqo5T1XG9evXaXrt3enIyM7jl9P04avc+/PKJj7j7f/PTbZLjOI7jpI2mCI4SbOzGbOC54NcD2JSMoKrrVHWTGp9i3S4TWtrY9kZOZga3nLYfx4zuw6+f/Ii/vPSZr9PhOI7jdEqaIjhmAmNUdbmqnicifYC+mACpjyzA36zYmI6bT9uPk/btzx+f/5TLn/yI6hrPGsdxHKdz0RTB8QowUEQmiEgu8HtsRsrmZAQRGRtmsxrUsN4AABFxSURBVCAio4E/Ave1gr3tkqyMBNedsjfnfmE37p6ygB/eP4PyKv/vFcdxHKfz0KjgUNUtwNeBG7GxHP2A80TkIhFZH6JNAuaJyDrgYeBO4OZWsbidkkgIlxy3O5eN353JHyxj0p1vs7GsMt1mOY7jOE6bIOkcUzBu3DidNm1a2s6fLh6fsYSfPfQew3oX8vczxjGwZ366TXIcx3GcHUZEpqvquFRh/udtaeDEfftz11kHsHT9Fibc/AZT565Jt0mO4ziO06q44EgThwwv4vEfHEz3/CxOu32qr0rqOI7jdGhccKSR3XoV8vgPDubgYUVc/OgH/PqJD6msrkm3WY7jOI7T4rjgSDNdc7O4c9L+nHPoEO6esoCJt73Jsg1b0m2W4ziO47QoLjh2AjISwqXjR3PjqfvwybKNHHfjf3l51sp0m+U4juM4LYYLjp2ICfv058nzD6FP11zO+sfbXPPsTKq8i8VxHMfpALjg2MkYGsZ1TDxgELe8MoeJf3+TRWtL022W4ziO4+wQLjh2QnKzMvj9yXtx46n7MHPZJr58w2s88NZC/x8Wx3Ecp93igmMnZsI+/Xn2gi+w98DuXPToB5x99zRWbixLt1mO4ziO02xccOzk9O+ex71nf47Ljx/NG7NXc8wNr/H4jCXe2uE4juO0K1xwtAMSCWHSwUN4+keHUrxLAT9+8F3OuPMtFqzZ3Hhix3Ecx9kJcMHRjhjaq5BHvvd5fjNhD95duJ5jrn+Nm1+eTUWVz2RxHMdxdm5ccLQzMhLCNw8q5sWfHsZRu/fh2udmMf7P/+X1z1an2zTHcRzHqRcXHO2UPl1zufm0/bhz0jjKqqo5/Y6pfPvut5m7qiTdpjmO4zjONrjgaOccMaoPL1xwGBcdO4o3567lmOtf48qnPmZDaWW6TXMcx3Gcrbjg6ADkZmXw3cOG8vLPDueUcQP4x//m8YVrX+bml2dTWlGVbvMcx3EcB0nn9Mpx48bptGnT0nb+jsrHSzfyx+dn8dLMlRQVZvP9w4fxjc8NIjcrI92mOY7jOB0YEZmuquNShrng6LhMX7CWPz73KVPmrqFft1y+f/hQThk30IWH4ziO0yq44OjkvDF7Ndc9P4t3Fq6nqDCHsw8ZwukHDqJLbla6TXMcx3E6EC44HFSVqfPWcvPLs/nvZ6vpkpvJGQcN5oyDiunTNTfd5jmO4zgdABccTh0+WLyBv746m2c+XE6GCMft1Y9JBxez36Ae6TbNcRzHace44HBSsnBNKXdPmc+/317EpvIq9h7YnTMOHMz4Mf18nIfjOI7TbFxwOA2yubyKR95ZzF1vzGfu6s10yc3kpH37c+r+gxi9a9d0m+c4juO0E1xwOE1CVXlz7loeeHshz3y4nIqqGvYe0I2vjh3A+L36sUthTrpNdBzHcXZiXHA4zWZ9aQWPzVjCg28vYubyTWQmhMNG9OLEfftz1O59yMv2LhfHcRynLi44nB3ik2UbefzdJTwxYynLN5aRn53BEaN6c9xe/Th8ZC/yszPTbaLjOI6zE+CCw2kRqmuUqXPX8NT7y3j+o+Ws2VxBblaCL47szTF79OHwEb3pUZCdbjMdx3GcNOGCw2lxqqpreHv+Op75cBnPfriclZvKSQiMHdyDI0b14cjdezO8dyEikm5THcdxnDbCBYfTqtTUKB8s2cB/Zq7kP5+s4KOlGwHo2zWXQ4cXceiIXhwyrIie3vrhOI7ToXHB4bQpyzeU8fKslbz+2Wpen72aDVsqEYHd+3blwN124XO79eRzQ3rSPd8FiOM4TkfCBYeTNqpD68d/P13FlLlrmL5gHeVVNYjAyD5d2L+4J2MH92Ds4B4M6JHnXTCO4zjtGBcczk5DeVU17y/ewJtz1jB13lpmLFzH5opqAHp1yWG/Qd0ZM6A7ew/ozl4DutEtz/9gznEcp73QkODw+YxOm5KTmcH+xT3Zv7gn52MtILOWb2L6wnW8s2AdMxau47mPVmyNv1tRAXv078Yeu3ZldL+ujN61K0W+AJnjOE67w1s4nJ2ODaWVvL9kPe8v3sB7i9bz0dKNLFm/ZWt47y45jOzbhZF9ujCibxdG9OnC8N6FFOS4fnYcx0kn3sLhtCu65Wdx6PBeHDq811a/DaWVfLRsAx8v3cjHyzby2YoS/vnmAsqrarbG6dctl2G9Cxnaq5ChvQooLiqgeJcCdu2eR0bCx4Y4juOkExccTrugW34Wnx9axOeHFm31q65RFq0tZebyTcxZVcKclSXMXlXCQ9MWbR0XApCdkWBgzzyGFBUwoEc+A3vmM7BHHoN2yad/9zy65Po4EcdxnNbGBYfTbslIiLViFBXU8VdVVmwsZ97qzcxfE9zqzSxYU8qUOWvqiBGArrmZ9O+RT//uufTvnkffbnn065ZLn665W3/9v2Mcx3F2DBccTodDROjbLZe+3XI5aOgudcJUlXWllSxaW8rCtaUsWb+Fpeu3sGTdFhav28LUeWvZVFa1zTG75GbSu0sOfbrm0rtLDr265FBUaK5Xlxx2KcymqDCHHvnZZGcm2upSHcdx2g0uOJxOhYjQsyCbngXZ7D2we8o4m8urWL6xjOUbgttYxqpN5azYWMbKTeVMW7CO1SXllFXWpEzfJTeTXQqy6VGQTY/8bLrnZ9EjP5se+Vl0y8+me14W3fKy6J5vv11zs+iSm0lmhgsVx3E6Lk0SHCJyIHAfMAB4EfiGqm6IxTkX+AOQBdysqhe2sK2O0yYU5GSGgaeF9cZRVTZXVLN6UzmrS8yt2VzB2pIK+91cwbrSClZuKmPW8k2sK62gNNaVs815szPommfio0tuFoU5mWE7k4LsTApzMynMyaQg6bIzyM82v/ycDPKzM8jPyiQvO8NbWRzH2eloVHCISD7wKPAj4CngZuAW4LRInLHAVcBBwBrgBRGZrap/bw2jHSfdiAiFOfayj48hqY/yqmo2bKlkQ2kl6yO/m8oq2bilio1llWzYUklJWRWbyitZX1rBorWlbCqvYnN5VaOCJUpmQsjLziAvK2Prb25WBrlZici27edk2nZOZoKcrAS5mSZYcjIT4Tdj63Z2ZoLsjARZGbXb2ZkJsjKErEiYzwpyHCdOU1o4jgCWqOpDACJyCTBfRApVtSTEmQjcraozQ5yrgJ8CLjgcJ5CTmUHvLhn07pK7Xemra5TNFVWUlFVRWlHF5vJqNoff0goTJKUV1WyJbJdVVrOlspotFfZbXlnD6pIKyiqrKauqZktFDeVV1ZRX1VBRlbqLaHtICGRmJMhKiP1mmCjJzBCyEgkyM4TMRNLPBEpmiJuZkK37GQkhKyNBQmw/EfFPiB0vGpYhQkaCyLaFZ4TwhECGmF9yP7qdIYJI2A5pJRkn+CfDEwlBqN3f+oulSabb+hvi1t2vG3+bYwDE9iWkJZKeZPoQHpLVOX6d+GG7Nl7dNET8HKelaIrgGAXMEJEhwF9UdbyILAWGAzMicf4lIqcDA4F7gdGtYbDjdFYyEkLXXBvz0RrU1CgV1TWUV9ZQXm3ipLzKBElFECQV1TV1tiurlcrgVxnZr6y28Kpqpaq6horwW1Vj4VXVSlWNxa+use2KqhpKK6qpqqmhugaqayx+VYhTo0pVTYhfXUONQlVNDTU14Td9axh2eLaKn637tQIlGb41jIiSaSSOxOKkOnZdQxrcrZM+ansjh0mdLmWcVEY1fvSmpNteebc9unBor0L+dc6B23nG7acpgiMP2Aj0B0YEv/VAQYo4+wCDU4RvJYz1OBdg0KBB22W04zgtTyIh5Case8WGYrUvVJUaZas4qa5RqlWpqUkKFqjR2jCNxE0VVse/RlFMlCX9knGU5H7Sr9YWDeEaOT6RfVVCuMUjckwLs+MQ9UseY2uciF8QXUr02LX70bwikp5IvLh/8tyR3a3niO4nbUoVh5RxGk8fpa4VqeNskyZFpFTJ4tHi52ry+Zpw7KanbEKq7RTZvbtuXyvrjtIUwVECDAJmA88Fvx7AplicbsA7wNIU4VtR1duA28CWNt8uqx3HcWKICBmhK8RxnJ2PpgxlnwmMUdXlqnqeiPQB+mICJB7naVW9EzgA+LjlzXUcx3Ecpz3SFMHxCjBQRCaISC7we+BRVd0cifMgcKaIDBeR3sBlwD9a3FrHcRzHcdoljQoOVd0CfB24ERun0Q84T0QuEpH1Ic47wJXA28A8bK2OO1rLaMdxHMdx2hdp/Xt6EVkFLGilwxcBq1vp2M62eH63LZ7fbYvnd9vi+d32tFSeD1bVXqkC0io4WhMRmaaq49JtR2fB87tt8fxuWzy/2xbP77anLfLc1z92HMdxHKfVccHhOI7jOE6r05EFx23pNqCT4fndtnh+ty2e322L53fb0+p53mHHcDiO4ziOs/PQkVs4HMdxHMfZSXDB4TiO4zhOq9PhBIeIHCgic0SkXEQmi0i3dNvU0RCR74nIUhHZJCIviMjg4P/r4LdeRH6Ubjs7EiKyl4hUiMiosH+uiKwTkRIR+UO67etoiMhEEXlZRFaLyJ+Cn+d5KyAil4b6ZLOITBORQ4K/53cLIiKHisiymF/KPBaRDBG5VURKRWSliPxfixihW//lsP07IB/787hTgFxstdP70m1XR3LAIcBiYCSQga0w+wxwEvAZthLtbsAi4Oh029sRXMjnt7C/lBwFjAVWhu1ewLvAOem2s6M44ELgE+AIIDv4eZ63Tl6fAswKdYaE/XXA5zy/WzSfrwHKgOURv3rLNHAB8D/sT1nHAWuA3XfUjo7WwnEEsERVH1LVMuAS4GQRKUyzXR0JBb6nqrNUtRr4NzAcOA24QVWXqepcbCn8b6XRzo7EBcBmYGHYnwjcraozVXUVcBWe1y2CiOQBlwITVPUlVa0IQZ7nrcNIYLKqzlXjoeB/Dp7fLYaq/gITFlEaKtOnAb9V1Q2qOg24HzhjR+3oaIJjFDBDRIaIyGRVXYG1eAxPs10dBlV9Q1Wfinh9DfgvtXl/qYh8A5gKjE6HjR0JERkKXIxVwMkpZcm8Pl1ELsbzuiXZG6sXnw5dg0+ISF88z1uLh4ATQr7uIyK3AdOxfyT3/G5dGirTybDbRORgWij/O5rgyMP+YK4/MCL4rQcK0mZRB0ZEzsNU8oXU5v2Q4DzfdxAREeDvwDWqOjsSlMzrYqwp2vO65eiLdQd+NWzPBO7B87xVUNVZwF+wNSD+CZwI/BTP77agoTxOhu0Wwlsk/zN39AA7GSXAIGA28Fzw6wFsSptFHZDQ7HwnlrefV9U1IlKC9fe9iY3x8Hzfcc4BugPXxfyTef0O1oLned1ydAPeU9X3AETkMmADMAXP8xZHRE7CmuqLVXWliByGjQmbhed3a9NQPZIMew34ANiHFsj/jiY4ZgKnqupy4DwR6YN9pcxuOJnTTB4E5gDf0DDCCMv7Mar6VwAR+RnwcZrs6yichXUHrrbGDrpig0dfwPL6QgAR+Rqe1y3FBiyfAVDVShEpA+bied4aHAX8S1VXAqjqq2EmRQ2e361Nss5OlcfJsCtD2Lm0RP6ne/RsC4/EzcOU2gRslsqdwL3ptqsjuZC3rxJWqY34n4SN7O8DDMVnqbRG3s/H+lb3A5ZjYqQ3Nrr82+m2ryO4UH7XAPtjsybOC+Xa87x18vtsbDZEn7B/DDZL5QDP7xbP62LqzlKpt0xjA9VfAbqEZ6FFZql0qBYOVd0iIl8H7gV2Bf6DjTFwWo7DsSlr68JXd5IRwCNYy0c1cKWqvtDm1nUCVPUdEbkSeBvIAv6KTQF3dhBVXSEiZwP/wuqQT4D/U9X3Pc9bhTuBAcC7ItIVmAecpqpveX63Lo3UI38G9sSmzZYA56vqJzt6Tv8vFcdxHMdxWp2ONkvFcRzHcZydEBccjuM4juO0Oi44HMdxHMdpdVxwOI7jOI7T6rjgcBzHcRyn1XHB4TiO4zhOq+OCw3Ecx3GcVscFh+M4juM4rc7/BzbuaYpvh/1VAAAAAElFTkSuQmCC\n",
"text/plain": [
"<Figure size 648x144 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"pe というテンソルの i 個目の偶数番目と奇数番目に減衰する正弦波と余弦波が用意される\n",
"torch.Size([5000, 200])\n",
"tensor([[ 0.0000, 1.0000, 0.0000, 1.0000],\n",
" [ 0.8415, 0.5403, 0.7907, 0.6122],\n",
" [ 0.9093, -0.4161, 0.9681, -0.2505]])\n",
"tensor([[ 0.9563, -0.2925, 0.9055, -0.4243],\n",
" [ 0.2705, -0.9627, 0.2192, -0.9757],\n",
" [-0.6639, -0.7478, -0.6374, -0.7705]])\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 648x288 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"pe というテンソルはこうなる\n",
"torch.Size([5000, 1, 200])\n",
"tensor([[[ 0.0000, 1.0000, 0.0000, 1.0000]],\n",
"\n",
" [[ 0.8415, 0.5403, 0.7907, 0.6122]],\n",
"\n",
" [[ 0.9093, -0.4161, 0.9681, -0.2505]]])\n",
"tensor([[[ 0.9563, -0.2925, 0.9055, -0.4243]],\n",
"\n",
" [[ 0.2705, -0.9627, 0.2192, -0.9757]],\n",
"\n",
" [[-0.6639, -0.7478, -0.6374, -0.7705]]])\n",
"\n",
"◆ PositionalEncoder に単語列を埋め込んだテンソルを流してみる\n",
"◇ 訓練データの 0~34 個目の単語列\n",
"torch.Size([35, 20])\n",
"◇ 訓練データの 0~34 個目の単語列を200次元に埋め込み\n",
" (各単語列長は本当は20だが、5だけ表示)\n",
" (各単語の次元は本当は200だが、4だけ表示)\n",
"torch.Size([35, 20, 200])\n",
"tensor([[ 0.1248, 0.0463, 0.9071, -0.4357],\n",
" [-1.1538, -1.9721, 0.0941, -1.3863],\n",
" [ 2.2940, 1.2065, 0.6837, -1.8190],\n",
" [ 1.1506, 0.5202, 0.5958, 2.0696],\n",
" [-0.0296, -0.7435, 0.1943, 0.9146]], grad_fn=<SliceBackward>) 単語列0\n",
"tensor([[-0.0889, 2.2797, -0.9817, -0.5639],\n",
" [ 1.3507, -0.5374, -0.4463, -1.1063],\n",
" [-0.0830, 1.2043, -0.6070, 1.6978],\n",
" [-0.8962, 2.1992, 0.9791, 0.0878],\n",
" [-0.6931, -1.2100, 1.3738, -0.9831]], grad_fn=<SliceBackward>) 単語列1\n",
"tensor([[ 9.7651e-01, 5.0865e-01, -1.3232e+00, -1.2150e+00],\n",
" [ 7.5843e-01, 1.4521e+00, -1.0745e+00, 1.5824e-03],\n",
" [-1.4427e-02, -3.1398e-01, -1.7494e-01, 3.2904e-01],\n",
" [-1.1697e+00, -2.6854e-01, 8.9997e-02, 2.1359e+00],\n",
" [-5.5698e-01, -3.9223e-02, 1.7132e+00, -4.5476e-02]],\n",
" grad_fn=<SliceBackward>) 単語列2\n",
"◇ 訓練データの 0~34 個目の単語列を200次元に埋め込みして PositionalEncoding\n",
"torch.Size([35, 20, 200])\n",
"tensor([[ 0.1248, 1.0463, 0.9071, 0.5643],\n",
" [-1.1538, -0.9721, 0.0941, -0.3863],\n",
" [ 2.2940, 2.2065, 0.6837, -0.8190],\n",
" [ 1.1506, 1.5202, 0.5958, 3.0696],\n",
" [-0.0296, 0.2565, 0.1943, 1.9146]], grad_fn=<SliceBackward>) 単語列0\n",
"tensor([[ 0.7525, 2.8200, -0.1910, 0.0482],\n",
" [ 2.1922, 0.0029, 0.3444, -0.4941],\n",
" [ 0.7585, 1.7446, 0.1837, 2.3100],\n",
" [-0.0547, 2.7395, 1.7699, 0.6999],\n",
" [ 0.1483, -0.6697, 2.1645, -0.3710]], grad_fn=<SliceBackward>) 単語列1\n",
"tensor([[ 1.8858, 0.0925, -0.3551, -1.4655],\n",
" [ 1.6677, 1.0360, -0.1064, -0.2489],\n",
" [ 0.8949, -0.7301, 0.7932, 0.0785],\n",
" [-0.2604, -0.6847, 1.0581, 1.8854],\n",
" [ 0.3523, -0.4554, 2.6813, -0.2960]], grad_fn=<SliceBackward>) 単語列2\n"
]
}
],
"source": [
"import math\n",
"import torch.nn as nn\n",
"import torch.nn.functional as F\n",
"\n",
"%matplotlib inline\n",
"import matplotlib.pyplot as plt\n",
"from pylab import rcParams\n",
"rcParams['figure.figsize'] = 9, 4\n",
"rcParams['font.size'] = 12\n",
"rcParams['font.family']='Ume Hy Gothic O5'\n",
"\n",
"print('◆ モデル本体より先に、PositionalEncoding という単語列を埋め込んだテンソルに少しプレ処理する機能を用意する')\n",
"\n",
"class PositionalEncoding(nn.Module):\n",
"\n",
" def __init__(self, d_model, dropout=0.1, max_len=5000, debug=False):\n",
" super(PositionalEncoding, self).__init__()\n",
" self.dropout = nn.Dropout(p=dropout)\n",
" pe = torch.zeros(max_len, d_model)\n",
" position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1) # [[0], [1], ..., [4999]]\n",
" div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))\n",
" if debug:\n",
" print('埋め込み次元数の半分の長さ(100)まで指数的に減衰する成分が用意される')\n",
" print(div_term[:6])\n",
" print(div_term[94:])\n",
" fig, ax = plt.subplots(1, 1, sharex='col', figsize=(9, 2))\n",
" ax.set_title('埋め込み次元数の半分の長さ(100)まで指数的に減衰する成分')\n",
" ax.plot(div_term)\n",
" plt.show()\n",
" pe[:, 0::2] = torch.sin(position * div_term)\n",
" pe[:, 1::2] = torch.cos(position * div_term)\n",
" if debug:\n",
" print('pe というテンソルの i 個目の偶数番目と奇数番目に減衰する正弦波と余弦波が用意される')\n",
" print(pe.size())\n",
" print(pe[:3,:4])\n",
" print(pe[4997:,:4]) \n",
" fig, ax = plt.subplots(2, 1, sharex='col', figsize=(9, 4))\n",
" ax[0].set_title('pe の i 個目の偶数番目(本当は5000個まで用意される)')\n",
" ax[1].set_title('pe の i 個目の奇数番目(本当は5000個まで用意される)')\n",
" for i in range(10):\n",
" ax[0].plot(pe[i, 0::2])\n",
" ax[1].plot(pe[i, 1::2])\n",
" plt.show()\n",
" pe = pe.unsqueeze(0).transpose(0, 1)\n",
" if debug:\n",
" print('pe というテンソルはこうなる')\n",
" print(pe.size())\n",
" print(pe[:3,:,:4])\n",
" print(pe[4997:,:,:4]) \n",
" self.register_buffer('pe', pe)\n",
"\n",
" def forward(self, x):\n",
" x = x + self.pe[:x.size(0), :]\n",
" return self.dropout(x)\n",
"\n",
"pos_encoder = PositionalEncoding(d_model=200, dropout=0.0, debug=True)\n",
"\n",
"print('\\n◆ PositionalEncoder に単語列を埋め込んだテンソルを流してみる')\n",
"encoder = nn.Embedding(28785, 200)\n",
"print('◇ 訓練データの 0~34 個目の単語列')\n",
"print(data.size())\n",
"data_encoded = encoder(data)\n",
"print('◇ 訓練データの 0~34 個目の単語列を200次元に埋め込み')\n",
"print(' (各単語列長は本当は20だが、5だけ表示)')\n",
"print(' (各単語の次元は本当は200だが、4だけ表示)')\n",
"print(data_encoded.size())\n",
"print(data_encoded[0, :5, :4], '単語列0')\n",
"print(data_encoded[1, :5, :4], '単語列1')\n",
"print(data_encoded[2, :5, :4], '単語列2')\n",
"data_pos_encoded = pos_encoder.forward(data_encoded)\n",
"print('◇ 訓練データの 0~34 個目の単語列を200次元に埋め込みして PositionalEncoding')\n",
"print(data_pos_encoded.size())\n",
"print(data_pos_encoded[0, :5, :4], '単語列0')\n",
"print(data_pos_encoded[1, :5, :4], '単語列1')\n",
"print(data_pos_encoded[2, :5, :4], '単語列2')"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"単語列0の各単語には [ 0.0000, 1.0000, 0.0000, 1.0000, ...] というベクトルが足される.\n",
"単語列1の各単語には [ 0.8415, 0.5403, 0.7907, 0.6122, ...] というベクトルが足される.\n",
"単語列2の各単語には [ 0.9093, -0.4161, 0.9681, -0.2505, ...] というベクトルが足される.\n",
"バッチ内で何番目の単語列かによって、後の方ほど振動数が大きい正弦波/余弦波を単語に上乗せするのが PositionalEncoding.\n",
"※ バッチ内で何番目の単語列かという情報を振動数が違う正弦波/余弦波で表現するのはあくまでこのチュートリアルが採用した方法であり他の方法でもよい.\n"
]
}
],
"source": [
"print('単語列0の各単語には [ 0.0000, 1.0000, 0.0000, 1.0000, ...] というベクトルが足される.')\n",
"print('単語列1の各単語には [ 0.8415, 0.5403, 0.7907, 0.6122, ...] というベクトルが足される.')\n",
"print('単語列2の各単語には [ 0.9093, -0.4161, 0.9681, -0.2505, ...] というベクトルが足される.')\n",
"print('バッチ内で何番目の単語列かによって、後の方ほど振動数が大きい正弦波/余弦波を単語に上乗せするのが PositionalEncoding.')\n",
"print('※ バッチ内で何番目の単語列かという情報を振動数が違う正弦波/余弦波で表現するのはあくまでこのチュートリアルが採用した方法であり他の方法でもよい.')"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"◆ モデル本体を用意する\n",
"TransformerEncoderLayer = 2HeadAttention + 200次元の隠れ層が1層のFFN\n",
"今回のモデル = エンコーダ + PositionalEncoder + TransformerEncoderLayerその0 + TransformerEncoderLayerその1 + デコーダ\n",
"\n",
"◆ 今回学習するパラメータたち(TransformerEncoderLayerその0、TransformerEncoderLayerその1、エンコーダ、デコーダ)\n",
"transformer_encoder.layers.0.self_attn.in_proj_weight torch.Size([600, 200])\n",
"transformer_encoder.layers.0.self_attn.in_proj_bias torch.Size([600])\n",
"transformer_encoder.layers.0.self_attn.out_proj.weight torch.Size([200, 200])\n",
"transformer_encoder.layers.0.self_attn.out_proj.bias torch.Size([200])\n",
"transformer_encoder.layers.0.linear1.weight torch.Size([200, 200])\n",
"transformer_encoder.layers.0.linear1.bias torch.Size([200])\n",
"transformer_encoder.layers.0.linear2.weight torch.Size([200, 200])\n",
"transformer_encoder.layers.0.linear2.bias torch.Size([200])\n",
"transformer_encoder.layers.0.norm1.weight torch.Size([200])\n",
"transformer_encoder.layers.0.norm1.bias torch.Size([200])\n",
"transformer_encoder.layers.0.norm2.weight torch.Size([200])\n",
"transformer_encoder.layers.0.norm2.bias torch.Size([200])\n",
"transformer_encoder.layers.1.self_attn.in_proj_weight torch.Size([600, 200])\n",
"transformer_encoder.layers.1.self_attn.in_proj_bias torch.Size([600])\n",
"transformer_encoder.layers.1.self_attn.out_proj.weight torch.Size([200, 200])\n",
"transformer_encoder.layers.1.self_attn.out_proj.bias torch.Size([200])\n",
"transformer_encoder.layers.1.linear1.weight torch.Size([200, 200])\n",
"transformer_encoder.layers.1.linear1.bias torch.Size([200])\n",
"transformer_encoder.layers.1.linear2.weight torch.Size([200, 200])\n",
"transformer_encoder.layers.1.linear2.bias torch.Size([200])\n",
"transformer_encoder.layers.1.norm1.weight torch.Size([200])\n",
"transformer_encoder.layers.1.norm1.bias torch.Size([200])\n",
"transformer_encoder.layers.1.norm2.weight torch.Size([200])\n",
"transformer_encoder.layers.1.norm2.bias torch.Size([200])\n",
"encoder.weight torch.Size([28785, 200])\n",
"decoder.weight torch.Size([28785, 200])\n",
"decoder.bias torch.Size([28785])\n",
"\n",
"◆ モデルに単語列を流してみる\n",
"◇ 訓練データの 0~34 個目の単語列を流す\n",
"torch.Size([35, 20])\n",
"tensor([ 3, 25, 1849, 570, 7]) 単語列0\n",
"tensor([632, 4, 127, 6, 3]) 単語列34\n",
"----- TransformerEncoder層でこんなマスクをつかうよ -----\n",
"TransformerEncoder層は入力側の単語空間から出力側の単語空間への写像であるはずである.\n",
"1バッチ目の学習で 0~34 個目の単語列を流すが、0個目の単語列を写像するときに\n",
"1~34 個目の単語列を利用しないようにするためにマスクする必要がある.\n",
"具体的に、負の無限大をいれておくことで未来の単語列由来の Attention が発生しないようにしていると思う.\n",
"torch.Size([35, 35])\n",
"tensor([[0., -inf, -inf, -inf, -inf],\n",
" [0., 0., -inf, -inf, -inf],\n",
" [0., 0., 0., -inf, -inf],\n",
" [0., 0., 0., 0., -inf],\n",
" [0., 0., 0., 0., 0.]])\n",
"--------------------------------------------------------\n",
"----- 各単語を埋め込んだよ -----\n",
"torch.Size([35, 20, 200])\n",
"tensor([[-0.6279, -0.6731, -1.0157, 0.6879],\n",
" [ 1.3091, 0.7319, -0.1179, 0.0892],\n",
" [-0.2110, 0.7331, -1.1495, 1.0249],\n",
" [ 0.3094, 1.3982, 1.0791, 0.5063],\n",
" [ 0.1669, 0.1000, -0.5802, 0.2259]], grad_fn=<SliceBackward>) 単語列0\n",
"tensor([[ 0.9145, -0.9085, 1.1073, 0.1067],\n",
" [-1.0746, 0.4230, 0.5442, -1.2081],\n",
" [ 0.7832, 1.1152, -0.8875, -1.2305],\n",
" [ 0.0801, 0.5733, 1.1932, 1.3263],\n",
" [-0.6279, -0.6731, -1.0157, 0.6879]], grad_fn=<SliceBackward>) 単語列34\n",
"--------------------------------\n",
"----- PositionalEncoding したよ -----\n",
"torch.Size([35, 20, 200])\n",
"tensor([[-0.7849, 0.4086, -0.0000, 2.1098],\n",
" [ 0.0000, 0.0000, -0.1474, 1.3615],\n",
" [-0.2637, 2.1664, -1.4369, 2.5311],\n",
" [ 0.3867, 2.9978, 1.3488, 1.8829],\n",
" [ 0.0000, 1.3750, -0.7252, 1.5324]], grad_fn=<SliceBackward>) 単語列0\n",
"tensor([[ 1.8045, -2.1964, 0.8887, 1.2809],\n",
" [-0.6819, -0.5320, 0.1848, -0.3626],\n",
" [ 1.6403, 0.0000, -1.6049, -0.3905],\n",
" [ 0.7614, -0.3440, 0.9961, 2.8055],\n",
" [-0.1235, -1.9021, -1.7650, 2.0074]], grad_fn=<SliceBackward>) 単語列34\n",
"-------------------------------------\n",
"----- TransformerEncoder層に通したよ -----\n",
"torch.Size([35, 20, 200])\n",
"tensor([[-0.1566, 0.1365, -0.2389, -1.1040],\n",
" [-0.8418, -0.6476, -0.3431, 1.2286],\n",
" [-1.0668, 0.8735, -1.5316, 1.1909],\n",
" [ 0.0748, 0.6588, -1.0968, 0.5347],\n",
" [-0.4703, -0.2646, -1.3832, 0.0422]], grad_fn=<SliceBackward>) 単語列0につづくことが期待される単語列(埋め込み版)\n",
"tensor([[ 1.1223, -2.0096, 0.2688, 0.4822],\n",
" [-0.6019, -0.7603, -0.3600, -0.4463],\n",
" [ 1.2852, -0.4725, -1.2806, -0.6672],\n",
" [ 0.1246, -0.1841, 0.5772, 1.0651],\n",
" [ 0.8009, -2.0562, -1.0535, 1.3696]], grad_fn=<SliceBackward>) 単語列34につづくことが期待される単語列(埋め込み版)\n",
"------------------------------------------\n",
"----- 200次元の単語空間から28785個の単語上の確率分布に戻すよ(モデル内でSoftmaxまではしない) -----\n",
"torch.Size([35, 20, 28785])\n",
"tensor([[ 0.7065, 0.0610, 0.6539, 0.3053],\n",
" [-0.0994, -1.2828, -0.5313, 0.8495],\n",
" [ 0.2614, 0.1559, 1.2580, 0.2775],\n",
" [ 0.1664, -0.2835, -0.3288, 1.1031],\n",
" [-0.2702, 0.2202, 1.8064, -0.3899]], grad_fn=<SliceBackward>) 単語列0につづくことが期待される単語列(単語上の分布版)\n",
"tensor([[ 0.4869, -0.3151, 0.5294, 0.1446],\n",
" [-0.0557, -0.9696, -0.8336, 0.3696],\n",
" [ 0.5967, -0.5712, 0.8610, 0.3025],\n",
" [ 0.2908, 0.0891, 0.0876, -0.0476],\n",
" [ 1.3940, -0.4024, 0.5641, 0.7353]], grad_fn=<SliceBackward>) 単語列34につづくことが期待される単語列(単語上の分布版)\n",
"---------------------------------------------------------------------------------------------------\n",
"\n",
"◇ 単語列0につづくことが期待される予測単語列\n",
"[26292, 24561, 17166, 1744, 10627, 4781, 12237, 21242, 27323, 4728, 27100, 25329, 21128, 25945, 12959, 25505, 9062, 4781, 22295, 2187]\n",
"単語列に翻訳すると\n",
"['kreutzer', 'campanian', 'henriette', 'onto', 'pageant', 'numbered', 'berardi', 'delineated', 'pyramids', '1903', 'pentominoes', 'erwin', 'conformational', 'hxg4', '560', 'fleas', 'allegedly', 'numbered', 'mira', 'jane']\n"
]
}
],
"source": [
"print('◆ モデル本体を用意する')\n",
"\n",
"print('TransformerEncoderLayer = 2HeadAttention + 200次元の隠れ層が1層のFFN')\n",
"print('今回のモデル = エンコーダ + PositionalEncoder + TransformerEncoderLayerその0 + TransformerEncoderLayerその1 + デコーダ')\n",
"\n",
"class TransformerModel(nn.Module):\n",
" # ntoken : 語彙数\n",
" # ninp : 埋め込む次元\n",
" def __init__(self, ntoken, ninp, nhead, nhid, nlayers, dropout=0.5):\n",
" super(TransformerModel, self).__init__()\n",
" from torch.nn import TransformerEncoder, TransformerEncoderLayer\n",
" self.model_type = 'Transformer'\n",
" self.src_mask = None\n",
" self.pos_encoder = PositionalEncoding(ninp, dropout) # さっきの PositionalEncoder\n",
" encoder_layers = TransformerEncoderLayer(ninp, nhead, nhid, dropout)\n",
" self.transformer_encoder = TransformerEncoder(encoder_layers, nlayers)\n",
" self.encoder = nn.Embedding(ntoken, ninp)\n",
" self.ninp = ninp\n",
" self.decoder = nn.Linear(ninp, ntoken)\n",
" self.init_weights()\n",
"\n",
" def _generate_square_subsequent_mask(self, sz, debug=False):\n",
" mask = (torch.triu(torch.ones(sz, sz)) == 1).transpose(0, 1)\n",
" mask = mask.float().masked_fill(mask == 0, float('-inf')).masked_fill(mask == 1, float(0.0))\n",
" if debug:\n",
" print('----- TransformerEncoder層でこんなマスクをつかうよ -----')\n",
" print('TransformerEncoder層は入力側の単語空間から出力側の単語空間への写像であるはずである.')\n",
" print('1バッチ目の学習で 0~34 個目の単語列を流すが、0個目の単語列を写像するときに')\n",
" print('1~34 個目の単語列を利用しないようにするためにマスクする必要がある.')\n",
" print('具体的に、負の無限大をいれておくことで未来の単語列由来の Attention が発生しないようにしていると思う.')\n",
" print(mask.size())\n",
" print(mask[:5,:5])\n",
" print('--------------------------------------------------------')\n",
" return mask\n",
"\n",
" def init_weights(self):\n",
" initrange = 0.1\n",
" self.encoder.weight.data.uniform_(-initrange, initrange)\n",
" self.decoder.bias.data.zero_()\n",
" self.decoder.weight.data.uniform_(-initrange, initrange)\n",
"\n",
" def forward(self, src, debug=False):\n",
" if self.src_mask is None or self.src_mask.size(0) != len(src):\n",
" device = src.device\n",
" mask = self._generate_square_subsequent_mask(len(src), debug).to(device)\n",
" self.src_mask = mask\n",
" src = self.encoder(src) * math.sqrt(self.ninp)\n",
" if debug:\n",
" print('----- 各単語を埋め込んだよ -----')\n",
" print(src.size())\n",
" print(src[0, :5, :4], '単語列0')\n",
" print(src[34, :5, :4], '単語列34')\n",
" print('--------------------------------')\n",
" src = self.pos_encoder(src)\n",
" if debug:\n",
" print('----- PositionalEncoding したよ -----')\n",
" print(src.size())\n",
" print(src[0, :5, :4], '単語列0')\n",
" print(src[34, :5, :4], '単語列34')\n",
" print('-------------------------------------')\n",
" output = self.transformer_encoder(src, self.src_mask)\n",
" if debug:\n",
" print('----- TransformerEncoder層に通したよ -----')\n",
" print(output.size())\n",
" print(output[0, :5, :4], '単語列0につづくことが期待される単語列(埋め込み版)')\n",
" print(output[34, :5, :4], '単語列34につづくことが期待される単語列(埋め込み版)')\n",
" print('------------------------------------------')\n",
" output = self.decoder(output)\n",
" if debug:\n",
" print('----- 200次元の単語空間から28785個の単語上の確率分布に戻すよ(モデル内でSoftmaxまではしない) -----')\n",
" print(output.size())\n",
" print(output[0, :5, :4], '単語列0につづくことが期待される単語列(単語上の分布版)')\n",
" print(output[34, :5, :4], '単語列34につづくことが期待される単語列(単語上の分布版)')\n",
" print('---------------------------------------------------------------------------------------------------')\n",
" return output\n",
" \n",
"ntokens = len(TEXT.vocab.stoi) # 訓練データの語彙数(上述)\n",
"emsize = 200 # 単語を埋め込む次元\n",
"nhid = 200 # TransformerEncoder層の FFN の隠れ層の次元\n",
"nlayers = 2 # TransformerEncoder層を何層重ねるか\n",
"nhead = 2 # TransformerEncoder層内のMultiHeadAttention層のヘッド数\n",
"dropout = 0.2\n",
"\n",
"model = TransformerModel(ntokens, emsize, nhead, nhid, nlayers, dropout).to('cpu')\n",
"\n",
"print('\\n◆ 今回学習するパラメータたち(TransformerEncoderLayerその0、TransformerEncoderLayerその1、エンコーダ、デコーダ)')\n",
"for name, param in model.named_parameters():\n",
" print(name.ljust(14), param.size())\n",
" \n",
"print('\\n◆ モデルに単語列を流してみる')\n",
"print('◇ 訓練データの 0~34 個目の単語列を流す')\n",
"print(data.size())\n",
"print(data[0, :5], '単語列0')\n",
"print(data[34, :5], '単語列34')\n",
"output = model.forward(data, debug=True)\n",
"model.zero_grad()\n",
"\n",
"print('\\n◇ 単語列0につづくことが期待される予測単語列')\n",
"pred0 = [torch.max(output[:1, i, :], 1)[1].item() for i in range(20)] # max index をとる\n",
"print(pred0)\n",
"print('単語列に翻訳すると')\n",
"print([TEXT.vocab.itos[i] for i in pred0])"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"◆ 損失は交差エントロピー\n",
"◆ 訓練する\n",
"| epoch 1 | 200/ 2981 batches | lr 5.00 | ms/batch 339.02 | loss 7.99 | ppl 2964.75\n",
"| epoch 1 | 400/ 2981 batches | lr 5.00 | ms/batch 331.12 | loss 6.78 | ppl 880.85\n",
"| epoch 1 | 600/ 2981 batches | lr 5.00 | ms/batch 330.54 | loss 6.36 | ppl 578.69\n",
"| epoch 1 | 800/ 2981 batches | lr 5.00 | ms/batch 330.58 | loss 6.22 | ppl 504.51\n",
"| epoch 1 | 1000/ 2981 batches | lr 5.00 | ms/batch 332.90 | loss 6.11 | ppl 451.92\n",
"| epoch 1 | 1200/ 2981 batches | lr 5.00 | ms/batch 331.87 | loss 6.09 | ppl 440.12\n",
"| epoch 1 | 1400/ 2981 batches | lr 5.00 | ms/batch 337.76 | loss 6.05 | ppl 422.34\n",
"| epoch 1 | 1600/ 2981 batches | lr 5.00 | ms/batch 341.21 | loss 6.05 | ppl 424.50\n",
"| epoch 1 | 1800/ 2981 batches | lr 5.00 | ms/batch 340.24 | loss 5.97 | ppl 389.90\n",
"| epoch 1 | 2000/ 2981 batches | lr 5.00 | ms/batch 344.83 | loss 5.96 | ppl 386.73\n",
"| epoch 1 | 2200/ 2981 batches | lr 5.00 | ms/batch 345.09 | loss 5.85 | ppl 347.05\n",
"| epoch 1 | 2400/ 2981 batches | lr 5.00 | ms/batch 346.63 | loss 5.90 | ppl 363.87\n",
"| epoch 1 | 2600/ 2981 batches | lr 5.00 | ms/batch 349.56 | loss 5.91 | ppl 366.96\n",
"| epoch 1 | 2800/ 2981 batches | lr 5.00 | ms/batch 354.65 | loss 5.81 | ppl 332.75\n",
"-----------------------------------------------------------------------------------------\n",
"| end of epoch 1 | time: 1061.99s | valid loss 5.70 | valid ppl 300.33\n",
"-----------------------------------------------------------------------------------------\n",
"| epoch 2 | 200/ 2981 batches | lr 4.51 | ms/batch 364.47 | loss 5.81 | ppl 333.28\n",
"| epoch 2 | 400/ 2981 batches | lr 4.51 | ms/batch 361.44 | loss 5.77 | ppl 321.51\n",
"| epoch 2 | 600/ 2981 batches | lr 4.51 | ms/batch 360.41 | loss 5.60 | ppl 271.70\n",
"| epoch 2 | 800/ 2981 batches | lr 4.51 | ms/batch 363.80 | loss 5.64 | ppl 281.70\n",
"| epoch 2 | 1000/ 2981 batches | lr 4.51 | ms/batch 368.53 | loss 5.59 | ppl 267.25\n",
"| epoch 2 | 1200/ 2981 batches | lr 4.51 | ms/batch 362.11 | loss 5.62 | ppl 276.96\n",
"| epoch 2 | 1400/ 2981 batches | lr 4.51 | ms/batch 365.81 | loss 5.63 | ppl 278.81\n",
"| epoch 2 | 1600/ 2981 batches | lr 4.51 | ms/batch 365.77 | loss 5.66 | ppl 288.42\n",
"| epoch 2 | 1800/ 2981 batches | lr 4.51 | ms/batch 363.54 | loss 5.59 | ppl 266.53\n",
"| epoch 2 | 2000/ 2981 batches | lr 4.51 | ms/batch 365.22 | loss 5.61 | ppl 272.91\n",
"| epoch 2 | 2200/ 2981 batches | lr 4.51 | ms/batch 365.55 | loss 5.51 | ppl 246.89\n",
"| epoch 2 | 2400/ 2981 batches | lr 4.51 | ms/batch 365.03 | loss 5.57 | ppl 261.77\n",
"| epoch 2 | 2600/ 2981 batches | lr 4.51 | ms/batch 361.33 | loss 5.58 | ppl 265.62\n",
"| epoch 2 | 2800/ 2981 batches | lr 4.51 | ms/batch 362.20 | loss 5.51 | ppl 247.59\n",
"-----------------------------------------------------------------------------------------\n",
"| end of epoch 2 | time: 1131.27s | valid loss 5.55 | valid ppl 256.85\n",
"-----------------------------------------------------------------------------------------\n",
"| epoch 3 | 200/ 2981 batches | lr 4.29 | ms/batch 365.98 | loss 5.55 | ppl 256.72\n",
"| epoch 3 | 400/ 2981 batches | lr 4.29 | ms/batch 363.26 | loss 5.55 | ppl 258.13\n",
"| epoch 3 | 600/ 2981 batches | lr 4.29 | ms/batch 362.61 | loss 5.36 | ppl 212.86\n",
"| epoch 3 | 800/ 2981 batches | lr 4.29 | ms/batch 365.65 | loss 5.42 | ppl 224.78\n",
"| epoch 3 | 1000/ 2981 batches | lr 4.29 | ms/batch 365.14 | loss 5.38 | ppl 217.48\n",
"| epoch 3 | 1200/ 2981 batches | lr 4.29 | ms/batch 365.68 | loss 5.42 | ppl 225.63\n",
"| epoch 3 | 1400/ 2981 batches | lr 4.29 | ms/batch 360.36 | loss 5.44 | ppl 229.99\n",
"| epoch 3 | 1600/ 2981 batches | lr 4.29 | ms/batch 358.62 | loss 5.48 | ppl 239.10\n",
"| epoch 3 | 1800/ 2981 batches | lr 4.29 | ms/batch 357.22 | loss 5.41 | ppl 223.48\n",
"| epoch 3 | 2000/ 2981 batches | lr 4.29 | ms/batch 354.21 | loss 5.44 | ppl 229.41\n",
"| epoch 3 | 2200/ 2981 batches | lr 4.29 | ms/batch 355.91 | loss 5.32 | ppl 205.04\n",
"| epoch 3 | 2400/ 2981 batches | lr 4.29 | ms/batch 353.65 | loss 5.40 | ppl 221.81\n",
"| epoch 3 | 2600/ 2981 batches | lr 4.29 | ms/batch 354.29 | loss 5.42 | ppl 225.57\n",
"| epoch 3 | 2800/ 2981 batches | lr 4.29 | ms/batch 358.52 | loss 5.35 | ppl 209.82\n",
"-----------------------------------------------------------------------------------------\n",
"| end of epoch 3 | time: 1112.92s | valid loss 5.47 | valid ppl 237.13\n",
"-----------------------------------------------------------------------------------------\n",
"=========================================================================================\n",
"| End of training | test loss 5.38 | test ppl 216.82\n",
"=========================================================================================\n"
]
}
],
"source": [
"print('◆ 損失は交差エントロピー')\n",
"criterion = nn.CrossEntropyLoss()\n",
"lr = 5.0 # learning rate\n",
"optimizer = torch.optim.SGD(model.parameters(), lr=lr)\n",
"scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 1.0, gamma=0.95)\n",
"\n",
"import time\n",
"def train(debug=False):\n",
" model.train() # Turn on the train mode\n",
" total_loss = 0.\n",
" start_time = time.time()\n",
" ntokens = len(TEXT.vocab.stoi)\n",
" for batch, i in enumerate(range(0, train_data.size(0) - 1, bptt)):\n",
" data, targets = get_batch(train_data, i)\n",
" optimizer.zero_grad()\n",
" output = model(data)\n",
" loss = criterion(output.view(-1, ntokens), targets)\n",
" loss.backward()\n",
" torch.nn.utils.clip_grad_norm_(model.parameters(), 0.5)\n",
" optimizer.step()\n",
" total_loss += loss.item()\n",
" if batch % 200 == 0 and batch > 0:\n",
" cur_loss = total_loss / 200\n",
" elapsed = time.time() - start_time\n",
" print('| epoch {:3d} | {:5d}/{:5d} batches | '\n",
" 'lr {:02.2f} | ms/batch {:5.2f} | '\n",
" 'loss {:5.2f} | ppl {:8.2f}'.format(\n",
" epoch, batch, len(train_data) // bptt, scheduler.get_lr()[0],\n",
" elapsed * 1000 / 200,\n",
" cur_loss, math.exp(cur_loss)))\n",
" total_loss = 0\n",
" start_time = time.time()\n",
" if debug:\n",
" if batch == 400:\n",
" break\n",
"\n",
"def evaluate(eval_model, data_source):\n",
" eval_model.eval() # Turn on the evaluation mode\n",
" total_loss = 0.\n",
" ntokens = len(TEXT.vocab.stoi)\n",
" with torch.no_grad():\n",
" for i in range(0, data_source.size(0) - 1, bptt):\n",
" data, targets = get_batch(data_source, i)\n",
" output = eval_model(data)\n",
" output_flat = output.view(-1, ntokens)\n",
" total_loss += len(data) * criterion(output_flat, targets).item()\n",
" return total_loss / (len(data_source) - 1)\n",
"\n",
"print('◆ 訓練する')\n",
"best_val_loss = float(\"inf\")\n",
"epochs = 3 # The number of epochs\n",
"best_model = None\n",
"for epoch in range(1, epochs + 1):\n",
" epoch_start_time = time.time()\n",
" train(debug=False)\n",
" val_loss = evaluate(model, val_data)\n",
" print('-' * 89)\n",
" print('| end of epoch {:3d} | time: {:5.2f}s | valid loss {:5.2f} | '\n",
" 'valid ppl {:8.2f}'.format(epoch, (time.time() - epoch_start_time), val_loss, math.exp(val_loss)))\n",
" print('-' * 89)\n",
" if val_loss < best_val_loss:\n",
" best_val_loss = val_loss\n",
" best_model = model\n",
" scheduler.step()\n",
" \n",
"test_loss = evaluate(best_model, test_data)\n",
"print('=' * 89)\n",
"print('| End of training | test loss {:5.2f} | test ppl {:8.2f}'.format(test_loss, math.exp(test_loss)))\n",
"print('=' * 89)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"◇ 単語列0につづくことが期待される予測単語列\n",
"[12, 6, 5, 1519, 4, 8, 8, 21, 40, 13, 5, 4, 3, 9, 40, 0, 3, 8, 36, 40]\n",
"単語列に翻訳すると\n",
"['=', '.', ',', 'rainfall', 'the', 'and', 'and', 'with', 'first', 'was', ',', 'the', '<eos>', 'in', 'first', '<unk>', '<eos>', 'and', 'be', 'first']\n"
]
}
],
"source": [
"print('\\n◇ 単語列0につづくことが期待される予測単語列')\n",
"output = best_model.forward(data, debug=False)\n",
"best_model.zero_grad()\n",
"pred0 = [torch.max(output[:1, i, :], 1)[1].item() for i in range(20)] # max index をとる\n",
"print(pred0)\n",
"print('単語列に翻訳すると')\n",
"print([TEXT.vocab.itos[i] for i in pred0])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.7.0"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment