El código usado para crear los TFRecords está basado en TensorFlow 1.x, esta versión de TensorFlow no debería ser usada para nuevos proyectos, aquí les preparé una implementación con TensorFlow 2.x si tienen comentarios y/o correcciones, son bienvenidos:
def class_text_to_int(row_label):if row_label ==MOTORCYCLE_LABEL:return1 elif row_label ==CAR_LABEL:return2else:returnNonedef split(df, group):""" Create a namedtuple with the filename and all data related to cars
and/or motorcycles found on the picture"""
data =namedtuple('data',['filename','object']) gb = df.groupby(group) # group DataFrame by filename
return[data(filename, gb.get_group(x))for filename, x inzip(gb.groups.keys(), gb.groups)]def create_tf_example(group, path):""" Create TFRecord files""" image = tf.keras.utils.load_img(os.path.join(DATASET_PATH, group.filename)) width, height = image.size image_format = image.format.encode('utf8') image = tf.io.encode_jpeg(tf.keras.utils.img_to_array(image)) filename = group.filename.encode('utf8') # check if the image format is matching with your images.xmins=[] xmaxs =[] ymins =[] ymaxs =[] classes_text =[] classes =[]for index, row in group.object.iterrows(): xmins.append(row['xmin']/ width) xmaxs.append(row['xmax']/ width) ymins.append(row['ymin']/ height) ymaxs.append(row['ymax']/ height) classes_text.append(row['classname'].encode('utf8')) classes.append(class_text_to_int(row['classname'])) tf_example = tf.train.Example(features=tf.train.Features(feature={'image/height': dataset_util.int64_feature(height),'image/width': dataset_util.int64_feature(width),'image/filename': dataset_util.bytes_feature(filename),'image/source_id': dataset_util.bytes_feature(filename),'image/encoded': dataset_util.bytes_feature(image.numpy()),'image/format': dataset_util.bytes_feature(image_format),'image/object/bbox/xmin': dataset_util.float_list_feature(xmins),'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs),'image/object/bbox/ymin': dataset_util.float_list_feature(ymins),'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs),'image/object/class/text': dataset_util.bytes_list_feature(classes_text),'image/object/class/label': dataset_util.int64_list_feature(classes),}))return tf_example
No me corre bien aun localmente, pero algunas cosas menores:
motos y carro los pusiste invertidos
¿seguro del cambio de "class" por "classname" en el for loop?
Muchas gracias por el código adaptado :)
# Es fundamental remplazar las clases con las mismas clases del proyecto.# Los nombres deben estar escritos exactamente igual.# Si existen más clases en tu proyecto agregarias un ELIF.defclass_text_to_int(row_label):if row_label =='carro':return1elif row_label =='moto':return2else:returnNonedefsplit(df, group):""" Create a namedtuple with the filename and all data related to cars
and/or motorcycles found on the picture""" data = namedtuple('data',['filename','object']) gb = df.groupby(group)# group DataFrame by filenamereturn[data(filename, gb.get_group(x))for filename, x inzip(gb.groups.keys(), gb.groups)]defcreate_tf_example(group, path):""" Create TFRecord files""" image = tf.keras.utils.load_img(os.path.join(path, group.filename)) width, height = image.size
image_format = image.format.encode('utf8') image = tf.io.encode_jpeg(tf.keras.utils.img_to_array(image)) filename = group.filename.encode('utf8')# check if the image format is matching with your images. xmins =[] xmaxs =[] ymins =[] ymaxs =[] classes_text =[] classes =[]for index, row in group.object.iterrows(): xmins.append(row['xmin']/ width) xmaxs.append(row['xmax']/ width) ymins.append(row['ymin']/ height) ymaxs.append(row['ymax']/ height) classes_text.append(row['class'].encode('utf8')) classes.append(class_text_to_int(row['class'])) tf_example = tf.train.Example(features=tf.train.Features(feature={'image/height': dataset_util.int64_feature(height),'image/width': dataset_util.int64_feature(width),'image/filename': dataset_util.bytes_feature(filename),'image/source_id': dataset_util.bytes_feature(filename),'image/encoded': dataset_util.bytes_feature(image.numpy()),'image/format': dataset_util.bytes_feature(image_format),'image/object/bbox/xmin': dataset_util.float_list_feature(xmins),'image/object/bbox/xmax': dataset_util.float_list_feature(xmaxs),'image/object/bbox/ymin': dataset_util.float_list_feature(ymins),'image/object/bbox/ymax': dataset_util.float_list_feature(ymaxs),'image/object/class/text': dataset_util.bytes_list_feature(classes_text),'image/object/class/label': dataset_util.int64_list_feature(classes),}))return tf_example
Con las correcciones de Omar. ¡Muchas gracias!
Proceso de instalación de la librería object detection:
Ejecutar esta linea para instalar la libreria object detection:
!pip install tensorflow-object-detection-api
esto resuelve el problema marcado en amarillo que aparece al copiar y pegar el contenido de "Converting from *.csv to *.record" en el enlace que comparte el profe
¿Por qué se dividen los x y y máximos y mínimos con la altura y anchura?
Hola Daniel
Muchas gracias por tomarte el tiempo de preguntar, excelente pregunta. En ese caso realizamos una normalización para que el bbox se encuentre entre 0 y 1.
Las x min y maximas las dividimos por el ancho y las y por la altura de esta forma cuando creemos el tfrecord file tendremos valores entre 0 y 1. Y esta es la entrada esperada del archivo tfrecord.
Saludos
En el minuto 8:40 donde se explica la variable path, se usa la función os.path.join() la cuál se usa para concanetar cadenas en formato ruta del sistema, por lo que si le mando, por ejemplo: "hola", "mundo" tendrás diferentes salidas de acuerdo al SO que uses, si usas windows tendrás: "hola\mundo", si usas linux o mac: "hola/mundo", sabiendo esto, sabes que no tiene sentido mandarse solo un parámetro como se hace en el video, por lo que debería ser elimida.
Mejoraría mucha la experiencia si se trabajará con Drive. Muchas veces no me sube el archivo zip donde estaban las fotos, no sé que pasaba pero muchas veces ni me cargaba. Así que voy a ver como me va cargando la información en drive
Hemos visto cuál sería el procedimiento para instalar la librería de Object Detection en Colab, pero cuál sería el procedimiento para una instalación local en PC?
cuando se refiere a dataset original se refiere al dataset del principio el que no estaba dividido en train , test? o en el ya esta filtrado?
Es correcto, el que no estaba dividido
Excelente ver el video final del curso en LinkedIn, muy buen trabajo Ivan Josue
Me genera un error de sintaxis y solo copie el codigo. De principio utilice el codigo de la sección de recursos y me generaba un error y en esta ocasión decidi usar el codigo de la sección de aporte, porque mencionaba que estaba más actualizado
Hola hola Sensusassoupire,
Podrias subir una foto en donde se visualize el error que te aparece para poder ayudarte.
Posiblemente sea un error en librerias, TensorFlow constantemente esta actualizando y mejorando las librerias. Te recomiendo que ejecutes el codigo de la sección de Recursos pero teniendo en cuenta la instalación de Object Detection, creeamos un blog que te servira para poder evitar los errores. Sin embargo si te aparece uno, compartelo por acá y te ayudo a solucionar.
Hice algunos cambios logre avanzar un poco, ahora me arrojo este error.
¿Por qué necesitamos específicamente la versión con el hash 58d19c67e1d30d905dd5c6e5092348658fed80af?, en la documentación oficial no mencionan nada al respecto.
Me gustaría más detalles de los paquetes que se instalan y para qué son usados, instalarlos y ya no nos muestra la necesidad de tener esos paquetes.
Hola Daniel,
Gracias por preguntar, TF es una librería que se va actualizando y va siempre buscando ser más sencilla y con menos requerimientos de instalación; anteriormente el proceso para instalar la API de object detection era un poco tedioso y se necesitaba realizar unas pre configuraciones y unas versiones en específico, en este caso la versión que funcionaba era 58d19c67e1d30d905dd5c6e5092348658fed80af junto a las librería indicadas en el proceso de instalación (Si no lo ejecutabas así, generaba ciertos conflictos de librería y tenias que modificar su instalación, sufrí varios meses con esos problemas y lo que genere en el curso fue una forma en la cual me aseguro que funcione con las librería indicadas), sin embargo al pasar las nuevas versiones el proceso para instalar object detection se ha vuelto mucho más sencillo.
Ahora si lo vas a instalar local solo debes que clonarlo y ejecutar un par de comandos
Muchas gracias por compartir en los comentarios otra forma de generar el tfrecord con versiones más actualizadas, sé que esos comentarios generan mucho valor para tus compañeros.
Saludos
tengo una duda. alguien ya haya hecho. con tensorFlow 2. Tutorial de la API de detección de objetos de TensorFlow 2. no me funciona con el del prof. . help please
Hola Godofredo Quea,
Que error te sale? si me lo compartes te puedo dar una mano para solucionarlo
Me cuentas, saludos
Para transformar un archivo CSV a TFRecord, aquí tienes una guía detallada paso a paso. Supongamos que tu archivo dataset.csv tiene las siguientes columnas:
2. **Definir las funciones de ayuda para la conversión a TFRecord**
Cada característica en los datos debe transformarse al formato adecuado (bytes, int64 o float), y se utiliza un tf.train.Example para almacenar la información en el formato TFRecord.
print("Imagen (bytes):", len(image_raw), "bytes") # Verifica el tamaño en bytes
```
### Explicación de los pasos
- **Conversión de tipos de datos**: Las funciones \_bytes\_feature y \_int64\_feature convierten los valores de las características al tipo que espera tf.train.Example.
- **Creación de tf.train.Example**: Se crea un ejemplo con las características necesarias, en este caso la imagen en bytes y la etiqueta.
- **Escritura en TFRecord**: TFRecordWriter escribe cada ejemplo en el archivo dataset.tfrecord.
- **Lectura de TFRecord**: Con tf.data.TFRecordDataset, puedes leer y decodificar cada ejemplo, lo que permite verificar que los datos están almacenados correctamente.
Este proceso optimiza el almacenamiento y facilita la carga rápida en TensorFlow para entrenamiento y evaluación en grandes conjuntos de datos.