[Программирование, Машинное обучение] Распознавание речи с помощью инструментов машинного обучения
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
В своей работе я столкнулся с необходимостью проверить записи звонков на соблюдение сотрудниками скрипта разговора с клиентами. Обычно для этого выделяется сотрудник, который тратит большое количество времени на прослушивание записей разговоров. Мы поставили себе задачу — уменьшить временные затраты на проверку с помощью инструментов автоматического распознавания речи (ASR). Один из таких инструментов мы рассмотрим подробнее.Nvidia NeMo — набор инструментов машинного обучения для создания и обучения моделей на базе графического процессора.Модели в составе NeMo используют современный подход к распознаванию речи — коннекционистская временная классификация (CTC).До СТС использовался подход, при котором входной аудиофайл разбивался на отдельные речевые сегменты и по ним предсказывались токены. Далее токены объединялись, повторяющиеся сворачивались в один, и результат подавался на вывод модели.При этом страдала точность распознавания, так как слово с повторяющимися буквами не считалось корректно распознанным на 100%. Например, «кООперация» приводилось к «кОперация».С CTC — все еще предсказываю один токен на временной сегмент речи и дополнительно используем пустой токен, чтобы выяснить где свернуть повторяющиеся токены. Появление пустого токена помогает отделить повторяющиеся буквы, которые не должны быть свернуты.Для своей задачи я взял одну из моделей (Jasper 10×5) и обучил ее с нуля. Для обучения был выбран публичный датасет телефонных разговоров, содержащий нарезанные аудиозаписи и их транскрибацию.Чтобы обучить модель, необходимо подготовить файл-манифест, содержащий информацию об аудиофайле и транскрибацию этого файла. Файл манифест имеет свой формат:
{{"audio_filepath": "path/to/audio.wav", "duration": 3.45, "text": "sometext"}…{"audio_filepath": "path/to/audio.wav", "duration": 3.45, "text": "sometext"}}
Модель принимает аудиофайлы только в формате *.wav. Необходимо пробежаться циклом по всему списку аудиофайлов и при помощи консольной утилиты перекодировать аудиофайлы с отличным от необходимого разрешением:
def convertToWav(self, ext):
if not os.path.exists(self.datadir + '/dataset'):
tar = tarfile.open(self.an4Path);
tar.extractall(path=self.datadir);
sphList = glob.glob(self.datadir + '/dataset/**/*' + ext, recursive=True);
for sph in sphList:
wav = sph[:-4] + '.wav';
cmd = ["sox", sph, wav];
subprocess.run(cmd);
print('renamed ' + ext + ' to ' + wav);
Для построения тестового и тренировочного манифеста я использовал следующую функцию, в которой получили длительность аудиофайла с помощью функции getduration(filename=audiopath) библиотеки Librosa, путь к файлам транскрибации и аудиофайлам нам известен:
def buildManifest(self, transcript_path, manifest_path, wav_path):
with open(transcript_paths, 'r') as fin:
with open(manifest_path, 'w') as fout:
for line in fin:
transcript = line[: line.find('(')-1].lower();
transcript = transcript.replace('<s>', '').replace('</s>', '');
transcript = transcript.strip();
file_id = line[line.find('(')+1 : -2];
audio_path = os.path.join(self.datadir, wav_paths, file_id[file_id.find('-')+1 : file_id.rfind('-')], file_id +'.wav');
duration = librosa.core.get_duration(filename=audio_path);
metadata = {
"audio_filepath": audio_path,
"duration": duration,
"text": transcript
}
print(metadata);
json.dump(metadata, fout);
fout.write('\n');
Для инициализации модели я сформировал специальный файл конфигурации, в котором прописываются все параметры модели:
config.yaml:
name: &name "Jasper10x5"
model:
sample_rate: &sample_rate 16000
labels: &labels [" ", "a", "б", "в", "г", "д", "е", "ё", "ж", "з", "и", "й", "к", "л",
"м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш", "щ", "ъ", "ь", "э", "ю", "я", "'"]
preprocessor:
_target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor
normalize: "per_feature"
sample_rate: *sample_rate
features: &n_mels 64
n_fft: 512
frame_splicing: 1
dither: 0.00001
stft_conv: false
Достаточно загрузить этот файл в конструктор модели и приступать к ее обучению. Для этого необходимо добавить к параметрам модели пути к тестовому и проверочному манифесту и с помощью инструмента pytorch_lighting запустить процесс обучения:
import nemo;
class NemoASR:
def __init__(self, dataDir):
self.datadir = dataDir;
self.CONF_PATH = './config.yaml';
yaml = YAML(typ="safe");
with open(self.CONF_PATH) as f:
self.CONFIG = yaml.load(f);
def train(self, transcriptionPATH, manifestPATH, wavPATH, testTranscriptionPATH, testManifestPATH, testWavPATH):
print("begin train");
train_transcripts = self.datadir + transcriptionPATH;
train_manifest = self.datadir + manifestPATH;
if not os.path.isfile(train_manifest):
self.buildManifest(train_transcripts, train_manifest, wavPATH);
test_transcripts = self.datadir + testTranscriptionPATH;
test_manifest = self.datadir + testManifestPATH;
if not os.path.isfile(test_manifest):
self.buildManifest(test_transcripts, test_manifest, testWavPATH);
# params from ./config.yaml
self.CONFIG['model']['train_ds']['manifest_filepath'] = train_manifest;
self.CONFIG['model']['validation_ds']['manifest_filepath'] = test_manifest;
trainer = pl.Trainer(max_epochs=500, gpus=1);
self.model = nemo_asr.models.EncDecCTCModel(cfg=DictConfig(self.CONFIG['model']), trainer=trainer);
trainer.fit(self.model);
print("end train");
#-------------------------------------------------------------
nemoASR = NemoASR('.');
if (nemoASR.checkExistsDataSet()):
print('dataset loaded');
nemoASR.train('./dataset/etc/train.transcription', './dataset/train_manifest.json','./dataset/wav/an4_clstk', './dataset/etc/test.transcription', './dataset/test_manifest.json', './dataset/wav/an4test_clstk');
nemoASR.model.save_to('./model.sbc');
После обучения готовую модель можно использовать для распознавания речи:
files = ['./an4/wav/an4_clstk/mgah/cen2-mgah-b.wav'];
for fname, transcription in zip(files, nemoASR.model.transcribe(paths2audio_files=files)):
print(f"Audio in {fname} was recognized as: {transcription}");
В результате мне удалось добиться достаточной точности, чтобы уверенно распознавать аудиофайлы.При использовании инструмента NeMo я выделил для себя следующие достоинства:
- быстрое обучение на GPU;
- возможность менять настройки модели из одного места, не меняя код;
- простота обучения.
Из недостатков можно отметить необходимость включения большого количества тяжеловесных библиотек, а также то, что инструмент относительно свежий и некоторые функции модели находятся в бета-тесте.При решении задачи по распознаванию речи я получил интересный опыт работы с ASR моделями. Смог обучить модель на случайном датасете и получили достаточную точность для уверенного распознавания телефонных разговоров.Предлагаем использовать данный инструмент не только для распознавания речи, но и для генерации аудиофайлов на основе текста (TTS) и распознавания диктора (speaker recognition).
===========
Источник:
habr.com
===========
Похожие новости:
- [Системное администрирование, Программирование, IT-инфраструктура, DevOps] Создание современных процессов CI/CD для бессерверных приложений с Red Hat OpenShift Pipelines и Argo CD. Часть 2 (перевод)
- [Программирование, Java, Микросервисы] Spring Cloud и Spring Boot. Часть 1: использование Eureka Server (перевод)
- [Программирование микроконтроллеров, Компьютерное железо, DIY или Сделай сам] Raspberry Pi Pico на МК RP2040: начало и первые шаги. Что есть поесть за $4
- [Разработка веб-сайтов, JavaScript, Программирование, ReactJS] Почему Context — это не инструмент «управления состоянием» (перевод)
- [Занимательные задачки, Программирование, Управление разработкой, Удалённая работа] Как отсеивать плохих программистов. 10 лучших автоматических инструментов проверки качества кода
- [Обработка изображений, Microsoft Azure, Машинное обучение, Разработка для интернета вещей] Azure Custom Vision без Azure, или «где у них маска». Как мы распознавали маску на лице (и других частях тела)
- [Алгоритмы, Apache, Машинное обучение, Hadoop] Масштабирование итеративных алгоритмов в Spark (перевод)
- [Python, Программирование, Алгоритмы, Машинное обучение, Искусственный интеллект] Нейронная Сеть CLIP от OpenAI: Классификатор, который не нужно обучать. Да здравствует Обучение без Обучения
- [Программирование, Go, DevOps] Prometheus in Action: from default counters to SLO-related queries
- [Разработка веб-сайтов, JavaScript, Программирование] Углублённое руководство по JavaScript: генераторы. Часть 1, основы (перевод)
Теги для поиска: #_programmirovanie (Программирование), #_mashinnoe_obuchenie (Машинное обучение), #_nvidia_nemo, #_mashinnoe_obuchenie (машинное обучение), #_python, #_programmirovanie (
Программирование
), #_mashinnoe_obuchenie (
Машинное обучение
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 14:49
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
В своей работе я столкнулся с необходимостью проверить записи звонков на соблюдение сотрудниками скрипта разговора с клиентами. Обычно для этого выделяется сотрудник, который тратит большое количество времени на прослушивание записей разговоров. Мы поставили себе задачу — уменьшить временные затраты на проверку с помощью инструментов автоматического распознавания речи (ASR). Один из таких инструментов мы рассмотрим подробнее.Nvidia NeMo — набор инструментов машинного обучения для создания и обучения моделей на базе графического процессора.Модели в составе NeMo используют современный подход к распознаванию речи — коннекционистская временная классификация (CTC).До СТС использовался подход, при котором входной аудиофайл разбивался на отдельные речевые сегменты и по ним предсказывались токены. Далее токены объединялись, повторяющиеся сворачивались в один, и результат подавался на вывод модели.При этом страдала точность распознавания, так как слово с повторяющимися буквами не считалось корректно распознанным на 100%. Например, «кООперация» приводилось к «кОперация».С CTC — все еще предсказываю один токен на временной сегмент речи и дополнительно используем пустой токен, чтобы выяснить где свернуть повторяющиеся токены. Появление пустого токена помогает отделить повторяющиеся буквы, которые не должны быть свернуты.Для своей задачи я взял одну из моделей (Jasper 10×5) и обучил ее с нуля. Для обучения был выбран публичный датасет телефонных разговоров, содержащий нарезанные аудиозаписи и их транскрибацию.Чтобы обучить модель, необходимо подготовить файл-манифест, содержащий информацию об аудиофайле и транскрибацию этого файла. Файл манифест имеет свой формат: {{"audio_filepath": "path/to/audio.wav", "duration": 3.45, "text": "sometext"}…{"audio_filepath": "path/to/audio.wav", "duration": 3.45, "text": "sometext"}}
def convertToWav(self, ext):
if not os.path.exists(self.datadir + '/dataset'): tar = tarfile.open(self.an4Path); tar.extractall(path=self.datadir); sphList = glob.glob(self.datadir + '/dataset/**/*' + ext, recursive=True); for sph in sphList: wav = sph[:-4] + '.wav'; cmd = ["sox", sph, wav]; subprocess.run(cmd); print('renamed ' + ext + ' to ' + wav); def buildManifest(self, transcript_path, manifest_path, wav_path):
with open(transcript_paths, 'r') as fin: with open(manifest_path, 'w') as fout: for line in fin: transcript = line[: line.find('(')-1].lower(); transcript = transcript.replace('<s>', '').replace('</s>', ''); transcript = transcript.strip(); file_id = line[line.find('(')+1 : -2]; audio_path = os.path.join(self.datadir, wav_paths, file_id[file_id.find('-')+1 : file_id.rfind('-')], file_id +'.wav'); duration = librosa.core.get_duration(filename=audio_path); metadata = { "audio_filepath": audio_path, "duration": duration, "text": transcript } print(metadata); json.dump(metadata, fout); fout.write('\n'); config.yaml:
name: &name "Jasper10x5" model: sample_rate: &sample_rate 16000 labels: &labels [" ", "a", "б", "в", "г", "д", "е", "ё", "ж", "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш", "щ", "ъ", "ь", "э", "ю", "я", "'"] preprocessor: _target_: nemo.collections.asr.modules.AudioToMelSpectrogramPreprocessor normalize: "per_feature" sample_rate: *sample_rate features: &n_mels 64 n_fft: 512 frame_splicing: 1 dither: 0.00001 stft_conv: false import nemo;
class NemoASR: def __init__(self, dataDir): self.datadir = dataDir; self.CONF_PATH = './config.yaml'; yaml = YAML(typ="safe"); with open(self.CONF_PATH) as f: self.CONFIG = yaml.load(f); def train(self, transcriptionPATH, manifestPATH, wavPATH, testTranscriptionPATH, testManifestPATH, testWavPATH): print("begin train"); train_transcripts = self.datadir + transcriptionPATH; train_manifest = self.datadir + manifestPATH; if not os.path.isfile(train_manifest): self.buildManifest(train_transcripts, train_manifest, wavPATH); test_transcripts = self.datadir + testTranscriptionPATH; test_manifest = self.datadir + testManifestPATH; if not os.path.isfile(test_manifest): self.buildManifest(test_transcripts, test_manifest, testWavPATH); # params from ./config.yaml self.CONFIG['model']['train_ds']['manifest_filepath'] = train_manifest; self.CONFIG['model']['validation_ds']['manifest_filepath'] = test_manifest; trainer = pl.Trainer(max_epochs=500, gpus=1); self.model = nemo_asr.models.EncDecCTCModel(cfg=DictConfig(self.CONFIG['model']), trainer=trainer); trainer.fit(self.model); print("end train"); #------------------------------------------------------------- nemoASR = NemoASR('.'); if (nemoASR.checkExistsDataSet()): print('dataset loaded'); nemoASR.train('./dataset/etc/train.transcription', './dataset/train_manifest.json','./dataset/wav/an4_clstk', './dataset/etc/test.transcription', './dataset/test_manifest.json', './dataset/wav/an4test_clstk'); nemoASR.model.save_to('./model.sbc'); files = ['./an4/wav/an4_clstk/mgah/cen2-mgah-b.wav'];
for fname, transcription in zip(files, nemoASR.model.transcribe(paths2audio_files=files)): print(f"Audio in {fname} was recognized as: {transcription}");
=========== Источник: habr.com =========== Похожие новости:
Программирование ), #_mashinnoe_obuchenie ( Машинное обучение ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 14:49
Часовой пояс: UTC + 5