개인적으로 읽고 쓰는 공부용 리뷰입니다.

틀린 점이 있을 수도 있으니 감안하고 읽어주세요. 피드백은 댓글로 부탁드립니다.

paper overview

  • 논문링크 : paper link
  • CVPR 2022
  • convnet + transfomer
  • cnn과 transformer의 장점을 적절히 섞으면서 성능향상을 이끌어 냄

Abstract

transformer가 대부분의 downstream task에서 sota찍고 날라다니지만 CNN 아직 죽지않았다. 심폐소생술 가능하다. 보여주겠다. 

1. Introduction

  • CNN은 sliding window” 전략을 택한다.
  • VIT의 주요한 포인트는 큰 데이터와 큰 모델의 "scaling"
  • 이 둘을 잘 조합한게 swin transformer
  • convolution의 본질은 여전히 살아있으며 아직도 중요하다.
The essence of convolution is not becoming irrelevant; rather, it remains much desired and has never faded.
  • 이를 증명하기 위해서 resnet에 transfomer의 특징을 하나씩 적용해가며 성능을 끌어올린다.
How do design decisions in Transformers impact ConvNets’ performance? 

2. Modernizing a ConvNet: a Roadmap

사실 상 이 그림이 이 논문의 전부를 표현함. 일단 x축은 imagenet 성능을 나타내고 y축은 적용한 방법이다. 남색 막대는 resnet50의 성능이고 회색바는 resnet200의 성능이다. 별은 resnet50의 GFLOPs를 의미한다. 

조금 더 부연설명하자면 vanilla resnet50의 성능은 78.8이고 여기에 stage ratio 를 적용했을 때, 79.4로 성능향상 0.4GFLOPs 증가인 것이다. 거기에 추가로 patchify stem을 적용했을 때 추가로 79.5까지 성능이 증가된 것이다. 빗금 쳐진 Kernel size 9, 11은 채택되지 않은 방법을 의미한다. 


논문의 나머지는 이제부터 78.8에서 82.0까지  성능을 끌어올린 각각의 세부 기법들에 대해서 설명한다.

 

2.1. Training Techniques

사실 resnet이 처음 나왔을 때에 비해 현재는 많은 학습 방법들이 생겨났다. optimizer, scheduler, augmentation 등등.

그렇기 때문에 초기 resnet에 단순히 최신 학습 기법들만 적용해도 성능은 향상할 것이다. 

왼쪽 table처럼 학습을 했을 때 모델은 기존 성능은 76.1에서 78.8로 향상한다. ConvNeXt모델은 여기서부터 시작한다.

2.2. Macro Design

Changing stage compute ratio : resnet의 기존 convbolck 구조 (3,4,6,3)에서 swin transformer처럼 (3,3,9,3)으로 바꿨더니 79.4로 성능 향상. ( Swin-T, on the other hand, followed the same principle but with a slightly different stage compute ratio of 1:1:3:1)

Changing stem to “Patchify” : Resnet은 처음에 7by7 conv with s=2 적용하고 maxpool 때려서 초기에 1/4로 featuremap 크기를 줄이는데 이 방식을 transformer의 patch 처럼 바꿔서 적용한다. ( We replace the ResNet-style stem cell with a patchify layer implemented using a 4×4, stride 4 convolutional layer. ) 성능은 79.5로 향상


2.3. ResNeXt-ify

  • Resnet을 ResNeXt처럼 변경. depthwise conv와 3x3 group conv 적용. ( ResNeXt employs grouped convolution for the 3×3 conv layer in a bottleneck block. Depthwise conv is similar to the weighted sum operation in self-attention. )
  • SwinTransformer와 같은 width를 가지도록 채널을 96으로 증가 ( we increase the network width to the same number of channels as Swin-T’s (from 64 to 96). ) 
  • 성능은 80.5로 향상

2.4. Inverted Bottleneck


(a) is a ResNeXt block
(b) is an inverted bottleneck block
  • Transformer block is that it creates an inverted bottleneck. MLP block is four times wider than the input dimension. 
  • depthwise conv에서 연산량이 증가하긴 하지만 downsampling convlayer에서 연산량이 많이 줄어들어서 전체 연산량은 줄어들었음.
  • 성능은 80.5에서 80.6으로 향상

