Статьи

Создание интеллектуального ИИ-собаки от Microsoft менее чем за 100 строк кода

Совсем недавно Microsoft выпустила приложение, использующее AI для определения породы собак. Когда я проверил это на своем бигле, хотя …

Приложение идентифицирует бигля как салюки

Хм, не совсем, приложение. Не совсем.

В свободное от SitePoint время я также работаю в Diffbot — стартапе, о котором вы, возможно, слышали за последние несколько недель, — который также увлекался искусственным интеллектом. Чтобы проверить, как они сравниваются, в этом уроке мы воссоздадим приложение Microsoft с использованием технологии Diffbot, чтобы увидеть, справляется ли оно лучше с распознаванием очаровательных зверей, которых мы бросаем в него!

Мы создадим очень примитивное однофайловое «приложение» для загрузки изображений и вывода информации о породе в форме.

Предпосылки

Если вы хотите подписаться, зарегистрируйтесь для получения бесплатного 14-дневного токена на Diffbot.com , если у вас еще нет аккаунта.

Для установки клиента мы используем следующий файл composer.json

 {
    "require": {
        "swader/diffbot-php-client": "^2",
        "php-http/guzzle6-adapter": "^1.0"
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "require-dev": {
        "symfony/var-dumper": "^3.0"
    }
}

Затем мы запускаем composer install

Флаг минимальной стабильности установлен, потому что часть пакета Puli все еще находится в бета-версии, и теперь это зависимость от проекта PHP HTTP . Директива Предпочтительная Стабильность предназначена для того, чтобы убедиться, что используется самая стабильная версия пакета, если она доступна. Нам также нужен HTTP-клиент, и в этом случае я выбрал Guzzle6, хотя PHP-клиент Diffbot поддерживает любой современный HTTP-клиент через Httplug , так что не стесняйтесь использовать свой любимый.

После того, как эти элементы были установлены, мы можем создать файл index.php Но сначала, начальная загрузка:

 <?php

require 'vendor/autoload.php';

$token = 'my_token';

Загрузить

Давайте создадим примитивную форму загрузки поверх содержимого PHP нашего файла index.php

 <form action="/" method="post" enctype="multipart/form-data">
    <h2>Please either paste in a link to the image, or upload the image directly.</h2>
    <h3>URL</h3>
    <input type="text" name="url" id="url" placeholder="Image URL">
    <h3>Upload</h3>
    <input type="file" name="file" id="file">
    <input type="submit" value="Analyze">
</form>

<?php

...

Мы фокусируемся только на стороне PHP, поэтому не будем использовать CSS. Я извиняюсь перед твоими глазами.

Уродливая форма

Мы будем использовать Imgur для размещения изображений, так что нам не нужно будет размещать приложение для того, чтобы совершать вызовы в Diffbot (изображения будут общедоступными, даже если наше приложение нет, что экономит нам расходы на хостинг). Давайте сначала зарегистрируем приложение на Imgur по этой ссылке :

Регистрация имгура

Это создаст идентификатор клиента и секрет, хотя мы будем использовать только идентификатор клиента (анонимная загрузка), поэтому мы должны добавить его в наш файл:

 $token = 'my_token';
$imgur_client = 'client';

Анализ изображений

Так как же будет проводиться анализ?

Как описано в документации , Diffbot Image API может принять URL, а затем сканирует страницу на наличие изображений. Все найденные изображения дополнительно анализируются и о них возвращаются некоторые данные.

Данные, которые нам нужны — это tags tagshttp://dbpedia.org для соответствующего ресурса. Нам не понадобятся эти ссылки в этом руководстве, но мы рассмотрим их в следующем выпуске. Массив tags

 "tags": [
        {
          "id": 4368,
          "label": "Beagle",
          "uri": "http://dbpedia.org/resource/Beagle"
        },
        {
          "id": 2370241,
          "label": "Treeing Walker Coonhound",
          "uri": "http://dbpedia.org/resource/Treeing_Walker_Coonhound"
        }
      ]

Как видите, каждый тег имеет вышеупомянутые значения. Если есть только один тег, будет представлен только один объект. По умолчанию Diffbot возвращает до 5 тегов на каждую запись — поэтому каждое изображение может иметь до 5 тегов, и они не должны быть связаны напрямую (например, отправка изображения кроссовки может вернуть тег Nike и тег обувь ).

Именно эти ярлыки мы будем использовать как предполагаемые догадки пород собак. Как только запрос пройдет и вернет теги в ответе, мы напечатаем предложенные ярлыки под изображением.

Обработка заявок

Чтобы обработать форму, мы добавим некоторую базовую логику ниже объявления токена. :

 if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    if (isset($_FILES['file']['tmp_name']) && !empty($_FILES['file']['tmp_name'])) {
        $filename = $_FILES['file']['tmp_name'];

        $c = new Client();
        $response = $c->request('POST', 'https://api.imgur.com/3/image.json', [
            'headers' => [
                'authorization' => 'Client-ID ' . $imgur_client
            ],
            'form_params' => [
                'image' => base64_encode(fread(fopen($filename, "r"),
                    filesize($filename)))
            ]
        ]);

        $body = json_decode($response->getBody()->getContents(), true);
        $url = $body['data']['link'];
        if (empty($url)) {
            echo "<h2>Upload failed</h2>";
            die($body['data']['error']);
        }
    }

    if (!isset($url) && isset($_POST['url'])) {
        $url = $_POST['url'];
    }

    if (!isset($url) || empty($url)) {
        die("That's not gonna work.");
    }

    $d = new Swader\Diffbot\Diffbot($token);
    /** @var Image $imageDetails */
    $imageDetails = $d->createImageAPI($url)->call();
    $tags = $imageDetails->getTags();

    echo "<img width='500' src='{$url}'>";

    switch (count($tags)) {
        case 0:
            echo "<h4>We couldn't figure out the breed :(</h4>";
            break;
        case 1:
            echo "<h4>The breed is probably " . labelSearchLink($tags[0]['label']) . "</h4>";
            echo iframeSearch($tags[0]['label']);
            break;
        default:
            echo "<h4>The breed could be any of the following:</h4>";
            echo "<ul>";
            foreach ($tags as $tag) {
                echo "<li>" . labelSearchLink($tag['label']) . "</li>";
            }
            echo "</ul>";
            echo iframeSearch($tags[0]['label']);
            break;
    }
}

