오토마우스 


보건의료인이라면 의무적으로 듣는 보수교육이 있습니다. 이 보수교육을 주로 온라인으로 듣는데요. 온라인으로 듣는 보수교육으로부터 해방시켜줄 오토마우스를 소개합니다.

 

오토 마우스 다운로드


auto_mouse.exe
11.71MB

 

사용법


1. 첨부파일에 걸어둔 auto_mouse.exe을 다운로드 받습니다.

 

2. 자동 클릭할 위치에 커서를 올려두고, 키보드에서 "Enter"을 누릅니다. 그러면, 커서의 현 위치가 프로그램에 등록됩니다.

3. 몇초마다 클릭할 것인지 세팅합니다. 보통 10초 또는 5초정도 맞춰넣고, 적용을 누릅니다.

 

4. 보수교육 창(브라우저)를 띄워놓고 "자동 클릭"버튼을 눌러, 자동으로 클릭되도록합니다.

5. 중지를 시키려면 "멈춤"버튼을 누르고, "간격" 만큼 기다립니다.

 

2개의 창을 동시에 2개를 클릭하는법


오토마우스 프로그램을 2개를 켜두고, 웹브라우저도 2개를 켜놓고, 각각에 대해서 좌표설정(Enter), 간격설정(적용), 시작(클릭)을 하면됩니다.

 

개발과정


pyinstaller [python_file_path]--noconsole --onefile

 

반응형

요약


Swin TransformerViT(Vision Transformer)와 유사하게 이미지를 패치로 나누어, 각 패치를 토큰처럼 취급하여Transfomer에 전달하는 모델이다. ViT와의 차이점은 ViT은 패치를 레이어를 통과시키면서, 고정크기로만 연산하는 것에 반해, Swin Transformer레이어를 지나면서 각 패치들을 합쳐서, 패치의 크기를 크게 만들고, Self-attention의 범위를 확장시키는데 그 차이가 있다(Figure 1).  추가적인 주요 특징으로는 윈도우 내 영역내 여러 패치가 존재할 때, Attention을 줄 영역을 윈도우 내로만 주는 것이 아니라, 이전 레이어의 Window영역을 가로지를 수 있게 다음 레이어에서 Attention할 영역의 Window을 매번 달리하는 것이 있다.

Figure 1. Swin Transformer에서의 패치 영역을 합치는 단계의 예시 (a)

 

모델 설명: 1) 패치의 분리, 2) 패치의 임베딩, 3) 트렌스포머(어텐션 + Shifted window 파티셔닝), 4) 패치 병합과정의 연속


1. 이미지를 작은 단위의 이미지인 패치(Patch)형태로 분리한다: 각각의 패치는 겹치지않도록 분리하며 ViT(Vision Transformer)의 방식과 동일하게 이미지를 분리한다. 즉, 각 패치는 정사각형의 p x p의 형태를 갖는다. 예를들어, MNIST의 28 x 28의 이미지 크기라면, 4x4패치를 만든다고 가정하면, 49개의 패치가 생긴다(49=28/4 * 28/ 4) (Figure 2. 패치 파티셔닝의 예시).  

Figure 2. 패치 파티셔닝의 예시

  

 

2. 각 패치의 벡터 형태로 변환한다. 1. 단계에서의 패치의 크기는 $P \times P $이다. 이 이미지가 3차원이었다면, 이를 모두 concat함과 동시에 Flatten하여 $ P \cdot P \cdot 3 $의 형태로 변경한다. 즉, 채널에 해당하는 벡터까지 옆으로 펼쳐서(Flatten) 벡터화 한다. 

 

3. 선형결합을 하여 C차원을 가진 벡터로 만든다. 패치의 가로X세로가 PXP인 것을 3채널을 펼쳐(Flatten)하여 PxPx3의 벡터를 만들었다. 이 벡터를 압축하여, 임의의 크기가 C인 벡터로 만들어준다(=쉽게 말해 Dense(C)을 한번 거쳐준다). 이 연산의 결과의 벡터는 $\mathbb{R}^{C}$이다. 

 

 

4. Stage 1에서는 Swin transformer block을 통과시킨다: 이 때의 각 패치의 차원은 동일하게 유지한다. 즉 C에서 C로 나온다. 다만 벡터내 원소의 숫자는 다르다.

 

5. Stage 2. 인접패치를 합쳐준다: 첫 번째로 임베딩된 패치들은 근처의 2x2패치들을 합친다(Concat). 3의 단계에서 각 패치들을 C차원의 벡터로 만들었기 때문에, 4C 차원의 벡터가 만들어진다. 이 합치는 연산은 토큰의 숫자를 많이 줄여든다. 일종의 Pooling과 비슷하다(=본문에 ”down sampling of resolution”라고 기술됨.).   

