Main Content

딥러닝 신경망을 위한 코드 생성

이 예제에서는 딥러닝을 사용하는 영상 분류 응용 사례에서 코드 생성을 수행하는 방법을 보여줍니다. 이 예제에서는 codegen 명령을 사용하여, MobileNet-v2, ResNet, GoogLeNet과 같은 영상 분류 신경망을 사용하여 예측을 실행하는 MEX 함수를 생성합니다.

타사 선행 조건

필수

이 예제는 CUDA MEX를 생성하며, 다음과 같은 타사 요구 사항이 있습니다.

  • CUDA® 지원 NVIDIA® GPU 및 호환되는 드라이버.

선택 사항

정적, 동적 라이브러리 또는 실행 파일과 같은 비 MEX 빌드의 경우, 이 예제에는 다음과 같은 추가 요구 사항이 있습니다.

GPU 환경 확인하기

coder.checkGpuInstall (GPU Coder) 함수를 사용하여 이 예제를 실행하는 데 필요한 컴파일러와 라이브러리가 올바르게 설치되었는지 확인합니다.

envCfg = coder.gpuEnvConfig('host');
envCfg.DeepLibTarget = 'cudnn';
envCfg.DeepCodegen = 1;
envCfg.Quiet = 1;
coder.checkGpuInstall(envCfg);

mobilenetv2_predict 진입점 함수

MobileNet-v2는 컨벌루션 신경망이며, ImageNet 데이터베이스의 1백만 개가 넘는 영상에 대해 훈련되었습니다. 이 신경망에는 155개의 계층이 있으며, 영상을 키보드, 마우스, 연필, 각종 동물 등 1,000가지 사물 범주로 분류할 수 있습니다. 신경망의 영상 입력 크기는 224×224입니다. analyzeNetwork 함수를 사용하여 딥러닝 신경망 아키텍처의 대화형 시각화를 표시합니다.

net = mobilenetv2();
analyzeNetwork(net);

mobilenetv2_predict.m 진입점 함수는 영상을 입력값으로 받아서 사전 훈련된 MobileNet-v2 컨벌루션 신경망을 사용하여 영상에 대해 예측을 실행합니다. 이 함수는 영속 객체 mynet을 사용하여 series network 객체를 불러온 후 후속 호출에서 예측을 위해 영속 객체를 재사용합니다.

type('mobilenetv2_predict.m')
% Copyright 2017-2019 The MathWorks, Inc.

function out = mobilenetv2_predict(in) 
%#codegen

persistent mynet;

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

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

MEX 코드 생성 실행하기

mobilenetv2_predict 진입점 함수에 대한 CUDA 코드를 생성하려면 MEX 대상에 대한 GPU 코드 구성 객체를 만들고 대상 언어를 C++로 설정하십시오. coder.DeepLearningConfig (GPU Coder) 함수를 사용하여 CuDNN 딥러닝 구성 객체를 만들고 이 객체를 GPU 코드 구성 객체의 DeepLearningConfig 속성에 할당합니다. codegen 명령을 실행하고 입력 크기를 [224,224,3]으로 지정합니다. 이 값은 MobileNet-v2 신경망의 입력 계층 크기입니다.

cfg = coder.gpuConfig('mex');
cfg.TargetLang = 'C++';
cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn');
codegen -config cfg mobilenetv2_predict -args {ones(224,224,3)} -report
Code generation successful: View report

생성된 코드에 대한 설명

시리즈 신경망은 155개의 계층 클래스로 구성된 배열과 신경망을 설정, 예측, 정리하는 함수를 가지는 C++ 클래스로 생성됩니다.

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

이 클래스의 setup() 메서드는 핸들을 설정하고 network 객체의 각 계층에 대해 메모리를 할당합니다. predict() 메서드는 신경망의 155개 계층 각각에 대해 예측을 수행합니다.

생성된 코드 파일 mobilenetv2_predict.cu의 진입점 함수 mobilenetv2_predict()b_mobilenetv2 클래스 유형의 정적 객체를 생성하고 이 network 객체에서 setup과 predict를 호출합니다.

static b_mobilenetv2_0 mynet;
static boolean_T mynet_not_empty;
/* Function Definitions */
void mobilenetv2_predict(const real_T in[150528], real32_T out[1000])
{
  if (!mynet_not_empty) {
    DeepLearningNetwork_setup(&mynet);
    mynet_not_empty = true;
  }
   /*  pass in input    */
   DeepLearningNetwork_predict(&mynet, in, out);
 }

신경망의 완전 연결 계층, 컨벌루션 계층처럼 파라미터를 가지는 계층에 대한 이진 파일이 내보내집니다. 예를 들어, cnn_mobilenetv2_conv*_w 파일과 cnn_mobilenetv2_conv*_b 파일은 이 신경망에서 각각 컨벌루션 계층의 가중치 파라미터와 편향 파라미터에 해당합니다. 생성된 파일의 목록을 보려면 다음을 사용하십시오.

dir(fullfile(pwd, 'codegen', 'mex', 'mobilenetv2_predict'))

