from mistralai import Mistral
import pyperclip
import random

questions = {2.00: """
import re
import nltk
import unicodedata
import string
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from langdetect import detect

nltk.download('punkt', quiet=True)
nltk.download('stopwords', quiet=True)

def get_stopwords(lang):
    lang_map = {
        'en': 'english',
        'ru': 'russian'
    }
    
    lang = lang_map.get(lang, lang)

    return set(stopwords.words(lang))

def process_text(text, lang='en'):
    text = text.lower()
    text = text.replace('“', '"').replace('”', '"').replace('‘', "'").replace('’', "'")
    text = re.sub(r'\d+', '<NUM>', text))
    text = re.sub(r'\b[a-zа-яё]\b', '', text)
    text = re.sub(r'@\w+', '<MENTION>', text)
    text = re.sub(r'#\w+', '<HASHTAG>', text)
    text = re.sub(r'<.*?>', ' ', text)
    text = re.sub(r'[^\w\s]', ' ', text)
    text = re.sub(r'\b[a-zA-Z]\b', '', text)
    text = re.sub(r'\s+', ' ', text).strip()

    stop_words = get_stopwords(lang)
    tokens = word_tokenize(text)
    tokens = [word for word in tokens if word not in stop_words]

    return ' '.join(tokens)

from collections import Counter
import pandas as pd
from sklearn.model_selection import train_test_split
from torch.utils.data import DataLoader, Dataset
import torch
import torch.nn as nn
from torch.nn.utils.rnn import pad_sequence
import torch.optim as optim
import time
from sklearn.metrics import accuracy_score, classification_report

df = pd.read_csv('файл.csv')
df.head()

df['x'] = df['X'].apply(process_text)

def tokenize(text):
    return text.split()

all_tokens = [token for line in df['X'] for token in tokenize(line)]

vocab = {word: i+1 for i, (word, _) in enumerate(Counter(all_tokens).most_common())}

vocab['<PAD>'] = 0
vocab['<UNK>'] = 1

def encode(text):
    encoded = [vocab.get(word, 1) for word in tokenize(text)]
    return encoded[:20]

df['encoded'] = df['X'].apply(encode)

X = df['encoded'].tolist()
y = df['label'].tolist()

X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, test_size=0.2, random_state=42)

class Dataset(Dataset):
    def __init__(self, X, y):
        self.X = [torch.tensor(x, dtype=torch.long) for x in X]
        self.y = torch.tensor(y, dtype=torch.long)

    def __len__(self):
        return len(self.y)

    def __getitem__(self, idx):
        return self.X[idx], self.y[idx]

def collate_fn(batch):
    inputs, targets = zip(*batch)
    inputs_padded = pad_sequence(inputs, batch_first=True, padding_value=0)
    return inputs_padded, torch.tensor(targets)

train_ds = SMSDataset(X_train, y_train)
test_ds = SMSDataset(X_test, y_test)

train_loader = DataLoader(train_ds, batch_size=8, shuffle=True, collate_fn=collate_fn)
test_loader = DataLoader(test_ds, batch_size=8, collate_fn=collate_fn)
""",
             2.01: "class_weights = compute_class_weight(class_weight='balanced', classes=np.array([0, 1]), y=y_enc)\npos_weight = class_weights[1] / class_weights[0]\npos_weight\nmodel_2 = Model_1(X_processed.shape[1], 1)\nloss_func = nn.BCEWithLogitsLoss(pos_weight=th.tensor(pos_weight, dtype=th.float32))\noptimizer = optim.Adam(model_2.parameters(), lr=0.001)\nepochs = 10\n\nmodel_train_weights = train_func(model=model_2,\n                                loader=train_loader,\n                                n_epochs=epochs,\n                                loss_func=loss_func,\n                                optimizer=optimizer,\n                                metric_dict=metric_dict,\n                                print_every=5,\n                                test_loader=test_loader,\n                               )\ntest_results_w, test_loss, y_pred, y_true = eval_metrics(model_train_weights[1], test_loader, metric_dict, loss_func)\n\ny_pred = y_pred.numpy()\ny_true = y_true.numpy()\n\ncm = confusion_matrix(y_true, y_pred)\n\nplt.figure(figsize=(4, 2))\nsns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=['Class 0', 'Class 1'], yticklabels=['Class 0', 'Class 1'])\nplt.xlabel('Predicted')\nplt.ylabel('Actual')\nplt.title('Confusion Matrix')\nplt.show()\n\nprint('Classification Report:')\nprint(classification_report(y_true, y_pred, target_names=['Class 0', 'Class 1']))\nplt.plot(model_train_weights[0]['test_metric_scores']['F1'], label='Weighted Model (F1)')\nplt.plot(model_train[0]['test_metric_scores']['F1'], label='Baseline Model (F1)')\n\nplt.xlabel('Epochs')\nplt.ylabel('F1 Score')\nplt.title('F1 Score Over Epochs')\nplt.legend()\nplt.show() ",
             2.02 : "class Model_drop(nn.Module):\n    def __init__(self, n_inputs: int, n_classes: int) -> None:\n        super().__init__()\n        self.layer_1 = nn.Linear(n_inputs, 16)\n        self.layer_2 = nn.Linear(16, n_classes)\n        self.relu = nn.ReLU()\n        self.drop = nn.Dropout(p=0.5)\n\n    def forward(self, X: th.Tensor) -> th.Tensor:\n        out = self.layer_1(X)\n        out = self.relu(out)\n        out = self.drop(out)\n        out = self.layer_2(out)\n        return out\nmodel_dr = Model_drop(X_processed.shape[1], 2)\n\nloss_func = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model_dr.parameters(), lr=0.001)\nepochs = 10\n\nmodel_train_drop = train_func(model=model_dr,\n                                loader=train_loader,\n                                n_epochs=epochs,\n                                loss_func=loss_func,\n                                optimizer=optimizer,\n                                metric_dict=metric_dict,\n                                print_every=5,\n                                test_loader=test_loader,\n                               )\nplt.plot(model_train_drop[0]['epoch_losses'], label='Model with Dropout (F1)')\nplt.plot(model_train[0]['epoch_losses'], label='Baseline Model (F1)')\n\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\nplt.show()\n_, _, y_pred, y_true = eval_metrics(model_train_drop[1], test_loader, metric_dict, loss_func)\n\ny_pred = y_pred.numpy()\ny_true = y_true.numpy()\n\ncm = confusion_matrix(y_true, y_pred)\n\nplt.figure(figsize=(4, 2))\nsns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=['Class 0', 'Class 1'], yticklabels=['Class 0', 'Class 1'])\nplt.xlabel('Predicted')\nplt.ylabel('Actual')\nplt.title('Confusion Matrix')\nplt.show()\n\nprint('Classification Report:')\nprint(classification_report(y_true, y_pred, target_names=['Class 0', 'Class 1']))\nplt.plot(model_train_drop[0]['test_metric_scores']['F1'], label='Model with Dropout (F1)')\nplt.plot(model_train[0]['test_metric_scores']['F1'], label='Baseline Model (F1)')\n\nplt.xlabel('Epochs')\nplt.ylabel('F1 Score')\nplt.title('F1 Score Over Epochs')\nplt.legend()\nplt.show() ",
             2.03 : "optimizers = {\n    'Adam': lambda params: optim.Adam(params, lr=0.001),\n    'SGD': lambda params: optim.SGD(params, lr=0.01, momentum=0.9),\n    'RMSprop': lambda params: optim.RMSprop(params, lr=0.001)\n}\n\nepochs=10\nresults = {}\n\nfor name, optimizer_fn in optimizers.items():\n    print(f'Training {name} optimizer')\n    model = Model_1(X_processed.shape[1], 2)\n    optimizer = optimizer_fn(model.parameters())\n    \n    train_results, _ = train_func(\n        model=model,\n        loader=train_loader,\n        n_epochs=epochs,\n        loss_func=loss_func,\n        optimizer=optimizer,\n        metric_dict=metric_dict,\n        print_every=epochs // 2,\n        test_loader=test_loader,\n    )\n    results[name] = train_results\n\nplt.figure(figsize=(12, 6))\n\nplt.subplot(1, 2, 1)\nfor name, res in results.items():\n    plt.plot(res['epoch_losses'], label=f'{name} Loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.title('Train Loss')\nplt.legend()\n\nplt.subplot(1, 2, 2)\nfor name, res in results.items():\n    plt.plot(res['test_metric_scores']['F1'], label=f'{name} F1 Score')\nplt.xlabel('Epochs')\nplt.ylabel('F1 Score')\nplt.title('Test F1 Score')\nplt.legend()\n\nplt.tight_layout()\nplt.show()\n ",
             2.11 : "optimizers = {\n    'Adam': lambda params: optim.Adam(params, lr=0.001),\n    'SGD': lambda params: optim.SGD(params, lr=0.01, momentum=0.9),\n    'RMSprop': lambda params: optim.RMSprop(params, lr=0.001)\n}\n\nepochs=20\nresults = {}\n\nfor name, optimizer_fn in optimizers.items():\n    print(f'Training {name} optimizer')\n    model = Model_1(X.shape[1], 4)\n    optimizer = optimizer_fn(model.parameters())\n    \n    train_results, _ = train_func(\n        model=model,\n        loader=train_loader,\n        n_epochs=epochs,\n        loss_func=loss_func,\n        optimizer=optimizer,\n        metric_dict=metric_dict,\n        print_every=5,\n        test_loader=test_loader,\n    )\n    results[name] = train_results\n\nplt.figure(figsize=(12, 6))\n\nplt.subplot(1, 2, 1)\nfor name, res in results.items():\n    plt.plot(res['epoch_losses'], label=f'{name} Loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.title('Train Loss')\nplt.legend()\n\nplt.subplot(1, 2, 2)\nfor name, res in results.items():\n    plt.plot(res['test_metric_scores']['R2'], label=f'{name} R2')\nplt.xlabel('Epochs')\nplt.ylabel('R2')\nplt.title('Test R2')\nplt.legend()\n\nplt.tight_layout()\nplt.show() ",
             2.10 : "import pandas as pd\nimport numpy as np\n\nimport torch as th\nfrom torch import nn, optim\nfrom torch.utils.data import Dataset, DataLoader, TensorDataset\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import StandardScaler, OneHotEncoder, LabelEncoder\nfrom sklearn.compose import ColumnTransformer\nfrom torch.utils.data import TensorDataset, DataLoader, WeightedRandomSampler, random_split\nimport torchmetrics as M\nfrom sklearn.metrics import confusion_matrix, classification_report\nimport seaborn as sns\nfrom sklearn.utils.class_weight import compute_class_weight\n\nimport matplotlib.pyplot as plt\ndata = pd.read_csv('for_exam/datasets/regression/gold.csv')\nscaler = StandardScaler()\ndata[data.columns] = scaler.fit_transform(data[data.columns])\n\ny_cols = ['Gold_T-7', 'Gold_T-14', 'Gold_T-22', 'Gold_T+22']\nX = data.drop(columns=y_cols)\ny = data[y_cols]\n\nX = th.FloatTensor(X.values)\ny = th.FloatTensor(y.values)\n\ndataset = TensorDataset(X, y)\n\ngenerator = th.Generator().manual_seed(0)\ntrain_dataset, test_dataset = random_split(dataset, [0.8, 0.2], generator=generator)\n\ntrain_loader = DataLoader(train_dataset, batch_size=8, shuffle=True)\ntest_loader = DataLoader(test_dataset, batch_size=8, shuffle=False)\ndef train_func(model,\n               loader,\n               loss_func,\n               optimizer,\n               metric_dict,\n               mean_metric=M.MeanMetric(),\n               n_epochs: int = 100,\n               print_every: int = 1,\n               test_loader=None,\n               ):\n\n    out_dict = {}\n    epoch_losses = []\n    metric_scores = {name: [] for name in metric_dict.keys()}\n    test_metric_scores = {name: [] for name in metric_dict.keys()} if test_loader else None\n    test_losses = [] if test_loader else None\n    \n    model.train()\n    for epoch in range(n_epochs):\n        mean_metric.reset()\n        \n        for name, metric in metric_dict.items():\n            metric.reset()\n\n        for X_batch, y_batch in loader:\n            y_batch = y_batch.float()\n            y_pred = model(X_batch)\n            \n            loss = loss_func(y_pred, y_batch)\n            mean_metric.update(loss)\n            \n            for name, metric in metric_dict.items():\n                metric.update(y_pred, y_batch)\n            \n            loss.backward()\n            \n            optimizer.step()\n            optimizer.zero_grad()\n\n        epoch_loss = mean_metric.compute()\n        epoch_losses.append(epoch_loss.item())\n        \n        for name, metric in metric_dict.items():\n            metric_score = metric.compute().item()\n            metric_scores[name].append(metric_score)\n        \n        if test_loader:\n            test_results, test_loss, _, _ = eval_metrics(model, test_loader, metric_dict, loss_func)\n            test_losses.append(test_loss)\n            for name, score in test_results.items():\n                test_metric_scores[name].append(score)\n\n        if print_every != 0 and (epoch % print_every == 0 or epoch == n_epochs - 1):\n            metrics_str = ', '.join([f'{name}: {metric_scores[name][-1]:.4f}' for name in metric_dict.keys()])\n            if test_loader:\n                test_metrics_str = ', '.join([f'test_{name}: {test_results[name]:.4f}' for name in test_results.keys()])\n                print(f'Epoch {epoch + 1}, Loss: {epoch_loss.item():.4f}, {metrics_str}, \n'\n                      f'Test Loss: {test_loss:.4f}, {test_metrics_str}')\n            else:\n                print(f'Epoch {epoch + 1}, Loss: {epoch_loss.item():.4f}, {metrics_str}')\n    \n    out_dict['epoch_losses'] = epoch_losses\n    out_dict['metric_scores'] = metric_scores\n    if test_loader:\n        out_dict['test_metric_scores'] = test_metric_scores\n        out_dict['test_losses'] = test_losses\n    return out_dict, model\n\n\n@th.no_grad()\ndef eval_metrics(model, loader, metric_dict, loss_func):\n    model.eval()\n    results = {}\n    mean_metric = M.MeanMetric()\n    mean_metric.reset()\n\n    for name, metric in metric_dict.items():\n        metric.reset()\n\n    all_preds = []\n    all_targets = []\n\n    for X_batch, y_batch in loader:\n        y_batch = y_batch.float()\n        y_pred = model(X_batch)\n        \n        loss = loss_func(y_pred, y_batch)\n        mean_metric.update(loss)\n        \n        all_preds.append(y_pred)\n        all_targets.append(y_batch)\n\n        for name, metric in metric_dict.items():\n            metric.update(y_pred, y_batch)\n    \n    for name, metric in metric_dict.items():\n        results[name] = metric.compute().item()\n    \n    loss_value = mean_metric.compute().item()\n    return results, loss_value, th.cat(all_preds), th.cat(all_targets)\nclass Model_1(nn.Module):\n    def __init__(self, n_inputs: int, n_classes: int) -> None:\n        super().__init__()\n        self.layer_1 = nn.Linear(n_inputs, 10)\n        self.layer_2 = nn.Linear(10, n_classes)\n        self.relu = nn.ReLU()\n\n    def forward(self, X: th.Tensor) -> th.Tensor:\n        out = self.layer_1(X)\n        out = self.relu(out)\n        out = self.layer_2(out)\n        return out\nmodel = Model_1(X.shape[1], 4)\n\nloss_func = nn.MSELoss()\noptimizer = optim.Adam(model.parameters(), lr=0.001)\nepochs = 50\n\nmetric_dict = {\n    'R2':M.R2Score(num_outputs=4),\n}\n\nmodel_train = train_func(model=model,\n                                loader=train_loader,\n                                n_epochs=epochs,\n                                loss_func=loss_func,\n                                optimizer=optimizer,\n                                metric_dict=metric_dict,\n                                print_every=5,\n                                test_loader=test_loader,\n                               )\n ",
             2.20 : "data = pd.read_csv('datasets/regression/bike_cnt.csv')\n\nX = data.drop(columns='cnt', axis=1)\ny = data['cnt'].values\n\nscaler_y = StandardScaler()\ny = scaler_y.fit_transform(y.reshape(-1, 1))\ncategorical_cols = X.select_dtypes(include=['object', 'category']).columns\nX = pd.get_dummies(X, columns=categorical_cols, drop_first=True)\nX = X.astype({col: 'int64' for col in X.select_dtypes(include=['bool']).columns})\nnumerical_cols = X.select_dtypes(include=['int64', 'float64']).columns\n\nscaler = StandardScaler()\nX[numerical_cols] = scaler.fit_transform(X[numerical_cols])\n\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\nX_train = torch.tensor(X_train.values, dtype=torch.float32)\ny_train = torch.tensor(y_train, dtype=torch.float32).unsqueeze(1)\nX_test = torch.tensor(X_test.values, dtype=torch.float32)\ny_test = torch.tensor(y_test, dtype=torch.float32).unsqueeze(1)\n\nclass RegressionModel(nn.Module):\n    def __init__(self, input_size):\n        super().__init__()\n        self.fc = nn.Sequential(\n            nn.Linear(input_size, 128),\n            nn.ReLU(),\n            nn.Linear(128, 64),\n            nn.ReLU(),\n            nn.Linear(64, 32),\n            nn.ReLU(),\n            nn.Linear(32, 1)\n        )\n        \n    def forward(self, x):\n        return self.fc(x)\n    \ntrain_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)\ntest_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)\n\ndef train_model(model, train_loader, test_loader, num_epochs=100, lr=0.001):\n    criterion = nn.MSELoss()\n    optimizer = optim.Adam(model.parameters(), lr=lr)\n    \n    train_losses = []\n    test_r2_scores = []\n\n    for epoch in range(num_epochs):\n        model.train()\n        epoch_loss = 0\n        \n        for batch_X, batch_y in train_loader:\n            optimizer.zero_grad()\n            y_pred = model(X_train)\n            loss = criterion(y_pred, y_train)\n            loss.backward()\n            optimizer.step()\n            epoch_loss += loss.item()\n        \n        train_losses.append(epoch_loss/len(train_loader))\n        \n        model.eval()\n        y_test_pred = []\n        y_test_true = []\n        with torch.no_grad():\n            for batch_X, batch_y in test_loader:\n                preds = model(batch_X)\n                y_test_pred.append(preds)\n                y_test_true.append(batch_y)\n                \n        y_test_pred = th.cat(y_test_pred).numpy()\n        y_test_true = th.cat(y_test_true).numpy()\n\n        r2 = r2_score(y_test_true, y_test_pred)\n        test_r2_scores.append(r2)\n        \n        if (epoch + 1) % 10 == 0:\n            print(f'Epoch {epoch+1}/{num_epochs}, Loss: {loss.item():.4f}, R^2: {r2:.4f}')\n    \n    return train_losses, test_r2_scores\n\ninput_size = X_train.shape[1]\nmodel = RegressionModel(input_size)\ntrain_losses, test_r2_scores = train_model(model, train_loader, test_loader)\n\ndef evaluate_model(model, test_loader):\n    model.eval()\n    y_test_pred = []\n    y_test_true = []\n    with torch.no_grad():\n        for batch_X, batch_y in test_loader:\n            preds = model(batch_X)\n            y_test_pred.append(preds)\n            y_test_true.append(batch_y)\n\n    y_test_pred = torch.cat(y_test_pred).numpy()\n    y_test_true = torch.cat(y_test_true).numpy()\n\n    return r2_score(y_test_true, y_test_pred)\n\nr2_without_bn = evaluate_model(model, test_loader)\nprint(f'R^2 without BatchNorm: {r2_without_bn:.4f}') ",
             2.21 : "class RegressionModelBatchNorm(nn.Module):\n    def __init__(self, input_size):\n        super().__init__()\n        self.fc = nn.Sequential(\n            nn.Linear(input_size, 128),\n            nn.BatchNorm1d(128),\n            nn.ReLU(),\n            nn.Linear(128, 64),\n            nn.ReLU(),\n            nn.Linear(64, 32),\n            nn.BatchNorm1d(32),\n            nn.ReLU(),\n            nn.Linear(32, 1)\n        )\n        \n    def forward(self, x):\n        return self.fc(x)\nmodel_bn = RegressionModelBatchNorm(input_size)\ntrain_losses_bn, test_r2_scores_bn = train_model(model_bn, train_loader, test_loader)\nplt.figure(figsize=(10, 5))\nplt.plot(train_losses, label='Without BatchNorm')\nplt.plot(train_losses_bn, label='With BatchNorm')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\nplt.title('Training Loss')\nplt.show()\nplt.figure(figsize=(10, 5))\nplt.plot(test_r2_scores, label='Without BatchNorm')\nplt.plot(test_r2_scores_bn, label='With BatchNorm')\nplt.xlabel('Epochs')\nplt.ylabel('R^2')\nplt.legend()\nplt.title('Test R^2')\nplt.show()\nr2_with_bn = evaluate_model(model_bn, test_loader)\n\nprint(f'R^2 with BatchNorm: {r2_with_bn:.4f}') ",
             3.00 : "\nimport os\nimport zipfile\nimport torch\nfrom torch import nn, optim\nfrom torch.utils.data import DataLoader, random_split\nfrom torchvision import datasets, transforms\nfrom sklearn.metrics import classification_report, confusion_matrix\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport numpy as np\nfrom scipy.spatial.distance import cdist\n\nwith zipfile.ZipFile(\'datasets/images/sign_language.zip\', \'r\') as zip_ref:\n    zip_ref.extractall(\'images/\')\n\ndata_transforms = transforms.Compose([\n    transforms.Resize((64, 64)),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.5], std=[0.5])\n])\n\ndataset = datasets.ImageFolder(\'images/sign_language\', transform=data_transforms)\ntrain_size = int(0.8 * len(dataset))\ntest_size = len(dataset) - train_size\ntrain_dataset, test_dataset = random_split(dataset, [train_size, test_size])\n\ntrain_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)\ntest_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)\n\nclass SignLanguageCNN(nn.Module):\n    def __init__(self, num_classes):\n        super().__init__()\n        self.features = nn.Sequential(\n            nn.Conv2d(3, 32, kernel_size=3, padding=1),\n            nn.ReLU(),\n            nn.MaxPool2d(2),\n            nn.Conv2d(32, 64, kernel_size=3, padding=1),\n            nn.ReLU(),\n            nn.MaxPool2d(2),\n            nn.Conv2d(64, 128, kernel_size=3, padding=1),\n            nn.ReLU(),\n            nn.MaxPool2d(2)\n        )\n        self.classifier = nn.Sequential(\n            nn.Flatten(),\n            nn.Linear(128 * 8 * 8, 256),\n            nn.ReLU(),\n            nn.Linear(256, num_classes)\n        )\n\n    def forward(self, x):\n        x = self.features(x)\n        x = self.classifier(x)\n        return x\n\nnum_classes = len(dataset.classes)\nmodel = SignLanguageCNN(num_classes).to(\'cuda\' if torch.cuda.is_available() else \'cpu\')\n\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=0.001)\ndevice = \'cuda\' if torch.cuda.is_available() else \'cpu\'\n\ndef train_model(model, train_loader, test_loader, num_epochs=10):\n    model.to(device)\n    for epoch in range(num_epochs):\n        model.train()\n        running_loss = 0.0\n        for images, labels in train_loader:\n            images, labels = images.to(device), labels.to(device)\n            optimizer.zero_grad()\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n            loss.backward()\n            optimizer.step()\n            running_loss += loss.item()\n        \n        print(f'Epoch {epoch+1}/{num_epochs}, Loss: {running_loss/len(train_loader):.4f}')\n    return model\n\nmodel = train_model(model, train_loader, test_loader, num_epochs=10)\n\ndef evaluate_model(model, test_loader):\n    model.eval()\n    y_true = []\n    y_pred = []\n    with torch.no_grad():\n        for images, labels in test_loader:\n            images = images.to(device)\n            outputs = model(images)\n            _, preds = torch.max(outputs, 1)\n            y_true.extend(labels.cpu().numpy())\n            y_pred.extend(preds.cpu().numpy())\n    return y_true, y_pred\n\ny_true, y_pred = evaluate_model(model, test_loader)\n\ncm = confusion_matrix(y_true, y_pred)\nplt.figure(figsize=(10, 8))\nsns.heatmap(cm, annot=True, fmt=\'d\', cmap=\'Blues\')\nplt.xlabel(\'Predicted\')\nplt.ylabel(\'True\')\nplt.title(\'Confusion Matrix\')\nplt.show()\n\nprint(classification_report(y_true, y_pred, target_names=dataset.classes))\n'",
             3.01 : "'\nimport os\nimport zipfile\nimport torch\nfrom torch import nn, optim\nfrom torch.utils.data import DataLoader, random_split\nfrom torchvision import datasets, transforms\nfrom sklearn.metrics import classification_report, confusion_matrix\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport numpy as np\nfrom scipy.spatial.distance import cdist\n\ndata_transforms = transforms.Compose([\n    transforms.Resize((64, 64)),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.5], std=[0.5])\n])\n\ndataset = datasets.ImageFolder(\'images/sign_language\', transform=data_transforms)\ntrain_size = int(0.8 * len(dataset))\ntest_size = len(dataset) - train_size\ntrain_dataset, test_dataset = random_split(dataset, [train_size, test_size])\n\ntrain_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)\ntest_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)\n\nclass SignLanguageCNN(nn.Module):\n    def __init__(self, num_classes):\n        super().__init__()\n        self.features = nn.Sequential(\n            nn.Conv2d(3, 32, kernel_size=3, padding=1),\n            nn.ReLU(),\n            nn.MaxPool2d(2),\n            nn.Conv2d(32, 64, kernel_size=3, padding=1),\n            nn.ReLU(),\n            nn.MaxPool2d(2),\n            nn.Conv2d(64, 128, kernel_size=3, padding=1),\n            nn.ReLU(),\n            nn.MaxPool2d(2)\n        )\n        self.classifier = nn.Sequential(\n            nn.Flatten(),\n            nn.Linear(128 * 8 * 8, 256),\n            nn.ReLU(),\n            nn.Linear(256, num_classes)\n        )\n\n    def forward(self, x):\n        x = self.features(x)\n        x = self.classifier(x)\n        return x\n\nnum_classes = len(dataset.classes)\nmodel = SignLanguageCNN(num_classes).to(\'cuda\' if torch.cuda.is_available() else \'cpu\')\n\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=0.001)\ndevice = \'cuda\' if torch.cuda.is_available() else \'cpu\'\n\ndef train_model(model, train_loader, test_loader, num_epochs=10):\n    model.to(device)\n    for epoch in range(num_epochs):\n        model.train()\n        running_loss = 0.0\n        for images, labels in train_loader:\n            images, labels = images.to(device), labels.to(device)\n            optimizer.zero_grad()\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n            loss.backward()\n            optimizer.step()\n            running_loss += loss.item()\n        \n        print(f'Epoch {epoch+1}/{num_epochs}, Loss: {running_loss/len(train_loader):.4f}')\n    return model\n\nmodel = train_model(model, train_loader, test_loader, num_epochs=10)\n\ndef evaluate_model(model, test_loader):\n    model.eval()\n    y_true = []\n    y_pred = []\n    with torch.no_grad():\n        for images, labels in test_loader:\n            images = images.to(device)\n            outputs = model(images)\n            _, preds = torch.max(outputs, 1)\n            y_true.extend(labels.cpu().numpy())\n            y_pred.extend(preds.cpu().numpy())\n    return y_true, y_pred\n\ny_true, y_pred = evaluate_model(model, test_loader)\n\ncm = confusion_matrix(y_true, y_pred)\nplt.figure(figsize=(10, 8))\nsns.heatmap(cm, annot=True, fmt=\'d\', cmap=\'Blues\')\nplt.xlabel(\'Predicted\')\nplt.ylabel(\'True\')\nplt.title(\'Confusion Matrix\')\nplt.show()\n\nprint(classification_report(y_true, y_pred, target_names=dataset.classes))\n\nerrors = [(i, t, p) for i, (t, p) in enumerate(zip(y_true, y_pred)) if t != p]\nerror_idx, true_label, pred_label = errors[0]\nerror_image, _ = test_dataset[error_idx]\n\ndef get_hidden_representations(model, dataset):\n    model.eval()\n    hidden_vectors = []\n    images_list = []\n    with torch.no_grad():\n        for image, _ in dataset:\n            image = image.unsqueeze(0).to(device)\n            features = model.features(image)\n            features = features.view(features.size(0), -1)\n            hidden_vectors.append(features.cpu().numpy())\n            images_list.append(image.cpu().numpy())\n    return np.vstack(hidden_vectors), images_list\n\nhidden_vectors, images_list = get_hidden_representations(model, test_dataset)\n\nerror_vector = hidden_vectors[error_idx]\ndistances = cdist([error_vector], hidden_vectors, metric=\'cosine\').flatten()\nsimilar_indices = distances.argsort()[:5]\n\nplt.figure(figsize=(15, 5))\nplt.subplot(1, 6, 1)\nplt.title('Error Image')\nplt.imshow(error_image.permute(1, 2, 0).numpy() * 0.5 + 0.5)\nfor i, idx in enumerate(similar_indices):\n    plt.subplot(1, 6, i + 2)\n    plt.title(f'Similar {i + 1}')\n    plt.imshow(images_list[idx].squeeze().transpose(1, 2, 0) * 0.5 + 0.5)\nplt.show()\n\n\n",
             3.02 : "'\nimport os\nimport zipfile\nimport torch\nfrom torch import nn, optim\nfrom torch.utils.data import DataLoader, random_split\nfrom torchvision import datasets, transforms\nfrom sklearn.metrics import classification_report, confusion_matrix\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport numpy as np\nfrom scipy.spatial.distance import cdist\n\nwith zipfile.ZipFile(\'datasets/images/sign_language.zip\', \'r\') as zip_ref:\n    zip_ref.extractall(\'images/\')\n\ndata_dir = 'image/sign_language'\n\n# Предобработка изображений\ntransform = transforms.Compose([\n    transforms.Resize(100),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5))\n])\n\n# Загрузка данных\nfull_dataset = ImageFolder(data_dir, transform=transform)\n\ntrain_size = int(0.7 * len(full_dataset))\ntest_size = len(full_dataset) - train_size\ntrain_dataset, test_dataset = torch.utils.data.random_split(full_dataset, [train_size, test_size])\n\nclass CNN(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.conv1 = nn.Conv2d(3, 6, 5)\n        self.pool = nn.MaxPool2d(2, 2)\n        self.conv2 = nn.Conv2d(6, 16, 5)\n        self.fc1 = nn.Linear(16 * 22 * 22, 120)\n        self.fc2 = nn.Linear(120, 84)\n        self.fc3 = nn.Linear(84, 10)\n\n    def forward(self, x, return_features=False):\n        x = self.pool(F.relu(self.conv1(x)))\n        x = self.pool(F.relu(self.conv2(x)))\n        features = torch.flatten(x, 1)\n        x = F.relu(self.fc1(features))\n        x = F.relu(self.fc2(x))\n        x = self.fc3(x)\n        if return_features:\n            return x, features\n        return x\n\nbatch_size = 64\nnum_epochs = 5\nprint_every = 1\nnum_classes = len(full_dataset.classes)\n\nmodel = CNN()\ncriterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n\ntrain_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\ntest_loader = DataLoader(test_dataset, batch_size=batch_size)\n\nepoch_losses = []\n\nfor epoch in range(num_epochs):\n    model.train()\n    epoch_loss = 0\n\n    for i, data in enumerate(train_loader, 0):\n        inputs, labels = data\n\n        optimizer.zero_grad()\n        outputs = model(inputs)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n\n        epoch_loss += loss.item()\n\n    epoch_losses.append(epoch_loss / len(train_loader))\n\n    if (epoch + 1) % print_every == 0:\n        print(f'Epoch {epoch+1}/{num_epochs}, Loss: {epoch_loss / len(train_loader):.4f}')\n\nplt.figure(figsize=(10, 6))\nplt.plot(range(1, num_epochs + 1), epoch_losses, label='Training Loss')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.title('Training Loss Curve')\nplt.legend()\nplt.show()\n\nmodel.eval()\ncorrect = 0\ntotal = 0\nall_preds = []\nall_labels = []\n\nwith torch.no_grad():\n    for data in test_loader:\n        inputs, labels = data\n        outputs = model(inputs)\n        _, predicted = torch.max(outputs.data, 1)\n        total += labels.size(0)\n        correct += (predicted == labels).sum().item()\n\n        all_preds.extend(predicted.cpu().numpy())\n        all_labels.extend(labels.cpu().numpy())\n\nprint('\nClassification Report:')\nprint(classification_report(all_labels, all_preds, target_names=full_dataset.classes))\n\nconf_matrix = confusion_matrix(all_labels, all_preds)\nprint('\nConfusion Matrix:')\nprint(conf_matrix)\n\nplt.figure(figsize=(10, 8))\nsns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', xticklabels=full_dataset.classes, yticklabels=full_dataset.classes)\nplt.xlabel('Predicted Labels')\nplt.ylabel('True Labels')\nplt.title('Confusion Matrix')\nplt.show()\n\nembeddings = []\ntrue_labels = []\nwith torch.no_grad():\n    for inputs, labels in test_loader:\n        _, features = model(inputs, return_features=True)\n        embeddings.append(features)\n        true_labels.append(labels)\n\nembeddings = torch.cat(embeddings, dim=0).numpy()\ntrue_labels = torch.cat(true_labels, dim=0).numpy()\n\npca = PCA(n_components=2)\nembeddings_2d = pca.fit_transform(embeddings)\n\nplt.figure(figsize=(10, 8))\nscatter = plt.scatter(embeddings_2d[:, 0], embeddings_2d[:, 1], c=true_labels, cmap='tab10', alpha=0.6)\nplt.colorbar(scatter, ticks=range(num_classes), label='Class')\nplt.xlabel('PCA Component 1')\nplt.ylabel('PCA Component 2')\nplt.title('2D PCA Visualization of Hidden Representations')\nplt.show()\n'",
             3.03 : "\nimport torch as th\nimport torch.nn as nn\nimport torchmetrics as M\nfrom torch.utils.data import DataLoader, Dataset, TensorDataset, random_split\nfrom torch.nn.functional import cosine_similarity\nimport torchvision.transforms.v2 as T\nfrom torchvision.datasets import ImageFolder\n\nfrom sklearn.preprocessing import StandardScaler, OneHotEncoder, OrdinalEncoder\nfrom sklearn.compose import ColumnTransformer\nfrom sklearn.metrics import classification_report, confusion_matrix\n\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom tqdm.auto import tqdm\nfrom PIL import Image\nfrom zipfile import ZipFile\nimport gc\n\nimport warnings\nwarnings.filterwarnings('ignore')\n\nwith ZipFile('/content/sign_language.zip') as f:\n    f.extractall()\n\ndir = '/content/sign_language'\n\ntransforms = T.Compose([\n    T.Resize((224, 224)),\n    T.ToTensor(),\n])\n\ndataset = ImageFolder(dir, transform = transforms)\n\ntrain, test = random_split(dataset, [0.8, 0.2])\n\ntrain_loader = DataLoader(train, batch_size = 256)\n\nmean = 0.\nstd = 0.\nfor X_batch, y_batch in tqdm(train_loader):\n\n  mean += X_batch.mean(dim=(0, 2, 3))\n  std += X_batch.std(dim=(0, 2, 3))\n\nmean /= len(data)\nstd /= len(data)\n\nmean, std\n\ntransforms = T.Compose([\n    T.Resize((224, 224)),\n    T.ToTensor(),\n    T.Normalize(mean = mean, std = std)\n])\n\ndataset = ImageFolder(dir, transform = transforms)\ntrain, test = random_split(dataset, [0.8, 0.2])\ntrain_loader = DataLoader(train, batch_size = 64, shuffle = True)\ntest_loader = DataLoader(test, batch_size = 64, shuffle = True)\n\ndataset.classes\n\nfirst_model = nn.Sequential(\n    nn.Conv2d(3, 10, 3, padding = 1),\n    nn.ReLU(),\n    nn.MaxPool2d(2, 2),\n    nn.Conv2d(10, 10, 3, padding = 1),\n    nn.ReLU(),\n    nn.MaxPool2d(2, 2),\n    nn.Conv2d(10, 10, 3, padding = 1),\n    nn.ReLU(),\n    nn.MaxPool2d(2, 2),\n    nn.Conv2d(10, 10, 3, padding = 1),\n    nn.ReLU(),\n    nn.MaxPool2d(2, 2),\n    nn.Flatten(),\n    nn.Linear(1960, 64),\n    nn.ReLU(),\n    nn.Linear(64, 32),\n    nn.ReLU(),\n    nn.Linear(32, 10)\n)\n\nsecond_model = nn.Sequential(\n    nn.Conv2d(3, 10, 3, padding = 1),\n    nn.ReLU(),\n    nn.MaxPool2d(2, 2),\n    nn.Conv2d(10, 10, 3, padding = 1),\n    nn.ReLU(),\n    nn.MaxPool2d(2, 2),\n    # nn.Conv2d(10, 10, 3, padding = 1),\n    # nn.ReLU(),\n    # nn.MaxPool2d(2, 2),\n    # nn.Conv2d(10, 10, 3, padding = 1),\n    # nn.ReLU(),\n    # nn.MaxPool2d(2, 2),\n    nn.Flatten(),\n    nn.Linear(31360, 64),\n    nn.ReLU(),\n    nn.Linear(64, 32),\n    nn.ReLU(),\n    nn.Linear(32, 10)\n)\n\nthird_model = nn.Sequential(\n    nn.Conv2d(3, 10, 3, padding = 1),\n    nn.ReLU(),\n    nn.MaxPool2d(2, 2),\n    nn.Conv2d(10, 10, 3, padding = 1),\n    nn.ReLU(),\n    nn.MaxPool2d(2, 2),\n    nn.Conv2d(10, 10, 3, padding = 1),\n    nn.ReLU(),\n    nn.MaxPool2d(2, 2),\n    # nn.Conv2d(10, 10, 3, padding = 1),\n    # nn.ReLU(),\n    # nn.MaxPool2d(2, 2),\n    nn.Flatten(),\n    nn.Linear(7840, 64),\n    nn.ReLU(),\n    nn.Linear(64, 32),\n    nn.ReLU(),\n    nn.Linear(32, 10)\n)\n\ncriterion = nn.CrossEntropyLoss()\nmodel = first_model\noptimizer = th.optim.AdamW(model.parameters(), lr = 0.001)\nf1_scores_for_first_model = []\nfor epoch in range(5):\n    f1 = M.F1Score(num_classes = 10, task='multiclass', average = 'micro')\n    model.train()\n    for X_batch, y_batch in train_loader:\n        y_pred = model(X_batch)\n        loss = criterion(y_pred, y_batch)\n        loss.backward()\n        optimizer.step()\n        optimizer.zero_grad()\n    model.eval()\n    with th.no_grad():\n        for X_batch, y_batch in test_loader:\n            y_pred = model(X_batch)\n            y_pred = th.argmax(y_pred, dim = 1)\n            f1.update(y_pred, y_batch)\n    print(f1.compute())\n    f1_scores_for_first_model.append(f1.compute())\n\n\ncriterion = nn.CrossEntropyLoss()\nmodel = second_model\noptimizer = th.optim.AdamW(model.parameters(), lr = 0.001)\nf1_scores_for_second_model = []\nfor epoch in range(5):\n    f1 = M.F1Score(num_classes = 10, task='multiclass', average = 'micro')\n    model.train()\n    for X_batch, y_batch in train_loader:\n        y_pred = model(X_batch)\n        loss = criterion(y_pred, y_batch)\n        loss.backward()\n        optimizer.step()\n        optimizer.zero_grad()\n    model.eval()\n    with th.no_grad():\n        for X_batch, y_batch in test_loader:\n            y_pred = model(X_batch)\n            y_pred = th.argmax(y_pred, dim = 1)\n            f1.update(y_pred, y_batch)\n    print(f1.compute())\n    f1_scores_for_second_model.append(f1.compute())\n\n\n\ncriterion = nn.CrossEntropyLoss()\nmodel = third_model\noptimizer = th.optim.AdamW(model.parameters(), lr = 0.001)\nf1_scores_for_third_model = []\nfor epoch in range(5):\n    f1 = M.F1Score(num_classes = 10, task='multiclass', average = 'micro')\n    model.train()\n    for X_batch, y_batch in train_loader:\n        y_pred = model(X_batch)\n        loss = criterion(y_pred, y_batch)\n        loss.backward()\n        optimizer.step()\n        optimizer.zero_grad()\n    model.eval()\n    with th.no_grad():\n        for X_batch, y_batch in test_loader:\n            y_pred = model(X_batch)\n            y_pred = th.argmax(y_pred, dim = 1)\n            f1.update(y_pred, y_batch)\n    print(f1.compute())\n    f1_scores_for_third_model.append(f1.compute())\n\n\n\nplt.plot(f1_scores_for_first_model, label = '4 слоя свёртки')\nplt.plot(f1_scores_for_second_model, label = '2 слоя свёртки')\nplt.plot(f1_scores_for_third_model, label = '3 слоя свёртки')\nplt.legend()\nplt.ylabel('f1_micro')\nplt.xlabel('epochs')\n",
             3.10 : "'\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.data import DataLoader, random_split\nfrom torchvision import transforms, datasets\nfrom sklearn.metrics import f1_score\nimport numpy as np\nimport os\nimport glob\nfrom PIL import Image\nfrom zipfile import ZipFile\n\nwith ZipFile(\'/content/sign_language.zip\') as f:\n    f.extractall()\n\ndir = \'/content/sign_language\'\n\n# Transformation for the dataset\ntransform = transforms.Compose([\n    transforms.Resize((100, 100)),  # Resize images to 100x100\n    transforms.ToTensor(),          # Convert images to tensors\n    transforms.Normalize(mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5))  # Normalize\n])\n\n# Dataset\nclass MultiLabelDataset(Dataset):\n    def __init__(self, data_dir, transform):\n        self.image_paths = glob.glob(f'{data_dir}/*/*')\n        self.transform = transform\n        self.colors = sorted({p.split('/')[-2].split('_')[0] for p in self.image_paths})\n        self.items = sorted({p.split('/')[-2].split('_')[1] for p in self.image_paths})\n        self.color_to_idx = {c: i for i, c in enumerate(self.colors)}\n        self.item_to_idx = {i: j for j, i in enumerate(self.items)}\n\n    def __len__(self):\n        return len(self.image_paths)\n\n    def __getitem__(self, idx):\n        path = self.image_paths[idx]\n        color, item = path.split('/')[-2].split('_')\n        image = self.transform(Image.open(path).convert('RGB'))\n        return image, torch.tensor(self.color_to_idx[color]), torch.tensor(self.item_to_idx[item])\n\ndataset = MultiLabelDataset(data_dir, transform)\ntrain_size = int(0.7 * len(dataset))\ntrain_set, test_set = random_split(dataset, [train_size, len(dataset) - train_size])\ntrain_loader = DataLoader(train_set, batch_size=64, shuffle=True)\ntest_loader = DataLoader(test_set, batch_size=64)\n\nclass MultiLabelCNN(nn.Module):\n    def __init__(self, num_colors, num_items):\n        super().__init__()\n        self.conv1 = nn.Conv2d(3, 16, 3)\n        self.conv2 = nn.Conv2d(16, 32, 3)\n        self.pool = nn.MaxPool2d(2, 2)\n        self.fc1 = nn.Linear(32 * 23 * 23, 128)\n        self.fc_color = nn.Linear(128, num_colors)\n        self.fc_item = nn.Linear(128, num_items)\n\n    def forward(self, x):\n        x = self.pool(F.relu(self.conv1(x)))\n        x = self.pool(F.relu(self.conv2(x)))\n        x = torch.flatten(x, 1)\n        x = F.relu(self.fc1(x))\n        return self.fc_color(x), self.fc_item(x)\n\n\nmodel = MultiLabelCNN(len(dataset.colors), len(dataset.items))\ncriterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n\n# Training loop\nepochs = 5\nprint_every = 1\n\nfor epoch in range(epochs):\n    epoch_loss = 0\n    model.train()\n\n    for images, color_labels, item_labels in train_loader:\n        images, color_labels, item_labels = images, color_labels, item_labels\n\n        # Forward pass\n        color_output, item_output = model(images)\n\n        # Compute loss\n        loss_color = criterion(color_output, color_labels)\n        loss_item = criterion(item_output, item_labels)\n        loss = loss_color + loss_item\n\n        # Backward pass and optimization\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        epoch_loss += loss.item()\n\n    if (epoch + 1) % print_every == 0:\n        print(f'Epoch {epoch+1}/{epochs}, Loss: {epoch_loss:.4f}')\n\n\n# Evaluation\ndef evaluate(loader):\n    model.eval()\n    all_color_preds, all_item_preds, all_color_labels, all_item_labels = [], [], [], []\n    with torch.no_grad():\n        for images, color_labels, item_labels in loader:\n            images = images\n            color_output, item_output = model(images)\n            all_color_preds.extend(torch.argmax(color_output, 1).cpu().numpy())\n            all_item_preds.extend(torch.argmax(item_output, 1).cpu().numpy())\n            all_color_labels.extend(color_labels.numpy())\n            all_item_labels.extend(item_labels.numpy())\n    f1_color = f1_score(all_color_labels, all_color_preds, average='weighted')\n    f1_item = f1_score(all_item_labels, all_item_preds, average='weighted')\n    return f1_color, f1_item\n\nf1_train = evaluate(train_loader)\nf1_test = evaluate(test_loader)\nprint(f'Train F1 Scores - Color: {f1_train[0]:.4f}, Item: {f1_train[1]:.4f}')\nprint(f'Test F1 Scores - Color: {f1_test[0]:.4f}, Item: {f1_test[1]:.4f}')\n'",
             3.11 : "'\nzfile = zipfile.ZipFile(\'/content/drive/MyDrive/FIN/DL/Exam/Data/ImageClassification/clothes_multi.zip\')\nzfile.extractall(\'/content\')\n\nmean, std = 0., 0.\ndata = DataLoader(full_dataset, batch_size=256)\n\nfor X_batch, y_batch in tqdm(data):\n    mean += X_batch.mean(dim=(0, 2, 3))\n    std += X_batch.std(dim=(0, 2, 3))\n\nmean /= len(data)\nstd /= len(data)\n\nmean, std\n\ndata_dir = '/content/clothes_multi'\n\n# Предобработка изображений\ntransform = T.Compose([\n    T.Resize((56, 56)),\n    T.ToTensor(),\n    T.Normalize(mean=mean, std=std)\n\n])\n\n# Загрузка данных\nfull_dataset = ImageFolder(data_dir, transform=transform)\n\ntrain_size = int(0.7 * len(full_dataset))\ntest_size = len(full_dataset) - train_size\ntrain_dataset, test_dataset = th.utils.data.random_split(full_dataset, [train_size, test_size])\n\ntrain_loader = DataLoader(train_dataset, batch_size=16, pin_memory=True, num_workers=0)\nval_loader = DataLoader(test_dataset, batch_size=16, pin_memory=True, num_workers=0)\n\nclass Trainer():\n  def __init__(self, train_loader, val_loader, model, criterion, optimizer, metric, epochs):\n    self.train_loader = train_loader\n    self.val_loader = val_loader\n    self.model = model\n    self.criterion = criterion\n    self.optimizer = optimizer\n    self.metric = metric\n    self.epochs = epochs\n\n  def train(self):\n\n    for epoch in tqdm(range(self.epochs), desc=\'Epochs\'):\n\n      train_loss = M.MeanMetric()\n      train_metric = M.MeanMetric()\n\n      val_metric = M.MeanMetric()\n\n      for batch in tqdm(self.train_loader, desc=\'Trian\', leave=False):\n        X_batch, y_batch = batch\n\n        y_pred = self.model(X_batch.float())\n        loss = self.criterion(y_pred, y_batch)\n        metric = self.metric(y_pred.argmax(dim=1), y_batch)\n\n        train_loss.update(loss)\n        train_metric.update(metric)\n\n        loss.backward()\n        self.optimizer.step()\n        self.optimizer.zero_grad()\n\n      with th.no_grad():\n        for batch in tqdm(self.val_loader, desc=\'Trian\', leave=False):\n          X_batch, y_batch = batch\n\n          y_pred = self.model(X_batch)\n          val_metric.update(self.metric(y_pred.argmax(dim=1), y_batch))\n\n      print(f\'| Epoch [{epoch + 1}/{self.epochs}] | Train Loss: {train_loss.compute():.3f} | Train Metric: {train_metric.compute():.2f} | Val Metric: {val_metric.compute():.2f}\')\n\n      model = nn.Sequential(\n     nn.Conv2d(3, 16, kernel_size=(3, 3), stride=1, padding=1),\n     nn.ReLU(),\n     nn.MaxPool2d(kernel_size=2, stride=2),\n\n     nn.Conv2d(16, 32, kernel_size=(3, 3), stride=1, padding=1),\n     nn.ReLU(),\n     nn.MaxPool2d(kernel_size=2, stride=2),\n\n     nn.Flatten(),\n     nn.Linear(6272, 128),\n     nn.ReLU(),\n     nn.Linear(128, 32),\n     nn.ReLU(),\n     nn.Linear(32, 37),\n )\n\ntrainer = Trainer(\n  train_loader=train_loader,\n  val_loader=val_loader,\n  model=model,\n  criterion=nn.CrossEntropyLoss(),\n  optimizer=th.optim.Adam(model.parameters(), lr=0.001),\n  metric=M.F1Score(task=\'multiclass\', num_classes=37),\n  epochs=5\n)\n\ntrainer.train()\n\nimgs = []\nlabels = []\n\nfor img, label in val_loader:\n  imgs.append(img)\n  labels.append(label)\n\nimgs = th.cat(imgs)\nlabels = th.cat(labels)\n\ny_pred = model(imgs)\nprint(classification_report(y_pred.argmax(dim=1), labels))\n\nplt.figure(figsize=(15, 10))\nsns.heatmap(confusion_matrix(y_pred.argmax(dim=1), labels), annot=True, fmt=\'.0f\')\nplt.title(\'Confusion Matrix\')\nplt.show()\n\nemb_model = nn.Sequential(*list(model.children())[:-2])\nemb_model\n\nmiss_class = th.where(y_pred.argmax(dim=1) != labels)[0]\n\nmiss_imgs = []\nmiss_labels = []\n\nfor ind in tqdm(miss_class):\n  miss_imgs.append(test_dataset[ind][0].tolist())\n  miss_labels.append([test_dataset[ind][1], ])\n\nmiss_imgs = th.tensor(miss_imgs)\nmiss_labels = th.tensor(miss_labels)\n\nemb_miss_imgs = emb_model(miss_imgs)\nemb_imgs = emb_model(imgs)\n\nsim_ind = cosine_similarity(emb_miss_imgs[0], emb_imgs).argsort(descending=True)[1:5]\n\nplt.figure(figsize=(15, 10))\n\nplt.subplot(1, 5, 1)\nplt.imshow(miss_imgs[0].permute(1, 2, 0))\n\nfor ind, s_img in enumerate(imgs[sim_ind]):\n  plt.subplot(1, 5, ind+2)\n  plt.imshow(s_img.permute(1, 2, 0))\n\nplt.show()\n'",
             3.12 : "'\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.data import DataLoader, random_split\nfrom torchvision import transforms, datasets\nfrom sklearn.metrics import f1_score\nimport numpy as np\nimport os\nimport glob\nfrom PIL import Image\nfrom zipfile import ZipFile\n\nwith ZipFile(\'/content/sign_language.zip\') as f:\n    f.extractall()\n\ndir = \'/content/sign_language\'\n\n# Transformation for the dataset\ntransform = transforms.Compose([\n    transforms.Resize((100, 100)),  # Resize images to 100x100\n    transforms.ToTensor(),          # Convert images to tensors\n    transforms.Normalize(mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5))  # Normalize\n])\n\n# Dataset\nclass MultiLabelDataset(Dataset):\n    def __init__(self, data_dir, transform):\n        self.image_paths = glob.glob(f'{data_dir}/*/*')\n        self.transform = transform\n        self.colors = sorted({p.split('/')[-2].split('_')[0] for p in self.image_paths})\n        self.items = sorted({p.split('/')[-2].split('_')[1] for p in self.image_paths})\n        self.color_to_idx = {c: i for i, c in enumerate(self.colors)}\n        self.item_to_idx = {i: j for j, i in enumerate(self.items)}\n\n    def __len__(self):\n        return len(self.image_paths)\n\n    def __getitem__(self, idx):\n        path = self.image_paths[idx]\n        color, item = path.split('/')[-2].split('_')\n        image = self.transform(Image.open(path).convert('RGB'))\n        return image, torch.tensor(self.color_to_idx[color]), torch.tensor(self.item_to_idx[item])\n\ndataset = MultiLabelDataset(data_dir, transform)\ntrain_size = int(0.7 * len(dataset))\ntrain_set, test_set = random_split(dataset, [train_size, len(dataset) - train_size])\ntrain_loader = DataLoader(train_set, batch_size=64, shuffle=True)\ntest_loader = DataLoader(test_set, batch_size=64)\n\nclass MultiLabelCNN(nn.Module):\n    def __init__(self, num_colors, num_items):\n        super().__init__()\n        self.conv1 = nn.Conv2d(3, 16, 3)\n        self.conv2 = nn.Conv2d(16, 32, 3)\n        self.pool = nn.MaxPool2d(2, 2)\n        self.fc1 = nn.Linear(32 * 23 * 23, 128)\n        self.fc_color = nn.Linear(128, num_colors)\n        self.fc_item = nn.Linear(128, num_items)\n\n    def forward(self, x):\n        x = self.pool(F.relu(self.conv1(x)))\n        x = self.pool(F.relu(self.conv2(x)))\n        x = torch.flatten(x, 1)\n        x = F.relu(self.fc1(x))\n        return self.fc_color(x), self.fc_item(x)\n\n\nmodel = MultiLabelCNN(len(dataset.colors), len(dataset.items))\ncriterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n\n# Training loop\nepochs = 5\nprint_every = 1\n\nfor epoch in range(epochs):\n    epoch_loss = 0\n    model.train()\n\n    for images, color_labels, item_labels in train_loader:\n        images, color_labels, item_labels = images, color_labels, item_labels\n\n        # Forward pass\n        color_output, item_output = model(images)\n\n        # Compute loss\n        loss_color = criterion(color_output, color_labels)\n        loss_item = criterion(item_output, item_labels)\n        loss = loss_color + loss_item\n\n        # Backward pass and optimization\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        epoch_loss += loss.item()\n\n    if (epoch + 1) % print_every == 0:\n        print(f'Epoch {epoch+1}/{epochs}, Loss: {epoch_loss:.4f}')\n\n\n# Evaluation\ndef evaluate(loader):\n    model.eval()\n    all_color_preds, all_item_preds, all_color_labels, all_item_labels = [], [], [], []\n    with torch.no_grad():\n        for images, color_labels, item_labels in loader:\n            images = images\n            color_output, item_output = model(images)\n            all_color_preds.extend(torch.argmax(color_output, 1).cpu().numpy())\n            all_item_preds.extend(torch.argmax(item_output, 1).cpu().numpy())\n            all_color_labels.extend(color_labels.numpy())\n            all_item_labels.extend(item_labels.numpy())\n    f1_color = f1_score(all_color_labels, all_color_preds, average='weighted')\n    f1_item = f1_score(all_item_labels, all_item_preds, average='weighted')\n    return f1_color, f1_item\n\nf1_train = evaluate(train_loader)\nf1_test = evaluate(test_loader)\nprint(f'Train F1 Scores - Color: {f1_train[0]:.4f}, Item: {f1_train[1]:.4f}')\nprint(f'Test F1 Scores - Color: {f1_test[0]:.4f}, Item: {f1_test[1]:.4f}')\n'",
             3.20 : "'\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.data import DataLoader, random_split\nfrom torchvision import transforms, datasets\nfrom sklearn.metrics import f1_score\nimport numpy as np\nimport os\nimport glob\nfrom PIL import Image\nfrom zipfile import ZipFile\n\nwith ZipFile(\'/content/eng_handwritten.zip\') as f:\n    f.extractall()\n\ndir = \'/content/eng_handwritten\'\n\nimport time\n\nimage_size = 50\nbatch_size = 64\n\n# Data preprocessing and augmentation\ntransform = transforms.Compose([\n    transforms.Resize((64, 64)),\n    transforms.CenterCrop(image_size),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=(0.5,), std=(0.5,))\n])\n\n# Load dataset\ndata_dir = '/content/eng_handwritten/eng_handwritten'\ndataset = datasets.ImageFolder(root=data_dir, transform=transform)\n\n# Split dataset into train, validation, and test sets\ntrain_size = int(0.7 * len(dataset))\nval_size = int(0.15 * len(dataset))\ntest_size = len(dataset) - train_size - val_size\ntrain_dataset, val_dataset, test_dataset = random_split(dataset, [train_size, val_size, test_size])\n\n# Data loaders\ntrain_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\nval_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)\ntest_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)\n\nclass CNN(nn.Module):\n    def __init__(self, num_classes):\n        super(CNN, self).__init__()\n        self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)  # Fewer filters\n        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)\n        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)  # Pooling layer reduces dimensions\n        self.fc1 = nn.Linear(32 * (image_size // 4) * (image_size // 4), 64)  # Smaller fully connected layer\n        self.fc2 = nn.Linear(64, num_classes)\n\n    def forward(self, x):\n        x = self.pool(torch.relu(self.conv1(x)))\n        x = self.pool(torch.relu(self.conv2(x)))\n        x = torch.flatten(x, 1)\n        x = torch.relu(self.fc1(x))\n        x = self.fc2(x)\n        return x\n\nnum_classes = len(dataset.classes)\nmodel = CNN(num_classes)\n\nbatch_size = 64\nnum_epochs = 5\nlearning_rate = 0.01\npatience = 2\n\n# Loss and optimizer\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=learning_rate)\n\n# Training loop with early stopping\nbest_f1 = -1\npatience_counter = 0\n\nfor epoch in range(num_epochs):\n    model.train()\n    running_loss = 0.0\n    start_time = time.time()\n\n    # Train phase\n    for X_batch, y_batch in train_loader:\n        X_batch, y_batch = X_batch, y_batch\n\n        optimizer.zero_grad()\n        outputs = model(X_batch)\n        loss = criterion(outputs, y_batch)\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item()\n\n    # Validation phase\n    model.eval()\n    val_true = []\n    val_preds = []\n    with torch.no_grad():\n        for X_batch, y_batch in val_loader:\n            X_batch, y_batch = X_batch, y_batch\n            outputs = model(X_batch)\n            _, predicted = torch.max(outputs, 1)\n            val_true.extend(y_batch.cpu().numpy())\n            val_preds.extend(predicted.cpu().numpy())\n\n    # Calculate validation micro F1 score\n    micro_f1 = f1_score(val_true, val_preds, average=\'micro\')\n    print(f'Epoch {epoch + 1}, Loss: {running_loss / len(train_loader):.4f}, Val Micro F1: {micro_f1:.4f}')\n\n    # Early stopping\n    if micro_f1 > best_f1:\n        best_f1 = micro_f1\n        patience_counter = 0\n        torch.save(model.state_dict(), 'best_model.pth')\n    else:\n        patience_counter += 1\n\n    if patience_counter >= patience:\n        print(f'Early stopping triggered at epoch {epoch + 1}.')\n        break\n\n    print(f'Epoch {epoch + 1} completed in {time.time() - start_time:.2f}s.')\n\n\n# Load the best model\nmodel.load_state_dict(torch.load('best_model.pth'))\n\n# Test set evaluation\nmodel.eval()\ntest_preds, test_labels = [], []\nwith torch.no_grad():\n    for images, labels in test_loader:\n        outputs = model(images)\n        preds = torch.argmax(outputs, dim=1)\n        test_preds.extend(preds.cpu().numpy())\n        test_labels.extend(labels.cpu().numpy())\n\n# Calculate test micro F1\ntest_f1 = f1_score(test_labels, test_preds, average='micro')\nprint(f'Test Micro F1: {test_f1:.4f}')\n'",
             3.21 : "'\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.data import DataLoader, random_split\nfrom torchvision import transforms, datasets\nfrom sklearn.metrics import f1_score\nimport numpy as np\nimport os\nimport glob\nfrom PIL import Image\nfrom zipfile import ZipFile\n\nwith ZipFile(\'/content/eng_handwritten.zip\') as f:\n    f.extractall()\n\ndir = \'/content/eng_handwritten\'\n\nimport time\n\nimage_size = 50\nbatch_size = 64\n\n# Data preprocessing and augmentation\ntransform = transforms.Compose([\n    transforms.Resize((64, 64)),\n    transforms.CenterCrop(image_size),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=(0.5,), std=(0.5,))\n])\n\n# Load dataset\ndata_dir = '/content/eng_handwritten/eng_handwritten'\ndataset = datasets.ImageFolder(root=data_dir, transform=transform)\n\n# Split dataset into train, validation, and test sets\ntrain_size = int(0.7 * len(dataset))\nval_size = int(0.15 * len(dataset))\ntest_size = len(dataset) - train_size - val_size\ntrain_dataset, val_dataset, test_dataset = random_split(dataset, [train_size, val_size, test_size])\n\n# Data loaders\ntrain_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\nval_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)\ntest_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)\n\nclass CNN(nn.Module):\n    def __init__(self, num_classes):\n        super(CNN, self).__init__()\n        self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)  # Fewer filters\n        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)\n        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)  # Pooling layer reduces dimensions\n        self.fc1 = nn.Linear(32 * (image_size // 4) * (image_size // 4), 64)  # Smaller fully connected layer\n        self.fc2 = nn.Linear(64, num_classes)\n\n    def forward(self, x):\n        x = self.pool(torch.relu(self.conv1(x)))\n        x = self.pool(torch.relu(self.conv2(x)))\n        x = torch.flatten(x, 1)\n        x = torch.relu(self.fc1(x))\n        x = self.fc2(x)\n        return x\n\nnum_classes = len(dataset.classes)\nmodel = CNN(num_classes)\n\nbatch_size = 64\nnum_epochs = 5\nlearning_rate = 0.01\npatience = 2\n\n# Loss and optimizer\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=learning_rate)\n\n# Training loop with early stopping\nbest_f1 = -1\npatience_counter = 0\n\nfor epoch in range(num_epochs):\n    model.train()\n    running_loss = 0.0\n    start_time = time.time()\n\n    # Train phase\n    for X_batch, y_batch in train_loader:\n        X_batch, y_batch = X_batch, y_batch\n\n        optimizer.zero_grad()\n        outputs = model(X_batch)\n        loss = criterion(outputs, y_batch)\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item()\n\n    # Validation phase\n    model.eval()\n    val_true = []\n    val_preds = []\n    with torch.no_grad():\n        for X_batch, y_batch in val_loader:\n            X_batch, y_batch = X_batch, y_batch\n            outputs = model(X_batch)\n            _, predicted = torch.max(outputs, 1)\n            val_true.extend(y_batch.cpu().numpy())\n            val_preds.extend(predicted.cpu().numpy())\n\n    # Calculate validation micro F1 score\n    micro_f1 = f1_score(val_true, val_preds, average=\'micro\')\n    print(f'Epoch {epoch + 1}, Loss: {running_loss / len(train_loader):.4f}, Val Micro F1: {micro_f1:.4f}')\n\n    # Early stopping\n    if micro_f1 > best_f1:\n        best_f1 = micro_f1\n        patience_counter = 0\n        torch.save(model.state_dict(), 'best_model.pth')\n    else:\n        patience_counter += 1\n\n    if patience_counter >= patience:\n        print(f'Early stopping triggered at epoch {epoch + 1}.')\n        break\n\n    print(f'Epoch {epoch + 1} completed in {time.time() - start_time:.2f}s.')\n\n\n# Load the best model\nmodel.load_state_dict(torch.load('best_model.pth'))\n\n# Test set evaluation\nmodel.eval()\ntest_preds, test_labels = [], []\nwith torch.no_grad():\n    for images, labels in test_loader:\n        outputs = model(images)\n        preds = torch.argmax(outputs, dim=1)\n        test_preds.extend(preds.cpu().numpy())\n        test_labels.extend(labels.cpu().numpy())\n\n# Calculate test micro F1\ntest_f1 = f1_score(test_labels, test_preds, average='micro')\nprint(f'Test Micro F1: {test_f1:.4f}')\n'",
             3.30 : "'\nimport os\nimport zipfile\nimport torch\nfrom torch import nn, optim\nfrom torch.utils.data import DataLoader, random_split\nfrom torchvision import datasets, transforms\nfrom sklearn.metrics import f1_score\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport torchvision.utils\n\n\n\nwith zipfile.ZipFile(\'datasets/images/chars.zip\', \'r\') as zip_ref:\n    zip_ref.extractall(\'chars_data\')\n\nbasic_transforms = transforms.Compose([\n    transforms.Resize((64, 64)),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.5], std=[0.5])\n])\n\naugmentation_transforms = transforms.Compose([\n    transforms.Resize((64, 64)),\n    transforms.RandomHorizontalFlip(),\n    transforms.RandomRotation(15),\n    transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.5], std=[0.5])\n])\n\ndataset = datasets.ImageFolder(\'chars_data\', transform=basic_transforms)\ntrain_size = int(0.8 * len(dataset))\ntest_size = len(dataset) - train_size\ntrain_dataset, test_dataset = random_split(dataset, [train_size, test_size])\n\n\ntrain_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)\ntest_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)\n\nclass SimpleCNN(nn.Module):\n    def __init__(self, num_classes):\n        super(SimpleCNN, self).__init__()\n        self.features = nn.Sequential(\n            nn.Conv2d(3, 32, kernel_size=3, padding=1),\n            nn.ReLU(),\n            nn.MaxPool2d(2),\n            nn.Conv2d(32, 64, kernel_size=3, padding=1),\n            nn.ReLU(),\n            nn.MaxPool2d(2),\n        )\n        self.classifier = nn.Sequential(\n            nn.Flatten(),\n            nn.Linear(64 * 16 * 16, 128),\n            nn.ReLU(),\n            nn.Linear(128, num_classes)\n        )\n\n    def forward(self, x):\n        x = self.features(x)\n        x = self.classifier(x)\n        return x\n\ndef train_and_evaluate(train_loader, test_loader, num_classes, num_epochs=10, use_augmentation=False):\n    device = \'cuda\' if torch.cuda.is_available() else \'cpu\'\n    model = SimpleCNN(num_classes).to(device)\n    criterion = nn.CrossEntropyLoss()\n    optimizer = optim.Adam(model.parameters(), lr=0.001)\n    \n    # Обновление аугментаций, если требуется\n    if use_augmentation:\n        train_loader.dataset.dataset.transform = augmentation_transforms\n\n    # Тренировка\n    model.train()\n    for epoch in range(num_epochs):\n        for images, labels in train_loader:\n            images, labels = images.to(device), labels.to(device)\n            optimizer.zero_grad()\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n            loss.backward()\n            optimizer.step()\n\n    # Оценка\n    model.eval()\n    y_true, y_pred = [], []\n    with torch.no_grad():\n        for images, labels in test_loader:\n            images = images.to(device)\n            outputs = model(images)\n            _, preds = torch.max(outputs, 1)\n            y_true.extend(labels.cpu().numpy())\n            y_pred.extend(preds.cpu().numpy())\n    \n    f1 = f1_score(y_true, y_pred, average=\'micro\')\n    return f1\n\n\nnum_classes = len(dataset.classes)\n\nprint('Training without augmentation...')\nf1_no_augmentation = train_and_evaluate(train_loader, test_loader, num_classes)\nprint(f'F1 Score without augmentation: {f1_no_augmentation:.4f}')\n\nprint('Training with augmentation...')\nf1_with_augmentation = train_and_evaluate(train_loader, test_loader, num_classes, use_augmentation=True)\nprint(f'F1 Score with augmentation: {f1_with_augmentation:.4f}')\n\n\n# Функция для отображения изображений с метками классов\ndef show_images_with_labels(data_loader, class_names, title, num_images=8):\n    data_iter = iter(data_loader)\n    images, labels = next(data_iter)\n\n    # Отображаем первые `num_images` изображений\n    images = images[:num_images]\n    labels = labels[:num_images]\n\n    # Обратное преобразование нормализации для отображения\n    images = images * 0.5 + 0.5  # Denormalize: (image - mean) / std -> image * std + mean\n\n    grid_img = torchvision.utils.make_grid(images, nrow=num_images, padding=2)\n    plt.figure(figsize=(15, 5))\n    plt.imshow(grid_img.permute(1, 2, 0))\n    plt.title(title, fontsize=16)\n    plt.axis(\'off\')\n    for i in range(num_images):\n        plt.text(\n            x=(i * (grid_img.shape[2] // num_images) + 10),\n            y=(grid_img.shape[1] - 10),\n            s=class_names[labels[i].item()],\n            color=\'white\',\n            fontsize=10,\n            bbox=dict(facecolor=\'black\', alpha=0.5, boxstyle=\'round,pad=0.3\')\n        )\n    plt.show()\n\n# Вывод примеров изображений из обучающего и тестового множества\nprint('Displaying sample training images...')\nshow_images_with_labels(train_loader, dataset.classes, 'Training Samples')\n\nprint('Displaying sample test images...')\nshow_images_with_labels(test_loader, dataset.classes, 'Test Samples')\n\n# Функция для оценки модели (добавлена визуализация ошибок)\ndef evaluate_model_with_visuals(model, data_loader, class_names, criterion):\n    model.eval()\n    y_true, y_pred = [], []\n    total_loss = 0\n    error_images, error_labels, error_preds = [], [], []\n    with torch.no_grad():\n        for images, labels in data_loader:\n            images, labels = images.to(device), labels.to(device)\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n            total_loss += loss.item()\n\n            preds = outputs.argmax(dim=1)\n            y_true.extend(labels.cpu().numpy())\n            y_pred.extend(preds.cpu().numpy())\n\n            # Сохраняем ошибочные предсказания\n            errors = preds != labels\n            if errors.sum() > 0:\n                error_images.append(images[errors])\n                error_labels.append(labels[errors])\n                error_preds.append(preds[errors])\n\n    f1 = f1_score(y_true, y_pred, average='micro')\n\n    # Визуализация ошибок (показываем максимум 8)\n    if error_images:\n        error_images = torch.cat(error_images)[:8]\n        error_labels = torch.cat(error_labels)[:8]\n        error_preds = torch.cat(error_preds)[:8]\n\n        print('Displaying sample errors...')\n        show_images_with_labels(\n            [(img, label) for img, label in zip(error_images.cpu(), error_preds.cpu())],\n            class_names,\n            title='Sample Errors (Predictions Shown)'\n        )\n\n    return total_loss / len(data_loader), f1\n'",
             3.31 : "'\nimport os\nimport zipfile\nimport torch\nfrom torch import nn, optim\nfrom torch.utils.data import DataLoader, random_split\nfrom torchvision import datasets, transforms\nfrom sklearn.metrics import f1_score\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport torchvision.utils\n\n\n\nwith zipfile.ZipFile(\'datasets/images/chars.zip\', \'r\') as zip_ref:\n    zip_ref.extractall(\'chars_data\')\n\nbasic_transforms = transforms.Compose([\n    transforms.Resize((64, 64)),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.5], std=[0.5])\n])\n\naugmentation_transforms = transforms.Compose([\n    transforms.Resize((64, 64)),\n    transforms.RandomHorizontalFlip(),\n    transforms.RandomRotation(15),\n    transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.5], std=[0.5])\n])\n\ndataset = datasets.ImageFolder(\'chars_data\', transform=basic_transforms)\ntrain_size = int(0.8 * len(dataset))\ntest_size = len(dataset) - train_size\ntrain_dataset, test_dataset = random_split(dataset, [train_size, test_size])\n\n\ntrain_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)\ntest_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)\n\nclass SimpleCNN(nn.Module):\n    def __init__(self, num_classes):\n        super(SimpleCNN, self).__init__()\n        self.features = nn.Sequential(\n            nn.Conv2d(3, 32, kernel_size=3, padding=1),\n            nn.ReLU(),\n            nn.MaxPool2d(2),\n            nn.Conv2d(32, 64, kernel_size=3, padding=1),\n            nn.ReLU(),\n            nn.MaxPool2d(2),\n        )\n        self.classifier = nn.Sequential(\n            nn.Flatten(),\n            nn.Linear(64 * 16 * 16, 128),\n            nn.ReLU(),\n            nn.Linear(128, num_classes)\n        )\n\n    def forward(self, x):\n        x = self.features(x)\n        x = self.classifier(x)\n        return x\n\ndef train_and_evaluate(train_loader, test_loader, num_classes, num_epochs=10, use_augmentation=False):\n    device = \'cuda\' if torch.cuda.is_available() else \'cpu\'\n    model = SimpleCNN(num_classes).to(device)\n    criterion = nn.CrossEntropyLoss()\n    optimizer = optim.Adam(model.parameters(), lr=0.001)\n    \n    # Обновление аугментаций, если требуется\n    if use_augmentation:\n        train_loader.dataset.dataset.transform = augmentation_transforms\n\n    # Тренировка\n    model.train()\n    for epoch in range(num_epochs):\n        for images, labels in train_loader:\n            images, labels = images.to(device), labels.to(device)\n            optimizer.zero_grad()\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n            loss.backward()\n            optimizer.step()\n\n    # Оценка\n    model.eval()\n    y_true, y_pred = [], []\n    with torch.no_grad():\n        for images, labels in test_loader:\n            images = images.to(device)\n            outputs = model(images)\n            _, preds = torch.max(outputs, 1)\n            y_true.extend(labels.cpu().numpy())\n            y_pred.extend(preds.cpu().numpy())\n    \n    f1 = f1_score(y_true, y_pred, average=\'micro\')\n    return f1\n\n\nnum_classes = len(dataset.classes)\n\nprint('Training without augmentation...')\nf1_no_augmentation = train_and_evaluate(train_loader, test_loader, num_classes)\nprint(f'F1 Score without augmentation: {f1_no_augmentation:.4f}')\n\nprint('Training with augmentation...')\nf1_with_augmentation = train_and_evaluate(train_loader, test_loader, num_classes, use_augmentation=True)\nprint(f'F1 Score with augmentation: {f1_with_augmentation:.4f}')\n\n\n# Функция для отображения изображений с метками классов\ndef show_images_with_labels(data_loader, class_names, title, num_images=8):\n    data_iter = iter(data_loader)\n    images, labels = next(data_iter)\n\n    # Отображаем первые `num_images` изображений\n    images = images[:num_images]\n    labels = labels[:num_images]\n\n    # Обратное преобразование нормализации для отображения\n    images = images * 0.5 + 0.5  # Denormalize: (image - mean) / std -> image * std + mean\n\n    grid_img = torchvision.utils.make_grid(images, nrow=num_images, padding=2)\n    plt.figure(figsize=(15, 5))\n    plt.imshow(grid_img.permute(1, 2, 0))\n    plt.title(title, fontsize=16)\n    plt.axis(\'off\')\n    for i in range(num_images):\n        plt.text(\n            x=(i * (grid_img.shape[2] // num_images) + 10),\n            y=(grid_img.shape[1] - 10),\n            s=class_names[labels[i].item()],\n            color=\'white\',\n            fontsize=10,\n            bbox=dict(facecolor=\'black\', alpha=0.5, boxstyle=\'round,pad=0.3\')\n        )\n    plt.show()\n\n# Вывод примеров изображений из обучающего и тестового множества\nprint('Displaying sample training images...')\nshow_images_with_labels(train_loader, dataset.classes, 'Training Samples')\n\nprint('Displaying sample test images...')\nshow_images_with_labels(test_loader, dataset.classes, 'Test Samples')\n\n# Функция для оценки модели (добавлена визуализация ошибок)\ndef evaluate_model_with_visuals(model, data_loader, class_names, criterion):\n    model.eval()\n    y_true, y_pred = [], []\n    total_loss = 0\n    error_images, error_labels, error_preds = [], [], []\n    with torch.no_grad():\n        for images, labels in data_loader:\n            images, labels = images.to(device), labels.to(device)\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n            total_loss += loss.item()\n\n            preds = outputs.argmax(dim=1)\n            y_true.extend(labels.cpu().numpy())\n            y_pred.extend(preds.cpu().numpy())\n\n            # Сохраняем ошибочные предсказания\n            errors = preds != labels\n            if errors.sum() > 0:\n                error_images.append(images[errors])\n                error_labels.append(labels[errors])\n                error_preds.append(preds[errors])\n\n    f1 = f1_score(y_true, y_pred, average='micro')\n\n    # Визуализация ошибок (показываем максимум 8)\n    if error_images:\n        error_images = torch.cat(error_images)[:8]\n        error_labels = torch.cat(error_labels)[:8]\n        error_preds = torch.cat(error_preds)[:8]\n\n        print('Displaying sample errors...')\n        show_images_with_labels(\n            [(img, label) for img, label in zip(error_images.cpu(), error_preds.cpu())],\n            class_names,\n            title='Sample Errors (Predictions Shown)'\n        )\n\n    return total_loss / len(data_loader), f1\n'"}

themes = '''
2.00 Общая часть в датасете bank
2.01 Модифицируйте функцию потерь с учетом несбалансированности классов
2.02 Добавьте в модель слои dropout
2.03 Сравните несколько различных оптимизаторов и графически продемонстрируйте
2.10 Общая часть в датасете gold
2.11 Сравните несколько различных оптимизаторов и графически продемонстрируйте
2.20 Общая часть в датасете bike_cnt
2.21 Добавьте слои BatchNorm1d
3.00 Общая часть в датасете sign_language
3.01 Выберите один пример из тестового множества (zip-извлечение в общей части)
3.02 Уменьшите размерность
3.03 micro F1, качество от кол-ва сверт. блоков
3.10 Общая часть в датасете clothes_multi 
3.11 clothes_multi (версия 1 (трэш))
3.12 F1
3.20 Общая часть в датасете eng_handwritten
3.21 Логика ранней остановки + micro f1
3.30 Общая часть в датасете chars
3.31 F1
'''

api_keys = ['uQwjntCIJ9omN9z8jLTV1VOUvYlbaDIv',
            'tgPxn1rFujtuJe1H0j4PQTSjbLthvjyO',
            'Z0XHjxUHj6QXJblxACLxDhJoQAUreqt4',
            'iOSObqKAYAliBWRglH4gpZb7JN0KF91j',
            'E42w9TME0Ykm1WMsVwdzS6DxV9q2Xhgx',
            'uQmDdzM1nrw3cbmksP1BWhRnjOKGLWi1',
            'AhRiKjuHaXm4WccJ0BDI0NRBJ1X9RxSE',
            'mtddNQsqAMbL5GNHroRNRsSOwOr8vusH',
            'tpxt5xsU7jetD1x9u9r0IiKxqwajlTXO',
            'bSJCJVsREAKubT9AgGfgYL6pojIzoK11',
            'icjd6jfH7hmPxNMSEyD70UKg13kbtaB5',
            'Oxz67oTMVHw48CJhJZOKLkHw1eAlTwki',
            'zVrmIUh4z2wEjS1ze9XpJtfbGQTGognI',
            'ez9voi9pZb7CwPbqrglrTSL59GgUZFCX',
            'BQUqloQ3WynP4ySfHhTOxz44Diidniq1'
            ]

