{"id":300168,"date":"2020-03-15T21:00:18","date_gmt":"2020-03-15T21:00:18","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=300168"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=300168","title":{"rendered":"FastText: \u0440\u0435\u0446\u0435\u043f\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u043e \u043a\u043e\u0434\u0443"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/492432\/\"><i>\u0414\u043e\u0431\u0440\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0443\u0442\u043e\u043a, \u0434\u0440\u0443\u0437\u044c\u044f! \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438: <a href=\"https:\/\/medium.com\/@mariamestre\/fasttext-stepping-through-the-code-259996d6ebc4\" rel=\"nofollow\">FastText: stepping through the code<\/a> \u0430\u0432\u0442\u043e\u0440\u0430 Maria Mestre.<\/p>\n<p>  <i>\u041d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435: \u0447\u0430\u0441\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u0435\u0440\u043d\u043e\u0439 \u0432 \u0441\u0438\u043b\u0443 \u0442\u0435\u0447\u0435\u043d\u0438\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0438 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445 \u043e\u0448\u0438\u0431\u043e\u043a \u0430\u0432\u0442\u043e\u0440\u0430. \u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043b\u044e\u0431\u043e\u0439 \u0444\u0438\u0434\u0431\u0435\u043a \u0431\u0443\u0434\u0435\u0442 \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c!<\/i><\/p>\n<p>  \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0412\u0430\u043c \u0434\u043e\u0432\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0442\u044c\u0441\u044f \u0441 \u0442\u0430\u043a\u0438\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u043a\u0430\u043a FastText \u0434\u043b\u044f \u0432\u0435\u043a\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0430\u0448\u0438\u0445 \u043a\u043e\u0440\u043f\u0443\u0441\u043e\u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432, \u043d\u043e \u0437\u043d\u0430\u043b\u0438 \u043b\u0438 \u0432\u044b \u0447\u0442\u043e FastText \u0442\u0430\u043a \u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u0438 \u0438\u0445 \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439? \u0410 \u043c\u043e\u0436\u0435\u0442 \u0438 \u0437\u043d\u0430\u043b\u0438, \u043d\u043e \u0437\u043d\u0430\u043b\u0438 \u043b\u0438 \u043a\u0430\u043a \u043e\u043d \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442? \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0436\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043d\u0435\u0433\u043e \u0438\u0437\u043d\u0443\u0442\u0440\u0438\u2026 \u0432 \u0441\u043c\u044b\u0441\u043b\u0435, \u0447\u0435\u0440\u0435\u0437 \u044d\u043a\u0440\u0430\u043d.<br \/>  <\/i><br \/>  \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 FastText, \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0431\u044b\u043b\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 Facebook \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u0432, \u043d\u043e \u0442\u0430\u043a \u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0434\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u044d\u043c\u0431\u0435\u0434\u0438\u043d\u0433\u043e\u0432 \u0441\u043b\u043e\u0432. \u0421 \u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u043a\u043e\u0433\u0434\u0430 FastText \u0441\u0442\u0430\u043b \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 2016 \u043e\u043d \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0448\u0438\u0440\u043e\u043a\u043e\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0445\u043e\u0440\u043e\u0448\u0435\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u043a\u0438 \u0438 \u043e\u0442\u043b\u0438\u0447\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438.<br \/>  <a name=\"habracut\"><\/a><br \/>  \u0427\u0438\u0442\u0430\u044f \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e (\u043e\u0447\u0435\u043d\u044c \u0441\u043a\u0443\u0434\u043d\u0430\u044f \u043d\u0430 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u044f), \u044f \u043f\u043e\u043d\u044f\u043b \u0447\u0442\u043e \u0442\u0430\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u043c\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u044b\u043b\u043e \u0440\u0435\u0448\u0435\u043d\u043e \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u0432\u0441\u0435 \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u0441 \u0447\u0435\u043c \u044d\u0442\u043e \u0435\u0434\u044f\u0442. \u041d\u0430\u0447\u0430\u043b \u044f \u0441 \u0447\u0442\u0435\u043d\u0438\u044f \u0433\u043b\u0430\u0432\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u043e\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u043d\u0430 \u0421\u0442\u0435\u043d\u0444\u043e\u0440\u0434\u0441\u043a\u043e\u0433\u043e \u043a\u0443\u0440\u0441\u0430 \u043f\u043e \u0433\u043b\u0443\u0431\u043e\u043a\u043e\u043c\u0443 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044e \u0432 \u041d\u041b\u041f. \u0412 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e\u0433\u043e \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u044f, \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432 \u0443 \u043c\u0435\u043d\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u0431\u0430\u0432\u0438\u043b\u043e\u0441\u044c. \u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443: \u0447\u0442\u043e \u0432 \u043a\u0443\u0440\u0441\u0435 \u043b\u0435\u043a\u0446\u0438\u0439 \u0421\u0442\u0435\u043d\u0444\u043e\u0440\u0434\u0430 \u0438 \u0432 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0447\u0430\u0441\u0442\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u043e\u0431 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 N-\u0433\u0440\u0430\u043c\u043c, \u043d\u043e \u043d\u0435 \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439 \u043f\u043e \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e. \u0422\u0430\u043a-\u0436\u0435, \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435, \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0442 \u0432 \u0441\u0435\u0431\u044f \u043d\u0435\u043a\u0438\u0439 bucket \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0437\u0432\u0443\u0447\u0430\u0442 \u043a\u0430\u043a \u00ab\u0447\u0438\u0441\u043b\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432(\u0431\u0430\u043a\u0435\u0442\u043e\u0432)\u00bb. \u041a\u0430\u043a \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u044e\u0442\u0441\u044f \u044d\u0442\u0438 N-\u0433\u0440\u0430\u043c\u043c\u044b? \u0411\u0430\u043a\u0435\u0442\u044b? \u041d\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u2026 \u041e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434 \u043d\u0430 <a href=\"https:\/\/github.com\/facebookresearch\/fastText\" rel=\"nofollow\">github<\/a>.<\/p>\n<h4>\u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0432\u0441\u0435\u0433\u043e \u0434\u043e\u0431\u0440\u0430 \u0431\u044b\u043b\u043e \u0432\u044b\u044f\u0441\u043d\u0435\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435<\/h4>\n<p>  <\/p>\n<ul>\n<li> FastText \u0441 \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 N-\u0433\u0440\u0430\u043c\u043c\u044b \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0441 \u0442\u0435\u043c \u0436\u0435 \u0443\u0441\u043f\u0435\u0445\u043e\u043c \u043a\u0430\u043a \u0438 N-\u0433\u0440\u0430\u043c\u043c\u044b \u0441\u043b\u043e\u0432.<\/li>\n<li>FastText \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043c\u043d\u043e\u0433\u043e\u043a\u043b\u0430\u0441\u0441\u043e\u0432\u0443\u044e \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0442\u0430\u043a \u0443\u0436 \u0438 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e \u0441 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0440\u0430\u0437\u0430<\/li>\n<li>\u0427\u0438\u0441\u043b\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043c\u043e\u0434\u0435\u043b\u0438<\/li>\n<\/ul>\n<p>  <\/p>\n<h4>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 \u043c\u043e\u0434\u0435\u043b\u044c<\/h4>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/1f2\/9c1\/c4a\/1f29c1c4a8cf961b0b1a87bfeb64817f.png\" alt=\"image\"><\/p>\n<p>  \u0421\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0441\u0442\u0430\u0442\u044c\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438, \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0437 \u0441\u0435\u0431\u044f \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0443\u044e \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u0443\u044e \u0441\u0435\u0442\u044c \u0441 \u043e\u0434\u043d\u0438\u043c \u0441\u043a\u0440\u044b\u0442\u044b\u043c \u0441\u043b\u043e\u0435\u043c. \u0422\u0435\u043a\u0441\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043c\u0435\u0448\u043a\u043e\u043c \u0441\u043b\u043e\u0432 (BOW) \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u043b\u043e\u0439 \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043d \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u044d\u043c\u0431\u0435\u0434\u0438\u043d\u0433\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430. \u0412 \u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u044d\u043c\u0431\u0435\u0434\u0438\u043d\u0433\u0438 \u043e\u0441\u0440\u0435\u0434\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u0442\u0435\u043a\u0441\u0442\u0443 \u0438 \u0441\u0432\u043e\u0434\u044f\u0442\u0441\u044f \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c\u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u0442\u0435\u043a\u0441\u0442\u0443. \u0412 \u0441\u043a\u0440\u044b\u0442\u043e\u043c \u0441\u043b\u043e\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 <i>n_words * dim<\/i> \u0447\u0438\u0441\u043b\u043e\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0433\u0434\u0435 <i>dim<\/i> \u044d\u0442\u043e \u0440\u0430\u0437\u043c\u0435\u0440 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430, \u0430 <i>n_words<\/i> \u0440\u0430\u0437\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430\u0440\u044f \u0434\u043b\u044f \u0442\u0435\u043a\u0441\u0442\u0430. \u041f\u043e\u0441\u043b\u0435 \u043e\u0441\u0440\u0435\u0434\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0434\u0438\u043d \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440: \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f softmax \u0434\u043b\u044f \u043b\u0438\u043d\u043e\u0433\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f(\u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f) \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u044f \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0435\u0442 \u043c\u0430\u0442\u0440\u0438\u0446\u0430 \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c\u044e <i>dim * n_output<\/i>, \u0433\u0434\u0435 <i>n_output<\/i> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u0448\u0438\u043c \u0447\u0438\u0441\u043b\u043e\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432. \u0412 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043a\u043e\u043d\u0435\u0447\u043d\u0430\u044f \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f <i>log-likelyhood<\/i>:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/bda\/562\/e9f\/bda562e9f48277570c5ee94c33cbf6c8.png\" alt=\"image\"><\/p>\n<p>  \u0433\u0434\u0435:<\/p>\n<ul>\n<li>x_n \u044d\u0442\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043b\u043e\u0432\u0430 \u0432 n-\u0433\u0440\u0430\u043c\u043c\u0435. <\/li>\n<li>\u0410 \u044d\u0442\u043e look_up \u043c\u0430\u0442\u0440\u0438\u0446\u0430 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u044e\u0449\u0430\u044f \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433 \u0441\u043b\u043e\u0432\u0430.<\/li>\n<li>\u0412 \u044d\u0442\u043e \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/li>\n<li>f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441\u0430\u043c\u0430 \u0444\u0443\u043d\u0446\u0438\u044f softmax.<\/li>\n<\/ul>\n<p>  \u0412\u0441\u0435 \u0432 \u0446\u0435\u043b\u043e\u043c \u043d\u0435 \u0442\u0430\u043a \u043f\u043b\u043e\u0445\u043e, \u043d\u043e \u0432\u0441\u0435 \u0436\u0435 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u0437\u0433\u043b\u044f\u043d\u0435\u043c \u043d\u0430 \u043a\u043e\u0434:<\/p>\n<h4>\u041a\u043e\u0434 \u043a\u0430\u043a \u0442\u0440\u0430\u043d\u0441\u043b\u044f\u0446\u0438\u044f \u0438\u0434\u0435\u0438<\/h4>\n<p>  \u0424\u0430\u0439\u043b \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0444\u043e\u0440\u043c\u0435: __label__0 (\u0442\u0435\u043a\u0441\u0442).<\/p>\n<p>  \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432:<br \/>  __label__cat This thext is about cats.<br \/>  __label__dog This text is about dogs. <\/p>\n<p>  \u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 train. \u0424\u0443\u043d\u043a\u0446\u0438\u044f train \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442 \u0441 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u043f\u043e\u0441\u043b\u0435\u044e\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <i>dict_<\/i>.<\/p>\n<pre><code class=\"cpp\">void FastText::train(const Args args) {   args_ = std::make_shared&lt;Args&gt;(args);   dict_ = std::make_shared&lt;Dictionary&gt;(args_);   if (args_-&gt;input == &quot;-&quot;) {     \/\/ manage expectations     throw std::invalid_argument(&quot;Cannot use stdin for training!&quot;);   }   std::ifstream ifs(args_-&gt;input);   if (!ifs.is_open()) {     throw std::invalid_argument(         args_-&gt;input + &quot; cannot be opened for training!&quot;);   }   dict_-&gt;readFromFile(ifs);<\/code><\/pre>\n<p>  dict_ \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0430 Dictionary.<\/p>\n<pre><code class=\"cpp\"> Dictionary::Dictionary(std::shared_ptr&lt;Args&gt; args) : args_(args),   word2int_(MAX_VOCAB_SIZE, -1), size_(0), nwords_(0), nlabels_(0),   ntokens_(0), pruneidx_size_(-1) {}<\/code><\/pre>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430, \u043c\u044b \u043d\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0434\u0432\u0430 \u0432\u0435\u043a\u0442\u043e\u0440\u0430:<\/p>\n<ul>\n<li> words_ \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u043d\u044b\u0435 \u0438\u0437 \u0442\u0435\u043a\u0441\u0442\u0430<\/li>\n<li>word2int_ \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0445\u044d\u0448\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u0435\u0433\u043e \u043f\u043e\u0437\u0438\u0446\u0438\u0435\u0439 \u0432 \u0432\u0435\u043a\u0442\u043e\u0440\u0435 <i>words_<\/i>. \u042d\u0442\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u043e\u0432 \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u0410<\/li>\n<\/ul>\n<p>  \u0412\u0435\u043a\u0442\u043e\u0440 <i>words_<\/i> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b entry. \u041a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u0438\u043f\u043e\u043c word \u0434\u043b\u044f <i>label<\/i> \u0438 \u0438\u043c\u0435\u0442\u044c \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0439 \u043a \u043d\u0438\u043c. \u0422\u0430\u043a \u0436\u0435 \u0442\u0443\u0442 \u0435\u0449\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u043e\u043b\u0435 <i>subwords<\/i>, \u043d\u043e \u0435\u0433\u043e \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0447\u0443\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<pre><code class=\"cpp\">struct entry {   std::string word;   int64_t count;   entry_type type;   std::vector&lt;int32_t&gt; subwords; };<\/code><\/pre>\n<p>  \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u044f \u0441\u043b\u043e\u0432\u0430 \u0438\u043b\u0438 \u043c\u0435\u0442\u043a\u0438 \u0432 <i>word2int_<\/i> \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e, \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0438 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u044e\u0442\u0441\u044f \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e \u043c\u044b \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043e\u0431\u0440\u0430\u0442\u0438\u043c\u0441\u044f \u043a \u0434\u0432\u0443\u043c \u0440\u0430\u0437\u043d\u044b\u043c \u0441\u043b\u043e\u0432\u0430\u043c \u0438\u043c\u0435\u044e\u0449\u0438\u043c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441. \u0422\u0430\u043a\u0438\u0445 \u043f\u043e\u043f\u0440\u043e\u0441\u0442\u0443 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442. <\/p>\n<pre><code class=\"cpp\">int32_t Dictionary::find(const std::string&amp; w, uint32_t h) const {   int32_t word2intsize = word2int_.size();   int32_t id = h % word2intsize;   while (word2int_[id] != -1 &amp;&amp; words_[word2int_[id]].word != w) {     id = (id + 1) % word2intsize;   }   return id; }  int32_t Dictionary::find(const std::string&amp; w) const {   return find(w, hash(w)); }  void Dictionary::add(const std::string&amp; w) {   int32_t h = find(w);   ntokens_++;   if (word2int_[h] == -1) {     entry e;     e.word = w;     e.count = 1;     e.type = getType(w);     words_.push_back(e);     word2int_[h] = size_++;   } else {     words_[word2int_[h]].count++;   } }<\/code><\/pre>\n<p>  \u041e\u0431\u0430 \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u0444\u0438\u043b\u044c\u0442\u0440\u0443\u044e\u0442\u0441\u044f, \u0434\u0430\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0442\u043e\u043c \u0447\u0442\u043e \u0441\u043b\u043e\u0432\u0430 \u0438 \u043c\u0435\u0442\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u044e\u0442\u0441\u044f \u0445\u043e\u0442\u044f \u0431\u044b \u0440\u0430\u0437, \u0431\u044b\u043b\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u044b. \u041f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0447\u0430\u0441\u0442\u0438 \u0433\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <i>readFromFile<\/i> \u0433\u0434\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <i>initNgrams<\/i>. \u041c\u044b \u043f\u043e\u0447\u0442\u0438 \u043f\u043e\u0434\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c \u043a \u043c\u0438\u0441\u0442\u0438\u043a\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f N-\u0433\u0440\u0430\u043c\u043c. <\/p>\n<pre><code class=\"cpp\"> void Dictionary::readFromFile(std::istream&amp; in) {   std::string word;   int64_t minThreshold = 1;   while (readWord(in, word)) {     add(word);     if (ntokens_ % 1000000 == 0 &amp;&amp; args_-&gt;verbose &gt; 1) {       std::cerr &lt;&lt; &quot;\\rRead &quot; &lt;&lt; ntokens_  \/ 1000000 &lt;&lt; &quot;M words&quot; &lt;&lt; std::flush;     }     if (size_ &gt; 0.75 * MAX_VOCAB_SIZE) {       minThreshold++;       threshold(minThreshold, minThreshold);     }   }   threshold(args_-&gt;minCount, args_-&gt;minCountLabel);   initTableDiscard();   initNgrams();<\/code><\/pre>\n<p>  \u0424\u0443\u043d\u043a\u0446\u0438\u044f <i>initNgrams<\/i> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0432\u0441\u0435 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438 N-\u0433\u0440\u0430\u043c\u043c \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0445 \u0432 \u0432\u0435\u043a\u0442\u043e\u0440 <i>ngram<\/i>. \u0412 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432, \u043e\u0431\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u0445\u0435\u0448\u0438 \u0434\u043b\u044f N-\u0433\u0440\u0430\u043c\u043c \u0438 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0432\u0435\u043a\u0442\u043e\u0440\u0435 <i>ngram<\/i>, \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044f \u0440\u0430\u0437\u043c\u0435\u0440 <i>bucket<\/i>. \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u0445\u044d\u0448\u0438 N-\u0433\u0440\u0430\u043c\u043c \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0445\u044d\u0448\u0435\u0439 N-\u0433\u0440\u0430\u043c\u043c \u0441\u043b\u043e\u0432. \u041a\u0430\u043a \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435 \u0438\u0445 \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u043d\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u044e\u0442\u0441\u044f \u0441 \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u043c\u0438 \u0441\u043b\u043e\u0432, \u043d\u043e \u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0442\u044c\u0441\u044f \u0434\u0440\u0443\u0433 \u0441 \u0434\u0440\u0443\u0433\u043e\u043c. <\/p>\n<p>  \u0412 \u0446\u0435\u043b\u043e\u043c, \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 \u0432 \u0442\u0435\u043a\u0441\u0442\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c <i>subwords<\/i>\u2026 N-\u0433\u0440\u0430\u043c\u043c\u044b \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432.<br \/>  \u041c\u0430\u0442\u0440\u0438\u0446\u0430 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u043e\u0432 \u0410 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ul>\n<li>\u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 nwords_ \u0441\u0442\u0440\u043e\u043a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 \u0438\u0437 \u0438\u043c\u0435\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u0434\u043b\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u0441\u043b\u043e\u0432\u0430\u0440\u044f.<\/li>\n<li>\u041f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0442\u0435 bucket \u0441\u0442\u0440\u043e\u043a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435 \u0432 \u0441\u0435\u0431\u0435 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 N-\u0433\u0440\u0430\u043c\u043c\u044b \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"cpp\"> void Dictionary::initNgrams() {   for (size_t i = 0; i &lt; size_; i++) {     std::string word = BOW + words_[i].word + EOW;     words_[i].subwords.clear();     words_[i].subwords.push_back(i);     if (words_[i].word != EOS) {       computeSubwords(word, words_[i].subwords);     }   } }  void Dictionary::computeSubwords(const std::string&amp; word,                                std::vector&lt;int32_t&gt;&amp; ngrams) const {   for (size_t i = 0; i &lt; word.size(); i++) {     std::string ngram;     if ((word[i] &amp; 0xC0) == 0x80) continue;     for (size_t j = i, n = 1; j &lt; word.size() &amp;&amp; n &lt;= args_-&gt;maxn; n++) {       ngram.push_back(word[j++]);       while (j &lt; word.size() &amp;&amp; (word[j] &amp; 0xC0) == 0x80) {         ngram.push_back(word[j++]);       }       if (n &gt;= args_-&gt;minn &amp;&amp; !(n == 1 &amp;&amp; (i == 0 || j == word.size()))) {         int32_t h = hash(ngram) % args_-&gt;bucket;         pushHash(ngrams, h);       }     }   } }  void Dictionary::pushHash(std::vector&lt;int32_t&gt;&amp; hashes, int32_t id) const {   if (pruneidx_size_ == 0 || id &lt; 0) return;   if (pruneidx_size_ &gt; 0) {     if (pruneidx_.count(id)) {       id = pruneidx_.at(id);     } else {       return;     }   }   hashes.push_back(nwords_ + id); }<\/code><\/pre>\n<p>  \u0422.\u043e \u043c\u044b \u0440\u0430\u0437\u0433\u0430\u0434\u0430\u043b\u0438 \u043c\u0438\u0441\u0442\u0438\u0447\u043d\u044b\u0435 N-\u0433\u0440\u0430\u043c\u043c \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0436\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f \u0442\u0435\u043f\u0435\u0440\u044c \u0441 N-\u0433\u0440\u0430\u043c\u043c\u0430\u043c\u0438 \u0441\u043b\u043e\u0432.<\/p>\n<p>  \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044f\u0441\u044c \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <i>train<\/i>, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"cpp\">  if (args_-&gt;pretrainedVectors.size() != 0) {     loadVectors(args_-&gt;pretrainedVectors);   } else {     input_ = std::make_shared&lt;Matrix&gt;(dict_-&gt;nwords()+args_-&gt;bucket, args_-&gt;dim);     input_-&gt;uniform(1.0 \/ args_-&gt;dim);   }    if (args_-&gt;model == model_name::sup) {     output_ = std::make_shared&lt;Matrix&gt;(dict_-&gt;nlabels(), args_-&gt;dim);   } else {     output_ = std::make_shared&lt;Matrix&gt;(dict_-&gt;nwords(), args_-&gt;dim);   }   output_-&gt;zero();   startThreads();<\/code><\/pre>\n<p>  \u042d\u0442\u043e \u0442\u043e \u043c\u0435\u0441\u0442\u043e \u0433\u0434\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043c\u0430\u0442\u0440\u0438\u0446\u0430 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u043e\u0432 \u0410. \u041d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 pretrainedVectors \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439, \u0442\u043e \u0434\u0430\u043d\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043e\u0439. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 \u0442\u0430\u043a\u043e\u0432\u043e\u0433\u043e \u043d\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0442\u043e \u043c\u0430\u0442\u0440\u0438\u0446\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u043c \u0447\u0438\u0441\u043b\u0430\u043c\u0438 <i>-1\/dim <\/i> \u0438 <i>1\/dim<\/i>, \u0433\u0434\u0435 <i>dim<\/i> \u2014 \u0440\u0430\u0437\u043c\u0435\u0440 \u043d\u0430\u0448\u0435\u0433\u043e \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430. \u0420\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u0410 (<i>n_words_<\/i> + <i>bucket<\/i>; <i>dim<\/i>), \u0442.\u043e. \u043c\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u044d\u0442\u0438 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430. \u0412\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u0430\u043a \u0436\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043d\u0430 \u044d\u0442\u043e\u043c \u0448\u0430\u0433\u0435.<\/p>\n<p>  \u041a\u0430\u043a \u0438\u0442\u043e\u0433 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0447\u0430\u0441\u0442\u044c \u0433\u0434\u0435 \u043c\u044b \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u043a\u0443 \u043d\u0430\u0448\u0435\u0439 \u043c\u043e\u0434\u0435\u043b\u0438. <\/p>\n<pre><code class=\"cpp\"> void FastText::trainThread(int32_t threadId) {   std::ifstream ifs(args_-&gt;input);   utils::seek(ifs, threadId * utils::size(ifs) \/ args_-&gt;thread);    Model model(input_, output_, args_, threadId);   if (args_-&gt;model == model_name::sup) {     model.setTargetCounts(dict_-&gt;getCounts(entry_type::label));   } else {     model.setTargetCounts(dict_-&gt;getCounts(entry_type::word));   }    const int64_t ntokens = dict_-&gt;ntokens();   int64_t localTokenCount = 0;   std::vector&lt;int32_t&gt; line, labels;   while (tokenCount_ &lt; args_-&gt;epoch * ntokens) {     real progress = real(tokenCount_) \/ (args_-&gt;epoch * ntokens);     real lr = args_-&gt;lr * (1.0 - progress);     if (args_-&gt;model == model_name::sup) {       localTokenCount += dict_-&gt;getLine(ifs, line, labels);       supervised(model, lr, line, labels);     } else if (args_-&gt;model == model_name::cbow) {       localTokenCount += dict_-&gt;getLine(ifs, line, model.rng);       cbow(model, lr, line);     } else if (args_-&gt;model == model_name::sg) {       localTokenCount += dict_-&gt;getLine(ifs, line, model.rng);       skipgram(model, lr, line);     }     if (localTokenCount &gt; args_-&gt;lrUpdateRate) {       tokenCount_ += localTokenCount;       localTokenCount = 0;       if (threadId == 0 &amp;&amp; args_-&gt;verbose &gt; 1)         loss_ = model.getLoss();     }   }   if (threadId == 0)     loss_ = model.getLoss();   ifs.close(); }<\/code><\/pre>\n<p>  \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0434\u0432\u0430 \u0433\u043b\u0430\u0432\u043d\u044b\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u0430. \u041f\u0435\u0440\u0432\u044b\u0439, \u0444\u0443\u043d\u043a\u0446\u0438\u044f <i>getLine<\/i> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <i>dict_<\/i>. \u0412\u0442\u043e\u0440\u043e\u0439, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <i>supervised<\/i>.<\/p>\n<pre><code class=\"cpp\">int32_t Dictionary::getLine(std::istream&amp; in,                             std::vector&lt;int32_t&gt;&amp; words,                             std::vector&lt;int32_t&gt;&amp; labels) const {   std::vector&lt;int32_t&gt; word_hashes;   std::string token;   int32_t ntokens = 0;    reset(in);   words.clear();   labels.clear();   while (readWord(in, token)) {     uint32_t h = hash(token);     int32_t wid = getId(token, h);     entry_type type = wid &lt; 0 ? getType(token) : getType(wid);      ntokens++;     if (type == entry_type::word) {       addSubwords(words, token, wid);       word_hashes.push_back(h);     } else if (type == entry_type::label &amp;&amp; wid &gt;= 0) {       labels.push_back(wid - nwords_);     }&lt;source lang=&quot;cpp&quot;&gt;     if (token == EOS) break;   }   addWordNgrams(words, word_hashes, args_-&gt;wordNgrams);   return ntokens; }<\/code><\/pre>\n<p>  \u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u044b\u0448\u0435, \u043c\u044b \u0447\u0438\u0442\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442\u044b \u0438\u0437 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 \u0434\u0440\u0443\u0433 \u0437\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f <i>word2int_<\/i>. \u041c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0435 \u044d\u0442\u0438 \u0441\u043b\u043e\u0432\u0430 N-\u0433\u0440\u0430\u043c\u043c\u044b \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <i>words<\/i>, \u043a\u0430\u043a \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u043a\u043e\u0434\u0435. \u0418 \u0432 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043c\u0435\u0442\u043a\u0438 \u043f\u0440\u044f\u043c\u0438\u043a\u043e\u043c \u0432 \u0432\u0435\u043a\u0442\u043e\u0440 <i>labels<\/i>. <\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430(\u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f) \u043f\u0440\u044f\u043c\u0438\u043a\u043e\u043c \u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043d\u0438\u0445 \u0432\u0435\u043a\u0442\u043e\u0440\u0430, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430 \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 N-\u0433\u0440\u0430\u043c\u043c\u044b. \u042d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f <i>addWordNgrams<\/i>.<\/p>\n<pre><code class=\"cpp\">void Dictionary::addWordNgrams(std::vector&lt;int32_t&gt;&amp; line,                                const std::vector&lt;int32_t&gt;&amp; hashes,                                int32_t n) const {   for (int32_t i = 0; i &lt; hashes.size(); i++) {     uint64_t h = hashes[i];     for (int32_t j = i + 1; j &lt; hashes.size() &amp;&amp; j &lt; i + n; j++) {       h = h * 116049371 + hashes[j];       pushHash(line, h % args_-&gt;bucket);     }   } }<\/code><\/pre>\n<p>  \u0421\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0430\u043b\u044c\u0448\u0435. \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f <i>hashes<\/i> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043d\u0430\u0431\u043e\u0440 \u0445\u044d\u0448\u0435\u0439 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 \u0442\u0435\u043a\u0441\u0442\u0430, \u0433\u0434\u0435 <i>line<\/i> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u043e\u043c\u0435\u0440\u0430 \u0441\u043b\u043e\u0432 \u0432 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0438 \u0447\u0438\u0441\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 N-\u0433\u0440\u0430\u043c\u043c. \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <i>n<\/i> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c <i>wordNgrams<\/i> \u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u0441\u043b\u0438\u043d\u0443 N-\u0433\u0440\u0430\u043c\u043c\u044b \u0441\u043b\u043e\u0432. \u041a\u0430\u0436\u0434\u0430\u044f N-\u0433\u0440\u0430\u043c\u043c\u0430 \u0441\u043b\u043e\u0432 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0441\u0432\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0445\u044d\u0448 \u0432\u044b\u0441\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0435 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e\u0439 \u0444\u043e\u0440\u043c\u0443\u043b\u043e\u0439 <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/c70\/1cd\/976\/c701cd976a56e939de663e60e50886f3.svg\" alt=\"$h = h*116049371+hashes[j]$\" data-tex=\"display\"><\/math><\/p>\n<p>. \u0414\u0430\u043d\u043d\u0430\u044f \u0444\u043e\u0440\u043c\u0443\u043b\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044f\u043b\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function\" rel=\"nofollow\">FNV \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c<\/a> \u0445\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0433\u043e \u043a \u0441\u0442\u0440\u043e\u043a\u0435: \u043e\u043d \u0431\u0435\u0440\u0435\u0442 \u0445\u044d\u0448 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 \u0432 N-\u0433\u0440\u0430\u043c\u043c\u0435 \u0441\u043b\u043e\u0432 \u0438 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u0438\u0445. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0431\u043e\u0440 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0445\u044d\u0448\u0435\u0439. \u0412 \u0438\u0442\u043e\u0433\u0435, \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043c) \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u043f\u043e \u043c\u043e\u0434\u0443\u043b\u044e.<\/p>\n<p>  \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, N-\u0433\u0440\u0430\u043c\u043c\u044b \u0441\u043b\u043e\u0432 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u0430\u043a \u0436\u0435 \u043a\u0430\u043a \u0438 N-\u0433\u0440\u0430\u043c\u043c\u044b \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u043d\u043e \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043e\u0442\u043b\u0438\u0447\u0438\u0435\u043c, \u0442.\u043a \u043c\u044b \u043d\u0435 \u0445\u0435\u0448\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0435 \u0441\u043b\u043e\u0432\u043e. \u0423\u0434\u0438\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0445\u043e\u0434.<\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <i>supervised<\/i>. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\u043c\u0435\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0442\u043e\u043a, \u043c\u044b \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043e\u0434\u043d\u0443 \u0438\u0437 \u043d\u0438\u0445.<\/p>\n<pre><code class=\"cpp\"> void FastText::supervised(     Model&amp; model,     real lr,     const std::vector&lt;int32_t&gt;&amp; line,     const std::vector&lt;int32_t&gt;&amp; labels) {   if (labels.size() == 0 || line.size() == 0) return;   std::uniform_int_distribution&lt;&gt; uniform(0, labels.size() - 1);   int32_t i = uniform(model.rng);   model.update(line, labels[i], lr); }<\/code><\/pre>\n<p>  \u0418 \u043d\u0430 \u043a\u043e\u043d\u0435\u0446, \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438.<\/p>\n<pre><code class=\"cpp\">void Model::computeHidden(const std::vector&lt;int32_t&gt;&amp; input, Vector&amp; hidden) const {   assert(hidden.size() == hsz_);   hidden.zero();   for (auto it = input.cbegin(); it != input.cend(); ++it) {     if(quant_) {       hidden.addRow(*qwi_, *it);     } else {       hidden.addRow(*wi_, *it);     }   }   hidden.mul(1.0 \/ input.size()); }  void Model::update(const std::vector&lt;int32_t&gt;&amp; input, int32_t target, real lr) {   assert(target &gt;= 0);   assert(target &lt; osz_);   if (input.size() == 0) return;   computeHidden(input, hidden_);   if (args_-&gt;loss == loss_name::ns) {     loss_ += negativeSampling(target, lr);   } else if (args_-&gt;loss == loss_name::hs) {     loss_ += hierarchicalSoftmax(target, lr);   } else {     loss_ += softmax(target, lr);   }   nexamples_ += 1;    if (args_-&gt;model == model_name::sup) {     grad_.mul(1.0 \/ input.size());   }   for (auto it = input.cbegin(); it != input.cend(); ++it) {     wi_-&gt;addRow(grad_, *it, 1.0);   } }<\/code><\/pre>\n<p>  \u0412\u0445\u043e\u0434\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <i>supervised<\/i> \u0438\u043c\u0435\u044e\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432 \u0432\u0441\u0435\u0445 \u0441\u0432\u043e\u0438\u0445 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0445 (\u0441\u043b\u043e\u0432, N-\u0433\u0440\u0430\u043c\u043c \u0441\u043b\u043e\u0432 \u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432) \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0426\u0435\u043b\u044c\u044e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <i>computeHidden<\/i> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0432\u0441\u0435 \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043f\u043e\u0438\u0441\u043a\u0430 \u0438\u0445 \u0432 \u043c\u0430\u0442\u0440\u0438\u0446\u0435 <i>wi_<\/i> \u0438 \u043e\u0441\u0440\u0435\u0434\u043d\u0435\u043d\u0438\u044f (\u0441\u0443\u043c\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f <i>addRow<\/i> \u0438 \u0434\u0435\u043b\u0438\u0442\u0441\u044f \u043d\u0430 \u0438\u0445 \u0440\u0430\u0437\u043c\u0435\u0440). \u041f\u043e\u0441\u043b\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u0435\u043a\u0442\u043e\u0440\u0430 <i>hidden_<\/i> \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0445 \u043d\u0430 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044e \u0432 softmax \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043c\u0435\u0442\u043a\u0443.<\/p>\n<p>  \u042d\u0442\u043e\u0442 \u0443\u0447\u0430\u0441\u0442\u043e\u043a \u043a\u043e\u0434\u0430 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 <i>softmax<\/i>. \u0422\u0430\u043a \u0436\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f<i> log-loss<\/i>.<\/p>\n<pre><code class=\"cpp\">void Model::computeOutputSoftmax(Vector&amp; hidden, Vector&amp; output) const {   if (quant_ &amp;&amp; args_-&gt;qout) {     output.mul(*qwo_, hidden);   } else {     output.mul(*wo_, hidden);   }   real max = output[0], z = 0.0;   for (int32_t i = 0; i &lt; osz_; i++) {     max = std::max(output[i], max);   }   for (int32_t i = 0; i &lt; osz_; i++) {     output[i] = exp(output[i] - max);     z += output[i];   }   for (int32_t i = 0; i &lt; osz_; i++) {     output[i] \/= z;   } }  void Model::computeOutputSoftmax() {   computeOutputSoftmax(hidden_, output_); }  real Model::softmax(int32_t target, real lr) {   grad_.zero();   computeOutputSoftmax();   for (int32_t i = 0; i &lt; osz_; i++) {     real label = (i == target) ? 1.0 : 0.0;     real alpha = lr * (label - output_[i]);     grad_.addRow(*wo_, i, alpha);     wo_-&gt;addRow(hidden_, i, alpha);   }   return -log(output_[target]); }<\/code><\/pre>\n<p>  \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043c\u044b \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u043e\u0441\u0442\u0430 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 N-\u0433\u0440\u0430\u043c\u043c \u0441\u043b\u043e\u0432 \u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432. \u0420\u043e\u0441\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438\u043c\u0435\u044e\u0449\u0438\u043c\u0441\u044f \u0447\u0438\u0441\u043b\u043e\u043c <i>buckets<\/i>. <\/p>\n<p>  \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e FastText \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 N-\u0433\u0440\u0430\u043c\u043c\u044b, \u043d\u043e \u043d\u0430\u043c \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b:<\/p>\n<ul>\n<li>bucker = 2000000; wordNgrams &gt; 1 \u0438\u043b\u0438 maxn &gt; 0 <\/li>\n<li>dim=100<\/li>\n<li>n_output=2<\/li>\n<li>n_words=500000<\/li>\n<\/ul>\n<p>  \u0412 \u0441\u0443\u043c\u043c\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0434\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/611\/def\/963\/611def963eded751b5446962116f18f3.svg\" alt=\"$(5000000+2000000)*100+(2*100) = 250,000,000$\" data-tex=\"display\"><\/math><\/p>\n<p>. \u041c\u043d\u043e\u0433\u043e\u0432\u0430\u0442\u043e, \u043d\u0435 \u0442\u0430\u043a \u043b\u0438?) \u041a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0434\u0430\u0436\u0435 \u0447\u0435\u0440\u0435\u0437 \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0447\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0434\u0430\u0436\u0435 \u0442\u0438\u043f\u0438\u0447\u043d\u043e \u0434\u043b\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0433\u043b\u0443\u0431\u043e\u043a\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u0433\u0440\u0443\u0431\u0430\u044f \u043e\u0446\u0435\u043d\u043a\u0430, \u043a\u0430\u043a \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0438\u0441\u043b\u043e N-\u0433\u0440\u0430\u043c\u043c \u0432\u0437\u044f\u0442\u043e\u0435 \u0437\u0430 2_000_000, \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e \u0431\u044b \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u0440\u044f\u0434\u043e\u043a. \u0412 \u0446\u0435\u043b\u043e\u043c, \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u0437\u0438\u0442\u044c \u043f\u0443\u0442\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0433\u0438\u043f\u0435\u0440\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a <i>bucket<\/i> \u0438\u043b\u0438 \u0436\u0435 \u043f\u043e\u0440\u043e\u0433 \u0432\u0437\u044f\u0442\u0438\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0438.<\/p>\n<p>  \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0441\u044b\u043b\u043a\u0438 \u043c\u043e\u0433\u0443\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c\u0438:<br \/>  <a href=\"https:\/\/research.fb.com\/fasttext\/\" rel=\"nofollow\">research.fb.com\/fasttext<\/a><br \/>  <a href=\"https:\/\/arxiv.org\/pdf\/1607.01759.pdf\" rel=\"nofollow\">arxiv.org\/pdf\/1607.01759.pdf<\/a> and <a href=\"https:\/\/arxiv.org\/pdf\/1607.04606v1.pdf\" rel=\"nofollow\">arxiv.org\/pdf\/1607.04606v1.pdf<\/a><br \/>  <a href=\"https:\/\/www.youtube.com\/watch?v=isPiE-DBagM&amp;index=5&amp;list=PLU40WL8Ol94IJzQtileLTqGZuXtGlLMP_\" rel=\"nofollow\">www.youtube.com\/watch?v=isPiE-DBagM&amp;index=5&amp;list=PLU40WL8Ol94IJzQtileLTqGZuXtGlLMP_<\/a> (from 47:39)<\/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\/492432\/\"> https:\/\/habr.com\/ru\/post\/492432\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/492432\/\"><i>\u0414\u043e\u0431\u0440\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0443\u0442\u043e\u043a, \u0434\u0440\u0443\u0437\u044c\u044f! \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438: <a href=\"https:\/\/medium.com\/@mariamestre\/fasttext-stepping-through-the-code-259996d6ebc4\" rel=\"nofollow\">FastText: stepping through the code<\/a> \u0430\u0432\u0442\u043e\u0440\u0430 Maria Mestre.<\/p>\n<p>  <i>\u041d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435: \u0447\u0430\u0441\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u0435\u0440\u043d\u043e\u0439 \u0432 \u0441\u0438\u043b\u0443 \u0442\u0435\u0447\u0435\u043d\u0438\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0438 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445 \u043e\u0448\u0438\u0431\u043e\u043a \u0430\u0432\u0442\u043e\u0440\u0430. \u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043b\u044e\u0431\u043e\u0439 \u0444\u0438\u0434\u0431\u0435\u043a \u0431\u0443\u0434\u0435\u0442 \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c!<\/i><\/p>\n<p>  \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0412\u0430\u043c \u0434\u043e\u0432\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0442\u044c\u0441\u044f \u0441 \u0442\u0430\u043a\u0438\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u043a\u0430\u043a FastText \u0434\u043b\u044f \u0432\u0435\u043a\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0430\u0448\u0438\u0445 \u043a\u043e\u0440\u043f\u0443\u0441\u043e\u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432, \u043d\u043e \u0437\u043d\u0430\u043b\u0438 \u043b\u0438 \u0432\u044b \u0447\u0442\u043e FastText \u0442\u0430\u043a \u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u0438 \u0438\u0445 \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439? \u0410 \u043c\u043e\u0436\u0435\u0442 \u0438 \u0437\u043d\u0430\u043b\u0438, \u043d\u043e \u0437\u043d\u0430\u043b\u0438 \u043b\u0438 \u043a\u0430\u043a \u043e\u043d \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442? \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0436\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043d\u0435\u0433\u043e \u0438\u0437\u043d\u0443\u0442\u0440\u0438\u2026 \u0432 \u0441\u043c\u044b\u0441\u043b\u0435, \u0447\u0435\u0440\u0435\u0437 \u044d\u043a\u0440\u0430\u043d.<br \/>  <\/i><br \/>  \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 FastText, \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0431\u044b\u043b\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 Facebook \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u0432, \u043d\u043e \u0442\u0430\u043a \u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0434\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u044d\u043c\u0431\u0435\u0434\u0438\u043d\u0433\u043e\u0432 \u0441\u043b\u043e\u0432. \u0421 \u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u043a\u043e\u0433\u0434\u0430 FastText \u0441\u0442\u0430\u043b \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 2016 \u043e\u043d \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0448\u0438\u0440\u043e\u043a\u043e\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0445\u043e\u0440\u043e\u0448\u0435\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u043a\u0438 \u0438 \u043e\u0442\u043b\u0438\u0447\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438.  <\/p>\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-300168","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/300168","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=300168"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/300168\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=300168"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=300168"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=300168"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}