exponenta event banner

Системные объекты для классификации и создания кодов

В этом примере показано, как генерировать код C из системного object™ MATLAB ®, который классифицирует изображения цифр с помощью обученной модели классификации. В этом примере также показано, как использовать объект System для классификации в Simulink ®. Преимущество использования системных объектов над функцией MATLAB состоит в том, что системные объекты более подходят для обработки больших объемов потоковых данных. Дополнительные сведения см. в разделе Что такое системные объекты?.

Этот пример основан на методе создания кода для классификации изображений, которая является альтернативой процедуре классификации цифр с использованием функций HOG (Computer Vision Toolbox).

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

Загрузить digitimages.

load digitimages.mat

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);

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

Масштабировать интенсивности пикселей так, чтобы они находились в интервале [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

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

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

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

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

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

Перекрестная проверка модели ECOC двоичных учеников SVM и случайного леса на основе результатов обучения. Используйте пятикратную перекрестную проверку.

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

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

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

coding = {'onevsone' 'onevsall'};
boxconstraint = logspace(-1,2,3);
cvLossECOC = 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});
        cvLossECOC(i,j) = kfoldLoss(CVMdl);
        fprintf('cvLossECOC = %f for model using %s coding and box constraint=%f\n',...
            cvLossECOC(i,j),coding{i},boxconstraint(j))
    end
end
cvLossECOC = 0.058333 for model using onevsone coding and box constraint=0.100000
cvLossECOC = 0.057083 for model using onevsone coding and box constraint=3.162278
cvLossECOC = 0.050000 for model using onevsone coding and box constraint=100.000000
cvLossECOC = 0.120417 for model using onevsall coding and box constraint=0.100000
cvLossECOC = 0.121667 for model using onevsall coding and box constraint=3.162278
cvLossECOC = 0.127917 for model using onevsall coding and box constraint=100.000000

Для случайного леса измените максимальное количество разбиений, используя значения в последовательности {32,33,..., 3 m}. m является таким, что 3m не превышает n-1. Для воспроизведения случайных выборок предикторов укажите'Reproducible',true.

n = size(X,1);
m = floor(log(n - 1)/log(3));
maxNumSplits = 3.^(2:m);
cvLossRF = nan(numel(maxNumSplits));
for i = 1:numel(maxNumSplits)
    t = templateTree('MaxNumSplits',maxNumSplits(i),'Reproducible',true);
    CVMdl = fitcensemble(X(idxTrn,:),Y(idxTrn),'Method','bag','Learners',t,...
        'KFold',5);
    cvLossRF(i) = kfoldLoss(CVMdl);
    fprintf('cvLossRF = %f for model using %d as the maximum number of splits\n',...
        cvLossRF(i),maxNumSplits(i))
end
cvLossRF = 0.319167 for model using 9 as the maximum number of splits
cvLossRF = 0.192917 for model using 27 as the maximum number of splits
cvLossRF = 0.066250 for model using 81 as the maximum number of splits
cvLossRF = 0.015000 for model using 243 as the maximum number of splits
cvLossRF = 0.013333 for model using 729 as the maximum number of splits
cvLossRF = 0.009583 for model using 2187 as the maximum number of splits

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

minCVLossECOC = min(cvLossECOC(:))
minCVLossECOC = 0.0500
linIdx = find(cvLossECOC == minCVLossECOC,1);
[bestI,bestJ] = ind2sub(size(cvLossECOC),linIdx);
bestCoding = coding{bestI}
bestCoding = 
'onevsone'
bestBoxConstraint = boxconstraint(bestJ)
bestBoxConstraint = 100
minCVLossRF = min(cvLossRF(:))
minCVLossRF = 0.0096
linIdx = find(cvLossRF == minCVLossRF,1);
[bestI,bestJ] = ind2sub(size(cvLossRF),linIdx);
bestMNS = maxNumSplits(bestI)
bestMNS = 2187

Случайный лес достигает меньшей степени перекрестной проверки ошибочной классификации.

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

t = templateSVM('BoxConstraint',bestBoxConstraint,'Standardize',true);
MdlECOC = fitcecoc(X(idxTrn,:),Y(idxTrn),'Learners',t,'Coding',bestCoding);
t = templateTree('MaxNumSplits',bestMNS);
MdlRF = fitcensemble(X(idxTrn,:),Y(idxTrn),'Method','bag','Learners',t);

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

