Esta página aún no se ha traducido para esta versión. Puede ver la versión más reciente de esta página en inglés.

Objetos de sistema para clasificación y generación de código

En este ejemplo se muestra cómo generar código C a partir de un objeto de sistema de MATLAB®™ que clasifica imágenes de dígitos mediante un modelo de clasificación entrenado. Este ejemplo también muestra cómo utilizar el objeto System para la clasificación en Simulink®. La ventaja de utilizar objetos del sistema sobre la función MATLAB es que los objetos del sistema son más apropiados para procesar grandes cantidades de datos de streaming. Para obtener más información, consulte.¿Qué son los objetos del sistema? (MATLAB)

Este ejemplo se basa en, que es un flujo de trabajo alternativo a.Generación de código para clasificación de imágenesDigit Classification Using HOG Features (Computer Vision Toolbox)

Cargar datos

Cargue el.digitimages

load digitimages.mat

es una matriz de enteros de 28 por 28 por 3000.imagesuint16 Cada página es una imagen ráster de un dígito. Cada elemento es una intensidad de píxel. Las etiquetas correspondientes están en el vector numérico 3000-by-1.Y Para obtener más información, escriba en la línea de comandos.Description

Almacene el número de observaciones y el número de variables predictoras. Cree una partición de datos que especifique que se mantenga el 20% de los datos. Extraiga los índices de entrenamiento y de conjunto de pruebas de la partición de datos.

rng(1); % For reproducibility n = size(images,3); p = numel(images(:,:,1)); cvp = cvpartition(n,'Holdout',0.20); idxTrn = training(cvp); idxTest = test(cvp);

Reescalar datos

Vuelva a escalar las intensidades de píxel para que se extienden en el intervalo [0,1] dentro de cada imagen. Específicamente, supongamos que

<math display="block">
<mrow>
<msub>
<mrow>
<mi>p</mi>
</mrow>
<mrow>
<mi>i</mi>
<mi>j</mi>
</mrow>
</msub>
</mrow>
</math>
es la intensidad de píxeles
<math display="block">
<mrow>
<mi>j</mi>
</mrow>
</math>
dentro de la imagen
<math display="block">
<mrow>
<mi>i</mi>
</mrow>
</math>
. Para la imagen
<math display="block">
<mrow>
<mi>i</mi>
</mrow>
</math>
, reescalar todas sus intensidades de píxeles utilizando esta fórmula:

<math display="block">
<mrow>
<msub>
<mrow>
<munderover accent="true">
<mrow>
<mi>p</mi>
</mrow>
<mrow></mrow>
<mrow>
<mo>ˆ</mo>
</mrow>
</munderover>
</mrow>
<mrow>
<mi>i</mi>
<mi>j</mi>
</mrow>
</msub>
<mo>=</mo>
<mfrac>
<mrow>
<msub>
<mrow>
<mi>p</mi>
</mrow>
<mrow>
<mi>i</mi>
<mi>j</mi>
</mrow>
</msub>
<mo>-</mo>
<munder>
<mrow>
<mi mathvariant="normal">min</mi>
</mrow>
<mrow>
<mi>j</mi>
</mrow>
</munder>
<mo stretchy="false">(</mo>
<msub>
<mrow>
<mi>p</mi>
</mrow>
<mrow>
<mi>i</mi>
<mi>j</mi>
</mrow>
</msub>
<mo stretchy="false">)</mo>
</mrow>
<mrow>
<munder>
<mrow>
<mi mathvariant="normal">max</mi>
</mrow>
<mrow>
<mi>j</mi>
</mrow>
</munder>
<mo stretchy="false">(</mo>
<msub>
<mrow>
<mi>p</mi>
</mrow>
<mrow>
<mi>i</mi>
<mi>j</mi>
</mrow>
</msub>
<mo stretchy="false">)</mo>
<mo>-</mo>
<munder>
<mrow>
<mi mathvariant="normal">min</mi>
</mrow>
<mrow>
<mi>j</mi>
</mrow>
</munder>
<mo stretchy="false">(</mo>
<msub>
<mrow>
<mi>p</mi>
</mrow>
<mrow>
<mi>i</mi>
<mi>j</mi>
</mrow>
</msub>
<mo stretchy="false">)</mo>
</mrow>
</mfrac>
<mo>.</mo>
</mrow>
</math>

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

