Tutorial: Inspección visual automatizada mediante el aprendizaje de transferencia con la API Image Classification de ML.NET
Obtenga información sobre cómo entrenar un modelo de aprendizaje profundo personalizado mediante el aprendizaje de transferencia, un modelo TensorFlow previamente entrenado y la API Image Classification de ML.NET para clasificar las imágenes de superficies de hormigón como con grietas o sin grietas.
En este tutorial aprenderá a:
- Entender el problema
- Obtener información sobre la API Image Classification de ML.NET
- Comprender el modelo entrenado previamente
- Usar el aprendizaje de transferencia para entrenar un modelo de clasificación de imágenes de TensorFlow personalizado
- Clasificar imágenes con el modelo personalizado
Requisitos previos
Información general del ejemplo de transferencia de aprendizaje de clasificación de imágenes
Este ejemplo es una aplicación de consola de .NET Core de C# que clasifica imágenes mediante un modelo TensorFlow de aprendizaje profundo entrenado previamente. El código de este ejemplo se puede encontrar en el explorador ed ejemplos.
Entender el problema
La clasificación de imágenes es un problema de visión informática. La clasificación de imágenes toma una imagen como entrada y la categoriza en una clase prescrita. Los modelos de clasificación de imágenes se entrenan normalmente mediante el aprendizaje profundo y las redes neuronales. Consulte Aprendizaje profundo frente a aprendizaje automático para obtener más información.
A continuación se muestran algunos escenarios en los que la clasificación de imágenes es útil:
- Reconocimiento facial
- Detección de emociones
- Diagnóstico médico
- Detección de puntos de referencia
En este tutorial se entrena un modelo de clasificación de imágenes personalizado para realizar una inspección visual automatizada de los tableros de puente con el fin de identificar las estructuras dañadas por las grietas.
API Image Classification de ML.NET
ML.NET proporciona varias formas de realizar la clasificación de imágenes. En este tutorial se aplica el aprendizaje de transferencia mediante la API Image Classification. La API Image Classification utiliza TensorFlow.NET, una biblioteca de bajo nivel que proporciona enlaces de C# para la API C++ de TensorFlow.
¿Qué es el aprendizaje de transferencia?
El aprendizaje de transferencia aplica los conocimientos obtenidos de la resolución de un problema a otro problema relacionado.
Entrenar un modelo de aprendizaje profundo desde cero requiere establecer varios parámetros, una enorme cantidad de datos de entrenamiento etiquetados y una gran cantidad de recursos informáticos (cientos de horas de GPU). El uso de un modelo entrenado previamente, junto con el aprendizaje de transferencia, permite acceso directo al proceso de entrenamiento.
Proceso de entrenamiento
La API Image Classification inicia el proceso de entrenamiento mediante la carga de un modelo TensorFlow previamente entrenado. El proceso de entrenamiento consta de dos pasos:
- Fase de cuello de botella
- Fase de entrenamiento
Fase de cuello de botella
Durante la fase de cuello de botella, se carga el conjunto de imágenes de aprendizaje y los valores de píxeles se usan como entrada, o características, para las capas inmovilizadas del modelo previamente entrenado. Las capas inmovilizadas incluyen todas las capas de la red neuronal hasta la penúltima capa, que se conoce como capa de cuello de botella. Estas capas se denominan inmovilizadas porque en ellas no se producirá ningún aprendizaje y las operaciones son de paso a través. En estas capas inmovilizadas es donde se calculan los patrones de nivel inferior que ayudan a un modelo a diferenciar entre las distintas clases. Cuanto mayor sea el número de capas, más intensiva a nivel de computación será este paso. Afortunadamente, puesto que se trata de un cálculo que se realiza una sola vez, los resultados se pueden almacenar en caché y usar en ejecuciones posteriores cuando se experimente con parámetros distintos.
Fase de entrenamiento
Una vez calculados los valores de salida de la fase de cuello de botella, se usan como entrada para volver a entrenar la capa final del modelo. Este proceso es iterativo y se ejecuta durante el número de veces que especifican los parámetros del modelo. Durante cada ejecución, se evalúan la pérdida y la precisión. Después, se realizan los ajustes adecuados para mejorar el modelo con el objetivo de minimizar la pérdida y maximizar la precisión. Una vez finalizado el entrenamiento, se generan dos formatos del modelo. Uno de ellos es la versión .pb
del modelo y el otro es la versión serializada de ML.NET .zip
. Cuando se trabaja en entornos compatibles con ML.NET, se recomienda usar la versión .zip
del modelo. Sin embargo, en entornos en los que no se admite ML.NET, se tiene la opción de usar la versión .pb
.
Descripción del modelo entrenado previamente
El modelo previamente entrenado que se usa en este tutorial es la variante de capa 101 del modelo de Residual Network v2 (ResNet). El modelo original se ha entrenado para clasificar las imágenes en mil categorías. El modelo toma como entrada una imagen de tamaño 224 x 224 y genera las probabilidades de clase para cada una de las clases en las que se ha entrenado. Parte de este modelo se usa para entrenar un nuevo modelo mediante imágenes personalizadas con el fin de realizar predicciones entre dos clases.
Creación de una aplicación de consola
Ahora que tiene conocimientos generales del aprendizaje de transferencia y de la API Image Classification, es momento de compilar la aplicación.
Cree una aplicación de consola en C# llamada "DeepLearning_ImageClassification_Binary". Haga clic en el botón Next (Siguiente).
Seleccione .NET 6 como marco de trabajo que va a usarse. Haga clic en el botón Crear.
Instale el paquete NuGet Microsoft.ML:
Nota
En este ejemplo se usa la versión estable más reciente de los paquetes NuGet mencionados, a menos que se indique lo contrario.
- En el Explorador de soluciones, haga clic con el botón derecho en Administrar paquetes NuGet.
- Elija "nuget.org" como origen del paquete.
- Seleccione la pestaña Examinar.
- Active la casilla Incluir versión preliminar.
- Busque Microsoft.ML.
- Seleccione el botón Instalar.
- Seleccione el botón Aceptar en el cuadro de diálogo Vista previa de cambios y, a continuación, seleccione el botón Acepto del cuadro de diálogo Aceptación de la licencia en caso de que esté de acuerdo con los términos de licencia de los paquetes mostrados.
- Repita estos pasos para los paquetes NuGetMicrosoft.ML.Vision, SciSharp.TensorFlow.Redist versión 2.3.1 y Microsoft.ML.ImageAnalytics.
Preparar y entender los datos
Nota
Los conjuntos de valores de este tutorial están tomados del documento "SDNET2018: A concrete crack image dataset for machine learning applications" (2018) (SDNET2018: Un conjunto de datos de imágenes de hormigón descifradas para aplicaciones de aprendizaje automático) de Marc Maguire, Sattar Dorafshan y Robert J. Thomas. Examinar todos los conjuntos de datos. Documento 48. https://digitalcommons.usu.edu/all_datasets/48
SDNET2018 es un conjunto de datos de imágenes que contiene anotaciones para estructuras de hormigón con grietas y sin grietas (tableros de puente, muros y pavimento).
Los datos se organizan en tres subdirectorios:
- D contiene imágenes de tableros de puente
- P contiene imágenes de pavimentos
- W contiene imágenes de muros
Cada uno de estos subdirectorios contiene a su vez dos subdirectorios adicionales con prefijos:
- C es el prefijo usado para las superficies con grietas.
- U es el prefijo usado para las superficies sin grietas.
En este tutorial, solo se usan imágenes de tableros de puente.
- Descargue el conjunto de datos y descomprímalo.
- Cree un directorio llamado "recursos" en el proyecto para guardar los archivos del conjunto de datos.
- Copie los subdirectorios CD y UD del directorio descomprimido recientemente en el directorio recursos.
Creación de las clases de entrada y salida
Abra el archivo Program.cs y reemplace las instrucciones
using
existentes en la parte superior del archivo por las siguientes:using System; using System.Collections.Generic; using System.Linq; using System.IO; using Microsoft.ML; using static Microsoft.ML.DataOperationsCatalog; using Microsoft.ML.Vision;
Debajo de la clase
Program
en Program.cs, cree una clase llamadaImageData
. Esta clase se utiliza para representar los datos cargados inicialmente.class ImageData { public string ImagePath { get; set; } public string Label { get; set; } }
ImageData
contiene las propiedades siguientes:ImagePath
es la ruta de acceso completa donde se almacena la imagen.Label
es la categoría a la que pertenece la imagen. Este es el valor que se va a predecir.
Cree clases para los datos de entrada y salida.
Debajo de la clase
ImageData
, defina el esquema de los datos de entrada en una nueva clase llamadaModelInput
.class ModelInput { public byte[] Image { get; set; } public UInt32 LabelAsKey { get; set; } public string ImagePath { get; set; } public string Label { get; set; } }
ModelInput
contiene las propiedades siguientes:Image
es la representaciónbyte[]
de la imagen. El modelo espera que los datos de la imagen sean de este tipo para el entrenamiento.LabelAsKey
es la representación numérica deLabel
.ImagePath
es la ruta de acceso completa donde se almacena la imagen.Label
es la categoría a la que pertenece la imagen. Este es el valor que se va a predecir.
Solo se usan
Image
yLabelAsKey
para entrenar el modelo y hacer predicciones. Las propiedadesImagePath
yLabel
se conservan por comodidad para tener acceso al nombre y categoría del archivo de imagen original.Después, debajo de la clase
ModelInput
, defina el esquema de los datos de salida en una nueva clase llamadaModelOutput
.class ModelOutput { public string ImagePath { get; set; } public string Label { get; set; } public string PredictedLabel { get; set; } }
ModelOutput
contiene las propiedades siguientes:ImagePath
es la ruta de acceso completa donde se almacena la imagen.Label
es la categoría original a la que pertenece la imagen. Este es el valor que se va a predecir.PredictedLabel
es el valor que predice el modelo.
De forma similar a
ModelInput
, solo se requierePredictedLabel
para realizar predicciones, ya que contiene la predicción que realiza el modelo. Las propiedadesImagePath
yLabel
se conservan por comodidad para tener acceso al nombre y categoría del archivo de imagen original.
Creación del directorio del área de trabajo
Cuando los datos de entrenamiento y validación no cambian a menudo, se recomienda almacenar en caché los valores de cuello de botella calculados para las ejecuciones posteriores.
- En el proyecto, cree un directorio llamado workspace para almacenar los valores de cuello de botella calculados y la versión
.pb
del modelo.
Definición de rutas de acceso e inicialización de variables
Debajo de las instrucciones using, defina la ubicación de los recursos, los valores de cuello de botella calculados y la versión
.pb
del modelo.var projectDirectory = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "../../../")); var workspaceRelativePath = Path.Combine(projectDirectory, "workspace"); var assetsRelativePath = Path.Combine(projectDirectory, "assets");
Inicialice la variable
mlContext
con una instancia nueva de MLContext.MLContext mlContext = new MLContext();
La clase MLContext es un punto de partida para todas las operaciones de ML.NET. Al inicializar mlContext se crea un entorno de ML.NET que se puede compartir entre los objetos del flujo de trabajo de creación de modelos. Como concepto, se parece a
DbContext
en Entity Framework.
Carga de los datos
Creación de un método de utilidad de carga de datos
Las imágenes se almacenan en dos subdirectorios. Antes de cargar los datos, se debe dar formato a una lista de objetos de ImageData
. Para ello, llame al método LoadImagesFromDirectory
.
IEnumerable<ImageData> LoadImagesFromDirectory(string folder, bool useFolderNameAsLabel = true)
{
}
En
LoadImagesFromDirectory
, agregue el código siguiente para obtener todas las rutas de acceso de archivo de los subdirectorios:var files = Directory.GetFiles(folder, "*", searchOption: SearchOption.AllDirectories);
Luego, recorra en iteración cada uno de los archivos mediante una instrucción
foreach
.foreach (var file in files) { }
En la instrucción
foreach
, compruebe que se admiten las extensiones de archivo. La API Image Classification admite formatos JPEG y PNG.if ((Path.GetExtension(file) != ".jpg") && (Path.GetExtension(file) != ".png")) continue;
Después, obtenga la etiqueta del archivo. Si el parámetro
useFolderNameAsLabel
está establecido entrue
, el directorio principal donde se guarda el archivo se usa como etiqueta. De lo contrario, espera que la etiqueta sea un prefijo del nombre de archivo o el propio nombre de archivo.var label = Path.GetFileName(file); if (useFolderNameAsLabel) label = Directory.GetParent(file).Name; else { for (int index = 0; index < label.Length; index++) { if (!char.IsLetter(label[index])) { label = label.Substring(0, index); break; } } }
Por último, cree una nueva instancia de
ModelInput
.yield return new ImageData() { ImagePath = file, Label = label };
Preparar los datos
Llame al método de utilidad
LoadImagesFromDirectory
, para obtener la lista de imágenes que se usan para el entrenamiento después de la inicialización de la variablemlContext
.IEnumerable<ImageData> images = LoadImagesFromDirectory(folder: assetsRelativePath, useFolderNameAsLabel: true);
Luego, cargue las imágenes en un elemento
IDataView
con el métodoLoadFromEnumerable
.IDataView imageData = mlContext.Data.LoadFromEnumerable(images);
Los datos se cargan en el orden en que se han leído desde los directorios. Para equilibrar los datos, ordénelos aleatoriamente mediante el método
ShuffleRows
.IDataView shuffledData = mlContext.Data.ShuffleRows(imageData);
Los modelos de Machine Learning esperan que la entrada esté en formato numérico. Por lo tanto, es necesario realizar algún procesamiento previo en los datos antes del entrenamiento. Cree un elemento
EstimatorChain
formado por las transformacionesMapValueToKey
yLoadRawImageBytes
. La transformaciónMapValueToKey
toma el valor de categoría en la columnaLabel
, lo convierte en un valorKeyType
numérico y lo almacena en una nueva columna llamadaLabelAsKey
.LoadImages
toma los valores de la columnaImagePath
, junto con el parámetroimageFolder
, con el fin de cargar las imágenes para el entrenamiento.var preprocessingPipeline = mlContext.Transforms.Conversion.MapValueToKey( inputColumnName: "Label", outputColumnName: "LabelAsKey") .Append(mlContext.Transforms.LoadRawImageBytes( outputColumnName: "Image", imageFolder: assetsRelativePath, inputColumnName: "ImagePath"));
Use el método
Fit
para aplicar los datos apreprocessingPipeline
EstimatorChain
seguido del métodoTransform
, que devuelve un elementoIDataView
que contiene los datos procesados previamente.IDataView preProcessedData = preprocessingPipeline .Fit(shuffledData) .Transform(shuffledData);
Para entrenar un modelo, es importante tener un conjunto de datos de entrenamiento, así como un conjunto de datos de validación. El modelo se entrena en el conjunto de entrenamiento. La calidad de las predicciones en los datos no vistos la mide el rendimiento en el conjunto de validación. En función de los resultados de ese rendimiento, el modelo realiza ajustes sobre lo que ha aprendido en un esfuerzo por mejorar. El conjunto de validación puede proceder de dividir el conjunto de datos original o de otro origen que ya se haya reservado para esta finalidad. En este caso, el conjunto de datos procesado previamente se divide en conjuntos de entrenamiento, validación y pruebas.
TrainTestData trainSplit = mlContext.Data.TrainTestSplit(data: preProcessedData, testFraction: 0.3); TrainTestData validationTestSplit = mlContext.Data.TrainTestSplit(trainSplit.TestSet);
En el ejemplo de código anterior se realizan dos divisiones. En primer lugar, los datos procesados previamente se dividen y el 70 % de estos se usa para el entrenamiento, mientras que el 30 % restante se utiliza para la validación. Después, 30 % perteneciente al conjunto de validación se divide en conjuntos de validación y pruebas, donde el 90 % se usa para la validación y el 10 % se usa para las pruebas.
Una manera de pensar en la finalidad de estas particiones de datos es hacer un examen. Al estudiar para un examen, se revisan las notas, libros u otros recursos para obtener una idea sobre los conceptos que hay que preparar para el examen. Esto es para lo que sirve el conjunto de entrenamiento. Después, se puede realizar un examen ficticio para poner a prueba los conocimientos. Aquí es donde el conjunto de validación es práctico. Se quiere comprobar si se tiene una idea correcta de los conceptos antes de realizar el examen real. En función de estos resultados, tome nota de lo que no haya acertado o de lo que no haya entendido bien e incorpore los cambios a medida que repasa para el examen real. Por último, realice el examen. Esto es para lo que se usa el conjunto de prueba. Nunca ha visto las preguntas que aparecen en el examen y ahora puede usar lo que ha aprendido a partir del entrenamiento y la validación para aplicar sus conocimientos a la tarea que nos ocupa.
Asigne a las particiones sus respectivos valores para los datos de entrenamiento, validación y prueba.
IDataView trainSet = trainSplit.TrainSet; IDataView validationSet = validationTestSplit.TrainSet; IDataView testSet = validationTestSplit.TestSet;
Definición de la canalización de entrenamiento
El entrenamiento del modelo consta de un par de pasos. En primer lugar, se usa la API Image Classification para entrenar el modelo. Luego, las etiquetas codificadas de la columna PredictedLabel
se convierten de nuevo a su valor de categoría original mediante la transformación MapKeyToValue
.
Cree una variable para almacenar un conjunto de parámetros obligatorios y opcionales para un ImageClassificationTrainer.
var classifierOptions = new ImageClassificationTrainer.Options() { FeatureColumnName = "Image", LabelColumnName = "LabelAsKey", ValidationSet = validationSet, Arch = ImageClassificationTrainer.Architecture.ResnetV2101, MetricsCallback = (metrics) => Console.WriteLine(metrics), TestOnTrainSet = false, ReuseTrainSetBottleneckCachedValues = true, ReuseValidationSetBottleneckCachedValues = true };
ImageClassificationTrainer admite varios parámetros opcionales:
FeatureColumnName
es la columna que se utiliza como entrada del modelo.LabelColumnName
es la columna del valor que se va a predecir.ValidationSet
esIDataView
que contiene los datos de validación.Arch
define la arquitectura de modelo previamente entrenada que se va a usar. En este tutorial se usa la variante de capa 101 del modelo ResNetv2.MetricsCallback
enlaza una función para realizar un seguimiento del progreso durante el entrenamiento.TestOnTrainSet
indica al modelo que mida el rendimiento en el conjunto de entrenamiento cuando no haya ningún conjunto de validación.ReuseTrainSetBottleneckCachedValues
indica al modelo si se deben usar los valores almacenados en caché de la fase de cuello de botella en las ejecuciones posteriores. La fase de cuello de botella es un cálculo de paso a través único que es intensiva a nivel de computación la primera vez que se realiza. Si los datos de entrenamiento no cambian y quiere experimentar con un número distinto de épocas o tamaño de lote, el uso de los valores almacenados en caché reduce considerablemente la cantidad de tiempo necesario para entrenar un modelo.ReuseValidationSetBottleneckCachedValues
es parecido aReuseTrainSetBottleneckCachedValues
solo que, en este caso, se usa para el conjunto de validación.WorkspacePath
define el directorio donde se almacenan los valores de cuello de botella calculados y la versión.pb
del modelo.
Defina la canalización de entrenamiento
EstimatorChain
que consta demapLabelEstimator
y ImageClassificationTrainer.var trainingPipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(classifierOptions) .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));
Use el método
Fit
para entrenar el modelo.ITransformer trainedModel = trainingPipeline.Fit(trainSet);
Uso del modelo
Ahora que se ha entrenado el modelo, es el momento de usarlo para clasificar las imágenes.
Cree un método de utilidad llamado OutputPrediction
para mostrar información de predicción en la consola.
private static void OutputPrediction(ModelOutput prediction)
{
string imageName = Path.GetFileName(prediction.ImagePath);
Console.WriteLine($"Image: {imageName} | Actual Value: {prediction.Label} | Predicted Value: {prediction.PredictedLabel}");
}
Clasificación de una sola imagen
Cree un método llamado
ClassifySingleImage
para crear y generar una predicción de una sola imagen.void ClassifySingleImage(MLContext mlContext, IDataView data, ITransformer trainedModel) { }
Cree un elemento
PredictionEngine
en el métodoClassifySingleImage
.PredictionEngine
es una API de conveniencia, que permite pasar datos y luego realizar una predicción en una única instancia de datos.PredictionEngine<ModelInput, ModelOutput> predictionEngine = mlContext.Model.CreatePredictionEngine<ModelInput, ModelOutput>(trainedModel);
Para acceder a una única instancia de
ModelInput
, conviertaIDataView
dedata
en un elementoIEnumerable
mediante el métodoCreateEnumerable
y, después, obtenga la primera observación.ModelInput image = mlContext.Data.CreateEnumerable<ModelInput>(data,reuseRowObject:true).First();
Use el método
Predict
para clasificar la imagen.ModelOutput prediction = predictionEngine.Predict(image);
Genere la predicción en la consola con el método
OutputPrediction
.Console.WriteLine("Classifying single image"); OutputPrediction(prediction);
Llame a
ClassifySingleImage
debajo de la llamada al métodoFit
mediante el conjunto de prueba de imágenes.ClassifySingleImage(mlContext, testSet, trainedModel);
Clasificación de varias imágenes
Agregue un método nuevo llamado
ClassifyImages
debajo del métodoClassifySingleImage
para realizar y generar varias predicciones de imágenes.void ClassifyImages(MLContext mlContext, IDataView data, ITransformer trainedModel) { }
Cree un elemento
IDataView
que contenga las predicciones mediante el métodoTransform
. Agregue el código siguiente dentro del métodoClassifyImages
.IDataView predictionData = trainedModel.Transform(data);
Para recorrer en iteración las predicciones, convierta
IDataView
depredictionData
en un elementoIEnumerable
con el métodoCreateEnumerable
y, después, obtenga las diez primeras observaciones.IEnumerable<ModelOutput> predictions = mlContext.Data.CreateEnumerable<ModelOutput>(predictionData, reuseRowObject: true).Take(10);
Recorra en iteración y genere las etiquetas originales y previstas de las predicciones.
Console.WriteLine("Classifying multiple images"); foreach (var prediction in predictions) { OutputPrediction(prediction); }
Por último, llame a
ClassifyImages
debajo del métodoClassifySingleImage()
mediante el conjunto de prueba de imágenes.ClassifyImages(mlContext, testSet, trainedModel);
Ejecutar la aplicación
Ejecute la aplicación de consola. La salida debe ser similar a la siguiente. Es posible que vea advertencias o mensajes de procesamiento, si bien se han quitado de los resultados siguientes para mayor claridad. Por motivos de brevedad, la salida se ha resumido.
Fase de cuello de botella
No se imprime ningún valor para el nombre de la imagen porque las imágenes se cargan como un elemento byte[]
y, por lo tanto, no hay ningún nombre de imagen para mostrar.
Phase: Bottleneck Computation, Dataset used: Train, Image Index: 279
Phase: Bottleneck Computation, Dataset used: Train, Image Index: 280
Phase: Bottleneck Computation, Dataset used: Validation, Image Index: 1
Phase: Bottleneck Computation, Dataset used: Validation, Image Index: 2
Fase de entrenamiento
Phase: Training, Dataset used: Validation, Batch Processed Count: 6, Epoch: 21, Accuracy: 0.6797619
Phase: Training, Dataset used: Validation, Batch Processed Count: 6, Epoch: 22, Accuracy: 0.7642857
Phase: Training, Dataset used: Validation, Batch Processed Count: 6, Epoch: 23, Accuracy: 0.7916667
Salida de clasificación de imágenes
Classifying single image
Image: 7001-220.jpg | Actual Value: UD | Predicted Value: UD
Classifying multiple images
Image: 7001-220.jpg | Actual Value: UD | Predicted Value: UD
Image: 7001-163.jpg | Actual Value: UD | Predicted Value: UD
Image: 7001-210.jpg | Actual Value: UD | Predicted Value: UD
Al inspeccionar la imagen 7001-220.jpg, puede ver que, de hecho, no tiene grietas.
¡Enhorabuena! Ha compilado correctamente un modelo de aprendizaje profundo para la clasificación de imágenes.
Mejora del modelo
Si no está satisfecho con los resultados del modelo, puede intentar mejorar su rendimiento probando algunos de los enfoques siguientes:
- Más datos: cuanto mayor sea el número de ejemplos de los que pueda aprender un modelo, mejor funcionará. Descargue el conjunto de datos SDNET2018 completo y úselo para entrenar.
- Aumentar los datos: Una técnica común para agregar diversidad a los datos es aumentarlos tomando una imagen y aplicando distintas transformaciones (girar, voltear, desplazar o recortar). Esto agrega ejemplos más variados para que el modelo aprenda de ellos.
- Entrenar durante más tiempo: cuanto más tiempo se entrene, más ajustado estará el modelo. Aumentar el número de épocas puede mejorar el rendimiento del modelo.
- Experimentar con otros hiperparámetros: además de los parámetros que se usan en este tutorial, se pueden ajustar otros parámetros para mejorar potencialmente el rendimiento. Cambiar la velocidad de aprendizaje, que determina el tamaño de las actualizaciones realizadas en el modelo después de cada época, puede mejorar el rendimiento.
- Usar una arquitectura de modelo diferente: en función de lo que parezcan los datos, puede variar el modelo que sea capaz de aprender mejor sus características. Si no está satisfecho con el rendimiento del modelo, intente cambiar la arquitectura.
Pasos siguientes
En este tutorial, se ha obtenido información sobre cómo compilar un modelo de aprendizaje profundo personalizado mediante el aprendizaje de transferencia, un modelo TensorFlow de clasificación de imágenes previamente entrenado y la API Image Classification de ML.NET para clasificar las imágenes de superficies de hormigón como con grietas o sin grietas.
Siga con el siguiente tutorial para obtener más información.