6. Stage 2단계를 2번, 위와 비슷한 Stage 3단계를 6번, Stage 4단계를 2번진행한다.  

 

 

Window 영역 내에서만 attention을 적용하는 이유? 계산 복잡도 때문에...


Transformer에서는 토큰과 토큰사이의 관계를 모두 Attention을 적용하며 학습한다. 토큰의 수가 N이라면, NxN의 Attention weight matrix가 나오게 되는 것이다. Vision문제에서 이를 쉽게 적용할 수 있을까? 그렇지 않다. 이미지 자체가 128 x 128이면 엄청난 크기의 attention weight matrix가 생성되어야하기 때문이다. 저자들은 이를 해결하기 위한 방법을 고안했다.

1) Self-attention in non overlapped window: Window 영역을 정하고, 이 내에서만 self attention을 적용하는 것. 아래와 같이 작은 사각형은 각 패치를 의미하고, 두꺼운 줄을 가진 큰 사각형은 Window으로 정의해보자. 윈도우 영역내에는 4x4 (본문내 M x M)개의 패치가 있다. 이를 global self attention을 한다고생각하면, ....다음과 같은 계산이 나온다.

Window 영역내 self attention 예시 그림

한 윈도우에, 패치가 M x M이 있다고 가정하고, 일반적인 global self-attention을 하는 경우(1)와 widnow내 h x w개의 패치가 있는 경우를 계산복잡도를 구하면 아래와 같다. 중요한건 총 패치수인 h x w 수가 증가할 때, (1)의 식은 제곱으로 복잡도가 증가하지만, (2)의 식은 선형적으로 증하한다는 것이다. 윈도우 내에만 self attention하는 것이 컴퓨터비전에서 계산 복잡도를 낮출 수 있기 때문에, 이 방법을 저자들은 생각했다.

 

 

Shift window 을 구현하는 방법과 그 이유: 윈도우 내에서만 attention을 계산하면, 윈도우 넘어 연결성이 부족하기에... 윈도우 영역을 돌려가며(cyclic) 윈도우를 정의


Shift attention을 적용하기위해서 각 attention을 적용하는 단계를 본 논문에서는 module이라고 부른다. 논문에서는 2개의 모듈을 사용하는데, 첫번째는 왼쪽 상단에서 규칙적인 모양을 가진 window로 attention을 하고, 두 번째 모듈에서는 규칙적으로 분할된 윈도우에서 $(\lfloor\frac{M}{2}\rfloor,\lfloor\frac{M}{2}\rfloor)$ 만큼 떼어냏어 옮긴 후에 attention을 적용하는 것이다.

W-MSA(Window-Multihead Self-Attention) 방법과 이를 Shift(Cyclic shfit)하여 옮긴후에 attention하는방법

 

 

반응형

요약


LCA(Latent class analysis)은 클러스터링 분석과 유사하게 어느 집단에서 하위그룹이 있는지 알아보는 통계적 방법론이다. 이 하위그룹을 LCA에서는 latent group(=subgroup, 또는 class)라고 한다.

 

언제사용하나? 내가 분석하고자하는 군을 더 나누고자할 때,


LCA은 k-means clustering과 유사하게 연구대상자(cases)을 더 하위 그룹으로 쪼개어 분석하고자할 때, 시행하는 분석방법이다.[1]

 

 

모형(LCA model)의 품질평가. 잠재계층의 수를 어떻게 결정하는가?


LCA의 모형이 얼마나 데이터셋을 잘 평가하는지는 the likelihood-ratio statistic (G2), Akaike information criterion (AIC), Bayesian information criterion (BIC), Adjusted BIC, the log-likelihood, Entropy가 있다. Entropy 값은 클수록, G2 , AIC, BIC, Adjusted BIC와 the log-likelihood 값은 작을수록 모형 이 자료에 적합하다는 것을 의미한다.

K-means clsutering에 보면 inertia라는 값이 있다. Inertia은 클러스터 내의 l2 distnace의 합계이다. 클러스터링의 품질을 평가할 때, 결정요소 K을 inertia로 계산하고, 이 inertia가 툭툭 떨어지다가 잘 안떨어지는 구간을 통상 K로 결정한다. AIC, BIC도 유사하다. AIC, BIC 값이 크게 떨어지다가 감소폭이 떨어지는 잠재계층 수를 연구자가 결정하면된다.

 

 

 