model = "mistral-large-latest"


dfs = {
    'corona': {
        'example': '''
            UserName\tScreenName\tLocation\tTweetAt\tOriginalTweet\tSentiment
5655\t50607\tOhio, USA\t17-03-2020\tGuess?, Inc. Provides COVID-19 Business Update - https://t.co/XvaNRd1Qxu ANGELES--(BUSINESS WIRE)--Guess?, Inc. (NYSE: GES) announced today that, after careful consideration for its customers, store associates and communities, it will temporarily close all of its retail stores... https://t.co/TiHPo6dkOl\tPositive
7718\t52670\tOlney, England\t18-03-2020\tSo much panic-bought food fresh food will never be eaten. Thrown out because past its best, and those that needed it never had a chance. #ThinkBeforeYouBuy #COVID2019\tPositive
32455\t77407\tlahore pakistan\t04-04-2020\tInstead of giving financial aid that is close to NOTHING. why don't you remove the taxes and cut down the prices of the utility goods? #COVID2019 #lockdown @ImranKhanPTI\tPositive
24302\t69254\tFlorida\t25-03-2020\tWAIT A DAMN MINUTE\r\r\n\r\r\nso Amazon workers tested positive for COVID-19 in 8 warehouses so far...\r\r\n\r\r\nthe virus has shown to survive on surfaces for 48-72 hours...\r\r\n\r\r\neveryone is shopping online now...\r\r\n\r\r\nAmazon Prime items arrive to customers in 48 hours...\r\r\n\r\r\ny'all seeing what I'M seeing?!? https://t.co/J0UyaopMEq\tPositive
30973\t75925\tStoneleigh Park, Warwickshire\t03-04-2020\tPig prices were up this week at 163 39p kg amp the supply chain is coping well with esp considering the shift in demand away from into supermarkets Other gd news is that ports are opening in China So let s keep a positive outlook as we Extremely Positive
        '''
    },
    'tweet_cat': {
        'example': '''
            text\ttype
@ACNI2012 @TheToka920 Never knew having 1 or 2 followers had anything to do with reality...Malinga has never been s… https://t.co/SSmLS18O4k\tsports
MYCA Magical Moments:\n\nSeptember, 2011: Sham Chotoo of the Bowie Boys and Girls Club joins Maryland Youth Cricket a… https://t.co/zpbqXvK21S\tsports
The current state of last year's @BBL finalists - \n@StarsBBL - P10 - W9 L1\n@RenegadesBBL - P10 - W1 L9 \n\n😲🙃😵😵😵 #Cricket #BBL09\tsports
@HOLLYJISOO Why did you bring a cricket...\tsports
Babar Azam only Pakistani included in the ICC ODI team of the year. If we had more test like other nations, Babar s… https://t.co/uRHi87uEsf\tsports
        '''
    },
    'activities': {
        'example': '''
            Text Review-Activity\tSeason
go to the beach, hiking and go on vacation\tACTIVITY\tSUMMER
Spending time with my grandkids in our pool.  Reading books in my swing under the Pecan tree.  Going on vacation to New Mexico to my sister's for two week.\tACTIVITY\tSUMMER
Painting  Traveling   Video game\tACTIVITY\tWINTER
Newer isn't always better: If you have ever played the earlier version of life please do yourself a favor and avoid this "new" version like the blak plague. My friends and I used to play the old version every single day up to late hours. Once we learned the new version was out we ran and bought it. WHAT A DISAPOINTMENT!!!! Compared to the old version this one is HORRIBLE. It isn't fun. The new rules [are not good]. You can not bet anymore. Money isn't the way it used to be (what's with the litte pieces of carton?) Maybe if someone at MB reads this they will go back to the basics and bring back what was once a great and fun family game to play. Lucky for us we still have, and play with, our old and much better version of Life.\tREVIEW\tNOT APPLICABLE
Worst of Disney: I just saw it tonight at a local dollar theater. It was awful, painful to sit through. And I actually like Adam Sandler in other movies such as Don't Mess with the Zohan.\tREVIEW\tNOT APPLICABLE
        '''
    },
    'tweets_disaster': {
        'example': '''
            id\tkeyword\tlocation\ttext\ttarget
0\tablaze\tNaN\tCommunal violence in Bhainsa, Telangana. "Stones were pelted on Muslims' houses and some houses and vehicles were set ablaze…\t1
1\tablaze\tNaN\tTelangana: Section 144 has been imposed in Bhainsa from January 13 to 15, after clash erupted between two groups on January 12. Po…\t1
2\tablaze\tNew York City\tArsonist sets cars ablaze at dealership https://t.co/gOQvyJbpVI\t1
3\tablaze\tMorgantown, WV\tArsonist sets cars ablaze at dealership https://t.co/0gL7NUCPlb https://t.co/u1CcBhOWh9\t1
4\tablaze\tNaN\t"Lord Jesus, your love brings freedom and pardon. Fill me with your Holy Spirit and set my heart ablaze with your l… https://t.co/VlTznnPNi8\t0
        '''
    },
    'news': {
        'example': '''
            Class Index\tTitle\tDescription
2\tIowa Expecting Capital One Invitation (AP)\tAP - Here's some advice from the Capital One Bowl for Iowa fans thinking about reserving flights to Orlando: Book them.
1\t106 mainland enterprises listed outside mainland market\tBy the end of August 2004, a total of 106 Chinese mainland enterprises had been listed on stockmarkets outside the mainland, an official from China Securities Regulatory Commission (CSRC) said here Friday.
4\tInternet crackdown leads to over 100 arrests\tIn what is being called the largest global crackdown ever conducted, the US Department of Justice #39;s  quot;Operation Web Snare quot; has led to over 100 arrests.
2\tWilliams vs Klitschko: When A Comet Crashes Into A Tower\t09.12.04 - By Janne Romppainen: Unlike many perhaps expected beforehand, in the year 2004 the heavyweight division has given the fans plenty of interesting fights.
4\tDell Gets \$700M Deal From Royal Philips\tDell Inc. said Thursday that it has won a \$700 million, 5-year contract to provide computers and services for Royal Philips Electronics.
        '''
    },
    'pos': {
        'example': '''
Пример 1:
{
  "sentence": "how long do you have to pay back debt after claiming chapter 11 bankruptcy",
  "tags": [
    "WH",
    "ADV",
    "AUX",
    "PART",
    "VERB",
    "TO",
    "VERB",
    "PART",
    "NOUN",
    "PREP",
    "VERB",
    "NOUN",
    "NUMB",
    "NOUN"
  ]
}

Пример 2:
{
  "sentence": "what shakespearean play featured shylock",
  "tags": [
    "WH",
    "ADJ",
    "NOUN",
    "VERB",
    "NOUN"
  ]
}

Пример 3:
{
  "sentence": "which magazine is fine entertainment for men",
  "tags": [
    "WH",
    "NOUN",
    "AUX",
    "ADJ",
    "NOUN",
    "PREP",
    "NOUN"
  ]
}

Пример 4:
{
  "sentence": "what features of the african elephant are larger than those of the indian elephant",
  "tags": [
    "WH",
    "VERB",
    "PREP",
    "DT",
    "ADJ",
    "NOUN",
    "AUX",
    "ADJ",
    "PREP",
    "DT",
    "PREP",
    "DT",
    "ADJ",
    "NOUN"
  ]
}

Пример 5:
{
  "sentence": "what ocean surrounds the maldive islands",
  "tags": [
    "WH",
    "NOUN",
    "VERB",
    "DT",
    "ADJ",
    "NOUN"
  ]
}
        '''
    },
    'quotes': {
        'example': '''
Пример 1:
{
  "Quote": "Don't cry because it's over, smile because it happened.",
  "Author": "Dr. Seuss",
  "Tags": [
    "attributed-no-source",
    "cry",
    "crying",
    "experience",
    "happiness",
    "joy",
    "life",
    "misattributed-dr-seuss",
    "optimism",
    "sadness",
    "smile",
    "smiling "
  ],
  "Popularity": 0.15566615566615566,
  "Category": "life"
}

Пример 2:
{
  "Quote": "Don't cry because it's over, smile because it happened.",
  "Author": "Dr. Seuss",
  "Tags": [
    "attributed-no-source",
    "cry",
    "crying",
    "experience",
    "happiness",
    "joy",
    "life",
    "misattributed-dr-seuss",
    "optimism",
    "sadness",
    "smile",
    "smiling "
  ],
  "Popularity": 0.15566615566615566,
  "Category": "happiness"
}

Пример 3:
{
  "Quote": "I'm selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can't handle me at my worst, then you sure as hell don't deserve me at my best.",
  "Author": "Marilyn Monroe",
  "Tags": [
    "attributed-no-source",
    "best",
    "life",
    "love",
    "mistakes",
    "out-of-control",
    "truth",
    "worst "
  ],
  "Popularity": 0.12912212912212911,
  "Category": "love"
}

Пример 4:
{
  "Quote": "I'm selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can't handle me at my worst, then you sure as hell don't deserve me at my best.",
  "Author": "Marilyn Monroe",
  "Tags": [
    "attributed-no-source",
    "best",
    "life",
    "love",
    "mistakes",
    "out-of-control",
    "truth",
    "worst "
  ],
  "Popularity": 0.12912212912212911,
  "Category": "life"
}

Пример 5:
{
  "Quote": "I'm selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can't handle me at my worst, then you sure as hell don't deserve me at my best.",
  "Author": "Marilyn Monroe",
  "Tags": [
    "attributed-no-source",
    "best",
    "life",
    "love",
    "mistakes",
    "out-of-control",
    "truth",
    "worst "
  ],
  "Popularity": 0.12912212912212911,
  "Category": "truth"
}
        '''
    },
    'sents': {
        'example': '''
jaccard.pt: Пример наполнения: tensor([0, 0, 0, 0, 0])
sents_pairs.pt: Пример наполнения: Тензор размерности 3: torch.Size([31125, 2, 50])
sents_pairs_npy.py: Пример наполнения: Массив размерности 3: (31125, 2, 50)
sents_pairs_itos.json: Пример наполнения:
Пример 1: "<PAD>"
Пример 2: "<UNK>"
Пример 3: "the"
Пример 4: "to"
Пример 5: "and"
        '''
    },
    'sents_pairs': {
        'example': '''
Тензор размерности 3: torch.Size([31125, 2, 50])
        '''
    },
    'sents_pairs_npy': {
        'example': '''
Массив размерности 3: (31125, 2, 50)
        '''
    },
    'sents_pairs_itos': {
        'example': '''
Пример 1: "<PAD>"
Пример 2: "<UNK>"
Пример 3: "the"
Пример 4: "to"
Пример 5: "and"
        '''
    }
}

