Hasta ahora solo hemos usado explícitamente modelos secuenciales (donde las capas conectan directa y linealmente), para esta ocasión estamos manejando un modelo funcional, por lo que la conexión de capas debe ser explícita.
Conectando las nuevas capas
Anteriormente cortamos la configuración de InceptionV3 en el mixed7 para considerarlo nuestra última capa no entrenable.
Ahora la conectaremos con nuestras capas personalizadas. Recuerda que como manejamos un modelo funcional, debemos expresar explícitamente desde cuál capa viene conectada, esto lo haremos con la notación de paréntesis al final de la definición de cada objeto.
Aplanaremos todos los datos desde una capa flatten, agregaremos una capa densa de 128 neuronas con activación relu y un dropout de 20%, finalmente definiremos la nueva salida con 24 neuronas de activación softmax (la configuración original trae 1000 posibles outputs pero podemos personalizarla a voluntad).
Con todas las capas conectadas, definiremos el modelo final con la clase Model de Keras, esta recibirá el inicio y el final del modelo.
Al compilar y resumir el modelo podemos notar que todas las capas después de mixed7 no existen, además de que la cantidad de parámetros bajó de casi 22 millones a casi 14, además solo 5 son entrenables (lo que reducirá la complejidad del modelo).
Total params:13,795,384Trainable params:4,820,120Non-trainable params:8,975,264
Entrenando el nuevo modelo
Entrenaremos el nuevo modelo con los nuevos generadores durante 5 épocas. Notarás que el entrenamiento durará mucho más tiempo pero no tendremos que crear las abstracciones del modelo desde 0.
Podemos notar que incluso después de la primer iteración el accuracy y val_accuracy mantuvieron un tiempo de entrenamiento excelente, donde en la épica final tuvimos una aproximación total en entrenamiento, una pérdida mínima y una precisión en validación del 98.95%.
The gradient, que es una revista de inteligencia artificial, habla de que ya hay modelos muy potentes pero que que toman mucho su tiempo, por eso ya se habla de models Fundation, modelos pre entrenados que son pontentes para que sean llevados a otras areas de conocimiento
Gracias por los aportes Fredy !!.. estan muy buenos!!
gracias bro
No había comentado en las clases anteriores, pero este curso está EXCELENTE!!!
Pienso lo mismo, al ver el potencial de las redes neuronales prácticamente no hay limites.
¿Cómo decido a partir de dónde romper el modelo y realizar la configuración final para la clasificación?
Ej. en este caso detuvimos el model en mixed7, ¿por qué ahì?
Hola Itzá Alejandra,
Es una excelente pregunta porque no hay una respuesta absoluta, realmente depende de la perspectiva y el conocimiento del creado de la red neuronal.
Pero tenemos que tener varios conceptos claros para poder sacarle provecho y conocer en que lugar detener nuestra red pre entrenada. La red pre entrenada la utilizamos para poder aprovechar toda las capas enfocadas en extraer características principales, esto quiere decir que las primeras capas son las que realmente nos interesa tener. El segundo concepto importante es entender que cada red pre entrenada tiene una configuración diferente (Debemos entenderla y analizarla), en la mayoría de los casos vamos a tener convoluciones y filtros pooling, estas convoluciones y filtros pooling van a reducir el tamaño de la imagen (te recomiendo mucho el curso de curso de redes neuronales convoluciones con Python y Keras).
Y por último la capa al final de la extracción de características se le conoce como la capa cuello de botella, la forma de reconocerla es porque viene antes de una capa flatten, después de esta capa ya viene el modelo clasificador (Las capas totalmente conectadas).
Ahora analicemos nuestro caso puntual, iniciamos con una imagen de 150, 150, 3, y en nuestro caso utilizamos el modelo pre entrenado Inception v3; la capa de cuello de botella es la capa 3x3x320 ya es la ultima capa de características, pero para MI perspectiva, el mapa de características 3x3 ya es muy pequeño, por eso lo detuvimos en 7x7 para mantener un mapa de características suficientemente grande. Sin embargo como tú sabes en las redes neuronales no hay nada escrito. Seria muy interesante si lo detienes en la 3x3 y vuelves a entrenar la red y nos cuenta si mejora o empeora el sistema.
Resumen de proceso:
Analiza la arquitectura de la red pre entrenada.
Busca el cuello de botella de la red (Ultima capa antes de la capa flatten y totalmente conectada)
Decide si tomar quizás la capa de cuello de botella o mejor un par de capas arriba para que mantengas un mapa de características lo suficientemente grande.
Me cuentas, saludos
El calculo de los weights en estas redes solo se efectua en las redes que yo defino, es asi?
Es correcto, en las capas que asignaste como verdadero la variable training (training=True)
¿Podría cortar el modelo en una capa diferente a un mixed? Por ejemplo cortarlo en un Conv2D.
Claro usted puede cortarlo en cualquier capa inclusive en la InputLayer que es la inicial.
Decidí usar un dataset para clasificar imágenes sísmicas (350 imagenes aprox en total). El mejor resultado de val_accuracy que obtuve fue de 0.62. Con Transfer Learning usando InceptionV3 llegó hasta 0.86 (usando la misma cantidad de épocas, 20). Que tema tan interesante
En paralelo estos siguiendo el proyecto de clasificación de tumores, hice uso del modelo NASNetLarge, pero al parecer necesito entender cómo aplicarlo mejor, ya que no logré mejorar el 60% de accuracy.
A mi me acaba de pasar lo mismo
Me paso algo similar con el mismo dataset, lograste mejorarlo?
Hola, llevo todo el curso con una duda en mente, a ver si alguien es capaz de respondérmela:
No se supone que de esta manera contaminamos el entrenamiento con datos que supuestamente el modelo no debería ver? Mis sospechas se reafirman con lo siguiente: parece ser que el "test accuracy" es mayor que el "validation accuracy", cosa que puede suceder pero resulta inquietante:
Un saludo y gracias de antemano!
Hola Julen Alvaro,
Excelente pregunta, y para resolverla voy a explicar el funcionamiento de cada una de las bases de datos y con un ejemplo clásico:
Vamos a replicar la forma en la que entrenamos la red neuronal con la forma en la que le enseñamos a un niño a diferenciar entre un carro y una moto.
Tenemos un álbum de fotos de carros y motos (1000 en total), dividimos 700 imágenes a una carpeta de entrenamiento, 150 a una de validación y 150 a una de testeo.
También es importante entender que son los epoch, para una red neuronal sería cada vez que hacemos forward y backward propagation (Recalculamos los pesos de la base de datos, buscando reducir el error), y en nuestro caso del niño veámoslo como una clase.
Vamos a decir que tenemos 10 epochs (10 clases con el niño)
Bases de datos de entrenamiento - Única base de datos con la que se entrena el modelo. Carpeta de carros y motos se las mostramos a nuestro niño en aprendizaje.
Bases de datos de validación - Base de datos que se utilizara al final de cada epoch (Clase con el niño) para verificar que tanto ha generalizado el modelo con datos que no conoce. (Ver que tan bueno es el niño en clasificar carros y motos con imágenes que no conoce)
Bases de datos de test - Se utilizan únicamente al final para verificar que tan bueno es nuestro modelo. (Veámoslo como un examen final para el niño, en donde tomamos el tercer álbum y le mostramos todos los ejemplos y medimos que tanto aprendió)
Entendiéndola así, podríamos decir que la clase de validación son datos nuevos (No se usan en entrenamiento) que nos permiten ver que tan buena es nuestra red neuronal durante el proceso de entrenamiento. Como profesor en la clase del niño, podrias entender como es el progreso o avance del niño en su aprendizaje.
Y nuestros datos de test también son datos nuevos (No se utilizan en entrenamiento) nos permite ver que tan buena es nuestra red neuronal al final de todo el entrenamiento.
Me cuentas si es más claro.
Saludos y Feliz año nuevo.
Hola Adonaí,
Gracias por tu respuesta, muy buena la analogía con el niño y las clases. No obstante mi duda persiste:
Como se puede observar en la captura del código, tanto el validation_generator como el test_generator hacen referencia al mismo directorio. Salvo que haya algo que se me esté escapando, me parece que el ImageDataGenerator va a tomar aleatoriamente archivos del test_dir y se van a mezclar, contaminando la fase de validación con archivos que después se usarán en la fase de test.
Opino que tendríamos que crear un validation_dir o en su defecto utilizar alguna función tfds.load() de tf para separar las imágenes de test_dir en dos grupos y asegurar que no se mezclen entre ellas. Dime por favor si me equivoco y si estamos teniendo esto en cuenta en alguna parte del código y no me estoy dando cuenta.
Mil gracias y feliz año!
Hola Adonai espero te encuentres bien. Yo tengo una duda algo técnica. Tengo una GPU con bastantes núcleos, cómo les saco provecho? Justo en esta clase me di cuenta con el monitoreo que ahora que hay más parámetros usó el 50 % (cosa que no pasaba antes), por lo tanto, el uso de los núcleos está relacionado con la cantidad de parámetros/operaciones? Saludos.
Hola Adrian
Si tienes una GPU con muchos núcleos, puedes aprovechar su potencia paralelizando el entrenamiento. La GPU puede realizar operaciones en paralelo, lo que es útil para tareas que implican cálculos intensivos, como los que ves en esta clase, es importante recordar que debes instalar las versiones compatibles de TensorFlow, CUDA, CuDNN y todos los drivers respectivos para que el computador y TF pueda acceder a la tarjeta grafica.
Respecto al consumo de GPU, el porcentaje de uso de la GPU está relacionado con la cantidad de parámetros y operaciones que estás realizando. A medida que aumentan, la GPU trabaja más y el uso de los núcleos aumenta. Sin embargo, un bajo uso de los núcleos no es necesariamente malo, puede haber limitaciones en el código o la carga de trabajo.
Espero que esta respuesta te sea útil, ¡y si tienes más preguntas, estaré encantado de ayudarte!
Hola Adonaí, como estás?
Antes que nada comentarte que es excelente el curso, tanto contenido, como tu dinámica para explicar.
Quería hacerte una consulta
en esta línea model_keras = tf.keras.Model(pre_trained_model.input, x)
cuando estamos indicando el comienzo del modelo hasta donde termina, ¿como identifica que tiene que llegar hasta la capa mixed 7? . Gracias.
Estás creando un nuevo modelo model_keras utilizando la entrada del modelo pre-entrenado (pre_trained_model.input) y una nueva salida x. Sin embargo, la conexión con la capa "mixed7" se realiza en las líneas anteriores, donde obtienes la salida de esa capa específica y luego construyes nuevas capas a partir de esa salida.
Utilizas pre_trained_model.get_layer('mixed7') para obtener la capa "mixed7" del modelo pre-entrenado.
Luego, obtienes la salida de esa capa con last_layer.output.
A continuación, construyes nuevas capas (Flatten, Dense, Dropout, Dense) a partir de la salida de la capa "mixed7" (last_output).
Por lo tanto, en realidad estás especificando manualmente hasta qué capa del modelo pre-entrenado deseas utilizar, y luego agregas tus propias capas después de esa capa. Esto te permite aprovechar las características aprendidas por el modelo pre-entrenado en las capas anteriores, mientras personalizas las capas finales para tu tarea específica de clasificación.
Espero que esta explicación te ayude a entender cómo se conecta la capa "mixed7" en tu modelo.
Si tienes alguna otra pregunta o necesitas más clarificaciones, ¡no dudes en preguntar!
Y gracias por tu comentario, feliz de leerlo.
yo use InceptionV3,NASNetMobile y no me funcionaba para mi data sets de 120-dog-breed-image-classification sin embargo me decidi usar NASNetLarge y si veo que se tarda mucho.
Sin embargo con InceptionV3 el accuracy me llego a 0.8 el val_accuracy me llegaba hasta 0.5 en 120 epocas
con NASNetLarge en la epocca 7 me comenzo a dar accuracy 0.8 y val_accuracy 0.8
Lo que concluyo es que la arquitecura NASNetLarge con 7 epocas tardo menos que la inveptionv3 con 120.
Además le agregue unos callbacks [ModelCheckpoiont, EarlyStpping, ReduceLROnPlateau]
En mi caso, pase de tener un val_accuracy de 71% a uno de 92% un cambio realmente sorprendente. 🤣
Definir el Modelo de Keras:
Utiliza Keras para definir tu modelo de aprendizaje profundo. Puedes usar cualquier modelo que desees, como InceptionResNetV2, VGG16, etc.
Agrega las capas necesarias para tu tarea específica, como capas de convolución, capas de agrupamiento, capas completamente conectadas