Как можно указать ключевые слова для Watson's Speech-To-Text Unity SDK?

Я пытаюсь указать ключевые слова в Watson Speech-To-Text Unity SDK, но не знаю, как это сделать.

На странице сведений нет примера (см. Здесь: https://www.ibm.com/watson/developercloud/doc/speech-to-text/output.shtml),

и другие сообщения на форуме написаны для приложений Java (см. здесь: Как указать фонетические ключевые слова для службы Speech2text IBM Watson?).

Я пробовал жестко закодировать эти значения в классе RecognizeRequest, созданном в функции «Распознать», вот так, но безуспешно:

** РЕДАКТИРОВАТЬ - эта функция никогда не вызывается - **

public bool Recognize(AudioClip clip, OnRecognize callback)
    {
        if (clip == null)
            throw new ArgumentNullException("clip");
        if (callback == null)
            throw new ArgumentNullException("callback");

        RESTConnector connector = RESTConnector.GetConnector(SERVICE_ID, "/v1/recognize");
        if (connector == null)
            return false;

        RecognizeRequest req = new RecognizeRequest();
        req.Clip = clip;
        req.Callback = callback;

        req.Headers["Content-Type"] = "audio/wav";
        req.Send = WaveFile.CreateWAV(clip);
        if (req.Send.Length > MAX_RECOGNIZE_CLIP_SIZE)
        {
            Log.Error("SpeechToText", "AudioClip is too large for Recognize().");
            return false;
        }
        req.Parameters["model"] = m_RecognizeModel;
        req.Parameters["continuous"] = "false";
        req.Parameters["max_alternatives"] = m_MaxAlternatives.ToString();
        req.Parameters["timestamps"] = m_Timestamps ? "true" : "false";
        req.Parameters["word_confidence"] = m_WordConfidence ? "true" :false";

        //these "keywords" and "keywords_threshold" and "keywordsThreshold" parameters
        //are just my guess for how to set these values            
        req.Parameters["keywords"] = new string[] {"fun", "match", "test" };
        req.Parameters["keywordsThreshold"] = .2;
        req.Parameters["keywords_threshold"] = .2;
        //end my test insertions

        req.OnResponse = OnRecognizeResponse;

        return connector.Send(req);
    }

но возвращенное значение результата SpeechRecognitionEvent не содержит никакого keywords_result. Это моя цель. Я пытаюсь проверить достоверность каждого ключевого слова в объекте keyword_result, но объект keywords_result возвращается как null.

private void OnRecognize(SpeechRecognitionEvent result) {
    Debug.Log("Recognizing!");
    m_ResultOutput.SendData(new SpeechToTextData(result));

    if (result != null && result.results.Length > 0) {
        if (m_Transcript != null)
            m_Transcript.text = "";

        foreach (var res in result.results) {
            //the res.keywords_result comes back as null
            foreach (var keyword in res.keywords_result.keyword) {
                string text = keyword.normalized_text;
                float confidence = keyword.confidence;
                Debug.Log(text + ": " + confidence);                                            
            }
        }
    }
}

Кто-нибудь успешно реализовал оценку достоверности ключевых слов с помощью пакета SDK Watson Speech-To-Text в Unity или C #? Все идеи и предложения приветствуются.

PS Это мой первый пост :)


person Brandon Rivera-Melo    schedule 09.10.2016    source источник
comment
Это нужно делать с Ватсоном? Если нет, то посмотрите здесь.   -  person Programmer    schedule 09.10.2016
comment
Думаю, нужно попробовать понизить порог. Попробуйте 0,1 вместо 0,2 или даже 0,00001   -  person Nikolay Shmyrev    schedule 09.10.2016
comment
Функция преобразования текста в текст Unity использует для работы Watson. См. Здесь, в разделе комментариев: assetstore.unity3d.com/en/#! / content / 69399   -  person Brandon Rivera-Melo    schedule 09.10.2016
comment
@NikolayShmyrev Я тоже снизил порог. Не в этом проблема. Пожалуйста, прочтите требования этого поста. См. Решение ниже   -  person Brandon Rivera-Melo    schedule 09.10.2016
comment
Привет, я часть команды Watson. Если вы откроете вопрос, я уверен, что Тадж (наш технический руководитель) поможет вам в этом. Вы даже можете создать запрос на перенос! github.com/watson-developer-cloud/unity-sdk/issues   -  person German Attanasio    schedule 10.10.2016
comment
@GermanAttanasio отлично! Я отправил запрос на перенос, и Тадж обратился ко мне раньше, чтобы прокомментировать мой ответ ниже, но, похоже, он пропал. Я тоже открыл вопрос на странице github! Я рад внести свой вклад! Замечательный сервис: D   -  person Brandon Rivera-Melo    schedule 11.10.2016


Ответы (1)


Оказывается, мне нужно было указать ключевые слова в функции «SendStart» следующим образом:

private void SendStart() {
        if (m_ListenSocket == null)
            throw new WatsonException("SendStart() called with null connector.");

        Dictionary<string, object> start = new Dictionary<string, object>();
        start["action"] = "start";
        start["content-type"] = "audio/l16;rate=" + m_RecordingHZ.ToString() + ";channels=1;";
        start["continuous"] = EnableContinousRecognition;
        start["max_alternatives"] = m_MaxAlternatives;
        start["interim_results"] = EnableInterimResults;
        start["word_confidence"] = m_WordConfidence;
        start["timestamps"] = m_Timestamps;

        //specify keywords here
        start["keywords"] = keywordsToCheck.ToArray();
        start["keywords_threshold"] = 0.05;
        //end additions here 

        m_ListenSocket.Send(new WSConnector.TextMessage(Json.Serialize(start)));
        m_LastStartSent = DateTime.Now;
    }

