본격적으로 Faster-RCNN을 구현하기 전에,
용어 정리부터하고 가자:
RPN (Region Proposal Network): CNN 모델로, 객체가 있을만한 영역을 예측하는 용도로 사용. (object localization에 활용)
Faster RCNN 아키텍처
핵심요소: RPN, end-to-end
이 FurkanOM 깃헙이 구현할만한 소스인 것 같다.
github.com/FurkanOM/tf-faster-rcnn
FurkanOM/tf-faster-rcnn
Tensorflow 2 Faster-RCNN implementation from scratch supporting to the batch processing with MobileNetV2 and VGG16 backbones - FurkanOM/tf-faster-rcnn
github.com
Table of Contents
파악해야할 소스 10개 내외
top-down 방식으로 파악해보자. 가장 먼저 볼 코드는 전체 wrapper인 faster_rcnn_trainer.py이다.
1-1. configuration [1, 22]
라인 | 내용 | dependency |
[1, 4] | 필요한 모듈 임포팅 | utils, models |
[6, 8] | args 불러오고 gpu로 돌리는 거 가능한지 확인 | io_utils |
[10, 15] | constants 설정 (args.backbone 사용) | io_utils |
[17, 20] | mobilenet_v2 or vgg16 선택 | models |
[22] | 하이퍼 파라미터 불러오기 | train_utils |
1-2. prepare input data [24, 50]
라인 | 내용 | dependency |
[24, 27] | 훈련 및 검증 데이터 불러오기, item 개수는 이후 step size에 활용됨 (default: voc 2007) -> X 데이터 | data_utils.get_dataset 등 |
[29, 33] | voc 2012의 경우, 데이터 불러오기 | data_utils |
[35] | labels 불러오기 -> Y 데이터 | data_utils.get_labels |
[37] | backbone의 hyper-parameter 말고 현재 데이터에 맞게 설정 | line [22] |
[39, 41] | 전처리 (사이즈 조정 등) | data_utils.preprocessing |
[43, 46] | 데이터 사이즈 파악하고 패딩 입히기 | data_utils |
[48, 50] | 앵커 생성, 데이터와 앵커 매핑 (frcnn에 feed될 형식으로 완성됨) |
bbox_utils, train_utils |
1-3. modeling [52, 80]
라인 | 내용 | dependency |
[52] | rpn model 로딩 | 라인 [18] 혹은 [20] |
[53] | frcnn model 객체 생성 | models.faster_rcnn |
[54, 56] | 모델 컴파일 및 초기화 | models.faster_rcnn |
[59, 62] | rpn 사전훈련된 거 있으면 가중치 가져오기 (optional) | 라인 [12], io_utils |
[64, 67] | frcnn model 경로 불러오고, 가중치 불러올 수 있으면 가져옴 | io_utils, models.faster_rcnn |
[68, 71] | 각종 콜백 정의 | io_utils, ModelCheckpoint |
[73, 80] | 모델 스텝 정의 및 훈련 실시 | train_utils.get_step_size |
이제 각종 utils에 대해서 알아보자. (순서: io_utils, data_utils, bbox_utils, train_utils)
함수 5개 정의됨
2-1. get_log_path 함수 [1, 15]
라인 | 내용 |
[1, 4] | 각종 모듈 임포팅 |
[7, 14] | 텐서보드에 로그 그릴 목적인 함수 인자 설명, (1) 모델은 rpn 혹은 faster_rcnn (2) 백본: vgg16 혹은 mobilenet_v2 (이하 생략) |
2-2. get_model_path 함수 [17, 29]
h5 파일이 있는 경로를 반환하는 함수
(만약 "trained"라는 폴더가 없으면 만들어줌)
2-3. handle_args 함수 [31, 43]
cmd 아규먼트 파싱해주는 함수 (gpu, backbone을 설정해줌)
2-4. is_valid_backbone 함수 [45, 50]
assert condition
조건이 참이 아니라면 AssertionError을 발생시킨다.
즉, backbone은 vgg16이거나 mobilenet_v2 둘 중에 하나여야 한다.
2-5. handle_gpu_compatibility 함수 [52, 59]
gpu 호환성 검사하는 함수, 에러 발생하면 print해줌
총 12개 함수 있음
3-0. 필요한 모듈 임포팅 [1, 5]
모듈 임포팅하는 라인 [1, 5]에서 다른 특별할 것은 없는데
라인 [3]의 tfds는 voc 데이터셋을 이미 제공하고 있다, (아래 링크 참고)
faster_rcnn_trainer.py 라인[25]에서 "voc/2007" 데이터를 불러오는데, 다음과 같은 형태로 로딩된다.
3-1. preprocessing 함수 [7, 29]
말 그대로 전처리하는 함수이다. 이미지와 타겟 사이즈를 입력값으로 주면 해당 사이즈로 만들고, 해당 이미지에 매핑된 바운딩박스와 레이블을 반환함. 데이터 증강이나 평가도 가능함.
3-2. get_random_bool 함수 [31, 36]
랜덤한 불리언 값 반환함, 아래 randomly_apply_operation 함수에 활용됨
3-3. randomly_apply_operation 함수 [38, 52]
인자: 호출할 수 있는 함수, 이미지, 정답 박스
tf.cond | TensorFlow Core v2.4.1
tf.cond(pred, true_fn=None, false_fn=None, name=None) 참이면 true_fn 반환, 거짓이면 false_fn 반환
3-4. flip_horizontally 함수 [54, 68]
말 그대로 수평으로 돌림 (이미지뿐만 아니라 정답 박스도)
3-5. get_dataset 함수 [70, 82]
tsdf에서 테이터셋 불러와줌 (voc 2007, voc 2012 등)
3-6. get_total_item_size 함수 [84, 95]
주어진 split (i.e. train 혹은 validation)으로 요소들의 개수를 반환해줌. (step size를 알기 위해 필요한 preliminary 정보)
3-7. get_labels 함수 [97, 104]
wrapper 파일 (faster_rcnn_trainer.py) 라인 [35]에서 레이블을 얻기 위해 사용됨.
3-8 & 3-9. get_custom_imgs & custom_data_generator 함수 [106, 136]
tensorflow dataset에서 가져오지 않고 따로 커스텀 데이터를 불러오는 경우 사용하는 함수
3-10 & 3-11 & 3-12. get_data_types & get_data_shape & get_padding_values 함수
각각 가져오라는 거 가져와주는 함수 (데이터 타입, 데이터 모양, 패팅 값)
약간 기타 잡동사니 함수 느낌
함수 8개
4-1. generate_base_anchors 함수 [3, 21]
임포트하는 것은 tensorflow뿐이다.
generate_anchors 함수를 완성시키기 위해 사용되는 재료 함수. 일단 기본 앵커 만들어주는 함수이다.
하이퍼 파라미터에 들어있는 이미지 사이즈, 앵커 ratios 및 scales가 활용된다.
4-2. generate_anchors 함수 [23, 46]
주어진 이미지의 하이퍼파라미터대로 모든 앵커 박스를 만들어주는 함수.
[line 36] tf.cast("조건"): 조건에 대해 True면 1, False면 0을 반환함
[line 38] tf.meshgrid: 2차원 또는 삼차원 변수의 격자점 좌표를 생성하는 명령어
[line 40] tf.stack(values, axis=0, name='stack'): Stacks a list of rank-R tensors into one rank-(R+1) tensor
[line 46] tf.clip_by_value(t, clip_value_min, clip_value_max, name=None): Clips tensor values to a specified min and max. 텐서에서 clip_value_min 보다 작은 값은 clip_value_min이 되고, clip_value_max 보다 큰 값은 clip_value_max이 됨. 즉, 정한 최소값 최대 값 사이 바깥의 값은 짜른다.
4-3. non_max_suppression 함수 [48, 70]
내부 알고리즘 같은 자세한 내용은 tf.image.combined_non_max_suppression | TensorFlow Core v2.4.1 참고.
NMS 적용해주는 함수.
cf> *args 파라미터를 몇 개 받을지 모르는 경우 사용하고 형태는 튜플; **kwargs: keyword arguments의 줄임말, 딕셔너리 형태
4-4. get_bboxes_from_deltas 함수 [72, 96]
models.faster_rcnn.py에서 활용됨.
anc 는 anchor의 줄임말, ctr는 center의 줄임말.
[line 81] The ellipsis (three dots) indicates "as many ':' as needed". This makes it easy to manipulate only one dimension of an array, letting numpy do array-wise operations over the "unwanted" dimensions. (ScyPy Cookbook Indexing)
[line 86] tf.exp: Computes exponential of x element-wise. e^x. e denotes Euler's number and is approximately equal to 2.718281.
4-5. get_deltas_from_bboxes 함수 [98, 124]
[line 119] tf.where(condition, x=None, y=None, name=None): Return the elements where condition is True (multiplexing x and y). tf.where | TensorFlow Core v2.4.1
[line 119] tf.math.equal(x, y, name=None): Returns the truth value of (x == y) element-wise.
[line 119] tf.zeros_like(input, dtype=None, name=None): Creates a tensor with all elements set to zero. 받은 인풋과 같은 크기로 0으로 이루어진 텐서를 만들어줌.
[line 119] tf.math.truediv(x, y, name=None): Divides x / y elementwise (using Python 3 division operator semantics).
[line 121] tf.math.log(x, name=None): Computes natural logarithm of x element-wise.
4-6. generate_iou_map 함수 [126, 150]
배치마다 IoU (Intersection over Union) 계산. gt는 ground_truth의 줄임말.
[line 135] tf.split(value, num_or_size_splits, axis=0, num=None, name='split'): 바운딩박스들(bboxes)을 자동의 축(axis=-1)에 따라 4개씩 잘라라.
[line 141] tf.transpose(a, perm=None, conjugate=False, name='transpose'): 예시 perm=[0, 2, 1] 참고
x = tf.constant([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
# x.shape=(2, 2, 3)
tf.transpose(x, perm=[0, 2, 1])
# <tf.Tensor: shape=(2, 3, 2), dtype=int32, numpy=
# array([[[1, 4],
# [2, 5],
# [3, 6]],
# [[7, 10],
# [8, 11],
# [9, 12]]], dtype=int32)>
4-7 & 4-8. normalize_bboxes & denormalize_bboxes 함수 [152, 182]
정규화(normalize) 함수는 0-1 사이의 값으로 만들어주고, 비정규화 함수는 원래의 값으로 돌려준다
함수 9개
5-0. configuration
필요한 모듈 임포팅. 여기서 주목할 점은 bbox_utils를 사용한다는 점이다. 또한 RPN은 vgg16 혹은 mobilenet_v2에 따라 feature map의 크기가 다르다.
5-1. get_hyper_params 함수 [20, 42]
동적으로 하이퍼파라미터를 생성한다.
5-2. get_step_size 함수 [44, 52]
총 아이템 개수와 배치 사이즈를 알아서 스텝 사이즈를 구한다. (단순히 나누는 작업이다.)
5-3. randomly_select_xyz_mask 함수 [54, 69]
아래의 calculate_rpn_actual_outputs 함수에 활용되는 서브 함수.
[line 64] tf.random.uniform(shape, minval=0, maxval=None, dtype=tf.dtypes.float32, seed=None, name=None): Outputs random values from a uniform distribution.
[line 65] tf.cast(x, dtype, name=None): Casts a tensor to a new type.
5-4. faster_rcnn_generator 함수 [71, 86]
Removing Duplicate Images (0) | 2021.05.04 |
---|---|
Faster RCNN (PyTorch implementation) (0) | 2021.04.22 |
Weakly Supervised Learning (0) | 2021.04.19 |
Bank Check OCR (0) | 2021.04.19 |
RCNN Miscellaneous Repository (0) | 2021.04.15 |