2.5. Large Kernel Sizes

Moving up depthwise conv layer  
아까 b처럼 바꿨던 부분을 transformer처럼 3by3 conv부분을 위로 올려서 적용.
당연히 연산량도 엄청 줄어들고 성능도 79.9로 감소

Increasing the kernel size : conv layer를 위로 올려서 생긴 연산량 및 성능 감소를 보완하기 위해 3by3대신 보다 큰 kernel을 사용 5~11까지 사용해봤는데 7by7 conv를 적용했을 때 80.6으로 연산량과 성능에서 제일 좋았음. -> 7by7 선택


2.6. Micro Design

Replacing ReLU with GELU    
왼쪽 그림처럼 ReLU가 사용 되는 부분을 GELU로 변경. GELU는 다양한 transformer에서 사용 됨

GELU, which can be thought of as a smoother variant of ReLU, is utilized in the most advanced Transformers, including BERT and GPT-2 and, most recently, ViTs.

성능은 똑같이 80.6

Fewer activation functions

Transformers have fewer activation functions compared to ResNet.
There is only one activation function present in the MLP block.

transformer는 MLP block내에서 하나의 활성화 함수만 가지기 때문에 이것도 똑같이 처리함.

성능은 81.3으로 향상. 
( 이 부분이 많은 성능 향상을 가져왔는데 분석이 없어서 아쉬움. )

Fewer normalization layers : transformer block은 activation 함수처럼 normalization layer도 1개만 갖기 때문에 맨위 BN 빼고 아래 두 BN을 삭제. 성능은 81.4로 향상.

Substituting BN with LN : 마찬가지로 transformer block은 LN을 사용하기 때문에 1개 남은 BN을 LN으로 교체. 81.5로 성능 향상

Separate downsampling layers : resnet은 downsampling을 3x3 layer에서 stride 높여서 처리했는데, swin은 이부분을 나눠서 처리함. 이처럼 똑같이 독립시켜서 적용함. ( we use 2×2 conv layers with stride 2 for spatial downsampling. This modification surprisingly leads to diverged training.  Adding normalization layers at spatial resolution changes aids in training stability. ) 성능은 82.0으로 향상

이로써 최종적으로, 타겟팅한 swin transformer의 성능을 따라잡음. model scaling도 마찬가지로 resnet 200이 swin base의 성능을  뛰어 넘음.


이 뒤의 내용은 실험부분이고 주목할만한 부분은 없어서 스킵.

 

NIH Chest X-ray 14 (이하 NIH)에서 가져온 일부 데이터에 대해서 Google Health에서 새로 레이블링 진행하고 논문 쓴 고퀄리티의 dataset.

핵심 포인트

  • 위 figure에 설명 된 것처럼 초기 112,120장에서 split 별로 랜덤 샘플링 진행하고 필터링 진행 후 추가 레이블링 진행.
  • NIH Dataset의 경우 Train, validataion은 따로 구분 안 되어있는데 어떻게 했지? -> The remaining 86,524 images from 28,008 patients were randomly split into training (68,801 images) and validation sets (17,723).
  • train 13,343 + val 2,412 + test 1,962 총 17,717장 구성
  • trainset은 아쉽게도 annotation을 공개하지 않지만 validation, test는 annotation 공개. 상단 링크에서 다운로드 가능.
  • 기흉, 결절, 골절, opacity 4가지에 대해서만 레이블이 되어있음.
  • 각 영상들은 3명의 radiologists 리뷰하에 진행하고 불일치가 있을 경우 재 리뷰를 다섯번까지 진행. 그래도 안될 경우 다수결. 
  •  

'Deep Learning > 기타' 카테고리의 다른 글

vscode에서 서버 연결할 때, XHR failed  (0) 2021.08.26
coco label items  (0) 2021.08.11
Darknet validationset 학습 포함 여부  (0) 2021.07.29

개인적으로 읽고 쓰는 공부용 리뷰입니다.

