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

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

Для более подробных примеров рабочего процесса генерации кода смотрите Генерацию кода для Прогноза Модели Машинного обучения в Командной строке и Генерацию кода для Прогноза Модели Машинного обучения Используя Приложение 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.

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

Можно допускать дополнительные аргументы пары "имя-значение" путем определения 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 = loadLearnerForCoder(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.

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

| | | | |

Похожие темы