В проекте Sphinx, разрабатываемом университетом Карнеги-Меллона, создаются средства распознавания речи с открытым исходным кодом для разработчиков и пользователей. В этой статье набор исходных кодов Sphinx-4 применяется для автоматического распознавания очень маленького словаря часто встречающихся букв и цифр. Преобразование этой произносимой информации в текст и анализ строк на наличие определенных структур данных, таких как телефонные номера и аббревиатуры, позволяет автоматически создавать содержательные аннотации устных разговоров.
Одна из наиболее полезных областей, к которым можно применить этот проект – это создание приложения для аннотирования телеконференций. Когда вы в следующий раз присоединитесь к конференции разработчиков, вы сможете запустить аннотатор устной речи и автоматически получать информацию о людях на основе их телефонных номеров, когда их назовут на конференции, или узнать, что означает сегодняшняя "аббревиатура дня", воспользовавшись поисковой системой. Вам не придется отвлекаться от своей текущей задачи, чтобы получить всю информацию о последней упомянутой аббревиатуре или порядковом номере сотрудника. Проект Sphinx-4 и создаваемый здесь аннотатор устной речи помогут вам избавиться от большой части рутинной работы.
Sphinx – очень ресурсоемкое приложение и требует современного и достаточно производительного оборудования. Для удовлетворительной работы приложения требуется довольно много оперативной памяти, поэтому рекомендуется запускать Sphinx на ПК с процессором не младше Intel® Pentium® 4 и минимум с 1 ГБ ОЗУ. В то же время обработка текста является гораздо менее ресурсоемкой операцией, поэтому можно спокойно запускать её параллельно с распознаванием речи на том же ПК без потерь в производительности для последней.
Приложения, которые будут созданы в ходе данной статьи, можно запускать на платформах Linux® или Microsoft® Windows®. Для Sphinx-4 требуется последняя версия JDK и Apache Ant для создания пользовательского обработчика грамматики. Также понадобится Perl и соответствующие поисковые (lookup) модули (выбираются на ваше усмотрение). Ссылки на дополнительные сведения об упомянутых программных пакетах, а также ссылки, по которым можно загрузить эти пакеты, см. в разделе Ресурсы.
В рамках проекта Sphinx создаются различные пакеты для различных задач распознавания речи. В этой статье используется пакет Sphinx-4, наиболее удобный из последних выпусков для пользователей и разработчиков. Установка Sphinx-4 может показаться некоторым сложной, поэтому здесь приведены основные шаги из инструкции по установке.
- Загрузите и распакуйте Apache Ant.
- Загрузите и распакуйте Sun JDK (на момент написания статьи последняя версия была 1.6.0_02).
- Загрузите и распакуйте пакет с исходным кодом Sphinx-4, так как мы будем изменять одну из демонстрационных программ, чтобы она соответствовала нашим целям.
- Установите переменные среды при помощи следующих команд:
export ANT_HOME=${PWD}/apache-ant-1.7.0 export JAVA_HOME=${PWD}/jdk1.6.0_02 export PATH=${PATH}:${ANT_HOME}/bin
В ОС Windows может потребоваться установить переменные среды в оснастке "Control Panel (Панель управления) > System (Система) > Advanced (Дополнительно) > Environment variables (Переменные среды)". - Перейдите в каталог "sphinx4-beta", затем в подкаталог "lib".
- Активируйте бинарную лицензию JSAPI, запустив сценарий оболочки jsapi.sh. Sphinx-4 поддерживает JSAPI с бинарной лицензией, так что потребуется принять лицензионное соглашение.
- Может потребоваться установить uudecode, чтобы распаковать компоненты, требуемые для JSAPI. В большинство дистрибутивов Linux включен пакет, так или иначе содержащий uudecode, так что проверьте сначала доступные пакеты, если потребуется установить uudecode. В ОС Windows дважды щелкните правой кнопкой мыши файл jsapi.exe и примите лицензионное соглашение.
- Вернитесь в корневой каталог Sphinx4.
- Запустите команду
ant: должен начаться процесс сборки.
Сообщение о состоянии "BUILD SUCCESSFUL" означает, что среда успешно настроена, и можно переходить к шагам модификации. Если отобразится другое сообщение, проверьте каталог сборки и настройки переменных среды или обратитесь к руководствам по Apache Ant и Sphinx-4 за более подробными инструкциями по установке для вашей среды.
Стратегия независимого от диктора распознавания букв и чисел в речи
Всегда кажется, что технологии распознавания речи осталось от 2 до 10 лет до успешного независимого от диктора распознавания большого словаря речи. Аннотировать разговор с множеством голосов, с одновременной речью, различными акцентами и многочисленными техническими и разговорными выражениями, - задача почти неразрешимая для любого программного обеспечения потребительского класса, доступного на рынке. Однако пакеты Sphinx, и, в частности, Sphinx-4, предоставляют все необходимое опции, чтобы достоверно распознать маленький (но тем не менее полезный) словарь без привязки к диктору.
Мы уже определили наш ограниченный словарь: буквы английского алфавита A-Z и цифры 0-9. Наша стратегия - это просто выделять любые области, где были произнесены эти буквы или цифры. Общее название такого подхода - выделение слов. Хотя в настоящее время Sphinx-4 не поддерживает выделение слов, мы тем не менее можем достичь полезных результатов, проверяя каждое произносимое звукосочетание на соответствие по крайней мере одному слову из грамматики. Затем, имея список наиболее подходящих букв и цифр, мы можем применить стандартные инструменты обработки текста и информационные справочники для извлечения полезной информации.
Пользовательский словарь, модификация примера "Hello World"
На первом шаге создания механизма "выделения слов" мы создадим файл с заданным словарем. В дереве директорий Sphinx-4 есть директория под названием
bld/models/edu/cmu/sphinx/model/acoustic/WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz/dict/.
Здесь содержатся файлы со словарями под названием alpha.dict и digit.dict. На первый взгляд кажется, что сочетание этих двух словарей даст желаемый файл. Это совсем не так. Нам надо создать наши файлы словаря из файла cmudict.0.6d в той же директории.
Заходим в директорию bld/models/edu/cmu/sphinx/model/acoustic/WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz/dict/ и применяем следующие команды для создания желаемого файла словаря:
perl -ne 'print if( /^[A-Z]\ / )' cmudict* > alN.dict perl -ne 'print if(/^(ZERO|ONE|TWO|THREE|FOUR)[ (]/)' cmudict* >> alN.dict perl -ne 'print if(/^(FIVE|SIX|SEVEN|EIGHT|NINE)[ (]/)' cmudict* >> alN.dict |
В листинге 1 показан созданный файл alN.dict, содержимым которого являются только буквы и цифры.
Листинг 1. Часть файла alN.dict
...
W D AH B AH L Y UW
X EH K S
Y W AY
Z Z IY
FOUR F AO R
ONE HH W AH N
ONE(2) W AH N
THREE TH R IY
...
|
Модификации примера "Hello World"
Sphinx-4 предоставляет множество настроек, позволяющих удовлетворить практически любые требования в области распознавания речи. В нашем случае наиболее эффективным подходом будет изменение имеющегося примера "Hello World". В корневой директории Sphinx-4 заходим в директорию
demo/sphinx/helloworld и редактируем файл helloworld.config.xml. В листинге 2 показана единственная строка, которую требуется изменить для использования файла alN.dict, который мы создали.
Листинг 2. Изменения в файле helloworld.config.xml
original (line 114):
<property name="dictionaryPath"
value="resource:/edu.cmu.sphinx.model.
acoustic.WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz.
Model!/edu/cmu/sphinx/model/acoustic/WSJ_8gau_13d
Cep_16k_40mel_130Hz_6800Hz/dict/cmudict.0.6d"/>
new:
<property name="dictionaryPath"
value="resource:/edu.cmu.sphinx.model.
acoustic.WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz.
Model!/edu/cmu/sphinx/model/acoustic/WSJ_8gau_13d
Cep_16k_40mel_130Hz_6800Hz/dict/alN.dict"/>
|
Также надо изменить файл с грамматикой hello.gram в той же директории. В листинге 3 показаны изменения, которые нужно внести, чтобы собирать только буквы и цифры из нашего файла словаря.
Листинг 3. Изменения в файле hello.gram
original:
public <greet> = (Good morning | Hello)
( Bhiksha | Evandro | Paul | Philip | Rita | Will );
new:
public <greet> = ( zero | one | two | three | four | five | six |seven | eight | nine |
a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v |
w | x | y | z) * ;
|
Нам также надо внести незначительные изменения в файл HelloWorld.java, как показано ниже:
Листинг 4. Изменения в файле HelloWorld.java
original (line 59):
System.out.println
("Say: (Good morning | Hello) " +
"( Bhiksha | Evandro | Paul | Philip | Rita | Will )");
new:
System.out.println
("Listening for letters and numbers");
|
Когда сделаны все необходимые изменения, мы можем собрать и запустить пример. В домашней директории Sphinx-4 выполняем команду ant (то же сообщение "BUILD SUCCESSFUL" даст вам знать, правильно ли вы внесли все изменения). Запустите обновленный пример с помощью команды $JAVA_HOME/bin/java -mx312m -jar
bin/HelloWorld.jar (в системе Linux). Для Windows команда будет такой: java -mx312m
-jar bin/HelloWorld.jar. Проговорите следующее предложение: "The phone number for IBM tech support is one eight zero zero four two six seven three seven eight" (Номер телефона IBM - один восемь ноль ноль четыре два шесть семь три семь восемь) и вы получите примерно такой результат, как показано ниже:
f o nine r four i b m x a four t one eight zero zero four two six seven three seven eight |
Как вы можете видеть, выделение букв и цифр из произнесенного предложения закончилось лишь частичным успехом. Буквы "IBM" и цифры телефонного номера распознаются правильно, но оставшиеся слова были неправильно распознаны как различные буквы и цифры, наиболее подходящие для определенных звуков.
Возможно, у вас даже назрел вопрос: что мешает использовать многотысячный словарь, чтобы обработать те самые неправильно распознанные случаи? В конце концов, в Sphinx-4 доступны языковые модели и большие словарные базы. Почему бы просто не настроить демонстрационный пример на распознавание оставшейся части предложения: "The phone number for tech support is", а также любых других слов, которые могут быть произнесены?
Ответ: Sphinx-4 — хорошее приложение, но не идеальное. Расширение файла словаря для распознавания сотен и тысяч слов резко снизит эффективность распознавания отдельных цифр и букв. Убедиться в этом можно, ознакомившись с другими программами в подкаталоге demo пакета Sphinx-4 или изменив существующие примеры, настроив их на использование больших файлов словарей и расширенных грамматических списков. Как оказывается, последующая обработка текста, состоящего только из букв и цифр, для поиска данных более высокого уровня — гораздо более простой метод построения работоспособной и полезной системы аннотирования на основе доступных систем с открытым исходным кодом.
Извлечение аббревиатур и телефонных номеров из выходного текста становится достаточно простой задачей, если следовать двум простым правилам: сочетание трех любых букв считается аббревиатурой, а сочетание любых пяти или более цифр – телефонным номером. В листингах 5, 6 и 7 рассматриваются компоненты сценария annotateAcrNum.pl, которые производят эти запросы и извлечения:
Листинг 5. annotateAcrNum.pl часть 1 — основная логика программы
#!/usr/bin/perl -w
# annotateAcrNum.pl - извлекает и ищет аббревиатуры и цифры в текстовом
# файле с записанной речью
use strict;
use Yahoo::Search;
use Net::Dict;
$|=1; # результаты не буферизуются для улучшения скорости отклика
my %numHash =
("zero" => "0",
"one" => "1",
"two" => "2",
"three" => "3",
"four" => "4",
"five" => "5",
"six" => "6",
"seven" => "7",
"eight" => "8",
"nine" => "9" );
while( my $line = <STDIN> )
{
print "$line" if( $line =~ /(Start|You said:)/ );
next unless ( $line =~ /You said:/ );
my @words = split " ", substr($line,9); # ignore the "You said:" prefix
my @numArr = ();
my @letArr = ();
foreach my $chunk ( @words )
{
if( length($chunk) == 1 )
{
phoneNmSearch(@numArr) if( @numArr > 4 );
@numArr = ();
push @letArr, $chunk;
if( @letArr > 2 )
{
acronymSearch( @letArr );
shift( @letArr );
}
}elsif( length($chunk) > 1 )
{
push @numArr, $numHash{$chunk};
@letArr = ();
}#если длина больше
}#для каждого слова
phoneNmSearch( @numArr ) if( @numArr > 4 );
acronymSearch( @letArr ) if( @letArr > 2 );
}#while stdin
|
Приведенная выше основная логика программы ищет последовательности букв и цифр, соответствующих нашим простым критериям. Для каждой строки текста с результатами распознавания речи измененного кода "Hello World" программа строит отдельно массивы букв и цифр. Поиск по массиву букв осуществляет подпрограмма acronymSearch, о которой мы расскажем ниже. Обратите внимание, что массив букв сдвигается после каждой встреченной аббревиатуры, чтобы можно было найти в строке "i b m x" и "ibm", и "bmx" . В массиве цифр мы такой сдвиг не выполняем, вместо этого мы берем длинные номера, которые программа может найти, и выполняем поиск в Интернете.
Листинг 6. annotateAcrNum.pl часть 2 — программа acronymSearch
sub acronymSearch
{
my $dict = Net::Dict->new('dict.org');
my $str = @_; $str =~ s/ //g;
my $eref = $dict->define($str);
next if ($eref eq "" );
foreach my $entry (@$eref)
{
my ($db, $definition) = @$entry;
next if ( !(defined($definition)) || !(defined($db)) );
if( $db =~ /(wn|vera|gazetteer|foldoc)/ ){ print "$db: $definition\n" }
}#для каждого определения
}#acronymSearch
|
Подпрограмма acronymSearch использует полезный модуль Net::Dict. Мы просто задаем сервер словарей и запрос на поиск во множестве доступных баз данных. Регулярное выражение /(wn|vera|gazetteer|foldoc)/ ограничивает вывод тех баз данных, которые дают относительно короткие описания. Возможно, вы обнаружите, что ваша совокупность аббревиатур лучше представлена в других базах данных сайта dict.org – тогда это ограничение нужно будет убрать из регулярного выражения.
Листинг 7. annotateAcrNum.pl часть 3 — phoneNmSearch
sub phoneNmSearch
{
my $str = @_; $str =~ s/ //g;
if( length($str) == 11 )
{
$str =~ /(\d)(\d\d\d)(\d\d\d)(\d\d\d\d)/;
$str = "$1-$2-$3-$4\n";
}elsif( length($str) == 10 )
{
$str =~ /(\d\d\d)(\d\d\d)(\d\d\d\d)/;
$str = "$1-$2-$3\n";
}elsif( length($str) == 7 )
{
$str =~ /(\d\d\d)(\d\d\d\d)/;
$str = "$1-$2\n";
}
print "Results for: $str\n";
my @results = Yahoo::Search->Results(Doc => "$str", AppId => "PhNmLookup" );
warn $@ if $@; # report any errors
my $recCount = 0;
for my $res (@results)
{
print "Title: ", $res->Title, " \n";
print $res->Summary, "\n";
print $res->Url, "\n";
print "\n";
last if( $recCount > 1 ); # print first 3 results only
$recCount++;
}#для каждого результата
}#phoneNmSearch
|
Некоторые механизмы поиска дают гораздо более точные результаты, если добавить к телефонным номерам форматирование. Этим занимается первый блок подпрограммы phoneNmSearch, меня, например, 18004267378 на 1-800-426-7378 или 4152042 на 415-2042. Затем такой слегка модифицированный телефонный номер используется как параметр запроса в поисковике Yahoo! с помощью удобного модуля Джеффри Фридла (Jeffrey Friedl) Yahoo::Search, написанного на Perl.
Теперь, имея наш механизм распознавания речи на основе Sphinx-4 и Perl-программу annotateAcrNum, мы можем начинать аннотировать разговорные диалоги. Запустите аннотатор командой $JAVA_HOME/bin/java -mx312m -jar bin/HelloWorld.jar | perl
annotateAcrNum.pl (для Linux). Для Windows команда выглядит так:
java -mx312m -jar bin/HelloWorld.jar | perl
annotateAcrNum.pl.
На рисунке 1 показан вывод аннотатора в терминале на Vector Linux. Обратите внимание на подчеркнутые ссылки. По этим ссылкам открываются страницы, найденные с помощью Web-поиска.
Рисунок 1. Скриншот аннотатора диалогов в терминале на Vector Linux
Типы запросов и баз данных, выбранные для поиска в данной статье, - это лишь общие примеры полезности аннотирования. Возможно, для вас эффективнее будет использовать Google в качестве Web-поисковика, или вы можете производить поиск телефонных номеров в адресной книге своих сотрудников. То же касается и методов извлечения данных более высокого порядка из распознаваемых букв и цифр. Может быть, в ваших диалогах чаще встречаются IP-адреса или регистрационные номера сотрудников. Используя описанные методы, вы можете извлекать IP-адреса, уникальные идентификаторы сотрудников и ссылки для поиска по своим собственным базам данных.
Sphinx-4 также предоставляет множество возможностей для повышения эффективности распознавания речи. Подумайте о возможности создания своей собственной акустической модели на основе обучения для себя и членов вашей команды, чтобы обеспечить значительно более высокий уровень точности. Расширьте файл словаря, включив в него десятки тысяч часто употребляемых слов, и попробуйте, как Sphinx-4 транскрибирует речь в режиме реального времени.
| Описание | Имя | Размер | Метод загрузки |
|---|---|---|---|
| Пример кода | os-sphinxspeechrecAnnotations_0.1.zip | 4 КБ | HTTP |
Научиться
- Оригинал статьи Create automated verbal conversation annotations for phone numbers, acronyms, and other spoken words
(EN).
- Чтобы изучить применение методов C++ в качестве сервиса, прочитайте статью "Использование приложений на C++ для Web-сервисов с помощью XML-RPC" (EN).
- Подкасты developerWorks - интересные интервью и дискуссии для разработчиков программного обеспечения (EN).
- Следите за техническими событиями и Web-трансляциями на developerWorks (EN).
- Следите за проходящими по всему миру конференциями, выставками, web-трансляциями и другими событиями, интересными для разработчиков ПО с открытым исходным кодом для IBM (EN).
- • Получайте информацию о технологиях IBM и ПО с открытым исходным кодом, функциях продуктов из бесплатных демонстраций developerWorks по требованию (EN).
Получить продукты и технологии
- Узнайте подробнее о пакете Sphinx-4 и загрузите его.
-
binary
extractor V1.6.0_02 - JDK-файл, использованный в данном проекте.
-
В Perl-скриптах для аннотаций используются модули Net::Dict и Yahoo::Search из CPAN.
-
Если в вашей системе не установлен Perl, загрузите его с сайта Perl.org.
- Используйте в вашем следующем проекте с открытым исходным кодом ознакомительное программное обеспечение IBM, которое можно загрузить через Интернет или заказать на DVD.
-
Загрузите ознакомительные версии продуктов IBM и испробуйте инструментальные средства разработки приложений и программы промежуточного уровня DB2®, Lotus®, Rational®, Tivoli® и WebSphere®.
Обсудить
- Примите участие в обсуждении материала на форуме.
-
Принимайте участие в блогах developerWorks и подключайтесь к сообществу developerWorks.