Blog
Utilice los modelos Keras con Scikit-Learn Para el Machine Learning
- Publicado por: Rafael Fernandez
- Categoría: Deep Learning
-En esta lección descubrirá cómo puede utilizar los modelos de Deep Learning de Keras con la biblioteca Scikit-Learn de Python.
-Cómo envolver un modelo de Keras para usarlo con scikit-learn.
-Cómo evaluar fácilmente los modelos de Keras utilizando la validación cruzada en scikit-learn.
-Cómo ajustar los hiperparámetros del modelo Keras usando la búsqueda en cuadrícula en scikit-learn.
La biblioteca Scikit-Learn es la biblioteca más popular para Machine Learning en Python.
Descripción general
Keras es una biblioteca popular para Deep Learning en Python y el enfoque de la biblioteca es fundamentalmente Deep Learning. La biblioteca scikit-learn en Python está construida sobre SciPy para un cálculo numérico eficiente. Es un programa con todas las funciones para el Machine Learning de propósito general y proporciona muchas utilidades que son útiles para el desarrollo de modelos de Deep Learning. No menos importante:
- Evaluación de modelos utilizando métodos de remuestreo como la validación cruzada k-fold.
- Eficaz búsqueda y evaluación de hiperparámetros de modelos.
La biblioteca Keras proporciona una envoltura conveniente para los modelos de Deep Learning que se utilizarán como estimadores de clase o regresión en scikit-learn. En las próximas secciones trabajaremos a través de ejemplos de uso de la envoltura del KerasClassifier para una red neuronal de clasificación creada en Keras y usando scikit-learn.
Evaluar modelos con Validación Cruzada
Las clases KerasClassifier y KerasRegressor en Keras toman un argumento build_fn que es el nombre de la función a llamar para crear su modelo. Debes definir una función llamada para definir tu modelo, lo compila y lo devuelve. En el ejemplo de abajo diseñamos una función para create_model() que crea una simple red neuronal multicapa para el problema.
Pasamos este nombre de función a la clase KerasClassifier por el argumento build_fn. También pasamos argumentos adicionales de epochs=150 y batch_size=10. Éstos se agrupan automáticamente y se pasan a la función fit(), que es llamada internamente por la función Clase KerasClassifier. En este ejemplo usamos el scikit-learn StratifiedKFold para realizar la Validación Cruzada estratificada 10 veces. Se trata de una técnica de remuestreo que puede proporcionar una robusta estimación del rendimiento de un modelo de Machine Learning sobre datos no vistos. Usamos el método scikit-learn function cross_val_score() para evaluar nuestro modelo usando el esquema de Validación Cruzada e imprimimos los resultados.
# MLP para un conjunto de datos de 10-fold validacion cruzada via sklearn from keras.models import Sequential from keras.layers import Dense from keras.wrappers.scikit_learn import KerasClassifier from sklearn.model_selection import StratifiedKFold from sklearn.model_selection import cross_val_score import numpy # funcion para crear el modelo, requerido por KerasClassifier def create_model(): # crea el modelo model = Sequential() model.add(Dense(12, input_dim=8, activation='relu')) model.add(Dense(8, activation='relu')) model.add(Dense(1, activation='sigmoid')) # Compila el modelo model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) return model # Fija las semillas aleatorias para la reproducibilidad seed = 7 numpy.random.seed(seed) # carga los datos dataset = numpy.loadtxt("pima.csv", delimiter=",") # split into input (X) and output (Y) variables X = dataset[:,0:8] Y = dataset[:,8] # crea el modelo model = KerasClassifier(build_fn=create_model, epochs=150, batch_size=10, verbose=0) # evalua usando 10-fold validacion cruzada kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=seed) results = cross_val_score(model, X, Y, cv=kfold) print(results.mean())
Al ejecutar el ejemplo se muestra la habilidad del modelo para cada epoch. Se crean y evalúan un total de 10 modelos y se muestra el promedio de precisión.
Using TensorFlow backend. 0.6952324017301782
Puede ver que cuando el modelo Keras está envuelto, la estimación de la precisión del modelo puede ser mucho más eficiente, comparada con la enumeración manual de los pliegues de validación cruzada realizada en la lección anterior.
Búsqueda en Cuadrícula Parámetros del modelo de Deep Learning
El ejemplo anterior mostró lo fácil que es envolver tu modelo de aprendizaje profundo de Keras y usarlo en funciones de la biblioteca scikit-learn. En este ejemplo vamos un paso más allá. Ya sabemos que podemos proporcionar argumentos a la función fit(). La función que especificamos al argumento build_fn cuando creamos la envoltura del KerasClassifier también puede tomar argumentos. Podemos utilizar estos argumentos para personalizar aún más la construcción del modelo.
En este ejemplo utilizamos una búsqueda en cuadrícula para evaluar las configuraciones diferentes de nuestro modelo de red neural e informar sobre la combinación que proporciona el mejor rendimiento estimado. La función create model() se define para tomar dos argumentos optimizer e init, ambos de los cuales deben tener valores por defecto. Esto nos permitirá evaluar el efecto de usar diferentes algoritmos de optimización y esquemas de inicialización de peso para nuestra red. Después de crear nuestro modelo definimos vectores de valores para el parámetro que deseamos buscar, específicamente:
- Optimizadores para la búsqueda de valores de peso diferentes.
- Inicializadores para la preparación de las ponderaciones de red mediante esquemas diametralmente opuestos.
- Número de epoch para la formación del modelo para el número de exposiciones al conjunto de datos de formación.
- Lotes para variar el número de muestras antes de las actualizaciones de peso.
Las opciones se especifican en un diccionario y se pasan a la configuración de la clase GridSearchCV de scikit-learn. Esta clase evaluará una versión de nuestro modelo de red neural para cada combinación de parámetros (2 3 3 3 3) para las combinaciones de optimizadores, inicializaciones, epoch y batches. A continuación, cada combinación se evalúa utilizando el valor por defecto de 3-fold stratied
cross-validation.
Son muchos modelos y mucha computación. Este no es un plan que quieras usar a la ligera debido al tiempo que tardará en calcularse. Puede ser útil para que usted diseñe pequeños experimentos con un subconjunto más pequeño de sus datos que se completarán en un tiempo razonable. Este experimento es razonable en este caso debido a la pequeña red y el pequeño conjunto de datos (menos de 1.000 instancias y 9 atributos). Por último, el rendimiento y la combinación se muestran para el mejor modelo, seguido por el rendimiento de todas las combinaciones de parámetros.
#Búsqueda en Cuadrícula via scikit-learn from keras.models import Sequential from keras.layers import Dense from keras.wrappers.scikit_learn import KerasClassifier from sklearn.model_selection import GridSearchCV import numpy # funcion para crear el modelo, requerido por KerasClassifier def create_model(optimizer='rmsprop', init='glorot_uniform'): # crea el modelo model = Sequential() model.add(Dense(12, input_dim=8, kernel_initializer=init, activation='relu')) model.add(Dense(8, kernel_initializer=init, activation='relu')) model.add(Dense(1, kernel_initializer=init, activation='sigmoid')) # Compile model model.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy']) return model # ajusta la semilla random seed = 7 numpy.random.seed(seed) # carga los datos dataset = numpy.loadtxt("pima.csv", delimiter=",") # divide los input entre (X) y salida de (Y) variables X = dataset[:,0:8] Y = dataset[:,8] # crea el modelo model = KerasClassifier(build_fn=create_model, verbose=0) # busqueda en la cuadricula, epochs, batch size y optimizer optimizers = ['rmsprop', 'adam'] inits = ['glorot_uniform', 'normal', 'uniform'] epochs = [50, 100, 150] batches = [5, 10, 20] param_grid = dict(optimizer=optimizers, epochs=epochs, batch_size=batches, init=inits) grid = GridSearchCV(estimator=model, param_grid=param_grid) grid_result = grid.fit(X, Y) # resultados print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_)) means = grid_result.cv_results_['mean_test_score'] stds = grid_result.cv_results_['std_test_score'] params = grid_result.cv_results_['params'] for mean, stdev, param in zip(means, stds, params): print("%f (%f) with: %r" % (mean, stdev, param))
Esto puede tardar unos 5 minutos en completarse en la CPU de su PC. Podemos ver que la búsqueda en cuadrícula descubrió que utilizando un esquema de inicialización uniforme, el optimizador rmsprop, 150 epochs y un batch_size de 5 alcanzaba la mejor puntuación de validación cruzada de aproximadamente el 75% en este problema.
Best: 0.748698 using {'batch_size': 5, 'epochs': 150, 'init': 'uniform', 'optimizer': 'rmsprop'} 0.691406 (0.015947) with: {'batch_size': 5, 'epochs': 50, 'init': 'glorot_uniform', 'optimizer': 'rmsprop'} 0.682292 (0.046146) with: {'batch_size': 5, 'epochs': 50, 'init': 'glorot_uniform', 'optimizer': 'adam'} 0.704427 (0.017566) with: {'batch_size': 5, 'epochs': 50, 'init': 'normal', 'optimizer': 'rmsprop'} 0.707031 (0.020915) with: {'batch_size': 5, 'epochs': 50, 'init': 'normal', 'optimizer': 'adam'} 0.716146 (0.012075) with: {'batch_size': 5, 'epochs': 50, 'init': 'uniform', 'optimizer': 'rmsprop'} 0.718750 (0.005524) with: {'batch_size': 5, 'epochs': 50, 'init': 'uniform', 'optimizer': 'adam'} 0.697917 (0.015733) with: {'batch_size': 5, 'epochs': 100, 'init': 'glorot_uniform', 'optimizer': 'rmsprop'} 0.674479 (0.043303) with: {'batch_size': 5, 'epochs': 100, 'init': 'glorot_uniform', 'optimizer': 'adam'} 0.734375 (0.019401) with: {'batch_size': 5, 'epochs': 100, 'init': 'normal', 'optimizer': 'rmsprop'} 0.729167 (0.016053) with: {'batch_size': 5, 'epochs': 100, 'init': 'normal', 'optimizer': 'adam'} 0.726563 (0.016573) with: {'batch_size': 5, 'epochs': 100, 'init': 'uniform', 'optimizer': 'rmsprop'} 0.748698 (0.022628) with: {'batch_size': 5, 'epochs': 100, 'init': 'uniform', 'optimizer': 'adam'} 0.701823 (0.041504) with: {'batch_size': 5, 'epochs': 150, 'init': 'glorot_uniform', 'optimizer': 'rmsprop'} 0.694010 (0.045368) with: {'batch_size': 5, 'epochs': 150, 'init': 'glorot_uniform', 'optimizer': 'adam'} 0.729167 (0.021236) with: {'batch_size': 5, 'epochs': 150, 'init': 'normal', 'optimizer': 'rmsprop'} 0.743490 (0.014382) with: {'batch_size': 5, 'epochs': 150, 'init': 'normal', 'optimizer': 'adam'} 0.748698 (0.017566) with: {'batch_size': 5, 'epochs': 150, 'init': 'uniform', 'optimizer': 'rmsprop'} 0.726563 (0.011500) with: {'batch_size': 5, 'epochs': 150, 'init': 'uniform', 'optimizer': 'adam'} 0.657552 (0.028940) with: {'batch_size': 10, 'epochs': 50, 'init': 'glorot_uniform', 'optimizer': 'rmsprop'} 0.648438 (0.016573) with: {'batch_size': 10, 'epochs': 50, 'init': 'glorot_uniform', 'optimizer': 'adam'} 0.686198 (0.006639) with: {'batch_size': 10, 'epochs': 50, 'init': 'normal', 'optimizer': 'rmsprop'} 0.701823 (0.020505) with: {'batch_size': 10, 'epochs': 50, 'init': 'normal', 'optimizer': 'adam'} 0.703125 (0.019918) with: {'batch_size': 10, 'epochs': 50, 'init': 'uniform', 'optimizer': 'rmsprop'} 0.695313 (0.012758) with: {'batch_size': 10, 'epochs': 50, 'init': 'uniform', 'optimizer': 'adam'} 0.680990 (0.034401) with: {'batch_size': 10, 'epochs': 100, 'init': 'glorot_uniform', 'optimizer': 'rmsprop'} 0.559896 (0.168357) with: {'batch_size': 10, 'epochs': 100, 'init': 'glorot_uniform', 'optimizer': 'adam'} 0.694010 (0.043067) with: {'batch_size': 10, 'epochs': 100, 'init': 'normal', 'optimizer': 'rmsprop'} 0.727865 (0.017566) with: {'batch_size': 10, 'epochs': 100, 'init': 'normal', 'optimizer': 'adam'} 0.733073 (0.015733) with: {'batch_size': 10, 'epochs': 100, 'init': 'uniform', 'optimizer': 'rmsprop'} 0.701823 (0.012890) with: {'batch_size': 10, 'epochs': 100, 'init': 'uniform', 'optimizer': 'adam'} 0.694010 (0.011201) with: {'batch_size': 10, 'epochs': 150, 'init': 'glorot_uniform', 'optimizer': 'rmsprop'} 0.704427 (0.025780) with: {'batch_size': 10, 'epochs': 150, 'init': 'glorot_uniform', 'optimizer': 'adam'} 0.746094 (0.022999) with: {'batch_size': 10, 'epochs': 150, 'init': 'normal', 'optimizer': 'rmsprop'} 0.705729 (0.012890) with: {'batch_size': 10, 'epochs': 150, 'init': 'normal', 'optimizer': 'adam'} 0.744792 (0.022628) with: {'batch_size': 10, 'epochs': 150, 'init': 'uniform', 'optimizer': 'rmsprop'} 0.722656 (0.014616) with: {'batch_size': 10, 'epochs': 150, 'init': 'uniform', 'optimizer': 'adam'} 0.583333 (0.141933) with: {'batch_size': 20, 'epochs': 50, 'init': 'glorot_uniform', 'optimizer': 'rmsprop'} 0.673177 (0.013279) with: {'batch_size': 20, 'epochs': 50, 'init': 'glorot_uniform', 'optimizer': 'adam'} 0.673177 (0.020256) with: {'batch_size': 20, 'epochs': 50, 'init': 'normal', 'optimizer': 'rmsprop'} 0.695312 (0.029232) with: {'batch_size': 20, 'epochs': 50, 'init': 'normal', 'optimizer': 'adam'} 0.694010 (0.018136) with: {'batch_size': 20, 'epochs': 50, 'init': 'uniform', 'optimizer': 'rmsprop'} 0.694010 (0.019225) with: {'batch_size': 20, 'epochs': 50, 'init': 'uniform', 'optimizer': 'adam'} 0.667969 (0.039192) with: {'batch_size': 20, 'epochs': 100, 'init': 'glorot_uniform', 'optimizer': 'rmsprop'} 0.683594 (0.017758) with: {'batch_size': 20, 'epochs': 100, 'init': 'glorot_uniform', 'optimizer': 'adam'} 0.709635 (0.010253) with: {'batch_size': 20, 'epochs': 100, 'init': 'normal', 'optimizer': 'rmsprop'} 0.709635 (0.009744) with: {'batch_size': 20, 'epochs': 100, 'init': 'normal', 'optimizer': 'adam'} 0.705729 (0.012075) with: {'batch_size': 20, 'epochs': 100, 'init': 'uniform', 'optimizer': 'rmsprop'} 0.710938 (0.025315) with: {'batch_size': 20, 'epochs': 100, 'init': 'uniform', 'optimizer': 'adam'} 0.678385 (0.016053) with: {'batch_size': 20, 'epochs': 150, 'init': 'glorot_uniform', 'optimizer': 'rmsprop'} 0.703125 (0.024080) with: {'batch_size': 20, 'epochs': 150, 'init': 'glorot_uniform', 'optimizer': 'adam'} 0.729167 (0.026557) with: {'batch_size': 20, 'epochs': 150, 'init': 'normal', 'optimizer': 'rmsprop'} 0.720052 (0.038051) with: {'batch_size': 20, 'epochs': 150, 'init': 'normal', 'optimizer': 'adam'} 0.720052 (0.021710) with: {'batch_size': 20, 'epochs': 150, 'init': 'uniform', 'optimizer': 'rmsprop'} 0.723958 (0.012890) with: {'batch_size': 20, 'epochs': 150, 'init': 'uniform', 'optimizer': 'adam'}
Resumen del post
En esta lección usted descubrió cómo puede envolver sus modelos de Deep Learning en Keras y utilizarlos en la biblioteca de Machine Learning de scikit-learn. Aprendiste:
- Específicamente cómo envolver los modelos Keras para que puedan ser usados con el scikit-learn biblioteca de Machine Learning.
- Cómo usar un modelo Keras envuelto como parte de la evaluación del rendimiento del modelo en scikit-learn.
- Cómo realizar la sintonización de hiperparámetros en scikit-learn usando un modelo de Keras envuelto.
Usted puede ver que el uso de scikit-learn para las operaciones de Machine Learning, tales como la evaluación del modelo y la optimización de hiperparámetros del modelo pueden ahorrar mucho tiempo.
➡ ¿Quieres aprender mas de Deep Learning? Ingresa a nuestro curso:
[…] permite usar modelos de redes neuronales desarrollados con Keras en scikit-learn como vimos en el post anterior. Hay una clase de keras el KerasClassifier que puede ser usada como un Estimador en scikit-learn, […]
[…] permite usar modelos de redes neuronales desarrollados con Keras en scikit-learn como vimos en el post anterior. Hay una clase de keras el KerasClassifier que puede ser usada como un Estimador en scikit-learn, […]