Этот пример демонстрирует генерацию кода для приложения классификации изображений, которое использует глубокое обучение. Это использует команду codegen
, чтобы сгенерировать MEX-функцию, которая запускает прогноз с помощью популярных сетей классификации изображений, таких как AlexNet, ResNet и GoogLeNet.
CUDA® включил NVIDIA®, графический процессор с вычисляет возможность 3.2 или выше.
NVIDIA инструментарий CUDA и драйвер.
Библиотека NVIDIA cuDNN (v7) или выше.
Переменные окружения для компиляторов и библиотек. Для получения информации о поддерживаемых версиях компиляторов и библиотек, смотрите Сторонние продукты. Для подготовки переменных окружения смотрите Подготовку Необходимых как условие продуктов.
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.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);
Загрузите сеть 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
Чтобы сгенерировать код 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
Загрузите входное изображение.
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;
Мы можем также использовать популярную сеть 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]
Сгенерируйте код 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 для 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]
Сгенерируйте код 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;