Сначала мы проверяем, был ли выбран файл для загрузки. Если это так, он имеет приоритет над отправкой на основе ссылок. Изображение загружается в Imgur, а URL-адрес, который возвращает Imgur, передается в Diffbot. Если был указан только URL, он используется напрямую.

Мы использовали Guzzle в качестве HTTP-клиента напрямую, потому что мы уже установили его, чтобы PHP-клиент Diffbot мог использовать его для вызовов API

После того, как данные изображения возвращены, мы берем теги из объекта Image и выводим их на экран вместе со ссылкой на результаты поиска Bing для этой породы и iframe, отображающими эти результаты прямо там и сейчас.

Ниже перечислены функции, создающие HTML-элемент search-link и iframe:

 function labelSearchLink($label) {
    return '<a href="http://www.bing.com/images/search?q='.urlencode($label).'&qs=AS&pq=treein&sc=8-6&sp=1&cvid=92698E3A769C4AFE8C6CA1B1F80FC66D&FORM=QBLH" target="_blank">'.$label.'</a>';
}

function iframeSearch($label) {
    return '<iframe width="100%" height="400" src="http://www.bing.com/images/search?q='.urlencode($label).'&qs=AS&pq=treein&sc=8-6&sp=1&cvid=92698E3A769C4AFE8C6CA1B1F80FC66D&FORM=QBLH" />';
}

Бигль слегка неопознан

Опять же, прошу прощения за дизайн кода и веб-страницы — так как это всего лишь быстрый прототип, CSS и фреймворки могли бы отвлечь.

Тестирование и сравнение

Как видно из изображения выше, Diffbot также неправильно идентифицировал собаку, но не так сильно, как Microsoft. В этом случае мой бигль действительно больше похож на охотника на древесных пород, чем на типичного бигля.

Давайте посмотрим еще несколько примеров.

Diffbot не работает, MS успешно

Ах, проклятия! Microsoft выигрывает этот раунд — Diffbot думал, что у него больше шансов угадать между бассет-хаундом и охотником за деревьями, но он пропустил оба. Как насчет другого?

Бинго!

Бинго! Обе они на месте, хотя Diffbot старается не рисковать, снова предлагая ходункам в качестве альтернативы. Хорошо, этот был слишком очевиден — как насчет жесткого?

Derps

Весело , этот дерьмовый образ, похоже, напоминает обоим ИИ о валлийском корги!

Что, если на изображении больше одной собаки?

Ой, Diffbot понял это очень неправильно

Восхитительно, Diffbot, но без сигары — молодец, Microsoft!

Хорошо, последний.

Спящий бигль

Отличная работа на обоих фронтах. Очевидно, что «ИИ обнаружения собаки» исчерпан! Конечно, у Diffbot есть небольшое преимущество в том, что он также способен распознавать лица, текст, марки, другие типы животных и многое другое в изображениях, но их «признание собаки» — это с ног до головы.

Вывод

В этом уроке мы увидели, как легко использовать возможности современного ИИ, чтобы хотя бы несколько точно идентифицировать породы собак. Хотя у обоих движков есть много возможностей для улучшения, чем больше контента мы им подпитываем, тем лучше они станут.

Это была демонстрация простоты использования мощных алгоритмов дистанционного машинного обучения и введение в более сложную тему, которую мы скоро изучим — следите за обновлениями!