и напишите код для правильного анализа keyword_results в функции "ParseRecognizeResponse":

private SpeechRecognitionEvent ParseRecognizeResponse(IDictionary resp){

        if (resp == null)
            return null;


        List<SpeechRecognitionResult> results = new List<SpeechRecognitionResult>();
        IList iresults = resp["results"] as IList;
        if (iresults == null)
            return null;

        foreach (var r in iresults)
        {
            IDictionary iresult = r as IDictionary;
            if (iresults == null)
                continue;

            SpeechRecognitionResult result = new SpeechRecognitionResult();

            //added this section, starting here
            IDictionary iKeywords_result = iresult["keywords_result"] as IDictionary;
            result.keywords_result = new KeywordResults();
            List<KeywordResult> keywordResults = new List<KeywordResult>();
            foreach (string key in keywordsToCheck) {
                if (iKeywords_result[key] != null) {
                    IList keyword_Results = iKeywords_result[key] as IList;
                    if (keyword_Results == null) {
                        continue;
                    }
                    foreach (var res in keyword_Results) {
                        IDictionary kw_resultDic = res as IDictionary;
                        KeywordResult keyword_Result = new KeywordResult();
                        keyword_Result.confidence = (double)kw_resultDic["confidence"];
                        keyword_Result.end_time = (double)kw_resultDic["end_time"];
                        keyword_Result.start_time = (double)kw_resultDic["start_time"];
                        keyword_Result.normalized_text = (string)kw_resultDic["normalized_text"];
                        keywordResults.Add(keyword_Result);
                    }
                }
            }
            result.keywords_result.keyword = keywordResults.ToArray();                   
            //ends here

            result.final = (bool)iresult["final"];

            IList ialternatives = iresult["alternatives"] as IList;
            if (ialternatives == null)
                continue;

            List<SpeechRecognitionAlternative> alternatives = new List<SpeechRecognitionAlternative>();
            foreach (var a in ialternatives)
            {
                IDictionary ialternative = a as IDictionary;
                if (ialternative == null)
                    continue;

                SpeechRecognitionAlternative alternative = new SpeechRecognitionAlternative();
                alternative.transcript = (string)ialternative["transcript"];
                if (ialternative.Contains("confidence"))
                    alternative.confidence = (double)ialternative["confidence"];

                if (ialternative.Contains("timestamps"))
                {
                    IList itimestamps = ialternative["timestamps"] as IList;

                    TimeStamp[] timestamps = new TimeStamp[itimestamps.Count];
                    for (int i = 0; i < itimestamps.Count; ++i)
                    {
                        IList itimestamp = itimestamps[i] as IList;
                        if (itimestamp == null)
                            continue;

                        TimeStamp ts = new TimeStamp();
                        ts.Word = (string)itimestamp[0];
                        ts.Start = (double)itimestamp[1];
                        ts.End = (double)itimestamp[2];
                        timestamps[i] = ts;
                    }

                    alternative.Timestamps = timestamps;
                }
                if (ialternative.Contains("word_confidence"))
                {
                    IList iconfidence = ialternative["word_confidence"] as IList;

                    WordConfidence[] confidence = new WordConfidence[iconfidence.Count];
                    for (int i = 0; i < iconfidence.Count; ++i)
                    {
                        IList iwordconf = iconfidence[i] as IList;
                        if (iwordconf == null)
                            continue;

                        WordConfidence wc = new WordConfidence();
                        wc.Word = (string)iwordconf[0];
                        wc.Confidence = (double)iwordconf[1];
                        confidence[i] = wc;
                    }

                    alternative.WordConfidence = confidence;
                }

                alternatives.Add(alternative);
            }
            result.alternatives = alternatives.ToArray();
            results.Add(result);
        }

        return new SpeechRecognitionEvent(results.ToArray());                        
    }

Итак, теперь, когда OnRecognize получает это событие SpeechRecognitionEvent, я изменил код для отображения альтернативных слов и их оценки достоверности, чтобы отображать результаты ключевых слов и их оценку достоверности, например:

private void OnRecognize(SpeechRecognitionEvent result) {
    //Debug.Log("Recognizing!");
    m_ResultOutput.SendData(new SpeechToTextData(result));

    if (result != null && result.results.Length > 0) {
        if (m_Transcript != null)
            m_Transcript.text = "";

        foreach (var res in result.results) {
            //start keyword recognition changes here
            if (res.keywords_result != null) {
                if (res.keywords_result.keyword != null) {
                    foreach (var keyword in res.keywords_result.keyword) {
                        m_Transcript.text += string.Format("{0} ({1}, {2:0.00})\n",
                            keyword.normalized_text, res.final ? "Final" : "Interim", keyword.confidence);
                    }
                }
            }
            //end here                
        }
    }
}

Обратите внимание: использование значений достоверности результатов ключевых слов гораздо более ценно, чем выполнение жестко запрограммированной проверки, чтобы увидеть, соответствуют ли альтернативные слова вашим ключевым словам, а затем использовать там значение достоверности. Значения достоверности возвращаются намного выше при проверке значений keyword_results.keyword []. Достоверности, потому что он уже проверяет эти слова. Это послужило толчком для завершения этого процесса и анализа значения результата SpeechRecognitionEvent для правильного включения значений keywords_result.

Для некоторой предыстории я создаю ритмическую игру для детей с дислексией, чтобы выучить словообразование, так что подумайте, что Guitar Hero встречает улицу Сезам.

person Brandon Rivera-Melo    schedule 09.10.2016