Aquí se reúnen las palabras, términos, conceptos etc. claves a tener en cuenta a modo de recordatorio. No tiene ningún tipo de orden, ni pretende ser el primer capítulo a visualizar.
La letra ‘x’ se asocia a la variable independiente, lo que usamos para hacer predicciones, por ejemplo imágenes. Mientras que la letra ‘y’ se asocia a la variable dependiente, lo que se denominan etiquetas y es nuestro objetivo obtener una predicción que tenga una alta probabilidad de parecerse a dicha ‘y’, un ejemplo de etiquetas pueden ser los nombres de las imágenes que permiten clasificar razas de perros.
weigth = pesos: valores aleatorios con los que se inicializan a las neuronas, estos parámetros son fundamentales para determinar el tipo de funcionamiento de una red.
Forma (shape) → w(tamaño input, número de neuronas)
bias = sesgo:
Forma (shape) → b(1, número de neuronas)
Un set de datos de puede dividir en:
Set de entrenamiento (train set).
Set de desarrollo o validación (dev set o validation set).
Set de pruebas (test set)
Función de pérdida (Loss function): función que mide el rendimiento del modelo en uno de los ejemplos del set de entrenamiento.
Función de coste (Cost function): función que mide el rendimiento del modelo en todos los ejemplos del set de entrenamiento. Sería la media de cada una de las funciones de pérdidas de cada ejemplo del set de entrenamiento.
Dataset: una colección que devuelve un tuple de su variable independiente y dependiente para un solo elemento.
DataLoader: un iterador que proporciona un flujo de grupos reducidos (mini-batches), donde cada grupo reducido es un tuple de un lote de variables independientes y un lote de variables dependientes.
one-hot encoding: vectores de 0’s con el tamaño del número de clases que tenga el dataset, cada categoría representa una posición en el vector por lo que si la imagen contiene algún elemento de alguna clase el vector tendrá un 1 en la posición del vector que corresponderá a su clase.
Es importante saber que una clasificación pretende predecir una clase o categoría mientras que un modelo de regresión intenta predecir 1 o más cantidades numéricas.
Capítulo 0: Útiles
0.1. Descomprimir ficheros
Muchos de los datasets se encuentran comprimidos, si usamos Colab será pesado subir los ficheros a Drive además del tiempo requerido para ello.
Podemos utilizar WandB para el registro de la evolución de nuestro módulo. Utilizar WandB nos permite obtener un registro del aprendizaje del modelo, compartir información en tiempo real, etc.
import wandb!wandb login# Ejemplo de parámetros que podemos rellenar para crear una instanciawandb.init( settings = wandb.Settings(start_method="thread"), project ="Transfer-Learning-Inception-Perros-vs-Gatos", config = {"learning_rate": lr,"epochs": num_epocas,"batch_size": tam_batch,"loss_function": "binary_crossentropy","architecture": "Inception","dataset": "Dog-vs-Cat" } )config = wandb.config
0.3. Utilizar modelos pre-entrenados
Al importar la librería de Tensorflow, podemos utilizar tf.keras.applications. para que aparezca la lista de modelos pre-entrenados disponibles.
Tener en cuenta, que dependiendo del modelo pre-entrenado a utilizar deberemos seguir pasos específicos. Por ejemplo, por cómo ha sido entrenado ResNet no podemos utilizar ni BatchNormalization() ni tampoco realizar normalización en los datos ya que requiere realizar el procesado de la siguiente manera:
train_datagen =ImageDataGenerator( dtype='float32', preprocessing_function = preprocess_input, horizontal_flip =True, validation_split =0.05# Division del dataset de entrenamiento a 80/20, 20 para validación)
El ejemplo anterior es uno de los múltiples casos que se puedan dar por lo que lo más recomendado es visitar siempre la documentación de Tensorflow .
Lo primero para poder hacer uso de los modelos pre-entrenados de Tensorflow es cargar el modelo con los ajustes deseados:
import tensorflow as tf# Modelomodelo_base = tf.keras.applications.ResNet50( weights ='imagenet', # Pesos con los que ha sido entrenado el modelo input_shape = (224, 224, 3), # Dimensión de los datos esperada por el modelo include_top =False# Eliminamos las últimas capas)
Posteriormente, debemos congelar los parámetros del modelo para no reentrenarlos.
for capa in modelo_base.layers: capa.trainable =False
Para ajustar el modelo pre-entrenado a nuestro problema, debemos añadir nuevas capas al modelo. Estas serán las capas que entrenaremos en primera instancia para posteriormente descongelar el modelo y entrenarlo al completo.
defModelo(modelo_base):# Con modelo_base.summary() podemos ver todas las capas que cuenta el modelo# Estas capas se encuentran asociadas a un nombre que también se ve reflejado# al usar el método summary() por lo que apuntamos el nombre de la última capa ultima_capa = modelo_base.get_layer('conv5_block3_out') salida_capa = ultima_capa.output x = layers.Flatten()(salida_capa) x = layers.Dense(units =512, activation ='relu')(x) x = layers.Dropout(rate =0.2)(x) x = layers.Dense(units =256, activation ='relu')(x) x = layers.Dropout(rate =0.2)(x) x = layers.Dense(units = num_clases, activation ='softmax')(x) modelo =Model(modelo_base.input, x) modelo.compile( optimizer = Optimizer.Adam(learning_rate = lr), loss = loss.CategoricalCrossentropy(), metrics = ['accuracy'] )return modelomodelo =Modelo(modelo_base)
0.4. Mostrar gráficas de pérdidas y accuracy
history = modelo.fit(...)# Creamos una gráfica para mostrar el accuracy obtenido tanto en el set de entrenamiento como en el de validacionplt.plot(history.history['accuracy'])plt.plot(history.history['val_accuracy'])plt.grid(which ='both', axis ='both')plt.title('Precisión del modelo')plt.ylabel('Precisión')plt.xlabel('Época')plt.legend(['Entrenamiento', 'Test'], loc='upper right')plt.show()# Creamos una gráfica para mostrar la función de pérdida obtenida tanto en el set de entrenamiento como en el de validacion
plt.plot(history.history['loss'])plt.plot(history.history['val_loss'])plt.grid(which ='both', axis ='both')plt.title('Pérdida del modelo')plt.ylabel('Pérdida')plt.xlabel('Época')plt.legend(['Entrenamiento', 'Test'], loc='upper right')plt.show()
0.5. ImageDataGenerator
Podemos utilizar generadores de datos para la manipulación de datos de nuestro dataset. Con ello, conseguimos realizar aumentación datos, divisiones de datos para entrenamiento, validación y pruebas, entre otras herramientras.
1.0.3. Tipos de arquitecturas para visión computacional
1.1. Lenguaje de signos, SIGN MNIST
1.1.1. Anotaciones
1.1.2. Código
import tensorflow.keras as kerasimport pandas as pdimport tensorflow as tffrom tensorflow.keras.preprocessing.image import ImageDataGeneratorimport matplotlib.pyplot as pltfrom google.colab import drivedrive.mount('/content/drive')# Cargamos los datos desde los ficheros CSVtrain_df = pd.read_csv("/content/drive/MyDrive/Colab Notebooks/data/sign_mnist_train.csv")valid_df = pd.read_csv("/content/drive/MyDrive/Colab Notebooks/data/sign_mnist_valid.csv")# Separamos el contenido de los ficheros CSVy_train = train_df['label']y_valid = valid_df['label']del train_df['label']del valid_df['label']# Obtenemos los datos de entrenamiento y validaciónx_train = train_df.valuesx_valid = valid_df.values# Obtenemos nuestras etiquetas utilizando categorias binarias (one-hot)num_classes =24y_train = keras.utils.to_categorical(y_train, num_classes)y_valid = keras.utils.to_categorical(y_valid, num_classes)x_train = x_train.reshape(-1,28,28,1)x_valid = x_valid.reshape(-1,28,28,1)print(x_train.shape)print(x_valid.shape)defModelo(): modelo = tf.keras.models.Sequential([ tf.keras.layers.Conv2D(32, (3, 3), strides=1, padding="same", activation="relu", input_shape=(28, 28, 1)), tf.keras.layers.MaxPool2D((2, 2), strides=2, padding="same"), tf.keras.layers.BatchNormalization(), tf.keras.layers.Conv2D(64, (3, 3), strides=1, padding="same", activation="relu"), tf.keras.layers.MaxPool2D((2, 2), strides=2, padding="same"), tf.keras.layers.BatchNormalization(), tf.keras.layers.Dropout(0.25), tf.keras.layers.Conv2D(64, (3, 3), strides=1, padding="same", activation="relu"), tf.keras.layers.MaxPool2D((2, 2), strides=2, padding="same"), tf.keras.layers.BatchNormalization(), tf.keras.layers.Dropout(0.25), tf.keras.layers.Conv2D(128, (3, 3), strides=1, padding="same", activation="relu"), tf.keras.layers.MaxPool2D((2, 2), strides=2, padding="same"), tf.keras.layers.BatchNormalization(), tf.keras.layers.Dropout(0.25), tf.keras.layers.Flatten(), tf.keras.layers.Dense(units=512, activation="relu"), tf.keras.layers.BatchNormalization(), tf.keras.layers.Dropout(0.5), tf.keras.layers.Dense(units=256, activation="relu"), tf.keras.layers.BatchNormalization(), tf.keras.layers.Dropout(0.5), tf.keras.layers.Dense(units=num_classes, activation="softmax") ]) modelo.compile( optimizer=tf.keras.optimizers.Adam(learning_rate =1e-3), loss=tf.keras.losses.CategoricalCrossentropy(), metrics=['accuracy'] )return modelomodel =Modelo()train_datagen =ImageDataGenerator( rescale =1./255, rotation_range=15, # randomly rotate images in the range (degrees, 0 to 180) zoom_range=0.1, # Randomly zoom image width_shift_range=0.1, # randomly shift images horizontally (fraction of total width) height_shift_range=0.1, # randomly shift images vertically (fraction of total height) horizontal_flip=True, # randomly flip images horizontally brightness_range = (0.4, 0.75), validation_split =0.2)test_datagen =ImageDataGenerator( rescale =1./255)train_gen = train_datagen.flow( x_train, y_train, batch_size =64, subset ='training')valid_gen = train_datagen.flow( x_train, y_train, batch_size =64, subset ='validation')test_gen = test_datagen.flow( x_valid, y_valid, batch_size=64,)classCallBack(tf.keras.callbacks.Callback):defon_epoch_end(self,epocas,logs={}):if(logs.get('val_accuracy')>=0.98):print("\nSe alcanzo un 98% de precision, cancelamos el entrenamiento") self.model.stop_training =Truecallback =CallBack()# Para la reducción del learning rate atenderemos a la métrica de la precisión del set de validaciónreducir_lr = tf.keras.callbacks.ReduceLROnPlateau( monitor ='val_accuracy', factor =0.1, patience =3, min_lr =1e-5, verbose =1)callbacks = [callback, reducir_lr]history = model.fit(train_gen, epochs =30, validation_data = valid_gen, callbacks = callbacks )# Creamos una gráfica para mostrar el accuracy obtenido tanto en el set de entrenamiento como en el de validacionplt.plot(history.history['accuracy'])plt.plot(history.history['val_accuracy'])plt.grid(which ='both', axis ='both')plt.title('Precisión del modelo')plt.ylabel('Precisión')plt.xlabel('Época')plt.legend(['Entrenamiento', 'Test'], loc='upper right')plt.show()# Creamos una gráfica para mostrar la función de pérdida obtenida tanto en el set de entrenamiento como en el de validacion
plt.plot(history.history['loss'])plt.plot(history.history['val_loss'])plt.grid(which ='both', axis ='both')plt.title('Pérdida del modelo')plt.ylabel('Pérdida')plt.xlabel('Época')plt.legend(['Entrenamiento', 'Test'], loc='upper right')plt.show()
1.2. Perros vs Gatos
1.2.1. Anotaciones
1.2.2. Código
import osimport tensorflow as tffrom tensorflow.keras.preprocessing.image import ImageDataGeneratorimport matplotlib.pyplot as pltimport pandas as pdimport numpy as npimport zipfile!wget --no-check-certificate https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip# Hiperparámetrosnum_epocas =40lr =1e-3batch_size =64local_zip ='./cats_and_dogs_filtered.zip'zip_ref = zipfile.ZipFile(local_zip, 'r')zip_ref.extractall()zip_ref.close()# Vamos a cargar el dataset# El dataset se encuentra en E:\Datasets\data\dogs-vs-cats, contamos con 2 carpetas: train y testbase_dir ='./cats_and_dogs_filtered'print("Contenido en el directorio base:")print(os.listdir(base_dir))print("\nContenido en el directorio de entrenamiento:")# Con mostrar algunos ejemplos es suficienteprint(os.listdir(f'{base_dir}/train'))print("\nContenido en el directorio de test:")print(os.listdir(f'{base_dir}/validation'))train_dir = os.path.join(base_dir, 'train')validation_dir = os.path.join(base_dir, 'validation')# ModelodefModelo(): modelo = tf.keras.models.Sequential([ tf.keras.layers.Conv2D(filters = 32, kernel_size = (3, 3), strides = (1, 1), input_shape = (150, 150, 3), activation = 'relu'),
tf.keras.layers.MaxPool2D(pool_size = (2, 2)), tf.keras.layers.BatchNormalization(),#tf.keras.layers.Dropout(rate = 0.25), tf.keras.layers.Conv2D(filters =64, kernel_size = (3, 3), strides = (1, 1), activation ='relu'), tf.keras.layers.MaxPool2D(pool_size = (2, 2)), tf.keras.layers.BatchNormalization(),#tf.keras.layers.Dropout(rate = 0.25), tf.keras.layers.Conv2D(filters =64, kernel_size = (3, 3), strides = (1, 1), activation ='relu'), tf.keras.layers.MaxPool2D(pool_size = (2, 2)), tf.keras.layers.BatchNormalization(),#tf.keras.layers.Dropout(rate = 0.25), tf.keras.layers.Conv2D(filters =128, kernel_size = (3, 3), strides = (1, 1), activation ='relu'), tf.keras.layers.MaxPool2D(pool_size = (2, 2)), tf.keras.layers.BatchNormalization(),#tf.keras.layers.Dropout(rate = 0.25), tf.keras.layers.Flatten(), tf.keras.layers.Dense(units =512, activation ='relu'),#tf.keras.layers.Dropout(rate = 0.5), tf.keras.layers.Dense(units =128, activation ='relu'),#tf.keras.layers.Dropout(rate = 0.5), tf.keras.layers.Dense(units =1, activation ='sigmoid') ]) modelo.compile( optimizer=tf.keras.optimizers.Adam(learning_rate = lr), loss=tf.keras.losses.BinaryCrossentropy(), metrics=['accuracy'] )return modelotrain_datagen =ImageDataGenerator( rescale =1./255, vertical_flip =True, horizontal_flip =True, rotation_range =40, # Gira entre 0 y 40 grados width_shift_range =0.2, # Cantidad aleatoria para desplazar el centro de una imagen height_shift_range =0.2, shear_range =0.2, # shear = cizallar, realizar cortes en la imagen para cambiar perspectivas por ejemplo zoom_range =0.2, fill_mode ='nearest'# Intenta recrear la información perdida tras una transformación como shear )train_datagen =ImageDataGenerator(rescale =1.0/255)test_datagen =ImageDataGenerator(rescale =1.0/255)train_generator = train_datagen.flow_from_directory( train_dir, batch_size = batch_size, class_mode ='binary', target_size = (150, 150) )validation_generator = test_datagen.flow_from_directory( validation_dir, batch_size = batch_size, class_mode ='binary', target_size = (150, 150) )modelo =Modelo()modelo.summary()early_stopping = tf.keras.callbacks.EarlyStopping( monitor ='val_loss', min_delta =1e-3, patience =10, verbose =1, mode ='auto', restore_best_weights =True)# Para la reducción del learning rate atenderemos a la métrica de la precisión del set de validaciónreducir_lr = tf.keras.callbacks.ReduceLROnPlateau( monitor ='val_accuracy', factor =0.1, patience =8, min_lr =1e-5, verbose =1)callbacks = [early_stopping, reducir_lr]history = modelo.fit( train_generator, epochs = num_epocas, callbacks = callbacks, verbose =2, validation_data = validation_generator )# Creamos una gráfica para mostrar el accuracy obtenido tanto en el set de entrenamiento como en el de validacionplt.plot(history.history['accuracy'])plt.plot(history.history['val_accuracy'])plt.grid(which ='both', axis ='both')plt.title('Precisión del modelo')plt.ylabel('Precisión')plt.xlabel('Época')plt.legend(['Entrenamiento', 'Test'], loc='upper right')plt.show()# Creamos una gráfica para mostrar la función de pérdida obtenida tanto en el set de entrenamiento como en el de validacion
plt.plot(history.history['loss'])plt.plot(history.history['val_loss'])plt.grid(which ='both', axis ='both')plt.title('Pérdida del modelo')plt.ylabel('Pérdida')plt.xlabel('Época')plt.legend(['Entrenamiento', 'Test'], loc='upper right')plt.show()
1.3. Implementación YOLO
Para hacer uso de las utilidades, modelo y demás herramientas, debemos descargar las herramientas del repositorio.
1.3.0. Teoría
1.3.1. Anotaciones
El modelo YOLO ha sido entrenado con datos de entrada con tamaños de (m, 608, 608, 3). Cada salida resultante, consiste en un cuadro delimitador (bounding boxes) con la clase reconocida. A su vez, cada cuadro está representado por 6 números (𝑝𝑐, 𝑏𝑥, 𝑏𝑦, 𝑏ℎ, 𝑏𝑤, 𝑐). Para este ejemplo de algoritmo de YOLO, usaremos yad2k (YAD2K: Yet Another Darknet 2 Keras) que cuenta con 80 clases.
Las cajas de anclaje se eligen explorando los datos de entrenamiento para elegir proporciones razonables de altura y anchura que representen mejor a las diferentes clases. Para esta tarea, se han elegido 5 cajas de anclaje (para cubrir las 80 clases), almacenados en el archivo './model_data/yolo_anchors.txt'
La dimensión para las cajas de anclaje es la penúltima dimensión en la codificación (𝑚, 𝑛𝐻, 𝑛𝑊, 𝑎𝑛𝑐ℎ𝑜𝑟𝑠, 𝑐𝑙𝑎𝑠𝑒𝑠) .
Dado que estamos utilizando 5 cajas de anclaje, cada una de las 19 x19 celdas codifica información sobre 5 cajas. Las cajas de anclaje se definen únicamente por su anchura y altura.
Para simplificar, aplanaremos las dos últimas dimensiones de la codificación de la forma (19, 19, 5, 85), de modo que la salida de la CNN profunda es (19, 19, 425).
Ahora, para cada caja (de cada celda) se calculará un producto y se extraerá una probabilidad de que la caja contenga una determinada clase. La puntuación (score) de clase, calculado como 𝑖 = 𝑝𝑐 × 𝑐𝑖, consistiría en la probabilidad de que haya un objeto 𝑝𝑐 por la probabilidad de que el objeto sea de una determinada clase 𝑐𝑖 .
1.3.2. Código
Al tratarse de un código más complejo, iremos dividiéndolo en partes acompañados por una explicación.
En primer lugar, vamos a aplicar un filtro para el umbral, lo que implica que eliminará cualquier casilla cuya puntuación de clase sea inferior a un umbral elegido. El modelo arrojará un total de 19x19x6x85 números, con cada caja descrita por 85 números. Es conveniente reordenar el tensor dimensional (19, 19, 5, 85) o (19, 19, 425) en las siguientes variables:
box_confidence: tensor de forma (19, 19, 5, 1) que contiene 𝑝𝑐 (probabilidad de confianza de que haya algún objeto) para cada una de las 5 cajas previstas en cada una de las 19x19 casillas.
boxes: tensor de forma (19, 19, 5, 4) que contiene el punto medio y las dimensiones (𝑏𝑥, 𝑏𝑦, 𝑏ℎ, 𝑏𝑤) para cada una de las 5 cajas en cada celda.
box_class_probs: tensor de forma (19, 19, 5, 80) que contiene las "probabilidades de clase" (𝑐1, 𝑐2, ..., 𝑐80) para cada una de las 80 clases para cada una de las 5 cajas por celda.
defyolo_filter_boxes(boxes,box_confidence,box_class_probs,threshold=.6):# Step 1: Compute box scores##(≈ 1 line) box_scores = box_confidence * box_class_probs# Step 2: Find the box_classes using the max box_scores, keep track of the corresponding score##(≈ 2 lines) box_classes = tf.math.argmax(input = box_scores, axis =-1) box_class_scores = tf.math.reduce_max(input_tensor = box_scores, axis =-1)# Step 3: Create a filtering mask based on "box_class_scores" by using "threshold". The mask should have the# same dimension as box_class_scores, and be True for the boxes you want to keep (with probability >= threshold)## (≈ 1 line) filtering_mask = box_class_scores >= threshold# Step 4: Apply the mask to box_class_scores, boxes and box_classes## (≈ 3 lines) scores = tf.boolean_mask(tensor = box_class_scores, mask = filtering_mask) boxes = tf.boolean_mask(tensor = boxes, mask = filtering_mask) classes = tf.boolean_mask(tensor = box_classes, mask = filtering_mask)return scores, boxes, classes
Implementar IoU (Intersection over Union). No es necesario implementarlo pero para que veamos cómo se haría.
defiou(box1,box2): (box1_x1, box1_y1, box1_x2, box1_y2) = box1 (box2_x1, box2_y1, box2_x2, box2_y2) = box2# Calculate the (yi1, xi1, yi2, xi2) coordinates of the intersection of box1 and box2. Calculate its Area.##(≈ 7 lines) xi1 =max(box1_x1, box2_x1) yi1 =max(box1_y1, box2_y1) xi2 =min(box1_x2, box2_x2) yi2 =min(box1_y2, box2_y2) inter_width = xi2-xi1 inter_height = yi2-yi1 inter_area =max(inter_width, 0)*max(inter_height, 0)# Calculate the Union area by using Formula: Union(A,B) = A + B - Inter(A,B)## (≈ 3 lines) box1_area = (box1_x2 - box1_x1) * (box1_y2 - box1_y1) box2_area = (box2_x2 - box2_x1) * (box2_y2 - box2_y1) union_area = box1_area + box2_area - inter_area# compute the IoUreturn inter_area / union_area
Implementar Non-Max Suppression.Tensorflow tiene dos funciones incorporadas que se utilizan para implementar la supresión de no-máximos (por lo que no es necesario utilizar la función iou()).
defyolo_non_max_suppression(scores,boxes,classes,max_boxes=10,iou_threshold=0.5):# tensor to be used in tf.image.non_max_suppression() max_boxes_tensor = tf.Variable(max_boxes, dtype='int32')# Use tf.image.non_max_suppression() to get the list of indices corresponding to boxes you keep nms_indices = tf.image.non_max_suppression( boxes = boxes, scores = scores, max_output_size = max_boxes, iou_threshold = iou_threshold)# Use tf.gather() to select only nms_indices from scores, boxes and classes scores = tf.gather(params = scores, indices = nms_indices) boxes = tf.gather(params = boxes, indices = nms_indices) classes = tf.gather(params = classes, indices = nms_indices)return scores, boxes, classes
Convertir las predicciones de la caja YOLO en esquinas de la caja delimitadora.
Convertimos la salida de la codificación YOLO (un montón de cajas) en sus cajas predichas junto con sus puntuaciones, coordenadas de caja y clases.
defyolo_eval(yolo_outputs,image_shape= (720,1280),max_boxes=10,score_threshold=.6,iou_threshold=.5):### START CODE HERE# Retrieve outputs of the YOLO model (≈1 line) box_xy, box_wh, box_confidence, box_class_probs = yolo_outputs# Convert boxes to be ready for filtering functions (convert boxes box_xy and box_wh to corner coordinates) boxes =yolo_boxes_to_corners(box_xy, box_wh) # Use one of the functions you've implemented to perform Score-filtering with a threshold of score_threshold (≈1 line)
scores, boxes, classes =yolo_filter_boxes(boxes, box_confidence, box_class_probs, score_threshold)# Scale boxes back to original image shape. boxes =scale_boxes(boxes, image_shape)# Use one of the functions you've implemented to perform Non-max suppression with # maximum number of boxes set to max_boxes and a threshold of iou_threshold (≈1 line) scores, boxes, classes =yolo_non_max_suppression(scores, boxes, classes, max_boxes, iou_threshold)return scores, boxes, classes
Podemos probar un modelo pre-entrenado de YOLO. Dicho modelo ha sido entrenado en el dataset de COCO basado en un problema de conducción autónoma.
Capítulo 2: Procesamiento del Lenguaje Natural, NLP
2.0. Teoría
Modelos secuenciales:
Transformers:
Capítulo 3: Procesamiento de Audio
3.1. Reconocimiento de audio
3.1.1. Anotaciones
3.1.2. Código
Podemos utilizar la librería librosa de Python para el procesado de señales de audio. Para este caso, podemos convertir el sonido en espectrogramas para posteriormente tratar el problema como un clasificador por visión computacional.
Ejemplo de código para procesar señales de audio a espectrogramas:
import librosaimport numpy as np# Leemos el ficherofile ="temp/processed_file.wav"sig, fs = librosa.core.load(file, sr=8000)# Procesamos el ficheroabs_spectrogram = np.abs(librosa.core.spectrum.stft(sig))audio_signal = librosa.core.spectrum.griffinlim(abs_spectrogram)print(audio_signal, audio_signal.shape)# Podemos realizar la conversión inversa de un espectrograma a una imagenlibrosa.output.write_wav('test2.wav', audio_signal, fs)