Main Content

로고 인식 신경망

이 예제에서는 딥러닝을 사용하는 로고 분류 응용 분야를 위한 코드 생성을 보여줍니다. LogoNet이라는 사전 훈련된 신경망을 사용하고 입력 영상을 32개의 로고 범주로 분류합니다. 이 예제에서는 전처리된 훈련 데이터 세트를 사용하여 신경망을 훈련시키는 방법도 보여줍니다. 마지막으로 이 예제는 codegen 명령을 사용하여 MEX 함수를 생성하고 예측을 수행합니다.

이 예제에서는 다음과 같은 개념을 보여줍니다.

  • 로고를 추출하고 크기는 227×227×3으로 조정하여 훈련 영상을 전처리합니다. 이어서 영상 증대를 사용하여 훈련 데이터 크기를 늘립니다.

  • SGDM(Stochastic Gradient Descent with Momentum: 모멘텀을 사용한 확률적 경사하강법) 최적화 함수를 사용하여 신경망을 훈련시킵니다.

  • CUDA® MEX를 생성하고 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);

로고 인식 신경망

로고는 사용자의 브랜드 식별 및 인식을 돕습니다. 많은 기업들이 광고, 문서 자료 및 홍보에 자사의 로고를 적용합니다. 로고 인식 신경망은 MATLAB®에서 개발되었고 22개의 계층을 포함합니다. 이 신경망에는 4 세트의 컨벌루션 최댓값 풀링 계층, 3개의 완전 연결 계층, 계산 비용을 줄이는 드롭아웃 계층이 포함됩니다. 이 신경망은 크기가 227×227×3인 입력 영상을 취하고 이 영상을 32개의 로고 범주로 분류합니다. 이 신경망은 인식에 주력하므로 위치 추정이 필요하지 않은 응용 분야에서 사용할 수 있습니다. 이 신경망은 Flickr32Logos[1]와 Flickr32 Plus[2] 훈련 데이터 세트를 사용하여 MATLAB에서 훈련되었습니다. 두 데이터 세트에는 각 로고에 대한 영상이 약 200개 들어 있습니다. 이 신경망은 SGDM(모멘텀을 사용한 확률적 경사하강법) 최적화 함수, 학습률 0.0001, Epoch 40회, 미니 배치 크기 45를 사용하여 훈련되었습니다. 기본적으로 이 예제에서는 사전 훈련된 로고 인식 신경망을 사용합니다. 사전 훈련된 신경망을 사용하면 훈련이 완료될 때까지 기다리지 않고 전체 예제를 실행할 수 있습니다.

신경망을 훈련시키려면 다음 코드에서 doTraining 변수를 true로 설정하십시오. 또한, Deep Learning for Logo Recognition에서 Logos-32plus 데이터 세트를 다운로드하고 다운로드한 Logos-32plus_v1.0.1.zip 파일의 위치를 logozipPath에 제공해야 합니다. Logos-32plus 데이터 세트의 크기는 1.95GB입니다. 인터넷 연결에 따라 다운로드 과정에 약간의 시간이 걸릴 수 있습니다. 데이터 세트는 총 7,830개의 다양한 브랜드 로고 영상이 포함된 32개의 영상 하위 폴더로 구성되어 있습니다. groundtruth MAT 파일은 각 영상 속 로고의 경계 상자 정보를 제공합니다.

preprocessLogoData 함수는 신경망 훈련을 위해 데이터를 전처리합니다. Logos-32plus 데이터 세트에 들어 있는 영상은 크기가 다양합니다. 신경망의 입력 계층 크기(227×227×3)에 맞게 영상 크기를 조정해야 합니다. 영상에는 제거되어야 하는 배경 정보도 들어 있습니다. preprocessLogoData.m은 로고를 추출하기 위해 경계 상자 정보를 사용하여 이러한 단계를 수행하고 신경망 훈련에 사용할 수 있는 imageDatastore 객체를 만듭니다. trainLogonet 함수는 로고 인식 계층을 만들고 지정된 훈련 옵션을 사용하여 신경망을 훈련시킵니다. 신경망은 로고마다 최소 110개의 영상을 포함하는 데이터를 사용하여 훈련됩니다.

