Задайте аргументы Переменного Размера для генерации кода

Этот пример показывает, как задать входные параметры переменного размера, когда вы генерируете код для объектных функций объектов модели регрессии и классификации. Данные переменного размера являются данными, размер которых может измениться во время выполнения. Определение входных параметров переменного размера удобно, когда у вас есть данные с неизвестным размером во время компиляции. Этот пример также описывает, как включать аргументы пары "имя-значение" в функцию точки входа и как задать их при генерации кода.

Для более подробных примеров рабочего процесса генерации кода смотрите Генерацию кода для Прогноза Модели Машинного обучения в Командной строке и Генерацию кода для Прогноза Модели Машинного обучения Используя Приложение MATLAB Coder.

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

Загрузите ирисовый набор данных Фишера. Преобразуйте метки в символьную матрицу.

load fisheriris
species = char(species);

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

Mdl = fitctree(meas,species);

Mdl является моделью ClassificationTree.

Сохраните модель Используя saveCompactModel

Сохраните обученное дерево классификации в файл с именем ClassTreeIris.mat в вашей текущей папке при помощи saveCompactModel.

MdlName = 'ClassTreeIris';
saveCompactModel(Mdl,MdlName);

Задайте функцию точки входа

В вашей текущей папке задайте функцию с именем точки входа mypredictTree.m, который делает следующее:

  • Примите измерения со столбцами, соответствующими meas, и примите допустимые аргументы пары "имя-значение".

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

  • Предскажите метки и соответствующие очки, числа узла и классификационные индексы от загруженного дерева классификации.

Можно допускать дополнительные аргументы пары "имя-значение" путем определения varargin как входного параметра. Для получения дополнительной информации смотрите Генерацию кода для Списков аргументов Переменной длины (MATLAB Coder).

type mypredictTree.m  % Display contents of mypredictTree.m file
function [label,score,node,cnum] = mypredictTree(x,savedmdl,varargin) %#codegen
%MYPREDICTTREE Predict iris species using classification tree
%   MYPREDICTTREE predicts iris species for the n observations in the
%   n-by-4 matrix x using the classification tree stored in the MAT-file
%   whose name is in savedmdl, and then returns the predictions in the
%   array label. Each row of x contains the lengths and widths of the petal
%   and sepal of an iris (see the fisheriris data set). For other output
%   argument descriptions, see the predict reference page.
CompactMdl = loadCompactModel(savedmdl);
[label,score,node,cnum] = predict(CompactMdl,x,varargin{:});
end

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

Сгенерируйте код

Задайте аргументы Переменного Размера

Поскольку C и C++ являются статически типизированными языками, необходимо определить свойства всех переменных в функции точки входа во время компиляции использование опции -args codegen.

Используйте coder.Constant, чтобы задать время компиляции постоянный вход.

coder.Constant(v)

coder.Constant(v) создает переменную типа coder.Constant, значения которой являются постоянными, то же самое как v, во время генерации кода.

Используйте coder.typeof, чтобы задать вход переменного размера.

coder.typeof(example_value, size_vector, variable_dims)

Значения example_value, size_vector и variable_dims задают свойства входного массива, который может принять сгенерированный код.

  • Входной массив имеет совпадающий тип данных как значения в качестве примера в example_value.

  • size_vector является размером массивов входного массива, если соответствующим значением variable_dims является false.

  • size_vector является верхней границей размера массивов, если соответствующим значением variable_dims является true.

  • variable_dims задает, имеет ли каждая размерность массива переменный размер или фиксированный размер. Значение true (логическая единица) означает, что соответствующая размерность имеет переменный размер; значение false (логический ноль) означает, что соответствующая размерность имеет фиксированный размер.

Функция точки входа mypredictTree принимает данные о предикторе, имя MAT-файла, содержащее обученный объект модели и дополнительные аргументы пары "имя-значение". Предположим, что вы хотите сгенерировать код, который принимает массив переменного размера для данных о предикторе и аргумента пары "имя-значение" 'Subtrees' с вектором переменного размера для его значения. Затем у вас есть четыре входных параметра: данные о предикторе, имя MAT-файла, и имя и значение аргумента пары "имя-значение" 'Subtrees'.

Задайте 4 1 массив ячеек и присвойте каждый тип входного параметра функции точки входа к каждой ячейке.

ARGS = cell(4,1);

Для первого входа используйте coder.typeof, чтобы указать, что переменная данных предиктора является двойной точностью с одинаковым числом столбцов как данные о предикторе, используемые в обучении модель, но что количество наблюдений (строки) произвольно.

p = numel(Mdl.PredictorNames);
ARGS{1} = coder.typeof(0,[Inf,p],[1,0]);

