Генерация кода для нейронных сетей для глубокого обучения с ARM вычисляет библиотеку

С MATLAB® Coder™ можно сгенерировать код для прогноза от уже обученной сверточной нейронной сети (CNN), предназначаясь для встроенной платформы, которая использует процессор ARM®, который поддерживает расширение NEON. Генератор кода использует в своих интересах ARM, Вычисляют Библиотеку для компьютерного зрения и машинного обучения. Сгенерированный код реализует CNN, который имеет архитектуру, слои и параметры, заданные в сетевом объекте входа SeriesNetwork или DAGNetwork.

Сгенерируйте код при помощи одного из этих методов:

Когда вы генерируете код для нейронной сети при помощи codegen или приложения MATLAB Coder, сгенерированный код использует главное столбцом размещение для ваших данных массива. Чтобы совпадать с главным строкой размещением, которое использует библиотека глубокого обучения, генератор кода должен вставить операции, чтобы преобразовать главное столбцом размещение в главное строкой размещение. Эти операции преобразования могут ухудшить производительность сгенерированного кода. Генерация кода для глубоких нейронных сетей не поддерживает MATLAB Coder главные строкой опции, такие как параметр конфигурации RowMajor.

Требования

  • Интерфейс MATLAB Coder для Библиотек Глубокого обучения. Чтобы установить пакет поддержки, выберите его из меню MATLAB Add-Ons.

  • ARM Вычисляет Библиотеку для компьютерного зрения, и машинное обучение должно быть установлено на целевом компьютере.

  • Deep Learning Toolbox™.

  • Переменные окружения для компиляторов и библиотек.

Для поддерживаемых версий библиотек и для получения информации о подготовке переменных окружения, смотрите Предпосылки для Глубокого обучения для MATLAB Coder.

Генерация кода при помощи codegen

Чтобы сгенерировать код для глубокого обучения на ARM предназначаются при помощи codegen:

  • Запишите функцию точки входа, которая загружает предварительно обученный CNN и вызывает predict. Например:

    function out = squeezenet_predict(in)
    %#codegen
    
    persistent net;
    opencv_linkflags = '`pkg-config --cflags --libs opencv`';
    coder.updateBuildInfo('addLinkFlags',opencv_linkflags);
    if isempty(net)
        net = coder.loadDeepLearningNetwork('squeezenet', 'squeezenet');
    end
    
    out = net.predict(in);
    end
    

  • Если ваш целевой компьютер является Raspberry Pi™, можно использовать в своих интересах Пакет Поддержки MATLAB для Оборудования Raspberry Pi. С пакетом поддержки codegen перемещает сгенерированный код в Raspberry Pi и создает исполняемую программу на Raspberry Pi. Когда вы генерируете код для цели, которая не имеет пакета аппаратной поддержки, вы должны команды выполнения, чтобы переместить сгенерированные файлы и создать исполняемую программу.

  • Генерация MEX не поддержана для генерации кода для глубокого обучения на целях ARM.

Генерация кода для глубокого обучения на Raspberry Pi

Когда вы сделали, чтобы MATLAB Поддержал Пакет для Оборудования Raspberry Pi, сгенерировал код для глубокого обучения на Raspberry Pi:

  1. Чтобы соединиться с Raspberry Pi, используйте raspi. Например:

    r = raspi('raspiname','username','password');
    

  2. Создайте объект настройки генерации кода для библиотеки или исполняемого файла при помощи coder.config. Установите свойство TargetLang на 'C++'.

    cfg = coder.config('exe');
    cfg.TargetLang = 'C++';
    

  3. Создайте объект настройки глубокого обучения при помощи coder.DeepLearningConfig. Установите свойства ArmComputeVersion и ArmArchitecture. Установите свойство DeepLearningConfig объекта настройки генерации кода к объекту coder.ARMNEONConfig. Например:

    dlcfg = coder.DeepLearningConfig('arm-compute');
    dlcfg.ArmArchitecture = 'armv7';
    dlcfg.ArmComputeVersion = '18.03';
    cfg.DeepLearningConfig = dlcfg;
    

  4. Чтобы сконфигурировать аппаратные настройки генерации кода для Raspberry Pi, создайте объект coder.Hardware, при помощи coder.hardware. Установите свойство Hardware объекта настройки генерации кода к объекту coder.Hardware.

    hw = coder.hardware('Raspberry Pi');
    cfg.Hardware = hw;
    

  5. Если вы генерируете исполняемую программу, предоставьте C++ основную программу. Например:

    cfg.CustomSource = 'main.cpp';

  6. Чтобы сгенерировать код, используйте codegen. Задайте объект настройки генерации кода при помощи опции -config. Например:

    codegen -config cfg squeezenet_raspi_predict -args {ones(227, 227, 3,'single')} -report

Для примера смотрите Генерацию кода для Глубокого обучения на Raspberry Pi.

Генерация кода, когда у вас нет пакета аппаратной поддержки

Чтобы сгенерировать код для глубокого обучения, когда у вас нет пакета аппаратной поддержки для цели:

  1. Сгенерируйте код по хосту Linux® только.

  2. Создайте объект настройки для библиотеки. Например:

    cfg = coder.config('lib');

    Не используйте объект настройки для исполняемой программы.

  3. Сконфигурируйте генерацию кода, чтобы сгенерировать Код С++ и сгенерировать исходный код только.

    cfg.GenCodeOnly = true;
    cfg.TargetLang = 'C++';

  4. Чтобы задать генерацию кода с ARM Вычисляют Библиотеку, создают объект coder.ARMNEONConfig при помощи coder.DeepLearningConfig. Установите свойства ArmComputeVersion и ArmArchitecture. Установите свойство DeepLearningConfig объекта настройки генерации кода к объекту coder.ARMNEONConfig.

    dlcfg = coder.DeepLearningConfig('arm-compute');
    dlcfg.ArmArchitecture = 'armv7';
    dlcfg.ArmComputeVersion = '18.05';
    cfg.DeepLearningConfig = dlcfg;
    

  5. Чтобы сконфигурировать параметры генерации кода, которые характерны для целевого компьютера, устанавливает свойство ProdHWDeviceType объекта HardwareImplementation.

    • Для архитектуры ARMv7 используйте 'ARM Compatible->ARM Cortex'.

    • для архитектуры ARMv8 используйте 'ARM Compatible->ARM 64-bit (LP64)'.

    Например:

    cfg.HardwareImplementation.ProdHWDeviceType = 'ARM Compatible->ARM 64-bit (LP64)';

  6. Чтобы сгенерировать код, используйте codegen. Задайте объект настройки генерации кода при помощи опции -config. Например:

    codegen -config cfg squeezenet_predict -args {ones(227, 227, 3, 'single')} -d arm_compute

Для примера смотрите Генерацию кода для Глубокого обучения на Целях ARM.

Сгенерированный код

Серийная сеть сгенерирована как класс C++, содержащий массив классов слоя.

class b_squeezenet_0
{
 public:
  int32_T batchSize;
  int32_T numLayers;
  real32_T *inputData;
  real32_T *outputData;
  MWCNNLayer *layers[68];
 private:
  MWTargetNetworkImpl *targetImpl;
 public:
  b_squeezenet_0();
  void presetup();
  void postsetup();
  void setup();
  void predict();
  void cleanup();
  real32_T *getLayerOutput(int32_T layerIndex, int32_T portIndex);
  ~b_squeezenet_0();
};

Метод setup() класса настраивает указатели и выделяет память для каждого слоя сетевого объекта. Метод predict() вызывает прогноз для каждого из слоев в сети. Предположим, что вы генерируете код для функции точки входа, squeezenet_predict. В сгенерированном "для вас" файл, squeezenet_predict.cpp, функция точки входа squeeznet_predict() создает статический объект b_squeezenet_0 типа класса и вызывает setup и predict на сетевом объекте.

static b_squeezenet_0 net;
static boolean_T net_not_empty;

// Function Definitions
//
// A persistent object net is used to load the DAGNetwork object.
//  At the first call to this function, the persistent object is constructed and
//  set up. When the function is called subsequent times, the same object is reused
//  to call predict on inputs, avoiding reconstructing and reloading the
//  network object.
// Arguments    : const real32_T in[154587]
//                real32_T out[1000]
// Return Type  : void
//
void squeezenet_predict(const real32_T in[154587], real32_T out[1000])
{
  //  Copyright 2018 The MathWorks, Inc.
  if (!net_not_empty) {
    DeepLearningNetwork_setup(&net);
    net_not_empty = true;
  }

  DeepLearningNetwork_predict(&net, in, out);
}

Двоичные файлы экспортируются для слоев, которые имеют параметры, такой, как полностью соединено и слои свертки в сети. Например, файлы с именами, имеющими шаблон, cnn_squeezenet_*_w и cnn_squeezenet_*_b соответствуют весам и смещают параметры для слоев свертки в сети.

cnn_squeezenet_conv10_b            
cnn_squeezenet_conv10_w            
cnn_squeezenet_conv1_b             
cnn_squeezenet_conv1_w             
cnn_squeezenet_fire2-expand1x1_b   
cnn_squeezenet_fire2-expand1x1_w   
cnn_squeezenet_fire2-expand3x3_b   
cnn_squeezenet_fire2-expand3x3_w   
cnn_squeezenet_fire2-squeeze1x1_b  
cnn_squeezenet_fire2-squeeze1x1_w 
...

