exponenta event banner

Создание кода для классификации изображений

В этом примере показано, как создать код C из функции MATLAB ®, которая классифицирует изображения цифр с использованием обученной модели классификации. В этом примере демонстрируется альтернативный рабочий процесс классификации цифр с использованием функций HOG (Computer Vision Toolbox). Однако для поддержки создания кода в этом примере можно выполнить шаги создания кода в этом примере.

Автоматизированная классификация изображений является повсеместным инструментом. Например, обученный классификатор может быть развернут на беспилотнике для автоматического выявления аномалий на суше в отснятых кадрах или на машине, которая сканирует рукописные почтовые коды на письмах. В последнем примере после того, как машина найдет почтовый индекс и сохранит отдельные изображения цифр, развернутый классификатор должен угадать, какие цифры находятся в изображениях, чтобы восстановить почтовый индекс.

В этом примере показано, как обучить и оптимизировать мультиклассовую модель классификации выходных кодов с исправлением ошибок (ECOC) для классификации цифр на основе интенсивности пикселей в растровых изображениях. Модель ECOC содержит учеников бинарного вектора поддержки (SVM). Затем в этом примере показано, как создать код C, который использует обученную модель для классификации новых изображений. Данные представляют собой синтетические изображения деформированных цифр различных шрифтов, которые имитируют рукописные цифры.

Настройка компилятора C

Для создания кода C/C + + необходимо иметь доступ к компилятору C/C + +, который настроен правильно. MATLAB Coder™ находит и использует поддерживаемый установленный компилятор. Вы можете использоватьmex -setup для просмотра и изменения компилятора по умолчанию. Дополнительные сведения см. в разделе Изменение компилятора по умолчанию.

Допущения и ограничения

Для генерации кода C используется кодер MATLAB:

  • Требуется правильно настроенный компилятор.

  • Требуется, чтобы поддерживаемые функции находились в определяемой функции MATLAB. Базовый рабочий процесс см. в разделе Введение в создание кода.

  • Запрещает объекты в качестве входных аргументов определенной функции.

Что касается последнего ограничения, то следует учитывать, что:

  • Обученные модели классификации являются объектами

  • Поддержка кодера MATLAB predict для классификации наблюдений с использованием обученных моделей, но не поддерживает подгонку модели

Чтобы обойти ограничения генерации кода для классификации, обучайте модель классификации с помощью MATLAB, а затем передайте результирующий объект модели в saveLearnerForCoder. saveLearnerForCoder функция удаляет некоторые свойства, которые не требуются для прогнозирования, а затем сохраняет обученную модель на диск в виде массива структуры. Как и модель, структурный массив содержит информацию, используемую для классификации новых наблюдений.

После сохранения модели на диск загрузите ее в функцию MATLAB с помощью loadLearnerForCoder. loadLearnerForCoder функция загружает сохраненный массив структуры, а затем реконструирует объект модели. В функции MATLAB для классификации наблюдений можно передать модель и набор данных предиктора, который может быть входным аргументом функции, в predict.

Создание кода для потока операций классификации

Перед развертыванием классификатора образов на устройстве:

  1. Получите достаточное количество помеченных изображений.

  2. Выберите элементы для извлечения из изображений.

  3. Подготовка и оптимизация классификационной модели. Этот шаг включает в себя выбор соответствующего алгоритма и настройку гиперпараметров, то есть параметров модели, не подходящих во время обучения.

  4. Сохранение модели на диск с помощью saveLearnerForCoder.

  5. Определите функцию для классификации новых изображений. Функция должна загрузить модель с помощью loadLearnerForCoderи может возвращать метки, такие как оценки классификации.

  6. Настройте компилятор Си.

  7. Определите среду для выполнения созданного кода.

  8. Создайте код C для функции.

Загрузить данные

Загрузить digitimages набор данных.

load digitimages

images множество 28 на 28 на 3000 uint16 целые числа. Каждая страница представляет собой растровое изображение цифры. Каждый элемент имеет пиксельную интенсивность. Соответствующие метки находятся в числовом векторе 3000 на 1 Y. Для получения дополнительной информации введите Description в командной строке.

