كيفية التعرف على الأهداف من الكلام باستخدام Speech SDK for C#‎

تتكامل خدمات Azure الذكاء الاصطناعي Speech SDK مع خدمة Language Understanding (LUIS) لتوفير التعرف على الهدف. الهدف هو شيء يريد المستخدم القيام به: حجز رحلة، أو معرفة حالة الطقس، أو إجراء مكالمة. يمكن للمستخدم أن يستخدم أي مصطلحات تبدو طبيعية. يعين LUIS طلبات المستخدم إلى الأهداف التي حددتها.

إشعار

يحدد تطبيق LUIS الأهداف والكيانات التي تريد التعرف عليها. إنه منفصل عن تطبيق C# الذي يستخدم خدمة الكلام. في هذه المقالة، يميز السياق بين تطبيق LUIS وتطبيق C# الذي يشير إلى تعليمات C# البرمجية.

في هذا الدليل، تستخدم Speech SDK لتطوير تطبيق وحدة تحكم C# يستمد الأهداف من عبارات المستخدم عبر ميكروفون جهازك. ‏‫ستتعلم كيفية:

  • أنشئ مشروع Visual Studio بالرجوع إلى حزمة Speech SDK NuGet
  • إنشاء تكوين الكلام والحصول علـى أداة التعرف على الهدف
  • احصل على نموذج لتطبيق LUIS وأضف الأهداف التي تحتاج إليها
  • حدد لغة التعرف على الكلام
  • التعرف على الكلام من ملف
  • استخدم التعرف المستمر غير المتزامن المستند إلى الحدث

المتطلبات الأساسية

تأكد من أن لديك العناصر التالية قبل بدء هذا الدليل:

تطبيق LUIS والكلام

يتكامل LUIS مع خدمة الكلام للتعرف على الأهداف من الكلام. لا يلزمك اشتراك خدمة Speech، فقط LUIS.

يستخدم LUIS نوعي مفاتيح:

نَوع المفتاح الغرض
التأليف يوفر لك إنشاء تطبيقات LUIS وتعديلها برمجيًا
التنبؤ يستخدم للوصول إلى تطبيق LUIS في وقت التشغيل

من أجل هذا الدليل، تحتاج إلى نوع مفتاح التنبؤ. يستخدم هذا الدليل مثال Home Automation من تطبيق LUIS، والذي يمكنك إنشاؤه باتباع دليل التشغيل السريع استخدام تطبيق التشغيل الآلي المنزلي المبني مسبقًا. إذا قمت بإنشاء تطبيق LUIS خاص بك، يمكنك استخدامه بدلا من ذلك.

عند إنشاء تطبيق LUIS، يقوم LUIS تلقائيًا بإنشاء مفتاح تأليف حتى تتمكن من اختبار التطبيق باستخدام استعلامات نصية. لا يمكن هذا المفتاح تكامل خدمة الكلام ولا يعمل مع هذا الدليل. أنشئ مورد LUIS في لوحة معلومات Azure وخصصه لتطبيق LUIS. يمكن استخدام طبقة الاشتراك المجانية لهذا الدليل.

بعد إنشاء مورد LUIS في لوحة معلومات Azure، سجِّل الدخول إلى مدخل LUIS، واختر تطبيقك على صفحة تطبيقاتي، ثم قم بالتبديل إلى صفحة الإدارة في التطبيق. وأخيرًا، حدد موارد Azure في الشريط الجانبي.

Shows a screenshot of the LUIS portal keys and endpoint settings.

في الصفحة موارد Azure:

حدد الأيقونة بجانب مفتاح لنسخه إلى الحافظة. (يمكنك استخدام أي من المفتاحين.)

إنشاء المشروع وإضافة حمل العمل

لإنشاء مشروع Visual Studio لتطوير Windows، تحتاج إلى إنشاء المشروع، وإعداد Visual Studio لتطوير .NET لسطح المكتب، وتثبيت Speech SDK، واختيار الهيكلة المستهدفة.

