Main Content

Preparar una red para la transferencia del aprendizaje mediante Deep Network Designer

Este ejemplo muestra cómo preparar una red para la transferencia del aprendizaje de manera interactiva mediante la app Deep Network Designer.

La transferencia del aprendizaje es un proceso que consiste en elegir una red de deep learning preentrenada y ajustarla para aprender una tarea nueva. Utilizar la transferencia del aprendizaje es normalmente un proceso más rápido y sencillo que entrenar una red desde cero. Puede transferir de forma rápida las características aprendidas a una nueva tarea con menos cantidad de datos.

Extraer datos

Extraiga el conjunto de datos MathWorks Merch. Se trata de un conjunto de datos pequeño que contiene 75 imágenes de artículos promocionales de MathWorks que pertenecen a cinco clases distintas (gorra, cubo, naipes, destornillador y linterna). Los datos están dispuestos de manera que las imágenes estén en subcarpetas que corresponden a estas cinco clases.

folderName = "MerchData";
unzip("MerchData.zip",folderName);

Cree un almacén de datos de imágenes. Un almacén de datos de imágenes permite almacenar grandes colecciones de datos de imágenes, incluidos los que no caben en la memoria, y leer eficazmente lotes de imágenes durante el entrenamiento de una red neuronal. Especifique la carpeta con las imágenes extraídas e indique que los nombres de las subcarpetas corresponden a las etiquetas de las imágenes.

imds = imageDatastore(folderName, ...
    IncludeSubfolders=true, ...
    LabelSource="foldernames");

Visualice algunas imágenes de muestra.

numImages = numel(imds.Labels);
idx = randperm(numImages,16);
I = imtile(imds,Frames=idx);
figure
imshow(I)

Extraiga los nombres de las clases y el número de clases.

classNames = categories(imds.Labels);
numClasses = numel(classNames)
numClasses = 5

Divida los datos en conjuntos de datos de entrenamiento, validación y prueba. Utilice el 70% de las imágenes para el entrenamiento, el 15% para la validación y el 15% para la prueba. La función splitEachLabel divide el almacén de datos de imágenes en dos nuevos almacenes de datos.

[imdsTrain,imdsValidation,imdsTest] = splitEachLabel(imds,0.7,0.15,0.15,"randomized");

Seleccionar una red preentrenada

Para abrir Deep Network Designer, en la pestaña Apps, en Machine Learning and Deep Learning, haga clic en el icono de la app. Como alternativa, puede abrir la app desde la línea de comandos:

deepNetworkDesigner

Deep Network Designer proporciona una selección de redes de clasificación de imágenes que han aprendido representaciones ricas en características adecuadas para una amplia gama de imágenes. La transferencia del aprendizaje funciona mejor si las imágenes son similares a las imágenes utilizadas originalmente para entrenar la red. Si sus imágenes de entrenamiento son imágenes naturales como las de la base de datos ImageNet, cualquiera de las redes preentrenadas es adecuada. Para obtener una lista de redes disponibles y aprender a compararlas, consulte Redes neuronales profundas preentrenadas.

Si sus datos son muy diferentes a los datos de ImageNet (por ejemplo, si tiene imágenes diminutas, espectrogramas o datos que no sean imágenes) será mejor entrenar una nueva red. Para ver un ejemplo de cómo entrenar una red desde cero, consulte Get Started with Time Series Forecasting.

SqueezeNet no requiere otro paquete de soporte. Para otras redes preentrenadas, si no ha instalado los paquetes de soporte requeridos, la app ofrece la opción Install.

Seleccione SqueezeNet de la lista de redes preentrenadas y haga clic en Open.

Explorar una red

Deep Network Designer muestra una vista alejada de la totalidad de la red en el panel Designer.

Explore la gráfica de red. Para ampliarla con el ratón, utilice Ctrl + la rueda de desplazamiento. Para desplazarse, utilice las teclas de flecha o mantenga pulsada la rueda de desplazamiento y arrastre el ratón. Seleccione una capa para ver sus propiedades. Quite la selección de todas las capas para ver el resumen de la red en el panel Properties.

Seleccione la capa de entrada de imagen, 'input'. Puede ver que el tamaño de entrada para esta red es de 227 por 227 por 3 píxeles.

Guarde el tamaño de entrada en la variable inputSize.

inputSize = [227 227 3];

Preparar la red para el entrenamiento

Para usar una red preentrenada para la transferencia del aprendizaje, debe modificar el número de clases de forma que coincida con el nuevo conjunto de datos. En primer lugar, encuentre la última capa de aprendizaje de la red. En SqueezeNet, la última capa de aprendizaje es la última capa convolucional ('conv10'). Seleccione la capa 'conv10'. En la parte inferior del panel Properties, haga clic en Unlock Layer. En el cuadro de advertencia que aparece, haga clic en Unlock Anyway. Se desbloquearán las propiedades de la capa para que pueda adaptarlas a su nueva tarea.

Antes de la versión R2023b: Para adaptar la red a los nuevos datos, debe remplazar las capas en vez de desbloquearlas. En la nueva capa convolucional 2D, establezca FilterSize en [1 1].

La propiedad NumFilters define el número de clases para los problemas de clasificación. Cambie NumFilters por el número de clases de los nuevos datos (5 en este ejemplo).

