MATLAB

MathWorks - Extract Image Features Using Pretrained Network (사전 훈련된 신경망을 사용하여 영상 특징 추출하기)

RiLLa_0511 2023. 8. 16. 11:33
728x90

 

https://kr.mathworks.com/help/deeplearning/ug/extract-image-features-using-pretrained-network.html

 

사전 훈련된 신경망을 사용하여 영상 특징 추출하기 - MATLAB & Simulink - MathWorks 한국

이 예제의 수정된 버전이 있습니다. 사용자가 편집한 내용을 반영하여 이 예제를 여시겠습니까?

kr.mathworks.com

 

※ 사전 훈련된 컨볼루션 신경망에서 학습된 영상을 추출한 다음 추출한 특징을 사용하여 영상 분류기를 훈련시키는 예제

 

< SVM 개념 참고 블로그 >

https://sanghyu.tistory.com/7

 

SVM(Support Vector Machine) 원리

어떠한 '분류'라는 문제를 풀기 위해 패턴 인식 분야는 꾸준히 발전하였다. 가장 오랜 역사를 가진 통계적 분류방법에서 출발해서 신경망이 개발되었고 트리분류기, 은닉마코프모델등이 개발되

sanghyu.tistory.com

 

● 데이터 불러오기

unzip('MerchData.zip');

% 이미지 데이터를 불러와 처리하기 위해 이미지 데이터 저장소(imageDatastore)를 생성 -> imds
% 'MerchData' : 이미지 데이터의 폴더 경로
% 'IncludeSubfolders', true : 서브폴더 내의 이미지도 모두 포함하도록
% 'LabelSource','foldernames' : 각 폴더의 이름이 해당 이미지들의 레이블로 사용됨 
imds = imageDatastore('MerchData','IncludeSubfolders',true,'LabelSource','foldernames');

% 데이터를 훈련 세트와 테스트 세트로 나눔
% 0.7 -> 전체 데이터에서 훈련 세트에 할당할 비율 => 70%의 데이터가 훈련 세트로 사용됨 
[imdsTrain,imdsTest] = splitEachLabel(imds,0.7,'randomized');
% 훈련 데이터 세트의 이미지 수를 계산
% imdsTrain.Labels : 훈련 데이터 세트의 이미지에 대한 레이블
% numel : 배열 내 원소의 개수를 반환하는 함수
numTrainImages = numel(imdsTrain.Labels);

% 훈련 데이터 이미지 중에서 16개의 이미지를 무작위로 선택한 후, 선택된 이미지들의 인덱스는 'idx' 배열에 저장됨
idx = randperm(numTrainImages,16);


figure


for i = 1:16
    subplot(4,4,i) % 4x4 크기의 서브플롯 중 i번째 위치에 현재 이미지를 배치
    I = readimage(imdsTrain,idx(i)); % 변수 I에 imdsTrain에서 idx(i) 번째 이미지를 저장
    imshow(I)
end

 

● 사전 훈련된 신경망 불러오기

% ResNet-18 : 딥러닝에서 사용되는 컨볼루션 신경망(CNN) 아키텍처 중 하나
% MATLAB에서 미리 구현된 ResNet-18 모델을 불러와 net 변수에 할당

net = resnet18
% ResNet-18 모델의 첫 번째 레이어의 입력 크기를 가져와서 inputSize 변수에 저장
% ResNet-18 모델의 첫 번째 레이어는 입력 이미지를 받는 부분으로, 이를 통해 모델의 입력 크기를 추출
inputSize = net.Layers(1).InputSize;

% 불러온 ResNet-18 모델 net을 분석하여 모델의 구조와 레이어들의 정보를 시각화하여 보여줌
analyzeNetwork(net)

 

 

● 영상 특징 추출하기

% 훈련 데이터와 테스트 데이터 증강하기

augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain);
augimdsTest = augmentedImageDatastore(inputSize(1:2),imdsTest);
% ResNet-18 모델에서 사용할 레이어 선택
% pool5 : ResNet-18 아키텍처에서 마지막 풀링 레이어
layer = 'pool5';

% 선택한 레이어를 통과한 훈련 데이터의 특성 추출
% augimdsTrain: 데이터 증강을 적용한 훈련 데이터 저장소
% 'OutputAs', 'rows': 레이어의 출력을 행 벡터로 반환하도록 지정
featuresTrain = activations(net,augimdsTrain,layer,'OutputAs','rows');