للبدء، أنشئ المشروع في Visual Studio، وتأكد من إعداد Visual Studio لتطوير .NET لسطح المكتب:

  1. افتح Visual Studio 2019.

  2. في نافذة البدء، حدد إنشاء مشروع جديد.

  3. في نافذة Create a new project ، اختر Console App (.NET Framework)، ثم حدد Next.

  4. في نافذة Configure your new project، أدخل helloworld في Project name، واختر مسار الدليل أو أنشئه في Location، ثم حدد Create.

  5. من شريط القوائم Visual Studio، حدد أدوات>الحصول على الأدوات والميزات، والتي تفتح Visual Studio Installer وتعرض مربع الحوار تعديل .

  6. تحقق مما إذا كان حمل عمل تطوير سطح المكتب .NET متوفرا. إذا لم يتم تثبيت حمل العمل، فحدد خانة الاختيار الموجودة بجانبه، ثم حدد تعديل لبدء التثبيت. التنزيل والتثبيت قد يستغرقان بضع دقائق.

    إذا كانت خانة الاختيار بجوار تطوير سطح المكتب .NET محددة بالفعل، فحدد إغلاق للخروج من مربع الحوار.

    Enable .NET desktop development

  7. أغلق Visual Studio Installer.

قم بتثبيت Speech SDK

الخطوة التالية هي تثبيت حزمة Speech SDK NuGet، بحيث يمكنك الرجوع إليها في التعليمة البرمجية.

  1. في مستكشف الحلول، انقر بزر الماوس الأيمن فوق مشروع helloworld، ثم حدد Manage NuGet Packages لإظهار مدير الحِزَم NuGet.

    NuGet Package Manager

  2. في الركن الأيمن العلوي، ابحث عن المربع المنسدل مصدر الحزمة ، وتأكد من تحديد nuget.org.

  3. في الزاوية العلوية اليمنى، حدد Browse.

  4. في مربع البحث، اكتب Microsoft.CognitiveServices.Speech وحدد Enter.

  5. من نتائج البحث، حدد حزمة Microsoft.CognitiveServices.Speech ، ثم حدد تثبيت لتثبيت أحدث إصدار مستقر.

    Install Microsoft.CognitiveServices.Speech NuGet package

  6. اقبل جميع الاتفاقيات والتراخيص لبدء التثبيت.

    بعد تثبيت الحزمة، يظهر تأكيد في نافذة وحدة التحكم مدير الحِزَم.

اختيار الهيكلة المستهدفة

الآن، لإنشاء وتشغيل تطبيق وحدة التحكم، أنشئ تكوين النظام الأساسي المطابق لهيكلة الكمبيوتر الخاص بك.

  1. من شريط القوائم، حدد Build>Configuration Manager. يظهر مربع الحوار Configuration Manager.

    Configuration Manager dialog box

  2. في المربع المنسدلة النظام الأساسي للحل النشط، حدد جديد. يظهر مربع الحوار New Solution Platform.

  3. في المربع المنسدلة اكتب أو حدد النظام الأساسي الجديد:

    • إذا كنت تقوم بتشغيل Windows 64 بت، فحدد x64.
    • إذا كنت تقوم بتشغيل Windows 32 بت، فحدد x86.
  4. حدد موافق ثم إغلاق.

أضف التعليمات البرمجية

