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

Этот пример демонстрирует генерацию кода для приложения классификации изображений, которое использует глубокое обучение. Это использует команду codegen, чтобы сгенерировать MEX-функцию, которая запускает прогноз с помощью популярных сетей классификации изображений, таких как AlexNet, ResNet и GoogLeNet.

Предпосылки

  • CUDA® включил NVIDIA®, графический процессор с вычисляет возможность 3.2 или выше.

  • NVIDIA инструментарий CUDA и драйвер.

  • Библиотека NVIDIA cuDNN (v7) или выше.

  • Переменные окружения для компиляторов и библиотек. Для получения информации о поддерживаемых версиях компиляторов и библиотек, смотрите Сторонние продукты (GPU Coder). Для подготовки переменных окружения смотрите Подготовку Необходимых как условие продуктов (GPU Coder).

  • Computer Vision Toolbox™ для видео средства чтения и средства просмотра используется в примере.

  • Deep Learning Toolbox™ для использования SeriesNetwork или объектов DAGNetwork.

  • Image Processing Toolbox™ для чтения и отображения изображений.

  • GPU Coder™ для генерации кода CUDA.

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

Проверьте среду графического процессора

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

coder.checkGpuInstall('gpu','codegen','cudnn','quiet');

О функции 'alexnet_predict'

Функция alexnet_predict.m берет вход изображений и запускает прогноз на изображении с помощью нейронной сети для глубокого обучения, сохраненной в alexnet.mat файле. Функция загружает сетевой объект от alexnet.mat в персистентную переменную mynet. На последующих вызовах функции постоянный объект снова используется для прогноза.

type('alexnet_predict.m')
% Copyright 2017 The MathWorks, Inc.

function out = alexnet_predict(in) 
%#codegen

% A persistent object mynet is used to load the series network object.
% At the first call to this function, the persistent object is constructed and
% setup. When the function is called subsequent times, the same object is reused 
% to call predict on inputs, thus avoiding reconstructing and reloading the
% network object.

persistent mynet;

if isempty(mynet)
    mynet = coder.loadDeepLearningNetwork('alexnet.mat','alexnet');
end

% pass in input   
out = mynet.predict(in);

Получите предварительно обученный SeriesNetwork

Загрузите сеть AlexNet и сохраните в alexnet.mat, если это не существует.

net = getAlexnet();

Сеть содержит 25 слоев включая свертку, полностью соединенную и классификация выходные слои.

net.Layers
ans = 

  25x1 Layer array with layers:

     1   'data'     Image Input                   227x227x3 images with 'zerocenter' normalization
     2   'conv1'    Convolution                   96 11x11x3 convolutions with stride [4  4] and padding [0  0  0  0]
     3   'relu1'    ReLU                          ReLU
     4   'norm1'    Cross Channel Normalization   cross channel normalization with 5 channels per element
     5   'pool1'    Max Pooling                   3x3 max pooling with stride [2  2] and padding [0  0  0  0]
     6   'conv2'    Convolution                   256 5x5x48 convolutions with stride [1  1] and padding [2  2  2  2]
     7   'relu2'    ReLU                          ReLU
     8   'norm2'    Cross Channel Normalization   cross channel normalization with 5 channels per element
     9   'pool2'    Max Pooling                   3x3 max pooling with stride [2  2] and padding [0  0  0  0]
    10   'conv3'    Convolution                   384 3x3x256 convolutions with stride [1  1] and padding [1  1  1  1]
    11   'relu3'    ReLU                          ReLU
    12   'conv4'    Convolution                   384 3x3x192 convolutions with stride [1  1] and padding [1  1  1  1]
    13   'relu4'    ReLU                          ReLU
    14   'conv5'    Convolution                   256 3x3x192 convolutions with stride [1  1] and padding [1  1  1  1]
    15   'relu5'    ReLU                          ReLU
    16   'pool5'    Max Pooling                   3x3 max pooling with stride [2  2] and padding [0  0  0  0]
    17   'fc6'      Fully Connected               4096 fully connected layer
    18   'relu6'    ReLU                          ReLU
    19   'drop6'    Dropout                       50% dropout
    20   'fc7'      Fully Connected               4096 fully connected layer
    21   'relu7'    ReLU                          ReLU
    22   'drop7'    Dropout                       50% dropout
    23   'fc8'      Fully Connected               1000 fully connected layer
    24   'prob'     Softmax                       softmax
    25   'output'   Classification Output         crossentropyex with 'tench' and 999 other classes

Запустите генерацию кода MEX для функции 'alexnet_predict'

