Автор: Цин Лань, Рошани Нагмоте

В недавнем выпуске MXNet версии 1.2.0 был выпущен новый MXNet Scala Inference API. Этот выпуск ориентирован на оптимизацию взаимодействия разработчиков с приложениями вывода, написанными на Scala. Scala - это язык программирования общего назначения, который поддерживает как функциональное программирование, так и систему строгих статических типов, и используется с крупномасштабной распределенной обработкой с такими платформами, как Apache Spark.

Теперь, когда вы познакомились с новым Scala Inference API в первом посте серии, вы готовы попробовать его сами. Сначала вам нужно настроить среду разработки с помощью пакета mxnet-full, а затем вы можете попробовать свои силы на примере классификации изображений и примере обнаружения объектов (которые мы продемонстрируем в следующем посте).

Настройка среды (Linux / OSX)

Используйте maven для установки пакета mxnet-full. Добавьте зависимость в файл pom. Измените ‹your_platform› на платформу, которую вы используете в настоящее время. (OSX: osx-x86_64-cpu, Linux: linux-x86_64-cpu / gpu)

<dependency>
  <groupId>org.apache.mxnet</groupId>
  <artifactId>mxnet-full_2.11-<your_platform></artifactId>
  <version>1.2.0</version>
</dependency>

Если вы используете IntelliJ, вы должны увидеть, какой пакет импортируется. Вы также можете следовать этому руководству, чтобы настроить IntelliJ с пакетом MXNet Scala.

Пример классификатора изображений

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

Ниже приведены библиотеки, необходимые для восстановления этого примера.

import org.apache.mxnet.Shape                      
import org.apache.mxnet.{DType, DataDesc, Context}
import org.apache.mxnet.infer.ImageClassifier
import scala.collection.JavaConverters._
import java.io.File
import scala.collection.mutable.ListBuffer

Шаг 1: создайте основную функцию для запуска примера

object ImageClassifierExample {
  private val logger = LoggerFactory.getLogger(classOf[ImageClassifierExample])
  def main(args: Array[String]): Unit = {
    val inst = new ImageClassifierExample
    val parser: CmdLineParser = new CmdLineParser(inst)
    val context = Context.cpu()
    ...

Контекст здесь должен определить модель, в которой будет работать код. Вы можете изменить эту строку на context.gpu(), если хотите работать с графическим процессором. В этом примере мы используем это изображение.

    ...
    val modelPathPrefix = "absolute/path/to/your/model"
    val inputImagePath = "absolute/path/to/your/image"
    ...

Затем вы добавляете пути к моделям и тестовое изображение для использования Inference API.

Шаг 2. Загрузите модель и сделайте вывод

Следующий код является продолжением предыдущих блоков кода:

    ...
    val dType = DType.Float32
    val inputShape = Shape(1, 3, 224, 224)
    val inputDescriptor = IndexedSeq(DataDesc("data", inputShape, dType, "NCHW"))
    ...

InputDescriptor требуется для определения источника ввода и конфигурации для модели. «Данные» - это имя входных данных. входная форма - это форма входного изображения. Входная матрица будет трехканальной с размерами 224 * 224 пикселей.

   ...
   val imgClassifier: ImageClassifier = new
        ImageClassifier(modelPathPrefix, inputDescriptor, context)
   val img = ImageClassifier.loadImageFromFile(inputImagePath)
   val output = imgClassifier.classifyImage(img, Some(5))
   ...

После того, как мы отсортируем все входные данные, мы создаем объект классификатора изображений и используем его для загрузки изображения. Затем мы начинаем классификацию этого образца изображения. Поле «Some (5)» означает, что мы выберем 5 лучших прогнозов с максимальной точностью. Это поле является необязательным, и по умолчанию будут использоваться прогнозы без сортировки. Как только мы закончим этот шаг, нам просто нужно показать результат.

   ...
   for (i <- singleOutput(0)) {
           printf("Classes with top 5 probability = %s \n", i)
   }
}

Результат

После того, как вы закончите предыдущий шаг, вы должны увидеть результат, аналогичный показанному ниже (здесь мы использовали изображение мопса):

Classes with top 5 probability = (n02110958 pug, pug-dog,0.5032309) 
Classes with top 5 probability = (n13905792 wrinkle, furrow, crease, crinkle, seam, line,0.06664828) 
Classes with top 5 probability = (n02084732 pooch, doggie, doggy, barker, bow-wow,0.029262988) 
Classes with top 5 probability = (n02085374 toy dog, toy,0.028741771) 
Classes with top 5 probability = (n02083346 canine, canid,0.02784521)

Первым элементом является класс «n02110958 мопс, мопс-собака», а вторым значением является достоверность класса, определенная классификатором.

Заключение

После этого краткого обзора вы сможете создать классификатор изображений с помощью MXNet Scala Inference API. Вы можете найти более подробную информацию о коде для этого примера в Scala Infer Пример классификатора изображений репозитория проектов MXNet.

В нашей следующей записи блога мы познакомимся с обработкой задач обнаружения объектов с помощью MXNet Scala API. Проверьте это дальше!