【Domain】Adversarial Discriminative Domain Adaptation = ADDA

  • 논문 : Adversarial Discriminative Domain Adaptation - y2017,c1875
  • 분류 : Unsupervised Domain Adaptation
  • 저자 : Eric Tzeng, Judy Hoffman, Kate Saenko (California, Stanford, Boston University)
  • 읽는 배경 : (citation step1) Open Componunt Domain Adaptation에서 Equ (1), (2) [the domain-confusion loss]가 이해가 안되서 읽는 논문. 근데 introduction읽다가 이해해 버렸다. 좀만 더 읽어보자.
  • 읽으면서 생각할 포인트 : 핵심만 읽자. 모든 것을 다 읽으려고 하지 말자. 영어계 저자는 어떻게 썼는지 한번 확인해 보자.

느낀점

  1. 이해 50프로 밖에 못한것 같다.
  2. 이 논문을 읽으면서, “이해안되도 아가리 닥치고 일단 Experience까지 미친듯이 읽어보자. 그리고 다시 과거에 이해는 안되지만 대충이라도 요약했던 내용을, 다시 읽어보면! 이해가 될 가능성이 높다.”
  3. 그래도 이 논문을 통해서 Adversarial 접근이 GAN의 generator와 discriminator만을 두고 얘기하는게 아니라는 것을 깨달았다. 하나는 ‘이러한 목적’을 위해 학습한다면, 다른 한쪽에서 ‘반대의 목적’을 위한 Loss로 학습하게 만드는 것들, 전부가 Adversarial learning이라는 것을 깨달았다.
  4. 하지만 나는 믿는다. 그냥 아가리 닥치고 계속 읽고 정리하고 많은 논문을 읽어가다 보면 언젠간. 언젠간. 많은 지식이 쌓여 있고, 누구에게 뒤쳐지지 않는 나를 발견할 수 있을거라는 사실을. 그니까 그냥 해보자. 좌절하지말고 재미있게 흥미롭게. 않는 나를 발견할 수 있을거라는 사실을. 그니까 그냥 해보자. 좌절하지말고 재미있게 흥미롭게.**
  5. (3)번까지 relative work다 읽느라 지쳐서 핵심적인 부분은 거의 이해도 안하고 대충대충 넘겼다. 진짜 중요한 부분이 어딘지 생각해봐라. 초반에 이해안되는거 가지고 붙잡고 늘어지기 보다는, 일단 이 논문이 제시하는 model이 구체적으로 뭔지부터 읽는 것도 좋았겠다.
  6. 헛소리 이해하려고, 핵심적인 4번 내용은 이해하지도 않았다. 솔직히 여기 있는 relative work를 언제 다시 볼 줄 알고, 이렇게 깔끔하게 정리해 놨냐. 정말 필요하면 이 직접 논문으로 relative work를 다시 읽었겠지. 그러니 **핵심 먼저 파악하고!! 쓸대 없는 잡소리 이해는 나중에 하자.**
  7. 별거도 아닌거 삐까번쩍하게도 적어놨다... 이래서 아래로 최대한 빨리 내려가서 구체적인 핵심먼저 파악해야한다.

0. Abstract

  • 현재 기술들과 문재점
    • Adversarial learning(approaches) 사용 및 효과
      • generate diverse domain data를 한 후에 improve recognition despite target domain을 수행한다.
      • 그렇게 해서 reduce the difference하고 Improve generalization performance한다.
    • 하지만 이런 generative approaches의 문제점은 - smaller shifts만 가능하다는 것이다.
    • discriminative approaches 문제점 - larger domain shifts가 가증하지만, tied(=sharing) weights, GAN-based loss를 사용하지 않는다.
  • **Ours **
    • 지금까지의 접근방법들을 잘 융합하고, 적절히 변형한다.
    • Use (별거도 아닌거 삐까번쩍하게도 적어놨다… 이래서 아래로 최대한 빨리 내려가서 구체적인 핵심먼저 파악해야한다.)
      • **(1) discriminative modeling(base models) **
      • **(2) untied weight sharing, **
      • (3) GAN loss(adversarial loss)
    • 즉 우리 것은 이것이다. general(=generalized, optimized) framework of discriminative modeling(=adversarial adaptation) = ADDA
    • SOTA 달성했다. - digit classification, object classification
    • 논문 핵심 : (Related work) Adversarial 을 사용하는 방법론들은 항상 같은 고충을 격는다. “Discriminator가 잘 학습이 되지 않는다든지, Discriminator를 사용해서 Adversarial 관점을 적용해도 원한는데로 Model이 target data까지 섭렵하는 모델로 변하지 않는다던지 등등 원하는데로 학습이 잘 이뤄지지 않는 문제점” 을 격는다. 이 논문은 많은 문제점을 고려해서 가장 최적의 Discriminator 공식과 Adversarial 공식을 완성했다고 주장한다.

1. Introduction

  • 과거의 방법론들
    • dataset bias(source만 데이터 많음 target없음) + domain shift 문제해결은 일반적으로 fine-tune으로 했었다. But labeled-data is not enough.
    • 서로 다른 feature space를 mapping 시켜주는 deep neural transformations 방법도 존재한다. 그때 이런 방법을 사용했다. maximum mean discrepancy [5, 6] or correlation distances [7, 8] 또는
    • the source representation(source를 encoding한 후 나오는 feature)를 decoder에 집어넣어서, target domain을 reconstruct하는 방법도 있다.[9] (encoding + decoding의 결과가 target data모양이 되도록. 그렇게 만든 data로 classifier 재 학습??)
  • 현재의 기술들
    • Adversarial adaptation : domain discriminator에서 adversarial objective(Loss)를 사용하여, domain discrepancy를 최소화 했다.
    • generative adversarial learning [10] : generator(이미지 생성) discriminator(generated image, real image 구별) 를 사용해서 network가 어떤 domain인지 판단하지 못하게 만든다. [10,11,12,13] 이것들의 방식은 조금씩 다르다. 예를 들어, 어디에 generator를 위치시키고, loss는 무엇이고, weight share for source&target을 하는지 안하는지 등등
  • Ours
    • 위 Ours의 (1)(2)(3)
    • discriminative representation를 학습하는게 우선이다.
    • image-20210122185525171
    • ADDA 간략히 정리하자면…
      1. Learn discriminative representation (using the labels in the source domain). -> 그냥 Source classifier 학습시키기.
      2. Learn a separate encoding through a domain-adversarial loss. (domain discriminator 학습 및 target CNN 학습시키기)

2. Related work

(이렇게 자세하게 적는게 무슨 의미지? 반성하자. 어차피 머리속에 남은것도 없고, 다시 읽어도 뭔소린지 모르고 머리에도 안남잖아. 시간버린거야.)

  • MiniMizing Difference between feature distributions.[MMD사용모델들]
    1. MMD[3] : Computes the norm of the difference between two domain means.
    2. DDC[5] : MMD in addition to the regular classification loss for both discriminative and domain invariant.
    3. The Deep Adaptation Network[6] : effectively matching higher order statistics of the two distributions
    4. CORAL [8] : match the mean and covariance of the two distributions
  • Using adversarial loss to minimize domain shift. & learning a representation not being able to distinguish between domains(어떤 domain이든 공통된 feature extractor 제작) - 2015
    1. [12] : a domain classifier and a domain confusion loss
    2. ReverseGrad[11] : the loss of the domain classifier by reversing its gradients
    3. DRCN[9] : [11]과 같은 방식 + learn to reconstruct target domain images
  • GAN - for generating - 2015
    1. G : capture distribution. D : distinguishes. (Generative Adversarial Network)
    2. BiGAN [14] : learn the inverse mapping(??) from image to latent space and also learn useful features for image classification task.
    3. CGAN [15] : generate “a distribution vector” conditional on image features. and G and D receive the additional vector.
  • GAN for domain transfer problem - 2013
    1. CoGAN [13] : generate both source and target images respectively. 이로써 a domain invariant feature space 를 만들어 낼 수 있었다. discriminator output 윗단에 classifier layer를 추가해서 학습을 시켰다. 이게 좋은 성과를 냈지만, source와 target간의 domain 차이가 심하다면 사용하기 어려운 방법이다. 하지만 쓸데없이 generator를 사용했다고 여겨진다.
  • Ours (위 figure 참조))
    1. image distribution(분포, 확률분포, generator)는 필수적인게 아니다.
    2. 진짜 중요한 것은, discriminative approach 이다.
  • 정리표 : image-20210123225939714

3. Generalized adversarial adaptation - related work

  • 우리의 학습 순서 요약

    • image-20210123225514370
    1. Source CNN 학습시키기.
    2. Adversarial adaptation 수행.
    3. Target CNN을 학습.
  • 먼저 학습시켰던 Discriminator를 사용해서, cannot reliably predict their domain label 하게 만듬으로써 Target CNN을 학습시킨다.
  • test 할 때, target encoder to the shared feature space(?) 그리고 source classifier(targetCNN도 원래는 Source CNN을 기반으로 하는 모델이므로)를 사용한다.
  • 점선은 Fixed network parameters를 의미한다.
  • (Related work) Adversarial 을 사용하는 방법론들은 항상 같은 고충을 격는다. “Discriminator가 잘 학습이 되지 않는다든지, Discriminator를 사용해서 Adversarial 관점을 적용해도 원한는데로 Model이 target data까지 섭렵하는 모델로 변하지 않는다던지 등등 원하는데로 학습이 잘 이뤄지지 않는 문제점” 을 격는다. 이 논문은 많은 문제점을 고려해서 가장 최적의 Discriminator 공식과 Adversarial 공식을 완성했다고 주장한다.
    1. 일반적인 adversarial adaptation 의 formula
    • image-20210125141320232
    1. 3.1. Source and target mappings (Mapping - Ms,Mt는 어떻게 설정해야 하는가?)
      • 목적 : mapping 신경망이 source에서든 target에서든 잘 동작하게 만들기. 각각을 위한 mapping 신경망이 최대한 가깝게(비슷하게) 만들기. source에서든 target에서든 좋은 classification 성능을 내기
      • 과거의 방법 : mapping constrain = target과 source를 위한 mapping. Ms,Mt = feature extractor = network parameter sharing
      • Ours : partial alignment = partially shared weights
    2. 3.2. Adversarial losses (위의 Loss_adv_M은 무엇으로 해야하는가?)
    • [16] image-20210125141617468 을 사용하기도 했지만, 이 방법에서 Discriminator가 빨리 수렴하기 때문에, (같이 적절하게 학습된 후 동시에 수렴되야 하는데..) 문제가 있다.
    • GAN loss function [17] image-20210125141823643 provides stronger gradients to the target mapping.(Mt는 Xt를 잘 classification 하도록 학습되면서도, D가 잘 못 판단하게 만들게끔 학습 된다. ) -> 문제점 : oscillation. 둘다 너무 수렴하지 않음. D가 괜찮아지려면 M이 망하고, M이 괜찮아 지려만 D가 망한다.
    • [12] : image-20210125142625114
      target이 들어오면, D가 잘못 판단하게끔 Mt가 학습되면서도, D가 잘 판단하게끔 Mt가 학습된다. 반대로 source가 들어오면, 또 D가 잘못 판단하게끔 Ms가 학습되면서도, D가 잘 판단하게끔 만드는 항도 있다.
    1. 이러한 고민들이 계속 있었다. Ours의 결론은 위의 정리표 참조.
    • image-20210125143353867

4. Adversarial discriminative domain adaptation

  • 사용한 objective function ⭐⭐
    image-20210125144836013
    1. 맨위 수식 : Source Dataset의 Classification을 잘하는 모델 탄생시킨다.
    2. 최적의 Discriminator 공식 : Target이 들어오면 0을 out하고, Source가 들어오면 1을 out하도록 하는 Discriminator를 만들기 위한 Loss 함수이다.
    3. 심플하게 Source 신경망은 고정시킨다. Target이미지를 넣어서 나오는 Out이 Discriminator가 1이라고 잘못 예측하게 만드는 M_t만 학습시킨다. Ms는 건들지도 않고 source가 들어갔을때, discriminator가 0이라고 잘못 예측하게 만든는 작업 또한 하지 않는다.
  • 최종 모델 학습 과정
    • image-20210125145015365
    • 헷갈리는 내용은 다시 논문 5 page ⭐⭐참조.

5. Experiments

  • 실험을 통해서 왜 논문에서 선택한 위의 objective function이 적절한 function이었는지를 말해준다.

【Domain】Open Compound Domain Adaptation

  • 논문 : Open Compound Domain Adaptation - y2020.03,c5

  • 분류 : paperswithcode - Unsupervised Domain Adaptation

  • 저자 : Ziwei Liu1∗, Zhongqi Miao2∗, Xingang Pan, Xiaohang Zhan

  • 읽는 배경 : 판 페이 박사과정 선배가 추천해준 논문이자, 우상현 랩장과 박광영 박사과정 선배님이 최근에 발표하신 ‘Discover, Hallucinate, and Adapt’의 기본이 되는 논문이다.

  • 읽으면서 생각할 포인트 : the present and problems and issues, ours Solution 흐름으로 정리하고 기록해놓자.

  • 느낀점
    • 이해 60%. 필요 논문을 찾아읽고 다시 읽어야 겠다.
  • 다 읽은 후, 읽어야 겠다고 생각이 든 논문
    1. [45, 36, 28], Memory is storing class centroids.
      • 45 -y2017-c1912
      • 36 -y2019-c69
      • 28 -y2019-c103
    2. curriculum domain adaptation-y2018-c32 56 - curriculum domain adaptation에서 m이 의미하는것
    3. the domain-confusion loss-y2017,c1875 48 - Equ (1), (2)이 의미하는 수학적 의미 -> 이제 알았음.
    4. [27, 10], Adopting cosine classifiers, L2 norm before softmax classification.
      • 10 -y2018c372
    5. t-SNE Visualization
    6. 이 논문에서 experiment compare하기 위해 사용했던 참고한 논문 자료.
      1. Digits: conventional unsupervised domain adaptation (ADDA [48], JAN [30], MCD [42])
      2. Digits: the recent multi-target domain adaptation methods (MTDA [9], BTDA [5], DADA [39])
      3. segmentation: three state-of-the-art methods, AdaptSeg [47], CBST [58], IBN-Net [35] and PyCDA [26]

    논문 핵심

    1. Domain encoder를 만들어 내는 것. (Equation말고 Algorithm 2 figure 먼저 볼 것)
      1. 처음에는 Classification을 위한 class encoder와 같은 방식으로 학습시키다가,
      2. Decoder( classEncoder(x), domainEncoder(x) ) = x 이처럼 완벽한 reconstruction이 되게 만들면서,
      3. classification 능력은 random label을 이용한 cross entropy loss로 제거해버린다.
    2. Domain encoder를 활용해서, target domain image feature와 source domain image feature 사이의 거리 계산하기
    3. Memory module(class centroids)을 사용해서, taget domain의 feature denoising 하기. (ProDA에서는 class centroids와의 거리 정보를 target domain feature에 곱해서 denoising 해줬지만…) 여기서는 V_transfer feature를 만드는 수식 사용했다.
    4. 자세한 내용은 코드를 보기. (논문보지 말고)

0. Abstract

  • the present
    • A typical domain adaptation approach이란?
    • Clear distinctions between source and target
  • Ours
    • open compound domain adaptation (OCDA) 의 2가지 핵심기술
      1. instance-specific curriculum domain adaptation strategy : generalization across domains / in a data-driven self-organizing fashion(???)
      2. a memory module : the model’s agility(예민함, 민첩한 적응?) towards novel domains / memory augmented features for handling open domains. (메모리가, 우리가 가진 Feature Extractor 와 classifier 에 더 정확하게 작동하는, feature map이 생성되도록 도움을 준다.)
    • 실험을 적용해본 challenges
      1. digit classification
      2. facial expression recognition
      3. semantic segmentation
      4. reinforcement learning

1. Introduction

  • the present & problem
  • Supervised learning : 좋은 성능이지만 비현실적
  • domain adaptation : 1 source : 1target 에 대해서 clear distinction를 정의하려고 노력하지만 이것도 비현실적. 현실은 많은 요소들(비,바람,눈,날씨)에 의해서 다양한 domain의 데이터가 함께 존재하므로.
  • Ours - open compound domain adaptation
    • more realistic
    • adapt labeled source model /to unlabeled compound target
      • 예를 들어 SVHN [33], MNIST [21], MNISTM [7], USPS [19], and SynNum [7] 는 모두 digits-recognition인데, 이들을 모두 다른 domain이라고 고려하는 것은 현실적이지 않다.
    • 우리는 compound target domains로써 그들을 고려하고, unseen data까지 test해볼 계획이다.
      • 기존의 domain adaptation : rely on some holistic measure of instance difficulty.
      • 우리의 domain adaptation : rely on their individual gaps to the labeled source domain
    • 네트워크 학습 과정
      1. classes in labeled source domain를 discriminate(classify) 하는 모델 학습
      2. (source와 많이 다르지 않은) easy target를 넣어서 domain invariance(domain의 변화에도 강건한)를 capture하게 한다.
      3. source와 easy target 모두에서 잘 동작하기 시작하면, hard target을 feed한다.
      4. 이런 방식으로 classification도 잘하고, 모든 domain에서 robust한 모델을 만든다.
    • Technical insight
      1. Tech1 : domain-specific feature representations을 가지는 Classification Network에 대해서, source와의 feature distance가 가까운 target은 Network 변화에 많은 기여를 하지 않는 것을 이용한다. 그래서 distill(증류해 제거해나간다,) the domain-specific factors (즉 domain에 robust한 Network 제작)
      2. Tech2 : memory module이 inference를 하는 동안 open-domain에서도 정확한 feature를 추출하도록 도와준다. the input-activated memory features(input에 따라 다르게 행동하는 memory feature)

