
DETR > Deformable-DETR > RT-DETR의 핵심 아이디어를 순서 기반으로 Review했던 글
RT-DETRRT-DETR은 Real-Time DEtection TRansformer의 약자로,
현재 DETR variants에서 가장 Real-Time한 Detector이다.
성능이 워낙 좋아서 상업적으로 많이 사용되는 YOLO Series들이 SOTA Leaderboard를 꽉 잡고 있는데,
그 중에서 DETR variants인 RT-DETR의 이름이 올라간 것을 볼 수 있다. (현재 2024.07.08 기준)



위 Table 5.의 결과가 눈에 띄었다.
column은 6개의 layer를 전체 학습시키고나서, inference 때 layer(row)까지만 forward했을 때의 결과를 나타낸다.
여기서 생각할 수 있는 것은 Decoder의 각 layer들은 약간의 성능 향상을 도와줄 뿐, 거의 대부분의 성능은 backbone & encoder에서 형성되는 듯 하다.
➡️ 따라서 "decoder의 computatoin을 많이 줄여도 성능 하락이 적을 것이다"라는 가설을 세웠다.
만약 이 가설이 맞다면, RT-DETR의 efficiency를 더욱 높힐 수 있는 여러 방법을 생각할 수 있을 것이다.
예를 들어,
(1) Decoder를 없애고 다른 효율적인 방법을 제시할 수 있다.
(2) decoder의 Object Queries 수를 동적으로 조절하여 decoder의 computation을 조절함과 동시에 성능을 유지시킬 수 있다.
(3) decoder의 layer 수를 동적으로 조절하여 decoder의 computation을 조절함과 동시에 성능을 유지시킬 수 있다.
파악한 결과,

