ответвлено от main/neurocomputers-python
1371 строка
50 KiB
Plaintext
1371 строка
50 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### ЛАБОРАТОРНАЯ РАБОТА №2\n",
|
||
"## МНОГОСЛОЙНЫЙ ПЕРСЕПТРОН"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"> Цель работы: изучение алгоритмов обучения многослойного персептрона, выбор структуры и контроль качества обучения нейронной сети, решение задачи\n",
|
||
"классификации многомерных данных.\n",
|
||
">\n",
|
||
"> Задание\n",
|
||
"> 1. Открыть хранящиеся в файле `min_water.csv` данные о сорока образцах минеральной воды. Проведя предварительный анализ данных, выделить из 23-х признаков наиболее информативные для классификации образцов признаки. Разделить имеющуюся выборку на три части: для обучения, для верификации, для тестирования. Сохранить исходные данные.\n",
|
||
"> 2. Создать многослойный персептрон с одним нейроном в выходном слое. Решить задачу классификации имеющихся данных об образцах минеральной воды по пяти классам, используя при обучении алгоритм обратного распространения ошибки. Проанализировать полученные результаты.\n",
|
||
"> 3. Создать многослойный персептрон с пятью нейронами в выходном слое и снова решить задачу классификации имеющихся данных об образцах минеральной воды по пяти классам. Проанализировать\n",
|
||
"полученные результаты. По результатам п.2 выбрать наилучшую структуру ИНС для решения поставленной задачи.\n",
|
||
"> 4. Решить задачу классификации образцов минеральной воды по четырем классам, предварительно пометив один из классов, как недоступный в процессе обучения. Проанализировать результаты классификации, предъявив обученной ИНС неизвестный сорт минеральной воды. Объяснить полученные результаты."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Импорт библиотек:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"executionInfo": {
|
||
"elapsed": 4,
|
||
"status": "ok",
|
||
"timestamp": 1768213447856,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "FwCw1KfEpbsm"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"import numpy as np\n",
|
||
"import pandas as pd\n",
|
||
"import seaborn as sns\n",
|
||
"import torch\n",
|
||
"import matplotlib.pyplot as plt\n",
|
||
"from IPython.display import clear_output\n",
|
||
"from sklearn.model_selection import train_test_split\n",
|
||
"\n",
|
||
"from torch import nn\n",
|
||
"\n",
|
||
"%matplotlib inline"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Pandas — это библиотека Python, представляющая собой «обёртку» над NumPy, специально разработанную для работы с табличными (структурированными) данными. Она предоставляет два ключевых типа данных: `Series` (одномерный массив с метками) и `DataFrame` (двумерная таблица с колонками разного типа). В отличие от «чистых» массивов NumPy, pandas позволяет: удобно индексировать данные по строкам и столбцам, обрабатывать пропуски (`NaN`), работать с разнородными типами данных в одной таблице, легко выполнять фильтрацию, группировку, агрегацию и слияния таблиц. При этом pandas сохраняет высокую производительность за счёт внутренней опоры на оптимизированные операции NumPy и C‑код.\n",
|
||
"\n",
|
||
"Официальная документация: https://pandas.pydata.org/docs/"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Содержание: \n",
|
||
"[1. Подготовка данных](#p_1) \n",
|
||
"[2. Задача бинарной классификации](#p_2) \n",
|
||
"[3. Задача многоклассовой классификации](#p_3) \n",
|
||
"[4. Задача многоклассовой классификации (с исключением одного из классов)](#p_4)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 1. Подготовка данных<a id=\"p_1\"></a>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Загрузим в датафрейм `data` данные о сорока образцах минеральной воды, хранящиеся в файле `min_water.txt`.\n",
|
||
"\n",
|
||
"Первый столбец содержит разметку для задачи бинарной классификации образцов воды (метки `0`и `1`), второй столбец — разметку для задачи многоглассовой классификации (каждому из 5 сортов минеральной воды соответствуют по 5 елассов их образцов). Оставшиеся 23 столбца рассматриваются как входные признаки."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/",
|
||
"height": 236
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 112,
|
||
"status": "ok",
|
||
"timestamp": 1768213447972,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "PkNWYbQCpsl_",
|
||
"outputId": "a19eff1c-593c-47b6-ed64-0aa6f84f56c2"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"data = pd.read_csv('min_water.csv')\n",
|
||
"data.head(n=5)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Вынесем в отдельные переменные:\n",
|
||
" - `y_binary` — выходной признак для задачи бинарной классификации (первый столбец датафрейма);\n",
|
||
" - `y_multiclass` — выходной признак для задачи многоклассовой классификации (второй столбец датафрейма);\n",
|
||
" - `X_data` — входные признаки (оставшиеся столбцы)."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"executionInfo": {
|
||
"elapsed": 17,
|
||
"status": "ok",
|
||
"timestamp": 1768213447974,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "D_QiYrPkpsu0"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"y_binary = data.iloc[:, 0]\n",
|
||
"y_multiclass = data.iloc[:, 1]\n",
|
||
"\n",
|
||
"X_data = data.iloc[:, 2:]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Нам необходимо отобрать из исходных 23 признаков наиболее информативные и полезные для задач бинарной и многоклассовой классификации.\n",
|
||
"\n",
|
||
"Вычислим матрицу парных коэффициентов корреляции Пирсона для всех признаков в `X_data`. Это позволит нам:\n",
|
||
"- выявить сильно коррелирующие признаки (|r| > 0,7–0,8), которые несут избыточную информацию;\n",
|
||
"- снизить риск переобучения за счёт удаления дублирующих признаков;\n",
|
||
"- упростить модель и ускорить обучение без потери качества;\n",
|
||
"- понять структуру данных и взаимосвязи между признаками;\n",
|
||
"- избежать проблем мультиколлинеарности в линейных моделях (когда коэффициенты становятся неустойчивыми из‑за сильной взаимной зависимости признаков)."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/",
|
||
"height": 820
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 27,
|
||
"status": "ok",
|
||
"timestamp": 1768213448004,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "-6Mo3AnWusFT",
|
||
"outputId": "92e51428-c6a4-4e18-eab6-96e3af0a4eee"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"X_data_correlation = X_data.corr(method='pearson')\n",
|
||
"X_data_correlation"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Для наглядности построим тепловую карту корреляционной матрицы. Отметим на карте только те пары признаков, у которых коэффициент корреляции Пирсона больше 0.75:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/",
|
||
"height": 456
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 369,
|
||
"status": "ok",
|
||
"timestamp": 1768213448385,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "usQSk41iuVuW",
|
||
"outputId": "143b4366-59ca-48c8-ff7a-10442a2f0d24"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"plt.figure(figsize=(10, 8))\n",
|
||
"sns.heatmap(X_data_correlation > 0.75)\n",
|
||
"plt.show()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Выпишите в список `features` отобранные в процессе анализа признаки (формат: `features = ['VAR1', 'VAR2']`):"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"features = # Ваш код здесь"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Датафрейм с отобранными входными признаками `X_data_filtered`:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"X_data_filtered = X_data.loc[:, features]\n",
|
||
"X_data_filtered.head(n=5)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Метрика accuracy (доля правильно классифицированных примеров от общего числа) будет общей и для задачи бинарной классификации, и для задачи многоклассовой классификации:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"executionInfo": {
|
||
"elapsed": 21,
|
||
"status": "ok",
|
||
"timestamp": 1768213448636,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "vcEZHV2G1fSQ"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"def accuracy(y_pred, y_true):\n",
|
||
" return torch.sum(y_pred == y_true) / len(y_true)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 2. Задача бинарной классификации<a id=\"p_2\"></a>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Изучите [документацию](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html) к функции `train_test_split`, чтобы разделить исходные данные на обучающую, валидационную и тестовую выборки — стандартный этап подготовки данных для обучения и оценки моделей машинного обучения.\n",
|
||
"\n",
|
||
"В первом её вызове отделите, например, 20% исходных данных (`X_data_filtered`, `y_binary`) в тестовую выборку (`X_binary_test`, `y_binary_test`), 80% оставьте для обучения (`X_binary_train`, `y_binary_train`). Через параметр `stratify` сохраните соотношение классов в обеих выборках.\n",
|
||
"\n",
|
||
"Во втором вызове отделите 20% данных для обучения в тестовую выборку (`X_binary_valid`, `y_binary_valid`), 80% оставьте для финального обучения (`X_binary_train`, `y_binary_train`). Не забудьте про параметр `stratify`.\n",
|
||
"\n",
|
||
"*Примечание*. Валидационная выборка помогает подбирать гиперпараметры (например, число эпох, скорость обучения) и следить за переобучением. Тестовая выборка «заморожена» до конца обучения и используется только для итоговой оценки, чтобы избежать смещения в оценке качества. Их соотношение с обучающей выборкой может быть и иным."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"X_binary_train, X_binary_test, y_binary_train, y_binary_test = # Ваш код здесь\n",
|
||
"\n",
|
||
"X_binary_train, X_binary_valid, y_binary_train, y_binary_valid = # Ваш код здесь"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Входные признаки для нейронной сети необходимо либо нормализовывать, либо стандартизировать — чтобы привести их к единому масштабу. Это ускоряет сходимость градиентного спуска и делает обучение стабильнее (спуск движется более прямо к минимуму, требует меньше итераций для сходимости, менее подвержен «взрыву» или «исчезновению» градиентов).\n",
|
||
"\n",
|
||
"Нормализация (Min‑Max Scaling) приводит значения признака к фиксированному диапазону (обычно `[0, 1]`):\n",
|
||
" \n",
|
||
"$$\n",
|
||
"x_{\\text{norm}} = \\frac{x - x_{\\min}}{x_{\\max} - x_{\\min}}\n",
|
||
"$$ \n",
|
||
"где: \n",
|
||
"- $x$ — исходное значение признака; \n",
|
||
"- $x_{\\min}$ — минимальное значение признака в выборке; \n",
|
||
"- $x_{\\max}$ — максимальное значение признака в выборке.\n",
|
||
"\n",
|
||
"\n",
|
||
"Стандартизация преобразует распределение признака к среднему `0` и стандартному отклонению `1`: \n",
|
||
"$$\n",
|
||
"x_{\\text{standard}} = \\frac{x - \\mu}{\\sigma}\n",
|
||
"$$ \n",
|
||
"где: \n",
|
||
"- $x$ — исходное значение признака; \n",
|
||
"- $\\mu$ — среднее значение признака в выборке; \n",
|
||
"- $\\sigma$ — стандартное отклонение признака в выборке."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Произведём стандартизацию входных признаков (но по аналогии можете произвести нормализацию):"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"X_means = X_binary_train.mean(axis=0)\n",
|
||
"X_stds = X_binary_train.std(axis=0, ddof=1)\n",
|
||
"\n",
|
||
"X_binary_train = # Ваш код здесь\n",
|
||
"X_binary_valid = # Ваш код здесь\n",
|
||
"X_binary_test = # Ваш код здесь"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"id": "rP2B8eJk2sYX"
|
||
},
|
||
"source": [
|
||
"Представим данные обучающей, валидационной и тестовой выборок в виде тензоров:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"executionInfo": {
|
||
"elapsed": 54,
|
||
"status": "ok",
|
||
"timestamp": 1768213448693,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "jsWiE7Ke1p9S"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"X_binary_train = torch.tensor(X_binary_train.values).float()\n",
|
||
"X_binary_valid = torch.tensor(X_binary_valid.values).float()\n",
|
||
"X_binary_test = torch.tensor(X_binary_test.values).float()\n",
|
||
"\n",
|
||
"y_binary_train = torch.tensor(y_binary_train.values).reshape(-1, 1).float()\n",
|
||
"y_binary_valid = torch.tensor(y_binary_valid.values).reshape(-1, 1).float()\n",
|
||
"y_binary_test = torch.tensor(y_binary_test.values).reshape(-1, 1).float()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Создайте экземпляр нейронной сети для решения задачи бинарной классификации — например, через `nn.Sequential()`, как было показано в первой лабораторной работе.\n",
|
||
"\n",
|
||
"Важно соблюсти два ключевых условия при проектировании архитектуры:\n",
|
||
"- число входных признаков в первом слое (`in_features`) должно точно соответствовать размерности признаков в обучающих данных (количеству столбцов в `X_binary_train`) (воспользуйтесь свойством `X_binary_train.shape`);\n",
|
||
"- в выходном слое необходимо использовать один нейрон с сигмоидальной функцией активации — напомним, что это гарантирует, что сеть будет выдавать значение в диапазоне [0, 1], интерпретируемое как вероятность принадлежности к положительному классу в задаче бинарной классификации."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"model_binary = nn.Sequential(\n",
|
||
" # Ваш код здесь\n",
|
||
")\n",
|
||
"\n",
|
||
"model_binary"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Удостоверимся, что наша сеть работает — рассчитаем по её выходу, который представляет собой предсказанные вероятности принадлежности к классу 1:\n",
|
||
" - значение функции потерь (бинарная кросс-энтропия);\n",
|
||
" - метрику accuracy."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/"
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 22,
|
||
"status": "ok",
|
||
"timestamp": 1768213448710,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "zP1t3NsT3xiH",
|
||
"outputId": "b722665a-ee83-4393-b45a-457076a3ac29"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"y_binary_train_prob = model_binary(X_binary_train)\n",
|
||
"\n",
|
||
"criterion = nn.BCELoss()\n",
|
||
"print(f'Loss: {criterion(y_binary_train_prob, y_binary_train).item():.6f}')\n",
|
||
"print(f'Accuracy: {accuracy((y_binary_train_prob > 0.5).float(), y_binary_train).item():.3f}')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/"
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 17,
|
||
"status": "ok",
|
||
"timestamp": 1768213448728,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "tfLMe06S5m4V",
|
||
"outputId": "281962d3-e691-439e-9b39-bd463c7ad8a8"
|
||
},
|
||
"source": [
|
||
"Теперь перейдём к обучению нейронной сети для решения поставленной задачи бинарной классификации.\n",
|
||
"\n",
|
||
"Зададим \n",
|
||
" - экземпляр нейронной сети;\n",
|
||
" - количество эпох или итераций в процессе обучения;\n",
|
||
" - скорость обучение и коэффициент импульса;\n",
|
||
" - оптимизатор;\n",
|
||
" - функцию потерь (поскольку решается задача бинарной классификации, выберем бинарную кросс-энтропию `nn.BCELoss()`).\n",
|
||
" \n",
|
||
" \n",
|
||
"*Примечание*. Вы можете использовать для обучения сети либо код ниже, либо модифицированный на его основе — например, реализовать функцию обучения нейронной сети и проверки её работы."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"executionInfo": {
|
||
"elapsed": 9,
|
||
"status": "ok",
|
||
"timestamp": 1768213448730,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "z-pABN4e6bAf"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Перебор seed для инициализации параметров\n",
|
||
"torch.manual_seed(seed=42)\n",
|
||
"\n",
|
||
"model_binary = # Ваш код здесь\n",
|
||
"\n",
|
||
"epochs = # Ваш код здесь\n",
|
||
"\n",
|
||
"learning_rate = # Ваш код здесь\n",
|
||
"momentum = # Ваш код здесь\n",
|
||
"\n",
|
||
"optimizer = # Ваш код здесь\n",
|
||
"criterion = nn.BCELoss()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"**Обучение нейронной сети для решения задачи бинарной классификации:**"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/",
|
||
"height": 504
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 22752,
|
||
"status": "ok",
|
||
"timestamp": 1768213471478,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "qKimvoStsZXv",
|
||
"outputId": "e903f88f-542f-4ab7-c291-2be72f726d39"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"loss_train_history, loss_valid_history = [], []\n",
|
||
"\n",
|
||
"for epoch in range(epochs):\n",
|
||
" model_binary.train()\n",
|
||
"\n",
|
||
" optimizer.zero_grad()\n",
|
||
"\n",
|
||
" y_binary_train_prob = model_binary(X_binary_train)\n",
|
||
"\n",
|
||
" loss_train = criterion(y_binary_train_prob, y_binary_train)\n",
|
||
" loss_train_history.append(loss_train.item())\n",
|
||
"\n",
|
||
" loss_train.backward()\n",
|
||
"\n",
|
||
" optimizer.step()\n",
|
||
"\n",
|
||
" model_binary.eval()\n",
|
||
" \n",
|
||
" # Отключаем градиенты для этапа валидации\n",
|
||
" with torch.no_grad():\n",
|
||
" y_binary_valid_prob = model_binary(X_binary_valid) \n",
|
||
" loss_valid = criterion(y_binary_valid_prob, y_binary_valid)\n",
|
||
" \n",
|
||
" loss_valid_history.append(loss_valid.item())\n",
|
||
"\n",
|
||
" if (epoch + 1) % 5 == 0:\n",
|
||
"\n",
|
||
" clear_output(True)\n",
|
||
" plt.plot(range(1, epoch+2), loss_train_history, label='Train', color='green')\n",
|
||
" plt.plot(range(1, epoch+2), loss_valid_history, label='Valid', color='red')\n",
|
||
" plt.title(f'Epoch: {epoch + 1}, Loss Train: {loss_train_history[-1]:.6f}, Loss Valid: {loss_valid_history[-1]:.6f}')\n",
|
||
" plt.grid(True, alpha=0.3)\n",
|
||
" plt.legend(loc='best')\n",
|
||
" plt.show()\n",
|
||
" \n",
|
||
" print('Accuracy')\n",
|
||
" print(f'Train: {accuracy((y_binary_train_prob > 0.5).float(), y_binary_train).item():.3f}')\n",
|
||
" print(f'Valid: {accuracy((y_binary_valid_prob > 0.5).float(), y_binary_valid).item():.3f}')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"После того, как вы подобрали параметры и добились приемлемого качества работы сети на обучающей и валидационной выборках, в качестве финального шага проверьте работу сети на отложенной тестовой выборке:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/"
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 35,
|
||
"status": "ok",
|
||
"timestamp": 1768213471518,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "V__6qHAe-7VS",
|
||
"outputId": "61ab4f43-fc4d-4a07-d1a9-921f91a2d0fc"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"with torch.no_grad():\n",
|
||
" y_binary_test_prob = model_binary(X_binary_test)\n",
|
||
" loss_test = criterion(y_binary_test_prob, y_binary_test)\n",
|
||
" \n",
|
||
"print(f'Loss Test: {loss_test.item():.6f}')\n",
|
||
"print(f'Accuracy Test: {accuracy((y_binary_valid_prob > 0.5).float(), y_binary_valid).item():.3f}')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"executionInfo": {
|
||
"elapsed": 30,
|
||
"status": "ok",
|
||
"timestamp": 1768213471544,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "ZtJ4WeKCATqU"
|
||
},
|
||
"source": [
|
||
"Если качество схожее, нейронная сеть не переобучена.\n",
|
||
"\n",
|
||
"Поэкспериметируйте — сделайте несколько вариантов с разными архитектурами сети, оптимизаторами, значениями скорости обучения и коэффициента импульса. Выберите лучшие по качеству обучения и количеству эпох."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 3. Задача многоклассовой классификации<a id=\"p_3\"></a>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Для решения задачи многоклассовой классификации по аналогии с задачей бинарной классификации:\n",
|
||
" - с помощью функции `train_test_split` разбейте данные (`X_data_filtered`, `y_multiclass`) на обучающую (`X_multiclass_train`, `y_multiclass_train`), валидационную (`X_multiclass_valid`, `y_multiclass_valid`) и тестовую выборки (`X_multiclass_test`, `y_multiclass_test`) с сохранением соотншений классов (сортов минеральной воды);\n",
|
||
" - стандартизируйте или нормализуйте входные признаки;\n",
|
||
" - из векторов с выходным признаком вычтите единицу и представьте их в виде тензоров целочисленного формата (метод `.long()`)."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"X_multiclass_train, X_multiclass_test, y_multiclass_train, y_multiclass_test = # Ваш код здесь\n",
|
||
"\n",
|
||
"X_multiclass_train, X_multiclass_valid, y_multiclass_train, y_multiclass_valid = # Ваш код здесь"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Ваш код здесь"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/"
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 25,
|
||
"status": "ok",
|
||
"timestamp": 1768213471611,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "CsGt0n6-B5WA",
|
||
"outputId": "c555da32-2652-48a2-8954-21b76ffaa019"
|
||
},
|
||
"source": [
|
||
"Для задач многоклассовой классификации в машинном обучении применяют функцию активации `softmax`, которая посредством нормализации преобразует вектор логитов (выходов последнего слоя) в распределение вероятностей: \n",
|
||
" $$\n",
|
||
" p_k = \\frac{e^{z_k}}{\\sum_{k=1}^{K} e^{z_k}},\n",
|
||
" $$ \n",
|
||
" где $z_k$ — выход для $k$-го класса, $K$ — число классов. \n",
|
||
" - Свойства: \n",
|
||
" - все выходы ∈ [0, 1]; \n",
|
||
" - сумма выходов = 1; \n",
|
||
" - максимальный выход соответствует наиболее вероятному классу.\n",
|
||
"\n",
|
||
"Реализованная в PyTorch функция потерь `nn.CrossEntropyLoss()` объединяет в себе `log_softmax` (численно устойчивая версия softmax + логарифм) и `NLLLoss` (отрицательная логарифмическая правдоподобность). Она принимает на вход именно логиты.\n",
|
||
"\n",
|
||
"Создадим экземпляр нейронной сети для решения задачи многоклассовой классификации — например, также через `nn.Sequential()`:\n",
|
||
" - число входных признаков в первом слое (`in_features`) должно точно соответствовать размерности признаков в обучающих данных (количеству столбцов в `X_binary_train`) (воспользуйтесь свойством `X_binary_train.shape`);\n",
|
||
" - количество нейроной в выходном слое должно совпадать с количеством классов;\n",
|
||
" - в связи с тем, что сеть нам должна выдавать логиты, функцию активации на выходном слое можно не использовать (хотя можно взять `nn.ReLU()`)."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/"
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 9,
|
||
"status": "ok",
|
||
"timestamp": 1768213471622,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "l2wN73_-BlzP",
|
||
"outputId": "b630d430-2215-41f3-9a62-93db01a5207a"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"model_multiclass = nn.Sequential(\n",
|
||
" nn.Linear(in_features=X_multiclass_train.shape[1], out_features=y_multiclass.nunique()),\n",
|
||
" nn.ReLU()\n",
|
||
")\n",
|
||
"\n",
|
||
"model_multiclass"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Пропустив данные через эту сеть, получим логиты, представляющие собою вектора, чья длина равна количеству классов:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/"
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 21,
|
||
"status": "ok",
|
||
"timestamp": 1768213471644,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "4BTXxrftCJzK",
|
||
"outputId": "e3568629-6f98-4b92-ef3b-92c607a92f9b"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"y_multiclass_train_logits = model_multiclass(X_multiclass_train)\n",
|
||
"y_multiclass_train_logits[:3]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Проверим работу функции потерь с ними:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/"
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 15,
|
||
"status": "ok",
|
||
"timestamp": 1768213471707,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "4ZQizLNZAT8_",
|
||
"outputId": "113bf8b1-8c80-4a82-d09a-7db97eb2222f"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"criterion = nn.CrossEntropyLoss()\n",
|
||
"criterion(y_multiclass_train_logits, y_multiclass_train)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Отметим, что для задачи классификации нормализация через `softmax` не требуется — в качестве ответа (метки класса) берем индекс максимального элемента в логите:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/"
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 8,
|
||
"status": "ok",
|
||
"timestamp": 1768213471654,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "RBufWh2CDW1P",
|
||
"outputId": "7c14a8d4-9306-429f-b870-50337e29ccaa"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"y_multiclass_train_logits.argmax(dim=1)[:3]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Метрика accuracy:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/"
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 48,
|
||
"status": "ok",
|
||
"timestamp": 1768213471704,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "Cz58yMsGDYmx",
|
||
"outputId": "8c93fa6f-09d5-43b6-dadf-67022c236dc5"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"accuracy(y_multiclass_train_logits.argmax(dim=1), y_multiclass_train).item()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"По аналогии с задачей бинарной классификации создайте, обучите и проверьте нейронную сеть для решения задачи многоклассовой классификации:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"executionInfo": {
|
||
"elapsed": 6,
|
||
"status": "ok",
|
||
"timestamp": 1768213471720,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "V1CgE0O7Lz0g"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Ваш код здесь"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"id": "3lHwSPaz35VQ"
|
||
},
|
||
"source": [
|
||
"Поэкспериметируйте — сделайте несколько вариантов с разными архитектурами сети, оптимизаторами, значениями скорости обучения и коэффициента импульса. Выберите лучшие по качеству обучения и количеству эпох."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"id": "1RTQgj4gLz5O"
|
||
},
|
||
"source": [
|
||
"## 4. Задача многоклассовой классификации (с исключением одного из классов)<a id=\"p_4\"></a>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Введите метку класса, который хотите исключить (1, 2, 3, 4 или 5):"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"label_to_exclude = # Ваш код здесь"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Маска (логическое условие) исключения в выходном признаке меток с этим классом:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/",
|
||
"height": 1000
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 83,
|
||
"status": "ok",
|
||
"timestamp": 1768217647959,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "Ge_M2-suvOfq",
|
||
"outputId": "7562cae1-5c7c-4ee8-c013-6428ec959db6"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"mask_to_exclude = y_multiclass != label_to_exclude\n",
|
||
"y_multiclass[mask_to_exclude]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"id": "3jVGVtJGw3Du"
|
||
},
|
||
"source": [
|
||
"Значения входных признаков, которые соответствуют исключённому классу (`X_data_exclude`):"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/",
|
||
"height": 300
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 139,
|
||
"status": "ok",
|
||
"timestamp": 1768217650943,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "i1AGN9v0w3eC",
|
||
"outputId": "9c78af34-6e8d-4b3d-f535-51d00ac100a6"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"X_data_exclude = X_data_filtered.loc[~mask_to_exclude, :]\n",
|
||
"X_data_exclude"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Значения входных признаков, которые соответствуют оставленным классам (`X_data_include`):"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/",
|
||
"height": 1000
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 109,
|
||
"status": "ok",
|
||
"timestamp": 1768217652781,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "81fKKw_xvyfc",
|
||
"outputId": "c31b50ed-6c3b-4362-d8c4-65dde73b5615"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"X_data_include = X_data_filtered.loc[mask_to_exclude, :]\n",
|
||
"X_data_include"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Для корректной работы с нейронной сетью модифицируем выходной признак с метками оставленных классов — значения меток выше исключённого класса уменьшим на единицу, чтобы выровнять их порядок (в дальнейшем вернём исходные). Результатом будет вектор `y_include`:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/",
|
||
"height": 1000
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 15,
|
||
"status": "ok",
|
||
"timestamp": 1768217655753,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "YeSoZPu1vakq",
|
||
"outputId": "4d1b5c42-161c-4b41-8441-d4f77f16c68c"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"y_include = y_multiclass[mask_to_exclude].apply(lambda y: y - 1 if y >= label_to_exclude else y)\n",
|
||
"y_include"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"executionInfo": {
|
||
"elapsed": 39,
|
||
"status": "ok",
|
||
"timestamp": 1768217660798,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "uvneeNEq2gkW"
|
||
},
|
||
"source": [
|
||
"По аналогии с задачами выше:\n",
|
||
" - с помощью функции `train_test_split` разбейте данные (`X_data_include`, `y_include`) на обучающую (`X_include_train`, `y_include_train`), валидационную (`X_include_valid`, `y_include_valid`) и тестовую выборки (`X_include_test`, `y_include_test`) с сохранением соотншений классов (сортов минеральной воды);\n",
|
||
" - стандартизируйте или нормализуйте входные признаки и представьте их в виде тензоров;\n",
|
||
" - из векторов с выходным признаком вычтите единицу и представьте их в виде тензоров целочисленного формата (метод `.long()`)."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"id": "vXnQuhb7vaoL"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Ваш код здесь"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"id": "LdbLhuA0vasw"
|
||
},
|
||
"source": [
|
||
"По аналогии с задаче многоклассовой классификации создайте нейронную сеть для этих данных:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"model_include = nn.Sequential(\n",
|
||
" # Ваш код здесь\n",
|
||
")\n",
|
||
"\n",
|
||
"model_include"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"id": "BjsyXLHgva1X"
|
||
},
|
||
"source": [
|
||
"Получим логиты (длина векторов уменьшилась до 4):"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/"
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 44,
|
||
"status": "ok",
|
||
"timestamp": 1768217668726,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "HIsQ_5MR3Jal",
|
||
"outputId": "74349107-0245-4696-eb9d-36f5e50ceaec"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"y_include_train_logits = model_include(X_include_train)\n",
|
||
"y_include_train_logits[:3]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Проверим работу функцию потерь на этих логитах и модимцированном выходном признаке:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/"
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 51,
|
||
"status": "ok",
|
||
"timestamp": 1768217670810,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "2XQimt7T3Xcc",
|
||
"outputId": "1bf129bc-aed1-433e-8083-2cea475f86ee"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"criterion = nn.CrossEntropyLoss()\n",
|
||
"criterion(y_include_train_logits, y_include_train)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"id": "qu9a65IQva5f"
|
||
},
|
||
"source": [
|
||
"По аналогии с задачей многоклассовой классификации с полным количеством классов создайте, обучите и проверьте нейронную сеть:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"id": "8wQa5g4Bva-I"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Ваш код здесь"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"id": "l4l-aUPz37ju"
|
||
},
|
||
"source": [
|
||
"Поэкспериметируйте — сделайте несколько вариантов с разными архитектурами сети, оптимизаторами, значениями скорости обучения и коэффициента импульса. Выберите лучшие по качеству обучения и количеству эпох."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"executionInfo": {
|
||
"elapsed": 9,
|
||
"status": "ok",
|
||
"timestamp": 1768217700545,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "k4sqBf5q41AC"
|
||
},
|
||
"source": [
|
||
"Значения входных признаков, которые соответствуют исключённому классу (`X_data_exclude`) так же, как и значения входных признаков из выборок выше, стандартизируйте или нормализируйте и представьте их в виде тензоров: "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"X_data_exclude = # Ваш код здесь"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Пропустим обработанные признаки через обученную и проверенную нейронную сеть `model_include`, чтобы получить логиты.\n",
|
||
"\n",
|
||
"По данным логитам произведём классификацию (с учётом метки исключённого класса), чтобы ответить на вопрос — к каким сортам минеральной воды из оставленных соответствуют образцы исключённого класса:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {
|
||
"colab": {
|
||
"base_uri": "https://localhost:8080/"
|
||
},
|
||
"executionInfo": {
|
||
"elapsed": 14,
|
||
"status": "ok",
|
||
"timestamp": 1768217702125,
|
||
"user": {
|
||
"displayName": "V N",
|
||
"userId": "10751591882973173608"
|
||
},
|
||
"user_tz": -180
|
||
},
|
||
"id": "4bflOWXX5YqN",
|
||
"outputId": "5bea95d9-0e02-455e-9163-8f14ce3664c3"
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"y_exclude_logits = model_include(X_data_exclude)\n",
|
||
"\n",
|
||
"(y_exclude_logits.argmax(dim=1) + 1).apply_(lambda y: y + 1 if y >= label_to_exclude else y)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Проделайте данный пункт, исключив каждый из пяти сортов. Результатом должны стать пять тензоров с восемью метками классов. Проанализируйте результаты."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Литература:\n",
|
||
"1. Бородкин А.А., Елисеев В.Л. Основы и применение искусственных нейронных сетей. Сборник лабораторных работ: методическое пособие. – М.: Издательский дом МЭИ, 2017.\n",
|
||
"2. MachineLearning.ru — профессиональный информационно-аналитический ресурс, посвященный машинному обучению, распознаванию образов и интеллектуальному анализу данных: http://www.machinelearning.ru\n",
|
||
"3. Modern State of Artificial Intelligence — Online Masters program at MIPT: https://girafe.ai/"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
" "
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"colab": {
|
||
"authorship_tag": "ABX9TyP49vkWVMyMLjNYOlwKa9fi",
|
||
"provenance": []
|
||
},
|
||
"kernelspec": {
|
||
"display_name": "Python 3",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.7.3"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 1
|
||
}
|