클러스터 분석(Cluster analysis)와의 차이/공통점은 무엇인가?


클러스터 분석과 대표적인 차이를 이해하는 것은 잘 알려진 k-means 알고리즘과 LCA의 차이를 생각해보면 직관적으로 이해가 가능하다.

  LCA K-means
공통점 Person-orient analysis Person-orient analysis
차이점    
  Membership 각 군에 속할 확률이 계산 지정됨.
각 연구대상자가 2군이상 중복되지 않음
  변수 연속형 외 다 가능 연속형
  결측치 결측치에 영향이 별로 없다고 알려짐 많이 영향받음
이상치가 있으면 centroid에 영향줄 수 있음.
  잠재계층의수 Likelihood을 이용하여 AIC, BIC 측정 클러스터링 품질지표(예, 군내 L2거리의 합, 실루엣 계수 등)

 

공통점:

1)     두 분석 모두 “Person-oriented analysis”이다. 각 연구대상자들의 패턴을 비교해서 각 연구대상자들이 어느 그룹에 묶일지를 식별하는 분석방법이다. 이와 반대로, variable centered approach가 있는데, 이건 변수들이 어떤 관계가 있을거다라고 가정하고, 변수들간의 해석을 목적으로하는 분석방법이다. 두 분석 모두 “연구대상자가 어느 그룹으로 할당될지”에 대한 초점이므로 Person-oriented analysis에 해당된다.

차이점:

1.     가정이 다르다. 같은 클러스터(=군)에 있는 연구참여자들이 매우 유사한 변수들을 가지고 있을 것이라 가정한다. 반면, LCA은 잠재계층(latent classes)가 존재하며, 잠재계층의 각 군으로 전 연구대상자들을 설명할 수 있을거라고 가정한다.

2.     클러스터 분석에서는 변수들의 평균을 구하면, 각 연구참여자들의 변수들이 얼마나 평균에 가까운지 측정할 수 있다(=편차). 그렇기에, 분석할 변수들이 연속형이어야한다. 클러스터 분석에 대표적인 사례인 K-means을 생각해보면, 범주형변수로 k-means을 돌리면, 각 범주형변수들의 L2 distance가 잘 측정이 안될 수도 있다. L2은 유클리디언 공간에서의 크기를 의미하기 때문이다[3]. 반면 LCA은 분석할 변수가 범주형이다(최근엔 범주/연속 둘다 쓸 수 있는 모형도 있다).

3.     클러스터분석은 각 연구대상자들이 분석후에 A군인지 ,B군인지, C군인지 등 명확하게 그룹이 결정된다. 반면에 LCA은 확률이 주어지기에 명확히 A,B,C인지는 알수없다. 다만, 각 군에 확률만 알 수 있을 뿐이다.

4.     LCA은 모형학적 군집방식이기에, 잠재계층의 군집수를 알아서 정해준다. 자세히는 군집방식에 parameter로 군집 수가 있으며, 데이터(x)을 이용해 파라미터(Θ)을 찾는 likelihood을 이용해서, 잠재계층의 수를 찾는다. K-means은 반면 K을 연구자가 지정해야한다.

 

Case study


1.     아래는 LCA분석의 결과이다. LCA 분석에서 얼마나 모형이 품질이 있는지 AIC, BIC 등으로 평가한다고 했다. 이 중에 군집이 3개까지 AIC, BIC도 낮아지는 폭이 크다. 이 중에 군집이 3개까지 AIC, BIC도 낮아지는 폭이 크다. 군집에 3개라고 가정하고 분석하면된다. latent class 수를 더 키우면 무조건 낮아진다. 직관적으로 N=100일떄, 각 100개가 독립적인 subgroup이라고 생각하면 제일 잘 맞는 모형이다. 우리는 다 각자의 인생을 살듯이?

https://jkan.or.kr/pdf/10.4040/jkan.2019.49.6.701

 

2. 세 그룹으로 나뉘어진 것을 알았으니, 각 군에 이름을 붙여본다. 이 간호학과 선생님들께서는 Current non-drinkers, Binge drinkers, Problem drinkers 라고 네이밍을 줬다. 첫 행은 각 군에 대한 membership에 대한 확률을 나타낸다. Current non drinker은 대부분 24,417명중에 69%정도는 이 군에 할당될 확률이 있단 말이다. 그리고, 이 군에 있는 사람들은Drink during the pas 30 days할 확률은 0.12라는 말이다. 즉 이 변수("Drink during the pas 30 days")인 카테고리컬이다. 이 변수에 해당되냐 안되냐를 보여준다. 반면 Binge drinkers, Problem drinkers에서는 1.00, 1.00이니 무조건 이 군에 속할려면 최근 30일 이내 술마셔야하는 사람이어야 한다는 것이다.

 