Запишите количество наблюдений и число переменных предиктора. Создайте раздел данных, определяющий удержание 20% данных. Извлеките индексы обучающего и тестового наборов из раздела данных.

rng(1) % For reproducibility
n = size(images,3);
p = numel(images(:,:,1));
cvp = cvpartition(n,'Holdout',0.20);
idxTrn = training(cvp);
idxTest = test(cvp);

Отображение девяти случайных изображений из данных.

figure
for j = 1:9
    subplot(3,3,j)
    selectImage = datasample(images,1,3);
    imshow(selectImage,[])
end

Масштабировать данные

Поскольку интенсивности необработанных пикселей сильно различаются, следует нормализовать их значения перед обучением классификационной модели. Масштабировать интенсивности пикселей так, чтобы они находились в интервале [0,1]. То есть предположим, что pij - интенсивность j пикселя в изображении. Для изображения i масштабируйте все его интенсивности пикселя, используя следующую формулу:

pˆij=pij-minj (pij) maxj (pij) -minj (pij).

X = double(images);
for i = 1:n
    minX = min(min(X(:,:,i)));
    maxX = max(max(X(:,:,i)));
    X(:,:,i) = (X(:,:,i) - minX)/(maxX - minX);
end

Кроме того, при наличии лицензии на Toolbox™ обработки изображений можно эффективно масштабировать интенсивности пикселей изображений до [0,1] с помощью mat2gray. Дополнительные сведения см. в разделе mat2gray(Панель инструментов обработки изображений).

Изменение формы данных

Для генерации кода данные предиктора для обучения должны быть в таблице числовых переменных или числовой матрице.

Преобразование данных в матрицу таким образом, чтобы переменные предиктора (интенсивности пикселей) соответствовали столбцам, а изображения (наблюдения) - строкам. Поскольку reshape принимает элементы по столбцам, необходимо транспонировать их результат.

X = reshape(X,[p,n])';

Для того чтобы предварительная обработка данных поддерживала изображение, постройте график первого наблюдения в X.

figure
imshow(reshape(X(1,:),sqrt(p)*[1 1]),[],'InitialMagnification','fit')

Извлечь элементы

Computer Vision Toolbox™ предлагает несколько методов извлечения функций для изображений. Одной из таких методик является извлечение гистограммы признаков ориентированного градиента (HOG). Сведения о том, как обучить модель ECOC с использованием функций HOG, см. в разделе Классификация цифр с использованием функций HOG (Computer Vision Toolbox). Дополнительные сведения о других поддерживаемых методах см. в разделе Обнаружение и извлечение локальных функций (панель инструментов Computer Vision Toolbox). В этом примере в качестве переменных предиктора используются масштабированные интенсивности пикселей.

Подготовка и оптимизация модели классификации

Линейные модели SVM часто применяются к наборам данных изображения для классификации. Однако SVM являются двоичными классификаторами, и в наборе данных имеется 10 возможных классов.

Можно создать многоклассовую модель из нескольких двоичных учеников SVM с помощью fitcecoc. fitcecoc объединяет несколько двоичных учеников, используя схему кодирования. По умолчанию fitcecoc применяет конструкцию «один против одного», которая определяет обучающих бинарных учеников на основе наблюдений из всех комбинаций пар классов. Например, в проблеме с 10 классами, fitcecoc должен обучить 45 бинарных моделей SVM.

Как правило, при обучении модели классификации следует настраивать гиперпараметры до тех пор, пока не будет достигнута удовлетворительная ошибка обобщения. Таким образом, следует выполнить перекрестную проверку моделей для определенных наборов гиперпараметров, а затем сравнить показатели ошибочной классификации.

Можно выбрать собственные наборы значений гиперпараметров или указать для реализации байесовской оптимизации. (Общие сведения о байесовской оптимизации см. в разделе Рабочий процесс байесовской оптимизации.) В этом примере выполняется перекрестная проверка выбранной сетки значений.

