Es posible que sea necesario actualizar los modelos de redes neuronales de aprendizaje profundo que se utilizan para el modelado predictivo.
Esto puede deberse a que los datos han cambiado desde que se desarrolló e implementó el modelo, o puede darse el caso de que se hayan puesto a disposición datos etiquetados adicionales desde que se desarrolló el modelo y se espera que los datos adicionales mejoren el rendimiento del modelo. .
Es importante experimentar y evaluar con una variedad de enfoques diferentes al actualizar modelos de redes neuronales para nuevos datos, especialmente si la actualización del modelo será automatizada, como en un programa periódico.
Hay muchas formas de actualizar modelos de redes neuronales, aunque los dos enfoques principales implican usar el modelo existente como punto de partida y reentrenarlo, o dejar el modelo existente sin cambios y combinar las predicciones del modelo existente con un modelo nuevo.
En este tutorial, descubrirá cómo actualizar los modelos de redes neuronales de aprendizaje profundo en respuesta a nuevos datos.
Después de completar este tutorial, sabrá:
- Es posible que los modelos de redes neuronales deban actualizarse cuando cambien los datos subyacentes o cuando estén disponibles nuevos datos etiquetados.
- Cómo actualizar modelos de redes neuronales entrenados con solo datos nuevos o combinaciones de datos antiguos y nuevos.
- Cómo crear un conjunto de modelos nuevos y existentes entrenados solo con datos nuevos o combinaciones de datos antiguos y nuevos.
Empecemos.
Descripción general del tutorial
Este tutorial se divide en tres partes; son:
- Actualización de modelos de redes neuronales
- Reentrenamiento de estrategias de actualización
- Actualizar modelo solo en datos nuevos
- Actualizar modelo en datos antiguos y nuevos
- Estrategias de actualización de conjuntos
- Modelo de conjunto con modelo solo en datos nuevos
- Modelo de conjunto con modelo sobre datos antiguos y nuevos
Actualización de modelos de redes neuronales
Seleccionar y finalizar un modelo de red neuronal de aprendizaje profundo para un proyecto de modelado predictivo es solo el comienzo.
Luego, puede comenzar a usar el modelo para hacer predicciones sobre nuevos datos.
Un posible problema que puede encontrar es que la naturaleza del problema de predicción puede cambiar con el tiempo.
Puede notar esto por el hecho de que la efectividad de las predicciones puede comenzar a disminuir con el tiempo. Esto puede deberse a que las suposiciones hechas y capturadas en el modelo están cambiando o ya no se mantienen.
Generalmente, esto se conoce como el problema de «deriva del concepto”Donde las distribuciones de probabilidad subyacentes de las variables y las relaciones entre las variables cambian con el tiempo, lo que puede afectar negativamente al modelo construido a partir de los datos.
Para obtener más información sobre la deriva del concepto, consulte el tutorial:
La deriva del concepto puede afectar su modelo en diferentes momentos y depende específicamente del problema de predicción que está resolviendo y del modelo elegido para abordarlo.
Puede resultar útil supervisar el rendimiento de un modelo a lo largo del tiempo y utilizar una caída clara en el rendimiento del modelo como desencadenante para realizar un cambio en el modelo, como volver a entrenarlo con datos nuevos.
Alternativamente, puede saber que los datos de su dominio cambian con la frecuencia suficiente como para que se requiera un cambio en el modelo periódicamente, como semanalmente, mensualmente o anualmente.
Finalmente, puede operar su modelo por un tiempo y acumular datos adicionales con resultados conocidos que desea usar para actualizar su modelo, con la esperanza de mejorar el rendimiento predictivo.
Es importante destacar que tiene mucha flexibilidad cuando se trata de responder a un cambio en el problema o la disponibilidad de nuevos datos.
Por ejemplo, puede tomar el modelo de red neuronal entrenado y actualizar los pesos del modelo con los nuevos datos. O podríamos querer dejar intacto el modelo existente y combinar sus predicciones con un nuevo modelo que se ajuste a los nuevos datos disponibles.
Estos enfoques pueden representar dos temas generales en la actualización de modelos de redes neuronales en respuesta a nuevos datos, son:
- Vuelva a entrenar las estrategias de actualización.
- Estrategias de actualización de conjuntos.
Echemos un vistazo más de cerca a cada uno de ellos.
Reentrenamiento de estrategias de actualización
Un beneficio de los modelos de redes neuronales es que sus pesos se pueden actualizar en cualquier momento con entrenamiento continuo.
Al responder a cambios en los datos subyacentes o la disponibilidad de nuevos datos, existen algunas estrategias diferentes para elegir al actualizar un modelo de red neuronal, como:
- Continúe entrenando el modelo solo con los datos nuevos.
- Continúe entrenando el modelo con los datos nuevos y antiguos.
También podríamos imaginar variaciones en las estrategias anteriores, como usar una muestra de los datos nuevos o una muestra de datos nuevos y antiguos en lugar de todos los datos disponibles, así como posibles ponderaciones basadas en instancias en los datos muestreados.
También podríamos considerar extensiones del modelo que congelan las capas del modelo existente (por ejemplo, para que los pesos del modelo no puedan cambiar durante el entrenamiento), luego agregar nuevas capas con pesos del modelo que pueden cambiar, injertando extensiones en el modelo para manejar cualquier cambio en el datos. Quizás esta sea una variación del reentrenamiento y el enfoque de conjunto en la siguiente sección, y lo dejaremos por ahora.
Sin embargo, estas son las dos estrategias principales a considerar.
Hagamos estos enfoques concretos con un ejemplo trabajado.
Actualizar modelo solo en datos nuevos
Podemos actualizar el modelo solo con los nuevos datos.
Una versión extrema de este enfoque es no utilizar ningún dato nuevo y simplemente volver a entrenar el modelo con los datos antiguos. Esto podría ser lo mismo que «hacer nada”En respuesta a los nuevos datos. En el otro extremo, un modelo podría ajustarse solo a los nuevos datos, descartando los datos antiguos y el modelo antiguo.
- Ignore los datos nuevos, no haga nada.
- Actualice el modelo existente con nuevos datos.
- Ajustar el nuevo modelo a los nuevos datos, descartar el modelo y los datos antiguos.
Nos centraremos en el término medio en este ejemplo, pero podría ser interesante probar los tres enfoques en su problema y ver cuál funciona mejor.
Primero, podemos definir un conjunto de datos de clasificación binario sintético y dividirlo por la mitad, luego usar una parte como «datos antiguos«Y otra parte como»nuevos datos. «
... # definir conjunto de datos X, y = make_classification(n_samples=1000, n_features=20, n_informativo=15, n_redundante=5, estado_aleatorio=1) # registrar el número de características de entrada en los datos n_features = X.forma[[1] # dividir en datos nuevos y antiguos X_old, X_new, y_old, y_new = train_test_split(X, y, test_size=0,50, estado_aleatorio=1) |
Luego, podemos definir un modelo de perceptrón multicapa (MLP) y ajustarlo solo a los datos antiguos.
... # definir el modelo modelo = Secuencial() modelo.agregar(Denso(20, kernel_initializer=‘él_normal’, activación=‘relu’, input_dim=n_features)) modelo.agregar(Denso(10, kernel_initializer=‘él_normal’, activación=‘relu’)) modelo.agregar(Denso(1, activación=‘sigmoideo’)) # definir el algoritmo de optimización optar = SGD(tasa de aprendizaje=0,01, impulso=0,9) # compilar el modelo modelo.compilar(optimizador=optar, pérdida=‘binary_crossentropy’) # ajustar el modelo a datos antiguos modelo.encajar(X_old, y_old, épocas=150, tamaño del lote=32, verboso=0) |
Entonces podemos imaginarnos guardando el modelo y usándolo durante algún tiempo.
El tiempo pasa y deseamos actualizarlo sobre los nuevos datos que estén disponibles.
Esto implicaría usar una tasa de aprendizaje mucho más pequeña de lo normal para que no eliminemos los pesos aprendidos en los datos antiguos.
Nota: deberá descubrir una tasa de aprendizaje adecuada para su modelo y conjunto de datos que logre un mejor rendimiento que simplemente ajustar un nuevo modelo desde cero.
... # actualizar el modelo en nuevos datos solo con una tasa de aprendizaje menor optar = SGD(tasa de aprendizaje=0,001, impulso=0,9) # compilar el modelo modelo.compilar(optimizador=optar, pérdida=‘binary_crossentropy’) |
Luego, podemos ajustar el modelo a los nuevos datos solo con esta tasa de aprendizaje más pequeña.
... modelo.compilar(optimizador=optar, pérdida=‘binary_crossentropy’) # ajustar el modelo a nuevos datos modelo.encajar(X_new, y_new, épocas=100, tamaño del lote=32, verboso=0) |
Al unir esto, el ejemplo completo de actualización de un modelo de red neuronal solo con datos nuevos se enumera a continuación.
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 |
# actualizar la red neuronal solo con datos nuevos desde sklearn.conjuntos de datos importar make_classification desde sklearn.model_selection importar train_test_split desde tensorflow.keras.modelos importar Secuencial desde tensorflow.keras.capas importar Denso desde tensorflow.keras.optimizadores importar SGD # definir conjunto de datos X, y = make_classification(n_samples=1000, n_features=20, n_informativo=15, n_redundante=5, estado_aleatorio=1) # registrar el número de características de entrada en los datos n_features = X.forma[[1] # dividir en datos nuevos y antiguos X_old, X_new, y_old, y_new = train_test_split(X, y, test_size=0,50, estado_aleatorio=1) # definir el modelo modelo = Secuencial() modelo.agregar(Denso(20, kernel_initializer=‘él_normal’, activación=‘relu’, input_dim=n_features)) modelo.agregar(Denso(10, kernel_initializer=‘él_normal’, activación=‘relu’)) modelo.agregar(Denso(1, activación=‘sigmoideo’)) # definir el algoritmo de optimización optar = SGD(tasa de aprendizaje=0,01, impulso=0,9) # compilar el modelo modelo.compilar(optimizador=optar, pérdida=‘binary_crossentropy’) # ajustar el modelo a datos antiguos modelo.encajar(X_old, y_old, épocas=150, tamaño del lote=32, verboso=0) # guardar modelo … # cargar modelo … # actualizar el modelo en nuevos datos solo con una tasa de aprendizaje menor optar = SGD(tasa de aprendizaje=0,001, impulso=0,9) # compilar el modelo modelo.compilar(optimizador=optar, pérdida=‘binary_crossentropy’) # ajustar el modelo a nuevos datos modelo.encajar(X_new, y_new, épocas=100, tamaño del lote=32, verboso=0) |
A continuación, veamos cómo actualizar el modelo con datos nuevos y antiguos.
Actualizar modelo en datos antiguos y nuevos
Podemos actualizar el modelo en una combinación de datos nuevos y antiguos.
Una versión extrema de este enfoque es descartar el modelo y simplemente ajustar un nuevo modelo a todos los datos disponibles, nuevos y antiguos. Una versión menos extrema sería utilizar el modelo existente como punto de partida y actualizarlo en función del conjunto de datos combinado.
Nuevamente, es una buena idea probar ambas estrategias y ver qué funciona bien para su conjunto de datos.
Nos centraremos en la estrategia de actualización menos extrema en este caso.
El modelo y el conjunto de datos sintéticos se pueden ajustar al conjunto de datos antiguo como antes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 |
... # definir conjunto de datos X, y = make_classification(n_samples=1000, n_features=20, n_informativo=15, n_redundante=5, estado_aleatorio=1) # registrar el número de características de entrada en los datos n_features = X.forma[[1] # dividir en datos nuevos y antiguos X_old, X_new, y_old, y_new = train_test_split(X, y, test_size=0,50, estado_aleatorio=1) # definir el modelo modelo = Secuencial() modelo.agregar(Denso(20, kernel_initializer=‘él_normal’, activación=‘relu’, input_dim=n_features)) modelo.agregar(Denso(10, kernel_initializer=‘él_normal’, activación=‘relu’)) modelo.agregar(Denso(1, activación=‘sigmoideo’)) # definir el algoritmo de optimización optar = SGD(tasa de aprendizaje=0,01, impulso=0,9) # compilar el modelo modelo.compilar(optimizador=optar, pérdida=‘binary_crossentropy’) # ajustar el modelo a datos antiguos modelo.encajar(X_old, y_old, épocas=150, tamaño del lote=32, verboso=0) |
Hay nuevos datos disponibles y deseamos actualizar el modelo en una combinación de datos antiguos y nuevos.
Primero, debemos usar una tasa de aprendizaje mucho menor en un intento de usar las ponderaciones actuales como punto de partida para la búsqueda.
Nota: deberá descubrir una tasa de aprendizaje adecuada para su modelo y conjunto de datos que logre un mejor rendimiento que simplemente ajustar un nuevo modelo desde cero.
... # modelo de actualización con una tasa de aprendizaje menor optar = SGD(tasa de aprendizaje=0,001, impulso=0,9) # compilar el modelo modelo.compilar(optimizador=optar, pérdida=‘binary_crossentropy’) |
Luego, podemos crear un conjunto de datos compuesto compuesto por datos nuevos y antiguos.
... # crear un conjunto de datos compuesto de datos nuevos y antiguos X_ambos, y_both = vstack((X_old, X_new)), hstack((y_old, y_new)) |
Finalmente, podemos actualizar el modelo en este conjunto de datos compuestos.
... # ajustar el modelo a nuevos datos modelo.encajar(X_ambos, y_both, épocas=100, tamaño del lote=32, verboso=0) |
Al unir esto, el ejemplo completo de actualización de un modelo de red neuronal en datos nuevos y antiguos se enumera a continuación.
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 |
# actualizar la red neuronal con datos nuevos y antiguos desde numpy importar vstack desde numpy importar hstack desde sklearn.conjuntos de datos importar make_classification desde sklearn.model_selection importar train_test_split desde tensorflow.keras.modelos importar Secuencial desde tensorflow.keras.capas importar Denso desde tensorflow.keras.optimizadores importar SGD # definir conjunto de datos X, y = make_classification(n_samples=1000, n_features=20, n_informativo=15, n_redundante=5, estado_aleatorio=1) # registrar el número de características de entrada en los datos n_features = X.forma[[1] # dividir en datos nuevos y antiguos X_old, X_new, y_old, y_new = train_test_split(X, y, test_size=0,50, estado_aleatorio=1) # definir el modelo modelo = Secuencial() modelo.agregar(Denso(20, kernel_initializer=‘él_normal’, activación=‘relu’, input_dim=n_features)) modelo.agregar(Denso(10, kernel_initializer=‘él_normal’, activación=‘relu’)) modelo.agregar(Denso(1, activación=‘sigmoideo’)) # definir el algoritmo de optimización optar = SGD(tasa de aprendizaje=0,01, impulso=0,9) # compilar el modelo modelo.compilar(optimizador=optar, pérdida=‘binary_crossentropy’) # ajustar el modelo a datos antiguos modelo.encajar(X_old, y_old, épocas=150, tamaño del lote=32, verboso=0) # guardar modelo … # cargar modelo … # modelo de actualización con una tasa de aprendizaje menor optar = SGD(tasa de aprendizaje=0,001, impulso=0,9) # compilar el modelo modelo.compilar(optimizador=optar, pérdida=‘binary_crossentropy’) # crear un conjunto de datos compuesto de datos nuevos y antiguos X_ambos, y_both = vstack((X_old, X_new)), hstack((y_old, y_new)) # ajustar el modelo a nuevos datos modelo.encajar(X_ambos, y_both, épocas=100, tamaño del lote=32, verboso=0) |
A continuación, veamos cómo usar modelos de conjuntos para responder a nuevos datos.
Estrategias de actualización de conjuntos
Un conjunto es un modelo predictivo que se compone de muchos otros modelos.
Hay muchos tipos diferentes de modelos de conjuntos, aunque quizás el enfoque más simple sea promediar las predicciones de múltiples modelos diferentes.
Para obtener más información sobre los algoritmos de conjuntos para redes neuronales de aprendizaje profundo, consulte el tutorial:
Podemos utilizar un modelo de conjunto como estrategia al responder a cambios en los datos subyacentes o la disponibilidad de nuevos datos.
Reflejando los enfoques de la sección anterior, podríamos considerar dos enfoques de los algoritmos de aprendizaje por conjuntos como estrategias para responder a nuevos datos; son:
- El conjunto del modelo existente y el modelo nuevo se ajustan únicamente a datos nuevos.
- Conjunto de modelo existente y nuevo modelo que se ajusta a datos antiguos y nuevos.
Nuevamente, podríamos considerar variaciones en estos enfoques, como muestras de datos antiguos y nuevos, y más de un modelo existente o adicional incluido en el conjunto.
Sin embargo, estas son las dos estrategias principales a considerar.
Hagamos estos enfoques concretos con un ejemplo trabajado.
Modelo de conjunto con modelo solo en datos nuevos
Podemos crear un conjunto del modelo existente y un nuevo modelo que se ajuste solo a los nuevos datos.
La expectativa es que las predicciones de conjunto funcionen mejor o sean más estables (menor varianza) que usando el modelo antiguo o el modelo nuevo solo. Esto debe comprobarse en su conjunto de datos antes de adoptar el conjunto.
Primero, podemos preparar el conjunto de datos y ajustar el modelo anterior, como hicimos en las secciones anteriores.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 |
... # definir conjunto de datos X, y = make_classification(n_samples=1000, n_features=20, n_informativo=15, n_redundante=5, estado_aleatorio=1) # registrar el número de características de entrada en los datos n_features = X.forma[[1] # dividir en datos nuevos y antiguos X_old, X_new, y_old, y_new = train_test_split(X, y, test_size=0,50, estado_aleatorio=1) # definir el modelo antiguo viejo modelo = Secuencial() viejo modelo.agregar(Denso(20, kernel_initializer=‘él_normal’, activación=‘relu’, input_dim=n_features)) viejo modelo.agregar(Denso(10, kernel_initializer=‘él_normal’, activación=‘relu’)) viejo modelo.agregar(Denso(1, activación=‘sigmoideo’)) # definir el algoritmo de optimización optar = SGD(tasa de aprendizaje=0,01, impulso=0,9) # compilar el modelo viejo modelo.compilar(optimizador=optar, pérdida=‘binary_crossentropy’) # ajustar el modelo a datos antiguos viejo modelo.encajar(X_old, y_old, épocas=150, tamaño del lote=32, verboso=0) |
Pasa un tiempo y hay nuevos datos disponibles.
We can then fit a new model on the new data, naturally discovering a model and configuration that works well or best on the new dataset only.
In this case, we’ll simply use the same model architecture and configuration as the old model.
... # define the new model new_model = Sequential() new_model.add(Dense(20, kernel_initializer=‘he_normal’, activation=‘relu’, input_dim=n_features)) new_model.add(Dense(10, kernel_initializer=‘he_normal’, activation=‘relu’)) new_model.add(Dense(1, activation=‘sigmoid’)) # define the optimization algorithm opt = SGD(learning_rate=0.01, momentum=0.9) # compile the model new_model.compile(optimizer=opt, loss=‘binary_crossentropy’) |
We can then fit this new model on the new data only.
... # fit the model on old data new_model.fit(X_new, y_new, epochs=150, batch_size=32, verbose=0) |
Now that we have the two models, we can make predictions with each model, and calculate the average of the predictions as the “ensemble prediction.”
... # make predictions with both models yhat1 = old_model.predict(X_new) yhat2 = new_model.predict(X_new) # combine predictions into single array combined = hstack((yhat1, yhat2)) # calculate outcome as mean of predictions yhat = mean(combined, axis=–1) |
Tying this together, the complete example of updating using an ensemble of the existing model and a new model fit on new data only is listed below.
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 |
# ensemble old neural network with new model fit on new data only desde numpy import hstack desde numpy import mean desde sklearn.datasets import make_classification desde sklearn.model_selection import train_test_split desde tensorflow.keras.models import Sequential desde tensorflow.keras.layers import Dense desde tensorflow.keras.optimizers import SGD # define dataset X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=1) # record the number of input features in the data n_features = X.shape[[1] # split into old and new data X_old, X_new, y_old, y_new = train_test_split(X, y, test_size=0.50, random_state=1) # define the old model old_model = Sequential() old_model.add(Dense(20, kernel_initializer=‘he_normal’, activation=‘relu’, input_dim=n_features)) old_model.add(Dense(10, kernel_initializer=‘he_normal’, activation=‘relu’)) old_model.add(Dense(1, activation=‘sigmoid’)) # define the optimization algorithm opt = SGD(learning_rate=0.01, momentum=0.9) # compile the model old_model.compile(optimizer=opt, loss=‘binary_crossentropy’) # fit the model on old data old_model.fit(X_old, y_old, epochs=150, batch_size=32, verbose=0) # save model… # load model… # define the new model new_model = Sequential() new_model.add(Dense(20, kernel_initializer=‘he_normal’, activation=‘relu’, input_dim=n_features)) new_model.add(Dense(10, kernel_initializer=‘he_normal’, activation=‘relu’)) new_model.add(Dense(1, activation=‘sigmoid’)) # define the optimization algorithm opt = SGD(learning_rate=0.01, momentum=0.9) # compile the model new_model.compile(optimizer=opt, loss=‘binary_crossentropy’) # fit the model on old data new_model.fit(X_new, y_new, epochs=150, batch_size=32, verbose=0) # make predictions with both models yhat1 = old_model.predict(X_new) yhat2 = new_model.predict(X_new) # combine predictions into single array combined = hstack((yhat1, yhat2)) # calculate outcome as mean of predictions yhat = mean(combined, axis=–1) |
Ensemble Model With Model on Old and New Data
We can create an ensemble of the existing model and a new model fit on both the old and the new data.
The expectation is that the ensemble predictions perform better or are more stable (lower variance) than using either the old model or the new model alone. This should be checked on your dataset before adopting the ensemble.
First, we can prepare the dataset and fit the old model, as we did in the previous sections.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dieciséis 17 18 |
... # define dataset X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=1) # record the number of input features in the data n_features = X.shape[[1] # split into old and new data X_old, X_new, y_old, y_new = train_test_split(X, y, test_size=0.50, random_state=1) # define the old model old_model = Sequential() old_model.add(Dense(20, kernel_initializer=‘he_normal’, activation=‘relu’, input_dim=n_features)) old_model.add(Dense(10, kernel_initializer=‘he_normal’, activation=‘relu’)) old_model.add(Dense(1, activation=‘sigmoid’)) # define the optimization algorithm opt = SGD(learning_rate=0.01, momentum=0.9) # compile the model old_model.compile(optimizer=opt, loss=‘binary_crossentropy’) # fit the model on old data old_model.fit(X_old, y_old, epochs=150, batch_size=32, verbose=0) |
Some time passes and new data becomes available.
We can then fit a new model on a composite of the old and new data, naturally discovering a model and configuration that works well or best on the new dataset only.
In this case, we’ll simply use the same model architecture and configuration as the old model.
... # define the new model new_model = Sequential() new_model.add(Dense(20, kernel_initializer=‘he_normal’, activation=‘relu’, input_dim=n_features)) new_model.add(Dense(10, kernel_initializer=‘he_normal’, activation=‘relu’)) new_model.add(Dense(1, activation=‘sigmoid’)) # define the optimization algorithm opt = SGD(learning_rate=0.01, momentum=0.9) # compile the model new_model.compile(optimizer=opt, loss=‘binary_crossentropy’) |
We can create a composite dataset from the old and new data, then fit the new model on this dataset.
... # create a composite dataset of old and new data X_both, y_both = vstack((X_old, X_new)), hstack((y_old, y_new)) # fit the model on old data new_model.fit(X_both, y_both, epochs=150, batch_size=32, verbose=0) |
Finally, we can use both models together to make ensemble predictions.
... # make predictions with both models yhat1 = old_model.predict(X_new) yhat2 = new_model.predict(X_new) # combine predictions into single array combined = hstack((yhat1, yhat2)) # calculate outcome as mean of predictions yhat = mean(combined, axis=–1) |
Tying this together, the complete example of updating using an ensemble of the existing model and a new model fit on the old and new data is listed below.
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 50 51 52 |
# ensemble old neural network with new model fit on old and new data desde numpy import hstack desde numpy import vstack desde numpy import mean desde sklearn.datasets import make_classification desde sklearn.model_selection import train_test_split desde tensorflow.keras.models import Sequential desde tensorflow.keras.layers import Dense desde tensorflow.keras.optimizers import SGD # define dataset X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=1) # record the number of input features in the data n_features = X.shape[[1] # split into old and new data X_old, X_new, y_old, y_new = train_test_split(X, y, test_size=0.50, random_state=1) # define the old model old_model = Sequential() old_model.add(Dense(20, kernel_initializer=‘he_normal’, activation=‘relu’, input_dim=n_features)) old_model.add(Dense(10, kernel_initializer=‘he_normal’, activation=‘relu’)) old_model.add(Dense(1, activation=‘sigmoid’)) # define the optimization algorithm opt = SGD(learning_rate=0.01, momentum=0.9) # compile the model old_model.compile(optimizer=opt, loss=‘binary_crossentropy’) # fit the model on old data old_model.fit(X_old, y_old, epochs=150, batch_size=32, verbose=0) # save model… # load model… # define the new model new_model = Sequential() new_model.add(Dense(20, kernel_initializer=‘he_normal’, activation=‘relu’, input_dim=n_features)) new_model.add(Dense(10, kernel_initializer=‘he_normal’, activation=‘relu’)) new_model.add(Dense(1, activation=‘sigmoid’)) # define the optimization algorithm opt = SGD(learning_rate=0.01, momentum=0.9) # compile the model new_model.compile(optimizer=opt, loss=‘binary_crossentropy’) # create a composite dataset of old and new data X_both, y_both = vstack((X_old, X_new)), hstack((y_old, y_new)) # fit the model on old data new_model.fit(X_both, y_both, epochs=150, batch_size=32, verbose=0) # make predictions with both models yhat1 = old_model.predict(X_new) yhat2 = new_model.predict(X_new) # combine predictions into single array combined = hstack((yhat1, yhat2)) # calculate outcome as mean of predictions yhat = mean(combined, axis=–1) |
Further Reading
This section provides more resources on the topic if you are looking to go deeper.
Tutorials
Summary
In this tutorial, you discovered how to update deep learning neural network models in response to new data.
Specifically, you learned:
- Neural network models may need to be updated when the underlying data changes or when new labeled data is made available.
- How to update trained neural network models with just new data or combinations of old and new data.
- How to create an ensemble of existing and new models trained on just new data or combinations of old and new data.
Do you have any questions?
Ask your questions in the comments below and I will do my best to answer.