Compartir a través de


Tutorial: Inspección visual automatizada mediante el aprendizaje de transferencia con la API de clasificación de imágenes 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 de clasificación de imágenes de ML.NET para clasificar imágenes de superficies concretas como agrietadas o sin procesar.

En este tutorial, aprenderá a:

  • Comprender el problema
  • Más información sobre ML.NET Image Classification API
  • Comprender el modelo entrenado previamente
  • Uso del aprendizaje de transferencia para entrenar un modelo personalizado de clasificación de imágenes de TensorFlow
  • Clasificación de imágenes con el modelo personalizado

Prerrequisitos

Comprender el problema

La clasificación de imágenes es un problema de Computer Vision. La clasificación de imágenes toma una imagen como entrada y la clasifica en una clase prescrita. Los modelos de clasificación de imágenes suelen entrenarse mediante el aprendizaje profundo y las redes neuronales. Para más información, consulte Aprendizaje profundo frente al aprendizaje automático.

Algunos escenarios en los que la clasificación de imágenes es útil son:

  • 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 cubiertas de puente para identificar estructuras dañadas por grietas.

API de clasificación de imágenes de ML.NET

ML.NET proporciona varias maneras de realizar la clasificación de imágenes. En este tutorial se aplica el aprendizaje de transferencia mediante Image Classification API. Image Classification API usa TensorFlow.NET, una biblioteca de bajo nivel que proporciona enlaces de C# para la API de C++ de TensorFlow.

¿Qué es el aprendizaje de transferencia?

El aprendizaje de transferencia aplica conocimientos adquiridos de resolver un problema a otro problema relacionado.

El entrenamiento de un modelo de aprendizaje profundo desde cero requiere establecer varios parámetros, una gran cantidad de datos de entrenamiento etiquetados y una gran cantidad de recursos de proceso (cientos de horas de GPU). El uso de un modelo preentrenado junto con el aprendizaje por transferencia le permite acortar el proceso de entrenamiento.

Proceso de entrenamiento

Image Classification API inicia el proceso de entrenamiento cargando un modelo tensorFlow previamente entrenado. El proceso de entrenamiento consta de dos pasos:

  1. Fase de cuello de botella.
  2. Fase de entrenamiento.

Pasos de entrenamiento

Fase de cuello de botella

Durante la fase de cuello de botella, se carga el conjunto de imágenes de entrenamiento y los valores de píxel se usan como entrada, o características, para las capas congeladas del modelo preentrenado. Las capas inmovilizadas incluyen todas las capas de la red neuronal hasta la penúltima capa, conocida informalmente como capa de cuello de botella. Estas capas se conocen como congeladas porque no se producirá ningún entrenamiento en estas capas y que las operaciones se pasan a través. Se encuentra en estas capas inmovilizadas 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 intensivo de cálculo es este paso. Afortunadamente, dado que se trata de un cálculo único, los resultados se pueden almacenar en caché y usarse en ejecuciones posteriores al experimentar con parámetros diferentes.

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 para el número de veces que especifican los parámetros del modelo. Durante cada ejecución, se evalúa la pérdida y la precisión. A continuación, 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 de modelo. Una de ellas es la .pb versión del modelo y la otra es la .zip ML.NET versión serializada del modelo. Cuando se trabaja en entornos admitidos por ML.NET, se recomienda usar la .zip versión del modelo. Sin embargo, en entornos en los que no se admite ML.NET, tiene la opción de usar la .pb versión.

Comprender el modelo entrenado previamente

El modelo entrenado previamente usado en este tutorial es la variante de capa 101 del modelo de red residual (ResNet) v2. El modelo original se entrena para clasificar 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 entrena. Parte de este modelo se usa para entrenar un nuevo modelo mediante imágenes personalizadas para realizar predicciones entre dos clases.

Creación de una aplicación de consola