0 для значения example_value подразумевает, что типом данных является double, потому что double является типом числовых данных по умолчанию MATLAB. [Inf,p] для значения size_vector и [1,0] для значения variable_dims подразумевают, что размер первой размерности является переменным и неограниченным, и размер второго измерения фиксируется, чтобы быть p.

Второй вход является именем MAT-файла, которое должно быть постоянным временем компиляции. Используйте coder.Constant, чтобы задать тип второго входа.

ARGS{2} = coder.Constant(MdlName);

Последние два входных параметров являются именем и значением аргумента пары "имя-значение" 'Subtrees'. Имена аргументов пары "имя-значение" должны быть константами времени компиляции.

ARGS{3} = coder.Constant('Subtrees');

Используйте coder.typeof, чтобы указать, что значение 'Subtrees' является вектором - строкой с двойной точностью и что верхней границей размера вектора - строки является max(Mdl.PrunedList).

m = max(Mdl.PruneList);
ARGS{4} = coder.typeof(0,[1,m],[0,1]);

Снова, 0 для значения example_value подразумевает, что типом данных является double, потому что double является типом числовых данных по умолчанию MATLAB. [1,m] для значения size_vector и [0,1] для значения variable_dims подразумевают, что размер первой размерности фиксируется, чтобы быть 1, и размер второго измерения является переменным, и его верхней границей является m.

Сгенерируйте код Используя codegen

Сгенерируйте MEX-функцию от функции точки входа mypredictTree с помощью массива ячеек ARGS, который включает типы входного параметра для mypredictTree. Задайте типы входного параметра с помощью опции -args. Задайте количество выходных аргументов в сгенерированной функции точки входа использование опции -nargout. Сгенерировать код включает конкретное количество выходных аргументов в порядке, в котором они происходят в определении функции точки входа.

codegen mypredictTree -args ARGS -nargout 2

codegen генерирует MEX-функцию mypredictTree_mex с зависимым платформой расширением в вашей текущей папке.

Функция predict принимает значения с одинарной точностью, значения с двойной точностью и 'all' для аргумента пары "имя-значение" 'SubTrees'. Однако можно задать только значения с двойной точностью, когда вы используете MEX-функцию для прогноза, потому что тип данных, заданный ARGS{4}, является двойным.

Проверьте сгенерированный код

Предскажите метки для случайного выбора 15 значений от данных тренировки с помощью сгенерированной MEX-функции и поддерева при сокращении уровня 1. Сравните метки от MEX-функции с предсказанными predict.

rng('default'); % For reproducibility
Xnew = datasample(meas,15);
[labelMEX,scoreMEX] = mypredictTree_mex(Xnew,MdlName,'Subtrees',1);
[labelPREDICT,scorePREDICT] = predict(Mdl,Xnew,'Subtrees',1);
labelPREDICT
labelPREDICT = 15x10 char array
    'virginica '
    'virginica '
    'setosa    '
    'virginica '
    'versicolor'
    'setosa    '
    'setosa    '
    'versicolor'
    'virginica '
    'virginica '
    'setosa    '
    'virginica '
    'virginica '
    'versicolor'
    'virginica '

labelMEX
labelMEX = 15x1 cell array
    {'virginica' }
    {'virginica' }
    {'setosa'    }
    {'virginica' }
    {'versicolor'}
    {'setosa'    }
    {'setosa'    }
    {'versicolor'}
    {'virginica' }
    {'virginica' }
    {'setosa'    }
    {'virginica' }
    {'virginica' }
    {'versicolor'}
    {'virginica' }

Предсказанные метки совпадают с метками MEX-функции за исключением типа данных. Когда типом данных ответа является char, и codegen не может решить, что значение Subtrees является скаляром, затем вывод от сгенерированного кода является массивом ячеек из символьных векторов.

Для сравнения можно преобразовать labelsPREDICT в массив ячеек и использовать isequal.

cell_labelPREDICT = cellstr(labelPREDICT);
verifyLabel = isequal(labelMEX,cell_labelPREDICT)
verifyLabel = logical
   1

isequal возвращает логическую единицу (true), что означает, что все входные параметры равны.

Сравните вторые выходные параметры также. scoreMex может включать различия в округлении по сравнению с scorePREDICT. В этом случае сравните scoreMEX и scorePREDICT, позволив маленький допуск.

find(abs(scorePREDICT-scoreMEX) > 1e-8)
ans =

  0x1 empty double column vector

find возвращает пустой вектор, если поэлементная абсолютная разность между scorePREDICT и scoreMEX не больше, чем заданный допуск 1e-8. Сравнение подтверждает, что scorePREDICT и scoreMEX равны в допуске 1e–8.

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

| | | | |

Похожие темы