위 1., 2.의 실험을 바탕으로 생각해볼 수 있는 것은 decoder의 computation은 이미 매우 최적화되어 있고,
다른 Transformer decoder에 비하면 computational cost가 매우 작다는 것을 알 수 있다.
그렇다면 왜 RT-DETR Decoder의 Layer들은 computational cost가 이렇게 적을까?
| module | #parameters or shape | #flops |
|:----------------------------------------|:-----------------------|:-----------|
| model | 42.891M | 68.984G |
| backbone | 23.474M | 35.321G |
| backbone.conv1 | 28.512K | 2.92G |
| backbone.conv1.conv1_1.conv | 0.864K | 88.474M |
| backbone.conv1.conv1_2.conv | 9.216K | 0.944G |
| backbone.conv1.conv1_3.conv | 18.432K | 1.887G |
| backbone.res_layers | 23.446M | 32.401G |
| backbone.res_layers.0.blocks | 0.213M | 5.453G |
| backbone.res_layers.1.blocks | 1.212M | 8.389G |
| backbone.res_layers.2.blocks | 7.078M | 11.954G |
| backbone.res_layers.3.blocks | 14.942M | 6.606G |
| decoder | 7.467M | 8.156G |
| decoder.input_proj | 0.198M | 0.555G |
| decoder.input_proj.0 | 66.048K | 0.423G |
| decoder.input_proj.1 | 66.048K | 0.106G |
| decoder.input_proj.2 | 66.048K | 26.419M |
| decoder.decoder.layers | 5.975M | 5.275G |
| decoder.decoder.layers.0 | 0.996M | 0.879G |
| decoder.decoder.layers.1 | 0.996M | 0.879G |
| decoder.decoder.layers.2 | 0.996M | 0.879G |
| decoder.decoder.layers.3 | 0.996M | 0.879G |
| decoder.decoder.layers.4 | 0.996M | 0.879G |
| decoder.decoder.layers.5 | 0.996M | 0.879G |
| decoder.denoising_class_embed | 20.736K | |
| decoder.denoising_class_embed.weight | (81, 256) | |
| decoder.query_pos_head.layers | 0.134M | 0.24G |
| decoder.query_pos_head.layers.0 | 2.56K | 3.686M |
| decoder.query_pos_head.layers.1 | 0.131M | 0.236G |
| decoder.enc_output | 66.304K | 0.561G |
| decoder.enc_output.0 | 65.792K | 0.551G |
| decoder.enc_output.1 | 0.512K | 10.752M |
| decoder.enc_score_head | 20.56K | 0.172G |
| decoder.enc_score_head.weight | (80, 256) | |
| decoder.enc_score_head.bias | (80,) | |
| decoder.enc_bbox_head.layers | 0.133M | 1.11G |
| decoder.enc_bbox_head.layers.0 | 65.792K | 0.551G |
| decoder.enc_bbox_head.layers.1 | 65.792K | 0.551G |
| decoder.enc_bbox_head.layers.2 | 1.028K | 8.602M |
| decoder.dec_score_head | 0.123M | 6.144M |
| decoder.dec_score_head.0 | 20.56K | |
| decoder.dec_score_head.1 | 20.56K | |
| decoder.dec_score_head.2 | 20.56K | |
| decoder.dec_score_head.3 | 20.56K | |
| decoder.dec_score_head.4 | 20.56K | |
| decoder.dec_score_head.5 | 20.56K | 6.144M |
| decoder.dec_bbox_head | 0.796M | 0.238G |
| decoder.dec_bbox_head.0.layers | 0.133M | 39.629M |
| decoder.dec_bbox_head.1.layers | 0.133M | 39.629M |
| decoder.dec_bbox_head.2.layers | 0.133M | 39.629M |
| decoder.dec_bbox_head.3.layers | 0.133M | 39.629M |
| decoder.dec_bbox_head.4.layers | 0.133M | 39.629M |
| decoder.dec_bbox_head.5.layers | 0.133M | 39.629M |
| encoder | 11.951M | 25.508G |
| encoder.input_proj | 0.919M | 1.472G |
| encoder.input_proj.0 | 0.132M | 0.842G |
| encoder.input_proj.1 | 0.263M | 0.42G |
| encoder.input_proj.2 | 0.525M | 0.21G |
| encoder.encoder.0.layers.0 | 0.79M | 0.398G |
| encoder.encoder.0.layers.0.self_attn | 0.263M | 0.187G |
| encoder.encoder.0.layers.0.linear1 | 0.263M | 0.105G |
| encoder.encoder.0.layers.0.linear2 | 0.262M | 0.105G |
| encoder.encoder.0.layers.0.norm1 | 0.512K | 0.512M |
| encoder.encoder.0.layers.0.norm2 | 0.512K | 0.512M |
| encoder.lateral_convs | 0.132M | 0.132G |
| encoder.lateral_convs.0 | 66.048K | 26.419M |
| encoder.lateral_convs.1 | 66.048K | 0.106G |
| encoder.fpn_blocks | 4.465M | 17.859G |
| encoder.fpn_blocks.0 | 2.232M | 3.572G |
| encoder.fpn_blocks.1 | 2.232M | 14.287G |
| encoder.downsample_convs | 1.181M | 1.181G |
| encoder.downsample_convs.0 | 0.59M | 0.945G |
| encoder.downsample_convs.1 | 0.59M | 0.236G |
| encoder.pan_blocks | 4.465M | 4.465G |
| encoder.pan_blocks.0 | 2.232M | 3.572G |
| encoder.pan_blocks.1 | 2.232M | 0.893G |
이를 취합해보면 다음과 같다.
RT-DETR은
convolution에 대한 (GFLOPs, #Params)의 비율이 전체의 (GFLOPs:85.46%, #Params:80.74%)이고,
attention에 대한 (GFLOPs, #Params)의 비율이 전체의 (GFLOPs:13.54%, #Params:19.26%)이다.
➡️ 다시 생각해보면,
RT-DETR은 DETR variants이긴하지만, CNN-based Detector인 YOLO에 더 가깝다고 충분히 생각할 수 있다.
물론 약간의 attention 연산과 convolution이 혼합되어 시너지 효과가 있을 수는 있어도,
Detector에서 더욱 우세적인 YOLO series는 거의 대부분을 conv 연산을 사용하기 때문에 전체 성능에 대한 기여량은 conv 연산이 더 많을 것이라고 볼 수 있다.
➡️ 그래서,
RT-DETR에 있는 attention computation에 대해 ablation study를 통해,
소량의 attention computation이 과연 전체 RT-DETR의 성능 향상을 얼만큼 이뤄내는지 살펴볼 것이다.
attention computation이 있는 곳은 딱 두 곳 뿐이다.
1. Encoder의 AIFI module
2. Decoder (위에서 이미 했음. Table 5.)

AIFI(Attention-based Intra Feature Interaction) Module은
Deformable-DETR에서의 단점이었던 Encoder의 input length(concat())를 줄이기 위해
backbone의 intermediate feature 만 Self-Attn 연산을 적용하는 Module이다.
AIFI는 RT-DETR의 전체 computational cost 중 2.71%만 차지한다.
과연 이 AIFI module은 RT-DETR에서 꼭 필요한 module일까?
이를 알아보기 위해,
AIFI module을 제거하여 1x schedule로 training(12 epochs)을 시켜봤다.
AIFI module을 제거했기 때문에 기존의 Multi-Scale을 fusion하는 module이었던 CCFF의 input으로 (AIFI(), , ) 대신 (, , )이 사용되었다.
w/o(=without) AIFI는 1x schedule training에서 0.7 mAP 성능 하락만 발생하였다.
앞서 RT-DETR에 대해서 6x schedule(72 epochs)로 많은 실험을 진행해본 결과,
1x(12 epochs)에서 0.7 mAP 성능 차이는 6x(72 epochs)에서 충분히 극복할 수 있을 정도의 아주아주 작은 성능 하락이다.
(6x training이었다면 최종 성능에서는 차이가 아예 없을 것으로 예상한다)
(이에 대한 근거로 아래 그림을 첨부.)
(1x에서 1.6mAP 차이가 났었지만 6x에서는 0.1mAP 차이로 극복됨.)

1.6 mAP 성능 차이
0.1 mAP 성능 차이
RT-DETR의 computational redundancy 1 :
하지만 만약에 한 image에 object가 딱 1개 있는데 300개의 set prediction을 한다면,RT-DETR의 computational redundancy 2 : 
RT-DETR의 computational redundancy 3 : 위 세가지 RT-DETR의 computational redundancy를 줄일 수 있는 나의 연구 아이디어는 다음과 같다.
backbone 또는 Encoder(AIFI)에서 image-specific한 #objects에 대해 prediction을 한다.
이는 몇 개의 set prediction을 할지에 대한 'hint'가 되고, 이 기준에 따라 adaptive computation을 구성한다.
idea 2보다 parameter와 computation은 더 많이 추가될 것 같다.
hint 정보(= predicted #objs)를 갖고, Fusion block과 decoder에 어떻게 adaptation을 적용할 것인지? Loss는 어떻게 구성해야 할지?
생각해봐야 함.
Backbone 또는 AIFI에서 예측한 object 개수로 adaptive set prediction을 할 수 있는
image-specific Adaptive RT-DETR을 만든다.