بعد ذلك، تضيف التعليمة البرمجية إلى المشروع.

  1. من مستكشف الحلول، افتح الملف Program.cs.

  2. استبدل مجموعة عبارات using في بداية الملف بالبيانات التالية:

    using System;
    using System.Threading.Tasks;
    using Microsoft.CognitiveServices.Speech;
    using Microsoft.CognitiveServices.Speech.Audio;
    using Microsoft.CognitiveServices.Speech.Intent;
    
  3. استبدل أسلوب Main() المقدم بالمكافئ غير المتزامن التالي:

    public static async Task Main()
    {
        await RecognizeIntentAsync();
        Console.WriteLine("Please press Enter to continue.");
        Console.ReadLine();
    }
    
  4. أنشئ أسلوبًا غير متزامن فارغًا RecognizeIntentAsync()، كما هو موضح هنا:

    static async Task RecognizeIntentAsync()
    {
    }
    
  5. في نص هذا الأسلوب الجديد، أضف هذه التعليمة البرمجية:

    // Creates an instance of a speech config with specified subscription key
    // and service region. Note that in contrast to other services supported by
    // the Cognitive Services Speech SDK, the Language Understanding service
    // requires a specific subscription key from https://www.luis.ai/.
    // The Language Understanding service calls the required key 'endpoint key'.
    // Once you've obtained it, replace with below with your own Language Understanding subscription key
    // and service region (e.g., "westus").
    // The default language is "en-us".
    var config = SpeechConfig.FromSubscription("YourLanguageUnderstandingSubscriptionKey", "YourLanguageUnderstandingServiceRegion");
    
    // Creates an intent recognizer using microphone as audio input.
    using (var recognizer = new IntentRecognizer(config))
    {
        // Creates a Language Understanding model using the app id, and adds specific intents from your model
        var model = LanguageUnderstandingModel.FromAppId("YourLanguageUnderstandingAppId");
        recognizer.AddIntent(model, "YourLanguageUnderstandingIntentName1", "id1");
        recognizer.AddIntent(model, "YourLanguageUnderstandingIntentName2", "id2");
        recognizer.AddIntent(model, "YourLanguageUnderstandingIntentName3", "any-IntentId-here");
    
        // Starts recognizing.
        Console.WriteLine("Say something...");
    
        // Starts intent recognition, and returns after a single utterance is recognized. The end of a
        // single utterance is determined by listening for silence at the end or until a maximum of 15
        // seconds of audio is processed.  The task returns the recognition text as result. 
        // Note: Since RecognizeOnceAsync() returns only a single utterance, it is suitable only for single
        // shot recognition like command or query. 
        // For long-running multi-utterance recognition, use StartContinuousRecognitionAsync() instead.
        var result = await recognizer.RecognizeOnceAsync().ConfigureAwait(false);
    
        // Checks result.
        if (result.Reason == ResultReason.RecognizedIntent)
        {
            Console.WriteLine($"RECOGNIZED: Text={result.Text}");
            Console.WriteLine($"    Intent Id: {result.IntentId}.");
            Console.WriteLine($"    Language Understanding JSON: {result.Properties.GetProperty(PropertyId.LanguageUnderstandingServiceResponse_JsonResult)}.");
        }
        else if (result.Reason == ResultReason.RecognizedSpeech)
        {
            Console.WriteLine($"RECOGNIZED: Text={result.Text}");
            Console.WriteLine($"    Intent not recognized.");
        }
        else if (result.Reason == ResultReason.NoMatch)
        {
            Console.WriteLine($"NOMATCH: Speech could not be recognized.");
        }
        else if (result.Reason == ResultReason.Canceled)
        {
            var cancellation = CancellationDetails.FromResult(result);
            Console.WriteLine($"CANCELED: Reason={cancellation.Reason}");
    
            if (cancellation.Reason == CancellationReason.Error)
            {
                Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}");
                Console.WriteLine($"CANCELED: ErrorDetails={cancellation.ErrorDetails}");
                Console.WriteLine($"CANCELED: Did you update the subscription info?");
            }
        }
    }
    
  6. استبدل العناصر النائبة في هذا الأسلوب بمفتاح مورد LUIS والمنطقة ومعرف التطبيق كما يلي.

    Placeholder استبدال بـ
    YourLanguageUnderstandingSubscriptionKey مفتاح مورد LUIS الخاص بك. مرة أخرى، يجب أن تحصل على هذا العنصر من لوحة معلومات Azure الخاصة بك. يمكنك العثور عليه في الصفحة موارد Azure لدى التطبيق (ضمن الإدارة) في مدخل LUIS.
    YourLanguageUnderstandingServiceRegion المعرف القصير للمنطقة التي يوجد بها مورد LUIS، مثل westus غرب الولايات المتحدة. انظر المناطق.
    YourLanguageUnderstandingAppId معرّف تطبيق LUIS. يمكنك العثور عليه في صفحة الإعدادات لدى تطبيقك في مدخل LUIS.

باستخدام هذه التغييرات التي تم إجراؤها، يمكنك إنشاء (Control+Shift+B) وتشغيل (F5) التطبيق. عندما يُطلب منك ذلك، حاول أن تقول «أطفئ الأضواء» في ميكروفون جهاز الكمبيوتر الخاص بك. يعرض التطبيق النتيجة في نافذة وحدة التحكم.

وتشمل الأقسام التالية مناقشة التعليمة البرمجية.

إنشاء أداة التعرف على الهدف

أولاً، تحتاج إلى إنشاء تكوين كلام من مفتاح تنبؤ ومنطقة LUIS. يمكنك استخدام تكوينات الكلام لإنشاء أدوات تعرف للقدرات المختلفة لـ Speech SDK. يحتوي تكوين الكلام على طرق متعددة لتحديد المورد الذي تريد استخدامه؛ هنا، نستخدم FromSubscription، الذي يأخذ مفتاح المورد والمنطقة.

إشعار

استخدم المفتاح والمنطقة لمورد LUIS الخاص بك، وليس مورد Speech.

بعد ذلك، قم بإنشاء أداة التعرف على الهدف باستخدام new IntentRecognizer(config). نظرا لأن التكوين يعرف بالفعل المورد الذي يجب استخدامه، فلن تحتاج إلى تحديد المفتاح مرة أخرى عند إنشاء أداة التعرف.

استيراد نموذج LUIS وإضافة أهداف

استورد الآن النموذج من تطبيق LUIS باستخدام LanguageUnderstandingModel.FromAppId() وأضف أهداف LUIS التي ترغب في التعرف عليها عبر أسلوب AddIntent() لأداة التعرف. تعمل هاتان الخطوتان على تحسين دقة التعرف على الكلام من خلال الإشارة إلى الكلمات التي من المحتمل أن يستخدمها المستخدم في طلباته. ليست عليك إضافة جميع أهداف التطبيق إذا لم تكن بحاجة إلى التعرف عليها جميعًا في تطبيقك.

لإضافة الأهداف، يجب توفير ثلاث وسيطات: نموذج LUIS (المسمى model)، واسم الهدف، ومعرف الهدف. الفرق بين المعرّف والاسم هو كما يلي.

وسيطة AddIntent() الغرض
intentName اسم الهدف كما محدد في تطبيق LUIS. يجب أن تتطابق هذه القيمة مع اسم هدف LUIS بالضبط.
intentID تم تعيين معرّف لهدف تم التعرف عليه من قِبل Speech SDK. هذه القيمة يمكن أن تكون ما تريد؛ ولا تحتاج إلى التوافق مع اسم الهدف كما هو محدد في تطبيق LUIS. إذا تم التعامل مع أهداف متعددة بواسطة نفس التعليمة البرمجية، على سبيل المثال، يمكنك استخدام نفس المعرّف لها.

يحتوي Home Automation في تطبيق LUIS على هدفين: أحدهما لتشغيل جهاز والآخر لإيقاف تشغيل جهاز. وتضيف السطور الواردة أدناه هذه الأهداف إلى أداة التعرف، وتستبدل السطور الثلاثة AddIntent في أسلوب RecognizeIntentAsync() بهذه التعليمات البرمجية.

recognizer.AddIntent(model, "HomeAutomation.TurnOff", "off");
recognizer.AddIntent(model, "HomeAutomation.TurnOn", "on");

بدلاً من إضافة الأهداف الفردية، يمكنك أيضًا استخدام الأسلوب AddAllIntents لإضافة جميع الأهداف في نموذج إلى أداة التعرف.

بدء التعرف

