En este artículo, veremos cómo podemos guardar un modelo que hemos entrenado en Keras.
Primero, crearemos un modelo CNN muy simple usando Keras y entrenaremos ese modelo en el Moda MNIST conjunto de datos Luego le mostraré cómo guardar y posteriormente restaurar ese modelo entrenado y realizar la predicción.
Entiendo que guardar un modelo para un problema muy básico como MNIST de moda puede sonar trivial.
Sin embargo, piense en una situación en la que estamos entrenando un modelo muy complejo que requiere una gran cantidad de tiempo, como horas o incluso días, para entrenar.
En tales casos, suele ser útil guardar el modelo. Entonces, en el futuro, si necesitamos hacer predicciones, simplemente podemos cargar el modelo entrenado y hacer nuestras predicciones en lugar de entrenar nuestro modelo nuevamente desde cero.
En Keras, los modelos se guardan en los siguientes tres formatos.
Veamos cómo guardar el modelo en cada uno de estos formatos.
HDF5:
Generalmente, los modelos se guardan en este formato. HDF5 es la abreviatura de formato de datos jerárquicos. El número cinco indica la versión.
El formato HDF almacenará todo nuestro modelo. Guarda toda la información sobre nuestro modelo, incluida la arquitectura, los pesos del modelo, los parámetros entrenados, los detalles del optimizador, etc.
En Keras, guardar un modelo en formato HDF5 es bastante simple. Keras tiene una función save() que nos permite guardar fácilmente el modelo en este formato.
modelo.guardar(‘modelo.h5’)
modelo.ahorrar(‘modelo.h5‘) |
h5 es la extensión utilizada para guardar el modelo en formato HDF.
YAML O JSON:
En lugar de guardar el modelo completo, Keras también nos brinda la flexibilidad de guardar la arquitectura y los pesos de los modelos por separado.
Podemos usar cualquiera de estos dos formatos para guardar solo la arquitectura del modelo sin los pesos, los parámetros, la pérdida o la configuración del optimizador.
Podemos usar las siguientes funciones para guardar el modelo en formato JSON o YAML.
model.to_json() # para guardar el modelo como json model.to_yaml() # para guardar el modelo como yaml
modelo.to_json() # para guardar el modelo como json modelo.to_yaml() # para guardar el modelo como yaml |
Dado que estos formatos solo guardan la arquitectura, necesitamos guardar el peso del modelo por separado.
Los pesos se pueden almacenar en el formato h5. Para guardar los pesos podemos usar el método save_weights().
modelo.save_weights(‘peso.h5’)
modelo.guardar_pesos(‘peso.h5‘) |
Ahora vamos a hacer un poco de codificación.
En primer lugar, importaremos todos los paquetes necesarios y el conjunto de datos. Usaremos el Moda MNIST conjunto de datos
importar keras importar numpy como np de keras.models importar secuencial de keras.layers importar Dense, Dropout, Flatten de keras.layers importar Conv2D, MaxPooling2D de keras importar backend como K de keras.datasets importar fashion_mnist de keras.utils importar np_utils
importar queras importar entumecido como notario público de queras.modelos importar Secuencial de queras.capas importar Denso, Abandonar, Aplanar de queras.capas importar Conv2D, MaxPooling2D de queras importar back-end como k de queras.conjuntos de datos importar moda_mnista de queras.útiles importar np_utils |
A continuación, crearemos nuestro modelo CNN. El siguiente fragmento de código se tomó de Keras Github Repo.
batch_size = 128 num_classes = 10 epochs = 50 # dimensiones de la imagen de entrada img_rows, img_cols = 28, 28 # los datos, divididos entre conjuntos de entrenamiento y prueba (x_train, y_train), (x_test, y_test) = fashion_mnist.load_data() si K. image_data_format() == ‘channels_first’: x_train = x_train.reshape(x_train.shape[0]1, img_rows, img_cols) x_test = x_test.reshape(x_test.shape[0]1, img_rows, img_cols) input_shape = (1, img_rows, img_cols) else: x_train = x_train.reshape(x_train.shape[0]img_rows, img_cols, 1) x_test = x_test.reshape(x_test.shape[0]img_rows, img_cols, 1) input_shape = (img_rows, img_cols, 1) x_train = x_train.astype(‘float32’) x_test = x_test.astype(‘float32’) x_train /= 255 x_test /= 255 print(‘x_train forma: ‘, tren_x.forma) print(tren_x.forma[0]’entrenar muestras’) print(x_test.shape[0]’muestras de prueba’) # convertir vectores de clase en matrices de clase binaria y_train = keras.utils.to_categorical(y_train, num_classes) y_test = keras.utils.to_categorical(y_test, num_classes) #Construyendo nuestro modelo CNN = Sequential() model.add (Conv2D(32, kernel_size=(3, 3), activación=’relu’, input_shape=input_shape)) modelo.add(Conv2D(64, (3, 3), activación=’relu’)) modelo.add(MaxPooling2D (pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(128, activación=’relu’)) model.add(Dropout(0.5) ) model.add(Dense(num_classes, activación=’softmax’)) #compilar el modelo model.compile(loss=keras.losses.categorical_crossentropy, Optimizer=keras.optimizers.Adadelta(), metrics=[‘accuracy’])
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
tamaño del lote = 128 num_clases = 10 épocas = 50 # dimensiones de la imagen de entrada img_filas, img_cols = 28, 28 # los datos, divididos entre entrenar y probar conjuntos (x_tren, y_tren), (x_prueba, y_prueba) = moda_mnista.Cargar datos() si k.formato_de_datos_de_imagen() == ‘canales_primero’: x_tren = x_tren.remodelar(x_tren.forma[0], 1, img_filas, img_cols) x_prueba = x_prueba.remodelar(x_prueba.forma[0], 1, img_filas, img_cols) entrada_forma = (1, img_filas, img_cols) más: x_tren = x_tren.remodelar(x_tren.forma[0], img_filas, img_cols, 1) x_prueba = x_prueba.remodelar(x_prueba.forma[0], img_filas, img_cols, 1) entrada_forma = (img_filas, img_cols, 1) x_tren = x_tren.un tipo(‘flotador32’) x_prueba = x_prueba.un tipo(‘flotador32’) x_tren /= 255 x_prueba /= 255 impresión(‘x_tren forma:’, x_tren.forma) impresión(x_tren.forma[0], ‘muestras de tren’) impresión(x_prueba.forma[0], ‘muestras de prueba’) # convertir vectores de clase a matrices de clase binaria y_tren = queras.útiles.a_categórico(y_tren, num_clases) y_prueba = queras.útiles.a_categórico(y_prueba, num_clases) #Construyendo nuestra CNN modelo = Secuencial() modelo.agregar(Conv2D(32, kernel_size=(3, 3), activación=‘relú’, entrada_forma=entrada_forma)) modelo.agregar(Conv2D(64, (3, 3), activación=‘relú’)) modelo.agregar(MaxPooling2D(tamaño de la piscina=(2, 2))) modelo.agregar(Abandonar(0.25)) modelo.agregar(Aplanar()) modelo.agregar(Denso(128, activación=‘relú’)) modelo.agregar(Abandonar(0.5)) modelo.agregar(Denso(num_clases, activación=‘softmax’)) #compilar el modelo modelo.compilar(pérdida=queras.pérdidas.categorical_crossentropy, optimizador=queras.optimizadores.Adadelta(), métrica=[‘accuracy’]) |
Finalmente, podemos entrenar nuestro modelo usando la función model.fit().
history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, detallado=1, validation_split=0.2, )
historia = modelo.adaptar(x_tren, y_tren, tamaño del lote=tamaño del lote, épocas=épocas, verboso=1, validación_dividir=0.2, ) |
Como ahora tenemos nuestro modelo entrenado, veamos cómo guardar nuestro modelo en el formato HDF5.
Como ya hemos visto, es súper sencillo. Solo necesitamos llamar al método model.save().
modelo.guardar(‘Moda_Mnist_CNN.h5’)
modelo.ahorrar(‘Moda_Mnist_CNN.h5’) |
Eso es todo. El modelo se guardará en su directorio de trabajo actual.
En la mayoría de los casos, no cargaremos un modelo guardado en la misma sesión. Sin embargo, para fines de demostración, carguemos nuestro modelo.
de keras.models import load_model modelo_restaurado = load_model(‘/content/Fashion_Mnist_CNN.h5’)
de queras.modelos importar cargar_modelo modelo_restaurado = cargar_modelo(‘/content/Moda_Mnist_CNN.h5’) |
Ahora podemos usar nuestro modelo restaurado para hacer predicciones.
index = np.random.randint(0, len(x_test)-1) # elegir aleatoriamente una muestra del conjunto de prueba sample = np.array([x_test[index]]) predicción = modelo_restaurado.predict(muestra) print(‘Número de muestra:’,índice,’n’,’nClase prevista:’,np.argmax([prediction[0]]), ‘Clase real:’,np.argmax(y_test[index]))
índice = notario público.aleatorio.al azar(0, Len(x_prueba)–1) # elegir al azar una muestra de la prueba establecer muestra = notario público.formación([x_test[index]]) predicción = modelo_restaurado.predecir(muestra) impresión(‘Numero de muestra:’,índice,‘norte’,‘nClase prevista:’,notario público.argmax([prediction[0]]), ‘Clase real:’,notario público.argmax(y_prueba[index])) |
Salida: – Número de muestra: 5902 Clase prevista: 5 Clase real: 5
Producción:- Número de muestra: 5902 Clase prevista: 5 Clase real: 5 |
De manera similar, veamos cómo guardar el modelo en formatos JSON y YAML.
Guarde el modelo en formatos JSON y YAML:
En primer lugar, veremos cómo guardar el modelo en formato json. El siguiente fragmento de código guardará nuestro modelo en formato json.
json_string = model.to_json() #guardar nuestro modelo como json con open(‘model.json’,’w’) como json_file: json_file.write(json_string)
cadena_json = modelo.to_json() #guardar nuestro modelo como json con abierto(‘modelo.json’,‘w’) como archivo_json: archivo_json.escribe(cadena_json) |
El modelo se convierte en una cadena JSON en la primera línea y luego, en la segunda y tercera línea, la cadena JSON se almacena en un archivo llamado model.json.
Dado que JSON solo guarda la arquitectura, debemos guardar el peso del modelo por separado.
Los pesos se pueden almacenar en el formato h5. El método save_weights () se puede utilizar para guardar los pesos.
#guardando los pesos del modelo model.save_weights(‘weights.h5’)
#ahorro de pesos de modelos modelo.guardar_pesos(‘pesos.h5’) |
Como ahora tenemos nuestros pesos y arquitectura, reconstruyamos nuestro modelo a partir del archivo JSON.
desde keras.models importe model_from_yaml con open(‘/content/model.json’, ‘r’) como json_file: json_string = json_file.read() json_file.close() json_model = model_from_json(json_string)
de queras.modelos importar modelo_de_yaml con abierto(‘/contenido/modelo.json’, ‘r’) como archivo_json: cadena_json = archivo_json.leer() archivo_json.cerca() modelo_json = modelo_de_json(cadena_json) |
El código anterior se explica por sí mismo. En primer lugar, estamos importando la clase model_from_json.
En la segunda y tercera línea, abrimos el archivo y leemos su contenido.
Finalmente, pasamos el contenido de json_string a model_from_json para reconstruir el modelo.
Ahora, si necesitamos hacer predicciones, necesitamos cargar los pesos y compilar nuestro modelo. Para cargar los pesos en nuestro modelo, podemos usar la función load_weights().
# cargar los pesos json_model.load_weights(‘/content/weights.h5’) # compilar el modelo new_model.compile(loss=keras.losses.categorical_crossentropy, Optimizer=keras.optimizers.Adadelta(), metrics=[‘accuracy’])
# cargar las pesas modelo_json.pesos_de_carga(‘/contenido/pesos.h5’) # compilar el modelo nuevo modelo.compilar(pérdida=queras.pérdidas.categorical_crossentropy, optimizador=queras.optimizadores.Adadelta(), métrica=[‘accuracy’]) |
Ahora podemos hacer predicciones con nuestro modelo.
index = np.random.randint(0, len(x_test)-1) # elegir aleatoriamente una muestra del conjunto de prueba sample = np.array([x_test[index]]) predicción = json_model.predict(sample) print(‘Número de muestra:’,index,’n’,’nClase prevista:’,np.argmax([prediction[0]]), ‘Clase real:’,np.argmax(y_test[index]))
índice = notario público.aleatorio.al azar(0, Len(x_prueba)–1) # elegir al azar una muestra del conjunto de prueba muestra = notario público.formación([x_test[index]]) predicción = modelo_json.predecir(muestra) impresión(‘Numero de muestra:’,índice,‘norte’,‘nClase prevista:’,notario público.argmax([prediction[0]]), ‘Clase real:’,notario público.argmax(y_prueba[index])) |
SALIDA: – Número de muestra: 5645 Clase prevista: 5 Clase real: 5
PRODUCCIÓN:- Número de muestra: 5645 Clase prevista: 5 Clase real: 5 |
Guardar un modelo en YAML es muy similar a guardarlo en JSON. Sólo tenemos que hacer un par de cambios.
Reemplace model.to_json con model.to_yaml e importe model_from_yaml en lugar de model_from_json.
# guardando el modelo yaml_model = model.to_yaml() con open(‘model.yaml’,’w’) como yaml_file: yaml_file.write(yaml_model) # cargando el modelo guardado desde keras.models import model_from_yaml # reconstrucción del modelo desde yaml con open(‘/content/model.yaml’,’r’) as yaml_file: yaml_string = yaml_file.read() yaml_model = model_from_yaml(yaml_string) #carga pesos yaml_model.load_weights(‘/content/weights.h5’) #compila el model yaml_model.compile(loss=keras.losses.categorical_crossentropy, Optimizer=keras.optimizers.Adadelta(), metrics=[‘accuracy’]) # hacer predicciones importar numpy como np index = np.random.randint(0, len(x_test)-1) sample = np.array([x_test[index]]) predicción = yaml_model.predict(sample) print(‘Número de muestra:’,index,’n’,’nClase prevista:’,np.argmax([prediction[0]]), ‘Clase real:’,np.argmax(y_test[index]))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 19 20 21 22 23 24 25 26 |
# guardar el modelo modelo_yaml = modelo.to_yaml() con abierto(‘modelo.yaml’,‘w’) como archivo_yaml: archivo_yaml.escribe(modelo_yaml) # cargando el modelo guardado de queras.modelos importar modelo_de_yaml # reconstrucción del modelo desde yaml con abierto(‘/contenido/modelo.yaml’,‘r’) como archivo_yaml: cadena_yaml = archivo_yaml.leer() modelo_yaml = modelo_de_yaml(cadena_yaml) #cargar pesos modelo_yaml.pesos_de_carga(‘/contenido/pesos.h5’) #compilar el modelo modelo_yaml.compilar(pérdida=queras.pérdidas.categorical_crossentropy, optimizador=queras.optimizadores.Adadelta(), métrica=[‘accuracy’]) # hacer predicciones importar entumecido como notario público índice = notario público.aleatorio.al azar(0, Len(x_prueba)–1) muestra = notario público.formación([x_test[index]]) predicción = modelo_yaml.predecir(muestra) impresión(‘Numero de muestra:’,índice,‘norte’,‘nClase prevista:’,notario público.argmax([prediction[0]), ‘Clase real:’,notario público.argmax(y_prueba[index])) |
También hay otro método para guardar el modelo en Keras. Es mediante el uso de las devoluciones de llamada.
Guarde el modelo en Keras usando Callbacks:
Las devoluciones de llamada de Keras son funciones que se ejecutan durante el proceso de entrenamiento. Según la documentación de Keras, una devolución de llamada es un conjunto de funciones que se aplicarán en determinadas etapas del procedimiento de formación.
He escrito un artículo que explica algunas de las devoluciones de llamadas de uso común. Puede leer el artículo Keras Callbacks para obtener más información sobre las devoluciones de llamada.
Ahora, para esta publicación, veamos cómo guardar un modelo usando la devolución de llamada de Model Checkpoint.
Al utilizar la devolución de llamada del punto de control del modelo, podemos guardar nuestro modelo a intervalos regulares.
La devolución de llamada del punto de control del modelo guarda los pesos del modelo junto con la estructura una vez que avanzamos, como alcanzar una nueva precisión o pérdida de validación. También podríamos guardar el modelo para cada época.
La firma de la devolución de llamada es la siguiente
ModelCheckpoint(filepath, monitor=”val_loss”, verbose=0, save_best_only=False, save_weights_only=False, mode=”auto”, period=1)
ModeloPunto de control(ruta de archivo, monitor=‘val_loss’, verboso=0, save_best_only=Falso, save_weights_only=Falso, modo=‘auto’, período=1) |
- monitor: cantidad a monitorear
- save_best_only: si es VERDADERO guarda solo el mejor modelo de acuerdo con la cantidad monitoreada
- Guardar_pesos_solo: si es TRUE solo se guardan los pesos del modelo
- modo: uno de . En modo min, el entrenamiento se detendrá cuando la cantidad monitoreada haya dejado de disminuir; en modo máximo, se detendrá cuando la cantidad monitoreada haya dejado de aumentar; modo automático, la dirección se infiere automáticamente del nombre de la cantidad monitoreada.
- período: después de cuántas épocas necesita verificar el modelo
El código es el mismo hasta la parte model_compile(). Agregue lo siguiente después de model.compile().
# importar la devolución de llamada desde keras.callbacks import ModelCheckpoint # crear la devolución de llamada model_ckpt = ModelCheckpoint(monitor=”val_loss”, save_best_only=True, verbose=1, mode=”auto”,filepath=filepath) # pasar la devolución de llamada al ajuste( ) historial del método = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, detallado=1, validation_split=0.2, callbacks=[model_ckpt])
# importar la devolución de llamada de queras.devoluciones de llamada importar ModeloPunto de control # crear la devolución de llamada modelo_ckpt = ModeloPunto de control(monitor=‘val_loss’, save_best_only=Verdadero, verboso=1, modo=‘auto’,ruta de archivo=ruta de archivo) # pasar la devolución de llamada al método fit() historia = modelo.adaptar(x_tren, y_tren, tamaño del lote=tamaño del lote, épocas=épocas, verboso=1, validación_dividir=0.2, devoluciones de llamada=[model_ckpt]) |
En el fragmento de código anterior, creamos la devolución de llamada del punto de control del modelo y la pasamos a la función de ajuste. Guardará nuestro modelo en el formato h5 cada vez que mejore nuestra pérdida de validación.
Resumen:
En este artículo, analizamos diferentes formas de guardar un modelo y reconstruirlo nuevamente en Keras.
En primer lugar, vimos cómo guardar un modelo completo, incluida la arquitectura, los parámetros entrenados, los pesos, los estados de pérdida y optimización, etcétera.
En segundo lugar, discutimos los formatos JSON y YAML, que solo almacenan la arquitectura del modelo.
Finalmente, usamos el punto de control del modelo de devolución de llamada de Keras para guardar el modelo a intervalos regulares cada vez que alcanzamos una mejor pérdida de validación.
Visitar este repositorio de Github para obtener el código completo.