Volver a entrenar redes neuronales para clasificar nuevas imágenes
En este ejemplo se muestra cómo volver a entrenar una red neuronal SqueezeNet preentrenada para clasificar una nueva colección de imágenes.
Puede volver a entrenar redes preentrenadas para nuevos conjuntos de datos adaptando la red neuronal de forma que se ajuste a la nueva tarea y usando sus pesos aprendidos como punto de partida. Para adaptar la red a los nuevos datos, reemplace las últimas capas (conocidas como cabeza de red) de forma que la red neuronal genere puntuaciones de predicción para cada una de las clases de la nueva tarea.
Existen varias técnicas para volver a entrenar una red neuronal.
Nuevo entrenamiento desde cero: entrene la red neuronal desde cero usando la misma arquitectura de red.
Transferencia del aprendizaje: congele los pesos de la red neuronal preentrenada y vuelva a entrenar solo la cabeza de red.
Ajuste: vuelva a entrenar algunos o todos los pesos de la red neuronal y, opcionalmente, ralentice el entrenamiento de los pesos preentrenados.
Realizar la transferencia del aprendizaje y el ajuste de una red neuronal preentrenada suele requerir menos datos, ser mucho más rápido y fácil que entrenar una red neuronal desde cero.
Este diagrama ilustra el proceso general de volver a entrenar una red neuronal.
En este ejemplo se vuelve a entrenar una red neuronal SqueezeNet usando transferencia del aprendizaje. Esta red se ha entrenado con más de un millón de imágenes y puede clasificarlas en 1000 categorías de objetos (como teclado, taza de café, lápiz y muchos animales). La red ha aprendido representaciones ricas en características para una amplia gama de imágenes. La red toma una imagen como entrada y produce como salida una puntuación de predicción para cada una de estas clases.
Cargar los datos de entrenamiento
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. 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)
Visualice los nombres de las clases y el número de clases.
classNames = categories(imds.Labels)
classNames = 5×1 cell
{'MathWorks Cap' }
{'MathWorks Cube' }
{'MathWorks Playing Cards'}
{'MathWorks Screwdriver' }
{'MathWorks Torch' }
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 tres nuevos almacenes de datos.
[imdsTrain,imdsValidation,imdsTest] = splitEachLabel(imds,0.7,0.15,"randomized");
Cargar una red preentrenada
Para adaptar una red neuronal preentrenada a una nueva tarea, reemplace las últimas capas (la cabeza de red) de forma que genere puntuaciones de predicción para cada una de las clases de la nueva tarea. Este diagrama describe la arquitectura de una red neuronal que realiza predicciones para clases e ilustra cómo editar la red para que genere predicciones para clases.
Cargue una red neuronal SqueezeNet preentrenada en el área de trabajo usando la función imagePretrainedNetwork
. A fin de devolver una red neuronal lista para volver a ser entrenada para los datos nuevos, especifique el número de clases. Cuando especifica el número de clases, la función imagePretrainedNetwork
adapta la red neuronal de forma que genere puntuaciones de predicción para cada número de clases especificado.
Puede probar otras redes preentrenadas. Deep Learning Toolbox™ proporciona varias redes preentrenadas que tienen distintos tamaños, velocidades y precisiones. Estas redes adicionales normalmente requieren un paquete de soporte. Si no ha instalado el paquete de soporte para una red seleccionada, la función proporciona un enlace de descarga. Para obtener más información, consulte Redes neuronales profundas preentrenadas.
net = imagePretrainedNetwork(
"squeezenet",NumClasses=numClasses)
net = dlnetwork with properties: Layers: [68×1 nnet.cnn.layer.Layer] Connections: [75×2 table] Learnables: [52×3 table] State: [0×3 table] InputNames: {'data'} OutputNames: {'prob_flatten'} Initialized: 1 View summary with summary.
Visualice la arquitectura de red usando la función analyzeNetwork
. Tome nota de la capa de entrada y la última capa con parámetros que se pueden aprender.
analyzeNetwork(net)
La capa de entrada muestra el tamaño de entrada de la red neuronal.
Obtenga el tamaño de entrada de la red neuronal de la capa de entrada. La función networkInputSize
, incluida en este ejemplo como un archivo de soporte, extrae el tamaño de entrada de la capa de entrada. Para acceder a esta función, abra el ejemplo como un script en vivo.
inputSize = networkInputSize(net)
inputSize = 1×3
227 227 3
La capa que se puede aprender de la cabeza de red (la última capa con parámetros que se pueden aprender) requiere un nuevo entrenamiento. Esta suele ser una capa totalmente conectada o una capa convolucional con un tamaño de salida que coincide con el número de clases.
La función networkHead
, incluida en este ejemplo como un archivo de soporte, devuelve la capa y los nombres de los parámetros que se pueden aprender de la capa que se puede aprender en la cabeza de red. Para acceder a esta función, abra el ejemplo como un script en vivo.
[layerName,learnableNames] = networkHead(net)
layerName = "conv10"
learnableNames = 2×1 string
"conv10/Weights"
"conv10/Bias"
Para la transferencia del aprendizaje, puede congelar los pesos de las capas anteriores de la red estableciendo las tasas de aprendizaje de esas capas en 0. Durante el entrenamiento, la función trainnet
no actualiza los parámetros de estas capas congeladas. Dado que la función no calcula los gradientes de las capas congeladas, congelar los pesos puede acelerar significativamente el entrenamiento de redes. Para conjuntos de datos pequeños, congelar las capas de red evita un sobreajuste de estas capas al nuevo conjunto de datos.
Congele los pesos de la red, manteniendo la última capa que se puede aprender sin congelar, mediante la función freezeNetwork
, incluida en este ejemplo como archivo de soporte. Para acceder a esta función, abra el ejemplo como un script en vivo.
net = freezeNetwork(net,LayerNamesToIgnore=layerName);
Consejo: como alternativa a congelar los pesos de las capas anteriores, puede reducir el nivel de actualizaciones de estas capas y aumentar el nivel de actualizaciones de la nueva cabeza de clasificación. Esto se conoce como ajuste. Para hacerlo, aumente los factores de tasa de aprendizaje de los parámetros que se pueden aprender en la nueva cabeza de clasificación usando la función setLearnRateFactor
. Luego, disminuya la tasa de aprendizaje global utilizando el argumento InitialLearnRate
de trainingOptions
.
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.
Para este ejemplo, use las opciones siguientes:
Entrenar usando el optimizador Adam.
Valide la red usando los datos de validación cada cinco iteraciones. Para conjuntos de datos más grandes, para impedir que la validación ralentice el entrenamiento, aumente este valor.
Muestre el progreso del entrenamiento en una gráfica y monitorice la métrica de precisión.
Deshabilite la salida detallada.
options = trainingOptions("adam", ... ValidationData=augimdsValidation, ... ValidationFrequency=5, ... Plots="training-progress", ... Metrics="accuracy", ... Verbose=false);
Entrenar redes neuronales
Entrene la red neuronal con la función trainnet
. Para la 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(augimdsTrain,net,"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)
Evalúe la precisión de clasificación para los datos de prueba. La precisión es el porcentaje de predicciones correctas.
acc = mean(TTest==YTest)
acc = 1
Hacer predicciones con nuevos datos
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
. Si hay disponible para el cálculo una GPU compatible, convierta primero los datos a un objeto 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
imagePretrainedNetwork
| dlnetwork
| trainingOptions
| trainnet