¿Cómo mejorar el rendimiento del modelo CNN para un conjunto de datos

¿Cómo mejorar el rendimiento del modelo CNN para un conjunto de datos específico? Obtención de baja precisión tanto en el entrenamiento como en el conjunto de datos de prueba

Nos dieron una tarea en la que se suponía que debíamos implementar nuestra propia red neuronal y otras dos redes neuronales ya desarrolladas. Lo hice y, sin embargo, este no es el requisito de la tarea, pero aún así me gustaría saber cuáles son los pasos/procedimientos que puedo seguir para mejorar la precisión de mis modelos.

Soy bastante nuevo en Deep Learning y Machine Learning en general, así que no tengo mucha idea.

El conjunto de datos proporcionado contiene un total de 15 clases (avión, silla, etc.) y se nos proporcionan alrededor de 15 imágenes de cada clase en el conjunto de datos de entrenamiento. El conjunto de datos de prueba tiene 10 imágenes de cada clase.

El repositorio completo de github de mi código se puede encontrar aquí (archivo de Jupyter Notebook): https:/ /github.com/hassanashas/Deep-Learning-Modelos

Primero lo probé con mi propia CNN (hice uno usando tutoriales de Youtube). El código es el siguiente,

X_train = X_train/255.0
model = Sequential()

model.add(Conv2D(64, (3, 3), input_shape = X_train.shape[1:]))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(128, (3, 3)))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(64))

model.add(Dense(16)) # added 16 because it model.fit gave error on 15 
model.add(Activation('softmax'))

Para la compilación del Modelo,

from tensorflow.keras.optimizers import SGD

model.compile(loss='sparse_categorical_crossentropy', 
             optimizer=SGD(learning_rate=0.01), 
             metrics=['accuracy'])

Utilicé una entropía cruzada categórica dispersa porque mi etiqueta "y" tenía valores enteros, que iban del 1 al 15.

Ejecuté este modelo de la siguiente manera,

model_fit = model.fit(X_train, y_train, batch_size=32, epochs=30, validation_split=0.1)

Me dio una precisión de 0.2030 en training dataset y solo 0.0733 en testing dataset (ambos conjuntos de datos están presentes en el repositorio de github)

Luego, probé AlexNet CNN (seguí un tutorial de Youtube para su código)

Ejecuté AlexNet en el mismo conjunto de datos durante 15 épocas. Mejoró la precisión en el conjunto de datos de entrenamiento a 0.3317, sin embargo, la precisión en el conjunto de datos de prueba fue incluso peor que la de mi propia CNN, con solo 0.06

Después, probé el VGG16 CNN, nuevamente siguiendo un Tutorial de Youtube.

Ejecuté el código en Google Colab durante 10 Epochs. Se las arregló para mejorar al 100 % de precisión en training dataset en la octava época. Pero este modelo dio la peor precisión de los tres en el conjunto de datos de prueba con solo 0.0533

No puedo entender este comportamiento contrastante de todos estos modelos. He probado diferentes valores de época, funciones de pérdida, etc. pero los actuales dieron relativamente el mejor resultado. Mi propia CNN pudo obtener una precisión del 100 % cuando la ejecuté en 100 epochs (sin embargo, dio resultados muy deficientes en el conjunto de datos de prueba)

¿Qué puedo hacer para mejorar el rendimiento de estos modelos? Y específicamente, ¿cuáles son las pocas cosas cruciales que uno siempre debe tratar de seguir para mejorar la eficiencia de un modelo de aprendizaje profundo? Busqué varias preguntas similares en Stackoverflow, pero casi todas estaban trabajando en conjuntos de datos proporcionados por tensorflow, como el conjunto de datos mnist, etc., y no encontré mucha ayuda en ellos.

Mostrar la mejor respuesta

¿Sobreequipamiento quizás?

Dos observaciones. (1) Su conjunto de datos se siente muy pequeño (15 imágenes por clase para entrenar), que pueden ser muy pocos datos de entrenamiento para que una red aprenda. (2) El 100 % de precisión en los datos de entrenamiento es un indicador de que el modelo se ha sobreajustado. Básicamente significa que la red memorizó los datos de entrenamiento pero no pudo aprender ningún patrón significativo, por lo que es básicamente aleatorio para los datos de prueba.

@Hassan Ashas ¿Conseguiste mejorar la precisión? ¿Qué técnicas aplicó y cuál fue su resultado? Creo que puede ser útil compartir esta información para futuros lectores.

Descargo de responsabilidad: han pasado algunos años desde que jugué con CNN, por lo que solo puedo transmitir algunos consejos y sugerencias generales.

