Antecedentes
Con el rápido desarrollo de Machine Learning, especialmente Deep Learning, el speech recognition se ha mejorado significativamente. Dicha tecnología se basa en una gran cantidad de datos de alta calidad. Sin embargo, los modelos creados para lenguajes no populares tienen un rendimiento peor que los de los populares, como el inglés. Esto se debe al hecho de que solo hay unos pocos conjuntos de datos de capacitación disponibles, y que es difícil recopilar datos de alta calidad de manera efectiva. Esta publicación de blog le mostrará cómo de manera eficiente recopilar datos de speech recognition para cualquier idioma .
Mientras Mozilla ha lanzado un proyecto de código abierto llamado Voz común que alentó las personas a contribuir con sus voces el año pasado, la mayoría de las personas no conocen este proyecto o no están dispuestas a participar en él. La siguiente figura muestra el pequeño progreso en la recopilación de datos para diferentes idiomas de Common Voice.
Gracias a la abundancia de programas de televisión y dramas disponibles en Youtube, es posible recopilar datos de speech recognition de una manera altamente eficiente con participación casi humana.
Como se muestra en la imagen anterior, algunos de estos dramas o espectáculos están incrustados con subtítulos, que se pueden extraer mediante OCR. El texto extraído junto con el audio recortado puede formar una muestra de datos de speech recognition.
Descripción general
La siguiente figura muestra una descripción general de la canalización de recopilación de datos completa que contiene varios módulos. Primero utilizamos la API de Youtube V3 para buscar y descargar los videos asociados con el nombre de los programas de TV que especificamos. FFMPEG se aprovecha para dividir videos en cuadros, cada uno de los cuales es procesado por un Mask-RCNN autodidacta (más detalles más adelante) para mantener solo el área de subtítulos de la imagen. Luego, las imágenes procesadas se envían a la API de Google Vision para obtener el texto y la confianza pronosticados. Con la biblioteca de Pandas, ordenamos los resultados por marca de tiempo y luego los agregamos para generar un archivo SRT para cada video. Los siguientes le mostrarán cómo implementar cada uno de estos módulos.
Requisito previo
- Python == 3.6
- FFMPEG
- joblib == 0.12.0
- numpy == 1.13.3
- pandas == 0.23.3
- tensorflow-gpu == 1.4.0
- keras == 2.1.3
- google-cloud-vision == 0.32.0
- pafy == 0.5.4
- youtube-dl == 2017.12.2
- tqdm == 4.23.4
- editdistance == 0.4
Implementación
Esta sección está dividida por el módulo en la canalización de recopilación de datos, con cada subsección correspondiente a un módulo.
Descargar videos & Extraer audios
Vaya a Youtube para buscar un drama de televisión que le interese. Asegúrese de que puede encontrar una lista de reproducción de ese programa porque la calidad de los videos en una lista de reproducción tiende a ser uniforme. Compruebe si el primer video contiene subtítulos incrustados, podemos suponer que toda la lista de reproducción está incrustada en los subtítulos.
https://medium.com/media/e4ee471d5f3bb45583cde3ca5bec5e12/href
Lo anterior El código muestra cómo buscar una lista de reproducción de Youtube. Debe solicitar una clave API para usar el cliente API de Youtube V3. En la línea 27,
youtube.search (). List (q = name, type = "playlist", part = "id", maxResults = 1) .execute ()
realiza literalmente una búsqueda de Youtube con consulta el nombre del drama y devuelve la id de la lista de reproducción del primer resultado.
Con la ID de la lista de reproducción, podemos obtener los ID de todos los videos de esta lista de reproducción.
https://medium.com/media/ccb905a0ae016eb888cf983725f75ef9/ href
De manera similar, en la línea 15,
youtube.playlistItems (). list (part = & # 039; contentDetails & # 039;, maxResults = 50, playlistId = playlist_id) .execute ()
busca el ID de hasta 50 videos (limitados por la API) dado el ID de la lista de reproducción.
Luego, podemos comenzar a descargar videos.
https://medium.com/media/f960ad1b77661bbe18ade312d6675a08/href
Paquete Pafy Python se utiliza para descargar los videos de la resolución más alta disponible. Después de descargar los videos, aprovechamos FFMPEG para extraer el audio de cada uno de los videos.
https://medium.com/media/14437fb4b9df90300eff8ffe2cf96601/href
Dado que FFMPEG no es compatible con el SDK de Python, debemos llamarlo en concha. Al activar la función subprocess.call (), podemos ejecutar el comando de shell especificado en el parámetro. Ahora, ha descargado con éxito los videos y audios del programa de TV que especificó.
Videos divididos
Luego, dividimos los videos descargados en cuadros en los que ejecutamos el OCR.
https://medium.com / media / ca4a1da95489f541f7b16be3ba2a1080 / href
Solo la mitad del 60% de los videos se divide en fotogramas, ya que la primera y la última parte del 20% pueden contener canciones de apertura o finalización, que no se pueden usar para el speech recognition.
, FFMPEG fue llamado en shell con subproceso. Los parámetros de división de videos se describen de la siguiente manera:
- ss: tiempo de inicio en segundo
- t: intervalo de tiempo para dividir video en segundo
- r: frecuencia de muestreo
Cuanto mayor sea la frecuencia de muestreo, más precisa del lapso de tiempo de subtítulos predicho. Sin embargo, hay una compensación entre el tiempo y la precisión. Aquí, lo configuré para que sea 2.
Entrene y evalúe la máscara-RCNN
Ahora, usted tiene marcos de cada uno de los videos. Si prueba algunas imágenes en sitio web oficial de la API de Google Vision para OCR (detección de texto del documento, ya que los subtítulos son caracteres escritos). Descubrirá que el resultado no es satisfactorio ya que el fondo de estas imágenes es muy complicado.
Aquí es cuando entra en juego Mask-RCNN. Mask-RCNN es parte de la familia RCNN para detección de objetos y segmentación de instancias publicada en 2017. Es capaz de clasificar a nivel de píxel.
Nuestro objetivo es capacitar a Mask-RCNN para ayudarnos a identificar qué píxeles son los subtítulos.
Capacitación
Para asegurar que los modelos entrenados sean lo suficientemente generalizados como para todo tipo de videos, descargo videos de una docena de dramas de TV y animaciones. Se aplican diferentes tamaños de fuente, tipos de fuente y ubicación vertical de fuente para enriquecer el conjunto de datos de capacitación. El 40% inferior de las imágenes se recorta para asegurarnos de que los subtítulos agregados manualmente en los datos de entrenamiento no se superpongan con los subtítulos originales. Esto también asegura que las partes que no son subtítulos provienen de una distribución de espacio de color muy similar.
https://medium.com/media/4da8a8d33f36e1c7fbb9403c4265273c/href
El código anterior aprovecha el paquete Python PIL para agregar textos a las imágenes . Como Mask-RCNN trata a cada componente conectado como una instancia, en algunos idiomas, un personaje puede estar compuesto por diferentes instancias. Por ejemplo, el carácter “把” comprende los dos componentes izquierdo y derecho. Para encontrar el componente conectado, podemos usar la función label () en el paquete skimage como se muestra en el siguiente código.
https://medium.com/media/4da8a8d33f36e1c7fbb9403c4265273c/href
Se muestran los datos de entrenamiento generados en las siguientes imágenes. La izquierda muestra las imágenes de entrada, mientras que la derecha muestra las verdades de la tierra. Como puede ver en la diferencia de color de algunos caracteres de la derecha, un solo carácter puede constar de varias instancias.
Para entrenar Mask-RCNN, uso una implementación excelente usando Keras y Tensorflow en este Github Repo . Lo que tenemos que hacer es especificar la configuración de nuestro modelo de capacitación como se muestra a continuación.
https://medium.com/media/ae42771d49593dca2123dd70d02a6024/href
Solo necesita establecer NUM_CLASSES = 1 + 1 (subtítulo + fondo), y especifique IMAGE_MIN_DIM así como IMAGE_MAX_DIM que depende de la resolución de sus datos de entrenamiento. Se requiere que MEAN_PIXEL se compute manualmente para la estandarización en la etapa de preprocesamiento. Luego, puede comenzar a cargar datos y capacitación.
Evaluación
Después de entrenar durante 100 épocas, comencemos a ejecutar el modelo entrenado en algunas imágenes.
La parte superior muestra el izquierda muestra las imágenes de entrada, mientras que la derecha muestra la salida. Puede ver que el subtítulo ha sido claramente identificado. Aunque hay algo de ruido arriba, no tienen efecto en la predicción de los subtítulos a continuación cuando se ejecuta OCR. El problema principal es que a veces Mask-RCNN es demasiado estricto como para eliminar algunas partes del texto. En el segundo ejemplo anterior, el segundo carácter “難” se borró parcialmente, lo que podría disminuir el rendimiento de OCR. Para recuperar este error, decidí usar Ensemble.
Ensemble se refiere al uso de modelos múltiples para la predicción. En lugar de usar un único modelo para la predicción, como se muestra en la figura anterior, entrené otro modelo con diferente configuración. La imagen de entrada se alimenta a ambos modelos, y los resultados finales serán la unión de las predicciones de estos dos modelos.
Los cuadros resultantes procesados por Mask-RCNN se muestran a continuación. La inferior izquierda es la imagen de entrada original, la inferior derecha es la predicción con un solo modelo y la superior izquierda es el resultado del conjunto. (la parte superior derecha es el resultado Aumento del tiempo de prueba que ha sido reemplazado por el conjunto en la tubería actual)
Ejecutar OCR
Después de procesar las imágenes con el módulo Mask-RCNN, estamos listos para ejecutar OCR en estas imágenes. A diferencia de la clave de la API de Youtube, debe solicitar una credencial de Vision API en Google Cloud Platform y almacenarla en el disco local.
https://medium.com/media/92f3ac57f114ccc7c1efb941ad9867f4/href
El código anterior codifique su archivo de imagen, envíe a OCR API y reciba la respuesta. La respuesta contiene el carácter predicho, las coordenadas del cuadro delimitador de cada personaje, junto con la confianza para cada personaje. Puede decidir su propio umbral para filtrar el resultado de poca confianza. El resultado final se escribe en un archivo CSV con cada fila que representa cada fotograma.
https://medium.com/media/00df423d6cf2547a8f20604f05876fe7/href
Generar resultado final de SRT
Finalmente, aquí viene el último módulo de ¡la tubería! Por lo general, una pieza de subtítulo dura 2-3 segundos, lo que significa que hay alrededor de 4-6 cuadros continuos que contienen el mismo subtítulo. El problema persiste es cómo fusionamos el resultado de diferentes cuadros en uno, decidiendo la hora de inicio, la hora de finalización y el subtítulo de un discurso. Simplemente necesitamos verificar si el subtítulo actual coincide con el último. Un desafío principal es que a veces dos cuadros tienen el mismo subtítulo, pero el OCR predijo resultados diferentes. Su algoritmo para determinar si dos subtítulos son iguales debería ser capaz de manejar estos casos.
https://medium.com/media/2aec58a48f360ce29825be30a32ef04e/href
El código anterior se basa en la heurística. Devuelve True si los caracteres en estas dos cadenas del cuadro actual y del último cuadro son el 70% iguales sin importar el orden de cada carácter.
Conclusión
Si sigue las instrucciones anteriores correctamente, tiene éxito en la construcción un conducto de recopilación de datos de speech recognition automático. Puede dividir fácilmente el audio en función del tiempo especificado con FFMPEG, pero se lo dejo a usted. Un problema menor es que podría haber una pequeña falta de alineación entre el discurso y el texto desde el momento en que aparecen los subtítulos y el tiempo del discurso correspondiente podría ser algo diferente. Esto se puede resolver con un modelo de lenguaje para ajustar ligeramente el tiempo de cada subtítulo según el habla. Para obtener más información e implementar detalles, consulte este Github Repo . Si tiene alguna pregunta, no dude en ponerse en contacto conmigo por correo electrónico: huangkh19951228@gmail.com .
La recopilación automática de datos de speech recognition con Youtube V3 API, Mask-RCNN y API de Google Vision fue originalmente publicado en Towards Data Science en Medium, donde las personas continúan la conversación resaltando y respondiendo a esta historia.