이미지에서 blur(블러, 흐림 현상)을 확인하는 데 사용되는 다양한 알고리즘과 지표들이 있습니다. 주로 이미지의 선명도, 엣지(경계)의 강도를 측정하여 블러를 평가합니다. 대표적인 지표 및 알고리즘들은 다음과 같습니다:

 

1. Laplacian Variance (라플라시안 분산)

라플라시안 분산은 라플라시안 커널을 이용해서, 이미지의 2차미분을 구해 분산을 구하는 방법입니다. 이 분산이 뜻하는 바는 픽셀의 흩어짐 정도로, 또렷한 이미지일수록 높은 분산값을 가지며, 흐릿한 이미지일수록 낮은 분산값을 가지게 됩니다. 특정한 임계점을 두어 또렷하다, 흐리다라고 판단할 수 있습니다. 

다음의 장점을 지닙니다.

  • 간단하고 빠릅니다.: 계산이 비교적 간단하여 실시간 블러 감지에도 적합합니다.
  • 효과적임: 엣지 정보를 기반으로 하므로 다양한 종류의 블러를 효과적으로 감지할 수 있습니다.
  • 수학적 직관성: 분산을 이용한 접근 방식은 통계적으로도 타당성이 있습니다.

 

2차원 이미지에서는 다음과 같이 표현합니다. 2차미분을 구하기 위해서는 Laplacian kernel을 이용해서 구합니다. 

$\nabla^2 I = \frac{\partial^2 I}{\partial x^2} + \frac{\partial^2 I}{\partial y^2}$

이를 메트릭스 연산으로 표현하면, 라플라시안 커널이 됩니다.

$$\begin{bmatrix}
0 & 1 & 0 \\
1 & -4 & 1 \\
0 & 1 & 0
\end{bmatrix}
$$

import cv2
import numpy as np


def cal_laplacian_variance(image_array: np.ndarray):
    """라플라시안 분산을 구함

    Args:
        image_array (np.ndarray): RGB image array

    Returns:
        float: Laplacian variance
    """

    gray_image = cv2.cvtColor(image_array, cv2.COLOR_RGB2GRAY)
    laplacian = cv2.Laplacian(gray_image, cv2.CV_64F)
    return laplacian.var()

라플라시안 분산은 분산이기에 항상 0또는 양의값을 갖게됩니다. 이런 경계면이 모호한 이미지를 바로 식별할 수 있습니다.

또는 경계면이 또렷한(=focal plane)에 맞게 하는 경우의 이미지도 선택할 수 있습니다.

반응형

요약


`register_buffer`는 모델의 상태(state)로서 관리하고 싶은 텐서를 등록하는 데 사용됩니다. 즉, 이 메서드는 `state_dict`에 포함되어서, `torch.nn.Module.state_dict()`에 함께 저장되어, torch.save을 할 때, 함께 저장됩니다. 또한, ` register_buffer`으로 등록된 텐서는 기본적으로 기울기를 계산하지 않습니다.

 

기능 1. state_dict을 통해 모델을 저장/로드 할 때, 함께 포함되도록

`torch.nn.Module`로 딥러닝 네트워크를 구성하고, 필요한 텐서(non-trainable)도 함께 저장이 가능합니다.

아래의 예시를 살펴보겠습니다.

  • 9번줄: ` self.register_buffer("running_mean", torch.zeros(10))`으로 텐서를 하나 저장합니다. 이렇게되면 `self. running_mean`에 속성으로도 저장됩니다.
  • 21번줄: `torch.save(model.state_dict(), "model_with_buffer.pth")`에서 ` model.state_dict()`을 이용해서 state_dict을 저장합니다. 이 때, `. register_buffer`으로 등록한 `running_mean= torch.zeros(10)`도 함께 state_dict에 저장됩니다.
  • 24번줄: register_buffer을 사용하지않고 저장하려면, state_dict의 딕셔너리에 key-value을 별도로 이렇게 저장해줘야합니다.

 

기능 2. non-trainable parameter을 저장하는 경우

배치 정규화에서 배치 단위의 평균(mean)과 분산(var)은 통계량값만 저장하고, gradient로는 사용되지 않습니다. 이 때도 사용이 가능합니다.

 

반응형

IEEE TCSVT, 2023

 

