{"id":326255,"date":"2021-07-10T15:00:28","date_gmt":"2021-07-10T15:00:28","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=326255"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=326255","title":{"rendered":"BERT \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0440\u0443\u0441\u0441\u043a\u043e\u044f\u0437\u044b\u0447\u043d\u044b\u0445 \u0442\u0435\u043a\u0441\u0442\u043e\u0432"},"content":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<h2>\u0417\u0430\u0447\u0435\u043c<\/h2>\n<p>\u0412 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435 \u043f\u043e\u043b\u043d\u043e \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u044b\u0445 \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u0440\u043e BERT. \u041d\u043e \u0447\u0430\u0441\u0442\u043e \u043e\u043d\u0438 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u044b \u0434\u043b\u044f \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u043e\u0447\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u043e\u0431\u0443\u0447\u0438\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u043b\u044f \u0441\u0432\u043e\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438. \u0414\u0430\u043d\u043d\u044b\u0439 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0444\u0430\u0439\u043d\u0442\u044e\u043d\u0438\u0442\u044c \u0440\u0443\u0441\u0441\u043a\u043e\u044f\u0437\u044b\u0447\u043d\u044b\u0439 BERT \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447\u0438 \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438. \u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043d\u0430 <a href=\"https:\/\/github.com\/shitkov\/bert4classification\" rel=\"noopener noreferrer nofollow\">github<\/a>, \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u0432 <strong>google colab<\/strong> \u043e\u0434\u043d\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u043e\u0439.<\/p>\n<h2>Workflow<\/h2>\n<ol>\n<li>\n<p>\u0414\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c<\/p>\n<\/li>\n<li>\n<p>Helpers<\/p>\n<\/li>\n<li>\n<p>Train<\/p>\n<\/li>\n<li>\n<p>Inference<\/p>\n<\/li>\n<\/ol>\n<h2>\u0414\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f<\/h2>\n<p>\u0414\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u043e\u0447\u0438\u0449\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0440\u0443\u0441\u0441\u043a\u043e\u044f\u0437\u044b\u0447\u043d\u043e\u0433\u043e \u0442\u0432\u0438\u0442\u0442\u0435\u0440\u0430 \u0438\u0437 \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0430 <a href=\"https:\/\/study.mokoron.com\/\" rel=\"noopener noreferrer nofollow\">RuTweetCorp<\/a>. \u0414\u0430\u043d\u043d\u044b\u0435 \u0440\u0430\u0437\u043c\u0435\u0447\u0435\u043d\u044b \u043d\u0430 2 \u043a\u043b\u0430\u0441\u0441\u0430:<\/p>\n<ul>\n<li>\n<p>&#8216;0&#8217; &#8212; \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u044b\u0435<\/p>\n<\/li>\n<li>\n<p>&#8216;1&#8217; &#8212; \u043f\u043e\u0437\u0438\u0442\u0438\u0432\u043d\u044b\u0435<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 Dataset:<\/p>\n<pre><code class=\"python\">from torch.utils.data import Dataset  class CustomDataset(Dataset):    def __init__(self, texts, targets, tokenizer, max_len=512):     self.texts = texts     self.targets = targets     self.tokenizer = tokenizer     self.max_len = max_len    def __len__(self):     return len(self.texts)    def __getitem__(self, idx):     text = str(self.texts[idx])     target = self.targets[idx]      encoding = self.tokenizer.encode_plus(         text,         add_special_tokens=True,         max_length=self.max_len,         return_token_type_ids=False,         padding='max_length',         return_attention_mask=True,         return_tensors='pt',     )      return {       'text': text,       'input_ids': encoding['input_ids'].flatten(),       'attention_mask': encoding['attention_mask'].flatten(),       'targets': torch.tensor(target, dtype=torch.long)     } <\/code><\/pre>\n<p>\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438 <code>__init__<\/code>, <code>__len__<\/code>, <code>__getitem__<\/code>. \u0412 \u043c\u0435\u0442\u043e\u0434\u0435 <code>__init__<\/code><strong> <\/strong>\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0442\u0435\u043a\u0441\u0442\u044b, \u043c\u0435\u0442\u043a\u0438, \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u0434\u0438\u043d\u0443 \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0442\u043e\u043a\u0435\u043d\u0430\u0445, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0442\u043e\u043a\u0435\u043d\u0430\u0439\u0437\u0435\u0440. \u0422\u043e\u043a\u0435\u043d\u0430\u0439\u0437\u0435\u0440 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0438\u0437 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f huggingface <a href=\"https:\/\/huggingface.co\/cointegrated\/rubert-tiny\" rel=\"noopener noreferrer nofollow\">rubert-tiny<\/a>. \u0414\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<\/p>\n<pre><code class=\"python\">from transformers import BertTokenizer tokenizer_path = 'cointegrated\/rubert-tiny' tokenizer = BertTokenizer.from_pretrained(tokenizer_path)<\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 <strong>len <\/strong>\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0434\u043b\u0438\u043d\u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0430. \u041c\u0435\u0442\u043e\u0434 <strong>getitem <\/strong>\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043b\u043e\u0432\u0430\u0440\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0441\u0430\u043c\u043e\u0433\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430, \u0441\u043f\u0438\u0441\u043a\u0430 \u0442\u043e\u043a\u0435\u043d\u043e\u0432, \u043c\u0430\u0441\u043a\u0438 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043c\u0435\u0442\u043a\u0438 \u043a\u043b\u0430\u0441\u0441\u0430. \u041e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <code>.encode_plus()<\/code>. \u0412 \u044d\u0442\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 \u043c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u0443, \u0447\u0442\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u043c\u043b\u044f\u0442\u044c \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u044b\u043c\u0438 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438 <code>add_special_tokens=True<\/code>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u044b \u0434\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u0438\u043d\u044b <code>padding='max_len'<\/code>.<\/p>\n<h3>\u041c\u043e\u0434\u0435\u043b\u044c<\/h3>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0440\u0443\u0441\u0441\u043a\u043e\u044f\u0437\u044b\u0447\u043d\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c BERT \u0438\u0437 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f huggingface <a href=\"https:\/\/huggingface.co\/cointegrated\/rubert-tiny\" rel=\"noopener noreferrer nofollow\">rubert-tiny<\/a>. \u0414\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<\/p>\n<pre><code class=\"python\">from transformers import BertForSequenceClassification model_path = 'cointegrated\/rubert-tiny' model = BertForSequenceClassification.from_pretrained(model_path)<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0441\u0432\u044f\u0437\u043d\u044b\u0439 \u0441\u043b\u043e\u0439, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u0445\u043e\u0434\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u2014 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044f\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430 \u0441\u0435\u0442\u0438, \u0430 \u0432\u044b\u0445\u043e\u0434 &#8212; \u0447\u0438\u0441\u043b\u043e \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0443 \u043d\u0430\u0441 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043d\u0430 2 \u043a\u043b\u0430\u0441\u0441\u0430, \u0430 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044e\u044e \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c,\u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<\/p>\n<pre><code class=\"python\">out_features = model.bert.encoder.layer[1].output.dense.out_features<\/code><\/pre>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0432\u043d\u0430 <code>312<\/code>. \u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u043b\u043d\u043e\u0441\u0432\u044f\u0437\u043d\u044b\u0439 \u0441\u043b\u043e\u0439:<\/p>\n<pre><code class=\"python\">model.classifier = torch.nn.Linear(312, 2)<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">class BertClassifier:      def __init__(self, model_path, tokenizer_path, n_classes=2, epochs=1, model_save_path='\/content\/bert.pt'):         self.model = BertForSequenceClassification.from_pretrained(model_path)         self.tokenizer = BertTokenizer.from_pretrained(tokenizer_path)         self.device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")         self.model_save_path=model_save_path         self.max_len = 512         self.epochs = epochs         self.out_features = self.model.bert.encoder.layer[1].output.dense.out_features         self.model.classifier = torch.nn.Linear(self.out_features, n_classes)         self.model.to(self.device)<\/code><\/pre>\n<\/div>\n<\/details>\n<h2>Helpers<\/h2>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b.<\/p>\n<h4>DataLoader<\/h4>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0430\u0442\u0447\u0435\u0439. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u0434\u0430\u0442\u0430\u0441\u0435\u0442, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u0435\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u044d\u043c\u043f\u043b\u043e\u0432 \u0432 \u0431\u0430\u0442\u0447\u0435.<\/p>\n<pre><code class=\"python\">from torch.utils.data DataLoader train_set = CustomDataset(X_train, y_train, tokenizer) train_loader = DataLoader(train_set, batch_size=2, shuffle=True)<\/code><\/pre>\n<h4>Optimizer<\/h4>\n<p>\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0442\u043e\u0440 \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u043d\u043e\u0433\u043e \u0441\u043f\u0443\u0441\u043a\u0430. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043d\u0430\u0448\u0435\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 <code>model.parameters()<\/code>, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f <code>lr<\/code>.<\/p>\n<pre><code class=\"python\">from transformers import AdamW optimizer = AdamW(model.parameters(), lr=2e-5, correct_bias=False)<\/code><\/pre>\n<h4>Scheduler<\/h4>\n<p>\u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a, \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0442\u043e\u0440, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043e\u0431\u0449\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0448\u0430\u0433\u043e\u0432 \u0434\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0440\u0430\u0432\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0431\u0430\u0442\u0447\u0435\u0439 \u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u043e\u0447\u043d\u043e\u0439 \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u043d\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u044d\u043f\u043e\u0445 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"python\">from transformers import get_linear_schedule_with_warmup scheduler = get_linear_schedule_with_warmup(                 optimizer,                 num_warmup_steps=0,                 num_training_steps=len(train_loader) * epochs             )<\/code><\/pre>\n<h4>Loss<\/h4>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u0442\u0435\u0440\u044c, \u0441\u0447\u0438\u0442\u0430\u0435\u043c \u043f\u043e \u043d\u0435\u0439 \u043e\u0448\u0438\u0431\u043a\u0443 \u043c\u043e\u0434\u0435\u043b\u0438:<\/p>\n<pre><code>loss_fn = torch.nn.CrossEntropyLoss()<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0445\u044d\u043b\u043f\u0435\u0440\u043e\u0432:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">def preparation(self, X_train, y_train, X_valid, y_valid):     # create datasets     self.train_set = CustomDataset(X_train, y_train, self.tokenizer)     self.valid_set = CustomDataset(X_valid, y_valid, self.tokenizer)      # create data loaders     self.train_loader = DataLoader(self.train_set, batch_size=2, shuffle=True)     self.valid_loader = DataLoader(self.valid_set, batch_size=2, shuffle=True)      # helpers initialization     self.optimizer = AdamW(self.model.parameters(), lr=2e-5, correct_bias=False)     self.scheduler = get_linear_schedule_with_warmup(             self.optimizer,             num_warmup_steps=0,             num_training_steps=len(self.train_loader) * self.epochs         )     self.loss_fn = torch.nn.CrossEntropyLoss().to(self.device)<\/code><\/pre>\n<\/div>\n<\/details>\n<h2>Train<\/h2>\n<details class=\"spoiler\">\n<summary>\u041e\u0431\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0439 \u044d\u043f\u043e\u0445\u0438:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">def fit(self):     self.model = self.model.train()     losses = []     correct_predictions = 0      for data in self.train_loader:         input_ids = data[\"input_ids\"].to(self.device)         attention_mask = data[\"attention_mask\"].to(self.device)         targets = data[\"targets\"].to(self.device)          outputs = self.model(             input_ids=input_ids,             attention_mask=attention_mask             )          preds = torch.argmax(outputs.logits, dim=1)         loss = self.loss_fn(outputs.logits, targets)          correct_predictions += torch.sum(preds == targets)          losses.append(loss.item())                  loss.backward()         torch.nn.utils.clip_grad_norm_(self.model.parameters(), max_norm=1.0)         self.optimizer.step()         self.scheduler.step()         self.optimizer.zero_grad()      train_acc = correct_predictions.double() \/ len(self.train_set)     train_loss = np.mean(losses)     return train_acc, train_loss<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0414\u0430\u043d\u043d\u044b\u0435 \u0432 \u0446\u0438\u043a\u043b\u0435 \u0431\u0430\u0442\u0447\u0430\u043c\u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0441  \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>DataLoader<\/code>:<\/p>\n<pre><code class=\"python\">for data in self.train_loader:     input_ids = data[\"input_ids\"].to(self.device)     attention_mask = data[\"attention_mask\"].to(self.device)     targets = data[\"targets\"].to(self.device)<\/code><\/pre>\n<p>\u0411\u0430\u0442\u0447 \u043f\u043e\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043c\u043e\u0434\u0435\u043b\u044c:<\/p>\n<pre><code class=\"python\">outputs = self.model(     input_ids=input_ids,     attention_mask=attention_mask     )<\/code><\/pre>\n<p>\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u0438 \u043f\u043e \u043a\u043b\u0430\u0441\u0441\u0430\u043c \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438:<\/p>\n<pre><code>preds = torch.argmax(outputs.logits, dim=1) loss = self.loss_fn(outputs.logits, targets)<\/code><\/pre>\n<p>\u0414\u0435\u043b\u0430\u0435\u043c \u0448\u0430\u0433 \u043d\u0430 \u0432\u0441\u0435\u0445 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445:<\/p>\n<ul>\n<li>\n<p><code>loss.backward()<\/code>: \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0435 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438;<\/p>\n<\/li>\n<li>\n<p><code>clip_grad_norm()<\/code>: \u043e\u0431\u0440\u0435\u0437\u0430\u0435\u043c \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f &#171;\u0432\u0437\u0440\u044b\u0432\u0430&#187; \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p><code>optimizer.step()<\/code>: \u0448\u0430\u0433 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0442\u043e\u0440\u0430;<\/p>\n<\/li>\n<li>\n<p><code>scheduler.step()<\/code>: \u0448\u0430\u0433 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430;<\/p>\n<\/li>\n<li>\n<p><code>optimizer.zero_grad()<\/code>: \u043e\u0431\u043d\u0443\u043b\u044f\u0435\u043c \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u044b.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u043c\u0435\u0442\u043e\u0434\u0430 eval:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">def eval(self):     self.model = self.model.eval()     losses = []     correct_predictions = 0      with torch.no_grad():         for data in self.valid_loader:             input_ids = data[\"input_ids\"].to(self.device)             attention_mask = data[\"attention_mask\"].to(self.device)             targets = data[\"targets\"].to(self.device)              outputs = self.model(                 input_ids=input_ids,                 attention_mask=attention_mask                 )              preds = torch.argmax(outputs.logits, dim=1)             loss = self.loss_fn(outputs.logits, targets)             correct_predictions += torch.sum(preds == targets)             losses.append(loss.item())          val_acc = correct_predictions.double() \/ len(self.valid_set)     val_loss = np.mean(losses)     return val_acc, val_loss<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0414\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u044d\u043f\u043e\u0445\u0430\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 <code>train<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u044b <code>fit<\/code> \u0438 <code>eval<\/code>.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u043c\u0435\u0442\u043e\u0434\u0430 train:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">def train(self):     best_accuracy = 0     for epoch in range(self.epochs):         print(f'Epoch {epoch + 1}\/{self.epochs}')         train_acc, train_loss = self.fit()         print(f'Train loss {train_loss} accuracy {train_acc}')          val_acc, val_loss = self.eval()         print(f'Val loss {val_loss} accuracy {val_acc}')         print('-' * 10)          if val_acc &gt; best_accuracy:             torch.save(self.model, self.model_save_path)             best_accuracy = val_acc      self.model = torch.load(self.model_save_path)<\/code><\/pre>\n<\/div>\n<\/details>\n<h2>Inference<\/h2>\n<p>\u0414\u043b\u044f \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 <code>predict,<\/code> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438. \u041c\u0435\u0442\u043e\u0434 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<ul>\n<li>\n<p>\u0422\u043e\u043a\u0435\u043d\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u0435\u043a\u0441\u0442;<\/p>\n<\/li>\n<li>\n<p>\u0422\u043e\u043a\u0435\u043d\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u043f\u043e\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043c\u043e\u0434\u0435\u043b\u044c;<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043c\u0435\u0442\u043a\u0443 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u043c\u0435\u0442\u043e\u0434\u0430 predict: <\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">def predict(self, text):     encoding = self.tokenizer.encode_plus(         text,         add_special_tokens=True,         max_length=self.max_len,         return_token_type_ids=False,         truncation=True,         padding='max_length',         return_attention_mask=True,         return_tensors='pt',     )          out = {           'text': text,           'input_ids': encoding['input_ids'].flatten(),           'attention_mask': encoding['attention_mask'].flatten()       }          input_ids = out[\"input_ids\"].to(self.device)     attention_mask = out[\"attention_mask\"].to(self.device)          outputs = self.model(         input_ids=input_ids.unsqueeze(0),         attention_mask=attention_mask.unsqueeze(0)     )          prediction = torch.argmax(outputs.logits, dim=1).cpu().numpy()[0]      return prediction<\/code><\/pre>\n<\/div>\n<\/details>\n<h2>\u0421\u0441\u044b\u043b\u043a\u0438<\/h2>\n<ol>\n<li>\n<p><a href=\"https:\/\/github.com\/shitkov\/bert4classification\" rel=\"noopener noreferrer nofollow\">\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u043d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/study.mokoron.com\/\" rel=\"noopener noreferrer nofollow\">RuTweetCorp<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/huggingface.co\/cointegrated\/rubert-tiny\" rel=\"noopener noreferrer nofollow\">ruBert tiny<\/a><\/p>\n<\/li>\n<\/ol>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0425\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0438 \u043a\u0440\u0430\u0442\u043a\u043e, \u043d\u043e \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043a\u0430\u043a-\u0442\u043e \u043e\u0431\u044a\u0435\u043c\u043d\u043e. \u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u044f, \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442\u0441\u044f!<\/p>\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\/567028\/\"> https:\/\/habr.com\/ru\/post\/567028\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<h2>\u0417\u0430\u0447\u0435\u043c<\/h2>\n<p>\u0412 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435 \u043f\u043e\u043b\u043d\u043e \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u044b\u0445 \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u0440\u043e BERT. \u041d\u043e \u0447\u0430\u0441\u0442\u043e \u043e\u043d\u0438 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u044b \u0434\u043b\u044f \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u043e\u0447\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u043e\u0431\u0443\u0447\u0438\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u043b\u044f \u0441\u0432\u043e\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438. \u0414\u0430\u043d\u043d\u044b\u0439 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0444\u0430\u0439\u043d\u0442\u044e\u043d\u0438\u0442\u044c \u0440\u0443\u0441\u0441\u043a\u043e\u044f\u0437\u044b\u0447\u043d\u044b\u0439 BERT \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447\u0438 \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438. \u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043d\u0430 <a href=\"https:\/\/github.com\/shitkov\/bert4classification\" rel=\"noopener noreferrer nofollow\">github<\/a>, \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u0432 <strong>google colab<\/strong> \u043e\u0434\u043d\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u043e\u0439.<\/p>\n<h2>Workflow<\/h2>\n<ol>\n<li>\n<p>\u0414\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c<\/p>\n<\/li>\n<li>\n<p>Helpers<\/p>\n<\/li>\n<li>\n<p>Train<\/p>\n<\/li>\n<li>\n<p>Inference<\/p>\n<\/li>\n<\/ol>\n<h2>\u0414\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f<\/h2>\n<p>\u0414\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u043e\u0447\u0438\u0449\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0440\u0443\u0441\u0441\u043a\u043e\u044f\u0437\u044b\u0447\u043d\u043e\u0433\u043e \u0442\u0432\u0438\u0442\u0442\u0435\u0440\u0430 \u0438\u0437 \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0430 <a href=\"https:\/\/study.mokoron.com\/\" rel=\"noopener noreferrer nofollow\">RuTweetCorp<\/a>. \u0414\u0430\u043d\u043d\u044b\u0435 \u0440\u0430\u0437\u043c\u0435\u0447\u0435\u043d\u044b \u043d\u0430 2 \u043a\u043b\u0430\u0441\u0441\u0430:<\/p>\n<ul>\n<li>\n<p>&#8216;0&#8217; &#8212; \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u044b\u0435<\/p>\n<\/li>\n<li>\n<p>&#8216;1&#8217; &#8212; \u043f\u043e\u0437\u0438\u0442\u0438\u0432\u043d\u044b\u0435<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 Dataset:<\/p>\n<pre><code class=\"python\">from torch.utils.data import Dataset  class CustomDataset(Dataset):    def __init__(self, texts, targets, tokenizer, max_len=512):     self.texts = texts     self.targets = targets     self.tokenizer = tokenizer     self.max_len = max_len    def __len__(self):     return len(self.texts)    def __getitem__(self, idx):     text = str(self.texts[idx])     target = self.targets[idx]      encoding = self.tokenizer.encode_plus(         text,         add_special_tokens=True,         max_length=self.max_len,         return_token_type_ids=False,         padding='max_length',         return_attention_mask=True,         return_tensors='pt',     )      return {       'text': text,       'input_ids': encoding['input_ids'].flatten(),       'attention_mask': encoding['attention_mask'].flatten(),       'targets': torch.tensor(target, dtype=torch.long)     } <\/code><\/pre>\n<p>\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438 <code>__init__<\/code>, <code>__len__<\/code>, <code>__getitem__<\/code>. \u0412 \u043c\u0435\u0442\u043e\u0434\u0435 <code>__init__<\/code><strong> <\/strong>\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0442\u0435\u043a\u0441\u0442\u044b, \u043c\u0435\u0442\u043a\u0438, \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u0434\u0438\u043d\u0443 \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0442\u043e\u043a\u0435\u043d\u0430\u0445, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0442\u043e\u043a\u0435\u043d\u0430\u0439\u0437\u0435\u0440. \u0422\u043e\u043a\u0435\u043d\u0430\u0439\u0437\u0435\u0440 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0438\u0437 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f huggingface <a href=\"https:\/\/huggingface.co\/cointegrated\/rubert-tiny\" rel=\"noopener noreferrer nofollow\">rubert-tiny<\/a>. \u0414\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<\/p>\n<pre><code class=\"python\">from transformers import BertTokenizer tokenizer_path = 'cointegrated\/rubert-tiny' tokenizer = BertTokenizer.from_pretrained(tokenizer_path)<\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 <strong>len <\/strong>\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0434\u043b\u0438\u043d\u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0430. \u041c\u0435\u0442\u043e\u0434 <strong>getitem <\/strong>\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043b\u043e\u0432\u0430\u0440\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0441\u0430\u043c\u043e\u0433\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430, \u0441\u043f\u0438\u0441\u043a\u0430 \u0442\u043e\u043a\u0435\u043d\u043e\u0432, \u043c\u0430\u0441\u043a\u0438 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043c\u0435\u0442\u043a\u0438 \u043a\u043b\u0430\u0441\u0441\u0430. \u041e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <code>.encode_plus()<\/code>. \u0412 \u044d\u0442\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 \u043c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u0443, \u0447\u0442\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u043c\u043b\u044f\u0442\u044c \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u044b\u043c\u0438 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438 <code>add_special_tokens=True<\/code>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u044b \u0434\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u0438\u043d\u044b <code>padding='max_len'<\/code>.<\/p>\n<h3>\u041c\u043e\u0434\u0435\u043b\u044c<\/h3>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0440\u0443\u0441\u0441\u043a\u043e\u044f\u0437\u044b\u0447\u043d\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c BERT \u0438\u0437 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f huggingface <a href=\"https:\/\/huggingface.co\/cointegrated\/rubert-tiny\" rel=\"noopener noreferrer nofollow\">rubert-tiny<\/a>. \u0414\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<\/p>\n<pre><code class=\"python\">from transformers import BertForSequenceClassification model_path = 'cointegrated\/rubert-tiny' model = BertForSequenceClassification.from_pretrained(model_path)<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0441\u0432\u044f\u0437\u043d\u044b\u0439 \u0441\u043b\u043e\u0439, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u0445\u043e\u0434\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u2014 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044f\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0430 \u0441\u0435\u0442\u0438, \u0430 \u0432\u044b\u0445\u043e\u0434 &#8212; \u0447\u0438\u0441\u043b\u043e \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0443 \u043d\u0430\u0441 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043d\u0430 2 \u043a\u043b\u0430\u0441\u0441\u0430, \u0430 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044e\u044e \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c,\u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<\/p>\n<pre><code class=\"python\">out_features = model.bert.encoder.layer[1].output.dense.out_features<\/code><\/pre>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0432\u043d\u0430 <code>312<\/code>. \u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u043b\u043d\u043e\u0441\u0432\u044f\u0437\u043d\u044b\u0439 \u0441\u043b\u043e\u0439:<\/p>\n<pre><code class=\"python\">model.classifier = torch.nn.Linear(312, 2)<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">class BertClassifier:      def __init__(self, model_path, tokenizer_path, n_classes=2, epochs=1, model_save_path='\/content\/bert.pt'):         self.model = BertForSequenceClassification.from_pretrained(model_path)         self.tokenizer = BertTokenizer.from_pretrained(tokenizer_path)         self.device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")         self.model_save_path=model_save_path         self.max_len = 512         self.epochs = epochs         self.out_features = self.model.bert.encoder.layer[1].output.dense.out_features         self.model.classifier = torch.nn.Linear(self.out_features, n_classes)         self.model.to(self.device)<\/code><\/pre>\n<\/div>\n<\/details>\n<h2>Helpers<\/h2>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b.<\/p>\n<h4>DataLoader<\/h4>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0430\u0442\u0447\u0435\u0439. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u0434\u0430\u0442\u0430\u0441\u0435\u0442, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u0435\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u044d\u043c\u043f\u043b\u043e\u0432 \u0432 \u0431\u0430\u0442\u0447\u0435.<\/p>\n<pre><code class=\"python\">from torch.utils.data DataLoader train_set = CustomDataset(X_train, y_train, tokenizer) train_loader = DataLoader(train_set, batch_size=2, shuffle=True)<\/code><\/pre>\n<h4>Optimizer<\/h4>\n<p>\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0442\u043e\u0440 \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u043d\u043e\u0433\u043e \u0441\u043f\u0443\u0441\u043a\u0430. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043d\u0430\u0448\u0435\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 <code>model.parameters()<\/code>, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f <code>lr<\/code>.<\/p>\n<pre><code class=\"python\">from transformers import AdamW optimizer = AdamW(model.parameters(), lr=2e-5, correct_bias=False)<\/code><\/pre>\n<h4>Scheduler<\/h4>\n<p>\u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a, \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0442\u043e\u0440, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043e\u0431\u0449\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0448\u0430\u0433\u043e\u0432 \u0434\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0440\u0430\u0432\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0431\u0430\u0442\u0447\u0435\u0439 \u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u043e\u0447\u043d\u043e\u0439 \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u043d\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u044d\u043f\u043e\u0445 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"python\">from transformers import get_linear_schedule_with_warmup scheduler = get_linear_schedule_with_warmup(                 optimizer,                 num_warmup_steps=0,                 num_training_steps=len(train_loader) * epochs             )<\/code><\/pre>\n<h4>Loss<\/h4>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u0442\u0435\u0440\u044c, \u0441\u0447\u0438\u0442\u0430\u0435\u043c \u043f\u043e \u043d\u0435\u0439 \u043e\u0448\u0438\u0431\u043a\u0443 \u043c\u043e\u0434\u0435\u043b\u0438:<\/p>\n<pre><code>loss_fn = torch.nn.CrossEntropyLoss()<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0445\u044d\u043b\u043f\u0435\u0440\u043e\u0432:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">def preparation(self, X_train, y_train, X_valid, y_valid):     # create datasets     self.train_set = CustomDataset(X_train, y_train, self.tokenizer)     self.valid_set = CustomDataset(X_valid, y_valid, self.tokenizer)      # create data loaders     self.train_loader = DataLoader(self.train_set, batch_size=2, shuffle=True)     self.valid_loader = DataLoader(self.valid_set, batch_size=2, shuffle=True)      # helpers initialization     self.optimizer = AdamW(self.model.parameters(), lr=2e-5, correct_bias=False)     self.scheduler = get_linear_schedule_with_warmup(             self.optimizer,             num_warmup_steps=0,             num_training_steps=len(self.train_loader) * self.epochs         )     self.loss_fn = torch.nn.CrossEntropyLoss().to(self.device)<\/code><\/pre>\n<\/div>\n<\/details>\n<h2>Train<\/h2>\n<details class=\"spoiler\">\n<summary>\u041e\u0431\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0439 \u044d\u043f\u043e\u0445\u0438:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">def fit(self):     self.model = self.model.train()     losses = []     correct_predictions = 0      for data in self.train_loader:         input_ids = data[\"input_ids\"].to(self.device)         attention_mask = data[\"attention_mask\"].to(self.device)         targets = data[\"targets\"].to(self.device)          outputs = self.model(             input_ids=input_ids,             attention_mask=attention_mask             )          preds = torch.argmax(outputs.logits, dim=1)         loss = self.loss_fn(outputs.logits, targets)          correct_predictions += torch.sum(preds == targets)          losses.append(loss.item())                  loss.backward()         torch.nn.utils.clip_grad_norm_(self.model.parameters(), max_norm=1.0)         self.optimizer.step()         self.scheduler.step()         self.optimizer.zero_grad()      train_acc = correct_predictions.double() \/ len(self.train_set)     train_loss = np.mean(losses)     return train_acc, train_loss<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0414\u0430\u043d\u043d\u044b\u0435 \u0432 \u0446\u0438\u043a\u043b\u0435 \u0431\u0430\u0442\u0447\u0430\u043c\u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0441  \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>DataLoader<\/code>:<\/p>\n<pre><code class=\"python\">for data in self.train_loader:     input_ids = data[\"input_ids\"].to(self.device)     attention_mask = data[\"attention_mask\"].to(self.device)     targets = data[\"targets\"].to(self.device)<\/code><\/pre>\n<p>\u0411\u0430\u0442\u0447 \u043f\u043e\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043c\u043e\u0434\u0435\u043b\u044c:<\/p>\n<pre><code class=\"python\">outputs = self.model(     input_ids=input_ids,     attention_mask=attention_mask     )<\/code><\/pre>\n<p>\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u0438 \u043f\u043e \u043a\u043b\u0430\u0441\u0441\u0430\u043c \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438:<\/p>\n<pre><code>preds = torch.argmax(outputs.logits, dim=1) loss = self.loss_fn(outputs.logits, targets)<\/code><\/pre>\n<p>\u0414\u0435\u043b\u0430\u0435\u043c \u0448\u0430\u0433 \u043d\u0430 \u0432\u0441\u0435\u0445 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445:<\/p>\n<ul>\n<li>\n<p><code>loss.backward()<\/code>: \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0435 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438;<\/p>\n<\/li>\n<li>\n<p><code>clip_grad_norm()<\/code>: \u043e\u0431\u0440\u0435\u0437\u0430\u0435\u043c \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f &#171;\u0432\u0437\u0440\u044b\u0432\u0430&#187; \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p><code>optimizer.step()<\/code>: \u0448\u0430\u0433 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0442\u043e\u0440\u0430;<\/p>\n<\/li>\n<li>\n<p><code>scheduler.step()<\/code>: \u0448\u0430\u0433 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430;<\/p>\n<\/li>\n<li>\n<p><code>optimizer.zero_grad()<\/code>: \u043e\u0431\u043d\u0443\u043b\u044f\u0435\u043c \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u044b.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u043c\u0435\u0442\u043e\u0434\u0430 eval:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">def eval(self):     self.model = self.model.eval()     losses = []     correct_predictions = 0      with torch.no_grad():         for data in self.valid_loader:             input_ids = data[\"input_ids\"].to(self.device)             attention_mask = data[\"attention_mask\"].to(self.device)             targets = data[\"targets\"].to(self.device)              outputs = self.model(                 input_ids=input_ids,                 attention_mask=attention_mask                 )              preds = torch.argmax(outputs.logits, dim=1)             loss = self.loss_fn(outputs.logits, targets)             correct_predictions += torch.sum(preds == targets)             losses.append(loss.item())          val_acc = correct_predictions.double() \/ len(self.valid_set)     val_loss = np.mean(losses)     return val_acc, val_loss<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0414\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u044d\u043f\u043e\u0445\u0430\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 <code>train<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u044b <code>fit<\/code> \u0438 <code>eval<\/code>.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u043c\u0435\u0442\u043e\u0434\u0430 train:<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">def train(self):     best_accuracy = 0     for epoch in range(self.epochs):         print(f'Epoch {epoch + 1}\/{self.epochs}')         train_acc, train_loss = self.fit()         print(f'Train loss {train_loss} accuracy {train_acc}')          val_acc, val_loss = self.eval()         print(f'Val loss {val_loss} accuracy {val_acc}')         print('-' * 10)          if val_acc &gt; best_accuracy:             torch.save(self.model, self.model_save_path)             best_accuracy = val_acc      self.model = torch.load(self.model_save_path)<\/code><\/pre>\n<\/div>\n<\/details>\n<h2>Inference<\/h2>\n<p>\u0414\u043b\u044f \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 <code>predict,<\/code> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438. \u041c\u0435\u0442\u043e\u0434 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<ul>\n<li>\n<p>\u0422\u043e\u043a\u0435\u043d\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u0435\u043a\u0441\u0442;<\/p>\n<\/li>\n<li>\n<p>\u0422\u043e\u043a\u0435\u043d\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u043f\u043e\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043c\u043e\u0434\u0435\u043b\u044c;<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043c\u0435\u0442\u043a\u0443 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u043c\u0435\u0442\u043e\u0434\u0430 predict: <\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">def predict(self, text):     encoding = self.tokenizer.encode_plus(         text,         add_special_tokens=True,         max_length=self.max_len,         return_token_type_ids=False,         truncation=True,         padding='max_length',         return_attention_mask=True,         return_tensors='pt',     )          out = {           'text': text,           'input_ids': encoding['input_ids'].flatten(),           'attention_mask':<\/code><\/pre>\n<\/div>\n<\/details>\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-326255","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/326255","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=326255"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/326255\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=326255"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=326255"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=326255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}