def info():
    '''
    Добавляет в буфер обмена список тем, по которым потом обращаться при помощи функции get(n, m), где n - номер темы, m = 0 => теория, m = 1 => практика
    '''
    pyperclip.copy(themes)

class info_cl():
    '''
    Создает класс, в документации которого список тем, по которым потом обращаться при помощи функции get(n, m), где n - номер темы, m = 0 => теория, m = 1 => практика
    '''
    __doc__ = themes
    

def get(n):
    '''
    Добавляет в буфер обмена ответ по теме (n - номер темы)
    '''
    if 0 < n < len(questions) + 1:
        pyperclip.copy(questions[n])
    else:
        pyperclip.copy('Неправильный выбор номера темы')

class get_cl:
    '''
    Добавляет в документацию класса ответ по теме (n - номер темы)
    '''
    def __init__(self, n):
        self.n = n
        self.doc = questions[self.n]

    @property
    def __doc__(self):
        return self.doc  

def m_get(message, dataset: str = None, code=False):
    '''
    message: запрос, dataset: название вашего датасета (если не вводить, то запрос делается без указания датасета),
    code: если True, в ответе будет только код без комментариев и пояснений
    '''
    api_key = random.choice(api_keys)
    client = Mistral(api_key=api_key)
    
    if code:
        please = ' В ответе должен быть только код без комментариев и пояснений'
    else:
        please = ''
        
    if dataset:
        example = dfs[dataset]['example']
        try:
            chat_response = client.chat.complete(
                model=model,
                messages=[
                    {
                        "role": "user",
                        "content": message + example + please,
                    },
                ]
            )
            response_content = chat_response.choices[0].message.content
        except:
            response_content = 'Либо неправильное название датасета, либо ошибка на стороне мистраля'
    else:
        try:
            chat_response = client.chat.complete(
                model=model,
                messages=[
                    {
                        "role": "user",
                        "content": message + please,
                    },
                ]
            )
            response_content = chat_response.choices[0].message.content
        except:
            response_content = 'Ошибка на стороне мистраля'

    pyperclip.copy(response_content)


class m_get_cl:
    def __init__(self, message, dataset: str = None, code=False):
        '''
        message: запрос, dataset: название вашего датасета (если не вводить, то запрос делается без указания датасета),
        code: если True, в ответе будет только код без комментариев и пояснений
        '''
        api_key = random.choice(api_keys)
        client = Mistral(api_key=api_key)
        
        if code:
            please = ' В ответе должен быть только код без комментариев и пояснений'
        else:
            please = ''
            
        if dataset:
            example = dfs[dataset]['example']
            try:
                chat_response = client.chat.complete(
                    model=model,
                    messages=[
                        {
                            "role": "user",
                            "content": message + example + please,
                        },
                    ]
                )
                response_content = chat_response.choices[0].message.content
            except:
                response_content = 'Либо неправильное название датасета, либо ошибка на стороне мистраля'
        else:
            try:
                chat_response = client.chat.complete(
                    model=model,
                    messages=[
                        {
                            "role": "user",
                            "content": message + please,
                        },
                    ]
                )
                response_content = chat_response.choices[0].message.content
            except:
                response_content = 'Ошибка на стороне мистраля'

        self.answer = response_content

    @property
    def __doc__(self):
        return self.answer
