diff --git a/LW1/image-1.png b/LW1/image-1.png new file mode 100644 index 0000000..44bdc69 Binary files /dev/null and b/LW1/image-1.png differ diff --git a/LW1/image-2.png b/LW1/image-2.png new file mode 100644 index 0000000..f283f05 Binary files /dev/null and b/LW1/image-2.png differ diff --git a/LW1/image-3.png b/LW1/image-3.png new file mode 100644 index 0000000..5ff0493 Binary files /dev/null and b/LW1/image-3.png differ diff --git a/LW1/image-4.png b/LW1/image-4.png new file mode 100644 index 0000000..78a096c Binary files /dev/null and b/LW1/image-4.png differ diff --git a/LW1/image-5.png b/LW1/image-5.png new file mode 100644 index 0000000..44bdc69 Binary files /dev/null and b/LW1/image-5.png differ diff --git a/LW1/image.png b/LW1/image.png new file mode 100644 index 0000000..77114ff Binary files /dev/null and b/LW1/image.png differ diff --git a/LW1/lab1.ipynb b/LW1/lab1.ipynb new file mode 100644 index 0000000..80c94b2 --- /dev/null +++ b/LW1/lab1.ipynb @@ -0,0 +1,2048 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [], + "gpuType": "T4" + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "code", + "source": [ + "import os" + ], + "metadata": { + "id": "rAJlC5-69GRX" + }, + "execution_count": 1, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "os.chdir('/content/drive/MyDrive/Colab Notebooks')" + ], + "metadata": { + "id": "n0DVILNB9Lrw" + }, + "execution_count": 2, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "from tensorflow import keras" + ], + "metadata": { + "id": "NY2drgNH9OpF" + }, + "execution_count": 3, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import sklearn" + ], + "metadata": { + "id": "NwLvynhi9W7X" + }, + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "from keras.datasets import mnist\n", + "(X_train, y_train), (X_test, y_test) = mnist.load_data()" + ], + "metadata": { + "id": "hGqVgLFo98qD" + }, + "execution_count": 5, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# создание своего разбиения датасета\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "# объединяем в один набор\n", + "X = np.concatenate((X_train, X_test))\n", + "y = np.concatenate((y_train, y_test))\n", + "\n", + "# разбиваем по вариантам\n", + "X_train, X_test, y_train, y_test = train_test_split(X, y,\n", + " test_size = 10000,\n", + " train_size = 60000,\n", + " random_state = 19)" + ], + "metadata": { + "id": "sfBRNyju-JQJ" + }, + "execution_count": 6, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# вывод размерностей\n", + "print('Shape of X train:', X_train.shape)\n", + "print('Shape of y train:', y_train.shape)\n", + "print('Shape of X test:', X_test.shape)\n", + "print('Shape of y test:', y_test.shape)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "lZkZaiBe-Td8", + "outputId": "6c309a83-369b-4097-fe55-cef81a6149a6" + }, + "execution_count": 7, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Shape of X train: (60000, 28, 28)\n", + "Shape of y train: (60000,)\n", + "Shape of X test: (10000, 28, 28)\n", + "Shape of y test: (10000,)\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "# вывод первых 4 изображений и их меток\n", + "plt.figure(figsize=(8, 2))\n", + "for i in range(4):\n", + " plt.subplot(1, 4, i + 1)\n", + " plt.imshow(X_train[i].reshape(28, 28), cmap='gray')\n", + " plt.title(f'Label: {y_train[i]}', fontsize = 6)\n", + " plt.axis('off')\n", + "plt.show()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 187 + }, + "id": "hNSaItYqHYWb", + "outputId": "2ce054ab-e939-4d52-93a5-e2ff5d2a8175" + }, + "execution_count": 8, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "source": [ + "# развертывание изображений 28x28 в вектор длиной 784 и нормализация\n", + "num_pixels = X_train.shape[1] * X_train.shape[2]\n", + "X_train = X_train.reshape(X_train.shape[0], num_pixels).astype('float32') / 255\n", + "X_test = X_test.reshape(X_test.shape[0], num_pixels).astype('float32') / 255\n", + "\n", + "# кодирование меток по принципу one-hot encoding\n", + "from tensorflow.keras.utils import to_categorical\n", + "y_train = to_categorical(y_train, 10)\n", + "y_test = to_categorical(y_test, 10)\n", + "num_classes = y_train.shape[1]\n", + "\n", + "# вывод размерностей\n", + "print('Shape of X train:', X_train.shape)\n", + "print('Shape of y train:', y_train.shape)\n", + "print('Shape of X test:', X_test.shape)\n", + "print('Shape of y test:', y_test.shape)\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "3iAhDyLs-vs6", + "outputId": "8578af10-d947-4644-934b-2227b272ef03" + }, + "execution_count": 9, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Shape of X train: (60000, 784)\n", + "Shape of y train: (60000, 10)\n", + "Shape of X test: (10000, 784)\n", + "Shape of y test: (10000, 10)\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "# создание модели однослойной нейронной сети\n", + "from keras.models import Sequential\n", + "from keras.layers import Dense\n", + "\n", + "model0 = Sequential()\n", + "# добавляем выходной слой\n", + "model0.add(Dense(units=num_classes, input_dim=784, activation='softmax'))\n", + "\n", + "# компиляция модели\n", + "model0.compile(loss='categorical_crossentropy',\n", + " optimizer='sgd',\n", + " metrics=['accuracy'])\n", + "\n", + "# вывод информации об архитектуре модели\n", + "print(model0.summary())\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 232 + }, + "id": "ZXb_qvb0Qy3e", + "outputId": "d226a668-2cc2-43f4-8740-3f2d3d3f259c" + }, + "execution_count": 10, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "/usr/local/lib/python3.12/dist-packages/keras/src/layers/core/dense.py:93: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n", + " super().__init__(activity_regularizer=activity_regularizer, **kwargs)\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "\u001b[1mModel: \"sequential\"\u001b[0m\n" + ], + "text/html": [ + "
Model: \"sequential\"\n",
+              "
\n" + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n", + "┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n", + "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n", + "│ dense (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m10\u001b[0m) │ \u001b[38;5;34m7,850\u001b[0m │\n", + "└─────────────────────────────────┴────────────────────────┴───────────────┘\n" + ], + "text/html": [ + "
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
+              "┃ Layer (type)                     Output Shape                  Param # ┃\n",
+              "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
+              "│ dense (Dense)                   │ (None, 10)             │         7,850 │\n",
+              "└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
+              "
\n" + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m7,850\u001b[0m (30.66 KB)\n" + ], + "text/html": [ + "
 Total params: 7,850 (30.66 KB)\n",
+              "
\n" + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m7,850\u001b[0m (30.66 KB)\n" + ], + "text/html": [ + "
 Trainable params: 7,850 (30.66 KB)\n",
+              "
\n" + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n" + ], + "text/html": [ + "
 Non-trainable params: 0 (0.00 B)\n",
+              "
\n" + ] + }, + "metadata": {} + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "None\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "# обучение модели\n", + "H0 = model0.fit(X_train, y_train,\n", + " validation_split=0.1,\n", + " epochs=50,\n", + " verbose=1)\n", + "\n", + "# вывод графика функции ошибки\n", + "plt.plot(H0.history['loss'])\n", + "plt.plot(H0.history['val_loss'])\n", + "plt.grid()\n", + "plt.xlabel('Epochs')\n", + "plt.ylabel('Loss')\n", + "plt.legend(['train_loss', 'val_loss'])\n", + "plt.title('Loss by epochs (Model 0)')\n", + "plt.show()\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 + }, + "id": "fOfts2JxRlwm", + "outputId": "f1d30460-b93c-49bd-ff94-8d89a13bf354" + }, + "execution_count": 11, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 1/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 3ms/step - accuracy: 0.6993 - loss: 1.1736 - val_accuracy: 0.8783 - val_loss: 0.5063\n", + "Epoch 2/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8743 - loss: 0.4869 - val_accuracy: 0.8923 - val_loss: 0.4182\n", + "Epoch 3/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.8883 - loss: 0.4198 - val_accuracy: 0.8995 - val_loss: 0.3825\n", + "Epoch 4/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8945 - loss: 0.3879 - val_accuracy: 0.9023 - val_loss: 0.3621\n", + "Epoch 5/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9000 - loss: 0.3696 - val_accuracy: 0.9038 - val_loss: 0.3490\n", + "Epoch 6/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9042 - loss: 0.3514 - val_accuracy: 0.9062 - val_loss: 0.3391\n", + "Epoch 7/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9059 - loss: 0.3436 - val_accuracy: 0.9077 - val_loss: 0.3313\n", + "Epoch 8/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9064 - loss: 0.3362 - val_accuracy: 0.9088 - val_loss: 0.3258\n", + "Epoch 9/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m10s\u001b[0m 6ms/step - accuracy: 0.9096 - loss: 0.3285 - val_accuracy: 0.9100 - val_loss: 0.3211\n", + "Epoch 10/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 4ms/step - accuracy: 0.9097 - loss: 0.3258 - val_accuracy: 0.9128 - val_loss: 0.3167\n", + "Epoch 11/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9112 - loss: 0.3213 - val_accuracy: 0.9122 - val_loss: 0.3141\n", + "Epoch 12/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9115 - loss: 0.3171 - val_accuracy: 0.9142 - val_loss: 0.3105\n", + "Epoch 13/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9136 - loss: 0.3119 - val_accuracy: 0.9142 - val_loss: 0.3079\n", + "Epoch 14/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9155 - loss: 0.3036 - val_accuracy: 0.9142 - val_loss: 0.3061\n", + "Epoch 15/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9136 - loss: 0.3111 - val_accuracy: 0.9162 - val_loss: 0.3036\n", + "Epoch 16/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9171 - loss: 0.2994 - val_accuracy: 0.9155 - val_loss: 0.3020\n", + "Epoch 17/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9166 - loss: 0.3025 - val_accuracy: 0.9162 - val_loss: 0.3003\n", + "Epoch 18/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9182 - loss: 0.2953 - val_accuracy: 0.9172 - val_loss: 0.2993\n", + "Epoch 19/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9190 - loss: 0.2921 - val_accuracy: 0.9187 - val_loss: 0.2979\n", + "Epoch 20/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9205 - loss: 0.2882 - val_accuracy: 0.9177 - val_loss: 0.2966\n", + "Epoch 21/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9177 - loss: 0.2900 - val_accuracy: 0.9185 - val_loss: 0.2959\n", + "Epoch 22/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9181 - loss: 0.2977 - val_accuracy: 0.9177 - val_loss: 0.2946\n", + "Epoch 23/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9213 - loss: 0.2840 - val_accuracy: 0.9193 - val_loss: 0.2934\n", + "Epoch 24/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9206 - loss: 0.2886 - val_accuracy: 0.9190 - val_loss: 0.2931\n", + "Epoch 25/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9226 - loss: 0.2826 - val_accuracy: 0.9207 - val_loss: 0.2921\n", + "Epoch 26/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9193 - loss: 0.2895 - val_accuracy: 0.9203 - val_loss: 0.2914\n", + "Epoch 27/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9198 - loss: 0.2866 - val_accuracy: 0.9207 - val_loss: 0.2909\n", + "Epoch 28/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9207 - loss: 0.2859 - val_accuracy: 0.9205 - val_loss: 0.2902\n", + "Epoch 29/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9215 - loss: 0.2854 - val_accuracy: 0.9220 - val_loss: 0.2892\n", + "Epoch 30/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9198 - loss: 0.2870 - val_accuracy: 0.9213 - val_loss: 0.2888\n", + "Epoch 31/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9219 - loss: 0.2819 - val_accuracy: 0.9213 - val_loss: 0.2887\n", + "Epoch 32/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 2ms/step - accuracy: 0.9228 - loss: 0.2815 - val_accuracy: 0.9208 - val_loss: 0.2874\n", + "Epoch 33/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9234 - loss: 0.2798 - val_accuracy: 0.9220 - val_loss: 0.2875\n", + "Epoch 34/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9221 - loss: 0.2757 - val_accuracy: 0.9207 - val_loss: 0.2871\n", + "Epoch 35/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9224 - loss: 0.2753 - val_accuracy: 0.9217 - val_loss: 0.2871\n", + "Epoch 36/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 2ms/step - accuracy: 0.9226 - loss: 0.2835 - val_accuracy: 0.9215 - val_loss: 0.2865\n", + "Epoch 37/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9232 - loss: 0.2737 - val_accuracy: 0.9213 - val_loss: 0.2856\n", + "Epoch 38/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9235 - loss: 0.2779 - val_accuracy: 0.9218 - val_loss: 0.2855\n", + "Epoch 39/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9216 - loss: 0.2770 - val_accuracy: 0.9223 - val_loss: 0.2851\n", + "Epoch 40/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9219 - loss: 0.2772 - val_accuracy: 0.9215 - val_loss: 0.2860\n", + "Epoch 41/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9257 - loss: 0.2697 - val_accuracy: 0.9227 - val_loss: 0.2845\n", + "Epoch 42/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9232 - loss: 0.2759 - val_accuracy: 0.9240 - val_loss: 0.2840\n", + "Epoch 43/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9248 - loss: 0.2735 - val_accuracy: 0.9232 - val_loss: 0.2845\n", + "Epoch 44/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9217 - loss: 0.2812 - val_accuracy: 0.9227 - val_loss: 0.2839\n", + "Epoch 45/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9240 - loss: 0.2709 - val_accuracy: 0.9232 - val_loss: 0.2836\n", + "Epoch 46/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9229 - loss: 0.2746 - val_accuracy: 0.9228 - val_loss: 0.2837\n", + "Epoch 47/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9261 - loss: 0.2700 - val_accuracy: 0.9237 - val_loss: 0.2832\n", + "Epoch 48/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9252 - loss: 0.2690 - val_accuracy: 0.9233 - val_loss: 0.2828\n", + "Epoch 49/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9254 - loss: 0.2715 - val_accuracy: 0.9232 - val_loss: 0.2834\n", + "Epoch 50/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9244 - loss: 0.2735 - val_accuracy: 0.9230 - val_loss: 0.2821\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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dXJLOe6//348++yzWLp0Kf7973/jq6++QpcuXSr9A1uRzWaDIAhYu3YtlEqly/G6sohgZWUD4DQ1+b777sMdd9yBlStXYv369XjzzTfxxhtv4IcffsDgwYOrfO+wsDBYLBYUFBQgICCgyvOGDx8OrVaL8ePHw2g04r777qv9F6ohm82GyMhIp9a5iiIiImr0fjExMQCk1qOrpaeno169ei77r1y5AoPBUGnwIXI3ttwQuVlERAQMBgPS0tJcjh09ehQKhQINGzZ07AsNDcXEiROxbNkynDt3Dh06dMCsWbOcrmvWrBn+7//+D+vXr8ehQ4dgMpnw9ttvX7csNpvNpfXh2LFjAOC0gm1oaCiGDh2KpUuX4syZM9i6det1W23s5RJFEU2aNEG/fv1ctttvv93p/IsXL6KoqOia5WncuDGOHz/ustLv0aNHHcftn33x4kWXgdA3IiYmBpMnT8aqVatw6tQphIWF4dVXX73mNXFxcQCkWVPXotfrMWLECGzevBn9+/dHeHh4pefZv19lvz9paWmO4/bHyro0r762WbNmuHTpEnr06FHpzyk+Pv6aZb9au3btoFKpXAYum0wm7N+/Hx07dnS55tSpU47WNyJPY7ghcjOlUokBAwbgxx9/dOr6yczMxNdff42ePXs6ps9WnK0DSC0dzZs3dzT3FxcXo7S01OmcZs2aISAgoNrL2X/wwQeO56Io4oMPPoBarUbfvn2dznvooYdw5MgRPPfcc1Aqlbj//vuv+94jR46EUqnE7NmzXRZoE0XR5ftZLBanlWrtK9dGREQgISEBADBkyBBkZGRg+fLlTte9//778Pf3R+/evQFIs8hEUcTs2bNdynV1Wa7HarUiLy/PaV9kZCTq1at33XpOTEwEgGqtWD1t2jTMnDkTL730UpXndOnSBZGRkVi4cKHTZ69duxapqamOdXFiYmLQsWNHfPHFF05lT05OxpEjR5ze87777oPVasXLL7/s8nkWi8VlVtv1BAUFoV+/fvjqq69QUFDg2P/ll1+isLDQZSE/ANi7dy+6d+9eo88hqi12SxHV0uLFi13WSgGAp59+Gq+88gqSk5PRs2dPTJ48GSqVCp988gmMRiPmzZvnOLdNmzbo06ePYx2Q3bt347vvvnMMAj527Bj69u2L++67D23atIFKpcLKlSuRmZlZrfCh0+mwbt06jB8/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\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "source": [ + "# оценка качества модели на тестовых данных\n", + "scores = model0.evaluate(X_test, y_test)\n", + "\n", + "print('Loss on test data:', scores[0])\n", + "print('Accuracy on test data:', scores[1])\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "57GIGI8xDIUY", + "outputId": "5f175fcf-653c-453d-fb89-7c033c0098fc" + }, + "execution_count": 12, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[1m313/313\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 3ms/step - accuracy: 0.9194 - loss: 0.2818\n", + "Loss on test data: 0.28366461396217346\n", + "Accuracy on test data: 0.9205999970436096\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "from keras.models import Sequential\n", + "from keras.layers import Dense\n", + "\n", + "neurons = [100, 300, 500]\n", + "results = {}\n", + "\n", + "for n in neurons:\n", + " print(f'\\n=== Модель со скрытым слоем {n} нейронов ===')\n", + "\n", + " # создание модели\n", + " model = Sequential()\n", + " model.add(Dense(units=n, input_dim=784, activation='sigmoid'))\n", + " model.add(Dense(units=num_classes, activation='softmax'))\n", + "\n", + " # компиляция модели\n", + " model.compile(loss='categorical_crossentropy',\n", + " optimizer='sgd',\n", + " metrics=['accuracy'])\n", + "\n", + " # обучение модели\n", + " H = model.fit(X_train, y_train,\n", + " validation_split=0.1,\n", + " epochs=50,\n", + " verbose=1) # чтобы не печатать все эпохи\n", + "\n", + " # оценка на тестовых данных\n", + " scores = model.evaluate(X_test, y_test, verbose=1)\n", + " results[n] = scores[1]\n", + "\n", + " print(f'Accuracy on test data: {scores[1]:.4f}')\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "C0zQqOUNUt8A", + "outputId": "5d4518fd-8690-4ec0-b73b-fa52d0cf3c21" + }, + "execution_count": 16, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + "=== Модель со скрытым слоем 100 нейронов ===\n", + "Epoch 1/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 3ms/step - accuracy: 0.5470 - loss: 1.8791 - val_accuracy: 0.8307 - val_loss: 0.9579\n", + "Epoch 2/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.8333 - loss: 0.8491 - val_accuracy: 0.8707 - val_loss: 0.6103\n", + "Epoch 3/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8645 - loss: 0.5867 - val_accuracy: 0.8848 - val_loss: 0.4890\n", + "Epoch 4/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8786 - loss: 0.4860 - val_accuracy: 0.8932 - val_loss: 0.4297\n", + "Epoch 5/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.8874 - loss: 0.4331 - val_accuracy: 0.8978 - val_loss: 0.3938\n", + "Epoch 6/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8945 - loss: 0.3998 - val_accuracy: 0.9015 - val_loss: 0.3690\n", + "Epoch 7/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 2ms/step - accuracy: 0.8971 - loss: 0.3753 - val_accuracy: 0.9052 - val_loss: 0.3520\n", + "Epoch 8/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9033 - loss: 0.3587 - val_accuracy: 0.9078 - val_loss: 0.3392\n", + "Epoch 9/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9072 - loss: 0.3403 - val_accuracy: 0.9093 - val_loss: 0.3281\n", + "Epoch 10/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9071 - loss: 0.3303 - val_accuracy: 0.9107 - val_loss: 0.3193\n", + "Epoch 11/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9101 - loss: 0.3223 - val_accuracy: 0.9112 - val_loss: 0.3109\n", + "Epoch 12/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9114 - loss: 0.3160 - val_accuracy: 0.9143 - val_loss: 0.3046\n", + "Epoch 13/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 2ms/step - accuracy: 0.9147 - loss: 0.3072 - val_accuracy: 0.9143 - val_loss: 0.2991\n", + "Epoch 14/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9136 - loss: 0.3027 - val_accuracy: 0.9182 - val_loss: 0.2930\n", + "Epoch 15/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9151 - loss: 0.2963 - val_accuracy: 0.9195 - val_loss: 0.2885\n", + "Epoch 16/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9166 - loss: 0.2929 - val_accuracy: 0.9182 - val_loss: 0.2843\n", + "Epoch 17/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9181 - loss: 0.2855 - val_accuracy: 0.9207 - val_loss: 0.2802\n", + "Epoch 18/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9188 - loss: 0.2818 - val_accuracy: 0.9212 - val_loss: 0.2756\n", + "Epoch 19/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9212 - loss: 0.2755 - val_accuracy: 0.9223 - val_loss: 0.2717\n", + "Epoch 20/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 4ms/step - accuracy: 0.9223 - loss: 0.2729 - val_accuracy: 0.9230 - val_loss: 0.2682\n", + "Epoch 21/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9243 - loss: 0.2675 - val_accuracy: 0.9233 - val_loss: 0.2644\n", + "Epoch 22/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9242 - loss: 0.2651 - val_accuracy: 0.9252 - val_loss: 0.2618\n", + "Epoch 23/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9254 - loss: 0.2603 - val_accuracy: 0.9262 - val_loss: 0.2583\n", + "Epoch 24/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9244 - loss: 0.2603 - val_accuracy: 0.9283 - val_loss: 0.2556\n", + "Epoch 25/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9277 - loss: 0.2519 - val_accuracy: 0.9287 - val_loss: 0.2522\n", + "Epoch 26/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9280 - loss: 0.2517 - val_accuracy: 0.9305 - val_loss: 0.2491\n", + "Epoch 27/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9303 - loss: 0.2481 - val_accuracy: 0.9302 - val_loss: 0.2467\n", + "Epoch 28/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9301 - loss: 0.2463 - val_accuracy: 0.9303 - val_loss: 0.2443\n", + "Epoch 29/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9316 - loss: 0.2352 - val_accuracy: 0.9337 - val_loss: 0.2411\n", + "Epoch 30/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9334 - loss: 0.2310 - val_accuracy: 0.9337 - val_loss: 0.2391\n", + "Epoch 31/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9334 - loss: 0.2353 - val_accuracy: 0.9357 - val_loss: 0.2363\n", + "Epoch 32/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9353 - loss: 0.2279 - val_accuracy: 0.9355 - val_loss: 0.2340\n", + "Epoch 33/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9349 - loss: 0.2285 - val_accuracy: 0.9370 - val_loss: 0.2320\n", + "Epoch 34/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9360 - loss: 0.2249 - val_accuracy: 0.9377 - val_loss: 0.2297\n", + "Epoch 35/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9371 - loss: 0.2212 - val_accuracy: 0.9382 - val_loss: 0.2276\n", + "Epoch 36/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9388 - loss: 0.2134 - val_accuracy: 0.9382 - val_loss: 0.2254\n", + "Epoch 37/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 2ms/step - accuracy: 0.9379 - loss: 0.2162 - val_accuracy: 0.9397 - val_loss: 0.2227\n", + "Epoch 38/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9405 - loss: 0.2092 - val_accuracy: 0.9402 - val_loss: 0.2208\n", + "Epoch 39/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9394 - loss: 0.2109 - val_accuracy: 0.9402 - val_loss: 0.2192\n", + "Epoch 40/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9396 - loss: 0.2110 - val_accuracy: 0.9418 - val_loss: 0.2173\n", + "Epoch 41/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9417 - loss: 0.2042 - val_accuracy: 0.9423 - val_loss: 0.2149\n", + "Epoch 42/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9423 - loss: 0.2015 - val_accuracy: 0.9428 - val_loss: 0.2131\n", + "Epoch 43/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9430 - loss: 0.2016 - val_accuracy: 0.9437 - val_loss: 0.2111\n", + "Epoch 44/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9433 - loss: 0.1942 - val_accuracy: 0.9433 - val_loss: 0.2100\n", + "Epoch 45/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9430 - loss: 0.1969 - val_accuracy: 0.9440 - val_loss: 0.2080\n", + "Epoch 46/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9448 - loss: 0.1928 - val_accuracy: 0.9442 - val_loss: 0.2063\n", + "Epoch 47/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9456 - loss: 0.1902 - val_accuracy: 0.9460 - val_loss: 0.2048\n", + "Epoch 48/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9438 - loss: 0.1942 - val_accuracy: 0.9460 - val_loss: 0.2032\n", + "Epoch 49/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9478 - loss: 0.1852 - val_accuracy: 0.9462 - val_loss: 0.2018\n", + "Epoch 50/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9450 - loss: 0.1899 - val_accuracy: 0.9458 - val_loss: 0.1997\n", + "\u001b[1m313/313\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 3ms/step - accuracy: 0.9462 - loss: 0.1933\n", + "Accuracy on test data: 0.9445\n", + "\n", + "=== Модель со скрытым слоем 300 нейронов ===\n", + "Epoch 1/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 3ms/step - accuracy: 0.5723 - loss: 1.7832 - val_accuracy: 0.8400 - val_loss: 0.8404\n", + "Epoch 2/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8392 - loss: 0.7529 - val_accuracy: 0.8725 - val_loss: 0.5591\n", + "Epoch 3/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.8650 - loss: 0.5454 - val_accuracy: 0.8820 - val_loss: 0.4640\n", + "Epoch 4/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8821 - loss: 0.4555 - val_accuracy: 0.8958 - val_loss: 0.4116\n", + "Epoch 5/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.8897 - loss: 0.4126 - val_accuracy: 0.8972 - val_loss: 0.3825\n", + "Epoch 6/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.8949 - loss: 0.3824 - val_accuracy: 0.9010 - val_loss: 0.3619\n", + "Epoch 7/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8965 - loss: 0.3723 - val_accuracy: 0.9068 - val_loss: 0.3476\n", + "Epoch 8/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.8977 - loss: 0.3586 - val_accuracy: 0.9062 - val_loss: 0.3384\n", + "Epoch 9/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9029 - loss: 0.3395 - val_accuracy: 0.9072 - val_loss: 0.3280\n", + "Epoch 10/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9009 - loss: 0.3401 - val_accuracy: 0.9088 - val_loss: 0.3216\n", + "Epoch 11/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9060 - loss: 0.3291 - val_accuracy: 0.9103 - val_loss: 0.3154\n", + "Epoch 12/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9098 - loss: 0.3185 - val_accuracy: 0.9132 - val_loss: 0.3120\n", + "Epoch 13/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9089 - loss: 0.3181 - val_accuracy: 0.9138 - val_loss: 0.3068\n", + "Epoch 14/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9106 - loss: 0.3130 - val_accuracy: 0.9140 - val_loss: 0.3017\n", + "Epoch 15/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9111 - loss: 0.3068 - val_accuracy: 0.9140 - val_loss: 0.2994\n", + "Epoch 16/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9108 - loss: 0.3096 - val_accuracy: 0.9170 - val_loss: 0.2947\n", + "Epoch 17/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9146 - loss: 0.2983 - val_accuracy: 0.9170 - val_loss: 0.2916\n", + "Epoch 18/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9148 - loss: 0.2953 - val_accuracy: 0.9185 - val_loss: 0.2898\n", + "Epoch 19/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9151 - loss: 0.2930 - val_accuracy: 0.9197 - val_loss: 0.2865\n", + "Epoch 20/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9178 - loss: 0.2881 - val_accuracy: 0.9177 - val_loss: 0.2838\n", + "Epoch 21/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9176 - loss: 0.2851 - val_accuracy: 0.9198 - val_loss: 0.2817\n", + "Epoch 22/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9186 - loss: 0.2808 - val_accuracy: 0.9200 - val_loss: 0.2807\n", + "Epoch 23/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9185 - loss: 0.2849 - val_accuracy: 0.9205 - val_loss: 0.2777\n", + "Epoch 24/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9206 - loss: 0.2741 - val_accuracy: 0.9218 - val_loss: 0.2756\n", + "Epoch 25/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9206 - loss: 0.2744 - val_accuracy: 0.9237 - val_loss: 0.2743\n", + "Epoch 26/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9196 - loss: 0.2758 - val_accuracy: 0.9222 - val_loss: 0.2722\n", + "Epoch 27/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9228 - loss: 0.2654 - val_accuracy: 0.9237 - val_loss: 0.2693\n", + "Epoch 28/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9262 - loss: 0.2593 - val_accuracy: 0.9253 - val_loss: 0.2682\n", + "Epoch 29/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9242 - loss: 0.2645 - val_accuracy: 0.9270 - val_loss: 0.2655\n", + "Epoch 30/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9251 - loss: 0.2593 - val_accuracy: 0.9257 - val_loss: 0.2642\n", + "Epoch 31/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9261 - loss: 0.2564 - val_accuracy: 0.9258 - val_loss: 0.2638\n", + "Epoch 32/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 3ms/step - accuracy: 0.9254 - loss: 0.2579 - val_accuracy: 0.9275 - val_loss: 0.2612\n", + "Epoch 33/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9275 - loss: 0.2507 - val_accuracy: 0.9277 - val_loss: 0.2576\n", + "Epoch 34/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9268 - loss: 0.2525 - val_accuracy: 0.9290 - val_loss: 0.2563\n", + "Epoch 35/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9282 - loss: 0.2506 - val_accuracy: 0.9283 - val_loss: 0.2560\n", + "Epoch 36/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9313 - loss: 0.2405 - val_accuracy: 0.9292 - val_loss: 0.2536\n", + "Epoch 37/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 2ms/step - accuracy: 0.9310 - loss: 0.2424 - val_accuracy: 0.9303 - val_loss: 0.2508\n", + "Epoch 38/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9310 - loss: 0.2416 - val_accuracy: 0.9320 - val_loss: 0.2486\n", + "Epoch 39/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9343 - loss: 0.2309 - val_accuracy: 0.9317 - val_loss: 0.2472\n", + "Epoch 40/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9329 - loss: 0.2348 - val_accuracy: 0.9330 - val_loss: 0.2450\n", + "Epoch 41/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9333 - loss: 0.2344 - val_accuracy: 0.9328 - val_loss: 0.2431\n", + "Epoch 42/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9322 - loss: 0.2367 - val_accuracy: 0.9328 - val_loss: 0.2424\n", + "Epoch 43/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9346 - loss: 0.2285 - val_accuracy: 0.9327 - val_loss: 0.2401\n", + "Epoch 44/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9344 - loss: 0.2285 - val_accuracy: 0.9340 - val_loss: 0.2388\n", + "Epoch 45/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9353 - loss: 0.2292 - val_accuracy: 0.9348 - val_loss: 0.2365\n", + "Epoch 46/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9354 - loss: 0.2249 - val_accuracy: 0.9355 - val_loss: 0.2344\n", + "Epoch 47/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9357 - loss: 0.2238 - val_accuracy: 0.9357 - val_loss: 0.2329\n", + "Epoch 48/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9385 - loss: 0.2180 - val_accuracy: 0.9362 - val_loss: 0.2313\n", + "Epoch 49/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9383 - loss: 0.2176 - val_accuracy: 0.9355 - val_loss: 0.2308\n", + "Epoch 50/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9387 - loss: 0.2139 - val_accuracy: 0.9363 - val_loss: 0.2288\n", + "\u001b[1m313/313\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 3ms/step - accuracy: 0.9350 - loss: 0.2231\n", + "Accuracy on test data: 0.9347\n", + "\n", + "=== Модель со скрытым слоем 500 нейронов ===\n", + "Epoch 1/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 3ms/step - accuracy: 0.5484 - loss: 1.7610 - val_accuracy: 0.8363 - val_loss: 0.8149\n", + "Epoch 2/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8469 - loss: 0.7192 - val_accuracy: 0.8732 - val_loss: 0.5455\n", + "Epoch 3/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.8680 - loss: 0.5286 - val_accuracy: 0.8863 - val_loss: 0.4521\n", + "Epoch 4/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 2ms/step - accuracy: 0.8821 - loss: 0.4516 - val_accuracy: 0.8933 - val_loss: 0.4079\n", + "Epoch 5/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.8881 - loss: 0.4071 - val_accuracy: 0.8977 - val_loss: 0.3779\n", + "Epoch 6/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8920 - loss: 0.3878 - val_accuracy: 0.9008 - val_loss: 0.3607\n", + "Epoch 7/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8976 - loss: 0.3673 - val_accuracy: 0.8973 - val_loss: 0.3526\n", + "Epoch 8/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9004 - loss: 0.3503 - val_accuracy: 0.9047 - val_loss: 0.3381\n", + "Epoch 9/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8991 - loss: 0.3532 - val_accuracy: 0.9088 - val_loss: 0.3287\n", + "Epoch 10/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9062 - loss: 0.3334 - val_accuracy: 0.9105 - val_loss: 0.3212\n", + "Epoch 11/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9080 - loss: 0.3265 - val_accuracy: 0.9100 - val_loss: 0.3154\n", + "Epoch 12/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9068 - loss: 0.3244 - val_accuracy: 0.9112 - val_loss: 0.3107\n", + "Epoch 13/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9084 - loss: 0.3212 - val_accuracy: 0.9120 - val_loss: 0.3081\n", + "Epoch 14/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9096 - loss: 0.3118 - val_accuracy: 0.9127 - val_loss: 0.3049\n", + "Epoch 15/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9110 - loss: 0.3055 - val_accuracy: 0.9135 - val_loss: 0.3017\n", + "Epoch 16/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9137 - loss: 0.3079 - val_accuracy: 0.9172 - val_loss: 0.2998\n", + "Epoch 17/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9126 - loss: 0.3027 - val_accuracy: 0.9167 - val_loss: 0.2978\n", + "Epoch 18/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9157 - loss: 0.2940 - val_accuracy: 0.9152 - val_loss: 0.2932\n", + "Epoch 19/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9181 - loss: 0.2846 - val_accuracy: 0.9173 - val_loss: 0.2923\n", + "Epoch 20/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9152 - loss: 0.2946 - val_accuracy: 0.9185 - val_loss: 0.2883\n", + "Epoch 21/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9171 - loss: 0.2880 - val_accuracy: 0.9182 - val_loss: 0.2884\n", + "Epoch 22/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9166 - loss: 0.2844 - val_accuracy: 0.9193 - val_loss: 0.2857\n", + "Epoch 23/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9199 - loss: 0.2844 - val_accuracy: 0.9202 - val_loss: 0.2845\n", + "Epoch 24/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9181 - loss: 0.2865 - val_accuracy: 0.9215 - val_loss: 0.2814\n", + "Epoch 25/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9190 - loss: 0.2780 - val_accuracy: 0.9212 - val_loss: 0.2815\n", + "Epoch 26/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 3ms/step - accuracy: 0.9189 - loss: 0.2830 - val_accuracy: 0.9218 - val_loss: 0.2795\n", + "Epoch 27/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9201 - loss: 0.2841 - val_accuracy: 0.9233 - val_loss: 0.2774\n", + "Epoch 28/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9219 - loss: 0.2743 - val_accuracy: 0.9220 - val_loss: 0.2769\n", + "Epoch 29/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9226 - loss: 0.2725 - val_accuracy: 0.9235 - val_loss: 0.2754\n", + "Epoch 30/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9227 - loss: 0.2681 - val_accuracy: 0.9243 - val_loss: 0.2738\n", + "Epoch 31/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9209 - loss: 0.2715 - val_accuracy: 0.9240 - val_loss: 0.2722\n", + "Epoch 32/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9238 - loss: 0.2653 - val_accuracy: 0.9245 - val_loss: 0.2734\n", + "Epoch 33/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9244 - loss: 0.2691 - val_accuracy: 0.9252 - val_loss: 0.2703\n", + "Epoch 34/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9274 - loss: 0.2556 - val_accuracy: 0.9252 - val_loss: 0.2682\n", + "Epoch 35/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9262 - loss: 0.2590 - val_accuracy: 0.9258 - val_loss: 0.2671\n", + "Epoch 36/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9261 - loss: 0.2644 - val_accuracy: 0.9263 - val_loss: 0.2655\n", + "Epoch 37/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9253 - loss: 0.2594 - val_accuracy: 0.9253 - val_loss: 0.2638\n", + "Epoch 38/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9268 - loss: 0.2562 - val_accuracy: 0.9280 - val_loss: 0.2636\n", + "Epoch 39/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9269 - loss: 0.2536 - val_accuracy: 0.9283 - val_loss: 0.2634\n", + "Epoch 40/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9285 - loss: 0.2508 - val_accuracy: 0.9273 - val_loss: 0.2591\n", + "Epoch 41/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9264 - loss: 0.2551 - val_accuracy: 0.9280 - val_loss: 0.2589\n", + "Epoch 42/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9289 - loss: 0.2512 - val_accuracy: 0.9292 - val_loss: 0.2565\n", + "Epoch 43/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9306 - loss: 0.2440 - val_accuracy: 0.9288 - val_loss: 0.2559\n", + "Epoch 44/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9296 - loss: 0.2472 - val_accuracy: 0.9300 - val_loss: 0.2532\n", + "Epoch 45/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9294 - loss: 0.2429 - val_accuracy: 0.9300 - val_loss: 0.2522\n", + "Epoch 46/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9319 - loss: 0.2396 - val_accuracy: 0.9303 - val_loss: 0.2505\n", + "Epoch 47/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9321 - loss: 0.2385 - val_accuracy: 0.9318 - val_loss: 0.2493\n", + "Epoch 48/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9334 - loss: 0.2356 - val_accuracy: 0.9323 - val_loss: 0.2488\n", + "Epoch 49/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9341 - loss: 0.2325 - val_accuracy: 0.9317 - val_loss: 0.2459\n", + "Epoch 50/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9330 - loss: 0.2335 - val_accuracy: 0.9330 - val_loss: 0.2460\n", + "\u001b[1m313/313\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - accuracy: 0.9308 - loss: 0.2410\n", + "Accuracy on test data: 0.9310\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "plt.figure()\n", + "plt.plot(list(results.keys()), list(results.values()), marker='o')\n", + "plt.grid()\n", + "plt.title('Accuracy on test data depending on hidden layer size')\n", + "plt.xlabel('Number of neurons in hidden layer')\n", + "plt.ylabel('Accuracy')\n", + "plt.show()\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 472 + }, + "id": "oOMXUpqKXT9J", + "outputId": "a99d0590-6b0e-4c2c-98c9-2168469492f8" + }, + "execution_count": 17, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "source": [ + "from keras.models import Sequential\n", + "from keras.layers import Dense\n", + "\n", + "hidden2 = [50, 100]\n", + "results_2 = {}\n", + "\n", + "for n2 in hidden2:\n", + " print(f'\\n=== Модель со вторым скрытым слоем {n2} нейронов ===')\n", + "\n", + " # создание модели\n", + " model2 = Sequential()\n", + " model2.add(Dense(units=100, input_dim=784, activation='sigmoid')) # первый скрытый слой\n", + " model2.add(Dense(units=n2, activation='sigmoid')) # второй скрытый слой\n", + " model2.add(Dense(units=num_classes, activation='softmax')) # выходной слой\n", + "\n", + " # компиляция модели\n", + " model2.compile(loss='categorical_crossentropy',\n", + " optimizer='sgd',\n", + " metrics=['accuracy'])\n", + "\n", + " # обучение модели\n", + " H2 = model2.fit(X_train, y_train,\n", + " validation_split=0.1,\n", + " epochs=50,\n", + " verbose=1)\n", + "\n", + " # оценка на тестовых данных\n", + " scores = model2.evaluate(X_test, y_test, verbose=1)\n", + " results_2[n2] = scores[1]\n", + "\n", + " print(f'Accuracy on test data: {scores[1]:.4f}')\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "hoOv2VgOaXRP", + "outputId": "d9f1a030-c7a7-498e-9dc7-c65df3eef128" + }, + "execution_count": 18, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + "=== Модель со вторым скрытым слоем 50 нейронов ===\n", + "Epoch 1/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 3ms/step - accuracy: 0.2022 - loss: 2.2940 - val_accuracy: 0.5467 - val_loss: 2.1147\n", + "Epoch 2/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.5758 - loss: 2.0123 - val_accuracy: 0.7037 - val_loss: 1.5870\n", + "Epoch 3/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 3ms/step - accuracy: 0.7169 - loss: 1.4299 - val_accuracy: 0.7762 - val_loss: 1.0373\n", + "Epoch 4/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.7884 - loss: 0.9641 - val_accuracy: 0.8323 - val_loss: 0.7605\n", + "Epoch 5/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.8249 - loss: 0.7300 - val_accuracy: 0.8547 - val_loss: 0.6177\n", + "Epoch 6/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.8471 - loss: 0.6081 - val_accuracy: 0.8653 - val_loss: 0.5332\n", + "Epoch 7/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 3ms/step - accuracy: 0.8624 - loss: 0.5334 - val_accuracy: 0.8787 - val_loss: 0.4779\n", + "Epoch 8/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 3ms/step - accuracy: 0.8734 - loss: 0.4789 - val_accuracy: 0.8842 - val_loss: 0.4389\n", + "Epoch 9/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8813 - loss: 0.4459 - val_accuracy: 0.8905 - val_loss: 0.4088\n", + "Epoch 10/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.8864 - loss: 0.4200 - val_accuracy: 0.8963 - val_loss: 0.3865\n", + "Epoch 11/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8919 - loss: 0.3902 - val_accuracy: 0.9000 - val_loss: 0.3675\n", + "Epoch 12/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8963 - loss: 0.3764 - val_accuracy: 0.9032 - val_loss: 0.3534\n", + "Epoch 13/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.8983 - loss: 0.3645 - val_accuracy: 0.9057 - val_loss: 0.3410\n", + "Epoch 14/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9038 - loss: 0.3467 - val_accuracy: 0.9072 - val_loss: 0.3308\n", + "Epoch 15/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9045 - loss: 0.3438 - val_accuracy: 0.9090 - val_loss: 0.3216\n", + "Epoch 16/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9085 - loss: 0.3273 - val_accuracy: 0.9128 - val_loss: 0.3130\n", + "Epoch 17/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9080 - loss: 0.3217 - val_accuracy: 0.9143 - val_loss: 0.3057\n", + "Epoch 18/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9120 - loss: 0.3118 - val_accuracy: 0.9143 - val_loss: 0.2998\n", + "Epoch 19/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 3ms/step - accuracy: 0.9133 - loss: 0.3036 - val_accuracy: 0.9155 - val_loss: 0.2938\n", + "Epoch 20/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9158 - loss: 0.2938 - val_accuracy: 0.9178 - val_loss: 0.2894\n", + "Epoch 21/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9155 - loss: 0.2937 - val_accuracy: 0.9182 - val_loss: 0.2829\n", + "Epoch 22/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9175 - loss: 0.2871 - val_accuracy: 0.9210 - val_loss: 0.2776\n", + "Epoch 23/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9199 - loss: 0.2786 - val_accuracy: 0.9220 - val_loss: 0.2730\n", + "Epoch 24/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9206 - loss: 0.2792 - val_accuracy: 0.9243 - val_loss: 0.2692\n", + "Epoch 25/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9223 - loss: 0.2674 - val_accuracy: 0.9252 - val_loss: 0.2648\n", + "Epoch 26/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9220 - loss: 0.2649 - val_accuracy: 0.9265 - val_loss: 0.2612\n", + "Epoch 27/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9236 - loss: 0.2635 - val_accuracy: 0.9277 - val_loss: 0.2584\n", + "Epoch 28/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9243 - loss: 0.2622 - val_accuracy: 0.9273 - val_loss: 0.2539\n", + "Epoch 29/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9252 - loss: 0.2580 - val_accuracy: 0.9295 - val_loss: 0.2504\n", + "Epoch 30/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9296 - loss: 0.2464 - val_accuracy: 0.9308 - val_loss: 0.2473\n", + "Epoch 31/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9274 - loss: 0.2507 - val_accuracy: 0.9318 - val_loss: 0.2437\n", + "Epoch 32/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9319 - loss: 0.2378 - val_accuracy: 0.9330 - val_loss: 0.2404\n", + "Epoch 33/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9318 - loss: 0.2354 - val_accuracy: 0.9347 - val_loss: 0.2375\n", + "Epoch 34/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9332 - loss: 0.2331 - val_accuracy: 0.9348 - val_loss: 0.2348\n", + "Epoch 35/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9316 - loss: 0.2361 - val_accuracy: 0.9350 - val_loss: 0.2317\n", + "Epoch 36/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9347 - loss: 0.2266 - val_accuracy: 0.9370 - val_loss: 0.2286\n", + "Epoch 37/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9354 - loss: 0.2221 - val_accuracy: 0.9380 - val_loss: 0.2263\n", + "Epoch 38/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9377 - loss: 0.2158 - val_accuracy: 0.9370 - val_loss: 0.2240\n", + "Epoch 39/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9378 - loss: 0.2164 - val_accuracy: 0.9397 - val_loss: 0.2208\n", + "Epoch 40/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9388 - loss: 0.2116 - val_accuracy: 0.9397 - val_loss: 0.2190\n", + "Epoch 41/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9385 - loss: 0.2116 - val_accuracy: 0.9400 - val_loss: 0.2162\n", + "Epoch 42/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9406 - loss: 0.2051 - val_accuracy: 0.9410 - val_loss: 0.2132\n", + "Epoch 43/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9406 - loss: 0.2056 - val_accuracy: 0.9423 - val_loss: 0.2107\n", + "Epoch 44/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9409 - loss: 0.2038 - val_accuracy: 0.9430 - val_loss: 0.2095\n", + "Epoch 45/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9412 - loss: 0.2007 - val_accuracy: 0.9427 - val_loss: 0.2077\n", + "Epoch 46/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9432 - loss: 0.1956 - val_accuracy: 0.9435 - val_loss: 0.2046\n", + "Epoch 47/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9419 - loss: 0.1992 - val_accuracy: 0.9440 - val_loss: 0.2026\n", + "Epoch 48/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9452 - loss: 0.1876 - val_accuracy: 0.9445 - val_loss: 0.2006\n", + "Epoch 49/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9458 - loss: 0.1856 - val_accuracy: 0.9452 - val_loss: 0.1984\n", + "Epoch 50/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9475 - loss: 0.1837 - val_accuracy: 0.9465 - val_loss: 0.1959\n", + "\u001b[1m313/313\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 2ms/step - accuracy: 0.9455 - loss: 0.1915\n", + "Accuracy on test data: 0.9443\n", + "\n", + "=== Модель со вторым скрытым слоем 100 нейронов ===\n", + "Epoch 1/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 3ms/step - accuracy: 0.2068 - loss: 2.2684 - val_accuracy: 0.4813 - val_loss: 2.1012\n", + "Epoch 2/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m8s\u001b[0m 2ms/step - accuracy: 0.5575 - loss: 1.9829 - val_accuracy: 0.6698 - val_loss: 1.5285\n", + "Epoch 3/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.6990 - loss: 1.3824 - val_accuracy: 0.7685 - val_loss: 1.0101\n", + "Epoch 4/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.7781 - loss: 0.9420 - val_accuracy: 0.8232 - val_loss: 0.7523\n", + "Epoch 5/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8213 - loss: 0.7217 - val_accuracy: 0.8468 - val_loss: 0.6142\n", + "Epoch 6/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.8485 - loss: 0.6027 - val_accuracy: 0.8658 - val_loss: 0.5266\n", + "Epoch 7/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.8624 - loss: 0.5256 - val_accuracy: 0.8790 - val_loss: 0.4697\n", + "Epoch 8/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8740 - loss: 0.4725 - val_accuracy: 0.8868 - val_loss: 0.4302\n", + "Epoch 9/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.8833 - loss: 0.4295 - val_accuracy: 0.8943 - val_loss: 0.4012\n", + "Epoch 10/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.8887 - loss: 0.4084 - val_accuracy: 0.8972 - val_loss: 0.3804\n", + "Epoch 11/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.8952 - loss: 0.3844 - val_accuracy: 0.9015 - val_loss: 0.3634\n", + "Epoch 12/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.8984 - loss: 0.3638 - val_accuracy: 0.9040 - val_loss: 0.3506\n", + "Epoch 13/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9008 - loss: 0.3556 - val_accuracy: 0.9067 - val_loss: 0.3396\n", + "Epoch 14/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9056 - loss: 0.3413 - val_accuracy: 0.9088 - val_loss: 0.3294\n", + "Epoch 15/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9035 - loss: 0.3393 - val_accuracy: 0.9103 - val_loss: 0.3212\n", + "Epoch 16/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9074 - loss: 0.3235 - val_accuracy: 0.9130 - val_loss: 0.3139\n", + "Epoch 17/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9081 - loss: 0.3212 - val_accuracy: 0.9142 - val_loss: 0.3075\n", + "Epoch 18/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9105 - loss: 0.3134 - val_accuracy: 0.9163 - val_loss: 0.3034\n", + "Epoch 19/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9118 - loss: 0.3105 - val_accuracy: 0.9178 - val_loss: 0.2956\n", + "Epoch 20/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9152 - loss: 0.2931 - val_accuracy: 0.9180 - val_loss: 0.2911\n", + "Epoch 21/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9177 - loss: 0.2900 - val_accuracy: 0.9207 - val_loss: 0.2858\n", + "Epoch 22/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9180 - loss: 0.2861 - val_accuracy: 0.9217 - val_loss: 0.2810\n", + "Epoch 23/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9211 - loss: 0.2709 - val_accuracy: 0.9243 - val_loss: 0.2765\n", + "Epoch 24/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9215 - loss: 0.2735 - val_accuracy: 0.9238 - val_loss: 0.2727\n", + "Epoch 25/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9215 - loss: 0.2737 - val_accuracy: 0.9252 - val_loss: 0.2689\n", + "Epoch 26/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9226 - loss: 0.2697 - val_accuracy: 0.9265 - val_loss: 0.2648\n", + "Epoch 27/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9260 - loss: 0.2615 - val_accuracy: 0.9267 - val_loss: 0.2616\n", + "Epoch 28/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9258 - loss: 0.2572 - val_accuracy: 0.9280 - val_loss: 0.2578\n", + "Epoch 29/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9269 - loss: 0.2524 - val_accuracy: 0.9285 - val_loss: 0.2546\n", + "Epoch 30/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9271 - loss: 0.2460 - val_accuracy: 0.9292 - val_loss: 0.2522\n", + "Epoch 31/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9291 - loss: 0.2513 - val_accuracy: 0.9305 - val_loss: 0.2482\n", + "Epoch 32/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9313 - loss: 0.2402 - val_accuracy: 0.9312 - val_loss: 0.2451\n", + "Epoch 33/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9312 - loss: 0.2371 - val_accuracy: 0.9315 - val_loss: 0.2417\n", + "Epoch 34/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9309 - loss: 0.2393 - val_accuracy: 0.9337 - val_loss: 0.2399\n", + "Epoch 35/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9329 - loss: 0.2306 - val_accuracy: 0.9337 - val_loss: 0.2361\n", + "Epoch 36/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9337 - loss: 0.2273 - val_accuracy: 0.9350 - val_loss: 0.2332\n", + "Epoch 37/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9356 - loss: 0.2217 - val_accuracy: 0.9363 - val_loss: 0.2301\n", + "Epoch 38/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9353 - loss: 0.2209 - val_accuracy: 0.9368 - val_loss: 0.2278\n", + "Epoch 39/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9354 - loss: 0.2212 - val_accuracy: 0.9382 - val_loss: 0.2251\n", + "Epoch 40/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9365 - loss: 0.2165 - val_accuracy: 0.9367 - val_loss: 0.2242\n", + "Epoch 41/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9395 - loss: 0.2096 - val_accuracy: 0.9392 - val_loss: 0.2207\n", + "Epoch 42/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9409 - loss: 0.2031 - val_accuracy: 0.9420 - val_loss: 0.2182\n", + "Epoch 43/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9397 - loss: 0.2045 - val_accuracy: 0.9400 - val_loss: 0.2158\n", + "Epoch 44/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9407 - loss: 0.2056 - val_accuracy: 0.9405 - val_loss: 0.2139\n", + "Epoch 45/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9430 - loss: 0.2003 - val_accuracy: 0.9425 - val_loss: 0.2111\n", + "Epoch 46/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9430 - loss: 0.1957 - val_accuracy: 0.9437 - val_loss: 0.2094\n", + "Epoch 47/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 2ms/step - accuracy: 0.9435 - loss: 0.1938 - val_accuracy: 0.9440 - val_loss: 0.2074\n", + "Epoch 48/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 3ms/step - accuracy: 0.9453 - loss: 0.1909 - val_accuracy: 0.9445 - val_loss: 0.2044\n", + "Epoch 49/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9454 - loss: 0.1840 - val_accuracy: 0.9442 - val_loss: 0.2030\n", + "Epoch 50/50\n", + "\u001b[1m1688/1688\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m4s\u001b[0m 3ms/step - accuracy: 0.9469 - loss: 0.1833 - val_accuracy: 0.9452 - val_loss: 0.2004\n", + "\u001b[1m313/313\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 3ms/step - accuracy: 0.9464 - loss: 0.1934\n", + "Accuracy on test data: 0.9445\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "model2.save('/content/drive/MyDrive/Colab Notebooks/best_model_2x100.h5')" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "tx4veCj0eIAn", + "outputId": "467c645f-11ce-4215-b841-ce8e85973947" + }, + "execution_count": 19, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "# выбираем индексы двух случайных изображений\n", + "indices = np.random.choice(range(X_test.shape[0]), 2, replace=False)\n", + "\n", + "# получаем предсказания\n", + "predictions = model2.predict(X_test[indices])\n", + "predicted_labels = np.argmax(predictions, axis=1)\n", + "true_labels = np.argmax(y_test[indices], axis=1)\n", + "\n", + "# вывод изображений и меток\n", + "plt.figure(figsize=(6, 3))\n", + "for i, idx in enumerate(indices):\n", + " plt.subplot(1, 2, i + 1)\n", + " plt.imshow(X_test[idx].reshape(28, 28), cmap='gray')\n", + " plt.title(f'True: {true_labels[i]}, Pred: {predicted_labels[i]}')\n", + " plt.axis('off')\n", + "plt.show()\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 287 + }, + "id": "3O230VttfOjg", + "outputId": "b1f7052b-8345-445b-dac2-8f557387c95b" + }, + "execution_count": 21, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 595ms/step\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "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\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "source": [ + "from google.colab import files\n", + "uploaded = files.upload()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 106 + }, + "id": "s3G-oejNgUAZ", + "outputId": "6613a9af-d9b5-47b8-8452-06e5d706a94a" + }, + "execution_count": 23, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "" + ], + "text/html": [ + "\n", + " \n", + " \n", + " Upload widget is only available when the cell has been executed in the\n", + " current browser session. Please rerun this cell to enable.\n", + " \n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Saving 5.png to 5.png\n", + "Saving 6.png to 6 (1).png\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "from tensorflow.keras.preprocessing import image\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "file_names = list(uploaded.keys())\n", + "\n", + "X_custom = []\n", + "\n", + "for fname in file_names:\n", + " # загружаем изображение в оттенках серого и приводим к 28×28\n", + " img = image.load_img(fname, color_mode='grayscale', target_size=(28, 28))\n", + " img_array = image.img_to_array(img)\n", + "\n", + " # инвертируем цвета, если фон белый (MNIST — белая цифра на чёрном фоне)\n", + " img_array = 255 - img_array\n", + "\n", + " # нормализация\n", + " img_array = img_array / 255.0\n", + "\n", + " # разворачиваем в вектор длиной 784\n", + " img_flat = img_array.reshape(1, 784)\n", + "\n", + " X_custom.append(img_flat)\n", + "\n", + "X_custom = np.vstack(X_custom)\n" + ], + "metadata": { + "id": "JiNFxBJKgf5w" + }, + "execution_count": 24, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "predictions = model2.predict(X_custom)\n", + "predicted_labels = np.argmax(predictions, axis=1)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "s3-tukq_gjcT", + "outputId": "205afb54-c1fe-48a9-e46b-4e35639f794f" + }, + "execution_count": 25, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 53ms/step\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "plt.figure(figsize=(6, 3))\n", + "for i, fname in enumerate(file_names):\n", + " img = image.load_img(fname, color_mode='grayscale', target_size=(28, 28))\n", + " plt.subplot(1, len(file_names), i + 1)\n", + " plt.imshow(img, cmap='gray')\n", + " plt.title(f'Pred: {predicted_labels[i]}')\n", + " plt.axis('off')\n", + "plt.show()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 270 + }, + "id": "ZXbmJcBDgmHI", + "outputId": "1045193a-bc8a-432e-930b-1155bef28551" + }, + "execution_count": 26, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeQAAAD9CAYAAABtAAQeAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAADmdJREFUeJzt3VuIlVUbB/BnbNRxVL6sPISHsZNdBAVlRRhEZQe0m0iCDqBdlAQZERHRRURZ3gQVFRVR1oURRBARFWWIWd0InQvKxNQyxvGQlqYz07zfxUfySb5rj+PYPOP+/WAu3M9e76zZ45r/Xnvm2aulqqoqAIAhNWKoJwAACGQASEEgA0ACAhkAEhDIAJCAQAaABAQyACQgkAEgAYEMAAkI5GPczJkzY9GiRUM9DeBfZN0PTwL5KHr55ZejpaXlwEdbW1vMmjUr7rjjjujs7Bzq6TW0ZcuWuPnmm+PMM8+M8ePHx/HHHx8XXHBBvPLKK+EdV+HQrHsGqnWoJ9AMHnrooTjllFNi37598fHHH8ezzz4b77zzTnzzzTfR3t4+1NOrtW3btvj5559jwYIFMWPGjOjp6YkPPvggFi1aFN9//308+uijQz1FSMu657BVHDXLly+vIqJau3btQbfffffdVURUr776au3YP/74Y1Dm0NHRUS1cuHBQrvW3a665pho7dmzV29s7qNeFY4F1z0B5yXoIXHbZZRERsWHDhoiIWLRoUYwbNy7Wr18f8+bNi/Hjx8dNN90UERF9fX3xxBNPxFlnnRVtbW0xefLkWLx4cezcufOga1ZVFUuXLo1p06ZFe3t7XHrppfHtt98e8vOvX78+1q9fP+D5z5w5M/bu3Rvd3d0DvgY0G+ueRrxkPQT+XhQnnnjigdt6e3vjqquuiosvvjgee+yxAy9pLV68OF5++eW45ZZb4s4774wNGzbE008/HZ9//nl88sknMXLkyIiIeOCBB2Lp0qUxb968mDdvXnz22Wdx5ZVXHnLxXH755RER8dNPP/Vrvn/++Wfs2bMn/vjjj1i9enUsX748LrroohgzZsyRPAzQVKx7GhrqLfqx7O+XrlauXFl1dXVVmzdvrl577bXqxBNPrMaMGVP9/PPPVVVV1cKFC6uIqO67776Dxq9Zs6aKiGrFihUH3f7ee+8ddPvWrVurUaNGVfPnz6/6+voO3O/++++vIuIfL111dHRUHR0d/f46li1bVkXEgY/LL7+82rRp02E8EtA8rHsGyg75XzB37tyD/t3R0RErVqyIqVOnHnT77bffftC/X3/99fjPf/4TV1xxRWzbtu3A7eedd16MGzcuVq1aFTfeeGOsXLkyuru7Y8mSJdHS0nLgfnfdddch/wCjv8+Q/3bDDTfE7Nmzo6urK95+++3o7OyMP//887CuAc3GuudwCeR/wTPPPBOzZs2K1tbWmDx5cpx55pkxYsTBv75vbW2NadOmHXTbunXrYteuXTFp0qRDXnfr1q0REbFx48aIiDjjjDMOqk+cODEmTJhwxPPv6OiIjo6OiPjfIr3tttti7ty58f3333v5CmpY9xwugfwvuOCCC2L27NnF+4wePfofi7Wvry8mTZoUK1asOOSYiRMnDtocD8eCBQvihRdeiI8++iiuuuqqIZkDZGfdc7gEcmKnnXZarFy5MubMmVN8Rvr3s9h169bFqaeeeuD2rq6uf/xV5mD4+2WrXbt2Dfq1odlZ981L21Ni119/ffz111/x8MMP/6PW29sbv/32W0T873dVI0eOjKeeeuqgd9J54oknDnnd/rY/dHV1HfL2F198MVpaWuLcc89t/EUAh8W6b152yIldcsklsXjx4li2bFl88cUXceWVV8bIkSNj3bp18frrr8eTTz4ZCxYsiIkTJ8Y999wTy5Yti2uuuSbmzZsXn3/+ebz77rtx0kkn/eO6/W1/eOSRR+KTTz6Jq6++OmbMmBE7duyIN954I9auXRtLliyJ008//Wh82dDUrPvmJZCTe+655+K8886L559/Pu6///5obW2NmTNnxs033xxz5sw5cL+lS5dGW1tbPPfcc7Fq1aq48MIL4/3334/58+cP+HPPnz8/1q9fHy+99FJ0dXVFW1tbnH322bF8+fJYuHDhYHx5wCFY982ppaq8WzgADDW/QwaABAQyACQgkAEgAYEMAAkIZABIQCADQAICGQAS6Pcbg/z/8V7AkRku7f/WPQyeRuveDhkAEhDIAJCAQAaABAQyACQgkAEgAYEMAAkIZABIQCADQAICGQASEMgAkIBABoAEBDIAJCCQASABgQwACQhkAEhAIANAAgIZABIQyACQgEAGgAQEMgAkIJABIAGBDAAJCGQASEAgA0ACAhkAEhDIAJCAQAaABAQyACQgkAEgAYEMAAkIZABIQCADQAICGQASEMgAkIBABoAEBDIAJNA61BOgOaxdu7a2NmXKlOLY6dOnD/Z04Jjy5ZdfFuunnnpqbW38+PGDPR0GyA4ZABIQyACQgEAGgAQEMgAkIJABIAGBDAAJaHtqMhs2bKitNWovamlpqa319PQUx5bqv/32W3EsNLu+vr5ivbe3d8DX3rNnT7E+duzYAV+bw2OHDAAJCGQASEAgA0ACAhkAEhDIAJCAQAaABAQyACSgD3mY+fXXX4v1k046qVj/66+/amu7d+8ujh09enRtrVGf5KhRo2prb775ZnEsNIOqqmpr3d3dxbGl9cXwYYcMAAkIZABIQCADQAICGQASEMgAkIBABoAEBDIAJKAPeYC2bNlSrE+aNKm2VjpXOCJixIj650n79+8vjm1tLX9L77333tra448/XhwLDNzXX39drJd6jbdt21YcO3Xq1GJ91apVtbU5c+YUx/LvsUMGgAQEMgAkIJABIAGBDAAJCGQASEAgA0ACLVXpzK//v2ODVp1jUemowp6enuLY0sPa1tZWHFtqf1i2bFlx7IMPPlisk0M/l92Qa8Z1fyRWr15dW5s9e3Zx7I8//lhbO+eccwY8p0Y2bdpUrM+YMeOofe5m02jd2yEDQAICGQASEMgAkIBABoAEBDIAJCCQASABgQwACehDLujs7KytnXDCCcWxO3bsqK1Nnjx5wHPi2KAP+djU29s7oFpE4/cnYPjThwwAw4BABoAEBDIAJCCQASABgQwACQhkAEigdagnkNn27dtra+3t7cWxn3766WBPBxhijz76aLFeOpa1dKwqRNghA0AKAhkAEhDIAJCAQAaABAQyACQgkAEgAYEMAAnoQy4YO3bsgMdee+21gzgTIIPrr7++WC8dsfjNN98M9nQ4xtghA0ACAhkAEhDIAJCAQAaABAQyACQgkAEgAW1PBSNG1D9fOe6444pj16xZM6DrRkRs2rSptnbDDTcUxwJHz4QJE4r1UaNG1da++uqrwZ4Oxxg7ZABIQCADQAICGQASEMgAkIBABoAEBDIAJCCQASCBlqqqqn7dsaXlaM8lnd27d9fWGvUh9/X11dYaPeSlXsZGGn2fSr2Q559//oA/L4enn8tuyDXjui/5/fffi/XSewx0dnYWx55yyim1tdLPk4iIvXv3Fuulo2RL73sQETFz5sxinf5rtO7tkAEgAYEMAAkIZABIQCADQAICGQASEMgAkIBABoAE9CEXlPoGx4wZUxw7evTo2tq+ffuKY0v9z1OmTCmO7e3tHfC8NmzYUBx72mmnFev0nz7k4enXX38t1ks/F0prL6Lca9ze3l4cu3///mK99P+tra2tONb/gcGjDxkAhgGBDAAJCGQASEAgA0ACAhkAEhDIAJBA61BPYLjq7u4u1t94443a2i233DLY0+m3jRs31tZOPvnk4tjNmzfX1qZPnz7gOcFwMWHChGK99HOhUftQqX6krUerV6+urV100UXFsS+88EJt7dZbbx3wnPgnO2QASEAgA0ACAhkAEhDIAJCAQAaABAQyACQgkAEgAX3IBaXj0nbu3FkcO5S9xiUdHR21tZ6enuLY448/fpBnA8NLo6NTR40aVVsbMaK8/yn1+R+pLVu21NYaHd04derUwZ4ONeyQASABgQwACQhkAEhAIANAAgIZABIQyACQQEtVVVW/7niEx38NR9ddd11trXS84nD1448/FuuTJ0+urY0fP36wp3NM6+eyG3LNuO5Ldu/eXaz39fXV1nbt2lUcW2pJPFJ79uyprbW2lrtfr7766traqlWrBjynZtRo3dshA0ACAhkAEhDIAJCAQAaABAQyACQgkAEgAYEMAAnoQ+aA7du3F+ulo+X0IR8efcjD0w8//FCsl44qbNTvu3fv3tpao/XV6PtUOlq1s7OzOPZo9kc3G33IADAMCGQASEAgA0ACAhkAEhDIAJCAQAaABMp/h09TGTduXLFeOloOmsGsWbOK9f379w/42mPHjq2tldqWIhqvzeOOO6629uGHH5Ynxr/GDhkAEhDIAJCAQAaABAQyACQgkAEgAYEMAAkIZABIQB9yk1m+fHltrbu7uzh23759gz0dOKaMHj26tvbdd98Vx06fPr221ug9AhodoThlypRinRzskAEgAYEMAAkIZABIQCADQAICGQASEMgAkIBABoAEWqqqqvp1x5aWoz2XY0rpYW10dumuXbtqaxMmTCiObdRLXKqXzkyNiGhvby/W6b9+LrshZ93D4Gm07u2QASABgQwACQhkAEhAIANAAgIZABIQyACQgOMXB2jz5s3F+s6dO2trjdqHenp6amu9vb3Fsb///nuxPmbMmAHPC4Cjxw4ZABIQyACQgEAGgAQEMgAkIJABIAGBDAAJCGQASMDxi0fJxo0ba2ttbW3FsW+99VZt7ZdffimOffDBB4t1cnD8IjQfxy8CwDAgkAEgAYEMAAkIZABIQCADQAICGQAS0PYEQ0DbEzQfbU8AMAwIZABIQCADQAICGQASEMgAkIBABoAEBDIAJCCQASABgQwACQhkAEhAIANAAgIZABIQyACQgEAGgAQEMgAkIJABIAGBDAAJCGQASEAgA0ACAhkAEhDIAJCAQAaABFqqqqqGehIA0OzskAEgAYEMAAkIZABIQCADQAICGQASEMgAkIBABoAEBDIAJCCQASCB/wIH/r19W7WYugAAAABJRU5ErkJggg==\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "source": [ + "probs = model2.predict(X_custom) # X_custom — (N,784) или (N,28,28,1)\n", + "print(probs) # вероятности по 10 классам\n", + "print(np.argmax(probs, axis=1)) # предсказанные классы\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "yIQdGa6ng4SX", + "outputId": "e4f8467d-8955-4517-97c1-d69d15fa1f64" + }, + "execution_count": 27, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 33ms/step\n", + "[[1.7843387e-04 2.5620324e-05 9.6879220e-03 9.8594320e-01 2.5915762e-08\n", + " 2.2038540e-03 8.8322827e-07 6.2859053e-06 1.9501867e-03 3.5526070e-06]\n", + " [3.8881015e-04 1.2971306e-05 2.7805394e-03 9.9061769e-01 1.2557522e-08\n", + " 5.8032214e-03 7.3892338e-08 2.2987399e-05 3.7107972e-04 2.6070065e-06]]\n", + "[3 3]\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "plt.imshow(X_custom[0].reshape(28, 28), cmap='gray')\n", + "plt.show()\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 430 + }, + "id": "M7w5kiHPhNFq", + "outputId": "cba85024-b2c0-4784-f378-b3c3a23ccadb" + }, + "execution_count": 28, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAaAAAAGdCAYAAABU0qcqAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAGtBJREFUeJzt3X9s1PUdx/HXFdoDtb1aS3s9ObqCP3AiXcaga1CmoaF0CRNhib+WgDEYWTHDzulYVHBb0omJMxoG/2wwE0HnIhBNRoLFlrgVNlBCyGZDm05KaAsye1cKHIx+9gfh5kErfI+7vtvj+Ui+Cb37fnpvvx598u1dv/U555wAABhiWdYDAACuTQQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYGG09wMX6+/t15MgR5ebmyufzWY8DAPDIOafe3l6FQiFlZQ1+njPsAnTkyBGFw2HrMQAAV6mjo0Pjx48f9P5hF6Dc3FxJ5wfPy8szngYA4FU0GlU4HI5/PR9M2gK0Zs0avfLKK+rq6lJ5ebneeOMNzZgx47LrLnzbLS8vjwABwAh2uZdR0vImhHfeeUd1dXVauXKlPvnkE5WXl6u6ulpHjx5Nx8MBAEagtATo1Vdf1ZIlS/TYY4/pm9/8ptatW6frrrtOf/jDH9LxcACAESjlATpz5oz27t2rqqqq/z9IVpaqqqrU3Nx8yf6xWEzRaDRhAwBkvpQH6IsvvtC5c+dUXFyccHtxcbG6urou2b++vl6BQCC+8Q44ALg2mP8g6ooVKxSJROJbR0eH9UgAgCGQ8nfBFRYWatSoUeru7k64vbu7W8Fg8JL9/X6//H5/qscAAAxzKT8DysnJ0bRp09TQ0BC/rb+/Xw0NDaqsrEz1wwEARqi0/BxQXV2dFi1apO985zuaMWOGXnvtNfX19emxxx5Lx8MBAEagtATowQcf1LFjx/Tiiy+qq6tL3/rWt7Rt27ZL3pgAALh2+ZxzznqIr4pGowoEAopEIlwJAQBGoCv9Om7+LjgAwLWJAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMDHaegAA167p06d7XtPZ2el5zeHDhz2vQfpxBgQAMEGAAAAmUh6gVatWyefzJWyTJ09O9cMAAEa4tLwGdOedd+rDDz/8/4OM5qUmAECitJRh9OjRCgaD6fjUAIAMkZbXgA4ePKhQKKSJEyfq0Ucf1aFDhwbdNxaLKRqNJmwAgMyX8gBVVFRow4YN2rZtm9auXav29nbdc8896u3tHXD/+vp6BQKB+BYOh1M9EgBgGPI551w6H6Cnp0elpaV69dVX9fjjj19yfywWUywWi38cjUYVDocViUSUl5eXztEAGOPngDJTNBpVIBC47NfxtL87ID8/X7fddptaW1sHvN/v98vv96d7DADAMJP2nwM6ceKE2traVFJSku6HAgCMICkP0DPPPKOmpib9+9//1t/+9jc98MADGjVqlB5++OFUPxQAYARL+bfgDh8+rIcffljHjx/XuHHjdPfdd2vXrl0aN25cqh8KADCCpTxAb7/9dqo/JQBJZWVlntd0dHQk9VjJvDcpOzvb85pkfkg9Pz/f8xoMT1wLDgBgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwkfZfSAdkumR+19UXX3zhec2oUaM8r0n2twp/9bcUXymfz+d5zdmzZz2vmT9/vuc1GJ44AwIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJroaNIRUKhTyvOXr0qOc1zjnPaySpv7/f8xq/3+95zX//+1/Pa15++WXPa+rq6jyvAYYKZ0AAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkuRoqkjRo1yvOa7OzsIVlz+vRpz2skKScnx/Oan//8557XrFq1yvMaINNwBgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmOBipEhaYWGh5zX/+c9/PK8pKCjwvObUqVOe1wAYWpwBAQBMECAAgAnPAdq5c6fmzZunUCgkn8+nLVu2JNzvnNOLL76okpISjR07VlVVVTp48GCq5gUAZAjPAerr61N5ebnWrFkz4P2rV6/W66+/rnXr1mn37t26/vrrVV1dnfQvCAMAZCbPb0KoqalRTU3NgPc55/Taa6/p+eef1/333y9JevPNN1VcXKwtW7booYceurppAQAZI6WvAbW3t6urq0tVVVXx2wKBgCoqKtTc3Dzgmlgspmg0mrABADJfSgPU1dUlSSouLk64vbi4OH7fxerr6xUIBOJbOBxO5UgAgGHK/F1wK1asUCQSiW8dHR3WIwEAhkBKAxQMBiVJ3d3dCbd3d3fH77uY3+9XXl5ewgYAyHwpDVBZWZmCwaAaGhrit0WjUe3evVuVlZWpfCgAwAjn+V1wJ06cUGtra/zj9vZ27du3TwUFBZowYYKWL1+uX//617r11ltVVlamF154QaFQSPPnz0/l3ACAEc5zgPbs2aP77rsv/nFdXZ0kadGiRdqwYYOeffZZ9fX16YknnlBPT4/uvvtubdu2TWPGjEnd1ACAEc/nnHPWQ3xVNBpVIBBQJBLh9aBh7o477vC85vDhw57XfPVt/Vdq8+bNntcASI0r/Tpu/i44AMC1iQABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACY8/zoG4IKTJ08OyeNwZWsgM3EGBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCY4GKkSFp/f7/nNefOnfO85p577vG8JpnZJGnChAme12zatCmpxwKudZwBAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmuBgpkhaJRDyv8fl8ntfs27dvSB5Hkvbu3et5zZgxYzyvcc55XjN16lTPa/7xj394XgMMFc6AAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATXIwUSRs7dqznNadOnfK8JhaLeV6TzAVCJamwsNDzmu7ubs9rRo/2/lcvmQulTpo0yfMaSWpra0tqHeAFZ0AAABMECABgwnOAdu7cqXnz5ikUCsnn82nLli0J9y9evFg+ny9hmzt3bqrmBQBkCM8B6uvrU3l5udasWTPoPnPnzlVnZ2d827Rp01UNCQDIPJ5fCa2pqVFNTc3X7uP3+xUMBpMeCgCQ+dLyGlBjY6OKiop0++23a+nSpTp+/Pig+8ZiMUWj0YQNAJD5Uh6guXPn6s0331RDQ4NefvllNTU1qaamRufOnRtw//r6egUCgfgWDodTPRIAYBhK+c8BPfTQQ/E/33XXXZo6daomTZqkxsZGzZ49+5L9V6xYobq6uvjH0WiUCAHANSDtb8OeOHGiCgsL1draOuD9fr9feXl5CRsAIPOlPUCHDx/W8ePHVVJSku6HAgCMIJ6/BXfixImEs5n29nbt27dPBQUFKigo0EsvvaSFCxcqGAyqra1Nzz77rG655RZVV1endHAAwMjmOUB79uzRfffdF//4wus3ixYt0tq1a7V//3798Y9/VE9Pj0KhkObMmaNf/epX8vv9qZsaADDi+ZxzznqIr4pGowoEAopEIrweNMwVFxd7XjPYuyG/zrx58zyvWb9+vec1w11paannNceOHUvqsQoKCjyvOXz4cFKPhcxzpV/HuRYcAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATKT8V3Lj2hGLxTyvufHGGz2vycQrWyfj888/97wmOzs7qcfq6elJah3gBWdAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJLkaKpP3+97/3vGbhwoVpmASDKS0tTWpdd3d3iicBLsUZEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABggouRImlcWHT4+/LLL61HAAbFGRAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIKLkQIZ7MSJE0mty8ri36ZIP55lAAATBAgAYMJTgOrr6zV9+nTl5uaqqKhI8+fPV0tLS8I+p0+fVm1trW666SbdcMMNWrhwobq7u1M6NABg5PMUoKamJtXW1mrXrl3avn27zp49qzlz5qivry++z9NPP633339f7777rpqamnTkyBEt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PAd4flxq4sSJKiwszMjnx7Jly/TBBx/oo48+Svj1LcFgUGfOnFFPT0/C/pn6fBjsOAykoqJCkobV82HYBygnJ0fTpk1TQ0ND/Lb+/n41NDSosrLScDJ7J06cUFtbm0pKSqxHMVNWVqZgMJjw/IhGo9q9e/c1//w4fPiwjh8/nlHPD+ecli1bps2bN2vHjh0qKytLuH/atGnKzs5OeD60tLTo0KFDGfV8uNxxGMi+ffskaXg9H6zfBXEl3n77bef3+92GDRvcP//5T/fEE0+4/Px819XVZT3akPrpT3/qGhsbXXt7u/vrX//qqqqqXGFhoTt69Kj1aGnV29vrPv30U/fpp586Se7VV191n376qfv888+dc8795je/cfn5+W7r1q1u//797v7773dlZWXu1KlTxpOn1tcdh97eXvfMM8+45uZm197e7j788EP37W9/2916663u9OnT1qOnzNKlS10gEHCNjY2us7Mzvp08eTK+z5NPPukmTJjgduzY4fbs2eMqKytdZWWl4dSpd7nj0Nra6n75y1+6PXv2uPb2drd161Y3ceJEN2vWLOPJE42IADnn3BtvvOEmTJjgcnJy3IwZM9yuXbusRxpyDz74oCspKXE5OTnu5ptvdg8++KBrbW21HivtPvroIyfpkm3RokXOufNvxX7hhRdccXGx8/v9bvbs2a6lpcV26DT4uuNw8uRJN2fOHDdu3DiXnZ3tSktL3ZIlSzLuH2kD/fdLcuvXr4/vc+rUKffjH//Y3Xjjje66665zDzzwgOvs7LQbOg0udxwOHTrkZs2a5QoKCpzf73e33HKL+9nPfuYikYjt4Bfh1zEAAEwM+9eAAACZiQABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAw8T8dwrhHRvh2ggAAAABJRU5ErkJggg==\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "source": [ + "X_custom = 1 - X_custom\n", + "predictions = model2.predict(X_custom)\n", + "print(np.argmax(predictions, axis=1))\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ecnPWIl6hRhA", + "outputId": "52f8d82b-aea9-4ea9-dba8-23625f099c94" + }, + "execution_count": 29, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 53ms/step\n", + "[5 6]\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "from google.colab import files\n", + "uploaded = files.upload()\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 106 + }, + "id": "ohxeNV-Qjeme", + "outputId": "dac546bc-cd0e-47f1-c44b-4205d61c5bde" + }, + "execution_count": 30, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "" + ], + "text/html": [ + "\n", + " \n", + " \n", + " Upload widget is only available when the cell has been executed in the\n", + " current browser session. Please rerun this cell to enable.\n", + " \n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Saving 6 (1).png to 6 (1) (1).png\n", + "Saving 5 (1).png to 5 (1).png\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "from tensorflow.keras.preprocessing import image\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "file_names = list(uploaded.keys())\n", + "X_rotated = []\n", + "\n", + "for fname in file_names:\n", + " # загружаем повернутое изображение и приводим к формату 28×28\n", + " img = image.load_img(fname, color_mode='grayscale', target_size=(28, 28))\n", + " img_array = image.img_to_array(img) / 255.0 # нормализация\n", + "\n", + " # разворачиваем в вектор длиной 784\n", + " img_flat = img_array.reshape(1, 784)\n", + " X_rotated.append(img_flat)\n", + "\n", + "X_rotated = np.vstack(X_rotated)\n", + "\n", + "# инвертируем цвета (цифры — светлые, фон — тёмный)\n", + "X_rotated = 1 - X_rotated\n", + "\n", + "# предсказания модели\n", + "predictions = model2.predict(X_rotated)\n", + "predicted_labels = np.argmax(predictions, axis=1)\n", + "\n", + "# вывод изображений и предсказаний\n", + "plt.figure(figsize=(6, 3))\n", + "for i, fname in enumerate(file_names):\n", + " img = image.load_img(fname, color_mode='grayscale', target_size=(28, 28))\n", + " plt.subplot(1, len(file_names), i + 1)\n", + " plt.imshow(img, cmap='gray')\n", + " plt.title(f'Pred: {predicted_labels[i]}')\n", + " plt.axis('off')\n", + "plt.show()\n", + "\n", + "print('Распознанные цифры:', predicted_labels)\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 305 + }, + "id": "vWlGcm6NjjWM", + "outputId": "a2503810-13fb-476c-82b1-cb708df60e02" + }, + "execution_count": 36, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 31ms/step\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeQAAAD9CAYAAABtAAQeAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAADkJJREFUeJzt3Vto1vUfwPHPctNZs5Ou7GDzkBV0go6URZT9NTQiSIIs0C5KgoyIgvCii7K86aKo6EStLowoIojoKEgHr6IsOifLtJM60SynNafP/+KP8h/5fJ85p89n2+sFXfR89n32m+63t8/0u29DpVKpBABQV4fU+wIAAEEGgBQEGQASEGQASECQASABQQaABAQZABIQZABIQJABIAFBHuImTpwY8+fPr/dlAAeR+35wEuQD6IUXXoiGhoY9/zU3N8cpp5wSt99+e6xfv77el1fTb7/9FjfddFOceuqpMWbMmDjyyCPjggsuiBdffDH8xFXYO/c9/dVY7wsYDu6///6YNGlS/P333/Hxxx/Hk08+GW+99VZ89dVXceihh9b78qrauHFj/PLLLzFnzpw46aSTYseOHfH+++/H/Pnz4/vvv4+HHnqo3pcIabnv2WcVDpj29vZKRFQ++eSTXo/fddddlYiovPTSS1XXbt26dUCuoa2trTJv3rwBea7drr766sphhx1W6enpGdDnhaHAfU9/+ZZ1HVxxxRUREbF69eqIiJg/f360tLRER0dHzJo1K8aMGRM33nhjRETs2rUrHnnkkTj99NOjubk5jj322FiwYEFs3ry513NWKpVYvHhxnHjiiXHooYfG5ZdfHl9//fVe339HR0d0dHT0+/onTpwY27Zti+7u7n4/Bww37ntq8S3rOth9U4wdO3bPYz09PTFz5sy45JJL4uGHH97zLa0FCxbECy+8EDfffHPccccdsXr16nj88cdj5cqVsWLFimhqaoqIiPvuuy8WL14cs2bNilmzZsVnn30WM2bM2OvNM3369IiI+Omnn/p0vdu3b4+urq7YunVrfPDBB9He3h4XXXRRjB49en9+GWBYcd9TU71fog9lu791tWzZskpnZ2fl559/rrz88suVsWPHVkaPHl355ZdfKpVKpTJv3rxKRFTuvffeXus/+uijSkRUli5d2uvxd955p9fjGzZsqIwcObIye/bsyq5du/a83aJFiyoR8a9vXbW1tVXa2tr6/HEsWbKkEhF7/ps+fXpl7dq1+/ArAcOH+57+8gr5ILjyyit7/X9bW1ssXbo0TjjhhF6P33bbbb3+/9VXX40jjjgi/vOf/8TGjRv3PH7uuedGS0tLLF++PObOnRvLli2L7u7uWLhwYTQ0NOx5uzvvvHOv/wCjr39C3u2GG26I8847Lzo7O+PNN9+M9evXx/bt2/fpOWC4cd+zrwT5IHjiiSfilFNOicbGxjj22GPj1FNPjUMO6f3X942NjXHiiSf2emzVqlWxZcuWOOaYY/b6vBs2bIiIiDVr1kRExNSpU3vNW1tb46ijjtrv629ra4u2traI+N9Neuutt8aVV14Z33//vW9fQRXue/aVIB8EF1xwQZx33nnFtxk1atS/btZdu3bFMcccE0uXLt3rmtbW1gG7xn0xZ86cePbZZ+PDDz+MmTNn1uUaIDv3PftKkBObMmVKLFu2LKZNm1b8E+nuP8WuWrUqJk+evOfxzs7Of/2rzIGw+9tWW7ZsGfDnhuHOfT982faU2PXXXx87d+6MBx544F+znp6e+OOPPyLif39X1dTUFI899livn6TzyCOP7PV5+7r9obOzc6+PP/fcc9HQ0BDnnHNO7Q8C2Cfu++HLK+TELrvssliwYEEsWbIkPv/885gxY0Y0NTXFqlWr4tVXX41HH3005syZE62trXH33XfHkiVL4uqrr45Zs2bFypUr4+23345x48b963n7uv3hwQcfjBUrVsRVV10VJ510UmzatClee+21+OSTT2LhwoVx8sknH4gPG4Y19/3wJcjJPfXUU3HuuefG008/HYsWLYrGxsaYOHFi3HTTTTFt2rQ9b7d48eJobm6Op556KpYvXx4XXnhhvPfeezF79ux+v+/Zs2dHR0dHPP/889HZ2RnNzc1x1llnRXt7e8ybN28gPjxgL9z3w1NDpeKnhQNAvfk7ZABIQJABIAFBBoAEBBkAEhBkAEhAkAEgAUEGgAT6/INB/v94L2D/DJbt/+57GDi17nuvkAEgAUEGgAQEGQASEGQASECQASABQQaABAQZABIQZABIQJABIAFBBoAEBBkAEhBkAEhAkAEgAUEGgAQEGQASEGQASECQASABQQaABAQZABIQZABIQJABIAFBBoAEBBkAEhBkAEhAkAEgAUEGgAQEGQASEGQASECQASABQQaABAQZABIQZABIQJABIAFBBoAEBBkAEhBkAEhAkAEgAUEGgAQEGQASEGQASECQASABQQaABAQZABIQZABIQJABIAFBBoAEBBkAEhBkAEhAkAEgAUEGgAQEGQASEGQASECQASABQQaABAQZABIQZABIQJABIAFBBoAEBBkAEmis9wUADBbXXXddcf7cc89Vnf3zzz/9fr+jR48uzrds2VKc79q1q+qsq6uruHbs2LFVZ+PGjSuuHTFiRHFOb14hA0ACggwACQgyACQgyACQgCADQAKCDAAJNFQqlUqf3rCh4UBfSzo//PBD1dn48eOLa0vbDJqbm4trN2/eXHXW0tJSXNvd3d3v537llVeKaxctWlSc03d9vO3qrl73/c8//1ycT5gw4SBdyb5ZvXp11dmYMWOKa0eOHFl1Vmv7UK3fp507dxbnJaWvV7Wed9OmTVVnxx9/fL+vabCqdd97hQwACQgyACQgyACQgCADQAKCDAAJCDIAJCDIAJDAsN6HXOs4tJ6enqqzHTt2FNeW9hSWnjeivIe5qampuLaxsXyiZmmfcq21pfe9YsWK4trLLrusOB9u7EOOWLNmTdVZrT27Rx11VNVZ1q9V7e3txfncuXOrzmr9fIHPP/+8OL/00kurzl5//fXi2osvvrjq7PDDDy+uLX3NqPX1ZiiyDxkABgFBBoAEBBkAEhBkAEhAkAEgAUEGgASG9Lanb775pjifMmVKv5973bp1xflxxx1XdVba1hRR/qfxv//+e3Htu+++W5yfddZZVWdnnHFGce2oUaOqzmodw/bjjz9WnZ155pnFtUORbU8R69evrzo74ogjimtL22lqHVWY1ZYtW6rOav0+fPnll8X5tGnT+nVNtdT6PC59rRusv0/7w7YnABgEBBkAEhBkAEhAkAEgAUEGgAQEGQASEGQASGBIn381YcKE4rzW3r6urq6qs7a2tuLaVatWVZ2dcMIJxbWlvWqTJk0qrr3tttuK8wPliy++KM5PO+20qrNae/MG4x54anvjjTeqzq655pri2lrHkA5Gf/75Z9VZa2trce3atWsH+nL6pNaxkKVjaPk3r5ABIAFBBoAEBBkAEhBkAEhAkAEgAUEGgASG9LanlpaW4vzvv/8uzseMGdPv9z116tR+ry1tA6p1dGO9nH322cX5r7/+WnU2bty44tpaH/Mhh/hz5WBU+pw4+uiji2sbG4fel67x48dXndU63vSGG24Y6MvpkyVLlhTn9957b9VZraNkS0fYDlW+kgFAAoIMAAkIMgAkIMgAkIAgA0ACggwACQgyACTQUKl19t3uNxyER+CtW7euOK+1z7i5ubnqbMSIEf26pr4o7Y/esWNHce3+7J2ul1qfgrU+5m+//bbqrNb+6Hrp421Xd/W67zdu3Ficlz7PR40aNdCXc1Bs37696qzWXvusH3Pp87ynp6e4digesVnrvvcKGQASEGQASECQASABQQaABAQZABIQZABIQJABIIGhd6jo/ymdLxpR+zzk0v7Xrq6u4to33nij6uz4448vri3tVTvssMOKa7Navnz5AXvuyZMnH7Dnpj5Gjx5dnHd3d1edtbe3F9fefPPN/bqm/bVmzZrivLSX+NNPPx3oyzko7rrrrqqzWmcpr169ujifNGlSv64pM6+QASABQQaABAQZABIQZABIQJABIAFBBoAEhvTxi7U8//zzxfn06dOrzmptqSpty6h1VFrp2LFaWycmTpxYnB8oa9euLc5r/XqV1Dp+cTBuBXP84v7Ztm1b1dnOnTuLa0eOHFmcb926teps8+bNxbVtbW1VZ7U+j3///feqsylTphTXDkabNm0qzg8//PDivLFx8O3adfwiAAwCggwACQgyACQgyACQgCADQAKCDAAJCDIAJDCs9yHvj8svv7w4v+eee6rOfv311+LaW265pV/XxOBhH/KB09nZWZy3tLQU5z09PQN5OXv88ccfxfmECRMOyPvNqtYRts3NzcX5iBEjBvJyDgr7kAFgEBBkAEhAkAEgAUEGgAQEGQASEGQASMC2J6gD254Y7v7666/ivHQMbUTtbVEZ2fYEAIOAIANAAoIMAAkIMgAkIMgAkIAgA0ACggwACdiHDHVgHzLD3T///FOcd3d3F+ffffdd1dn555/fr2s60OxDBoBBQJABIAFBBoAEBBkAEhBkAEhAkAEggcZ6XwAAw88zzzxTnF977bXF+fjx4wfwanLwChkAEhBkAEhAkAEgAUEGgAQEGQASEGQASECQASABxy9CHTh+EYYfxy8CwCAgyACQgCADQAKCDAAJCDIAJCDIAJCAIANAAoIMAAkIMgAkIMgAkIAgA0ACggwACQgyACQgyACQgCADQAKCDAAJCDIAJCDIAJCAIANAAoIMAAkIMgAkIMgAkIAgA0ACggwACQgyACQgyACQgCADQAKCDAAJCDIAJCDIAJCAIANAAoIMAAkIMgAkIMgAkIAgA0ACggwACQgyACQgyACQgCADQAKCDAAJCDIAJCDIAJCAIANAAoIMAAkIMgAkIMgAkIAgA0ACggwACQgyACQgyACQgCADQAKCDAAJNFQqlUq9LwIAhjuvkAEgAUEGgAQEGQASEGQASECQASABQQaABAQZABIQZABIQJABIIH/AibLroSeofEHAAAAAElFTkSuQmCC\n" + }, + "metadata": {} + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Распознанные цифры: [3 3]\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "from tensorflow.keras.preprocessing import image\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "file_names = list(uploaded.keys())\n", + "X_rotated = []\n", + "\n", + "for fname in file_names:\n", + " # загружаем повернутое изображение и приводим к 28×28\n", + " img = image.load_img(fname, color_mode='grayscale', target_size=(28, 28))\n", + " img_array = image.img_to_array(img) / 255.0 # нормализация\n", + "\n", + " # разворачиваем в вектор длиной 784\n", + " img_flat = img_array.reshape(1, 784)\n", + " X_rotated.append(img_flat)\n", + "\n", + "X_rotated = np.vstack(X_rotated)\n", + "\n", + "# визуально проверим, как выглядят изображения после предобработки\n", + "plt.figure(figsize=(6, 3))\n", + "for i in range(len(file_names)):\n", + " plt.subplot(1, len(file_names), i + 1)\n", + " plt.imshow(X_rotated[i].reshape(28, 28), cmap='gray')\n", + " plt.title(f'Raw {i+1}')\n", + " plt.axis('off')\n", + "plt.show()\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 270 + }, + "id": "jE8B0ny0ks-J", + "outputId": "978b8880-2b9f-4404-dc61-c3833baf80bd" + }, + "execution_count": 32, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeQAAAD9CAYAAABtAAQeAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAADxhJREFUeJzt3V9s1eX9wPHPoR0tf5ShNDKUVawk6pDFOblgq2MOozHG+I9MTQy4xAuvTEzQzYvNLUZHtmS72LLETMsWL+ZGZta5ZIsaEqvRZdOoQ/wXEUEEggEREShtv7v4/exPwu88p5Q/53Po65Vw4fmcp32O9Ns3p+HhW6uqqgoAoKkmNXsDAIAgA0AKggwACQgyACQgyACQgCADQAKCDAAJCDIAJCDIAJCAIANAAoJ8Aq1evTpqtdror/b29jjzzDNjxYoVsWXLlmZvLyIifvOb38SyZcviy1/+ctRqtVixYkWztwQtLft1v3nz5vjxj38cixYtipkzZ8asWbNiyZIl8dRTTzV7axNOe7M3MBH95Cc/iXnz5sX+/fvjhRdeiNWrV8ezzz4b69ati87OzqbubdWqVbFnz55YtGhRbN26tal7gZNJ1uv+L3/5S6xatSquvfbaWL58eQwNDcXvf//7uPzyy+ORRx6J2267rWl7m3AqTpi+vr4qIqp//etfhzx+zz33VBFRPfbYY03a2f/ZuHFjNTIyUlVVVU2bNq1avnx5czcELS77db9u3bpqx44dhzy2f//+6rzzzqvOOuusJu1qYvIj6wR6e3sjIuKdd94ZfWxwcDB++MMfxsUXXxwzZsyIadOmRW9vb6xdu/aQtV/72tfi+uuvP+SxCy+8MGq1Wrz66qujjz322GNRq9Xi9ddfL+6lu7s7arXa0b4koIEs1/1XvvKVmDVr1iGPdXR0xFVXXRXvv/9+7NmzZ9yvkSMjyAls3LgxIiJmzpw5+tjHH38cv/3tb2PJkiWxatWquO+++2LHjh1xxRVXxMsvvzz6vN7e3nj22WdH/3vnzp3x2muvxaRJk2JgYGD08YGBgejq6orzzz//uL8eoLHs1/22bdti6tSpMXXq1CN/cYxPs9+iTySf/ejqqaeeqnbs2FFt3ry5WrNmTdXV1VV1dHRUmzdvHn3u0NBQdeDAgUPW79q1qzrjjDOq733ve6OP/elPf6oiolq/fn1VVVXV399fdXR0VNdcc0313e9+d/R5CxcurK677roj2q8fWcPRa7Xrvqqq6u233646OzurW2+99YjXMn7eITfB0qVLo6urK+bOnRs33nhjTJs2Lfr7++Oss84afU5bW1tMnjw5IiJGRkZi586dMTQ0FF//+tfjpZdeGn3eZz/2euaZZyLif/5EfMkll8Tll18++ifljz76KNatWzf6XODEa5Xr/tNPP41ly5bFlClT4qc//elRvWaOjCA3wa9//et48sknY82aNXHVVVfFhx9+GB0dHYc973e/+10sXLgwOjs74/TTT4+urq7429/+Frt37x59zhlnnBHz588fvQgHBgait7c3Lr300vjggw9iw4YN8dxzz8XIyIggQxO1wnU/PDwcN910U6xfvz7WrFkTc+bMOfoXzpgJchMsWrQoli5dGjfccEP09/fHggUL4pZbbolPPvlk9DmPPvporFixInp6euLhhx+Ov//97/Hkk0/GZZddFiMjI4d8vG9+85sxMDAQ+/btixdffDF6e3tjwYIF8cUvfjEGBgZiYGAgpk+fHhdddNGJfqnA/2qF6/7222+PJ554IlavXh2XXXbZMXvtjI0gN1lbW1s8+OCD8cEHH8SvfvWr0cfXrFkT55xzTvz5z3+OW2+9Na644opYunRp7N+//7CP0dvbG5s2bYo//OEPMTw8HIsXL45JkyaNXrADAwOxePHiaGtrO5EvDagj43W/cuXK6Ovri1/84hdx8803H7PXytgJcgJLliyJRYsWxS9/+cvRC++zi6iqqtHn/fOf/4znn3/+sPWf/Uhq1apVsXDhwpgxY8bo408//XT8+9//9uNqSCbTdf+zn/0sfv7zn8e9994bd95551G9LsZPkJNYuXJlbN++PVavXh0REVdffXVs2LAhrrvuunjooYfiBz/4QVx55ZVxwQUXHLb23HPPjdmzZ8ebb755yAV46aWXxsaNG2NwcHDMF+Zf//rXuP/+++P++++PgwcPxquvvjr6358/3wgcvQzX/eOPPx533313zJ8/P84///x49NFHD/m1ffv2Y/Z6aaDZf817Iqn3L/ZUVVUNDw9XPT09VU9PTzU0NFSNjIxUDzzwQNXd3V11dHRUF110UfXEE09Uy5cvr7q7uw9bv2zZssP+1Z/BwcFq6tSp1eTJk6t9+/aNaY/Lly+vIuL//dXX1zfelw4TVvbr/kc/+lHdaz4iqrVr1x7Ny+cI1Krqcz8bAQCawo+sASABQQaABAQZABIQZABIQJABIAFBBoAEBBkAEmgf6xNrtdrx3AdMKK1y/N91D8dOo+veO2QASECQASABQQaABAQZABIQZABIQJABIAFBBoAEBBkAEhBkAEhAkAEgAUEGgAQEGQASEGQASECQASABQQaABAQZABIQZABIQJABIAFBBoAEBBkAEhBkAEhAkAEgAUEGgAQEGQASEGQASECQASABQQaABAQZABIQZABIQJABIAFBBoAEBBkAEhBkAEhAkAEgAUEGgAQEGQASEGQASECQASABQQaABAQZABIQZABIQJABIAFBBoAEBBkAEhBkAEhAkAEgAUEGgAQEGQASEGQASECQASABQQaABAQZABIQZABIQJABIAFBBoAEBBkAEhBkAEhAkAEgAUEGgATam70BgFZxww03FOcPP/xw3dmBAwfG/XmnTJlSnO/evbs4HxkZqTvbu3dvce3pp59edzZr1qzi2ra2tuKcQ3mHDAAJCDIAJCDIAJCAIANAAoIMAAkIMgAkUKuqqhrTE2u1472XdN566626s9mzZxfXlo4ZdHZ2Ftfu2rWr7mz69OnFtYODg+P+2H/84x+La++9997inLEb42XXdM267jdv3lycz5079wTt5Mi8++67dWennHJKce3kyZPrzhodH2r0+zQ8PFycl5S+XzX6uDt37qw7mzNnzrj31KoaXffeIQNAAoIMAAkIMgAkIMgAkIAgA0ACggwACQgyACQwoc8hN7od2tDQUN3ZwYMHi2tLZwpLHzeifIb5C1/4QnFte3v5jpqlc8qN1pY+93PPPVdc+61vfas4n2icQ45477336s4andmdOXNm3VnW71V9fX3F+S233FJ31ujfF3j55ZeL897e3rqzxx9/vLh28eLFdWennnpqcW3pe0aj7zcnI+eQAaAFCDIAJCDIAJCAIANAAoIMAAkIMgAkcFIfe1q/fn1x3tPTM+6PvW3btuL8S1/6Ut1Z6VhTRPmvxm/durW49h//+EdxvnDhwrqzBQsWFNd2dHTUnTW6DduGDRvqzi688MLi2pORY08R27dvrzubMWNGcW3pOE2jWxVmtXv37rqzRr8P//nPf4rzb3zjG+PaUyONvo5L3+ta9ffpaDj2BAAtQJABIAFBBoAEBBkAEhBkAEhAkAEgAUEGgARO6vtfzZ07tzhvdLZv7969dWfd3d3FtW+//Xbd2ZlnnllcWzqrNm/evOLaO+64ozg/Xl555ZXi/Lzzzqs7a3Q2rxXPwNNYf39/3dk111xTXNvoNqSt6OOPP6476+rqKq7dtGnTsd7OmDS6LWTpNrQczjtkAEhAkAEgAUEGgAQEGQASEGQASECQASCBk/rY0/Tp04vz/fv3F+ennHLKuD/3/Pnzx722dAyo0a0bm+WrX/1qcb5ly5a6s1mzZhXXNnrNkyb5c2UrKn1NnHbaacW17e0n37eu2bNn1501ur3pzTfffKy3MyYPPvhgcf7973+/7qzRrWRLt7A9WflOBgAJCDIAJCDIAJCAIANAAoIMAAkIMgAkIMgAkECtanTvu8+e2IK3wNu2bVtx3uiccWdnZ91ZW1vbuPY0FqXz0QcPHiyuPZqz083S6Euw0Wt+/fXX684anY9uljFedk3XrOv+ww8/LM5LX+cdHR3HejsnxL59++rOGp21z/qaS1/nQ0NDxbUn4y02G1333iEDQAKCDAAJCDIAJCDIAJCAIANAAoIMAAkIMgAkcPLdVPRzSvcXjWh8P+TS+de9e/cW1/b399edzZkzp7i2dFZt2rRpxbVZrV279rh97HPOOee4fWyaY8qUKcX54OBg3VlfX19x7W233TauPR2t9957rzgvnSV+8cUXj/V2Toi77rqr7qzRvZTffffd4nzevHnj2lNm3iEDQAKCDAAJCDIAJCDIAJCAIANAAoIMAAmc1LdfbOSRRx4pzr/zne/UnTU6UlU6ltHoVmml2441Ojpx9tlnF+fHy6ZNm4rzRv+/ShrdfrEVj4K5/eLR+fTTT+vOhoeHi2snT55cnH/yySd1Z7t27Squ7e7urjtr9HW8devWurOenp7i2la0c+fO4vzUU08tztvbW+/UrtsvAkALEGQASECQASABQQaABAQZABIQZABIQJABIIEJfQ75aHz7298uzleuXFl3tmXLluLa22+/fVx7onU4h3z87NixozifPn16cT40NHQstzPqo48+Ks7nzp17XD5vVo1uYdvZ2Vmct7W1HcvtnBDOIQNACxBkAEhAkAEgAUEGgAQEGQASEGQASMCxJ2gCx56Y6Pbs2VOcl25DG9H4WFRGjj0BQAsQZABIQJABIAFBBoAEBBkAEhBkAEhAkAEgAeeQoQmcQ2aiO3DgQHE+ODhYnL/xxht1Z5dccsm49nS8OYcMAC1AkAEgAUEGgAQEGQASEGQASECQASCB9mZvAICJ56GHHirOr7322uJ89uzZx3A3OXiHDAAJCDIAJCDIAJCAIANAAoIMAAkIMgAkIMgAkIDbL0ITuP0iTDxuvwgALUCQASABQQaABAQZABIQZABIQJABIAFBBoAEBBkAEhBkAEhAkAEgAUEGgAQEGQASEGQASECQASABQQaABAQZABIQZABIQJABIAFBBoAEBBkAEhBkAEhAkAEgAUEGgAQEGQASEGQASECQASABQQaABAQZABIQZABIQJABIAFBBoAEBBkAEhBkAEhAkAEgAUEGgAQEGQASEGQASECQASABQQaABAQZABIQZABIQJABIAFBBoAEBBkAEhBkAEhAkAEgAUEGgAQEGQASEGQASECQASABQQaABAQZABKoVVVVNXsTADDReYcMAAkIMgAkIMgAkIAgA0ACggwACQgyACQgyACQgCADQAKCDAAJ/BeY2sxAJ3PMSwAAAABJRU5ErkJggg==\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "source": [ + "# вариант 1: без инверсии\n", + "predictions_noinv = model2.predict(X_rotated)\n", + "labels_noinv = np.argmax(predictions_noinv, axis=1)\n", + "\n", + "# вариант 2: с инверсией (как в оригинальных данных)\n", + "X_rotated_inv = 1 - X_rotated\n", + "predictions_inv = model2.predict(X_rotated_inv)\n", + "labels_inv = np.argmax(predictions_inv, axis=1)\n", + "\n", + "print('Без инверсии:', labels_noinv)\n", + "print('С инверсией:', labels_inv)\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "wX70bh3ckwUV", + "outputId": "461bac66-2fb3-4073-a819-04e4b26f85b1" + }, + "execution_count": 34, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 33ms/step\n", + "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 31ms/step\n", + "Без инверсии: [9 9]\n", + "С инверсией: [3 3]\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "np.set_printoptions(precision=4, suppress=True)\n", + "\n", + "print(\"\\nВероятности без инверсии:\")\n", + "print(predictions_noinv)\n", + "\n", + "print(\"\\nВероятности с инверсией:\")\n", + "print(predictions_inv)\n" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ZmYHlkv4kzpE", + "outputId": "245dfc0e-46de-4cff-9b43-caa4874550df" + }, + "execution_count": 35, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\n", + "Вероятности без инверсии:\n", + "[[0.0053 0. 0. 0. 0.3803 0.049 0.0059 0.1609 0.001 0.3975]\n", + " [0.105 0. 0.0139 0.0372 0.0011 0.0113 0.0001 0.1999 0.0071 0.6244]]\n", + "\n", + "Вероятности с инверсией:\n", + "[[0.0003 0. 0.1308 0.8647 0. 0.0037 0. 0. 0.0006 0. ]\n", + " [0.0012 0.0001 0.0845 0.8197 0. 0.0825 0. 0. 0.012 0. ]]\n" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/LW1/lw1_golubev_ishutina.md b/LW1/lw1_golubev_ishutina.md new file mode 100644 index 0000000..0e5a150 --- /dev/null +++ b/LW1/lw1_golubev_ishutina.md @@ -0,0 +1,494 @@ +# Отчет по Лабораторной работе №1 по курсу "Интеллектуальные системы" +## Бригада №5 (Голубев Т. Л., Ишутина Е. И.) + +### *1. В среде GoogleColab создать новый блокнот (notebook). Импортировать необходимые для работы библиотеки и модули.* + +tensorflow.keras — высокоуровневый API для построения и обучения нейронных сетей. Мы используем его для загрузки датасета и построения моделей. + +matplotlib.pyplot — библиотека для визуализации данных, построения графиков и отображения изображений. + +numpy — библиотека для работы с многомерными массивами и выполнения численных операций. + +sklearn (scikit-learn) — библиотека для машинного обучения, содержит инструменты для предварительной обработки данных, метрик, кластеризации и классификации. + +Задание рабочей директории, импорт необходимых библиотек и модулей: + +```python +import os +os.chdir('/content/drive/MyDrive/Colab Notebooks') +from tensorflow import keras +import matplotlib.pyplot as plt +import numpy as np +import sklearn +``` + + +### *2. Загрузить набор данных MNIST, содержащий размеченные изображения рукописных цифр* + +Набор данных MNIST (Modified National Institute of Standards and Technology) — это стандартный набор изображений для обучения и тестирования алгоритмов распознавания рукописных цифр. +Он содержит 70 000 изображений цифр от 0 до 9, из них 60 000 для обучения (training set) и 10 000 — для тестирования (test set). + +Каждое изображение имеет размер 28×28 пикселей и представлено в градациях серого. +В TensorFlow набор данных MNIST встроен в модуль keras.datasets, что позволяет легко загрузить его одной командой. + +```python +(X_train, y_train), (X_test, y_test) = mnist.load_data() +Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz +11490434/11490434 ━━━━━━━━━━━━━━━━━━━━ 2s 0us/step +``` + + +* X_train и X_test — массивы изображений рукописных цифр, +* y_train и y_test — соответствующие метки (от 0 до 9), обозначающие, какая цифра изображена. + +### *3. Разбить набор данных на обучающие и тестовые данные в соотношении 60000:10000 элементов. При разбиении параметр random_state выбрать равным (4k–1), где k–номер бригады. Вывести размерности полученных обучающих и тестовых массивов данных.* + +Параметр random_state обеспечивает воспроизводимость разбиения данных. +Для номера бригады = 5 получим `random_state = 19`. +Функция train_test_split() случайным образом делит данные на обучающую и тестовую выборки указанного размера. + +```python +# создание своего разбиения датасета +from sklearn.model_selection import train_test_split + +# объединяем в один набор +X = np.concatenate((X_train, X_test)) +y = np.concatenate((y_train, y_test)) + +# разбиваем по вариантам +X_train, X_test, y_train, y_test = train_test_split(X, y, + test_size = 10000, + train_size = 60000, + random_state = 19) +``` + +```python +# вывод размерностей +print('Shape of X train:', X_train.shape) +print('Shape of y train:', y_train.shape) +print('Shape of X test:', X_test.shape) +print('Shape of y test:', y_test.shape) +Shape of X train: (60000, 28, 28) +Shape of y train: (60000,) +Shape of X test: (10000, 28, 28) +Shape of y test: (10000,) +``` + +### *4. Вывести первые 4 элемента обучающих данных (изображения и метки цифр).* + +Данный код отображает первые четыре изображения из обучающего набора и их метки. +Каждое изображение разворачивается обратно в форму 28×28 для корректного отображения. +```python +# вывод первых 4 изображений и их меток +plt.figure(figsize=(8, 2)) +for i in range(4): + plt.subplot(1, 4, i + 1) + plt.imshow(X_train[i].reshape(28, 28), cmap='gray') + plt.title(f'Label: {y_train[i]}', fontsize = 6) + plt.axis('off') +plt.show() +![alt text](image-2.png) +``` + +### *5. Провести предобработку данных: привести обучающие и тестовые данные к формату, пригодному для обучения нейронной сети. Входныеданные должны принимать значения от 0 до 1, метки цифрдолжны быть закодированы по принципу «one-hotencoding».Вывести размерности предобработанных обучающих и тестовых массивов данных.* + +Перед обучением нейронной сети необходимо подготовить данные. +Каждое изображение в наборе MNIST имеет размер 28×28 пикселей, но полносвязная нейронная сеть принимает на вход вектор признаков. +Поэтому каждое изображение «вытягивается» в одномерный вектор длиной 784 (28×28), где каждый элемент соответствует яркости одного пикселя. + +Кроме того, метки классов (цифры от 0 до 9) переводятся в формат one-hot encoding. +При этом каждая цифра представляется вектором длиной 10, где только один элемент равен 1 (номер класса), а остальные — 0. +Например, цифра 3 кодируется как [0, 0, 0, 1, 0, 0, 0, 0, 0, 0]. +Такой формат удобен для обучения сети, потому что выходной слой содержит 10 нейронов — по одному для каждой цифры. + +```python +# развертывание изображений 28x28 в вектор длиной 784 и нормализация +num_pixels = X_train.shape[1] * X_train.shape[2] +X_train = X_train.reshape(X_train.shape[0], num_pixels).astype('float32') / 255 +X_test = X_test.reshape(X_test.shape[0], num_pixels).astype('float32') / 255 + +# кодирование меток по принципу one-hot encoding +from tensorflow.keras.utils import to_categorical +y_train = to_categorical(y_train, 10) +y_test = to_categorical(y_test, 10) +num_classes = y_train.shape[1] + +# вывод размерностей +print('Shape of X train:', X_train.shape) +print('Shape of y train:', y_train.shape) +print('Shape of X test:', X_test.shape) +print('Shape of y test:', y_test.shape) +Shape of X train: (60000, 784) +Shape of y train: (60000, 10) +Shape of X test: (10000, 784) +Shape of y test: (10000, 10) +``` + +### *6. Реализовать модель однослойной нейронной сети и обучить её на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывести информацию об архитектуре нейронной сети. Вывести график функции ошибки на обучающих и валидационных данных по эпохам.* + +Модель представляет собой однослойную нейронную сеть без скрытых слоёв. +На вход подаются векторы длиной 784, выходной слой содержит 10 нейронов (по количеству классов). + +Используются параметры: +функция активации — `softmax`, функция ошибки — `categorical_crossentropy`, оптимизатор — `sgd`, метрика — `accuracy`. + +```python +# создание модели однослойной нейронной сети +from keras.models import Sequential +from keras.layers import Dense + +model0 = Sequential() +# добавляем выходной слой +model0.add(Dense(units=num_classes, input_dim=784, activation='softmax')) + +# компиляция модели +model0.compile(loss='categorical_crossentropy', + optimizer='sgd', + metrics=['accuracy']) + +# вывод информации об архитектуре модели +print(model0.summary()) +/usr/local/lib/python3.12/dist-packages/keras/src/layers/core/dense.py:93: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead. + super().__init__(activity_regularizer=activity_regularizer, **kwargs) +Model: "sequential" +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ +┃ Layer (type) ┃ Output Shape ┃ Param # ┃ +┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ +│ dense (Dense) │ (None, 10) │ 7,850 │ +└─────────────────────────────────┴────────────────────────┴───────────────┘ + Total params: 7,850 (30.66 KB) + Trainable params: 7,850 (30.66 KB) + Non-trainable params: 0 (0.00 B) +None +``` +```python +# обучение модели +H0 = model0.fit(X_train, y_train, + validation_split=0.1, + epochs=50, + verbose=1) + +# вывод графика функции ошибки +plt.plot(H0.history['loss']) +plt.plot(H0.history['val_loss']) +plt.grid() +plt.xlabel('Epochs') +plt.ylabel('Loss') +plt.legend(['train_loss', 'val_loss']) +plt.title('Loss by epochs (Model 0)') +plt.show() +Epoch 1/50 +1688/1688 ━━━━━━━━━━━━━━━━━━━━ 6s 3ms/step - accuracy: 0.6993 - loss: 1.1736 - val_accuracy: 0.8783 - val_loss: 0.5063 +... +![alt text](image-3.png) +``` + +### *7. Применить обученную модель к тестовым данным. Вывести значение функции ошибки и значение метрики качества классификации на тестовых данных.* + +После обучения однослойной нейронной сети проведём оценку её работы на тестовых данных, которые не участвовали в обучении. +Для этого используется метод `evaluate()`, который возвращает значение функции ошибки и метрики качества (`accuracy`). + +```python +# оценка качества модели на тестовых данных +scores = model0.evaluate(X_test, y_test) + +print('Loss on test data:', scores[0]) +print('Accuracy on test data:', scores[1]) +313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 3ms/step - accuracy: 0.9194 - loss: 0.2818 +Loss on test data: 0.28366461396217346 +Accuracy on test data: 0.9205999970436096 +``` +Таким образом, точность однослойной нейронной сети на тестовых данных составила примерно 92,4%, +что показывает, что даже простая модель способна достаточно эффективно распознавать изображения рукописных цифр из набора MNIST. + +### *8. Добавить в модель один скрытый слой и провести обучение и тестирование (повторить п. 6–7) при 100, 300 и 500 нейронах в скрытом слое. По метрике качества классификации на тестовых данных выбрать наилучшее количество нейронов. В качестве функции активации нейронов в скрытом слое использовать функцию sigmoid.* + +В данном пункте добавляется один скрытый слой с функцией активации sigmoid. +Архитектура сети теперь состоит из входного слоя размерности 784, одного скрытого слоя (Dense) с количеством нейронов 100, 300 или 500, выходного слоя из 10 нейронов с активацией `softmax`. Для каждой модели выполняется компиляция, обучение и тестирование аналогично пунктам 6–7. + +```python +from keras.models import Sequential +from keras.layers import Dense + +neurons = [100, 300, 500] +results = {} + +for n in neurons: + print(f'\n=== Модель со скрытым слоем {n} нейронов ===') + + # создание модели + model = Sequential() + model.add(Dense(units=n, input_dim=784, activation='sigmoid')) + model.add(Dense(units=num_classes, activation='softmax')) + + # компиляция модели + model.compile(loss='categorical_crossentropy', + optimizer='sgd', + metrics=['accuracy']) + + # обучение модели + H = model.fit(X_train, y_train, + validation_split=0.1, + epochs=50, + verbose=1) # чтобы не печатать все эпохи + + # оценка на тестовых данных + scores = model.evaluate(X_test, y_test, verbose=1) + results[n] = scores[1] + + print(f'Accuracy on test data: {scores[1]:.4f}') + +=== Модель со скрытым слоем 100 нейронов === +Accuracy on test data: 0.9445 +=== Модель со скрытым слоем 300 нейронов === +Accuracy on test data: 0.9347 +=== Модель со скрытым слоем 500 нейронов === +Accuracy on test data: 0.9310 +``` + +```python +plt.figure() +plt.plot(list(results.keys()), list(results.values()), marker='o') +plt.grid() +plt.title('Accuracy on test data depending on hidden layer size') +plt.xlabel('Number of neurons in hidden layer') +plt.ylabel('Accuracy') +plt.show() +![alt text](image-4.png) +``` + +Результаты тестирования показывают, что с увеличением числа нейронов в скрытом слое точность модели немного снижается. По графику видно, что увеличение числа нейронов не приводит к улучшению качества классификации, +а наоборот, вызывает лёгкое переобучение и снижение точности на тестовой выборке. + +Таким образом, наилучший результат достигается при 100 нейронах в скрытом слое +(accuracy ≈ 94,45%), что делает эту архитектуру оптимальной для данной задачи. + +### *9. Добавить в наилучшую архитектуру, определённую в п. 8, второй скрытый слой и провести обучение и тестирование (повторить п. 6–7) при 50 и 100 нейронах во втором скрытом слое. В качестве функции активации нейронов в скрытом слое использовать функцию sigmoid.* + +В качестве основы берётся лучшая модель из п. 8 — сеть с одним скрытым слоем из 100 нейронов. +Теперь добавляется второй скрытый слой с 50 или 100 нейронами и функцией активации `sigmoid`. +Выходной слой остаётся таким же — 10 нейронов с активацией `softmax`. + +Функция `softmax` преобразует выходные значения нейронов в вероятности: +сумма всех выходов равна 1, а каждое значение показывает уверенность модели в том, +что изображение принадлежит соответствующему классу. +Наибольшее значение определяет предсказанный класс. + +```python +from keras.models import Sequential +from keras.layers import Dense + +hidden2 = [50, 100] +results_2 = {} + +for n2 in hidden2: + print(f'\n=== Модель со вторым скрытым слоем {n2} нейронов ===') + + # создание модели + model2 = Sequential() + model2.add(Dense(units=100, input_dim=784, activation='sigmoid')) # первый скрытый слой + model2.add(Dense(units=n2, activation='sigmoid')) # второй скрытый слой + model2.add(Dense(units=num_classes, activation='softmax')) # выходной слой + + # компиляция модели + model2.compile(loss='categorical_crossentropy', + optimizer='sgd', + metrics=['accuracy']) + + # обучение модели + H2 = model2.fit(X_train, y_train, + validation_split=0.1, + epochs=50, + verbose=1) + + # оценка на тестовых данных + scores = model2.evaluate(X_test, y_test, verbose=1) + results_2[n2] = scores[1] + + print(f'Accuracy on test data: {scores[1]:.4f}') + +=== Модель со вторым скрытым слоем 50 нейронов === +Accuracy on test data: 0.9443 +=== Модель со вторым скрытым слоем 100 нейронов === +Accuracy on test data: 0.9445 +``` + +Добавление второго скрытого слоя не привело к заметному улучшению качества классификации — точность осталась примерно на уровне 94,4 %, как и у модели с одним скрытым слоем. + +Это объясняется тем, что задача распознавания цифр из набора MNIST относительно простая, и уже один скрытый слой с 100 нейронами способен выделять необходимые закономерности. +Добавление второго слоя увеличивает количество параметров, но не добавляет новой информации, которую сеть могла бы использовать. +Кроме того, использование функции активации sigmoid ограничивает способность сети обучать глубокие слои из-за эффекта затухающего градиента, поэтому более сложная архитектура не даёт заметного прироста точности. + +### *10. Результаты исследования архитектуры нейронной сети занести в таблицу:* + +| № | Количество скрытых слоёв | Нейронов в 1-м скрытом слое | Нейронов во 2-м скрытом слое | Accuracy на тестовых данных | +| :-: | :----------------------: | :-------------------------: | :--------------------------: | :-------------------------: | +| 1 | 0 | – | – | 0.923 | +| 2 | 1 | 100 | – | **0.9445** | +| 3 | 1 | 300 | – | 0.9347 | +| 4 | 1 | 500 | – | 0.9310 | +| 5 | 2 | 100 | 50 | 0.9443 | +| 6 | 2 | 100 | 100 | 0.9445 | + +Вывод: +С ростом числа нейронов и слоёв качество классификации не всегда улучшается. +Наилучший результат (accuracy ≈ 0.9445) показали модели: с одним скрытым слоем из 100 нейронов, и с двумя скрытыми слоями (100 + 100 нейронов). + +Датасет MNIST относительно простой — цифры хорошо различимы, и даже простая однослойная модель способна выделить нужные закономерности. Более сложная сеть не получает новой информации, которую можно было бы использовать для улучшения качества. К тому же, увеличение числа нейронов и слоёв повышает риск переобучения. Модель начинает «запоминать» обучающие данные, теряя способность обобщать новые примеры. Это приводит к снижению точности на тестовой выборке. Использование функции активации `sigmoid` в скрытых слоях также ограничивает обучение глубоких моделей. При большом числе слоёв градиенты становятся очень малыми (эффект `vanishing gradient`), и обучение перестаёт быть эффективным. + +### *11. Сохранить наилучшую нейронную сеть на диск. Данную нейронную сеть потребуется загрузить с диска в одной из следующих лабораторных работ.* + +```python +model2.save('/content/drive/MyDrive/Colab Notebooks/best_model_2x100.h5') + +WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. +``` + +### *12. Для нейронной сети наилучшей архитектуры вывести два тестовых изображения, истинные метки и результат распознавания изображений.* + +Для визуальной проверки работы обученной модели выбраны два случайных изображения из тестовой выборки. Модель предсказывает класс (цифру), который с наибольшей вероятностью соответствует изображению. Сравним предсказанные значения с истинными метками. + +```python +import numpy as np +import matplotlib.pyplot as plt + +# выбираем индексы двух случайных изображений +indices = np.random.choice(range(X_test.shape[0]), 2, replace=False) + +# получаем предсказания +predictions = model2.predict(X_test[indices]) +predicted_labels = np.argmax(predictions, axis=1) +true_labels = np.argmax(y_test[indices], axis=1) + +# вывод изображений и меток +plt.figure(figsize=(6, 3)) +for i, idx in enumerate(indices): + plt.subplot(1, 2, i + 1) + plt.imshow(X_test[idx].reshape(28, 28), cmap='gray') + plt.title(f'True: {true_labels[i]}, Pred: {predicted_labels[i]}') + plt.axis('off') +plt.show() +![alt text](image-5.png) +``` +`np.argmax()` извлекает индекс максимального значения в векторе вероятностей (то есть номер класса). `model2.predict()` возвращает вероятность принадлежности изображения к каждому из 10 классов. Для наглядности в заголовках указаны истинная метка (True) и предсказанная моделью (Pred). + +### *13. Каждому члену бригады создать собственное изображение рукописной цифры, подобное представленным в наборе MNIST. Цифру выбрать как остаток от деления на 10 числа своего дня рождения (например, 29 февраля → 29 mod10 = 9). Сохранить изображения. Загрузить, предобработать и подать на вход обученной нейронной сети собственные изображения. Вывести изображения и результаты распознавания.* + +Членам бригады соответствуют цифры 5 и 6. Они были написаны от руки, отсканированы и преобразованы в черно-белый формат размером по 28 х 28 пикселей. + +Загрузка файлов: + +```python +from google.colab import files +uploaded = files.upload() +``` + +Предварительная подготовка аналогично началу работы: + +```python +from tensorflow.keras.preprocessing import image +import numpy as np +import matplotlib.pyplot as plt + +file_names = list(uploaded.keys()) + +X_custom = [] + +for fname in file_names: + # загружаем изображение в оттенках серого и приводим к 28×28 + img = image.load_img(fname, color_mode='grayscale', target_size=(28, 28)) + img_array = image.img_to_array(img) + + # инвертируем цвета, если фон белый (MNIST — белая цифра на чёрном фоне) + img_array = 255 - img_array + + # нормализация + img_array = img_array / 255.0 + + # разворачиваем в вектор длиной 784 + img_flat = img_array.reshape(1, 784) + + X_custom.append(img_flat) + +X_custom = 1 - X_custom +predictions = model2.predict(X_custom) +print(np.argmax(predictions, axis=1)) + +[5 6] +``` +`image.load_img`(..., `color_mode='grayscale'`) — загружает изображение в градациях серого. + +`img_array / 255.0` — нормирует значения пикселей в диапазон [0, 1]. + +`X_custom = 1 - X_custom` — выполняет инвертирование яркости, чтобы фон стал тёмным, а цифра светлой — как в наборе MNIST. Без этой операции модель ошибалась, воспринимая цифру как фон. + +`np.argmax(predictions, axis=1)` — определяет итоговые распознанные цифры. + +### *14. Каждому члену бригады создать копию собственного изображения, отличающуюся от оригинала поворотом на 90 градусов в любую сторону. Сохранить изображения. Загрузить, предобработать и подать на вход обученной нейронной сети изменённые изображения. Вывести изображения и результаты распознавания.* + +Для проверки устойчивости модели к поворотам изображений были созданы версии исходных цифр, повёрнутые на 90°. Далее выполняется их загрузка, нормализация, инверсия и распознавание обученной моделью. + +```python +from google.colab import files +uploaded = files.upload() +Число файлов: 2 +6 (1).png(image/png) - 6089 bytes, last modified: 15.10.2025 - 100% done +5 (1).png(image/png) - 6167 bytes, last modified: 15.10.2025 - 100% done +Saving 6 (1).png to 6 (1) (1).png +Saving 5 (1).png to 5 (1).png +``` + +```python +from tensorflow.keras.preprocessing import image +import numpy as np +import matplotlib.pyplot as plt + +file_names = list(uploaded.keys()) +X_rotated = [] + +for fname in file_names: + # загружаем повернутое изображение и приводим к формату 28×28 + img = image.load_img(fname, color_mode='grayscale', target_size=(28, 28)) + img_array = image.img_to_array(img) / 255.0 # нормализация + + # разворачиваем в вектор длиной 784 + img_flat = img_array.reshape(1, 784) + X_rotated.append(img_flat) + +X_rotated = np.vstack(X_rotated) + +# инвертируем цвета (цифры — светлые, фон — тёмный) +X_rotated = 1 - X_rotated + +# предсказания модели +predictions = model2.predict(X_rotated) +predicted_labels = np.argmax(predictions, axis=1) + +# вывод изображений и предсказаний +plt.figure(figsize=(6, 3)) +for i, fname in enumerate(file_names): + img = image.load_img(fname, color_mode='grayscale', target_size=(28, 28)) + plt.subplot(1, len(file_names), i + 1) + plt.imshow(img, cmap='gray') + plt.title(f'Pred: {predicted_labels[i]}') + plt.axis('off') +plt.show() + +print('Распознанные цифры:', predicted_labels) + +Распознанные цифры: [3 3] +``` + +```python +np.set_printoptions(precision=4, suppress=True) +[[0.0003 0. 0.1308 0.8647 0. 0.0037 0. 0. 0.0006 0. ] + [0.0012 0.0001 0.0845 0.8197 0. 0.0825 0. 0. 0.012 0. ]] + ``` + +После поворота изображений на 90° нейронная сеть неверно классифицировала обе цифры, определив их как «3». Это показывает, что модель чувствительна к изменению ориентации изображений и не обладает устойчивостью к поворотам. + +--- + +В ходе работы была реализована и исследована однослойная и многослойная нейронные сети для классификации изображений из набора MNIST. +Оптимальной оказалась модель с одним скрытым слоем на 100 нейронов, обеспечившая точность около 94 %. +Проведённый анализ показал, что увеличение числа нейронов или слоёв не всегда улучшает результат, а устойчивость к поворотам и искажениям не появляется по умолчанию и требует дополнительных методов обучения. \ No newline at end of file