testImages = X(idxTest,:);
testLabelsECOC = predict(MdlECOC,testImages);
testLabelsRF = predict(MdlRF,testImages);

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

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

saveLearnerForCoder(MdlECOC,'DigitImagesECOC');
saveLearnerForCoder(MdlRF,'DigitImagesRF');

Создание системного объекта для прогнозирования

Создайте два системных объекта, один для модели ECOC, а другой для случайного леса, которые:

  • Загрузка ранее сохраненной обучаемой модели с помощью loadLearnerForCoder.

  • Делать последовательные прогнозы с помощью step способ.

  • Не применять изменения размера к входным данным.

  • Принудительно использовать скалярные выходные данные с двойной точностью.

type ECOCClassifier.m % Display contents of ECOCClassifier.m file
classdef ECOCClassifier < matlab.System
    % ECOCCLASSIFIER Predict image labels from trained ECOC model
    %
    % ECOCCLASSIFIER loads the trained ECOC model from
    % |'DigitImagesECOC.mat'|, and predicts labels for new observations
    % based on the trained model.  The ECOC model in
    % |'DigitImagesECOC.mat'| was cross-validated using the training data
    % in the sample data |digitimages.mat|.

    properties(Access = private)
        CompactMdl % The compacted, trained ECOC model
    end
        
    methods(Access = protected)
        
        function setupImpl(obj)
            % Load ECOC model from file
            obj.CompactMdl = loadLearnerForCoder('DigitImagesECOC');
        end
        
        function y = stepImpl(obj,u)
            y = predict(obj.CompactMdl,u);
        end
        
        function flag = isInputSizeMutableImpl(obj,index)
            % Return false if input size is not allowed to change while
            % system is running
            flag = false;
        end
        
        function dataout = getOutputDataTypeImpl(~)
            dataout = 'double';
        end
        
        function sizeout = getOutputSizeImpl(~)
            sizeout = [1 1];
        end
    end
end
type RFClassifier.m % Display contents of RFClassifier.m file
classdef RFClassifier < matlab.System
    % RFCLASSIFIER Predict image labels from trained random forest
    %
    % RFCLASSIFIER loads the trained random forest from
    % |'DigitImagesRF.mat'|, and predicts labels for new observations based
    % on the trained model.  The random forest in |'DigitImagesRF.mat'|
    % was cross-validated using the training data in the sample data
    % |digitimages.mat|.

    properties(Access = private)
        CompactMdl % The compacted, trained random forest
    end
        
    methods(Access = protected)
        
        function setupImpl(obj)
            % Load random forest from file
            obj.CompactMdl = loadLearnerForCoder('DigitImagesRF');
        end
        
        function y = stepImpl(obj,u)
            y = predict(obj.CompactMdl,u);
        end
        
        function flag = isInputSizeMutableImpl(obj,index)
            % Return false if input size is not allowed to change while
            % system is running
            flag = false;
        end
        
        function dataout = getOutputDataTypeImpl(~)
            dataout = 'double';
        end
        
        function sizeout = getOutputSizeImpl(~)
            sizeout = [1 1];
        end
    end
end

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

Основные требования к системным объектам см. в разделе Определение основных системных объектов.

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

Определите две функции MATLAB, называемые predictDigitECOCSO.m и predictDigitRFSO.m. Функции:

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

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

  • Прогнозирование меток с помощью ECOCClassifier и RFClassifier Системные объекты соответственно.

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

type predictDigitECOCSO.m % Display contents of predictDigitECOCSO.m file
function label = predictDigitECOCSO(X) %#codegen
%PREDICTDIGITECOCSO Classify digit in image using ECOC Model System object
%   PREDICTDIGITECOCSO classifies the 28-by-28 images in the rows of X
%   using the compact ECOC model in the System object ECOCClassifier, and
%   then returns class labels in label.
classifier = ECOCClassifier;
label = step(classifier,X); 
end
type predictDigitRFSO.m % Display contents of predictDigitRFSO.m file
function label = predictDigitRFSO(X) %#codegen
%PREDICTDIGITRFSO Classify digit in image using RF Model System object
%   PREDICTDIGITRFSO classifies the 28-by-28 images in the rows of X
%   using the compact random forest in the System object RFClassifier, and
%   then returns class labels in label.
classifier = RFClassifier;
label = step(classifier,X); 
end

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

