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

В этом примере показано, как сгенерировать код С от функции MATLAB®, которая классифицирует изображения цифр с помощью обученной модели классификации. Этот пример демонстрирует альтернативный рабочий процесс Классификации Цифр, использующей Функции ПОЖИРАТЕЛЯ РЕСУРСОВ (Computer Vision Toolbox). Однако, чтобы поддержать генерацию кода в том примере, можно выполнить шаги генерации кода в этом примере.

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

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

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

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

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

Сгенерировать код С, MATLAB Coder:

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

  • Требует, чтобы поддерживаемые функции были в функции MATLAB, которую вы задаете. Для основного рабочего процесса смотрите Введение в Генерацию кода.

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

Относительно последнего ограничения полагайте что:

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

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

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

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

Генерация кода для рабочего процесса классификации

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

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

  2. Решите который функции извлечь из изображений.

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

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

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

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

  7. Решите среду, в которой можно выполнить сгенерированный код.

  8. Сгенерируйте код С для функции.

Загрузка данных

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

load digitimages

images 28 28 3 000 массивов 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. Для изображения 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

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

Измените данные

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

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

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

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

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

Выделить признаки

Computer Vision Toolbox™ предлагает несколько методов извлечения признаков для изображений. Один такой метод является экстракцией гистограммы ориентированного градиента (ПОЖИРАТЕЛЬ РЕСУРСОВ) функции. Чтобы изучить, как обучить модель ECOC, использующую функции ПОЖИРАТЕЛЯ РЕСУРСОВ, смотрите, что Классификация Цифр использует Функции ПОЖИРАТЕЛЯ РЕСУРСОВ (Computer Vision Toolbox). Для получения дополнительной информации на других поддерживаемых методах, смотрите Обнаружение Локального признака и Экстракцию (Computer Vision Toolbox). Этот пример использует перемасштабированные интенсивности пикселей в качестве переменных предикторов.

Обучите и оптимизируйте модель классификации

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

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

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

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

Чтобы перекрестный подтвердить модель ECOC бинарных учеников SVM на основе учебных наблюдений, используйте 5-кратную перекрестную проверку. Несмотря на то, что значения предиктора имеют ту же область значений, чтобы избежать числовых трудностей во время обучения, стандартизируйте предикторы. Кроме того, оптимизируйте ECOC, кодирующий проект и ограничение поля SVM. Используйте все комбинации этих значений:

  • Для ECOC, кодирующего проект, используйте один по сравнению с одним и one-all.

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

Для всех моделей сохраните 5-кратные перекрестные подтвержденные misclassification уровни.

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

Определите индексы гиперпараметра, которые дают к минимальному misclassification уровню. Обучите модель 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 возвращает логическую единицу (true), что означает, что все входные параметры равны. predictDigitECOC дает к ожидаемым результатам.

Решите который среда выполнить сгенерированный код

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

  • В среде MATLAB как файл MEX на C

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

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

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

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

Скомпилируйте функцию MATLAB к файлу MEX

Скомпилируйте predictDigitECOC.m к файлу MEX с помощью codegen. Задайте эти опции:

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

  • -args — MATLAB Coder требует, чтобы вы задали свойства всех входных аргументов функции. Один способ сделать это должно обеспечить codegen с примером входных значений. Следовательно, MATLAB Coder выводит свойства из значений в качестве примера. Задайте изображения набора тестов, соразмерные с 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 возвращает логическую единицу (true), означая, что файл MEX дает к ожидаемым результатам.

Смотрите также

| | | (MATLAB Coder)

Похожие темы