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) + ")")