ответвлено от main/neurocomputers-python
Сравнить коммиты
3 Коммитов
| Автор | SHA1 | Дата | |
|---|---|---|---|
| 603ec44720 | |||
| 6c5da44cc3 | |||
| fe6b803876 |
@@ -12,9 +12,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "15BpjnZQzAUG"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"> Цель работы: знакомство с применением многослойного персептрона для решения задач сжатия данных, прогнозирования временных рядов и распознавания образов.\n",
|
||||
">\n",
|
||||
@@ -23,15 +21,15 @@
|
||||
"> а) для исходных данных из 5-ти классов; \n",
|
||||
"> б) для исходных данных из 4-х классов. \n",
|
||||
"> Провести визуализацию данных в скрытом слое каждой сети на плоскость и в 3-х мерное пространство. Проанализировать полученные результаты. Выбрать и сохранить автоассоциативные ИНС, обеспечивающие наилучшее сжатие исходных данных. \n",
|
||||
"> 2. … \n",
|
||||
"> 2. Исследовать возможности ИНС по прогнозированию поведения нелинейных динамических систем (построение странного аттрактора) на примере отображения Хенона. Аттрактор Хенона может быть получен из уравнений $x_{n+1} = 1 - \\alpha x_{n}^2 + y_{n}$ и $y_{n+1} = \\beta x_{n}$, где $α = 1.4$, $β = 0.3$.\n",
|
||||
"> Для прогнозирования предлагается использовать многослойный персептрон и сеть с радиально-базисными функциями.\n",
|
||||
"> Постройте также прогноз курса доллара на один день вперед. В качестве исходных данных загрузить актуальные данные с сайта центрального банка России (http://www.cbr.ru).\n",
|
||||
"> 3. Решить задачу распознавания 9-ти изображений самолетов. Исходные данные (файлы avia1.bmp, …, avia9.bmp) необходимо предварительно преобразовать в набор векторов со значениями признаков 0 или 1. Обученная нейронная сеть должна правильно определять модель самолета и его класс (истребитель/бомбардировщик). Принадлежность модели к определенному классу выбирается студентом самостоятельно."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "F1-sSuk2zAUI"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Импорт библиотек:"
|
||||
]
|
||||
@@ -46,11 +44,11 @@
|
||||
"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 mpl_toolkits.mplot3d import Axes3D\n",
|
||||
"from sklearn.model_selection import train_test_split\n",
|
||||
"\n",
|
||||
"from torch import nn\n",
|
||||
"\n",
|
||||
@@ -59,9 +57,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "GtZJ1mGmzAUL"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Содержание: \n",
|
||||
"[1. Подготовка данных](#p_1) \n",
|
||||
@@ -71,18 +67,14 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "HZNHPPKUzAUM"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1. Подготовка данных<a id=\"p_1\"></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "h2JqhwwrzAUN"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Загрузим в датафрейм `data` данные о сорока образцах минеральной воды, хранящиеся в файле `min_water.txt`."
|
||||
]
|
||||
@@ -96,7 +88,7 @@
|
||||
"height": 256
|
||||
},
|
||||
"id": "PkNWYbQCpsl_",
|
||||
"outputId": "1de6457f-9cc1-42a1-b4f1-2c13c5b66100"
|
||||
"outputId": "ee2dd8c3-2d7d-4962-bc40-a5cc2dded5db"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -106,9 +98,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "YjqpAWl9zAUR"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Вынесем в отдельные переменные:\n",
|
||||
" - `y_binary` — выходной признак для задачи бинарной классификации (первый столбец датафрейма);\n",
|
||||
@@ -132,9 +122,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "rpgOkJkPzAUT"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Выпишите в список `features` отобранные в прошлой лабораторной работе признаки (формат: `features = ['VAR1', 'VAR2']`):"
|
||||
]
|
||||
@@ -142,9 +130,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "R0bIf4PUzAUT"
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"features = # Ваш код здесь"
|
||||
@@ -152,9 +138,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ddwgNPoyzAUV"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Датафрейм с отобранными входными признаками `X_data_filtered`:"
|
||||
]
|
||||
@@ -168,7 +152,7 @@
|
||||
"height": 206
|
||||
},
|
||||
"id": "d6eTUCk2Cjdc",
|
||||
"outputId": "656c9a35-26f6-4425-b35e-ca06930abc82"
|
||||
"outputId": "d89643dd-a410-42b2-9b91-c4534966fd1d"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -180,7 +164,7 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"C помощью функции `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`) с сохранением соотншений классов (сортов минеральной воды):"
|
||||
"Произведите нормализацию или стандартизацию (на выбор) отобранных входных данных `X_data_filtered`. Результат сохраните в переменную `X_data_preprocessed`, которую затем представьте в виде тензора `X_data_tensor`:"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -191,37 +175,19 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"X_multiclass_train, X_multiclass_test, y_multiclass_train, y_multiclass_test = # Ваш код здесь\n",
|
||||
"# Ваш код здесь\n",
|
||||
"\n",
|
||||
"X_multiclass_train, X_multiclass_valid, y_multiclass_train, y_multiclass_valid = # Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "LAOh4V56zAUV"
|
||||
},
|
||||
"source": [
|
||||
"Произведите нормализацию или стандартизацию (на выбор) входных данных. Результат сохраните в переменные (`X_multiclass_train`, `X_multiclass_valid`, `X_multiclass_test`), которую затем представьте в виде тензоров:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"X_means = # Ваш код здесь\n",
|
||||
"X_stds = # Ваш код здесь\n",
|
||||
"\n",
|
||||
"X_multiclass_train = # Ваш код здесь\n",
|
||||
"X_multiclass_valid = # Ваш код здесь\n",
|
||||
"X_multiclass_test = # Ваш код здесь"
|
||||
"X_data_preprocessed = # Ваш код здесь\n",
|
||||
"\n",
|
||||
"X_data_tensor = # Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "AtGktiZmJiUV",
|
||||
"outputId": "f9edb4f0-c5ab-4a62-af28-6552c981512f"
|
||||
},
|
||||
@@ -247,9 +213,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "asRgUuyNzAUY"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Допишите класс `Autoencoder` структурами энкодера и декодера на основе полносвязных слоёв `nn.Linear`. В качестве функций активации используйте `nn.ReLU()`. При этом на выходе энкодера функцию активации можно не применять — это позволит сохранить отрицательные значения в кодированном представлении."
|
||||
]
|
||||
@@ -257,9 +221,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "F297Z81wzAUY"
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class Autoencoder(nn.Module):\n",
|
||||
@@ -280,9 +242,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "R5sVUOy7zAUZ"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Создайте экземпляр модели с двумя нейронами в «узком горле»:"
|
||||
]
|
||||
@@ -290,9 +250,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "MlSSzk2yzAUa"
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"model_2 = Autoencoder(# Ващ код здесь\n",
|
||||
@@ -302,6 +260,9 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "tGS2_TqjK_SI",
|
||||
"outputId": "a1a63c33-5dd5-461e-8d20-97fc34455f21"
|
||||
},
|
||||
@@ -317,18 +278,16 @@
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "Y3GS-3AaKYt7",
|
||||
"outputId": "81ecb257-7d72-443e-aa9e-256271a17a6e"
|
||||
"outputId": "981a4cd8-3b19-4bf6-ac07-ddd13e3df131"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"model_2(X_multiclass_train[:3])"
|
||||
"model_2(X_data_tensor[:3])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "8hJk8GWIzAUb"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Удостоверимся, что размерность её выхода совпадает с размерностью её входа:"
|
||||
]
|
||||
@@ -336,19 +295,15 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "pDmdGMRZzAUc"
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assert X_multiclass_train[:3].shape == model_2(X_multiclass_train[:3]).shape"
|
||||
"assert X_data_tensor[:3].shape == model_2(X_data_tensor[:3]).shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "IjoYYn-ozAUc"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Проверим, как модель обучается. Зададим оптимизатор и среднеквадратическую функцию потерь:"
|
||||
]
|
||||
@@ -367,9 +322,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "HqcQqxN7zAUd"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Рассчитаем значение функции потерь:"
|
||||
]
|
||||
@@ -382,21 +335,19 @@
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "5kKYW89_KY8j",
|
||||
"outputId": "a5ece716-5c89-4553-c78c-1e5c7e20eedf"
|
||||
"outputId": "94e90485-ca86-4204-e61d-75d247a87fc4"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"decoded = model_2(X_multiclass_train)\n",
|
||||
"decoded = model_2(X_data_tensor)\n",
|
||||
"\n",
|
||||
"loss = criterion(decoded, X_multiclass_train)\n",
|
||||
"loss = criterion(decoded, X_data_tensor)\n",
|
||||
"loss"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "JVplv7O8zAUd"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Выполните несколько раз эту и предыдущую ячейку, чтобы убедиться в уменьшении ошибки:"
|
||||
]
|
||||
@@ -416,9 +367,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "iXqI-DurzAUe"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Задайте параметры для обучения автоассоциативной сети с двумя нейронами в «узком горле»:"
|
||||
]
|
||||
@@ -426,9 +375,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "5s4GjW_PzAUe"
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"torch.manual_seed(seed=42)\n",
|
||||
@@ -446,9 +393,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "SN8PZ41vzAUp"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Обучение нейронной сети:**"
|
||||
]
|
||||
@@ -459,21 +404,16 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"loss_train_history, loss_valid_history = [], []\n",
|
||||
"loss_history = []\n",
|
||||
"\n",
|
||||
"for epoch in range(epochs):\n",
|
||||
" # Ваш код здесь\n",
|
||||
"\n",
|
||||
" # Отключаем градиенты для этапа валидации\n",
|
||||
" with torch.no_grad():\n",
|
||||
" # Ваш код здесь\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.plot(range(1, epoch+2), loss_history, label='Loss')\n",
|
||||
" plt.title(f'Epoch: {epoch + 1}, Loss: {loss_history[-1]:.6f}')\n",
|
||||
" plt.grid(True, alpha=0.3)\n",
|
||||
" plt.legend(loc='best')\n",
|
||||
" plt.show()"
|
||||
@@ -482,54 +422,6 @@
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Проверим качество обученной сети на тестовой выборке:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "t-Xkwg4h3gyS",
|
||||
"outputId": "ddfc13ae-f942-4328-9036-92b318c726bc"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"with torch.no_grad():\n",
|
||||
" decoded_test = model_2(X_multiclass_test)\n",
|
||||
" loss_test = criterion(decoded_test, X_multiclass_test)\n",
|
||||
"\n",
|
||||
"print(f'Loss Test: {loss_test.item():.6f}')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Далее необходимо через обученную сети пропустить все имеющиеся входные данные. Здесь можно сконкатенировать обучающую, валидационную и тестовую выборки, но можно и заново стандартизировать исходные данные `X_data_filtered` с помощью переменных `X_means` и `X_stds`, которые обязательно должны быть ранее рассчитаны на обучающей выборке `X_multiclass_train` (аналогично будет и для нормировки данных). Результат будет прелставлен в виде тензора.\n",
|
||||
"\n",
|
||||
"Такой вариант сохранит исходный порядок записей в данных и позволит нам использовать исходный вектор `y_multiclass` для разметки классов ниже."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "0RbKOwMeZUcn"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"X_data_tensor = torch.tensor(((X_data_filtered - X_means) / X_stds).values).float()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "TrWOUf0vzAUq"
|
||||
},
|
||||
"source": [
|
||||
"После обучения сети получим двумерные данные с выхода энкодера:"
|
||||
]
|
||||
@@ -542,7 +434,7 @@
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "HFcSAdGoOaog",
|
||||
"outputId": "1233f17c-2188-402e-d1dc-697dc6c0bfb4"
|
||||
"outputId": "36330737-7606-4a6a-e532-6bf372deb34d"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -552,9 +444,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "GjtM4NXLzAUr"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Построим двумерную диаграмму рассеяния и отметим классы с помощью `y_multiclass`:"
|
||||
]
|
||||
@@ -568,7 +458,7 @@
|
||||
"height": 430
|
||||
},
|
||||
"id": "KkToPCInQQ1J",
|
||||
"outputId": "8469b911-292a-4016-fbd3-38f92997adad"
|
||||
"outputId": "244bae8a-94a9-4817-a564-69c630efea98"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -584,9 +474,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "t0EmzLHXzAUs"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"По аналогии обучите автоассоциативную сеть с тремя нейронами в «узком горле»:"
|
||||
]
|
||||
@@ -594,9 +482,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "WasLielLzAUt"
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"torch.manual_seed(seed=42)\n",
|
||||
@@ -609,9 +495,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "cFxc9xD-zAUt"
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Ваш код здесь"
|
||||
@@ -619,19 +503,15 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "18f786y5zAUv"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"После обучения сети получите трёхмерные данные с выхода энкодера (снова по всем данным `X_data_tensor`, которые уже были подготовлены выше):"
|
||||
"После обучения сети получите трёхмерные данные с выхода энкодера:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "PLjKuu-szAUw"
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"encoded_3d = # Ваш код здесь"
|
||||
@@ -639,9 +519,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "BYn45sTnzAUx"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Построим трёхмерную диаграмму рассеяния:"
|
||||
]
|
||||
@@ -655,7 +533,7 @@
|
||||
"height": 653
|
||||
},
|
||||
"id": "RpqVg5EeT72I",
|
||||
"outputId": "7b9aac3c-68d5-44d7-db56-8f7a53e3aa37"
|
||||
"outputId": "2f5e070d-aa49-4eab-cd8e-277bd3a2c4b5"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -685,9 +563,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "NNWL9ZakzAUy"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Сохраним в бинарные файлы `.npy` выходы энкодеров обеих моделей — для следующей лабораторной работы:"
|
||||
]
|
||||
@@ -695,9 +571,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "p2Zx-Jz4zAUz"
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"np.save('encoded_2d.npy', encoded_2d)\n",
|
||||
@@ -706,18 +580,14 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "K-pYtaxBzAUz"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 3. Автоассоциативная нейронная сеть на неполных данных<a id=\"p_3\"></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "J3RSV5WDzAU0"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Выберите класс, который нужно исключить:"
|
||||
]
|
||||
@@ -725,9 +595,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "_UuEf5TRzAU0"
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"label_to_exclude = # Ваш код здесь"
|
||||
@@ -735,9 +603,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "MmlBKShgzAU1"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Создадим маску для исключения данных этого класса:"
|
||||
]
|
||||
@@ -755,9 +621,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "SA3A39ARzAU1"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Данные исключены:"
|
||||
]
|
||||
@@ -766,60 +630,22 @@
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "I7sTKdWgQRWQ"
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "I7sTKdWgQRWQ",
|
||||
"outputId": "95d2a292-7e2f-401e-e473-7d5f09b0d7fb"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"X_data_include = X_data_filtered.loc[mask_to_exclude, :]\n",
|
||||
"y_include = y_multiclass[mask_to_exclude]"
|
||||
"X_data_tensor[mask_to_exclude].shape"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"По аналогии с помощью функции `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`) с сохранением соотншений классов:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"X_include_train, X_include_test, y_include_train, y_include_test = # Ваш код здесь\n",
|
||||
"\n",
|
||||
"X_include_train, X_include_valid, y_include_train, y_include_valid = # Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Обратите внимание, что `X_means` и `X_stds` перерасчитываются уже на другой по составу обучающей выборке."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"X_means = # Ваш код здесь\n",
|
||||
"X_stds = # Ваш код здесь\n",
|
||||
"\n",
|
||||
"X_include_train = # Ваш код здесь\n",
|
||||
"X_include_valid = # Ваш код здесь\n",
|
||||
"X_include_test = # Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "V2MUFTkczAU2"
|
||||
},
|
||||
"source": [
|
||||
"По аналогии с предыдущим пунктом реализуйте обучение автоассоциативных сетей с двумя и тремя нейронами в «узком горле».\n",
|
||||
"По аналогии с предыдущим пунктом реализуйте обучение автоассоциативных сетей с двумя и тремя нейронами в «узком горле» на неполных данных (т.е. на каждой эпохе вместо полных данных `X_data_tensor` на модель нужно подавать неполные данные `X_data_tensor[mask_to_exclude]`).\n",
|
||||
"\n",
|
||||
"Результаты выходов энкодеров в обоих случаях также сохраните в отдельные бинарные файлы."
|
||||
]
|
||||
@@ -827,9 +653,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "qnSnyqNGzAU2"
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Ваш код здесь"
|
||||
@@ -838,41 +662,12 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "MMW6h5P1zAU3"
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Обратите внимание, что тензор `X_data_tensor` снова получен из исходных данных `X_data_filtered`, но уже с пересчитанными `X_means` и `X_stds` (без одного класса):"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "1FjpRmrCaOp4"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"X_data_tensor = torch.tensor(((X_data_filtered - X_means) / X_stds).values).float()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"encoded_2d_include = # Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
@@ -884,39 +679,9 @@
|
||||
"# Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"encoded_3d_include = # Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"np.save('encoded_2d_include.npy', encoded_2d_include)\n",
|
||||
"np.save('encoded_3d_include.npy', encoded_3d_include)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "-BXig37czAU6"
|
||||
},
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Литература:\n",
|
||||
"1. Бородкин А.А., Елисеев В.Л. Основы и применение искусственных нейронных сетей. Сборник лабораторных работ: методическое пособие. – М.: Издательский дом МЭИ, 2017.\n",
|
||||
@@ -926,10 +691,10 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "-KIqZEHczAU6"
|
||||
},
|
||||
"source": []
|
||||
"metadata": {},
|
||||
"source": [
|
||||
" "
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
|
||||
989
lab3/3.2_rbf.ipynb
Обычный файл
989
lab3/3.2_rbf.ipynb
Обычный файл
@@ -0,0 +1,989 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "AoAuVqmYggH6"
|
||||
},
|
||||
"source": [
|
||||
"### ЛАБОРАТОРНАЯ РАБОТА №3\n",
|
||||
"## Применение многослойного персептрона. Автоассоциативная ИНС"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "32GlCnm4ggH9"
|
||||
},
|
||||
"source": [
|
||||
"> Цель работы: знакомство с применением многослойного персептрона для решения задач сжатия данных, прогнозирования временных рядов и распознавания образов.\n",
|
||||
">\n",
|
||||
"> Задание\n",
|
||||
"> 1. Открыть файл с данными по минеральной воде, который использовался при решении задач классификации в предыдущей лабораторной работе. Построить и обучить автоассоциативные нейронные сети с 2-мя и 3-мя нейронами в скрытом слое: \n",
|
||||
"> а) для исходных данных из 5-ти классов; \n",
|
||||
"> б) для исходных данных из 4-х классов. \n",
|
||||
"> Провести визуализацию данных в скрытом слое каждой сети на плоскость и в 3-х мерное пространство. Проанализировать полученные результаты. Выбрать и сохранить автоассоциативные ИНС, обеспечивающие наилучшее сжатие исходных данных. \n",
|
||||
"> 2. Исследовать возможности ИНС по прогнозированию поведения нелинейных динамических систем (построение странного аттрактора) на примере отображения Хенона. Аттрактор Хенона может быть получен из уравнений $x_{n+1} = 1 - \\alpha x_{n}^2 + y_{n}$ и $y_{n+1} = \\beta x_{n}$, где $α = 1.4$, $β = 0.3$.\n",
|
||||
"> Для прогнозирования предлагается использовать многослойный персептрон и сеть с радиально-базисными функциями.\n",
|
||||
"> Постройте также прогноз курса доллара на один день вперед. В качестве исходных данных загрузить актуальные данные с сайта центрального банка России (http://www.cbr.ru).\n",
|
||||
"> 3. Решить задачу распознавания 9-ти изображений самолетов. Исходные данные (файлы avia1.bmp, …, avia9.bmp) необходимо предварительно преобразовать в набор векторов со значениями признаков 0 или 1. Обученная нейронная сеть должна правильно определять модель самолета и его класс (истребитель/бомбардировщик). Принадлежность модели к определенному классу выбирается студентом самостоятельно."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "k_B6wp5VggH_"
|
||||
},
|
||||
"source": [
|
||||
"Импорт библиотек:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "tHv-NgtJ30SO"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"import pandas as pd\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import torch\n",
|
||||
"from IPython.display import clear_output\n",
|
||||
"from torch import nn\n",
|
||||
"from sklearn.cluster import KMeans\n",
|
||||
"from sklearn.linear_model import LinearRegression\n",
|
||||
"\n",
|
||||
"%matplotlib inline"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "4vwZ6H2DggIB"
|
||||
},
|
||||
"source": [
|
||||
"Среднеквадратическая ошибка:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "OGGq8mjQggIC"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def mse(y_pred, y_true):\n",
|
||||
" return np.mean((y_pred - y_true) ** 2)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Содержание: \n",
|
||||
"[1. Подготовка данных](#p_1) \n",
|
||||
"[2. Сеть с радиально-базисными функциями](#p_2) \n",
|
||||
"[3. Многослойный персептрон](#p_3) \n",
|
||||
"[4. Сравнение моделей](#p_4) \n",
|
||||
"[5. Прогнозирование курса доллара](#p_5)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "iaKX-JW9ggIC"
|
||||
},
|
||||
"source": [
|
||||
"## 1. Подготовка данных<a id=\"p_1\"></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "C4MQNIvaggIC"
|
||||
},
|
||||
"source": [
|
||||
"Функция с реализацией отображения Хенона — уравнения $x_{n+1} = 1 - \\alpha x_{n}^2 + y_{n}$ и $y_{n+1} = \\beta x_{n}$, где $α = 1.4$, $β = 0.3$:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "3nMMP4Zj1Bwu"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def xenon_map(x=0, y=0, alpha=1.4, beta=0.3):\n",
|
||||
" x_next = 1 - alpha * x ** 2 + y\n",
|
||||
" y_next = beta * x\n",
|
||||
" return x_next, y_next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "9HXiFkDoggID"
|
||||
},
|
||||
"source": [
|
||||
"Укажите количество точек во временном ряде, который будет получен из отображения Хенона:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "BUgZtjUyggID"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"n_points = # Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "XPr65SPMggIE"
|
||||
},
|
||||
"source": [
|
||||
"Сгенерируем необходимое количество точек — помним, что нужна только переменная $x$:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "iJQi12wm22eR"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"x, y = 0, 0\n",
|
||||
"xenon_data = []\n",
|
||||
"for i in range(n_points):\n",
|
||||
" x, y = xenon_map(x, y)\n",
|
||||
" xenon_data.append(x)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "vKcPkUDCggIF"
|
||||
},
|
||||
"source": [
|
||||
"Поскольку исходная задача является задачей прогнозирования, то обучающая выборка должна включать в себя первый участок временного ряда, на котором будет обучаться модель. Валидационная выборка, на которой мы оцениваем качество предсказания модели, всегда должна идти после обучающей (аналогично с тестовой).\n",
|
||||
"\n",
|
||||
"Выделим, к примеру, первые 70% данных временного ряда `xenon_data` для обучающей выборки, следующие данные по 15% отнесём к вылидационной и тестовой выборкам (вторая и третья части данных соответственно):"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "1ZMHrs0c4Ihy"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"train_size = int(0.7 * n_points)\n",
|
||||
"valid_size = int(0.15 * n_points)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "JDK1n0N-ggIF"
|
||||
},
|
||||
"source": [
|
||||
"Представим данные для выборок на графике:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 430
|
||||
},
|
||||
"id": "fcaFy3iWjeQQ",
|
||||
"outputId": "64abe542-cee1-4183-b616-6c7e9c41118e"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"plt.plot(xenon_data, color='k', label='Xenon Data')\n",
|
||||
"plt.axvspan(0, train_size, alpha=0.35, color='blue', label='Train')\n",
|
||||
"plt.axvspan(train_size, train_size+valid_size, alpha=0.35, color='orange', label='Valid')\n",
|
||||
"plt.axvspan(train_size+valid_size, n_points, alpha=0.35, color='green', label='Test')\n",
|
||||
"plt.legend(loc='best')\n",
|
||||
"plt.grid(True, alpha=0.3)\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "pej4dfNRggIG"
|
||||
},
|
||||
"source": [
|
||||
"Пройдём с единичным шагом по всем данным `xenon_data` скользящим окном длиною `seq_length`(например, длиною 10). Таким образом сформируем пары «вход‑выход» для модели:\n",
|
||||
" - `X_data`: последовательности из `seq_length` элементов (скользящее окно по `xenon_data`),\n",
|
||||
" - `y_data`: элемент, следующий сразу за каждой последовательностью в `X_data`.\n",
|
||||
"\n",
|
||||
"***Примечание***. С помощью `[:-1]` мы убираем в `X_data` последнее окно, для которого нет «следующего значения» в `y_data`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "C2KR8vptSKVH"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"seq_length = 10\n",
|
||||
"\n",
|
||||
"X_data = np.lib.stride_tricks.sliding_window_view(xenon_data, window_shape=seq_length)[:-1]\n",
|
||||
"y_data = xenon_data[seq_length:]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "wM5lRDRnLWY4"
|
||||
},
|
||||
"source": [
|
||||
"Посмотрим конец полученных данных. Видно, что последнее значение `y_data` не включено в окна из `X_data`:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "13yK1ZsbUfWk",
|
||||
"outputId": "5e86b1ee-c455-4087-f1c9-b1accff382fd"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"X_data[-2:]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "5639fOPUTl2Q",
|
||||
"outputId": "483d2e6d-36e5-4d4a-cbed-726dc0ed4eec"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"y_data[-4:]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "04Pd841VggII"
|
||||
},
|
||||
"source": [
|
||||
"Длина наших данных — без учёта последнего значения:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "k62uvZDNONY1"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assert len(X_data) == len(y_data) == n_points - seq_length"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "v8vK2daVggIJ"
|
||||
},
|
||||
"source": [
|
||||
"Разделим данные на обучающую, валидационную и тестовую выборку по заданному выше соотношению 70%/15%/15%:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "jvRzLs7rS9QF"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"X_train, X_valid, X_test = X_data[:train_size], X_data[train_size:train_size+valid_size], X_data[train_size+valid_size:]\n",
|
||||
"y_train, y_valid, y_test = y_data[:train_size], y_data[train_size:train_size+valid_size], y_data[train_size+valid_size:]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "i4VgXIcRV91m"
|
||||
},
|
||||
"source": [
|
||||
"Отнормируйте или отстанлартизируйте входные и выходные данные.\n",
|
||||
"\n",
|
||||
"Поскольку нормирующие или стандартизирующие величины (минимум, максимум, среднее, СКО) всегда расчитываются только по значениям обучающей выборки, берём из исходных данных `xenon_data` также значения, которые попадут в последнее окно (и снова исключаем самое последнее значение):"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "fjN96i_1ggIJ"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"X_mean = np.mean(xenon_data[:train_size+seq_length-1])\n",
|
||||
"X_std = np.std(xenon_data[:train_size+seq_length-1], ddof=1)\n",
|
||||
"y_mean = np.mean(y_data[:train_size])\n",
|
||||
"y_std = np.std(y_data[:train_size], ddof=1)\n",
|
||||
"\n",
|
||||
"X_train_scaled = # Ваш код здесь\n",
|
||||
"X_valid_scaled = # Ваш код здесь\n",
|
||||
"X_test_scaled = # Ваш код здесь\n",
|
||||
"\n",
|
||||
"y_train_scaled = # Ваш код здесь\n",
|
||||
"y_valid_scaled = # Ваш код здесь\n",
|
||||
"y_test_scaled = # Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "gGVJqQGUggIK"
|
||||
},
|
||||
"source": [
|
||||
"## 2. Сеть с радиально-базисными функциями<a id=\"p_2\"></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "xm61W3LPggIK"
|
||||
},
|
||||
"source": [
|
||||
"РБФ-сеть (Radial Basis Function Network, RBF) — это нейронная сеть, которая использует радиально-базисные функции в качестве функций активации нейронов скрытого слоя. Архитектура такой сети обычно включает три слоя:\n",
|
||||
" - Входной слой — принимает входные данные (значения временного ряда).\n",
|
||||
" - Скрытый слой — содержит нейроны с радиальными базисными функциями. Каждый нейрон вычисляет расстояние между входным вектором и заранее определённым центром функции, а затем преобразует это расстояние с помощью радиальной функции.\n",
|
||||
" - Выходной слой — линейно комбинирует (взвешенно суммирует) выходы скрытых нейронов, чтобы получить итоговый результат.\n",
|
||||
"\n",
|
||||
"Таким образом, выходной сигнал РБФ‑сети вычисляется по формуле:\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"y(\\mathbf{x}) = \\sum_{j=1}^{H} w_j \\cdot \\phi(\\|\\mathbf{x} - \\mathbf{c}_j\\|_2)\n",
|
||||
"$$\n",
|
||||
"где:\n",
|
||||
"* $y(\\mathbf{x})$ — выходной сигнал сети для входного вектора $\\mathbf{x}$;\n",
|
||||
"* $H$ — количество нейронов в скрытом слое;\n",
|
||||
"* $w_j$ — вес связи от $j$-го нейрона скрытого слоя к выходному слою;\n",
|
||||
"* $\\mathbf{c}_j$ — центр $j$-й радиально-базисной функции;\n",
|
||||
"* $\\phi$ — радиально-базисная функция;\n",
|
||||
"* $\\|\\mathbf{x} - \\mathbf{c}_j\\|_2$ — евклидово расстояние между входным вектором $\\mathbf{x}$ и центром $\\mathbf{c}_j$.\n",
|
||||
"\n",
|
||||
"Радиально-базисная функция — это функция, которая зависит только от расстояния между входным вектором и центром функции. Чаще всего используется гауссова функция:\n",
|
||||
"$$\n",
|
||||
"\\phi(r) = \\exp\\left(-\\frac{r^2}{2\\sigma^2}\\right)\n",
|
||||
"$$\n",
|
||||
"где $r = \\|\\mathbf{x} - \\mathbf{c}\\|_2$, $\\sigma$ — параметр ширины окна.\n",
|
||||
"\n",
|
||||
"Обучение РБФ‑сетей обычно проходит в два этапа:\n",
|
||||
"\n",
|
||||
"1. Определение параметров радиально-базисной функции (центров $\\mathbf{c}_i$ и ширин $\\sigma_i$):\n",
|
||||
" * кластеризация (например, k‑means) для нахождения центров;\n",
|
||||
" * эвристические методы или кросс‑валидация для ширин.\n",
|
||||
"\n",
|
||||
"2. Обучение выходных весов $w_j$:\n",
|
||||
" * решение задачи линейной регрессии (с использованием обучения с учителем, например, методом наименьших квадратов или градиентного спуска).\n",
|
||||
" \n",
|
||||
"Таким образом, на первом этапе сеть определяет, где в пространстве признаков сосредоточены основные закономерности данных. Для этого, например, используются алгоритмы кластеризации: объекты (значения временного ряда) внутри одного кластера получатся максимально похожи друг на друга, а объекты разных классов — максимально различны (т.о. определим важные зоны или паттерны ряда).\n",
|
||||
"\n",
|
||||
"После определения центров сеть анализирует, как каждая точка соотносится с ними. Это показывает гауссова РБФ — для каждой точки вычисляется расстояние до каждого из центров, и чем ближе точка к центру, тем выше значение функции (близко к 1), а также наоборот — чем дальше точка к центру, тем ниже (РБФ стремится к 0). Для каждой точки получается вектор активаций — набор чисел, показывающих, насколько она «похожа» на каждый из центров. Так, точка между двумя центрами даст средние значения для обоих, а точка рядом с одним центром — высокое значение для него и низкие для остальных.\n",
|
||||
"\n",
|
||||
"На этих активациях для получения весов между скрытым и выходным слоями обучается линейная регрессия. Она находит оптимальные веса для каждого выхода скрытого слоя: какие локальные паттерны важнее для прогноза, какие — менее значимы."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "2y2jya41ggIL"
|
||||
},
|
||||
"source": [
|
||||
"Реализуем с помощью класса `RBFPredictor` РБФ-сеть с описанной выше архитектурой.\n",
|
||||
"\n",
|
||||
"При инициализации (`.__init__()`) задаётся `n_centers` — число центров (нейронов скрытого слоя), устанавливается параметр ширины окна `sigma` для гауссовой функции, создаётся модель линейной регрессии `linear_model` для выходного слоя (взята из библиотеки sklearn).\n",
|
||||
"\n",
|
||||
"Выбор `n_centers` центров из входных данных происходит в методе `.fit()`. Для этого используется алгоритм k‑means (взят из библиотеки sklearn).\n",
|
||||
"\n",
|
||||
"Далее в скрытом слое (метод `._radial_basis()`) для каждого входного вектора (объекта) вычисляются расстояния до всех центров. Расстояния преобразуются в значения гауссовой РБФ. На выходе получается матрица активаций размером (число объектов, число центров).\n",
|
||||
"\n",
|
||||
"На данной матрице активаций скрытого слоя `phi` и целевых значениях `y` обучается модель линейной регрессии `linear_model`. Веса регрессии становятся весами связей от скрытого слоя к выходному.\n",
|
||||
"\n",
|
||||
"При прогнозировании (метод `.predict()`) для новых данных вычисляются активации скрытого слоя (через гауссовы РБФ относительно тех же центров), а обученная линейная модель применяет веса к этим активациям и выдаёт финальный прогноз."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "yjn8NBbYXA5p"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class RBFPredictor:\n",
|
||||
" def __init__(self, n_centers, sigma=1.0):\n",
|
||||
" self.n_centers = n_centers\n",
|
||||
" self.sigma = sigma\n",
|
||||
" self.centers = None\n",
|
||||
" self.linear_model = LinearRegression()\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" def _radial_basis(self, X, centers):\n",
|
||||
" distances = np.zeros((X.shape[0], centers.shape[0]))\n",
|
||||
" for i, center in enumerate(centers):\n",
|
||||
" distances[:, i] = np.sqrt(np.sum((X - center) ** 2, axis=1))\n",
|
||||
" return np.exp(-(distances ** 2) / (2 * self.sigma ** 2))\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" def fit(self, X, y):\n",
|
||||
" # Выбираем центры с помощью кластеризации\n",
|
||||
" kmeans = KMeans(n_clusters=self.n_centers, random_state=42)\n",
|
||||
" self.centers = kmeans.fit(X).cluster_centers_\n",
|
||||
" # Вычисляем выход скрытого слоя\n",
|
||||
" phi = self._radial_basis(X, self.centers)\n",
|
||||
" # Обучаем линейный выходной слой\n",
|
||||
" self.linear_model.fit(phi, y)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" def predict(self, X):\n",
|
||||
" phi = self._radial_basis(X, self.centers)\n",
|
||||
" return self.linear_model.predict(phi)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "2IAX5UXUggIL"
|
||||
},
|
||||
"source": [
|
||||
"Обучите модель `model_rbf`. Для этого подберите подходящее количество центров `n_centers` и ширину окна `sigma`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "a5RQRqH5ggIM"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"model_rbf = RBFPredictor(\n",
|
||||
" # Ваш код здесь\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"model_rbf.fit(X_train_scaled, y_train_scaled)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "bOlEYLHGggIN"
|
||||
},
|
||||
"source": [
|
||||
"При подборе добейтесь примерно одинаковой (или хотя бы сопоставимой) ошибки на обучающей и вадилационной выборках:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "T1RLJMCyivU1",
|
||||
"outputId": "00671844-3026-4302-ecfc-0130c6f840f0"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"pred_rbf_train = model_rbf.predict(X_train_scaled)\n",
|
||||
"pred_rbf_valid = model_rbf.predict(X_valid_scaled)\n",
|
||||
"\n",
|
||||
"print('Loss')\n",
|
||||
"print(f'Train: {mse(pred_rbf_train, y_train_scaled):.6f}')\n",
|
||||
"print(f'Valid: {mse(pred_rbf_valid, y_valid_scaled):.6f}')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "NLZo9mQKggIm"
|
||||
},
|
||||
"source": [
|
||||
"Проверка `model_rbf` на тестовых данных будет ниже."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "G2kFrJUAmWRz"
|
||||
},
|
||||
"source": [
|
||||
"## 3. Многослойный персептрон<a id=\"p_3\"></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "3kvNrdq3ggIn"
|
||||
},
|
||||
"source": [
|
||||
"Представим входные и выходные данные в виде тензоров PyTorch:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "-GkRe60zptZd"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"X_train_tensor = torch.tensor(X_train_scaled).float()\n",
|
||||
"y_train_tensor = torch.tensor(y_train_scaled).reshape(-1, 1).float()\n",
|
||||
"X_valid_tensor = torch.tensor(X_valid_scaled).float()\n",
|
||||
"y_valid_tensor = torch.tensor(y_valid_scaled).reshape(-1, 1).float()\n",
|
||||
"X_test_tensor = torch.tensor(X_test_scaled).float()\n",
|
||||
"y_test_tensor = torch.tensor(y_test_scaled).reshape(-1, 1).float()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "p6INgMk6ggIn"
|
||||
},
|
||||
"source": [
|
||||
"Реализуйте в классе `MLPPredictor` с помощью полносвязных слоёв `nn.Linear` многослойный персептрон. В качестве промежуточных функций активации используйте `nn.ReLU()`, а поскольку решается задача прогнозирования вещественных данных, на выходе сети функцию активации можно не добавлять."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "Cg-m7jZNggIn"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class MLPPredictor(nn.Module):\n",
|
||||
" def __init__(self, input_size):\n",
|
||||
" super().__init__()\n",
|
||||
" self.seq = nn.Sequential(\n",
|
||||
" # Ваш код здесь\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" def forward(self, x):\n",
|
||||
" return self.seq(x)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "YPF9PyDcycNn"
|
||||
},
|
||||
"source": [
|
||||
"Создайте экземпляр модели:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "T2WBlrBMhA08",
|
||||
"outputId": "41040db9-10fe-4705-e27a-9f42ebd7ac4f"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"model_mlp = MLPPredictor(input_size=seq_length)\n",
|
||||
"model_mlp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "CTVh4iOjggIp"
|
||||
},
|
||||
"source": [
|
||||
"Проверим, как модель обучается. Зададим оптимизатор и среднеквадратическую функцию потерь:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "VGWgT-_UKY5S"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"optimizer = torch.optim.SGD(model_mlp.parameters(), lr=0.01)\n",
|
||||
"criterion = nn.MSELoss()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "-YGsKE_SggIp"
|
||||
},
|
||||
"source": [
|
||||
"Рассчитаем значение функции потерь:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "8qFQWNrMZyzM",
|
||||
"outputId": "a7e21b4c-425d-46c5-8406-1a27c6c193ef"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"pred_mlp_train = model_mlp(X_train_tensor)\n",
|
||||
"\n",
|
||||
"loss = criterion(pred_mlp_train, y_train_tensor)\n",
|
||||
"loss"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "drYc365KggIq"
|
||||
},
|
||||
"source": [
|
||||
"Выполните несколько раз эту и предыдущую ячейку, чтобы убедиться в уменьшении ошибки:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "UlggYk-KbfnF"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"loss.backward()\n",
|
||||
"optimizer.step()\n",
|
||||
"optimizer.zero_grad()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "F1hRU9Uj07TE"
|
||||
},
|
||||
"source": [
|
||||
"Задайте параметры для обучения нейронной сети:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "nkJ3lGsgggIr"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Перебор seed для инициализации параметров\n",
|
||||
"torch.manual_seed(seed=42)\n",
|
||||
"\n",
|
||||
"model_mlp = # Ваш код здесь\n",
|
||||
"\n",
|
||||
"epochs = # Ваш код здесь\n",
|
||||
"\n",
|
||||
"learning_rate = # Ваш код здесь\n",
|
||||
"momentum = # Ваш код здесь\n",
|
||||
"\n",
|
||||
"optimizer = # Ваш код здесь\n",
|
||||
"criterion = # Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "9rpN21H-ggIs"
|
||||
},
|
||||
"source": [
|
||||
"**Обучение нейронной сети:**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "4tZGNdtWggIs"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"loss_train_history, loss_valid_history = [], []\n",
|
||||
"\n",
|
||||
"for epoch in range(epochs):\n",
|
||||
" # Ваш код здесь\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()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "RbvISk2MfSC5"
|
||||
},
|
||||
"source": [
|
||||
"## 4. Сравнение моделей<a id=\"p_4\"></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "CDKiO9MDggIt"
|
||||
},
|
||||
"source": [
|
||||
"Получим прогнозы на тестовой выборке от РБФ-сети и многослойного персептрона:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "tKZ0sdh0eB91"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"pred_rbf_test = model_rbf.predict(X_test_scaled)\n",
|
||||
"\n",
|
||||
"with torch.no_grad():\n",
|
||||
" pred_mlp_test = model_mlp(X_test_tensor).squeeze().numpy()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "UA_BcjAjggIu"
|
||||
},
|
||||
"source": [
|
||||
"Поскольку обучение шло на нормированных или стандартизированных данных, приведём прогнозы к исходной шкале и рассчитаем среднеквадратическую ошибку:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "tl6X5LGZfjOY",
|
||||
"outputId": "bef46cea-f16c-41a2-8f12-8f3e967a5ac3"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"pred_rbf_test_descaled = (pred_rbf_test * y_std + y_mean)\n",
|
||||
"pred_mlp_test_descaled = (pred_mlp_test * y_std + y_mean)\n",
|
||||
"\n",
|
||||
"print('Loss')\n",
|
||||
"print(f'RBF: {mse(pred_rbf_test_descaled, y_test):.6f}')\n",
|
||||
"print(f'MLP: {mse(pred_mlp_test_descaled, y_test):.6f}')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "oLOykwtViDsY"
|
||||
},
|
||||
"source": [
|
||||
"Построим графики прогнозов для сравнения с исходными тестовыми данными:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 303
|
||||
},
|
||||
"id": "b0IlMe5EjpNl",
|
||||
"outputId": "6fa95c1b-3756-41fe-f020-358c07dd6b8c"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"plt.figure(figsize=(12, 4))\n",
|
||||
"\n",
|
||||
"plt.plot(y_test, label='True Values')\n",
|
||||
"plt.plot(pred_rbf_test_descaled, label='RBF Pred')\n",
|
||||
"plt.plot(pred_mlp_test_descaled, label='MLP Pred')\n",
|
||||
"plt.grid(True, alpha=0.3)\n",
|
||||
"plt.legend(loc='best')\n",
|
||||
"\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "Vs0-pqwUnqlL"
|
||||
},
|
||||
"source": [
|
||||
"## 5. Прогнозирование курса доллара<a id=\"p_5\"></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "4Od-qc-cnqqe"
|
||||
},
|
||||
"source": [
|
||||
"По аналогии с отображением Хенона самостоятельно реализуйте прогнозирование курса доллара.\n",
|
||||
"\n",
|
||||
"Для этого скачайте актуальную информацию по курсу с сайта http://www.cbr.ru в формате `.xlsx`.\n",
|
||||
"\n",
|
||||
"Введите в виже строки имя скачанного файла с расширением:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "Z0OkaJZ8ggIw"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"dollar_course_filename = # Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "cIxIxznLggIx"
|
||||
},
|
||||
"source": [
|
||||
"Загрузим данные в массив NumPy:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "oDN_CihKC4SB",
|
||||
"outputId": "14391340-b0b6-4017-8771-f54f6306ce71"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"dollar_data = pd.read_excel(dollar_course_filename).curs[::-1]\n",
|
||||
"\n",
|
||||
"# По необходимости можно сгладить данные скользящим окном -\n",
|
||||
"# в данном случае берём среднее за 7 дней\n",
|
||||
"dollar_data = dollar_data.rolling(window=7).mean().dropna()\n",
|
||||
"\n",
|
||||
"dollar_data = dollar_data.values"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "_HnJACO1ggIy"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "mwXH9dIBggI4"
|
||||
},
|
||||
"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": {
|
||||
"id": "Je7Xm08vggI5"
|
||||
},
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"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
|
||||
}
|
||||
@@ -19,7 +19,9 @@
|
||||
"> а) для исходных данных из 5-ти классов; \n",
|
||||
"> б) для исходных данных из 4-х классов. \n",
|
||||
"> Провести визуализацию данных в скрытом слое каждой сети на плоскость и в 3-х мерное пространство. Проанализировать полученные результаты. Выбрать и сохранить автоассоциативные ИНС, обеспечивающие наилучшее сжатие исходных данных. \n",
|
||||
"> 2. … \n",
|
||||
"> 2. Исследовать возможности ИНС по прогнозированию поведения нелинейных динамических систем (построение странного аттрактора) на примере отображения Хенона. Аттрактор Хенона может быть получен из уравнений $x_{n+1} = 1 - \\alpha x_{n}^2 + y_{n}$ и $y_{n+1} = \\beta x_{n}$, где $α = 1.4$, $β = 0.3$.\n",
|
||||
"> Для прогнозирования предлагается использовать многослойный персептрон и сеть с радиально-базисными функциями.\n",
|
||||
"> Постройте также прогноз курса доллара на один день вперед. В качестве исходных данных загрузить актуальные данные с сайта центрального банка России (http://www.cbr.ru).\n",
|
||||
"> 3. Решить задачу распознавания 9-ти изображений самолетов. Исходные данные (файлы avia1.bmp, …, avia9.bmp) необходимо предварительно преобразовать в набор векторов со значениями признаков 0 или 1. Обученная нейронная сеть должна правильно определять модель самолета и его класс (истребитель/бомбардировщик). Принадлежность модели к определенному классу выбирается студентом самостоятельно."
|
||||
]
|
||||
},
|
||||
|
||||
621
lab4/4_kohonen.ipynb
Обычный файл
621
lab4/4_kohonen.ipynb
Обычный файл
@@ -0,0 +1,621 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### ЛАБОРАТОРНАЯ РАБОТА №4\n",
|
||||
"## Сеть Кохонена"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"> Цель работы: знакомство с применением многослойного персептрона для решения задач сжатия данных, прогнозирования временных рядов и распознавания образов.\n",
|
||||
">\n",
|
||||
"> Задание\n",
|
||||
"> 1. Изучить разделы справки связанные с обучением сети Кохонена. Загрузить набор данных, содержащий измерения длины и ширины чашелистика и лепестка 150 экземпляров ириса (ирисы Фишера). Создать сеть Кохонена и выполнить с помощью неё кластеризацию сортов ириса. Проанализировать полученные результаты. Выполнить визуализацию исходных данных.\n",
|
||||
"> 2. Построить и обучить сеть Кохонена для кластеризации данных скрытого слоя автоассоциативной сети из п.1. лабораторной работы №3. Проанализировать результаты и сравнить их с результатами классификации многослойным персептроном, полученными в лабораторной работе №2.."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Импорт библиотек:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "5pnjRdYLSLXZ"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"import pandas as pd\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"from IPython.display import clear_output\n",
|
||||
"from mpl_toolkits.mplot3d import Axes3D\n",
|
||||
"from sklearn.datasets import load_iris\n",
|
||||
"\n",
|
||||
"%matplotlib inline"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Содержание: \n",
|
||||
"[1. Ирисы Фишера](#p_1) \n",
|
||||
"[2. Данные скрытого слоя](#p_2)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1. Ирисы Фишера<a id=\"p_1\"></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Сеть Кохонена (или самоорганизующаяся карта) — это тип нейронных сетей без учителя (unsupervised learning), разработанный финским учёным Теуво Кохоненом. \n",
|
||||
"\n",
|
||||
"Основная цель таких сетей — визуализация и кластеризация многомерных данных путём их проецирования на пространство меньшей размерности (чаще всего двумерное).\n",
|
||||
"\n",
|
||||
"Ключевые особенности:\n",
|
||||
" - Без учителя: не требует размеченных данных для обучения.\n",
|
||||
" - Топологическое упорядочивание: сохраняет пространственные отношения между точками данных — близкие входные векторы активируют соседние нейроны на карте.\n",
|
||||
" - Конкурентное обучение: в каждый момент времени «побеждает» только один нейрон (ближайший к входному вектору).\n",
|
||||
"\n",
|
||||
"Обучение сети Кохонена происходит итеративно, по одному примеру за раз.\n",
|
||||
" - Шаг 1. Инициализация. \n",
|
||||
"Веса всех нейронов инициализируются случайными значениями (обычно из того же распределения, что и входные данные).\n",
|
||||
" - Шаг 2. Выбор входного вектора. \n",
|
||||
"Из набора данных случайным образом выбирается один образец $x$ (пусть количество признаков равно $m$).\n",
|
||||
" - Шаг 3. Определение «нейрона‑победителя». \n",
|
||||
"Находится нейрон, вектор весов которого наиболее близок к входному вектору. Мера близости — обычно евклидово расстояние:\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"d(x, w_i) = \\sqrt{\\sum_{j=1}^{m} (x_j - w_{ij})^2}\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
" - Шаг 4. Обновление весов. \n",
|
||||
"Вектор весов нейрона‑победителя (и, опционально, его соседей) подтягивается ближе к входному вектору:\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"w_i(t+1) = w_i(t) + \\eta(t) \\cdot (x(t) - w_i(t))\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"где $w_i$ — вектор весов $i$-го нейрона (кластера); $\\eta(t)$ — скорость обучения (learning rate) в момент времени $t$, которая определяет, насколько сильно будут скорректированы веса; $x(t)$ — текущий входной вектор.\n",
|
||||
"\n",
|
||||
" - Шаг 5. Уменьшение скорости обучения. \n",
|
||||
"На этом этапе скорость обучения $\\eta$ постепенно уменьшается с каждой эпохой. Это необходимо для стабилизации карты в конце обучения: на ранних этапах допускаются большие корректировки весов (чтобы быстро приблизиться к оптимальной конфигурации), а на поздних — только мелкие уточнения. Обновление скорости обучения происходит по следующему правилу:\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
"\\eta(t+1) = \\eta(t) \\times \\text{decay}\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"где $\\text{decay}$ — коэффициент затухания (гиперпараметр, обычно близкий к $1$, например $0{,}99$ или $0{,}95$).\n",
|
||||
"\n",
|
||||
" - Шаг 6. Повторение. \n",
|
||||
"Шаги 2–5 повторяются заданное число эпох или до сходимости (т.е. пока значения весов нейронов в карте практически не перестанут меняться от эпохи к эпохе — структура карты, таким образом, уже сформирована и отражает топологию входных данных).\n",
|
||||
"\n",
|
||||
"Преимущества сетей Кохонена:\n",
|
||||
" - простота реализации и интерпретации;\n",
|
||||
" - наглядная визуализация сложных данных;\n",
|
||||
" - устойчивость к шуму в данных;\n",
|
||||
" - сохранение топологических свойств исходного пространства.\n",
|
||||
"\n",
|
||||
"Недостатки:\n",
|
||||
" - чувствительность к инициализации весов;\n",
|
||||
" - необходимость ручного подбора числа кластеров;\n",
|
||||
" - относительно медленное обучение на больших наборах данных.\n",
|
||||
" - результат может зависеть от порядка предъявления данных (поэтому их необходимо перемешивать).\n",
|
||||
"\n",
|
||||
"Описанная выше сеть Кохонена реализована в классе `KohonenClustering`:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "JJtHNld8SOWL"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class KohonenClustering:\n",
|
||||
" def __init__(self, n_clusters, lr=0.1, decay=0.99):\n",
|
||||
" self.n_clusters = n_clusters\n",
|
||||
" self.lr = lr\n",
|
||||
" self.decay = decay\n",
|
||||
" self.cluster_weights = None\n",
|
||||
"\n",
|
||||
" def winner(self, x):\n",
|
||||
" \n",
|
||||
" # Вычисляем евклидово расстояние от входного вектора до каждого кластера\n",
|
||||
" distances = np.zeros((x.shape[0], self.n_clusters))\n",
|
||||
" for i, cluster_weight in enumerate(self.cluster_weights):\n",
|
||||
" distances[:, i] = np.sqrt(np.sum((x - cluster_weight) ** 2, axis=1))\n",
|
||||
" \n",
|
||||
" # Находим индексы нейронов с минимальным расстоянием (победителей)\n",
|
||||
" winner_idx = np.argmin(distances, axis=1)\n",
|
||||
" return winner_idx\n",
|
||||
"\n",
|
||||
" def fit(self, data, epochs=100):\n",
|
||||
"\n",
|
||||
" self.cluster_weights = np.random.randn(self.n_clusters, data.shape[1]).astype(np.float32)\n",
|
||||
" \n",
|
||||
" lr_history = []\n",
|
||||
" for epoch in range(epochs):\n",
|
||||
"\n",
|
||||
" # Перемешиваем индексы данных для случайного выбора векторов\n",
|
||||
" indices = np.random.permutation(data.shape[0])\n",
|
||||
" \n",
|
||||
" # Проходим по всем векторам в случайном порядке\n",
|
||||
" for i in indices:\n",
|
||||
" # Извлекаем один вектор\n",
|
||||
" x = data[i:i+1]\n",
|
||||
" \n",
|
||||
" # Определяем нейрон‑победитель для текущего входного вектора\n",
|
||||
" winner_idx = self.winner(x)\n",
|
||||
" \n",
|
||||
" # Обновляем веса победившего нейрона: подтягиваем их ближе к входному вектору\n",
|
||||
" for i, idx in enumerate(winner_idx):\n",
|
||||
" self.cluster_weights[idx] += self.lr * (x[i] - self.cluster_weights[idx])\n",
|
||||
"\n",
|
||||
" lr_history.append(self.lr)\n",
|
||||
"\n",
|
||||
" # Постепенно уменьшаем скорость обучения для стабилизации карты\n",
|
||||
" self.lr *= self.decay\n",
|
||||
"\n",
|
||||
" if (epoch + 1) % 5 == 0:\n",
|
||||
"\n",
|
||||
" clear_output(True)\n",
|
||||
" plt.plot(range(1, epoch+2), lr_history, label='Learning Rate')\n",
|
||||
" plt.title(f'Epoch: {epoch + 1}, Learning Rate: {lr_history[-1]:.6f}')\n",
|
||||
" plt.grid(True, alpha=0.3)\n",
|
||||
" plt.legend(loc='best')\n",
|
||||
" plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Загрузим данные ирисов для их анализа с помощью сети Кохонена:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "N7kdsjBEWy3P"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"iris_data = load_iris()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Значения четырёх входных признаков:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "1qmf6ZAxWy8A",
|
||||
"outputId": "b7eaeee4-39ea-4204-e6e7-f9b47a10f73f",
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"X_iris_data = iris_data['data']\n",
|
||||
"print(X_iris_data[:5])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Названия признаков — длина и ширина чашелистика, длина и ширина лепестка:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "UDNslebrcXfK",
|
||||
"outputId": "9ece4206-94c9-436d-c6a2-d6bbf2495fa0"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"iris_data['feature_names']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Значения выходного признака — метки классов (три сорта ирисов):"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "IF6_sIBtXjNI",
|
||||
"outputId": "c59b99c6-3c1d-4576-d88c-6b7c870a9428"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"y_iris_data = iris_data['target']\n",
|
||||
"print(y_iris_data)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Названия сортов ирисов:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "IWZwrWKaX2R8",
|
||||
"outputId": "59e3f58e-71a1-40e2-9410-8871c5b0b695"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"iris_names = iris_data['target_names']\n",
|
||||
"print(iris_names)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Поскольку при обучении сети Кохонена вычисляются евклидовы расстояния между входными данными и весами нейронов, входные данные рекомендуются отнормировать или отстандартизировать:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"X_means = X_iris_data.mean(axis=0)\n",
|
||||
"X_stds = X_iris_data.std(axis=0, ddof=1)\n",
|
||||
"\n",
|
||||
"X_iris_data_scaled = # Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Обучите модель `kohonen_iris` на нормированных (или стандартизированных) данных.\n",
|
||||
"\n",
|
||||
"Для этого подберите количество кластеров `n_clusters`, скорость обучения `lr`, шаг снижения скорости обучения `decay`. При неоходимости измените количество эпох `epochs`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"kohonen_iris = KohonenClustering(\n",
|
||||
" n_clusters= # Ваш код здесь\n",
|
||||
" lr= # Ваш код здесь\n",
|
||||
" decay= # Ваш код здесь\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"kohonen_iris.fit(X_iris_data_scaled, epochs=100)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Получим метки кластеров — сопоставьте их с исходными метками классов:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "4gVxatZFYVCm",
|
||||
"outputId": "bfa24efd-eb30-4036-c01d-5e09aa8b931e"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"clusters_iris = kohonen_iris.winner(X_iris_data_scaled)\n",
|
||||
"print(clusters_iris)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Построим диаграмму рассеяния, например, для пары признаков — длины и ширины лепестка. Точки разметим по трём сортам ирисов:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 450
|
||||
},
|
||||
"id": "B8vgAwpQd4Zh",
|
||||
"outputId": "ebf196cd-ea4e-4367-a88b-cbc22bb9a7c5"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"scatter = plt.scatter(X_iris_data[:, 2], X_iris_data[:, 3], c=y_iris_data)\n",
|
||||
"plt.xlabel('petal length (cm)')\n",
|
||||
"plt.ylabel('petal width (cm)')\n",
|
||||
"plt.grid(True, alpha=0.3)\n",
|
||||
"\n",
|
||||
"# Код для легенды\n",
|
||||
"handles, _ = scatter.legend_elements(prop='colors')\n",
|
||||
"plt.legend(handles, iris_names, loc='best', title='Classes')\n",
|
||||
"\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Построим такую же диаграмму, олнако точки в ней будут размечены по меткам кластеров: "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 450
|
||||
},
|
||||
"id": "hWedmXtmeKXH",
|
||||
"outputId": "0c8b239e-b140-4cdc-d80f-238bc3038304"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"scatter = plt.scatter(X_iris_data[:, 2], X_iris_data[:, 3], c=clusters_iris)\n",
|
||||
"plt.xlabel('petal length (cm)')\n",
|
||||
"plt.ylabel('petal width (cm)')\n",
|
||||
"plt.grid(True, alpha=0.3)\n",
|
||||
"\n",
|
||||
"# Код для легенды\n",
|
||||
"handles, labels = scatter.legend_elements(prop='colors')\n",
|
||||
"plt.legend(handles, labels, loc='best', title='Clusters')\n",
|
||||
"\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "6Wlm1xrBYzuf"
|
||||
},
|
||||
"source": [
|
||||
"Поэкспериментируйте с количеством кластеров `n_clusters`. Проанализируйте варианты, когда:\n",
|
||||
" - количество кластеров совпадает с количеством сортов ирисов;\n",
|
||||
" - кластеров меньше сортов ирисов;\n",
|
||||
" - кластеров больше сортов ирисов."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2. Данные скрытого слоя<a id=\"p_2\"></a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Загрузим из файла `encoded_2d.npy` двумерные данные с выхода энкодера автоассоциативной сети из третьей лабораторной работы:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "B0OS99x8Dz9v",
|
||||
"outputId": "9b21ab60-5422-421f-e83b-64e378763bd7"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"encoded_2d = np.load('encoded_2d.npy')\n",
|
||||
"print(encoded_2d[:5])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Обучите модель `kohonen_2d` на этих данных. Количество кластеров пусть совпадает с количеством сортов минеральной воды (т.е. 5)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "3TXtr9d6SZ9a"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"kohonen_2d = KohonenClustering(\n",
|
||||
" # Ваш код здесь\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"kohonen_2d.fit(encoded_2d, epochs=100)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "LOv1vQ1kWKKf"
|
||||
},
|
||||
"source": [
|
||||
"Получим метки кластеров:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "zm3DoRAEStuR"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"clusters_2d = kohonen_2d.winner(encoded_2d)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "arnxu4zcSzyk"
|
||||
},
|
||||
"source": [
|
||||
"Построим двухмерную диаграмму рассеяния:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 430
|
||||
},
|
||||
"id": "KkToPCInQQ1J",
|
||||
"outputId": "418558e8-8c2a-4521-9ef1-6b25b971cff0"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"scatter = plt.scatter(x=encoded_2d[:, 0], y=encoded_2d[:, 1], c=clusters_2d, cmap='viridis')\n",
|
||||
"plt.grid(True, alpha=0.3)\n",
|
||||
"\n",
|
||||
"# Код для легенды\n",
|
||||
"handles, labels = scatter.legend_elements(prop='colors')\n",
|
||||
"plt.legend(handles, labels, loc='best', title='Clusters')\n",
|
||||
"\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Сравните диаграмму с соответствующим результатом из третьей лабораторной работы. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Загрузите данные из остальных файлов (`encoded_3d.npy`, `encoded_2d_include.npy`, `encoded_3d_include.npy`) и также обучите на них по отдельному экземпляру сети Кохонена. Получите метки кластеров и постройте для каждого набора диаграммы рассеяния. Сравните их с соответствующими диаграммами из третьей лабораторной работы."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "QwJagpWTWMIb"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Ваш код здесь"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"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": {
|
||||
"id": "w2UD2JKOWyrb"
|
||||
},
|
||||
"source": [
|
||||
" "
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"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
|
||||
}
|
||||
Ссылка в новой задаче
Block a user