|
|
@ -0,0 +1,313 @@
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cells": [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"# Лабораторная работа 2\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"## 1 Полносвязная нейронная сеть\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"Реализовать нейронную сеть, состоящую из двух полносвязных слоев и решающую задачу классификации на наборе данных из лабораторной работы 1."
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
|
|
"execution_count": 1,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"outputs": [],
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"import numpy as np\n",
|
|
|
|
|
|
|
|
"import matplotlib.pyplot as plt\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"from scripts.classifiers.neural_net import TwoLayerNet\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"%matplotlib inline\n",
|
|
|
|
|
|
|
|
"plt.rcParams['figure.figsize'] = (10.0, 8.0) \n",
|
|
|
|
|
|
|
|
"plt.rcParams['image.interpolation'] = 'nearest'\n",
|
|
|
|
|
|
|
|
"plt.rcParams['image.cmap'] = 'gray'\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"def rel_error(x, y):\n",
|
|
|
|
|
|
|
|
" \"\"\" returns relative error \"\"\"\n",
|
|
|
|
|
|
|
|
" return np.max(np.abs(x - y) / (np.maximum(1e-8, np.abs(x) + np.abs(y))))"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"1. Добавьте реализации методов класса TwoLayerNet . Проверьте вашу реализацию на модельных данных (Код приведен ниже). "
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
|
|
"execution_count": 3,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"outputs": [],
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"input_size = 4\n",
|
|
|
|
|
|
|
|
"hidden_size = 10\n",
|
|
|
|
|
|
|
|
"num_classes = 3\n",
|
|
|
|
|
|
|
|
"num_inputs = 5\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"def init_toy_model():\n",
|
|
|
|
|
|
|
|
" np.random.seed(0)\n",
|
|
|
|
|
|
|
|
" return TwoLayerNet(input_size, hidden_size, num_classes, std=1e-1)\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"def init_toy_data():\n",
|
|
|
|
|
|
|
|
" np.random.seed(1)\n",
|
|
|
|
|
|
|
|
" X = 10 * np.random.randn(num_inputs, input_size)\n",
|
|
|
|
|
|
|
|
" y = np.array([0, 1, 2, 2, 1])\n",
|
|
|
|
|
|
|
|
" return X, y\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"net = init_toy_model()\n",
|
|
|
|
|
|
|
|
"X, y = init_toy_data()"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"# Прямой проход: вычисление выхода сети\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"Реализуйте первую часть метода TwoLayerNet.loss, вычисляющую оценки классов для входных данных. \n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"Сравните ваш выход сети с эталонными значениями. Ошибка должна быть очень маленькой (можете ориентироваться на значение < 1e-7) ."
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"outputs": [],
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"scores = net.loss(X)\n",
|
|
|
|
|
|
|
|
"print('Your scores:')\n",
|
|
|
|
|
|
|
|
"print(scores)\n",
|
|
|
|
|
|
|
|
"print()\n",
|
|
|
|
|
|
|
|
"print('correct scores:')\n",
|
|
|
|
|
|
|
|
"correct_scores = np.asarray([\n",
|
|
|
|
|
|
|
|
" [-0.81233741, -1.27654624, -0.70335995],\n",
|
|
|
|
|
|
|
|
" [-0.17129677, -1.18803311, -0.47310444],\n",
|
|
|
|
|
|
|
|
" [-0.51590475, -1.01354314, -0.8504215 ],\n",
|
|
|
|
|
|
|
|
" [-0.15419291, -0.48629638, -0.52901952],\n",
|
|
|
|
|
|
|
|
" [-0.00618733, -0.12435261, -0.15226949]])\n",
|
|
|
|
|
|
|
|
"print(correct_scores)\n",
|
|
|
|
|
|
|
|
"print()\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"print('Difference between your scores and correct scores:')\n",
|
|
|
|
|
|
|
|
"print(np.sum(np.abs(scores - correct_scores)))"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"# Прямой проход: вычисление loss\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"Реализуйте вторую часть метода, вычисляющую значение функции потерь. Сравните с эталоном. Ошибка должна быть очень маленькой (можете ориентироваться на значение < 1e-12) ."
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"outputs": [],
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"loss, _ = net.loss(X, y, reg=0.05)\n",
|
|
|
|
|
|
|
|
"correct_loss = 1.30378789133\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"print('Difference between your loss and correct loss:')\n",
|
|
|
|
|
|
|
|
"print(np.sum(np.abs(loss - correct_loss)))"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"# Обратный проход\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"Реализуйте третью часть метода loss. Используйте численную реализацию расчета градиента для проверки вашей реализации обратного прохода. Если прямой и обратный проходы реализованы верно, то ошибка будет < 1e-8 для каждой из переменных W1, W2, b1, и b2. \n"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"outputs": [],
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"from scripts.gradient_check import eval_numerical_gradient\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"loss, grads = net.loss(X, y, reg=0.05)\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"for param_name in grads:\n",
|
|
|
|
|
|
|
|
" f = lambda W: net.loss(X, y, reg=0.05)[0]\n",
|
|
|
|
|
|
|
|
" param_grad_num = eval_numerical_gradient(f, net.params[param_name], verbose=False)\n",
|
|
|
|
|
|
|
|
" print('%s max relative error: %e' % (param_name, rel_error(param_grad_num, grads[param_name])))"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"# Обучение нейронной сети на смоделированных данных\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"Реализуйте методы TwoLayerNet.train и TwoLayerNet.predict. Обучайте сеть до тех пор, пока значение loss не будет < 0.02.\n"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"outputs": [],
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"net = init_toy_model()\n",
|
|
|
|
|
|
|
|
"stats = net.train(X, y, X, y,\n",
|
|
|
|
|
|
|
|
" learning_rate=1e-1, reg=5e-6,\n",
|
|
|
|
|
|
|
|
" num_iters=100, verbose=False)\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"print('Final training loss: ', stats['loss_history'][-1])\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"plt.plot(stats['loss_history'])\n",
|
|
|
|
|
|
|
|
"plt.xlabel('iteration')\n",
|
|
|
|
|
|
|
|
"plt.ylabel('training loss')\n",
|
|
|
|
|
|
|
|
"plt.title('Training Loss history')\n",
|
|
|
|
|
|
|
|
"plt.show()"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"# Обучение нейронной сети на реальном наборе данных (CIFAR-10, MNIST)"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"Загрузите набор данных, соответствующий вашему варианту. \n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"Разделите данные на обучающую, тестовую и валидационную выборки.\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"Выполните предобработку данных, как в ЛР 1. \n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"Обучите нейронную сеть на ваших данных. \n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"При сдаче лабораторной работы объясните значения всех параметров метода train."
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"outputs": [],
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"input_size = 32 * 32 * 3\n",
|
|
|
|
|
|
|
|
"hidden_size = 50\n",
|
|
|
|
|
|
|
|
"num_classes = 10\n",
|
|
|
|
|
|
|
|
"net = TwoLayerNet(input_size, hidden_size, num_classes)\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"stats = net.train(X_train, y_train, X_val, y_val,\n",
|
|
|
|
|
|
|
|
" num_iters=1000, batch_size=200,\n",
|
|
|
|
|
|
|
|
" learning_rate=1e-4, learning_rate_decay=0.95,\n",
|
|
|
|
|
|
|
|
" reg=0.25, verbose=True)\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"val_acc = (net.predict(X_val) == y_val).mean()\n",
|
|
|
|
|
|
|
|
"print('Validation accuracy: ', val_acc)"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"Используя параметры по умолчанию, вы можете получить accuracy, примерно равный 0.29. \n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"Проведите настройку гиперпараметров для увеличения accuracy. Поэкспериментируйте со значениями гиперпараметров, например, с количеством скрытых слоев, количеством эпох, скорости обучения и др. Ваша цель - максимально увеличить accuracy полносвязной сети на валидационном наборе. Различные эксперименты приветствуются. Например, вы можете использовать методы для сокращения размерности признакового пространства (например, PCA), добавить dropout слои и др. \n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"Для лучшей модели вычислите acсuracy на тестовом наборе. \n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"Для отладки процесса обучения часто помогают графики изменения loss и accuracy в процессе обучения. Ниже приведен код построения таких графиков. "
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"outputs": [],
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"plt.subplot(2, 1, 1)\n",
|
|
|
|
|
|
|
|
"plt.plot(stats['loss_history'])\n",
|
|
|
|
|
|
|
|
"plt.title('Loss history')\n",
|
|
|
|
|
|
|
|
"plt.xlabel('Iteration')\n",
|
|
|
|
|
|
|
|
"plt.ylabel('Loss')\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"plt.subplot(2, 1, 2)\n",
|
|
|
|
|
|
|
|
"plt.plot(stats['train_acc_history'], label='train')\n",
|
|
|
|
|
|
|
|
"plt.plot(stats['val_acc_history'], label='val')\n",
|
|
|
|
|
|
|
|
"plt.title('Classification accuracy history')\n",
|
|
|
|
|
|
|
|
"plt.xlabel('Epoch')\n",
|
|
|
|
|
|
|
|
"plt.ylabel('Classification accuracy')\n",
|
|
|
|
|
|
|
|
"plt.legend()\n",
|
|
|
|
|
|
|
|
"plt.show()"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"outputs": [],
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"from scripts.vis_utils import visualize_grid\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"def show_net_weights(net):\n",
|
|
|
|
|
|
|
|
" W1 = net.params['W1']\n",
|
|
|
|
|
|
|
|
" W1 = W1.reshape(32, 32, 3, -1).transpose(3, 0, 1, 2)\n",
|
|
|
|
|
|
|
|
" plt.imshow(visualize_grid(W1, padding=3).astype('uint8'))\n",
|
|
|
|
|
|
|
|
" plt.gca().axis('off')\n",
|
|
|
|
|
|
|
|
" plt.show()\n",
|
|
|
|
|
|
|
|
"\n",
|
|
|
|
|
|
|
|
"show_net_weights(net)"
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"source": [
|
|
|
|
|
|
|
|
"Сделайте выводы по результатам первой части работы. "
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
|
|
|
"metadata": {},
|
|
|
|
|
|
|
|
"outputs": [],
|
|
|
|
|
|
|
|
"source": []
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
"metadata": {
|
|
|
|
|
|
|
|
"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.4"
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
"nbformat": 4,
|
|
|
|
|
|
|
|
"nbformat_minor": 2
|
|
|
|
|
|
|
|
}
|