Remodele los datos

Para la generación de código, los Datos predictores para el entrenamiento deben estar en una tabla de variables numéricas o una matriz numérica.

Cambie la forma de los datos a una matriz, de forma que las variables predictoras correspondan a columnas e imágenes que correspondan a filas. Debido a que toma elementos en la columna, transponer su resultado.reshape

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

Entrenar y optimizar modelos de clasificación

Valide de forma cruzada un modelo ECOC de estudiantes binarios de SVM y un bosque aleatorio basado en las observaciones de formación. Utilice la validación cruzada de 5 veces.

Para el modelo ECOC, especifique la estandarización de predictores y optimice el error de clasificación sobre el diseño de codificación ECOC y la restricción de caja SVM. Explore todas las combinaciones de estos valores:

  • Para el diseño de codificación ECOC, utilice uno contra uno y uno contra todos.

  • Para la restricción de cuadro SVM, utilice tres valores espaciados logarmicamente de 0,1 a 100 cada uno. Para todos los modelos, almacene las tasas de clasificación errónea de 5 veces con validación cruzada.

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 

Para el bosque aleatorio, puede variar el número máximo de divisiones utilizando los valores de la secuencia

<math display="block">
<mrow>
<mo stretchy="false">{</mo>
<msup>
<mrow>
<mn>3</mn>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>,</mo>
<msup>
<mrow>
<mn>3</mn>
</mrow>
<mrow>
<mn>3</mn>
</mrow>
</msup>
<mo>,</mo>
<mo>.</mo>
<mo>.</mo>
<mo>.</mo>
<mo>,</mo>
<msup>
<mrow>
<mn>3</mn>
</mrow>
<mrow>
<mi>m</mi>
</mrow>
</msup>
<mo stretchy="false">}</mo>
</mrow>
</math>
. m es tal que
<math display="block">
<mrow>
<msup>
<mrow>
<mn>3</mn>
</mrow>
<mrow>
<mi>m</mi>
</mrow>
</msup>
</mrow>
</math>
no es mayor que-1.n Para reproducir selecciones de predictor aleatorias, especifique.'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.323750 for model using 9 as the maximum number of splits cvLossRF = 0.198333 for model using 27 as the maximum number of splits cvLossRF = 0.075417 for model using 81 as the maximum number of splits cvLossRF = 0.017083 for model using 243 as the maximum number of splits cvLossRF = 0.012083 for model using 729 as the maximum number of splits cvLossRF = 0.012083 for model using 2187 as the maximum number of splits 

Para cada algoritmo, determine los índices de hiperparámetros que producen las tasas mínimas de clasificación errónea.

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.0121 
linIdx = find(cvLossRF == minCVLossRF,1); [bestI,bestJ] = ind2sub(size(cvLossRF),linIdx); bestMNS = maxNumSplits(bestI)
bestMNS = 729 

El bosque aleatorio logra una tasa de clasificación errónea con validación cruzada más pequeña.

Entrenar un modelo ECOC y un bosque aleatorio utilizando los datos de entrenamiento. Proporcione las combinaciones de hiperparámetros óptimas.

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

Cree una variable para las imágenes de muestra de prueba y utilice los modelos entrenados para predecir las etiquetas de muestra de prueba.

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

Guardar modelo de clasificación en disco

y son modelos de clasificación predictiva, pero debe prepararlos para la generación de código.MdlECOCMdlRF Guardar y en su carpeta de trabajo actual utilizando.MdlECOCMdlRFsaveCompactModel

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

Crear objeto de sistema para predicción

