Могу ли я изменить частоту обновления распознавателя ключевых слов PocketSphinx?

Я запускаю PocketSphinx на Android (версия 5prealpha). Я использую определяемый файлом распознаватель ключевых слов, указанный в следующем фрагменте (kwfile — это файл определения ключевого слова, а mRecognizer — экземпляр SpeechRecognizer):

mRecognizer.addKeywordSearch(DESCRIPTOR, kwfile);

В целом, производительность распознавания довольно хорошая после оптимизации пороговых значений ключевых слов. Однако, если я выжидаю некоторое произвольное количество времени (от 5 секунд до нескольких минут) между одним произнесением ключевого слова и следующим, эффективность распознавания второго высказывания снижается. Например, я скажу «ключевое слово», и оно будет распознано. Если я подожду менее 5 секунд и снова скажу «ключевое слово», второе высказывание, скорее всего, будет распознано (коэффициент распознавания более 95%). Однако, если я подожду 15 секунд, уровень распознавания резко упадет до менее 50%.

Моя гипотеза состоит в том, что когда я произношу ключевое слово во второй раз, распознаватель находится в середине обновления, то есть между событием Stop Recognition и событием Start Recognition, и что моя речь превосходит это событие. Вот типичный вид моего logcat. Обратите внимание, что через 5 секунд распознаватель «обновляется». Это происходит примерно каждые 5 секунд, по большей части. Иногда между «обновлениями» может пройти до 30 секунд, но обычно это около 5 секунд.

09-26 07:11:06.800  20397-20397/...﹕ Start recognition "kwfile"
09-26 07:11:06.815  20397-23642/...﹕ Starting decoding
09-26 07:11:11.310  20397-20397/...﹕ Stop recognition
09-26 07:11:11.315  20397-20397/...﹕ Start recognition "kwfile"
09-26 07:11:11.360  20397-23645/...﹕ Starting decoding
09-26 07:11:17.405  20397-20397/...﹕ Stop recognition

Итак, мой вопрос: могу ли я что-нибудь сделать, чтобы контролировать эту «частоту обновления»? Это вызвано чем-то, что я делаю неправильно в своей реализации RecognitionListener (см. ниже, но обратите внимание: я обычно не получаю частичных результатов между высказываниями.)? Или есть вызов API PocketSphinx, о котором я не знаю, чтобы установить эту частоту обновления? Или есть что-то, что я мог бы изменить в исходном коде PocketSphinx, чтобы улучшить это поведение?

class VoiceListener implements RecognitionListener{

        private boolean isCommand = false;

        @Override
        public void onBeginningOfSpeech() {
            Log.d(TAG,"Beginning of Speech");
            // do nothing
        }

        @Override
        public void onEndOfSpeech() {
            Log.d(TAG,"End of Speech");
            // do nothing
        }

        @Override
        public void onPartialResult(Hypothesis arg0) {
            if( arg0 != null){
                Log.d(TAG, "Partial results list: " + arg0.getHypstr());

                isCommand = false;

                // handle recognition results for keywords
                for( String command : this.getCurrentCommands() ) {
                    if (arg0.getHypstr().contains(command)) {
                        this.onRecognition(arg0.getHypStr());
                        isCommand = true;
                        mRecognizer.stop();
                    }
                }

                // call stop, and let onResults() handle grammar results
                if( arg0.getHypstr().contains(Command.STOP_WORD))
                    mRecognizer.stop();

            }
        }

        @Override
        public void onResult(Hypothesis results) {

            String data;
            if( results == null ){
                data = null;
            }else{
                data = results.getHypstr();
            }

            Log.d(TAG,"Final results: " + data );

            // handle grammar recognition results
            if( !isCommand ){
                this.onRecognition(data);
            }
            return;

        }

person Brad Kriel    schedule 26.09.2015    source источник


Ответы (1)


Нет такого понятия, как «частота обновления». Точность распознавания падает, вероятно, из-за того, что у вас есть шумы на фоне, и они не отфильтровываются должным образом. Вы можете изучить необработанные дампы, чтобы выяснить, считается ли молчание речью. Вы можете поделиться необработанными аудиодампами, чтобы получить помощь по этому вопросу.

В вашем коде есть вещи, которые не очень разумны. Если вы используете только обнаружение ключевых слов, нет необходимости останавливать и перезапускать распознаватель в onEndOfSpeech, как вы делаете сейчас, вы можете просто пропустить его. В режиме обнаружения вам не нужно ждать окончания речи, чтобы получить результат, вы можете просто использовать частичный результат для вызова действий и перезапуска распознавателя.

person Nikolay Shmyrev    schedule 26.09.2015
comment
Спасибо, Николай. На самом деле я распознаю как ключевые слова, так и грамматику, используя один и тот же RecognitionListener. Таким образом, я мог бы либо убрать функцию stop() и посмотреть, улучшит ли это ситуацию, либо разбить ее на два экземпляра SpeechRecognizer, один для ключевых слов, а другой для грамматик, а затем иметь два отдельных слушателя, один с остановкой и другой без него. В любом случае, я поиграю с вариантами и дам вам знать, как это работает. Если у меня все еще есть проблемы, я добавлю несколько аудиозаписей. - person Brad Kriel; 28.09.2015
comment
Не рекомендуется использовать два экземпляра. Затем вам нужно использовать один экземпляр и переключаться между поисками, но вы также должны отслеживать текущий поиск и избегать остановки распознавателя, если текущий поиск является ключевым словом. Демонстрация Android делает это правильно, вы можете просто следовать ей. - person Nikolay Shmyrev; 28.09.2015
comment
ХОРОШО. Я понял. Я также изменю свой блок кода с вашим ответом. Я убрал все из onEndOfSpeech() и обрабатываю ключевые слова прямо в onPartialResult(), а грамматики — в onResult(). Дополнительным бонусом является то, что теперь распознавание ключевых слов происходит значительно быстрее, поскольку не нужно ждать, пока распознаватель вызовет onResult(). Спасибо! - person Brad Kriel; 30.09.2015