Физтех.Статистика
Скачать ipynb
Введение в анализ данных¶
Домашнее задание 4. Нейронные сети.¶
Правила, прочитайте внимательно:
- Выполненную работу нужно отправить телеграм-боту
@miptstats_ds24_bot
. Для начала работы с ботом каждый раз отправляйте/start
. Работы, присланные иным способом, не принимаются. - Дедлайн см. в боте. После дедлайна работы не принимаются кроме случаев наличия уважительной причины.
- Прислать нужно ноутбук в формате
ipynb
. - Следите за размером файлов. Бот не может принимать файлы весом более 20 Мб. Если файл получается больше, заранее разделите его на несколько.
- Выполнять задание необходимо полностью самостоятельно. При обнаружении списывания все участники списывания будут сдавать устный зачет.
- Решения, размещенные на каких-либо интернет-ресурсах, не принимаются. Кроме того, публикация решения в открытом доступе может быть приравнена к предоставлении возможности списать.
- Для выполнения задания используйте этот ноутбук в качестве основы, ничего не удаляя из него. Можно добавлять необходимое количество ячеек.
- Комментарии к решению пишите в markdown-ячейках.
- Выполнение задания (ход решения, выводы и пр.) должно быть осуществлено на русском языке.
- Если код будет не понятен проверяющему, оценка может быть снижена.
- Никакой код из данного задания при проверке запускаться не будет. Если код студента не выполнен, недописан и т.д., то он не оценивается.
Правила оформления теоретических задач:
- Решения необходимо прислать одним из следующих способов:
- фотографией в правильной ориентации, где все четко видно, а почерк разборчив,
- отправив ее как файл боту вместе с ноутбуком или
- вставив ее в ноутбук посредством
Edit -> Insert Image
;
- в виде $LaTeX$ в markdown-ячейках.
- фотографией в правильной ориентации, где все четко видно, а почерк разборчив,
- Решения не проверяются, если какое-то требование не выполнено. Особенно внимательно все проверьте в случае выбора второго пункта (вставки фото в ноутбук). Неправильно вставленные фотографии могут не передаться при отправке. Для проверки попробуйте переместить
ipynb
в другую папку и открыть его там. - В решениях поясняйте, чем вы пользуетесь, хотя бы кратко. Например, если пользуетесь независимостью, то достаточно подписи вида "X и Y незав."
- Решение, в котором есть только ответ, и отсутствуют вычисления, оценивается в 0 баллов.
Баллы за задание:
Легкая часть (достаточно на "хор"):
- Задача 1 — 60 баллов
- Задача 2 — 30 баллов
Сложная часть (необходимо на "отл"):
- Задача 3 — 60 баллов
# Bot check
# HW_ID: fpmi_ad4
# Бот проверит этот ID и предупредит, если случайно сдать что-то не то.
# Status: not final
# Перед отправкой в финальном решении удали "not" в строчке выше.
# Так бот проверит, что ты отправляешь финальную версию, а не промежуточную.
# Никакие значения в этой ячейке не влияют на факт сдачи работы.
import numpy as np
import scipy.stats as sps
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(font_scale=1.2, palette='Set2')
%matplotlib inline
Перед выполнением задания обязательно посмотрите презентацию и обучающий ноутбук с занятия по нейронным сетям.
Легкая часть¶
Задача 1.¶
Рассмотрим двухслойную нейронную сеть, которая принимает на вход $x\in\mathbb{R}$ и возвращает $y\in\mathbb{R}$. Выход первого слоя возвращает $u \in\mathbb{R}^2$. После первого слоя используется функция активации $\sigma(x) = \frac{1}{1 + \exp(-x)}$, после второго слоя функция активации не используется (или используется тождественная). Тем самым нашу нейронную можно представить в виде
$$\widehat{y}(x) = \sum_{h=1}^2 w_{2h}u_h(x) + b_2,$$$$u_h(x) = \sigma(w_{1h}x + b_{1h}),$$$$\text{где} \; h \in \{1, 2\}.$$1. Нарисуйте схематически данную нейронную сеть. Сколько у нее обучаемых параметров?
...
2. Пусть нам дана обучающая выборка $(X_1, Y_1), ..., (X_n, Y_n)$, где $X_i \in \mathbb{R}$ и $Y_i \in \mathbb{R}$. Нейронная сеть обучается по этой выборке, минимизируя заданную функцию $L$ — функцию ошибки. Положим, что $L$ — это MSE: $$\text{MSE} = L(X, Y) = \frac{1}{n}\sum_{i=1}^n \big(Y_i - \widehat{y}(X_i)\big)^2.$$
Наша задача — найти оптимальные параметры нашей модели для минимизации $L(X, Y)$ на заданном наборе данных. Мы будем решать эту задачу с помощью градиентного спуска. Для этого нам понадобится выписать производные по всем параметрам сети. Конечно, в данном случае довольно просто выписать все производные напрямую. Однако мы воспользуемся следующей хитростью: мы будем считать производные поэтапно, причем начнем с конца вычислительной цепочки и, используя формулу производной сложной функции, последовательно посчитаем все необходимые производные. Этот процесс называется методом обратного распространения ошибки (backpropagation).
2.1. Начнем с производной MSE по выходам сети $$\frac{\partial\:\text{MSE}}{\partial \widehat{y}(X_i)} = \; ...$$
2.2 Возьмем производные выходов сети по параметрам последнего слоя
$$\frac{\partial \widehat{y}(X_i)}{\partial w_{2h}} = \; ...$$$$\frac{\partial \widehat{y}(X_i)}{\partial b_2} = \; ...$$Также выпишем производные выходов сети по входам последнего слоя
$$\frac{\partial \widehat{y}(X_i)}{\partial u_h(X_i)} = \; ...$$Теперь выпишем производные MSE по параметрам и входам последнего слоя. Для этого вспомните правило производной сложной функции из математического анализа. Обратите внимание на то, что нам не нужно прописывать все производные до конца, достаточно заполнить пропуски в записи ниже:
$$\frac{\partial\:\text{MSE}}{\partial w_{2h}} = \sum_{i=1}^n \frac{\partial\:\text{MSE}}{\partial ...} \frac{\partial ...}{\partial w_{2h}}$$$$\frac{\partial\:\text{MSE}}{\partial b_2} = \sum_{i=1}^n \frac{\partial\:\text{MSE}}{\partial ...} \frac{\partial ...}{\partial b_2}$$$$\frac{\partial\:\text{MSE}}{\partial u_h} = \sum_{i=1}^n \frac{\partial\:\text{MSE}}{\partial ...} \frac{\partial ...}{\partial u_h}$$2.2. Теперь будем разбираться с производными по параметрам первого слоя.
Для начала нам пригодится производная функции активации, запишите ее так, чтобы ответе осталась функция от $\sigma(x)$
$$\frac{\partial\:\sigma(x)}{\partial x} = \; ...$$Теперь возьмем производные выходов первого слоя по его параметрам
$$\frac{\partial u_h(X_i)}{\partial w_{1h}} = \; ...$$$$\frac{\partial u_h(X_i)}{\partial b_{1h}} = \; ...$$Наконец, выпишем производные MSE по параметрам первого слоя. Так же как и раньше достаточно заполнить пропуски в записи ниже
$$\frac{\partial\:\text{MSE}}{\partial w_{1h}} = \; \sum_{i=1}^n \frac{\partial\:\text{MSE}}{\partial ...} \frac{\partial ...}{\partial w_{1h}}$$$$\frac{\partial\:\text{MSE}}{\partial b_{1h}} = \; \sum_{i=1}^n \frac{\partial\:\text{MSE}}{\partial ...} \frac{\partial ...}{\partial b_{1h}}$$3. Пусть обучающая выборка очень большая. Что нужно делать в таком случае? Запишите, как нужно поменять правило обновления параметров.
...
Вывод: ...
Задача 2.¶
Напишите нейронную сеть из задачи 1 с помощью библиотеки pytorch
, используя Sequential-стиль. Перед выполнением задачи рекомендуется посмотреть ноутбук с занятия. Функция активации реализована как torch.nn.Sigmoid
.
Внимание. Для выполнения задачи потребуется установить библиотеку pytorch
. Альтернативный вариант — выполнение в Google Colab. Учитывайте, что при длительном бездействии Colab может сам завершить работу ядра.
Сгенерируем данные. Возьмите какую-либо нелинейную функцию $y(x)$.
sample_size = int(1e6)
X = sps.norm.rvs(size=(sample_size, 1))
y = ...
assert y.shape == (sample_size,)
Обучите нейросеть на этих данных. Используйте код с занятия.
Визуализируйте предсказания и посчитайте MSE на тестовой части данных.
Вывод: ...
Сложная часть¶
Задача 3.¶
Теперь реализуйте класс нейронной сети из задачи 1 в стиле scikit-learn, например, см. шаблон класса задачи 4 из задания 3. Предусмотрите возможность обучения по случайным батчам. При реализации можно использовать только библиотеку numpy
.
Обучите нейронную сеть на рассмотренных ранее данных, а также простую линейную регрессию. Для линейной регрессии стоит взять реализацию из sklearn
. Сравните эту нейросеть, линейную регрессию и pytorch-сеть из задачи 2.
Визуализируйте предсказания данных моделей и посчитайте MSE на тестовой части данных.
Повторите вычисления для другой нелинейной функции $y(x)$.
Вывод: ...