틀린 점이 있을 수도 있으니 감안하고 읽어주세요. 피드백은 댓글로 부탁드립니다.

paper overview

  • 논문링크 : paper link
  • ICLR 2022
  • model ensemble

Abstract

  • model ensemble이나 cascade를 committee라고 한다.
  • 우리는 기초로 돌아가서 committee base models의 효율성을 입증한다.
  • 간단한 committee는 NAS 등의 방법을 뛰어넘는다.
  • 우리의 결과는 efficientnet, vit등에서 이를 입증한다.

1. Introduction

  • We use the term “committee” to refer to model ensembles or cascades, which indicates that they are built using multiple independent models.
  • independently pre-trained models to build ensembles or cascades.
  • Ensemble multiple pre-trained models via a simple average over their predictions.
  • Cascades, we sequentially apply each model and use a simple heuristic to determine when to exit from the cascade.
  • We summarize our findings as follows:
    • Ensembles are more cost-effective than a single model in the large computation regime.
    • Cascades outperform single models in all computation regimes.
    • Committee based models" can be applied to various tasks, including not only image classification but also video classification and semantic segmentation.

2. Related Works

별 내용 없어서 pass

3. ENSEMBLES ARE ACCURATE, EFFICIENT, AND FAST TO TRAIN

  • 총 계산량이 제한되어 있을 때, 가장 높은 성능을 내는 것은 단일 모델인가 앙상블인가?
    실제 리얼 월드에서는 굉장히 중요하지만 이것을 다루는 연구는 거의 없다.
  • 그래서 우리가 한다. imagenet에서 efficientnet, resnet, mobilenetv2를 사용한다.
  • Figure 2에 단일 모델과 앙상블 및 cascade 성능을 보여준다. 조합이 많이 나올 수 있기 때문에 Pareto optimal ensembles만 보여준다.
  • 검정 네모 박스가 단일 모델 빨강 파랑 초록 네모박스가 앙상블 별이 cascade.
  • 앙상블은 작은 모델에선 조금 뒤쳐지지만 큰 모델에서는 단일 대비 좋은 성능을 보인다.
  • cascade는 전체적으로 단일 모델 대비 성능 연산속도에서 더 좋은 경향을 보인다. 여기서 cascade는 각 앙상블을 다이렉트로 변환한 것.
  • 대체로 앙상블이 작은 모델(or 적은 연산량)에서는 효율적이지 못한 모습을 보이는데 논문에서는 이를 두고 큰 모델은 작은 바이어스 및 큰 분산을 갖게 되는데 test err은 보통 분산의 영향이 크기 때문이라고 주장. 그렇기때문에 앙상블은 분산을 줄여주어 큰 연산에서 효율적이다라고 주장. 이 부분은 잘 이해가 안감

 

4. FROM ENSEMBLES TO CASCADES

  • 모델 cascade 방법 그냥 n개의 모델을 순차적으로 처리. 출력은 모두 평균내면서.
  • 만약 threshold보다 넘어가면 ealry exit 진행 -> 이로 인해 앙상블보다 평균 flops가 낮아짐
  • 만약 모든 모델을 통과했다면 앙상블과 같아짐.

4.1 CONFIDENCE FUNCTION

  • The higher g(α) is, the more likely the prediction α is correct.
  • max, the gap between the top-2 logits or prob, negative entropy 등등 해보고 결과 출력한게 figure 3.
  • All the metrics demonstrate reasonably good performance.
  • We adopt the maximum probability metric.
  • Threshold 별 연산량 및 정확도를 나타낸 cascade. t=1 일때 앙상블이랑 같으므로 연산량이 제일 많음
  • 그렇기 때문에 t가 커질수록 연산량도 많아짐.
  • 연산량 대비 정확도는 t가 커질수록 수렴하기 때문에 적당한 위치에서 고르면 됨.

4.2. CONVERTING ENSEMBLES TO CASCADES

  • 이제 뭐 바로 이해 될텐데, family 내 한단계 낮은 모델의 cascade와 단일 모델을 비교한 것. 정확도를 비슷하게 유지하면 속도가 빨라지고, 반대로 flops를 비슷하게 유지하면 정확도가 향상 된다. ( 모든 케이스에서 그러하다는 것에 주목)