Скомпилировать функцию прогнозирования, которая обеспечивает лучшую точность тестовой выборки для файла MEX с помощью codegen. Укажите изображения тестового набора с помощью -args аргумент.

if(minCVLossECOC <= minCVLossRF)
    codegen predictDigitECOCSO -args testImages    
else   
    codegen predictDigitRFSO -args testImages
end
Code generation successful.

Убедитесь, что созданный файл MEX создает те же прогнозы, что и функция MATLAB.

if(minCVLossECOC <= minCVLossRF)
    mexLabels = predictDigitECOCSO_mex(testImages);
    verifyMEX = sum(mexLabels == testLabelsECOC) == numel(testLabelsECOC)    
else   
    mexLabels = predictDigitRFSO_mex(testImages);
    verifyMEX = sum(mexLabels == testLabelsRF) == numel(testLabelsRF)    
end
verifyMEX = logical
   1

verifyMEX является 1, что указывает на то, что прогнозы, сделанные сгенерированным MEX-файлом и соответствующей функцией MATLAB, одинаковы.

Прогнозирование меток с помощью системных объектов в Simulink

Создайте видеофайл, в котором отображаются покадровые изображения тестового набора.

v = VideoWriter('testImages.avi','Uncompressed AVI');
v.FrameRate = 1;
open(v);
dim = sqrt(p)*[1 1];
for j = 1:size(testImages,1)
    writeVideo(v,reshape(testImages(j,:),dim));
end
close(v);

Определение функции с именем scalePixelIntensities.m который преобразует изображения RGB в градации серого, а затем масштабирует результирующие интенсивности пикселей так, чтобы их значения находились в интервале [0,1].

type scalePixelIntensities.m % Display contents of scalePixelIntensities.m file
function x = scalePixelIntensities(imdat)
%SCALEPIXELINTENSITIES Scales image pixel intensities
%   SCALEPIXELINTENSITIES scales the pixel intensities of the image such
%   that the result x is a row vector of values in the interval [0,1].
imdat = rgb2gray(imdat);

minimdat = min(min(imdat));
maximdat = max(max(imdat));
x = (imdat - minimdat)/(maximdat - minimdat);
end

Загрузка модели Simulink ®slexClassifyAndDisplayDigitImages.slx.

SimMdlName = 'slexClassifyAndDisplayDigitImages';
open_system(SimMdlName);

На рисунке показана модель Simulink ®. В начале моделирования блок From Multimedia File загружает видеофайл изображений тестового набора. Для каждого изображения в видео:

  • Блок From Multimedia File преобразует и выводит изображение в матрицу интенсивностей пикселей 28 на 28.

  • Блок данных процесса масштабирует интенсивности пикселей с помощью scalePixelIntensities.mи выводит вектор масштабированных интенсивностей 1 на 784.

  • Блок подсистемы классификации прогнозирует метки с учетом обработанных данных изображения. Блок выбирает объект System, который минимизирует ошибку классификации. В этом случае блок выбирает случайный лес. Блок выводит скалярную метку двойной точности.

  • Блок преобразования типа данных преобразует метку в int32 скаляр.

  • Блок «Вставить текст» встраивает прогнозируемую метку в текущий кадр.

  • Блок «На видео» отображает аннотированный кадр.

Моделирование модели.

sim(SimMdlName)

Модель быстро отображает все 600 тестовых изображений и их прогноз. Последнее изображение остается на видеодисплее. Можно создавать прогнозы и отображать их с соответствующими изображениями один за другим, нажав кнопку Шаг вперед (Step Forward).

При наличии лицензии Simulink ® Coder™ можно создать код C изslexClassifyAndDisplayDigitImages.slx в Simulink ® или из командной строки с помощьюslbuild (Симулинк). Дополнительные сведения см. в разделе Создание кода C для модели (Simulink Coder).

См. также

| | |

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