{ "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", "execution_count": 17, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "L5IVcsqZFrPb", "outputId": "04670098-8677-4300-d7b4-2577d0f39110", "collapsed": true }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount(\"/content/drive\", force_remount=True).\n" ] } ], "source": [ "from google.colab import drive\n", "drive.mount('/content/drive')\n", "import os\n", "os.chdir('/content/drive/MyDrive/Colab Notebooks/is_lab3')\n", "\n", "from tensorflow import keras\n", "from tensorflow.keras import layers\n", "from tensorflow.keras.models import Sequential\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "from sklearn.metrics import classification_report, confusion_matrix\n", "from sklearn.metrics import ConfusionMatrixDisplay" ] }, { "cell_type": "code", "source": [ "from keras.datasets import mnist\n", "(X_train, y_train), (X_test, y_test) = mnist.load_data()" ], "metadata": { "id": "LyXMgOAxIJxj" }, "execution_count": 18, "outputs": [] }, { "cell_type": "code", "source": [ "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 = 7)\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)" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "vRJoFvi_IPl2", "outputId": "38672d14-c658-4149-d12d-408f5ce7ea35", "collapsed": true }, "execution_count": 19, "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": [ "# Зададим параметры данных и модели\n", "num_classes = 10\n", "input_shape = (28, 28, 1)\n", "\n", "# Приведение входных данных к диапазону [0, 1]\n", "X_train = X_train / 255\n", "X_test = X_test / 255\n", "\n", "# Расширяем размерность входных данных, чтобы каждое изображение имело\n", "# размерность (высота, ширина, количество каналов)\n", "\n", "X_train = np.expand_dims(X_train, -1)\n", "X_test = np.expand_dims(X_test, -1)\n", "print('Shape of transformed X train:', X_train.shape)\n", "print('Shape of transformed X test:', X_test.shape)\n", "\n", "# переведем метки в one-hot\n", "y_train = keras.utils.to_categorical(y_train, num_classes)\n", "y_test = keras.utils.to_categorical(y_test, num_classes)\n", "print('Shape of transformed y train:', y_train.shape)\n", "print('Shape of transformed y test:', y_test.shape)" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "MW1azavSIkbr", "outputId": "f82440c0-2098-401a-eaf4-37694f72c60c", "collapsed": true }, "execution_count": 20, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Shape of transformed X train: (60000, 28, 28, 1)\n", "Shape of transformed X test: (10000, 28, 28, 1)\n", "Shape of transformed y train: (60000, 10)\n", "Shape of transformed y test: (10000, 10)\n" ] } ] }, { "cell_type": "code", "source": [ "# создаем модель\n", "model = Sequential()\n", "model.add(layers.Conv2D(32, kernel_size=(3, 3), activation=\"relu\", input_shape=input_shape))\n", "model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n", "model.add(layers.Conv2D(64, kernel_size=(3, 3), activation=\"relu\"))\n", "model.add(layers.MaxPooling2D(pool_size=(2, 2)))\n", "model.add(layers.Dropout(0.5))\n", "model.add(layers.Flatten())\n", "model.add(layers.Dense(num_classes, activation=\"softmax\"))\n", "\n", "model.summary()" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 418 }, "id": "e0heiHVGKz1U", "outputId": "8f95e97d-0e15-4ccc-92dc-2228f87d933c", "collapsed": true }, "execution_count": 21, "outputs": [ { "output_type": "stream", "name": "stderr", "text": [ "/usr/local/lib/python3.12/dist-packages/keras/src/layers/convolutional/base_conv.py:113: 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_1\"\u001b[0m\n" ], "text/html": [ "
Model: \"sequential_1\"\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",
"│ conv2d_2 (\u001b[38;5;33mConv2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m26\u001b[0m, \u001b[38;5;34m26\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m320\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ max_pooling2d_2 (\u001b[38;5;33mMaxPooling2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m13\u001b[0m, \u001b[38;5;34m13\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ conv2d_3 (\u001b[38;5;33mConv2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m11\u001b[0m, \u001b[38;5;34m11\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m18,496\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ max_pooling2d_3 (\u001b[38;5;33mMaxPooling2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m5\u001b[0m, \u001b[38;5;34m5\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dropout_1 (\u001b[38;5;33mDropout\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m5\u001b[0m, \u001b[38;5;34m5\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ flatten_1 (\u001b[38;5;33mFlatten\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1600\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_1 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m10\u001b[0m) │ \u001b[38;5;34m16,010\u001b[0m │\n",
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n"
],
"text/html": [
"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
"┃ Layer (type) ┃ Output Shape ┃ Param # ┃\n",
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
"│ conv2d_2 (Conv2D) │ (None, 26, 26, 32) │ 320 │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ max_pooling2d_2 (MaxPooling2D) │ (None, 13, 13, 32) │ 0 │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ conv2d_3 (Conv2D) │ (None, 11, 11, 64) │ 18,496 │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ max_pooling2d_3 (MaxPooling2D) │ (None, 5, 5, 64) │ 0 │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dropout_1 (Dropout) │ (None, 5, 5, 64) │ 0 │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ flatten_1 (Flatten) │ (None, 1600) │ 0 │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_1 (Dense) │ (None, 10) │ 16,010 │\n",
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
"\n"
]
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m34,826\u001b[0m (136.04 KB)\n"
],
"text/html": [
"Total params: 34,826 (136.04 KB)\n", "\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/plain": [ "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m34,826\u001b[0m (136.04 KB)\n" ], "text/html": [ "
Trainable params: 34,826 (136.04 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": {} } ] }, { "cell_type": "code", "source": [ "# компилируем и обучаем модель\n", "batch_size = 512\n", "epochs = 15\n", "model.compile(loss=\"categorical_crossentropy\", optimizer=\"adam\", metrics=[\"accuracy\"])\n", "model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)\n" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "VGOpmicHLkU6", "outputId": "0620fd72-b723-4efd-8a26-253a8ee98eb3", "collapsed": true }, "execution_count": 22, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Epoch 1/15\n", "\u001b[1m106/106\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m13s\u001b[0m 61ms/step - accuracy: 0.6299 - loss: 1.2590 - val_accuracy: 0.9473 - val_loss: 0.1893\n", "Epoch 2/15\n", "\u001b[1m106/106\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - accuracy: 0.9374 - loss: 0.2104 - val_accuracy: 0.9685 - val_loss: 0.1111\n", "Epoch 3/15\n", "\u001b[1m106/106\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - accuracy: 0.9607 - loss: 0.1312 - val_accuracy: 0.9757 - val_loss: 0.0825\n", "Epoch 4/15\n", "\u001b[1m106/106\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - accuracy: 0.9687 - loss: 0.1022 - val_accuracy: 0.9788 - val_loss: 0.0674\n", "Epoch 5/15\n", "\u001b[1m106/106\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - accuracy: 0.9702 - loss: 0.0913 - val_accuracy: 0.9812 - val_loss: 0.0597\n", "Epoch 6/15\n", "\u001b[1m106/106\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - accuracy: 0.9756 - loss: 0.0814 - val_accuracy: 0.9843 - val_loss: 0.0522\n", "Epoch 7/15\n", "\u001b[1m106/106\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - accuracy: 0.9783 - loss: 0.0720 - val_accuracy: 0.9837 - val_loss: 0.0488\n", "Epoch 8/15\n", "\u001b[1m106/106\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - accuracy: 0.9802 - loss: 0.0644 - val_accuracy: 0.9865 - val_loss: 0.0447\n", "Epoch 9/15\n", "\u001b[1m106/106\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - accuracy: 0.9812 - loss: 0.0596 - val_accuracy: 0.9862 - val_loss: 0.0430\n", "Epoch 10/15\n", "\u001b[1m106/106\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - accuracy: 0.9818 - loss: 0.0568 - val_accuracy: 0.9858 - val_loss: 0.0432\n", "Epoch 11/15\n", "\u001b[1m106/106\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 12ms/step - accuracy: 0.9843 - loss: 0.0515 - val_accuracy: 0.9863 - val_loss: 0.0406\n", "Epoch 12/15\n", "\u001b[1m106/106\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 12ms/step - accuracy: 0.9839 - loss: 0.0523 - val_accuracy: 0.9890 - val_loss: 0.0372\n", "Epoch 13/15\n", "\u001b[1m106/106\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 11ms/step - accuracy: 0.9832 - loss: 0.0538 - val_accuracy: 0.9892 - val_loss: 0.0346\n", "Epoch 14/15\n", "\u001b[1m106/106\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - accuracy: 0.9856 - loss: 0.0456 - val_accuracy: 0.9892 - val_loss: 0.0337\n", "Epoch 15/15\n", "\u001b[1m106/106\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 10ms/step - accuracy: 0.9856 - loss: 0.0446 - val_accuracy: 0.9893 - val_loss: 0.0335\n" ] }, { "output_type": "execute_result", "data": { "text/plain": [ "
Model: \"sequential_3\"\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_4 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m300\u001b[0m) │ \u001b[38;5;34m235,500\u001b[0m │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_5 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m10\u001b[0m) │ \u001b[38;5;34m3,010\u001b[0m │\n",
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n"
],
"text/html": [
"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
"┃ Layer (type) ┃ Output Shape ┃ Param # ┃\n",
"┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
"│ dense_4 (Dense) │ (None, 300) │ 235,500 │\n",
"├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
"│ dense_5 (Dense) │ (None, 10) │ 3,010 │\n",
"└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
"\n"
]
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m238,512\u001b[0m (931.69 KB)\n"
],
"text/html": [
"Total params: 238,512 (931.69 KB)\n", "\n" ] }, "metadata": {} }, { "output_type": "display_data", "data": { "text/plain": [ "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m238,510\u001b[0m (931.68 KB)\n" ], "text/html": [ "
Trainable params: 238,510 (931.68 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": "display_data", "data": { "text/plain": [ "\u001b[1m Optimizer params: \u001b[0m\u001b[38;5;34m2\u001b[0m (12.00 B)\n" ], "text/html": [ "
Optimizer params: 2 (12.00 B)\n", "\n" ] }, "metadata": {} } ] }, { "cell_type": "code", "source": [ "# развернем каждое изображение 28*28 в вектор 784\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 = 7)\n", "num_pixels = X_train.shape[1] * X_train.shape[2]\n", "X_train = X_train.reshape(X_train.shape[0], num_pixels) / 255\n", "X_test = X_test.reshape(X_test.shape[0], num_pixels) / 255\n", "print('Shape of transformed X train:', X_train.shape)\n", "print('Shape of transformed X train:', X_test.shape)\n", "\n", "# переведем метки в one-hot\n", "y_train = keras.utils.to_categorical(y_train, num_classes)\n", "y_test = keras.utils.to_categorical(y_test, num_classes)\n", "print('Shape of transformed y train:', y_train.shape)\n", "print('Shape of transformed y test:', y_test.shape)" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "rQNRFPX1PGTc", "outputId": "e1ab1ccc-6cd8-4321-f87f-ee58733a3d6e", "collapsed": true }, "execution_count": 30, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Shape of transformed X train: (60000, 784)\n", "Shape of transformed X train: (10000, 784)\n", "Shape of transformed y train: (60000, 10)\n", "Shape of transformed y test: (10000, 10)\n" ] } ] }, { "cell_type": "code", "source": [ "# Оценка качества работы модели на тестовых данных\n", "scores = model.evaluate(X_test, y_test)\n", "print('Loss on test data:', scores[0])\n", "print('Accuracy on test data:', scores[1])" ], "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "QqJZMAa-PNn8", "outputId": "26ce3d0d-d4b4-4f45-8d8a-09b8e50f0463", "collapsed": true }, "execution_count": 31, "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.9016 - loss: 0.3667\n", "Loss on test data: 0.37091827392578125\n", "Accuracy on test data: 0.9013000130653381\n" ] } ] }, { "cell_type": "code", "source": [], "metadata": { "id": "hJ0tLgh1PfoO" }, "execution_count": 31, "outputs": [] }, { "cell_type": "code", "source": [], "metadata": { "id": "OO-ulBjiPf6q" }, "execution_count": 31, "outputs": [] } ] }