2. Relative work

image-20210121162754802

  1. Unsupervised Domain Adaptation :
    • 1 source - 1 target
    • cannot deal with more complicated scenarios
    • 참고 논문들 : latent distribution alignment [12], backpropagation [7], gradient reversal [8], adversarial discrimination [48], joint maximum mean discrepancy [30], cycle consistency [17] and maximum classifier discrepancy [42].
  2. Latent & Multi-Target Domain Adaptation :
    • clear domain distinction&labels(domain끼리의 차이가 분명함-하지만 현실은 continuous함) / not real-world scenario
    • 참고 논문들 : latent [16, 51, 32] or multiple [11, 9, 54] or continuous [2, 13, 31, 50] target domains
  3. Open/Partial Set Domain Adaptation :
    • target이 source에 없는 카테고리를 가지거나, subset of categories 를 가지거나.
    • “openness” of domains = unseen domain data에 대해서 고려하기 시작
    • 참고 논문들 : open set [37, 43] and partial set [55, 3] domain adaptation.
  4. Domain Generalized/Agnostic Learning :
    • Learn domain-invariant universal representations (domain이 변하더라도 같은 특징을 잘 추출하는 신경망 모델)
    • 참고 논문들 : Domain generalization [52, 23, 22] and domain agnostic learning [39, 5]
  5. 바로 위의 논문들의 문제점과 our 해결
    • 문제점 : they largely neglect the latent structures inside the target domains
    • 해결책 : Modelling the latent structures (figure4의 구조 같음) inside the compound target domain by learning domain-focused factors(domain_encoder)

3. Our Approach to OCDA

  • 3.1. Disentangling Domain Characteristics with class labels in the source domain

    • Separate specific characteristics(representation) between classes.

      • image-20210121191720032 : classifier encoder up to the second-to-the-last layer
      • image-20210121191749345 : the classifier
    • 위의 Class_encoder로 발혀지지 않은 factors(features)들은 reflect domain characteristics.
      image-20210121192005408 : domain encoder. 아래의 성질은 만족하게 encoder를 만들어 낸다.

      1. Completeness : class[classifier ] encoder와 domain encoder의 정보를 모두 합쳐, decode하면 거의 완벽한 reconstruction이 된다. 즉 x에 대한 모든 factor(feature)를 가진다. (아래의 Algorithm2를 읽어보면 이해가능)

      2. Orthogonality : E_domain(x) E_class(x)는 서로 상관관계가 없다.

        • 이를 위해서 class-confusion algorithm 를 제안한다.

          1. image-20210122183736379

          2. (1) 값이 최소가 되도록 domain encoder가 학습된다
            (2) 값이 최소가 되도록 Discriminator가 학습된다
            이 과정을 통해서, "Class_encoder라는 큰 수박에서, Domain_encoder의 능력을 가진 맛있는 부분을 살살살 긁어 뽑아내는 작업이다" 라고 생각하면 편하다.
            ---
            i : the instance index
            D : discriminator. - 이름은 discriminator인데 아래의 알고리즘을 잘보면, 저렇게 학습시키면 그냥 classifier가 된다. 
            
          3. The E_domain(·) is class-confusing due to z^i_random

          4. image-20210121201223970

          5. 위의 알고리즘 과정을 통해서, Eecoder_domain은 class정보를 최대한 무시하면서도, domain에 관련된 representation만을 최대한 추출하는 Encoder가 되도록 학습된다.
    • image-20210121205438920

  • 3.2. Curriculum Domain Adaptation

    • target domain instance들을 source domain과의 거리를 기준으로 rank(정렬)한다.
    • 거리를 측정하는 방법 : image-20210121201751297
    • 가까운 domain instance들부터, Network 학습에 사용한다. 그때 Loss는 아래와 같다.
      • Loss1 : One is the cross-entropy loss defined over the labeled source
      • Loss2 : the domain-confusion loss[48]
  • 3.3. Memory Module for Open Domains ​⭐⭐​

    • 문제점 : target data를 기존의 신경망(classifier??)에 넣으면?? v_direct 나옴. v_direct 자체는 representation로써 불충분한 정보를 가지고 있다! 즉 신경망이 충분한 feature 추출 불가능!!
    • 해결책 : Memory Module은 memory-transferred knowledge를 가지고 있다. 이것이 input으로 들어온 new domain data를 balance하게 만들어 준다.
      1. Class Memory (M)
        • Store the class information from the source domain
        • by [45, 36, 28], Store class centroids {c_k}(k = 1~K class number)
      2. Enhancer (v_enhance)
        • image-20210121204035066
        • 행렬곱 (1 x e) = (1 x d) * (d x e)
        • M(d x e) 덕분에, target domain의 data가 source 쪽으로 이동한다.
      3. Domain Indicator (e_domain)
        • 약간 learning Late 처럼, 얼마나 source 쪽으로 vector를 옮길 것인가. 를 말한다. 아래 수식 참조. gap이 크면 input vector를 크게 옮겨 놓고, gap이 작으면 input vector를 작게 옮긴다.
        • Domain indicator = image-20210121204712193
      4. Source-Enhanced Representation (v_transfer)
        • v_direct에서 source를 중심으로 balance가 맞춰진 vector
          image-20210121204841026
        • ⊗ is element-wise multiplication
        • Adopting cosine classifiers [27, 10], 이렇게 만들어지 v_transfer를 l2-normalize한다. 그리고 softmax classification layer에 보낸다.
        • domain mismatch 에 효과적이다.
  • image-20210121212155095

4. Experiments

  • Datasets

    • typesourcetargetopen
      Classify-DigitsSVHNMNIST, MNIST-M, and USPSSWIT
      C-Faces(Multi-PIE)C05C08-C14C19
      C-DrivingGTA-5BDD100KBDD100K
      C-Mazesthe GridWorld  
  • Network Architectures

    • backbone : LeNet-5, ResNet-18, VGG-16
    • Compare with :
      1. Digits: conventional unsupervised domain adaptation (ADDA [48], JAN [30], MCD [42])
      2. Digits: the recent multi-target domain adaptation methods (MTDA [9], BTDA [5], DADA [39])
      3. segmentation: three state-of-the-art methods, AdaptSeg [47], CBST [58], IBN-Net [35] and PyCDA [26]
  • Ablation Study

    1. the Domain-Focused Factors Disentanglement - k-nearest neighbors
    2. the Curriculum Domain Adaptation - USPS is the furthest target domain -> Good Classification
    3. Memory-Enhanced Representations. - Figure 5

【Domain】Two-phase Pseudo Label based Domain Adaptation

  • 논문 : Two-phase Pseudo Label Densification for Self-training based Domain Adaptation
  • 분류 : paperswithcode - Unsupervised Domain Adaptation

  • 저자 : Inkyu Shin, Sanghyun Woo, Fei Pan, In So Kweon

  • 읽는 배경 : 현재 Domain adapation, Self-supervise이 연구실의 중심 연구 주제로 많이 사용되고 있다. 판 페이 박사과정 선배가 추천해준 논문을 읽기 전에, 신인규 석사과정 선배님이 작성하신 논문을 먼저 읽는게 좋을 것 같다고 생각했다. 아래의 배울 포인트 때문이다.

  • 읽으면서 생각할 포인트 : Reference를 어떻게 추가했나? domain adaptation과 Self-supervised에 대해서 내가 추가적으로 공부해야하는게 뭘까? Abstract가 가장 중요하다고 하는데 선배님은 어떻게 작성하셨나? relative work에 대해서 얼마나 상세하게 이해하셨고 그 흐름을 어떤 식으로 잡고 가셨나? (어떤 의문, 반박으로 다른 모델이 나왔고 등등… 그래서 핵심 모델은 뭐고 과거 흐름은 뭐였는지 등등…) 석사 1년동안 내가 이정도 논문을 쓰기위해서 가져아할 자세는 무엇일까?
  • 느낀점
    1. 현재 나와있는 모델에 대한 의문, 의심, 질문, 반박에서 논문이 시작했다.
    2. “Make your paper look similar to a typical ML paper.” 을 지키기 위해 아래와 같이 논문의 흐름. the present and problems and issues, ours Solution 으로 나열해가는 흐름에 대해서 잘 기록해 두자. 지금부터 해야한다.
    3. 역시나 deeplab을 사용하고 그 위에 CRST를 올리고 그 위에 TPLD를 올린방식이다. 따라서 deeplab까지의 계보 즉, recognition의 계보를 최대한 확실히 알아놔야 겠다.
  • 질문&답변
    1. ^yk가 pseudo targer label이라면 이건 어떤 신경망으로 target data를 예측해놓은 결과이지?? w는 아닐테고…
      • w로 예측하는거 맞다. 그리고 대신 ^yk값은 Eq.(2)(4) 번 처럼 1 or 0의 값을 가진다. softmax 확률 값이 아니다.
    2. 이 분야를 항상 관심을 두고 계셨던 건지? 그래서 그 분야의 논문을 항상 읽어오신 건지?
    3. 논문을 준비하신 기간?
    4. 코드 제작은 어떻게 하셨는지? 어떤 코드 참고 및 어떤 방식으로 수정? 몇 퍼센트 수정 및 추가? 코드 제작 긱나?
    5. 석사기간에 이런 좋은 논문을 쓰는게 쉽지 않은데… 혹시 팁이 있으신지?
  • 1선배님조언
    • 논문 읽는데 너무 많은 시간을 투자하지 말아라. 핵심만 읽어라
    • 최근 논문으로 흐름을 항상 따라라
  • 2선배님조언
    • AD에서 연결할 수 있는 관심있으신 분야 -> Video, Active learning, Semi-supervise, Labeling down + Performance increment
    • Awesome domain adaptation 을 참고해서 괜찮은거 공부해보고, 일부 분야는 발행 논문이 적은데 그 곳을 집중해서 파보는 것도 괜찮다.
    • 특히 DA분야는 가짜가 많으니 조심. 정말 모델에 대입 해봤을 때, 성능향상이 이뤄진다면 짜릿.
    • 과제!! 현재 과제가 어떤 과제가 있는지 알아보고, 그 과제를 하기 위해서 미리미리 공부해놓고 그 과제를 하고 싶다고 먼저 말해놓는게 좋다. 따라서 몇몇 대화를 해본 선배님들에게 직접 찾아가서 현재 하시는 과제가 무엇인지 무엇을 미리 공부해놓으면 좋은지 알아보기
  • 다 읽은 후, 필수로 읽어야 겠다고 생각이 든 논문
    • CBST-class-balanced self-training-2018 (class-wise thresholding value λ 가 뭔지 알려줌 [39])
    • CRST-Confidence Regularized Self-Training - 2019 [40]
    • ADVENT: Adversarial Entropy Minimization for Domain Adaptation - easy vs hard 분별하는 discriminator 왜 사용하는지 적혀 있음 [37]
    • Training deep neural networks on noisy labels with bootstrapping (12. 2014) - bootstrapping
    • map high-dimensional features to 2D space feature Using t-SNE [27]
    • [1] domain adaptation - object detection
    • [4] domain adaptation - semantic segmentation

0. Abstract

  • the present and problems : The self-training generates target pseudo labels like only the confident predictions(Relative work의 self-training내용 참조). So that this approach produce sparse pseudo labels (희박한/흐릿흐릿한/빈약한 예측 결과) in practice.
  • why problem : suboptimal, error-prone model
  • Solution : TPLD (Two-phase Pseudo Label Densification) ⭐⭐​
    • the first phase : Sliding window voting to propagate the confident predictions, Using Image’s intrinsic spatial-correlations.
    • the second phase : image-level confidence score -> easy-hard classification.
      • easy samples : easy’s full pseudo label. ,while pushing hard to easy.
      • hard samples : adversarial learning to enforce hard-to-easy feature alignment.
  • additional tech : the bootstrapping mechanism (in order to ease the training process and avoid noisy predictions.)
  • result : 다른 self-training 모델에 쉽게 integrated 가능. 최근 self-training framework, CRST에 결합해서 SOTA달성

1. Introduction

  • the present models
    • Unsupervised domain adaptation (UDA) 는 labeled source 에서 unlabeled target를 학습하는데 도움이 된다. 이 논문에서는 Semantic segmentation 문제에 대해 UDA를 적용한다.
    • UDA 의 핵심적으로 adversarial learning에 근간을 둔다. 이 방법을 통해서 source와 target의 feature distributions을 효과적으로 줄일 수 있다.
    • 최근에는 다른 방향으로 self-training 이라는 것이 나왔다. pseudo labels corresponding to high prediction scores(예측 결과를 “가짜 label(annotation)”로 사용한 것)을 이용해서 네트워크를 생성한다. 대표적인 모델이 CBST-2018와 CRST-2019 이다. in multiple UDA.
      • [labeled source data] VS [pseudo labeled target data]
      • CBST’s key word - self-training loss / domain-invariant ‘features and classifiers’ / class balancing strategy and spatial priors.
      • CRST’s key word - the feasible space of pseudo labels / regularizer in loss to prevent overconfident predictions.
  • 문제점 : excessively cut-out the predictions.
    • 문제로 인한 결과 : sparse pseudo labels.
    • 멍청한 해결책 : lowering the selection threshold.
  • ​우리의 해결책 : ⭐⭐​
    • Abstract의 Solution에 정리 잘해 둠. 그거 다시 읽기.
    • 경험적으로, Easy sample(label 예측을 confident자신있게 판단한 이미지)은 ground-true에 가까웠다. 따라서 easy sample’s full pseudo labels(GT은 아니만 그래도 GT와 가까운 예측값=가짜 라벨값)을 사용하기로 했다. 반대로 hard sample에 대해서는 (hard-easy adaption의) adversarial loss를 사용했다.
    • the bootstrapping mechanism 사용
  • Summarize our contributions
    • 이것을 사용한 첫번째 사례이다. / TPLD 요약 / 새로운 loss bootstrapping mech. / ablation studies

2. Related works

  • Domain Adaptation
    • 목적 : the performance drop by the distribution mismatch
    • 계보 : adversarial learning -> minimize the discrepancy between source and target feature -> unsupervised domain adaptation. -> 아래 처럼 3개로 분류 가능.
      • input-level alignment [5, 17, 28, 34]
      • intermediate feature-level alignment [18, 19, 23, 25, 37]
      • output-level alignment [36]
    • 하지만 위 방법들은 taget domain signal을 충분히 이용하지 못한다.
      • 그래서 self-training based UDA approaches [CBST, CRST]이 나와서, 성능에서 우의를 차지하고 있다.
  • Self-training
    • 장점 : 위의 문제점 해결. Explore the supervision signals from the target domain.
    • 간단 메카니즘 :
      1. Use prediction target data from the source-trained model (= pseudo-labels).
      2. Re-train the current model in the target domain. (pseudo-labels를 GT로 설정하여)
    • CBST, CRST도 있지만, 우리는 sparse pseudo label 문제에 집중했다. introduction정리와 동일.

3. Preliminaries

  • source domain : (xs, ys)
  • target domain : (xt)
  • we train the network to infer pseudo target label.
    image-20210120205807928 여기서 K는 the total number of classes.
  • image-20210120215743750
  • (2): image-20210120224540664 = image-20210120215755474 Pseudo Label은 가짜이지만 ‘정답’값(GT값)이므로 0 or 1 의 값을 가져야 한다.

Noisy label handling

  • Training deep neural networks on noisy labels with bootstrapping (12. 2014)
  • bootstrapping loss = (-붙어야 함. 아래 수식에 붙음) image-20210120220855936
  • beta는 그냥 trade-off의 벨런스 조정 값이다. 어떤 값에 집중하게 만들 것 인가.
  • 직관적으로 w모델이 pseudo target label을 더 잘 예측하게 만들고, 그 예측값에 더 confident하게 만든다.