Cree dos objetos System, uno para el modelo ECOC y el otro para el bosque aleatorio, que:

  • Cargue el modelo entrenado previamente guardado mediante.loadCompactModel

  • Hacer predicciones secuenciales por el método.step

  • Exigir cambios de tamaño a los datos de entrada.

  • Aplique una salida escalar de doble precisión.

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 = loadCompactModel('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 = loadCompactModel('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 

Si pulsa el botón situado en la sección superior derecha de esta página y abre este ejemplo en MATLAB®, MATLAB® abre la carpeta de ejemplo.Note: Esta carpeta incluye los archivos usados en este ejemplo.

Para los requisitos básicos del objeto System, consulte.Definir objetos básicos del sistema (MATLAB)

Definir funciones de predicción para generación de código

Defina dos funciones de MATLAB llamadas y.predictDigitECOCSO.mpredictDigitRFSO.m Las funciones:

  • Incluya la Directiva de generación de código.%#codegen

  • Acepte datos de imagen proporcionales a.X

  • Predecir etiquetas utilizando los objetos System y, respectivamente.ECOCClassifierRFClassifier

  • Devuelva las etiquetas pronosticadas.

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 

Compile la función MATLAB en el archivo MEX

Compile la función de predicción que logra una mejor precisión de la muestra de prueba a un archivo MEX mediante el uso de.codegen Especifique las imágenes del conjunto de pruebas mediante el argumento.-args

if(minCVLossECOC <= minCVLossRF)     codegen predictDigitECOCSO -args testImages     else        codegen predictDigitRFSO -args testImages end

Verifique que el archivo MEX generado produzca las mismas predicciones que la función 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

es, lo que indica que las predicciones realizadas por el archivo MEX generado y la función MATLAB correspondiente son las mismas.verifyMEX1

Predecir etiquetas mediante el uso de objetos de sistema en Simulink

Cree un archivo de vídeo que muestre las imágenes de conjunto de pruebas fotograma a fotograma.

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

Defina una función llamada que convierta las imágenes RGB a escala de grises y, a continuación, escale las intensidades de píxel resultantes para que sus valores estén en el intervalo [0,1].scalePixelIntensities.m

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 

Cargue el modelo® de Simulink.slexClassifyAndDisplayDigitImages.slx

SimMdlName = 'slexClassifyAndDisplayDigitImages'; open_system(SimMdlName);

La figura muestra el modelo de® de Simulink. Al principio de la simulación, el bloque from multimedia File carga el archivo de vídeo de las imágenes del conjunto de pruebas. Para cada imagen del vídeo:

  • El bloque from multimedia File convierte y genera la imagen en una matriz de intensidades de píxel de 28 por 28.

  • El bloque datos de proceso escala las intensidades de píxel utilizando y genera un vector de 1 por 784 de intensidades escaladas.scalePixelIntensities.m

  • El bloque subsistema de clasificación predice las etiquetas dadas los datos de imagen procesados. El bloque elige el objeto System que minimiza el error de clasificación. En este caso, el bloque elige el bosque aleatorio. El bloque genera una etiqueta escalar de doble precisión.

  • El bloque conversión de tipo de datos convierte la etiqueta en un escalar.int32

  • El bloque insertar texto incrusta la etiqueta pronosticada en el fotograma actual.

  • El bloque para visualizar vídeo muestra el fotograma anotado.

Simular el modelo.

sim(SimMdlName)

El modelo muestra todas las imágenes de conjunto de pruebas 600 y su predicción rápidamente. La última imagen permanece en la pantalla de vídeo. Puede generar predicciones y mostrarlas con las imágenes correspondientes una a una haciendo clic en el botón en su lugar.Step Forward

Si también tiene una licencia de Simulink® Coder™, puede generar código C desde Simulink® o desde la línea de comandos.slexClassifyAndDisplayDigitImages.slxrtwbuild Para obtener más información, consulte.Generate C Code for a Model (Simulink Coder)

Consulte también

| | |

Temas relacionados