Чтобы сгенерировать код CUDA из файла проекта alexnet_predict.m, создайте объект настройки графического процессора кода для цели MEX и установите выходной язык на C++. Используйте кодер. DeepLearningConfig функционируют, чтобы создать объект настройки глубокого обучения CuDNN и присвоить его свойству DeepLearningConfig объекта настройки графического процессора кода. Запустите команду codegen, задающую вход размера [227,227,3]. Это значение соответствует входному размеру слоя сети AlexNet.

cfg = coder.gpuConfig('mex');
cfg.TargetLang = 'C++';
cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn');
codegen -config cfg alexnet_predict -args {ones(227,227,3)} -report
Code generation successful: To view the report, open('codegen/mex/alexnet_predict/html/report.mldatx').

Описание сгенерированного кода

Серийная Сеть сгенерирована как класс C++, содержащий массив 25 классов слоя и функций, чтобы настроить, предсказать, и очистить сеть.

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

Настройка () метод класса настраивает указатели и выделяет память для каждого слоя сетевого объекта. Предсказывание () метод вызывает прогноз для каждого из этих 25 слоев в сети.

Функция точки входа alexnet_predict () в файле сгенерированного кода alexnet_predict.cu создает статический объект b_alexnet типа класса и вызывает настройку, и предскажите на этом сетевом объекте.

static b_alexnet mynet;
static boolean_T mynet_not_empty;
/* Function Definitions */
void alexnet_predict(alexnet_predictStackData *SD, const real_T in[154587],
                  real32_T out[1000])
{
   if (!mynet_not_empty) {
     DeepLearningNetwork_setup(&mynet);
     mynet_not_empty = true;
   }
    DeepLearningNetwork_predict(SD, &mynet, in, out);
 }

Двоичные файлы для сетевых параметров

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

dir(fullfile(pwd, 'codegen', 'mex', 'alexnet_predict'))
.                              cnn_alexnet_avg                
..                             cnn_alexnet_conv1_b            
DeepLearningNetwork.cu         cnn_alexnet_conv1_w            
DeepLearningNetwork.h          cnn_alexnet_conv2_b            
MWCNNLayerImpl.cu              cnn_alexnet_conv2_w            
MWCNNLayerImpl.hpp             cnn_alexnet_conv3_b            
MWCudaDimUtility.cu            cnn_alexnet_conv3_w            
MWCudaDimUtility.h             cnn_alexnet_conv4_b            
MWFusedConvReLULayer.cpp       cnn_alexnet_conv4_w            
MWFusedConvReLULayer.hpp       cnn_alexnet_conv5_b            
MWFusedConvReLULayerImpl.cu    cnn_alexnet_conv5_w            
MWFusedConvReLULayerImpl.hpp   cnn_alexnet_fc6_b              
MWTargetNetworkImpl.cu         cnn_alexnet_fc6_w              
MWTargetNetworkImpl.hpp        cnn_alexnet_fc7_b              
alexnet_predict.cu             cnn_alexnet_fc7_w              
alexnet_predict.h              cnn_alexnet_fc8_b              
alexnet_predict_data.cu        cnn_alexnet_fc8_w              
alexnet_predict_data.h         cnn_alexnet_labels.txt         
alexnet_predict_initialize.cu  cnn_api.cpp                    
alexnet_predict_initialize.h   cnn_api.hpp                    
alexnet_predict_mex.map        cpp_mexapi_version.cpp         
alexnet_predict_mex.mexa64     gpu_codegen_info.mat           
alexnet_predict_mex.sh         html                           
alexnet_predict_terminate.cu   interface                      
alexnet_predict_terminate.h    predict.cu                     
alexnet_predict_types.h        predict.h                      
build                          rt_nonfinite.h                 
build.ninja                    rtwtypes.h                     
buildInfo.mat                  

Запустите сгенерированный MEX

Загрузите входное изображение.

im = imread('peppers.png');
imshow(im);

Вызов AlexNet предсказывает на входном изображении.

im = imresize(im, [227,227]);
predict_scores = alexnet_predict_mex(double(im));

Сопоставьте лучшие пять очков прогноза со словами в synset словаре.

fid = fopen('synsetWords.txt');
synsetOut = textscan(fid,'%s', 'delimiter', '\n');
synsetOut = synsetOut{1};
fclose(fid);

[val,indx] = sort(predict_scores, 'descend');
scores = val(1:5)*100;
labels = synsetOut(indx(1:5));

Отобразите лучшие пять меток классификации.

imfull = zeros(227,400,3, 'uint8');
for k = 1:3
   imfull(:,174:end,k) = im(:,:,k);
