MNIST Small
MNIST Small — учебный датасет рукописных цифр.
Это уменьшенный вариант известного датасета MNIST. Он достаточно большой, чтобы показать настоящую задачу распознавания изображений, но при этом подходит для учебных примеров и работает быстрее полного MNIST.
В датасете 5000 записей. Каждая запись соответствует одному изображению рукописной цифры от 0 до 9 в разрешении 28 на 28 пикселов в градациях серого.
Как хранятся изображения
Заголовок раздела «Как хранятся изображения»Изображения в MNIST Small хранятся не как картинки, а как строки таблицы.
Каждая строка имеет вид:
label, pixel_0, pixel_1, ..., pixel_783label — первое поле. Это правильный ответ: цифра, которая изображена на картинке.
Остальные 784 поля — яркости пикселей изображения.
Почему именно 784?
28 × 28 = 784То есть каждое изображение имеет размер 28 на 28 пикселей, а в таблице оно развёрнуто в одну длинную строку чисел.
картинка 28×28 → 784 числовых признакаMNIST Small — это задача многоклассовой классификации.
Модель должна определить, какая цифра изображена:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9В отличие от Iris, здесь не 3 класса, а 10. И не 4 признака, а 784.
Информация о датасете
Заголовок раздела «Информация о датасете»uses MLABC;
begin Datasets.Language := 'ru';
var ds := Datasets.MnistSmall; ds.Info; Println;
ds.ClassCounts .OrderBy(kv -> kv.Key) .PrintLines(kv -> ds.ClassName(kv.Key) + ' → ' + kv.Value + ' шт');end.Эта программа выводит общую информацию о датасете, количество объектов каждого класса и первые строки таблицы.
Вывод:
Датасет: mnist_small
Описание:Сбалансированный поднабор MNIST из 5000 изображений для классификации рукописных цифр.
Задача: ClassificationСтрок: 5000Признаков: 784Цель: label
0 → 500 шт1 → 500 шт2 → 500 шт3 → 500 шт4 → 500 шт5 → 500 шт6 → 500 шт7 → 500 шт8 → 500 шт9 → 500 штИз вывода видно, что датасет сбалансирован: каждая цифра представлена 500 изображениями.
Отображение цифр
Заголовок раздела «Отображение цифр»Так как данные фактически являются изображениями, для MNIST Small особенно полезна визуализация.
uses MLABC, PlotML;
begin var ds := Datasets.MnistSmall; var df := ds.Data;
var X := df.ToMatrix(ds.Features); var y := df.ToVector(ds.Target);
var rows := new List<integer>; for var digit := 0 to 9 do rows.AddRange(y.Indices(v -> v = digit).Take(12));
var sample := X.TakeRows(rows);
Plot.Title := 'MnistSmall: по 12 изображений каждой цифры'; Plot.ImageGrid(sample, 28, 28, count := 120, cols := 12, invert := True, spacing := 0);end.Здесь для каждой цифры от 0 до 9 выбираются первые 12 изображений. Поэтому на рисунке получается 10 строк: в первой строке нули, во второй единицы, затем двойки и так далее.
Вывод:
Классификация цифр
Заголовок раздела «Классификация цифр»Пример может работать несколько секунд: признаков много, а задача уже ближе к реальному распознаванию изображений.
uses MLABC;
begin var ds := Datasets.MnistSmall; var df := ds.Data;
var X := df.ToMatrix(ds.Features); var y := df.EncodeLabels(ds.Target);
var (Xtrain, Xtest, ytrain, ytest) := Validation.TrainTestSplit(X, y, testRatio := 0.2, seed := 42);
// Для изображений полезно привести яркости пикселей к сопоставимому масштабу. var scaler := new MinMaxScaler; Xtrain := scaler.FitTransform(Xtrain); Xtest := scaler.Transform(Xtest);
var model := new LogisticRegression( learningRate := 1.0, epochs := 50 );
model.Fit(Xtrain, ytrain);
var pred := model.Predict(Xtest); var acc := Metrics.Accuracy(ytest, pred);
Println($'Accuracy: {acc:F3}');end.Вывод:
Accuracy: 0.879Это означает, что модель правильно распознала примерно 88% цифр из тестовой выборки.
Для первого примера это уже неплохой результат: модель видит не готовые картинки, а 784 числовых признака - яркости пикселей. Но это не предел. Другие модели могут распознавать цифры точнее, поэтому качество результата сильно зависит от выбранной модели и её параметров.
Матрица ошибок
Заголовок раздела «Матрица ошибок»Для многоклассовой классификации полезна матрица ошибок. Она показывает, какие цифры модель распознаёт хорошо, а какие путает между собой.
uses MLABC;
begin var ds := Datasets.MnistSmall; var df := ds.Data;
var X := df.ToMatrix(ds.Features); var y := df.EncodeTarget(ds.Target);
var (Xtrain, Xtest, ytrain, ytest) := Validation.TrainTestSplit(X, y.Labels, testRatio := 0.2, seed := 42);
var model := new RandomForestClassifier( nTrees := 20, maxDepth := 20, seed := 42 );
model.Fit(Xtrain, ytrain);
var pred := model.Predict(Xtest); var acc := Metrics.Accuracy(ytest, pred);
var cm := new ConfusionMatrix(ytest, pred, y.ClassNames); cm.Println(normalize := MatrixNormalization.Rows, sortClassNames := True);end.Вывод:
Предсказано →Реально ↓ 0 1 2 3 4 5 6 7 8 90 97.4% 0.0% 0.0% 0.0% 0.0% 0.0% 1.7% 0.9% 0.0% 0.0%1 0.0% 95.7% 2.2% 0.0% 0.0% 0.0% 1.1% 0.0% 1.1% 0.0%2 1.0% 0.0% 90.8% 1.0% 1.0% 0.0% 1.0% 0.0% 2.0% 3.1%3 0.0% 0.0% 0.9% 83.5% 0.0% 6.4% 0.0% 0.9% 4.6% 3.7%4 0.0% 0.0% 2.3% 0.0% 93.0% 0.0% 2.3% 0.0% 0.0% 2.3%5 0.0% 0.0% 0.0% 2.4% 0.0% 90.6% 4.7% 1.2% 0.0% 1.2%6 0.0% 2.0% 1.0% 0.0% 0.0% 2.0% 95.0% 0.0% 0.0% 0.0%7 0.0% 0.0% 4.0% 0.0% 0.0% 0.0% 0.0% 90.9% 1.0% 4.0%8 0.0% 2.8% 0.0% 3.7% 1.9% 1.9% 0.0% 1.9% 87.0% 0.9%9 0.9% 0.9% 0.0% 2.8% 1.9% 0.0% 0.0% 3.8% 0.0% 89.6%В матрице ошибок строки соответствуют настоящим цифрам, а столбцы — предсказанным.
Из данной матрицы видно, что реальная цифра 3 правильно распознается всего лишь в 83.5% случаев.
При этом алгоритм путает ее с цифрой 5 в 6.4% случаев, а с цифрой 8 — в 4.6% случаев. Из этой же матрицы следует, что алгоритм никогда не путает реальную цифру 3 с цифрами 0, 1, 6. Другое интересное наблюдение: лучше всех распознается цифра 0 — она распознается алгоритмом в 97.4% случаев.
Когда использовать MNIST Small
Заголовок раздела «Когда использовать MNIST Small»MNIST Small — хороший следующий шаг после Iris.
Iris → 3 класса, 4 признакаMNIST Small → 10 классов, 784 признакаНа этом датасете удобно показывать:
- многоклассовую классификацию;
- работу с большим числом признаков;
- представление изображений в виде таблицы;
- визуализацию изображений;
- матрицу ошибок для 10 классов.