Ahora que tiene conocimientos generales sobre el aprendizaje de transferencia y la API de clasificación de imágenes, es el momento de compilar la aplicación.

  1. Cree una aplicación de consola de C# denominada "DeepLearning_ImageClassification_Binary". Haga clic en el botón Siguiente .

  2. Elija .NET 8 como marco que se va a usar y, a continuación, seleccione Crear.

  3. Instale el paquete NuGet de 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.

    1. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto y seleccione Administrar paquetes NuGet.
    2. Elija "nuget.org" como origen del paquete.
    3. Seleccione la pestaña Examinar.
    4. Active la casilla Incluir versión preliminar .
    5. Busque Microsoft.ML.
    6. Seleccione el botón Instalar .
    7. Seleccione el botón Acepto en el cuadro de diálogo Aceptación de licencia si está de acuerdo con los términos de licencia de los paquetes enumerados.
    8. Repita estos pasos para los paquetes NuGet Microsoft.ML.Vision, SciSharp.TensorFlow.Redist (versión 2.3.1) y Microsoft.ML.ImageAnalytics .

Preparación y comprensión de los datos

Nota:

Los conjuntos de datos de este tutorial proceden de Maguire, Marc; Dorafshan, Sattar; y Thomas, Robert J., "SDNET2018: un conjunto de datos de imagen de grieta concreto para aplicaciones de aprendizaje automático" (2018). Examine 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 agrietadas y no agrietadas (cubiertas de puentes, paredes y pavimento).

muestras del tablero de puente del conjunto de datos SDNET2018

Los datos se organizan en tres subdirectorios:

  • D contiene imágenes de baraja de puente
  • P contiene imágenes de pavimento
  • W contiene imágenes de muros

Cada uno de estos subdirectorios contiene dos subdirectorios con prefijo adicionales:

  • C es el prefijo usado para superficies agrietadas.
  • U es el prefijo usado para superficies sin aplicar

En este tutorial, solo se usan imágenes del tablero del puente.

  1. Descargue el conjunto de datos y descomprima.
  2. Cree un directorio denominado "Assets" en el proyecto para guardar los archivos del conjunto de datos.
  3. Copie los subdirectorios CD y UD del directorio descomprimido recientemente en el directorio Assets .

Creación de clases de entrada y salida

  1. Abra el archivo Program.cs y reemplace el contenido existente por las siguientes using directivas:

    using Microsoft.ML;
    using Microsoft.ML.Vision;
    using static Microsoft.ML.DataOperationsCatalog;
    
  2. Cree una clase denominada ImageData. Esta clase se usa para representar los datos cargados inicialmente.

    class ImageData
    {
        public string? ImagePath { get; set; }
        public string? Label { get; set; }
    }
    

    ImageData contiene las siguientes propiedades:

    • ImagePath es la ruta 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.
  3. Cree clases para los datos de entrada y salida.

    1. Debajo de la ImageData clase , defina el esquema de los datos de entrada en una nueva clase denominada ModelInput.

      class ModelInput
      {
          public byte[]? Image { get; set; }
          public uint LabelAsKey { get; set; }
          public string? ImagePath { get; set; }
          public string? Label { get; set; }
      }
      

      ModelInput contiene las siguientes propiedades:

      • Image es la byte[] representación de la imagen. El modelo espera que los datos de imagen sean de este tipo para el entrenamiento.
      • LabelAsKey es la representación numérica de Label.
      • 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 Image y LabelAsKey se usan para entrenar el modelo y realizar predicciones. Las ImagePath propiedades y Label se conservan para mayor comodidad para tener acceso al nombre y la categoría del archivo de imagen original.

    2. A continuación, debajo de la ModelInput clase , defina el esquema de los datos de salida en una nueva clase denominada ModelOutput.

      class ModelOutput
      {
          public string? ImagePath { get; set; }
          public string? Label { get; set; }
          public string? PredictedLabel { get; set; }
      }
      

      ModelOutput contiene las siguientes propiedades:

      • 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 previsto por el modelo.

      De forma similar a ModelInput, solo PredictedLabel es necesario realizar predicciones, ya que contiene la predicción realizada por el modelo. Las ImagePath propiedades y Label se conservan para mayor comodidad para tener acceso al nombre y la categoría del archivo de imagen original.

Definición de rutas de acceso e inicialización de variables

  1. En las using directivas , agregue el código siguiente a:

    • Defina la ubicación de los recursos.

    • Inicialice la mlContext variable con una nueva instancia de MLContext.

      La clase MLContext es un punto de partida para todas las operaciones de ML.NET e inicializar mlContext crea un nuevo entorno de ML.NET que se puede compartir entre los objetos de flujo de trabajo de creación de modelos. Es similar, conceptualmente, a DbContext en Entity Framework.

    var projectDirectory = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "../../../"));
    var assetsRelativePath = Path.Combine(projectDirectory, "Assets");
    
    MLContext mlContext = new();
    

Carga de los datos

Crear método de utilidad de carga de datos

Las imágenes se almacenan en dos subdirectorios. Antes de cargar los datos, estos necesitan ser formateados como una lista de objetos ImageData. Para ello, cree el LoadImagesFromDirectory método :

static IEnumerable<ImageData> LoadImagesFromDirectory(string folder, bool useFolderNameAsLabel = true)
{
    var files = Directory.GetFiles(folder, "*",
        searchOption: SearchOption.AllDirectories);

    foreach (var file in files)
    {
        if ((Path.GetExtension(file) != ".jpg") && (Path.GetExtension(file) != ".png"))
            continue;

        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[..index];
                    break;
                }
            }
        }

        yield return new ImageData()
        {
            ImagePath = file,
            Label = label
        };
    }
}

El método LoadImagesFromDirectory realiza las acciones siguientes:

  • Obtiene todas las rutas de acceso de los archivos de los subdirectorios.
  • Recorre en iteración cada uno de los archivos mediante una foreach instrucción y comprueba que se admiten las extensiones de archivo. Image Classification API admite formatos JPEG y PNG.
  • Obtiene la etiqueta del archivo. Si el parámetro useFolderNameAsLabel se establece en true, el directorio padre donde se guarda el archivo se usa como etiqueta. De lo contrario, espera que la etiqueta sea un prefijo del nombre de archivo o del propio nombre de archivo.
  • Crea una nueva instancia de ModelInput.

Preparación de los datos

Agregue el código siguiente después de la línea donde cree la nueva instancia de MLContext.

IEnumerable<ImageData> images = LoadImagesFromDirectory(folder: assetsRelativePath, useFolderNameAsLabel: true);

IDataView imageData = mlContext.Data.LoadFromEnumerable(images);

IDataView shuffledData = mlContext.Data.ShuffleRows(imageData);

var preprocessingPipeline = mlContext.Transforms.Conversion.MapValueToKey(
        inputColumnName: "Label",
        outputColumnName: "LabelAsKey")
    .Append(mlContext.Transforms.LoadRawImageBytes(
        outputColumnName: "Image",
        imageFolder: assetsRelativePath,
        inputColumnName: "ImagePath"));

IDataView preProcessedData = preprocessingPipeline
                    .Fit(shuffledData)
                    .Transform(shuffledData);

TrainTestData trainSplit = mlContext.Data.TrainTestSplit(data: preProcessedData, testFraction: 0.3);
TrainTestData validationTestSplit = mlContext.Data.TrainTestSplit(trainSplit.TestSet);

IDataView trainSet = trainSplit.TrainSet;
IDataView validationSet = validationTestSplit.TrainSet;
IDataView testSet = validationTestSplit.TestSet;

El código anterior:

  • Llama al LoadImagesFromDirectory método de utilidad para obtener la lista de imágenes usadas para el entrenamiento después de inicializar la mlContext variable.

  • Carga las imágenes en un IDataView utilizando el método LoadFromEnumerable.

  • Baraja los datos mediante el método ShuffleRows. Los datos se cargan en el orden en que se leyeron de los directorios. El orden aleatorio se realiza para equilibrarlo.

  • Realiza algún preprocesamiento en los datos antes del entrenamiento. Esto se hace porque los modelos de aprendizaje automático esperan que la entrada esté en formato numérico. El código de preprocesamiento crea un EstimatorChain compuesto por las transformaciones de MapValueToKey y LoadRawImageBytes. La MapValueToKey transformación toma el valor de categoría en la Label columna, lo convierte en un valor numérico KeyType y lo almacena en una nueva columna denominada LabelAsKey. LoadImages toma los valores de la ImagePath columna junto con el imageFolder parámetro para cargar imágenes para el entrenamiento.

  • Usa el Fit método para aplicar los datos al preprocessingPipelineEstimatorChain seguido del Transform método , que devuelve un IDataView objeto que contiene los datos preprocesados.

  • Divide los datos en conjuntos de entrenamiento, validación y pruebas.

    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 forma en que realiza predicciones sobre datos no vistos se mide mediante el rendimiento en el conjunto de validación. En función de los resultados de ese rendimiento, el modelo realiza ajustes en lo que ha aprendido en un esfuerzo por mejorar. El conjunto de validación puede proceder de fragmentar el conjunto de datos original o de otro recurso ya reservado para este propósito.

    El ejemplo de código realiza dos divisiones. En primer lugar, los datos preprocesados se dividen y se usan 70% para el entrenamiento, mientras que los 30% restantes se usan para la validación. A continuación, el conjunto de validación de 30% se divide aún más en conjuntos de validación y pruebas donde se usan 90% para la validación y se usan 10% para las pruebas.

    Una manera de pensar en el propósito de estas particiones de datos es realizar un examen. Al estudiar para un examen, revise sus notas, libros u otros recursos para comprender los conceptos que se encuentran en el examen. Esto es para lo que sirve el tren. Después, puede realizar un examen ficticio para validar sus conocimientos. Aquí es donde el conjunto de validación resulta útil. Quiere comprobar si tiene una buena comprensión de los conceptos antes de realizar el examen real. En función de esos resultados, tomas nota de lo que te has equivocado o no has entendido bien e incorporas los cambios a medida que te preparas para el examen real. Finalmente, tú tomas el examen. Esto es lo que se usa el conjunto de pruebas para. Nunca has visto las preguntas que se encuentran en el examen y ahora usas lo que has aprendido del entrenamiento y la validación para aplicar tus conocimientos a la tarea en cuestión.

  • Asigna las particiones a sus respectivos valores para los datos de entrenamiento, validación y prueba.

Definir la canalización de entrenamiento

El entrenamiento del modelo consta de dos pasos. En primer lugar, image Classification API se usa para entrenar el modelo. A continuación, las etiquetas codificadas de la PredictedLabel columna se convierten de nuevo en su valor de categoría original mediante la MapKeyToValue transformación.

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

var trainingPipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(classifierOptions)
    .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));

ITransformer trainedModel = trainingPipeline.Fit(trainSet);

El código anterior:

  • Crea una nueva variable para almacenar un conjunto de parámetros obligatorios y opcionales para .ImageClassificationTrainer Un ImageClassificationTrainer toma varios parámetros opcionales:

    • FeatureColumnName es la columna que se usa como entrada para el modelo.
    • LabelColumnName es la columna del valor que se va a predecir.
    • ValidationSet es el IDataView que contiene los datos de validación.
    • Arch define cuál de las arquitecturas de modelo previamente entrenadas que se van 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 presente.
    • ReuseTrainSetBottleneckCachedValues indica al modelo si se deben usar los valores almacenados en caché de la fase de cuello de botella en ejecuciones posteriores. La fase de cuello de botella es un cálculo de paso a través único que consume mucho cálculo la primera vez que se realiza. Si los datos de entrenamiento no cambian y desea experimentar con un número diferente de épocas o tamaño de lote, el uso de los valores almacenados en caché reduce significativamente la cantidad de tiempo necesario para entrenar un modelo.
    • ReuseValidationSetBottleneckCachedValues es similar a ReuseTrainSetBottleneckCachedValues solo que, en este caso, es para el conjunto de datos de validación.
  • Define la EstimatorChain canalización de entrenamiento que consta de y mapLabelEstimator .ImageClassificationTrainer

  • Usa el Fit método para entrenar el modelo.

Uso del modelo

Ahora que ha entrenado el modelo, es el momento de usarlo para clasificar imágenes.

Cree un nuevo método de utilidad llamado OutputPrediction para mostrar información de predicción en la consola.

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

  1. Cree un método llamado ClassifySingleImage para realizar y generar una única predicción de imagen.

    static void ClassifySingleImage(MLContext mlContext, IDataView data, ITransformer trainedModel)
    {
        PredictionEngine<ModelInput, ModelOutput> predictionEngine = mlContext.Model.CreatePredictionEngine<ModelInput, ModelOutput>(trainedModel);
    
        ModelInput image = mlContext.Data.CreateEnumerable<ModelInput>(data, reuseRowObject: true).First();
    
        ModelOutput prediction = predictionEngine.Predict(image);
    
        Console.WriteLine("Classifying single image");
        OutputPrediction(prediction);
    }
    

    El método ClassifySingleImage realiza las acciones siguientes:

    • Crea un PredictionEngine elemento dentro del ClassifySingleImage método . PredictionEngine es una API útil que le permite pasar y, a continuación, realizar una predicción en una sola instancia de datos.
    • Para tener acceso a una sola ModelInput instancia, convierte en dataIDataView un IEnumerable mediante el CreateEnumerable método y, a continuación, obtiene la primera observación.
    • Usa el Predict método para clasificar la imagen.
    • Muestra la predicción en la consola con el método OutputPrediction.
  2. Llame a ClassifySingleImage después de llamar al método Fit utilizando el conjunto de imágenes de prueba.

    ClassifySingleImage(mlContext, testSet, trainedModel);
    

Clasificación de varias imágenes

  1. Cree un método llamado ClassifyImages para realizar y generar varias predicciones de imagen.

    static void ClassifyImages(MLContext mlContext, IDataView data, ITransformer trainedModel)
    {
        IDataView predictionData = trainedModel.Transform(data);
    
        IEnumerable<ModelOutput> predictions = mlContext.Data.CreateEnumerable<ModelOutput>(predictionData, reuseRowObject: true).Take(10);
    
        Console.WriteLine("Classifying multiple images");
        foreach (var prediction in predictions)
        {
            OutputPrediction(prediction);
        }
    }
    

    El método ClassifyImages realiza las acciones siguientes:

    • Crea un IDataView objeto que contiene las predicciones mediante el Transform método .
    • Para iterar sobre las predicciones, convierte el predictionDataIDataView en un IEnumerable usando el método CreateEnumerable y, a continuación, obtiene las primeras 10 observaciones.
    • Itera y genera las etiquetas originales y predichas para las predicciones.
  2. Llame a ClassifyImages después de llamar al método ClassifySingleImage() utilizando el conjunto de imágenes de prueba.

    ClassifyImages(mlContext, testSet, trainedModel);
    

Ejecutar la aplicación

Ejecute la aplicación de consola. La salida debe ser similar a la siguiente salida.

Nota:

Es posible que vea advertencias o mensajes de procesamiento; esos mensajes se han eliminado de los siguientes resultados para mayor claridad. Por motivos de brevedad, el resultado se ha condensado.

Fase de cuello de botella

No se imprime ningún valor para el nombre de la imagen porque las imágenes se cargan como , byte[] 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

Clasificación de la salida 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

Tras la inspección de la imagen 7001-220.jpg, puede comprobar que no está agrietado, como predijo el modelo.

imagen de conjunto de datos de SDNET2018 usada para la predicción

¡Felicidades! Ahora ha logrado crear con éxito un modelo de aprendizaje profundo para clasificar 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: cuantos más ejemplos obtenga un modelo, mejor funciona. Descargue el conjunto de datos de SDNET2018 completo y úselo para entrenarlo.
  • Aumentar los datos: una técnica común para agregar variedad a los datos es aumentar los datos tomando una imagen y aplicando diferentes transformaciones (rotación, volteo, desplazamiento, recorte). Esto agrega ejemplos más variados para que el modelo obtenga información.
  • Entrenar durante más tiempo: Cuanto más tiempo se entrene, más ajustado estará el modelo. Aumentar el número de épocas podría mejorar el rendimiento del modelo.
  • Experimento con los hiperparámetres: además de los parámetros usados en este tutorial, se pueden ajustar otros parámetros para mejorar el rendimiento. Cambiar la velocidad de aprendizaje, que determina la magnitud de las actualizaciones realizadas en el modelo después de cada época, podría mejorar el rendimiento.
  • Usar una arquitectura de modelo diferente: dependiendo del aspecto de los datos, el modelo que mejor pueda aprender sus características podría diferir. Si no está satisfecho con el rendimiento del modelo, pruebe a cambiar la arquitectura.

Pasos siguientes

En este tutorial, ha aprendido a crear 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 de clasificación de imágenes de ML.NET para clasificar imágenes de superficies concretas como agrietadas o sin procesar.

Pase al siguiente tutorial para obtener más información.

Consulte también