5.MODEL SELECTION FOR BUILDING CASCADES

  • 모델 선정은 별거 없음 그냥 가능한 조합 중 Accuracy랑 flops 계산하여 적절하게 선정
  • 아래 테이블은 worst case를 고려해서 연산량이 기준치 안으로 오게 선정한 것.

  • self cascade. Test time augmentation을 cascade에 적용해본 것.

  • semantic segmentation with cascade. 
  • cityscapes 같은 경우 찾기 쉬운 road class도 있고 찾기 어려운 신호등도 있는데 연산량을 위해 grid 단위로 설정 512 일 경우는 1024/512 * 2046/512 = 8개의 grid로 설정

개인적으로 읽고 쓰는 공부용 리뷰입니다.

틀린 점이 있을 수도 있으니 감안하고 읽어주세요. 피드백은 댓글로 부탁드립니다.

paper overview

논문이라기보다는 technical report에 가깝지만 내용이 재밌어서 가져왔다. 주 내용은 제목 그대로 "작은 모델들 앙상블 하는 것이 큰 모델 보다 효과적이다" 라는 것이다. 증명을 위해 cifar와 imagenet으로 실험을 진행했으며, 각 데이터셋에 wide resnet, efficientnet을 사용한다. 사실 내용은 크게 볼 것 없지만 google reseach길래..

Abstract

  • 모델 앙상블이 하나의 모델보다 속도도 빠르고 더 정확하다. 심지어 이 차이는 모델의 사이즈가 점점 커질수록 크다.
  • cifar10이랑 imagenet에서 검증한다.
  • 하나의 거대 모델을 튜닝하는 것보다는 모델 앙상블 하는 것이 trade-off에서 더 유연하다. 

1. Introduction

  • 일반적으로 모델의 파라미터 수를 증가시켜면 동일한 파라미터나 연산 수의 앙상블보다는 좋을 것이라고 예상함 ( 오버피팅 제외) 왜냐하면, 모델 앙상블은 하나의 거대 모델보다 less connectivity하기 때문이다.
  • 단일 모델보다 적은 연산 량으로 더 높은 정확도를 보이는 앙상블을 찾는 것을 보여준다.
  • 이를 위해 우리는 cifar에는 wide-resnet을, imagenet에는 efficientnet을 활용한다.
  • NAS를 통해 다양한 조합을 시도해봤지만 같은 구조의 모델 앙상블 보다 더 나은 방법을 찾기 못했다.
  • 다양한 구조를 활용하는 것은 더 나은 방법 ( NAS 보다)을 사용하거나 차라리 단일 모델을 튜닝하는 것이 낫다. 

2. Approaches and Experiments

  • 앙상블 할 때 같은 구조를 독립적으로 학습한다. 
  • 각 모델의 출력은 기하 평균으로 계산. (element-wise 곱의 제곱근으로 계산)

2.1. Image Classification on CIFAR-10

  • wide resnet family 선정, 8개씩 각각 학습
  • n=16 ( WRN 논문 기준 N=2), k = {1,2,4,8}, image size 32x32. 
  • 오버피팅 방지 위해 작은 모델 사용.

  •  파란선은 wrn 16-1을 사용하여 1~8개씩 앙상블 한 결과를 보여줌. 노란선 ~ 빨간선도 마찬가지.
  • 초록색 3 즉 wrn16-4 3개가 wrn 16-8 1개보다 높은 성능을 보이며 더 적은 연산량을 가짐. 하지만 파란거 3보다 주황색1이 조금더 높은 성능을 보임. 즉 Abstract에서 말한 "this gap in im- provement widens as models become large." 것이 이 부분.

WRN 구조 기본적으로 4개의 conv layer를 갖고 N이 커질수록 6개씩 커짐 즉 6N+4 의 개수를 가지며 k는 conv block의 width를 의미.

2.2. Image Classification on ImageNet

  • efficientnet b0~b7 사용. 3개씩 각각 학습.
  • 오버피팅 효과를 더 잘보기위해 autoaugment, randaugment등 사용하지 않음.

