1 votos

Implementación del ajuste automático de hiperparámetros dentro de un bucle de validación cruzada manual

Tengo varias preguntas que voy a tratar de agrupar en una sola aquí. Actualmente estoy tratando de implementar el entrenamiento de redes neuronales convolucionales en un conjunto de datos de imágenes públicas. Estoy tratando de probar y comparar varias arquitecturas CNN diferentes, por ejemplo, InceptionV3, ResNet, DenseNet, y algunos otros. Para ello, estoy tratando de mantener todo lo demás en el código y el enfoque constante, sólo cambiando la arquitectura. Estoy utilizando una validación cruzada de 5 veces con un conjunto de pruebas de retención del 20%.

Sin embargo, me encuentro con el reto de implementar el ajuste automatizado de los hiperparámetros. Mi código está diseñado de la siguiente manera.

  1. Dividir los datos en entrenamiento (80%) y prueba (20%)
  2. Crear KFolds (n=5) a partir de los datos del tren (80% tren, 20% val para cada pliegue).
  3. Bucle For que itera a través de cada pliegue.
  4. Dentro del bucle for, estoy usando una función personalizada de data_aumentation que toma los datos X_train, X_val, y_train, y_val, y aumenta los datos de entrenamiento usando ImageDataGenerator().
  5. Ajustar el modelo en cada pliegue, guardar el modelo con mejor rendimiento por val_loss.
  6. Ensamblar los modelos y evaluarlos en el conjunto de pruebas (retención inicial del 20%).

Estoy utilizando la API funcional de Keras para la creación de mi modelo. Actualmente estoy estableciendo los hiperparámetros manualmente antes de los pasos de ajuste del modelo + CV.

Así que a mis preguntas:

  1. Mi pregunta principal es ¿cuál es el mejor enfoque a partir de aquí para implementar el ajuste automatizado de los hiperparámetros? He encontrado algunas APIs diferentes como hype-tune, pero todas parecen a) no funcionar bien con la API funcional de Keras, o b) tener validación cruzada incorporada, por lo que no puedo usar mi propia función de validación cruzada que he construido.

  2. Además, quiero comprobar lo que entiendo que debería ocurrir con el ajuste automatizado: ¿es tan sencillo como que los pasos 2-5 anteriores se repitan para cada conjunto de hiperparámetros candidatos, y luego se tome el rendimiento medio (val_loss) de todos los pliegues y se seleccione el conjunto de hiperparámetros con el menor val_loss medio?

  3. Para cualquiera que responda a la pregunta 1), ¿hay alguna forma de hacer el ajuste de hiperparámetros más sofisticado (bayesiano, descenso de gradiente, algoritmos evolutivos)?

  4. ¿Es éste, en general, un enfoque razonable del problema? ¿Hay algún mérito en reconsiderar CV+holdout, en lugar de hacer algo como la validación cruzada anidada?

Mi código correspondiente:

Función de aumento de datos:

def data_aug(X_train,X_test,y_train,y_test,train_batch_size,test_batch_size):
train_datagen = ImageDataGenerator(
    rotation_range=60,
    # rescale=1.0/255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    vertical_flip=True,
    fill_mode='nearest')
test_datagen = ImageDataGenerator()  # nothing applied to test dataset
train_batch = train_datagen.flow(X_train,y_train,batch_size=train_batch_size, seed=33)
test_batch = test_datagen.flow(X_test,y_test,batch_size=test_batch_size, seed=33)
return (train_batch,test_batch)

Función de validación cruzada

kfold = KFold(n_splits=5, shuffle=True, random_state=33)

cvscores = []
Fold = 1
for train, val in kfold.split(X_train_all, y_train_all):
    gc.collect()
    K.clear_session()
    print ('Fold: ',Fold)

    X_train = X_train_all[train]
    X_val = X_train_all[val]
    X_train = X_train.astype('float32')
    X_val = X_val.astype('float32')
    y_train = y_train_all[train]
    y_val = y_train_all[val]

    # Data Augmentation and Normalization
    train_batch, val_batch = data_aug(X_train,X_val,y_train,y_val, batch_size, batch_size)

    # If model checkpoint is used UNCOMMENT THIS
    model_name = 'cnn_keras_Fold_'+str(Fold)+'.h5'

    cb = callback()

    # create model
    model = create_model()      # CUSTOM ARCHITECTURE

    # Fit generator for Data Augmentation - UNCOMMENT THIS FOR DATA AUGMENTATION
    model.fit(train_batch, 
              validation_data=val_batch, 
              epochs=epochs, 
              validation_steps= X_val.shape[0] // batch_size, 
              steps_per_epoch= X_train.shape[0] // batch_size, 
              callbacks=cb, 
              verbose=2)

    # evaluate the model
    scores = model.evaluate(X_val, y_val, verbose=0)
    print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
    cvscores.append(scores[1] * 100)

    Fold += 1

print("%s: %.2f%%" % ("Mean Accuracy: ",np.mean(cvscores)))
print("%s: %.2f%%" % ("Standard Deviation: +/-", np.std(cvscores)))

0voto

Mariam Elosta Puntos 49

He creado un paquete que puede darte algunas ideas.

Está hecho para trabajar con estimadores del tipo sklearn, así que no creo que esté preparado para ser usado con keras. Pero usted puede echar un vistazo, tal vez usted consigue una idea para su configuración:

https://github.com/JaimeArboleda/nestedcvtraining/blob/master/README.md

Mi enfoque consiste en utilizar un esquema de CV anidado, construyendo conjuntos de modelos internos (o ajustando un único modelo) y estimando la calidad en el bucle externo. Está preparado para optimizar los hiperparámetros (y los parámetros del post-proceso) utilizando el enfoque bayesiano con la biblioteca skopt.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X