Mewa i łabądź

Cognitive Services: Jak korzystać z API Microsoftu do sztucznej inteligencji?

Rozpoznawanie twarzy na zdjęciach, emocji jakie wyrażają, opisywanie zawartości fotografii, przetwarzanie języka naturalnego – te i wiele więcej tematów powiązanych ze sztuczną inteligencją znane są nam od dawna. Jednak od niedawna są one tak bardzo na wyciągnięcie ręki. Rzućmy okiem na Microsoft Cognitive Services.

Czym jest Microsoft Cognitive Services?

Cognitive Services jest usługą Microsoftu ogłoszoną na tegorocznej konferencji Build 2016. Udostępnia ona dobrodziejstwa uczenia maszynowego deweloperom aplikacji. Proces użycia tego produktu został uproszczony najbardziej jak tylko się da. Dostępny jest bowiem przez webowe API. Usług uruchomionych w ramach API Cognitive Services jest dokładnie 22. Począwszy od lokalizowania twarzy na zdjęciach, rozpoznawania ich emocji, skończywszy na usłudze wykrywania tekstu na fotografiach, konwertowania mowy na tekst, czy autosugestii wprowadzanego tekstu prosto z wyszukiwarki Bing.

Konstrukcja API

API Cognitive Services jest tak skonstruowane, że nie ma znaczenia z jakiego języka korzystamy przy pisaniu aplikacji do jego obsługi. Cała komunikacja przebiega przy pomocy protokołu HTTP. Dla pokazania możliwości nowej zabawki od Microsoftu, napiszemy prostą aplikację w języku C#, której celem będzie wykrycie zawartości dowolnej fotografii.

Rejestracja

API, z którego skorzystamy w poniższym przykładzie nazywa się Computer Vision API. Zanim z niego skorzystamy, musimy zarejestrować się w serwisie Cognitive Services i podczas tego procesu poprosić o unikalny, przypisany do nas klucz, który będziemy używać przy każdym zapytaniu. Tutaj należy dodać, że dostęp do API jest darmowy, dopóki nie nadużywamy życzliwości Microsoftu w testowaniu ich usługi 🙂 W zależności od wybranego API, mamy możliwość wykonania określonej liczby zapytań za darmo. W przypadku Computer Vision jest to 5 000 zapytań na miesiąc. Wystarczy do malutkiej aplikacji.

Przygotowanie do zapytania

Napiszmy prostą funkcję, której zadaniem będzie wywołanie usługi Computer Vision. Podstawowym adresem do zapytań jest:

https://api.projectoxford.ai/vision/v1.0/analyze

Dodatkowo do adresu możemy dodać parametr określający, co chcielibyśmy dowiedzieć się o przesyłanym zdjęciu. Wybór mamy spośród kategorii: “Categories”, “Tags”, “Description”, “Faces”, “ImageType”, “Color”, “Adult”. W naszej aplikacji chcemy zbadać pełen zestaw tego co ma nam Computer Vision do zaoferowania, dlatego wpisujemy je wszystkie po przecinku do parametru o nazwie visualFeatures. Adres, na który będziemy wysyłać zapytanie przyjmie następującą postać:

https://api.projectoxford.ai/vision/v1.0/analyze?visualFeatures= Categories,Tags,Description,Faces,ImageType,Color,Adult

Po szczegółowy opis każdej kategorii, dodatkowych parametrów oraz przykładów wywołania odsyłam do dokumentacji Computer Vision.

Pierwszy request

Zapytanie powinno być wysłane metodą POST, zaś w nagłówku musi znaleźć się nasz klucz API, który dostaliśmy po rejestracji. Przykładowa implementacja wywołania API może wyglądać następująco:

/*...*/

var client = new HttpClient();

client.DefaultRequestHeaders.Add(
  "Ocp-Apim-Subscription-Key", 
  "a7a61eeaa971401987a1db9e048eef14");

var visualFeatures = new[]
{
  "Categories",
  "Tags",
  "Description",
  "Faces",
  "ImageType",
  "Color",
  "Adult"
};

var uri = "https://api.projectoxford.ai/vision/v1.0/analyze?" +
         $"visualFeatures={string.Join(",", visualFeatures)}";