[1] Latent Class Analysis: A Guide to Best Practice

[3] 잠재계층분석기법(Latent Class Analysis)을 활용한 영화 소비자 세분화에 관한 연구

반응형

 

요약

 


ViT(Vision Transofmer)은 자연어처리(NLP)분야에서는 성공적인 성능을 보이는 트랜스포머(Transfomer)을 컴퓨터 비전까지 적용하기에는 제한이 있어왔는데, 이를 시도한 사례이다. 트랜스포머에서 각 토큰을 임베딩하여 샐프 어텐션(Self-attention)하는 것과 같이, 각 토큰을 이미지로 생각하여 트랜스포머의 인코딩에 전달하는 것이 이 모델의 골자이다.

 

Vision Transformer의 시각화. 각 이미지를 1부터 9까지 패치를 만든다음에, 각 패치를 단어처럼 취급해서 임베딩한다. 임베딩할때는 0, 1, 2와 같이 이미지 패치가 어디서부터 기원했는지에 위치정보를 더해주는 포지셔널 인코딩(positional encoding)과 유사하게 패치 위치를 가리키는 벡터도 포함한다. 이를 트랜스포머의 인코딩에만 전달하면 ViT의 완성이다. GIF 출처: https://en.wikipedia.org/wiki/Vision_transformer#/media/File:Vision_Transformer.gif

 

 

모델 아키텍처 설명


본문에서는 별 다른 수정없이(with the fewest posiible modification) NLP에 쓰이던 트랜스포머를 영상처리에도 쓸 수 있다고 소개한다. 그림은 아래와 같다. 큰 순서는 다음과 같다. 1) 이미지를 잘게 자른 패치(Patch)로 N개의 패치를 만든다. 2) 패치를 Flatten하게 벡터화한다. 3) 벡터화한 이미지를 선형으로 결합하여 임베딩한다. 4) 임베딩된 결과에 클레스를 예측하는 클래스 토큰을 더해준다. 그리고, 포지셔널인 임베딩을 더해주어 패치의 위치를 더해 연산한다. 

 

 

자세히는 아래와 같다.

1) 이미지를 잘게 자른 패치(Patch)로 N개의 패치를 만든다. 원래 이미지가 H, W에 C채널 이미지인 것으로 고려한다. 컬러가 R, G, B였다면 C는 3이고, (1024, 1024)의 HD 이미지면 H는 1024, W은 1024값을 갖는다. 이런 이미지를 겹치지 않게(Not overlapping) N개의 정사각형 패치로 나눈다. 패치의 크기는 P이고, 개수는 N개이다. 이 때, 당연히, N개의 개수가 정수형이어야하고, 이미지와 맞아떨어져야하므로, $N=HW/P^{2}$으로 계산해야한다. C개의 채널을 가진 가로,세로가 각각 P인 패치를 그러면 N개를 생성하게 된다. 이렇게 만든 패치를 Flatten하여 원소의 길이가 $P*P*C$인 벡터를 얻는다. 이 벡터가 그리고 N개가 있다.

 

가로(W), 세로(H), 채널 수(C)개의 이미지를 가로(P), 세로(P)인 N개의 패치(작은 이미지)로 나눈다. 그리고 이 이미지를 Flatten한다. $\times$은 메트릭스와 같이 차원이 있다는 얘기기고, "."은 그냥 차원이 없다는 의미이다.

 

2) 각각의 패치를 각각 선형결합하여 임베딩시킨다: 각 패치를 선형결합시켜서(Dense layer을 통과시켜) 원소의 길이가 D인 벡터를 만든다. 이 단계가 $\mathbb{R}^{P^{2}C} \cdot \mathbb{R}^{P^{2} C \times D}->\mathbb{R}^{D}$에 해당한다. Linear projection을 해서 원소의 개수가 D개인 벡터를 만드는 단계이다.

 

3) 각 임베딩한 원소를 concat하고 포지션임베딩을 더해준다.: 각 원소의 길이가 D개인 벡터를 모두 concat해서 길게 만든다. 가령 N개의 패치에 D개의 원소의개수를 가진 벡터로 패치를 선형결합시킨 결과를 얻었다고하면 $N \times D$의 차원의 메트릭스를 얻게된다. 거기에 하나를 더해서 클레스임베딩($x_{class}$)을 정의하여(\mathbb{R}^{D}) 더 concat해준다. 결과적으로 $\mathbb{R}^{(N+1)\timesD}$의 메트릭스를 얻게된다. 거기에 포지셔넝임베딩을 하나 정의하여 함께 더해준다. 이 포지셔널 임베딩의 크기는 $\mathbb{R}^{(N+1)\timesD}$ 와 같다.

 

 