생성된 MEX 실행하기

입력 영상 하나를 불러옵니다.

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

입력 영상에 대해 mobilenetv2_predict_mex를 호출합니다.

im = imresize(im, [224,224]);
predict_scores = mobilenetv2_predict_mex(double(im));

상위 5개의 예측 점수와 그 레이블을 가져옵니다.

[scores,indx] = sort(predict_scores, 'descend');
classNames = net.Layers(end).ClassNames;
classNamesTop = classNames(indx(1:5));

h = figure;
h.Position(3) = 2*h.Position(3);
ax1 = subplot(1,2,1);
ax2 = subplot(1,2,2);

image(ax1,im);
barh(ax2,scores(5:-1:1))
xlabel(ax2,'Probability')
yticklabels(ax2,classNamesTop(5:-1:1))
ax2.YAxisLocation = 'right';
sgtitle('Top Five Predictions That Use MobileNet-v2')

메모리로 불러온 정적 network 객체를 지웁니다.

clear mex;

ResNet-50 신경망을 사용한 영상 분류

DAG 신경망 ResNet-50을 영상 분류에 사용할 수도 있습니다. MATLAB에서 사용 가능한 사전 훈련된 ResNet-50 모델은 Deep Learning Toolbox Model for ResNet-50 Network 지원 패키지에서 제공됩니다. 지원 패키지를 다운로드하여 설치하려면 애드온 탐색기를 사용하십시오. 애드온을 찾아서 설치하는 방법에 대해 자세히 알아보려면 애드온을 받고 관리하기 항목을 참조하십시오.

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

         Layers: [177×1 nnet.cnn.layer.Layer]
    Connections: [192×2 table]
     InputNames: {'input_1'}
    OutputNames: {'ClassificationLayer_fc1000'}

MEX 코드 생성 실행하기

resnet_predict.m 진입점 함수에 대한 CUDA 코드를 생성하려면 MEX 대상에 대한 GPU 코드 구성 객체를 만들고 대상 언어를 C++로 설정하십시오. 이 진입점 함수는 resnet50 함수를 호출하여 신경망을 불러오고 입력 영상에 대해 예측을 수행합니다.

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: View report

입력 영상에 대해 resnet_predict_mex를 호출합니다.

predict_scores = resnet_predict_mex(double(im));

상위 5개의 예측 점수와 그 레이블을 가져옵니다.

[scores,indx] = sort(predict_scores, 'descend');
classNames = net.Layers(end).ClassNames;
classNamesTop = classNames(indx(1:5));

h = figure;
h.Position(3) = 2*h.Position(3);
ax1 = subplot(1,2,1);
ax2 = subplot(1,2,2);

image(ax1,im);
barh(ax2,scores(5:-1:1))
xlabel(ax2,'Probability')
yticklabels(ax2,classNamesTop(5:-1:1))
ax2.YAxisLocation = 'right';
sgtitle('Top Five Predictions That Use ResNet-50')

메모리로 불러온 정적 network 객체를 지웁니다.

clear mex;

GoogLeNet(Inception) 신경망을 사용한 영상 분류

MATLAB에서 사용 가능한 사전 훈련된 GoogLeNet 모델은 Deep Learning Toolbox Model for GoogLeNet Network 지원 패키지에서 제공됩니다. 지원 패키지를 다운로드하여 설치하려면 애드온 탐색기를 사용하십시오. 애드온을 찾아서 설치하는 방법에 대해 자세히 알아보려면 애드온을 받고 관리하기 항목을 참조하십시오.

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

         Layers: [144×1 nnet.cnn.layer.Layer]
    Connections: [170×2 table]
     InputNames: {'data'}
    OutputNames: {'output'}

MEX 코드 생성 실행하기

googlenet_predict.m 진입점 함수에 대한 CUDA 코드를 생성합니다. 이 진입점 함수는 googlenet 함수를 호출하여 신경망을 불러오고 입력 영상에 대해 예측을 수행합니다. 이 진입점 함수에 대한 코드를 생성하려면 MEX 대상에 대한 GPU 구성 객체를 만드십시오.

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: View report

입력 영상에 대해 googlenet_predict_mex를 호출합니다.

im = imresize(im, [224,224]);
predict_scores = googlenet_predict_mex(double(im));

상위 5개의 예측 점수와 그 레이블을 가져옵니다.

[scores,indx] = sort(predict_scores, 'descend');
classNames = net.Layers(end).ClassNames;
classNamesTop = classNames(indx(1:5));

h = figure;
h.Position(3) = 2*h.Position(3);
ax1 = subplot(1,2,1);
ax2 = subplot(1,2,2);

image(ax1,im);
barh(ax2,scores(5:-1:1))
xlabel(ax2,'Probability')
yticklabels(ax2,classNamesTop(5:-1:1))
ax2.YAxisLocation = 'right';
sgtitle('Top Five Predictions That Use GoogLeNet')

메모리로 불러온 정적 network 객체를 지웁니다.

clear mex;

관련 항목