4. Method

  • phase1을 충분히 학습시키고, phase2를 더 학습시켰다. 모든 phase에서 bootstrapping 방법을 사용하였다.
  • image
  • 4.1 : 1st phase : Voting based Densification

    • 문제점 : (2)의 수식에서 보듯이, class에 따른 possibility값이 큰 class에 대해, λ_k이상의 값을 가져아 pseudo label값이 주어진다. 여기서 sparse pseudo labels 문제가 발생한다.
    • 해결책 : Sliding window-based voting. 주변 픽셀은 (픽셀, 예측)값이 비슷할 수 있다는 사실을 이용.
      • the neighboring confident prediction values. 아래에서 x3은 iteration.
      • image-20210120225352890
      • Loss 함수 교체
      • image-20210120225601619
  • 4.2 : 2nd phase: Easy-Hard Classification based Densification

    • 위와 같은 voting 작업을 한다 할지라도, fully densified pseudo labels을 만들수가 없다. local window이기 때문이다. 따라서 full-pseudo label training을 위해서 다른 방법을 제시하였다.

    • target sample을 hard와 easy로 나누는 방법

      • 한장의 이미지를 예측하면 w x h x K 의 prediction possibility 값이 나올거다. 그것에 대해서,
      • image-20210120232531704
      • Nk_t는 k-class를 가지는 pixel의 전체 수
      • Nk_t*는 Nk_t 중에서 λ_k(class-wise thresholding value[39]) 이상의 픽셀 수
      • 위의 2개를 나누면, k클래스에 대해서 모델이 자신있게 predict를 하는 비율을 의미한다.
      • 이미지 한장이 가지는 conf값이 충분히(q 보다) 크면, 이 target 이미지를 자신있게 예측했어! 라는 의미로 이 이미지는 easy Image라고 정의한다.
      • 이미지 한장이 가지는 conf값이 q 보다 작으면, 이 target 이미지를 자신없게 예측했어ㅠ 라는 의미로 이 이미지는 hard Image라고 정의한다.
      • λ_k(1이하)로 한번 나눠준 이유는, 너무 많은 easy가 나오지 않도록 만든다. 예측하기 아주 쉬운 이미지에 대해서.
      • 실험을 통해서 q를 0.3으로 설정하는 것이 가장 좋은 mIOU를 가져다 주는 것으로 판단할 수 있었다.
    • 이미지를 easy, hard로 나누고, 각각에 대해 다른 Loss 함수를 적용했다.

      • easy : full pseudo label predictions + bootstrapping loss

        • image-20210120234937826
      • hard : adversarial learning to push hard examples to be like easy samples

        • In order to align the feature from hard to easy, discriminator D_intra를 학습시킨다. 이 discriminator는 이 이미지가 hard이미지인지 easy이미지 인지 판단하는 discriminator이다.
        • 이 내용을 완벽하게 이해하려면 [37] 을 이해해야한다. 위의 식은 easy면 1. hard만 0.로 판단하는 discriminator를 만들기 위한 loss값이고, 아래는 hard를 1이라고 판단하게 만드는 discriminator loss이다.
        • image-20210121000048267

5. Experiments

  • GTA5 [31] to Cityscapes [6]
  • SYNTHIA [32] to Cityscapes
  • 5.2 - Implementation details (backbone모델(VGG16), segmentation model(deeplab))
  • 5.3 - Main Results (with Figure)
  • 5.4 - Ablation study, 5.5 - Parameter analysis
    • conf에서 1/λ의 역할
    • image-20210121120518169
  • 5.6 Loss function analysis
    • image-20210121120536719
    • Especially for the hard sample training, we conduct a contrastive analysis in Fig. 6. (이 FIg 6 그림을 이해하기 위해서는 논문 [26]을 꼭 일어야 겠다.)
    • We map high-dimensional features of (c) and (d) to 2-D space features of (e) and (f) respectively using t-SNE [26]
    • image-20210121121012523

6. Conclusions

  • Unsuperivsed Domain Adaptation에서 좋은 성능을 내었다.

【segmentation】The Devil Boundary for Instance Segmentation w/ advice

  • 논문 : The Devil is in the Boundary: Exploiting Boundary Representation for Basis-based Instance Segmentation

  • 동영상 : https://www.youtube.com/watch?v=XvLo5WrtHu0 -> why, how, what in the past 에 대한 내용들이 잘 담겨 있으니 꼭 참고.

  • 저자 : Myungchul Kim, Sanghyun Woo, Dahun Kim, In So Kweon

  • 읽는 배경 : 현재 Domain adapation, Self-supervise, Transformer 등에 관심이 가지만, 그래도 가장 구체적이며 많은 지식을 가지고 있는, Segmentation이나 Object Detection과 관련된 이 논문을 먼저 읽어보고 싶었다. 같은 랩 석사 선배님이 적으신 논문으로써, 내가 1년 안에 이런 논문을 만들어야 한다는 마음 가짐으로 논문을 읽어보려고 한다.

  • 읽으면서 생각할 포인트 : Reference를 어떻게 추가했나? 실험은 어떤 것을 어떻게 하였나? Relative work는 어느정도로 작성하였나? 과거 지식은 어느 정도가 필요한가? 코드 개발은 어떻게 하였나?

  • 느낀점

    1. 논문 안에는 핵심 내용(global 사용, score 사용) 등이 있는데, 최근 논문들의 핵심 내용만 쏙쏙 캐치해서 그것들을 잘~융합해서 개발이 되었다. -> 이런 논문 작성 방식도 추구하자.
    2. 논문 많이 읽어야 겠다… 완벽하게 이해는 안되고, 60% 정도만 이해가 간다. 필수적으로 읽어야 하는 논문 몇가지만 읽고 나면 다 이해할 수 도 있을 듯 하다. 지금은 전체다 이해가 안된다고 해도 좌절하지 말자.

    3. 정말 많은 노력이 보였다. 내가 과연 이정도를 할 수 있을까? 라는 생각이 들었지만 딱 한달 동안 이와 관련된 매일 논문 1개씩 읽는다면, 잘하면 좀더 창의력과 실험을 가미해서 더 높은 성능을 내는 모델을 만들 수 있지 않을까? 하는 생각은 든다. 따라서 하나의 관심 분야를 가지고 그 분야의 논문 20개는 읽어야 그 쪽은 조금 안다고 할 수 있을 것 같다.

    4. 만약 Segmentation을 계속 하고 싶다면, 아래의 ‘필수 논문’을 차례대로 읽도록 하자.


질문&답변 ⭐⭐​

  • 질문
    1. 논문 내용에 대한 질문은 없다. 왜냐면 내가 찾아 읽는게 먼저이기 때문이다. 필수로 읽어야 겠다고 생각한 논문들을 먼저 읽고 모르는 걸 질문해야겠다.
    2. 현재도 Segmentation을 매인 주제로 연구하고 계신지? 아니면 다른 과제나 연구로 바꾸셨는지?논문을 준비하신 기간?
    3. 이 분야를 항상 관심을 두고 계셨던 건지? 그래서 그 분야의 논문을 항상 읽어오신 건지?
    4. 논문을 준비하신 기간?
    5. 코드 제작은 어떻게 하셨는지? 어떤 코드 참고 및 어떤 방식으로 수정? 몇 퍼센트 수정 및 추가?
    6. 아무래도 saturation된 Instance Segmentation에 대해서 계속 공부해나가시는거에 대한 두려움은 없으신지?
    7. 석사기간에 이런 좋은 논문을 쓰는게 쉽지 않은데… 혹시 팁이 있으신지?
  • 선배님답변 간략히 정리 (정말 감사합니다)
    1. 공부에는 왕도가 없다. 어떤 문제와 관심분야를 하나로 정해두고 끝장을 보겠다고 해도 끝이 없다.
    2. 일정 분야에 대해서 흥미를 가지는 마음가짐이 굉장히 중요하다. 이 마음이 사라지고 의무와 책임만 남는 상황이라면 진정한 나만의 연구, 나만의 결과, 행복한 연구, 행복한 생활을 이뤄나갈 수 없다.
    3. 조급함 보다는 꾸준함이 중요하다. 꾸준하게 조금씩, 라이프 밸런스를 맞춰가며 취미도 해가며 흥미롭게 나의 연구와 공부를 해 나가는게 중요하다. 연구와 공부에 대한 의무감이 생기면 좋은 연구, 좋은 결과를 낼 수 없다.
    4. 왜 이런 논문이 나왔지? 지금까지의 계보는 어떻고, 그런 계보가 나온 이유가 무엇이지? 어떤 개념과 어떤 문제, 어떤 정의에 의심을 가지고 시작된 연구이지? 라는 생각을 가지고 논문을 읽고 공부하는 것이 굉장이 중요하다. 예를 들어서 mask score이 나온 이유는 뭐지? boundary score가 사실은 더 중요한거 아닐까? mask-rcnn에서 masking이 왜 잘되지? BB가 이미 잘 만들어지기 때문에? 이걸 없애야 하지 않을까?? 그렇다면 어떻게 없애야지? 이 loss, 이 score가 과연 맞는 건가? 이런 의심, 질문, 반박을 찾아 논문을 읽고, 나도 이런 마음을 가지고 생각하는 것이 굉장히 중요하다.
    5. 마음을 잡고 논문을 준비한 기간은, 6개월 7개월. 코드 작성도 걱정 할거 없다.
    6. 다양한 걱정, 고민, 근심이 드는 것은 너무 당연한 생각이다. 너무 걱정하지말고 꾸준히 해나간다면 분명 잘 할 수 있다.
    7. recognition, reconstruction, reorganization 이라는 3가지 3R 문제가 딥러닝에서 있다. 특히 recognition을 잘 따라간다면, 어떤 문제에서도 적용되어 사용하는 것을 알 수 있다.
    8. classification 부터 object detection, segmentation 에 대한 계보들을 보면서, 왜?? 라는 생각을 가지고 하나하나를 바라보아야 한다. 이건 왜 쓰였지? 이건 왜 나온거지? 이건 왜 좋지? 이러다보면 정말 과거 계보부터 봐야하기도 하지만 그것도 나의 선택이다. 정말 필요하다고 생각이 들면 찾아서 공부하면 되는거고, 아니다 다른게 더 중요하다 하면, 다른거 새로운 기술을 공부해도 좋은거다. 정답은 없다. 그건 나의 선택이고 걱정하지 말고 흥미를 가지고 꾸준하게 하면 되는 거다.
  • 다 읽은 후, 필수로 읽어야 겠다고 생각이 든 논문
    • YOLACT [4]-2019
    • BlendMask [6] - 2020
    • Boundary-preserving Mask RCNN[11] - 2020
    • Mask scoring r-cnn - 2019
    • Zimmermann et al.[47] - auxiliary edge loss. Boundary Learning - 2019
    • Single shot instance segmentation with point representation [global-area-based methods] 2020
    • a Dice metric [13]
    • CondInst [37]
    • basis 개념 [4, 5, 38, 6, 37] 중에 적당한거 하나


The Devil is in the Boundary

1. Abstract, Introduction

  • the present and problems
    • most instance segmentation 의 문제점
      1. two-stages-instance-segmentation은 first-stage’s bounding box에 mask결과값이 많이 의존된다(step-wise).
      2. 성능이 구리다. region-specific information 만을 사용하고, ROI-pooled features 를 사용하기 때문이다. 이 두가지 문제를 아래의 것들로 해결했다.
    • 최근까지 자주 사용되고 있는 [4, 5, 38, 6, 37]
      1. basis framework : global image-level information 을 사용한다.
      2. 하지만 정확한 지도학습적 방법으로, 적절한 Loss를 사용하서, global mask representations 를 학습하진 않는다. (?) last mask output signal에 의해서 학습 되므로.
    • boundary 관점에서 집중하는 최근 논문으로는 Boundary-preserving Mask RCNN (2-stage) 논문도 있다. a boundary prediction head in ‘mask head’ 를 사용한다.
  • 우리의 방법
    1. a boundary prediction head 를 추가적으로 사용했다.
    2. holistic image-level instance boundaries( = global boundary representations ) 을 학습한다. 그러기 위해서 우리는 the boundary ground-truths 를 사용한다.
    3. 새로운 측정지표로써 novel instance-wise boundary-aware mask score 를 사용했다.
    4. Blend-Mask(strongest single-stage instance segmentation methods)를 보완하여 만듬
    5. state-of-the art methods on the COCO dataset.

  • two-stage

    1. Mask RCNN : RoIAlign
    2. PANet : FPN+Mask
    3. Mask scoring RCNN (읽어야함): alignment between the confidence score and localization accuracy of predicted masks
    • 문제점 : (1) RoI pooling에 의한 정보 손실 (2) quite slow
  • Single-stage

    • pixel-wise predictions of cues 픽셀 관점 예측 단서들 : (a) directional vectors (b) pairwise affinity (c) watershed energy (d) embedding learning (= local-area-based methods, 각각에 대한 설명은 각 paper 참고) -> and then grouping pixel-wise predictions for object instances -> not good ….
    • global-area-based methods 탄생 [4, 6, 38] :
      1. Generate intermediate FCN feature maps, called ‘basis’.
      2. Assemble the extracted basis features.
  • Boundary learning for instance segmentation

    • the past and problems
    • CASENet : sementic segmentation. category-aware boundary detection.
      • InstanceCut : instance-level.
      • 이 둘은 expensive! (super-pixel extractions and grouping computations 때문에)
    • the present and problems
      • Zimmermann et al.[47]: Boundary Learning, auxiliary edge loss.
      • Boundary-preserving mask r-cnn[11] : instance-level boundaries head ([47]에서 업그레이드)
      • 하지만 위의 2가지 방법은 two-stage methods(RoI-wise)! 이다. ROI는 local!적이므로 global 정보를 이용하지 못한다.

3. Background (single-stage)

  • (global-area-based) Basis-based instance segmentation의 시작 :
    image
    1. Basic Head(=Protonet) : FCN으로 a set of basis mask representations 를 생성한다.
    2. Detection Head(=Prediction head) : Detected Box를 찾는다. 즉 instance-level parameters(= instance-specific information)를 예측한다.
    3. (1과 2를 결합해서) instance segmentation을 수행한다.
  • 위의 pipeline을 따르는 모델들
    1. YOLACT : 32 global base, the according instance-specific scalar coefficients, a linear combination among the bases. —> cause [rich instance features vs effective assembly methods]
    2. improved the assembly parameters : BlendMask [6], SipMask [5], and CenterMask [38]
    3. instance-specific representation : CondInst [37] (Key word: dynamic filter weights, sliding window, the predicted convolution weight filters)

4. Boundary Representation

  • B2Inst
    1. backbone for feature extraction
    2. instance-specific detection head (Detection head)
    3. the global basis head, the global image information (Basis head)
    4. Bundary Basis = mask scoring head
    5. (2번)과 (3번)을 결합해서, final masks 예측.
    6. BlendMask instantiation (boundary basis)

image-20210119165307132

  • Details
    1. basis head
      • FPN feature를 받고, a set of K(=#Bases) global basis features를 생성한다
      • 4개의 3x3 conv 통과 + upsampling + reduce the channel-size
      • The previous basis head is supervised by the last mask loss only. (?)
    2. Detection Head
      • Basic head와 병렬로, instance-level parameters 들을 추측한다.
      • 특히 여기서 나오는 attention map feature는 Boundary Basic (BlendMask 참고)에서 사용된다.
    3. Loss 함수
      • 1) binary cross-entropy loss
      • 2) dice loss
      • 3) boundary loss
    4. image boundary (그림에 없음)
      • a holistic boundary of all instances (= global boundary representations) in a scene (instance 하나하나 아니라)
      • Overlapping objects and complex shapes 문제에서 좋은 성능을 가져다 준다.
      • the boundary supervision 은 어렵지 않다. mask annotations를 그냥 이용하면 되므로. the binary mask ground-truths에서 soft boundaries를 찾기 위해서, Laplacian operator 를 사용한다.
  • Boundary-aware mask scoring
    1. Mask scoring R-CNN 에서 a mask IoU scoring module 이 제안됐었다.
    2. basis head에서 global view를 바라봤었다면, 이 과정을 통해서, an instance-level(local view)을 바라보게 된다.
    3. mask IoU score = the IoU + boundary quality 로 분리해 고려했다.
    4. S_boundary 정의 : Boundary score
      • a Dice metric [13] 을 차용했다.
      • image-20210119181451921
      • i는 i번째 pixel을 의미하고, epsilon은 분모가 0이 되는 것을 막는다.
    5. Scoring head(위 오른쪽 묘듈)
      • S_boundary와 S_IOU 를 학습의 Loss 함수로 사용한다.
      • Input은 concatenation of [predicted mask (M_pred), boundary (B_pred), RoI-pooled FPN features (F_RoI)]
      • 결론 및 효과 : only for test-time. 학습을 하는 동안 이 score도 추측할 수 있게 만들어 놓으면, test할때 확율값이 얼마인지 확인가능하기도 하고, 학습 성능이 좋아지는 효과도 볼 수 있다.
    6. Score definition at inference
      • Object Detection 모델도 confidence score를 예측하듯이, Mask Score를 예측하는 부분도 만들었다. GT가 뭐고 아래를 어떻게 사용하는지는 나중에 논문이나, 코드 참고하자.
      • image-20210119183330139

5. Experiment - Ablation study

  • 우리 모델에서의 main ‘components’
    1. Holistic Boundary basis
    2. Boundary-aware mask scoring (Boundary_S + Mask_S)
  • Basis head design choices
    • image-20210119184502140
    • boundary supervision을 globally하고, the boundary supervision_loss and its prediction를 모두 사용하는 (e)에서 가장 성능이 좋았다.
    • 마지막 단의 색갈 channel은 original basis를 의미하고, 특히 Red는 the additional image boundary basis를 의미한다.


B2Inst WACV2021 영상

1

1

1

1

1

1

