Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

26 KiB

import os
os.chdir('/content/drive/MyDrive/Colab Notebooks/is_dnn/labworks/LW1')
# импорт модулей
import tensorflow as tf
from tensorflow import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import to_categorical
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
import os
import pandas as pd
# Загрузка датасета
(X_train_orig, y_train_orig), (X_test_orig, y_test_orig) = mnist.load_data()

# разбиваем выборку на обучающую и тестовую выборку
X = np.concatenate((X_train_orig, X_test_orig))
y = np.concatenate((y_train_orig, y_test_orig))


X_train, X_test, y_train, y_test = train_test_split(
    X, y,
    test_size=10000,
    train_size=60000,
    random_state=3,
)
# Вывод первых 4 изображений
fig, axes = plt.subplots(1, 4, figsize=(12, 3))
for i in range(4):
    axes[i].imshow(X_train[i], cmap='gray')
    axes[i].set_title(f'Метка: {y_train[i]}')
    axes[i].axis('off')
plt.tight_layout()
plt.show()
# развернем каждое изображение 28*28 в вектор 784
num_pixels = X_train.shape[1] * X_train.shape[2]
X_train = X_train.reshape(X_train.shape[0], num_pixels) / 255
X_test = X_test.reshape(X_test.shape[0], num_pixels) / 255
print('Shape of transformed X train:', X_train.shape)
# переведем метки в one-hot
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
print('Shape of transformed y train:', y_train.shape)
num_classes = y_train.shape[1]
model_0 = Sequential()
model_0.add(Dense(units=num_classes, input_dim=num_pixels, activation='softmax'))

# Компиляция модели
model_0.compile(loss='categorical_crossentropy',
                optimizer='sgd',
                metrics=['accuracy'])

# Вывод информации об архитектуре
print("Архитектура однослойной сети:")
model_0.summary()

# Обучение модели
history_0 = model_0.fit(X_train, y_train,
                        validation_split=0.1,
                        epochs=50)
# График функции ошибки по эпохам
plt.figure(figsize=(10, 6))
plt.plot(history_0.history['loss'], label='Обучающая выборка')
plt.plot(history_0.history['val_loss'], label='Валидационная выборка')
plt.title('Функция ошибки по эпохам (Однослойная сеть)')
plt.xlabel('Эпохи')
plt.ylabel('Ошибка')
plt.legend()
plt.grid(True)
plt.show()
# Оценка на тестовых данных
scores_0 = model_0.evaluate(X_test, y_test, verbose=0)
print("Результаты однослойной сети:")
print(f"Ошибка на тестовых данных: {scores_0[0]}")
print(f"Точность на тестовых данных: {scores_0[1]}")
# Функция для создания и обучения модели
def create_and_train_model(hidden_units, model_name):
    model = Sequential()
    model.add(Dense(units=hidden_units, input_dim=num_pixels, activation='sigmoid'))
    model.add(Dense(units=num_classes, activation='softmax'))

    model.compile(loss='categorical_crossentropy',
                  optimizer='sgd',
                  metrics=['accuracy'])

    history = model.fit(X_train, y_train,
                        validation_split=0.1,
                        epochs=50)

    scores = model.evaluate(X_test, y_test, verbose=0)

    return model, history, scores
# Эксперименты с разным количеством нейронов
hidden_units_list = [100, 300, 500]
models_1 = {}
histories_1 = {}
scores_1 = {}
# Обучение сетей с одним скрытым слоем
for units in hidden_units_list:
    print(f"\nОбучение модели с {units} нейронами...")
    model, history, scores = create_and_train_model(units, f"model_{units}")

    models_1[units] = model
    histories_1[units] = history
    scores_1[units] = scores

    print(f"Точность: {scores[1]}")
# Выбор наилучшей модели
best_units_1 = max(scores_1.items(), key=lambda x: x[1][1])[0]
print(f"\nНаилучшее количество нейронов: {best_units_1}")
print(f"Точность: {scores_1[best_units_1][1]}")
# Графики ошибок для всех моделей
plt.figure(figsize=(15, 5))
for i, units in enumerate(hidden_units_list, 1):
    plt.subplot(1, 3, i)
    plt.plot(histories_1[units].history['loss'], label='Обучающая')
    plt.plot(histories_1[units].history['val_loss'], label='Валидационная')
    plt.title(f'{units} нейронов')
    plt.xlabel('Эпохи')
    plt.ylabel('Ошибка')
    plt.legend()
    plt.grid(True)
plt.tight_layout()
plt.show()
# Добавление второго скрытого слоя
second_layer_units = [50, 100]
models_2 = {}
histories_2 = {}
scores_2 = {}
for units_2 in second_layer_units:
    print(f"\nОбучение модели со вторым слоем {units_2} нейронов")

    model = Sequential()
    model.add(Dense(units=best_units_1, input_dim=num_pixels, activation='sigmoid'))
    model.add(Dense(units=units_2, activation='sigmoid'))
    model.add(Dense(units=num_classes, activation='softmax'))

    model.compile(loss='categorical_crossentropy',
                  optimizer='sgd',
                  metrics=['accuracy'])

    history = model.fit(X_train, y_train,
                        validation_split=0.1,
                        epochs=50)

    scores = model.evaluate(X_test, y_test)

    models_2[units_2] = model
    histories_2[units_2] = history
    scores_2[units_2] = scores

    print(f"Точность: {scores[1]}")
# Выбор наилучшей двухслойной модели
best_units_2 = max(scores_2.items(), key=lambda x: x[1][1])[0]
print(f"\nНаилучшее количество нейронов во втором слое: {best_units_2}")
print(f"Точность: {scores_2[best_units_2][1]:.4f}")
# Сбор результатов
results = {
    '0 слоев': {'нейроны_1': '-', 'нейроны_2': '-', 'точность': scores_0[1]},
    '1 слой_100': {'нейроны_1': 100, 'нейроны_2': '-', 'точность': scores_1[100][1]},
    '1 слой_300': {'нейроны_1': 300, 'нейроны_2': '-', 'точность': scores_1[300][1]},
    '1 слой_500': {'нейроны_1': 500, 'нейроны_2': '-', 'точность': scores_1[500][1]},
    '2 слоя_50': {'нейроны_1': best_units_1, 'нейроны_2': 50, 'точность': scores_2[50][1]},
    '2 слоя_100': {'нейроны_1': best_units_1, 'нейроны_2': 100, 'точность': scores_2[100][1]}
}
# Создаем DataFrame из результатов
df_results = pd.DataFrame([
    {'Кол-во скрытых слоев': 0, 'Нейроны_1_слоя': '-', 'Нейроны_2_слоя': '-', 'Точность': results['0 слоев']['точность']},
    {'Кол-во скрытых слоев': 1, 'Нейроны_1_слоя': 100, 'Нейроны_2_слоя': '-', 'Точность': results['1 слой_100']['точность']},
    {'Кол-во скрытых слоев': 1, 'Нейроны_1_слоя': 300, 'Нейроны_2_слоя': '-', 'Точность': results['1 слой_300']['точность']},
    {'Кол-во скрытых слоев': 1, 'Нейроны_1_слоя': 500, 'Нейроны_2_слоя': '-', 'Точность': results['1 слой_500']['точность']},
    {'Кол-во скрытых слоев': 2, 'Нейроны_1_слоя': best_units_1, 'Нейроны_2_слоя': 50, 'Точность': results['2 слоя_50']['точность']},
    {'Кол-во скрытых слоев': 2, 'Нейроны_1_слоя': best_units_1, 'Нейроны_2_слоя': 100, 'Точность': results['2 слоя_100']['точность']}
])