4) Self-attention 및 정규화 단계(NL): Transformer와 같이 진행한다. 이미 위의 단계에서 충분히 이미지를 임베딩하였으니 Transformer의 일반적인 연산과정을 거친다.

 

 

 

CNN과의 비교?

위의 연산과정을보면, ViT도 CNN과 유사한 방식을 사용한다. 패치사이즈인 16x16, stride 16의 convolution을 하는것과 같이 진행한다.

  1. 가장 큰 차이는 CNN은 국소성(locality)가 있어서 각 특징값들을 픽셀 단위에서 특징값으로 잘 표현되는데, ViT은 Transformer이다보니, 이미지의 패치의 시리즈간의 연결성도 강조할 수 있다. 즉 좌측상단의 패치와 우측상단의 패치가 연관성을 이어줄 수 있다는 것이다. 이러한 분석방법이 더욱 픽셀단위의 중요성을 강조할 수 있다고 소개되어있다[1]. 
  2. 하지만 CNN별로 데이터가 엄청나게 많지 않아도 잘 학습되는 반면, Vision Transformer은 꽤 많은 양의 데이터를 필요로한다. 
  3. Inductive bias을 줄일 수 있다. CNN은 이미지를 다루기 위한 Inductive bias을 갖고있다. 가령 CNN은 학습해야하는 커널이 각 이미지영역을 훑고 지나가면서, 근소한 이미지 연관성이 크게 학습되도록 꾸며져있고(=이를  Locality(근접 픽셀끼리의 종속성)라 함). 또한, 패치가 여러 영역을 훑기 때문에, Translation Invariance(사물의 위치가 바뀌어도 사물을 인식)의 이 된다. 하지만, 이러한 CNN의 가정들(메커니즘 방식)보다 각 패치의 연관성을 글로벌하게 연관지어 학습하기 때문에 Inductive bias을 줄일 수 있다고 한다[2][3].

 

[1] https://en.wikipedia.org/wiki/Vision_transformer

[2] Raghu, Maithra; Unterthiner, Thomas; Kornblith, Simon; Zhang, Chiyuan; Dosovitskiy, Alexey (2021-08-19). "Do Vision Transformers See Like Convolutional Neural Networks?". arXiv:2108.08810.

[3] Coccomini, Davide (2021-07-24). "Vision Transformers or Convolutional Neural Networks? Both!"Towards Data Science.

[4] https://arxiv.org/pdf/2010.11929.pdf

 

Vision transformer - Wikipedia

From Wikipedia, the free encyclopedia Jump to navigation Jump to search A Vision Transformer (ViT) is a transformer that is targeted at vision processing tasks such as image recognition.[1] Vision Transformers[edit] Vision Transformer Architecture for Imag

en.wikipedia.org


 

반응형

요약


Morphological transformation (형태변형)은 이미지의 형태를 변형하는 작업들 중 하나를 말한다. 이미지의 형태를 변형하는 하는 방법은 여러가지가 있는데, 주로 "입력 이미지"와 "구조적 원소(=커널이미지)"을 이용한 경우를 말한다. 그리고 형태변형은 주로 이진화 이미지(Binary image, 흑백이미지으로 0(흑), 1(백)으로만 이뤄져있는 이미지)를 연산하는 것을 의미한다[1]*. 주로 Erosion, Dilation이 주로 연산이며 Open, closing은 이것들의 변형들이다 . 

*주로라는 것은 이진화 이미지가 아닌 경우도 쓸 수 있다(예, grayscale)

 

 

주로 아래와 같은 연산들이 대표적으로 쓰인다. 아래의 글을 봐도 잘 이해가 안되는데, 예시와 함께 보는 것을 권장한다.

  1. Erosion (부식, 침식, Shrink, Reduce): 이미지의 boundary(가장자리)를 부식시키는 작업. 각 오브젝트의 두께가 줄여진다. [2]
  2. Dilation (확장):이미지의 boundary(가장자리)를 확장시키는 작업. 각 오브젝트의 두께가 커진다.
  3. Opening (오프닝): Erosion후에 Dilation을 적용하는 연산. Erosion으로 노이즈 같은 점을 없애주고 이미지를 확장하기에 noise reduction용으로도 쓰는듯하다.
  4. Closing (클로징): Dilation 후에 Erosion을 적용하는 연산. 반면에 Closing은 Object내에 이미지를 패딩해주는효과가 있다.