Генерация кода при помощи приложения MATLAB Coder

  1. Завершите шаги Define Input Types и Specify Source Files.

  2. Перейдите к шагу Generate Code. (Пропустите шаг Check for Run-Time Issues, потому что генерация MEX не поддержана для генерации кода с ARM, Вычисляют Библиотеку.)

  3. Установите Language на C++.

  4. Задайте целевое оборудование ARM.

    Если вашим целевым компьютером является Raspberry Pi, и вы установили Пакет Поддержки MATLAB для Оборудования Raspberry Pi:

    • Для Hardware Board выберите Raspberry Pi.

    • Чтобы получить доступ к настройкам Raspberry Pi, нажмите More Settings. Затем нажмите Hardware. Задайте Device Address, Username, Password и Build directory.

    Когда у вас нет пакета поддержки для вашей цели ARM:

    • Убедитесь, что Build type является Static Library или Dynamic Library, и установите флажок Generate code only.

    • Для Hardware Board выберите None - Select device below.

    • Для Device vendor выберите ARM Compatible.

    • Для Device type:

      • Для архитектуры ARMv7 выберите ARM Cortex.

      • Для архитектуры ARMv8 выберите ARM 64-bit (LP64).

    Примечание

    Если вы генерируете код для глубокого обучения на цели ARM и не используете пакет аппаратной поддержки, генерируют код по Linux разместите только.

  5. В панели Deep Learning, набор Target library к ARM Compute. Задайте ARM Compute Library version и ARM Compute Architecture.

    Примечание

    Если вы указываете, что версия ARM Вычисляет Библиотеку, которая является позже, чем v18.05, генератор кода производит код для v18.05. На цели ARM сгенерированный код может создать с более поздней версией библиотеки.

  6. Сгенерируйте код.

Генерация кода при помощи cnncodegen

  • Загрузите предварительно обученную сеть в MATLAB. Например:

    net = alexnet;
    

  • Сгенерируйте код для CNN при помощи cnncodegen с 'targetlib', заданным как 'arm-compute'.

    Укажите, что ARM Вычисляет версию Библиотеки и архитектуру ARM при помощи аргумента targetparams.

    Например:

    cnncodegen(net,'targetlib','arm-compute','targetparams',struct('ArmComputeVersion','18.05','ArmArchitecture','armv8'));

    Если вы указываете, что версия ARM Вычисляет Библиотеку, которая является позже, чем v18.05, генератор кода производит код для v18.05. На цели ARM сгенерированный код может создать с более поздней версией библиотеки.

  • Запишите C++ основную функцию, которая вызывает predict.

  • Переместите файлы в оборудование ARM и создайте исполняемую программу.

Для примера смотрите, что Генерация кода для Нейронных сетей для глубокого обучения с ARM Вычисляет Библиотеку.

Сгенерированный код

Команда cnncodegen генерирует Код С++ и make-файл, cnnbuild_rtw.mk. Сгенерированные файлы находятся в папке codegen. Не компилируйте сгенерированный код на хосте MATLAB. Переместите сгенерированный код в целевую платформу ARM для компиляции.

Серийная Сеть сгенерирована как класс C++, содержащий массив классов слоя.

class CnnMain
{
  ...
  public:
    CnnMain();
    ...
    void setup();
    void predict();
    void cleanup();
    ...
    ~CnnMain();
};

Метод setup() класса настраивает указатели и выделяет память для каждого слоя сетевого объекта. Метод predict() вызывает прогноз для каждого из слоев в сети.

void CnnMain::predict()
{
    int32_T idx;
    for (idx = 0; idx < 25; idx++) {
        this->layers[idx]->predict();
    }
}

Двоичные файлы экспортируются для слоев, которые имеют параметры такой, как полностью соединено и слои свертки в сети. Например, файлы cnn_CnnMain_conv*_w и cnn_CnnMain_conv*_b соответствуют весам и смещают параметры для слоев свертки в сети.

cnn_CnnMain_avg         cnn_CnnMain_conv5_w     
cnn_CnnMain_conv1_b     cnn_CnnMain_fc6_b       
cnn_CnnMain_conv1_w     cnn_CnnMain_fc6_w       
cnn_CnnMain_conv2_b     cnn_CnnMain_fc7_b       
cnn_CnnMain_conv2_w     cnn_CnnMain_fc7_w       
cnn_CnnMain_conv3_b     cnn_CnnMain_fc8_b       
cnn_CnnMain_conv3_w     cnn_CnnMain_fc8_w       
cnn_CnnMain_conv4_b     cnn_CnnMain_labels.txt  
cnn_CnnMain_conv4_w     
cnn_CnnMain_conv5_b      

Смотрите также

| | |

Похожие темы