print(" " * 20 + "ТАБЛИЦА РЕЗУЛЬТАТОВ")
print("=" * 70)
# print(df_results.to_string(index=False, formatters={
#     'Точность': '{:.4f}'.format
# }))
print(df_results.reset_index(drop=True))
# Выбор наилучшей модели
best_model_type = max(results.items(), key=lambda x: x[1]['точность'])[0]
best_accuracy = results[best_model_type]['точность']
print(f"\nНаилучшая архитектура: {best_model_type}")
print(f"Точность: {best_accuracy:.4f}")
# Определение наилучшей модели
if '0' in best_model_type:
    best_model = model_0
elif '1' in best_model_type:
    best_neurons = int(best_model_type.split('_')[1])
    best_model = models_1[best_neurons]
else:
    best_neurons_2 = int(best_model_type.split('_')[1])
    best_model = models_2[best_neurons_2]
# Сохранение модели
best_model.save('best_mnist_model.keras')
# вывод тестового изображения и результата распознавания (1)
n = 123
result = best_model.predict(X_test[n:n+1])
print('NN output:', result)
plt.imshow(X_test[n].reshape(28,28), cmap=plt.get_cmap('gray'))
plt.show()
print('Real mark: ', str(np.argmax(y_test[n])))
print('NN answer: ', str(np.argmax(result)))
# вывод тестового изображения и результата распознавания (3)
n = 353
result = best_model.predict(X_test[n:n+1])
print('NN output:', result)
plt.imshow(X_test[n].reshape(28,28), cmap=plt.get_cmap('gray'))
plt.show()
print('Real mark: ', str(np.argmax(y_test[n])))
print('NN answer: ', str(np.argmax(result)))
# загрузка собственного изображения (Цифры 2 и 7)
from PIL import Image
file_data_2 = Image.open('2.png')
file_data_7 = Image.open('7.png')
file_data_2 = file_data_2.convert('L') # перевод в градации серого
file_data_7 = file_data_7.convert('L') # перевод в градации серого
test_img_2 = np.array(file_data_2)
test_img_7 = np.array(file_data_7)
# вывод собственного изображения (цифра 2)
plt.imshow(test_img_2, cmap=plt.get_cmap('gray'))
plt.show()
# предобработка
test_img_2 = test_img_2 / 255
test_img_2 = test_img_2.reshape(1, num_pixels)
# распознавание
result = best_model.predict(test_img_2)
print('I think it\'s ', np.argmax(result))
# вывод собственного изображения (цифра 7)
plt.imshow(test_img_7, cmap=plt.get_cmap('gray'))
plt.show()
# предобработка
test_img_7 = test_img_7 / 255
test_img_7 = test_img_7.reshape(1, num_pixels)
# распознавание
result = best_model.predict(test_img_7)
print('I think it\'s ', np.argmax(result))
# Тестирование на собственных повернутых изображениях
file_data_2_90 = Image.open('2_90.png')
file_data_7_90 = Image.open('7_90.png')
file_data_2_90 = file_data_2_90.convert('L') # перевод в градации серого
file_data_7_90 = file_data_7_90.convert('L') # перевод в градации серого
test_img_2_90 = np.array(file_data_2_90)
test_img_7_90= np.array(file_data_7_90)
# вывод собственного изображения (цифра 2)
plt.imshow(test_img_2_90, cmap=plt.get_cmap('gray'))
plt.show()
# предобработка
test_img_2_90 = test_img_2_90 / 255
test_img_2_90 = test_img_2_90.reshape(1, num_pixels)
# распознавание
result = best_model.predict(test_img_2_90)
print('I think it\'s ', np.argmax(result))
# вывод собственного изображения (цифра 7)
plt.imshow(test_img_7_90, cmap=plt.get_cmap('gray'))
plt.show()
# предобработка
test_img_7_90 = test_img_7_90 / 255
test_img_7_90 = test_img_7_90.reshape(1, num_pixels)
# распознавание
result = best_model.predict(test_img_7_90)
print('I think it\'s ', np.argmax(result))