3. Result

  • 모델 크기가 작을 땐 앙상블의 효과가 적어 보일 수 있지만 모델이 커질수록 앙상블의 효과를 확실히 볼 수 있다.
  • 어쨌든 앙상블이 가능한 상황이라면, 하나의 모델을 짜내는 것보다 앙상블이 효과 적이다.
  • 단순히 같은 모델들의 학습 및 앙상블 보다 다양한 구조를 사용하면 더 좋을 것 같아서 NAS 써봤지만 효과 못 봤다.

Save

torch.save(model.state_dict(), PATH)

보통 torch.save를 사용해서 pytorch model을 저장하는데 이때 보통 .pt, .pth의 확장자를 쓴다. 그러나 .pth의 경우 python path와 충돌 위험이 있기때문에 .pt 확장자를 사용하는 것을 추천한다. 

Save for resume

torch.save({
            'epoch': epoch,
            'model_state_dict': model.state_dict(),
            'optimizer_state_dict': optimizer.state_dict(),
            'loss': loss,
            ...
            }, PATH)

일반적으로 모델을 저장할 때 학습 재개(resuming)를 위해 모델 파라미터 뿐만 아니라 optimizer, loss, epoch, scheduler등 다양한 정보를 함께 저장한다. 그래서 이러한 checkpoint는 모델만 저장할 때에 비해서 용량이 훨씬 커진다. 이럴때는 .tar 확장자를 사용한다. 나는 주로 .pth.tar를 사용한다.

To save multiple components, organize them in a dictionary and use torch.save() to serialize the dictionary. A common PyTorch convention is to save these checkpoints using the .tar file extension.

reference

예전에 vscode-ssh로 서버에 연결하려고 할 때, XHR failed가 뜨면서 문제가 됐던적이있다.

검색해보니 DNS문제 등등 다양한 문제가 원인이 될 수 있었는데,

내 경우는 서버가 인터넷에 연결이 안되어있어서 필요한 vscode-server를 다운받지 못해 발생하는 문제였다.

그래서 정말 다양한 방법을 시도해봤는데 결국 포기했다가 아래 링크를 찾았다. 

https://stackoverflow.com/questions/56671520/how-can-i-install-vscode-server-in-linux-offline

ssh 연결할때 뜨는 커밋 아이디가 있는데

위 이슈에 있는 링크에서 해당 커밋아이디의 파일을 다운받고

~/.vscode-server/bin/(commid id) 폴더에 해당 파일은 unzip하니 해결됐다

디테일한 명령어는 위 링크대로 따라했고 연결에 성공했다.

'Deep Learning > 기타' 카테고리의 다른 글

[Dataset] NIH Google  (0) 2024.05.24
coco label items  (0) 2021.08.11
Darknet validationset 학습 포함 여부  (0) 2021.07.29

개인적으로 읽고 쓰는 공부용 리뷰입니다.

틀린 점이 있을 수도 있으니 감안하고 읽어주세요. 피드백은 댓글로 부탁드립니다.

[TensorRT] 1. Build tensorrt engine (tensorRT 7.2.3)


Serializie는 나중에 재사용을 위해 저장하기위한 포맷으로 바꾸는 것을 의미한다. inference에 사용하기 위해서는 그냥 deserializie한 뒤 쓰면 된다. 보통 빌드과정이 시간을 소요하기 때문에 매번 빌드하는 것을 피하기 위해 이 과정을 한다.

// code for serializing ICudaEngine
IHostMemory *serializedModel = engine->serialize();
// store model to disk
// <…>
 serializedModel->destroy();

-

Deserialize code, The final argument is a plugin layer factory for applications using custom layers. For more information, see [Extending TensorRT With Custom Layers]
별거아니고, 마지막에 nullptr는 iplugin for custom layer인데 없다면 그냥 nullptr넣으면 된다.

// code for deserializing ICudaEngine
IRuntime* runtime = createInferRuntime(gLogger);
ICudaEngine* engine = runtime->deserializeCudaEngine(modelData, modelSize, nullptr)

