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

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

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

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

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

load fisheriris
species = char(species);

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

Mdl = fitctree(meas,species);

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

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

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

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

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

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

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

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

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

Вы можете разрешить дополнительные аргументы пары "имя-значение", указав вараргин как входной параметр. Для получения дополнительной информации смотрите Генерацию кода для списков аргументов переменной длины (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 = loadLearnerForCoder(savedmdl);
[label,score,node,cnum] = predict(CompactMdl,x,varargin{:});
end

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

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

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

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

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

coder.Constant(v)

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

Использование coder.typeof (MATLAB Coder) для задания входов переменного размера.

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 (логический 1) означает, что соответствующая размерность имеет переменный размер; значение false (логический 0) означает, что соответствующая размерность имеет фиксированный размер.

Функция точки входа 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
Code generation successful.

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

The 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
    {'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 возвращает логический 1 (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.

См. также

| | | (MATLAB CODER) | (MATLAB Coder) | (MATLAB Coder)

Похожие темы