{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "### ЛАБОРАТОРНАЯ РАБОТА №1.2\n", "## ИЗУЧЕНИЕ ОСНОВНЫХ ПОНЯТИЙ ТЕОРИИ ИСКУССТВЕННЫХ НЕЙРОННЫХ СЕТЕЙ" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> Цель работы: изучение основных понятий теории искусственных нейронных сетей на примере простых задач распознавания логических функций («И», «ИЛИ», «исключающее ИЛИ»)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Импорт библиотек:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "bvIkPEqTXcpG" }, "outputs": [], "source": [ "import numpy as np\n", "import torch\n", "import matplotlib.pyplot as plt\n", "from IPython.display import clear_output\n", "\n", "from torch import nn\n", "\n", "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В заключительной части данной лабораторной работы мы применяем PyTorch — современный фреймворк для научных вычислений и глубокого обучения в Python.\n", "\n", "PyTorch во многом напоминает NumPy по принципам работы и синтаксису:\n", "- оперирует многомерными массивами (в PyTorch они называются *тензорами*, или *Tensors*), которые являются прямым аналогом `ndarray` из NumPy;\n", "- поддерживает похожий синтаксис для базовых операций: индексация, срезы, арифметические действия;\n", "- реализует векторизованные вычисления и механизм broadcasting (широковещательное сложение);\n", "- позволяет выполнять стандартные математические операции с интуитивно понятными методами (например, `tensor.mean()` в PyTorch аналогичен `array.mean()` в NumPy).\n", "\n", "\n", "Некоторые основные компоненты PyTorch:\n", "\n", "1. Тензоры (Tensors) \n", " - многомерные массивы с поддержкой вычислений на GPU;\n", " - аналог `numpy.ndarray`, но с расширенными возможностями для машинного обучения.\n", "\n", "\n", "2. Автоматическое дифференцирование (Autograd) \n", " - механизм для автоматического вычисления градиентов;\n", " - критически важен для обучения нейронных сетей (реализует алгоритм обратного распространения ошибки). \n", " \n", "\n", "3. Модули (nn.Module) \n", " - базовые строительные блоки для создания нейронных сетей;\n", " - включают слои, функции активации, функции потерь и др.\n", "\n", "\n", "4. Оптимизаторы (optim) \n", " - реализации популярных алгоритмов оптимизации: SGD, Adam, RMSprop и др.;\n", " - упрощают обновление параметров модели.\n", "\n", "\n", "Ключевые возможности PyTorch:\n", "\n", "- Создание и обучение нейронных сетей любой сложности — от простых перцептронов до трансформеров.\n", "- Вычисления на CPU и GPU с минимальным изменением кода (достаточно переместить тензоры на устройство `cuda`).\n", "- Динамические вычислительные графы — в отличие от статических графов в некоторых других фреймворках, PyTorch строит граф операций «на лету», что упрощает отладку и эксперименты.\n", "- Гибкость в проектировании архитектур — легко создавать кастомные слои и модели, переопределять методы обратного прохода.\n", "\n", "\n", "Преимущества для исследований и разработки:\n", "\n", "- Интуитивный интерфейс, близкий к NumPy — низкий порог входа для тех, кто знаком с NumPy.\n", "- Гибкая система наследования — возможность создавать собственные модули и слои.\n", "- Обширное сообщество — множество туториалов, примеров, библиотек и форумов.\n", "- Совместимость с другими библиотеками — лёгкая интеграция с NumPy, SciPy, Matplotlib и др.\n", "- Производительность — ускорение вычислений на GPU (в 10–100 раз по сравнению с CPU для крупных задач).\n", "\n", "\n", "Официальная документация: https://pytorch.org/docs/stable/index.html" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В качестве примера вышесказанного переписанная на PyTorch метрика accuracy: " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "l4lzUxFY0ej5" }, "outputs": [], "source": [ "def accuracy(y_pred, y_true):\n", " return torch.sum(y_pred == y_true) / len(y_true)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Содержание: \n", "[1. Решение задачи логического «И»](#p_1) \n", "[2. Решение задачи логического «ИЛИ»](#p_2) \n", "[3. Решение задачи логического «исключающего ИЛИ»](#p_3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1. Решение задачи логического «И»" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Представим входные данные для решения задачи логического «И» в виде тензора `X_data`.\n", "\n", "Операции в нейронных сетях (умножение весов, активация, вычисление градиентов) выполняются только с вещественными числами, поэтому через `.float()` приводим тензор к вещественному типу данных — иначе далее возможна ошибка типа данных." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "Ej0DmW9uXlG0", "outputId": "b3821094-83d4-40f1-faa6-7773535b9ea6" }, "outputs": [], "source": [ "X_data = torch.tensor([[0, 0], [0, 1], [1, 0], [1, 1]]).float()\n", "print(X_data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Аналогичная операция с выходным вектором:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "khRrzE2fXlR4", "outputId": "a1aa980e-fa15-4c7c-ba68-18f0f5588f7f" }, "outputs": [], "source": [ "y_and_data = torch.tensor([0, 0, 0, 1]).reshape(-1, 1).float()\n", "print(y_and_data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Создание нейронной сети в PyTorch: последовательная модель**\n", "\n", "Один из самых простых и наглядных способов создать нейронную сеть в PyTorch — использовать `nn.Sequential`. Это контейнер, который организует слои в последовательный пайплайн: данные проходят через каждый слой по порядку, от входа к выходу — выход предыдущего слоя автоматически становится входом следующего.\n", "\n", "Создадим данным способом нейронную сеть `model_seq` с одним слоем нейронов.\n", "\n", "Пояснения к выбранным слоям в её архитектуре:\n", " 1. `nn.Linear(in_features=2, out_features=1)` — полностью соединённый (плотный, полносвязный) слой. \n", " \n", " Параметры:\n", " - `in_features=2` — размерность входного вектора (2 признака, соответствующие входам логической операции);\n", " - `out_features=1` — размерность выхода (1 нейрон для итогового результата).\n", " \n", " Математическая операция: \n", " $$\n", " y = W \\cdot X + b,\n", " $$ \n", "\n", " 2. `nn.Sigmoid()` — функция активации (сигмоида).\n", " \n", "После создания экземпляр `model_seq` можно:\n", "- вызывать как функцию: `model_seq(X_data)` — прямой проход через сеть;\n", "- получать параметры: `model_seq.parameters()` — для оптимизации;\n", "- выводить структуру: печать `model_seq` покажет последовательность слоёв." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "gqr4pECOoDpG", "outputId": "145244ca-2ede-498b-8a01-9841f6df041e" }, "outputs": [], "source": [ "model_seq = nn.Sequential(\n", " nn.Linear(in_features=2, out_features=1),\n", " nn.Sigmoid()\n", ")\n", "\n", "model_seq" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Переберём все обучаемые параметры сети `model_seq` — результатом будет список тензоров, содержащих исходные веса и смещения сети:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "32TRT1kv9_Ln", "outputId": "49e48ed3-3909-46d6-ac66-c0b59d1b9a5b" }, "outputs": [], "source": [ "[x for x in model_seq.parameters()]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Обратите внимание в выводе на флаг `requires_grad=True`.\n", "\n", "Он указывает, что для этого тензора в процессе обратного распространения ошибки нужно будет вычислять градиенты (производные) всех математических операций, через которые далее в коде этот тензор проходит. Без этого флага параметры не будут обновляться при обучении. Флаг при задании тензора также можно переключать на `False`.\n", "\n", "Как это работает:\n", "\n", " 1. Во время прямого прохода (`forward`) PyTorch строит вычислительный граф, запоминая операции с тензорами, у которых `requires_grad=True`.\n", " 2. При вызове `loss.backward()` автоматически вычисляются градиенты по всем параметрам с `requires_grad=True`, при этом значение каждое градиенты сохраняются в атрибуте `.grad` тензора.\n", " 3. Оптимизатор (объект, реализующий алгоритм обновления параметров модели на основе вычисленных градиентов — например, SGD) использует эти градиенты для обновления параметров." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Рассмотрим всё на примере.\n", "\n", "Выберем в качестве оптимизатора параметров `model_seq` SGD (с достаточно большим шагом обучения `lr` для наглядности) и среднеквадратичную функцию потерь:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "DMJYrTlE-VqS" }, "outputs": [], "source": [ "optimizer = torch.optim.SGD(model_seq.parameters(), lr=1.5)\n", "criterion = nn.MSELoss()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Пропустим входные данные `X_data` через `model_seq`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "5xiqGW-opJNK", "outputId": "44183227-fe44-45f7-fb95-3dff575d702e" }, "outputs": [], "source": [ "z = model_seq(X_data)\n", "z" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Атрибут `grad_fn=` в выводе обозначает:\n", "- Тензор `z` — результат работы сигмоиды в последнем слое сети;\n", "- PyTorch «запомнил» эту операцию в своём вычислительном графе;\n", "- При обратном распространении ошибки градиенты будут корректно рассчитаны по формуле производной сигмоиды и переданы дальше в сеть." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Рассчитаем значение функции потерь:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "kn_XCMP8-fVm", "outputId": "f5813ee6-a1f3-4b34-acee-77978ecf7b8f" }, "outputs": [], "source": [ "loss = criterion(z, y_and_data)\n", "loss" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В атрибуте `grad_fn=` аналогично видно, что в вычислительном графе к тензорам применена функция среднеквадратичной ошибки.\n", "\n", "Вычислим градиенты функции потерь по всем параметрам модели согласно вычислительному графу:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "kWc5ip2O-wKp" }, "outputs": [], "source": [ "loss.backward()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Обновим с помошью оптимизатора все параметры сети: " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "dxh8RIJV-1Hy" }, "outputs": [], "source": [ "optimizer.step()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Посмотрим значения обновлённых параметров:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "AQt5IglN_BJx", "outputId": "b916e29e-874d-4396-a447-3556d5b5757e" }, "outputs": [], "source": [ "[x for x in model_seq.parameters()]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Метод `optimizer.zero_grad()` вызывается обязательно перед каждым последующим обратным проходом (`loss.backward()`) в цикле обучения для **обнуления градиентов всех параметров** модели, управляемых этим оптимизатором.\n", "\n", "Почему это необходимо? \n", "\n", "В PyTorch градиенты по умолчанию накапливаются (суммируются) при каждом вызове `loss.backward()`. Если не обнулять градиенты:\n", "- значения градиентов будут расти с каждой итерацией;\n", "- веса модели начнут обновляться некорректно (с учётом «старых» градиентов);\n", "- возможен эффект «взрывных градиентов» (gradients explode), когда значения становятся настолько большими, что превращаются в `NaN` (не число)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "KRD01eVD_yjE" }, "outputs": [], "source": [ "optimizer.zero_grad()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Сделайте несколько проходов (итераций) от [первого шага обратного распространения ошибки](#loop_and) до данной ячейки. Убедитесь, что ошибка сети `loss` понижается." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Рассмотрим ещё один способ создания сети в PyTorch.\n", "\n", "**Создание нейронной сети в PyTorch: через ООП**\n", "\n", "В PyTorch принято определять архитектуры нейронных сетей как классы, наследующие от `nn.Module`. Это позволяет:\n", "- структурировать код в виде повторно используемых компонентов;\n", "- чётко разделять инициализацию параметров (`__init__`) и прямой проход (`forward`);\n", "- легко расширять и модифицировать модели;\n", "- использовать встроенные механизмы PyTorch (оптимизаторы, сохранение/загрузка моделей).\n", "\n", "Пример сети с одним полносвязным слоем и сигмоидой в качестве функции активации:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "PF5yli7WXlVd" }, "outputs": [], "source": [ "class OneLayerNetwork(nn.Module):\n", " def __init__(self, n_inputs=2, n_outputs=1):\n", " super().__init__()\n", " self.model = nn.Sequential(\n", " nn.Linear(in_features=n_inputs, out_features=n_outputs),\n", " nn.Sigmoid()\n", " )\n", "\n", " def forward(self, X):\n", " return self.model(X)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Сейчас все слои для удобства по-прежнему собраны в `nn.Sequential`. Чтобы повысить гибкость модели, в методе `__init__` можно по отдельности задать все необходимые слои, а в `forward` — определять порядок их применения. Такой способ даёт больше контроля над архитектурой (пример разберём в одной из следующих лабораторных работ).\n", "\n", "Сигмоиду здесь можно также заменить на `nn.ReLU` или другую функцию активации — но для отделения от экземплятор с исходной архитектурой создайте другой класс (например, `OneLayerReLUNetwork()`)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Создадим экземпляр однослойной сети этого класса для решения задачи логического «И»:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "kIuQLzUIwVwC", "outputId": "91aa25b7-aae4-4655-e83b-4abac88531c8" }, "outputs": [], "source": [ "model_one_layer = OneLayerNetwork()\n", "model_one_layer" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "По аналогии с прошлым ноутбуком зададим \n", " - данные для обучения (входные и выходные);\n", " - экземпляр нейронной сети (через последовательность `nn.Sequential()` или класс `OneLayerNetwork()`);\n", " - количество эпох или итераций в процессе обучения (желательно больше 5);\n", " - скорость обучение и коэффициент импульса;\n", " - оптимизатор (попробуйте разные алгоритмы — `torch.optim.SGD()`, `torch.optim.Adam()` и другие) (значение `learning_rate` передаётся в `lr`) (учтите, что в `torch.optim.Adam()` нет импульса);\n", " - функцию потерь (можно оставить `nn.MSELoss()`, однако поскольку решается задача бинарной классификации, можно выбрать бинарную кросс-энтропию `nn.BCELoss()`).\n", " \n", " \n", "*Примечание*. Вы можете использовать для обучения сети либо код ниже, либо модифицированный на его основе — например, реализовать функцию обучения нейронной сети и проверки её работы." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "p09jzhOY3MyQ" }, "outputs": [], "source": [ "y_true = y_and_data\n", "\n", "# Перебор seed для инициализации параметров\n", "torch.manual_seed(seed=42)\n", "\n", "model = # Ваш код здесь\n", "\n", "epochs = # Ваш код здесь\n", "\n", "learning_rate = # Ваш код здесь\n", "momentum = # Ваш код здесь\n", "\n", "optimizer = # Ваш код здесь\n", "criterion = # Ваш код здесь" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Обучение нейронной сети для решения задачи логического «И»:**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 556 }, "id": "qKimvoStsZXv", "outputId": "725ec1a2-2d68-4f24-91c6-3469a39efbc4" }, "outputs": [], "source": [ "loss_history = []\n", "\n", "for epoch in range(epochs):\n", " \n", " # Метод .train() переводит модель в режим обучения\n", " model.train()\n", "\n", " optimizer.zero_grad()\n", "\n", " z = model(X_data)\n", " model_answer_interpretation = (z >= 0.5).float()\n", "\n", " loss = criterion(z, y_true)\n", " \n", " # Метод .item() извлекает скалярное значение из тензора loss\n", " loss_history.append(loss.item())\n", "\n", " loss.backward()\n", "\n", " optimizer.step()\n", " \n", " # Метод .eval() переводит модель в режим валидации/тестирования (об этом в следующей лабораторной)\n", " model.eval()\n", "\n", " if (epoch + 1) % 5 == 0:\n", "\n", " clear_output(True)\n", " plt.plot(range(1, epoch+2), loss_history, label='Loss')\n", " plt.title(f'Epoch: {epoch + 1}, Loss: {loss:.6f}')\n", " plt.grid(True, alpha=0.3)\n", " plt.legend(loc='best')\n", " plt.show()\n", "\n", " print('Test:')\n", " for i in range(len(X_data)):\n", " # Метод .detach() создаёт копию тензора, отсоединённую от вычислительного графа,\n", " # чтобы избежать ненужного вычисления градиентов для исходного тензора\n", " print(f'Input: {X_data.numpy()[i]}, Output: {torch.round(z[i].detach() * 100).numpy() / 100}, Prediction: {model_answer_interpretation[i].numpy()}, True: {y_true[i].numpy()}')\n", "\n", " print(f'Accuracy: {accuracy(model_answer_interpretation, y_true):.2f}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Проверим качество обучения сети:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "assert accuracy(model_answer_interpretation, y_and_data) == 1\n", "assert np.mean(loss_history[:5]) > np.mean(loss_history[-5:])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Поэкспериметируйте с параметрами обучения — сделайте несколько вариантов с разными функциями потерь, оптимизаторами, значениями скорости обучения и коэффициента импульса. Выберите лучшие по качеству обучения и количеству эпох." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2. Решение задачи логического «ИЛИ»" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "По аналогии с задачей логического «И» решите задачу логического «ИЛИ».\n", "\n", "Выходные данные:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "UGFSsTGh4Xyp", "outputId": "40e554c0-51a0-4adb-ca8b-8e46c83c2e7d" }, "outputs": [], "source": [ "y_or_data = torch.tensor([0, 1, 1, 1]).reshape(-1, 1).float()\n", "print(y_or_data)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Ваш код здесь" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Ваш код здесь" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Проверьте качество обучения сети:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "assert accuracy(model_answer_interpretation, y_or_data) == 1\n", "assert np.mean(loss_history[:5]) > np.mean(loss_history[-5:])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Поэкспериметируйте с параметрами обучения — сделайте несколько вариантов с разными функциями потерь, оптимизаторами, значениями скорости обучения и коэффициента импульса. Выберите лучшие по качеству обучения и количеству эпох." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. Решение задачи логического «исключающего ИЛИ»" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Выходные данные:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "gNigOR9N5X3z", "outputId": "297e81ad-0eb7-403a-8dbf-0df7706c934e" }, "outputs": [], "source": [ "y_xor_data = torch.tensor([0, 1, 1, 0]).reshape(-1, 1).float()\n", "print(y_xor_data)" ] }, { "cell_type": "markdown", "metadata": { "id": "6hL-mvyF5T58" }, "source": [ "Напомним, что однослойной сетью задачу «исключающего ИЛИ» решить нельзя. В нейронную сеть требуется добавить ещё один слой с как минимум двумя нейронами.\n", "\n", "Модифицируем для этого класс `OneLayerNetwork()` в класс `TwoLayersNetwork()` — в последовательсти в `self.model` добавим ещё один полносвязный слой с сигмоидой для активации. Добавлен также параметр `n_hiddens` — количество нейронов в скрытом слое. Обратите внимание на задание размерности в последовательности слоёв." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "TGcgUAFQtXn7" }, "outputs": [], "source": [ "class TwoLayersNetwork(nn.Module):\n", " def __init__(self, n_inputs=2, n_hiddens=2, n_outputs=1):\n", " super().__init__()\n", " self.model = nn.Sequential(\n", " nn.Linear(in_features=n_inputs, out_features=n_hiddens),\n", " nn.Sigmoid(),\n", " nn.Linear(in_features=n_hiddens, out_features=n_outputs),\n", " nn.Sigmoid()\n", " )\n", "\n", " def forward(self, X):\n", " return self.model(X)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Создадим экземпляр двухслойной сети этого класса для решения задачи «исключающего ИЛИ»:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "afK0vsG1t2oL", "outputId": "bab9683b-fefe-4734-f948-340a353b99c8" }, "outputs": [], "source": [ "model_two_layers = TwoLayersNetwork()\n", "model_two_layers" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "По аналогии с задачами логического «И» и логического «ИЛИ» решите «задачу исключающего ИЛИ»:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Ваш код здесь\n", "\n", "# Вариант задания сети с разным количество нейронов в скрытом слое\n", "n_hiddens = 2\n", "model = TwoLayersNetwork(n_hiddens=n_hiddens)\n", "\n", "# Ваш код здесь" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Проверьте качество обучения сети:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "assert accuracy(model_answer_interpretation, y_xor_data) == 1\n", "assert np.mean(loss_history[:5]) > np.mean(loss_history[-5:])" ] }, { "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": { "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 }