форкнуто от main/is_dnn
Вы не можете выбрать более 25 тем
Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
94 KiB
94 KiB
from google.colab import drive
drive.mount('/content/drive') # Смонтировать Диск
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks/IS_LR3') # Правильный путьDrive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
import matplotlib.pyplot as plt
import numpy as np
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.metrics import ConfusionMatrixDisplayfrom keras.datasets import mnist
(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 ━━━━━━━━━━━━━━━━━━━━ 0s 0us/step
# создание своего разбиения датасета
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 = 123)
# вывод размерностей
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,)
# Зададим параметры данных и модели
num_classes = 10
input_shape = (28, 28, 1)
# Приведение входных данных к диапазону [0, 1]
X_train = X_train / 255
X_test = X_test / 255
# Расширяем размерность входных данных, чтобы каждое изображение имело
# размерность (высота, ширина, количество каналов)
X_train = np.expand_dims(X_train, -1)
X_test = np.expand_dims(X_test, -1)
print('Shape of transformed X train:', X_train.shape)
print('Shape of transformed X test:', X_test.shape)
# переведем метки в one-hot
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
print('Shape of transformed y train:', y_train.shape)
print('Shape of transformed y test:', y_test.shape)Shape of transformed X train: (60000, 28, 28, 1)
Shape of transformed X test: (10000, 28, 28, 1)
Shape of transformed y train: (60000, 10)
Shape of transformed y test: (10000, 10)
# создаем модель
model = Sequential()
model.add(layers.Conv2D(32, kernel_size=(3, 3), activation="relu", input_shape=input_shape))
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
model.add(layers.Conv2D(64, kernel_size=(3, 3), activation="relu"))
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
model.add(layers.Dropout(0.5))
model.add(layers.Flatten())
model.add(layers.Dense(num_classes, activation="softmax"))
model.summary()
# компилируем и обучаем модель
batch_size = 512
epochs = 15
model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)/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.
super().__init__(activity_regularizer=activity_regularizer, **kwargs)
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ ┃ Layer (type) ┃ Output Shape ┃ Param # ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ │ conv2d (Conv2D) │ (None, 26, 26, 32) │ 320 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ max_pooling2d (MaxPooling2D) │ (None, 13, 13, 32) │ 0 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ conv2d_1 (Conv2D) │ (None, 11, 11, 64) │ 18,496 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ max_pooling2d_1 (MaxPooling2D) │ (None, 5, 5, 64) │ 0 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ dropout (Dropout) │ (None, 5, 5, 64) │ 0 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ flatten (Flatten) │ (None, 1600) │ 0 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ dense (Dense) │ (None, 10) │ 16,010 │ └─────────────────────────────────┴────────────────────────┴───────────────┘
Total params: 34,826 (136.04 KB)
Trainable params: 34,826 (136.04 KB)
Non-trainable params: 0 (0.00 B)
Epoch 1/15
106/106 ━━━━━━━━━━━━━━━━━━━━ 47s 427ms/step - accuracy: 0.1470 - loss: 2.2933 - val_accuracy: 0.6295 - val_loss: 2.0603
Epoch 2/15
106/106 ━━━━━━━━━━━━━━━━━━━━ 44s 418ms/step - accuracy: 0.6329 - loss: 1.6934 - val_accuracy: 0.7963 - val_loss: 0.7763
Epoch 3/15
106/106 ━━━━━━━━━━━━━━━━━━━━ 81s 409ms/step - accuracy: 0.7699 - loss: 0.7786 - val_accuracy: 0.8455 - val_loss: 0.5514
Epoch 4/15
106/106 ━━━━━━━━━━━━━━━━━━━━ 43s 411ms/step - accuracy: 0.8124 - loss: 0.6159 - val_accuracy: 0.8683 - val_loss: 0.4603
Epoch 5/15
106/106 ━━━━━━━━━━━━━━━━━━━━ 82s 409ms/step - accuracy: 0.8372 - loss: 0.5313 - val_accuracy: 0.8857 - val_loss: 0.4070
Epoch 6/15
106/106 ━━━━━━━━━━━━━━━━━━━━ 45s 420ms/step - accuracy: 0.8568 - loss: 0.4730 - val_accuracy: 0.8968 - val_loss: 0.3593
Epoch 7/15
106/106 ━━━━━━━━━━━━━━━━━━━━ 81s 413ms/step - accuracy: 0.8738 - loss: 0.4254 - val_accuracy: 0.9078 - val_loss: 0.3253
Epoch 8/15
106/106 ━━━━━━━━━━━━━━━━━━━━ 44s 417ms/step - accuracy: 0.8831 - loss: 0.3899 - val_accuracy: 0.9178 - val_loss: 0.2952
Epoch 9/15
106/106 ━━━━━━━━━━━━━━━━━━━━ 44s 410ms/step - accuracy: 0.8929 - loss: 0.3607 - val_accuracy: 0.9250 - val_loss: 0.2665
Epoch 10/15
106/106 ━━━━━━━━━━━━━━━━━━━━ 82s 414ms/step - accuracy: 0.9030 - loss: 0.3290 - val_accuracy: 0.9317 - val_loss: 0.2452
Epoch 11/15
106/106 ━━━━━━━━━━━━━━━━━━━━ 43s 409ms/step - accuracy: 0.9082 - loss: 0.3079 - val_accuracy: 0.9367 - val_loss: 0.2267
Epoch 12/15
106/106 ━━━━━━━━━━━━━━━━━━━━ 45s 424ms/step - accuracy: 0.9152 - loss: 0.2844 - val_accuracy: 0.9405 - val_loss: 0.2093
Epoch 13/15
106/106 ━━━━━━━━━━━━━━━━━━━━ 79s 392ms/step - accuracy: 0.9207 - loss: 0.2666 - val_accuracy: 0.9462 - val_loss: 0.1969
Epoch 14/15
106/106 ━━━━━━━━━━━━━━━━━━━━ 43s 406ms/step - accuracy: 0.9227 - loss: 0.2617 - val_accuracy: 0.9482 - val_loss: 0.1836
Epoch 15/15
106/106 ━━━━━━━━━━━━━━━━━━━━ 83s 416ms/step - accuracy: 0.9276 - loss: 0.2425 - val_accuracy: 0.9503 - val_loss: 0.1760
<keras.src.callbacks.history.History at 0x7d6f78042540>
# Оценка качества работы модели на тестовых данных
scores = model.evaluate(X_test, y_test)
print('Loss on test data:', scores[0])
print('Accuracy on test data:', scores[1])313/313 ━━━━━━━━━━━━━━━━━━━━ 3s 9ms/step - accuracy: 0.9470 - loss: 0.1815
Loss on test data: 0.17656435072422028
Accuracy on test data: 0.9498999714851379
# вывод тестового изображения и результата распознавания
n = 123
result = model.predict(X_test[n:n+1])
print('NN output:', result)
plt.show()
plt.imshow(X_test[n].reshape(28,28), cmap=plt.get_cmap('gray'))
print('Real mark: ', np.argmax(y_test[n]))
print('NN answer: ', np.argmax(result))1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 181ms/step
NN output: [[3.0897139e-05 9.9081528e-01 4.4518107e-04 1.4293649e-03 9.3897019e-04
1.5827973e-04 2.9317071e-04 2.5718326e-03 8.2969037e-04 2.4873116e-03]]
Real mark: 1
NN answer: 1