Для перекрестной проверки модели ECOC двоичных учеников SVM на основе результатов обучения используйте пятикратную перекрестную проверку. Хотя значения предиктора имеют одинаковый диапазон, чтобы избежать численных трудностей во время обучения, стандартизируйте предикторы. Также оптимизируйте конструкцию кодирования ECOC и ограничение блока SVM. Используйте все комбинации этих значений:

  • Для проектирования кодирования ECOC используйте «один против одного» и «один против всех».

  • Для ограничения поля SVM используйте три логарифмически разнесенных значения от 0,1 до 100.

Для всех моделей сохраните 5-кратные показатели перекрестной проверки ошибочной классификации.

coding = {'onevsone' 'onevsall'};
boxconstraint = logspace(-1,2,3);
cvLoss = nan(numel(coding),numel(boxconstraint)); % For preallocation

for i = 1:numel(coding)
    for j = 1:numel(boxconstraint)
        t = templateSVM('BoxConstraint',boxconstraint(j),'Standardize',true);
        CVMdl = fitcecoc(X(idxTrn,:),Y(idxTrn),'Learners',t,'KFold',5,...
            'Coding',coding{i});
        cvLoss(i,j) = kfoldLoss(CVMdl);
        fprintf('cvLoss = %f for model using %s coding and box constraint=%f\n',...
            cvLoss(i,j),coding{i},boxconstraint(j))
    end
end
cvLoss = 0.052083 for model using onevsone coding and box constraint=0.100000
cvLoss = 0.055000 for model using onevsone coding and box constraint=3.162278
cvLoss = 0.050000 for model using onevsone coding and box constraint=100.000000
cvLoss = 0.116667 for model using onevsall coding and box constraint=0.100000
cvLoss = 0.123750 for model using onevsall coding and box constraint=3.162278
cvLoss = 0.125000 for model using onevsall coding and box constraint=100.000000

Определите индексы гиперпараметров, которые дают минимальный коэффициент неправильной классификации. Обучение модели ECOC с использованием данных обучения. Стандартизация обучающих данных и предоставление оптимальной комбинации гиперпараметров.

minCVLoss = min(cvLoss(:))
minCVLoss = 0.0500
linIdx = find(cvLoss == minCVLoss);
[bestI,bestJ] = ind2sub(size(cvLoss),linIdx);
bestCoding = coding{bestI}
bestCoding = 
'onevsone'
bestBoxConstraint = boxconstraint(bestJ)
bestBoxConstraint = 100
t = templateSVM('BoxConstraint',bestBoxConstraint,'Standardize',true);
Mdl = fitcecoc(X(idxTrn,:),Y(idxTrn),'Learners',t,'Coding',bestCoding);

Создайте матрицу путаницы для изображений тестового набора.

testImages = X(idxTest,:);
testLabels = predict(Mdl,testImages);
confusionMatrix = confusionchart(Y(idxTest),testLabels);

Диагональные и внедиагональные элементы соответствуют корректно и неправильно классифицированным наблюдениям соответственно. Mdl кажется, правильно классифицирует большинство изображений.

Если вы удовлетворены работой Mdl, затем можно продолжить создание кода для прогнозирования. В противном случае можно продолжить настройку гиперпараметров. Например, можно попробовать обучить слушателей SVM с помощью различных функций ядра.

Сохранить классификационную модель на диске

Mdl является прогностической классификационной моделью, но ее необходимо подготовить для создания кода. Сохранить Mdl в текущий рабочий каталог с помощью saveLearnerForCoder.

saveLearnerForCoder(Mdl,'DigitImagesECOC')

saveLearnerForCoder уплотняет Mdl, преобразует его в массив структуры и сохраняет в MAT-файле DigitImagesECOC.mat.

Определение функции прогнозирования для создания кода