데이터 증대를 사용하여 훈련 샘플의 개수를 늘릴 수도 있습니다. 데이터 증대는 신경망이 과적합되는 것을 방지하고 훈련 영상의 정확한 세부 정보가 기억되지 않도록 하는 데 도움이 됩니다. 훈련 데이터를 늘리기 위해 무작위 뒤집기, 가우스 블러, 전단, 대비 정규화의 네 가지 유형의 데이터 증대가 제공됩니다. 데이터 증대를 사용하려면 다음 코드에서 doAugmentation 변수를 true로 설정하십시오.

doTraining = false;

if ~doTraining
    getLogonet;
else
    logozipPath  = '';% provide path of the downloaded zip file
    zipData = fullfile(logozipPath,'Logos-32plus_v1.0.1.zip');
    unpackedData = fullfile(logozipPath,'Logos32plus');
    
    if ~exist(unpackedData,'dir')
        unzip(zipData,unpackedData);
    end

    doAugmentation = false;
    logoData = preprocessLogoData(unpackedData,doAugmentation);
    trainLogonet(logoData);
end

load('LogoNet.mat');
convnet
convnet = 
  SeriesNetwork with properties:

         Layers: [22×1 nnet.cnn.layer.Layer]
     InputNames: {'imageinput'}
    OutputNames: {'classoutput'}

신경망 아키텍처를 확인하려면 analyzeNetwork 함수를 사용하십시오.

analyzeNetwork(convnet)

logonet_predict 진입점 함수

logonet_predict.m 진입점 함수는 영상을 입력값으로 받아 LogoNet.mat 파일에 저장된 딥러닝 신경망을 사용하여 이 영상에 대해 예측을 수행합니다. 이 함수는 LogoNet.mat의 network 객체를 영속 변수 logonet으로 불러오고, 후속 예측 호출에서 영속 변수를 재사용합니다.

type('logonet_predict.m')
function out = logonet_predict(in)
%#codegen

% Copyright 2017-2022 The MathWorks, Inc.

% A persistent object logonet is used to load the 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 logonet;

if isempty(logonet)
    
    logonet = coder.loadDeepLearningNetwork('LogoNet.mat','logonet');
end

out = logonet.predict(in);

end

logonet_predict 함수에 대한 CUDA MEX 생성하기

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

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

생성된 MEX 실행하기

입력 영상 하나를 불러옵니다. 입력 영상에 대해 logonet_predict_mex를 호출합니다.

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

im = imresize(im, [227,227]);
predict_scores = logonet_predict_mex(im);

상위 5개의 예측 점수를 Wordnet 사전 synset(logos)에 있는 단어에 매핑합니다.

synsetOut = convnet.Layers(end).Classes;

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

상위 5개의 분류 레이블을 표시합니다.

outputImage = zeros(227,400,3, 'uint8');
for k = 1:3
    outputImage(:,174:end,k) = im(:,:,k);
end

scol = 1;
srow = 20;

for k = 1:5
    outputImage = insertText(outputImage, [scol, srow],...
        [char(top5labels(k)),' ',num2str(scores(k),'%2.2f'),'%'],...
        'TextColor', 'w','FontSize',15, 'BoxColor', 'black');
    srow = srow + 20;
end

 imshow(outputImage);

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

clear mex;

참고 문헌

[1] Romberg, Stefan, Lluis Garcia Pueyo, Rainer Lienhart, and Roelof van Zwol. "Scalable Logo Recognition in Real-World Images." ACM International Conference on Multimedia Retrieval 2011 (ICMR11): 1-8. https://doi.org/10.1145/1991996.1992021

[2] Bianco, Simone, Marco Buzzelli, Davide Mazzini, and Raimondo Schettini. "Deep Learning for Logo Recognition." Neurocomputing 245 (2017): 23-30. https://doi.org/10.1016/j.neucom.2017.03.051.

관련 항목