0.참고 자료
1. 사전훈련된 검출기 다운로드
doTraining = false; if ~doTraining && ~exist('fasterRCNNResNet50EndToEndVehicleExample.mat','file') disp('Downloading pretrained detector (118 MB)...'); pretrainedURL = 'https://www.mathworks.com/supportfiles/vision/data/fasterRCNNResNet50EndToEndVehicleExample.mat'; websave('fasterRCNNResNet50EndToEndVehicleExample.mat',pretrainedURL); end |
2. 데이터셋 불러오기
unzip vehicleDatasetImages.zip data = load('vehicleDatasetGroundTruth.mat'); vehicleDataset = data.vehicleDataset; |
3. 데이터셋을 훈련, 검증, 테스트 데이터셋으로 분할.
rng(0) shuffledIndices = randperm(height(vehicleDataset)); idx = floor(0.6 * height(vehicleDataset)); trainingIdx = 1:idx; trainingDataTbl = vehicleDataset(shuffledIndices(trainingIdx),:); validationIdx = idx+1 : idx + 1 + floor(0.1 * length(shuffledIndices) ); validationDataTbl = vehicleDataset(shuffledIndices(validationIdx),:); testIdx = validationIdx(end)+1 : length(shuffledIndices); testDataTbl = vehicleDataset(shuffledIndices(testIdx),:); |
4. imageDatastore과 boxLabelDatastore를 사용하여 데이터저장소를 만듦
imdsTrain = imageDatastore(trainingDataTbl{:,'imageFilename'}); bldsTrain = boxLabelDatastore(trainingDataTbl(:,'vehicle')); imdsValidation = imageDatastore(validationDataTbl{:,'imageFilename'}); bldsValidation = boxLabelDatastore(validationDataTbl(:,'vehicle')); imdsTest = imageDatastore(testDataTbl{:,'imageFilename'}); bldsTest = boxLabelDatastore(testDataTbl(:,'vehicle')); |
5. 영상 데이터저장소와 상자 레이블 데이터저장소를 결합
trainingData = combine(imdsTrain, bldsTrain); validationData = combine(imdsValidation, bldsValidation); testData = combine(imdsTest, bldsTest); |
6. 상자 레이블과 함께 훈련된 영상 중 하나를 표시
data = read(trainingData); I = data{1}; bbox = data{2}; annotatedImage = insertShape(I, 'rectangle', bbox); annotatedImage = imresize(annotatedImage, 3); figure imshow(annotatedImage) |
Faster R-CNN 검출 신경망 만들기
신경망 크기 지정
inputSize = [224 224 3]; |
훈련데이터의 사물크기를 기반으로 앵커상자를 추정
preprocessedTrainingData = transform(trainingData, @(data)preprocessData(data,inputSize)); numAnchors = 3; anchorBoxes = estimateAnchorBoxes(preprocessedTrainingData,numAnchors) |
resnet50 모델을 불러옴
featureExtractionNetwork = resnet50; |
activation_40_relu를 특징추출계층으로 선택
featureLayer = 'activation_40_relu'; |
검출할 클래스의 개수를 정의
numClasses = width(vehicleDataset)-1; |
Faster R-CNN 객체 검출 신경망을 만듦
lgraph = fasterRCNNLayers(inputSize, numClasses, anchorBoxes, featureExtractionNetwork, featureLayer) |
데이터 증대
augmentedTrainingData = transform(trainingData, @augmentData); augmentedData = cell(4,1); for k = 1:4 data = read(augmentedTrainingData); augmentedData{k} = insertShape(data{1},"rectangle", data{2}); reset(augmentedTrainingData); end figure montage(augmentedData, 'BorderSize', 10) |
훈련 데이터 전처리
trainingData = transform(augmentedTrainingData, @(data)preprocessData(data,inputSize)); validationData = transform(validationData, @(data)preprocesseData(data,inputSize)); |
전처리된 데이터 읽어들이기
data = read(trainingData); |
영상과 경계상자 표시
I = data{1}; bbox = data{2}; annotatedImage = insertShape(I, 'rectangle', bbox); annotatedImage = imresize(annotatedImage, 2); figure imshow(annotatedImage) |
Faster R-CNN 훈련시키기
신경망 훈련 옵션의 지정
options = trainingOptions('sgdm',... 'MaxEpochs',10,... 'MiniBatchSize',2,... 'InitialLearnRate',1e-3,... 'CheckpointPath',tempdir,... 'ValidationData',validationData); |
doTraining이 true인 경우, Faster R-CNN을 훈련시키며, 아닐경우 사전훈련된 신경망을 불러옴
if doTraining [detector, info] = trainFasterRCNNObjectDetector(trainingData, lgraph, options, ... 'NegativeOverlapRange', [0 0.3], ... 'PositiveOverlapRange', [0.6 1]); else pretrained = load('fasterRCNNResNet50EndToEndVehicleExample.mat'); detector = pretrained.detector; end |
1개의 테스트 영상에 대해 검출기 실행
I = imread(testDataTbl.imageFilename{3}); I = imresize(I,inputSize(1:2)); [bboxes, scores] = detect(detector, I); |
결과 표시
I = insertObjectAnnotation(I, 'rectangle', bboxes, scores); figure imshow(I) |
테스트 세트를 사용하여 검출기 평가하기
훈련데이터와 동일한 전처리 변환을 테스트 데이터에 적용
testData = transform(testData, @(data)preprocessData(data,inputSize)); |
모든 테스트 영상에 대해 검출기 실행
detectionResults = detect(detector, testData, 'MinibatchSize', 4); |
평균 정밀도를 사용하여 객체 검출기를 평가
[ap, recall, precision] = evaluateDetectionPrecision(detectionResults, testData); |
PR 곡선을 플로팅
figure plot(recall, precision) xlabel('Recall') ylabel('Precision') grid on title(sprintf('Average Precision = %.2f', ap)) |
지원 함수
function data = augmentData(data) % Randomly flip images and bounding boxes horizontally. tform = randomAffine2d('XReflection',true); sz = size(data{1}); rout = affineOutputView(sz,tform); data{1} = imwarp(data{1},tform,'OutputView',rout); % Sanitize boxes, if needed. This helper function is attached as a % supporting file. Open the example in MATLAB to open this function. % data{2} = helperSanitizeBoxes(data{2}); % Warp boxes. data{2} = bboxwarp(data{2},tform,rout); end |
function data = preprocessData(data,targetSize) % Resize image and bounding boxes to targetSize. sz = size(data{1},[1 2]); scale = targetSize(1:2)./sz; data{1} = imresize(data{1},targetSize(1:2)); % Sanitize boxes, if needed. This helper function is attached as a % supporting file. Open the example in MATLAB to open this function. % data{2} = helperSanitizeBoxes(data{2}); % Resize boxes. data{2} = bboxresize(data{2},scale); end |