# истинные метки классов
true_labels = np.argmax(y_test, axis=1)
# предсказанные метки классов
predicted_labels = np.argmax(model.predict(X_test), axis=1)
# отчет о качестве классификации
print(classification_report(true_labels, predicted_labels))
# вычисление матрицы ошибок
conf_matrix = confusion_matrix(true_labels, predicted_labels)
# отрисовка матрицы ошибок в виде "тепловой карты"
display = ConfusionMatrixDisplay(confusion_matrix=conf_matrix)
display.plot()
plt.show()313/313 ━━━━━━━━━━━━━━━━━━━━ 7s 23ms/step
precision recall f1-score support
0 0.97 0.98 0.98 984
1 0.97 0.98 0.98 1186
2 0.94 0.94 0.94 963
3 0.95 0.93 0.94 1004
4 0.96 0.96 0.96 978
5 0.94 0.96 0.95 931
6 0.97 0.98 0.97 938
7 0.94 0.94 0.94 1019
8 0.95 0.90 0.92 1013
9 0.91 0.93 0.92 984
accuracy 0.95 10000
macro avg 0.95 0.95 0.95 10000
weighted avg 0.95 0.95 0.95 10000

# загрузка собственного изображения
from PIL import Image
file_data = Image.open('test.png')
file_data = file_data.convert('L') # перевод в градации серого
test_img = np.array(file_data)
# вывод собственного изображения
plt.imshow(test_img, cmap=plt.get_cmap('gray'))
plt.show()
# предобработка
test_img = test_img / 255
test_img = np.reshape(test_img, (1,28,28,1))
# распознавание
result = model.predict(test_img)
print('I think it\'s ', np.argmax(result))
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 103ms/step
I think it's 4