0. Introduction
딥러닝을 연구하다 보면 훈련시킨 네트워크를 검증하기 위한 데이터가 필요하다.
예를 들어, 나는 딥러닝 네트워크들 중 YOLOv2를 MATLAB 상에서 KITTI dataset으로 훈련시켰고 이를 KITTI에서 제공하는 다른 데이터셋(ex Tracking dataset) 등에서 검증하였다. 하지만 다른 데이터셋에서도 높은 성능을 보일 수 있는지 궁금했고 자율주행을 위한 훈련 데이터셋으로 유명한 BDD를 활용하고자 했다.
https://bdd-data.berkeley.edu/
Berkley DeepDrive dataset에서 tracking dataset은 JSON 파일 형식으로 지원되며, 총 10개의 클래스로 분류된다. 현재 Sequence 상황에서의 성능 향상에 관련된 연구를 진행하고 있기 때문에 구현한 코드를 검증하기 위하여 해당 데이터셋을 활용하기로 결정하였고, 이를 위해서는 MATLAB에서 사용가능한 형태로로 변환할 필요가 있었다.
직접 파일을 구현하는건 매우 귀찮은 과정이기 때문에 관련 자료를 찾아봤지만 찾지 못했고 어쩔 수 없이 손수 코딩해야 했다. 다른 사람은 이런 과정을 거치지 않았으면 해서 구현한 코드를 구현한다.
JSON 파일 내부에 있는 데이터를 2D 객체 검출에서 활용하는 Bounding box(x, y, widty, height) 꼴로 변환해야 하며 이를 table 형태로 변환하여 활용한다.
코드를 긁어서 사용해도 되고, 링크의 github에서 clone하여 사용해도 좋다.
코드는 BDD에서 제공하는 JSON을 table로 변환한다. 이는 최적의 코드가 아니며, 변환의 결과물이 중요하니 그냥 넘어가자.
1. MATLAB function code
bdd_label함수
function GT = bdd_label(fname)
% fname is labels root
fid = fopen(fname);
raw = fread (fid, inf);
str = char (raw');
fclose (fid);
data = jsondecode (str);
imageFilename = string([]);
Ped = {};
Rid = {};
Car = {};
Tru = {};
Bus = {};
Tra = {};
Mot = {};
Bic = {};
TraL = {};
TraS = {};
fname = strcat(fname(1:11),'images\track\train', fname(37:54)); % images folder root
for i = 1:size(data,1)
imageFilename(i) = strcat(fname, '\', string(data(i).name));
for j = 1:size(data(i).labels,1)
if string(data(i).labels(j).category) == 'pedestrian'
C = {[data(i).labels(j).box2d.x1 data(i).labels(j).box2d.y1, (data(i).labels(j).box2d.x2-data(i).labels(j).box2d.x1), (data(i).labels(j).box2d.y2-data(i).labels(j).box2d.y1)]};
Ped(i,j) = C;
elseif string(data(i).labels(j).category) == 'rider'
C = {[data(i).labels(j).box2d.x1 data(i).labels(j).box2d.y1, (data(i).labels(j).box2d.x2-data(i).labels(j).box2d.x1), (data(i).labels(j).box2d.y2-data(i).labels(j).box2d.y1)]};
Rid(i,j) = C;
elseif string(data(i).labels(j).category) == 'car'
C = {[data(i).labels(j).box2d.x1 data(i).labels(j).box2d.y1, (data(i).labels(j).box2d.x2-data(i).labels(j).box2d.x1), (data(i).labels(j).box2d.y2-data(i).labels(j).box2d.y1)]};
Car(i,j) = C;
elseif string(data(i).labels(j).category) == 'truck'
C = {[data(i).labels(j).box2d.x1 data(i).labels(j).box2d.y1, (data(i).labels(j).box2d.x2-data(i).labels(j).box2d.x1), (data(i).labels(j).box2d.y2-data(i).labels(j).box2d.y1)]};
Tru(i,j) = C;
elseif string(data(i).labels(j).category) == 'bus'
C = {[data(i).labels(j).box2d.x1 data(i).labels(j).box2d.y1, (data(i).labels(j).box2d.x2-data(i).labels(j).box2d.x1), (data(i).labels(j).box2d.y2-data(i).labels(j).box2d.y1)]};
Bus(i,j) = C;
elseif string(data(i).labels(j).category) == 'train'
C = {[data(i).labels(j).box2d.x1 data(i).labels(j).box2d.y1, (data(i).labels(j).box2d.x2-data(i).labels(j).box2d.x1), (data(i).labels(j).box2d.y2-data(i).labels(j).box2d.y1)]};
Tra(i,j) = C;
elseif string(data(i).labels(j).category) == 'motorcycle'
C = {[data(i).labels(j).box2d.x1 data(i).labels(j).box2d.y1, (data(i).labels(j).box2d.x2-data(i).labels(j).box2d.x1), (data(i).labels(j).box2d.y2-data(i).labels(j).box2d.y1)]};
Mot(i,j) = C;
elseif string(data(i).labels(j).category) == 'bicycle'
C = {[data(i).labels(j).box2d.x1 data(i).labels(j).box2d.y1, (data(i).labels(j).box2d.x2-data(i).labels(j).box2d.x1), (data(i).labels(j).box2d.y2-data(i).labels(j).box2d.y1)]};
bic(i,j) = C;
elseif string(data(i).labels(j).category) == 'traffic light'
C = {[data(i).labels(j).box2d.x1 data(i).labels(j).box2d.y1, (data(i).labels(j).box2d.x2-data(i).labels(j).box2d.x1), (data(i).labels(j).box2d.y2-data(i).labels(j).box2d.y1)]};
TraL(i,j) = C;
elseif string(data(i).labels(j).category) == 'traffic sign'
C = {[data(i).labels(j).box2d.x1 data(i).labels(j).box2d.y1, (data(i).labels(j).box2d.x2-data(i).labels(j).box2d.x1), (data(i).labels(j).box2d.y2-data(i).labels(j).box2d.y1)]};
TraS(i,j) = C;
end
end
end
Car = mcc(Car);
if size(Car,1) ~= 0
Car(size(Car,1)+1:size(data,1),1) = {[]};
end
Rider = mcc(Rid);
if size(Rider,1) ~= 0
Rider(size(Rid,1)+1:size(data,1),1) = {[]};
end
Pedestrian = mcc(Ped);
if size(Ped,1) ~= 0
Pedestrian(size(Ped,1)+1:size(data,1),1) = {[]};
end
Truck = mcc(Tru);
if size(Truck,1) ~= 0
Truck(size(Tru,1)+1:size(data,1),1) = {[]};
end
Bus = mcc(Bus);
if size(Bus,1) ~= 0
Bus(size(Bus,1)+1:size(data,1),1) = {[]};
end
Motorcycle = mcc(Mot);
if size(Motorcycle,1) ~= 0
Motorcycle(size(Mot,1)+1:size(data,1),1) = {[]};
end
Train = mcc(Tra);
if size(Train,1) ~= 0
Train(size(Tra,1)+1:size(data,1), 1) = {[]};
end
Bicycle = mcc(Bic);
if size(Bicycle, 1) ~=0
Bicycle(size(Bic,1)+1:size(data,1), 1) = {[]};
end
TrafficLight = mcc(TraL);
if size(TrafficLight,1) ~= 0
TrafficLight(size(TraL,1)+1:size(data,1), 1) = {[]};
end
TrafficSign = mcc(TraS);
if size(TrafficSign,1) ~= 0
TrafficSign(size(TraS,1)+1:size(data,1), 1) = {[]};
end
imageFilename = imageFilename';
GT = table(imageFilename);
if ~isempty(Car) ; GT.Car = Car; end
if ~isempty(Pedestrian) ; GT.Pedestrian= Pedestrian; end
if ~isempty(Rider) ; GT.Rider = Rider; end
if ~isempty(Truck) ; GT.Truck = Truck; end
if ~isempty(Train) ; GT.Train = Train; end
if ~isempty(Bus) ; GT.Bus = Bus; end
if ~isempty(Bicycle) ; GT.Bicycle = Bicycle; end
if ~isempty(Motorcycle) ; GT.Motorcycle = Motorcycle; end
if ~isempty(TrafficSign) ; GT.TrafficSign = TrafficSign; end
if ~isempty(TrafficLight) ; GT.TrafficLight = TrafficLight; end
end
bdd_label함수를 활용할 때 필요한 mcc함수
function MakeClasscell = mcc(arr)
MakeClasscell = {};
if ~isempty(arr)
for l = 1:size(arr, 1)
sav = [];
for k = 1:size(arr,2)
if ~isempty(arr{l,k})
sav(size(sav,1)+1,1:4) = arr{l,k};
else
continue
end
end
MakeClasscell(l,1) = {sav};
end
end
end
2. 코드 설명 & 추가 활용법
input으로는 라벨의 경로를 넣어주면 된다. 이 파일을 사용할 때 주의해야 하는 점은 세 가지이다.
- 함수를 사용할 때는 파일의 확장자까지 넣어주어야 한다는 점을 기억해야 한다. BDD dataset의 라벨은 json 파일으로 제공되므로 'C:\User\users\...\abcd02020.json'와 같은 형식으로 함수의 인자에 넣어준다.
- mcc 함수 역시 github에 함께 올려 놓았으니 다운 받아서 사용하면 된다.
- 20번째 줄의 코드는 사용자에 따라 다를 수 있으니 이미지가 존재하는 폴더 경로로 변경해야 한다. (fname = strcat(fname(1:11),'images\track\train', fname(37:54));)
이를 활용해서 생성되는 것은 table 형식이며 이를 활용한 훈련이나 검증이 모두 가능하다. 하지만 혹여나 ground truth 형식으로 변환하고 싶다면(예를 들어, 훈련에 ground truth 형식의 변수가 필요하거나 image labeler 확장 앱으로 시각화하여 확인하고 싶다면) 아래의 코드로 ground truth 형식으로 변환할 수 있다.
'딥러닝 > 프로젝트' 카테고리의 다른 글
[Loss function] GIoU / DIoU / CIoU Matlab 코드 (0) | 2021.12.07 |
---|