var imageBytes = File.ReadAllBytes(imagePath);

HttpResponseMessage response;

using (var requestContent = new ByteArrayContent(imageBytes))
{
  requestContent.Headers.ContentType = 
    new MediaTypeHeaderValue("application/octet-stream");

  response = await client.PostAsync(uri, requestContent);
}

var imageDescriptionJson = await response.Content.ReadAsStringAsync();

/*...*/

Wywołanie powyższego kodu na wybranej fotografii zwraca nam JSONa. Na potrzeby testu, użyłem swojej fotografii profilowej i dostałem w odpowiedzi dosyć pokaźną analizę:


Poza tym, że nie mam na sobie krawatu i algorytm trochę przestrzelił mój wiek, reszta w miarę się zgadza 🙂

Drugi request

Załóżmy, że chcemy rozszerzyć naszą aplikację o wygenerowanie krótkiego podsumowania o przesłanym zdjęciu. Na przykład – wyświetlić jedynie opis, kategorię i tagi, co do których algorytm jest wysoce przekonany. Format danych, który dostajemy od API nie ułatwia nam tego typu analizy. Na szczęście – JSONa możemy w prosty sposób zdeserializować:

1. Stwórz klasę na podstawie JSONa

Visual Studio ma w sobie bardzo przydatną funkcję. Wystarczy skopiować odebranego JSONa i wkleić go do wybranego pliku przy pomocy polecenia:

Edit -> Paste Special -> Paste JSON as Classes

I voilà! Mamy gotową klasę.

2. Zainstaluj paczkę Newtonsoft.Json

Po zainstalowaniu dodatkowej NuGetowej paczki, będziemy mieli możliwość zdeserializowania JSONa do naszej klasy. Załóżmy, że nasza nowo utworzona klasa nazywa się ImageDescription. Wystarczy, że dodamy poniższy kod na końcu naszej metody i możemy szaleć 🙂

var imageDescription = 
  JsonConvert.DeserializeObject<ImageDescription>(imageDescriptionJson);

Testy

Przygotujmy funkcję, która przyjmie obiekt naszej klasy ImageDescription i zwróci w wyniku skrócone informacje o przesłanej fotografii w postaci stringu. Mogłaby ona wyglądać następująco:

static string GetImageShortSummary(ImageDescription imageDescription)
{
  var caption = imageDescription.description.captions
    .OrderByDescending(c => c.confidence)
    .FirstOrDefault()?.text;

  var category = imageDescription.categories
    .OrderByDescending(c => c.score)
    .FirstOrDefault()?.name;

  var tags = imageDescription.tags
    .OrderByDescending(t => t.confidence)
    .Where(t => t.confidence >= 0.9)
    .Select(t => t.name);

  return $"Caption: {caption}\n" +
         $"Category: {category}\n" +
         $"Tags: {string.Join(", ", tags)}";
}

Podsumowanie dla fotografii profilowej wygenerowane z powyższego JSONa prezentuje się następująco:


Caption: a man wearing a shirt and tie
Category: people_portrait
Tags: person, man, wall, indoor

Pozwoliłem sobie przetestować aplikację na kilku innych fotografiach:

Góry

Caption: a man on a snow covered mountain
Category: outdoor_mountain
Tags: snow, outdoor, sky, nature, mountain
Ptak

Caption: a bird is standing near a body of water
Category: animal_bird
Tags: bird, outdoor, water, gull, animal, standing, aquatic bird
Pociąg

Caption: a steam engine on a train track
Category: outdoor_
Tags: train, outdoor, track, mountain, steam
Samolot

Caption: a fighter jet flying through a blue sky
Category: sky_object
Tags: sky, outdoor, plane, flying, aircraft, airplane

Do czego może się to przydać?

Do przetestowania API użyłem stosunkowo prostych fotografii, jednak i tak jestem pod wielkim wrażeniem skuteczności rozpoznawania 🙂 Do czego może przydać się taki serwis? Miliardy pomysłów same nasuwają się na myśl. Tym bardziej, że wpis pokrywa jedynie kilka procent API, które udostępnia Microsoft. Pozostawiam Was z tym pytaniem i odsyłam do filmu promocyjnego Microsoft Cognitive Services: