Wednesday, 26 June 2019

Voice Bot Assistance Part 2 - Microsoft QandA Maker Service on Azure

In Voice Bot Assistance Part 1 - Microsoft.CognitiveServices.Speech configuration on Azure , I was able to set my Speech from my laptop Microphone to text and also this text was able to play back on my laptop's speaker. But now what I want is to set up a Bot who can answer my queries asked.

I did research and found there are many Chat Bot is available you can use like BotSharp and Microsoft BOT. But I want to create my own Bot which answer through my Knowledge base hence I have selected again a Microsoft Azure service - QnA maker.

You can easily set this up by clicking here.

I created a QNA Maker service resource, than created a Knowledge base and uploaded a sample chit chat file. Once it is ready, Click on Edit button and note these values :








These values are required to make a call from your code.

So once this is done you can POST a question to get answer. Below is the code which I used for getting the answer:


 public async static Task<string> GetAnswer(string question)
        {

            var uri = endpoint_host + endpointService + baseRoute + "/" + kbid + "/generateAnswer";

            //Console.WriteLine("Get answers " + uri + ".");

            using (var client = new HttpClient())
            using (var request = new HttpRequestMessage())
            {
                request.Method = HttpMethod.Post;
                request.RequestUri = new Uri(uri);
                request.Content = new StringContent("{question:'" + question + "'}", Encoding.UTF8, "application/json");

                // NOTE: The value of the header contains the string/text 'EndpointKey ' with the trailing space
                request.Headers.Add("Authorization", "EndpointKey " + endpoint_key);

                var response = await client.SendAsync(request);
                var responseBody = await response.Content.ReadAsStringAsync();
                //Console.WriteLine(PrettyPrint(responseBody));

                QNAResponse qnaResponse = JsonConvert.DeserializeObject<QNAResponse>(responseBody);

                return qnaResponse.answers[0].answer;

            //return responseBody.

            }

        }



So now my workflow for Voice BOT assistance is transitioning like this :














The whole code is published at below location :

https://github.com/LALITAMITTAL18/VoiceBotAssistance

Make sure to change the configuration values of your Azure Services subscription to see your BOT working.

Thank you for reading and enjoy your chit chat BOT :-)

Sunday, 23 June 2019

Voice Bot Assistance Part 1 - Microsoft.CognitiveServices.Speech configuration on Azure

As Siri and Google assistance is popular now these days, I thought of exploring developing one for mine. SO I started with System.Speech.dll 1.0.4 nuget package which comes out to be  not compatible with netcoreapp2.1 (.NETCoreApp,Version=v2.1).
Hence started looking for Microsoft.CognitiveServices.Speech Speech Services Documentation.

For this service to use first we have to create a Azure account and then we need to create a Speech Resource. Follow below steps to create the resource :

1. Login in to Azure portal using this Link .click on Create a resource and search for "Speech". Select Speech and click on create.



2. Fill in the details here, Resource Name , Subscription , Location(it is important. Respective region code will be used while coding), Pricing tier and Resource Group and click on create. Mine is free trial and below are the entries :

3. Once it is created, look for the subscription key. for this click on All resource , search for your resource.

4. Click on your resource and click on "Grab your Keys". Copy one of your key.



Hurray!! the configuration is done. Now we will consume it and convert our microphone speech to text.

Its very easy to convert what do you speak to text and vice versa. for this what I have done is to create a Visual studio solution and added a class library solution. I added nuget package of Microsoft.CognitiveServices.Speech. and write code as per the guidelines by Microsoft.

For Speech to Text, I wrote below code:

public async Task<string> ConvertSpeechtoTextFromMicrophone()
        {            
            SpeechConfig config = SpeechConfig.FromSubscription(Subscription.key, Subscription.region);
            string result = string.Empty;
            using (var recognizer = new SpeechRecognizer(config))
            {                
                var recognizerAsync = await recognizer.RecognizeOnceAsync().ConfigureAwait(false);
                if (recognizerAsync.Reason == ResultReason.RecognizedSpeech) result += recognizerAsync.Text;
                else if (recognizerAsync.Reason == ResultReason.NoMatch) result += ("Error");
                else if (recognizerAsync.Reason == ResultReason.Canceled)
                {
                    var cancellation = CancellationDetails.FromResult(recognizerAsync);
                    result +=  ($"CANCELED: Reason={cancellation.Reason}");
                    if (cancellation.Reason == CancellationReason.Error)
                    {
                        result += ($"CANCELED: ErrorCode={cancellation.ErrorCode}");
                        result += ($"CANCELED: ErrorDetails={cancellation.ErrorDetails}");
                        result += ($"CANCELED: Did you update the subscription info?");
                    }
                }
            }
            return result;
        }