주의 할점은 trt version, gpu, platform을 항시 잘 체크해야한다.

  • Serialized engines are not portable across platforms or TensorRT versions.
  • Engines are specific to the exact GPU model they were built on.

 

위에는 tensorrt reference의 코드인데 처음에보고 어떻게 더 추가해야할지 몰라서 막막했다.
아래는 실제로 내가 사용하는 serializing & save 코드다.

여기서 engine_ 은 빌드가 성공적으로 된 ICudaEngine이다.

bool saveEngine( std::string &fileName ) const 
{
    std::ofstream engineFile( fileName, std::ios::binary );
    if ( !engineFile ) {
        gLogFatal << "Cannot open engine file : " << fileName << std::endl;
        return false;
    }

    if ( engine_ == nullptr ) {
        gLogError << "Engine is not defined" << std::endl;
        return false;
    }
    nvinfer1::IHostMemory *serializedEngine{engine_->serialize()};
    if ( serializedEngine == nullptr ) {
        gLogError << "Engine serialization failed" << std::endl;
        return false;
    }

    engineFile.write( static_cast<char *>( serializedEngine->data() ),
                      serializedEngine->size() );
    if ( engineFile.fail() ) {
        gLogError << "Failed to save Engine." << std::endl;
        return false;
    }
    std::cout << "Successfully save to : " << fileName << std::endl;
    return true;
}

 

다음은 저장된 ICudaEngine을 load후 다시 deserializing하는 코드다. 

bool Load( const std::string &fileName ) {
    std::ifstream engineFile( fileName, std::ios::binary );
    if ( !engineFile ) {
        std::cout << "can not open file : " << fileName << std::endl;
        return false;
    }
    engineFile.seekg( 0, engineFile.end );
    auto fsize = engineFile.tellg();
    engineFile.seekg( 0, engineFile.beg );

    std::vector<char> engineData( fsize );
    engineFile.read( engineData.data(), fsize );

    Load( engineData.data(), ( long int )fsize );
    return true;
}

bool Load( const void *engineData, const long int fsize ) {
    nvinfer1::IRuntime *runtime = nvinfer1::createInferRuntime( gLogger.getTRTLogger() );
    engine_ = runtime->deserializeCudaEngine( engineData, fsize, nullptr );
    // if u want DLA core setting, then u shoud write code here
    runtime->destroy();
    return true;
}

두가지 방법으로 load할수있어서 오버로딩해놨다.

끝 

'Deep Learning > tensorrt' 카테고리의 다른 글

[TensorRT] 1. Build tensorrt engine (tensorRT 7.2.3)  (6) 2021.03.24

coco label 얻기

ids = list(sorted(coco.imgs.keys()))
coco_idx = [ids[idx]]  # from index to coco_index
coco.loadAnns(self.coco.getAnnIds(coco_idx))

아래처럼 object별로 7개의 key값을 가짐

segmentation은 annotation type이 두개가있다.
segmentation1 : list[float], polygon 좌표 xy인데 flatten시켰다. 
segmentation2 :  a run-length-encoded (RLE) bit mask 
    'counts' :
    'size'     :

area : 객체 안에 속한 pixel 수

iscrowd :  0 또는 1, 1이면 정확도 측정할 때 제외함 

image_id : 현재 객체가 속한 image의 index, 그래서 같은 이미지에 있는 객체들은 값이 같음. (82783: coco2014train)

bbox : bounding box 좌표, 좌상단xy wh로 구성되어있으며 normalizing 안되어있음

category_id : ojbect의 class index 총 80개며 1~90사이의 값을 가짐

id : 각 object에 대한 id인데 어떻게 라벨링 되는지는 모르겠음.

 

아 category_id가 좀 다를 것이다 0~79의 80개 class가 아니라 1~90으로 나온다. 몇개 삭제된 클래스가 있다. 아래 tuple써서 치환(?)하면 됨
(255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 255, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 255, 24, 25, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 255, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 255, 60, 255, 255, 61, 255, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 255, 73, 74, 75, 76, 77, 78, 79)

 

https://github.com/cocodataset/cocoapi/issues/184