【CV】Computer Vision at FastCampus2, chap7~10

  1. FastCampus 사이트의 Computer vision 강의 내용 정리
  2. 구글링을 해도 되지만은, 필요하면 강의를 찾아서 듣기
  3. FastCampus - Computer vision Lecture
  4. 이전 Post Link

chap7 - Binary

  1. cv2.threshold(src, thresh, maxval, type, dst=None) -> retval(사용된 임계값), dst

  2. Otsu 방법

    • image-20210119095215096
    • th, dst = cv2.threshold(src, 0, 255, cv2.THRESH_BINARYcv2.THRESH_OTSU)
  3. 균일하지 않은 조명 환경 - 픽셀 주변에 작은 윈도우를 설정하여 지역 이진화 수행

    • for y in range(4):
          for x in range(4):
              src_ = src[y*bh:(y+1)*bh, x*bw:(x+1)*bw]
              dst_ = dst2[y*bh:(y+1)*bh, x*bw:(x+1)*bw]
              cv2.threshold(src_, 0, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU, dst_)
      
    • cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize(슬라이딩 윈도우의 크기), C, dst=None) -> dst
  4. 모폴로지(Morphology, 침식과 팽창)

    1. 침식 연산 : 영역이 줄어듦. 잡음 제거 효과 - cv2.erode(src, kernel)

    2. 팽창 연산 : 영역이 불어남. 구멍이 채워짐 - cv2.dilate(src, kernel)

    3. kernerl 생성 방법 : cv2.getStructuringElement

    4. src = cv2.imread('circuit.bmp', cv2.IMREAD_GRAYSCALE)
            
      se = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 3))
            
      dst1 = cv2.erode(src, se)
      dst2 = cv2.dilate(src, None)
      
  5. 모폴로지(열기와 닫기)

    1. 열기 : 침식 -> 팽창
    2. 닫기 : 팽창 -> 침식
    3. image-20210119100131147
    4. 범용 모폴로지 연산 함수 : cv2.morphologyEx(src, op, kernel)
    5. 열기 연산을 이용한 잡음 제거 : 우선은 지역 이진화!! 필수 -> 그리고 열기 연산
  6. 레이블링

    • 객체 분활 클러스터링(Connected Component Labeling / Contour Tracing)
    • 4-neightbor connectivity / 8-neightbor connectivity
    • 레이블링 함수 : cv2.connectedComponents(image)
    • 객체 정보 함께 반환하는 레이블링 함수 : cv2.connectedComponentsWithStats(image)
      • image-20210119100708533
      • 바운딩 박스 정보가 나오므로, 숫자 검출 같은 행위가 가능해 진다.
  7. 외곽선 검출( Boundary tracking. Contour tracing)

    • cv2.findContours(image, mode, method)

    • cv2.drawContours(image, contours, contourIdx, color) : 외각 선만 그려줌 (내부x)

    • src = cv2.imread('contours.bmp', cv2.IMREAD_GRAYSCALE)
      #contours, hier = cv2.findContours(src, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
      contours, hier = cv2.findContours(src, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
      dst = cv2.cvtColor(src, cv2.COLOR_GRAY2BGR)
      idx = 0
      while idx >= 0:
          c = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
          cv2.drawContours(dst, contours, idx, c, 2, cv2.LINE_8, hier)
          idx = hier[0, idx, 0]
      
    • image-20210119103238413

    • 외각선 검출 및 도형의 크기나 특징 정보 반환하는 함수

      • 함수 이름설명
        cv2.arcLength()외곽선 길이를 반환
        cv2.contourArea()외곽선이 감싸는 영역의 면적을 반환
        cv2.boundingRect()주어진 점을 감싸는 최소 크기 사각형(바운딩 박스) 반환
        cv2.minEnclosingCircle()주어진 점을 감싸는 최소 크기 원을 반환
        cv2.minAreaRect()주어진 점을 감싸는 최소 크기 회전된 사각형을 반환
        cv2.minEnclosingTriangle()주어진 점을 감싸는 최소 크기 삼각형을 반환
        cv2.approxPolyDP()외곽선을 근사화(단순화) - 아래 실습에서 사용 예정
        cv2.fitEllipse()주어진 점에 적합한 타원을 반환
        cv2.fitLine()주어진 점에 적합한 직선을 반환
        cv2.isContourConvex()컨벡스인지를 검사
        cv2.convexHull()주어진 점으로부터 컨벡스 헐을 반환
        cv2.convexityDefects()주어진 점과 컨벡스 헐로부터 컨벡스 디펙트를 반환
  8. 다각형 검출 프로그램 실습하기

    • 구현 순서
      1. 이진화
      2. contour
      3. 외각선 근사화
      4. 너무 작은 객체, 컨벡스가 아닌 개체 제외
      5. 꼭지점 개수 확인 (사각형, 삼각형, 원 검출)
    • image-20210119104254897
  9. 실전 코딩 : 명함 인식 프로그램 만들기

    • image-20210119104456932

    • 코드 핵심 요약

      import sys
      import numpy as np
      import cv2
      import pytesseract
           
      # 입력 영상 전처리
      src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
      _, src_bin = cv2.threshold(src_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
      # 외곽선 검출 및 명함 검출
      contours, _ = cv2.findContours(src_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
           
      for pts in contours:
          # 외곽선 근사화
          approx = cv2.approxPolyDP(pts, cv2.arcLength(pts, True)*0.02, True)
          # 컨벡스가 아니고, 사각형이 아니면 무시
          if not cv2.isContourConvex(approx) or len(approx) != 4:
              continue
          cv2.polylines(cpy, [approx], True, (0, 255, 0), 2, cv2.LINE_AA)
               
      pers = cv2.getPerspectiveTransform(srcQuad, dstQuad)
      dst = cv2.warpPerspective(src, pers, (dw, dh))
      dst_gray = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY)
      print( pytesseract.image_to_string(dst_gray, lang='Hangul+eng') )
      
    • Tesseract(광학 문자 인식(OCR) 라이브러리)

      • 2006년부터 구글(Google)에서 관리. 현재는 2018년 이후 LSTM 기반 OCR 엔진 및 모델 추가.
      • 하지만 우리는 github 그대로 사용하지 않을 것. 이미 빌드된 실행 파일 사용할 것
      • 설치 옵션 및 설정 (이해 안되면 동영상 참고 하기)
        • 설치 시 “Additional script data” 항목에서 “Hangul Script”, “Hangul vertical script” 항목 체크, “Additional language data” 항목에서 “Korean” 항목 체크
        • 설치 후 시스템 환경변수 PATH에 Tesseract 설치 폴더 추가 (e.g.) c:\Program Files\Tesseract-OCR
        • image-20210119110127435
        • (안해도 됨) 설치 후 시스템 환경변수에 TESSDATA_PREFIX를 추가하고, 변수 값을 \tessdata 로 설정
        • \tessdata\script\ 폴더에 있는 Hangul.traineddata, Hangul_vert.traineddata 파일을 \tessdata\ 폴더로 복사
        • 그리고$ pip install pytesseract
      • python : pytesseract.image_to_string(dst_gray(np.array, gray, RGB도 가능, BGR 불가), lang=’Hangul+eng’)
      • 그리고 가능하면, CMD에서 (path가 지정되어 있으므로) python namecard.py 로 실행하기

chap8 - Segmentation & Detection

  1. 그랩컷 영상분할

    • 그래프 알고리즘을 이용해서 Segmentation을 수행하는 알고리즘 (정확한 알고리즘은 논문 참조)
    • cv2.grabCut(img, mask, rect)
      mask2 = np.where((mask == 0) | (mask == 2), 0, 1).astype(‘uint8’)
      dst = src * mask2[:, :, np.newaxis]
    • 마우스를 활용한 그랩컷 영상 분할 예제 : grabcut2.py 크게 어렵지 않음
  2. 모멘트 기반 (비슷한 모양 찾기 기법을 이용한) 내가 찾고자 하는 객체 검출

    • image-20210125090819511
    • Hu’s seven invariant moments : 크기, 회전, 이동, 대칭 변환에 불변
    • 모양 비교 함수: cv2.matchShapes(contour1, contour2, method, parameter) -> 영상 사이의 거리(distance)
  3. 템플릿 매칭

    • 입력영상에서 작은 크기의 템플릿과 일치하는 부분 찾는 기법

    • image-20210125091301957

    • cv2.matchTemplate(image, templ, method, result=None, mask=None) -> result
      image의 크기가 W x H 이고, templ의 크기가 w x h 이면 result 크기는 (W - w + 1) x (H - h +1)

    • method 부분에 들어가야할, distance 구하는 수식은 강의 및 강의 자료 참조

    • res = cv2.matchTemplate(src, templ, cv2.TM_CCOEFF_NORMED)
      res_norm = cv2.normalize(res, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)
      _, maxv, _, maxloc = cv2.minMaxLoc(res)
      
  4. 템플릿 매칭 (2) - 인쇄체 숫자 인식

    • image-20210125092302957
    • 오른쪽의 0~9까지는 미리 파일로 저장해놓음
    • 자세한 코드 사항은 강의 및 digitrec.py파일 참조
  5. 캐스케이드 분류기: 얼굴 검출

  6. HOG 보행자 검출

    • Histogram of Oriented Gradients, 지역적 그래디언트 방향 정보를 특징 벡터로 사용. SIFT에서의 방법을 최적화하여 아주 잘 사용한 방법

    • 2005년부터 한동안 가장 좋은 방법으로, 다양한 객체 인식에서 활용되었다.

    • image-20210125093630644

      • 9개 : 180도를 20도 단위로 나눠서 9개 단위로 gradient 분류
      • 1개 셀 8x8, 1개 블록 16 x 16. 블록 1개 는 36개(4블록 x 9개 Gradient)의 히스토그램 정보를 가짐
    • cv2.HOGDescriptor.detectMultiScale(img)
      hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())

    • cap = cv2.VideoCapture('vtest.avi')
      hog = cv2.HOGDescriptor()
      hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
      while True:
          ret, frame = cap.read()
          detected, _ = hog.detectMultiScale(frame)
          for (x, y, w, h) in detected:
          c = (random.randint(0, 255), random.randint(0, 255),
          random.randint(0, 255))
          cv2.rectangle(frame, (x, y), (x + w, y + h), c, 3)
      
  7. 실전 코딩: 간단 스노우앱

    • 구현 기능

      • 카메라 입력 영상에서 얼굴&눈 검출하기 (캐스케이드 분류기 사용)
      • 눈 위치와 맞게 투명한 PNG 파일 합성하기
      • 합성된 결과를 동영상으로 저장하기
    • ch8/snowapp.py 파일 참조

      face_classifier = cv2.CascadeClassifier('haarcascade_frontalface_alt2.xml')
      eye_classifier = cv2.CascadeClassifier('haarcascade_eye.xml')
           
      faces = face_classifier.detectMultiScale(frame, scaleFactor=1.2, minSize=(100, 100), maxSize=(400, 400))
      for (x, y, w, h) in faces:
          eyes = eye_classifier.detectMultiScale(faceROI)
          overlay(frame, glasses2, pos)
               
      def overlay(img, glasses, pos):
          # 부분 영상 참조. img1: 입력 영상의 부분 영상, img2: 안경 영상의 부분 영상
          img1 = img[sy:ey, sx:ex]   # shape=(h, w, 3)
          img2 = glasses[:, :, 0:3]  # shape=(h, w, 3)
          alpha = 1. - (glasses[:, :, 3] / 255.)  # shape=(h, w)
           
          # BGR 채널별로 두 부분 영상의 가중합
          img1[..., 0] = (img1[..., 0] * alpha + img2[..., 0] * (1. - alpha)).astype(np.uint8)
          img1[..., 1] = (img1[..., 1] * alpha + img2[..., 1] * (1. - alpha)).astype(np.uint8)
          img1[..., 2] = (img1[..., 2] * alpha + img2[..., 2] * (1. - alpha)).astype(np.uint8)
      

9. 특징점 검출과 매칭

  1. 코너 검출

    • image-20210126092522678
    • cv2.cornerHarris(src, blockSize, ksize, k)
    • cv2.goodFeaturesToTrack(image, maxCorners, qualityLevel, minDistance)
    • cv2.FastFeatureDetector_create(, threshold=None, nonmaxSuppression=None, type=None)
      cv2.FastFeatureDetector.detect(image) -> keypoints
    • 예제 및 사용법은 강의 자료 참조
  2. 특징점 검출 (local 영역만의 특징(Discriptor )을 가지는 곳을 특징점 이라고 한다.)

    • SIFT, KAZE, AKAZE, ORB
    • 아래의 방법들을 사용해서 feature 객체 생성
    • cv2.KAZE_create(, …) -> retval
    • cv2.AKAZE_create(, …) -> retval
    • cv2.ORB_create(, …) -> retval
    • cv2.xfeatures2d.SIFT_create(, …) -> retval
    • feature.detect(image, mask=None) -> keypoints
    • cv2.drawKeypoints(image, keypoints, outImage, color=None, flags=None) -> outImage
  3. 기술자 (Descriptor, feature vector)

    • image-20210126093448937
    • 특징점 근방의 Local feature을 표현하는 실수 또는 이진 벡터. 위에서는 하나의 특징점이 64개 원소의 백터를 기술자로 가진다.
    • 실수 특징 백터. 주로 백터 내부에는 방향 히스토그램을 특징 백터로 저장하는 알고리즘 : SIFT, SURF, KAZE
    • Binary descriptor. 주변 픽셀값 크기 테스트 값을 바이너리 값으로 저장하는 알고리즘 : AKAZE, ORB, BRIEF
    • 위 2. 특징점 검출에서 만든 feature 객체를 사용
      • cv2.Feature2D.compute(image, keypoints) -> keypoints, descriptors (이미 keypoint 있다면)
      • cv2.Feature2D.detectAndCompute(image) -> keypoints, descriptors
    • image-20210126094008801
    • KAZE, AKAZE이 속도 면에서 괜찮은 알고리즘. SIFT가 성능면에서 가장 좋은 알고리즘
  4. 특징점 매칭 (feature point matching)

    • image-20210126094928068
    • matcher 객체 생성 : cv2.BFMatcher_create(, normType=None, crossCheck=None)
    • matching 함수1 : matcher.match(queryDescriptors, trainDescriptors)
    • matching 함수2 : matcher.knnmatch(queryDescriptors, trainDescriptors)
    • cv2.drawMatches(img1, keypoints1, img2, keypoints2)
  5. 좋은 매칭 선별

    • 가장 좋은 매칭 결과에서 distance 값이 작은 것부터 사용하기 위해,

    • cv2.DMatch.distance 값을 기준으로 정렬 후 상위 N개 선택

    • # 특징점 매칭
      matcher = cv2.BFMatcher_create()
      matches = matcher.match(desc1, desc2)
           
      # 좋은 매칭 결과 선별 1번 (선발되는 mathcing 수는 내가 선택하기 나름)
      matches = sorted(matches, key=lambda x: x.distance)
      good_matches = matches[:80]
      # 좋은 매칭 결과 선별 2번 (전체 매칭 3159개 중, 384개가 선발됨)
      good_matches = []
      for m in matches:
      if m[0].distance / m[1].distance < 0.7:
      good_matches.append(m[0])
           
      # 특징점 매칭 결과 영상 생성
      dst = cv2.drawMatches(src1, kp1, src2, kp2, good_matches, None)
      
  6. 호모그래피와 영상 매칭

    • image-20210126100307371

    • cv2.findHomography(srcPoints, dstPoints) -> retval, mask

    • good_matches에서 queryIdx, trainIdx 와 같이 2장의 이미지 각각에 대한 특징점 검출 됨.

    • pts1 = np.array([kp1[m.queryIdx].pt for m in good_matches] ).reshape(-1, 1, 2).astype(np.float32) pts2 = np.array([kp2[m.trainIdx].pt for m in good_matches] ).reshape(-1, 1, 2).astype(np.float32)

    • H, _ = cv2.findHomography(pts1, pts2, cv2.RANSAC)

    • # 좋은 매칭 결과 선별
      matches = sorted(matches, key=lambda x: x.distance)
      good_matches = matches[:80]
      # 호모그래피 계산
      pts1 = np.array([kp1[m.queryIdx].pt for m in good_matches]
      ).reshape(-1, 1, 2).astype(np.float32)
      pts2 = np.array([kp2[m.trainIdx].pt for m in good_matches]
      ).reshape(-1, 1, 2).astype(np.float32)
      # Find Homography
      H, _ = cv2.findHomography(pts1, pts2, cv2.RANSAC)
      # 일단 matching된거 그리기
      dst = cv2.drawMatches(src1, kp1, src2, kp2, good_matches, None,
      flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
      # perspectiveTransform 하기 위한 다각형 꼭지점 설정
      (h, w) = src1.shape[:2]
      corners1 = np.array([[0, 0], [0, h-1], [w-1, h-1], [w-1, 0]]
      ).reshape(-1, 1, 2).astype(np.float32)
      # perspectiveTransform 적용
      corners2 = cv2.perspectiveTransform(corners1, H)
      corners2 = corners2 + np.float32([w, 0]) # drawMatches에서 오른쪽 영상이 왼쪽 영상 옆에 붙어서 나타나므로, 오른쪽 영상을 위한 coners2를 그쪽까지 밀어 줘야 함
      # 다각형 그리기
      cv2.polylines(dst, [np.int32(corners2)], True, (0, 255, 0), 2, cv2.LINE_AA)
      
    • image-20210126101521138
  7. 이미지 스티칭

  • 동일 장면의 사진을 자연스럽게(seamless) 붙여서 한 장의 사진으로 만드는 기술

  • 특징점과 matching 등등 매우 복잡한 작업이 필요하지만, OpenCV에서 하나의 함수로 구현되어 있다.

  • cv2.Stitcher_create(, mode=None) -> retval, pano

  • # 이미지 가져오기
    img_names = ['img1.jpg', 'img2.jpg', 'img3.jpg']
    imgs = []
    for name in img_names:
    img = cv2.imread(name)
    imgs.append(img)
    # 가져온 이미지, Stitcher에 때려넣기
    stitcher = cv2.Stitcher_create()
    _, dst = stitcher.stitch(imgs)
    cv2.imwrite('output.jpg', dst)
    
  1. : AR 비디오 플레이어

    • image-20210126101754082

    • 아래의 코드는 핵심만 기술해 놓은 코드. 전체는 ARPlayer.py파일 참조

    • # AKAZE 특징점 알고리즘 객체 생성
      detector = cv2.AKAZE_create()
      # 기준 영상에서 특징점 검출 및 기술자 생성
      kp1, desc1 = detector.detectAndCompute(src, None)
      # 해밍 거리를 사용하는 매칭 객체 생성
      matcher = cv2.BFMatcher_create(cv2.NORM_HAMMING)
      while True:
          ret1, frame1 = cap1.read() # 카메라 영상(Reference Image 나옴)
          # 호모그래피 계산
          H, inliers = cv2.findHomography(pts1, pts2, cv2.RANSAC)
          # 비디오 프레임을 투시 변환
          video_warp = cv2.warpPerspective(frame2, H, (w, h))
           
          white = np.full(frame2.shape[:2], 255, np.uint8) # Video 파일
          white = cv2.warpPerspective(white, H, (w, h))
           
          # 비디오 프레임을 카메라 프레임에 합성
          cv2.copyTo(video_warp, white, frame1)
      

10. 객체 추적과 모션 백터

  1. 배경 차분 : 정적 배경 차분

    • 배경 차분(Background Subtraction: BS) : 등록된 배경 이미지과 현재 입력 프레임 이미지와의 차이(img-src) 영상+Threshold을 이용하여 전경 객체를 검출
    • image-20210128090501840
    • 위의 Foreground mask에다가, 가이시안 필터 -> 레이블링 수행 -> 픽셀 수 100개 이상은 객체만 바운딩 박스 표시
    • image-20210128090747725
  2. 배경 차분 : 이동 평균 배경

    • 위의 방법은, 조도변화에 약하고 주차된 차도 움직이지 않아야 할 민큼 배경 이미지가 불변해야 한다.
    • 이와 같은 평균 영상을 찾자
      image-20210128091052381
    • 매 프레임이 들어올 때마다 평균 영상을 갱신
      image-20210128091120398
    • cv2.accumulateWeighted(src, dst, alpha, mask=None) -> dst
      즉, dst(x ,y ) = (1 - alpha) * dst(x ,y ) + alpha src(x ,y )
  3. 배경 차분 : MOG 배경 모델(Mixture of Gaussian = Gaussian Mixture Model))

    • 배경 픽셀값 하나하나가, 어떤 가오시간 분표를 따른다고 정의하고 그 분포를 사용하겠다.

    • 각 픽셀에 대해 MOG 확률 모델을 설정하여 배경과 전경을 구분 (구체적인 내용은 직접 찾아서 공부해보기-paper : Improved adaptive Gaussian mixture model for background subtraction)

    • image-20210128100755318

    • cap = cv2.VideoCapture('PETS2000.avi')
      bs = cv2.createBackgroundSubtractorMOG2()
      #bs = cv2.createBackgroundSubtractorKNN() # 직접 테스트 하고 사용 해야함. 뭐가 더 좋다고 말 못함.
      #bs.setDetectShadows(False) # 125 그림자값 사용 안함
           
      while True:
          ret, frame = cap.read()
          gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
          fgmask = bs.apply(gray)  # 0(검) 125(그림자) 255(백)
          back = bs.getBackgroundImage()
      
    • 동영상을 보면, 생각보다 엄청 잘되고, 엄청 신기하다…
  4. 평균 이동(Mean shift) 알고리즘

    • Tracking : Mean Shift, CamShift, Optical Flow, Trackers in OpenCV 3.x

    • Mean shift=mode seeking : 데이터가 가장 밀집되어 있는 부분을 찾아내기 위한 방법, 예를 들어 가오시안 이면 평균 위치를 찾는 방법. 아래에 하늘색 원을 랜덤으로 생성한 후, 그 내부의 빨간색 원들의 x,y평균을 찾는다. 그리고 그 x,y평균점으로 하늘색 원을 옮겨 놓는다(이래서 Mean shift). 이 작업을 반복하다 보면, 결국 하늘색 원은 빨간색 원이 가장 밀집한 곳으로 옮겨 가게 된다.
      image-20210128101804262

    • 사람의 얼굴 살색을, 히스토그램 역투영법으로 찾은 후 그 영역에 대한 평균점을 찾아가면서 Tracking을 한다.

    • cv2.meanShift(probImage, window, criteria) -> retval, window

      • probImage : 히스토그램 역투영 영생
      • window : 초기 검색 영역 윈도우 & 결과 영역 반환
    • image-20210128102346633

    • # 첫번째 프레임의 HS 히스토그램 구하기
      hist = cv2.calcHist([roi_hsv], channels, None, [45, 64], ranges)
      # 히스토그램 역투영 & 평균 이동 추적
      hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
      backproj = cv2.calcBackProject([hsv], channels, hist, ranges, 1)
      _, rc = cv2.meanShift(backproj, rc, term_crit) 
      
    • 히스토그램 역투영법, HS 히스토그램에 대해 궁금하면, 동영상 직접 찾아서 보기

    • 단점 : 객체가 항상 같은 크기이여야 함. 예를 들어, 위의 귤이 멀어져서 작아지면 검출 안된다.
  5. [Cam Sift(캠시프트)](https://fr.wikipedia.org/wiki/Camshift) 알고리즘

    • 위의 단점을 해결하기 위한 알고리즘, 위의 평균 이동 알고리즘을 이용.

    • 일단 평균 이동을 통해 박스를 이용한다. 그리고 히스토그램 역투영으로 나오는 영역에 대해서, 최적의 타원을 그린다. 만약 타원이 평균이동박스 보다 작으면, 이동박스를 작게 변경한다. 반대로 최적의 타원이 박스보다 크다면, 이동박스를 크게 변경한다. 이 과정을 반복한다.

    • cv2.CamShift(probImage, window, criteria) -> retval, window

    • # HS 히스토그램에 대한 역투영 & CamShift
      frame_hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
      backproj = cv2.calcBackProject([frame_hsv], channels, hist, ranges, 1)
      ret, rc = cv2.CamShift(backproj, rc, term_crit)
      
  6. 루카스-카나데 옴티컬 플로우(OneDrive\20.2학기\컴퓨터비전\OpticalFlow.pdf참조)

    • Optical flow : 객체의 움직임에 의해 나타나는 객체의 이동 (백터) 정보 패턴. 아래 식에서 V는 객체의 x,y방향 움직임 속도이고, I에 대한 미분값은 엣지검출시 사용하는 픽셀 미분값이다. (컴퓨터비전-윤성의교수님 강의 자료에 예시 문제 참고) image-20210129120210714

    • 추가 가정 : 이웃 픽셀은 같은 Flow를 가짐 → NxN Window를 사용하면 N^2개 방정식 → Least squares method

    • 루카스-카나데 알고리즘(Lucas-Kanade algorithm)

      • cv2.calcOpticalFlowPyrLK(…) : input parameter는 강의자료 + Official document 공부
      • Sparse points에 대한 이동 벡터 계산 → 특정 픽셀에서 옵티컬플로우 벡터 계산
      • 몇몇 특정한 점들에 대해서만, Optical Flow를 계산하는 방법
    • 파네백 알고리즘(Farneback’s algorithm)

    • cv2.calcOpticalFlowFarneback(…) : input parameter는 강의자료 + Official document 공부
    • Dense points에 대한 이동 벡터 계산 → 모든 픽셀에서 옵티컬플로우 벡터 계산
    • 이미지 전체 점들에 대해서, Optical Flow를 계산하는 방법

    • # 루카스-카나데 알고리즘(Lucas-Kanade algorithm)  
      pt1 = cv2.goodFeaturesToTrack(gray1, 50, 0.01, 10)
      pt2, status, err = cv2.calcOpticalFlowPyrLK(src1, src2, pt1, None)
      # 2개 이미지 겹친 이미지 만들기
      dst = cv2.addWeighted(src1, 0.5, src2, 0.5, 0)
      # 화면에 백터 표현하기
      for i in range(pt2.shape[0]):
          if status[i, 0] == 0:
              continue
          cv2.circle(dst, tuple(pt1[i, 0]), 4, (0, 255, 255), 2, cv2.LINE_AA)
          cv2.circle(dst, tuple(pt2[i, 0]), 4, (0, 0, 255), 2, cv2.LINE_AA)
          cv2.arrowedLine(dst, tuple(pt1[i, 0]), tuple(pt2[i, 0]), (0, 255, 0), 2)
      
    • image-20210129120901079
  7. 밀집 옵티컬플로우 (파네백 알고리즘 예제)

    • 만약 필요하다면, 아래의 코드를 그대로 가져와서 사용하기. 한줄한줄 이해는 (강의자료 보는것 보다는) 직접 찾아보고 ipynb에서 직접 쳐봐서 알아내기, 어렵지 않음

    • # dense_op1.py 
      flow = cv2.calcOpticalFlowFarneback(gray1, gray2, None,0.5, 3, 13, 3, 5, 1.1, 0)
           
      mag, ang = cv2.cartToPolar(flow[..., 0], flow[..., 1])
      hsv[..., 0] = ang*180/np.pi/2
      hsv[..., 2] = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX)
           
      bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
           
      cv2.imshow('frame', frame2)
      cv2.imshow('flow', bgr)
           
      gray1 = gray2
      
    • # # dense_op2.py
      def draw_flow(img, flow : calcOpticalFlowFarneback의 out값, step=16):
          h, w = img.shape[:2]
          y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2, -1).astype(int)
          fx, fy = flow[y, x].T
          lines = np.vstack([x, y, x+fx, y+fy]).T.reshape(-1, 2, 2)
          lines = np.int32(lines + 0.5)
          vis = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
          cv2.polylines(vis, lines, 0, (0, 255, 255), lineType=cv2.LINE_AA)
           
          for (x1, y1), (_x2, _y2) in lines:
              cv2.circle(vis, (x1, y1), 1, (0, 128, 255), -1, lineType=cv2.LINE_AA)
           
          return vis
      
    • image-20210129121417606

    • Optical flow를 사용하기 위해서 추천하는 함수들 : 맨 위가 가장 parents,super class이고 아래로 갈 수록 상속을 받는 Derived class,child class,sub class 등이 있다.

      • image-20210129121815328
  8. OpenCV 트래커

    • OpenCV 4.5 기준으로 4가지 트래킹 알고리즘 지원 (4.1 기준 8가지 지원. 사용안되는건 지원에서 빼 버린것 같다)

    • TrackerCSRT, TrackerGOTURN, TrackerKCF, TrackerMIL

    • image-20210129122329568

    • cap = cv2.VideoCapture('tracking1.mp4')
      tracker = cv2.TrackerKCF_create()
      ret, frame = cap.read()
      rc = cv2.selectROI('frame', frame)
      tracker.init(frame, rc)
      while True:
          ret, frame = cap.read()
          ret, rc = tracker.update(frame)
          rc = [int(_) for _ in rc]
          cv2.rectangle(frame, tuple(rc), (0, 0, 255), 2)
      
    • image-20210129122403908
  9. 실전 코딩: 핸드 모션 리모컨

    • 움직임이 있는 영역 검출 / 움직임 벡터의 평균 방향 검출

    • cv2.calcOpticalFlowFarneback() -> 움직임 벡터 크기가 특정 임계값(e.g. 2 pixels)보다 큰 영역 안의 움직임만 고려

    • 움직임 벡터의 x방향 성분과 y방향 성분의 평균 계산

    • mx = cv2.mean(vx, mask=motion_mask)[0]
      my = cv2.mean(vy, mask=motion_mask)[0]
      m_mag = math.sqrt(mx*mx + my*my)
             
      if m_mag > 4.0:
          m_ang = math.atan2(my, mx) * 180 / math.pi
          m_ang += 180
      
    • FastCampus_CV\opencv_python_ch06_ch10\ch10\hand_remocon.py