Here are the links to understand how it works :

And for Text to Speech , I wrote below code :

 
public async Task CovertTextToSpeechFromMicrophone(string TextToSpeek)
        {
            SpeechConfig config = SpeechConfig.FromSubscription(Subscription.key, Subscription.region);
            // Creates a speech synthesizer using the default speaker as audio output.
            using (var synthesizer = new SpeechSynthesizer(config))
            {
                using (var result = await synthesizer.SpeakTextAsync(TextToSpeek))
                {
                    if (result.Reason == ResultReason.SynthesizingAudioCompleted)
                    {
                        Console.WriteLine($"Voice Bot Assistance said :  [{TextToSpeek}]");
                    }
                    else if (result.Reason == ResultReason.Canceled)
                    {
                        var cancellation = SpeechSynthesisCancellationDetails.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?");
                        }
                    }
                }
            }
        }

Here are the links :

It was easy :-).  You can find my code here on github :


Now Next is to train my program to answer my questions. For this read my next blog on Voice Bot Assistance Part 2 - Microsoft QandA Maker Service on Azure



Friday, 7 June 2019

Which is faster - C# LINQ or Loops


I came from a background where I have written the algorithm which process millions of data; hence performance always plays an important role. I tried my every bit to reduce every single bit of time. So, I first started with implementing creating Asynchronous tasks using multi threading, parallel loops etc. It reduces huge amount of time but that was not enough.

In my code I used LINQ heavily, so just out of curiosity I thought to check how LINQ works internally.

LINQ is very easy to implement, and it saves huge amount of time on building logic. But when you have an application which is very time sensitive, BE AWARE before using LINQ because: 
  • LINQ internally uses legacy loops, so if you have chance to reduce your loop counts, LINQ prohibit it.
  • LINQ works on object which is heavier than any other primitive data type

x

 By removing LINQ, I was able to reduce huge amount of time.

I have taken below problem statement to prove my point:

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000. 

Let’s measure the performance now:

LINQ :

static void Main(string[] args)
        {
     Stopwatch sw = new Stopwatch();
            sw.Start();

             int sum = Enumerable.Range(1, 9999).Where(x => isDivisible(x)).Sum();
            sw.Stop();
            Console.WriteLine("Linq : Sum = {0} , Time Taken = {1} " , sum, sw.Elapsed);
           
       }

public static bool isDivisible(int x)
        {
            if (x % 3 == 0 || x % 5 == 0) { return true; }
            else return false;
        }

Output: Linq : Sum = 23331668 , Time Taken = 00:00:00.0141881


While Loop:

static void Main(string[] args)
        {

            Stopwatch sw = new Stopwatch();
            sw.Start();
            int sum2 = getSum();
            sw.Stop();
            Console.WriteLine("Legacy loop : Sum = {0} , Time Taken = {1} ", sum2, sw.Elapsed);
            Console.ReadLine();
        }
public static int getSum()
        {
            int sum = 0;
            int index = 1;
            int range = 10000;

            while (index < range) 
            {
                //int fivemult = 5 * index;

                if (index * 3 < range) sum = sum + index * 3;
                else break; //loop will end as soon as multiple of three cross 9999

                if (index * 5 < range && (index * 5) % 3 != 0) sum = sum + index * 5;
                //else break;

                index++;
            }

            return sum;
        }

Output: Legacy loop : Sum = 23331668 , Time Taken = 00:00:00.0002947

Did you notice the tremendous time difference in both?  So, choose wisely.

So if you are considering writing code for extremely time sensitive environment,  choose legacy loops over LINQ.

Your working perspective changes with the type of environment you have worked for.

I will be more than happy to know your points as well. Let me know what you think ðŸ˜Š