Modifique las tasas de aprendizaje para aprender más rápido en la nueva capa que en las capas transferidas estableciendo los valores WeightLearnRateFactor y BiasLearnRateFactor en 10.

Comprobar la red

Para comprobar que la red está preparada para el entrenamiento, haga clic en Analyze. Dado que el analizador Deep Learning Network Analyzer no detecta ningún error o advertencia, la red está preparada para el entrenamiento. Para exportar la red, haga clic en Export. La app guarda la red en la variable net_1.

Preparar los datos para el entrenamiento

Las imágenes del almacén de datos pueden tener diferentes tamaños. Para cambiar automáticamente el tamaño de las imágenes de entrenamiento, utilice un almacén de datos de imágenes aumentado. El aumento de datos también ayuda a evitar que la red se sobreajuste y memorice los detalles exactos de las imágenes de entrenamiento. Especifique estas operaciones de aumento adicionales para realizar en las imágenes de entrenamiento: voltear aleatoriamente las imágenes de entrenamiento a lo largo del eje vertical y trasladarlas aleatoriamente hasta 30 píxeles horizontal y verticalmente.

pixelRange = [-30 30];

imageAugmenter = imageDataAugmenter( ...
    RandXReflection=true, ...
    RandXTranslation=pixelRange, ...
    RandYTranslation=pixelRange);

augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain, ...
    DataAugmentation=imageAugmenter);

Para cambiar automáticamente el tamaño de las imágenes de validación y prueba sin realizar más aumentos de datos, utilice un almacén de datos de imágenes aumentadas sin especificar ninguna operación adicional de preprocesamiento.

augimdsValidation = augmentedImageDatastore(inputSize(1:2),imdsValidation);
augimdsTest = augmentedImageDatastore(inputSize(1:2),imdsTest);

Especificar las opciones de entrenamiento

Especifique las opciones de entrenamiento. Para escoger entre las opciones se requiere un análisis empírico. Para explorar diferentes configuraciones de opciones de entrenamiento mediante la ejecución de experimentos, puede utilizar la app Experiment Manager.

  • Entrenar usando el optimizador Adam.

  • Para ralentizar el aprendizaje en las capas transferidas, establezca la tasa de aprendizaje inicial en un valor pequeño.

  • Especifique un número pequeño de épocas. Una época es un ciclo de entrenamiento completo en el conjunto total de datos de entrenamiento. Para la transferencia del aprendizaje, no es necesario entrenar durante tantas épocas.

  • Especifique los datos de validación y la frecuencia de validación para que la precisión de los datos de validación se calcule una vez por época.

  • Especifique el tamaño de minilote, es decir, cuántas imágenes se pueden utilizar en cada iteración. Para asegurarse de que la totalidad del conjunto de datos se utiliza durante cada época, establezca el tamaño de minilote para dividir el número de muestras de entrenamiento de manera uniforme.

  • Muestre el progreso del entrenamiento en una gráfica y monitorice la métrica de precisión.

  • Deshabilite la salida detallada.

options = trainingOptions("adam", ...
    InitialLearnRate=0.0001, ...
    MaxEpochs=8, ...
    ValidationData=imdsValidation, ...
    ValidationFrequency=5, ...
    MiniBatchSize=11, ...
    Plots="training-progress", ...
    Metrics="accuracy", ...
    Verbose=false);

Entrenar redes neuronales

Entrene la red neuronal con la función trainnet. Para las tareas de clasificación, utilice la pérdida de entropía cruzada. De forma predeterminada, la función trainnet usa una GPU en caso de que esté disponible. Para utilizar una GPU se requiere una licencia de Parallel Computing Toolbox™ y un dispositivo GPU compatible. Para obtener información sobre los dispositivos compatibles, consulte GPU Computing Requirements (Parallel Computing Toolbox). De lo contrario, la función trainnet usa la CPU. Para especificar el entorno de ejecución, utilice la opción de entrenamiento ExecutionEnvironment.

net = trainnet(imdsTrain,net_1,"crossentropy",options);

Probar una red neuronal

Clasifique las imágenes de prueba. Para hacer predicciones con varias observaciones, utilice la función minibatchpredict. Para convertir las puntuaciones de predicción en etiquetas, utilice la función scores2label. La función minibatchpredict usa automáticamente una GPU en caso de que esté disponible.

YTest = minibatchpredict(net,augimdsTest);
YTest = scores2label(YTest,classNames);

Visualice la precisión de clasificación en una gráfica de confusión.

TTest = imdsTest.Labels;
figure
confusionchart(TTest,YTest);

Hacer predicciones con nuevos datos

Clasifique una imagen. Lea una imagen de un archivo JPEG, cambie su tamaño y conviértala al tipo de datos single.

im = imread("MerchDataTest.jpg");
im = imresize(im,inputSize(1:2));
X = single(im);

Clasifique la imagen. Para hacer una predicción con una sola observación, utilice la función predict. Para usar una GPU, primero convierta los datos a gpuArray.

if canUseGPU
    X = gpuArray(X);
end
scores = predict(net,X);
[label,score] = scores2label(scores,classNames);

Muestre la imagen con la etiqueta predicha y la puntuación correspondiente.

figure
imshow(im)
title(string(label) + " (Score: " + gather(score) + ")")

Consulte también

Temas relacionados