위의 모든 단계는 커널(kernel, structuring element 또는 probe 라고도 함)을 이용하는데, 이는 입력이미지와 연산할 매개체를 의미한다. 예를 들어, 입력이미지가 A, 연산이 @, 커널이 B면, A@B의 연산을 한다. 주로 @은 위와 같이 종류가 다양하고, B에 해당하는 커널을 바꾸면서도 여러 종류의 연산이 가능하다.

 

 

알아야할 개념: Kernel, Fit, Hit, Miss. 위의 알고리즘을 설명하기 위해서는 아래의 이미지 처리시 개념을 선행해야한다.


  • Kernel: 이미지 연산에 필요한 구조적인 요소(Structuring element). 이미지인데, 연산을 해줄 0또는 1로만 이뤄진 이미지를 의미한다. 입력이미지를 덮어가면서 연산할 이미지를 의미한다[3].
  • Fit: Kernel 이미지의 픽셀이 모든 입력이미지에 커버가 되는 경우.
  • Hit: Kernel 이미지의 픽셀 중 하나라도, 입력이미지에 커버가 되는 경우.
  • Miss: Kernel 이미지의 픽셀 중 하나라도 입력이미지에 커버가 되지 않는 경우.

Input 이미지와 Kernel이 주어진 경우, Hit, Fit, Miss의 예시

 

 

Erode (침식): 주로 오브젝트의 사이즈를 조금 줄일 때 사용


침식은 수학적인 표현으로는 주로 "$\ominus $"라는 표현을할 수 있다. 침식(Erode)은 모든 형태변형 알고리즘 연산과 같이 2개의 값을 요구한다. 하나는 입력이미지(침식 시킬 이미지, $A$), 또 하나는 커널(Kernel, $B$)이다. A를 커널 B로 침식시킨다는 표현은 $A\ominus B$로 표현할 수 있다.

erosion은 다음의 규칙으로 연산한다.

$A\ominus B$: A와 커널 B가 fit이면 1, 아니면 0을 채운다. 이 과정을 kernel의 중앙부가 0인 지점에따라 계산한다.

import cv2 as cv
import numpy as np

image = np.array(
    [
        [0,0,0,0,0],
        [0,1,1,1,0],
        [0,1,1,1,0],
        [0,1,1,0,0],
        [0,1,0,0,0],
    ],
    np.uint8
)

kernel = np.array(
    [[0,1,0],
     [1,1,1],
     [0,1,0]
     ],
     np.uint8
)

cv.erode(image, kernel)

그림으로 표현하면 다음과 같다. 커널의 중심부가 배경(0)인 지점을 모두 순회하면서 hit인 부분이 있으면 모두 0으로 바꿔준다.

그러면 가운데 하나만 1만 남게된다.

array([[0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]], dtype=uint8)

응용 예) 주로 두꺼운 펜으로 작성한 글씨나, 번져서온 이미지인 경우 Erode을 시키면 세밀해진 이미지를 얻을 수 있다.

 

erosion은 다음의 규칙으로 연산한다.

$A\ominus B$: A와 커널 B가 fit이면 1, 아니면 0을 채운다. 이 과정을 kernel의 중앙부가 0인 지점에따라 계산한다.

import cv2 as cv
import numpy as np

image = np.array(
    [
        [0,0,0,0,0],
        [0,1,1,1,0],
        [0,1,1,1,0],
        [0,1,1,0,0],
        [0,1,0,0,0],
    ],
    np.uint8
)

kernel = np.array(
    [[0,1,0],
     [1,1,1],
     [0,1,0]
     ],
     np.uint8
)

cv.erode(image, kernel)

그림으로 표현하면 다음과 같다. 커널의 중심부가 배경(0)인 지점을 모두 순회하면서 hit인 부분이 있으면 모두 0으로 바꿔준다.

그러면 가운데 하나만 1만 남게된다.

array([[0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]], dtype=uint8)

응용 예) 주로 두꺼운 펜으로 작성한 글씨나, 번져서온 이미지인 경우 Erode을 시키면 세밀해진 이미지를 얻을 수 있다.

 

 

Dilation (팽창): 주로 오브젝트보다 약간 큰 사이즈의 이미지를 얻기 위함.


방법: Dliation도 erosion과 마찬가지로, kernel에 hit인 부분을 0으로 바꾸는 대신에, 1로 채워준다. 좀 더 큰 이미지의 영역을 확보하기 위함이다.