https://github.com/facebookresearch/Detectron/issues/100

https://www.immersivelimit.com/tutorials/create-coco-annotations-from-scratch

https://www.youtube.com/watch?v=h6s61a_pqfM 

 

'Deep Learning > 기타' 카테고리의 다른 글

[Dataset] NIH Google  (0) 2024.05.24
vscode에서 서버 연결할 때, XHR failed  (0) 2021.08.26
Darknet validationset 학습 포함 여부  (0) 2021.07.29

 

링크 : darknet pretrained weights with MS-COCO detection dataset

틈틈히 작업하던 yolo to pytorch가 완성단계라 위 링크 weights들의 정확도를 재생산하는 것을 통해 검증하려고 하는데 validationset에 대한 결과가 이상하리만큼 높게 나오는 것을 발견했다.

yolov4 같은 겨우 width=608 height=608 in cfg: 65.7% mAP@0.5 (43.5% AP@0.5:0.95)  라고 적혀 있는데 (testset기준) 

coco 2017 validationset(5k)로 직접 evaluation 했더니

 Average Precision  (AP) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.500
 Average Precision  (AP) @[ IoU=0.50       | area=   all | maxDets=100 ] = 0.741

 

이 나왔다. 위 결과는 testset(40k)일테니 낮은건 이해하지만 유난히 높게 나왔다는 생각이 들어 조금 알아봤다.

 

왜 유난히 높다라는 생각이 들었냐면, 후속논문인 sclaed yolov4 에서 validationset을 통해 측정을 한 결과가 다음과 같다. yolov4-P5경우 896x896 이미지를 사용했는데 51.7 / 70.3 (아래 테이블 참조)이다. 따라서 위에서 yolov4로 돌린 결과가 이상하다고 볼 수 있다. 

 

첫번째로 yolov4를 학습할 때, validationset이 포함됐나?를 떠올렸다. 그러면 높은 결과가 이해가 되니까.

그러나 darknet 위키를 찾은결과 학습에는 분명히 validation 5k를 제외하고 학습이 되었다. 정말 이상해서 더 자료를 찾다가 원하는 내용의 issue를 찾았다.

The custom splits (trainvalno5k.txt and 5k.txt) for COCO 2014 are supposed to be the same as the default splits for COCO 2017 but they are not. This could explain why YOLOv4 does not produce the same validation results on both but a significantly better mAP on val2017. Also, this implies YOLO may be trained on a different training set compared with other object detectors. Then a direct comparison might not be fair. Any clarifications?

즉 coco2017과 darknet에서 쓰는 split (train, val, test)가 다르다. 이것은 trainset이 다르단 소리고 결과가 불공정하지않냐? 라는 질문이다.

그러면서 coco2014와 2017의 차이점도 친절하게 official에서 긁어놨다.

The only difference is the splits which COCO 2017 adopts as the long-ime convention from COCO 2014 in early object detection work. The detectron repo explicitly describes the COCO Minival Annotations (5k) as follows:

Our custom minival and valminusminival annotations are available for download here. Please note that minival is exactly equivalent to the recently defined 2017 val set. Similarly, the union of valminusminival and the 2014 train is exactly equivalent to the 2017 train set.

즉 2014와 2017은 이미지가 전혀 바뀐게 없고 split만 바꼈다는 것인데 다음과 같다. (valminusminival의 존재를 처음 앎;)

COCO_2017_train = COCO_2014_train + valminusminival 
COCO_2017_val = minival

거기에 대한 답은 이렇다.

- testset은 같다.
- validation이 다르지만 결국엔 똑같은 장수를 validation으로 뺐고 test는 같으니 결과는 문제없다!.
심지어 우리는 최종 weight에 5k를 빼고학습했으니 오히려 마이너스 요소가 될 수 있다. 가 답변이다.

왜 다른 split을 쓰는지는 나도 모르겠지만, test로 성능측정하려면 서버에 결과제출해야해서 귀찮은데..하 아무튼 이런 이슈가 존재한다. 

'Deep Learning > 기타' 카테고리의 다른 글

