Files
neurocomputers-python/lab3/3.3_image.ipynb

428 строки
15 KiB
Plaintext
Исходник Ответственный История

Этот файл содержит неоднозначные символы Юникода
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### ЛАБОРАТОРНАЯ РАБОТА №3\n",
"## Применение многослойного персептрона. Автоассоциативная ИНС"
]
},
{
"cell_type": "markdown",
"metadata": {},
"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": {},
"source": [
"Импорт библиотек:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "-jndqXPxywKw"
},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"import torch\n",
"import imageio\n",
"import warnings\n",
"\n",
"from torch import nn\n",
"from IPython.display import clear_output\n",
"\n",
"warnings.filterwarnings('ignore')\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": [
"Сохраним в список `X_data` все девять изображений. Каждое из них загрузим в виде NumPy-массива, затем преобразуем данный массив в `float32` и делением на 255 перемасштабируем в его диапазон `[0.0, 1.0]` (было `[0, 255]`). Само исходное изображение (по умолчанию цветное) преобразуем изображение в чёрно‑белое — для чего возьмём среднее по каналам R, G, B для каждого пикселя."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Y03Y-xWo9Br1"
},
"outputs": [],
"source": [
"X_data = []\n",
"\n",
"for i in range(1, 10):\n",
" filename = f'avia{i}.bmp'\n",
" img = imageio.imread(filename)\n",
" img = img.astype('float32') / 255.\n",
" img = np.mean(img, axis=2)\n",
" X_data.append(img)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Список `y_data` содержит в себе ответ — принадлежит ли силуэт на каждом из девяти изображений бомбардировщику (`1` если принадлежит, `0` если не принадлежит):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "HVW-f4IZ6Nvi"
},
"outputs": [],
"source": [
"y_data = [0, 1, 0, 0, 1, 0, 0, 0, 1]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Выведем все девять изображений и подпишем каждое из них:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 865
},
"id": "luwhswXP6NzI",
"outputId": "f6262617-d188-40f7-b38f-37deed860ab9"
},
"outputs": [],
"source": [
"fig, axes = plt.subplots(3, 3, figsize=(9, 9))\n",
"axes = axes.ravel()\n",
"\n",
"for i in range(9):\n",
" axes[i].imshow(X_data[i], cmap='gray')\n",
" aircraft_type = '\\nБомбардировщик' if y_data[i] == 1 else '\\nИстребитель'\n",
" axes[i].set_title(aircraft_type)\n",
" axes[i].axis('off')\n",
"\n",
"plt.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Представим данные в виде тензоров `X_data_tensor` и `y_data_tensor`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "zyU44xbVJ9EE"
},
"outputs": [],
"source": [
"X_data_tensor = torch.tensor(X_data).float()\n",
"y_data_tensor = torch.tensor(y_data).reshape(-1, 1).float()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Проверим размерность `X_data_tensor` — она показывает, что в тензоре лежат девять изображений размером 352 на 346:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "6uROCg66M2Ij",
"outputId": "eeb259ba-c3b2-4df2-b0b8-c5c38c33c416"
},
"outputs": [],
"source": [
"X_data_tensor.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Многослойный персептрон всегда принимает на вход одномерные векторы. Однако в нашей задаче классификации силуэтов саолётов исходные изображения — как видно из размерности, двуомерные тензоры. И чтобы подать их на вход сети, их необходимо «развернуть» в одномерные векторы, сохранив количество объектов (пикселей) неизменным.\n",
"\n",
"Такое преобразование позволяет использовать пространственную информацию пикселей как набор признаков для полносвязных слоёв персептрона.\n",
"\n",
"В PyTorch это можно сделать с помощью метода `.view()` следующим образом:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "Q9BNBxAmKK1Z",
"outputId": "42786382-bf08-4f7f-ffc6-8370db68f156"
},
"outputs": [],
"source": [
"X_data_tensor.view(X_data_tensor.size(0), -1).shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Для проверки перемножим длину и щирину одного из изображений:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "jOLmEcvSPeEH",
"outputId": "f924e2ab-338f-4359-cb8a-93a3318ff675"
},
"outputs": [],
"source": [
"np.prod(X_data[0].shape)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Классификация изображений<a id=\"p_2\"></a>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Реализуйте в классе `ImageClassifier` с помощью полносвязных слоёв `nn.Linear` многослойный персептрон. В качестве промежуточных функций активации используйте `nn.ReLU()`, а в качестве финальной — сигмоиду, поскольку решается задача бинарной классификации."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class ImageClassifier(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",
" x = x.view(x.size(0), -1)\n",
" return self.seq(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Создайте экземпляр модели:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model = ImageClassifier(input_size=# Ваш код здесь\n",
"\n",
"model"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Проверим, что модель при приходе данных возвращает вероятности:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "x3QUCgUnOy_Z",
"outputId": "be3f4404-b3d5-4bf3-b510-8d7b903e5fc8"
},
"outputs": [],
"source": [
"model(X_data_tensor)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Метрика accuracy:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "WMSGULyhQVNA"
},
"outputs": [],
"source": [
"def accuracy(y_pred, y_true):\n",
" return torch.sum(y_pred == y_true) / len(y_true)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Задайте параметры для обучения нейронной сети:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"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": {},
"outputs": [],
"source": [
"loss_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_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()\n",
"\n",
" print(f'Accuracy: {accuracy((y_prob > 0.5).float(), y_data_tensor).item():.3f}')"
]
},
{
"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
}