Preliminary

  1. Instance-based methods: 인스턴스 분류기를 슈도라벨을 이용해서 학습하고, Bag-level로 집계하는 방식
  2. Attention based bag level MIL: instance feature을 뽑은 후에, 이를 집계해서 bag label을 예측함. 주로 Attention weight을 이용하여 이를 instance-level classification처럼 이용.

 

Motivation: 기존 방법들의 단점

  1. Instance-base method: Bag label을 그대로 인스턴스 label로 할당하는 방법을 의미함. Instance pseudo label(할당된 라벨)의 노이즈가 많음. 실제 인스턴스 라벨을 모르기 때문에, 인스턴스 분류기의 품질을 모르고, 성능에 차이가 많이남 (Figure A).
  2. Bag-based method:
    1. Instance level classification 성능이 안좋음: 쉽게 식별가능한 인스턴스에 대해서만 Attention score가 높게 할당하여 학습되는 경향. 모든 positive 인스턴스를 고려하는 것이 아니라는 것 -> 몇 개의 인스턴스만 Attention score 엄청 높고 나머지 인스턴스는 낮게나옴
    2. Bag-level classification도 강건하지 않음: 몇개의 인스턴스만 스코어가 엄청 높아 이 스코어에 의존적으로 예측하다보니 Bag-level classification도 강건하지 않음. 만일 attention score가 높은 예측이 틀린경우, bag classification도 틀림(특히, positive instance가 몇 없는 경우). 논문내에서는 "laziness"라고 하여, 쉬운것만 배우려고하는 게으름(lazy)을 의미

 

 

Method


방법론 개괄: instance-based MIL에 1)contrastive learning, 2)prototype learning을 합친 INS을 제안

 

이 방법론의 주된 목적은 instance classifier을 학습하는 것. instance-based이기 때문.

  1. 임의의 패치($x_{i,j}$)을 하나 샘플링
  2. 이 패치를 서로 다른 방법으로 증강하여 View1(Query view), View2(Key view)을 생성
  3. Query view branch: Query view을 인코더에 전달하여 특징값을 뽑고, instance classifier와 projector에서 슈도라벨과임베딩 벧터를 얻음. 표기로는 클레스 예측($\hat{y}^{i,j} \in \mathbb R^{2}$)와 임베딩벡터 ($q_{i,j} \in \mathbb R^{d}$)에 해당.
  4. Key view branch: key view을 별도의 인코더에 넣고, 다시 projector에 넣어 임베딩 벡터($k_{i,j}\in \mathbb R^{d}$)을 획득.
  5. MoCo을 이용한 학습(Instance-level Weakly Supervised Contrastive learning):
    1. Enqueue: 인코더와 프로젝터의 학습은 MOCO 방식, Pico으로 업데이트. MoCo의 방식대로 key encoder의 값을 dictionary 에 enqueue 해서 넣음. 넣을 때, 슬라이드 이미지의 라벨에 따라 다르게 처리하여 넣음. MIL문제에서는 negative slide에서는 모두 negative patch이기 때문에, 모두 예측클레스를 사용하는게 아니라 0을 넣음. 반대로, positive slide에 대해서만 classifier을 추론시 킴. 그리고, 예측된 클레스( $\hat{y}^{i,j} $), 임베딩값($k_{i,j}$))을 넣음
    2. Contrastive learning: contrastive learning을 하기 위해서 positive, negative pair가 필요한데, 본문에서는 Family and Non-family Sample selection 이라고 표현.
      1. Family set $F(q_{i,j})$: 패밀리 샘플들은 2개의 집합의 합집합임. 첫 번째 집합은 같은 이미지로부터 나온 두 임베딩임 ($q_{i,j}, k_{i,j}$). 나머지 집합은 예측된 라벨과 같은 라벨을 지닌 이미지들임(즉, $\hat{y}_{i,j}$와 같은 임베딩값들을 의미함.
      2. Non-family set $F'(q_{i,j})$: Family set의 여집합을 의미. 즉, 여기서는 다른 예측 클레스 라벨(또는 negative slide)을 가진 임베딩인 경우.
    3. Positive key, Negative key selection: SuperCon(https://analytics4everything.tistory.com/303) 과 같은 알고리즘으로 contrastive learning을 진행. 차이라면, SuperCon에서는 instance label이 hard label로주어졋다면, 이 논문에서는 instance classifier와 negative bag을 이용해서 얻었다는 차이

    6. Prototype-based Psudo label (PPLG): Instance classifier을 학습하기 위한 방법. 주요가정: 고품질의 feature representation을 얻기위해서 정확학 psuedo labels을 할당해야함.

  • $s_{i,j}$: 슈도 라벨을 의미함. one-hot vector로 2차원으로 표현. [0, 1] 또는 [1, 0]임.
  • $\mu_{r}$: prototype vector을 의미함. $r$은 라벨을 의미함.

자세한 방법은 아래와 같음

  1. 2개의 슈도라벨을 생성: 프로토타입 벡터 ($\mu _{r} \in \mathbb R ^{d}, r=0,1$)을 생성. r은 라벨을 의미함. 즉 d차원을 가진 프로토타입 벡터를 생성
  2. 프로토타입 벡터 업데이트:
    1. True negative guided update: 패치가 negative positive bag에서 획득된 경우, 해당 패치도 negative일 것임. 따라서, $s_{i,j}=0$을 직접할당. 그리고 프로토타입 벡터도 이 임베딩값($q_{i,j}$)을 할당.
    2. Poistive update: positive prototype vector 
    3. 쿼리임베딩($q_{i,j}$)과 두 프로토타입($\mu_{r}$)과 내적. 내적값이 더 가까운쪽으로 학습하기위해서, onehot 인코딩으로 내적값을 [0, 1], 또는 [1, 0]으로 만듬
    4. 슈도라벨을 모멘텀 업데이트: $s_{i,j} = \alpha s_{i,j} + (1- \alpha ) z_{i,j}, z_{i,j} = onehot(argmax( q_{i,j}^{T}, \mu_{r))$
    5. 프로토타입 업데이트: 프로토타입 벡터($\mu_{c}$)을 classifier에 포워딩하여 얻은 클레스에 맞게 업데이트합니다.
    6. 슈도 라벨 업데이트: 식(7), 식(8)
    7. Bag constraint: mean pooling을 이용해서 bag embedding을 진행

 

    7. Loss

  • Bag loss: 패치 임베딩을 Mean pooling하여 라벨과 계산 (식10)
  • Total loss: $\mathcal{L}=\mathcal{L}_{IWSCL} + \mathcal{L}_{cls} +\mathcal{L}_{bc}$

 

 

 

 

반응형

 

Preliminary

  • Positive sampleOrigin이 동일한 이미지(또는 데이터포인트)
  • Negative sample: Origin이 다른 이미지(또는 데이터포인트)
  • Dictionary look-up task: 여기서는 contrastive learning을 의미합니다. Query image에서 하나의 positive이미와 나머지 (N-1)개의 negative이미지와 유사도를 계산하는 과정이기에 k-value와 같은 dictionary구조라고 일컫습니다.
  • InfoNCE: InfoNCE은 미니배치 K+1개에서 1개의 positive sample을 찾는 softmax 함수 + temperature scale추가

 

Methods: 딕셔너리 사이즈를 키워 negative samples을 포함할 수 있으면 좋은 학습방법이 될 것

Moco은 딕셔너리 사이즈를 키워, Negative key을 많이 갖고 있게되면 더 학습이 잘된다는 가설로 시작됩니다. 위의 딕셔너리가 가변적(dynamic)합니다. 하나의 query에 대해서 key도 augmentation을 달리하고, 인코더도 점차 학습되기 때문입니다. MoCo은 Negative sample을 임베딩하기에 Key encoder가 비교적 천천히 학습되고(=급격히 변하지 않고) 일관적으로 학습되는 것을 목표로 합니다.

1. MoCo은 샘플을 Queue방식으로 처리합니다. 즉, 새로운 샘플을 Queue에 넣으면, 먼저 들어가있던 오래된 샘플은 제외되는 방식입니다. 샘플을 넣는 과정을 "Enqueue" 제외하는 과정을 "dequeue"라 합니다. 따라서, 비교적 최근의 인코딩된 Key Image들은 enqueue후에 몇 회 재사용될 수 있습니다.

2. Momentum update: key encoder을 직접학습하는 대신에, query encoder을 학습하고 학습의 일부만 반영(=momentum)합니다. 이유는 key encoder에는 많은 negative samples에 대해서 backpropagation하기 어렵기 때문입니다즉, computational cost문제 때문입니다. 예를 들어, 이번 배치가 16개였고, 딕셔너리사이즈가 1024개면, 1,024개의 샘플에 대해서 backpropgation을 해야하기 때문에 계산량이 많아 현실적으로 어렵다는 것입니다. enqueue하는 방식으로는 back-propagation이가능하다는 글을 같이 공유합니다(URL, URL2) (보통, "intractable"이라 하면 미분이 불가능한, 다루기 어려운 이런 뜻인데 미분과 연관되어 쓰여 혼란이 있습니다)

또한 인코더가 급격하게 변하는 경우, 딕셔너리에 저장되어있던 기존의 인코딩의 값이 현재와 많이 상이하기에 천천히변화시켜야한다는 것입니다.

그래서 아래와 같이 momentum update을 대안으로 선택합니다. 아래의 수식(2)을 보면, query encoder의 파라미터의 내용이용하여 key encoder을 업데이트하는 방식으로 학습합니다.

 

$\theta_{k} \leftarrow m \theta_{k} + ( 1- m )\theta_{q}$ (2),

  • $\theta_{q}$: query encoder의 파라미터
  • $ \theta_{k} $: key encoder의 파라미터
  • $m$: 모멘텀계수. [0, 1]사이의 값

따라서, query encoder만 back-propagation을 진행합니다. 그리고, 급진적인 key encoder의 파라미터 변화를 막기 위해서, m값을 0.999로 학습합니다. 이는 m=0.9보다 성능이 더 좋았다고 합니다.

 

기타1: contrastive loss 학습방식

  • end-to-end update: query encoder와 key encoder가 동일한 경우를 의미합니다. 그리고, 딕셔너리는 항상 미니배치 사이즈와 같습니다. 따라서, 딕셔너리 사이즈를 엄청 키우진 못합니다.
  • memory bank: 메모리뱅크는 데이터셋에 모든 샘플을 일단 인코딩하여 넣어둡니다. 그리고, 매니배치에서 일부를 샘플링하여 contrastive learning에 사용합니다. 장점은 "큰 사이즈의 딕셔너리"라는 것입니다. 단점은 메모리뱅크의 업데이트이후 key encoder가 여러번업데이트되기 떄문에, 둘의 일관성(인코딩 차원에서의)이 다소 떨어지는다는 것입니다.

 

Linear probe 과정에서 learning rate을 30으로 한 이유

논문에서는 "optimal learning rate을 30, weight decay을 0"으로 진행합니다. 일반적으로 다른 hyper-parameter인데, 이 이유는 feature distirbtion ImageNet supervised training과 Instragram-1B와 크게 다름을 의미합니다.

반응형

GitHub에서 git pull을 할 때 아이디와 비밀번호를 묻지 않게 하려면, 다음의 방법들을 사용할 수 있습니다:

1. SSH 키를 사용한 인증 설정: SSH 키를 생성합니다:이 명령어를 실행하면 SSH 키 쌍이 생성됩니다. 기본 경로를 사용하면 ~/.ssh/id_rsa와 ~/.ssh/id_rsa.pub에 각각 개인 키와 공개 키가 저장됩니다.

$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com" # github 이메일을 쓰시면됩니다.

 

 

2.SSH 에이전트에 키를 추가합니다:

$ eval "$(ssh-agent -s)"
$ ssh-add ~/.ssh/id_rsa

 

3. github 계정에 SSH 공개키를 추가합니다: 생성된 공개 키(~/.ssh/id_rsa.pub)의 내용을 복사한 후, GitHub의 Settings > SSH and GPG keys에서 새로운 SSH 키로 추가합니다.

 

Settings

 

생성된 공개 키(~/.ssh/id_rsa.pub)의 내용을 복사한 후, GitHub의 Settings > SSH and GPG keys에서 새로운 SSH 키로 추가합니다.

$ cat ~/.ssh/id_rsa.pub  # 공개키 내용을 출력해서 복붙합니다.

 

4.원격 저장소 URL을 SSH로 변경합니다: `username`은 github의 계정명, `repository.git`은 사용할 github repositry에서의 이름을 쓰면됩니다. 예를들어, ".../4pygmalion/cosas.git`이면 `$ git remote set-url origin git@github.com:4pygmalion/cosas.git`에 해당됩니다.

$ git remote set-url origin git@github.com:username/repository.git

 

반응형

+ Recent posts