Fast R-CNN 코드 (Python3 Keras 사용)
github.com/leehe228/keras-frcnn
DOTA에는 Label이
x1, y1, x2, y2, x3, y3, x4, y4, category, difficult
위와 같이 작성되어 있다.
학습 전 Python3와 OpenCV를 이용해 정답 시각화를 해보았다.
#-*-coding:utf-8-*-
import cv2 as cv
import os
START = 1910
MAX = 2805
c = (0, 0, 255)
if __name__ == "__main__":
for idx in range(START, MAX + 1):
if idx % 20 == 0:
print(f"{int(float(idx - START) / float(MAX + 1 - START) * 100.0)}% : {idx - START}/{MAX + 1 - START}")
idxs = str(idx)
idxs = '0' * (4 - len(idxs)) + idxs
if os.path.isfile('./DOTA-v1.5_train/P' + str(idxs) + '.txt'):
try:
img = cv.imread('./part3/P' + str(idxs) + '.png')
f = open('./DOTA-v1.5_train/P' + str(idxs) + '.txt')
while True:
line = f.readline()
if not line:
break
l = list(map(str, line.split()))
if len(l) != 1:
s1 = (int(float(l[0])), int(float(l[1])))
s2 = (int(float(l[2])), int(float(l[3])))
s3 = (int(float(l[4])), int(float(l[5])))
s4 = (int(float(l[6])), int(float(l[7])))
cv.line(img, s1, s2, c, 1)
cv.line(img, s2, s3, c, 1)
cv.line(img, s3, s4, c, 1)
cv.line(img, s4, s1, c, 1)
cv.putText(img, l[8], s3, cv.FONT_HERSHEY_SIMPLEX, 0.5, c)
# img = cv.resize(img, dsize=(0, 0), fx=0.3, fy=0.3, interpolation=cv.INTER_LINEAR)
cv.imwrite('./result/P' + str(idxs) + '.png', img)
#cv.imshow('test', img)
#cv.waitKey(0)
#cv.destroyAllWindows()
except Exception as e:
print(f"at {idx}th image : {e}")
print('done')
Fast R-CNN은 Train Labels와 Train Image를 읽어 학습한다.
Fast R-CNN에서 요구하는 Train Labels 형태는 다음과 같다.
{IMAGE_DIRECTORY}, x1, y1, x2, y2, {CATEGORY}
DOTA Dataset은 HBB가 아닌 OBB 형태로, 정답률을 높였지만, Fast R-CNN에서는 HBB 형태로 학습한다. (점이 2개만 필요하다)
Python 코드를 통해 정답 레이블을 Fast R-CNN이 요구하는 학습용 레이블로 변환한다.
import os
import csv
START = 0
#MAX = 2805
MAX = 1000
HOME_PATH = 'C:/Users/dmslab/Desktop/DATASET/DOTA/'
CSV_PATH = 'C:/Users/dmslab/Desktop/DATASET/DOTA/train.csv'
if __name__ == "__main__":
csv_file = open(CSV_PATH, 'a', newline='')
wr = csv.writer(csv_file)
for idx in range(START, MAX + 1):
if idx % 20 == 0:
print(f"{int(float(idx - START) / float(MAX + 1 - START) * 100.0)}% : {idx - START}/{MAX + 1 - START}")
idxs = str(idx)
idxs = '0' * (4 - len(idxs)) + idxs
if os.path.isfile(HOME_PATH + 'LABEL/P' + str(idxs) + '.txt'):
try:
f = open(HOME_PATH + 'LABEL/P' + str(idxs) + '.txt')
while True:
line = f.readline()
if not line:
break
l = list(map(str, line.split()))
if len(l) != 1:
x1 = int(float(l[0]))
y1 = int(float(l[1]))
x2 = int(float(l[4]))
y2 = int(float(l[5]))
wr.writerow([HOME_PATH + 'IMAGE/P' + str(idxs) + '.png', x1, y1, x2, y2, l[8]])
except Exception as e:
print(f"at {idx}th : {e}")
print('done')
csv_file.close()
이 코드를 이용해 정답 레이블을 아래와 같은 형식으로 변환하였다.
학습 준비는 모두 마쳤다. 이제 아래와 같이 train_frcnn.py를 이용해 학습을 시작한다.
python train_frcnn.py -o simple -p train.txt
210,631개의 데이터를 epoch=1,000으로 지정해 학습을 시작했다.
시간 제약으로 인해 epoch 1000회를 채우지 못하고 약 40번 반복 후 학습을 종료시켰다. (약 5일 소요)
항공 이미지 데이터가 워낙 해상도가 커 용량이 크고, 하나의 사진에 포함된 object의 개수도 많아 학습이 매우 더디게 된다.
CNN Rotation Invariant, Fast R-CNN의 Regional Proposal Output 정답률이 떨어지는 것이 학습률 저하의 주요 원인인 듯 하다.
주 분야가 Computer Vision이 아니고, 현재 자율주행을 위한 3D Detection을 공부하고 있어, 이 학습과 공부는 여기서 마친다. 시간이 된다면 Detectron과 Fast R-CNN 모델 공부를 더 하려고 한다.