【Pyinstaller】Python file to EXE file (파이썬 파일 실행 파일로 만들기)

Python file to EXE file 파이썬 파일 실행 파일로 만들기

참고 동영상 : https://www.youtube.com/watch?v=UZX5kH72Yx4

$ pip install pyinstaller

$ pyinstaller --onefile -w <file_name.py>
  1. 옵션

    –onefile : 깔끔하게 exe 파일 하나만 만들어 줌

    -w : console을 열지 않음. 만약 터미널 창의 결과가 보이거나 터미널 창에 값을 입력할 console이 보여야 한다면, -w 옵선 설정하지 말기

  2. 실행 결과

    • 2개의 폴더 생성 build, dist
    • build는 지워버림 필요없음
    • dist에 .EXE 파일이 존재할 것임
    • 그거 그냥 실행하면 됨.
  • 주의할점!! 의존성이 있는 경우 : EXE파일을 dist내부에서 실행하지 말고, (아마 “$ cd ../” 위치) 바로 아래 디렉토리 위치에 EXE파일을 옮겨놓고 파일 실행하기.
    • from .ssd.modeling import detector
    • 이와 같은 문장을 python 파일에 적어놨다면, 파일의 위치가 일치해야 하므로.
  1. NSIS 라는 프로그램 이용하기
    • 이 프로그램을 이용하면, 위와 같은 의존성 문제 고려 안해도 된다.
    • 위의 방법은 패키지 내부의 .py 파일 하나만을 exe파일로 변경하는 것이 었다.
    • 패키지 전체를 하나의 installer 파일로 만들고 싶다면 이 프로그램을 이용해라.
    • drawing
    • Donwload link
    • 프로그램 사용방법은 맨 위 유투브 링크의, 6:30~8:30에 있음. 생각보다 매우 쉬우니 필요하면 해보기. -

【Attention】Attention Mechanism Overveiw

Attention and Transformer is salient mechanism in deep learning nowadays. I remain my note which I learn from reference.

0. reference

  1. a-brief-overview-of-attention-mechanism
  2. Attention mechanism with schematic
  3. the development of the attention mechanism
  4. How Transformers work in deep learning and NLP: an intuitive introduction

1. a-brief-overview-of-attention-mechanism

이 게시물 댓글이 말하길, “이 게시물은 쓰레기다.” 라고 적혀 있다. 딱 아래의 내용만 알자.

  1. What is Attention?
    • hundreds of words -압축-> several words : 정보 손실 발생.
    • 이 문제를 해소해주는 방법이 attention. : Attention allow translator focus on local or global feature(문장에 대한 zoom in or out의 역할을 해준다.)
  2. Why Attention?
    • Vanilla RNN : 비 실용적이다. Input의 길이와 Output의 길이가 꼭 같아야 한다. Gradient Vanishing/Exploding가 자주 일어난다. when sentences are long (more 4 words).
      • drawing
      • 한 단어씩 차례로 들어가 enbedding 작업을 거쳐서 encoder block에 저장된다, 각 block에는 각각 hidden vector가 존재하고 있다. 4번째 단어가 들어가서 마지막 encoder vertor(hidden vector inside)가 만들어 진다. 그것으로 Decoder가 generate words sequentially.
      • Issue : one hidden state really enough?

2. Attention mechanism