Определение функции точки входа с именем predictDigitECOC.m это делает следующее:

  • Включить директиву создания кода %#codegen где-то в функции.

  • Принять данные изображения, соответствующие X.

  • Груз DigitImagesECOC.mat использование loadLearnerForCoder.

  • Возврат прогнозируемых меток.

type predictDigitECOC.m % Display contents of predictDigitECOC.m file
function label = predictDigitECOC(X) %#codegen
%PREDICTDIGITECOC Classify digit in image using ECOC Model 
%   PREDICTDIGITECOC classifies the 28-by-28 images in the rows of X using
%   the compact ECOC model in the file DigitImagesECOC.mat, and then
%   returns class labels in label.
CompactMdl = loadLearnerForCoder('DigitImagesECOC.mat');
label = predict(CompactMdl,X); 
end

Примечание.Если нажать кнопку, расположенную в правом верхнем разделе этой страницы, и открыть этот пример в MATLAB, то MATLAB откроет папку примеров. Эта папка содержит файл функции начального уровня.

Убедитесь, что функция прогнозирования возвращает те же метки тестового набора, что и predict.

pfLabels = predictDigitECOC(testImages);
verifyPF = isequal(pfLabels,testLabels)
verifyPF = logical
   1

isequal возвращает логический 1 (true), что означает, что все входы равны. predictDigitECOC дает ожидаемые результаты.

Выбор среды для выполнения сгенерированного кода

Сгенерированный код может выполняться:

  • Внутри среды MATLAB в виде файла C-MEX

  • Вне среды MATLAB в качестве автономного исполняемого файла

  • Вне среды MATLAB в качестве общей утилиты, связанной с другим автономным исполняемым файлом

В этом примере создается файл MEX для выполнения в среде MATLAB. Создание такого MEX-файла позволяет протестировать сгенерированный код с помощью инструментов MATLAB перед развертыванием функции вне среды MATLAB. В функцию MEX можно включить код для проверки, но не для генерации кода, объявив команды как внешние с помощью coder.extrinsic (Кодер MATLAB). Внешние команды могут включать функции, не поддерживающие генерацию кода. Все внешние команды в функции MEX выполняются в MATLAB, но codegen не создает для них код.

Если планируется развертывание кода вне среды MATLAB, необходимо создать автономный исполняемый файл. Одним из способов указать выбор компилятора является использование -config вариант codegen. Например, чтобы создать статический исполняемый файл C, укажите -config:exe при звонке codegen. Дополнительные сведения о настройке параметров генерации кода см. в разделе -config вариант codegen (Кодер MATLAB).

Компиляция функции MATLAB в файл MEX

Собрать predictDigitECOC.m в файл MEX с использованием codegen. Укажите следующие параметры:

  • -report - Создает отчет о компиляции, который идентифицирует исходный код MATLAB и связанные файлы, которые codegen создается во время создания кода.

  • -args - Кодер MATLAB требует указания свойств всех входных аргументов функции. Один из способов сделать это - предоставить codegen с примером входных значений. Следовательно, кодер MATLAB выводит свойства из значений примера. Укажите изображения тестового набора, соответствующие X.

codegen predictDigitECOC -report -args {testImages}
Code generation successful: View report

codegen успешно сгенерирован код для функции прогнозирования. Отчет можно просмотреть, нажав кнопку View report ссылку или путем ввода open('codegen/mex/predictDigitECOC/html/report.mldatx') в окне команд. В случае неуспешного создания кода отчет может помочь в отладке.

codegen создает каталог pwd/codegen/mex/predictDigitECOC, где pwd является текущим рабочим каталогом. В дочернем каталоге codegen генерирует, среди прочего, MEX-файл predictDigitECOC_mex.mexw64.

Убедитесь, что файл MEX возвращает те же метки, что и predict.

mexLabels = predictDigitECOC_mex(testImages);
verifyMEX = isequal(mexLabels,testLabels)
verifyMEX = logical
   1

isequal возвращает логический 1 (true), что означает, что MEX-файл дает ожидаемые результаты.

См. также

| | | (кодер MATLAB)

Связанные темы