|
|
|
@ -1,764 +0,0 @@
|
|
|
|
|
{
|
|
|
|
|
"cells": [
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": [
|
|
|
|
|
"# Лабораторная работа 4"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": [
|
|
|
|
|
"Tensorflow 2.x\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"1) Подготовка данных\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"2) Использование Keras Model API\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"3) Использование Keras Sequential + Functional API"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": [
|
|
|
|
|
"https://www.tensorflow.org/tutorials"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": [
|
|
|
|
|
"Для выполнения лабораторной работы необходимо установить tensorflow версии 2.0 или выше .\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"Рекомендуется использовать возможности Colab'а по обучению моделей на GPU.\n",
|
|
|
|
|
"\n"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
"execution_count": 2,
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"import os\n",
|
|
|
|
|
"import tensorflow as tf\n",
|
|
|
|
|
"import numpy as np\n",
|
|
|
|
|
"import math\n",
|
|
|
|
|
"import timeit\n",
|
|
|
|
|
"import matplotlib.pyplot as plt\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"%matplotlib inline"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": [
|
|
|
|
|
"# Подготовка данных\n",
|
|
|
|
|
"Загрузите набор данных из предыдущей лабораторной работы. "
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"def load_cifar10(num_training=49000, num_validation=1000, num_test=10000):\n",
|
|
|
|
|
" \"\"\"\n",
|
|
|
|
|
" Fetch the CIFAR-10 dataset from the web and perform preprocessing to prepare\n",
|
|
|
|
|
" it for the two-layer neural net classifier. These are the same steps as\n",
|
|
|
|
|
" we used for the SVM, but condensed to a single function.\n",
|
|
|
|
|
" \"\"\"\n",
|
|
|
|
|
" # Load the raw CIFAR-10 dataset and use appropriate data types and shapes\n",
|
|
|
|
|
" cifar10 = tf.keras.datasets.cifar10.load_data()\n",
|
|
|
|
|
" (X_train, y_train), (X_test, y_test) = cifar10\n",
|
|
|
|
|
" X_train = np.asarray(X_train, dtype=np.float32)\n",
|
|
|
|
|
" y_train = np.asarray(y_train, dtype=np.int32).flatten()\n",
|
|
|
|
|
" X_test = np.asarray(X_test, dtype=np.float32)\n",
|
|
|
|
|
" y_test = np.asarray(y_test, dtype=np.int32).flatten()\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" # Subsample the data\n",
|
|
|
|
|
" mask = range(num_training, num_training + num_validation)\n",
|
|
|
|
|
" X_val = X_train[mask]\n",
|
|
|
|
|
" y_val = y_train[mask]\n",
|
|
|
|
|
" mask = range(num_training)\n",
|
|
|
|
|
" X_train = X_train[mask]\n",
|
|
|
|
|
" y_train = y_train[mask]\n",
|
|
|
|
|
" mask = range(num_test)\n",
|
|
|
|
|
" X_test = X_test[mask]\n",
|
|
|
|
|
" y_test = y_test[mask]\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" # Normalize the data: subtract the mean pixel and divide by std\n",
|
|
|
|
|
" mean_pixel = X_train.mean(axis=(0, 1, 2), keepdims=True)\n",
|
|
|
|
|
" std_pixel = X_train.std(axis=(0, 1, 2), keepdims=True)\n",
|
|
|
|
|
" X_train = (X_train - mean_pixel) / std_pixel\n",
|
|
|
|
|
" X_val = (X_val - mean_pixel) / std_pixel\n",
|
|
|
|
|
" X_test = (X_test - mean_pixel) / std_pixel\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" return X_train, y_train, X_val, y_val, X_test, y_test\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"# If there are errors with SSL downloading involving self-signed certificates,\n",
|
|
|
|
|
"# it may be that your Python version was recently installed on the current machine.\n",
|
|
|
|
|
"# See: https://github.com/tensorflow/tensorflow/issues/10779\n",
|
|
|
|
|
"# To fix, run the command: /Applications/Python\\ 3.7/Install\\ Certificates.command\n",
|
|
|
|
|
"# ...replacing paths as necessary.\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"# Invoke the above function to get our data.\n",
|
|
|
|
|
"NHW = (0, 1, 2)\n",
|
|
|
|
|
"X_train, y_train, X_val, y_val, X_test, y_test = load_cifar10()\n",
|
|
|
|
|
"print('Train data shape: ', X_train.shape)\n",
|
|
|
|
|
"print('Train labels shape: ', y_train.shape, y_train.dtype)\n",
|
|
|
|
|
"print('Validation data shape: ', X_val.shape)\n",
|
|
|
|
|
"print('Validation labels shape: ', y_val.shape)\n",
|
|
|
|
|
"print('Test data shape: ', X_test.shape)\n",
|
|
|
|
|
"print('Test labels shape: ', y_test.shape)"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"class Dataset(object):\n",
|
|
|
|
|
" def __init__(self, X, y, batch_size, shuffle=False):\n",
|
|
|
|
|
" \"\"\"\n",
|
|
|
|
|
" Construct a Dataset object to iterate over data X and labels y\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" Inputs:\n",
|
|
|
|
|
" - X: Numpy array of data, of any shape\n",
|
|
|
|
|
" - y: Numpy array of labels, of any shape but with y.shape[0] == X.shape[0]\n",
|
|
|
|
|
" - batch_size: Integer giving number of elements per minibatch\n",
|
|
|
|
|
" - shuffle: (optional) Boolean, whether to shuffle the data on each epoch\n",
|
|
|
|
|
" \"\"\"\n",
|
|
|
|
|
" assert X.shape[0] == y.shape[0], 'Got different numbers of data and labels'\n",
|
|
|
|
|
" self.X, self.y = X, y\n",
|
|
|
|
|
" self.batch_size, self.shuffle = batch_size, shuffle\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" def __iter__(self):\n",
|
|
|
|
|
" N, B = self.X.shape[0], self.batch_size\n",
|
|
|
|
|
" idxs = np.arange(N)\n",
|
|
|
|
|
" if self.shuffle:\n",
|
|
|
|
|
" np.random.shuffle(idxs)\n",
|
|
|
|
|
" return iter((self.X[i:i+B], self.y[i:i+B]) for i in range(0, N, B))\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"train_dset = Dataset(X_train, y_train, batch_size=64, shuffle=True)\n",
|
|
|
|
|
"val_dset = Dataset(X_val, y_val, batch_size=64, shuffle=False)\n",
|
|
|
|
|
"test_dset = Dataset(X_test, y_test, batch_size=64)"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"# We can iterate through a dataset like this:\n",
|
|
|
|
|
"for t, (x, y) in enumerate(train_dset):\n",
|
|
|
|
|
" print(t, x.shape, y.shape)\n",
|
|
|
|
|
" if t > 5: break"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": []
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": [
|
|
|
|
|
"\n"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": [
|
|
|
|
|
"# Keras Model Subclassing API"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": [
|
|
|
|
|
"\n",
|
|
|
|
|
"Для реализации собственной модели с помощью Keras Model Subclassing API необходимо выполнить следующие шаги:\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"1) Определить новый класс, который является наследником tf.keras.Model.\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"2) В методе __init__() определить все необходимые слои из модуля tf.keras.layer\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"3) Реализовать прямой проход в методе call() на основе слоев, объявленных в __init__()\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"Ниже приведен пример использования keras API для определения двухслойной полносвязной сети. \n",
|
|
|
|
|
"\n",
|
|
|
|
|
"https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/keras"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"class TwoLayerFC(tf.keras.Model):\n",
|
|
|
|
|
" def __init__(self, hidden_size, num_classes):\n",
|
|
|
|
|
" super(TwoLayerFC, self).__init__() \n",
|
|
|
|
|
" initializer = tf.initializers.VarianceScaling(scale=2.0)\n",
|
|
|
|
|
" self.fc1 = tf.keras.layers.Dense(hidden_size, activation='relu',\n",
|
|
|
|
|
" kernel_initializer=initializer)\n",
|
|
|
|
|
" self.fc2 = tf.keras.layers.Dense(num_classes, activation='softmax',\n",
|
|
|
|
|
" kernel_initializer=initializer)\n",
|
|
|
|
|
" self.flatten = tf.keras.layers.Flatten()\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" def call(self, x, training=False):\n",
|
|
|
|
|
" x = self.flatten(x)\n",
|
|
|
|
|
" x = self.fc1(x)\n",
|
|
|
|
|
" x = self.fc2(x)\n",
|
|
|
|
|
" return x\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"def test_TwoLayerFC():\n",
|
|
|
|
|
" \"\"\" A small unit test to exercise the TwoLayerFC model above. \"\"\"\n",
|
|
|
|
|
" input_size, hidden_size, num_classes = 50, 42, 10\n",
|
|
|
|
|
" x = tf.zeros((64, input_size))\n",
|
|
|
|
|
" model = TwoLayerFC(hidden_size, num_classes)\n",
|
|
|
|
|
" with tf.device(device):\n",
|
|
|
|
|
" scores = model(x)\n",
|
|
|
|
|
" print(scores.shape)\n",
|
|
|
|
|
" \n",
|
|
|
|
|
"test_TwoLayerFC()"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": [
|
|
|
|
|
"Реализуйте трехслойную CNN для вашей задачи классификации. \n",
|
|
|
|
|
"\n",
|
|
|
|
|
"Архитектура сети:\n",
|
|
|
|
|
" \n",
|
|
|
|
|
"1. Сверточный слой (5 x 5 kernels, zero-padding = 2)\n",
|
|
|
|
|
"2. Функция активации ReLU \n",
|
|
|
|
|
"3. Сверточный слой (3 x 3 kernels, zero-padding = 1)\n",
|
|
|
|
|
"4. Функция активации ReLU \n",
|
|
|
|
|
"5. Полносвязный слой \n",
|
|
|
|
|
"6. Функция активации Softmax \n",
|
|
|
|
|
"\n",
|
|
|
|
|
"https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/keras/layers/Conv2D\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/keras/layers/Dense"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"class ThreeLayerConvNet(tf.keras.Model):\n",
|
|
|
|
|
" def __init__(self, channel_1, channel_2, num_classes):\n",
|
|
|
|
|
" super(ThreeLayerConvNet, self).__init__()\n",
|
|
|
|
|
" ########################################################################\n",
|
|
|
|
|
" # TODO: Implement the __init__ method for a three-layer ConvNet. You #\n",
|
|
|
|
|
" # should instantiate layer objects to be used in the forward pass. #\n",
|
|
|
|
|
" ########################################################################\n",
|
|
|
|
|
" # *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" pass\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" # *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
|
|
|
|
|
" ########################################################################\n",
|
|
|
|
|
" # END OF YOUR CODE #\n",
|
|
|
|
|
" ########################################################################\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" def call(self, x, training=False):\n",
|
|
|
|
|
" scores = None\n",
|
|
|
|
|
" ########################################################################\n",
|
|
|
|
|
" # TODO: Implement the forward pass for a three-layer ConvNet. You #\n",
|
|
|
|
|
" # should use the layer objects defined in the __init__ method. #\n",
|
|
|
|
|
" ########################################################################\n",
|
|
|
|
|
" # *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" pass\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" # *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
|
|
|
|
|
" ########################################################################\n",
|
|
|
|
|
" # END OF YOUR CODE #\n",
|
|
|
|
|
" ######################################################################## \n",
|
|
|
|
|
" return scores"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"def test_ThreeLayerConvNet(): \n",
|
|
|
|
|
" channel_1, channel_2, num_classes = 12, 8, 10\n",
|
|
|
|
|
" model = ThreeLayerConvNet(channel_1, channel_2, num_classes)\n",
|
|
|
|
|
" with tf.device(device):\n",
|
|
|
|
|
" x = tf.zeros((64, 3, 32, 32))\n",
|
|
|
|
|
" scores = model(x)\n",
|
|
|
|
|
" print(scores.shape)\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"test_ThreeLayerConvNet()"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": [
|
|
|
|
|
"Пример реализации процесса обучения:"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"def train_part34(model_init_fn, optimizer_init_fn, num_epochs=1, is_training=False):\n",
|
|
|
|
|
" \"\"\"\n",
|
|
|
|
|
" Simple training loop for use with models defined using tf.keras. It trains\n",
|
|
|
|
|
" a model for one epoch on the CIFAR-10 training set and periodically checks\n",
|
|
|
|
|
" accuracy on the CIFAR-10 validation set.\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" Inputs:\n",
|
|
|
|
|
" - model_init_fn: A function that takes no parameters; when called it\n",
|
|
|
|
|
" constructs the model we want to train: model = model_init_fn()\n",
|
|
|
|
|
" - optimizer_init_fn: A function which takes no parameters; when called it\n",
|
|
|
|
|
" constructs the Optimizer object we will use to optimize the model:\n",
|
|
|
|
|
" optimizer = optimizer_init_fn()\n",
|
|
|
|
|
" - num_epochs: The number of epochs to train for\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" Returns: Nothing, but prints progress during trainingn\n",
|
|
|
|
|
" \"\"\" \n",
|
|
|
|
|
" with tf.device(device):\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" loss_fn = tf.keras.losses.SparseCategoricalCrossentropy()\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" model = model_init_fn()\n",
|
|
|
|
|
" optimizer = optimizer_init_fn()\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" train_loss = tf.keras.metrics.Mean(name='train_loss')\n",
|
|
|
|
|
" train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name='train_accuracy')\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" val_loss = tf.keras.metrics.Mean(name='val_loss')\n",
|
|
|
|
|
" val_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name='val_accuracy')\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" t = 0\n",
|
|
|
|
|
" for epoch in range(num_epochs):\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" # Reset the metrics - https://www.tensorflow.org/alpha/guide/migration_guide#new-style_metrics\n",
|
|
|
|
|
" train_loss.reset_states()\n",
|
|
|
|
|
" train_accuracy.reset_states()\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" for x_np, y_np in train_dset:\n",
|
|
|
|
|
" with tf.GradientTape() as tape:\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" # Use the model function to build the forward pass.\n",
|
|
|
|
|
" scores = model(x_np, training=is_training)\n",
|
|
|
|
|
" loss = loss_fn(y_np, scores)\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" gradients = tape.gradient(loss, model.trainable_variables)\n",
|
|
|
|
|
" optimizer.apply_gradients(zip(gradients, model.trainable_variables))\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" # Update the metrics\n",
|
|
|
|
|
" train_loss.update_state(loss)\n",
|
|
|
|
|
" train_accuracy.update_state(y_np, scores)\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" if t % print_every == 0:\n",
|
|
|
|
|
" val_loss.reset_states()\n",
|
|
|
|
|
" val_accuracy.reset_states()\n",
|
|
|
|
|
" for test_x, test_y in val_dset:\n",
|
|
|
|
|
" # During validation at end of epoch, training set to False\n",
|
|
|
|
|
" prediction = model(test_x, training=False)\n",
|
|
|
|
|
" t_loss = loss_fn(test_y, prediction)\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" val_loss.update_state(t_loss)\n",
|
|
|
|
|
" val_accuracy.update_state(test_y, prediction)\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" template = 'Iteration {}, Epoch {}, Loss: {}, Accuracy: {}, Val Loss: {}, Val Accuracy: {}'\n",
|
|
|
|
|
" print (template.format(t, epoch+1,\n",
|
|
|
|
|
" train_loss.result(),\n",
|
|
|
|
|
" train_accuracy.result()*100,\n",
|
|
|
|
|
" val_loss.result(),\n",
|
|
|
|
|
" val_accuracy.result()*100))\n",
|
|
|
|
|
" t += 1"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"hidden_size, num_classes = 4000, 10\n",
|
|
|
|
|
"learning_rate = 1e-2\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"def model_init_fn():\n",
|
|
|
|
|
" return TwoLayerFC(hidden_size, num_classes)\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"def optimizer_init_fn():\n",
|
|
|
|
|
" return tf.keras.optimizers.SGD(learning_rate=learning_rate)\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"train_part34(model_init_fn, optimizer_init_fn)"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": [
|
|
|
|
|
"Обучите трехслойную CNN. В tf.keras.optimizers.SGD укажите Nesterov momentum = 0.9 . \n",
|
|
|
|
|
"\n",
|
|
|
|
|
"https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/optimizers/SGD\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"Значение accuracy на валидационной выборке после 1 эпохи обучения должно быть > 0.5 ."
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"learning_rate = 3e-3\n",
|
|
|
|
|
"channel_1, channel_2, num_classes = 32, 16, 10\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"def model_init_fn():\n",
|
|
|
|
|
" model = None\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # TODO: Complete the implementation of model_fn. #\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" pass\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" # *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # END OF YOUR CODE #\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" return model\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"def optimizer_init_fn():\n",
|
|
|
|
|
" optimizer = None\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # TODO: Complete the implementation of model_fn. #\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" pass\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" # *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # END OF YOUR CODE #\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" return optimizer\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"train_part34(model_init_fn, optimizer_init_fn)"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": [
|
|
|
|
|
"# Использование Keras Sequential API для реализации последовательных моделей.\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"Пример для полносвязной сети:"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"learning_rate = 1e-2\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"def model_init_fn():\n",
|
|
|
|
|
" input_shape = (32, 32, 3)\n",
|
|
|
|
|
" hidden_layer_size, num_classes = 4000, 10\n",
|
|
|
|
|
" initializer = tf.initializers.VarianceScaling(scale=2.0)\n",
|
|
|
|
|
" layers = [\n",
|
|
|
|
|
" tf.keras.layers.Flatten(input_shape=input_shape),\n",
|
|
|
|
|
" tf.keras.layers.Dense(hidden_layer_size, activation='relu',\n",
|
|
|
|
|
" kernel_initializer=initializer),\n",
|
|
|
|
|
" tf.keras.layers.Dense(num_classes, activation='softmax', \n",
|
|
|
|
|
" kernel_initializer=initializer),\n",
|
|
|
|
|
" ]\n",
|
|
|
|
|
" model = tf.keras.Sequential(layers)\n",
|
|
|
|
|
" return model\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"def optimizer_init_fn():\n",
|
|
|
|
|
" return tf.keras.optimizers.SGD(learning_rate=learning_rate) \n",
|
|
|
|
|
"\n",
|
|
|
|
|
"train_part34(model_init_fn, optimizer_init_fn)"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": [
|
|
|
|
|
"Альтернативный менее гибкий способ обучения:"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"model = model_init_fn()\n",
|
|
|
|
|
"model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=learning_rate),\n",
|
|
|
|
|
" loss='sparse_categorical_crossentropy',\n",
|
|
|
|
|
" metrics=[tf.keras.metrics.sparse_categorical_accuracy])\n",
|
|
|
|
|
"model.fit(X_train, y_train, batch_size=64, epochs=1, validation_data=(X_val, y_val))\n",
|
|
|
|
|
"model.evaluate(X_test, y_test)"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": [
|
|
|
|
|
"Перепишите реализацию трехслойной CNN с помощью tf.keras.Sequential API . Обучите модель двумя способами."
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"def model_init_fn():\n",
|
|
|
|
|
" model = None\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # TODO: Construct a three-layer ConvNet using tf.keras.Sequential. #\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" pass\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" # *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # END OF YOUR CODE #\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" return model\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"learning_rate = 5e-4\n",
|
|
|
|
|
"def optimizer_init_fn():\n",
|
|
|
|
|
" optimizer = None\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # TODO: Complete the implementation of model_fn. #\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" pass\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" # *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # END OF YOUR CODE #\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" return optimizer\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"train_part34(model_init_fn, optimizer_init_fn)"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"model = model_init_fn()\n",
|
|
|
|
|
"model.compile(optimizer='sgd',\n",
|
|
|
|
|
" loss='sparse_categorical_crossentropy',\n",
|
|
|
|
|
" metrics=[tf.keras.metrics.sparse_categorical_accuracy])\n",
|
|
|
|
|
"model.fit(X_train, y_train, batch_size=64, epochs=1, validation_data=(X_val, y_val))\n",
|
|
|
|
|
"model.evaluate(X_test, y_test)"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": [
|
|
|
|
|
"# Использование Keras Functional API\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"Для реализации более сложных архитектур сети с несколькими входами/выходами, повторным использованием слоев, \"остаточными\" связями (residual connections) необходимо явно указать входные и выходные тензоры. \n",
|
|
|
|
|
"\n",
|
|
|
|
|
"Ниже представлен пример для полносвязной сети. "
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"def two_layer_fc_functional(input_shape, hidden_size, num_classes): \n",
|
|
|
|
|
" initializer = tf.initializers.VarianceScaling(scale=2.0)\n",
|
|
|
|
|
" inputs = tf.keras.Input(shape=input_shape)\n",
|
|
|
|
|
" flattened_inputs = tf.keras.layers.Flatten()(inputs)\n",
|
|
|
|
|
" fc1_output = tf.keras.layers.Dense(hidden_size, activation='relu',\n",
|
|
|
|
|
" kernel_initializer=initializer)(flattened_inputs)\n",
|
|
|
|
|
" scores = tf.keras.layers.Dense(num_classes, activation='softmax',\n",
|
|
|
|
|
" kernel_initializer=initializer)(fc1_output)\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" # Instantiate the model given inputs and outputs.\n",
|
|
|
|
|
" model = tf.keras.Model(inputs=inputs, outputs=scores)\n",
|
|
|
|
|
" return model\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"def test_two_layer_fc_functional():\n",
|
|
|
|
|
" \"\"\" A small unit test to exercise the TwoLayerFC model above. \"\"\"\n",
|
|
|
|
|
" input_size, hidden_size, num_classes = 50, 42, 10\n",
|
|
|
|
|
" input_shape = (50,)\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" x = tf.zeros((64, input_size))\n",
|
|
|
|
|
" model = two_layer_fc_functional(input_shape, hidden_size, num_classes)\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" with tf.device(device):\n",
|
|
|
|
|
" scores = model(x)\n",
|
|
|
|
|
" print(scores.shape)\n",
|
|
|
|
|
" \n",
|
|
|
|
|
"test_two_layer_fc_functional()"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"input_shape = (32, 32, 3)\n",
|
|
|
|
|
"hidden_size, num_classes = 4000, 10\n",
|
|
|
|
|
"learning_rate = 1e-2\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"def model_init_fn():\n",
|
|
|
|
|
" return two_layer_fc_functional(input_shape, hidden_size, num_classes)\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"def optimizer_init_fn():\n",
|
|
|
|
|
" return tf.keras.optimizers.SGD(learning_rate=learning_rate)\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"train_part34(model_init_fn, optimizer_init_fn)"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": [
|
|
|
|
|
"- **Filter size**: Above we used 5x5 and 3x3; is this optimal?\n",
|
|
|
|
|
"- **Number of filters**: Above we used 16 and 32 filters. Would more or fewer do better?\n",
|
|
|
|
|
"- **Pooling**: We didn't use any pooling above. Would this improve the model?\n",
|
|
|
|
|
"- **Normalization**: Would your model be improved with batch normalization, layer normalization, group normalization, or some other normalization strategy?\n",
|
|
|
|
|
"- **Network architecture**: The ConvNet above has only three layers of trainable parameters. Would a deeper model do better?\n",
|
|
|
|
|
"- **Global average pooling**: Instead of flattening after the final convolutional layer, would global average pooling do better? This strategy is used for example in Google's Inception network and in Residual Networks.\n",
|
|
|
|
|
"- **Regularization**: Would some kind of regularization improve performance? Maybe weight decay or dropout?"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "markdown",
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"source": [
|
|
|
|
|
"Поэкспериментируйте с архитектурой сверточной сети. Для вашего набора данных вам необходимо получить как минимум 70% accuracy на валидационной выборке за 10 эпох обучения. Опишите все эксперименты и сделайте выводы (без выполнения данного пункта работы приниматься не будут). \n",
|
|
|
|
|
"\n",
|
|
|
|
|
"Эспериментируйте с архитектурой, гиперпараметрами, функцией потерь, регуляризацией, методом оптимизации. \n",
|
|
|
|
|
"\n",
|
|
|
|
|
"https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/keras/layers/BatchNormalization#methods https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/keras/layers/Dropout#methods"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"cell_type": "code",
|
|
|
|
|
"execution_count": null,
|
|
|
|
|
"metadata": {},
|
|
|
|
|
"outputs": [],
|
|
|
|
|
"source": [
|
|
|
|
|
"class CustomConvNet(tf.keras.Model):\n",
|
|
|
|
|
" def __init__(self):\n",
|
|
|
|
|
" super(CustomConvNet, self).__init__()\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # TODO: Construct a model that performs well on CIFAR-10 #\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" pass\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" # *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # END OF YOUR CODE #\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" \n",
|
|
|
|
|
" def call(self, input_tensor, training=False):\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # TODO: Construct a model that performs well on CIFAR-10 #\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" pass\n",
|
|
|
|
|
"\n",
|
|
|
|
|
" # *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" # END OF YOUR CODE #\n",
|
|
|
|
|
" ############################################################################\n",
|
|
|
|
|
" return x\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"print_every = 700\n",
|
|
|
|
|
"num_epochs = 10\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"model = CustomConvNet()\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"def model_init_fn():\n",
|
|
|
|
|
" return CustomConvNet()\n",
|
|
|
|
|
"\n",
|
|
|
|
|
"def optimizer_init_fn():\n",
|
|
|
|
|
" learning_rate = 1e-3\n",
|
|
|
|
|
" return tf.keras.optimizers.Adam(learning_rate) \n",
|
|
|
|
|
"\n",
|
|
|
|
|
"train_part34(model_init_fn, optimizer_init_fn, num_epochs=num_epochs, is_training=True)"
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"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
|
|
|
|
|
}
|