이해하기 아주 좋은 게시물 이었다.

  1. visual attention
    • many animals focus on specific parts
    • we should select the most pertinent piece of information, rather than using all available information. (전체 이미지 No, 이미지의 일부 Yes)
    • Attention 개념은 많은 곳에서 사용된다. 예를 들어서, speech recognition, translation, and visual identification of objects 에서 다 쓰인다.
  2. Attention for Image Captioning
    • Basic 이미지 캠셔닝은 아래의 방법을 사용한다. Image를 CNN을 통해서 encoder해서 feature를 얻는데 그게 Hidden state h 가 된다. 이 h를 가지고, 맨 위부터 LSTM를 통해서 첫번째 단어와 h1을 얻고, h와 h1을 LSTM에 넣어서 2번째 단어를 얻는다.
    • drawing
    • 나오는 각각의 단어는 이미지의 한 부분만 본다.따라서 이미지 전체를 압축한 h를, 일정 부분만을 보고 결과를 추출해야하는 LSTM에, 넣는 것은 비효율적이다. 이래서 attention mechanism이 필요하다.
    • attention mechanism 전체 그림
      • drawing
  3. What is an attention model? 위의 이미지에서 Attention Model의 내부는 무엇일까?
    • drawing
    • attention Model에는 n개의 input이 들어간다. 위의 예시에서 y1 ~ yn이 되겠다.
    • 출력되는 z는 모든 y의 summary 이자, 옆으로 들어가는 c와도 연관된 information이다.
    • 각 변수의 의미
      • C : context, beginning.
      • Yi : the representations of the parts of the image. (예를 들어서 이미지 Final feature map의 Channel=n개라면, 1개 Channel을 Yi에 부여한다.)
      • Z : 다음 단어 예측을 위한 Image filter 값.
    • attention model 분석하기 (저게 최대 화질 이미지..)
      1. tanh를 통해서 m1,…mn이 만들어 진다. mi는 다른 yj와는 관계없이 생성된다는 것이 중요한 Point이다.
      2. softmax를 사용해서 각 yi를 얼마나 비중있게 봐야 하는가?에 대한 s1,s2…sn값이 나온다. argmax가 hard, softmax를 soft의 개념이라고 한다.
      3. 최종 Z는 y1 ,y2 …yn를 s1 ,s2 … sn를 사용해서 the weighted arithmetic mean을 한 것이다.
        image
    • 위 전체 과정을 아래와 같이 수정하는 방법도 있다.
      • tanh를 dot product로 바꾸기 : any other network, arithmetic(Ex.a dot product) 으로 수정될 수 있다. a dot product 는 두 백터의 연관성을 찾는 것이니, 좀 더 이해하기 쉽다.
      • hard attention
        1. 지금까지 본 것은 “Soft attention (differentiable deterministic mechanism)” 이다. hard attention은 a stochastic process이다. 확률값은 si값을 사용해서 랜덤으로 yi를 선택한다. (the gradient by Monte Carlo sampling)
        2. drawing
        3. 하지만 gradient 계산이 직관적인 Soft Attention를 대부분 사용한다.
    • 이 이후에, Z를 사용하는LSTM은, i번째 단어를 예측하고 다음에 집중해야하는 영역에 대한 정보를 담은 h_i+1을 return한다.
  4. Learning to Align in Machine Translation (언어 모델에서도 사용해보자)
    • Image와 다른 점은 attention model에 들어가는 y1,y2 … yi 값은, 문자열이 LSTM을 거쳐나오는 연속적인 hidden layer의 값이라는 것이다.
    • drawing
    • Attention model을 들여다 보면, 신기하게도 하나의 input당 하나의 output으로 matcing된다. 이것은 translation 과제에서 장점이자, 단점이 될 수 있다.

3. the development of the attention mechanism

drawing

  • 핵심 paper
    1. Seq2Seq, or RNN Encoder-Decoder (Cho et al. (2014), Sutskever et al. (2014))
    2. Alignment models (Bahdanau et al. (2015), Luong et al. (2015))
    3. Visual attention (Xu et al. (2015))
    4. Hierarchical attention (Yang et al. (2016))
    5. Transformer (Vaswani et al. (2017))
  1. Sequence to sequence (Seq2Seq) architecture for machine translation
    • two recurrent neural networks (RNN), namely encoder and decoder.
    • drawing
    • RNN,LSTM,GRU’s hidden state (from the encoder)를 the decoder에 source information 보낸다.
    • a fixed-length vector, only last one Hidden state 만을 이용해서 Decoding을 하는 것은 Long sentences issue가 발생할 수 있다.
    • RNN으로는 Gradient exploding, Gradient vanishing 문제가 크게 일어난다.
  2. Align & Translate
    • RNN을 한 방향으로만 하지말고, 양방향으로 한다. 이를 통해 얻은 at1, at2… atT를 사용해서, X1..XT 중 어떤것에 더 attetion할지에 대한 정보를 담을 수 있다.
    • 아래의 형태 말고도, 논문에는 더 많은 형태의 모델을 제시해놓았다.
    • drawing
  3. Visual attention
    • the image captioning problem 에서 input image와 oput word를 align 하기를 시도 했다.
    • CNN으로 feature를 뽑고, 그 정보를 RNN with attention 사용하였다. 위의 #2내용 다시 참조.
    • translation 보다 다른 많은 문제에서 attention을 쉽게 적용한 사례중 하나이다.
    • drawing
  4. Hierarchical Attention
    • effectively used on various levels
    • attention mechanism 이 classification problem에서도 쓰일 수 있다는 것을 보였다.
    • 내가 그림만 보고 이해하기로는 아래와 같은 분석을 할 수 있었다.
    • 2개의 Encoder를 사용했다. (word and sentence encoders)
    • drawing
  5. Transformer and BERT
    1. paper
    2. multi-head self-attention : 시간 효율적, representation을 하는데 매우 효율적이다. Convolution, recursive operation을 삭제하기 때문이다. 이 모듈에 대해서는 나중에 공부해볼 예정이다.
    3. BERT 는 pretrains bi-directional representations with the improved Transformer architecture. 그리고 XLNet, RoBERTa, GPT-2, and ALBERT 와 같은 논문들이 나오는데에 큰 도움을 주었다.
  6. Vision Transformer
    1. Transformer virtually replaces(대체해 버렸다) convolutional layers rather than complementing(보완하는게 아니라) them
    2. CNN’s golden age. Transformer에 의해서 RNN, LSTM 등이 종말을 마지한 것처럼.
  7. Conclusion

4. How Transformers work intuitively

  • The famous paper “Attention is all you need” in 2017 changed the way we were thinking about attention
  • Transformer의 기본 block은 self-attention이다.
  1. Representing the input sentence (sequential 한 데이터를 포현(함축)하는 방법)
    • transformer 의 탄생 배경 : “entire input sequence를 넣어주는거는 어떨까? 단어 단위로 잘라서 (tokenization) sequential 하게 넣어주지 말고!” (RNN과 LSTM과는 다르다. 그들은 sequentially 하게 일을 처리한다.)
    • tokenization를 해서 하나의 set을 만든다. 여기에는 단어가 들어가고, 단어간의 order는 중요하지 않다. (irrelevant)
    • 집합 내부 단어들을, (대체, 정사하다) project, (words를) in a distributed geometrical space로, 해야한다. (= word embeddings)
    • (1) Word Embeddings
      1. character <- word <- sentence와 같이 distributed low-dimensional space로 표현하는 것.
      2. 단어들은 각각의 의미만 가지고 있는게 아니라, 서로간의 상관관계를 가지기 때문에 3차원 공간상에 word set을 뿌려놓으면 비슷한 단어는 비슷한 위치에 존재하게 된다. visualize word Embeddings using t-SNE
      3. 단어 임배딩이 무엇이고 어떻게 구현하는가 : 특정 단어를 4차원 백터로 표현하는 방법
      4. drawing
      5. “이런게 있구나” 정도로만 이해했다. 어차피 내가 NLP 할 것은 아니니까.
    • (2) Positional encodings
      1. drawing
      2. 위에서는 단어의 order를 무시한다고 했다. 하지만 order (in a set) 을 모델에게 알려주는 것은 매우 중요하다.
      3. positional encoding : word embedding vector에 추가해주는 set of small constants(작은 상수) 이다.
        • sinusoidal function (sin함수) 를 positional encoding 함수로 사용한다.
        • sin함수에서 주파수(y=sin(fx), Cycle=2pi/f)와 the position in the sentence를 연관시킬 것이다.
        • 예를 들어보자. (위의 특정 단어를 4차원 백터로 표현한 그림 참고)
        • 만약 32개의 단어가 있고, 각각 1개의 단어는 512개의 백터로 표현가능하다.
        • 아래와 같이 1개 단어에 대한 512개의 sin(짝수번쨰단어),cos(홀수번째단어)함수 결과값을 512개의 백터 값으로 표현해주면 되는 것이다.
        • drawing
        • 이런 식으로 단어를 나타내는 자체 백터에 에 순서에 대한 정보를 넣어줄 수 있다.
        • 예를 들어, 영어사전 안에 3000개의 단어가 있다면 3000개의 단어를 각각 2048개의 백터로 표현해 놓는다. 프랑스어사전 안에서 그에 상응하는 3000개의 단어를 추출하고, 단어 각각 2048개의 백터로 임배딩 해놓는다. 그리고 아래의 작업을 한다고 상상해라.
  2. Encoder of the Transformer
    • Self-attention & key, value query
      • drawing
      • 매우 추천 동영상, Attention 2: Keys, Values, Queries : 위의 Attention Mechanism을 다시 설명해 주면서, key values, Query를 추가적으로 설명해준다.
      • 위의 ‘What is an attention model’ 내용에 weight 개념을 추가해준다. C,yi,si 부분에 각각 Query, key, Value라는 이름의 weight를 추가해준다.
      • NER = Named Entity Recognition : 이름을 보고, 어떤 유형인지 예측하는 test. Ex.아름->사람, 2018년->시간, 파리->나라
      • 직관적으로 이해해보자. ‘Hello I love you’라는 문장이 있다고 치자. Love는 hello보다는 I와 yout에 더 관련성이 깊을 것이다. 이러한 관련성, 각 단어에 대한 집중 정도를 표현해 주는 것이, 이게 바로 weight를 추가해주는 개념이 되겠다. 아래의 그림은 각 단어와 다른 단어와의 관련성 정도를 나타내주는 확률 표 이다.
      • drawing
    • Multi Head Attention
      • 참고 동영상, Attention 3: Multi Head Attention
      • I gave my dog Charlie some food. 라는 문장이 있다고 치자. 여기서 gave는 I, dog Charlie, food 모두와 관련 깊은데, 이게 위에서 처럼 weight 개념을 추가해 준다고 바로 해결 될까?? No 아니다. 따라서 우리는 extra attention 개념을 반복해야 한다.
      • drawing
    • Short residual skip connections
      • 블로그의 필자는, 아래의 Skip Connection구조를 직관적으로 이렇게 설명한다.
      • 인간은 top-down influences (our expectations) 구조를 사용한다. 즉 과거의 기대와 생각이 미래에 본 사물에 대한 판단에 영향을 끼지는 것을 말한다.
    • Layer Normalization, The linear layer 을 추가적으로 배치해서 Encoder의 성능을 높힌다.
    • drawing
  3. Decoder of the Transformer
    • DETR 와 Vit 논문안에 있는 내용 참조
  4. Attention 4 - Transformers
    • Multi-head attention is a mechanism to add context that’s not based on RNN
    • drawing
    • 아래 사진은 그냥 기본적인 내용의 설명 그림.
    • drawing
    • Input에는 문장이 들어가고, Multi-head Attention에서 각 단어에 대한 중요성을 softmax(si)로 계산 후, 그것을 가중치 wi로 두고, 원래 단어와 곱해놓는다. (What is an attention model?의 사진 참조)
    • Multi-head Attention doesn’t care about position. But Positional Enxoding push to care more about position.
  5. Why Multi-head Attention can be replaced RNN
    • drawing

【Domain-Adaptation】Deep Domain Adaptation Basics

Deep Domain Adaptation Basics

  • 2021.02.16 전체 복습 후 느낀점 : 정말 이 분야를 제대로 하고 싶다면, 아래의 내용들은 느낌만 알아가는데에 좋다. 더 자세한 내용들은 결국 논문을 찾아서 읽어야 한다.

Reference (Study order)

  1. https://towardsdatascience.com/deep-domain-adaptation-in-computer-vision-8da398d3167f
  2. http://www.eecs.umich.edu/eecs/pdfs/events/4142.pdf
  3. https://sudonull.com/post/9686-Overview-of-Deep-Domain-Adaptation-Basic-Methods-Part-1

1. Deep Domain Adaptation In Computer Vision

  • 이 Reference가 좋은 자료 인지 모르겠다. 애매모호 하기만 하다.

1. introduction

  • 특정 신겨망 모델을 NYC dataset로 학습시키고, Manhattan에서는 잘 동작하지만 Paris에서 사용하니 문제 발생!
  • images from different viewing angles / different lighting conditions
    • source distribution = source dataset : Pre-train을 위해서 사용했던 데이터셋(의 분포, 분야)
    • targer distribution = source dataset : domain changed 된, dataset.
  • 일반적으로, damain adaptation은 한개 혹은 그 이상의 데이터셋을 사용한다.

2. Domain Adaptation Categories

  • 참고 논문
    1. Deep Visual Domain Adaptation: A Survey (2018)
    2. A Survey of Unsupervised Deep Domain Adaptation (2019)
    3. 과제의 복잡성은 labeled/unlabeld data의 양, source/target의 차이 정도로 분류 가능하다.
  • domain adaptation : the task space is the same(해야하는 과제는 같다. maybe Ex. obejct detection, segment. , kinds of labels) But input domain is divergent.
  • 크게 분류
    • homogeneous (동족의) = source : target = 1 : 1 데이터셋
    • heterogeneous (여러 종류,종족의) = compound = source : target = 1 : 3 데이터셋
  • target data에 따라서
    • supervised : target data is labeled
    • semi-supervised : labeled and unlabeled
    • self-supervised : No labeled data

3. Task Relatedness(상관성, 유사성)

  • task relatedness : source가 task이 얼마나 유사한가?
  • Task Relatedness를 정의(수치화)하는 방법
    1. how close their parameter vectors.
    2. how same features
  • 그럼에도 불구하고, domain adaptation을 사용할 수 있는지 없는지 판단하는 방법은, 직접 학습시키고 테스트 해봐야한다.

4. One-Step Domain Adaptation

3가지 basic techniques

  1. divergence-based domain adapatation.
  2. adversarial-based domain adaptation using GAN, domain-confusion loss.
  3. reconstruction using stacked autoencoders.

하나씩 알아가보자.

4-1 Divergence-based Domain Adaptation

  • some divergence criterion (핵심 차이점 기준?) 을 최소화하고, domain-invariant feature representation 을 찾아내는 것(achieve) (domain 변화에도 변하지 않는 feature extractor Ex. 어떤 신호등 모양이든 같은 신호등feature가 나오도록)
  • 아래에 3가지 방법이 나오는데, 느낌만 가져가기. 뭔 개소리인지 정확히 모르겠다.
  • (1) MMD - Maximum Mean Discrepancy
    • drawing
    • two-stream architecture는 파라메터 공유하지 않음.
    • Soft-max, Regularization(Domain-discrepancy) loss를 사용해서, two-architecture가 similar feature representation(=extractor)가 되도록 만든다.
  • (2) CORAL - Correlation Alignment
    • drawing
    • (b)처럼 distribution만 맞춘다고 해서 해결되지 못한다. (c)처럼 soure에 target correlation값을 추가함으로써 align시켜준다.
    • align the second-order statistics (correlations) instead of the means
    • 좋은 논문 : Using a differentiable CORAL loss.
  • (3) CCD - Contrastive Domain Discrepancy
    • label distributions 을 사용한다. (라벨별 확률 분포) by looking at conditional distributions(조건적인 P(확률분포|특정라벨))
    • 두 데이터의 각 라벨에 대해, 교집합 domain feature를 찾는다.
    • minimizes(최소화 한다) the intra-class discrepancy, maximizing(최대화 한다) the inter-class discrepancy.
    • 좋은논문 : target labels are found by clustering. CCD is minimized.
  • 이런 방법으로
    1. 이런 방법을 optimal transport 라고 한다.
    2. 두 데이터 간의 feature and label distributions 가 서로 비슷해지게 만들거나,
    3. 두 architecture(extractor, representation) 간의 차이가 줄어들게 만든다.

4-2 adversarial-based domain adaptation

  • source domain에 관련된 인위적인 target data를 만들고, 이 데이터를 사용해서 target network를 학습시킨다. 그리고 진짜 target data를 network에 넣어서 결과를 확인해 본다.
  • (1) CoGAN - source와 연관성 있는 target data 생성
    • drawing
    • 일부 weight sharing 하는 layer는 domain-invariant feature space extractor로 변해간다.
  • (2) source/target converter network - source와 연관성 있는 target data 생성
    • Pixel-Level Domain Transfer (2016 - citation 232)
    • drawing
    • 2개의 discriminator를 사용한다.
    • 첫번째 discriminator는 source에 의해 생성된 target data가 그럴듯 한지 확인하고.
    • 두번째 discriminator는 생성된 target data와 source의 상관성이 있는지 확인한다.
    • 특히 이 방법은 unlabeled data in the target domain 상황에서 사용하기 좋다.
  • (3) Get rid of generators - 어떤 domain에서도 invariable-feature를 추출하는 extractor 제작
    • Unsupervised Domain Adaptation by Backpropagation (2015 - citation 2000)
    • domain confusion loss in addition to the domain classification loss : classificator가 어떤 domain의 data인지 예측하지 못하게 한다.
    • drawing
    • gradient reversal layer는 the feature distributions를 일치시키기 위해 존재한다.(두 데이터 간의 특징 분포를 일치시키기 위해)
      • 파랑색 부분은 class label를 잘 찾으려고 노력하고
      • 초록색 부분은 domain classifier가 틀리도록 학습되면서(input이미지에 대해서 어떤 domain에서도 invariable-feature를 추출하는 extractor를 만든다), class label을 잘 맞추려고 학습된다.
      • 빨간색은 그대로 domain label을 옳게 classify하도록 학습된다.
      • Generator & discriminator 구조가 아닌듯, 맞는듯한 신기한 구조를 가지고 있다.

