Рисунок 2.13. Образцы Fashion-MNIST
Fashion-MNIST разработан в дополнение к классическому набору данных MNIST, который часто используют как «Hello, World» для отладки методов машинного обучения в задачах компьютерного зрения. MNIST содержит изображения рукописных цифр (0, 1, 2 и т.д.) в формате, идентичном формату изображений одежды набора Fashion-MNIST. Для современных программ компьютерного зрения MNIST стал «слишком прост», поэтому применение более сложного набора данных полезно для отладки систем машинного обучения.
Загрузить набор данных можно, используя keras. Предварительно потребуется загрузить необходимые библиотеки:
# TensorFlow и tf.keras
import tensorflow as tf
from tensorflow import keras
# Вспомогательные библиотеки
import numpy as np
import matplotlib.pyplot as plt
Теперь можно загрузить набор данных и посмотреть одно из изображений:
fashion_mnist = keras.datasets.fashion_mnist
(X_train1, y_train),(X_test1,y_test)= fashion_mnist.load_data()
plt.figure()
plt.imshow(X_train1[10])
plt.colorbar()
plt.grid(False)
plt.show()
Как видно, диапазон изменения яркости пикселя от 0 до 255. Если подать такие значения на вход нейронной сети, качественные результаты классификации существенно упадут. Поэтому все значения нужно нормировать так, чтобы на вход сети поступили значения в диапазоне от 0 до 1, просто разделив каждое значение на 255:
X_train1=X_train1/255.0
X_test1=X_test1/255.0
Следующее, что нам необходимо сделать в процессе предобработки, это преобразовать двумерные массивы изображений 28 x 28 в одномерные векторы. Каждый такой вектор станет набором входных параметров размерностью 784:
X_train=np.reshape(X_train1,(X_train1.shape[0],X_train1.shape[1]*X_train1.shape[2]))
X_test=np.reshape(X_test1,(X_test1.shape[0],X_test1.shape[1]*X_test1.shape[2]))
В результате матрица X_train размерностью (60 000, 28, 28) будет преобразована в матрицу размером (60 000, 784), которую можно подать на вход нейронной сети для тренировки.
from sklearn.neural_network import MLPClassifier
clf = MLPClassifier(hidden_layer_sizes = [15, 15,],
alpha = 0.01,random_state = 0,
solver='adam').fit(X_train, y_train)
Обучение нейронной сети может занять несколько минут. Затем можно оценить качественные показатели классификатора командами:
predictions=clf.predict(X_test)
print('Accuracy of NN classifier on training set: {:.2f}'
.format(clf.score(X_train, y_train)))
print('Accuracy of NN classifier on test set: {:.2f}'
.format(clf.score(X_test, y_test)))
print(classification_report(y_test,predictions))
matrix = confusion_matrix(y_test, predictions)
print('Confusion matrix on test set\n',matrix)
Значение accuracy может быть примерно следующим:
Accuracy of NN classifier on training set: 0.89
Accuracy of NN classifier on test set: 0.86
Изменяя количество нейронов в слоях сети и параметр регуляризации alpha (например, hidden_layer_sizes = [75, 75], alpha = 0.015), можно несколько улучшить результат:
Accuracy of NN classifier on training set: 0.91
Accuracy of NN classifier on test set: 0.88
Примечание. Программу данного раздела MLF_MLP_Fashion_MNIST_001.ipynb можно получить по ссылке https://www.dropbox.com/s/ryk05tyxwlhz0m6/MLF_MLP_Fashion_MNIST_001.html?dl=0
2.9. Алгоритм k ближайших соседей (k-Nearest Neighbor k-NN)
Алгоритм [[58], [59]] основан на подсчете количества объектов каждого класса в сфере (гиперсфере) с центром в распознаваемом (классифицируемом) объекте. Классифицируемый объект относят к тому классу, объектов у которого больше всего в этой сфере. В данном методе предполагается, что веса выбраны единичными для всех объектов.
Если веса не одинаковы, то вместо подсчета количества объектов можно суммировать их веса. Таким образом, если в сфере вокруг распознаваемого объекта 10 эталонных объектов класса А весом 2 и 15 ошибочных/пограничных объектов класса Б весом 1, то классифицируемый объект будет отнесен к классу А.
Веса объектов в сфере можно представить как обратно пропорциональные расстоянию до распознаваемого объекта. Таким образом, чем ближе объект, тем более значимым он является для данного распознаваемого объекта. Расстояние между классифицируемыми объектами может рассчитываться как расстояние в декартовом пространстве (эвклидова метрика), но можно использовать и другие метрики: манхэттенскую (Manhattan), метрику Чебышева (Chebyshev), Минковского (Minkowski) и др.
В итоге метрический классификатор можно описать так:
где w(i, u) вес i-го соседа распознаваемого объекта u; a(u;Xl) класс объекта u, распознанный по выборке Xl.
Радиус гиперсферы может быть как фиксированным, так и изменяемым, причем в случае с изменяемым радиусом радиус для каждой точки подбирается так, чтобы количество объектов в каждой сфере было одинаковым. Тогда при распознавании в областях с разной плотностью выборки количество «соседних» объектов (по которым и происходит распознавание) будет одинаковым. Таким образом, исключается ситуация, когда в областях с низкой плотностью не хватает данных для классификации.
В целом это один из самых простых, но часто неточных алгоритмов классификации. Алгоритм также отличается высокой вычислительной сложностью. Объем вычислений при использовании эвклидовой метрики пропорционален квадрату от числа обучающих примеров.
Рассмотрим пример.
Загрузка соответствующей библиотеки и создание классификатора выполняются командами:
from sklearn import neighbors
clf = neighbors.KNeighborsClassifier(n_neighbors=5, weights='distance')
Используем уже упомянутый ранее набор данных Fashion-MNIST. Однако в связи с тем, что скорость обучения и особенно классификации KNeighborsClassifier значительно ниже, чем MLP, будем использовать только часть набора: 10 000 примеров для обучения и 2000 для тестирования:
X_train1=X_train1[0:10000,:,:]
y_train=y_train[0:10000]
X_test1=X_test1[0:2000,:,:]
y_test=y_test[0:2000]
Процесс обучения классификатора:
from sklearn.neighbors import KNeighborsClassifier
clf = KNeighborsClassifier(n_neighbors = 5, weights='distance')
clf.fit(X_train, y_train)
Вывод результатов выполняется практически так же, как и в предыдущем примере. Качественные показатели классификатора, примерно следующие:
Accuracy of kNN classifier on training set: 1.00
Accuracy of kNN classifier on test set: 0.82
Примечание. Программу MLF_KNN_Fashion_MNIST_001.ipynb, использованную в данном разделе, можно получить по ссылке https://www.dropbox.com/s/ei1tuaifi2zj2ml/MLF_KNN_Fashion_MNIST_001.html?dl=0
2.10. Алгоритм опорных векторов
Алгоритм опорных векторов (Support Vector Machines) [[60]] относится к группе граничных методов: он определяет классы при помощи границ областей. В основе метода лежит понятие плоскостей решений. Плоскость решения разделяет объекты с разной классовой принадлежностью. В пространствах высоких размерностей вместо прямых необходимо рассматривать гиперплоскости пространства, размерность которых на единицу меньше, чем размерность исходного пространства. В R3, например, гиперплоскость это двумерная плоскость.
Метод опорных векторов отыскивает образцы, находящиеся на границах классов (не меньше двух), т.е. опорные векторы, и решает задачу нахождения разделения множества объектов на классы с помощью линейной решающей функции. Метод опорных векторов строит классифицирующую функцию f(x) в виде:
где ⟨w,s⟩ скалярное произведение; w нормальный (перпендикулярный) вектор к разделяющей гиперплоскости; b вспомогательный параметр, который равен по модулю расстоянию от гиперплоскости до начала координат. Если параметр b равен нулю, гиперплоскость проходит через начало координат.
Объекты, для которых f(x) = 1, попадают в один класс, а объекты с f(x) = -1 в другой.
С точки зрения точности классификации лучше всего выбрать такую прямую, расстояние от которой до каждого класса максимально. Такая прямая (в общем случае гиперплоскость) называется оптимальной разделяющей гиперплоскостью. Задача состоит в выборе w и b, максимизирующих это расстояние.
В случае нелинейного разделения существует способ адаптации машины опорных векторов. Нужно вложить пространство признаков Rn в пространство H большей размерности с помощью отображения: φ = Rn H. Тогда решение задачи сводится к линейно разделимому случаю, т.е. разделяющую классифицирующую функцию вновь ищут в виде: f(x)=sign(⟨w,ϕ(x)⟩+b).
Возможен и другой вариант преобразования данных перевод в полярные координаты:
В общем случае машины опорных векторов строятся таким образом, чтобы минимизировать функцию стоимости вида:
где S
1
S0
log(hθ) loghθfkСущественным недостатком классификатора является значительное возрастание времени обучения при увеличении количества примеров. Другими словами, алгоритм обладает высокой вычислительной сложностью.
Рассмотрим пример.
Подключение алгоритма и создание классификатора выполняются командами:
from sklearn.svm import SVC
clf = SVC(kernel = 'rbf', C=1)
Используем еще раз набор данных Fashion-MNIST. Скорость обучения и особенно классификации SVC значительно ниже, чем MLP, поэтому, как и в случае с KNeighborsClassifier, будем использовать только часть набора: 10 000 примеров для обучения и 2000 для тестирования. Обучение классификатора со стандартными параметрами:
from sklearn.svm import SVC
clf = SVC(kernel = 'rbf',C=1).fit(X_train, y_train)
В результате получим примерно следующие значения accuracy:
Accuracy of SVC classifier on training set: 0.83
Accuracy of SVC classifier on test set: 0.82
Отметим, что, применив поиск оптимальных параметров классификатора (см. далее раздел «Подбор параметров по сетке»), можно получить значение accuracy, близкое к 0.87.
Примечание. Ноутбук MLF_SVC_Fashion_MNIST_001.ipynb, реализующий упомянутый пример, можно загрузить по ссылке https://www.dropbox.com/s/0p1i1dqk8wqwp5x/MLF_SVC_Fashion_MNIST_001.html?dl=0
Набор классификаторов scikit-learn включает кроме упомянутых алгоритмов еще и GaussianProcessClassifier, DecisionTreeClassifier, GaussianNB и др. Сравнение между собой классификаторов, имеющих стандартные параметры, описано в классическом примере [[61]], который можно рекомендовать как первую ступень в разработке программы выбора лучшего классификатора.
2.11. Статистические методы в машинном обучении. Наивный байесовский вывод
2.11.1. Теорема Байеса и ее применение в машинном обучении
Машинное обучение использует теорию вероятности для предсказания и классификации. Особенностью ML является создание алгоритмов, способных обучаться. Способ обучения в данном случае заключается в использовании статистических закономерностей. Одна из таких относительно простых возможностей использование теоремы Байеса.
Напомним, что теорема Байеса говорит о том, что если известна априорная вероятность гипотезы А P(A), априорная вероятность гипотезы B P(B) и условная вероятность наступления события B при истинности гипотезы A P(B|A), то мы можем рассчитать условную вероятность гипотезы А при наступлении события B:
Рассмотрим пример.
Предположим, что нам известна статистика дворовых игр в футбол и погода, при которых они состоялись, например, в таком виде:
То есть мы имеем информацию о количестве игр (14) и сведения о трех видах погоды, при которой они проходили: sunny солнечно, rainy дождливо, overcast пасмурно. Попробуем рассчитать, состоится ли очередная игра, если на улице солнечно (sunny). Для этого нам нужно рассчитать вероятность того, что игра состоится ('yes') при условии 'Sunny', то есть нам нужно рассчитать:
P('yes'|'Sunny').
Другими словами, мы хотим оценить вероятность справедливости гипотезы, что А = 'yes' игра состоится при условии, что B = 'Sunny'.
Для такого расчета нам нужно вычислить априорные вероятности того, что погода солнечная P('Sunny') и что игра вообще состоится P('yes'). Кроме этого, рассчитать условную вероятность того, что погода является солнечной при состоявшейся игре P('Sunny'|'yes'). Тогда в соответствии с теоремой Байеса мы сможем рассчитать искомую вероятность:
P('yes'|'Sunny') = P('Sunny'|'yes') * P('yes') / P('Sunny')
Используя таблицу, легко посчитать оценки указанных вероятностей. Положим, что:
A_value = 'yes'
B_hypothes = 'Sunny'
Тогда цель нашего расчета получить значение величины:
P(A_value|B_hypothes) = P('yes'|'Sunny') = P('Sunny'|'yes') * P('yes') / P('Sunny')
Рассчитаем условную вероятность:
P('Sunny'|'yes') = 3 / 9 = 0.33
Рассчитаем априорные вероятности солнечной погоды и того, что игра состоится:
P('Sunny') = 5 / 14 = 0.36
P('yes') = 9 / 14 = 0.64
Подставив полученные значения, получим:
P('yes'|'Sunny') = 0.33 * 0.64 / 0.36 = 0.60.
2.11.2. Алгоритм Naïve Bayes
Однако как быть, если игра зависит не только от погоды, но и от других условий, например, готовности поля, здоровья игроков и т.п.? В этом случае вывод классификатора можно строить на отношении условных вероятностей следующим образом:
где NBI
1
Оценки вероятностей вычисляются следующим образом:
где freq частота; N частота всех случаев данного класса. Примером служит выражение P('Sunny'|'yes') = 3 / 9 = 0,33.
В выражении Eq. 2 величина NBI принимает значения от 0 до +. Если NBI < 1, то это свидетельствует в пользу отрицательной гипотезы ('no'). Если NBI > 1, то это свидетельство того, что текущее сочетание условий дает возможность положительного вывода ('yes'). Отметим, что если мы используем выражение Eq. 2, то мы должны примириться с неравновесностью такого вывода.
Кроме того, если некоторые признаки встречаются только в сочетании с 'yes' или 'no', то мы можем получить ошибку вывода, когда произведение обращается в ноль либо происходит деление на ноль. Третья проблема связана с тем, что оценки условных вероятностей обычно имеют небольшое значение, и если их много, то итоговое произведение может стать меньше машинного нуля. Эти вычислительные недостатки разрешаются путем сглаживания и использования суммы логарифмов вместо произведения вероятностей. Чаще всего для исключения деления на ноль применяется сглаживание по Лапласу, например, для положительной гипотезы:
В этом выражении F количество свойств или параметров. В примере ниже F = 2 параметры: погода (Weather) и состояние поля (Field). В свою очередь, N частота всех случаев для данного класса, то есть для нашего примера это количество случаев, когда игра состоялась, 9.
Применение логарифмов позволяет перейти от произведения отношений вероятности к суммам логарифмов этих отношений, так как log(a*b) = log(a) + log(b). Тогда вывод классификатора можно рассчитать следующим образом:
Применение логарифмов позволяет работать с очень небольшими значениями вероятностей. Второе преимущество заключается в том, что при применении логарифмов шкала вывода будет равномерной в диапазоне от - до +. Величина NBIlog будет либо больше 0, что означает верность положительной гипотезы, либо меньше 0, что означает справедливость отрицательной гипотезы (рисунок 2.14).
Рисунок 2.14. Шкала вывода алгоритма Naïve Bayes при использовании выражений Eq. 2.21 (слева) и Eq. 2.24 (справа)
Обучение алгоритма Naïve Bayes выполняется просто путем расчета оценок вероятностей (Eq. 2.23, 2.24). После этого вывод обеспечивается по формуле Eq. 2.24.
Рассмотрим пример.
За основу возьмем данные, приведенные в предыдущем параграфе. Добавим еще одно свойство состояние игрового поля Field. Теперь набор данных содержит два свойства (Weather, Field) и целевую колонку Play: