Core ML es el framework de Apple para ejecutar modelos de machine learning en dispositivos iOS y macOS, usando la CPU, la GPU o el Neural Engine según el caso. Create ML es la herramienta complementaria para entrenar esos modelos en macOS sin salir del ecosistema Apple. La integración entre ambos es directa: entrenas en Create ML y despliegas con Core ML.
Entrenar modelos con Create ML
Create ML tiene una interfaz visual en macOS (app Create ML) y una API programática para automatizar el entrenamiento. El ejemplo más común es la clasificación de imágenes:
import CreateML
// Entrenar un clasificador de imágenes desde código
let datosEntrenamiento = URL(fileURLWithPath: "/datos/entrenamiento")
// La estructura de carpetas define las clases:
// entrenamiento/gatos/ ? imágenes de gatos
// entrenamiento/perros/ ? imágenes de perros
let parametros = MLImageClassifier.ModelParameters(
validation: .split(strategy: .automatic),
maxIterations: 20,
augmentationOptions: [.flip, .rotate, .blur]
)
do {
let clasificador = try MLImageClassifier(
trainingData: .labeledDirectories(at: datosEntrenamiento),
parameters: parametros
)
// Evaluar métricas
let metricas = clasificador.trainingMetrics
print("Exactitud: (metricas.classificationError)%")
// Guardar el modelo entrenado como .mlmodel
let destino = URL(fileURLWithPath: "/modelos/ClasificadorMascotas.mlmodel")
try clasificador.write(to: destino, metadata: MLModelMetadata(
author: "MiApp",
shortDescription: "Clasificador gatos vs perros",
version: "1.0"
))
} catch {
print("Error entrenando: (error)")
}
Integrar modelos con Core ML
Al añadir un fichero .mlpackage o .mlmodel al proyecto en Xcode, se genera automáticamente una clase Swift tipada. La predicción es síncrona pero se puede envolver en async:
import CoreML
import Vision
import UIKit
class ClasificadorMascotas {
private let modelo: ClasificadorMascotas // Clase generada por Xcode
init() throws {
let config = MLModelConfiguration()
config.computeUnits = .cpuAndNeuralEngine // Usar Neural Engine si está disponible
modelo = try ClasificadorMascotas(configuration: config)
}
func clasificar(imagen: UIImage) async throws -> String {
guard let cgImage = imagen.cgImage else {
throw ClasificacionError.imagenInvalida
}
return try await withCheckedThrowingContinuation { continuation in
let handler = VNImageRequestHandler(cgImage: cgImage)
let peticion = VNCoreMLRequest(model: try! VNCoreMLModel(for: modelo.model)) { peticion, error in
if let error {
continuation.resume(throwing: error)
return
}
if let resultado = peticion.results?.first as? VNClassificationObservation {
continuation.resume(returning: resultado.identifier)
}
}
try? handler.perform([peticion])
}
}
}
El framework Vision: clasificación y detección
Vision es la capa de alto nivel sobre Core ML para tareas de visión por computador. Incluye modelos preentrenados de Apple para tareas comunes:
import Vision
// Detección de rostros (sin Core ML explícito: usa el modelo del sistema)
func detectarRostros(en imagen: UIImage) async throws -> [VNFaceObservation] {
guard let cgImage = imagen.cgImage else { return [] }
return try await withCheckedThrowingContinuation { cont in
let peticion = VNDetectFaceRectanglesRequest { peticion, error in
if let error { cont.resume(throwing: error); return }
let rostros = peticion.results as? [VNFaceObservation] ?? []
cont.resume(returning: rostros)
}
try? VNImageRequestHandler(cgImage: cgImage).perform([peticion])
}
}
// Reconocimiento de texto (OCR)
func extraerTexto(de imagen: UIImage) async throws -> String {
guard let cgImage = imagen.cgImage else { return "" }
return try await withCheckedThrowingContinuation { cont in
let peticion = VNRecognizeTextRequest { peticion, error in
if let error { cont.resume(throwing: error); return }
let texto = (peticion.results as? [VNRecognizedTextObservation])?
.compactMap { $0.topCandidates(1).first?.string }
.joined(separator: "n") ?? ""
cont.resume(returning: texto)
}
peticion.recognitionLevel = .accurate
peticion.recognitionLanguages = ["es-ES", "en-US"]
try? VNImageRequestHandler(cgImage: cgImage).perform([peticion])
}
}
NLModel: modelos de procesamiento de texto
Create ML también permite entrenar modelos de clasificación de texto. La integración usa el framework Natural Language:
import NaturalLanguage
// Clasificador de sentimiento personalizado entrenado con Create ML
let url = Bundle.main.url(forResource: "SentimentClassifier", withExtension: "mlmodelc")!
let nlModel = try NLModel(contentsOf: url)
let clasificador = NLTagger(tagSchemes: [.tokenType])
clasificador.setModels([nlModel], forTagScheme: .tokenType)
clasificador.string = "Este producto es increíble"
let (etiqueta, _) = clasificador.tag(at: clasificador.string!.startIndex,
unit: .sentence, scheme: .tokenType)
print(etiqueta?.rawValue ?? "sin clasificar") // positivo
Actualización de modelos en background
Core ML permite actualizar modelos con datos nuevos del usuario para personalización, usando MLUpdateTask:
let modeloURL = Bundle.main.url(forResource: "MiModelo", withExtension: "mlmodelc")!
let datosPropios = try MLArrayBatchProvider(dictionary: [
"entrada": MLMultiArray(shape: [1, 10], dataType: .float32),
"etiqueta": MLMultiArray(shape: [1], dataType: .int32)
])
let config = MLModelConfiguration()
let tarea = try MLUpdateTask(
forModelAt: modeloURL,
trainingData: datosPropios,
configuration: config
) { contexto in
let modeloActualizado = contexto.model
// Guardar el modelo actualizado en documentos del usuario
let destino = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
.appendingPathComponent("ModeloPersonalizado.mlmodelc")
try? modeloActualizado.write(to: destino)
}
tarea.resume()
Resumen
El dúo Create ML / Core ML proporciona un pipeline de machine learning completo dentro del ecosistema Apple: Create ML para entrenar clasificadores de imágenes, texto, sonido y tablas de datos; Core ML para ejecutar inferencia en dispositivos con aceleración por Neural Engine; y Vision y Natural Language como capas de alto nivel para las tareas más comunes de visión por computador y NLP. La integración con Xcode convierte los modelos en clases Swift tipadas sin código de despliegue adicional.