4-3. Reconstruction-based Domain Adaptation

  • (1) DRCN
    • Deep Reconstruction-Classification Networks for Unsupervised Domain Adaptation (2016 - citation 435)
    • drawing
    • (i) classification of the source data (ii) reconstruction of the unlabeled target data
    • (i) 나중에 input에 target을 넣어도 잘 classifying 하게 만듬. (ii) reconstruction된 data가 task data와 유사하도록 학습된다. 따라서 초반 layer도 task data에 대한 정보를 함축하도록 만들어 진다.
    • 논문에서는, 위 신경망의 Input=Source Reconstruction=Target을 넣고 먼저 학습시킨다. 그리고 반대로 Input=Target Reconstruction=Source가 되도록 다시 학습시켰다고 한다.
    • 아래와 같은 학습 방법도 가능하다.
    • drawing
  • (2) cycle GANs
  • (3) conditional GANs
    • encoder-decoder GAN
    • conditional GANs are used to translate images from one domain to anothe
    • Pix2Pix GAN이 대표적이다.
    • reference를 주면, 그것을 이용해 ouput을 만드는 GAN을 말한다.
    • drawing

5. Conclusion

  • Deep domain adaptation/ enables us to get closer/ to human-level performance/ in terms of the amount of training data. (원하는 task data (to be relative real-scene)가 적을 때 유용하게 사용할 수 있는 방법이다.)
  • drawing


2. Domain adaptation - Boston Universiry

  • Domain Adaptation에 대한 설명을 그림으로 아주 재미있게 표현해놓은 좋은 자료.
  • 하지만 아래 내용은 참고만 할 것. 논문을 찾아 읽어봐야 한다.
  • Applications to different types of domain shift
    1. From dataset to dataset
    2. From simulated to real control
    3. From RGB to depth
    4. From 3D-CAD models to real images
  • models adapted without labels (NO labels in target domain)
    • adversarial alignment
    • correlation alignment
  • D = distributions/ xi, zj = Image/ yi = Label :
    drawing

(1) From dataset to dataset, From RGB to depth

  • DRCN와 유사하지만 좀 더 복잡한 형태의 confusion-loss 사용하는 논문
    • Simultaneous Deep Transfer Across Domains and Tasks - citation 889
    • drawing
    • domain classifier loss : Domain이 source인지 target인지 판단한다. 잘못 판단하면 Loss가 커지므로, 잘 판단될 수 있도록 학습 된다.
    • domain confusion loss : Domain이 source인지 target인지 잘못 판단하게 만든다.
    • 한번은 classifier loss로, 다른 한번은 confusion loss로 학습시키므로써, Network가 Source에서만 잘 동작하게 만드는게 아니라, Target에서도 잘 동작하게 만든다.
    • 지금의 feature extractor는 너무 source중심으로 domain loss통해서 target에 대한 정보도 feature extractor가 학습하게 만드는 것이다.
    • Target으로 Test해봤을 때, 그냥 Source만으로 학습된 Network를 사용하는 것보다 이 과정을 통해서 학습된 Network에서 더 좋은 Accuracy 결과가 나왔다.
  • ADDA

(2) From simulated to real control

(3) From 3D-CAD models to real images

drawing

【mmdetection】 mmdetection Tutorial and Overview

0. Readme 정리

  1. mmdetection/docs/model zoo 정리

    • mmdetection/configs : ‘다양한 종류의 신경망’ 모델 설계를 위한, model_config.py 파일이 존재한다.

    • 각 ‘신경망 모델’이름의 폴더에 들어가면, readme.md가 따로 있고, 그곳에 backbone, **style(pytorch/caffe 두가지 framework 사용됨)**, lr-schd, memory, fps, boxAP, cong, Download(model/log) 가 적혀 있어서 참고하면 된다.

  2. installation(mmdetection/docs/get_started.md)

    • Prerequisites
      • PyTorch 1.3 to 1.6
      • MMCV
    • installation
      • install mmcv : 이미 빌드가 된 버전 다운로드 & Git을 다운받아 setup을 실행해 직접 빌드하거나.
      • install mmdetection : Only Github download + 직접 setup & build
      • note - 코드 수정은 reinstall이 필요없이, 바로 적용될 것 이다.
      • 혹시 docker를 사용하고 싶다면, dockerfile도 사용해보기
  3. Getting Started (아래의 내용들 빠르게 공부하자)

    1. mmdetection/demo/MMDet_Tutorial.ipynb
    2. mmdetection/docs/with existing dataset
    3. mmdetection/docs/with new dataset
    4. mmdetection/demo/webcam_demo.py for beginners
    5. mmdetection official documetation : 여기에도 좋은 내용이 많다. 3번까지 공부하고 5번의 내용과 이 documentation의 내용 중 더 맘에 드는 내용을 공부해보자.
    6. (여기부터는 필요하면 공부하자. 내가 나중에 어떤 패키지를 가져와서 코드를 수정할지 모르니..)There are also tutorials for finetuning models, adding new dataset, designing data pipeline, customizing models, customizing runtime settings and useful tools.
  4. 느낀점 ⭐⭐

    • 생각보다, 거의 Torch, Torchvision 와 같은 큰~모듈 처럼, 내부를 모르는 채로 원하는 함수를 구글링, Official Document 검색으로 찾아서 해야할 만큼 큰 모듈이다. 내가 원하는 모델을 분석하기 위해서 이 패키지를 사용한다는 것은… 멍청한 행동인 것 같다. 그만큼 사소한거 하나하나가 모두 구현되어 있는 큰~모듈이다.
    • 만약 내가 어떤 신경망 모델의 내부 코드가 궁금하다면, Github에서 그 신경망 모델의 이름을 검색하고, 그 신경망만을 위한 코드를 보는것이 낫겠다.
    • 이전에는 이런 생각을 했다. “만약 SSD를 공부하고 싶다면, SSD 패키지를 Github에서 검색해서 사용하는 것 보다는, mmdetection에서 SSD가 어떻게 구현되어 있는지, 어떤 모듈을 사용하는지 찾아보는게 더 좋지 않나? 그게 더 안정화된 코드고 빠른 코드 아닐까? 그래야 내가 혹시 필요한 모듈을 그대로 가져와서 쓸 수 있지 않을까??” 라고 생각했다. 물론 맞는 말이다….
    • 하지만 지금 시간이 급하니.. 정말 필요할 때, ‘2. docs/with existing dataset.md’ 에서 나온 방법을 이용해서, test.py와 train.py를 디버깅하고 어떤 흐름으로, 어떤 함수와 클래스를 이용하며 학습이 되고, 테스트가 되는지 찾아보는 시간을 가지는 것도 좋을 듯 하다.
    • 그럼에도 불구하고, 만약 내가 BlendMask 라는 함수를 수정해서 , 선배님처럼 The Devil Boundary Mask 모델을 만들고 싶다면 mmdetection이나, detectron2를 사용하지 않아도 될 수 있다. 하지만 그래도!! Developer for practice로서, mmdetection과 detectrion2 사용법과 코드가 돌아가는 내부 흐름은 알아두어야 한다고 생각한다.
    • 따라서 개인 컴퓨터가 생기면 디버깅을 하면서, 직접 내부 흐름을 살펴보는 시간도 가져보자.

0. colab 전용 환경 설정

아래에 코드에 간단한, 에러해결의 고민이 적혀있다. 참고해도 좋지만, 새로운 환경에서 mmcv와 mmdetection을 설치하기 위해서, 그냥 주어진 mmcv와 mmdetection의 [github, official_document] 자료를 다시 읽어보고 공부해보는게 더 좋을 듯하다.

from google.colab import drive
drive.mount('/content/drive')
%cd /content/drive/MyDrive/GCPcode/torch_package
!ls

# !pip install torch==1.6.0 torchvision==0.7.0 # -> 오류 발생 이거 때문인지는 모름.
!pip install -U torch==1.5.1+cu101 torchvision==0.6.1+cu101 -f https://download.pytorch.org/whl/torch_stable.html
import torch ; torch.__version__
# Colab : 아래 나오는 Restart runtime 눌러야 버전 변경 됨.

import torch ; import torchvision
torch.__version__, torchvision.__version__

# Check nvcc version
!nvcc -V
# Check GCC version
!gcc --version

# colab error defence
!pip install addict==2.2.1
!pip install yapf==0.28.0
!pip install Pillow==7.0.0
from addict import Dict
from yapf.yapflib.yapf_api import FormatCode

"""
# 이렇게 설치해서 그런지 에러가 나는데..? GCC, GUDA 버전문제라고? torch, GUDA 버전문제라고?
#!git clone https://github.com/open-mmlab/mmcv.git
%cd /content/drive/MyDrive/GCPcode/torch_package/mmcv
!MMCV_WITH_OPS=1 python setup.py develop
# Finished processing dependencies for mmcv-full==1.2.5
# 에러 이름 : linux-gnu.so: undefined symbol 
# 해결 : mmcv.__version : 1.2.5 말고 1.2.6으로 설치하게 두니 설치 완료.
# git으로 설치해서 직접 빌드하는 거는 왜... 1.2.5로 다운받아지는 거지? 모르겠다.
"""
# mmcv Readmd.md 처럼 위의 셀로, 쿠타, 토치 버전을 알고 mmcv를 정확하게 설치하는 것도 좋은 방법이다.
# pip install mmcv-full -f https://download.openmmlab.com/mmcv/dist/{cu_version}/{torch_version}/index.html
!pip install mmcv-full # colab-tuto에는 그냥 이렇게만 설치하니까 나도 일단 이렇게 설치.
# mmcv.__version__ : 1.2.6

import mmcv
mmcv.__version__

%cd /content/drive/MyDrive/GCPcode/torch_package
#!git clone https://github.com/open-mmlab/mmdetection.git
%cd /content/drive/MyDrive/GCPcode/torch_package/mmdetection

!pip install -r requirements/build.txt
!pip install -v -e .  # or "python setup.py develop"

import mmdet 
mmdet.__version__
# mmdet 2.8.0

!python mmdet/utils/collect_env.py # truble shooting

# Check mmcv installation
from mmcv.ops import get_compiling_cuda_version, get_compiler_version
print(get_compiling_cuda_version())
print(get_compiler_version())

# Check installation
# Check Pytorch installation
import torch, torchvision
print(torch.__version__, torch.cuda.is_available())
# Check MMDetection installation
import mmdet
print(mmdet.__version__)
# Check mmcv installation
from mmcv.ops import get_compiling_cuda_version, get_compiler_version
print(get_compiling_cuda_version())
print(get_compiler_version())

0.0 colab코렙에서 간단한 debugging디버깅 방법

  • def func1(a, b):
        return a / b
      
    def func2(x):
        a = x
        b = x - 1
        return func1(a, b)
      
    #########
      
    func2(1)
      
    #########
      
    %debug
    
  • 마지막 셀에 아래를 치면 바로 위에서 일어났던 에러 직전의 변수들을 직접 검색해서 찾아볼 수 있다.

  • %xmode Plain
    %pdb on
    func2(1)
    
  • 이와 같이 먼저 위에 실행해 놓으면, 에러가 발생한 후 바로 interact모드로 들어간다.

  • interact모드에서 사용할 수 있는 약어는 다음과 같은 것들이 있다.

    image-20210128202827731

  • 혹은 파이썬 코드에 import pdb; pdb.set_trace() 을 넣어둠으로써, break point를 설정할 수 있다. (근데 이렇게까지 할 거면, editor를 어떻게든 이용하는 편이 낫겠다. docker든 ssh든 다양한 방법이 있으니까)

1. demo/MMDet_Tutorial.ipynb

1.1 only inference using pretrained_model

%cd /content/drive/MyDrive/GCPcode/torch_package/mmdetection

!mkdir checkpoints
!wget -c http://download.openmmlab.com/mmdetection/v2.0/mask_rcnn/mask_rcnn_r50_caffe_fpn_mstrain-poly_3x_coco/mask_rcnn_r50_caffe_fpn_mstrain-poly_3x_coco_bbox_mAP-0.408__segm_mAP-0.37_20200504_163245-42aa3d00.pth \
      -O checkpoints/mask_rcnn_r50_caffe_fpn_mstrain-poly_3x_coco_bbox_mAP-0.408__segm_mAP-0.37_20200504_163245-42aa3d00.pth

from mmdet.apis import inference_detector, init_detector, show_result_pyplot

Choose to use a config and initialize the detector

config = 'configs/mask_rcnn/mask_rcnn_r50_caffe_fpn_mstrain-poly_3x_coco.py'

checkpoint = 'checkpoints/mask_rcnn_r50_caffe_fpn_mstrain-poly_3x_coco_bbox_mAP-0.408__segm_mAP-0.37_20200504_163245-42aa3d00.pth'

model = init_detector(config, checkpoint, device='cuda:0')

img = 'demo/demo.jpg'

result = inference_detector(model, img)

show_result_pyplot(model, img, result, score_thr=0.3)

# ** What is 'result'? **
"""
type(result) -> tuple
len(result)  -> 2
type(result[0]), type(result[1])  -> (list, list)
len(result[0]), len(result[1]) -> (80,80)
print(result[0]) # [confidence 값, bountding_box_position]
print(result[1]) # 80개 객체에 대한 w * h * channel(80) 의 bool type의 mask 정보
"""
  • 원하는 모델 Inference 하는 마법같은 방법 (mmdetection/mmddet/apis/inference)
    1. 핵심 모듈 2개만 import한다. inference_detector, init_detector, show_result_pyplot
    2. config파일은 mmdetection/config 에서 골라서 가져오기, pth파일은 미리 다운받아 놓기.
    3. init_detector으로 model 생성하기
    4. inference_detector으로 원하는 이미지 추론
    5. show_result_pyplot으로 result 시각화

1.2 Train a detector on customized dataset

  1. Modify cfg

    • mmdetection에서는 config 파일을 .py 파일을 사용한다.

      • 이 파일은 꼭 from mmcv.Config import fromfile파일과 함께 사용된다.

      • mmcv.Config.fromfile path -> 그냥 쉽게 생각하며 dictionary이다!

      • fast_rcnn_r50_caffe_fpn_1x_coco.py 기에 들어가봐도, dict이라는 dictionary생성자를 이용해서 config파일을 생성한다.

      • from mmcv import Config
        cfg = Config.fromfile('./configs/faster_rcnn/faster_rcnn_r50_caffe_fpn_mstrain_1x_coco.py')
        
      • cfg.data 를 보면 아래와 같은 Key, Value가 있는 것을 확인할 수 있다.

      • type(cfg) # cv.utils.config.Config
        type(cfg.data) # mmcv.utils.config.ConfigDict
        cfg.data 
        """
        {'samples_per_gpu': 2,
         'test': {'ann_file': 'data/coco/annotations/instances_val2017.json',
          'img_prefix': 'data/coco/val2017/',
          'pipeline': [{'type': 'LoadImageFromFile'},
           {'flip': False,
            'img_scale': (1333, 800),
            'transforms': [{'keep_ratio': True, 'type': 'Resize'},
             {'type': 'RandomFlip'},
             {'mean': [103.53, 116.28, 123.675],
              'std': [1.0, 1.0, 1.0],
              'to_rgb': False,
              'type': 'Normalize'},
             {'size_divisor': 32, 'type': 'Pad'},
             {'keys': ['img'], 'type': 'ImageToTensor'},
             {'keys': ['img'], 'type': 'Collect'}],
            'type': 'MultiScaleFlipAug'}],
          'type': 'CocoDataset'},
         ....
         ....
        
      • 위에서 확인한 Key를 아래와 같이 수정할 수 있다. . (dot) 을 이용해서 수정이 가능하다.

      •    cfg.dataset_type = 'KittiTinyDataset'
           cfg.data_root = 'kitti_tiny/'
                  
           cfg.data.test.type = 'KittiTinyDataset'
           cfg.data.test.data_root = 'kitti_tiny/'
           cfg.data.test.ann_file = 'train.txt'
           cfg.data.test.img_prefix = 'training/image_2'
                  
           ... (mmdetection/demo/MMDet_Tutorial.ipynb 파일 참조)
                  
           # The original learning rate (LR) is set for 8-GPU training.
           # We divide it by 8 since we only use one GPU.
           cfg.optimizer.lr = 0.02 / 8
           cfg.lr_config.warmup = None
           cfg.log_config.interval = 10
                  
           # Change the evaluation metric since we use customized dataset.
           cfg.evaluation.metric = 'mAP'
           # We can set the evaluation interval to reduce the evaluation times
           cfg.evaluation.interval = 12
           # We can set the checkpoint saving interval to reduce the storage cost
           cfg.checkpoint_config.interval = 12
                  
           # print(cfg)를 이쁘게 보는 방법
           print(f'Config:\n{cfg.pretty_text}')
        
      • 여기서 핵심은, cfg.data.test/train/val.type = '내가 아래에 만들 새로운 dataset' 을 집어 넣는 것이다.
  2. Regist Out Dataset

    • 데이터 셋을 다운로드 한후, 우리는 데이터 셋을 COCO format, middle format으로 바꿔줘야 한다.

    • 여기서는 아래이 과정을 수행한다.

      1. from mmdet.datasets.custom import CustomDataset
      2. CustomDataset 을 상속하는 클래스를 만들고 def load_annotations 해주기
    • middle format MMDetection 은 아래와 같은 format이다. 1. cocodata format arrangement, 2. coco format official과 비슷하다.

      • [
            {
                'filename': 'a.jpg',
                'width': 1280,
                'height': 720,
                'ann': {
                    'bboxes': <np.ndarray> (n, 4),
                    'labels': <np.ndarray> (n, ),
                    'bboxes_ignore': <np.ndarray> (k, 4), (optional field)
                    'labels_ignore': <np.ndarray> (k, 4) (optional field)
                }
            },
            ...
        ]
        
    • load_annotations를 정의하는 과정과 코드는 아래와 같다

      • 코드 요약 :

        1. 아래의 load_annotations에 들어가는 매개변수로, ann_file(type : str)에는 여기서 지정한 파일이 들어간다. cfg.data.test.ann_file = 'train.txt'
        2. train.txt파일의 첫줄을 살펴보면 아래와 같다. Pedestrian 0.00 0 -0.20 712.40 143.00 810.73 307.92 1.89 0.48 1.20 1.84 1.47 8.41 0.01
        3. data_infos는 dict들을 저장해놓은 list이다. In detail, data_infos에는 [ 1장에 이미지에 있는 객체들의 정보를 저장해둔, data_info=dictionary]들이 원소 하나하나로 들어간다.
        4. data_info의 key는 filename, width, height, ann 이다. 특히 ann의 key는 bboxes, labels 등이 있다.
        5. (self.img_prefix 와 같은 CustomDataset 클래스의 맴버변수가 쓰여서 디버깅 못함)
      • 코드 :

        • import copy
          import os.path as osp
                   
          import mmcv
          import numpy as np
                   
          from mmdet.datasets.builder import DATASETS
          from mmdet.datasets.custom import CustomDataset
                   
          @DATASETS.register_module()
          class KittiTinyDataset(CustomDataset):
                   
              CLASSES = ('Car', 'Pedestrian', 'Cyclist')
                   
              def load_annotations(self, ann_file):
                  cat2label = {k: i for i, k in enumerate(self.CLASSES)}
                  # load image list from file
                  image_list = mmcv.list_from_file(self.ann_file)
                       
                  data_infos = []
                  # convert annotations to middle format
                  for image_id in image_list:
                      filename = f'{self.img_prefix}/{image_id}.jpeg'
                      image = mmcv.imread(filename)
                      height, width = image.shape[:2]
                       
                      data_info = dict(filename=f'{image_id}.jpeg', width=width, height=height)
                       
                      # load annotations
                      label_prefix = self.img_prefix.replace('image_2', 'label_2')
                      lines = mmcv.list_from_file(osp.join(label_prefix, f'{image_id}.txt'))
                       
                      content = [line.strip().split(' ') for line in lines]
                      bbox_names = [x[0] for x in content]
                      bboxes = [[float(info) for info in x[4:8]] for x in content]
                       
                      # 진짜 필요한 변수
                  	gt_bboxes = []
                      gt_labels = []
                      # 사용하지 않은 변수
                      gt_bboxes_ignore = []
                      gt_labels_ignore = []
                       
                      # filter 'DontCare'
                      for bbox_name, bbox in zip(bbox_names, bboxes):
                          if bbox_name in cat2label:
                              gt_labels.append(cat2label[bbox_name])
                              gt_bboxes.append(bbox)
                          else:
                              gt_labels_ignore.append(-1)
                              gt_bboxes_ignore.append(bbox)
                   
                      data_anno = dict(
                          bboxes=np.array(gt_bboxes, dtype=np.float32).reshape(-1, 4),
                          labels=np.array(gt_labels, dtype=np.long),
                          bboxes_ignore=np.array(gt_bboxes_ignore,
                                                 dtype=np.float32).reshape(-1, 4),
                          labels_ignore=np.array(gt_labels_ignore, dtype=np.long))
                   
                      data_info.update(ann=data_anno)
                      data_infos.append(data_info)
                   
                  return data_infos
          
  3. Train Our Model

  • from mmdet.datasets import build_dataset
    from mmdet.models import build_detector
    from mmdet.apis import train_detector
    
  • 위의 핵심 모듈을 사용해서, 우리가 정의한 dataset을 학습시켜보자

  • # Build dataset
    datasets = [build_dataset(cfg.data.train)]
         
    # Build the detector
    model = build_detector(cfg.model, train_cfg=cfg.train_cfg, test_cfg=cfg.test_cfg)
    # Add an attribute for visualization convenience
    model.CLASSES = datasets[0].CLASSES
         
    # Create work_dir
    mmcv.mkdir_or_exist(osp.abspath(cfg.work_dir))
    train_detector(model, datasets, cfg, distributed=False, validate=True)
    
  • 실행하면, 우리가 설정한 epoch=12로 12번 학습된다.
  1. Inference with Out Model

    • img = mmcv.imread('kitti_tiny/training/image_2/000068.jpeg')
           
      model.cfg = cfg
      result = inference_detector(model, img)
      show_result_pyplot(model, img, result)
      

2. docs/with existing dataset.md

  1. 위와 똑같은 Just Inference 하는 방법
  2. Asynchronous interface
    • Inference를 동시에, 다른 input으로, 혹은 다른 model을 사용하여 돌릴 수 있는 방법이다,
    • import asyncio 라는 모듈을 사용해서 thread와 CPU, GPU의 적절한 사용을 이뤄낸다.
    • (아직 내가 사용할 방법은 아닌 것 같음)
  3. Test existing models on standard datasets
    • public datasets including COCO, Pascal VOC, CityScapes, and more dataset 종류 를 사용하는 방법. 그리고 이 dataset을 어떤 Path에다가 위치시켜야 하는지.
    • tools/test.py 등을 이용해 test를 진행한다.
    • 다양한 상황에 대해서, argparse를 어떻게 집어넣어줘야 하는지 있으니 참고
  4. Train predefined models on standard datasets
    • tools/train.py 등을 이용해 train를 진행한다. 많은 예시들이 추가되어 있으니 참고
    • 다양한 상황에 대해서, argparse를 어떻게 집어넣어줘야 하는지 있으니 참고

3. Train with customized datasets

  1. detectron2에서 봤던것 처럼, ballon dataset 을 사용해서 공부한다,

  2. STEP

    1. Prepare the customized dataset
    2. Prepare a config
    3. Train, test, inference models on the customized dataset.
  3. (1) Prepare the customized dataset

    • coco format으로 (1. cocodata format arrangement, 2. coco format official) data format을 바꿔줘야 한다.
    • coco_json_file 에 image의 path와 image의 annotation정보가 모두 있기 때문에, 사실 우리의 python 코드는 json 하나만 보면 된다!!
    • 따라서 CSV이든 XML이든 어떤 파일 형식으로 annotation된 데이터가 있다면, coco 즉 json포멧으로 annotation을 바꾸는 코드가 분명 있을거야. github에도 있을거고, 나의 블로그 Post에 【Tensorflow】, 【Keras】파일에도 이에 대한 내용이 잇었으니까 참고하도록 하자.
    • mmdetection에서도 mmcv를 이용해서 어떤 파일형식이든, coco format형식으로 바꿔주는, def convert_balloon_to_coco(ann_file, out_file, image_prefix): 함수를 예시로 주어주었다. 가능하다면 이것을 사용해도 좋은 듯 하다.
  4. (2) Prepare a config

    • ballon dataset을 사용하기 위해, 어떻게 mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_balloon.py 파일을 만들었는지 나와 있으니 참고하도록 하자. (config.py 링크)
    • 위의 KittiTiny는 from mmdet.datasets.custom import CustomDataset 를 상속받아서 dataset을 만들어서 그런지, the number of class에 대한 고려는 안했지만, 여기서는 json파일을 직접 만들었기 때문에 #class를 고려를 해줬다.
  5. (3) Train, test, inference models on the customized dataset.

    • $ python tools/train.py configs/ballon/mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_balloon.py
      $ python tools/test.py configs/ballon/mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_balloon.py work_dirs/mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_balloon.py/latest.pth --eval bbox segm
      
    • 더 다양한 case에 대한 agupare 적용방법은, 2. docs/with existing dataset.md 파일 참조

4. webcam_demo.py

  •  model = init_detector(args.config, args.checkpoint, device=device)
        
    camera = cv2.VideoCapture(args.camera_id)
      
    print('Press "Esc", "q" or "Q" to exit.')
    while True:
        ret_val, img = camera.read()
        result = inference_detector(model, img)
        ch = cv2.waitKey(1)
        if ch == 27 or ch == ord('q') or ch == ord('Q'):
            break
        model.show_result( img, result, score_thr=args.score_thr, wait_time=1, show=True)
    
  • 매우 간단.

5. mmdetection for SSD

【Self-Supervise】 Self-Supervised-Learning Basics

Self-Supervised-Learning Basics

Self-Supervised-Learning Basics on webs

  • 데이터의 사람이 만든 ‘annotation Label’이 없어도, Feature Extractor(Pre-trained Model)을 만들 수 있는 몇가지 방법들에 대해 기초만 알아보자.

0. reference

  1. https://project.inria.fr/paiss/files/2018/07/zisserman-self-supervised.pdf
  2. https://lilianweng.github.io/lil-log/2019/11/10/self-supervised-learning.html
  3. https://www.fast.ai/2020/01/13/self_supervised/

1. zisserman-self-supervised - 2018.07

  1. 모델에 대한 상세한 설명은 없다. 하지만 전체적은 윤각선을 만들기 위해 먼저 빠르게 보기로 했다.
  2. Supervise-learning : With a large-scale dataset labelled / Can Specify a training loss / Easy to Train the network
  3. why self-supervision : high Expense of dataset / supervision-starved / vast numbers of unlabelled images/videos
  4. how infants may learn : The Development of Embodied Cognition
  5. What is Self-Supervision?

    • Self-Supervision을 통해서 Feature Extrator를 생성하고, 그렇게 얻은 (self를 해서 얻은) FeatureExtractor를 가지고, 적은 데이터 만을 가지고 (supervision 처럼) Classifier를 학습시키기 위함.
  6. Three parts
    • From Images
    • From videos
    • From videos with sound

2.Part (1) - Images

  • image
  • (2014) relative positioning : Origin Image만으로도 학습이 가능하다. 이걸로 Pretrained를 시키고 나중에 supervise로 refine 학습을 진행한다.
  • (2014) colourization
  • (2014) exemplar networks : Perturb/distort image crops, Train to classify as same class
  • 학습 절차
    • backbone에 self-supervised training을 먼저 수행한다. using 위의 다양한 방법들.
    • backbone freeze!
    • 그리고 train classifier.
    • 아래와 같이 supervised를 사용한 것 보다는 낮은 성능이지만, 그래도 성능이 좋아지고 있다. 그리고 아래 오른쪽에 새로운 Self-Supervised 방법들을 그림으로 추가해 놓았다. (참고만 하자)
    • image-20210115124531206
  • (2018) Image Transformation : Unsupervised representation learning by predicting image rotations
    • image-20210115134434239
    • Rotaion으로 학습한 AlexNet Architecture 모델에서 좋은 성능이 나왔다. then Relative Position, Colourization.

2.Part (2) - Videos

  • Video의 어떤 정보를 이용해서 Self-Supervised할 수 있을까?
    1. Temporal order of the frames => 1. Video sequence orde
    2. Nearby (in time) frames => 2. Video direction
    3. Motion of objects => 3. Video tracking
  • 1. Video sequence order 를 이용하는 방법

    • 예를 들어, 3개의 동영상 frame이 있다고 가정했을 때, frames order [1 -> 2 -> 3]를 예측하게 하는 방법
    • (a) Shuffle and Learn
      • Using ‘high motion window‘(동영상 중에서도 핵심적인 Action 부분 3장) of Dataset (Action Reognition) that is imformative(유용한) training tutples
      • Input : 이미지 튜플(3장의 프레임) -> Return : 각 프레임의 순서 예측
      • image-20210115135553374
      • 위와 같이, Sequence order를 이용해서 학습시킨다. 3개의 모델은 파라메터를 공유한다. 이 모델을 사용해 [Action Label 예측 모델’/’Human Pose Estimation] 데이터셋을 이용해 fine-tuning한다.
    • (b) Odd-One-Out Networks
      • image-20210115135851163
    • Summary
      • Important to select informative data in training : 중요한 정보를 선택해서 그것으로 학습을 시켜야 한다. 예를 들어 회전, 동영상 순서 등은 data에서 매우 중요한 정보라고 할 수 있다.
      • 직접적으로 의도하지는 않았지만, (a) shuffle and learn 과정을 통해서 모델은 ‘Human Pose Estimation’ 문제에서 필요한 feature extractor를 만들어 냈을 것 이다
  • 2. Video direction(방향) 를 이용하는 방법

    • video playing forwards or backwards, 정방향 재생중인가? 뒤로 거꾸로 재생중인가?
    • gravity, entropy, friction, causality 와 같은 물리적 법칙들에 대한 feature extractor를 생성할 것이다.
    • (a) T-CAM Model
      • Input: optical flow in two chunks(10 frame 동영상 뭉치)
      • image-20210115141419097
      • 동영상 전체에서, 핵심 장면을 이용한다.
      • 위의 pre-train network를 이용해서, Fine tune & test 한다. UCF101 (human action classification) 데이터를 사용해서. 그래서 Network는 the best performance ever를 얻었다.
  • 3. Video tracking 를 이용하는 방법

    • (a) Tracking Emerges by Colorizing Videos (2018)
      • image-20210115142442479
      • color 와 object tracking에는 분명한 관계가 있다!! 위의 그림처럼 같은 색을 tracking 한다면, Tracing 과제에서 절반이상은 성공이다.
      • Input : reference Frame (Color 존재), Input Frame(monochrome 흑백)
      • image-20210115143259887
        • A는 공간유사도(내적은 두 백터가 유사할 수록 큰 값이 나오므로.)
        • C_i는 참고하는 부분의 color
        • ∑Ac는 참고 공간(f_i)을 전체 훓어 봤을때, 가장 적절한 공간(f_j)의 색깔이 (다른 공간 색과 적절히 융합(∑)되어) 계산되어 나오겠다. 정답값인 C_j와 비교해서 loss 도출.
      • image-20210115143836240
      • 괜찮은 colorization 성능 도출 되었다.
      • 이렇게 학습시킨 모델을 사용해서, 아래의 문제에서도 좋은 결과를 얻을 수 있었다. 아래의 문제에서 Reference Frame은 각각 previous frame’s Instance color, previous frame’s pose은 항상 제공된다.
      • image-20210115144026487

2.Part (3) - Videos with Sound

  • Key : Sound and Frames are Semantically consistent and Synchronized. (일관적인 관계가 있다.)
  • Objective(목적): use vision and sound to learn from each other (서로서로를 예측하기 위해 서로를 사용한다.)
  • (a) Audio-Visual Embedding (AVE-Net)
    • image-20210115144930147
    • output : Positive or Negative.
    • Results Audio features extracor들을 Sound Classification (ESC-50 dataset) 에서 사용하면 아주 좋은 성능을 얻어냄.
    • Results Visual features extracor들을 ImageNet images에서 사용해서도 좋은 성능을 얻는다.
  • (b) AVOL-Net
    • 사진의 어디서 소리가 나는지 예측하는 모델. 아래의 그림만으로 이해가 한정적이니, 논문 보기.
    • image-20210115150920684
    • input: audio and video frame
    • Output: localization heatmap on frame
  • Other papers.. : (c) Ambient sound provides supervision for visual learning / Visually indicated sounds
  • DataSet : AudioSet from Youtube
  • 지금까지 소리와 이미지의 상관성(correspondence)를 파악하고자 노력했다. 이제는 이미지와 소리와의 synchronization을 파악하는 노력을 해보자.
    • 우리는 입모양으로 그 사람이 뭐라고 말하는지 유추가 가능하다. 시각장애인들은 더더욱.
    • image-20210115151120063
    • image-20210115151510905
    • 위와 같은 방식으로 모델을 학습시킨다. 그렇게 얻은 모델을 가지고 Lip Synchronization, Active speaker detection의 과제를 수행했을때 좋은 성능을 얻을 수 있었다.

2.3 - Summary

  1. Self-supervised learning from images/video
    • without explicit supervision, 학습이 가능하다. (Pre-train모델을 만들 수 있었다.)
    • we can Learn visual representations = 적절한 Visual Feature Extractor들을 뽑을 수 있었다.
  2. Self-Supervised Learning from videos with sound
    1. Intra- and cross-modal retrieval(회복) - 서로의 데이터를 가지고, 상호 학습이 가능했다.
    2. Learn to localize sounds (어디서 소리가 나는지 예측하는 모델)
    3. 영상+소리를 pair로 사용하는 것처럼, 다른 domain pair에는 무엇이 있을까??
      • face(not lip) - voice
      • Infrared(적외선) - visible
      • RGB - Depth
      • Stereo streams - visible

2번 3번 Reference는 나중에 필요하면 공부하자.

Pagination


© All rights reserved By Junha Song.