응용사례: Pill(알약)의 이미지보다 약간 큰 이미지 영역을 확보하기위해서, 이미지를 이진화(Binarization)시킨 다음, Dilation시켜서 좀더 큰 사이즈의 영역을 확보한다. 이는 약의 그림자 등 조금 큰 영역을 확보해서 Dection하는게 더 성능에 유리하기 때문에 이렇게 진행한다 

Pill Detection Model for Medicine Inspection Based on Deep Learning, ref : https://www.mdpi.com/2227-9040/10/1/4/pdf

 

 

Opening:주로 노이즈를 지우기 위해 사용.


응용 예:  이진화한 이미지에서 작은 점(노이즈)를 지울 때 사용한다. 또는 인공지능이 Segmentation한 영역에서 Background이미지에서 지저분하게 잘못 예측한 영역들을 오프닝으로 지울 수 있다.

 

 

 

Closing: 이미지 내 작은 구멍 및 점들은 채우기 위한 방법으로 사용.


의료영역에서 Closing 사용

Unet의 후속모델인 ResnetUnet을 이용하여 심장부와 폐부를 Segmentation했다. 그리고 그 예측결과 중에, predicted Mask처럼 구멍뚤린 부위를 후처리(Closing)을 이용해서 매꿔주어 성능을 향상시킬 수 있다.

 

 

[1] https://en.wikipedia.org/wiki/Binary_image

[2] https://homepages.inf.ed.ac.uk/rbf/HIPR2/erode.htm 

[3] https://www.cs.auckland.ac.nz/courses/compsci773s1c/lectures/ImageProcessing-html/topic4.htm

[4] https://docs.opencv.org/4.x/d9/d61/tutorial_py_morphological_ops.html

 

 

 

 

 

반응형

요약


확률 보정(Probability calibration)은 실제 데이터로 사건이 발생할(=분류할) 이벤트가 확률값처럼나오도록 하는 과정을 의미한다. 가령, 기상청에서 쓰는 강수확률모델이 강수확률이 80%이면, 기상조건이 같은 날짜만 모아서 예측한 경우, 80%만 비가왔어야한다. 이렇듯, 모델이 반환하는 확률값이 (정확히는 확률은 아니지만, 일종의 신뢰도 역할을 한다), 신뢰도 역할을 잘 잘 할 수 있도록 하는 작업을 확률 보정(Probability calibration)이라고 한다.

서론


Sklearn 공식 도큐먼트를보면 1.16에 Probability calibartion에 대해 소개가 되어있다 [1]. ML모델로 얻은 확률(.predict_proba로 얻은 확률)은 우리가 실제로 확률처럼 쓸수 있냐면? 그건 아니다. 이진분류라면, 모델이 반환한 확률값이 0.8이었다면(1=positive case), 실제 positive class중에 80%정도만 모델이 맞추었어야한다. 모델이 반환한 확률이 1이라면? 모델이 1이라고 찍은 데이터들은 100% positive case여야한다.

 

 

켈리브리에이션 커브(Calibation curves): 얼마나 확률이 신뢰도를 잘 대변하고 있는지 파악할 수 있는 다이어그램


아래의 그림을 Calibration curves (=reliabiltiy diagrmas)이라고 한다. 이는 확률 값이 실제로 이진분류상에서 얼마나 신뢰도를 대변할 수 있는지를 보여주는지를 알려주는 그림이다. X축은 모델이 각 평균적으로 내뱉는 확률값(구간화한값인듯), y축은 그 중에 실제 positive가 얼마나 있었는지를 의미한다. 확률이 잘 보정되었다면, 실제 positive case중에 모델이 예측한 케이스의 비율과 동일할 것이다. 즉 이 선은 기울기가 1인 점선처럼 나와야 한다.

각 4가지 모델에 대한 probabiltiy calibaration을 파악하기 위한 비교.

 

위의 그래프를보면, logistic 모델의 경우(녹색) 잘 보정이 되어있고, 다른 방법론들은 그러하지 못하다. GaussianNB은 대다수가 0, 또는 1에 가까운 확률을 내뱉는다. Random Forest의 경우에는 히스토그램이 0.2, 0.9에서 피크치고, Calibration curve에서도 S형을 보인다. 이에 대해서 한 연구자(Niculescu-Mizil and Caruana)가 다음과 같은 설명을 했다. Bagging 또는 random forest의 경우는 확률이 0 이나 1이 나오는 경우는, 유일하게 한가지로, 모든 random forest의 tree(앙상블방법들의 weak learner)가 다 0의 확률을 예측해야 한다. 사실상 조금 어려운 경우이고, 우리가 일부 RF에 노이즈를 주더라도 0에서 멀어질 수밖에 없다[2].

 

 