% 선택한 레이어를 통과한 테스트 데이터의 특성을 추출
featuresTest = activations(net,augimdsTest,layer,'OutputAs','rows');


% whos 명령어 -> featuresTrain 변수에 저장된 데이터의 정보를 출력
%  변수의 크기, 클래스, 메모리 사용량 등 알 수 있음
whos featuresTrain
% 훈련 데이터와 테스트 데이터로부터 클래스 레이블 추출

YTrain = imdsTrain.Labels;
YTest = imdsTest.Labels;

 

 

● 영상 분류기 피팅하기

% 훈련 영상으로부터 추출한 특징을 예측 변수로 사용
% fitcecoc(Statistics and Machine Learning Toolbox)를 사용하여 다중클래스 서포트 벡터 머신(SVM)을 피팅
% featuresTrain : 훈련 데이터의 특성을 나타내는 변수로 이전 단계에서 추출한 특성들이 포함됨
% YTrain: 훈련 데이터의 레이블을 나타내는 변수

classifier = fitcecoc(featuresTrain,YTrain);

 

 

● 테스트 영상 분류하기

% 훈련된 SVM 모델과 테스트 영상으로부터 추출한 특징을 사용하여 테스트 영상을 분류
% classifier: 이전 단계에서 학습한 분류기
% featuresTest: 테스트 데이터의 특성을 나타내는 변수로 이전 단계에서 추출한 특성들이 포함됨

YPred = predict(classifier,featuresTest);

 

 

● 테스트 영상 분류하기

% 4개의 샘플 테스트 영상을 예측된 레이블과 함께 표시
idx = [1 5 10 15];
figure
for i = 1:numel(idx)
    subplot(2,2,i)
    I = readimage(imdsTest,idx(i));
    label = YPred(idx(i));
    imshow(I)
    title(char(label))
end
% 예측된 레이블과 실제 레이블을 비교하여 테스트 세트에 대한 분류기의 정확도를 계산
accuracy = mean(YPred == YTest)

 

 

 

● 더 얕은 특징을 대상으로 분류기 훈련시키기

 → 얕은 계층에서 추출된 특징을 활용할 시, 모델이 좀 더 데이터의 세부적인 특성을 학습하게 됨

 → 특성 벡터의 차원이 줄어들고 차원 감소를 통해 더 빠른 학습 및 예측이 가능하며, 더 작은 데이터 세트에서도 일반화 능력을 향상시키는데 도움을 줄 수 있음

 → 계산량이 줄어들어 더 적은 계산 자원을 사용하여 훈련과 예측을 수행하도록 도와줌

layer = 'res3b_relu';
featuresTrain = activations(net,augimdsTrain,layer);
featuresTest = activations(net,augimdsTest,layer);
whos featuresTrain

 

 ※ 훈련 데이터와 테스트 데이터의 중간 특성을 축소하여 평균값을 계산하고 행렬의 차원을 조절하여 각각 featuresTrain과 featuresTest 변수에 저장

→ 각 이미지의 특성맵을 하나의 평균 특성 벡터로 변환하게 됨

% 훈련 데이터의 중간 특성에서 공간 차원을 축소하여 평균값을 계산하고 행렬의 차원 조절
featuresTrain = squeeze(mean(featuresTrain,[1 2]))';

% 테스트 데이터의 중간 특성에 대해 평균값을 계산하고 행렬의 차원 조절
featuresTest = squeeze(mean(featuresTest,[1 2]))';

% whos 명령어를 사용하여 featuresTrain 변수에 저장된 데이터의 정보를 출력
whos featuresTrain

 ※ 얕은 특징을 대상으로 SVM 분류기를 훈련시킨 후, 테스트 정확도 계산

 

% 훈련 데이터의 중간 특성을 입력으로 받아 다중 클래스 서포트 벡터 머신(SVM) 분류기를 훈련
classifier = fitcecoc(featuresTrain,YTrain);

% 테스트 데이터의 중간 특성을 입력으로 받아 분류기를 사용하여 예측 수행
YPred = predict(classifier,featuresTest);

% 예측된 레이블과 테스트 데이터의 실제 레이블을 비교하여 분류기의 정확도 계산
% YPred == YTest : 예측된 레이블과 실제 레이블을 비교한 결과로, 같은 경우에는 true를, 다른 경우에는 false를 반환
accuracy = mean(YPred == YTest)