مع إنشاء أداة التعرف وإضافة الأهداف، يمكن أن يبدأ التعرف. تدعم Speech SDK الاعتراف الفردي والمستمر على حدٍّ سواء.

وضع التعرف أساليب الاستدعاء النتيجة
فردي RecognizeOnceAsync() يعيد الهدف الذي تم التعرف عليه، إن وجد، بعد كلمة واحدة.
مستمر StartContinuousRecognitionAsync()
StopContinuousRecognitionAsync()
يتعرف على كلمات متعددة، ويصدر الأحداث (على سبيل المثال، IntermediateResultReceived) عندما تكون النتائج متاحة.

يستخدم التطبيق الوضع الفردي ومن ثم يستدعي RecognizeOnceAsync() لبدء التعرف. والنتيجة هي كائن IntentRecognitionResult يحتوي على معلومات حول الهدف الذي تم التعرف عليه. يمكنك استخراج رد LUIS JSON باستخدام التعبير التالي:

result.Properties.GetProperty(PropertyId.LanguageUnderstandingServiceResponse_JsonResult)

التطبيق لا يحلل نتيجة JSON. يعرض فقط نص JSON في نافذة وحدة التحكم.

Single LUIS recognition results

تحديد لغة التعرف

بشكل افتراضي، يتعرف LUIS على الأهداف باللغة الإنجليزية الأمريكية (en-us). من خلال تعيين تعليمة برمجية محلية لخاصية SpeechRecognitionLanguage من تكوين الكلام، يمكنك التعرف على الأهداف في اللغات الأخرى. على سبيل المثال، أضف config.SpeechRecognitionLanguage = "de-de"; في تطبيقنا قبل إنشاء أداة التعرف على الأهداف باللغة الألمانية. للمزيد من المعلومات، راجع دعم اللغة في LUIS.

التعرف المستمر من ملف

توضح التعليمات البرمجية التالية اثنين من قدرات التعرف على الهدف باستخدام Speech SDK. الأول، المذكور سابقًا، هو التعرف المستمر، حيث تصدر من أداة التعرف الأحداث عند توفر النتائج. تتم معالجة هذه الأحداث بواسطة معالجات الأحداث التي توفرها. مع التعرف المستمر، تستدعي أسلوب StartContinuousRecognitionAsync() لأداة التعرف لبدء التعرف بدلاً من RecognizeOnceAsync().

القدرة الأخرى هي قراءة الصوت الذي يحتوي على الكلام المراد معالجته من ملف WAV. يتضمن التنفيذ إنشاء تكوين صوتي يمكن استخدامه عند إنشاء أداة التعرف على الهدف. يجب أن يكون الملف أحادي القناة (أحادي) بمعدل أخذ عينات يبلغ 16 كيلو هيرتز.

لتجربة هذه الميزات، قم بحذف نص الأسلوب RecognizeIntentAsync() أو تعطيله، وأضف التعليمة البرمجية التالية في مكانه.

// Creates an instance of a speech config with specified subscription key
// and service region. Note that in contrast to other services supported by
// the Cognitive Services Speech SDK, the Language Understanding service
// requires a specific subscription key from https://www.luis.ai/.
// The Language Understanding service calls the required key 'endpoint key'.
// Once you've obtained it, replace with below with your own Language Understanding subscription key
// and service region (e.g., "westus").
var config = SpeechConfig.FromSubscription("YourLanguageUnderstandingSubscriptionKey", "YourLanguageUnderstandingServiceRegion");

