{"id":326613,"date":"2021-07-18T15:00:20","date_gmt":"2021-07-18T15:00:20","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=326613"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=326613","title":{"rendered":"\u041c\u043e\u0434\u0435\u043b\u0438 \u0433\u043b\u0443\u0431\u043e\u043a\u0438\u0445 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439 sequence-to-sequence \u043d\u0430 PyTorch (\u0427\u0430\u0441\u0442\u044c 6)"},"content":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<h2>6 &#8212; Attention is All You Need<\/h2>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0433\u043a\u0430\u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u0443\u044e\u0432\u0435\u0440\u0441\u0438\u044e \u043c\u043e\u0434\u0435\u043b\u0438 Transformer \u0438\u0437 \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/arxiv.org\/abs\/1706.03762\" rel=\"noopener noreferrer nofollow\">Attention is All You Need<\/a>. \u0412\u0441\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0432\u0437\u044f\u0442\u044b \u0438\u0437 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438. \u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e Transformer \u043e\u0431\u0440\u0430\u0449\u0430\u0439\u0442\u0435\u0441\u044c <a href=\"https:\/\/www.mihaileric.com\/posts\/transformers-attention-in-disguise\/\" rel=\"noopener noreferrer nofollow\">\u0441\u044e\u0434\u0430<\/a>, <a href=\"https:\/\/jalammar.github.io\/illustrated-transformer\/\" rel=\"noopener noreferrer nofollow\">\u0441\u044e\u0434\u0430<\/a> <a href=\"http:\/\/nlp.seas.harvard.edu\/2018\/04\/03\/attention.html\" rel=\"noopener noreferrer nofollow\">\u0438 \u0441\u044e\u0434\u0430<\/a>. \u041d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435 <a href=\"https:\/\/habr.com\/ru\/post\/486358\/\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a0a\/884\/6d5\/a0a8846d5cecd904cbbb9486f07cb962.png\" width=\"409\" height=\"595\"><figcaption><\/figcaption><\/figure>\n<h3>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h3>\n<p>\u041f\u043e\u0434\u043e\u0431\u043d\u043e \u0441\u0432\u0451\u0440\u0442\u043e\u0447\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 Sequence-to-Sequence, Transformer \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u0440\u0435\u043a\u0443\u0440\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u0438. \u041e\u043d \u0442\u0430\u043a\u0436\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u0432\u0451\u0440\u0442\u043e\u0447\u043d\u044b\u0435 \u0441\u043b\u043e\u0438. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0445 \u0441\u043b\u043e\u0435\u0432, \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u043e\u0432 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0438 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>\u041f\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e \u043d\u0430 \u044f\u043d\u0432\u0430\u0440\u044c 2020 \u0433\u043e\u0434\u0430 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0434\u043e\u043c\u0438\u043d\u0438\u0440\u0443\u044e\u0449\u0435\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043e\u0439 \u0432 NLP \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434\u043e\u0432\u044b\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0432\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0437\u0430\u0434\u0430\u0447, \u0438 \u043f\u043e\u0445\u043e\u0436\u0435, \u0447\u0442\u043e \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u043c\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u043c \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u044f\u0437\u044b\u043a\u043e\u0432.<\/p>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 Transformer \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u044d\u0442\u043e <a href=\"https:\/\/arxiv.org\/abs\/1810.04805\" rel=\"noopener noreferrer nofollow\">BERT<\/a> (<strong>B<\/strong>idirectional <strong>E<\/strong>ncoder <strong>R<\/strong>epresentations from <strong>T<\/strong>ransformers) \u0438 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 BERT \u043e\u0431\u044b\u0447\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u043c\u0435\u043d\u044b \u0441\u043b\u043e\u0451\u0432 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430 \u2014 \u0435\u0441\u043b\u0438 \u043d\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 &#8212; \u0432 NLP \u043c\u043e\u0434\u0435\u043b\u044f\u0445.<\/p>\n<p>\u0420\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0439 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u043d\u044b\u043c\u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0440\u0430\u043c\u0438, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/huggingface.co\/transformers\/\" rel=\"noopener noreferrer nofollow\">Transformers<\/a>, \u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 <a href=\"https:\/\/huggingface.co\/transformers\/pretrained_models.html\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a> \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439.<\/p>\n<p>\u0420\u0430\u0437\u043b\u0438\u0447\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0432 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0438 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435:<\/p>\n<ul>\n<li>\n<p>\u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043e\u0431\u0443\u0447\u0435\u043d\u043d\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u0443\u044e \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0443 \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439<\/p>\n<\/li>\n<li>\n<p>\u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0442\u043e\u0440 Adam \u0441\u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u0441 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0449\u0435\u0439\u0441\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e<\/p>\n<\/li>\n<li>\n<p>\u043c\u044b \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0433\u043b\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u043a<\/p>\n<\/li>\n<\/ul>\n<p>\u041c\u044b \u0432\u043d\u043e\u0441\u0438\u043c \u0432\u0441\u0435 \u044d\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d\u0438 \u0431\u043b\u0438\u0437\u043a\u0438 \u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c BERT \u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 Transformer \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0443\u044e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443.<\/p>\n<p>\u041a\u0430\u043a \u0438 \u0440\u0430\u043d\u0435\u0435, \u0435\u0441\u043b\u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u043f\u043e\u0441\u0442\u0430 \u0432\u0430\u0441 \u043d\u0435 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442, \u0442\u043e \u043d\u0438\u0436\u0435 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0443\u044e \u0438 \u0440\u0443\u0441\u0441\u043a\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e jupyter notebook:<\/p>\n<p><a href=\"https:\/\/github.com\/bentrevett\/pytorch-seq2seq\/blob\/master\/6%20-%20Attention%20is%20All%20You%20Need.ipynb\" rel=\"noopener noreferrer nofollow\">\u0418\u0441\u0445\u043e\u0434\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f<\/a> <a href=\"https:\/\/colab.research.google.com\/github\/bentrevett\/pytorch-seq2seq\/blob\/master\/6%20-%20Attention%20is%20All%20You%20Need.ipynb\" rel=\"noopener noreferrer nofollow\">Open jupyter notebook In Colab<\/a><\/p>\n<p><a href=\"https:\/\/github.com\/vasiliyeskin\/bentrevett-pytorch-seq2seq_ru\/blob\/master\/6%20-%20Attention%20is%20All%20You%20Need.ipynb\" rel=\"noopener noreferrer nofollow\">\u0420\u0443\u0441\u0441\u043a\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f<\/a> <a href=\"https:\/\/colab.research.google.com\/github\/vasiliyeskin\/bentrevett-pytorch-seq2seq_ru\/blob\/master\/6%20-%20Attention%20is%20All%20You%20Need.ipynb\" rel=\"noopener noreferrer nofollow\">Open jupyter notebook In Colab<\/a><\/p>\n<p><strong>\u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/strong>: \u0440\u0443\u0441\u0441\u043a\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f jupyter notebook \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u0432 \u043a\u043e\u043d\u0446\u0435 \u0442\u0435\u0441\u0442\u043e\u043c \u043d\u0430 \u0438\u043d\u0432\u0435\u0440\u0441\u0438\u044e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<h3>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/h3>\n<p>\u041a\u0430\u043a \u0432\u0441\u0435\u0433\u0434\u0430, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u0438 \u0437\u0430\u0434\u0430\u0434\u0438\u043c \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0435 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u0447\u0438\u0441\u043b\u0430 \u0434\u043b\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438.<\/p>\n<pre><code class=\"python\">import torch import torch.nn as nn import torch.optim as optim  import torchtext from torchtext.legacy.datasets import Multi30k from torchtext.legacy.data import Field, BucketIterator, TabularDataset  import matplotlib.pyplot as plt import matplotlib.ticker as ticker  import spacy import numpy as np  import random import math import time<\/code><\/pre>\n<pre><code class=\"python\">SEED = 1234  random.seed(SEED) np.random.seed(SEED) torch.manual_seed(SEED) torch.cuda.manual_seed(SEED) torch.backends.cudnn.deterministic = True<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 Google Colab \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b (\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 colab runtime! \u041d\u0430\u0438\u0431\u044b\u0441\u0442\u0440\u0435\u0439\u0448\u0438\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0440\u043e\u0442\u043a\u0443\u044e \u043a\u043e\u043c\u0430\u0434\u0443\uff1a <strong>Ctrl + M + .<\/strong>):<\/p>\n<pre><code class=\"python\">!pip install -U spacy==3.0 !python -m spacy download en_core_web_sm !python -m spacy download de_core_news_sm<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u0430\u0448\u0438 \u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u044b, \u043a\u0430\u043a \u0438 \u0440\u0430\u043d\u044c\u0448\u0435.<\/p>\n<pre><code class=\"python\">spacy_de = spacy.load('de_core_news_sm') spacy_en = spacy.load('en_core_web_sm')<\/code><\/pre>\n<pre><code class=\"python\">def tokenize_de(text):     \"\"\"     Tokenizes German text from a string into a list of strings     \"\"\"     return [tok.text for tok in spacy_de.tokenizer(text)]  def tokenize_en(text):     \"\"\"     Tokenizes English text from a string into a list of strings     \"\"\"     return [tok.text for tok in spacy_en.tokenizer(text)]   def tokenize_text(text):     \"\"\"     Tokenizes English text from a string into a list of strings     \"\"\"     return [tok.text for tok in text.split(' ')]<\/code><\/pre>\n<p>\u041d\u0430\u0448\u0438 \u043f\u043e\u043b\u044f \u0442\u0430\u043a\u0438\u0435 \u0436\u0435, \u043a\u0430\u043a \u0438 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0447\u0430\u0441\u0442\u044f\u0445. \u041c\u043e\u0434\u0435\u043b\u044c \u043e\u0436\u0438\u0434\u0430\u0435\u0442, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0432\u0432\u0435\u0434\u0435\u043d\u044b \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441 \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c\u044e \u0431\u0430\u0442\u0447\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c<code>batch_first = True<\/code>.<\/p>\n<pre><code class=\"python\"> SRC = Field(tokenize = tokenize_de,              init_token = '&lt;sos&gt;',              eos_token = '&lt;eos&gt;',              lower = True,              batch_first = True)  TRG = Field(tokenize = tokenize_en,              init_token = '&lt;sos&gt;',              eos_token = '&lt;eos&gt;',              lower = True,              batch_first = True)<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u043d\u0430\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 Multi30k \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u043b\u043e\u0432\u0430\u0440\u044c.<\/p>\n<pre><code class=\"python\">train_data, valid_data, test_data = Multi30k.splits(exts = ('.de', '.en'),                                                      fields = (SRC, TRG))<\/code><\/pre>\n<pre><code class=\"python\">SRC.build_vocab(train_data, min_freq = 2) TRG.build_vocab(train_data, min_freq = 2)<\/code><\/pre>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0434\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0438 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<pre><code class=\"python\">device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')<\/code><\/pre>\n<pre><code class=\"python\">BATCH_SIZE = 128  train_iterator, valid_iterator, test_iterator = BucketIterator.splits(     (train_data, valid_data, test_data),       batch_size = BATCH_SIZE,      device = device)<\/code><\/pre>\n<h3>\u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438<\/h3>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u043c\u043e\u0434\u0435\u043b\u044c. \u041a\u0430\u043a \u0438 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0447\u0430\u0441\u0442\u044f\u0445, \u043e\u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 <em>\u043a\u043e\u0434\u0435\u0440\u0430<\/em> \u0438 <em>\u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430<\/em>, \u0441 \u043a\u043e\u0434\u0435\u0440\u043e\u043c <em>\u043a\u043e\u0434\u0438\u0440\u0443\u044e\u0449\u0438\u043c<\/em> \u0432\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430\u043d\u0435\u043c\u0435\u0446\u043a\u043e\u043c\u044f\u0437\u044b\u043a\u0435 \u0432 <em>\u0432\u0435\u043a\u0442\u043e\u0440 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430<\/em> \u0438 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 <em>\u0434\u0435\u043a\u043e\u0434\u0438\u0440\u0443\u0435\u0442<\/em> \u044d\u0442\u043e\u0442 \u0432\u0435\u043a\u0442\u043e\u0440 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430\u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c\u044f\u0437\u044b\u043a\u0435.<\/p>\n<h4>\u041a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a<\/h4>\n<p>\u041f\u043e\u0434\u043e\u0431\u043d\u043e \u043c\u043e\u0434\u0435\u043b\u0438 ConvSeq2Seq, \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a Transformer \u043d\u0435 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0441\u0436\u0430\u0442\u044c \u0432\u0441\u0451 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435  <img decoding=\"async\" class=\"formula inline\" source=\"X = (x_1, ... ,x_n)\" alt=\"X = (x_1, ... ,x_n)\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2d6\/167\/8c1\/2d61678c15d4320ee9636eec14feee3c.svg\"> \u0432 \u0435\u0434\u0438\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 <img decoding=\"async\" class=\"formula inline\" source=\"z\" alt=\"z\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/003\/fbd\/df6\/003fbddf65e74338d209dabcefc87203.svg\">. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u043e\u043d \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 <img decoding=\"async\" class=\"formula inline\" source=\"Z = (z_1, ... , z_n)\" alt=\"Z = (z_1, ... , z_n)\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/414\/87a\/394\/41487a3941ea93ea42fdaa0af604fa7e.svg\">. \u0418\u0442\u0430\u043a, \u0435\u0441\u043b\u0438 \u0431\u044b \u043d\u0430\u0448\u0430 \u0432\u0445\u043e\u0434\u043d\u0430\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043b\u0430 \u0438\u0437 5 \u0442\u043e\u043a\u0435\u043d\u043e\u0432, \u0443 \u043d\u0430\u0441 \u0431\u044b\u043b\u043e \u0431\u044b <img decoding=\"async\" class=\"formula inline\" source=\"Z = (z_1, z_2, z_3, z_4, z_5)\" alt=\"Z = (z_1, z_2, z_3, z_4, z_5)\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b5c\/844\/f05\/b5c844f05a59d6af6ca6beba37864059.svg\">. \u041f\u043e\u0447\u0435\u043c\u0443 \u043c\u044b \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u044d\u0442\u043e\u0442 \u0442\u0435\u043d\u0437\u043e\u0440 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0445 \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432, \u0430 \u043d\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043a\u0440\u044b\u0442\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439? \u0421\u043a\u0440\u044b\u0442\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 <img decoding=\"async\" class=\"formula inline\" source=\"t\" alt=\"t\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5e7\/543\/fed\/5e7543fedeb287edc0951716d7a849ba.svg\"> \u0432 RNN \u0432\u0438\u0434\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u043a\u0435\u043d\u044b <img decoding=\"async\" class=\"formula inline\" source=\"x_t\" alt=\"x_t\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b10\/2bd\/866\/b102bd8660b553d359d57dee3a283873.svg\">\u0438 \u0432\u0441\u0435 \u0442\u043e\u043a\u0435\u043d\u044b, \u0447\u0442\u043e \u0431\u044b\u043b\u0438 \u043f\u0435\u0440\u0435\u0434 \u043d\u0438\u043c. \u041e\u0434\u043d\u0430\u043a\u043e \u0437\u0434\u0435\u0441\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 <code>\u0432\u0438\u0434\u0435\u043b<\/code> \u0432\u0441\u0435 \u0442\u043e\u043a\u0435\u043d\u044b \u0432\u043e \u0432\u0441\u0435\u0445 \u043f\u043e\u0437\u0438\u0446\u0438\u044f\u0445 \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6b7\/608\/d3b\/6b7608d3b5867a75a579729893761e57.png\" width=\"197\" height=\"369\"><figcaption><\/figcaption><\/figure>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0442\u043e\u043a\u0435\u043d\u044b \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442 \u0447\u0435\u0440\u0435\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0441\u043b\u043e\u0439 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u043a\u0443\u0440\u0440\u0435\u043d\u0442\u043d\u043e\u0439, \u043e\u043d\u0430 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u041c\u044b \u0440\u0435\u0448\u0430\u0435\u043c \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u043b\u043e\u0439 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 <em>\u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u043b\u043e\u0439 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430<\/em> positionalembeddinglayer. \u042d\u0442\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432\u0445\u043e\u0434\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435 \u0441\u0430\u043c \u0442\u043e\u043a\u0435\u043d, \u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u0442\u043e\u043a\u0435\u043d\u0430 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430, \u0442\u043e\u043a\u0435\u043d\u0430 <code>&lt;sos&gt;<\/code> \u043d\u0430\u0447\u0430\u043b\u043e\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 0. \u041f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433 \u0438\u043c\u0435\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u043b\u043e\u0432\u0430\u0440\u044f, \u0440\u0430\u0432\u043d\u044b\u0439 100, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043d\u0430\u0448\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u0438\u043d\u043e\u0439 \u0434\u043e 100 \u0442\u043e\u043a\u0435\u043d\u043e\u0432. \u0415\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c, \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0434\u043b\u0438\u043d\u043d\u044b\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f Transformer \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 Attention is All You Need \u043d\u0435 \u043e\u0431\u0443\u0447\u0430\u043b\u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0432 \u043d\u0435\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433. \u0421\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b Transformer, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a BERT, \u0432\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 \u044d\u0442\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044c <a href=\"http:\/\/nlp.seas.harvard.edu\/2018\/04\/03\/attention.html#positional-encoding\" rel=\"noopener noreferrer nofollow\">\u0441\u044e\u0434\u0430<\/a>, \u0447\u0442\u043e\u0431\u044b \u0443\u0437\u043d\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043e \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430\u0445, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 Transformer.<\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u0442\u043e\u043a\u0435\u043d \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430 \u043f\u043e\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043d\u043e \u0441\u0443\u043c\u043c\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u0435\u043a\u0442\u043e\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0442\u043e\u043a\u0435\u043d\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0435\u0433\u043e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u0435\u0440\u0435\u0434 \u0441\u0443\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430 \u043e\u043d\u0438 \u0443\u043c\u043d\u043e\u0436\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0440\u0430\u0432\u043d\u044b\u0439 <img decoding=\"async\" class=\"formula inline\" source=\"\\sqrt{d_{model}}\" alt=\"\\sqrt{d_{model}}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f82\/7d6\/115\/f827d6115b2f09d1b6da59e7ff966873.svg\">, \u0433\u0434\u0435 <img decoding=\"async\" class=\"formula inline\" source=\"d_{model}\" alt=\"d_{model}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8be\/65c\/e9c\/8be65ce9c64fc3b6e28bca836d00d2c0.svg\"> \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u043a\u0440\u044b\u0442\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f <code>hid_dim<\/code>. \u042d\u0442\u043e \u044f\u043a\u043e\u0431\u044b \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442 \u0434\u0438\u0441\u043f\u0435\u0440\u0441\u0438\u044e \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430, \u0438 \u043c\u043e\u0434\u0435\u043b\u044c \u0442\u0440\u0443\u0434\u043d\u043e \u043e\u0431\u0443\u0447\u0438\u0442\u044c \u0431\u0435\u0437 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u0430 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0417\u0430\u0442\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u0440\u043e\u043f\u0430\u0443\u0442 \u0434\u043b\u044f \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u044d\u043c\u0435\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430.<\/p>\n<p>\u041a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u044d\u043c\u0435\u0431\u0435\u0434\u0434\u0438\u043d\u0433 \u0437\u0430\u0442\u0435\u043c \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <img decoding=\"async\" class=\"formula inline\" source=\"N\" alt=\"N\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fd1\/6ce\/965\/fd16ce9653c1001ca43874b3207cf849.svg\"> <em>\u0441\u043b\u043e\u0435\u0432 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430<\/em> \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f <img decoding=\"async\" class=\"formula inline\" source=\"Z\" alt=\"Z\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1a3\/bd1\/224\/1a3bd1224217ba4f06b8ae3cc7296843.svg\">, \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u043e\u043c.<\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u0430\u044f \u043c\u0430\u0441\u043a\u0430 <code>src_mask<\/code> \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u043c\u0435\u0435\u0442 \u0442\u0443 \u0436\u0435 \u0444\u043e\u0440\u043c\u0443, \u0447\u0442\u043e \u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043d\u043e \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 1, \u043a\u043e\u0433\u0434\u0430 \u0442\u043e\u043a\u0435\u043d \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043a\u0435\u043d\u043e\u043c <code>&lt;pad&gt;<\/code> \u0438 0, \u043a\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u0442\u043e\u043a\u0435\u043d <code>&lt;pad&gt;<\/code>. \u042d\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0441\u043b\u043e\u044f\u0445 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u0434\u043b\u044f \u043c\u0430\u0441\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u043e\u0432 \u043c\u043d\u043e\u0433\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043a \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043d\u0430 \u0442\u043e\u043a\u0435\u043d\u044b <code>&lt;pad&gt;<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438.<\/p>\n<pre><code class=\"python\">class Encoder(nn.Module):     def __init__(self,                   input_dim,                   hid_dim,                   n_layers,                   n_heads,                   pf_dim,                  dropout,                   device,                  max_length = 100):         super().__init__()          self.device = device                  self.tok_embedding = nn.Embedding(input_dim, hid_dim)         self.pos_embedding = nn.Embedding(max_length, hid_dim)                  self.layers = nn.ModuleList([EncoderLayer(hid_dim,                                                    n_heads,                                                    pf_dim,                                                   dropout,                                                    device)                                       for _ in range(n_layers)])                  self.dropout = nn.Dropout(dropout)                  self.scale = torch.sqrt(torch.FloatTensor([hid_dim])).to(device)              def forward(self, src, src_mask):                  #src = [batch size, src len]         #src_mask = [batch size, 1, 1, src len]                  batch_size = src.shape[0]         src_len = src.shape[1]                  pos = torch.arange(0, src_len).unsqueeze(0).repeat(batch_size, 1).to(self.device)                  #pos = [batch size, src len]                  src = self.dropout((self.tok_embedding(src) * self.scale) + self.pos_embedding(pos))                  #src = [batch size, src len, hid dim]                  for layer in self.layers:             src = layer(src, src_mask)                      #src = [batch size, src len, hid dim]                      return src<\/code><\/pre>\n<h4>\u0421\u043b\u043e\u0439 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430<\/h4>\n<p>\u0421\u043b\u043e\u0438 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u2014 \u044d\u0442\u043e \u043c\u0435\u0441\u0442\u043e, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0435 \u0432\u0441\u044e \u00ab\u0441\u043e\u043b\u044c\u00bb \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u0435\u0433\u043e \u043c\u0430\u0441\u043a\u0443 \u0432 <em>\u0441\u043b\u043e\u0439 \u043c\u043d\u043e\u0433\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f<\/em>, \u0437\u0430\u0442\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0434\u0440\u043e\u043f\u0430\u0443\u0442 \u0434\u043b\u044f \u0435\u0433\u043e \u0432\u044b\u0445\u043e\u0434\u0430, \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0439\u0442\u0435 \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437 <a href=\"https:\/\/arxiv.org\/abs\/1607.06450\" rel=\"noopener noreferrer nofollow\">\u0441\u043b\u043e\u0439 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438<\/a>. \u0417\u0430\u0442\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u044b \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0447\u0435\u0440\u0435\u0437 \u0441\u043b\u043e\u0439 <em>\u0441\u0435\u0442\u0438 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u043e-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0433\u043e \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u044f<\/em> \u0438 \u0441\u043d\u043e\u0432\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u0434\u0440\u043e\u043f\u0430\u0443\u0442, \u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435, \u0441\u043b\u043e\u0439 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u044b\u0432\u043e\u0434 \u044d\u0442\u043e\u0433\u043e \u0441\u043b\u043e\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0441\u043b\u043e\u0439. \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043d\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0435\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f\u043e\u0431\u0449\u0438\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u043b\u043e\u044f\u043c\u0438.<\/p>\n<p>\u0421\u043b\u043e\u0439 \u043c\u043d\u043e\u0433\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0443\u0440\u043e\u0432\u043d\u0435\u043c \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u0434\u043b\u044f \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0435\u043d\u0438\u044f \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043d\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044e, \u0442\u043e \u0435\u0441\u0442\u044c \u043e\u043d \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043f\u043e \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044e \u043a \u0441\u0435\u0431\u0435, \u0430 \u043d\u0435 \u043a \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044d\u0442\u0443 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0443 \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f <em>\u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u043c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435\u043c<\/em>.<\/p>\n<p><a href=\"https:\/\/mlexplained.com\/2018\/01\/13\/weight-normalization-and-layer-normalization-explained-normalization-in-deep-learning-part-2\/\" rel=\"noopener noreferrer nofollow\">\u042d\u0442\u0430<\/a> \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043e \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u043b\u043e\u0435\u0432. \u0421\u0443\u0442\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0443\u044e\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0437\u043d\u0430\u043a\u043e\u0432 \u0442\u043e\u0435\u0441\u0442\u044c\u043f\u043e\u0441\u043a\u0440\u044b\u0442\u044b\u043c\u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f\u043c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u0440\u0438\u0437\u043d\u0430\u043a \u0438\u043c\u0435\u0435\u0442 \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 0 \u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u0438\u0435 1. \u042d\u0442\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u0435 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439 \u0441 \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0441\u043b\u043e\u0435\u0432, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a Transformer.<\/p>\n<pre><code class=\"python\">class EncoderLayer(nn.Module):     def __init__(self,                   hid_dim,                   n_heads,                   pf_dim,                    dropout,                   device):         super().__init__()                  self.self_attn_layer_norm = nn.LayerNorm(hid_dim)         self.ff_layer_norm = nn.LayerNorm(hid_dim)         self.self_attention = MultiHeadAttentionLayer(hid_dim, n_heads, dropout, device)         self.positionwise_feedforward = PositionwiseFeedforwardLayer(hid_dim,                                                                       pf_dim,                                                                       dropout)         self.dropout = nn.Dropout(dropout)              def forward(self, src, src_mask):                  #src = [batch size, src len, hid dim]         #src_mask = [batch size, 1, 1, src len]                           #self attention         _src, _ = self.self_attention(src, src, src, src_mask)                  #dropout, residual connection and layer norm         src = self.self_attn_layer_norm(src + self.dropout(_src))                  #src = [batch size, src len, hid dim]                  #positionwise feedforward         _src = self.positionwise_feedforward(src)                  #dropout, residual and layer norm         src = self.ff_layer_norm(src + self.dropout(_src))                  #src = [batch size, src len, hid dim]                  return src<\/code><\/pre>\n<h4>\u0421\u043b\u043e\u0439 \u043c\u043d\u043e\u0433\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f<\/h4>\n<p>\u041e\u0434\u043d\u0430 \u0438\u0437 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445, \u043d\u043e\u0432\u044b\u0445 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0439, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u043e Transformer, &#8212; \u044d\u0442\u043e <em>\u0441\u043b\u043e\u0439 \u043c\u043d\u043e\u0433\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f<\/em>.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5fa\/a07\/aeb\/5faa07aebb64ac758bfc50af5bbaa28a.png\" width=\"1050\" height=\"561\"><figcaption><\/figcaption><\/figure>\n<p>\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043a\u0430\u043a <em>\u0437\u0430\u043f\u0440\u043e\u0441\u044b<\/em>, <em>\u043a\u043b\u044e\u0447\u0438<\/em> \u0438 <em>\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f<\/em> &#8212; \u0433\u0434\u0435 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441 \u043a\u043b\u044e\u0447\u043e\u043c \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f (\u043e\u0431\u044b\u0447\u043d\u043e \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f <em>softmax<\/em> \u0438 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u044b \u0438\u043c\u0435\u044e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0442 0 \u0434\u043e 1, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u0441\u0443\u043c\u043c\u0435 \u0440\u0430\u0432\u043d\u044b 1), \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u0437\u0432\u0435\u0448\u0435\u043d\u043d\u043e\u0439 \u0441\u0443\u043c\u043c\u044b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0422\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <em>\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043a\u0430\u043b\u044f\u0440\u043d\u043e\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f<\/em>, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e <em>\u0437\u0430\u043f\u0440\u043e\u0441<\/em> \u0438 <em>\u043a\u043b\u044e\u0447<\/em> \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u0443\u0442\u0435\u043c \u0432\u0437\u044f\u0442\u0438\u044f \u0441\u043a\u0430\u043b\u044f\u0440\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438, \u0437\u0430\u0442\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e softmax \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u044f <img decoding=\"async\" class=\"formula inline\" source=\"d_k\" alt=\"d_k\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a8e\/f35\/001\/a8ef3500135efd2c4cbe6d7b9cf45b70.svg\">\u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c, \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u0443\u043c\u043d\u043e\u0436\u0438\u0442\u044c \u043d\u0430 <em>\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<\/em>. <img decoding=\"async\" class=\"formula inline\" source=\"d_k\" alt=\"d_k\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7d2\/40c\/116\/7d240c116b7289c5485d2ebc8d43d407.svg\">\u044d\u0442\u043e <em>\u0440\u0430\u0437\u043c\u0435\u0440 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f<\/em>, <code>head_dim<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0440\u0430\u0441\u043a\u0440\u043e\u0435\u043c \u0434\u0430\u043b\u0435\u0435.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"formula\" source=\"\\text{Attention}(Q, K, V) = \\text{Softmax} \\big( \\frac{QK^T}{\\sqrt{d_k}} \\big)V\" alt=\"\\text{Attention}(Q, K, V) = \\text{Softmax} \\big( \\frac{QK^T}{\\sqrt{d_k}} \\big)V\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4ab\/af9\/508\/4abaf950808101c9d475550688724d02.svg\" width=\"340\" height=\"52\"><\/p>\n<p>\u042d\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 <em>\u0441\u043a\u0430\u043b\u044f\u0440\u043d\u043e\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f<\/em>, \u043d\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043e <img decoding=\"async\" class=\"formula inline\" source=\"d_k\" alt=\"d_k\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/614\/d7d\/a20\/614d7da2061b6ba5220a280d57f5b85b.svg\">, \u043a\u043e\u0442\u043e\u0440\u043e\u0435, \u043a\u0430\u043a \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0441\u044f \u0432 \u0441\u0442\u0430\u0442\u044c\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0441\u043a\u0430\u043b\u044f\u0440\u043d\u044b\u0445 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0439, \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0449\u0438\u0435\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u044b \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u043c\u0438.<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043a\u0430\u043b\u044f\u0440\u043d\u043e\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043a \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c, \u043a\u043b\u044e\u0447\u0430\u043c \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c. \u0412\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043a \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c, \u043a\u043b\u044e\u0447\u0430\u043c \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c, \u0438\u0445 <code>hid_dim<\/code> \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0430 <img decoding=\"async\" class=\"formula inline\" source=\"h\" alt=\"h\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6e0\/a42\/c8a\/6e0a42c8aaeaf82ec2237adea40e2146.svg\"><em>\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0439<\/em> \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043a\u0430\u043b\u044f\u0440\u043d\u043e\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e \u0432\u0441\u0435\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u043c \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0443\u0434\u0435\u043b\u044f\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u043c\u0443 \u043f\u043e\u043d\u044f\u0442\u0438\u044e \u0437\u0430 \u043e\u0434\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f, \u043c\u044b \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 <img decoding=\"async\" class=\"formula inline\" source=\"h\" alt=\"h\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/878\/bb0\/df3\/878bb0df31e611632aa641f311d36e97.svg\">\u043f\u043e\u043d\u044f\u0442\u0438\u0439. \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u0438\u0445 <code>hid_dim<\/code> \u0444\u043e\u0440\u043c\u0443, \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043a\u0430\u0436\u0434\u044b\u0439 <code>hid_dim<\/code> \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 <img decoding=\"async\" class=\"formula inline\" source=\"h\" alt=\"h\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/baf\/d85\/045\/bafd8504515b5a7cdb7d364f9ac89858.svg\"> \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043e\u043d\u044f\u0442\u0438\u0439.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"formula\" source=\"\\text{MultiHead}(Q, K, V) = \\text{Concat}(\\text{head}_1,...,\\text{head}_h)W^O\" alt=\"\\text{MultiHead}(Q, K, V) = \\text{Concat}(\\text{head}_1,...,\\text{head}_h)W^O\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7bb\/1ac\/8e8\/7bb1ac8e80f695dd479af680e2454be0.svg\" width=\"491\" height=\"28\"><img loading=\"lazy\" decoding=\"async\" class=\"formula\" source=\"\\text{head}_i = \\text{Attention}(QW_i^Q, KW_i^K, VW_i^V) \" alt=\"\\text{head}_i = \\text{Attention}(QW_i^Q, KW_i^K, VW_i^V) \" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/01c\/e72\/6b7\/01ce726b76eb47c58b78c06f259dbb2f.svg\" width=\"370\" height=\"30\"><\/p>\n<p><img decoding=\"async\" class=\"formula inline\" source=\"W^O\" alt=\"W^O\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a44\/788\/0df\/a447880df1728b8d72fa975e212d0918.svg\"> \u044d\u0442\u043e \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0439 \u0441\u043b\u043e\u0439, \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0439 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0441\u043b\u043e\u044f \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u043c\u0438, <code>fc<\/code>. <img decoding=\"async\" class=\"formula inline\" source=\"W^Q, W^K, W^V\" alt=\"W^Q, W^K, W^V\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5a8\/b8f\/640\/5a8b8f6408a16ee56248dbe5b79a1903.svg\"> \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0435 \u0441\u043b\u043e\u0438 <code>fc_q<\/code>, <code>fc_k<\/code> \u0438 <code>fc_v<\/code>.<\/p>\n<p>\u041f\u0440\u043e\u0445\u043e\u0434\u044f \u043f\u043e \u043c\u043e\u0434\u0443\u043b\u044e, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c <img decoding=\"async\" class=\"formula inline\" source=\"QW^Q\" alt=\"QW^Q\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/abc\/8e5\/285\/abc8e5285ba2574395b1e980ed50e707.svg\">, <img decoding=\"async\" class=\"formula inline\" source=\"KW^K\" alt=\"KW^K\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8d8\/35a\/6be\/8d835a6befc1b57e417a5f7666c43ebf.svg\"> \u0438 <img decoding=\"async\" class=\"formula inline\" source=\"VW^V\" alt=\"VW^V\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7ed\/6bd\/002\/7ed6bd002b534d61763ca398604b326c.svg\"> \u0441 \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u044f\u043c\u0438 <code>fc_q<\/code>, <code>fc_k<\/code> \u0438 <code>fc_v<\/code>, \u0434\u0430\u044e\u0449\u0438\u0435 \u043d\u0430\u043c<code>Q<\/code>, <code>K<\/code> \u0438 <code>V<\/code>. \u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u043c <code>hid_dim<\/code> \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043a\u043b\u044e\u0447\u0430 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0430 <code>n_heads<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>.view<\/code> \u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0432 \u0438\u0445 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0435\u0440\u0435\u043c\u043d\u043e\u0436\u0438\u0442\u044c. \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c <code>energy<\/code> \u043d\u0435\u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0435\u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043f\u0443\u0442\u0435\u043c \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u044f <code>Q<\/code> \u0438 <code>K<\/code> \u0432\u043c\u0435\u0441\u0442\u0435 \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u044f \u0435\u0451 \u043d\u0430 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u044b\u0439 \u043a\u043e\u0440\u0435\u043d\u044c \u0438\u0437 <code>head_dim<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a <code>hid_dim \/\/ n_heads<\/code>. \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u043c\u0430\u0441\u043a\u0438\u0440\u0443\u0435\u043c \u044d\u043d\u0435\u0440\u0433\u0438\u044e, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043d\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f, \u0437\u0430\u0442\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c softmax \u0438 \u0434\u0440\u043e\u043f\u0430\u0443\u0442. \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043a \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0439 <code>V<\/code>, \u043f\u0435\u0440\u0435\u0434 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435\u043c <code>n_heads<\/code> \u0432\u043c\u0435\u0441\u0442\u0435. \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u044b \u0443\u043c\u043d\u043e\u0436\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430 <img decoding=\"async\" class=\"formula inline\" source=\"W^O\" alt=\"W^O\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f25\/6ad\/942\/f256ad9427d9fbf621815fbc918f6c8f.svg\">, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0435 <code>fc_o<\/code>.<\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0432 \u043d\u0430\u0448\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043b\u0438\u043d\u044b \u043a\u043b\u044e\u0447\u0435\u0439 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432\u0441\u0435\u0433\u0434\u0430 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438 \u043c\u0430\u0442\u0440\u0438\u0447\u043d\u043e\u043c \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u0438 \u0432\u044b\u0445\u043e\u0434 softmax, <code>attention<\/code>, \u0441 <code>V<\/code> \u0443 \u043d\u0430\u0441 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0434\u043b\u044f \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u0430\u0442\u0440\u0438\u0446. \u042d\u0442\u043e \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <code>torch.matmul<\/code> \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u043a\u043e\u0433\u0434\u0430 \u043e\u0431\u0430 \u0442\u0435\u043d\u0437\u043e\u0440\u0430 &gt; 2-\u043c\u0435\u0440\u043d\u044b, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0435 \u043c\u0430\u0442\u0440\u0438\u0447\u043d\u043e\u0435 \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u0434\u0432\u0443\u043c \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f\u043c \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0435\u043d\u0437\u043e\u0440\u0430. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 <strong>querylen,keylen x valuelen,headdim<\/strong> \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u0435 \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u043d\u0430 \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0430\u043a\u0435\u0442\u0430 \u0438 \u043a\u0430\u0436\u0434\u043e\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u0438\u0434\u0430 <strong>batchsize,nheads,querylen,headdim<\/strong>.<\/p>\n<pre><code class=\"python\">class MultiHeadAttentionLayer(nn.Module):     def __init__(self, hid_dim, n_heads, dropout, device):         super().__init__()                  assert hid_dim % n_heads == 0                  self.hid_dim = hid_dim         self.n_heads = n_heads         self.head_dim = hid_dim \/\/ n_heads                  self.fc_q = nn.Linear(hid_dim, hid_dim)         self.fc_k = nn.Linear(hid_dim, hid_dim)         self.fc_v = nn.Linear(hid_dim, hid_dim)                  self.fc_o = nn.Linear(hid_dim, hid_dim)                  self.dropout = nn.Dropout(dropout)                  self.scale = torch.sqrt(torch.FloatTensor([self.head_dim])).to(device)              def forward(self, query, key, value, mask = None):                  batch_size = query.shape[0]                  #query = [batch size, query len, hid dim]         #key = [batch size, key len, hid dim]         #value = [batch size, value len, hid dim]                          Q = self.fc_q(query)         K = self.fc_k(key)         V = self.fc_v(value)                  #Q = [batch size, query len, hid dim]         #K = [batch size, key len, hid dim]         #V = [batch size, value len, hid dim]                          Q = Q.view(batch_size, -1, self.n_heads, self.head_dim).permute(0, 2, 1, 3)         K = K.view(batch_size, -1, self.n_heads, self.head_dim).permute(0, 2, 1, 3)         V = V.view(batch_size, -1, self.n_heads, self.head_dim).permute(0, 2, 1, 3)                  #Q = [batch size, n heads, query len, head dim]         #K = [batch size, n heads, key len, head dim]         #V = [batch size, n heads, value len, head dim]                          energy = torch.matmul(Q, K.permute(0, 1, 3, 2)) \/ self.scale                  #energy = [batch size, n heads, query len, key len]                  if mask is not None:             energy = energy.masked_fill(mask == 0, -1e10)                  attention = torch.softmax(energy, dim = -1)                          #attention = [batch size, n heads, query len, key len]                          x = torch.matmul(self.dropout(attention), V)                  #x = [batch size, n heads, query len, head dim]                  x = x.permute(0, 2, 1, 3).contiguous()                  #x = [batch size, query len, n heads, head dim]                  x = x.view(batch_size, -1, self.hid_dim)                  #x = [batch size, query len, hid dim]                  x = self.fc_o(x)                  #x = [batch size, query len, hid dim]                  return x, attention<\/code><\/pre>\n<h4>\u0421\u043b\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u043e-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0433\u043e \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u044f<\/h4>\n<p>\u0414\u0440\u0443\u0433\u043e\u0439 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0431\u043b\u043e\u043a \u0432\u043d\u0443\u0442\u0440\u0438 \u0443\u0440\u043e\u0432\u043d\u044f \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u2014 \u044d\u0442\u043e <em>\u0441\u043b\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u043e-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0433\u043e \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u044f<\/em>. \u041e\u043d \u0443\u0441\u0442\u0440\u043e\u0435\u043d \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441\u043e \u0441\u043b\u043e\u0435\u043c \u043c\u043d\u043e\u0433\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f. \u0412\u0445\u043e\u0434 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044f \u0438\u0437 <code>hid_dim<\/code> \u0432 <code>pf_dim<\/code>, \u0433\u0434\u0435 <code>pf_dim<\/code> \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c <code>hid_dim<\/code>. \u041e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0422\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b <code>hid_dim<\/code> \u0438\u0437 512 \u0438 <code>pf_dim<\/code> \u0438\u0437 2048. \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 ReLU \u0438 \u0434\u0440\u043e\u043f\u0430\u0443\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0434\u043e \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043e\u043d \u0441\u043d\u043e\u0432\u0430 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 <code>hid_dim<\/code>.<\/p>\n<p>\u041f\u043e\u0447\u0435\u043c\u0443 \u043e\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f? \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u044d\u0442\u043e \u043d\u0438\u0433\u0434\u0435 \u043d\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442\u0441\u044f.<\/p>\n<p>BERT \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 <a href=\"https:\/\/arxiv.org\/abs\/1606.08415\" rel=\"noopener noreferrer nofollow\">GELU<\/a>, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0432 <code>torch.relu<\/code> \u043d\u0430 <code>F.gelu<\/code>. \u041f\u043e\u0447\u0435\u043c\u0443 \u043e\u043d\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 GELU? \u041e\u043f\u044f\u0442\u044c \u0436\u0435, \u044d\u0442\u043e \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u043b\u043e\u0441\u044c.<\/p>\n<pre><code class=\"python\">class PositionwiseFeedforwardLayer(nn.Module):     def __init__(self, hid_dim, pf_dim, dropout):         super().__init__()                  self.fc_1 = nn.Linear(hid_dim, pf_dim)         self.fc_2 = nn.Linear(pf_dim, hid_dim)                  self.dropout = nn.Dropout(dropout)              def forward(self, x):                  #x = [batch size, seq len, hid dim]                  x = self.dropout(torch.relu(self.fc_1(x)))                  #x = [batch size, seq len, pf dim]                  x = self.fc_2(x)                  #x = [batch size, seq len, hid dim]                  return x<\/code><\/pre>\n<h4>\u0414\u0435\u043a\u043e\u0434\u0435\u0440<\/h4>\n<p>\u0417\u0430\u0434\u0430\u0447\u0430 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430 \u2014 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0437\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f <img decoding=\"async\" class=\"formula inline\" source=\"Z\" alt=\"Z\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/21a\/70b\/b5b\/21a70bb5b2cc16206b2562571f90fff6.svg\"> \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0442\u043e\u043a\u0435\u043d\u044b \u0432 \u0446\u0435\u043b\u0435\u0432\u043e\u043c \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0438 <img decoding=\"async\" class=\"formula inline\" source=\"\\hat{Y}\" alt=\"\\hat{Y}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/788\/eb3\/368\/788eb3368fe14931497de7e7237e9dc4.svg\">. \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c <img decoding=\"async\" class=\"formula inline\" source=\"\\hat{Y}\" alt=\"\\hat{Y}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/83e\/edb\/58b\/83eedb58bbd56971656950807c32daed.svg\"> \u0441 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438 \u0432 \u0446\u0435\u043b\u0435\u0432\u043e\u043c \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0438 <img decoding=\"async\" class=\"formula inline\" source=\"Y\" alt=\"Y\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ce1\/89a\/9eb\/ce189a9eb41d41b867742a130e528a2a.svg\"> \u0434\u043b\u044f \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u043f\u043e\u0442\u0435\u0440\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u043e\u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0430 \u0437\u0430\u0442\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0432 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0442\u043e\u0440\u0435 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u0435\u0441\u043e\u0432 \u0441 \u0446\u0435\u043b\u044c\u044e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u043d\u043e\u0437\u044b.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/414\/524\/90a\/41452490ac956109a2dfdde649e24aa0.png\" width=\"304\" height=\"595\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u0435\u043a\u043e\u0434\u0435\u0440 \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a, \u043d\u043e \u0432 \u043d\u0451\u043c \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0434\u0432\u0430 \u0443\u0440\u043e\u0432\u043d\u044f \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u043c\u0438. <em>\u0421\u043b\u043e\u0439 \u043c\u043d\u043e\u0433\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0441 \u043c\u0430\u0441\u043a\u0438\u0440\u043e\u0432\u043a\u043e\u0439<\/em> \u043d\u0430\u0434 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u0438 \u0441\u043b\u043e\u0435\u043c \u043c\u043d\u043e\u0433\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u0434\u0435\u0440\u0430 \u043a\u0430\u043a \u043a\u043b\u044e\u0447 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0414\u0435\u043a\u043e\u0434\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433 \u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 &#8212; \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043d\u0443\u044e \u0441\u0443\u043c\u043c\u0443 &#8212; \u0441 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0446\u0435\u043b\u0435\u0432\u044b\u043c\u0438 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438, \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0438\u043c\u0438 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0434\u0440\u043e\u043f\u0430\u0443\u0442. \u041e\u043f\u044f\u0442\u044c \u0436\u0435, \u043d\u0430\u0448\u0438 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0438 \u0438\u043c\u0435\u044e\u0442 \u00ab\u0441\u043b\u043e\u0432\u0430\u0440\u044c\u00bb \u0440\u0430\u0432\u043d\u044b\u0439 100, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u0438\u043d\u043e\u0439 \u0434\u043e 100 \u0442\u043e\u043a\u0435\u043d\u043e\u0432. \u041f\u0440\u0438 \u0436\u0435\u043b\u0430\u043d\u0438\u0438 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c.<\/p>\n<p>\u041a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442 \u0447\u0435\u0440\u0435\u0437 <img decoding=\"async\" class=\"formula inline\" source=\"N\" alt=\"N\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6c0\/782\/cb2\/6c0782cb227d88070b8ae2b6fabe4d4f.svg\"> \u0441\u043b\u043e\u0451\u0432 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430, \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0437\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c <code>enc_src<\/code>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0438 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043c\u0430\u0441\u043a\u043e\u0439. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043b\u043e\u0435\u0432 \u0432 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0435 \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0440\u0430\u0432\u043d\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0441\u043b\u043e\u0435\u0432 \u0432 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0435, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043e\u0431\u0430 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u044b \u043a\u0430\u043a <img decoding=\"async\" class=\"formula inline\" source=\"N\" alt=\"N\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f39\/68f\/a9e\/f3968fa9ec72910581a48cd61c78cc7f.svg\">.<\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430 \u043f\u043e\u0441\u043b\u0435 N<img decoding=\"async\" class=\"formula inline\" source=\"N\" alt=\"N\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/857\/fc9\/20f\/857fc920f658c26aff7576bb20ff32a3.svg\">-\u0433\u043e \u0441\u043b\u043e\u044f \u0437\u0430\u0442\u0435\u043c \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0439 \u0441\u043b\u043e\u0439 <code>fc_out<\/code>. \u0412 PyTorch \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f softmax \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u0432 \u043d\u0430\u0448\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043e\u0442\u0435\u0440\u044c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u044f\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0434\u0435\u0441\u044c \u0441\u043b\u043e\u0439 softmax.<\/p>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u043c\u0430\u0441\u043a\u0438, \u043a\u0430\u043a \u043c\u044b \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u043b\u0438 \u0432 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0435, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0448\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0435 \u0432\u043b\u0438\u044f\u043b\u0430 \u043d\u0430 \u0442\u043e\u043a\u0435\u043d <code>&lt;pad&gt;<\/code>, \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0446\u0435\u043b\u0435\u0432\u0443\u044e \u043c\u0430\u0441\u043a\u0443. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u043e \u0434\u0430\u043b\u0435\u0435 \u0432 <code>Seq2Seq<\/code> \u043c\u043e\u0434\u0435\u043b\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u0438\u0440\u0443\u0435\u0442 \u043a\u0430\u043a \u043a\u043e\u0434\u0435\u0440, \u0442\u0430\u043a \u0438 \u0434\u0435\u043a\u043e\u0434\u0435\u0440, \u043d\u043e \u0441\u0443\u0442\u044c \u0435\u0435 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0442\u0443 \u0436\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e, \u0447\u0442\u043e \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430 \u0432 \u0441\u0432\u0451\u0440\u0442\u043e\u0447\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 sequence-to-sequence model. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0432\u0441\u0435 \u0446\u0435\u043b\u0435\u0432\u044b\u0435 \u0442\u043e\u043a\u0435\u043d\u044b \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e, \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u043c\u0435\u0442\u043e\u0434 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430 \u043e\u0442 \u00ab\u043e\u0431\u043c\u0430\u043d\u0430\u00bb, \u043f\u0440\u043e\u0441\u0442\u043e \u00ab\u0433\u043b\u044f\u0434\u044f\u00bb \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u0432 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438 \u0432\u044b\u0432\u043e\u0434\u044f \u0435\u0433\u043e.<\/p>\n<p>\u041d\u0430\u0448 \u0441\u043b\u043e\u0439 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0437\u0436\u0435 \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438\u0445 \u0433\u0440\u0430\u0444\u0438\u043a, \u0447\u0442\u043e\u0431\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u043d\u0430 \u0447\u0442\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430\u0448\u0430 \u043c\u043e\u0434\u0435\u043b\u044c.<\/p>\n<pre><code class=\"python\">class Decoder(nn.Module):     def __init__(self,                   output_dim,                   hid_dim,                   n_layers,                   n_heads,                   pf_dim,                   dropout,                   device,                  max_length = 100):         super().__init__()                  self.device = device                  self.tok_embedding = nn.Embedding(output_dim, hid_dim)         self.pos_embedding = nn.Embedding(max_length, hid_dim)                  self.layers = nn.ModuleList([DecoderLayer(hid_dim,                                                    n_heads,                                                    pf_dim,                                                    dropout,                                                    device)                                      for _ in range(n_layers)])                  self.fc_out = nn.Linear(hid_dim, output_dim)                  self.dropout = nn.Dropout(dropout)                  self.scale = torch.sqrt(torch.FloatTensor([hid_dim])).to(device)              def forward(self, trg, enc_src, trg_mask, src_mask):                  #trg = [batch size, trg len]         #enc_src = [batch size, src len, hid dim]         #trg_mask = [batch size, 1, trg len, trg len]         #src_mask = [batch size, 1, 1, src len]                          batch_size = trg.shape[0]         trg_len = trg.shape[1]                  pos = torch.arange(0, trg_len).unsqueeze(0).repeat(batch_size, 1).to(self.device)                                      #pos = [batch size, trg len]                      trg = self.dropout((self.tok_embedding(trg) * self.scale) + self.pos_embedding(pos))                          #trg = [batch size, trg len, hid dim]                  for layer in self.layers:             trg, attention = layer(trg, enc_src, trg_mask, src_mask)                  #trg = [batch size, trg len, hid dim]         #attention = [batch size, n heads, trg len, src len]                  output = self.fc_out(trg)                  #output = [batch size, trg len, output dim]                      return output, attention<\/code><\/pre>\n<h4>\u0421\u043b\u043e\u0439 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430<\/h4>\n<p>\u041a\u0430\u043a \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u043d\u0435\u0435, \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u0435\u043d \u0443\u0440\u043e\u0432\u043d\u044e \u043a\u043e\u0434\u0435\u0440\u0430, \u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u043d \u0438\u043c\u0435\u0435\u0442 \u0434\u0432\u0430 \u0443\u0440\u043e\u0432\u043d\u044f \u043c\u043d\u043e\u0433\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f <code>self_attention<\/code> \u0438 <code>encoder_attention<\/code>.<\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439, \u043a\u0430\u043a \u0438 \u0432 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0435, \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430, \u0432\u043f\u043b\u043e\u0442\u044c \u0434\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043a\u043b\u044e\u0447\u0430 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u0417\u0430\u0442\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0434\u0440\u043e\u043f\u0430\u0443\u0442, \u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0438 \u0441\u043b\u043e\u0439 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u042d\u0442\u043e\u0442 \u0441\u043b\u043e\u0439 <code>self_attention<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043c\u0430\u0441\u043a\u0443 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 <code>trg_mask<\/code>, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u00ab\u043e\u0431\u043c\u0430\u043d\u00bb \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430, \u043e\u0431\u0440\u0430\u0449\u0430\u044f \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u043e\u043a\u0435\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u00ab\u043e\u043f\u0435\u0440\u0435\u0436\u0430\u044e\u0442\u00bb \u0442\u043e\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043d \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 \u0442\u043e\u043a\u0435\u043d\u044b \u0432 \u0446\u0435\u043b\u0435\u0432\u043e\u043c \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e.<\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043a\u0430\u043a \u043c\u044b \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043f\u043e\u0434\u0430\u0451\u043c \u0437\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 <code>enc_src<\/code> \u0432 \u043d\u0430\u0448 \u0434\u0435\u043a\u043e\u0434\u0435\u0440. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u043e\u0435 \u043c\u043d\u043e\u0433\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u043c\u0438 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430, \u0430 \u043a\u043b\u044e\u0447\u0438 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u2014 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u043c\u0438 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430. \u0417\u0434\u0435\u0441\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u0430\u044f \u043c\u0430\u0441\u043a\u0430 <code>src_mask<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u043b\u043e\u0439 \u043c\u043d\u043e\u0433\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0449\u0430\u043b \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u043e\u043a\u0435\u043d <code>&lt;pad&gt;<\/code> \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u0417\u0430\u0442\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0442 \u0443\u0440\u043e\u0432\u043d\u0438 \u0434\u0440\u043e\u043f\u0430\u0443\u0442\u0430, \u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0433\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0438 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0447\u0435\u0440\u0435\u0437 \u0441\u043b\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u043e-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0433\u043e \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u0435\u0449\u0435 \u043e\u0434\u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0434\u0440\u043e\u043f\u0430\u0443\u0442\u0430, \u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0433\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0438 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0421\u043b\u043e\u0439 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430 \u043d\u0435 \u0432\u0432\u043e\u0434\u0438\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043d\u043e\u0432\u044b\u0445 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0439, \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0442\u043e\u0442 \u0436\u0435 \u043d\u0430\u0431\u043e\u0440 \u0441\u043b\u043e\u0435\u0432, \u0447\u0442\u043e \u0438 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a, \u043d\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443.<\/p>\n<pre><code class=\"python\">class DecoderLayer(nn.Module):     def __init__(self,                   hid_dim,                   n_heads,                   pf_dim,                   dropout,                   device):         super().__init__()                  self.self_attn_layer_norm = nn.LayerNorm(hid_dim)         self.enc_attn_layer_norm = nn.LayerNorm(hid_dim)         self.ff_layer_norm = nn.LayerNorm(hid_dim)         self.self_attention = MultiHeadAttentionLayer(hid_dim, n_heads, dropout, device)         self.encoder_attention = MultiHeadAttentionLayer(hid_dim, n_heads, dropout, device)         self.positionwise_feedforward = PositionwiseFeedforwardLayer(hid_dim,                                                                       pf_dim,                                                                       dropout)         self.dropout = nn.Dropout(dropout)              def forward(self, trg, enc_src, trg_mask, src_mask):                  #trg = [batch size, trg len, hid dim]         #enc_src = [batch size, src len, hid dim]         #trg_mask = [batch size, 1, trg len, trg len]         #src_mask = [batch size, 1, 1, src len]                  #self attention         _trg, _ = self.self_attention(trg, trg, trg, trg_mask)                  #dropout, residual connection and layer norm         trg = self.self_attn_layer_norm(trg + self.dropout(_trg))                      #trg = [batch size, trg len, hid dim]                      #encoder attention         _trg, attention = self.encoder_attention(trg, enc_src, enc_src, src_mask)                  #dropout, residual connection and layer norm         trg = self.enc_attn_layer_norm(trg + self.dropout(_trg))                              #trg = [batch size, trg len, hid dim]                  #positionwise feedforward         _trg = self.positionwise_feedforward(trg)                  #dropout, residual and layer norm         trg = self.ff_layer_norm(trg + self.dropout(_trg))                  #trg = [batch size, trg len, hid dim]         #attention = [batch size, n heads, trg len, src len]                  return trg, attention<\/code><\/pre>\n<h4>Seq2Seq<\/h4>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c <code>Seq2Seq<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u0438\u0440\u0443\u0435\u0442 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0438 \u0434\u0435\u043a\u043e\u0434\u0435\u0440, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u043c\u0430\u0441\u043e\u043a.<\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u0430\u044f \u043c\u0430\u0441\u043a\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u0430\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043d\u0435 \u0440\u0430\u0432\u043d\u0430 \u0442\u043e\u043a\u0435\u043d\u0443 <code>&lt;pad&gt;<\/code>. \u042d\u0442\u043e 1, \u043a\u043e\u0433\u0434\u0430 \u0442\u043e\u043a\u0435\u043d \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043a\u0435\u043d\u043e\u043c <code>&lt;pad&gt;<\/code>, \u0438 0, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u044d\u0442\u0438\u043c \u0442\u043e\u043a\u0435\u043d\u043e\u043c. \u0417\u0430\u0442\u0435\u043c \u043e\u043d &#171;\u0440\u0430\u0437\u0436\u0438\u043c\u0430\u0435\u0442\u0441\u044f&#187;, \u0447\u0442\u043e\u0431\u044b \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0442\u0440\u0430\u043d\u0441\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043c\u0430\u0441\u043a\u0438 \u043d\u0430 <code>energy<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u043c\u0435\u0435\u0442 \u0444\u043e\u0440\u043c\u0443 <strong><em>batchsize,nheads,seqlen,seqlen<\/em><\/strong>.<\/p>\n<p>\u0426\u0435\u043b\u0435\u0432\u0430\u044f \u043c\u0430\u0441\u043a\u0430 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043c\u0430\u0441\u043a\u0443 \u0434\u043b\u044f \u0442\u043e\u043a\u0435\u043d\u043e\u0432 <code>&lt;pad&gt;<\/code>, \u043a\u0430\u043a \u043c\u044b \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u043b\u0438 \u0434\u043b\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u043c\u0430\u0441\u043a\u0438. \u0414\u0430\u043b\u0435\u0435, \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u00ab\u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e\u00bb \u043c\u0430\u0441\u043a\u0443, <code>trg_sub_mask<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>torch.tril<\/code>. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u0434\u0438\u0430\u0433\u043e\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0430\u0442\u0440\u0438\u0446\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043d\u0430\u0434 \u0434\u0438\u0430\u0433\u043e\u043d\u0430\u043b\u044c\u044e \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0432\u043d\u044b \u043d\u0443\u043b\u044e, \u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043f\u043e\u0434 \u0434\u0438\u0430\u0433\u043e\u043d\u0430\u043b\u044c\u044e \u0431\u0443\u0434\u0443\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u044b \u043d\u0430 \u043b\u044e\u0431\u043e\u0439 \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u0435\u043d\u0437\u043e\u0440. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u043c \u0442\u0435\u043d\u0437\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0442\u0435\u043d\u0437\u043e\u0440, \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439 \u0435\u0434\u0438\u043d\u0438\u0446\u0430\u043c\u0438. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043d\u0430\u0448\u0430 <code>trg_sub_mask<\/code> \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a \u0434\u043b\u044f \u0446\u0435\u043b\u0438 \u0441 5 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"formula\" source=\"\\begin{matrix} 1 &amp; 0 &amp; 0 &amp; 0 &amp; 0\\\\ 1 &amp; 1 &amp; 0 &amp; 0 &amp; 0\\\\ 1 &amp; 1 &amp; 1 &amp; 0 &amp; 0\\\\ 1 &amp; 1 &amp; 1 &amp; 1 &amp; 0\\\\ 1 &amp; 1 &amp; 1 &amp; 1 &amp; 1\\\\ \\end{matrix}\" alt=\"\\begin{matrix} 1 &amp; 0 &amp; 0 &amp; 0 &amp; 0\\\\ 1 &amp; 1 &amp; 0 &amp; 0 &amp; 0\\\\ 1 &amp; 1 &amp; 1 &amp; 0 &amp; 0\\\\ 1 &amp; 1 &amp; 1 &amp; 1 &amp; 0\\\\ 1 &amp; 1 &amp; 1 &amp; 1 &amp; 1\\\\ \\end{matrix}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/62f\/4fb\/eb9\/62f4fbeb93cb4039f184b00f6035b273.svg\" width=\"131\" height=\"130\"><\/p>\n<p>\u042d\u0442\u043e \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u043d\u0430 \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0442\u043e\u043a\u0435\u043d \u0441\u0442\u0440\u043e\u043a\u0430 \u0441\u0442\u043e\u043b\u0431\u0435\u0446. \u041f\u0435\u0440\u0432\u044b\u0439 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0442\u043e\u043a\u0435\u043d \u0438\u043c\u0435\u0435\u0442 \u043c\u0430\u0441\u043a\u0443 <strong><em>1, 0, 0, 0, 0<\/em><\/strong>, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0442\u043e\u043a\u0435\u043d. \u0412\u0442\u043e\u0440\u043e\u0439 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0442\u043e\u043a\u0435\u043d \u0438\u043c\u0435\u0435\u0442 \u043c\u0430\u0441\u043a\u0443 <strong><em>1, 1, 0, 0, 0<\/em><\/strong>, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u043f\u0435\u0440\u0432\u044b\u0439, \u0442\u0430\u043a \u0438 \u0432\u0442\u043e\u0440\u043e\u0439 \u0446\u0435\u043b\u0435\u0432\u044b\u0435 \u0442\u043e\u043a\u0435\u043d\u044b.<\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u00ab\u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f\u00bb \u043c\u0430\u0441\u043a\u0430 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043c\u0430\u0441\u043a\u043e\u0439 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u0434\u0432\u0435 \u043c\u0430\u0441\u043a\u0438, \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u044f, \u0447\u0442\u043e \u043d\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u044b, \u043d\u0438 \u043c\u0430\u0440\u043a\u0435\u0440\u044b \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0431\u044b \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0434\u0432\u0430 \u0442\u043e\u043a\u0435\u043d\u0430 \u0431\u044b\u043b\u0438 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438 <code>&lt;pad&gt;<\/code>, \u043c\u0430\u0441\u043a\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u0430 \u0431\u044b \u0442\u0430\u043a:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"formula\" source=\"\\begin{matrix} 1 &amp; 0 &amp; 0 &amp; 0 &amp; 0\\\\ 1 &amp; 1 &amp; 0 &amp; 0 &amp; 0\\\\ 1 &amp; 1 &amp; 1 &amp; 0 &amp; 0\\\\ 1 &amp; 1 &amp; 1 &amp; 0 &amp; 0\\\\ 1 &amp; 1 &amp; 1 &amp; 0 &amp; 0\\\\ \\end{matrix}\" alt=\"\\begin{matrix} 1 &amp; 0 &amp; 0 &amp; 0 &amp; 0\\\\ 1 &amp; 1 &amp; 0 &amp; 0 &amp; 0\\\\ 1 &amp; 1 &amp; 1 &amp; 0 &amp; 0\\\\ 1 &amp; 1 &amp; 1 &amp; 0 &amp; 0\\\\ 1 &amp; 1 &amp; 1 &amp; 0 &amp; 0\\\\ \\end{matrix}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5eb\/1a9\/85c\/5eb1a985c27fe717e61df139567378e9.svg\" width=\"145\" height=\"143\"><\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u0430\u0441\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u044b, \u043e\u043d\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0441 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u043e\u043c \u0438 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u043e\u043c \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u0438 \u0446\u0435\u043b\u0435\u0432\u044b\u043c \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0430\u0448\u0435 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0435 \u0446\u0435\u043b\u0435\u0432\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u00aboutput\u00bb, \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435\u043c \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430 \u043a \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<pre><code class=\"python\">class Seq2Seq(nn.Module):     def __init__(self,                   encoder,                   decoder,                   src_pad_idx,                   trg_pad_idx,                   device):         super().__init__()                  self.encoder = encoder         self.decoder = decoder         self.src_pad_idx = src_pad_idx         self.trg_pad_idx = trg_pad_idx         self.device = device              def make_src_mask(self, src):                  #src = [batch size, src len]                  src_mask = (src != self.src_pad_idx).unsqueeze(1).unsqueeze(2)          #src_mask = [batch size, 1, 1, src len]          return src_mask          def make_trg_mask(self, trg):                  #trg = [batch size, trg len]                  trg_pad_mask = (trg != self.trg_pad_idx).unsqueeze(1).unsqueeze(2)                  #trg_pad_mask = [batch size, 1, 1, trg len]                  trg_len = trg.shape[1]                  trg_sub_mask = torch.tril(torch.ones((trg_len, trg_len), device = self.device)).bool()                  #trg_sub_mask = [trg len, trg len]                      trg_mask = trg_pad_mask &amp; trg_sub_mask                  #trg_mask = [batch size, 1, trg len, trg len]                  return trg_mask      def forward(self, src, trg):                  #src = [batch size, src len]         #trg = [batch size, trg len]                          src_mask = self.make_src_mask(src)         trg_mask = self.make_trg_mask(trg)                  #src_mask = [batch size, 1, 1, src len]         #trg_mask = [batch size, 1, trg len, trg len]                  enc_src = self.encoder(src, src_mask)                  #enc_src = [batch size, src len, hid dim]                          output, attention = self.decoder(trg, enc_src, trg_mask, src_mask)                  #output = [batch size, trg len, output dim]         #attention = [batch size, n heads, trg len, src len]                  return output, attention<\/code><\/pre>\n<h3>\u041e\u0431\u0443\u0447\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 Seq2Seq<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0430\u0448 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0438 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u044b. \u042d\u0442\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043c\u0435\u043d\u044c\u0448\u0435, \u0447\u0435\u043c \u0422\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u0432 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f\u0445, \u043d\u043e \u0435\u0451 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0435.<\/p>\n<pre><code class=\"python\">INPUT_DIM = len(SRC.vocab) OUTPUT_DIM = len(TRG.vocab) HID_DIM = 256 ENC_LAYERS = 3 DEC_LAYERS = 3 ENC_HEADS = 8 DEC_HEADS = 8 ENC_PF_DIM = 512 DEC_PF_DIM = 512 ENC_DROPOUT = 0.1 DEC_DROPOUT = 0.1  enc = Encoder(INPUT_DIM,                HID_DIM,                ENC_LAYERS,                ENC_HEADS,                ENC_PF_DIM,                ENC_DROPOUT,                device)  dec = Decoder(OUTPUT_DIM,                HID_DIM,                DEC_LAYERS,                DEC_HEADS,                DEC_PF_DIM,                DEC_DROPOUT,                device)<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0438 \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u0438\u0440\u0435\u043c \u043c\u043e\u0434\u0435\u043b\u044c sequence-to-sequence.<\/p>\n<pre><code class=\"python\">SRC_PAD_IDX = SRC.vocab.stoi[SRC.pad_token] TRG_PAD_IDX = TRG.vocab.stoi[TRG.pad_token]  model = Seq2Seq(enc, dec, SRC_PAD_IDX, TRG_PAD_IDX, device).to(device)<\/code><\/pre>\n<p>\u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0437\u0430\u043c\u0435\u0442\u0438\u0432, \u0447\u0442\u043e \u043e\u043d\u043e \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043c\u0435\u043d\u044c\u0448\u0435, \u0447\u0435\u043c 37 M \u0434\u043b\u044f \u043c\u043e\u0434\u0435\u043b\u0438 \u0441\u0432\u0451\u0440\u0442\u043e\u0447\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<pre><code class=\"python\">def count_parameters(model):     return sum(p.numel() for p in model.parameters() if p.requires_grad)  print(f'The model has {count_parameters(model):,} trainable parameters')<\/code><\/pre>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u043d\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442\u0441\u044f, \u043a\u0430\u043a\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0435\u0441\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0430\u0441\u044c, \u043e\u0434\u043d\u0430\u043a\u043e \u0444\u043e\u0440\u043c\u0430 Xavier, \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0430 \u0441\u0440\u0435\u0434\u0438 \u043c\u043e\u0434\u0435\u043b\u0435\u0439 Transformer, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0435\u0435 \u0437\u0434\u0435\u0441\u044c.<\/p>\n<pre><code class=\"python\">def initialize_weights(m):     if hasattr(m, 'weight') and m.weight.dim() &gt; 1:         nn.init.xavier_uniform_(m.weight.data)<\/code><\/pre>\n<pre><code class=\"python\">model.apply(initialize_weights);<\/code><\/pre>\n<p>\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0442\u043e\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 Transformer, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 Adam \u0441\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043f\u0435\u0440\u0438\u043e\u0434\u044b \u00ab\u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f\u00bb \u0438 \u00ab\u0442\u043e\u0440\u043c\u043e\u0436\u0435\u043d\u0438\u044f\u00bb. BERT \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 Transformer \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 Adam \u0441 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u044d\u0442\u043e. \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 <a href=\"http:\/\/nlp.seas.harvard.edu\/2018\/04\/03\/attention.html#optimizer\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u0443<\/a> \u0441\u0441\u044b\u043b\u043a\u0443 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u0433\u0440\u0430\u0444\u0438\u043a\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e Transformer.<\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043d\u0438\u0436\u0435, \u0447\u0435\u043c \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0439 \u0410\u0434\u0430\u043c\u043e\u043c, \u0438\u043d\u0430\u0447\u0435 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u043c.<\/p>\n<pre><code class=\"python\">LEARNING_RATE = 0.0005  optimizer = torch.optim.Adam(model.parameters(), lr = LEARNING_RATE)<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043d\u0430\u0448\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u043e\u0442\u0435\u0440\u044c, \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u044f \u043f\u043e\u0442\u0435\u0440\u0438, \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u0442\u043e\u043a\u0435\u043d\u0430\u043c <code>&lt;pad&gt;<\/code>. <\/p>\n<pre><code class=\"python\">criterion = nn.CrossEntropyLoss(ignore_index = TRG_PAD_IDX)<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043d\u0430\u0448 \u0446\u0438\u043a\u043b \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f. \u042d\u0442\u043e \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438.<\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0448\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u0430 \u0442\u043e\u043a\u0435\u043d <code>&lt;eos&gt;<\/code>, \u043d\u043e \u043d\u0435 \u0432\u044b\u0432\u043e\u0434\u0438\u043b\u0430 \u0435\u0433\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u043e\u0434\u0435\u043b\u0438, \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u0440\u0435\u0437\u0430\u0435\u043c \u0442\u043e\u043a\u0435\u043d <code>&lt;eos&gt;<\/code> \u0432 \u043a\u043e\u043d\u0446\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"formula\" source=\"\\begin{align*} \\text{trg} &amp;= [sos, x_1, x_2, x_3, eos]\\\\ \\text{trg[:-1]} &amp;= [sos, x_1, x_2, x_3] \\end{align*}\" alt=\"\\begin{align*} \\text{trg} &amp;= [sos, x_1, x_2, x_3, eos]\\\\ \\text{trg[:-1]} &amp;= [sos, x_1, x_2, x_3] \\end{align*}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/38e\/885\/061\/38e88506154cd453ea3ef94939647aa6.svg\" width=\"274\" height=\"54\"><\/p>\n<p><img decoding=\"async\" class=\"formula inline\" source=\"x_i\" alt=\"x_i\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fbe\/64b\/e6e\/fbe64be6e53da3869b5bb842bfad9fb5.svg\"> \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0432\u0432\u043e\u0434\u0438\u043c \u044d\u0442\u043e \u0432 \u043c\u043e\u0434\u0435\u043b\u044c, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f, \u043c\u044b \u043d\u0430\u0434\u0435\u0435\u043c\u0441\u044f, \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d <code>&lt;eos&gt;<\/code>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"formula\" source=\"\\begin{align*} \\text{output} &amp;= [y_1, y_2, y_3, eos] \\end{align*}\" alt=\"\\begin{align*} \\text{output} &amp;= [y_1, y_2, y_3, eos] \\end{align*}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ec1\/525\/924\/ec1525924459218249755877ff95ef69.svg\" width=\"229\" height=\"25\"><\/p>\n<p><img decoding=\"async\" class=\"formula inline\" source=\"y_i\" alt=\"y_i\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/95c\/8d3\/a57\/95c8d3a579efe21c82c9f8a4473b41d1.svg\"> \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u043f\u043e\u0442\u0435\u0440\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0442\u0435\u043d\u0437\u043e\u0440 <code>trg<\/code> \u0441 \u0442\u043e\u043a\u0435\u043d\u043e\u043c<code>&lt;sos&gt;<\/code>, \u043e\u0442\u0440\u0435\u0437\u0430\u043d\u043d\u044b\u043c \u0441\u043f\u0435\u0440\u0435\u0434\u0438, \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u0442\u043e\u043a\u0435\u043d<code>&lt;eos&gt;<\/code>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"formula\" source=\"\\begin{align*} \\text{output} &amp;= [y_1, y_2, y_3, eos]\\\\ \\text{trg[1:]} &amp;= [x_1, x_2, x_3, eos] \\end{align*}\" alt=\"\\begin{align*} \\text{output} &amp;= [y_1, y_2, y_3, eos]\\\\ \\text{trg[1:]} &amp;= [x_1, x_2, x_3, eos] \\end{align*}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f76\/b50\/2a2\/f76b502a25f7f08dcd7be31c4d558979.svg\" width=\"234\" height=\"54\"><\/p>\n<p>\u0420\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u0442\u0435\u0440\u0438 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u043a\u0430\u043a \u044d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0426\u0438\u043a\u043b \u043e\u0446\u0435\u043d\u043a\u0438 \u0442\u0430\u043a\u043e\u0439 \u0436\u0435, \u043a\u0430\u043a \u0446\u0438\u043a\u043b \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f, \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u0435\u0437 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u0430 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432.<\/p>\n<pre><code class=\"python\">def evaluate(model, iterator, criterion):          model.eval()          epoch_loss = 0          with torch.no_grad():              for i, batch in enumerate(iterator):              src = batch.src             trg = batch.trg              output, _ = model(src, trg[:,:-1])                          #output = [batch size, trg len - 1, output dim]             #trg = [batch size, trg len]                          output_dim = output.shape[-1]                          output = output.contiguous().view(-1, output_dim)             trg = trg[:,1:].contiguous().view(-1)                          #output = [batch size * trg len - 1, output dim]             #trg = [batch size * trg len - 1]                          loss = criterion(output, trg)              epoch_loss += loss.item()              return epoch_loss \/ len(iterator)<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c \u043d\u0430\u043c, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u044d\u043f\u043e\u0445\u0430.<\/p>\n<pre><code class=\"python\">def epoch_time(start_time, end_time):     elapsed_time = end_time - start_time     elapsed_mins = int(elapsed_time \/ 60)     elapsed_secs = int(elapsed_time - (elapsed_mins * 60))     return elapsed_mins, elapsed_secs<\/code><\/pre>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u044b \u043e\u0431\u0443\u0447\u0430\u0435\u043c \u043d\u0430\u0448\u0443 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c. \u042d\u0442\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u043e\u0447\u0442\u0438 \u0432 3 \u0440\u0430\u0437\u0430 \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u0447\u0435\u043c \u043c\u043e\u0434\u0435\u043b\u044c \u0441\u0432\u0435\u0440\u0442\u043e\u0447\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043c\u0435\u043d\u044c\u0448\u0443\u044e \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438!<\/p>\n<pre><code class=\"python\">N_EPOCHS = 10 CLIP = 1  best_valid_loss = float('inf') writer = SummaryWriter()  for epoch in range(N_EPOCHS):          start_time = time.time()          train_loss = train(model, train_iterator, optimizer, criterion, CLIP)     valid_loss = evaluate(model, valid_iterator, criterion)          end_time = time.time()          epoch_mins, epoch_secs = epoch_time(start_time, end_time)          if valid_loss &lt; best_valid_loss:         best_valid_loss = valid_loss         torch.save(model.state_dict(), 'tut6-model.pt')          print(f'Epoch: {epoch+1:02} | Time: {epoch_mins}m {epoch_secs}s')     print(f'\\tTrain Loss: {train_loss:.3f} | Train PPL: {math.exp(train_loss):7.3f}')     print(f'\\t Val. Loss: {valid_loss:.3f} |  Val. PPL: {math.exp(valid_loss):7.3f}')     writer.add_scalar(\"Train Loss\", train_loss, epoch+1)     writer.add_scalar(\"Train PPL\", math.exp(train_loss), epoch+1)     writer.add_scalar(\"Val. Loss\", valid_loss, epoch+1)     writer.add_scalar(\"Val. PPL\", math.exp(valid_loss), epoch+1)  writer.close()<\/code><\/pre>\n<p>\u041c\u044b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u043d\u0430\u0448\u0438 \u00ab\u043b\u0443\u0447\u0448\u0438\u0435\u00bb \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0438 \u0434\u043e\u0431\u0438\u0432\u0430\u0435\u043c\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438, \u0447\u0435\u043c \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u043b\u0438 \u0432\u0441\u0435 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438.<\/p>\n<pre><code class=\"python\">model.load_state_dict(torch.load('tut6-model.pt'))  test_loss = evaluate(model, test_iterator, criterion)  print(f'| Test Loss: {test_loss:.3f} | Test PPL: {math.exp(test_loss):7.3f} |')<\/code><\/pre>\n<h3>\u0412\u044b\u0432\u043e\u0434<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e\u0432 \u043d\u0430\u0448\u0435\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>translate_sentence<\/code>.<\/p>\n<p>\u0411\u044b\u043b\u0438 \u043f\u0440\u0435\u0434\u043f\u0440\u0438\u043d\u044f\u0442\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0448\u0430\u0433\u0438:<\/p>\n<ul>\n<li>\n<p>\u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u043d\u0435 \u0431\u044b\u043b\u043e \u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0439<\/p>\n<\/li>\n<li>\n<p>\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u043e\u043a\u0435\u043d\u044b <code>&lt;sos&gt;<\/code> \u0438 <code>&lt;eos&gt;<\/code><\/p>\n<\/li>\n<li>\n<p>\u043e\u0446\u0438\u0444\u0440\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0432 \u0442\u0435\u043d\u0437\u043e\u0440 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u0431\u0430\u0442\u0447\u0430<\/p>\n<\/li>\n<li>\n<p>\u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043c\u0430\u0441\u043a\u0443 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u043c\u0430\u0441\u043a\u0443 \u0432 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a<\/p>\n<\/li>\n<li>\n<p>\u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u043e\u043c <code>&lt;sos&gt;<\/code><\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u043a\u0430 \u043c\u044b \u043d\u0435 \u0434\u043e\u0441\u0442\u0438\u0433\u043b\u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b<\/p>\n<ul>\n<li>\n<p>\u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u0440\u043e\u0433\u043d\u043e\u0437 \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u0442\u0435\u043d\u0437\u043e\u0440 \u0441 \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c\u044e \u0431\u0430\u0442\u0447\u0430<\/p>\n<\/li>\n<li>\n<p>\u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043c\u0430\u0441\u043a\u0443 \u0446\u0435\u043b\u0435\u0432\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0432\u044b\u0445\u043e\u0434, \u0432\u044b\u0445\u043e\u0434 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u0438 \u043e\u0431\u0435 \u043c\u0430\u0441\u043a\u0438 \u0432 \u0434\u0435\u043a\u043e\u0434\u0435\u0440<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u043e\u0442 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435\u043c<\/p>\n<\/li>\n<li>\n<p>\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u043a \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u043d\u0438\u044e \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0435\u043c, \u0435\u0441\u043b\u0438 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u0431\u044b\u043b\u043e \u0442\u043e\u043a\u0435\u043d\u043e\u043c <code>&lt;eos&gt;<\/code><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\u0437 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432 \u0432 \u0442\u043e\u043a\u0435\u043d\u044b<\/p>\n<\/li>\n<li>\n<p>\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 (\u0441 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u044b\u043c \u0442\u043e\u043a\u0435\u043d\u043e\u043c <code>&lt;sos&gt;<\/code>) \u0438 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435\u043c \u0441 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0441\u043b\u043e\u044f<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"python\">def translate_sentence(sentence, src_field, trg_field, model, device, max_len = 50):          model.eval()              if isinstance(sentence, str):         nlp = spacy.load('de_core_news_sm')         tokens = [token.text.lower() for token in nlp(sentence)]     else:         tokens = [token.lower() for token in sentence]      tokens = [src_field.init_token] + tokens + [src_field.eos_token]              src_indexes = [src_field.vocab.stoi[token] for token in tokens]      src_tensor = torch.LongTensor(src_indexes).unsqueeze(0).to(device)          src_mask = model.make_src_mask(src_tensor)          with torch.no_grad():         enc_src = model.encoder(src_tensor, src_mask)      trg_indexes = [trg_field.vocab.stoi[trg_field.init_token]]      for i in range(max_len):          trg_tensor = torch.LongTensor(trg_indexes).unsqueeze(0).to(device)          trg_mask = model.make_trg_mask(trg_tensor)                  with torch.no_grad():             output, attention = model.decoder(trg_tensor, enc_src, trg_mask, src_mask)                  pred_token = output.argmax(2)[:,-1].item()                  trg_indexes.append(pred_token)          if pred_token == trg_field.vocab.stoi[trg_field.eos_token]:             break          trg_tokens = [trg_field.vocab.itos[i] for i in trg_indexes]          return trg_tokens[1:], attention<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043a \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0443 \u044d\u0442\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 8 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0439, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u044c \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435\u043c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u043d\u0438\u0445.<\/p>\n<pre><code class=\"python\">def display_attention(sentence, translation, attention, n_heads = 8, n_rows = 4, n_cols = 2):          assert n_rows * n_cols == n_heads          fig = plt.figure(figsize=(15,25))          for i in range(n_heads):                  ax = fig.add_subplot(n_rows, n_cols, i+1)                  _attention = attention.squeeze(0)[i].cpu().detach().numpy()          cax = ax.matshow(_attention, cmap='bone')          ax.tick_params(labelsize=12)         ax.set_xticklabels(['']+['&lt;sos&gt;']+[t.lower() for t in sentence]+['&lt;eos&gt;'],                             rotation=45)         ax.set_yticklabels(['']+translation)          ax.xaxis.set_major_locator(ticker.MultipleLocator(1))         ax.yaxis.set_major_locator(ticker.MultipleLocator(1))      plt.show()     plt.close()<\/code><\/pre>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u043e\u0437\u044c\u043c\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0437 \u043e\u0431\u0443\u0447\u0430\u044e\u0449\u0435\u0439 \u0432\u044b\u0431\u043e\u0440\u043a\u0438.<\/p>\n<pre><code class=\"python\">example_idx = 8  src = vars(train_data.examples[example_idx])['src'] trg = vars(train_data.examples[example_idx])['trg']  print(f'src = {src}') print(f'trg = {trg}')<\/code><\/pre>\n<h3>BLEU<\/h3>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u044b \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u043e\u0446\u0435\u043d\u043a\u0443 BLEU \u0434\u043b\u044f \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0440\u0430.<\/p>\n<pre><code class=\"python\">from torchtext.data.metrics import bleu_score  def calculate_bleu(data, src_field, trg_field, model, device, max_len = 50):          trgs = []     pred_trgs = []          for datum in data:                  src = vars(datum)['src']         trg = vars(datum)['trg']                  pred_trg, _ = translate_sentence(src, src_field, trg_field, model, device, max_len)                  #cut off &lt;eos&gt; token         pred_trg = pred_trg[:-1]                  pred_trgs.append(pred_trg)         trgs.append([trg])              return bleu_score(pred_trgs, trgs) <\/code><\/pre>\n<p>\u041c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043e\u0446\u0435\u043d\u043a\u0443 BLEU 36,52, \u0447\u0442\u043e \u043f\u0440\u0435\u0432\u043e\u0441\u0445\u043e\u0434\u0438\u0442 ~ 34 \u0434\u043b\u044f \u0441\u0432\u0451\u0440\u0442\u043e\u0447\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 sequence-to-sequence \u0438 ~ 28 \u0434\u043b\u044f \u043c\u043e\u0434\u0435\u043b\u0438 RNN, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043d\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0438. \u0418 \u0432\u0441\u0435 \u044d\u0442\u043e \u0441 \u043d\u0430\u0438\u043c\u0435\u043d\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0438 \u0441\u0430\u043c\u044b\u043c \u0431\u044b\u0441\u0442\u0440\u044b\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f!<\/p>\n<h3>\u041e\u0431\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u0435\u0442\u0438 \u0438\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>\u0412 \u043a\u043e\u043d\u0446\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043e\u0434\u0438\u043d \u0438\u0437 \u043c\u043e\u0438\u0445 \u043b\u044e\u0431\u0438\u043c\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432: \u0442\u0435\u0441\u0442 \u043d\u0430 \u0438\u043d\u0432\u0435\u0440\u0441\u0438\u044e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0434\u043b\u044f \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u0443\u0447\u0435\u043d\u0438\u043a\u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0448\u043a\u043e\u043b\u044b \u043e\u0431\u0443\u0447\u0430\u044e\u0442\u0441\u044f \u0437\u0430 10-15 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432, \u043d\u043e, \u043f\u043e\u0440\u043e\u0439, \u043d\u0435\u043f\u0440\u0435\u043e\u0434\u043e\u043b\u0438\u043c\u0430 \u0434\u043b\u044f \u0438\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c.<\/p>\n<p>\u0414\u043b\u044f Google Colab \u0441\u043a\u0430\u0447\u0430\u0435\u043c \u043e\u0431\u0443\u0447\u0430\u044e\u0449\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438<\/p>\n<pre><code class=\"python\">!wget https:\/\/raw.githubusercontent.com\/vasiliyeskin\/bentrevett-pytorch-seq2seq_ru\/master\/toy_revert\/train.csv -P toy_revert !wget https:\/\/raw.githubusercontent.com\/vasiliyeskin\/bentrevett-pytorch-seq2seq_ru\/master\/toy_revert\/val.csv -P toy_revert !wget https:\/\/raw.githubusercontent.com\/vasiliyeskin\/bentrevett-pytorch-seq2seq_ru\/master\/toy_revert\/test.csv -P toy_revert<\/code><\/pre>\n<p>\u0412 \u043d\u0430\u0447\u0430\u043b\u0435 \u043e\u0431\u0443\u0447\u0438\u043c \u0441\u0435\u0442\u044c \u0438\u043d\u0432\u0435\u0440\u0441\u0438\u0438 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<pre><code class=\"python\">SRC = Field(tokenize=\"spacy\",             init_token='&lt;sos&gt;',             eos_token='&lt;eos&gt;',             lower=True,              batch_first = True)  TRG = Field(tokenize=\"spacy\",             init_token='&lt;sos&gt;',             eos_token='&lt;eos&gt;',             lower=True,              batch_first = True)  data_fields = [('src', SRC), ('trg', TRG)] # load the dataset in csv format train_data, valid_data, test_data = TabularDataset.splits(     path='toy_revert',     train='train.csv',     validation='val.csv',     test='test.csv',     format='csv',     fields=data_fields,     skip_header=True )  SRC.build_vocab(train_data) TRG.build_vocab(train_data)<\/code><\/pre>\n<pre><code class=\"python\">device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')  BATCH_SIZE = 32  train_iterator, valid_iterator, test_iterator = BucketIterator.splits(     (train_data, valid_data, test_data),       batch_size = BATCH_SIZE,      sort_key = lambda x: len(x.src),      sort_within_batch=True,      device = device)    ################## create DNN Seq2Seq ###############################  INPUT_DIM = len(SRC.vocab) OUTPUT_DIM = len(TRG.vocab) HID_DIM = 64 ENC_LAYERS = 3 DEC_LAYERS = 3 ENC_HEADS = 8 DEC_HEADS = 8 ENC_PF_DIM = 512 DEC_PF_DIM = 512 ENC_DROPOUT = 0.1 DEC_DROPOUT = 0.1  enc = Encoder(INPUT_DIM,               HID_DIM,               ENC_LAYERS,               ENC_HEADS,               ENC_PF_DIM,               ENC_DROPOUT,               device)  dec = Decoder(OUTPUT_DIM,               HID_DIM,               DEC_LAYERS,               DEC_HEADS,               DEC_PF_DIM,               DEC_DROPOUT,               device)   SRC_PAD_IDX = SRC.vocab.stoi[SRC.pad_token] TRG_PAD_IDX = TRG.vocab.stoi[TRG.pad_token]  model = Seq2Seq(enc, dec, SRC_PAD_IDX, TRG_PAD_IDX, device).to(device)  ####################################################################   ####### initial weights model.apply(initialize_weights); # print(model)  print(f'The model has {count_parameters(model):,} trainable parameters')  optimizer = optim.Adam(model.parameters(), lr = LEARNING_RATE) criterion = nn.CrossEntropyLoss(ignore_index=TRG_PAD_IDX)  N_EPOCHS = 30 CLIP = 1  best_valid_loss = float('inf')  for epoch in range(N_EPOCHS):      start_time = time.time()      train_loss = train(model, train_iterator, optimizer, criterion, CLIP)     valid_loss = evaluate(model, valid_iterator, criterion)      end_time = time.time()      epoch_mins, epoch_secs = epoch_time(start_time, end_time)      if valid_loss &lt; best_valid_loss:         best_valid_loss = valid_loss         torch.save(model.state_dict(), 'tut3-model.pt')      print(f'Epoch: {epoch + 1:02} | Time: {epoch_mins}m {epoch_secs}s')     print(f'\\tTrain Loss: {train_loss:.3f} | Train PPL: {math.exp(train_loss):7.3f}')     print(f'\\t Val. Loss: {valid_loss:.3f} |  Val. PPL: {math.exp(valid_loss):7.3f}')      # writer.add_scalar(\"Train_loss_average_per_epoch\", train_loss, epoch)     # writer.add_scalar(\"Validate_loss_average_per_epoch\", valid_loss, epoch)  model.load_state_dict(torch.load('tut3-model.pt'))  test_loss = evaluate(model, test_iterator, criterion)  print(f'| Test Loss: {test_loss:.3f} | Test PPL: {math.exp(test_loss):7.3f} |')<\/code><\/pre>\n<pre><code class=\"python\">def translate_sentence(sentence, src_field, trg_field, model, device, max_len = 20):          model.eval()              if isinstance(sentence, str):         nlp = spacy.load('de_core_news_sm')         tokens = [token.text.lower() for token in nlp(sentence)]     else:         tokens = [token.lower() for token in sentence]      tokens = [src_field.init_token] + tokens + [src_field.eos_token]              src_indexes = [src_field.vocab.stoi[token] for token in tokens]      src_tensor = torch.LongTensor(src_indexes).unsqueeze(0).to(device)          src_mask = model.make_src_mask(src_tensor)          with torch.no_grad():         enc_src = model.encoder(src_tensor, src_mask)      trg_indexes = [trg_field.vocab.stoi[trg_field.init_token]]      for i in range(max_len):          trg_tensor = torch.LongTensor(trg_indexes).unsqueeze(0).to(device)          trg_mask = model.make_trg_mask(trg_tensor)                  with torch.no_grad():             output, attention = model.decoder(trg_tensor, enc_src, trg_mask, src_mask)                  pred_token = output.argmax(2)[:,-1].item()                  trg_indexes.append(pred_token)          if pred_token == trg_field.vocab.stoi[trg_field.eos_token]:             break          trg_tokens = [trg_field.vocab.itos[i] for i in trg_indexes]          return trg_tokens[1:], attention<\/code><\/pre>\n<pre><code class=\"python\">from torchtext.data.metrics import bleu_score  def calculate_bleu(data, src_field, trg_field, model, device, max_len = 20):          trgs = []     pred_trgs = []          for datum in data:                  src = vars(datum)['src']         trg = vars(datum)['trg']                  pred_trg, _ = translate_sentence(src, src_field, trg_field, model, device, max_len)                  #cut off &lt;eos&gt; token         pred_trg = pred_trg[:-1]                  pred_trgs.append(pred_trg)         trgs.append([trg])              return bleu_score(pred_trgs, trgs)<\/code><\/pre>\n<pre><code class=\"python\">example_idx = 10  src = vars(test_data.examples[example_idx])['src'] trg = vars(test_data.examples[example_idx])['trg']  print(f'src = {src}') print(f'trg = {trg}')  print(f'source        = {src}') translation, attention =  translate_sentence(src, SRC, TRG, model, device) display_attention(src, translation, attention)  print(f'predicted trg = {translation}')  src = ['a', 'b', 'c', 'a', 'd'] print(f'source        = {src}') translation, attention =  translate_sentence(src, SRC, TRG, model, device) display_attention(src, translation, attention) print(f'predicted trg = {translation}')  src = 'd b c d'.split(' ') print(f'source        = {src}') translation, attention =  translate_sentence(src, SRC, TRG, model, device) display_attention(src, translation, attention) print(f'predicted trg = {translation}')  src = ['a', 'a', 'a', 'a', 'd'] print(f'source        = {src}') translation, attention = translate_sentence(src, SRC, TRG, model, device) print(f'predicted trg = {translation}')  src = ['d', 'b', 'c', 'a'] print(f'source        = {src}') translation, attention = translate_sentence(src, SRC, TRG, model, device) print(f'predicted trg = {translation}')  src = ['d', 'd', 'd', 'd', 'd', 'd', 'd', 'd'] print(f'source        = {src}') translation, attention = translate_sentence(src, SRC, TRG, model, device) print(f'predicted trg = {translation}')   bleu_score = calculate_bleu(test_data, SRC, TRG, model, device) print(f'BLEU score = {bleu_score * 100:.2f}')<\/code><\/pre>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/568304\/\"> https:\/\/habr.com\/ru\/post\/568304\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<h2>6 &#8212; Attention is All You Need<\/h2>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0433\u043a\u0430\u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u0443\u044e\u0432\u0435\u0440\u0441\u0438\u044e \u043c\u043e\u0434\u0435\u043b\u0438 Transformer \u0438\u0437 \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/arxiv.org\/abs\/1706.03762\" rel=\"noopener noreferrer nofollow\">Attention is All You Need<\/a>. \u0412\u0441\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0432\u0437\u044f\u0442\u044b \u0438\u0437 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438. \u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e Transformer \u043e\u0431\u0440\u0430\u0449\u0430\u0439\u0442\u0435\u0441\u044c <a href=\"https:\/\/www.mihaileric.com\/posts\/transformers-attention-in-disguise\/\" rel=\"noopener noreferrer nofollow\">\u0441\u044e\u0434\u0430<\/a>, <a href=\"https:\/\/jalammar.github.io\/illustrated-transformer\/\" rel=\"noopener noreferrer nofollow\">\u0441\u044e\u0434\u0430<\/a> <a href=\"http:\/\/nlp.seas.harvard.edu\/2018\/04\/03\/attention.html\" rel=\"noopener noreferrer nofollow\">\u0438 \u0441\u044e\u0434\u0430<\/a>. \u041d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435 <a href=\"https:\/\/habr.com\/ru\/post\/486358\/\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<h3>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h3>\n<p>\u041f\u043e\u0434\u043e\u0431\u043d\u043e \u0441\u0432\u0451\u0440\u0442\u043e\u0447\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 Sequence-to-Sequence, Transformer \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u0440\u0435\u043a\u0443\u0440\u0440\u0435\u043d\u0442\u043d\u043e\u0441\u0442\u0438. \u041e\u043d \u0442\u0430\u043a\u0436\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u0432\u0451\u0440\u0442\u043e\u0447\u043d\u044b\u0435 \u0441\u043b\u043e\u0438. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0445 \u0441\u043b\u043e\u0435\u0432, \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u043e\u0432 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0438 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>\u041f\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e \u043d\u0430 \u044f\u043d\u0432\u0430\u0440\u044c 2020 \u0433\u043e\u0434\u0430 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0434\u043e\u043c\u0438\u043d\u0438\u0440\u0443\u044e\u0449\u0435\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043e\u0439 \u0432 NLP \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434\u043e\u0432\u044b\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0432\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0437\u0430\u0434\u0430\u0447, \u0438 \u043f\u043e\u0445\u043e\u0436\u0435, \u0447\u0442\u043e \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u043c\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u043c \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u044f\u0437\u044b\u043a\u043e\u0432.<\/p>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 Transformer \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u044d\u0442\u043e <a href=\"https:\/\/arxiv.org\/abs\/1810.04805\" rel=\"noopener noreferrer nofollow\">BERT<\/a> (<strong>B<\/strong>idirectional <strong>E<\/strong>ncoder <strong>R<\/strong>epresentations from <strong>T<\/strong>ransformers) \u0438 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 BERT \u043e\u0431\u044b\u0447\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u043c\u0435\u043d\u044b \u0441\u043b\u043e\u0451\u0432 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430 \u2014 \u0435\u0441\u043b\u0438 \u043d\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 &#8212; \u0432 NLP \u043c\u043e\u0434\u0435\u043b\u044f\u0445.<\/p>\n<p>\u0420\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0439 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u043d\u044b\u043c\u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0440\u0430\u043c\u0438, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/huggingface.co\/transformers\/\" rel=\"noopener noreferrer nofollow\">Transformers<\/a>, \u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 <a href=\"https:\/\/huggingface.co\/transformers\/pretrained_models.html\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a> \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439.<\/p>\n<p>\u0420\u0430\u0437\u043b\u0438\u0447\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0432 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0438 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435:<\/p>\n<ul>\n<li>\n<p>\u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043e\u0431\u0443\u0447\u0435\u043d\u043d\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u0443\u044e \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0443 \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439<\/p>\n<\/li>\n<li>\n<p>\u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0442\u043e\u0440 Adam \u0441\u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u0441 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0449\u0435\u0439\u0441\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e<\/p>\n<\/li>\n<li>\n<p>\u043c\u044b \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0433\u043b\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u043a<\/p>\n<\/li>\n<\/ul>\n<p>\u041c\u044b \u0432\u043d\u043e\u0441\u0438\u043c \u0432\u0441\u0435 \u044d\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d\u0438 \u0431\u043b\u0438\u0437\u043a\u0438 \u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c BERT \u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 Transformer \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0443\u044e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443.<\/p>\n<p>\u041a\u0430\u043a \u0438 \u0440\u0430\u043d\u0435\u0435, \u0435\u0441\u043b\u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u043f\u043e\u0441\u0442\u0430 \u0432\u0430\u0441 \u043d\u0435 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442, \u0442\u043e \u043d\u0438\u0436\u0435 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0443\u044e \u0438 \u0440\u0443\u0441\u0441\u043a\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e jupyter notebook:<\/p>\n<p><a href=\"https:\/\/github.com\/bentrevett\/pytorch-seq2seq\/blob\/master\/6%20-%20Attention%20is%20All%20You%20Need.ipynb\" rel=\"noopener noreferrer nofollow\">\u0418\u0441\u0445\u043e\u0434\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f<\/a> <a href=\"https:\/\/colab.research.google.com\/github\/bentrevett\/pytorch-seq2seq\/blob\/master\/6%20-%20Attention%20is%20All%20You%20Need.ipynb\" rel=\"noopener noreferrer nofollow\">Open jupyter notebook In Colab<\/a><\/p>\n<p><a href=\"https:\/\/github.com\/vasiliyeskin\/bentrevett-pytorch-seq2seq_ru\/blob\/master\/6%20-%20Attention%20is%20All%20You%20Need.ipynb\" rel=\"noopener noreferrer nofollow\">\u0420\u0443\u0441\u0441\u043a\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f<\/a> <a href=\"https:\/\/colab.research.google.com\/github\/vasiliyeskin\/bentrevett-pytorch-seq2seq_ru\/blob\/master\/6%20-%20Attention%20is%20All%20You%20Need.ipynb\" rel=\"noopener noreferrer nofollow\">Open jupyter notebook In Colab<\/a><\/p>\n<p><strong>\u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/strong>: \u0440\u0443\u0441\u0441\u043a\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f jupyter notebook \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u0432 \u043a\u043e\u043d\u0446\u0435 \u0442\u0435\u0441\u0442\u043e\u043c \u043d\u0430 \u0438\u043d\u0432\u0435\u0440\u0441\u0438\u044e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<h3>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/h3>\n<p>\u041a\u0430\u043a \u0432\u0441\u0435\u0433\u0434\u0430, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u0438 \u0437\u0430\u0434\u0430\u0434\u0438\u043c \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0435 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u0447\u0438\u0441\u043b\u0430 \u0434\u043b\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438.<\/p>\n<pre><code class=\"python\">import torch import torch.nn as nn import torch.optim as optim  import torchtext from torchtext.legacy.datasets import Multi30k from torchtext.legacy.data import Field, BucketIterator, TabularDataset  import matplotlib.pyplot as plt import matplotlib.ticker as ticker  import spacy import numpy as np  import random import math import time<\/code><\/pre>\n<pre><code class=\"python\">SEED = 1234  random.seed(SEED) np.random.seed(SEED) torch.manual_seed(SEED) torch.cuda.manual_seed(SEED) torch.backends.cudnn.deterministic = True<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 Google Colab \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b (\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 colab runtime! \u041d\u0430\u0438\u0431\u044b\u0441\u0442\u0440\u0435\u0439\u0448\u0438\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0440\u043e\u0442\u043a\u0443\u044e \u043a\u043e\u043c\u0430\u0434\u0443\uff1a <strong>Ctrl + M + .<\/strong>):<\/p>\n<pre><code class=\"python\">!pip install -U spacy==3.0 !python -m spacy download en_core_web_sm !python -m spacy download de_core_news_sm<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u0430\u0448\u0438 \u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u044b, \u043a\u0430\u043a \u0438 \u0440\u0430\u043d\u044c\u0448\u0435.<\/p>\n<pre><code class=\"python\">spacy_de = spacy.load('de_core_news_sm') spacy_en = spacy.load('en_core_web_sm')<\/code><\/pre>\n<pre><code class=\"python\">def tokenize_de(text):     \"\"\"     Tokenizes German text from a string into a list of strings     \"\"\"     return [tok.text for tok in spacy_de.tokenizer(text)]  def tokenize_en(text):     \"\"\"     Tokenizes English text from a string into a list of strings     \"\"\"     return [tok.text for tok in spacy_en.tokenizer(text)]   def tokenize_text(text):     \"\"\"     Tokenizes English text from a string into a list of strings     \"\"\"     return [tok.text for tok in text.split(' ')]<\/code><\/pre>\n<p>\u041d\u0430\u0448\u0438 \u043f\u043e\u043b\u044f \u0442\u0430\u043a\u0438\u0435 \u0436\u0435, \u043a\u0430\u043a \u0438 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0447\u0430\u0441\u0442\u044f\u0445. \u041c\u043e\u0434\u0435\u043b\u044c \u043e\u0436\u0438\u0434\u0430\u0435\u0442, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0432\u0432\u0435\u0434\u0435\u043d\u044b \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441 \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c\u044e \u0431\u0430\u0442\u0447\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c<code>batch_first = True<\/code>.<\/p>\n<pre><code class=\"python\"> SRC = Field(tokenize = tokenize_de,              init_token = '&lt;sos&gt;',              eos_token = '&lt;eos&gt;',              lower = True,              batch_first = True)  TRG = Field(tokenize = tokenize_en,              init_token = '&lt;sos&gt;',              eos_token = '&lt;eos&gt;',              lower = True,              batch_first = True)<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u043d\u0430\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 Multi30k \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u043b\u043e\u0432\u0430\u0440\u044c.<\/p>\n<pre><code class=\"python\">train_data, valid_data, test_data = Multi30k.splits(exts = ('.de', '.en'),                                                      fields = (SRC, TRG))<\/code><\/pre>\n<pre><code class=\"python\">SRC.build_vocab(train_data, min_freq = 2) TRG.build_vocab(train_data, min_freq = 2)<\/code><\/pre>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0434\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0438 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<pre><code class=\"python\">device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')<\/code><\/pre>\n<pre><code class=\"python\">BATCH_SIZE = 128  train_iterator, valid_iterator, test_iterator = BucketIterator.splits(     (train_data, valid_data, test_data),       batch_size = BATCH_SIZE,      device = device)<\/code><\/pre>\n<h3>\u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438<\/h3>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u043c\u043e\u0434\u0435\u043b\u044c. \u041a\u0430\u043a \u0438 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0447\u0430\u0441\u0442\u044f\u0445, \u043e\u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 <em>\u043a\u043e\u0434\u0435\u0440\u0430<\/em> \u0438 <em>\u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430<\/em>, \u0441 \u043a\u043e\u0434\u0435\u0440\u043e\u043c <em>\u043a\u043e\u0434\u0438\u0440\u0443\u044e\u0449\u0438\u043c<\/em> \u0432\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430\u043d\u0435\u043c\u0435\u0446\u043a\u043e\u043c\u044f\u0437\u044b\u043a\u0435 \u0432 <em>\u0432\u0435\u043a\u0442\u043e\u0440 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430<\/em> \u0438 \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 <em>\u0434\u0435\u043a\u043e\u0434\u0438\u0440\u0443\u0435\u0442<\/em> \u044d\u0442\u043e\u0442 \u0432\u0435\u043a\u0442\u043e\u0440 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430\u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c\u044f\u0437\u044b\u043a\u0435.<\/p>\n<h4>\u041a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a<\/h4>\n<p>\u041f\u043e\u0434\u043e\u0431\u043d\u043e \u043c\u043e\u0434\u0435\u043b\u0438 ConvSeq2Seq, \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a Transformer \u043d\u0435 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0441\u0436\u0430\u0442\u044c \u0432\u0441\u0451 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435   \u0432 \u0435\u0434\u0438\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 . \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u043e\u043d \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 . \u0418\u0442\u0430\u043a, \u0435\u0441\u043b\u0438 \u0431\u044b \u043d\u0430\u0448\u0430 \u0432\u0445\u043e\u0434\u043d\u0430\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043b\u0430 \u0438\u0437 5 \u0442\u043e\u043a\u0435\u043d\u043e\u0432, \u0443 \u043d\u0430\u0441 \u0431\u044b\u043b\u043e \u0431\u044b . \u041f\u043e\u0447\u0435\u043c\u0443 \u043c\u044b \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u044d\u0442\u043e\u0442 \u0442\u0435\u043d\u0437\u043e\u0440 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u044b\u0445 \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432, \u0430 \u043d\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043a\u0440\u044b\u0442\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439? \u0421\u043a\u0440\u044b\u0442\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438  \u0432 RNN \u0432\u0438\u0434\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u043a\u0435\u043d\u044b \u0438 \u0432\u0441\u0435 \u0442\u043e\u043a\u0435\u043d\u044b, \u0447\u0442\u043e \u0431\u044b\u043b\u0438 \u043f\u0435\u0440\u0435\u0434 \u043d\u0438\u043c. \u041e\u0434\u043d\u0430\u043a\u043e \u0437\u0434\u0435\u0441\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 <code>\u0432\u0438\u0434\u0435\u043b<\/code> \u0432\u0441\u0435 \u0442\u043e\u043a\u0435\u043d\u044b \u0432\u043e \u0432\u0441\u0435\u0445 \u043f\u043e\u0437\u0438\u0446\u0438\u044f\u0445 \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0442\u043e\u043a\u0435\u043d\u044b \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442 \u0447\u0435\u0440\u0435\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0441\u043b\u043e\u0439 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u043a\u0443\u0440\u0440\u0435\u043d\u0442\u043d\u043e\u0439, \u043e\u043d\u0430 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u041c\u044b \u0440\u0435\u0448\u0430\u0435\u043c \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u043b\u043e\u0439 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 <em>\u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u043b\u043e\u0439 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430<\/em> positionalembeddinglayer. \u042d\u0442\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432\u0445\u043e\u0434\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435 \u0441\u0430\u043c \u0442\u043e\u043a\u0435\u043d, \u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u0442\u043e\u043a\u0435\u043d\u0430 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430, \u0442\u043e\u043a\u0435\u043d\u0430 <code>&lt;sos&gt;<\/code> \u043d\u0430\u0447\u0430\u043b\u043e\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 0. \u041f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433 \u0438\u043c\u0435\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u043b\u043e\u0432\u0430\u0440\u044f, \u0440\u0430\u0432\u043d\u044b\u0439 100, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043d\u0430\u0448\u0430 \u043c\u043e\u0434\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u0438\u043d\u043e\u0439 \u0434\u043e 100 \u0442\u043e\u043a\u0435\u043d\u043e\u0432. \u0415\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c, \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0434\u043b\u0438\u043d\u043d\u044b\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f Transformer \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 Attention is All You Need \u043d\u0435 \u043e\u0431\u0443\u0447\u0430\u043b\u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0432 \u043d\u0435\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433. \u0421\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b Transformer, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a BERT, \u0432\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 \u044d\u0442\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044c <a href=\"http:\/\/nlp.seas.harvard.edu\/2018\/04\/03\/attention.html#positional-encoding\" rel=\"noopener noreferrer nofollow\">\u0441\u044e\u0434\u0430<\/a>, \u0447\u0442\u043e\u0431\u044b \u0443\u0437\u043d\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043e \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430\u0445, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 Transformer.<\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u0442\u043e\u043a\u0435\u043d \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430 \u043f\u043e\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043d\u043e \u0441\u0443\u043c\u043c\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u0435\u043a\u0442\u043e\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0442\u043e\u043a\u0435\u043d\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0435\u0433\u043e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u0435\u0440\u0435\u0434 \u0441\u0443\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430 \u043e\u043d\u0438 \u0443\u043c\u043d\u043e\u0436\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0440\u0430\u0432\u043d\u044b\u0439 , \u0433\u0434\u0435  \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u043a\u0440\u044b\u0442\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f <code>hid_dim<\/code>. \u042d\u0442\u043e \u044f\u043a\u043e\u0431\u044b \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442 \u0434\u0438\u0441\u043f\u0435\u0440\u0441\u0438\u044e \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430, \u0438 \u043c\u043e\u0434\u0435\u043b\u044c \u0442\u0440\u0443\u0434\u043d\u043e \u043e\u0431\u0443\u0447\u0438\u0442\u044c \u0431\u0435\u0437 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u0430 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0417\u0430\u0442\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u0440\u043e\u043f\u0430\u0443\u0442 \u0434\u043b\u044f \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u044d\u043c\u0435\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430.<\/p>\n<p>\u041a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u044d\u043c\u0435\u0431\u0435\u0434\u0434\u0438\u043d\u0433 \u0437\u0430\u0442\u0435\u043c \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437  <em>\u0441\u043b\u043e\u0435\u0432 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430<\/em> \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f , \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u0435\u043a\u043e\u0434\u0435\u0440\u043e\u043c.<\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u0430\u044f \u043c\u0430\u0441\u043a\u0430 <code>src_mask<\/code> \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u043c\u0435\u0435\u0442 \u0442\u0443 \u0436\u0435 \u0444\u043e\u0440\u043c\u0443, \u0447\u0442\u043e \u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043d\u043e \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 1, \u043a\u043e\u0433\u0434\u0430 \u0442\u043e\u043a\u0435\u043d \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043a\u0435\u043d\u043e\u043c <code>&lt;pad&gt;<\/code> \u0438 0, \u043a\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u0442\u043e\u043a\u0435\u043d <code>&lt;pad&gt;<\/code>. \u042d\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0441\u043b\u043e\u044f\u0445 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u0434\u043b\u044f \u043c\u0430\u0441\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u043e\u0432 \u043c\u043d\u043e\u0433\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043a \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043d\u0430 \u0442\u043e\u043a\u0435\u043d\u044b <code>&lt;pad&gt;<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438.<\/p>\n<pre><code class=\"python\">class Encoder(nn.Module):     def __init__(self,                   input_dim,                   hid_dim,                   n_layers,                   n_heads,                   pf_dim,                  dropout,                   device,                  max_length = 100):         super().__init__()          self.device = device                  self.tok_embedding = nn.Embedding(input_dim, hid_dim)         self.pos_embedding = nn.Embedding(max_length, hid_dim)                  self.layers = nn.ModuleList([EncoderLayer(hid_dim,                                                    n_heads,                                                    pf_dim,                                                   dropout,                                                    device)                                       for _ in range(n_layers)])                  self.dropout = nn.Dropout(dropout)                  self.scale = torch.sqrt(torch.FloatTensor([hid_dim])).to(device)              def forward(self, src, src_mask):                  #src = [batch size, src len]         #src_mask = [batch size, 1, 1, src len]                  batch_size = src.shape[0]         src_len = src.shape[1]                  pos = torch.arange(0, src_len).unsqueeze(0).repeat(batch_size, 1).to(self.device)                  #pos = [batch size, src len]                  src = self.dropout((self.tok_embedding(src) * self.scale) + self.pos_embedding(pos))                  #src = [batch size, src len, hid dim]                  for layer in self.layers:             src = layer(src, src_mask)                      #src = [batch size, src len, hid dim]                      return src<\/code><\/pre>\n<h4>\u0421\u043b\u043e\u0439 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430<\/h4>\n<p>\u0421\u043b\u043e\u0438 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 \u2014 \u044d\u0442\u043e \u043c\u0435\u0441\u0442\u043e, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0435 \u0432\u0441\u044e \u00ab\u0441\u043e\u043b\u044c\u00bb \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u0435\u0433\u043e \u043c\u0430\u0441\u043a\u0443 \u0432 <em>\u0441\u043b\u043e\u0439 \u043c\u043d\u043e\u0433\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f<\/em>, \u0437\u0430\u0442\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0434\u0440\u043e\u043f\u0430\u0443\u0442 \u0434\u043b\u044f \u0435\u0433\u043e \u0432\u044b\u0445\u043e\u0434\u0430, \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0439\u0442\u0435 \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437 <a href=\"https:\/\/arxiv.org\/abs\/1607.06450\" rel=\"noopener noreferrer nofollow\">\u0441\u043b\u043e\u0439 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438<\/a>. \u0417\u0430\u0442\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u044b \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0447\u0435\u0440\u0435\u0437 \u0441\u043b\u043e\u0439 <em>\u0441\u0435\u0442\u0438 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u043e-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0433\u043e \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u044f<\/em> \u0438 \u0441\u043d\u043e\u0432\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u0434\u0440\u043e\u043f\u0430\u0443\u0442, \u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435, \u0441\u043b\u043e\u0439 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u044b\u0432\u043e\u0434 \u044d\u0442\u043e\u0433\u043e \u0441\u043b\u043e\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0441\u043b\u043e\u0439. \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043d\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0435\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f\u043e\u0431\u0449\u0438\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u043b\u043e\u044f\u043c\u0438.<\/p>\n<p>\u0421\u043b\u043e\u0439 \u043c\u043d\u043e\u0433\u043e\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0443\u0440\u043e\u0432\u043d\u0435\u043c \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430 <\/p>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-326613","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/326613","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=326613"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/326613\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=326613"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=326613"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=326613"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}