[Dataset] NIH Google  (0) 2024.05.24
vscode에서 서버 연결할 때, XHR failed  (0) 2021.08.26
coco label items  (0) 2021.08.11

개인적으로 읽고 쓰는 공부용 리뷰입니다.

틀린 점이 있을 수도 있으니 감안하고 읽어주세요. 피드백은 댓글로 부탁드립니다.

paper overview

  • 논문링크 : paper link
  • fully convolutional network 
  • encoding & decoding

2015 CVPR에 나온 논문으로([Submitted on 14 Nov 2014 (v1), last revised 8 Mar 2015 (this version, v2)]), 2021년인 지금 깊게 공부하기엔 매우 올드하지만, 이 논문은 semantic segmentation의 초석을 닦은 연구라고 생각하기때문에, 한번쯤은 짚고 갈 필요가 매우 있다고 생각한다. 이 논문의 핵심은 semantic segmentation과 fully convolution이다.  semantic segmentation은 일반적인 classification과 유사하지만 결과물만 다르다. 이미지 전체를 토대로 classification을 하는 것이 아닌 픽셀단위로 classification을 하는 것이다. imagnet dataset을 예시로 들어보자면 classification 네트워크의 경우 ouput shape가 n x 1000 이라면 segmentation의 경우라면 ouput shape가 입력과 크기가 똑같은  N x H x W x 1000이 될 것 이다. 물론 imagenet으로는 학습 못한다. segmentation용으로 레이블링 된 데이터가 없으므로.

저 그림은 voc dataset이다. 그리고 이 데이터셋은 클래스가 21개다. 그렇기 때문에 위 그림의 아웃풋의 채널이 21인 것이다. pixelwise prediction 전까지는 classification downsampling과정이랑 같다. 그러나 그 뒤에 아웃풋의 shape가 다르다. 이 차이점이다. 보통 feature를 뽑아내는 과정을 encoding이라고 하고, 이 후에 이미지 크기로 다시 복원하는 과정을 decoding이라고 한다. 위 그림에는 이 디코딩 과정이 생략된 것이다. 그리고 이 모든 과정을 convolution layer로만 네트워크를 구축했다. 그래서 논문 이름이 fully convolutional network인 것이다. 보통 classification은 마지막에 fully connected layer(fcl)이 붙는데 fcl은 고정된 크기의 인풋을 요구한다. 근데 이게 사라졌으니까, 이론적으로는 크기에 불변이다. ㅋㅋ 근데 stride가 1/2씩 떨어지고 보통 1/32까지 떨구기때문에 입력 이미지의 크기는 32의 배수로 한다. ( 아니어도 되는데 fowarding 맞추기가 귀찮다.) 

figure 2의 위쪽은 classification을 의미한다. 이 과정이 semantic segmentation으로 포함되면 아래 부분처럼 heatmap형식으로 나타나는 것을 보여주는 figure다. 

figure 3는 fcn의 전체적인 플로우다. 전체적으로 encoding 과정은 전체적으로 VGG와 같다. 풀링레이어는 풀1에서 풀5까지 다섯개의 레이어가 있다. 각각 1/2씩 해상도가 떨어져서 1/32까지 떨어진다. 컨브6,7은 기존의 fcl을 컨볼루션으로 대체한 것이다. 32x 16x 8x 4x 2x 얘네들은 upsample layer로, transposed conv를 의미한다. feature map이 겹쳐져 있는부분은 덧셈을 의미한다. 

pool5 만 사용한것이 fcn32. pool5+ pool4가 fcn 16, pool5,4,3다 쓴것이 fcn8이다 fcn뒤에 붙은것은 아웃풋 피쳐맵의 누적 스트라이드라고 생각하면 된다. 

네트워크의 stride가 커지면 더 complex한 feature를 학습할수는 있지만 spatial information이 사라지기 마련이다. fcn은 이것을 앞쪽의 feature map을 inference에서 활용하는 쪽으로 방향을 잡았고, 많은 이 후 논문들이 이러한 방식을 택하고 있다. 따라서 결과 이미지로보나 수치로보나 fcn8s가 제일 좋다. 

+ Recent posts