159 KiB
Глубокое обучение¶
import os
os.environ["KERAS_BACKEND"] = "jax"
import keras
print(keras.__version__)
Классификация¶
Загрузка набора данных для задачи классификации¶
База данных MNIST (сокращение от "Modified National Institute of Standards and Technology") — объёмная база данных образцов рукописного написания цифр. База данных является стандартом, предложенным Национальным институтом стандартов и технологий США с целью обучения и сопоставления методов распознавания изображений с помощью машинного обучения в первую очередь на основе нейронных сетей. Данные состоят из заранее подготовленных примеров изображений, на основе которых проводится обучение и тестирование систем.
База данных MNIST содержит 60000 изображений для обучения и 10000 изображений для тестирования.
from keras.api.datasets import mnist
(X_train, y_train), (X_valid, y_valid) = mnist.load_data()
Отображение данных¶
Образцы из набора прошли сглаживание и приведены к серому полутоновому изображению размером 28x28 пикселей.
Под каждым изображением представлено соответствующее ему значение целевого признака (класс).
from turtle import width
from matplotlib import pyplot as plt
fig, axes = plt.subplots(3, 4, figsize=(5, 5))
for k in range(12):
current_axes = axes[k % 3][k % 4]
current_axes.imshow(X_train[k], cmap='grey')
current_axes.get_xaxis().set_ticks([])
current_axes.get_yaxis().set_ticks([])
current_axes.set_xlabel(y_train[k])
plt.tight_layout()
plt.show()
Предобработка данных¶
Количество классов - 10 (от 0 до 9).
Все изображения из X трансформируются в векторы длиной 784 (28*28) признака и нормализуются.
Для целевых признаков применяется унитарное кодирование в бинарные векторы длиной 10 (нормализация).
n_classes = 10
X_train = X_train.reshape(60000, 784).astype("float32") / 255
X_valid = X_valid.reshape(10000, 784).astype("float32") / 255
y_train = keras.utils.to_categorical(y_train, n_classes)
y_valid = keras.utils.to_categorical(y_valid, n_classes)
display(X_train[0])
display(y_train[0])
Проектирование архитектуры простой ИНС¶
Сеть состоит из:
- входного слоя с 784 входами (InputLayer);
- скрытого полносвязного слоя с 64 sigmoid-нейронами (dense_2);
- выходного слоя с 10 softmax-нейронами (многоклассовая классификация) (dense_3).
Количество параметров в слоях:
- dense_2: 784 64 + 64 = 50 176 + 64 = 50 240. У каждого из 64 нейронов 784 входа с 784 параметрами (w x) + 64 смещения (b).
- dense_3: 64 * 10 + 10 = 640 + 10 = 650.
Всего параметров: 50 240 + 650 = 50 890.
Все параметры настраиваются в процессе обучения.
from keras.api.models import Sequential
from keras.api.layers import Dense, InputLayer
simple_model = Sequential()
simple_model.add(InputLayer(shape=(28*28,)))
simple_model.add(Dense(64, activation="sigmoid"))
simple_model.add(Dense(n_classes, activation="softmax"))
simple_model.summary()
Обучение простой модели¶
Функция стоимости: MSE (квадратичная функция)
Оптимизатор: стохастический градиентный спуск (SGD)
Скорость обучения: 0.01
Количество эпох: 200
Размер пакета: 128
Всего пакетов: 60 000 / 128 = 468.75 (468 пакетов по 128 изображений и 1 пакет с 96 изображениями)
Метрика оценки качества: accuracy
Оценка качества и стоимость на обучающей выборке:\ accuracy: 0.4650 - loss: 0.0849
Оценка качества и стоимость на тестовой выборке:\ val_accuracy: 0.4703 - val_loss: 0.0845
from keras.api.optimizers import SGD
simple_model.compile(
loss="mean_squared_error",
optimizer=SGD(learning_rate=0.01),
metrics=["accuracy"],
)
simple_model.fit(
X_train,
y_train,
batch_size=128,
epochs=200,
validation_data=(X_valid, y_valid),
)
Оценка качества простой модели¶
Лучшее качество модели: 86.6 %
simple_model.evaluate(X_valid, y_valid)
Проектирование архитектуры более сложной ИНС¶
Добавлен дополнительный скрытый полносвязный слой
Все скрытые слои используют ReLU-нейроны
difficult_model = Sequential()
difficult_model.add(InputLayer(shape=(28 * 28,)))
difficult_model.add(Dense(64, activation="relu"))
difficult_model.add(Dense(64, activation="relu"))
difficult_model.add(Dense(10, activation="softmax"))
difficult_model.summary()
Обучение более сложной модели¶
Функция стоимости изменена на перекрестную энтропию (лучше подходит для классификации)
Количество эпох уменьшено с 200 до 20
difficult_model.compile(
loss="categorical_crossentropy",
optimizer=SGD(learning_rate=0.1),
metrics=["accuracy"],
)
difficult_model.fit(
X_train,
y_train,
batch_size=128,
epochs=20,
validation_data=(X_valid, y_valid),
)
Оценка качества более сложной модели¶
Лучшее качество модели: 97.4 %
При этом количество эпох обучения значительно сократилось (с 200 до 20).
difficult_model.evaluate(X_valid, y_valid)
Проектирование архитектуры глубокой ИНС¶
В ИНС теперь три скрытых полносвязных слоя с ReLU-нейронами
Для выходов каждого скрытого слоя используется пакетная нормализация
Для последнего скрытого слоя применяется прореживание, при котором отключается 20 % случайных нейронов
Keras автоматически корректирует значения (умножает входы на 0.8)
from keras.api.layers import Dropout
from keras.api.layers import BatchNormalization
deep_model = Sequential()
deep_model.add(InputLayer(shape=(28 * 28,)))
deep_model.add(Dense(64, activation="relu"))
deep_model.add(BatchNormalization())
deep_model.add(Dense(64, activation="relu"))
deep_model.add(BatchNormalization())
deep_model.add(Dense(64, activation="relu"))
deep_model.add(BatchNormalization())
deep_model.add(Dropout(0.2))
deep_model.add(Dense(10, activation="softmax"))
deep_model.summary()
Обучение глубокой модели¶
Вместо SGD используется оптимизатор Adam
deep_model.compile(
loss="categorical_crossentropy",
optimizer="adam",
metrics=["accuracy"],
)
deep_model.fit(
X_train,
y_train,
batch_size=128,
epochs=20,
validation_data=(X_valid, y_valid),
)
Оценка качества глубокой модели¶
Лучшее качество модели: 97.3 %
Качество модели незначительно улучшилось за счет улучшения архитектуры сети и смены оптимизатора
deep_model.evaluate(X_valid, y_valid)
Регрессия¶
Загрузка данных для задачи регрессии¶
Набор данных о жилье в Бостоне собран Службой переписи населения США.
Входные признаки:
- CRIM — уровень преступности на душу населения по районам;
- ZN — доля жилых земель, отведенных под участки площадью более 25 000 кв. футов;
- INDUS — доля неторговых акров в городе;
- CHAS — 1, если участок граничит с рекой; 0 в противном случае;
- NOX — концентрация оксидов азота;
- RM — среднее количество комнат в помещении;
- AGE — доля домов, построенных до 1940 года;
- DIS — взвешенные расстояния до пяти центров занятости Бостона;
- RAD — индекс доступности радиальных автомагистралей;
- TAX — ставка налога на имущество на полную стоимость;
- PTRATIO — соотношение учеников и учителей по районам;
- B — доля чернокожих по районам;
- LSTAT — % населения с более низким статусом.
Целевой признак:
- MEDV — медианная стоимость домов в тысячах долларов США.
Данные уже предобработаны
from keras.api.datasets import boston_housing
(X_train, y_train), (X_valid, y_valid) = boston_housing.load_data()
display(X_train)
display(y_train)
Проектирование ИНС для задачи регрессии¶
Для решения задачи регрессии в выходном слое используются нейроны с линейной функцией активации
Создавать более сложную архитектуру не имеет смысла, так как в наборе данных мало признаков
reg_model = Sequential()
reg_model.add(InputLayer(shape=(13,)))
reg_model.add(Dense(32, activation="relu"))
reg_model.add(BatchNormalization())
reg_model.add(Dense(16, activation="relu"))
reg_model.add(BatchNormalization())
reg_model.add(Dropout(0.2))
reg_model.add(Dense(1, activation="linear"))
reg_model.summary()
Обучение модели для регрессии¶
Функция стоимости: MSE (лучше подходит для задачи регрессии)
reg_model.compile(
loss="mean_squared_error",
optimizer="adam",
)
reg_model.fit(
X_train,
y_train,
batch_size=8,
epochs=32,
validation_data=(X_valid, y_valid),
)
Оценка качества модели для регрессии¶
Средняя ошибка на тестовой выборке: 19.1 тысячи долларов
import numpy as np
y_hat = reg_model.predict(np.reshape(X_valid[42], [1, 13]))
display(y_hat[0][0])
display(y_valid[42])