// Creates an intent recognizer using file as audio input.
// Replace with your own audio file name.
using (var audioInput = AudioConfig.FromWavFileInput("YourAudioFile.wav"))
{
    using (var recognizer = new IntentRecognizer(config, audioInput))
    {
        // The TaskCompletionSource to stop recognition.
        var stopRecognition = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);

        // Creates a Language Understanding model using the app id, and adds specific intents from your model
        var model = LanguageUnderstandingModel.FromAppId("YourLanguageUnderstandingAppId");
        recognizer.AddIntent(model, "YourLanguageUnderstandingIntentName1", "id1");
        recognizer.AddIntent(model, "YourLanguageUnderstandingIntentName2", "id2");
        recognizer.AddIntent(model, "YourLanguageUnderstandingIntentName3", "any-IntentId-here");

        // Subscribes to events.
        recognizer.Recognizing += (s, e) =>
        {
            Console.WriteLine($"RECOGNIZING: Text={e.Result.Text}");
        };

        recognizer.Recognized += (s, e) =>
        {
            if (e.Result.Reason == ResultReason.RecognizedIntent)
            {
                Console.WriteLine($"RECOGNIZED: Text={e.Result.Text}");
                Console.WriteLine($"    Intent Id: {e.Result.IntentId}.");
                Console.WriteLine($"    Language Understanding JSON: {e.Result.Properties.GetProperty(PropertyId.LanguageUnderstandingServiceResponse_JsonResult)}.");
            }
            else if (e.Result.Reason == ResultReason.RecognizedSpeech)
            {
                Console.WriteLine($"RECOGNIZED: Text={e.Result.Text}");
                Console.WriteLine($"    Intent not recognized.");
            }
            else if (e.Result.Reason == ResultReason.NoMatch)
            {
                Console.WriteLine($"NOMATCH: Speech could not be recognized.");
            }
        };

        recognizer.Canceled += (s, e) =>
        {
            Console.WriteLine($"CANCELED: Reason={e.Reason}");

            if (e.Reason == CancellationReason.Error)
            {
                Console.WriteLine($"CANCELED: ErrorCode={e.ErrorCode}");
                Console.WriteLine($"CANCELED: ErrorDetails={e.ErrorDetails}");
                Console.WriteLine($"CANCELED: Did you update the subscription info?");
            }

            stopRecognition.TrySetResult(0);
        };

        recognizer.SessionStarted += (s, e) =>
        {
            Console.WriteLine("\n    Session started event.");
        };

        recognizer.SessionStopped += (s, e) =>
        {
            Console.WriteLine("\n    Session stopped event.");
            Console.WriteLine("\nStop recognition.");
            stopRecognition.TrySetResult(0);
        };


        // Starts continuous recognition. Uses StopContinuousRecognitionAsync() to stop recognition.
        await recognizer.StartContinuousRecognitionAsync().ConfigureAwait(false);

        // Waits for completion.
        // Use Task.WaitAny to keep the task rooted.
        Task.WaitAny(new[] { stopRecognition.Task });

        // Stops recognition.
        await recognizer.StopContinuousRecognitionAsync().ConfigureAwait(false);
    }
}

قم بمراجعة التعليمة البرمجية لتشمل مفتاح تنبؤ LUIS والمنطقة ومعرّف التطبيق ولإضافة أهداف Home Automation، كما كانت من قبل. قم بتغيير whatstheweatherlike.wav إلى اسم ملفك الصوتي المسجل. ثم قم بإنشاء ونسخ الملف الصوتي إلى دليل الإنشاء وتشغيل التطبيق.

على سبيل المثال، إذا قلت "إيقاف تشغيل الأضواء"، وإيقاف مؤقت، ثم قل "تشغيل الأضواء" في ملف الصوت المسجل، فقد يظهر إخراج وحدة التحكم المشابه لما يلي:

Audio file LUIS recognition results

يحتفظ فريق Speech SDK بنشاط بمجموعة كبيرة من الأمثلة في المستودع مفتوح المصدر. للحصول على نموذج مستودع التعليمات البرمجية المصدر، راجع Azure الذكاء الاصطناعي Speech SDK على GitHub. هناك نماذج لـ C# وC++ وJava وPython وObjective-C وSwift وJavaScript وUWP وUnity وXamarin. ابحث عن التعليمة البرمجية من هذه المقالة في مجلد samples/csharp/sharedcontent/console.

الخطوات التالية

التشغيل السريع: التعرف على الكلام من ميكروفون