end
h = imshow(imfull, 'InitialMagnification',200);
text(get(h, 'Parent'), 1, 20, 'Classification with AlexNet' , 'color', 'w','FontSize', 20);
scol = 1;
srow = 50;
for k = 1:5
   t = text(get(h, 'Parent'), scol, srow, labels{k}, 'color', 'w','FontSize', 15);
   pos = get(t, 'Extent');
   text(get(h, 'Parent'), pos(1)+pos(3)+5, srow, sprintf('%2.2f%%', scores(k)), 'color', 'w', 'FontSize', 15);
   srow = srow + 20;
end

Классификация на видео

Включенный файл в качестве примера alexnet_live.m кадры захватов от веб-камеры, вызывает прогноз и отображает результаты классификации на каждом из полученных кадров видео. Примечание: Этот пример использует функцию веб-камеры, которая поддерживается через MATLAB® Support Package для USB Webcams™. Можно загрузить и установить пакет поддержки через Инсталлятор Пакета Поддержки.

  camera = webcam;
  while true
     % Take a picture
     ipicture = camera.snapshot;
     % Resize and cast the picture to single
     picture = imresize(ipicture,[227,227]);
     % Call MEX function for AlexNet prediction
     tic;
     pout = alexnet_predict(single(picture));
     newt = toc;
     % fps
     fps = .9*fps + .1*(1/newt);
     % top 5 scores
     [top5labels, scores] = getTopFive(pout, synsetOut);
     % display
     dispResults(ax, imfull, picture, top5labels, scores, fps);
  end

Очистите статический сетевой объект, загруженный в памяти.

clear mex;

Классификация с сетью ResNet-50

Мы можем также использовать популярную сеть DAG ResNet-50 для классификации изображений. Предварительно обученная модель ResNet-50 для MATLAB доступна в пакете поддержки ResNet-50 Deep Learning Toolbox. Чтобы загрузить и установить пакет поддержки, используйте Add-On Explorer. Чтобы узнать больше о нахождении и установке дополнений, смотрите, Получают Дополнения (MATLAB).

net = resnet50;
disp(net)
  DAGNetwork with properties:

         Layers: [177×1 nnet.cnn.layer.Layer]
    Connections: [192×2 table]

Запустите генерацию кода MEX для функции 'resnet_predict'

Сгенерируйте код CUDA из файла проекта resnet_predict.m. Этот файл проекта вызывает функцию resnet50, чтобы загрузить сеть, и выполнение предсказывают на входном изображении. Чтобы сгенерировать код из этого файла, создайте объект GPU Configuration для цели MEX как прежде.

cfg = coder.gpuConfig('mex');
cfg.TargetLang = 'C++';
cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn');
codegen -config cfg resnet_predict -args {ones(224,224,3)} -report
Code generation successful: To view the report, open('codegen/mex/resnet_predict/html/report.mldatx').

Вызов предсказывает на входном изображении.

im = imresize(im, [224,224]);
predict_scores = resnet_predict_mex(double(im));
[val,indx] = sort(predict_scores, 'descend');
scores = val(1:5)*100;
labels = synsetOut(indx(1:5));

Очистите статический сетевой объект, загруженный в памяти.

clear mex;

Классификация с сетью GoogLeNet (Inception)

Предварительно обученная модель GoogLeNet для MATLAB доступна в пакете поддержки GoogLeNet Deep Learning Toolbox. Чтобы загрузить и установить пакет поддержки, используйте Add-On Explorer. Чтобы узнать больше о нахождении и установке дополнений, смотрите, Получают Дополнения (MATLAB).

net = googlenet;
disp(net)
  DAGNetwork with properties:

         Layers: [144×1 nnet.cnn.layer.Layer]
    Connections: [170×2 table]

Запустите генерацию кода MEX для функции 'googlenet_predict'

Сгенерируйте код CUDA из файла проекта googlenet_predict.m. Этот файл проекта вызывает функцию googlenet, чтобы загрузить сеть, и выполнение предсказывают на входном изображении. Чтобы сгенерировать код из этого файла, создайте объект GPU Configuration для цели MEX как прежде.

cfg = coder.gpuConfig('mex');
cfg.TargetLang = 'C++';
cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn');
codegen -config cfg googlenet_predict -args {ones(224,224,3)} -report
Code generation successful: To view the report, open('codegen/mex/googlenet_predict/html/report.mldatx').

Вызов предсказывает на входном изображении.

im = imresize(im, [224,224]);
predict_scores = googlenet_predict_mex(double(im));
[val,indx] = sort(predict_scores, 'descend');
scores_googlenet = val(1:5)*100;
labels_googlenet = synsetOut(indx(1:5));

Очистите статический сетевой объект, загруженный в памяти.

clear mex;

Похожие темы