어떻게 확률를 조정(calibartion)할 수있나? 매핑함수를 하나 더 씌워본다


수식이 직관적이어서 바로 서두에 작성한다.
$p(y_{i}=1|f_{i})$ 을 해줄 후처리 함수하나만 만들면 된다.
국룰이 없다. 단, 모델을 훈련할 때 사용했던, 데이터로는 사용하지 말아야한다. 왜냐하면, 훈련데이터로하면 성능이 워낙 좋기때문에, test 데이터로 찍은 확률과 차이가 있을 수 있기 때문이다. 즉, 본인이 테스트할 데이터를 가지고 예측기에, 각 확률만큼 positive 케이스를 맞추도록 보정하여야한다. 이 보정은 어떤 함수여도 상관이 없다. Sklearn에서는 CalibratiedClassifierCV라는 툴을 제공해서 모델의 확률이 calibration되도록 만들어준다. 대표적으로 쓰이는 방법은 2가지인데, isotonic과 sigmoid 방법이다.


Isotonic: $\sum_{i=1}^{n}(y_{i}-\hat{f_{i})^{2}}$ where $ \hat{f_{i}^{2}} = m(f_{i}) + e_{i} $
- Isotonic 방법은 non-parametric 방법(학습할 파라미터가 없이)으로 확률값을 보정하는 방법이다. $y_{i}$은 $i$번째 샘플의 실제 라벨을 의미하고, $\hat{f_{i})^{2}}$은 calibration된 분류기의 출력을 의미한다. 즉, calibration 시키기위해서 단조증가 함수를 하나 씌워서 만드는 것이다.[3]. 여기에 해당하는 $m$을 하나 학습해야하는데, 이거는 iteration돌면서 윗 식을 최소화할 수 있는 m을 찾는다. 전반적으로 Isotonic이 아래의 Platt calbiration보다 성능이 좋다고 알려져있다.

Sigmoid (=Platt calibration) : $ P(y=1|f) = \frac{1}{1+exp(Af+b)}$
- 확률값(f)을 다시 A, B을 학습시켜서 학습할 수 있도록 하는 방법이다. 이 방법에서는 A, B을 찾기위해서 Gradient descent을 사용한다고 한다.


예제코드


아래와 같이 Calibration plot으로 실제 예측치 중에 몇의 positive case가 있는지 파악할 수 있다. prob_pred은 각 확률의 구간들을 평균낸 것이다. 예를들어 n_bins에 따라서, 하위구간의 확률을 가진 샘플 10개가 평균적으로 얼마의 확률을 가졌는지를 의미한다. 이에 해당하는 실제 positive data point의 수가 prob_true이다.

 

그렇게해서 아래와 같이 CalibrationDisplay함수를 이용해서 plot으로 확률이 어느정도 신뢰도를 대변할 수 있는지 파악할 수 있다 [3].

import sklearn
import numpy as np

from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC

x, y = make_classification(
    n_samples=10000, n_features=20, n_informative=2, n_redundant=10, random_state=42
)

x_train, x_test, y_train, y_test = train_test_split(x, y)

base_clf = SVC(probability=True)
base_clf.fit(x_train, y_train)


# Calibriation plot 그리기
from sklearn.calibration import calibration_curve, CalibrationDisplay

y_prob = base_clf.predict_proba(x_test)[:, 1]
prob_true, prob_pred = calibration_curve(y_test, y_prob, n_bins=10)

disp = CalibrationDisplay(prob_true, prob_pred, y_prob)
disp.plot()

 

Calibration은 아래와 같이 진행한다.

from sklearn.calibration import CalibratedClassifierCV
calibriated_clf = CalibratedClassifierCV(base_estimator=base_clf, method="isotonic", cv=2)
calibriated_clf.fit(x_test, y_test)

pred_y = calibriated_clf.predict_proba(x_test)[:, 1]
prob_true, prob_pred = calibration_curve(y_test, pred_y, n_bins=10)

disp = CalibrationDisplay(prob_true, prob_pred, pred_y)
disp.plot()

 

[1] https://scikit-learn.org/stable/modules/calibration.html#probability-calibration
[2] Predicting Good Probabilities with Supervised Learning, A. Niculescu-Mizil & R. Caruana, ICML 2005
https://www.cs.cornell.edu/~alexn/papers/calibration.icml05.crc.rev3.pdf

[3] https://scikit-learn.org/stable/modules/generated/sklearn.calibration.CalibrationDisplay.html#sklearn.calibration.CalibrationDisplay.from_estimator

반응형

+ Recent posts