En primer lugar, me gustaría hablar sobre los resultados que ha obtenido hasta ahora. Las dos primeras redes que entrenaste parecen al menos aprender algo de los datos de entrenamiento porque funcionan mejor que adivinar al azar.

Sin embargo: el rendimiento de los datos de prueba indica que la red no ha aprendido nada significativo porque esos números sugieren que la red es tan buena (o solo marginalmente mejor) que una suposición aleatoria.

En cuanto a la tercera red: la alta precisión de los datos de entrenamiento combinada con la baja precisión de los datos de prueba significa que su red se ha sobreajustado. Esto significa que la red ha memorizado los datos de entrenamiento pero no ha aprendido ningún patrón significativo.

No tiene sentido continuar entrenando una red que ha comenzado a sobreajustarse. Entonces, una vez que la precisión del entrenamiento aumenta y la precisión de la prueba disminuye durante algunas épocas consecutivas, puede detener el entrenamiento.

Aumentar el tamaño del conjunto de datos

Las redes neuronales se basan en una gran cantidad de buenos datos de entrenamiento para aprender patrones. Su conjunto de datos contiene 15 clases con 15 imágenes cada una, que son muy pocos datos de entrenamiento.

Por supuesto, sería genial si pudiera obtener datos de entrenamiento de alta calidad adicionales para expandir su conjunto de datos, pero eso no siempre es factible. Entonces, un enfoque diferente es expandir artificialmente su conjunto de datos. Puede hacer esto fácilmente aplicando un montón de transformaciones a los datos de entrenamiento originales. Piense en: duplicar, rotar, hacer zoom y recortar.

Recuerde no solo aplicar estas transformaciones a la ligera, ¡deben tener sentido! Por ejemplo, si desea que una red reconozca una silla, ¿también desea que reconozca las sillas que están al revés? O para detectar señales de tráfico: reflejarlas no tiene sentido porque el texto, los números y los gráficos nunca aparecerán reflejados en la vida real.

A partir de la breve descripción de las clases que tiene (aviones, sillas y todo eso...), creo que duplicar horizontalmente podría ser la mejor transformación para aplicar inicialmente. Eso ya duplicará el tamaño de tu conjunto de datos de entrenamiento.

Además, tenga en cuenta que un conjunto de datos inflado artificialmente nunca es tan bueno como uno del mismo tamaño que contiene todas las imágenes auténticas y reales. Una imagen reflejada contiene gran parte de la misma información que su original, simplemente esperamos que retrase el sobreajuste de la red y esperamos que aprenda los patrones importantes en su lugar.

Reducir la tasa de aprendizaje

Esta es una pequeña nota al margen, pero intente reducir la tasa de aprendizaje. Su red parece sobreajustarse en solo unas pocas épocas, lo cual es muy rápido. Obviamente, reducir la tasa de aprendizaje no combatirá el sobreajuste, pero ocurrirá más lentamente. Esto significa que, con suerte, puede encontrar una época con un mejor rendimiento general antes de que se produzca el sobreajuste.

Tenga en cuenta que una tasa de aprendizaje más baja nunca hará que una red con mal rendimiento sea buena por arte de magia. Es solo una forma de ubicar un conjunto de parámetros que funciona un poco mejor.

Aleatorizar el orden de los datos de entrenamiento

Durante el entrenamiento, los datos de entrenamiento se presentan en lotes a la red. Esto sucede a menudo en un orden fijo en todas las iteraciones. Esto puede dar lugar a ciertos sesgos en la red.

En primer lugar, asegúrese de que los datos de entrenamiento se mezclan al menos una vez. No desea presentar las clases una por una, por ejemplo, primero todas las imágenes de aviones, luego todas las sillas, etc. Esto podría llevar a que la red desaprendiera gran parte de la primera clase al final de cada época.

Además, reorganiza los datos de entrenamiento entre épocas. De nuevo, esto evitará posibles sesgos menores debido al orden de los datos de entrenamiento.

Mejorar el diseño de la red

Ha diseñado una red neuronal convolucional con solo dos capas de convolución y dos capas completamente conectadas. Tal vez este modelo sea demasiado superficial para aprender a diferenciar entre las diferentes clases.

Sepa que las capas de convolución tienden a captar primero pequeñas características visuales y luego tienden a combinarlas en patrones de nivel superior. Entonces, tal vez agregar una tercera capa de convolución podría ayudar a la red a identificar patrones más significativos.

Obviamente, el diseño de redes es algo con lo que tendrá que experimentar y hacer que las redes sean demasiado profundas o complejas también es un escollo que hay que tener en cuenta.