<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>jungminii.velog</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Mon, 13 Jul 2026 08:15:33 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>jungminii.velog</title>
            <url>https://velog.velcdn.com/images/jm_mg_se/profile/8b750c45-f084-4ce1-965d-69891b2e040a/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. jungminii.velog. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jm_mg_se" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[논문 리뷰] SAM 3: Segment Anything with Concepts (작성 중)]]></title>
            <link>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-SAM-3-Segment-Anything-with-Concepts</link>
            <guid>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-SAM-3-Segment-Anything-with-Concepts</guid>
            <pubDate>Mon, 13 Jul 2026 08:15:33 GMT</pubDate>
            <description><![CDATA[<p>sources: <a href="https://arxiv.org/abs/2511.16719">SAM 3: Segment Anything with Concepts</a></p>
<h1 id="introduction">Introduction</h1>
<p>SAM 3는 <strong>사용자가 지정한 하나의 물체를 분할하는 모델</strong>에서 <strong>사용자가 말한 개념에 해당하는 모든 물체를 찾아 분할하고 추적하는 모델</strong>로 SAM의 범위를 확장한 것이다.</p>
<p>기존 SAM은 <strong>개념 전체를 검색하는 문제</strong>는 직접 다루지 않았는데, 먼저 PVS와 PCS의 개념에 대해서 한 번 이해하고 넘어가보자.</p>
<blockquote>
<h3 id="pvs-promptable-visual-segmentation">PVS: Promptable Visual Segmentation</h3>
<p>SAM 1과 SAM 2의 기본 과업으로, 입력은 다음과 같다.</p>
</blockquote>
<ul>
<li>이미지 또는 비디오</li>
<li>Positive / Negative point</li>
<li>Bounding box</li>
<li>초기 mask<blockquote>
</blockquote>
핵심은 프롬프트가 <strong>물체의 의미가 아니라 위치를 지정한다는 것</strong>이다.
이미지 위에 점을 찍으면, SAM은 그 위치의 물체를 &#39;경계, 질감, 형태 등&#39;을 이용하여 하나의 <strong>coherent object</strong>로 분리한다.<blockquote>
<blockquote>
<p>&quot;이 좌표에서 내가 지목한 물체의 경계는 어디인가?&quot;</p>
</blockquote>
</blockquote>
</li>
<li>Positive point: 이 부분은 목표 물체에 포함</li>
<li>Negative point: 이 부분은 목표 물체에 포함 X<blockquote>
</blockquote>
즉, Negative Point도 &quot;이 물체는 고양이가 아니다&quot; 라는 의미가 아니라, <strong>단지 이 픽셀은 현재 선택한 인스턴스에 포함하지 말라</strong>는 공간적 신호이다.</li>
</ul>
<blockquote>
<h3 id="pcs-promptable-concept-segmentation">PCS: Promptable Concept Segmentation</h3>
<p>입력 프롬프트가 <strong>위치</strong>가 아니라 <strong>개념의 정의</strong>가 된다.</p>
</blockquote>
<pre><code class="language-text">비디오 + &quot;cat&quot;
        ↓
영상에 등장하는 모든 고양이 검출
        ↓
각 고양이의 마스크 생성
        ↓
고양이별 고유 ID 부여
        ↓
프레임 사이에서 각 ID 추적</code></pre>
<p>PCS가 해결해야 하는 문제는 네 단계이다.</p>
<blockquote>
</blockquote>
<pre><code>   1. **Recognition - 무엇인가?**
현재 이미지에 `cat`이라는 개념이 존재하는지 판단한다.
2. **Localization - 어디 있는가?**
고양이가 존재하는 위치와 개수를 찾는다.
3. **Segmentation - 정확한 경계가 어디인가?**
각 고양이의 픽셀 단위 마스크를 생성한다.
4. **Tracking - 다음 프레임의 어떤 물체와 같은가?**
여러 고양이가 있을 때 개별 identityfmf dbwlgksek.</code></pre><blockquote>
</blockquote>
<table>
<thead>
<tr>
<th>PVS</th>
<th>PCS</th>
</tr>
</thead>
<tbody><tr>
<td>box 자체가 목표 위치를 지정</td>
<td>box가 목표 개념의 예시를 제공</td>
</tr>
<tr>
<td>박스 안의 한 인스턴스 분할</td>
<td>예시와 같은 모든 인스턴스 검색</td>
</tr>
<tr>
<td>“이것”</td>
<td>“이것과 같은 것들”</td>
</tr>
</tbody></table>
<p>SAM 시리즈는 이미지 및 비디오를 위한 <strong>promptable segmentation</strong>작업을 도입했으며, 프롬프트당 단일 객체를 분할하기 위해 점, 상자 또는 마스크를 사용하는 <strong>프롬프트 기반 시각 분할 (Promptable Visual Segmentation, PVS)</strong>에 중점을 두었다.</p>
<table>
<thead>
<tr>
<th>모델</th>
<th align="right">시각 입력</th>
<th align="right">텍스트 의미 이해</th>
<th align="right">의미 기반 검색</th>
</tr>
</thead>
<tbody><tr>
<td>SAM 1</td>
<td align="right">O</td>
<td align="right">X</td>
<td align="right">X</td>
</tr>
<tr>
<td>SAM 2</td>
<td align="right">O</td>
<td align="right">X</td>
<td align="right">X</td>
</tr>
<tr>
<td>SAM 3 PVS 모드</td>
<td align="right">O</td>
<td align="right">필요 없음</td>
<td align="right">X</td>
</tr>
<tr>
<td>SAM 3 PCS 모드</td>
<td align="right">O</td>
<td align="right">O</td>
<td align="right">O</td>
</tr>
</tbody></table>
<p>이러한 방법들이 획기적인 발전을 이루긴 했지만, 입력 내 어디에든 나타나는 개념의 모든 인스턴스를 찾아 분할하는 일반적인 작업을 다루지는 못했다.</p>
<p>이에따라 SAM 2 대비 PVS를 개선하고, <strong>프롬프트 기반 개념 세그먼테이션(Promptable Concept Segmentation, PCS)의 새로운 표준을 제시하는 SAM 3</strong>를 저자들은 소개한다.</p>
<p>저자들은 <strong>Atomic Visual Concepts 인식</strong>을 중심으로 하기 위해 텍스트를 간단한 명사구로 제한한다고 한다.</p>
<blockquote>
<h4 id="sam-3가-말하는-concept의-범위">SAM 3가 말하는 &quot;Concept&quot;의 범위</h4>
<p>SAM 3의 텍스트 프롬프트는 원치적으로 <strong>간단한 명사구(noun phrase)</strong>인데, 예를 들자면 다음과 같다.</p>
</blockquote>
<ul>
<li><code>apple</code></li>
<li><code>red apple</code></li>
<li><code>striped cat</code></li>
<li><code>yellow school bus</code></li>
</ul>
<p>즉, 명사에 색상, 무늬, 속성 같은 Modifier가 붙는 형태이다. 논문은 이를 <strong>atomic visual concept</strong>라고 부른다. 하나의 시각적 범주로 직접 grounding 할 수 있는 개념에 초점을 둔다는 의미이다.</p>
<p>따라서 제목의 &quot;Anything&quot; 을 그대로 모든 자연어 질문으로 받아들이면 안된다. <strong>SAM 3의 open-endedness는 시각적으로 grounding 가능한 단순 명사구의 어휘가 고정되어 있지 않다</strong>는 뜻에 가깝다.</p>
<p>복잡한 언어 질의는 MLLM이 먼저 해석하여 단순한 개념 프롬프트로 변환하고, SAM 3가 실제 검출⋅분할을 수행하는 조합을 제안한다.</p>
<blockquote>
<p><strong>*&quot;Consistent with previous SAM versions, SAM 3 is fully interactive, allowing users to resolve ambituities by adding refinement prompts to guide the model towards their intended output.&quot;*</strong></p>
</blockquote>
<p><strong>SAM 3가 처음 내놓는 결과가 사용자의 의도와 다르다면, 사용자가 프롬프트를 주면서 결과를 반복적으로 고칠 수 있다</strong>는 뜻이다.
여기서 <code>ambiguity</code>는 모델이 프롬프트를 여러 방식으로 해석할 수 있는 상황을 말한다.</p>
<blockquote>
<p>예를 들어, 프롬프트로 <code>mouse</code>를 입력했는데, 컴퓨터 마우스와 동물 쥐가 있다면, 모델은 정확히 무엇을 원하는지 알기 어려울 것이다. 이때 <strong>refinement prompt</strong>를 추가한다.</p>
</blockquote>
<ul>
<li>동물 쥐에 <strong>positive exemplar box</strong></li>
<li>컴퓨터 마우스에 <strong>negative exemplar box</strong></li>
<li>누락된 물체에 <strong>positive exemplar</strong></li>
<li>개별 마스크 경계가 부정확하면 pos/neg click -&gt; 경계선 수정<blockquote>
</blockquote>
등과 같은 과정을 거칠 수 있다.</li>
</ul>
<blockquote>
<h3 id="clickpoint-와-exemplar의-차이">Click/Point 와 Exemplar의 차이</h3>
<table>
<thead>
<tr>
<th>구분</th>
<th>Click/Point</th>
<th>Image exemplar</th>
</tr>
</thead>
<tbody><tr>
<td>과업</td>
<td>PVS</td>
<td>PCS</td>
</tr>
<tr>
<td>형태</td>
<td>한 점의 좌표</td>
<td>물체를 둘러싼 bounding box</td>
</tr>
<tr>
<td>의미</td>
<td>“이 픽셀은 포함/제외해”</td>
<td>“이런 종류의 물체를 포함/제외해”</td>
</tr>
<tr>
<td>적용 범위</td>
<td>특정 인스턴스 하나</td>
<td>같은 concept의 전체 인스턴스</td>
</tr>
<tr>
<td>수정 대상</td>
<td>마스크 경계</td>
<td>검출 대상 집합/category 해석</td>
</tr>
<tr>
<td>시각 정보</td>
<td>클릭 위치 중심</td>
<td>박스 내부의 ROI visual feature 사용</td>
</tr>
</tbody></table>
</blockquote>
<hr>
<h3 id="모델의-핵심-설계">모델의 핵심 설계</h3>
<p>Introduction에서 설명하는 모델은 크게 세 부분으로 이해할 수 있다.</p>
<h4 id="1-detector">1. Detector</h4>
<p>DETR 기반 detector가 다음 입력을 조건으로 물체를 찾는다.</p>
<ul>
<li>텍스트 명사구</li>
<li>위치⋅박스 같은 geometry</li>
<li>Positive/negative image exemplar</li>
</ul>
<blockquote>
<h4 id="exemplar는-무엇인가요">Exemplar는 무엇인가요?</h4>
<p>SAM 3의 Image exemplar는 입력 형식으로는 <strong>bbox</strong>이다. 하지만 exemplar encoder가 단순히 bbox 좌표만 인코딩하는 것은 아니다.</p>
</blockquote>
<p>정확히는 하나의 exemplar가 다음 쌍으로 주어진다.</p>
<blockquote>
<p>$$$
e_i = (b_i, y_i)
$$$</p>
</blockquote>
<ul>
<li>$b_i$ = $(x_1, y_1, x_2, y_2)$: 예시 물체를 감싼 Bounding box</li>
<li>$y_i \in {\text{positive}, \text{negative}}$: 포함할 예시인지 제외할 예시인지 나타내는 binary label<blockquote>
</blockquote>
논문에 따르면 각 exemplar는 세 종류의 정보를 결합한다. <blockquote>
<p>$$$
t_i^{ex} = [E_{position}(b_i); E_{label}(y_i); \text{RoIPool}(F,b_i)]
$$$</p>
</blockquote>
</li>
<li><em>($E_{position}(b_i)$)*</em>와 <strong>$E_{label}(y_i)$</strong>는 각각 Position Embedding(bbox의 좌표와 크기)와 Label Embedding(pos/neg)이며, $\text{RoIPool}$만 알아봅시다.</li>
<li><strong>ROI-pooled visual feature</strong>
이미지를 먼저 SAM 3의 PE image encoder에 통과시키면 전체 이미지의 feature map $F$가 ㅁ나들어집니다.<blockquote>
</blockquote>
그 다음 bbox에 해당하는 영역의 feature를 ROI Pooling으로 추출합니다.</li>
</ul>
<p>Detector는 identity와 무관하게 현재 이미지 또는 프레임에서 조건에 맞는 물체를 찾는다.</p>
<h4 id="2-tracker">2. Tracker</h4>
<p>Tracker는 SAM 2의 transformer encoder-decoder 및 memory 구조를 계승한다.</p>
<p>Detector가 찾아낸 물체를 시작점으로 삼아 비디오 전체에서 mask와 identity를 전파한다.</p>
<p>Detector와 tracker가 동일한 vision encoder를 공유하지만, 두 모듈은 분리되어 있다. 그 이유는 두 과업의 목표가 충돌하기 때문이다.</p>
<ul>
<li>Detector: 같은 개념에 속하면 identity와 상관없이 모두 찾아야 한다.</li>
<li>Tracker: 비슷하게 생긴 물체끼리도 identity를 엄격히 분리해야 한다.</li>
</ul>
<p>따라서 SAM 3의 &quot;unified model&quot;은 모든 일을 하나의 decoder가 수행한다는 뜻이 아니라, <strong>공유 backbone 위에 역할이 분리된 detector와 tracker를 결합했다는 뜻</strong>이다.</p>
<blockquote>
<p><strong>*&quot;The tracker inherits the SAM 2 transformer encoder-decoder architecture, supporting video segmentation and interactive refinement.&quot;*</strong></p>
</blockquote>
<p>여기서 말하는 <strong>Transformer encoder-decoder는 언어를 생성하는 Transformer가 아니다</strong>. 현재 프레임과 과거 프레임의 시각 정보를 읽어, 특정 물체의 현재 마스크를 출력하는 visual Transformer이다.</p>
<blockquote>
</blockquote>
<p>SAM 2의 아키텍처는 비디오 추적 방식인데, <strong>이전 프레임의 마스크와 물체 appearance를 memory에 저장하고, 현재 프레임 feature와 비교하여 같은 물체의 새 마스크를 예측한다.</strong></p>
<blockquote>
</blockquote>
<p>SAM 2의 tracker는 다음 구성 요소를 가진다.</p>
<ul>
<li>Image Encoder</li>
<li>Prompt Encoder</li>
<li>Memoery Attention</li>
<li>Mask Decoder</li>
<li>Memory Encoder</li>
<li>Memory Bank<blockquote>
</blockquote>
<table>
<thead>
<tr>
<th>구성요소</th>
<th>역할</th>
</tr>
</thead>
<tbody><tr>
<td>Image Encoder</td>
<td>현재 프레임을 visual feature로 변환</td>
</tr>
<tr>
<td>Prompt Encoder</td>
<td>사용자의 점·박스·마스크를 token으로 변환</td>
</tr>
<tr>
<td>Memory Attention</td>
<td>현재 프레임과 과거 물체 memory를 비교</td>
</tr>
<tr>
<td>Mask Decoder</td>
<td>현재 프레임에서 해당 물체의 마스크 예측</td>
</tr>
<tr>
<td>Memory Encoder</td>
<td>예측한 마스크와 현재 feature를 memory로 변환</td>
</tr>
<tr>
<td>Memory Bank</td>
<td>과거 프레임의 물체 정보 저장</td>
</tr>
</tbody></table>
<blockquote>
</blockquote>
Memory는 <strong>위치 + 영역의 시각적 appearnce, identity</strong>를 spatial feature로 인코딩하여 memory bank에 넣는다. (MemLoTrack과 유사)<blockquote>
</blockquote>
다음 프레임에서는 현재 feature가 이 spatial memory와 cross-attention 하는 것입니다.<blockquote>
<blockquote>
<p><strong>SAM 3의 tracker는 SAM 2처럼 과거의 object mask와 appearance를 memory에 저장하고 Transformer attention으로 현재 프레임의 동일 물체를 찾아 mask를 디코딩하며, 사용자가 특정 프레임에서 click으로 mask를 수정하면 그 결과를 memory에 반영하여 비디오 전체로 다시 전파할 수 있다.</strong></p>
</blockquote>
</blockquote>
</li>
</ul>
<h4 id="3-presence-head-what과-where의-분리">3. Presence head: What과 Where의 분리</h4>
<p>open-vocabulary detection에서는 object query 하나가 동시에 두 질문을 해결해야 한다.</p>
<ol>
<li>이 이미지에 해당 개념이 존재하는가? - Recognition, <strong>What</strong></li>
<li>존재한다면 정확히 어디에 있는가? - Localization, <strong>Where</strong></li>
</ol>
<p>SAM 3는 별도의 <strong>presence head</strong>를 두어 이를 분리한다. </p>
<blockquote>
<p><strong>*&quot;Introduce a separate presence head to decouple recognition and localization&quot;*</strong></p>
</blockquote>
<p>Presence head는 이미지 전체를 보고 해당 개념의 존재 여부를 판단하고, object queries는 위치를 찾는 데 집중한다. 이는 특히 <strong>hard negative phrase</strong>를 학습할 때 중요하다.</p>
<p>예를 들어 이미지에 일반 의자는 있지만 <code>Adirondack chair</code>는 없을 수 있다. 비슷하게 생긴 물체가 있다는 이유만으로 마스크를 생성하면 False Positive가 되어버린다. </p>
<p>Presence Head는 이런 상황에서 &quot;정확히 그 개념은 존재하지 않는다&quot;라고 판단하는 역할을 한다.</p>
<hr>
<h3 id="data-engine">Data Engine</h3>
<p>Introduction에서 모델 구조만큼, 어쩌면 그보다 더 중요하다고 보는 것이 바로 데이터 엔진이다.</p>
<p>기존 데이터 엔진과 비교하여 세 가지를 확장한다.</p>
<ol>
<li><strong>Media curation</strong>
균일한 웹 이미지에 의존하지 않고 다양한 이미지⋅비디오 도메인을 수집한다.</li>
<li><strong>Label curation</strong>
ontology와 MLLM을 사용하여 매우 다양한 명사구와 hard negative를 생성한다.</li>
<li><strong>Label verification</strong>
fine-tuned MLLM을 AI verifier로 사용하여 마스크 품질과 누락 여부를 검사한다.</li>
</ol>
<h4 id="파이프라인은-대략-다음과-같다">파이프라인은 대략 다음과 같다.</h4>
<pre><code class="language-text">이미지·비디오 수집
→ 명사구 제안
→ SAM 3가 후보 마스크 생성
→ 이 후보 mask가 pseudo-label
→ 인간/AI가 마스크 품질 및 누락 검사
→ 오류 사례만 인간이 집중 수정
→ 개선된 SAM 3로 다시 후보 생성</code></pre>
<blockquote>
<h3 id="pseudo-labeling">Pseudo-labeling</h3>
<p>SAM 3에서 나오는 pseudo-labeling은 단순히 <strong>*&quot;현재 모델의 예측을 정답으로 저장한다.&quot;*</strong>가 아니다. 모델이 만든 noisy한 후보를 출발점으로 삼고, <strong>mask quality와 exhausitivity를 별도로 검증한 뒤, 필요한 경우 사람이 수정하는 데이터 엔진</strong>이다.</p>
<blockquote>
<p><strong>*&quot;Starting from noisy media-phrase-mask pseudo-labels&quot;*</strong></p>
</blockquote>
</blockquote>
<p>예를 들어보자면, </p>
<ul>
<li>Media: 고양이 3마리가 있는 이미지 </li>
<li>Noun phrase: &quot;cat&quot;</li>
<li>Mask set: {고양이 A mask, 고양이 B mask, 고양이 C mask} <blockquote>
</blockquote>
PCS에서는 단순히 마스크 하나가 정확한 것만으로 부족하다. 해당 Phrase에 맞는 <strong>모든 인스턴스가 빠짐없이 포함된 mask set</strong>이어야 한다.</li>
</ul>
<p>중요한 점은 AI가 모든 annotation을 대신하는 것이 아니라, <strong>쉽고 올바른 샘플을 자동으로 통과시키고 인간을 어려운 오류 사례에 집중시킨다는 것</strong>이다. </p>
<hr>
<h1 id="2-promptable-concept-segmentation-pcs">2. Promptable Concept Segmentation, PCS</h1>
<p>PCS를 한 문장으로 정의하면 다음과 같다.</p>
<blockquote>
<p>*&quot;detect, segment and track all instances of a visual concept specified by a short text phrase, image exemplars, or a combination of both.&quot;*</p>
</blockquote>
<p>즉, 이미지 또는 30초 이하의 짧은 영상에서 사용자가 정의한 시각적 개념에 해당하는 모든 인스턴스를 검출하고, 마스크로 분할하고, 비디오에서는 동일한 identity를 유지하며 추적하는 과업이다.</p>
<h3 id="pcs를-수학적으로-이해하기">PCS를 수학적으로 이해하기</h3>
<p>$$$
\mathcal{I} = (X, t, E)
$$$</p>
<ul>
<li>$X$: 이미지 또는 $T$개 프레임의 비디오</li>
<li>$t$: 선택적인 noun-phrase text prompt</li>
<li>$E$: 선택적인 image exemplar 집합</li>
</ul>
<p>위와 같은 입력이 있다고 가정해보자. 
각 exemplar는 대략 다음과 같다.
$$$
e_j = (f_j, b_j, l_j)
$$$</p>
<ul>
<li>$f_j$: exemplar가 지정된 프레임</li>
<li>$b_j$: bounding box</li>
<li>$l_j \in { +1, -1}$: positive 또는 negative label</li>
</ul>
<p>출력은 개념에 해당하는 인스턴스의 집합이다.
$$$
\mathcal{Y}<em>{image} = {(m_i, b_i, s_i)}^N</em>{i=1}
$$$</p>
<ul>
<li>$m_i$: instance mask</li>
<li>$b_i$: bounding box</li>
<li>$s_i$: concept matching confidence</li>
<li>$N$: 검출된 인스턴스 수 </li>
</ul>
<p>추가로 모든 instance mask를 합친 semantic mask도 출력할 수 있다.</p>
<p>$$$
m_{\text{semantic}} = \bigcup^N_{i=1}m_i  \ \mathcal{Y}<em>{video} = {(\text{ID}_i, m_i^1, m_i^2,...,m_i^T)}^N</em>{i=1}
$$$</p>
<p>하나의 물체에 속하는 시간 방향 마스크 집합을 논문에서는 <strong>masklet</strong>이라고 부른다.
$$$
\\text{masklet}<em>i = {m_i^t}^T</em>{t=1}
$$$
PCS에서는 단순히 각 프레임의 물체를 따로 검출하는 것으로 끝나지 않는다. 서로 다른 프레임의 마스크가 동일한 물체라면 같은 $\text{ID}_i$로 연결해야 한다.</p>
<p><strong>PVS와 PCS의 차이를 조금 더 자세히 표로 정리하면 다음과 같다.</strong></p>
<table>
<thead>
<tr>
<th>항목</th>
<th>PVS: SAM 1·2</th>
<th>PCS: SAM 3</th>
</tr>
</thead>
<tbody><tr>
<td>프롬프트 의미</td>
<td>이 위치의 물체</td>
<td>이 개념에 속하는 물체</td>
</tr>
<tr>
<td>입력</td>
<td>point, box, mask</td>
<td>noun phrase, image exemplar</td>
</tr>
<tr>
<td>기본 출력</td>
<td>프롬프트당 한 인스턴스</td>
<td>일치하는 모든 인스턴스</td>
</tr>
<tr>
<td>대상</td>
<td>특정 물체</td>
<td>물체 집합</td>
</tr>
<tr>
<td>핵심 문제</td>
<td>경계 추정</td>
<td>존재 판단 + 검색 + 분할</td>
</tr>
<tr>
<td>비디오</td>
<td>지정된 물체 전파</td>
<td>새 물체 검출 + identity 추적</td>
</tr>
<tr>
<td>사용자 보정</td>
<td>개별 마스크 수정</td>
<td>concept 집합 수정 + 개별 마스크 수정</td>
</tr>
</tbody></table>
<h3 id="pcs에서-사용할-수-있는-prompt">PCS에서 사용할 수 있는 Prompt</h3>
<p>PCS의 prompt는 크게 세 층으로 구분해야 한다.</p>
<h4 id="1-noun-phrase-prompt-category-정의">1. Noun-phrase prompt: category 정의</h4>
<p>텍스트는 명사와 선택적인 modifier로 구성된 단순 명사구이다.</p>
<ul>
<li><code>cat</code></li>
<li><code>striped cat</code></li>
<li><code>red apple</code></li>
<li><code>yellow school bus</code></li>
<li><code>small window</code></li>
<li><code>Adirondack chair</code></li>
</ul>
<p>Noun phrase는 이미지나 비디오 전체에 적용되는 <strong>global prompt</strong>이다.</p>
<p>비디오의 특정 프레임에 <code>fish</code>가 보이지 않더라도 text prompt의 의미가 그 프레임에서 사라지는 것은 아니다. 영상 전체에서 fish에 해당하는 물체를 검출하고 추적해야 한다.</p>
<h4 id="2-positive-exemplar">2. Positive exemplar</h4>
<p>사용자가 bounding box로 올바른 예시를 지정한다.
$$$ 
e^+ = (f, b, +1)
$$$
예를 들어, <code>bird</code>라는 텍스트만으로 특정 종류의 새를 잘 찾기 못한다면, 원하는 새 한마리를 positive exemplar로 제공할 수 있다.</p>
<p>그 결과는 단순히 그 박스의 물체 하나를 추가하는 것이 아니다.</p>
<p>$$$
\text{positive exemplar} \Rightarrow \text{비슷한 concept의 다른 인스턴스까지 검색}
$$$
따라서 positive exemplar는 다음 상황에 특히 유용하다.</p>
<ul>
<li>희귀한 concept이어서 텍스트만으로 잘 인식하지 못할 때 </li>
<li>여러 인스턴스 중 일부를 놓쳤을 때 </li>
<li>사용자가 의도한 의미가 텍스트만으로 분명하지 않을 때 </li>
<li>특정 도메인의 생소한 물체를 예시로 정의할 때 </li>
</ul>
<h4 id="3-negative-exemplar">3. Negative exemplar</h4>
<p>False Positive를 box로 지정한다.
$$$
e^- = (f, b, -1)
$$$
예를 들어 모델이 <code>bat</code>을 동물이 아니라 야구 방망이로 해석하였다면, 잘못 검출된 방망이를 negative exemplar로 제공할 수 있다.</p>
<p>Negative exemplar 역시 해당 물체 하나만 삭제하는 신호라기보다는, 그 예시가 대표하는 잘못된 해석을 억제하는 <strong>concept-level feedback</strong>이다.</p>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/e9dec52a-f03c-4f0e-97da-7df6534dbd12/image.png" alt=""></p>
<p>Figure 3는 PCS의 전체 흐름을 네 가지 단계로 보여준다.
유저가 모델과 어떻게 상호작용하며 원하는 결과를 얻는지 보여주는 흐름이다.</p>
<ol>
<li><strong>Initial Prompt</strong>: 먼저 유저가 <code>a fish</code>처럼 텍스트로 개념을 알려주거나, 특정 물고기 이미지를 긍정 예시로 주면서 &quot;이런 걸 찾아줘&quot; 하고 시작한다.</li>
<li><strong>Output (초기 결과)</strong>: 그럼 SAM 3가 그 프롬프트에 맞춰서 이미지나 비디오에서 해당 개념에 맞는 객체들을 분할한 마스크들을 보여준다. 이것이 모델의 첫 번째 시도 결과이다.</li>
<li><strong>Refinement Prompts</strong>: 만약 모델이 처음에 잘못 분할했거나 놓친 부분이 있다면 유저가 직접 긍정(초록) 또는 부정(빨강) 예시를 추가하여 피드백을 준다.</li>
<li><strong>Output (Refined)</strong>: 이 피드백을 받아 SAM 3는 마스크들을 다시 정제하고, 유저의 의도에 맞는 <strong>refined mask</strong>를 최종적으로 보여준다.<blockquote>
<p>기존 SAM식 correction과 가장 다른 점인데, </p>
</blockquote>
<ul>
<li>PVS correction: 한 번의 입력으로 물체 하나 수정</li>
<li>PCS correction: 한 번의 exemplar로 같은 오류를 공유하는 여러 물체가 함께 수정될 수 있음<blockquote>
</blockquote>
논문의 interactive experiment에서도 이러한 일반화 효과 때문에 PCS가 이상적인 PVS 기반 수동 수정 방식보다 빠르게 개선되는 경향을 보인다. 다만 exemplar로는 경계 자체의 품질을 계속 고칠 수 없기 때문에, 일정 시점 이후에는 PVS refinement와 결합하는 것이 유리하다.</li>
</ul>
</li>
</ol>
<h3 id="모든-prompt의-규칙">모든 Prompt의 규칙</h3>
<p>논문은 이 규칙을 강하게 제시한다.</p>
<blockquote>
<p><strong>모든 prompt는 같은 category definition을 가져야 한다.</strong></p>
</blockquote>
<p>Text와 exemplar가 동일한 category를 정의해야 하며, 그렇지 않으면 모델의 동작은 undefined이다.</p>
<p>논문에 나온 예시는 다음과 같다.</p>
<ul>
<li>text prompt: <code>fish</code></li>
<li>exemplar: <code>fish의 꼬리만 박스로 지정</code></li>
</ul>
<p>이 조합은 유효한 refinement가 아니다.</p>
<ul>
<li><code>fish</code>는 전체 물고기를 category로 정의한다.</li>
<li>꼬리만 지정하면 <code>fish tail</code>이라는 part category로 정의한다.</li>
<li>전체와 부분은 서로 다른 category이므로 prompt semantics가 충돌한다.</li>
</ul>
<p>올바른 방법은 text 자체를 <code>fish tail</code>로 변경하는 것이다.</p>
<h3 id="concept-prompt와-object-query의-구별">Concept prompt와 object query의 구별</h3>
<p>concept prompt와 object query는 명백히 다른 것이다.</p>
<p>DERT object query와 연결하면 PCS 구조를 더 정확하게 이해할 수 있다. </p>
<h4 id="concept-prompt">Concept prompt</h4>
<p><code>&quot;Stripped cat&quot;</code> 를 사용자의 semantic intent를 정의해보자.</p>
<h4 id="object-queries">Object queries</h4>
<p>SAM 3 detector 내부에는 기본적으로 $Q=200$개의 learned object query가 있다.
$$$ 
q_1, q_2,..., q_200
$$$
각 query는 concept prompt와 이미지 feature를 보면서 특정 위치의 물체 후보를 담당한다.
$$$
q_i \rightarrow(b_i, m_i, s_i)
$$$
따라서 하나의 concept prompt가 모든 object query를 조건화하여 200개의 Object query가 만들어지고, concept에 해당하는 여러 instance를 출력하는 관계이다.</p>
<p>다시 말해서 </p>
<ul>
<li>concept propmt와 물체는 <strong>1:N</strong></li>
<li>object query와 최종 물체는 대체로 <strong>1:1</strong></li>
<li>각 object query는 하나의 instance prediction slot</li>
<li>여러 query가 같은 concept의 서로 다른 물체를 담당할 수 있다.</li>
</ul>
<blockquote>
<h3 id="detr-object-query란">DETR object query란?</h3>
<p>DETR의 <strong>object query</strong>는 이미지 속 물체를 하나씩 찾아내기 위한 학습 가능한 <strong>prediction slot</strong>이다. (slot에 집중하자)</p>
</blockquote>
<p>예를 들어 SAM 3 detector가 $Q=200$개의 object query를 사용한다면, 각 query는 이미지 feature를 cross-attention으로 읽고 다음과 같은 하나의 후보를 출력한다.</p>
<blockquote>
<p>$$$
q_i \rightarrow (\text{box}_i, \text{mask}_i, \text{score}_i)
$$$
즉, object query 하나는 대략 다음 질문을 수행하는 셈이다. 
*&quot;내가 담당해야 할 물체가 이미지 어디에 있지&quot;*</p>
</blockquote>
<h3 id="query마다-물체-종류가-정해져-있는가">Query마다 물체 종류가 정해져 있는가?</h3>
<p>아니다. 예를 들어 $q_7$이 항상 고양이를 담당하는 것은 아니다.</p>
<ul>
<li>이미지 A에서는 $q_7$이 고양이를 담당</li>
<li>이미지 B에서는 자동차 담당</li>
<li>이미지 C에서는 아무 물체를 담당하지 X<blockquote>
</blockquote>
따라서 objecty query는 category 자체가 아니라, 물체 하나가 들어갈 수 있는 <strong>빈 출력 슬롯</strong>이다.<h3 id="one-to-one-hungarian-matching">One-to-one Hungarian matching</h3>
학습할 때는 예측 query와 GT 객체를 1:1로 대응시키기 위해 헝가리안 매칭을 사용한다.<blockquote>
</blockquote>
정답 물체가 세 개이고 query가 200개라면, </li>
<li>$q_7$ : 고양이</li>
<li>$q_31$ : 신호등</li>
<li>$q_62$ : 사람</li>
<li>나머지 197개 쿼리 : No object<blockquote>
</blockquote>
최적 매칭은 다음과 같이 구한다.<blockquote>
<p>$$$
\hat {sigma} = \argmin <em>{\sigma} \sum \limits</em>{j=1}^{N_\text{GT}} \mathcal(L)<em>{\text{match}}(y_j, \hat y</em>{\sigma(j)})
$$$
이 1:1 매칭으로 같은 GT 물체를 여러 query가 중복해서 담당하지 않도록 학습된다. 이것이 DETR에서 NMS 의존도를 없앨 수 있는 핵심 원리이다.</p>
</blockquote>
</li>
</ul>
<h3 id="왜-pcs는-본질적으로-모호하지">왜 PCS는 본질적으로 모호하지?</h3>
<p>PCS는 고정된 category list가 아니라 임의의 groundable noun phrase를 받는다. 어휘를 넓히는 순간 category definition을 데이터셋이 완전히 통제하기 어려워진다. </p>
<p>논문은 Ambiguity를 다섯 종류로 설명한다.</p>
<ul>
<li><p><strong>다의어</strong>: <code>mouse</code>는 컴퓨터 마우스, 동물 쥐가 가능하다.</p>
</li>
<li><p><strong>Subjective modifier</strong></p>
<ul>
<li><code>large dog</code>, <code>cozy chair</code>와 같은 주관적인 속성은 명확한 경계가 없다. 사람마다 포함하는 instance가 달라질 수 있다.</li>
</ul>
</li>
<li><p><strong>Context-dependent 또는 ungroundable concept</strong></p>
<ul>
<li><code>brand identity</code>: 이미지 안의 특정 픽셀 집합과 직접 대응하기 어려운 개념이다. 로고를 의미하는지, 색상 체계를 의미하는지, 제품 디자인 전체를 의미하는지 불분명하다.</li>
</ul>
</li>
<li><p><strong>Bondary ambiguity</strong></p>
<ul>
<li><code>mirror</code>: 거울의 반사면만 mask로 만들어야 하는지, 바깥 frame까지 포함해야 하는지 애매하다. 이는 category는 합의했지만, <strong>mask extent</strong>에 합의하지 못한 경우이다.</li>
</ul>
</li>
<li><p><strong>Visual uncertainty</strong></p>
<ul>
<li>occlusion</li>
<li>motion blur</li>
<li>낮은 해상도</li>
<li>물체 간 심한 중첩</li>
</ul>
</li>
</ul>
<p> 위와 같은 경우 concept 자체는 명확해도 어디까지가 물체인지 판단하기 어렵다.</p>
<h3 id="sam-3의-ambiguity-해결법">SAM 3의 ambiguity 해결법</h3>
<p>논문은 ambiguity를 네 층에서 처리한다.</p>
<h4 id="1-annotation-guideline">1. Annotation guideline</h4>
<p>가능하면 annotator들이 동일한 해석을 하도록 데이터 수집 지침을 설계한다. 지나치게 모호하거나 visual grounding이 불가능한 phrase는 거부할 수 있다.</p>
<h4 id="2-세-명의-독립-annotation">2. 세 명의 독립 annotation</h4>
<p>SA-Co/Gold의 주요 positive datapoint에는 세 명의 expert가 독립적으로 annotation을 수행한다.</p>
<p>중요한 점은 세 사람이 SAM 3 결과를 보고 수정한 것이 아니라, 각자 처음부터 mask를 생성했다는 것이다. 따라서 모델의 오류에 의해 해석이 유도되는 것을 줄인다.</p>
<h4 id="oracle-evaluation">Oracle evaluation</h4>
<p>모델 prediction을 세 개의 valid GT과 각각 비교한 후, 가장 높은 local F1을 주는 annotation을 선택한다. 
$$$
\text{score}(p) = \max_{g\in{g_1, g_2, g_3}} F_1(p,g)
$$$
이는 모델에게 무조건 유리하게 점수를 주려는 것이라기보다, <strong>여러 인간 해석 중 하나와 일치한 올바른 예측을 오답 처리하지 않기 위한 장치</strong>인 셈이다.</p>
<h4 id="ambiguity-head">Ambiguity head</h4>
<p>학습 데이터에 두 가지 해석이 절반식 존재한다고 해보자.</p>
<p>일반적인 단일 모델은 손실을 줄이기 위해 두 해석을 모두 약 50% confidence로 출력할 수 있다. 그 결과 서로 충돌하거나 겹치는 mask가 생긴다</p>
<p>SAM 3는 이를 피하기 위해 $K=2$인 mixture-of-experts 형태의 ambiguity head를 사용한다.</p>
<p>각 expert의 loss를 $L_K$라고 하면, 
$$$
k^* = \argmin_k L_k \ L_{\text{WTA}} = L_{k^<em>}
$$$
가장 낮은 loss를 얻은 expert만 gradient를 받는 *</em>winner-takes-all** 방식이다.
그 결과, </p>
<ul>
<li>Expert 1은 해석 A에 특화</li>
<li>Expert 2는 해석 B에 특화</li>
<li>Inference 시 classification head가 더 적절한 Expert 선택</li>
</ul>
<p>중요한 세부사항은 ambiguity head가 새로운 box나 mask를 직접 생성하는 것이 아니라 <strong>classification logits</strong>를 조정한다는 것이다. Box, mask, presence score 자체는 변경하지 않는다.</p>
<p>즉, 목표는 모든 해석이 합집합을 출력하는 것이 아니라 <strong>하나의 일관된 해석을 선택하는 것</strong>이다. </p>
<blockquote>
<h3 id="근데-expert는-무엇인가요">근데 Expert는 무엇인가요?</h3>
<p><strong>expert는 사람도 아니고 LLM Agent도 아니다.</strong> 
신경망 내부에 있는 여러 개의 작은 branch/head를 의미한다.</p>
</blockquote>
<p>SAM 3의 ambiguity head에서는 동일한 입력을 서로 다른 방식으로 해석할 수 있도록 $K$개의 expert를 <strong>병렬</strong>로 둔다.</p>
<pre><code>공유된 SAM 3 feature
        │
        ├── Expert 1 → 해석 A의 classification logits
        └── Expert 2 → 해석 B의 classification logits</code></pre><p>논문에서는 $K=2$가 가장 잘 작동했다고 한다.</p>
<h3 id="왜-이름이-expert이지">왜 이름이 Expert이지?</h3>
<p>각 branch가 서로 다른 데이터 패턴이나 해석에 <strong>전문화되어 학습되기 때문에</strong> 그렇게 부른다.</p>
<blockquote>
</blockquote>
<p>예를 들어 phrase가 <code>&quot;large circular shape&quot;</code>라고 할 때, 이미지에는 다음 모두가 있을 수 있다. </p>
<ul>
<li>큰 원영 물체 전체 </li>
<li>그 물체 안의 작은 원형 부분 <blockquote>
</blockquote>
두 해석이 학습 데이터에 섞여 있다면 일반 모델은 둘 다 50% confidence로 출력 및 충돌 mask가 생긴다. <blockquote>
</blockquote>
</li>
<li><em>Ambiguity head를 사용하면*</em></li>
<li>Expert 1 $\rightarrow$ 큰 원형 물체 전체라는 해석</li>
<li>Expert 2 $\rightarrow$ 내부의 원형 부분이라는 해석<blockquote>
</blockquote>
처럼 서로 다른 interpretation에 특화될 수 있다.<h3 id="그럼-inference에서-누가-선택">그럼 Inference에서 누가 선택?</h3>
사용할 expert를 사람이 직접 고르지는 않는다. 
별도의 classification head가 입력을 보고 어떤 expert의 해석이 더 적절한지 선택한다.<blockquote>
</blockquote>
또 SAM 3의 ambiguity head는 독립된 SAM 3 모델 두 개를 돌리는 구조가 아니다. 공유된 본체 위에서 <strong>classification logits를 다르게 조정하는 작은 전문가 분기들</strong>에 가깝고, box / mask / presence score 자체를 직접 새로 생성하지는 않는다. <blockquote>
<blockquote>
</blockquote>
</blockquote>
</li>
<li><strong>Human expert</strong>: SA-Co 평가용 annotation을 만드는 숙련된 사람</li>
<li><strong>AI verifier/annotator</strong>: 데이터 엔진에서 mask를 검사하는 <strong>MLLM</strong></li>
<li><strong>MoE expert</strong>: 신경망 내부의 학습 가능한 예측 brnach</li>
<li><strong>Agent</strong>: 외부 도구나 모델을 반복 호출하여 과제 수행하는 시스템</li>
</ul>
<h1 id="3-model">3. Model</h1>
<p>이 부분은 SAM 3의 전체 구조를 개요 수준에서 설명한다. 상세한 layer 구성, Loss, matching 설정, 학습 hyperparamteter는 Appendix에서 다룬다.</p>
<h2 id="sam-2를-pcs까지-일반화">SAM 2를 PCS까지 일반화</h2>
<p>SAM 3는 기존 SAM 2의 PVS 능력을 유지하면서 PCS까지 추가한 모델이다.</p>
<p>입력 prompt는 두 계열이다.</p>
<h3 id="concept-propmt-물체의-종류를-정의">Concept propmt: 물체의 종류를 정의</h3>
<ul>
<li>Simple noun phrase</li>
<li>positive/negative image exemplar</li>
</ul>
<p>이 prompt는 &quot;어떤 종류의 물체들을 모두 찾을 것인가?&quot;를 정의한다.</p>
<h3 id="visual-prompt-개별-물체를-지정">Visual prompt: 개별 물체를 지정</h3>
<ul>
<li>point</li>
<li>box</li>
<li>mask</li>
</ul>
<p>이 prompt는 기존 SAM처럼 &quot;이 특정 물체의 mask를 수정하라&quot;는 역할을 한다.</p>
<p>따라서 SAM 3의 interaction에는 두 수준이 공존한다.</p>
<table>
<thead>
<tr>
<th>보정 수준</th>
<th>사용 prompt</th>
<th>기능</th>
</tr>
</thead>
<tbody><tr>
<td>Concept-level</td>
<td>image exemplar</td>
<td>false positive/negative 인스턴스 집합 수정</td>
</tr>
<tr>
<td>Instance-level</td>
<td>point, box, mask</td>
<td>특정 인스턴스의 mask 경계 수정</td>
</tr>
</tbody></table>
<p>SAM 3의 전체 architecture는 크게 다음으로 나뉜다.
<code>Shared PE backbone</code> + <code>Detector</code> + <code>Tracker</code> + <code>Memory Bank</code>
<img src="https://velog.velcdn.com/images/jm_mg_se/post/ed934fc1-940a-4649-a2d5-a4b9dbde28bc/image.png" alt="">
Figure 4의 색은 각 구성 요소의 출처를 의미한다.</p>
<ul>
<li>초록색: Perception Encoder, PE에서 가져온 부분</li>
<li>파란색: SAM 2에서 계승한 부분</li>
<li>노란색: SAM 3에서 새로 추가한 detector</li>
<li>회색 화살표: 정보의 흐름</li>
</ul>
<p>핵심은 <strong>detector와 tracker가 서로 다른 역할을 동시에 수행한다는 것</strong>이다.</p>
<ul>
<li>Detector: 현재 프레임에서 concept에 맞는 물체를 새로 찾음</li>
<li>Tracker: 이미 추적 중인 물체의 위치와 mask를 현재 프레임으로 전파 </li>
<li>Matching: detector 결과와 tracker 결과가 같은 물체인지 연결</li>
<li>Memory: 확정된 결과를 다음 프레임 추적을 위해 저장</li>
</ul>
<h2 id="detector-architecture">Detector architecture</h2>
<p>Detector는 <strong>DETR 계열 구조</strong>이다.</p>
<p>전체 흐름은 다음과 같다.
<code>Image/Text/Exemplars</code> $\rightarrow$ <code>Encoding</code> $\rightarrow$ <code>Fusion Encoder</code> $\rightarrow$ <code>DETR-like Decoder</code> $\rightarrow$ <code>Boxes, Scores, Masks</code></p>
<h3 id="31-image와-text-encoding">3.1. Image와 text encoding</h3>
<p>이미지와 text prompt는 <strong>aligned Preception Encoder, PE</strong>를 통해 encoding 된다. </p>
<ul>
<li><strong>Image: <code>펭귄 여러 마리가 있는 프레임</code></strong></li>
<li><strong>Text</strong>: <code>a penguin</code></li>
</ul>
<p>PE는 이미지와 텍스트를 서로 비교할 수 있는 vision-language representation으로 변환한다.</p>
<p>Image exemplar가 있다면 별도의 exemplar encoder를 거친다.</p>
<pre><code>Text tokens ───────┐
                   ├── prompt tokens
Exemplar tokens ──┘</code></pre><p>** 논문은 text token과 image exemplar token을 합쳐서 prompt tokens**라고 부른다. 여기서 prompt token은 사용자의 concept를 표현하는 token이고, 뒤에 나오는 object query와는 다르다.</p>
<h3 id="32-fusion-encoder">3.2 Fusion Encoder</h3>
<p>Fusion Encoder는 말 그대로 <strong>이미지 정보와 프롬프트 정보를 먼저 융합하는 Transformer Encoder</strong>이다. Text Encoder와 Image Encoder를 묶어서 Fusion Encoder라고 부르는 것이 아니라, <strong>두 Encoder 뒤에 별도로 추가된 Transformer 모듈이다.</strong></p>
<p>그러니까 논문의 Figure 4에는 안보이지만, 아래와 같은 구조로 이루어지는 것이다.
Fusion Encoder가 <strong>6개의 Transformer block으로 구성</strong>되며, 각 block에는 대략 다음 연산이 들어간다. <code>Image-token self-attention</code> $\rightarrow$ <code>Image-to-prompt cross-attention</code> $\rightarrow$ <code>MLP</code></p>
<pre><code class="language-text">Image
  ↓
Image Encoder
  ↓
비조건화 image tokens X ──────────────┐
                                      │
Text                                  │
  ↓                                   │
Text Encoder                          │
  ↓                                   ▼
text tokens ────────────────→ Fusion Encoder
                                      │
Image exemplar                        │
  ↓                                   │
Exemplar Encoder                      │
  ↓                                   │
exemplar tokens ────────────→─────────┘
                                      ↓
                        조건화된 image tokens X&#39;
                                      ↓
                              DETR Decoder</code></pre>
<blockquote>
<h3 id="참고로-정렬과-융합은-다르다">참고로 정렬과 융합은 다르다.</h3>
</blockquote>
<ul>
<li>Image/text Encoder의 역할: Alignment<blockquote>
</blockquote>
이미지와 텍스트를 비교 가능한 표현 공간에 배치하는 것이고, </li>
<li><strong>Fusion Encoder의 역할: Conditional Interaction</strong><blockquote>
</blockquote>
Encoder들이 각 입력을 표현하고 Fusion Encoder가 그 표현들을 실제로 상호작용 시킨다. </li>
</ul>
<p>SAM 3에서는 이미지 encoder가 만든 feature를 곧바로 DETR decoder에게 넣지 않는다. 먼저 사용자가 입력한 text/exemplar prompt를 이미지 feature에 주입하여 <strong>prompt-aware image feature</strong>로 바꾼다.</p>
<p>Image encoder가 만든 feature는 아직 특정 prompt에 조건화되지 않은 상태이다. 
$$$
F_{\text{image}} = \text{ImageEncoder}(I)
$$$
Fusion Encoder는 image feature가 prompt token을 cross-attention 하도록 만든다.
$$$
F_{\text{conditioned}} = \text{FusionEncoder}(F_{\text{iamge}}, P)
$$$
여기서 $P$는 text와 exemplar로 구성된 prompt token이다.
이를 직관적으로 해석하면 다음과 같다. (조건화와 조건화되지 않은 차이를 살펴보자)</p>
<ul>
<li><strong>Unconditioned image feature</strong>: <code>&quot;이미지 안에 어떤 시각적 패턴들이 있는가?&quot;</code></li>
<li><strong>Conditioned image feature</strong>: <code>&quot;이미지에서 penguin과 관련된 시각적 패턴은 어디에 있는가?&quot;</code></li>
</ul>
<p>동일한 이미지라도 prompt가 달라지면 conditioned feature도 달라진다.
$$$
F(I, \text{&quot;penguin&quot;}) \neq F(I, \text{&quot;snow&quot;})
$$$</p>
<h3 id="33-detr-like-decoder와-object-query">3.3 DETR-like decoder와 object query</h3>
<p>Fusion Encoder 다음에는 DETR-like decoder가 있다. 
여기에는 여러 개의 learned object query가 들어간다.
$$$
q_1, q_2, ..., q_Q
$$$ 
각 object query는 다음에 cross-attention을 한다.</p>
<ul>
<li>conditional image embeddings</li>
<li>prompt tokens</li>
</ul>
<p>즉, query $q_i$는 다음 문제를 해결한다: <code>&quot;현재 프롬프트와 일치하는 물체 후보가 이 위치에 있는가?&quot;</code>
각 decoder layer는 object query마다 두 가지를 예측한다.</p>
<ol>
<li><strong>Classification logit</strong>
 이 query가 가리키는 물체가 prompt에 해당하는가?</li>
<li><strong>Bounding-box delta</strong>
 이전 decoder layer가 예측한 box를 어떻게 수정할 것인가?<h4 id="일반-detr와-다른-classification-의미">일반 DETR와 다른 classification 의미</h4>
일반적인 closed-vocabulary DETR라면 각 query가 <code>pereson</code>, <code>car</code>, <code>dog</code> 등 여러 class 중 하나를 예측한다.</li>
</ol>
<p>하지만 SAM 3는 prompt를 하나씩 조건으로 사용하기 때문에 기본 classification이 binary이다.
$$$
c_i = \Bigg{
\begin{aligned}
1, q_i\text{가 prompt concept과 일치} \
0, q_i\text{가 prompt concept과 불일치}
\end{aligned}
\Bigg}
$$$</p>
<p>예를 들어 prompt가 <code>a penguin</code>이라면, </p>
<ul>
<li>query 4: penguin과 일치</li>
<li>query 19: penguin과 일치</li>
<li>query 52: 바위이므로 불일치</li>
<li>query 87: 새처럼 보이지만 penguin은 아니므로 불일치 </li>
</ul>
<p>따라서 관계는 다음과 같다.
<code>하나의 concept prompt</code> $\rightarrow$ <code>여러 object queires</code> $rightarrow$ <code>여러 matching</code></p>
<h3 id="34-box-region-positional-bias">3.4 Box-region-positional bias</h3>
<p>SAM 3는 object query가 특정 box 주변에 attention을 집중하도록 <strong>box-region-positional bis</strong>를 사용한다.</p>
<p>Decoder가 box를 예측하면 다음 layer는 query의 해당 box와 관련된 pixel에 더 집중할 수 있다.</p>
<p>다만 논문은 최근 DETR 변형들이 복잡한 attention을 사용하는 것과 달리, SAM 3에서는 기본적으로 vanilla attention을 유지한다고 말한다.</p>
<p>여기서 말하는 <strong>vanilla attention</strong>은 원래 Transformer의 <strong>표준 dense multi-head attention</strong>을 말한다.
$$$
\text{Attention}(Q, K, V) = \text{softmax}(\frac{QK^\top}{\sqrt{d}})V 
$$$ </p>
<p>각 query가 모든 key와 유사도를 계산하고, softmax weight로 모든 value를 가중합한다.</p>
<p>SAM 3에서는 여기에 위치 정보를 위한 bias를 추가한다. 
$$$ 
\text{Attention}(Q, K, V) = \text{softmax}(\frac{QK^\top}{\sqrt{d}} + B_{\text{box-pos}})V 
$$$
따라서 SAM 3의 attention은 </p>
<blockquote>
<p><strong>연산 자체는 모든 token을 보는 표준 attention이고, 현재 query의 box와 pixel의 상대 위치를 bias로 넣어 관련 영역에 더 집중시킨다.</strong></p>
<h3 id="sam-3-decoder에서-무슨-일이-일어나는가">SAM 3 decoder에서 무슨 일이 일어나는가?</h3>
<p>SAM 3에는 기본저긍로 $Q=200$개의 object query가 있다.</p>
</blockquote>
<p>각 decoder layer에서 </p>
<pre><code>Object queries
    ↓ self-attention
서로 중복되지 않도록 정보 교환
    ↓ prompt cross-attention
noun phrase/exemplar 정보 확인
    ↓ image cross-attention
이미지의 모든 spatial token에서 물체 위치 탐색
    ↓
box, class score, mask 예측</code></pre><p>이미지 cross-attention에서 obejct query가 하나의 모든 image token과 attention을 계산한다.
$$$
q_i \longleftrightarrow {x_1, x_2, ..., x_P}
$$$
연산량은 대략 $O(N_qP)$이다. </p>
<ul>
<li>$N_q$: object query 수</li>
<li>$P$: Image token의 수 <blockquote>
</blockquote>
이것이 바로 <code>dense</code> 또는 <code>vanilla cross-attention</code>이다.</li>
</ul>
<h3 id="35-mask-head와-semantic-head">3.5 Mask head와 semantic head</h3>
<p>Detector는 box만 출력하는 것이 아니다.</p>
<h4 id="instance-mask-head">Instance mask head</h4>
<p>MaskFormer에서 가져온 mask head를 이용하여 object query 별 instance mask를 예측한다.
$$$
q_i \rightarrow (b_i, m_i, s_i)
$$$</p>
<ul>
<li>$b_i$: bounding box</li>
<li>$m_i$: instance mask</li>
<li>$s_i$: prompt matching score</li>
</ul>
<h4 id="semantic-segmentation-head">Semantic segmentation head</h4>
<p>별도의 semantic head는 각 pixel이 prompt concept에 해당하는지 binary하게 예측한다.
$$$
S(x, y) = p(\text{pixel}(x, y) \text{matches prompt})
$$$
예를 들어 prompt가 <code>penguin</code>이면</p>
<ul>
<li>instance semgentation: 펭귄 1, 2, 3을 각각 분리</li>
<li>semantic segmentation: 모든 펭귄 pixel을 하나의 foreground로 표시</li>
</ul>
<p>이 두 출력은 PCS가 instance-level과 semantic-level segmentation을 모두 지원하게 한다.</p>
<h2 id="presence-token">Presence token</h2>
<p>Section 3에서 가장 중요한 새로운 설계이다.
논문은 다음과 같이 지적한다.</p>
<blockquote>
<p><strong>*&quot;It can be difficult for each of the proposal queries to both recognize and localize an object.&quot;*</strong></p>
</blockquote>
<p>Oject query 하나가 동시에 다음 두 가지를 수행하면 목표가 충돌할 수 있다.</p>
<h4 id="recognition-what">Recognition: What</h4>
<p><code>이 이미지에 penguin이라는 concept가 존재하나?</code>
이 판단에는 이미지 전체의 context가 필요하다.</p>
<ul>
<li>설원인가?</li>
<li>주변에 새가 있는가?</li>
<li>주변 물체와 형태적 관계는 어떠한가?</li>
</ul>
<h4 id="localization-where">Localization: Where</h4>
<p><code>&quot;Penguin이 있다면 정확히 어디에 있는가?&quot;</code>
이는 특정 영역과 경계에 집중하는 local한 문제이다.</p>
<p>Recognition을 위해 query가 이미지 전체를 보도록 강제하면 localization 집중력이 떨어질 수 있다. 반대로 local region만 보면 해당 물체가 실제로 prompt concept인지 판단하기 어렵다.</p>
<p>SAM 3는 이를 <strong>global presence token</strong>으로 분리한다. </p>
<h3 id="presence-token의-역할">Presence token의 역할</h3>
<p>Presence token은 이미지 또는 프레임 전체에서 noun phrase가 존재하는지를 예측한다.
$$$
p_{\text{presence}} = p(\text{NP is present in input})
$$$
예를 들어 propmt가 <code>a penguin</code>이라면, 
$$$
p_{\text{presence}} = p(\text{현재 프레임에 penguin이 존재})
$$$
이 값은 모든 object query가 공유한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰] SAM: Segment Anything (작성 중)]]></title>
            <link>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-SAM-Segment-Anything</link>
            <guid>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-SAM-Segment-Anything</guid>
            <pubDate>Fri, 10 Jul 2026 05:29:20 GMT</pubDate>
            <description><![CDATA[<p>source: <a href="https://arxiv.org/pdf/2304.02643">Segment Anything</a>
이번에 살펴볼 논문은 SAM: Segment Anything이다.</p>
<p>사실 SAM을 VL-SAM, GenerateU 등 OED 모델들을 리뷰하기 전에 먼저 살펴봤어야하는데, 순서가 약간 뒤바뀌었다..😵‍💫</p>
<p>본 포스트에서는 SAM의 모든 부분을 리뷰하지는 않고, <strong>기존 Object detection의 proposal 개념을 SAM 방식으로 재해석</strong>하는 것에 초점을 맞추고자 한다.</p>
<p>SAM은 이미지 segmentation을 위한 하나의 Foundation Model이다.</p>
<blockquote>
<h3 id="sam은-rpn처럼-region-proposal-module을-학습하는-모델인가-아니면-promptable-segmentation-model을-proposal-generator처럼-사용하는-것인가">SAM은 RPN처럼 region proposal module을 학습하는 모델인가, 아니면 promptable segmentation model을 proposal generator처럼 사용하는 것인가?</h3>
</blockquote>
<p>위 질문을 가지고 SAM을 알아보고자 한다. </p>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/a1ceb0f1-2552-4c3f-80ee-30420849cff4/image.png" alt=""></p>
<p>저자들은 SAM이 Promptable하게 만들어져서 zeero-shot transfer가 가능하다고 한다.
Promptable이 대체 무엇이길래 이것이 가능할까?</p>
<blockquote>
<p><strong>promptable</strong>하다는 것은 &quot;무엇을 segment할지&quot;를 모델 파라미터 안에 고정하지 않고, <strong>inference 때 prompt로 지정할 수 있다</strong>는 뜻이다.</p>
</blockquote>
<p>그래서 새로운 task를 새로 학습하지 않고도 prompt 형태로 바꿔 넣으면 쓸 수 있고, 이게 <strong>zero-shot transfer</strong>와 연결된다.</p>
<p>기존 segmentaiton/detection 모델은 보통 task가 고정되어있다.</p>
<pre><code class="language-text">입력 이미지 -&gt; COCO 80개 class에 대한 mask 예측
입력 이미지 -&gt; LVIS class별 instance segmentation
입력 이미지 -&gt; semantic segmentation map</code></pre>
<p>이런 모델은 출력 공간이 훈련 때 정해져있어서 새로운 데이터셋, 새로운 클래스, 새로운 task가 오면 보통 fine-tuning이 필요하다.</p>
<p>반면 SAM은 다음과 같이 학습된다.
<code>이미지 + prompt -&gt; prompt가 가리키는 valid mask</code></p>
<p>여기서 prompt는 point, box, mask, text 등이 될 수 있다. 위에 첨부한 Figure 1에서 (a)를 보면 알 수 있다.</p>
<p>즉, 모델이 배우는 것은 &#39;고양이 클래스를 찾아라&#39;가 아니라, </p>
<pre><code>이 점이 가리키는 영역을 segment해라
이 box 안의 object를 segment해라
이 mask를 refine해라</code></pre><p>와 같은 <strong>조건부 mask 생성 능력</strong>이다.</p>
<p>그래서 zero-shot이 가능해진 이유는 </p>
<blockquote>
<p><strong>*&quot;새로운 task를 모델 head를 바꾸거나 재학습하지 않고, prompt를 설계해서 기존 Promptable segmentation task로 변환할 수 있기 때문이다.&quot;*</strong> </p>
</blockquote>
<p>근데, promptable하다고 자동으로 zero-shot이 보장되는 것은 아니다. 
<strong>새 task를 prompt 형태로 잘 바꿀 수 있을 때</strong> zero-shot transfer가 가능하다.</p>
<p>저자들은 SAM을 디자인할 때 <strong><em>광범위한 downstream application을 가능하게 할 만큼 충분히 일반적인 Promptable segmentation 작업을 정의한다</em></strong> 라고 말한다.</p>
<blockquote>
<p>&quot;광범위한 downstream application을 가능하게 한다&quot;?</p>
</blockquote>
<p>이것은 SAM을 특정 하나의 segmentation 모델로만 쓰는 것이 아닌, 여러 다른 vision task의 부품처럼 가져다 쓸 수 있다는 뜻이다.</p>
<blockquote>
</blockquote>
<p>여기서 downstream application은 &quot;SAM을 학습한 다음에 실제로 적용하는 하위/응용 task들&quot;을 말한다.</p>
<blockquote>
<p>그럼 <strong>promptable segmentation</strong>은 무엇이지?
이것은 말 그래도 <strong><em>이미지와 prompt를 같이 입력하면, 그 prompt가 가리키는 대상의 segmentation mask를 출력하는 task.</em></strong> 인 것이다.</p>
</blockquote>
<hr>
<p>우리가 주목할 것은 </p>
<h1 id="2-segment-ahything-task">2. Segment Ahything Task</h1>
<p>이다. 그 전에, Introduction을 아주 짧게 요약하자면 다음과 같다.</p>
<blockquote>
<h2 id="introduction-요약">Introduction 요약</h2>
<p>SAM 논문은 NLP의 Foundation model처럼, segmentation에서도 다양한 task와 데이터 분포에 일반화되는 모델을 만들고자 한다. 이를 위해 저자들은 특정 class나 task에 고정된 segmentation이 아니라, point/box/text 같은 prompt를 받아 어떤 대상이든 <strong>mask</strong>로 반환하는 <strong>promptable segmentation task</strong>를 제안하고, 이를 학습하기 위한 모델 SAM과 대규모 데이터셋 SA-1B를 함께 구축했다.</p>
</blockquote>
<p><strong>Section 2: Segment Anything Task</strong>는 SAM 논문의 &quot;문제 정의&quot; 파트이다. </p>
<blockquote>
<p>여기서 말하는 핵심은
<strong>*&quot;Segmentation을 특정 class를 맞히는 문제가 아니라, prompt가 주어졌을 때 그 prompt가 가리키는 valid mask를 출력하는 문제로 다시 정의하자&quot;*</strong> 이다.</p>
</blockquote>
<p>Introduction에서 저자들은 NLP의 Foundation Model에서 영감을 얻었다고 말했다.
Segmentation에서도 이러한 모델을 만들고자, 유사한 기능을 가진 작업을 정의하는데, <strong>Task</strong>는 다음과 같다.</p>
<h3 id="task">Task</h3>
<p>먼저 SAM에서의 prompt들을 살펴보면 다음과 같다.
<code>foreground / background point</code>, <code>rough box</code>, <code>rough mask</code>, <code>text</code>, <code>any information indicating what to segment</code>. 그래서 task는 단순하다.</p>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/2f08a0f2-f142-4422-bd8f-b5f0bc953ded/image.png" alt=""></p>
<p><strong>Image + prompt -&gt; Valid segmentation mask</strong>
여기서 중요한 것이 바로 <strong>Valid mask</strong>이다. 
논문의 저자들은 prompt가 애매할 수 있다고 본다. 예를 들어 한 점을 찍었는데 그 점이 사람의 셔츠 위라면, prompt가 의미하는 대상은 <code>셔츠</code>, <code>상반신</code>, <code>사람 전체</code> 모두 의미할 수 있다.</p>
<p>이때 SAM은 반드시 &quot;정답 하나&quot;만을 맞히는 게 아니라, 그중 하나라도 합리적인 mask를 내면 된다고 정의한다. 이게 SAM이 <strong>Ambiguity, 모호함</strong>을 다루는 출발점이다.</p>
<h3 id="왜-이런-task를-정의했을까">왜 이런 Task를 정의했을까?</h3>
<p>저자들은 NLP의 prompt 방식을 segmentation으로 가져오고 싶어 한다.
언어모델이 다양한 질문에 prompt로 반응하듯, segmentation 모델도 다양한 segmentation 요구를 prompt로 저리하게 만들자는 의미이다.</p>
<p>즉, 기존 방식이 <strong><em><code>Image -&gt; 정해진 class들의 segmentation</code></em></strong>이었다면, SAM은
<strong><em><code>Image + prompt -&gt; prompt가 지시하는 대상의 segmentation</code></em></strong> 으로 바꾼 것이다.</p>
<h3 id="pre-training은-어떻게-연결되는가">Pre-training은 어떻게 연결되는가?</h3>
<p>SAM은 학습할 때 interactive segmentation처럼 prompt sequence를 시뮬레이션 한다.</p>
<p>예를 들자면, </p>
<pre><code>처음 point 또는 box prompt 제공
-&gt; mask 예측
-&gt; 이전 예측 mask와 GT mask가 다른 영역(Error Region)에 추가 point 제공
-&gt; 다시 mask 예측</code></pre><blockquote>
<p>참고로 Error Region은 두 종류로, FP: Foregound Point로 추가, FN: Background point로 추가한다. </p>
</blockquote>
<p>SAM 학습에서는 이전 예측과 GT가 불일치하는 Error Region에서 다음 point를 뽑는다. 그 point가 <strong>FN에 있으면 Foreground point, FP에 있으면 Background point로 사용</strong>한다. </p>
<blockquote>
</blockquote>
<p>다시 말해서, <strong><em>이전 mask 예측이 GT와 다른 지점에 point를 찍어서, 그 위치가 target object에 포함되어야 하는지 아닌지를 prompt로 알려준다.</em></strong></p>
<p>하지만, 기존 interactive segmentation과도 차이가 있다. 기존 방식은 &quot;사람이 충분히 클릭하면 결국 맞추자&quot;에 가깝고, SAM은 <strong>Prompt가 하나만 있어도 가능한 valid mask를 내야 한다는 쪽</strong>이다.</p>
<h3 id="zero-shot-transfer와의-연결">Zero-shot transfer와의 연결</h3>
<p>이 Task 정의 덕분에 downstream task를 prompt로 바꿔서 풀 수 있다.</p>
<ul>
<li>Object proposal: Grid point prompt를 많이 넣기</li>
<li>Instance segmentation: Detector가 만든 box를 prompt로 넣기 </li>
<li>Interactive segmentation: 사람의 click을 point promptfh sjgrl </li>
<li>Mask refinement: Rough mask를 prompt로 넣기 </li>
</ul>
<p>즉, SAM은 각각의 task에 대해 새로 학습되는 것이 아닌, task를 prompt 형태로 바꿔서 수행한다. 이게 Section 2에서 말하는 zero-shot transfer의 핵심이다.</p>
<blockquote>
<h3 id="섹션의-core-idea">섹션의 Core idea</h3>
<p>SAM은 segmentation을 class-specific prediction문제가 아니라 prompt-conditioned mask generation 문제로 재정의한다. 이때 prompt가 모호하더라도 하나 이상의 합리적인 valid mask를 출력하도록 task를 설계했기 때문에, 다양한 downstream segmentation task를 prompt enginnering으로 zero-shot 수행할 수 있다.</p>
</blockquote>
<h1 id="3-segment-anything-model">3. Segment Anything Model</h1>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/6d0b7521-4400-44bf-bb7a-4173723537a4/image.png" alt=""></p>
<p>이번 파트는 Sectino 2의 task 정의를 실제 모델 구조로 구현한 부분이다.</p>
<p>핵심을 먼저 말하자면</p>
<blockquote>
<p><strong>*&quot;SAM은 이미지를 한 번 무겁게 인코딩하여 image embedding을 만들고, 이후 point/box/mask/text prompt를 가볍게 인코딩해서 빠른 mask decoder로 mask를 뽑는는 prompt-conditioned segmentation model이다.&quot;*</strong></p>
</blockquote>
<p>구조는 크게 3개이다.</p>
<ul>
<li><strong>Image Encoder</strong></li>
<li><strong>Prompt Encoder</strong></li>
<li><strong>Mask Decoder</strong></li>
</ul>
<p>전체 흐름은 다음과 같이 표현할 수 있다.</p>
<pre><code>image
 -&gt; image encoder
 -&gt; image embedding

prompt: point / box / mask / text
 -&gt; prompt encoder
 -&gt; prompt embedding

image embedding + prompt embedding
 -&gt; mask decoder
 -&gt; masks + predicted IoU score</code></pre><h3 id="image-encoder">Image Encoder</h3>
<p>이미지를 feature로 바꾸는 부분이다.</p>
<p>SAM에서는 ViT 기반 Image Encoder를 사용한다. 논문에서는 MAE로 pre-trained된 Vision Transformer를 사용한다고 설명한다.</p>
<p>역할은 단순하다. <code>입력 이미지 -&gt; dense image embedding</code></p>
<p>중요한 점은 image encoder가 <strong>무겁다</strong>라는 점이다. 대신 이미지를 한 번만 처리한다.</p>
<blockquote>
<p><strong><em>이미지 1장에 대해 Image Embedding을 미리 계산하여 여러 prompt가 들어와도 Image Encoder를 다시 돌리지 않는다.</em></strong></p>
</blockquote>
<p>이것이 바로 SAM이 Interactive하게 빠르게 동작할 수 있는 이유이다.
사용자가 점을 찍거나 box를 바꿀 때마다 전체 ViT를 다시 돌리는 것이 아닌, 이미 만들어둔 Image embedding에 prompt만 새로 넣어서 Decoder를 돌린다.</p>
<blockquote>
<h4 id="sam의-general-visual-knowledge는-대부분-image-encoder-안에-들어있다-prompt가-바뀌어도-image-embedding은-고정된다">SAM의 general visual knowledge는 대부분 Image Encoder 안에 들어있다. prompt가 바뀌어도 Image Embedding은 고정된다.</h4>
</blockquote>
<h3 id="prompt-encoder">Prompt Encoder</h3>
<p>prompt를 Embedding으로 바꾸는 부분이다.</p>
<p>논문은 prompt를 크게 두 종류로 나눈다. <strong>Sparse prompt: <code>point</code>, <code>box</code>, <code>text</code>와 Dense prompt: <code>mask</code>.</strong></p>
<p>point prompt는 위치 정보와 foreground/background 정보를 함께 가진다.
<em>(Foreground point: 이 위치는 target object 안쪽이다. background point: 이 위치는 target object 바깥쪽이다.)</em></p>
<p>box prompt는 top-left corner와 bottom-right corner를 Embedding으로 표현한다.</p>
<p>mask prompt는 이미 spatial한 형태라서 convolution을 통해 image embedding과 같은 공간적 feature처럼 바꿔준다.</p>
<p>즉, prompt encoder의 역할은 <strong>사람이 준 <code>클릭</code>, <code>박스</code>, <code>rough mask</code> 같은 입력을 mask decoder가 이해할 수 있는 token/embedding으로 바꿔주는 것</strong>이다. </p>
<p>여기서 중요한 건 Prompt가 class label이 아니라는 점이다.
<code>dog</code>, <code>car</code>, <code>person</code> 같은 class를 고르는 것이 아니라, <strong>어디를 segment할지 알려주는 조건 정보</strong>인 것이다.</p>
<h3 id="mask-decoder">Mask Decoder</h3>
<p>SAM에서 제일 중요한 부분이 바로 mask decoder이다.</p>
<p>역할은 <code>image embedding + prompt embedding -&gt; mask</code> 로 말할 수 있겠다.</p>
<p>논문에서는 <code>lightweight mask decoder</code>라고 부르는데, image encoder에 비해 훨씬 가볍게 설계되어 있어서 그렇게 부른다. 이러한 장점 덕분에 prompt가 바뀔 때마다 빠르게 mask를 다시 만들 수 있다.</p>
<p>mask decoder의 내부는 Transformer decoder 계열 구조이다. 핵심 아이디어는 <strong>Image feature와 prompt feature가 attention으로 서로 정보를 주고받는 것</strong>이다.</p>
<p>쉽게 말하자면, <strong><code>prompt token</code></strong>은 &quot;이 위치/박스/마스크가 관심 대상이야.&quot; 라고 알려주고, <strong><code>Image Embedding</code></strong>은 &quot;이미지 전체의 시각 정보는 이렇게 생겼어&quot; 라고 말해준다. </p>
<p>이 둘을 통해서 prompt가 가리키는 영역은 이미지에서 어디까지인가를 확인하고, mask foreground probability를 각 위치마다 예측한다. </p>
<h3 id="multi-masks-ambiguity-해결">Multi Masks: Ambiguity 해결</h3>
<p>여기가 바로 SAM다운 부분이다.</p>
<p>한 prompt가 항상 명확하지는 않다. 예를 들어서 사람의 셔츠 위에 점 하나를 찍으면 가능한 답이 여러 개가 될 수 있기 때문이다.</p>
<p>만약 모델이 mask 하나만 출력하면, 여러 가능한 정답을 평균낸 이상한 mask를 만들 수 있다. 그래서 SAM은 Ambiguous prompt에 대해 <strong>여러 개의 valid mask</strong>를 출력하도록 설계된다.</p>
<p>논문에서는 기본적으로 3개 mask output이 충분하다고 본다.</p>
<ul>
<li>mask 1: part</li>
<li>mask 2: object</li>
<li>mask 3: whole object/context</li>
</ul>
<p>정확히 이 세 이름으로 고정된 것은 아니지만, 직관적으로는 whole/part/subpart 구조를 커버하려는 것이다.</p>
<p>그리고 각 mask마다 score도 함께 출력한다.
<code>mask candidates + predicted IoU scores</code>
predicted IoU는 모델이 스스로 이 mask가 얼마나 좋을것 같은지 추정하는 confidence socre라고 보면 된다. </p>
<blockquote>
<h4 id="predicted-iou">Predicted IoU?</h4>
<p>이 predicted IoU의 평가 기준은 다음과 같다.
<strong>*&quot;이 mask가 GT mask와 얼마나 겹칠 것 같은지를 모델이 예측한 값&quot;*</strong></p>
</blockquote>
<p>즉, 기준은 일반적인 IoU이다. SAM은 학습할 때 GT mask를 알고 있으니까, 실제 IoU를 계산할 수 있다. 그래서 mask decoder가 mask 후보들을 만나면, 추가 Head가 각 mask에 대해 <strong>&quot;이 mask의 실제 IoU가 대략 얼마일까?</strong>를 예측하도록 학습된다.</p>
<blockquote>
</blockquote>
<p>중요한 점은 <strong>Inference</strong> 때에는 GT가 없다는 것이다. 그래서 실제 IoU를 계산할 수 없는데, 대신 SAM이 학습해둔 IoU Prediction Head가 &quot;품질 예상 점수&quot;를 뽑는다. 
<code>mask 1: predicted IoU 0.91 \ mask 2: predicted IoU: 0.76</code>.. 이런 식으로 말이다.</p>
<blockquote>
</blockquote>
<p>그래서 predicted IoU는 <strong>Class Confidence가 아니다.</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Grounding Model 선택 시 고려할 사항들]]></title>
            <link>https://velog.io/@jm_mg_se/Grounding-Model-%EC%84%A0%ED%83%9D-%EC%8B%9C-%EA%B3%A0%EB%A0%A4%ED%95%A0-%EC%82%AC%ED%95%AD%EB%93%A4</link>
            <guid>https://velog.io/@jm_mg_se/Grounding-Model-%EC%84%A0%ED%83%9D-%EC%8B%9C-%EA%B3%A0%EB%A0%A4%ED%95%A0-%EC%82%AC%ED%95%AD%EB%93%A4</guid>
            <pubDate>Wed, 08 Jul 2026 01:06:20 GMT</pubDate>
            <description><![CDATA[<p>먼저 <strong>Grounding Model</strong>은 무엇일까요?</p>
<blockquote>
<h2 id="grounding-model">Grounding Model</h2>
<p>&quot;언어(Text)와 시각 정보(Image)의 물리적 위치를 정확하게 연결(Mapping)해 주는 모델&quot;</p>
</blockquote>
<p>쉽게 말해, 기존의 AI가 이미지 전체를 보고 *&quot;이 사진엔 드론이 있네요&quot;*라고 단순 매칭(Image-Text Matching)을 했다면, 그라운딩 모델은 &quot;문장에서 말하는 &#39;드론&#39;은 바로 이미지 안의 [X좌표, Y좌표] 요기야!&quot; 하고 정확한 위치(박스나 마스크)를 짚어내는(Localization) 모델입니다. 언어라는 추상적인 개념을 실제 시각 공간에 닻을 내리듯(Grounding) 고정시킨다는 의미에서 붙은 이름입니다.</p>
<blockquote>
</blockquote>
<h3 id="main-tasks">Main Tasks</h3>
<h4 id="1-grounded-object-detection">1. Grounded Object Detection</h4>
<p>일반적인 Object Detection 모델은 미리 학습한 단어(예: car)만 찾을 수 있습니다. 하지만 그라운딩 모델은 자유롭고 복잡한 서술형 문장(Phrase)을 입력받아 정밀하게 물체를 찾아냅니다.</p>
<ul>
<li>텍스트 입력: &quot;오른쪽 나무 뒤에 숨어있는 빨간색 자동차&quot;</li>
<li>모델의 행동: 이미지 전체를 뒤져서 수많은 차 중, &#39;오른쪽&#39;, &#39;나무 뒤&#39;, &#39;빨간색&#39;이라는 텍스트 조건에 정확히 부합하는 타겟 영역에 바운딩 박스를 칩니다.<h4 id="2-rec-referring-expression-comprehension">2. REC (Referring Expression Comprehension)</h4>
말 그대로 &#39;지칭하는 표현을 이해&#39;하는 태스크입니다. 이미지 내에 동일한 사물이 여러 개 있을 때, 언어적 맥락을 파악해 정확히 사용자가 의도한 사물 하나를 골라내는 능력입니다</li>
</ul>
<p>그럼, 대표적인 Grounding Model로는 무엇이 있을까요?</p>
<p>본 포스트에서는 컴퓨터 비전 및 멀티모달 학계에서 베이스라인으로 가장 널리 쓰이는 핵심 모델들 세 가지를 알아보겠습니다.</p>
<h2 id="glip-vs-grounding-dino-vs-kosmos-2">GLIP vs Grounding DINO vs KOSMOS-2</h2>
<p>세 모델은 &#39;텍스트와 박스 좌표를 어떻게 연결(Grounding)하느냐&#39;의 아키텍처 관점에서 패러다임 차이가 있습니다.</p>
<h3 id="glip-grounded-language-image-pre-training">GLIP (Grounded Language-Image Pre-training)</h3>
<p>GLIP은 초기 기틀을 확립한 모델입니다.</p>
<p>기존의 Object Detection 문제(소프트맥스로 클래스 분류)를 &quot;구문 정렬(Phrase Grounding) 문제&quot;로 재정의하여 대성공을 거둔 모델입니다.</p>
<ul>
<li><p><strong>구조</strong>: 이미지 인코더와 텍스트 인코더가 독립적(e.g., Swin Transformer + BERT)으로 존재하고, 이 둘의 특성(Feature)을 깊게 융합(Deep Fusion)한 뒤, 이미지 패치와 단어 토큰 간의 유사도 매칭(Dot Product)을 통해 박스 위치를 찾아냅니다.</p>
<p>독립된 인코더에서 나온 것을 그냥 결합하는 것이 아닌, 네트워크 중간 레이어마다 서로 Deep Fusion하는것이 핵심입니다. Image Feature $O$, Text Feature $P$가 있을 때, 다음과 같은 형태로 서로의 정보를 흡수합니다.
$$$
O = \text{X-MHA}(O, P) = \text{X-MHA}(P, O)
$$$</p>
</li>
<li><p><strong>특징</strong>: 구조가 직관적이고 매칭 맵을 시각화하기엔 좋지만, &#39;박스 자체의 정밀한 좌표 회귀&#39; 전용 모듈의 힘이 조금 약합니다.</p>
</li>
</ul>
<h3 id="grounding-dino">Grounding DINO</h3>
<p>Grounding DINO는 현재 디텍션 베이스라인의 표준입니다.</p>
<p>강력한 <strong>DETR(DEtection TRansformer)</strong> 계열 디텍터인 <strong>DINO</strong> GLIP의 Grounded 개념을 결혼(Marrying)시킨 모델입니다.</p>
<ul>
<li><p>구조: 디텍터 내부의 Transformer 디코더 안에서 이미지 쿼리와 텍스트 프롬프트가 Cross-Modality Decoder 레이어를 거치며 아주 정밀하게 상호작용합니다.</p>
<ul>
<li><strong>핵심 레이어 1 (Feature Enhancer)</strong>: 이미지와 텍스트 피처를 입력받아 양방향 크로스 어텐션(Bi-Directional Cross-Attention)을 통해 초기 정렬을 수행합니다.</li>
<li><strong>핵심 레이어 2 (Cross-Modality Decoder)</strong>: 여기가 핵심입니다. 모델이 예측할 물체의 후보인 &#39;Learnable Object Queries&#39;를 이미지와 텍스트 정보 양쪽에 모두 어텐션(Attention) 시킵니다. 즉, 쿼리가 *&quot;이미지 속 사물 경계&quot;<em>와 *&quot;텍스트 프롬프트의 의미&quot;</em>를 동시에 고려하면서 박스 좌표와 카테고리를 동시에 정밀하게 깎아나갑니다.</li>
</ul>
</li>
<li><p>특징: 현재 오픈셋/오픈월드 연구에서 가장 강력하고 정밀한 박스 성능을 보여줍니다. 텍스트 조건(예: &quot;오른쪽 나무 뒤에 숨은 빨간 차&quot;)을 주었을 때 박스를 깎아내는 정밀도가 세 모델 중 가장 뛰어납니다.</p>
</li>
</ul>
<blockquote>
<h3 id="original-dino와의-차이">Original DINO와의 차이</h3>
<p>DINO라고 하면 보통 <strong>Meta의 DINO</strong>로, Self-Supervised Learning 기반의 비전 백본 모델을 많이 생각하십니다.</p>
</blockquote>
<p>하지만 Grounding DINO의 유래는 <strong>IDEA의 DETR 계열 SOTA Object Detector</strong>입니다.</p>
<ul>
<li>결정적인 차이점 (핵심 아이디어):<blockquote>
</blockquote>
<ul>
<li>일반 DINO (②번): 정해진 카테고리(예: 클래스 ID 0은 사람, 1은 자전거)의 인덱스만 맞추는 모델입니다. 언어(Text)를 전혀 모릅니다.<blockquote>
</blockquote>
<ul>
<li>Grounding DINO: 이 강력한 디텍터 DINO에 &#39;언어(Text)를 이해하는 뇌&#39;를 이식한 모델입니다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="kosmos-2">KOSMOS-2</h3>
<p>KOSMOS-2는 멀티모달 생성형 LLM (MLLM)입니다.</p>
<p>앞의 두 모델이 &#39;디텍터&#39; 기반이었다면, KOSMOS-2는 <strong>&quot;인과적 언어 모델(Causal Language Model, GPT 스타일)&quot; 기반의 멀티모달</strong> 모델입니다. 때문에 앞의 두 모델들과 달리 이미지와 박스 좌표를 전부 <strong>언어(Text)</strong>형태로 통일합니다.</p>
<ul>
<li><p>핵심 구조 (Pixel-to-Token): 이미지 영역을 표현하는 바운딩 박스 좌표 [$X_{min}$, $Y_{min}$, $X_{max}$, $Y_{max}$]를 이산화(Discretization)하여, 미리 정의된 위치 토큰(예: <code>&lt;box_start&gt;</code>, <code>&lt;loc_45&gt;</code>, <code>&lt;loc_122&gt;</code>, <code>&lt;box_end&gt;</code>)으로 변환합니다.</p>
</li>
<li><p>작동 방식: 입력으로 이미지가 들어오면, 차례대로 다음 토큰을 예측하는 디코딩을 수행합니다.</p>
</li>
</ul>
<p>출력 예시: &quot;In this image, we can see a <box_start><loc_12><loc_34>...<box_end> drone flying.&quot;</p>
<ul>
<li>특징: 디텍션 전용이 아니라 대화(VQA), 캡셔닝(Image Captioning)을 하면서 동시에 물체 위치를 짚어줄 수 있는 생성형 Open-Ended에 가깝습니다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰] Open-Det: An Efficient Learning Framework for Open-Ended Detection ]]></title>
            <link>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Open-Det-An-Efficient-Learning-Framework-for-Open-Ended-Detection</link>
            <guid>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Open-Det-An-Efficient-Learning-Framework-for-Open-Ended-Detection</guid>
            <pubDate>Tue, 07 Jul 2026 05:32:25 GMT</pubDate>
            <description><![CDATA[<p>source: <a href="https://arxiv.org/pdf/2505.20639">Open-Det: An Efficient Learning Framework for Open-Ended Detection </a></p>
<p>이 논문은 우리가 이전 포스트에서 다룬 GenerateU의 한계를 깨부순 새로운 모델이다.</p>
<p>때문에 GenerateU의 포스트를 먼저 보고 오는 것을 추천한다. 👉 <a href="https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-GenerateU-Generative-Region-Language-Pretraining-for-Open-Ended-Object-Detection">GenerateU 포스트 보러가기</a></p>
<h1 id="abstract">Abstract</h1>
<p>Open-Ended Object Detection(OED)는 추론 시 추가적인 카테고리를 요구하지 않고, 객체를 탐지하고 자유 형식으로 해당 범주 이름을 생성하는 태스크이다.</p>
<p>그러나 GenerateU와 같은 기존 OED 모델은 훈련을 위해 대규모 데이터셋을 필요로 하며, 수렴이 느리고 성능이 제한적이다.</p>
<p>이를 위해 저자들은 네 가지 모듈로 구성된 Open-Det 프레임워크를 제안한다.</p>
<p>Open-Det은 객체 탐지와 객체 이름 생성기를 재구성하여 바운딩 박스 및 객체 이름 생성 과정 모두에서 모델 훈련을 가속화한다.</p>
<p>Visual과 Language의 간극을 해소하기 위해, 저자는 <strong>V-to-L</strong> 및 <strong>L-to-V</strong> 정렬을 제안하고, 프롬프트 증류기와 결합하여 VLM의 지식을 VL-prompts로 전이시켜 LLM의 정확한 객체 이름 생성을 가능하게 한다.</p>
<p>또한 Contradictory Supervision을 제거하기 위해 새로운 손실 함수인 <strong>Masked Alignment Loss</strong>를 설계하고 분류를 향상시키기 위한 Joint Loss를 도입하여 효율을 높인다.
<img src="https://velog.velcdn.com/images/jm_mg_se/post/f5dc12a6-8c93-4836-b310-b1d69e2e49e9/image.png" alt="">
GenerateU와 비교하여 Open-Det은 훈련 데이터의 1.5%, 훈련 에포크의 20.8%, 더 적은 GPU(V100 4개 : A100 16개) 자원만을 사용하여 훨씬 더 높은 성능을 달성하였다.</p>
<p>Figure 1을 보면 GenerateU의 지표들은 학습이 진행됨에 따라 완만하고 느리게 상승하는 반면, <strong>Open-Det</strong>은 초기 에포크부터 매우 빠르게 성능이 올라가는 것을 볼 수 있다.</p>
<p>단 31 에포크만에 GenerateU가 훨씬 더 많은 데이터와 자원을 들여 달성한 최고 성능 지점들을 모두 추월하거나 대등한 수준에서 도달하여, 프레임워크가 추구하는 <strong>Effective Learning</strong>을 완벽히 보여준다.</p>
<h1 id="1-introduction">1. Introduction</h1>
<p>Open-Vocabulary Object Detection은 기존의 closed-set 탐지에서 Open-set 탐지로 범위를 크게 확장하여 훈련 데이터의 고정된 범주를 넘어선 객체 위치 파악 및 식별을 가능하게 한다.</p>
<p>그러나 OVD는 추론 시 탐지 결과를 얻기 위해 여전히 추가적인 어휘 입력을 필요로 하고, 이러한 의존성은 보조적 언어 지식 사전에 대한 필수적인 종속성을 생산하여, Open-world 시나리오에서의 모델 탐지 능력을 크게 제한한다.</p>
<p>최근 Open-Ended Object Detection, OED는 추론 단계에서 사전 정의 객체 범주의 필요성을 없애는 보다 일반적이고 실용적인 탐지 태스크로 부상했따.</p>
<p>GenerateU의 End-to-End 프레임워크는 OED를 <strong>Generation, 생성</strong>문제로 공식화하여, Dense Object Detection을 Free-form 및 관련 이름 생성을 가능하게 한다.</p>
<p>하지만, GenerateU의 비효율성을 야기하는 3가지 근본 원인이 있는데,</p>
<h3 id="1-vision-language-간의-semantic-gap">1) Vision-Language 간의 semantic gap</h3>
<p>Detector에서 나온 Vision query를 고차원 특징 공간에서 LLM으로 직접 연결하는 방식은 두 모달리티 간의 근본적 정렬 한계를 가진다. </p>
<blockquote>
<h3 id="표현-차원과-정보-밀도의-비대칭성">표현 차원과 정보 밀도의 비대칭성</h3>
<p>가장 직관적인 한계는 두 Feature Space의 차원과 채널 구조가 완전히 다르다는 것이다.</p>
</blockquote>
<ul>
<li>Vision Query ($Q_d$): 대개 Transformer 기반 탐지기의 디코더 쿼리는 $256$차원 수준의 상대적으로 압축된 채널을 가진다. 이는 bbox를 찾고 정렬 지표를 연산하는 데에 최적화되어 있는 것이다.</li>
<li>Text Embedding($T_e$ or <strong>LLM Space</strong>): CLIP이나 T5같은 거대한 모델의 임베딩 공간은 보통 768차원 혹은 그 이상의 고차원 공간에 텍스트 세맨틱이 넓고 Dense하게 분포되어 있다.<blockquote>
</blockquote>
256차원의 비전 쿼리를 단순히 Linear Layer 하나로 768 차원으로 맵핑해봐야, 고차원 언어 공간이 요구하는 풍부한 semantic 정보의 밀도를 채우지 못해 <strong>&#39;정보 결핍(Insufficient Information)&#39;</strong> 상태로 표현 정렬이 불완전해진다.</li>
</ul>
<h3 id="2-contradictory-supervision">2) Contradictory Supervision</h3>
<p>미니배치 혹은 이미지 내에 동일한 카테고리의 객체가 여러 개 존재할 때, <strong>단순 Contrastive Alignment Loss</strong>를 사용한다면 하나의 쿼리 외에 다른 동일한 카테고리 텍스트 임베딩을 전부 Negative로 처리하여 <strong>Gradient Conflict</strong>를 유발한다.</p>
<blockquote>
<p>GenerateU류 구조에서는 이미지 안의 객체 category들 사이의 관계를 충분히 고려하지 못해, alignment loss가 서로 충돌하는 supervision을 만들 수 있다고 주장한다.</p>
</blockquote>
<p>예를 들어, 어떤 query가 특정 텍스트 embedding과 가까워져야하는 동시에, 비슷한 category나 관련 object 때문에 다른 방향의 gradient를 받을 수 있다. 그러면 학습 신호가 깨끗하지 않고, 서로 반대 방향으로 당기는 gradient가 생기는 것이다.</p>
<blockquote>
<blockquote>
<p><strong>단순 Contrastive Alignment Loss는 무엇인가?</strong>
object query와 text embedding을 같은 공간에서 맞추는 loss이다.</p>
</blockquote>
<p>예를 들어, detector가 어떤 객체 query <code>q_i</code>를 만들고, text encoder가 category text embedding <code>t_j</code>를 만들었다고 해보자.
그러면 similarity matrix는 </p>
</blockquote>
<pre><code class="language-text">S(i, j) = similarity(q_i, t_j)</code></pre>
<p>즉, <code>q_i</code>가 각 text embedding과 얼마나 가까운지 계산한다.</p>
<blockquote>
<blockquote>
</blockquote>
<p>단순 contrastive loss는 보통 이렇게 생각한다.</p>
</blockquote>
<pre><code class="language-text">q_i의 정답 text = t_i
q_i는 t_i와 가까워져야 함.
q_i는 t_i를 제외한 모든 t_j와 멀어져야 함</code></pre>
<p>이건 classification softmax랑 비슷하게, <code>q_i</code>입장에서 <code>t_i</code> 하나만 정답 클래스고, 나머지 text embedding들은 전부 오답 class 인 것이다.
<strong>*&quot;중요한건 한 이미지 안에 같은 category 객체가 여러 개 있을 수 있으니, 문제가 발생하는 것이다.&quot;*</strong></p>
<blockquote>
<p>Open-Det은 Masked Alignment Loss로 이 False Negative를 제거해서 alignment 학습을 안정화하려고 하는 것이다.</p>
</blockquote>
<h3 id="3-헤비급-llm-head와-노이즈-정렬">3) 헤비급 LLM Head와 노이즈 정렬</h3>
<p>T5 같은 모델은 32,128 개의 토큰에 대응하는 무거운 선형 레이어를 가진다.
학습 초기 정렬되지 않은 비전 쿼리가 이 거대한 Head에 입력된다면, 사전 학습된 강력한 가중치를 망가뜨려 수렴을 저해한다.</p>
<blockquote>
<p><strong>그렇다면 대규모 데이터셋에 대한 의존성을 제거하면서 훈련 수럼을 가속화하고, 훈련 효율성과 탐지 성능을 높이는 더 효율적인 OED는 없는가?</strong></p>
</blockquote>
<p>이러한 의문을 위해 저자들은 <strong>Open-Det</strong>이라는 프레임워크를 제안한다. <strong>시각 탐지기</strong>와 <strong>객체 이름 생성기(LLM)</strong> 양단의 수렴을 가속화하며, 고정된 VLM으로부터 시각-언어 정렬 지식을 <strong>VL-prompts</strong> 형태로 증류(distillation)하는 혁신적 구조를 보인다.</p>
<p><strong>Open-Det</strong>은 네 가지 핵심 요소로 이루어져있다.</p>
<ol>
<li>객체 탐지기</li>
<li>프롬프트 증류기</li>
<li>객체 이름 생성기</li>
<li>시각-언어 정렬기</li>
</ol>
<p>구체적으로 Open-Det은 두 가지 주요 측면에서 전반적인 수렴 속도를 향상시킨다.
바로 <strong>(1)bbox detector</strong>와 <strong>(2)훈련 가속화</strong>.</p>
<h3 id="1-accelerating-the-training-for-the-box-detector">(1) Accelerating the training for the box detector</h3>
<p>기존의 Direct 매칭 방식과는 달리, Open-Det은 하나의 GT에 여러 쿼리를 매칭하는 <strong>One-to-Many</strong>구조와 최종 예측을 위한 <strong>One-to-One</strong> 구조를 분리하여 하나의 디코더 내에 통합했다.</p>
<p>이를 통해 추가적인 브렌치 없이 학습 수렴을 극대적으로 올린다.</p>
<ul>
<li>One-to-one matching만 쓰면 학습 신호가 sparse해서 느릴 수 있다.</li>
<li>One-to-many matching을 넣으면 positive supervision이 많아져서 학습이 빨라진다. </li>
</ul>
<p>하지만 inference 품질을 위해 one-to-one 구조도 유지를 해야하니, 이 둘을 <strong>Decoupled 하게 결합하여 detector convergence를 빠르게 만든다.</strong></p>
<h3 id="2-accelerating-the-training-for-the-object-name-generation">(2) Accelerating the training for the object name generation</h3>
<p><strong><em>사실 여기가 더 중요하다. 박스만 잘 찾는다고 끝나는 것이 아닌, 이름을 생성해야 한다.</em></strong></p>
<p>무거운 오리지널 LLM Head 가중치를 고정하여 초기 노이즈로부터 보호하고, 가벼운 LoRa Head만 학습시켜 파라미터를 아낀다.</p>
<blockquote>
<p>LoRA head는 작은 low-rank parameter만 학습하는 방식으로, trainable parameter 수가 줄고, 학습이 가벼워진다.</p>
</blockquote>
<p>LLM의 훈련을 용이하게 하고 robustness를 올리기 위해 <strong>Text Denoising</strong>훈련 접근 방식을 설계한다. </p>
<blockquote>
<p>이건 LLM이 객체 이름을 생성할 때 입력 text나 prompt 쪽의 noise에 더 강해지도록 만드는 학습이다.</p>
</blockquote>
<h3 id="3-vision-to-language-distillation-module-vld-m">(3) Vision-to-Language Distillation Module (VLD-M)</h3>
<p>시각-언어 증류 모듈(VLD-M)을 Prompt Distiller 안에 넣는 것을 제안하여 VLM으로부터 시각-언어 정렬 지식을 LLM을 위한 새로 도입된 VL-Prompts로 전이시킨다.</p>
<p><strong>GenerateU는 vision query를 LLM에 직접 넣는 쪽에 가까웠다면, Open-Det은 VLM의 vision-language alignment 지식을 가져와서 LLM이 이해하기 쉬운 VL-prompt로 바꾼다.</strong></p>
<p><strong>그 다음 BVLA-M이 나온다.</strong> BVLA-M은 Bidirectional Vision-Language Alignment Module로, Vision-Language Aligner 안에 들어가며, Vision query와 text embedding을 더 잘 맞추기 위해 설계된다.</p>
<blockquote>
<p>중요한 점은 <strong>Bidirectional</strong>인데, 단순 vision에서 language로 맞추는게 아니라, vision-to-language와 language-to-vision 방향을 함께 고려한다. 객체 검출에서는 vision query가 text category 의미를 잘 찾아야 하는 동시에 text embedding도 어떤 visual query와 잘 대응되는지 안정적으로 정렬되어야 하기 때문이다. </p>
<blockquote>
<p><strong>이거 VL-SAM의 양방향 트랜스포머랑 비슷한건가?</strong></p>
</blockquote>
<p>비슷한 계열은 맞지만, <strong>Open-Det의 BVLA-M은 VL-SAM의 양방향 Transformer와 같은 구조는 아니고</strong>, &quot;양방향으로 vision-language interaction/alignment를 보자&quot;라는 철학이 비슷한거다.</p>
</blockquote>
<pre><code class="language-text"># Open-Det의 BVLA-M 구조
S_align = cos(Q_d x M_VL, T_e) + cos(Q_d, T_e x M_LV)</code></pre>
<pre><code class="language-text">Q_d = detector가 만든 vision query
T_e = text encoder가 만든 text embedding
M_VL = vision → language 방향 projection
M_LV = language → vision 방향 projection
S_align = query-text alignment score matrix</code></pre>
<p>즉, Open-Det은 두 방향으로 similarity를 계산한다.
반면, <strong>VL-SAM의 양방향 Transformer가 SAM 계열의 two-way/bidirectional transformer이기 때문에, 이건 image token과 prompt/query token이 cross-attention으로 서로 정보를 주고 받는 구조</strong>이다. 서로 정보를 반영하면서 mask를 만드는 방향이다.</p>
<blockquote>
<blockquote>
</blockquote>
<p>정리하자면, </p>
<blockquote>
</blockquote>
<p><strong><em>“VL-SAM의 양방향 Transformer와 문제의식은 비슷하지만, Open-Det의 BVLA-M은 transformer fusion module이라기보다는 양방향 projection 기반 alignment scoring module이다.”</em></strong></p>
</blockquote>
<p>이어 저자들은 <strong>Masked Alignment Loss</strong>를 제안한다. 
이 loss의 목적은 contradictory loss와 gradient를 막는 것이다.
앞에서 말한 Contradictory Supervision 문제의 해결책이다.</p>
<blockquote>
<p>단순 alignment loss를 걸면 잘못된 negative supervisoin이 생길 수 있어, 이는 그런 모순적 pair를 무작정 밀어내지 않도록 mask를 씌우는 방식인 것이다</p>
</blockquote>
<p>또한 <strong>Joint loss</strong>도 소개한다. 이것은 Postiive query와 negative query의 classification을 더 잘 하도록 돕는다. </p>
<p>이 loss는 <strong>IoU score, alignment score, binary classifiaction score</strong>를 연결한다. </p>
<blockquote>
<p>즉 &quot;box가 정답과 얼마나 겹치는가&quot;와 &quot;text 의미와 얼마나 잘 맞는가&quot; 를 classification 학습에 함께 반영하려는 것이다.</p>
</blockquote>
<h3 id="3-contributions">3 Contributions</h3>
<h4 id="1-open-det이라는-효율적인-end-to-end-oed-프레임워크">(1) Open-Det이라는 효율적인 end-to-end OED 프레임워크</h4>
<p>여기서 end-to-end는 box detection과 object name generation을 분리된 후처리로 보지 않고 하나의 학습 프레임워크 안에서 다룬다는 것이다.</p>
<h4 id="2-bvla-m-masked-alignment-loss-joint-loss">(2) BVLA-M, Masked Alignment Loss, Joint Loss</h4>
<p>위 구조들을 통한 vision-language alignment와 classification을 개선한다.
즉, 단순히 모듈을 추가한 것이 아니라, 학습 신호 자체를 정리하려는 논문이다.</p>
<h4 id="3-실험-성능">(3) 실험 성능</h4>
<p>Open-Det은 GLIP(A)와 같은 OVD 모델보다 <code>AP_r + 6.8%</code>, 전체 <code>AP + 8.5%</code>를 달성한다고 주장한다. 또 GenerateU와 비교해서는 훈련 데이터 <code>1.5%</code>, epoch <code>20.8%</code>, 더 적은 GPU 만으로도 <code>AP_r + 1.0%</code>를 얻었다고 말한다.</p>
<blockquote>
<h3 id="정리">정리</h3>
<p>Open-Det은 <strong>detector 학습은 matching 구조로 빠르게 만들고, name generator 학습은 LLM head 안정화, text denoising, VLM 지식 증류, bidirectional alignment, loss 재설계를 통해 안정화</strong>한다는 논문이다. </p>
</blockquote>
<h1 id="2-related-work">2. Related work</h1>
<p>이 섹션은 길지 않지만, Open-Det이 어떤 연구 흐름 위에 있는지 보여준다.</p>
<p>CLIP 기반 OVD 방법들을 먼저 빠르게 살피고 넘어가자.</p>
<h2 id="clip-기반-ovd-방법들">CLIP 기반 OVD 방법들</h2>
<h3 id="vild">ViLD</h3>
<p>ViLD는 CLIP의 지식을 detector로 distillation한다. 즉, CLIP이 알고 있는 image-text alignment 지식을 detector가 배우도록 만드는 방식이다.</p>
<p>중요한 점은 detector가 단순히 box만 예측하는 것이 아니라, CLIP이 가진 language-aware visual representation을 흡수하도록 학습한다는 것이다.</p>
<h3 id="detpro">DetPro</h3>
<p><strong>DetPro</strong>는 prompt learning 계열이다. CLIP에서 text prompt가 성능에 큰 영향을 주기 때문에 사람이 prompt를 고정하는 대신 continuous prompt representation을 학습한다.</p>
<p>즉 <code>a photo of a {class}</code> 같은 수동 prompt를 넘어서, detection에 더 적합한 prompt embedding을 학습하는 방향이다.</p>
<h3 id="regionclip">RegionCLIP</h3>
<p><strong>RegionCLIP</strong>은 CLIP을 image-level이 아니라 region-level로 확장하려는 방법이다. CLIP은 원래 이미지 전체와 텍스트를 맞추는 데 강하지만, object detection은 이미지 안의 특정 region을 다뤄야 한다. </p>
<p>그래서 RegionCLIP은 object region 단위의 visual representation을 CLIP-style로 학습한다. </p>
<h3 id="baron">BARON</h3>
<p><strong>BARON</strong>은 region들을 bag 형태로 구성해서 OVD 성능을 높이려는 방법이다. </p>
<p>핵심은 개별 region 하나만 보는 것이 아니라, 여러 region 후보를 묶어서 region-text matching을 더 풍부하게 만드는 방향이다. </p>
<h2 id="transformer-기반-ovd-방법들">Transformer 기반 OVD 방법들</h2>
<p>논문은 그 다음으로 DETR/Transformer 계열 OVD도 말한다.</p>
<h3 id="mdetr">MDETR</h3>
<p>MDETR은 raw text query에 조건화된 object detection을 수행한다. </p>
<p>예를 들어 “red car” 같은 텍스트가 들어오면, 그 텍스트와 관련된 객체를 찾는 방식이다.
이건 detection을 language-conditioned task로 바꾼 중요한 흐름이다.</p>
<h3 id="ov-detr">OV-DETR</h3>
<p>OV-DETR은 conditional matching을 통해 OVD를 수행한다. DETR의 matching 구조를 open-vocabulary 설정에 맞게 확장했다고 보면 된다.</p>
<h3 id="vl-det">VL-DET</h3>
<p>VL-DET은 object-language alignment를 set matching 문제로 공식화한다. </p>
<p>이 논문 Open-Det에서도 alignment가 계속 중요하게 나오는데, VL-DET은 그런 흐름의 선행 작업 중 하나이다.</p>
<h3 id="cora">CORA</h3>
<p>CORA는 region prompting과 anchor pre-matching을 통해 region-text distribution을 개선한다. 즉, region과 text가 더 잘 맞도록 사전 매칭 구조를 강화한다.</p>
<blockquote>
<h2 id="region-text-alignment와-일반화">Region-Text Alignment와 일반화</h2>
<p>OVD 방법들이 많이 발전했지만, 여전히 공통 문제가 있다. </p>
</blockquote>
<p>논문은 이 문제를 <strong>region-text alignment</strong>와 <strong>limited generalization</strong>으로 본다.</p>
<blockquote>
</blockquote>
<p>OVD는 기본적으로 visual region과 text label을 맞추는 방식이다. 그런데 region representation이 text embedding과 잘 맞지 않으면, 학습하지 않은 category에 대한 일반화가 약해진다. 
또 inference 때 보통 category vocabulary나 text query를 넣어줘야 하므로, 완전히 자유로운 detection은 아니다.</p>
<blockquote>
</blockquote>
<p>즉, OVD는 closed-set detection보다 열려 있지만, 여전히 다음과 같은 한계들을 가진다.</p>
<ul>
<li>사전 category vocabulary 또는 text query 필요</li>
<li>region-text alignment가 어려움</li>
<li>새로운 category에 대한 일반화가 제한됨.</li>
<li>자유 형식 이름 생성은 직접 하지 않음<blockquote>
</blockquote>
이 지점이 바로 OED로 넘어가는 발판이다.</li>
</ul>
<hr>
<h1 id="3-method">3. Method</h1>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/859fcb77-64b7-4ed9-a1df-408dd0a6a415/image.png" alt=""></p>
<h2 id="31-main-architecture-of-the-open-det-framework">3.1. Main Architecture of the Open-Det Framework</h2>
<p>3.1.은 <strong>Open-Det 전체가 어떻게 연결되어 있는지</strong> 보여준다.</p>
<p>논문은 Open-Det을 &quot;<strong>four collaborative components&quot;</strong> 로 구성된 프레임워크라고 설명한다.</p>
<p>즉, 네 개의 모듈이 따로 노는 것이 아니라 detector, VLM, prompt distillation, LLM generation이 서로 연결되어 OED를 수행한다.</p>
<ul>
<li>detector</li>
<li>VLM</li>
<li>prompt distillation</li>
<li>LLM generation</li>
</ul>
<h3 id="object-detector-odr">Object Detector, ODR</h3>
<p>이미지에서 객체 후보를 찾고, bbox와 decoder query를 만든다.</p>
<p>입력 이미지는 논문 표기로 <code>I ∈ R^(H×W×3)</code> 이다. 여기서 <code>H</code>, <code>W</code>는 이미지의 높이와 너비이다.</p>
<p>Object Detector는 backbone과 transformer encoder-decoder를 거쳐 <strong>decoder queries <code>Q_d</code></strong> 를 생성한다. 이 <code>Q_d</code>가 중요하다. 이것은 단순 box 예측용 feature가 아니라, 나중에 object name generation에도 연결되는 핵심 visual representation이다. </p>
<p>즉, Object Detector의 출력은 크게 두 가지이다.</p>
<ul>
<li>Bounding boxes</li>
<li>Decoder queires <code>Q_d</code></li>
</ul>
<p>그리고 <code>Q_d</code>에서 binary score도 나온다. binary score는 이 query가 실제 객체인지 아닌지를 판단하는 점수이다. </p>
<h3 id="vision-language-aligner">Vision-Language Aligner</h3>
<p>이 모듈은 <strong>training</strong> 시에만 사용한다. </p>
<p>역할은 detector의 visual query <code>Q_d</code>와 VLM이 만든 text embedding <code>T_e</code>를 정렬하는 것이다.</p>
<p>학습 중에는 이미지에 대응되는 object names <code>T</code>가 있고, 이 object names는 VLM으로 들어간다. VLM은 텍스트를 embedding으로 바꿔 <code>T_e</code>를 만든다. 그 다음 Vision-Language Aligner가 <code>Q_d</code>와 <code>T_e</code> 사이의 alignment를 계산한다.</p>
<blockquote>
<p>정리해보면, <strong><code>T</code>는 학습 중에만 주어지는 category text로, inference시의 후보 vocabulary가 아니라 training dataset에 있는 annotation이다.</strong></p>
</blockquote>
<p>여기서 중요한 결과가 <strong><code>VL_align</code></strong> 이다. 논문은 이것을 query-text matching을 위한 alignment indices로 설명한다. 쉽게 말하면, 어떤 visual query가 어떤 object text와 대응되어야 하는지를 알려주는 <strong>매칭 정보</strong>이다.</p>
<p>이 <code>VL_align</code>은 Object Detector를 학습시키는 supervision으로 쓰인다. 
즉, Open-Det은 box만 보고 detector를 학습시키는 것이 아니라, <strong>이 query가 어떤 이름의 객체와 의미적으로 맞는지까지 고려</strong>한다.</p>
<h3 id="prompts-distiller">Prompts Distiller</h3>
<p>이것이 바로 Open-Det에서 GenerateU와 크게 달라지는 부분 중 하나이다.</p>
<p>GenerateU는 detector의 vision query를 LLM에 직접 넣는 방식에 가깝지만, Open-Det은 <strong>Prompt Distiller</strong>를 사용한다.</p>
<p>저자들은 이 모듈이 <strong>*&quot;replacing the direct use of vision queries as input for LLM in GenerateU&quot;*</strong> 라고 설명한다.</p>
<p>즉, 핵심은 이것이다.</p>
<blockquote>
<p>*<em>GenerateU: *</em>
<code>decoder query Q_d -&gt; LLM -&gt; object name</code></p>
<p>*<em>Open-Det: *</em>
<code>decoder query Q_d + VLM alignment knowledge -&gt; VL-prompts P_vl -&gt; LLM -&gt; object name</code></p>
</blockquote>
<p>Prompt Distiller 안에는 <strong>VLD-M</strong>, Vision-to-Language Distillation Module이 있다. 이 VLD-M은 다음 정보를 입력으로 받는다.</p>
<ul>
<li>backbone features <code>B</code></li>
<li>encoder features <code>E</code></li>
<li>decoder queries <code>Q_d</code></li>
<li>text embeddings <code>T_e</code></li>
<li>alignment indices <code>VL_align</code></li>
</ul>
<p>그리고 VLM이 가진 vision-language alignment 지식을 decoder query 쪽으로 전달해서 <strong>VL-prompts <code>P_vl</code></strong>을 만든다.</p>
<p>여기서 VL-prompt는 LLM이 이해하기 쉬운 형태로 정제된 visual-language prompt라고 보면 된다. raw visual query를 바로 LLM에 넣는 대신, VLM의 도움으로 언어 공간에 더 잘 맞는 prompt를 만드는 것이다.</p>
<h3 id="object-name-generator">Object Name Generator</h3>
<p>Object Name Generator는 최종적으로 객체 이름을 생성하는 부분이다. Figure 2에서는 Generative Language Model과 LoRA Head가 이 역할을 한다.</p>
<p>Prompts Distiller가 만든 <code>P_vl</code>이 generative LLM으로 들어가고, LLM은 Object names를 생성한다.</p>
<p>여기서 Open-Det은 LLM 전체를 무겁게 흔드는 대신, LoRA Head를 사용한다. Figure 2에 <strong>LoRA Head</strong>와 <strong>Text Denoising</strong> 흐름이 표시되어있는데, 이것은 뒤 3.5에서 더 자세히 알아보도록 하겠다. </p>
<hr>
<h2 id="32-object-detector">3.2. Object Detector</h2>
<p>3.2는 Figure 2의 파란색 1번 구역, 즉 <strong>Object Detector ODR</strong>을 설명하는 부분이다. </p>
<p>이 모듈의 역할은 단순히 bbox만 예측하는 것이 아니라, 저자들은 <strong>Bounding Boxes and vision queries</strong>를 생성한다고 한다. 여기서 중요한 것은 <code>vision queries</code>이다.</p>
<p>Open-Det에서는 detector query가 두 가지 역할을 한다.</p>
<h3 id="1-객체-위치를-찾는다">1. 객체 위치를 찾는다.</h3>
<p><code>Q_d -&gt; Box Head -&gt; bounding boxes</code></p>
<h3 id="2-객체-이름-생성을-위한-기반-feature가-된다">2. 객체 이름 생성을 위한 기반 feature가 된다.</h3>
<p><code>Q_d -&gt; VLD Module -&gt; VL-prompts -&gt; LLM -&gt; object names</code>
즉, ODR은 Open-Det 전체의 출발점이다. detector query가 부정확하면, box도 흔들리고, 뒤쪽 object name generation도 흔들린다.</p>
<p>때문에, 단순 Localization Module이 아니라, <strong>검출과 이름 생성 사이를 연결하는 visual query 생산기</strong>라고 보는 것이 좋다.</p>
<h3 id="왜-object-detector-학습을-빠르게-해야-하는가">왜 Object Detector 학습을 빠르게 해야 하는가?</h3>
<p>ODE에서는 detector가 불안정하면, 뒤의 LLM도 제대로 학습하기 어렵다.</p>
<p>LLM은 detector가 만든 query를 바탕으로 객체 이름을 생성한다. 그런데 detector query가 초반에 객체를 제대로 대표하지 못하면, LLM은 잘못된 visual signal을 받아 object name을 생성하려고 한다.</p>
<p>그래서 Open-Det은 ODR의 covergence를 빠르게 만드는 데 신경 쓴다.</p>
<p>저자들은 DINO의 효율성과 one-to-many matching의 빠른 convergence에서 영감을 받았다고 한다.DINO는 anchor box denoising으로 DETR 계열 학습을 빠르게 만든 방법이고, one-to-many matching은 하나의 GT 객체에 여러 prediction을 Positive로 연결하여 학습 신호를 늘리는 방식이다.</p>
<blockquote>
<p>여기서 말하는 DINO는 Meta의 self-supervised DINO가 아니라, <strong>object detection 쪽의 DINO detector를 말한다.</strong></p>
<blockquote>
<p><strong><em>DINO: DETR with Improved DeNoising Anchor Boxes for End-to-End Object Detection</em></strong></p>
</blockquote>
</blockquote>
<h3 id="one-to-one-matching">One-to-One Matching</h3>
<h4 id="기본-detr-방식">기본 DETR 방식</h4>
<p>DETR 계열 detector는 보통 <strong>one-to-one matching</strong>을 사용한다.</p>
<p>하나의 ground-truth object는 하나의 prediction query와만 매칭된다. <strong>이 방식의 장점은 중복 예측을 줄일 수 있다는 것</strong>이다.</p>
<p>예를 들어 이미지에 사람이 한 명 있다면, 최종적으로 하나의 query만 그 사람을 담당하게 된다. 그래서 <strong>NMS 없이도 깔끔한 detection</strong>이 된다.</p>
<p>하지만 <strong>단점도 있다.</strong>
학습 초반에는 정답 객체 하나당 positive query가 하나 뿐이다. 그러면 positive supervision이 적고, detector가 객체 위치를 빠르게 배우기 어렵다. 
<strong>특히 DETR 계열이 초반 convergence가 느리다는 문제와 연결</strong>된다.</p>
<h3 id="one-to-many-matching">One-to-Many Matching</h3>
<h4 id="학습-신호를-늘리는-방식">학습 신호를 늘리는 방식</h4>
<p><strong>One-to-Many matching</strong>은 하나의 ground-truth object를 여러 prediction query와 매칭한다.</p>
<p>예를 들어 사람 한 명에 대해 query 3개나 5개가 positive로 학습될 수 있다. 그러면 같은 객체에 대해 더 많은 query가 localization 학습을 받는다.</p>
<h4 id="장점은-명확하다-1-positive-sample의-증가">장점은 명확하다. 1: Positive sample의 증가</h4>
<p>정답 객체 하나를 여러 query가 배우므로, 학습 신호가 풍부해진다.</p>
<h4 id="2-box-localization이-빨라진다">2. Box localization이 빨라진다.</h4>
<p>여러 query가 같은 GT box를 향해 학습되기 때문에 초반 localization convergence가 빨라질 수 있다.</p>
<p><strong>하지만 one-to-many만 쓰면 문제가 있다.</strong> 같은 객체를 여러 query가 예측하므로 *<em>중복 detection이 많아질 수 있다. *</em> 최종 detection 결과는 깔끔해야 하기 때문에 one-to-one 구조도 필요하다.</p>
<h3 id="open-det의-핵심-decoupled-matching-decoder">Open-Det의 핵심: Decoupled Matching Decoder</h3>
<p>여기서 Open-Det의 설계가 나온다.</p>
<p>기존 방법들은 one-to-one과 one-to-many를 같이 쓰기 위해 별도 branch나 head를 추가하는 경우가 많았다. 그런데 Open-Det은 추가 branch 없이 decoder 내부에서 둘을 분리한다.</p>
<p>논문 표현으로는 <strong>&quot;Decoupling these two matching approaches&quot;</strong>이다. </p>
<p>구체적으로는 decoder layer를 앞/뒤로 나눈다. </p>
<h4 id="앞의-4개-layer">앞의 4개 Layer</h4>
<p>저자들은 &quot;first four layers employ one-to-many matching&quot; 이라고 한다.</p>
<p>앞쪽 layer에서는 one-to-many matching과 cross-attention을 사용한다. 목적은 <strong>box localization 강화</strong>이다. 여러 query가 GT object를 향해 학습되면서 객체 위치를 더 빨리 잡도록 만든다.</p>
<h4 id="뒤의-2개-layer">뒤의 2개 Layer</h4>
<p>저자들은 &quot;last two layers use one-to-one matching&quot; 이라고 한다.</p>
<p>뒤쪽 layer에서는 one-to-one matching과 self-attention을 사용한다. 목적은 <strong>중복 detection 제거</strong>이다. 여러 query가 같은 객체를 잡는 상황을 정리하고, 최종적으로 하나의 객체에 하나의 예측이 대응되도록 만든다.</p>
<p>즉, Open-Det detector는 이런 흐름이다.
<code>초반 layer: one-to-many로 빠르게 많이 배움</code>
<code>후반 layer: one-to-one으로 중복을 제거</code></p>
<pre><code>Decoder layer 1: one-to-many
Decoder layer 2: one-to-many
Decoder layer 3: one-to-many
Decoder layer 4: one-to-many
Decoder layer 5: one-to-one
Decoder layer 6: one-to-one</code></pre><p>지금까지의 구조를 다시 쓰면 
Image</p>
<pre><code>-&gt; Backbone
-&gt; Transformer Encoder
-&gt; encoder features E
-&gt; threshold-based query selection
-&gt; Transformer Decoder with 6 layers
   - layer 1-4: one-to-many matching
   - layer 5-6: one-to-one matching
-&gt; decoder queries Q_d
-&gt; Box Head / Binary Head</code></pre><h3 id="cross-attention--self-attention">Cross-Attention &amp; Self-Attention</h3>
<h4 id="cross-attention-이미지-feature를-보며-위치-잡기">Cross-Attention: 이미지 Feature를 보며 위치 잡기</h4>
<p>앞의 4개 layer는 cross-attention을 사용한다고 되어 있다.
Cross-attention은 query가 image feature를 참조하는 과정이다.</p>
<p>즉, query가 이미지의 어느 위치, 어느 feature를 봐야 하는지 학습한다.
그래서 localization을 강화하는 데 적합하다.</p>
<p><code>query -&gt; image feature를 바라봄 -&gt; 객체 위치 정보 획득 -&gt; box localization 개선</code></p>
<h4 id="self-attention-query끼리-조정하며-중복-줄이기">Self-Attention: Query끼리 조정하며 중복 줄이기</h4>
<p>뒤의 2개 layer는 self-attention을 사용한다. Self-attention은 query들끼리 서로를 보는 구조이다. </p>
<p>여러 query가 같은 객체를 잡고 있다면, query들 사이의 관계를 통해 누가 최종적으로 그 객체를 담당할지 정리할 수 있다.</p>
<p>그래서 후반부 self-attention은 duplicate detection 제거와 잘 맞는다.</p>
<h3 id="추가-branch-없이-단순화">추가 Branch 없이 단순화</h3>
<p>Open-Det이 강조하는 다른 포인트는 <strong>addition decoder branch가 필요 없다는 것</strong>이다.</p>
<p>기존 One-to-many + one-to-one 결합 방식은 별도 branch나 head를 두는 경우가 있었는데, Open-Det은 decoder layer 자체를 역할별로 나눈다.</p>
<p>그래서 구조적으로는 더 단순하다.
<code>별도 branch 추가</code>가 아니라,
<code>같은 decoder 안에서 앞 4 layer / 뒤 2 layer 역할 분리</code>
이 설계로 인해 training complexity를 낮추면서도 convergence를 더 빠르게 하려는 것이다.</p>
<h3 id="fixed-query-문제">Fixed Query 문제</h3>
<p>3.2.의 후반부는 또 다른 문제를 다룬다. 
기존 COD, VOD, OED framework들은 predefined queries에 의존하기 때문에 <strong>검출 가능한 객체 수가 고정되는 한계</strong>가 있다고 말한다.</p>
<p>DETR 계열을 떠올리면 보통 query 개수를 미리 정한다. 예를 들어 100개의 query를 두면, 모델은 최대 100개의 object slot을 가지고 예측한다. </p>
<p>물론 실제로 100개 안에서 충분한 경우가 많지만, 논문은 OED처럼 open-ended하고 객체 수가 유동적인 상황에서는 더 flexible한 query 선택이 필요하다고 본다. </p>
<blockquote>
<h3 id="object-slot이란">Object Slot이란?</h3>
<p><strong>Object slot</strong>은, detector가 &#39;여기 하나의 객체가 들어갈 수 있다&#39; 라고 준비한 <strong>예측 자리</strong>라고 보면 된다.</p>
</blockquote>
<p>DETR 계열에서는 보통 미리 정해진 개수의 query를 둔다고 했다. 
예를 들어 100개의 query면, 모델은 이미지 하나를 보고 100 개의 object slot을 가지고 예측하는 것이다.</p>
<blockquote>
</blockquote>
<pre><code class="language-text">slot 1 -&gt; box + class/objectness
slot 2 -&gt; box + class/objectness
slot 3 -&gt; no object
...
slot 100 -&gt; box + class/objectness</code></pre>
<p>slot의 각 출력은 위와 같은데, 중요한 것은 다음과 같다.
<strong>Object slot은 category slot</strong>이 아니다.
즉, <code>person slot</code>, <code>,car slot</code>, <code>dog slot</code> 처럼 class 별 자리가 아니라는 것이다. </p>
<blockquote>
</blockquote>
<p>그보다는 <strong>객체 instance 하나를 담당할 수 있는 빈 자리</strong>이다.</p>
<blockquote>
<h4 id="왜-slot이-필요한가">왜 Slot이 필요한가?</h4>
<p>DETR류 모델은 anchor box를 촘촘히 깔고 후처리 하는 방식이 아니라, <strong>query/slot들이 서로 경쟁하면서 객체를 하나씩 맡는다.</strong>
그래서 one-to-one matching에서는
<code>하나의 GT object &lt;-&gt; 하나의 object slot</code>
이 되도록 학습한다. 이 덕분에 중복 box를 줄일 수 있다. </p>
</blockquote>
<h3 id="threshold-based-query-selection">Threshold-Based Query Selection</h3>
<p>그래서 Open-Det은 <strong>threshold0based query selection</strong>을 도입한다.</p>
<pre><code>Q_id = { e_t ∈ E | σ(Linear(e_t)) &gt; λ }</code></pre><p>여기서 <code>E</code>는 Transformer Encoder가 만든 encoder features로, 이미지 전체의 token feature들이라고 보면 된다.</p>
<p><code>e_t</code>는  encoder feature <code>E</code> 안의 개별 token으로, 이미지 feature token 한 개이다.</p>
<p><code>Linear(e_t)</code>는 각 token이 decoder query로 선택될 만한지 점수를 내는 linear layer이다.</p>
<p><code>σ</code>는 sigmoid함수 이며, <code>λ</code>는 threshold로, 각 encoder token에 대해, 이 token을 query로 쓸만한지 측정하고 sigmoid score가 더 높으면 <strong>decoder query 후보로 선택</strong>한다.</p>
<blockquote>
<h3 id="왜-threshold-query-selection이-중요할까">왜 Threshold Query Selection이 중요할까?</h3>
<p>이 방식의 장점은 query 개수를 고정하지 않아도 된다는 것이다.</p>
</blockquote>
<p>기존 방식은 <code>미리 정한 N개의 query    사용</code>하는 방식이었지만, Open-Det은 <code>encoder token 중 threshold를 넘는 token을 query로 선택</code>하는 방식이다.</p>
<p>때문에 <strong>이미지마다 선택되는 query 수가 달라질 수 있다.</strong> 객체가 적은 이미지에서는 적은 query, 객체가 많은 이미지에서는 많은 query가 선택될 수 있는 것이다.</p>
<p><strong>저잗르은 이 설계를 통해 efficiency and flexibility</strong>를 얻는다고 한다.</p>
<blockquote>
<h3 id="32-and-process">3.2 and Process</h3>
<p>자, 그럼 3.2와 전체 구조를 연결해서 마무리해보자.
3.2의 Object Detector는 단순히 좋은 box를 만드는 모듈이 아니다.</p>
</blockquote>
<p>Open-Det 전체에서 ODR은 다음 세 가지를 담당한다. </p>
<h4 id="빠른-localization-학습">빠른 localization 학습</h4>
<p>앞 4개 decoder layer에서 one-to-many matching을 사용하여 box localization을 빠르게 배운다.</p>
<h4 id="중복-없는-최종-detection">중복 없는 최종 detection</h4>
<p>뒤 2개 decoder layer에서 one-to-one matching을 통해 duplicate detections를 제거한다.</p>
<h4 id="유동적인-object-query-생성">유동적인 object query 생성</h4>
<p>threshold-based query selection으로 이미지마다 필요한 만큼의 decoder query를 선택한다.</p>
<blockquote>
</blockquote>
<p>이렇게 만들어진 <code>Q_d</code>가 나중에 VLD Module과 LLM으로 이어지기 때문에, ODR은 object name generation의 기반이기도 하다.</p>
<blockquote>
<blockquote>
<p><strong>한 줄 요약: Open-Det의 Object Detector는 앞쪽 decoder layer에서 one-to-one matching으로 빠르게 위치를 배우고, 뒤쪽 layer에서 one-to-one matching으로 중복을 제거하며, threshold-based query selection으로 고정 query 수의 한계를 줄이는 모듈</strong>이다. </p>
</blockquote>
</blockquote>
<hr>
<h2 id="33-vision-language-aligner-with-bvla-m">3.3. Vision-Language Aligner with BVLA-M</h2>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/9c1bb69f-6a97-44d3-8a5a-8b7047d42096/image.png" alt="">
이 섹션의 목적은 간단하다.</p>
<p><strong>Detector가 만든 vision query <code>Q_d</code>와 VLM이 만든 text embedding <code>T_e</code>를 더 잘 정렬하자.</strong></p>
<p>논문은 이 alignment를 label matching의 핵심이라고 본다. 원분에서도 <strong>*&quot;Vision-Language modalities alignment is a core component&quot;*</strong> 라고 말한다.</p>
<h3 id="왜-alignment가-필요할까">왜 Alignment가 필요할까?</h3>
<p>Open-Det에서 detector는 decoder query <code>Q_d</code>를 만든다. 이 query는 이미지 안 객체 후보를 표현한다.</p>
<p>반면 VLM은 object name text를 받아 text embedding <code>T_e</code>를 만든다.</p>
<p>학습 중에는 이 둘을 맞춰야 한다.
<strong>둘은 의미 공간도 다르고, feature dimension도 다르다. 그래서 이 것을 해결하는 것이 핵심이다. 기존 방식의 단순 해결과 다르니, 주의깊게 보면 좋을 것 같다.</strong></p>
<p>학습 중에는 이 둘을 맞춰야 한다. <code>Q_d</code>와 <code>T_e</code>.</p>
<pre><code>vision query Q_d  &lt;-&gt;  text embedding T_e</code></pre><p>예를 들어, 어떤 query가 야구 선수의 배트를 보고 있다면, 그 query는 <code>&quot;baseball bat&quot;</code> 또는 해당 object name embedding과 가까워져야 한다.</p>
<p>이 정렬이 잘 되면, 다음과 같은 이점이 있다:</p>
<ul>
<li>어떤 query가 어떤 object name과 연결되는지 알 수 있다.</li>
<li>detector supervision이 더 좋아진다.</li>
<li>뒤의 VLD-M이 더 좋은 VL-prompt를 만들 수 있다.</li>
<li>최종 object name generation도 더 안정된다.</li>
</ul>
<h3 id="기존-방식의-문제-차원-불균형⭐️">기존 방식의 문제: 차원 불균형⭐️</h3>
<p>기존 방식과 해결하는 방식이 약간 다르다고 했다.</p>
<p>논문이 지적하는 중요한 문제는 <strong>vision query와 text embedding의 channel dimension이 다르다는 점</strong>이다. </p>
<p>논문에서 나온 예는 다음과 같다.</p>
<pre><code>Q_d: 256 channels
T_e: 768 channels</code></pre><p>즉, detector query는 <code>256</code>차원인데, text embedding은 <code>768</code>차원이다.</p>
<p>기존 방식은 보통 <code>Q_d</code>를 text embedding 차원으로 올려서 비교한다.</p>
<pre><code>Q_d: 256 -&gt; 768
T_e: 768</code></pre><p>그런데, 저자들은 이 방식이 충분하지 않다고 본다. 
왜냐하면 <code>Q_d</code>자체가 text embedding보다 정보량이 적은 저차원 feature인데, 단순히 768로 늘린다고 해서, language semantic information이 풍부해지는 것은 아니기 때문이다.</p>
<blockquote>
<p>근데 여기서 드는 의문이.. <strong>꼭 language semantic info가 풍부해져야하나..? 그냥 차원 맞춰서 연산만 되면 되는거 아냐?</strong> 인데..</p>
</blockquote>
<p><strong>Open-Det에서는 단순 연산 가능성이 아니라, similarity가 의미 있는 supervision으로 작동해야 한다는 것</strong>이다.</p>
<blockquote>
</blockquote>
<p>음 어렵다. 계속 알아보자. 
(차원을 맞추는 것과 의미를 맞추는 것은 다르다는 점을 생각하며 읽어보자.)</p>
<p>논문 표현으로는 이 language semantic info가 풍부해지지 않는 것을 <strong>alignment가 suboptimal Vision-Language alignment</strong>를 만들 수 있다고 한다.</p>
<h3 id="bvla-m-bidirectional-vision-language-alignment-module">BVLA-M: Bidirectional Vision-Language Alignment Module</h3>
<h4 id="핵심-아이디어">핵심 아이디어</h4>
<p>Open-Det은 한 방향으로만 맞추지 않는다.</p>
<p>기존 방식이 대채로</p>
<pre><code>Vision -&gt; Language</code></pre><p>로 늘리는 반면, BVLA-M은 다음 두 방향을 모두 사용한다.</p>
<pre><code>Vision-to-Language, V-to-L
Language-to-Vision, L-to-V</code></pre><p>즉, Vision query를 language space로 보내서 비교하고, 동시에 text embedding을 vision space로 보내서 비교한다.</p>
<p>이게 Figure 2 중 아래 구조의 핵심이다.
<img src="https://velog.velcdn.com/images/jm_mg_se/post/89450464-e130-44d7-aea3-4b8d47f6643f/image.png" alt=""></p>
<p>논문의 수식은 다음과 같다.
$$$
S_{align} = \cos(Q_d \times M_{V L}, T_e) + \cos(Q_d, T_e \times M_{LV})
$$$</p>
<h3 id="s_align의-의미는-다음과-같다">$S_{align}$의 의미는 다음과 같다.</h3>
<p>$S_{align}$은 query-text alignment score matrix 이다.
즉, <code>N</code>개의 decoder query와 <code>M</code>개의 text embedding 사이의 모든 pairwise score를 담고 있다. </p>
<p>예를 들어, $S_{align}[i, j]$는 <code>i</code>번째 decoder query가 <code>j</code>번째 object name text와 얼마나 잘 맞는지를 의미한다.</p>
<p>이 score는 뒤에서 query-text matching, <code>VL_align</code>, Masked Alignment Loss, VLD-M의 prompt distillation 등에 연결된다.</p>
<p>Figure 2에서 BVLA-M은 오른쪽 아래 확대 박스이다. (따로 회색만 뽑아 놓은 위 사진과 같다.)</p>
<p>왼쪽에서는 </p>
<pre><code>decoder queries Q_d</code></pre><p>오른쪽에서는 </p>
<pre><code>text embeddings T_e</code></pre><p>가 있다.
가운데에는 <code>V-to-L</code>, <code>L-to-V</code>로 양방향 화살표가 있다.</p>
<p>이 그림이 3.3의 거의 전부를 시각화하는데, Open-Det은 detector query와 text embedding을 단순히 한 방향으로만 맞추지 않고, 양쪽 공간에서 모두 similiary를 계산하여 alignment를 강화한다.</p>
<h4 id="더-자세한-비교">더 자세한 비교</h4>
<p>논문에서 정의한 shape은 다음과 같다. 
$$$
Q_d \in R^{N \times d_q}
$$$
$$$
T_e \in R^{M \times d_t}
$$$</p>
<ul>
<li>$N$: decoder query 수</li>
<li>$M$: text embedding 수</li>
<li>$d_q$: query feature dimension</li>
<li>$d_t$: text feature dimension</li>
</ul>
<p>논문 예시는 보통 이런 식이다.
$$$
Q_d : N \times 256 
$$$
$$$
T_e: M \times 768
$$$</p>
<p>즉, $Q_d$와 $T_e$는 channel dimension이 다르다. 그래서 바로 <strong>cosine similarity를 계산할 수 없다. 코사인 유사도는 마지막 feature dimension이 같아야 하니까 말이다.</strong></p>
<p>$$$
S_{align} = \cos(Q_d \times M_{V L}, T_e) + \cos(Q_d, T_e \times M_{LV})
$$$
에서 $+$를 기준으로 <strong>왼쪽 수식</strong>을 살펴보자.
$\cos(Q_d \times M_{VL}, T_e)$ 는 $Q_d$를 text embedding 차원으로 올려서 $T_e$와 비교한다. </p>
<ul>
<li>$Q_d$: $N \times 256$</li>
<li>$M_{VL}: 256 \times 768$</li>
<li>$Q_d \times M_{VL}: N \times 768$</li>
</ul>
<p>이제 $T_e$와 차원이 맞는다.
$$$
Q_d \times M_{VL}: N \times 768
$$$
$$$
T_e: M\times 768
$$$
그래서 <strong>pairwise cosine similarity를 계산하면</strong>
$$$
S_{VL} \in R^{N\times M}
$$$
가 된다.</p>
<ul>
<li>query 1은 perosn text와 가까운가?</li>
<li>query 1은 baseball bat text와 가까운가?</li>
<li>query 2는 glove text와 가까운가?
...
이런 식으로 <strong>각 Vision query가 어떤 text embedding과 가까운지를 보게 된다.</strong></li>
</ul>
<p>+를 기준으로 오른쪽 식도 같은 방식이다.</p>
<p>왼쪽 항과 오른쪽 항은 둘 다 최종적으로 같은 shape을 가진다.
$$$
\cos(Q_d \times M_{VL}, T_e) : N \times M
$$$
$$$
\cos(Q_d, T_e \times M_{VL}): N \times M
$$$
그래서 **element-wise로 더할 수 있다.
$$$
S_{align} = S_{VL} + S_{LV} \ \ | \ S_{align}\text{의 shape}: R^{N \times M}
$$$ 
이는 기존 방식의 중간 shape이 두 개 생기는 것과 명확히 다르다.
$$$
Q_d \times M_{VL} : N \times 768 \T_e \times M_{LV} : M \times 256
$$$
물론 최종 alignment score shape은 기존과 같다.</p>
<blockquote>
<p>한 방향 projection만 쓰면, <strong>저차원 visual query $Q_d$를 고차원 text space로 억지로 올려서 비교</strong> 하는데, 이 방식은 연산은 되지만, visual query가 text semantic space에 충분히 잘 올라갔는지 보장하기 어렵다.</p>
</blockquote>
<p>때문에 Open-Det의 BVLA-M은 양방향을 봐서 alignment를 한 공간에서만 판단하지 않고, 양쪽 modality의 관점에서 같이 확인한다.</p>
<blockquote>
<blockquote>
<p><strong>갑자기 또 드는 의문: Cosine similarity</strong>
여기서의 cosine similarity는 <strong>vision feature와 query를 결합하는 연산이 아니라, 이미 만들어진 두 쿼리와 임베딩을 의미적으로 맞는지만 계산하는 것이므로, 주의하자</strong></p>
</blockquote>
</blockquote>
<blockquote>
<h3 id="33과-전체-framework">3.3과 전체 Framework</h3>
<p>3.3은 독립적인 detectio module이라기 보다는, <strong>학습 신호를 깨끗하게 만드는 정렬 모듈</strong>이다.</p>
</blockquote>
<p>Open-Det 전체 흐름에서 보면</p>
<pre><code>Object Detector -&gt; Q_d 생성
VLM -&gt; T_e 생성
BVLA-M -&gt; Q_d와 T_e의 alignment score S_align 계산</code></pre><p>이 <code>S_align</code>이 좋아져야 뒤의 과정도 좋아진다.</p>
<ul>
<li>Object Detector가 더 정확한 query supervision을 받는다.</li>
<li>VLD-M이 더 좋은 text-query pair를 사용한다.</li>
<li>VL-prompt가 더 의미 있게 만들어진다.</li>
<li>LLM의 object name generation이 안정된다.<blockquote>
<blockquote>
<p><strong>한 줄 요약: BVLA-M은 detector query <code>Q_d</code>와 text embedding <code>T_e</code>를 Vision-to-Language와 Language-to-Vision으로 양방향 비교하여 더 안정적인 query-text alignment score <code>S_align</code>을 만드는 모듈이다.</strong></p>
</blockquote>
</blockquote>
</li>
</ul>
<hr>
<h2 id="34-vision-to-language-distillation-module">3.4. Vision-to-Language Distillation Module</h2>
<h3 id="이-섹션의-핵심">이 섹션의 핵심</h3>
<p>3.4.는 Figure 2의 <strong>Prompts Distiller</strong> 내부, 특히 <strong>VLD-M, Vision-to-Language Distillation Module</strong>을 설명한다.</p>
<p>한 문장으로 말하면</p>
<blockquote>
<p><strong>VLD-M은 detector query $Q_d$를 LLM이 이해하기 쉬운 VL-prompts $P_{vl}$로 바꾸는 모듈</strong>이다.</p>
</blockquote>
<p>이게 중요한 이유는, GenerateU처럼 detector query를 LLM에 바로 넣으면 semantic gap이 크다. $Q_d$는 시각 detector feature이고, LLM은 언어 생성 모델이다. 그래서 Open-Det은 중간에 VLD-M을 넣어 VLM의 vision-language 지식을 query에 증류한다.</p>
<blockquote>
<h4 id="증류란">증류란?</h4>
<p>큰 모델이나 이미 잘 학습된 모델이 가진 지식을, 다른 모델이나 작은 모듈이 배우도록 옮기는 과정이다.</p>
</blockquote>
<p>쉽게 말해서 Consistency Model의 Teacher와 Student를 생각하면 되겠다.</p>
<blockquote>
<h4 id="일반적인-knowledge-distillation">일반적인 Knowledge Distillation</h4>
<p>큰 image classifier가 있다고 해보자. 이미지를 보고 teacher model은 다음과 같이 예측했다.</p>
</blockquote>
<pre><code>dog: 0.70
wolf: 0.20
fox: 0.07
cat: 0.03</code></pre><p>정답 label은 <code>dog</code>하나 일 수 있지만, teacher의 출력에는 더 풍부한 정보가 있다.</p>
<pre><code>dog와 wolf가 비슷하다
dog와 fox도 약간 비슷하다
cat과는 덜 비슷하다</code></pre><p>Student 모델은 단순 정답 <code>dog</code>만 배우는 것이 아니라, teacher의 이러한 soft한 분포를 따라 하면서 더 좋은 representation을 배운다. </p>
<blockquote>
</blockquote>
<p><strong>이것이 바로 일반적인 knowledge distillation</strong>이다.</p>
<h4 id="그럼-open-det에서는-무엇을-증류하는데">그럼 Open-Det에서는 무엇을 증류하는데?</h4>
<p>Open-Det에서는 VLM이 이미 image-text pair로 학습되어 있어서, vision과 language를 맞추는 지식을 가지고 있다.</p>
<pre><code>&quot;baseball bat&quot;라는 text embedding은
야구 방망이처럼 생긴 visual pattern과 가까워야 한다
# 이 정도는 VLM이 이미 알고 있다. </code></pre><p>그리고 아래와 같은 vision-language semantic structure도 embedding 안에 어느 정도 들어 있다. </p>
<pre><code>&quot;person&quot;과 &quot;baseball player&quot;는 관련 있다
&quot;bat&quot;와 &quot;glove&quot;는 같은 장면에 자주 나온다
&quot;helmet&quot;은 사람 머리 근처에 나타난다</code></pre><p>Open-Det은 이 VLM의 지식을 <strong>VL-prompts</strong>에 옮기고 싶어 한다.</p>
<h4 id="vld-m은-뭘-배우는가">VLD-M은 뭘 배우는가?</h4>
<p>VLD-M은 detector query $Q_d$를 받아서 LLM이 사용할 수 있는 <strong>VL-prompt $P_{vl}$</strong>을 만든다. </p>
<blockquote>
</blockquote>
<p>그런데 이 $P_{vl}$이 아무렇게나 만들어지면 안된다. LLM이 객체 이름을 잘 생성하려면 $P_{vl}$이 VLM의 text embedding $T_e$와 의미적으로 가까워야 한다.</p>
<blockquote>
</blockquote>
<p>그래서 Open-Det은 VLM이 만든 text embedding $T_e$를 일종의 target 처럼 사용하는 것이다.</p>
<pre><code>VLD-M(Q_d, B, E, ...) -&gt; P_vl
VLM(text) -&gt; T_e
P_vl이 T_e와 가까워지도록 학습</code></pre><p>즉, VLD-M은 <strong>Detector query를 받아서 VLM text embedding과 비슷한 의미를 가진 VL-prompt를 만들도록 학습</strong>하는 것이다. 이것이 바로 VL-Prompt에 <strong>distill</strong>한다고 표현한다.</p>
<h3 id="근데-vld-m이-꼭-필요한가">근데 VLD-M이 꼭 필요한가?</h3>
<p>저자들은 먼저 기존 VLM의 한계를 말한다.
예를 들면 CLIP 같은 모델은 보통 <strong>web-scale image-text paired data</strong>로 학습된다.</p>
<p>즉, 이미지 전체와 문장/캡션을 맞추는 방식이다.
하지만 object detection에서 필요한 것은 이미지 전체가 아니라 <strong>region-text alignment</strong>이다.</p>
<p>이미지 안의 특정 region과 그 region 안의 객체들 각각의 text와 잘 맞춰야 하는데, 저자들은 바로 이 <strong>fine-grained region-text data</strong>가 얻기 힘들다고 한다. 이유는 복잡한 labeling과 높은 비용 때문이다.</p>
<p>문제는 바로 이것이다.</p>
<blockquote>
<h3 id="vlm은-image-text-alignment에는-강하지만-region-text-alignment에는-바로-강하지-않을-수-있다">VLM은 image-text alignment에는 강하지만, region-text alignment에는 바로 강하지 않을 수 있다.</h3>
</blockquote>
<p>그런데 OED는 region-level object name generation이 필요하다. 그래서 VLD-M이 필요한 것이다. </p>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/80bcb470-3a5d-4624-931c-fdb94016a434/image.png" alt="">
Figure 3은 VLD-M의 전체 구조이다.
<strong>아래에서 위로 읽으면 이해가 쉽다.</strong></p>
<h3 id="입력-1-decoder-queries-q_d">입력 1: Decoder Queries $Q_d$</h3>
<p>가장 아래 양쪽과 중앙에 $Q_d$가 있다.
이것은 Object Detector가 만든 decoder query인 것을 알고 있다. 이 query는 특정 객체 후보를 나타낸다.</p>
<p>하지만, $Q_d$만으로는 문제가 있다. <strong>이것은 region-level detector feature라서, CLIP과 같은 VLM의 image-level text embedding과 바로 맞추기에는 정보가 부족할 수 있다.</strong></p>
<p>그래서 VLD-M은 $Q_d$를 그냥 쓰지 않고, 주변 visual context를 더한다.</p>
<h3 id="입력-2-backbone-features-b">입력 2: Backbone Features $B$</h3>
<p>중앙 왼쪽에 backbone features $B$가 있다. </p>
<p>Backbone feature는 이미지의 spatial/local visual information을 담고 있다. texture, edge, local pattern, object 주변 배경과 같은 정보가 상대적으로 많이 남아 있다.</p>
<p>VLD-M은 $Q_d$가 $B$를 deformable cross-attention으로 보게 한다.</p>
<blockquote>
<p><strong>Deformable cross-attention</strong>은 query가 이미지 feature 전체를 다 보지 않고, <strong>자기 주변의 중요한 몇 개 위치만 골라서 보는 attention</strong>이다.</p>
</blockquote>
<p>이러면 $Q_d$가 그냥 detector query로만 남는 게 아니라, 객체 주변의 시각 정보를 더 보강한 query가 된다. 
<strong>Open-Det에서는 $Q_d$를 더 좋은 VL-prompt로 만들기 위해 주변 context를 추가하는 역할을 하는 것</strong>이다.</p>
<p>이렇게 왼쪽 branch에서 업데이트된 query $Q_b$가 만들어지게 되고, 이것은 backbone feature에서 보강된 query라고 보면 된다. </p>
<h3 id="입력-3-encoder-featuers-e">입력 3: Encoder Featuers $E$</h3>
<p>중앙에서 오른쪽에는 encoder features $E$가 있다.</p>
<p>Encoder feature는 transformer encoder를 거진 feature이기 때문에 더 <strong>global</strong>하고 <strong>contextual</strong>한 정보를 담는다. </p>
<blockquote>
<p>생각해보면, Transformer Encoder를 지나기 전의 Backbone에서 나온 feature는 <strong>지역적 시각 패턴에 강하다</strong>.</p>
</blockquote>
<p>예를 들어 CNN backbone feature는 선, 색, 형태와 같은 local 한 visual 정보들을 많이 담고 있다. 그런데, <strong>transformer Encoder에서는 feature token들이 self-attention을 한다.</strong></p>
<blockquote>
<blockquote>
<p>물론 깊어질수록 Receptive Field가 넓어져서, Global 정보를 반영하긴 하지만, <strong>기본 연산이 local conv</strong>이기 때문에 위와 같이 표현했다. </p>
</blockquote>
</blockquote>
<p>Self-attnetion은 각각 image token이 다른 token을 볼 수 있게 하여, <strong>특정 위치 feature도 자기 주변만 보는게 아니라, 다른 위치들과의 관계를 반영한다. 그래서 Encoder feature는 backbone feature보다 더 global/contextual한 정보를 담게 되는 것이다.</strong></p>
<blockquote>
<blockquote>
<p>Transformer Decoder에서도 Query들끼리 masked self-attention을 하지 않나? </p>
</blockquote>
<p>맞다. 그런데 정말 <strong>Query들 끼리만</strong>하기 때문에, <code>중복 detection 줄이기</code>, <code>각 query가 서로 다른 객체 담당하도록 조정하기</code> 등과 같은 효과가 나온다. </p>
</blockquote>
<p>이렇게 단순 local texture보다 객체 간 관계나 더 넓은 문맥이 반영되었고,</p>
<p>VLD-M은 $Q_d$가 $E$도 deformable cross-attetion으로 참고하게 된다. </p>
<p>그 결과 오른쪽 branch에서 $Q_e$가 만들어진다.</p>
<p>이것은 encoder feature에서 보강된 query이다.</p>
<h3 id="q_b-q_e-q_d의-세-갈래">$Q_b$, $Q_e$, $Q_d$의 세 갈래</h3>
<p>Figure3를 보면 세 갈래가 위로 올라간다.</p>
<p><strong>왼쪽 branch: $Q_b$</strong>: backbone feature $B$와 상호작용한 query이다.
<strong>오른쪽 branch $Q_e$</strong>: Encoder feature $E$와 상호작용한 query이다. 
<strong>중앙 branch: $Q_d$</strong>: 원래 Decoder query $Q_d$도 그대로 버리지 않고 가져온다. 중앙에서 MLP를 통과한다. </p>
<blockquote>
<p>MLP의 역할은 VLD-M 안에서 업데이트된 query들을 <strong>text embedding과 비교 가능한 표현으로 변환</strong>하는 역할이다. </p>
</blockquote>
<p>논문의 설명에 따르면, MLP는 두 개의 linear layer와 activation layer로 구성된다. 단순 선형 projection보다 더 유연하게 feature를 변환할 수 있다. </p>
<p>이 세 가지 정보를 같이 쓰는 이유는, 어느 하나만으로는 부족하기 때문이다.</p>
<ul>
<li>$Q_d$: 객체 후보 자체를 잘 표현</li>
<li>$Q_b$: local/background visual detail 보강</li>
<li>$Q_e$: Encoder-level semantic/contextual 정보 보강</li>
</ul>
<h3 id="vlm-knowledge-distillation">VLM Knowledge Distillation</h3>
<p>상단을 보면 <strong>VLM knowledge distillation</strong> 블록이 있다.</p>
<p>여기서 사용하는 것은 아래 4가지이다.</p>
<ul>
<li>text embeddings $T_e$</li>
<li>aligned indice $VL_{align}$</li>
<li>VL-prompts $P_{vl}$</li>
<li>Cosine Similarity Loss</li>
</ul>
<p>3.3에서 BVLA-M은 $Q_d$와 $T_e$ 사이의 alignment를 계산하고, aligned index $VL_{align}$을 만든다. 3.4에서는 이 $VL_{align}$을 사용해서 어떤 $P_{vl}$이 어떤 $T_e$와 잘 대응되어야 하는지 선택한다.</p>
<p>그 다음 $P_{vl}$과 $T_e$ 사이의 Cosine Similarity Loss를 게산한다.</p>
<p>즉, <strong>BVLA-M이 query-text pair를 정하고, VLD-M이 해당 query에서 VL-prompt를 생성하며, $P_{vl}$이 대응되는 $T_e$와 가까워지도록 증류한다.</strong></p>
<blockquote>
<h3 id="cosine-similarity-loss">Cosine Similarity Loss</h3>
<p>Cosine Similarity는 두 embedding의 방향이 얼마나 비슷한지 본다.</p>
</blockquote>
<p>VLM embedding 공간에서는 보통 방햐 유사도가 의미 유사도를 나타낸다. 그래서 $P_{vl}$이 대응되는 text embedding $T_e$와 같은 방향을 갖도록 만들면, LLM에 들어가는 prompt가 더 언어 의미에 가까워진다.</p>
<blockquote>
</blockquote>
<p>즉, <strong>VLD-M의 학습 목표는 $P_{vl}$이 object name text embedding $T_e$와 의미적으로 가까워지게 만들기!</strong></p>
<blockquote>
<h2 id="34-핵심-요약">3.4 핵심 요약</h2>
<p><strong>VLD-M은 detector query $Q_d$에 backbone/encoder context를 더해, image-like representation으로 보강하고, VLM text embedding $T_e$와의 cosine distillation을 통해 LLM 입력용 VL-prompts $P_{vl}$을 생성하는 모듈이다.</strong></p>
</blockquote>
<hr>
<p>쉽지 않네요 이번 논문... 
알아야 할 것들이 너무 많습니다... 화이팅 👏💪</p>
<h2 id="35-object-name-generator">3.5. Object Name Generator</h2>
<p>이 섹션은 <strong>객체 이름을 생성하는 LLM 부분을 어떻게 안정적으로 학습시킬 것인가</strong>를 다룬다.</p>
<p>Figure 2의 아래 주황색 영역을 참고하면 되겠다.
<img src="https://velog.velcdn.com/images/jm_mg_se/post/d15dc7ca-2b34-4ec6-9a60-1ea41a422a38/image.png" alt=""></p>
<p>흐름을 간단히 보자면,
VL-prompts $P_{vl}$ -&gt; Generative Language Model -&gt; object name 이다.</p>
<p>학습 초반에는 detector query와 language embedding 사이의 alignment가 아직 불안정하기 때문에, 약간 위험할 수 있다.</p>
<h3 id="문제-noisy-alignment">문제: Noisy Alignment</h3>
<p>저자들은 3.5를 <strong>Noisy Alignment</strong>라는 말과 함께 시작한다. </p>
<p>학습 초반에는 decoder queries $Q_d$가 아직 충분히 학습되지 않았다. 그래서 text embeddings $T_e$와 semantic gap이 크다.</p>
<p>즉, 초기에 발생하는 문제를 정리하자면, 
<strong>$Q_d$가 아직 객체 의미를 잘 담지 못하여 $Q_d$와 $T_e$의 alignment가 noisy 하다. 때문에 LLM이 불안정한 visual-language signal을 받는다.</strong></p>
<p>저자들은 이 문제가 <strong>LLM의 pretrained Weights를 망가뜨릴 위험</strong>이 있다고 말한다. 특히 text generation을 담당하는 <strong>heavy-weight head layer</strong>가 문제이다.</p>
<p>LLM Head는 vocabulary token을 예측하는 큰 출력층이다. T5처럼 token vocabulary가 큰 모델에서는 이 head가 무겁고 민감하다. 그런데 하긋ㅂ 초반에 quality 낮은 query-text alignment로 이 head를 업데이트해버리면, 원래 LLM이 갖고 있던 언어 생성 능력이 흔들릴 수 있다는 것이다.</p>
<h3 id="해결-1-llm-head-freeze--lora-head">해결 1: LLM Head Freeze + LoRA Head</h3>
<h4 id="llm-head-freeze-🥶">LLM Head Freeze 🥶</h4>
<p>Open-Det은 초반 학습 단계에서 LLM Head를 Freeze 한다.</p>
<p>중요한 점은 LLM 전체를 완전히 얼리는 것이 아니라, <strong>head를 freeze하고, other weights는 active</strong>하게 둔다는 것이다.</p>
<p>이렇게 하면 noisy alignment가 들어와도 가장 민감한 출력 head가 직접 망가지지 않는다.</p>
<h4 id="lora-head-도입-😵💫">LoRA Head 도입 😵‍💫</h4>
<p>그 대신 Open-Det은 <strong>LoRA Head</strong>를 추가한다.</p>
<p>LoRA는 큰 Weight 전체를 업데이트하지 않고, 작은 Low-rank parameter만 학습하는 방식이다. 그래서 trainable parameter가 크게 줄고, 학습이 더 가벼워진다.</p>
<p>이 전략의 목적은 두 가지로, <strong>초반 noisy signal이 기존 LLM Head를 망가뜨리지 않도록 pretrained LLM Head를 보호한다.</strong>
그리고, <strong>학습 효율 또한 증가</strong>한다.</p>
<h3 id="해결-2-text-denoising">해결 2: Text Denoising</h3>
<p>저자들은 흥미로운 관찰을 한다. text embeddings $T_e$를 LLM, 예를 들면 T5에 넣어서 text reconstruction을 시키면 training loss가 빠르게 감소한다고 한다.</p>
<p>이 말은 T5가 $T_e$같은 embedding을 받아 원래 text를 복원하는 능력을 꽤 잘 배울 수 있다는 뜻이다.</p>
<p>Open-Det은 이 관찰을 이용한다.</p>
<h4 id="gaussian-noise를-text-embedding에-추가">Gaussian Noise를 Text Embedding에 추가</h4>
<p>Figure 2를 보면 $T_e$쪽에 <strong>add noise</strong>가 표시되어 있다. 
<img src="https://velog.velcdn.com/images/jm_mg_se/post/6bc0948e-9949-42a0-979d-83a3cc6c4958/image.png" alt=""></p>
<p>논문은 text embeddings에 Gaussian Noise를 추가한다. 
$$$
\text{noise} ~ N(0, \sigma^2)
$$$
여기서 $\sigma$는 text embeddings $T_e$의 standard deviation이다.</p>
<p>즉, 깨끗한 embeddings만 주는 것이 아니라, 일부러 noise가 섞인 embedding을 넣고 T5가 text를 reconstruct하도록 학습한다.</p>
<blockquote>
<h3 id="text-denoising이-필요한-이유">Text Denoising이 필요한 이유</h3>
<p>실제 Open-Det 학습에서는 LLM이 항상 깨끗한 text embedding만 받는 것이 아니다. 최종적으로 VLD-M이 만든 VL-prompts $P_{vl}$을 받는다.</p>
</blockquote>
<p>그런데 $P_{vl}$은 detector query에서 출발한다. detector query는 초반에 noisy한데, 따라서 LLM은 어느 정도 오염된 prompt representation에서도 안정적으로 object name을 생성할 수 있어야 한다.</p>
<blockquote>
</blockquote>
<p>Text Denoising은 바로 이 상황을 미리 연습시키는 과정으로, 이를 통해 T5는 noisy input에 강해지고, 나중에 $P_{vl}$이 완벽하지 않아도 object name generation을 더 안정적으로 수행할 수 있다.</p>
<hr>
<h2 id="36-masked-alignment-loss-and-joint-loss">3.6. Masked Alignment Loss and Joint Loss</h2>
<p>이 섹션의 핵심은 Open-Det의 <strong>loss 설계</strong> 파트이다.</p>
<p>여기서 제안하는 loss는 두 개이다.
<strong>Masked Alignment Loss와 Joint Loss</strong>.</p>
<blockquote>
<h3 id="기존-alignment-loss의-문제">기존 Alignment Loss의 문제</h3>
<p>GenerateU에서는 Vision-Language alignment를 위해 BCE Loss를 사용한다. </p>
</blockquote>
<ul>
<li>matched query-text pair는 가깝게</li>
<li>Unmatched query-text pair는 멀리<blockquote>
</blockquote>
그런데 이 방식이 objecet name들 사이의 관계를 고려하지 못한다고 저자들을 말한다. <h4 id="contradictory-losses-and-gradients">Contradictory Losses and Gradients</h4>
예를 들어 Mini-batch 안에 비슷하거나 같은 category text가 여러 개 있다고 해보자.<pre><code>text 1: dog
text 2: puppy
text 3: dog</code></pre>어떤 query가 <code>text1: dog</code>와 매칭되면, 기존 BCE 방식에서는 나머지 unmatched text를 전부 negative로 볼 수 있다. 그러면 같은 의미의 <code>text3: dog</code>나 매우 유사한 <code>puppy</code>까지 밀어내는 gradient가 발생할 수 있다.<blockquote>
</blockquote>
즉, 모델은 동시에 <code>query를 dog쪽으로 당겨라</code>, <code>query를 또 다른 dog 또는 유사 dog text에서는 밀어내라</code>라는 신호를 받는다.<blockquote>
</blockquote>
이것이 바로 논문이 말하는 <strong>Contradictory losses and gradients</strong>이다. </li>
</ul>
<h3 id="masked-alignment-loss-mal">Masked Alignment Loss, MAL</h3>
<p>query-text alignment에서 생기는 <strong>모순된 supervision</strong>을 줄인다.</p>
<h4 id="핵심-아이디어-1">핵심 아이디어</h4>
<p>MAL은 text embedding끼리의 유사도를 먼저 계산하여, 같은 category 또는 매우 유사한 category를 negative로 취급하지 않도록 mask를 만든다.</p>
<p>논문은 binary mask를 이렇게 만든다.
$$$
M = T_e \times T_e^T
$$$
여기서 $T_e$는 text embeddings. 즉, text embedding끼리 서로 얼마나 비슷한지 보는 matrix를 만드는 것이다.</p>
<p>그 다음에는 threhsold를 적용한다. ($\tau = 0.99$)</p>
<p>유사도를 threshold와 비교하여 1, 0으로 둔다.
$$$
L_{MAL} = -\frac{1}{NM}[(VL_{align} \times M) \odot \log(S_{align} + (1-VL_{align} \times M) \odot \log(1-S_{align})]
$$$
여기서 $S_{align}$은 3.3에서 BVLA-M이 만든 query-text alignment score matrix이고, $N$은 query의 수, $M$은 text embedding 수 이다.</p>
<p><strong>MAL이 실제로 하는 일</strong>은 다음과 같다.
기존 방식에서는 $VL_{align}$에 표시된 하나의 text만 positive이고, 나머지는 거의 다 negative이다.</p>
<p>MAL은 여기에 text similarity mask $M$을 곱한다.</p>
<p>이렇게 하면 matched text와 같은 category로 판단되는 text들도 positive 쪽으로 보정된다.</p>
<p>즉, MAL은 alignment label을 더 똑똑하게 수정한다.</p>
<h3 id="joint-loss-jl">Joint Loss, JL</h3>
<p>binary score가 IoU score, alignment score와 일관되게 학습되도록 만든다.</p>
<p>Open-Det은 inference 시에, object name을 자동 생성한다. 그래서 OVD처럼 추론 시 외부 vocabulary를 넣고 alignment score로 결과를 다시 고르는 방식이 아니다. </p>
<p>또 detector는 많은 query를 만들 수 있으므로, duplicate detection을 줄이고 실제 object query만 남겨야 한다. 이를 위해 binary head가 필요하다.</p>
<p>문제는 binary label이 고정된 class label처럼 단순하지 않다는 것이다. Open-Det에서는 query가 positive인지, negative인지가 Vision-Language alignment와 matching 과정에 의해 동적으로 결정된다.</p>
<p>$$$
\mathcal L_{JL} = -\frac{1}{N} \sum \limits_{i=1} ^ N[(\sqrt{p_i^{\alpha}s_i^{\alpha}u_i^{1-2\alpha}} - p_i)^2 y_i \log(p_i) + p_i^2(1-\sqrt{p_i^{\alpha}s_i^{\alpha}u_i^{1-2\alpha}})(1-y_i)\log(1-p_i)]
$$$
Joint Loss는 $p_i$: binary score, $s_i$: alignment score, $u_i$: IoU score를 결합하는데, 이들을 geometric하게 섞은 joint quality score를 만든다.</p>
<p>즉, alignment와 binary score에 $\alpha$, IoU에는 $1-2\alpha$만큼의 비중을 둔다. </p>
<blockquote>
<h3 id="왜-square-root를-쓸까">왜 Square root를 쓸까?</h3>
<p>논문은 이 이유도 명확히 설명하는데, 세 score를 곱하면 값이 너무 작아질 수 있기 때문이다. </p>
</blockquote>
<blockquote>
<h3 id="joint-loss의-역할">Joint Loss의 역할</h3>
<p>Joint Loss는 binary prediction을 단순한 objectness 분류로 보지 않는다.</p>
</blockquote>
<p>대신 binary score가 다음과 함께 움직이도록 만든다.</p>
<ul>
<li>binary score $p_i$</li>
<li>alignment score $s_i$</li>
<li>IoU score $u_i$<blockquote>
</blockquote>
즉, 좋은 query는 object일 확률도 높고, text와 의미적으로도 잘 맞고, box도 정확해야 한다.<blockquote>
</blockquote>
이렇게 binary head가 단순 object처럼 보이는가?만 뱅는 것이 아니라, <strong>localization 품질과 language alignment 품질까지 반영한 objectness를 배우게 된다.</strong></li>
</ul>
<hr>
<h1 id="4-experiments">4. Experiments</h1>
<h3 id="datasets">Datasets</h3>
<p>학습 데이터는 <strong>VIsual Genome, VG</strong>를 사용한다. </p>
<blockquote>
<p><strong>*&quot;We train our model with a small set of detection data Visual Genome(VG).&quot;*</strong></p>
</blockquote>
<p>여기서 &quot;small set&quot;이 중요하다. VG 학습 이미지는 <strong>77,298장</strong>, 즉 약 <code>0.077M</code>이다. 앞에서 계속 강조했던 GenerateU보다 훨씬 적은 데이터로 학습한다는 주장을 실험 설정에서 실제로 고정한다.</p>
<p>즉, Open-Det은 대규모 image-text pretraining 데이터나 grounding dataset을 왕창 쓰는 쪽이 아닌, 비교적 작은 detection data로 OED를 학습하는 방향이다.</p>
<p>평가 데이터는 <strong>LVIS, COCO, Objects365</strong>이다.</p>
<p>주 평가 데이터는 <strong>zero-shot LVIS</strong>로, 카테고리 수가 1,203개로 많고, rare/common/frequent category 구분이 있어서 open-ended/open-vocabulary 성능을 보기 좋다.</p>
<p>추가로 <strong>COCO2017과 Objects365</strong>도 평가에 사용한다. 이 둘은 Open-Det이 LVIS에만 맞춰진 것이 아니라 다른 detection benchmark에서도 작동하는지 확인하기 위한 보조평가이다. </p>
<h3 id="evaluation-metrics">Evaluation Metrics</h3>
<h4 id="oed-평가는-단순-class-matching이-아니다">OED 평가는 단순 class matching이 아니다.</h4>
<p>OED는 class label을 고르는 문제가 아니라, object name을 생성하는 문제이다. 그래서 평가도 일반 closed-set detection처럼 predicted class id와 GT class id가 같은지만 보면 안된다. </p>
<blockquote>
<p><strong>*&quot;compute the similarity score between generated object names and annotated category names using a fixed pre-trained text encoder.&quot;*</strong></p>
</blockquote>
<p>즉, 모델이 생성한 object name과 정답 category name을 <strong>고정된 pretrained text encoder</strong>로 Embedding한 뒤, 둘의 similarity를 계산한다.</p>
<p>예를 들어 모델이 <code>&quot;couch&quot;</code>를 생성했고 GT가 <code>&quot;sofa&quot;</code>라면, 문자열은 다르지만 의미는 가깝다.</p>
<p>OED에서는 이러한 경우를 어느 정도 인정 할 수 있어야 하므로 text encoder similarity를 사용한다.</p>
<h4 id="사용하는-지표들">사용하는 지표들</h4>
<p>LVIS 기준으로 다음 AP들을 본다.
<code>AP_r</code>: rare categories에 대한 AP로, 이 논문에서 특히 중요하다.
<code>AP_c</code>: common categories에 대한 AP이다.
<code>AP_f</code>: frequent categories에 대한 AP이다.
<code>AP</code>: 전체 category 평균 AP이다.</p>
<p>평가는 LVIS <strong>5k MiniVal subset</strong>에서 수행한다. 이는 MDETR, GLIP, GenerateU 등 기존 연구 프로토콜을 따른다고 한다.</p>
<h3 id="implementatino-details">Implementatino Details</h3>
<p>Open-Det은 GenerateU와 공정하게 비교하고자 같은 계열의 backbone과 language model을 사용한다. </p>
<p>사용한 모델은 다음과 같다.</p>
<ul>
<li>Backbone: Swin-Tiny, Swin-Large</li>
<li>Generative LLM: FlanT5-base</li>
</ul>
<p>즉, 성능 향상이 단순히 더 큰 LLM이나 완전히 다른 backbone 때문이라고 보기 어렵게 맞춘 설정이다.</p>
<pre><code>mini-batch size: 8
GPU: 4 Tesla V100
optimizer: AdamW
weight decay: 0.05</code></pre><p>학습 설정은 위와 같은 설정을 따른다.</p>
<p>Learning Rate은 모듈별로 다른데, </p>
<pre><code>Object Detector: 1e-4
Prompts Distiller: 1e-4
Object Name Generator: 2e-4</code></pre><p>Object Name Generator가 더 크다. 이건 LLM 기반 생성부와 LoRA Head 등을 빠르게 적응시키려는 설정으로 볼 수 있다.</p>
<hr>
<h2 id="41-main-results">4.1. Main Results</h2>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/e9d3ec53-5e1f-4a7c-944c-049f32bbe01f/image.png" alt=""></p>
<h3 id="ovd-모델보다-vocabulary-free-측면에서-더-실용적이다">OVD 모델보다 Vocabulary-free 측면에서 더 실용적이다.</h3>
<p>GLIP, Grounding DINO 같은 OVD 모델은 infernece 시에 text vocabulary/prior가 필요하다.</p>
<p>Open-Det은 object name을 직접 생성하므로 <strong>Vocabulary-free</strong>이다.</p>
<h3 id="generateu보다-훨씬-효율적이다">GenerateU보다 훨씬 효율적이다.</h3>
<p>같은 VG 데이터만 사용했을 때 GenerateU는 <code>149 epochs</code>, Open-Det은 <code>31 epochs</code>이다. 그런데 Open-Det이 성능도 더 높다.</p>
<h3 id="적은-데이터-좋은-성능">적은 데이터, 좋은 성능</h3>
<p>Open-Det은 <code>0.077M</code> VG 데이터만 사용하는데, GenerateU가 <code>VG + GRIT5M = 5.077M</code>을 쓴 경우와도 경쟁하거나 이긴다.</p>
<p>Table 1이 바로 핵심인데, 평가 대상은 <strong>LVIS MiniVal</strong>이고, zero-shot domain transfer 성능을 본다.</p>
<p>표에서 먼저 봐야 할 column은 <code>Vocabulary-Free</code>, <code>Data Size</code>, <code>Epochs</code>, 그리고 <code>AP_r</code>와 <code>AP</code>이다. 여기서 <code>Vocabulary-Free</code>는 추론 시 추가적인 category vocabulary 없이 탐지가 가능한지를 의미한다. OVD 모델들은 대체로 텍스트 vocabulary나 category prior를 입력으로 받아야 하지만, Open-Det과 GenerateU는 객체 이름을 직접 생성하는 OED 모델이므로 vocabulary-free 설정에 해당한다.</p>
<h3 id="ovd-모델과의-비교">OVD 모델과의 비교</h3>
<p>먼저 GLIP, Grounding DINO와 같은 OVD 모델과 비교해보자.</p>
<p>GLIP(A)는 <code>0.660M</code> 데이터를 사용하고, LVIS MiniVal에서 <code>AP_r 14.2</code>, <code>AP 18.5</code>를 기록한다. 반면 Open-Det은 <code>0.077M</code> 데이터만 사용하고도 <code>AP_r 21.0</code>, <code>AP 27.0</code>을 달성한다.</p>
<p>즉 Open-Det은 GLIP(A)가 사용한 데이터의 약 <code>11.7%</code>만 사용하면서도 <code>AP_r +6.8</code>, 전체 <code>AP +8.5</code>의 성능 향상을 보인다. 여기서 중요한 점은 단순히 성능이 높다는 것만이 아니다. GLIP(A)는 vocabulary-free가 아니지만, Open-Det은 추론 시 추가 vocabulary 없이 객체 이름을 직접 생성한다.</p>
<p>GLIP(C)는 더 큰 데이터셋을 사용한다. <code>O365, GoldG, CAP4M</code>을 포함하여 총 <code>5.456M</code> 데이터를 사용하고 <code>AP 26.0</code>을 기록한다. 그런데 Open-Det은 <code>0.077M</code> 데이터만으로도 <code>AP 27.0</code>을 달성한다. 데이터 규모로 보면 Open-Det은 GLIP(C)의 약 <code>1.4%</code>만 사용하면서 더 높은 전체 AP를 얻은 것이다.</p>
<p>이 결과는 Open-Det의 핵심 주장을 잘 보여준다. Open-Det은 단순히 OVD 모델보다 좋은 점수를 내는 것이 아니라, 훨씬 적은 데이터와 vocabulary-free 추론 조건에서도 경쟁력 있는 성능을 낸다.</p>
<h3 id="generateu와의-비교">GenerateU와의 비교</h3>
<p>Open-Det의 가장 중요한 비교 대상은 GenerateU이다. GenerateU는 Open-Det 이전의 대표적인 OED 프레임워크이며, 마찬가지로 vocabulary-free 설정에서 객체 이름을 생성한다.</p>
<p>같은 <code>VG 0.077M</code> 데이터만 사용한 경우를 보면 차이가 명확하다.</p>
<p>GenerateU는 <code>149 epochs</code>를 학습했을 때 <code>AP_r 17.4</code>, <code>AP 25.4</code>를 기록한다. 반면 Open-Det은 <code>31 epochs</code>만 학습하고도 <code>AP_r 21.0</code>, <code>AP 27.0</code>을 달성한다.</p>
<p>즉 Open-Det은 GenerateU 대비 약 <code>20.8%</code>의 epoch만 사용하면서도 <code>AP_r +3.6</code>, <code>AP +1.6</code> 향상을 보인다. 이는 앞에서 Figure 1을 통해 확인했던 빠른 수렴 속도가 최종 성능표에서도 그대로 드러난 결과이다.</p>
<p>더 흥미로운 비교는 GenerateU가 추가 데이터인 GRIT5M을 사용한 경우이다. GenerateU는 <code>VG + GRIT5M</code>, 총 <code>5.077M</code> 데이터를 사용했을 때 <code>AP_r 20.0</code>, <code>AP 26.8</code>을 기록한다. 그런데 Open-Det은 <code>VG 0.077M</code>만 사용하고도 <code>AP_r 21.0</code>, <code>AP 27.0</code>을 달성한다.</p>
<p>즉 Open-Det은 GenerateU가 사용한 데이터의 약 <code>1.5%</code>만 사용하면서도 <code>AP_r +1.0</code>, <code>AP +0.2</code>를 보인다. 이 부분이 Open-Det의 데이터 효율성을 가장 강하게 보여주는 지점이다.</p>
<p>또한 Open-Det을 <code>50 epochs</code>까지 학습하면 성능은 <code>AP_r 21.9</code>, <code>AP 27.4</code>로 더 올라간다. GenerateU + GRIT5M과 비교하면 <code>AP_r +1.9</code>, <code>AP +0.6</code>이다. Open-Det은 적은 데이터로 빠르게 수렴할 뿐 아니라, 학습을 조금 더 진행했을 때 추가적인 성능 개선도 얻는다.</p>
<h3 id="backbone-scaling-결과">Backbone Scaling 결과</h3>
<p>Table 1의 하단은 backbone을 키웠을 때 Open-Det이 어떻게 확장되는지를 보여준다.</p>
<p>GenerateU Swin-Large는 <code>VG + GRIT5M 5.077M</code> 데이터를 사용해 <code>AP_r 22.3</code>, <code>AP 27.9</code>를 기록한다. 반면 Open-Det Swin-Small은 <code>VG 0.077M</code>만 사용하고도 <code>AP_r 26.0</code>, <code>AP 30.4</code>를 달성한다.</p>
<p>더 큰 backbone인 Open-Det Swin-Large를 사용하면 성능은 <code>AP_r 31.2</code>, <code>AP 33.1</code>까지 올라간다. GenerateU Swin-Large와 비교하면 <code>AP_r +8.9</code>, 전체 <code>AP +5.2</code>의 차이다.</p>
<p>이 결과는 Open-Det의 구조적 개선이 작은 모델에서만 우연히 나타난 것이 아니라, backbone scale이 커졌을 때도 유지된다는 것을 의미한다. 즉 Open-Det은 효율적인 구조이면서 동시에 확장성도 갖춘 프레임워크라고 볼 수 있다.</p>
<p>다만 Table 1의 모든 모델을 같은 의미로 직접 비교하면 안 된다. Mask R-CNN이나 Deformable DETR처럼 LVIS로 직접 학습되거나 fine-tuning된 모델은 Open-Det과 문제 설정이 다르다. Open-Det의 핵심 비교축은 closed-set detector와의 절대 우위가 아니라, vocabulary-free OED 설정에서의 데이터 효율성과 학습 효율성이다.</p>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/dd360256-1a2c-442f-bb80-d643a8826fc5/image.png" alt=""></p>
<p>Table 2는 COCO와 Objects365에서의 zero-shot 평가 결과이다. 이 표는 Open-Det의 성능 향상이 LVIS에만 국한된 것이 아니라 다른 detection benchmark에도 전이되는지를 확인하기 위한 실험이다.</p>
<p>GenerateU Swin-Large는 <code>VG</code>만 사용했을 때 COCO에서 <code>33.0 AP</code>, Objects365에서 <code>10.1 AP</code>를 기록한다. 추가 데이터인 <code>VG + GRIT</code>를 사용하면 각각 <code>33.6</code>, <code>10.5</code>까지 오른다.</p>
<p>반면 Open-Det Swin-Large는 <code>VG</code>만 사용하고도 COCO에서 <code>35.8 AP</code>, Objects365에서 <code>13.8 AP</code>를 달성한다. GenerateU가 추가 GRIT 데이터를 사용한 경우와 비교해도 COCO에서는 <code>+2.2 AP</code>, Objects365에서는 <code>+3.3 AP</code> 더 높다.</p>
<p>이 결과는 중요하다. Open-Det은 LVIS MiniVal에서만 좋은 것이 아니라, COCO와 Objects365처럼 다른 데이터 분포에서도 더 나은 zero-shot 성능을 보인다. 특히 추가 GRIT 데이터 없이 VG만 사용했다는 점에서, Open-Det의 개선이 단순히 데이터 규모에서 나온 것이 아니라 구조적 효율성에서 비롯된 것임을 보여준다.</p>
<blockquote>
<h3 id="정리-1">정리</h3>
</blockquote>
<p>Table 1과 Table 2는 Open-Det의 핵심 주장을 실험적으로 뒷받침한다.</p>
<blockquote>
</blockquote>
<p>Open-Det은 OVD 모델과 달리 추론 시 추가 vocabulary에 의존하지 않는다. GenerateU와 같은 vocabulary-free OED 모델과 비교해도 훨씬 적은 데이터와 적은 epoch으로 더 높은 성능을 달성한다. 특히 <code>0.077M</code> VG 데이터만으로 GenerateU의 <code>VG + GRIT5M 5.077M</code> 설정을 뛰어넘는 결과는 Open-Det의 데이터 효율성을 가장 잘 보여준다.</p>
<blockquote>
</blockquote>
<p>결국 이 실험 섹션의 메시지는 명확하다. Open-Det은 OED에서 단순히 성능을 높인 모델이 아니라, object detector, prompt distiller, object name generator, vision-language aligner를 함께 재설계하여 학습 효율과 데이터 효율을 동시에 개선한 프레임워크이다.</p>
<hr>
<h2 id="42-ablation-studies">4.2. Ablation Studies</h2>
<p>4.2에서는 Open-Det을 구성하는 각 모듈이 실제로 성능 향상에 얼마나 기여하는지를 분석한다.</p>
<p>앞선 Table 1, Table 2가 Open-Det이 기존 모델보다 좋은지를 보여줬다면, 4.2는 그 성능 향상이 <strong>어떤 구성요소에서 비롯되는지</strong>를 분해해서 보여주는 섹션이다.</p>
<p>즉, Open-Det이 단순히 여러 모듈을 붙여놓은 모델이 아니라, 각 구성요소가 실제로 의미 있는 역할을 하는지 검증하는 부분이다.</p>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/941d7473-baf5-44f3-b6de-7652a7a727b1/image.png" alt=""></p>
<h3 id="open-det-구성요소에-대한-ablation">Open-Det 구성요소에 대한 Ablation</h3>
<p>Table 3은 Open-Det의 주요 구성요소를 하나씩 추가했을 때 성능이 어떻게 변하는지를 보여준다.</p>
<p>가장 기본 baseline은 아무 구성요소도 추가하지 않은 상태이며, 이때 성능은 <code>AP_r 10.2</code>, <code>AP 19.6</code>이다. 여기서 ODR(Object Detector)을 추가하면 <code>AP_r 13.9</code>, <code>AP 23.1</code>로 상승한다.</p>
<p>이는 3.2에서 설명한 decoupled one-to-many / one-to-one matching 구조가 실제로 box detector의 수렴을 빠르게 만들고, 전체 detection 성능에도 영향을 준다는 것을 의미한다.</p>
<p><strong>ODR은 단순히 detector 구조를 바꾼 모듈이 아니라, Open-Det 전체의 학습 안정성과 localization 품질을 끌어올리는 출발점이다.</strong></p>
<p>그 다음 BVLA-M을 추가하면 <code>AP_r 14.7</code>, <code>AP 23.5</code>가 된다. 상승 폭 자체는 ODR만큼 크지는 않지만, Vision-Language alignment를 개선하는 방향으로 성능이 추가 개선된다.</p>
<p>BVLA-M은 decoder query $Q_d$와 text embedding $T_e$를 단순히 한 방향으로만 맞추지 않고, V-to-L과 L-to-V 양방향에서 alignment score를 계산한다. 따라서 query-text matching이 더 안정적으로 이루어진다.</p>
<h3 id="vld-m의-기여">VLD-M의 기여</h3>
<p>Table 3에서 가장 눈에 띄는 변화 중 하나는 VLD-M을 추가했을 때이다.</p>
<p>ODR과 BVLA-M만 사용한 경우에는 <code>AP_r 14.7</code>, <code>AP_c 20.3</code>, <code>AP 23.5</code>이다. 여기에 VLD-M을 추가하면 <code>AP_r 16.3</code>, <code>AP_c 24.2</code>, <code>AP 26.3</code>으로 오른다.</p>
<p>특히 <code>AP_c</code>는 <code>+3.9</code>, 전체 <code>AP</code>는 <code>+2.8</code> 상승한다.</p>
<p>이는 3.4에서 설명한 VLD-M의 역할이 실제로 중요하다는 것을 보여준다. VLD-M은 detector query를 그대로 LLM에 넣는 대신, backbone feature와 encoder feature를 통해 query에 visual context를 보강하고, VLM의 text embedding 지식을 VL-prompts로 증류한다.</p>
<p><strong>VLD-M의 성능 향상은 Open-Det에서 semantic gap을 줄이는 과정이 단순한 아이디어가 아니라 실제 성능에 직접적으로 기여한다는 근거이다.</strong></p>
<p>즉, Open-Det의 핵심은 “LLM을 붙였다”가 아니다. Detector query를 LLM이 이해할 수 있는 prompt representation으로 바꾸는 중간 과정이 핵심이다.</p>
<h3 id="object-name-generator와-losses">Object Name Generator와 Losses</h3>
<p>VLD-M까지 추가한 뒤 Object Name Generator, 즉 ONG를 추가하면 <code>AP_r 16.9</code>, <code>AP 26.3</code>이 된다. 전체 AP는 유지되지만 rare category 성능이 조금 오른다.</p>
<p>ONG에는 LoRA Head와 Text Denoising이 포함된다. 이는 LLM의 object name generation 학습을 안정화하기 위한 구성이다. 특히 rare category에서는 데이터가 부족하기 때문에, noisy prompt에서도 안정적으로 이름을 생성하는 능력이 중요하다.</p>
<p>마지막으로 Masked Alignment Loss와 Joint Loss를 추가하면 성능은 <code>AP_r 21.0</code>, <code>AP 27.0</code>까지 상승한다. Losses를 추가하기 전과 비교하면 <code>AP_r +4.1</code>, <code>AP +0.7</code>이다.</p>
<p><strong>Table 3에서 가장 중요한 점은 최종 성능 향상이 특정 모듈 하나에서만 나온 것이 아니라, detector 구조, vision-language alignment, prompt distillation, name generation, loss 설계가 함께 누적되어 만들어진다는 것이다.</strong></p>
<hr>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/a8c09828-34bd-461f-8c79-865f028c22fb/image.png" alt=""></p>
<h3 id="loss-function-ablation">Loss Function Ablation</h3>
<p>Table 4는 3.6에서 설명한 Masked Alignment Loss와 Joint Loss가 각각 어떤 영향을 주는지 보여준다.</p>
<p>기본 상태에서는 <code>AP_r 16.9</code>, <code>AP 26.3</code>이다.</p>
<p>Masked Alignment Loss만 추가하면 <code>AP_r 18.6</code>, <code>AP 26.6</code>이 된다. 즉 rare category 성능이 <code>+1.7</code> 상승한다.</p>
<p>MAL은 query-text alignment 과정에서 같은 의미의 text를 잘못 negative로 밀어내는 문제를 줄인다. 특히 rare category에서는 학습 샘플이 적기 때문에, 잘못된 negative supervision 하나하나가 더 큰 영향을 줄 수 있다.</p>
<p><strong>Masked Alignment Loss는 rare category에서 발생하기 쉬운 contradictory supervision을 줄여 alignment 학습을 안정화한다.</strong></p>
<p>Joint Loss만 추가한 경우에는 <code>AP_r 19.5</code>, <code>AP 26.5</code>이다. rare category 기준으로는 <code>+2.6</code> 상승한다.</p>
<p>Joint Loss는 binary score, alignment score, IoU score가 서로 일관되게 움직이도록 만든다. 좋은 query라면 object일 확률도 높고, box도 정확해야 하며, text와도 잘 맞아야 한다. Joint Loss는 이 세 조건을 함께 반영한다.</p>
<p>두 loss를 함께 사용하면 <code>AP_r 21.0</code>, <code>AP 27.0</code>으로 가장 좋은 성능을 얻는다.</p>
<p><strong>MAL은 alignment label의 모순을 줄이고, Joint Loss는 objectness prediction을 localization 및 semantic alignment와 연결한다. 두 loss는 서로 다른 문제를 해결하기 때문에 함께 사용할 때 가장 큰 효과를 낸다.</strong></p>
<hr>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/7afbeb35-03db-459e-b427-bb18dc8cd182/image.png" alt=""></p>
<h3 id="object-name-generator-구성요소-ablation">Object Name Generator 구성요소 Ablation</h3>
<p>Table 5는 Object Name Generator 내부의 LoRA Head와 Text Denoising이 각각 어떤 역할을 하는지 보여준다.</p>
<p>기본 상태에서는 <code>AP_r 15.3</code>, <code>AP 26.0</code>이다.</p>
<p>LoRA Head만 추가하면 <code>AP_r 16.5</code>, <code>AP 26.4</code>로 오른다. LoRA Head는 무거운 LLM head 전체를 직접 업데이트하지 않고, 작은 low-rank parameter를 통해 빠르게 적응하도록 돕는다.</p>
<p>이는 학습 초반 noisy alignment가 LLM의 pre-trained head를 망가뜨리는 문제를 줄인다.</p>
<p>Text Denoising만 추가하면 <code>AP_r 19.9</code>, <code>AP 26.2</code>가 된다. 특히 rare category에서 상승 폭이 크다.</p>
<p>Text Denoising은 text embedding에 Gaussian noise를 추가하고, LLM이 이를 다시 복원하도록 학습시키는 방식이다. 이를 통해 LLM은 완벽하지 않은 VL-prompt가 들어와도 더 안정적으로 object name을 생성할 수 있다.</p>
<p>LoRA Head와 Text Denoising을 함께 사용하면 <code>AP_r 21.0</code>, <code>AP 27.0</code>으로 가장 좋은 성능을 기록한다.</p>
<p><strong>Table 5는 Object Name Generator의 핵심이 단순히 LLM을 사용하는 것이 아니라, LLM을 noisy visual-language prompt에 안정적으로 적응시키는 데 있다는 것을 보여준다.</strong></p>
<hr>
<blockquote>
<h3 id="42-정리">4.2 정리</h3>
</blockquote>
<p>4.2의 ablation 결과는 Open-Det의 설계가 각각 독립적으로 의미 있는 기여를 한다는 것을 보여준다.</p>
<blockquote>
</blockquote>
<p>ODR은 detector convergence와 localization을 개선한다. BVLA-M은 query-text alignment를 강화한다. VLD-M은 VLM의 alignment 지식을 VL-prompts로 증류하여 semantic gap을 줄인다. Object Name Generator는 LoRA Head와 Text Denoising을 통해 LLM generation 학습을 안정화한다. 마지막으로 MAL과 Joint Loss는 alignment supervision과 binary classification을 더 일관되게 만든다.</p>
<blockquote>
</blockquote>
<p><strong>결국 Open-Det의 성능 향상은 하나의 큰 모듈에서 나온 것이 아니라, OED 학습 과정에서 발생하는 병목들을 detector, alignment, prompt, generator, loss 단계에서 각각 정리한 결과이다.</strong></p>
<hr>
<h2 id="43-improvements-in-vl-alignment-scores">4.3. Improvements in VL Alignment Scores</h2>
<p>4.3에서는 Open-Det이 실제로 Vision-Language alignment를 개선했는지 정량적으로 확인한다.</p>
<p>Open-Det에서 alignment 개선을 담당하는 핵심 모듈은 두 가지이다. 하나는 query-text alignment를 직접 개선하는 <strong>BVLA-M</strong>이고, 다른 하나는 VLM의 image-text knowledge를 VL-prompts로 증류하는 <strong>VLD-M</strong>이다.</p>
<p>논문은 LVIS MiniVal의 50,000개 이상 object instance를 대상으로 GenerateU와 Open-Det의 alignment score를 비교한다. Appendix의 Fig. 8에 따르면, GenerateU의 alignment score는 <code>0.448 ± 0.026</code>인 반면 Open-Det은 <code>0.555 ± 0.074</code>를 기록한다.</p>
<p><strong>이 결과는 Open-Det의 성능 향상이 단순히 detector 구조 개선에서만 나온 것이 아니라, vision query와 text embedding 사이의 정렬 자체가 더 강해졌기 때문임을 보여준다.</strong></p>
<p>또한 Appendix의 Fig. 9에서는 generated text와 ground-truth category name 사이의 similarity도 비교한다. Open-Det은 <code>0.628 ± 0.067</code>, GenerateU는 <code>0.620 ± 0.077</code>을 기록한다. 차이가 아주 크지는 않지만, Open-Det이 생성한 object name이 정답 category와 더 가까운 의미를 가진다는 근거로 볼 수 있다.</p>
<p>즉 4.3의 메시지는 명확하다. BVLA-M은 query-text alignment를 개선하고, VLD-M은 그 alignment 지식을 VL-prompts로 옮겨 LLM이 더 정확한 object name을 생성하도록 돕는다.</p>
<p><strong>Open-Det의 핵심은 box를 더 잘 찾는 것뿐 아니라, 찾은 region을 언어 의미와 더 정확히 연결하는 데 있다.</strong></p>
<hr>
<h2 id="44-visualization-and-analysis">4.4. Visualization and Analysis</h2>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/da9c9ef2-4915-4f74-b35d-82e08047f7c0/image.png" alt=""></p>
<p>4.4에서는 Figure 4를 통해 Open-Det의 정성적 결과를 보여준다.</p>
<p>Figure 4는 LVIS MiniVal 이미지에 대해 Ground Truth, GenerateU, Open-Det의 detection 결과를 비교한다. 논문은 Open-Det이 GenerateU보다 더 다양한 potential object를 탐지하고, 큰 객체뿐 아니라 작은 객체와 세밀한 부분까지 더 잘 잡아낸다고 설명한다.</p>
<p>예를 들어 Figure 4에서는 Open-Det이 <code>cabinet</code>, <code>rug</code>, <code>light</code>, <code>radiator</code>, <code>fireplace</code> 같은 실내 객체뿐 아니라, <code>sidewalk</code>, <code>shadows</code>, <code>street</code>, <code>small sign</code>, <code>sky lift</code>, <code>head</code>, <code>pole</code>, <code>ear</code>, <code>eye</code>, <code>pillow</code> 같은 세밀한 객체나 부분까지 더 풍부하게 탐지하는 모습을 보여준다.</p>
<p><strong>Figure 4의 핵심은 Open-Det이 사전 vocabulary 없이도 이미지 안의 다양한 객체를 더 폭넓게 발견하고 이름 붙일 수 있다는 점이다.</strong></p>
<p>GenerateU와 비교했을 때 Open-Det은 단순히 더 많은 box를 찍는 것이 아니라, 객체 크기와 granularity가 다른 대상까지 더 안정적으로 포착한다. 이는 앞선 Table 1, Table 2에서 보였던 성능 향상이 실제 시각화 결과에서도 드러난다는 의미이다.</p>
<p>결국 Figure 4는 Open-Det이 OED 모델로서 더 실용적인 이유를 직관적으로 보여준다. 추론 시 추가 category prior 없이도 이미지 속 다양한 객체 후보를 발견하고, 이를 자유 형식 이름으로 연결할 수 있기 때문이다.</p>
<hr>
<h2 id="45-limitations-and-future-works">4.5. Limitations and Future Works</h2>
<p>4.5에서는 Open-Det의 한계를 짚는다.</p>
<p>저자들은 Open-Det도 GenerateU와 마찬가지로 cross-modal semantic discrepancy 문제에서 완전히 자유롭지 않다고 말한다. 즉 visual region과 image-like textual embedding 사이에는 여전히 의미적 간극이 존재한다.</p>
<p>이 간극은 하나의 모듈에서만 발생하는 것이 아니다. Backbone, detector, VLM, LLM이 서로 연결되는 과정 전체에서 발생한다. Open-Det은 BVLA-M, VLD-M, MAL, Joint Loss로 이 문제를 줄이지만, 완전히 제거하지는 못한다.</p>
<p><strong>Open-Det의 한계는 결국 OED 자체의 어려움과 연결된다. Region-level visual feature를 free-form language generation으로 안정적으로 변환하는 것은 여전히 어려운 문제이다.</strong></p>
<p>저자들은 향후 개선 방향으로 더 강한 foundation model 사용을 제안한다. 예를 들어 vision backbone으로 InternImage나 Strip-MLP, VLM으로 ALIGN이나 CogVLM, language model로 DeepSeek 같은 모델을 사용할 수 있다고 언급한다. 또한 추가 데이터셋을 활용하는 것도 성능 향상에 도움이 될 수 있다고 본다.</p>
<p>또 하나의 흥미로운 방향은 segmentation decoder를 Open-Det에 통합하는 것이다. Segmentation decoder가 추가되면 mask prior를 통해 더 정밀한 region feature를 얻을 수 있고, 이는 semantic gap을 줄이는 데 도움이 될 수 있다.</p>
<p>즉 Open-Det은 향후 detection과 segmentation을 함께 다루는 unified framework로 확장될 가능성이 있다.</p>
<blockquote>
<p><strong>정리하면, Open-Det은 OED의 학습 효율과 성능을 크게 개선했지만, visual region과 language representation 사이의 의미 간극은 여전히 핵심 과제로 남아 있다.</strong></p>
</blockquote>
<hr>
<h1 id="5-conclusion">5. Conclusion</h1>
<p>이 논문은 Open-Ended Object Detection(OED)을 위한 새로운 generative framework인 <strong>Open-Det</strong>을 제안한다.</p>
<p>Open-Det의 핵심 목표는 명확하다. 기존 GenerateU가 OED를 가능하게 만들었지만, 대규모 데이터와 많은 GPU 자원, 긴 학습 epoch을 요구한다는 한계가 있었다. Open-Det은 이 문제를 해결하기 위해 detector, prompt distiller, object name generator, vision-language aligner를 함께 재설계한다.</p>
<p><strong>Open-Det의 핵심 기여는 OED에서 box detector와 LLM object name generator의 학습을 동시에 가속화했다는 점이다.</strong></p>
<p>Detector 측면에서는 decoupled one-to-many / one-to-one matching 구조를 통해 box localization의 수렴을 빠르게 만든다. Language generation 측면에서는 VLD-M을 통해 VLM의 alignment knowledge를 VL-prompts로 증류하고, 이를 LLM에 전달하여 object name generation을 안정화한다.</p>
<p>또한 BVLA-M은 vision query와 text embedding을 양방향으로 정렬하여 semantic gap을 줄이고, Masked Alignment Loss와 Joint Loss는 학습 과정에서 발생하는 contradictory supervision과 binary classification 불안정을 완화한다.</p>
<p>결국 Open-Det은 단순히 새로운 모듈 하나를 추가한 모델이 아니다. OED 학습 과정에서 발생하는 병목을 단계별로 나누어 해결한 프레임워크이다.</p>
<p><strong>정리하면, Open-Det은 적은 데이터와 적은 학습 자원으로도 vocabulary-free object detection과 free-form object name generation을 더 효율적으로 수행할 수 있음을 보여준다.</strong></p>
<p>실험적으로도 Open-Det은 GenerateU보다 훨씬 적은 데이터와 epoch을 사용하면서 더 높은 성능을 달성한다. 특히 LVIS, COCO, Objects365에서의 zero-shot 결과는 Open-Det이 특정 데이터셋에만 맞춰진 개선이 아니라, OED 설정 전반에서 유효한 구조적 개선임을 보여준다.</p>
<p>물론 한계도 남아 있다. Visual region과 language representation 사이의 semantic gap은 여전히 완전히 해결되지 않았다. 하지만 Open-Det은 이 간극을 줄이기 위한 효과적인 방향을 제시했고, 향후 더 강한 foundation model이나 segmentation decoder와 결합될 경우 detection-segmentation을 아우르는 더 일반적인 open-ended perception framework로 확장될 가능성이 있다.</p>
<p><strong>결론적으로 Open-Det은 OED를 더 실용적인 방향으로 밀어낸 논문이다. GenerateU가 “OED가 가능하다”를 보여준 논문이라면, Open-Det은 “OED를 더 효율적으로 학습할 수 있다”를 보여준 논문이라고 정리할 수 있다.</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰] GenerateU: Generative Region-Language Pretraining for Open-Ended Object Detection]]></title>
            <link>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-GenerateU-Generative-Region-Language-Pretraining-for-Open-Ended-Object-Detection</link>
            <guid>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-GenerateU-Generative-Region-Language-Pretraining-for-Open-Ended-Object-Detection</guid>
            <pubDate>Mon, 06 Jul 2026 07:04:48 GMT</pubDate>
            <description><![CDATA[<p>source: <a href="https://arxiv.org/pdf/2403.10191">Generative Region-Language Pretraining for Open-Ended Object Detection</a></p>
<p>이 논문은 기존 객체 탐지 패러다임을 &#39;미리 정의된 클래스 목록에서 분류하는 것&#39;에서 &#39;이미지 영역에 해당하는 객체 이름을 자유롭게 <strong>생성</strong>하는 것&#39;으로 재정의합니다.</p>
<p>이것은 open-ended를 처음 제시한 논문으로, 거대 언어 모델을 비전 탐지 테스크에 통합하는 효과적인 end-to-end 학습 프레임워크를 제안합니다.</p>
<hr>
<h1 id="abstract">Abstract</h1>
<p>최근 컴퓨터 비전 분야에서는 학습할 때 보지 못했던 새로운 클래스도 임의의 카테고리 이름만 주어지면 Inference시에 검출할 수 있도록 일반화하는 <strong>Open-Vocabulary Object Detection (OVOD)</strong> 가 큰 주목을 받고 있습니다.</p>
<p>그러나 OVOD는 <strong>사전 학습된 VLM을 사용하여 이미지와 임의 카테고리 셋 간의 유사도를 계산하는 방식에 의존</strong>하는데, 이는 Inference시에 여전히 사람이 정의한 클래스 셋을 미리 제공하는 것과 마찬가지이죠.</p>
<p>이 때 저자들이 던지는 의문은 다음과 같습니다.</p>
<blockquote>
<p><strong>*&quot;What if we do not have exact knowledge of object categories during in inference?&quot;*</strong>
<br>사실 이게 현실과 가장 가까운 문제인 것입니다.
이에 저자들은 위 한계 극복을 위해서 기존 OVOD보다 더 일반적이고 실용적인 <strong>&quot;Generative Open-Ended Object Detection&quot;</strong> 이라는 새로운 개념을 세계 최초로 제안합니다.</p>
</blockquote>
<h3 id="generateu">GenerateU</h3>
<p>직관적으로 보자면, 객체 검출을 사전에 정의된 카테고리 매칭이 아닌 텍스트 생성 문제(Generative Problem)으로 재정의합니다.</p>
<p>저자들은 <strong>GenerateU</strong>를 위해 Region Proposal Generator로 <strong>Deformable DETR</strong>를 사용합니다.</p>
<p>규격화되지 않은 자유 형식의 생성 결과물을 정량적으로 측정하기 위해 새로운 평가법 또한 새롭게 도입합니다.</p>
<p>LVIS 데이터셋에서 GenerateU는 추론 할 때 카테고리 이름을 아예 보지 않았음에도 카테고리를 미리 정의하고 사용하는 대표적 OVOD모델인 <strong>GLIP</strong>과 대등한 수준의 <strong>Zero-shot</strong> 검출 성능 또한 보입니다.</p>
<hr>
<h1 id="introduction">Introduction</h1>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/243b4074-48c9-4c27-a365-3c7f92b336ed/image.png" alt=""></p>
<p>전통적인 Object Detection은 단순 Localization+Classification 입니다. 
저자들은 이 과정에서 <code>predetermined</code>라는 단어에 집중하는데, Closed-set에서만 완벽할 뿐, 데이터셋 구축 과정에서 배제된 수많은 객체 앞에서는 무력하다는 것입니다.</p>
<p>이를 위해 대규모로 사전 학습된 VLM, 즉 CLIP 같은 텍스트 인코더의 풍부한 임베딩 공간을 탐지기에 이식하는 시도들이 이어졌습니다.</p>
<p>Image-text pairs를 활용하여 텍스트 레이블과 이미지 영역을 Alignment하는 방식인데, 이러한 기존 OVOD를 저자들은 반쪽짜리 Open이라고 비판합니다.</p>
<ol>
<li><p><strong>사전 지식의 부재</strong></p>
<ul>
<li>임베딩을 계산하려면 Inference시에 검출하고 싶은 카테고리 후보군 리스트를 텍스트로 넣어줘야 합니다. 그런데 실 상황에서는 텍스트 안에 어떠한 객체가 등장할지 알 수는 없지요.</li>
</ul>
</li>
<li><p><strong>언어적 모호성</strong></p>
<ul>
<li>만약 후보군을 대충 정해줘도 언어 자체의 모호성은 발생합니다.</li>
<li>Figure 1을 보면 모델이 하나의 객체를 보고 <code>person</code>, <code>a man</code>, <code>young boy</code> 중 무엇으로 예측할지 사람이 정의한 레이블 셋 안에서 혼선이 생기거나 유연성이 떨어지는 것입니다.</li>
</ul>
</li>
<li><p><strong>비효율적인 확장 비용</strong></p>
<ul>
<li>현실 세계의 모든 객체를 커버하기 위해 수만, 수십만 개의 거대한 라벨 세트를 사람이 직접 만지는 것은 말이 안됩니다.</li>
</ul>
</li>
</ol>
<h2 id="generateu의-등장">GenerateU의 등장</h2>
<blockquote>
<p>Inference 시 미리 정의된 객체 범주를 필요로 하지 않는 open-world dense object detection, </p>
<p>저자들은 Inference 시에 아예 &#39;카테고리 목록&#39; 자체를 지워버리는 <strong>Open-ended</strong> 검출을 하고자 합니다.</p>
</blockquote>
<p>이 문제를 &#39;시각 영역을 언어로 번역하는 생성 문제(Generative Problem)&#39;로 포맷을 바꿉니다.
시스템은 크게 두 가지 핵심 컴포넌트로 결합되어 end-to-end로 동시에 최적화됩니다.</p>
<ul>
<li><strong>Visual Object Detector</strong>: 객체의 Region을 클래스에 구애받지 않고 조밀하게 찾아냅니다.</li>
<li><strong>Language Model</strong>: 추출된 시각적 영역의 특징을 입력받아 인간이 읽을 수 있는 단어로 변환합니다.</li>
</ul>
<p>GenerateU의 지식 확장을 위해서 Human-annotated paired data도 사용하지만, 양이 적기 때문에 <strong>대규모 이미지-텍스트 쌍</strong>을 가져와 어휘 집합을 크게 늘립니다.</p>
<p>하지만 이미지 캡션은 이미지 내의 모든 객체들을 다 적어주지 않는다는 근본적인 한계가 있겠지요?
이미지 안의 모든 객체를 다 언어로 형용할 수는 없으니까요.</p>
<p>이를 위해 저자들은 <strong>pseudo-labeling method</strong>를 도입합니다. </p>
<blockquote>
<h3 id="pseudo-labeling-method는-무엇일까">Pseudo-labeling Method는 무엇일까?</h3>
<p>모델을 학습시킬 때 Unlabeled data를 활용하기 위해, <strong>사전학습 된 모델이 예측한 결과</strong>를 <strong>임시 정답(Pseudo label)</strong> 으로 간주하여 학습에 다시 사용하는 Semi-supervised learning 기법입니다.
<br> 저자들은 논문에서 두 가지 단계의 Pseudo-labeling 과정을 거쳤습니다.
    1. 기존 모델(KOSMOS-2) 기반의 1차 라벨링
    2. GenerateU 기반의 2차 보완
<br>먼저 대규모 이미지-텍스트 쌍 데이터셋을 가져와서 텍스트에 포함된 명사 구절과 이미지 영역을 매칭해주는 기존의 그라운딩 모델을 통과시킵니다. 이를 통해 캡션에 언급된 단어들에 해당하는 bbox(fake label)을 1차로 확보합니다.
<br>이후 1단계만으로 누락된 수많은 객체를 잡기 위해서, 데이터셋(VIsual Genome)으로 학습된 GenerateU를 이 이미지들에 다시 Inference 시킵니다. 모델이 캡션에 없더라도 이미지에서 찾아, 촘촘한 객체 영역과 이름을 추출하고, Confidence score에 따라서 필터링 후 누락된 객체 정답으로 보완하는 것입니다.
<br>이를 통해 데이터셋의 다양성과 포괄성을 높여, 추가 레이블이 모델 성능 향상에 효과적이었음을 Table 6를 통해서도 알 수 있습니다.
<img src="https://velog.velcdn.com/images/jm_mg_se/post/ada35a06-866f-4064-b2de-c4dde940c06f/image.png" alt="">src: <a href="https://arxiv.org/pdf/2211.10039">Why the pseudo label based semi-supervised learning algorithm is effective?</a></p>
<blockquote>
<p>저는 명확하게 와닿지 않아서 다시 한번 쉽게 정리해보려고 합니다..</p>
<p>GenerateU는 학습을 시작하기 전, 아무런 위치 정답이 없는 일반 이미지-텍스트 데이터셋을 가져와서 다음과 같은 과정을 통해 스스로 학습용 정답지(의사 레이블)를 구축합니다.</p>
<h3 id="1단계-명사구-추출">1단계: 명사구 추출</h3>
<p>먼저, 이미지에 딸린 캡션 문장에서 사물이 될 만한 단어들을 NLP로 뽑아냅니다.
<em>(이 NLP는 GenerateU의 일부가 아니라, 전처리 도구임: NLTK나 형태소 분석기를 사용한다고 함.)</em></p>
</blockquote>
</blockquote>
<ul>
<li>예시 캡션: &quot;한 남자가 공원에서 연을 날리며 솜사탕을 먹고 있다.&quot;</li>
<li>추출된 단어: <code>[남자. 공원, 연, 솜사탕]</code><blockquote>
<blockquote>
<h3 id="2단계-이미지-속에서-grounding">2단계: 이미지 속에서 Grounding</h3>
<p>기존에 이미 잘 학습되어 있는 사전학습 그라운딩 모델(Pre-trained Grounding Model)을 데려옵니다. 이 모델에게 이미지와 방금 뽑은 단어들을 던져서, 이미지 안에서 해당 사물들이 있을 법한 바운딩 박스 좌표를 대략적으로 따내게 합니다.</p>
</blockquote>
</blockquote>
</li>
<li>결과: 이미지 내에서 솜사탕이 있는 위치 <code>[X, Y, W, H]</code> 좌표를 찾아냅니다.<blockquote>
<blockquote>
<h3 id="3단계-generateu를-위한-역방향-정답지-완성">3단계: GenerateU를 위한 &#39;역방향 정답지&#39; 완성</h3>
<p>이제 이 두 정보를 합쳐서 의사 레이블(Pseudo-label)을 만듭니다.
여기서 GenerateU만의 독특한 점은, 이 데이터를 <code>[이미지 영역(Region) ➔ 텍스트 단어(Word)]</code>의 형태로 정렬한다는 것입니다.</p>
</blockquote>
</blockquote>
</li>
<li>최종 완성된 의사 레이블 정답지:<blockquote>
<blockquote>
</blockquote>
</blockquote>
</li>
<li>&quot;이 이미지의 <code>[X, Y, W, H]</code> 영역을 크롭해서 모델(언어 디코더)에게 주면, 모델은 반드시 <strong>&#39;솜사탕&#39;</strong>이라는 글자를 타이핑(Generation)해야 한다.&quot;*</li>
</ul>
<p>기존 연구들의 한계를 어떻게 풀어냈는지, 논문에서 말하는 주요 기여들은 다음과 같습니다.</p>
<ul>
<li>Open-ended object detection 이라는 실용적 문제를 정의하고 이를 생성형 모델로 재구성해서 사전 정의 작업에 들어가는 Human-based resources를 제거하였다.</li>
<li>시각 탐지기와 언어 모델을 결합하여 Free-form으로 객체명을 직접 뱉어내는 최초의 End-to-End 프레임워크인 <strong>GenerateU</strong> 를 개발</li>
<li>사전에 카테고리 입력을 받지 않는 극도의 제약조건 속에서도 zero-shot LVIS 벤치마크에서 기존 최고 수준의 OVOD 모델 GLIP과 비등한 성능을 보인다.</li>
</ul>
<p>서론을 정리하기 위해 Figure 1을 다시 한번 살펴봅시다.</p>
<ul>
<li>(a)는 DETR이 영역을 뽑으면 뒤에 Classifier Head가 붙어서 상단의 Text Encoder가 만든 텍스트 임베딩들과 일일이 내적하여 유사도가 가장 높은 클래스를 고르는 구조입니다.</li>
<li>반면 (c)는 Classifier Head를 없애고 DETR의 출력 레이어가 그대로 언어 모델의 Encoder-Decoder로 흘러가 문장을 생성하듯 단어를 한 글자씩 생성하는 구조입니다. 때문에 레이블에 없는 묘사가 가능한 것이죠.</li>
</ul>
<hr>
<h1 id="related-work">Related Work</h1>
<p>저자들이 제안하는 &#39;GenerateU&#39;가 다른 모델들과 비교했을 때 어떤 차별점이 있는지 알아봅시다.</p>
<h2 id="21-open-vocabulary-object-detection">2.1. Open-Vocabulary Object Detection</h2>
<p>기존 연구는 Language Supervision이나 대규모로 사전 학습된 VLM을 탐지기에 이식하려는 시도는 꽤 많았습니다. 이것들은 모델이 학습 과정에서 보지 못한 카테고리까지 일반화하는 것을 목표로 하지요.</p>
<p>하지만 GenerateU는 이미지 영역의 비전 특징과 사람이 미리 정의한 임의 카테고리 이름들 간의 &#39;유사도 계산&#39;을 하는 기존 방식을 벗어나, Inference시에 카테고리 정보가 완전히 Unknown한 시나리오까지 효과적입니다.</p>
<p>추론 시 범주를 미리 정의하는 틀을 깨부순 것이죠.</p>
<h2 id="22-multimodal-large-language-model">2.2. Multimodal Large Language Model</h2>
<p>최근 LLM의 강력한 능력을 활용하여 대규모 이미지-텍스트 pair를 학습한 BLIP-2, LLaMA-Adapter, LLaVA 등의 MLLM 모델이 급부상하였습니다. 나아가 Kosmos-2, UNINEXT, DetGPT 등은 텍스트 설명이나 사용자의 지시사항(Instructions)을 기반으로 bounding box를 제공하는 객체 위치 파악(Localization) 능력까지 확장해 나가고 있지요.</p>
<p><strong>GenerateU는</strong> 기존 MLLM 모델들이 사용자가 입력한 특정 자연어 표현을 참조하는 것을 이해하고 매칭하는 데에 초점이 맞춰진 방식과 달리, <strong>텍스트 입력 없이, 이미지 내에 존재하는 모든 관심 객체들을 스스로 식별하고 클래스 이름 부여까지 하는 것</strong>을 목표로 합니다.</p>
<h2 id="23-dense-captioning">2.3. Dense Captioning</h2>
<p>기존의 Dense Captioning은 이미지의 다양한 국소 영역을 추출하고, RNN 언어 모델 등을 통해 각 영역을 문장 형태로 설명하는 작업인데요, 각 영역을 하나의 개별 이미지처럼 다루며 여러 객체와 그들의 속성(Attributes), 행동 관계까지 포괄하는 문장형 캡션을 생성합니다. 이 때문에 기계 번역 평가에 쓰이는 문장 관점의 METEOR 메릭으로 성능을 평가합니다.</p>
<p><strong>GenerateU는</strong> 관계나 속성이 포함된 &#39;긴 문장&#39;을 뱉어내는 Dense Captioning과 달리 제로샷 환경에서 개별 객체 그 자체를 명확한 &#39;카테고리 이름(단어 혹은 명사구)&#39;으로 정확히 묘사하는 데 집중합니다. 최근 이 두 분야를 결합하려 했던 CapDet나 GRiT 같은 최신 연구들조차 결국 추론 시 사전 정의된 카테고리 공간이 여전히 필요하거나, 닫힌 집합(Closed-set) 문제에만 국한된다는 치명적인 한계가 있었습니다.</p>
<table>
<thead>
<tr>
<th align="center">기술 구분</th>
<th align="center">추론 시 텍스트 힌트 필요</th>
<th align="center">출력 형태</th>
<th align="center">핵심 한계</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><strong>OVOD</strong> (e.g., ViLD, GLIP)</td>
<td align="center">필수 (카테고리 리스트)</td>
<td align="center">선택된 클래스 레이블</td>
<td align="center">실전에서 후보군을 모르면 사용 불가</td>
</tr>
<tr>
<td align="center"><strong>MLLM</strong> (e.g., Kosmos-2)</td>
<td align="center">필수 (사용자 프롬프트 혹은 지시문)</td>
<td align="center">특정 객체의 Box</td>
<td align="center">이미지 내 전수조사 및 Dense Predict 불가</td>
</tr>
<tr>
<td align="center"><strong>Dense Captioning</strong></td>
<td align="center">불필요</td>
<td align="center">관계/속성 포함한 긴 문장</td>
<td align="center">개별 객체의 단치적 카테고리 정밀 묘사 한계 존재</td>
</tr>
<tr>
<td align="center"><strong>GenerateU</strong></td>
<td align="center">아예 불필요</td>
<td align="center">Free-form</td>
<td align="center">없음</td>
</tr>
</tbody></table>
<hr>
<h1 id="3-method">3. Method</h1>
<p>그럼 어떻게 이미지 입력으로부터 사전 정의 카테고리 없이도 Dense하게 영역을 탐지하고 Free-form으로 언어를 <strong>생성</strong>할까요?</p>
<p>GenerateU는 크게 두 가지 요소로 이루어져 있습니다. <strong>Open-world object detector</strong>와, <strong>Language Model</strong>.</p>
<h2 id="31-open-world-object-detection">3.1. Open-World Object Detection</h2>
<p>이미지에서 정확한 객체 영역을 추출하는 것이 중요하겠죠. 이를 위해 저자들은 open-world object detector를 개발합니다. </p>
<p>특정 객체 탐지 모델에 국한되는 것은 아닌데, 저자들은 다음과 같은 이유로 <strong>Deformable DETR를 선택</strong>했다고 해요.</p>
<ul>
<li>다른 One-stage, Two-stage 프레임워크랑 비교했을 때, 휴리스틱을 완화하고, 다용도 쿼리-인스턴스 파이프라인을 제공한다고 합니다.<blockquote>
<p>&#39;휴리스틱&#39;은 경험이나 직관에 기반한, 어느 정도 규칙이나 수동적 설계가 들어간 방법들을 의미합니다. 기존 1-stage, 2-stage 객체 탐지 프레임워크들은 이 휴리스틱한 요소들이 많이 필요했습니다.
<br>반면  Deformable DETR은 이런 수동적인 규칙이나 복잡한 설계 없이도 더 유연하고 효율적인 방식으로 객체를 찾아낸다는 장점이 있습니다.
<br><strong>&#39;휴리스틱을 완화한다&#39;는 건, 모델이 사람의 개입이나 특정 규칙 없이도 스스로 더 잘 학습하고 객체를 탐지할 수 있게 된다는 의미로 이해하면 됩니다.</strong></p>
</blockquote>
</li>
<li>Deformable DETR는 원본 DETR에 비해 더 빠른 수렴 속도와 정학도가 높다고 합니다.</li>
</ul>
<p>Deformable DETR, Original DETR는 <strong>헝가리안 매칭(Hungarian matching)</strong>을 사용하여 예측된 쿼리(query)와 실제 객체(ground truth object) 간의 매핑을 학습하며, 이후 매칭된 객체 쿼리를 분류 손실(classification loss)과 바운딩 박스 회귀 손실(bounding box regression loss)의 조합으로 해당 실제 값에 회귀하도록 훈련합니다.</p>
<p>저자들은 카테고리 정보에 의존하지 않는 <strong>Class-agnostic</strong>한 객체 검출기를 사용한다고 합니다.</p>
<blockquote>
<p><strong>Class-agnostic</strong>에 주의 깊게 봐야합니다.
DETR는 이 단계에서 물체가 <code>사람</code>인지, <code>개</code>인지 보지 않고, 오직 물체가 있을 법한 Dense Regions만 찾아내어 bbox 후보군을 추출하는 것이 핵심입니다.</p>
</blockquote>
<p><strong>손실함수로는 위치를 찾고 전경/배경만 구분하기 위해 BCE Loss, GIoU Loss, L1 Regression Loss 3 가지를 사용한다고 합니다.</strong></p>
<p>$$$
L = L_{bce} + L_{L1} + L_{gIoU} + L_{lm} + L_{align}
$$$</p>
<ul>
<li>탐지 손실($L_{bce}, L_{L1}, L_{gIoU}$):Deformable DET의 표준 손실 함수들</li>
<li><strong>언어 모델링 손실($L_{lm}$)</strong>:생성된 텍스트의 정확도를 높이기 위한 손실이다.$M$개의 탐지된 객체에 대해, 각 객체의 특징 $f_i$가 주어졌을 때, 정답 단어 시퀸스 {$w_1, ..., w_N$}의 음의 로그 우도(negative log likelihood)를 최소화한다.
$$$
L_{lm} = \sum \limits_{i=1}^M(-\sum \limits_{t=1}^N\log P(w_t|f_i, w_1,..., w_{t-1}) )
$$$
<br><br><br></li>
<li><strong>영역-단어 정렬 손실($L_{align}$)</strong>: 시각적 특징 표현의 분별력을 높이기 위한 보조 손실이다. 각 객체 쿼리에 대해, 해당하는 정답 단어를 positive samples로, 미니배치 내 다른 단어들을 negative samples로 간주한다. </li>
</ul>
<p>고정된 CLIP텍스트 인코더를 사용하여 텍스트 특징을 추출하고, 이진 교차 엔트로피 손실을 적용한다.
$$$
L_{align} = \sum \limits_{i=1}^M = [-\log \sigma(s_{ik}) + \sum_{t \in W&#39;}\log (1-\sigma (s_{it}))]
$$$</p>
<ul>
<li>$s_{ik}$: $i$번째 영역 특징과 그에 해당하는 $k$번째 긍정 단어 임베딩 간의 정렬 함수</li>
<li>$W&#39;$: 미니배치 내의 부정 단어 샘플 집합</li>
<li>$\sigma$: 활성화 함수</li>
</ul>
<p>이 손실 함수 구조는 탐지 정확도와 언어 생성 능력을 동시에 최적화하여, 본 연구의 핵심 목표인 생성적 개방형 객체 탐지를 가능하게 한다.</p>
<h2 id="32-transferring-from-a-frozen-multimodal-llm">3.2. Transferring from a Frozen Multimodal LLM</h2>
<p>객체 후보 위치가 파악되면, 훈련 비용을 줄이고 객체 이름 생성을 위한 강력한 zero-shot을 위해 MLLM을 사용하는 것이 자연스럽겠죠.</p>
<p>최근 MLLM은 일반적으로 세 가지 요소로 구성되어 있습니다.</p>
<ul>
<li>시각적 특징을 추출하는 <strong>이미지 인코더</strong></li>
<li>Modality gap을 해소하고 image embedding 수를 줄여 시각적 특징을 토큰으로 표현하는 <strong>Adaptor network</strong>.</li>
<li>시각 중심 태스크에 대한 예측을 생성하는 <strong>언어 모델</strong></li>
</ul>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/d7287c32-6b5b-4594-a0e4-7151c32f823f/image.png" alt=""></p>
<p>Figure 2에서와 같이, object query를 추출하기 위한 frozen image encoder를 가진 <strong>class-agnostic한 Deformable DETR</strong>를 MLLM에 통합합니다.</p>
<blockquote>
<h4 id="object-query">Object query?</h4>
<p>좌표가 아니라 고차원 &#39;숫자 벡터(Embedding Vector)&#39;입니다.
코드나 수식 차원에서 보자면 <code>[N, D]</code>형태의 매트릭스인데요.</p>
</blockquote>
<ul>
<li>$N$: 쿼리의 개수 (보통 100으로 많이들 설정하며, 연구자가 지정한 개수를 따릅니다.)</li>
<li>$D$: 피처 차원의 수 (보통 256 혹은 512)<blockquote>
</blockquote>
즉, 하나의 Object Query는 <code>[0.15, -0.42, 0.89, ...]</code> 같은 256개의 실수(Float) 정보가 담긴 무작위 연속 벡터일 뿐, 그 자체에 <code>[X, Y, 가로, 세로]</code> 같은 물리적인 좌표 정보가 직접 적혀있는 것은 아닙니다.<h4 id="좌표가-아닌데-어떻게-위치를-찾을까요">좌표가 아닌데 어떻게 위치를 찾을까요?</h4>
이 벡터 형태의 쿼리가 <strong>Detection Head(Transformer Decoder) 내부를 통과</strong>하면서 마법이 일어납니다.<blockquote>
</blockquote>
</li>
<li><em>① 1단계: 시각적 단서 탐색 (Cross-Attention)*</em>
이미지 인코더가 뽑아낸 피처 맵(예: <code>[H×W, 256]</code> 크기)과 <code>[100, 256]</code> 크기의 Object Queries가 서로 내적(Dot Product)을 하며 유사도를 계산합니다.
이 과정에서 쿼리 벡터들은 이미지 내부에서 &quot;물체가 있을 법한 강력한 시각적 특징(Edge, 질감 등)&quot;이 있는 위치의 정보들을 자석처럼 흡수하여 쿼리 벡터 내부를 채우게 됩니다.<blockquote>
</blockquote>
</li>
<li><em>② 2단계: 좌표로 변환하는 &#39;통역사&#39; (FFN)*</em>
디코더 레이어를 다 통과하고 나면, 시각 정보를 가득 머금은 <code>[100, 256]</code> 크기의 쿼리 벡터가 나옵니다. 이 벡터를 FFN(Feed-Forward Network) 레이어라는 아주 작은 선형 신경망에 통과시킵니다.</li>
<li>이 FFN이 일종의 &#39;통역사&#39; 역할을 합니다.</li>
<li>256 차원의 복잡한 벡터를 입력받아 <code>[정중앙X, 정중앙Y, 가로길이, 세로길이]</code>라는 딱 4개의 숫자(좌표)로 변환(Projection)해 줍니다.<blockquote>
<blockquote>
<p><strong>그냥 좌표를 쓰면 안되나?</strong>
  만약 처음부터 <code>[X, Y, W, H]</code> 같은 딱딱한 4개의 좌표 숫자로만 입력값을 주면, 이 인공지능 모델이 이미지 백본에서 뽑아낸 수만 가지의 <strong>정교한 시각적 특징(질감, 색상, 맥락 등)과 부드럽게 연산(Attention)을 주고받을 수 없기 때문</strong>입니다.</p>
</blockquote>
</blockquote>
</li>
</ul>
<p>그래서 학습과 연산은 풍부한 &#39;임베딩 벡터&#39; 형태로 진행하고, 최종 결과물을 뱉을 때만 4차원 좌표로 변환하는 방식을 취하는 것입니다.</p>
<p>MLLM을 고정된 상태로 유지하고, 유일하게 훈련 가능한 모듈은 detction head 뿐 입니다.</p>
<p>KOSMOS-2에서는 훈련 중 이미지가 $224 \times 224$로 들어가게 되는데요, 사실 객체 탐지에서는 multi-scale feature extraction을 위해서는 더 큰 사이즈를 사용하는 것이 일반적입니다.</p>
<p>때문에 저자들은 Linear Interpolation을 사용하여 position embedding을 확장합니다.</p>
<blockquote>
<h3 id="linear-interpolation으로-어떻게-pe">Linear Interpolation으로 어떻게 PE?</h3>
<p>알고리즘 내부에서는 &quot;두 점 사이의 비율을 찾는 선형 보간&quot;만 연속적으로 쓰입니다. </p>
</blockquote>
<p>Transformer는 이미치 패치별로 위치를 기억하기 위해 임베딩 벡터를 고유하게 가지지요.
이 때 $14\times 14$격자로 총 $14\times 14 = 196$개의 위치 임베딩 벡터를 미리 학습했습니다.
$\rightarrow$모델은 $(0,0)$부터 $(13, 13)$까지의 격자 좌표만 이해할 수 있습니다.
<Br>우리는 더 Dense한 능력을 위해 $50\times 50 = 2500$개의 위치 임베딩이 필요합니다.
<Br>이 때 기존 $14\times 14$에 있는 고유 벡터값들을 어떻게 $50 \times 50$으로 바꿀까? 가 바로 선형 보간이 해결해야 하는 문제입니다.</p>
<h4 id="1-새로운-좌표를-기존-좌표계로-매핑">1. 새로운 좌표를 기존 좌표계로 매핑</h4>
<p>  새로운 $50 \times 50$ 격자에서 어떤 특정 좌표가 기존 $14 \times 14$ 격자 상에서 비율적으로 어디쯤 위치하는지 역산합니다.</p>
<ul>
<li>예를 들어, 새로운 격자의 정중앙 좌표는 기존 격자에서도 정중앙인 $(6.5, 6.5)$ 위치에 정확히 매핑될 것입니다.<ul>
<li>(새 격자의 정중앙인 $24.5$는 기존 격자 비율로 연산했을 때의 상황입니다.)<ul>
<li>만약 새로운 격자의 어떤 좌표를 역산했더니 기존 격자의 정수 좌표가 아닌 $(2.3, 4.7)$ 같은 소수점 위치로 떨어졌다고 가정해 봅시다.<h4 id="2-주변-4개-정수-좌표의-벡터값-참조">2. 주변 4개 정수 좌표의 벡터값 참조</h4>
기존 $14 \times 14$ 격자에는 정수 좌표에만 학습된 위치 임베딩 벡터가 존재합니다. $(2.3, 4.7)$ 주변을 둘러싸고 있는 가장 가까운 4개의 실제 정수 좌표를 찾습니다.</li>
<li>왼쪽 위: $(2, 4)$의 벡터</li>
<li>오른쪽 위: $(3, 4)$의 벡터</li>
<li>왼쪽 아래: $(2, 5)$의 벡터</li>
<li>오른쪽 아래: $(3, 5)$의 벡터<h4 id="3-거리에-비례하여-가중-평균">3. 거리에 비례하여 가중 평균</h4>
$(2.3, 4.7)$이라는 위치는 $(2, 4)$에 더 가까울까요, $(3, 5)$에 더 가까울까요? 
소수점 자리인 0.3과 0.7이라는 거리를 가중치(Weight)로 삼아 주변 4개 고유 벡터 값을 섞어줍니다.</li>
<li>$(2, 4)$ 벡터에는 더 큰 가중치를 곱하고, 멀리 있는 $(3, 5)$ 벡터에는 작은 가중치를 곱한 뒤 모두 더합니다(Linear combination).
<br>이 과정을 통해 기존 데이터셋에는 존재하지 않던 소수점 위치 $(2.3, 4.7)$에 딱 맞는 &#39;가상의 새로운 위치 임베딩 벡터&#39;가 계산됩니다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<blockquote>
<h2 id="positional-embedding에-대한-해석">Positional Embedding에 대한 해석</h2>
<p><a href="https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Beyond-Labels-Advancing-Open-Vocabulary-Segmentation-With-Vision-Language-Models">Beyond labels 논문 리뷰</a>에서도 사실 PE에 대해서 이야기 한 적이 있습니다.</p>
</blockquote>
<p>그럼, 여기서도 선형 보간 대신, Fourier Feature Embedding, ALiBi 등을 사용하면 어떻게 될지 확인해보겠습니다.</p>
<h3 id="fourier-embedding">Fourier Embedding</h3>
<p>  Linear interpolation은 discrete한 격자 위에서 값을 찢어 늘리는 방식이기 때뭄ㄴ에, 해상도가 바뀔 때 미세한 정보는 왜곡될 수 있습니다. 반면 푸리에 임베딩은 고주파/저주파 성분을 활용했기 때문에 더 부드럽고 정확하게 추정할 수 있지요.</p>
<blockquote>
</blockquote>
<p>  실제로 Original DETR에서도 $x, y$를 표현할 때 Sine/Cosine 기반의 절대적 PE를 사용합니다. 따라서 GenerateU의 비전 탐지기와 결합할 때 Bbox를 잡는 데 더 정교합니다.</p>
<blockquote>
</blockquote>
<p>  <strong>하지만, GenerateU의 사전 학습된 MMLM을 Frozen하고 사용하려면, 기존 모델의 임베딩 레이어를 푸리에 형태로 통째로 갈아야 하므로 호환성이 깨집니다.</strong> 전체 모델을 처음부터 Pre-training하거나 Fine-tuning할 때만 유효한 전략이라고 할 수 있습니다.</p>
<h3 id="alibi">ALiBi</h3>
<p>  포지셔널 임베딩을 입력 토큰에 더해주는 대신, 어텐션 맵(Attention Map)의 쿼리(Query)와 키(Key) 사이의 거리에 비례하여 음수의 페널티(Bias)를 직접 주입하는 방식입니다. 자연어 처리(NLP)에서 엄청난 길이의 문맥 확장(Context Extrapolation)을 가능하게 만든 기술이죠.</p>
<blockquote>
</blockquote>
<p>  선형 보간은 학습 단계에서 보지 못한 &#39;아주 촘촘하고 거대한 격자 공간&#39;이 들어오면 성능이 열화될 위험이 있습니다. 반면 ALiBi 메커니즘을 비전 토큰(Patch 혹은 Object Query)에 맞게 2차원(2D ALiBi)으로 변형해 적용한다면, 모델이 훈련 과정에서 경험해보지 못한 초고해상도 이미지(예: $4K$ 해상도 드론 영상 등)가 들어와도 어텐션 메커니즘이 깨지지 않고 위치 관계를 안정적으로 유지할 수 있습니다.</p>
<blockquote>
<p>하지만 <strong>Dense Detection</strong>에서는 말이 다릅니다.
  ALiBi는 거리가 멀어질수록 관계성을 인위적으로 떨어뜨리는 속성이 있습니다. 객체 검출(특히 Deformable DETR 같은 구조)에서는 이미지 끝과 끝에 있는 물체 간의 글로벌한 맥락(Context)을 파악하거나, 전체 화면을 넓게 보고 객체 쿼리를 매칭하는 능력이 중요합니다. 
  <br>ALiBi의 강한 거리 페널티가 오히려 화면 전반에 걸친 조밀한 객체 예측(Dense Prediction)과 글로벌 컨텍스트 파악을 방해하는 독이 될 수 있습니다.</p>
</blockquote>
<p>  <strong>포지셔널 임베딩이 아예 존재하지 않는 구조가 되기 때문에, 위치 좌표 자체를 쿼리로 다루는 DETR 고유의 쿼리-인스턴스 매칭 파이프라인과 완벽히 충돌할 수 있어 아키텍처를 대대적으로 뜯어고쳐야 합니다.</strong></p>
<p>중요한건,**  이 구조가 단순함에도 불구하고, frozen MMLM을 사용해보니 도메인 불일치로 인해 성능이 저조하였다고 합니다.**</p>
<blockquote>
<p>기존 MMLM을 그대로 얼려두고 오직 Detection Head만 깔짝 가르치기만 해서는, 비전과 언어 사이의 간극을 메울 수 없는 것을 깨달은 과정인 것입니다.</p>
</blockquote>
<h2 id="33-generative-region-language-pretraining">3.3. Generative Region-Language Pretraining</h2>
<p>  따라서, Frozen MMLM을 사용하는 대신, open-world object detector를 언어 모델과 연결하고, 이미지 인코더와 언어 모델을 모두 <strong>trainable</strong>하게 활성화하는 <strong>GenerateU</strong>가 여기서 제안되는 것입니다.</p>
<p>  저자들은 Language Model로 Flan-T5를 사용하였는데, 이는 <strong>Encoder-Decoder</strong>구조 입니다. 텍스트 번역 모델을 상상하면 쉬운데, 번역에서는 인코더에 한국어 문장을 넣고 디코더에서 영어를 출력하는 방식과 유사합니다.</p>
<p>  저자들은 이 구조를 &quot;Vision-text 번역&quot; 매커니즘으로 트랜스포밍했습니다.</p>
<ul>
<li><strong>Encoder Input</strong>: 텍스트 대신 Visual Representation(시각적 영역 특징 벡터)을 입력</li>
<li><strong>Decoder&#39;s Goal</strong>: 그 영역에 알맞은 정답 텍스트 객체명(Associated text)을 단어 토큰 단위로 순차적으로 생성(Generation)해 내도록 만들기</li>
</ul>
<blockquote>
<p><strong>*&quot;Here we only use the object queries that have been successfully matched
with ground truth through Hungarian matching, ignoring the unmatched queries in the generating process.&quot;*</strong></p>
</blockquote>
<p>  여기가 조금 흥미로운데, 먼저 <strong>헝가리안 매칭</strong>이 무엇일까요?</p>
<h3 id="hungarian-matching--query-filtering">Hungarian Matching &amp; Query Filtering</h3>
<p>  Deformable DETR 같은 트랜스포머 기반 탐지기는 이미지에 물체가 몇 개 있든 상관없이, 사전에 설정된 수(이 논문에서는 $N=300$개)만큼의 &#39;Object Query(객체 질문 벡터)&#39;를 무조건 출력합니다.
학습할 때는 이 300개의 예측 박스 중 이미지 속 실제 정답(Ground Truth) 박스와 가장 유사한 것들을 1:1로 짝지어주는 이진 매칭 알고리즘(헝가리안 매칭)을 수행하는 것이죠.</p>
<blockquote>
</blockquote>
<p>  <em>(만약 이미지에 물체가 5개만 있다면? 300개의 쿼리 중 오직 5개만 정답 매칭에 성공(Matched)하고, 나머지 295개는 물체가 없는 배경(Unmatched, $\langle\text{no object}\rangle$)으로 분류됩니다)</em></p>
<blockquote>
</blockquote>
<p>  언어 모델의 Decoder에게 학습을 시킬 때, 물체가 없는 295개의 배경(Unmatched) 쿼리까지 전부 입력해서 텍스트를 만들라고 하면 모델이 심각한 혼선(물체도 없는데 이름을 지어내야 하는 모순)을 겪게 됩니다.</p>
<blockquote>
</blockquote>
<p>따라서 저자들은 헝가리안 매칭을 통과한 뒤, 실제 정답 객체와 매칭되는 데 성공한 똑똑한 쿼리 벡터<strong>(Visual representation)</strong>들만 골라내어 언어 모델 인코더에 집어넣고 , 매칭되지 못한 나머지 배경 쿼리들은 텍스트 생성 과정에서 철저히 무시(Ignoring)해 버리는 방식을 취한 것입니다.</p>
<blockquote>
<blockquote>
<p>이 파트의 핵심은 &quot;DETR이 이미지에서 수많은 박스 후보를 뽑으면(헝가리안 매칭) , 실제 물체가 들어있는 알짜배기 박스의 시각 특징만 쏙 골라내어(Object queries matched) T5 언어 모델의 인코더에 주입하고 , 디코더가 그 물체의 이름을 주관식으로 직접 서술하도록 학습시킨다.&quot;는 의미입니다.</p>
</blockquote>
</blockquote>
<h2 id="34-enrich-label-diversity">3.4. Enrich Label Diversity</h2>
<p>  의미적으로 풍부하고 방대한 탐지 데이터를 수집하는 데 상당한 노력이 투자되었습니다.</p>
<p>  그러나, 계속 반복적으로 말해왔던 문제인, Human-based annotation은 비용이 많이 들고 자원이 제약적이다. </p>
<p>  Kosmos-2 및 CLIP과 같은 이전 연구들은 image-text pair를 활용해서 어휘 규모를 확장했었죠. 이 이전 모델들은 pre-trained grounding model을 활용하여 캡션의 명사구와 정렬된 bbox를 생성합니다.</p>
<blockquote>
<p>Groundming Model 혹은 Visual Grounding 모델은 쉽게 말해 &quot;텍스트(단어, 구절, 문장)가 이미지 안에서 &#39;정확히 어느 영역(위치)&#39;을 가리키는지를 찾아내어 연결(정렬)해 주는 AI 모델&quot;을 의미합니다.</p>
</blockquote>
<p>  이러한 박스들은 차례로 모델 훈련을 위한 <strong>의사 탐지 레이블(Pseudo detection label)</strong>로 활용됩니다.</p>
<p>  그러나, 캡션이 이미지 내의 모든 객체를 포괄적으로 설명하지 못할 수 있어, 캡션의 명사 수는 일반적으로 해당 이미지에 존재하는 실 객체보다는 훨씬 적습니다. <strong>결과적으로 생성되는 의사 레이블의 양은 제한적입니다.</strong></p>
<blockquote>
<p><strong>*&quot;To address this, we use GenerateU pretrained on the available labels to generate
pseudo labels as a supplement for missing objects in images.&quot;*</strong></p>
</blockquote>
<p>  더 나아가, beam search가 자연스럽게 동의어를 생성하며 다양한 객체 레이블을 제공하는 것을 볼 수 있습니다. </p>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/d83b1bff-5aed-48c8-8a77-f9939906537b/image.png" alt=""></p>
<p>  Figure 3를 보면 GenerateU 모델이 제안한 Pseudo-labeling 방법론이 얼마나 다양하고 언어적으로 풍부한 객체들을 많이 만들어내는지 알 수 있습니다.</p>
<p>  그림을 자세히 보면, 흰색 밑줄(캡션 기반)이 쳐진 객체 외에도 수많은 촘촘한 바운딩 박스와 텍스트 레이블들이 이미지 전반을 덮고 있는데, 이것이 바로 저자들이 개발한 GenerateU 모델이 스스로 추론하여 누락된 객체들을 발견한 것입니다.</p>
<p>  우측 상단의 <strong>&#39;Thorntons&#39;</strong> 상점 간판과 같이 모델이 단순 하나의 클래스로 퉁치지 않고, 언어 모델 디코더의 Beam Search를 활성화한 덕분에, 하나의 영역을 두고 풍부한 동의어와 계층적 표현들이 만들어진 것을 볼 수 있습니다.</p>
<hr>
<h1 id="4-experiments">4. Experiments</h1>
<h2 id="41-datasets">4.1. Datasets</h2>
<p>저자들은 GenerateU를 학습시키기 위해 성격이 완전히 다른 두 가지 종류의 데이터를 혼합하는 <strong>Hybrid Supervision</strong> 방식을 사용했습니다.</p>
<ul>
<li><strong>객체 검줄 데이터 (Detection Data</strong>): <strong>Visual Genome (VG)</strong> 데이터셋에서 약 7.7만 장의 이미지를 사용했으며, 존 연구들(CapDet, GRiT 등)과 달리, 문장 형태로 여러 객체와 행동이 섞여 있는 &#39;지역 캡셔닝(Region captioning)&#39; 주석은 철저히 배제했습니다. 오직 하나의 바운딩 박스 영역에 군더더기 없이 딱 맞아떨어지는 간결하고 구체적인 객체 이름(Concise and specific object names)만 골라 탐지기 학습에 활용했습니다.</li>
<li><strong>이미지-텍스트 쌍 데이터 (Image-Text Data)</strong>: COYO700M에서 추출한 약 500만 개의 GRIT 이미지-텍스트 쌍을 활용했습니다. 앞서 우리가 깊게 다루었던 2단계 Pseudo-labeling전략을 통해 누락된 객체 박스와 레이블을 완벽하게 뻥튀기(Scaling up)하여 대규모 어휘집을 확보한 데이터셋입니다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/0f9a2972-145f-4c87-bc86-d839bb3b7036/image.png" alt="">  </p>
<blockquote>
<p>이 표는 LVIS 데이터셋을 학습에 사용하지 않고 제로샷으로 평가한 결과인데, GenerateU는 추론 시 카테고리 이름을 보지 않음에도 불구하고 카테고리 이름을 사용하는 Open-set 모델인 GLIP과 대등한 성능을 보인다.
<br>Swin-Tiny 백본 기준으로 보았을 때, 하이브리드 방식으로 진행한 GenerateU는 <strong>mAP 26.8</strong>을 기록했다. 이는 <strong>GLIP의 mAP 26.0</strong>보다 더 우수한 성적이다. 힌트 아예 없이 Open-ended상태에서 생성한 결과가 이 정도 성적인 것은 엄청난 파장이다.</p>
</blockquote>
<h4 id="ap_r의-급상승">$AP_r$의 급상승</h4>
<p>  VG데이터만 사용했을 때, rare 카테고리 점수($AP_r$)는 17.4이지만, GRIT5M을 추가하니 <strong>20.0</strong>으로 급상승 하였다. 이는 <strong>3.4. Enrich Label Diversity</strong>에서 <strong><em>이미지 텍스트의 풍부한 어휘력이 희귀 객체의 인지 능력을 대폭 올린다</em></strong>라는 가설을 입증한 것이다.</p>
<h4 id="scale-up의-유연성">Scale-up의 유연성</h4>
<p>  백본을 Swin-Large로 키우자 전체 mAP가 27.9까지 올라가며, 완전 지도학습 모델인 MDETR(24.2)을 가볍게 뛰어넘었다. 이는 아키텍처가 커져도 생성 메커니즘이 무너지지 않고 확장성(Scalability)이 훌륭함을 입증한다.</p>
<h2 id="42-evaluation-protocol-and-metrics">4.2. Evaluation protocol and metrics</h2>
<p>  선택지 중에서 고르는 기존 OVOD와는 달리, 지어내어 쓴 단어(Generative Open-Ended)를 어떻게 공정하게 채점할 것인가에 대해 저자들은 혁신적인 평가 모델을 제안합니다.</p>
<ul>
<li><strong>(a) 시맨틱 유사도 매핑 (Similarity Score)</strong>:
예를 들어, 사람이 라벨링한 정답은 laptop인데 모델이 PC나 computer라고 생성했다면 기존 방식에서는 오답 처리됩니다. 저자들은 이를 해결하기 위해 모델 학습에는 전혀 관여하지 않은 오프라인 텍스트 인코더(CLIP 또는 BERT-large)를 가져왔습니다. 모델이 뱉은 단어와 정답 단어의 임베딩 간 유사도를 계산하여, 데이터셋의 사전 정의된 카테고리로 매핑해 준 뒤 일반적인 고정 AP(Average Precision) 점수를 산출해 냈습니다.  </li>
</ul>
<ul>
<li><strong>(b) 텍스트 품질 평가 (METEOR)</strong>:
Dense Captioning에서 주로 쓰이는 자연어 처리(NLP) 평가 메트릭인 METEOR를 도입하여 생성된 단어의 언어적 퀄리티를 다각도로 검증했습니다.  </li>
</ul>
<ul>
<li><strong>벤치마크 타겟</strong>: 1,203개의 방대한 클래스를 가진 LVIS 데이터셋을 타겟으로 삼아, 빈도수에 따라 rare ($AP_r$), common ($AP_c$), frequent ($AP_f$), 그리고 전체 평균 mAP를 쪼개어 정밀 측정했습니다.</li>
</ul>
<h2 id="43-implementation-details">4.3. Implementation Details</h2>
<ul>
<li>*<em>Backbone: *</em>Swin-T, Swin-L for Visual Encoder</li>
<li><strong>Detector</strong>: Deformable DETR (6 encoder layers and 6 decoder layers)<ul>
<li>** Language Model**: Flan T5-base</li>
<li><strong>GPU</strong>: 16 A100 GPUs</li>
<li><strong>frozen MMLM</strong>: KOSMOS-2</li>
</ul>
</li>
</ul>
<table>
<thead>
<tr>
<th align="center">파라미터</th>
<th align="center">값</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Optimizer</td>
<td align="center">AdamW</td>
</tr>
<tr>
<td align="center">Weight Decay</td>
<td align="center">0.05</td>
</tr>
<tr>
<td align="center">Learning Rate (Vision Backbone / Detection Head)</td>
<td align="center">$2 \times 10^{-4}$</td>
</tr>
<tr>
<td align="center">Learning Rate (Language Model)</td>
<td align="center">$3 \times 10^{-4}$</td>
</tr>
<tr>
<td align="center">Object queries $N$</td>
<td align="center">300</td>
</tr>
<tr>
<td align="center">Beam Size</td>
<td align="center">3 (default)</td>
</tr>
</tbody></table>
<h2 id="44-generative-open-ended-detection-results">4.4. Generative Open-Ended Detection Results</h2>
<blockquote>
<p><strong>*&quot;Remarkably, we observe that even with only VG as training data, our model demonstrates commendable performance on zero-shot LVIS. This result suggests that predefined class names might not be necessary for open-world object detection during inference, especially when models are trained with extensive visual concepts.&quot;*</strong>
  <br>타겟 데이터인 LVIS의 정답지 목록을 전혀 제공받지 않았음에도 불구하고, <strong>Visual Genome(VG)</strong>데이터셋의 객체-텍스트 쌍 만으로 학습했을 때에도 zero-shot LVIS에서 $mAP$가 <strong>25.4</strong>가 나온 점이다.</p>
</blockquote>
<p>  기존 비전 모델들이 고정된 Classification Head로 인해 카테고리의 특정 틀 안에 종속되었던 반면, GenerateU는 풍부한 시각적 개념을 얻어 모델의 텍스트 생성 능력과 End-to-End로 연결해둔 덕분에 추론 시 카테고리 목록이 필요 없는 효율성이 입증되었다.</p>
<blockquote>
<p><strong>*&quot;In contrast to open vocabulary object detection methods, we do not need to switch the classifier to the specific category text embeddings.&quot;*</strong></p>
</blockquote>
<p>  기존 OVOD 모델들은 새로운 데이터셋(예: COCO)을 테스트하려면, 그 데이터셋이 가진 클래스 명칭들을 다시 텍스트 인코더에 넣어 새로운 &#39;분류기 가중치 행렬(Classifier text embeddings)&#39;을 동적으로 생성해 교체해 주어야 했다.</p>
<blockquote>
</blockquote>
<p>  하지만 GenerateU는 주관식 모델이므로 데이터셋이 바뀌어도 그 어떤 아키텍처 수정이나 분류기 교체 작업 없이(Without requiring any modifications) 그냥 이미지만 밀어 넣으면 즉시 작동합니다</p>
<h2 id="45-ablation-study">4.5. Ablation Study</h2>
<p>  <img src="https://velog.velcdn.com/images/jm_mg_se/post/56e8adf9-3579-47c3-9a5e-ca1cb9041c49/image.png" alt="">
  저자들은 기존 MMLM을 활용하는 방식과 GenerateU의 학습법을 비교하였다.</p>
<ul>
<li><p><strong>Init from MMLM (KOSMOS-2 기반)</strong></p>
<ul>
<li>이미지 인코더와 언어 모델을 모두 <strong>Freeze</strong>하고, Detection Head만 학습했을 때, <strong>전체 mAP 14.3</strong><ul>
<li>이미지 인코더만 Train: <strong>mAP가 21.9로 상승</strong></li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Init from LLM (FlanT5-base 기반 - GenerateU)</strong></p>
<ul>
<li>이미지 인코더, 탐지 헤드, 언어 모델을 전부 열어두고 통째로 학습(Train)시키는 엔드투엔드 정공법을 썼을 때: mAP 26.8 ($AP_r$ 20.0)로 최고 성능을 달성</li>
</ul>
</li>
</ul>
<h3 id="beam-search">Beam Search</h3>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/4c88f8f6-98d1-4331-bd16-4a64c84fb4d0/image.png" alt=""></p>
<p>  언어 모델이 단어를 생성할 때 얼마나 많은 후보군을 고려할지 결정하는 하이퍼파라미터인 Beam Size에 따른 성능 그래프이다. </p>
<ul>
<li>빔 사이즈가 1일 때는 희귀 객체 점수가 12.3으로 매우 낮았다.</li>
<li>빔 사이즈를 2, 3으로 키워나감에 따라 $AP_r$점수가 <strong>17.2</strong> $\rightarrow$ <strong>20.0</strong>으로 상승한다.<blockquote>
<p>빔 서치를 적용하면 단어 디코딩 과정에서 다채로운 동의어(Synonyms)와 계층적 단어 표현들이 함께 탐색 된다. </p>
</blockquote>
이 유연성 덕분에 데이터셋에서 자주 등장하지 않는 롱테일(Long-tail) 및 희귀 카테고리($AP_r$)의 텍스트 생성 정확도가 비약적으로 향상되는 효과를 낳았다. 저자들은 가성비가 가장 좋은 3을 기본 빔 사이즈 세팅으로 채택했다.</li>
</ul>
<h3 id="region-word-alignment">Region-word Alignment</h3>
<p>  <img src="https://velog.velcdn.com/images/jm_mg_se/post/8a93a650-c269-4b6b-bbb1-e4094b43152d/image.png" alt=""></p>
<p>  <strong>위에서 다룬 영역-단어 정렬 손실($L_{align}$)</strong>의 유무에 따른 성능 차이 비교 테이블이다.</p>
<ul>
<li><p>VG 데이터 셋팅:</p>
<ul>
<li>$L_{align}$ 없이 탐지 손실과 언어 생성 손실만 썼을 때: mAP 22.5</li>
</ul>
</li>
<li><p>$L_{align}$을 추가했을 때: mAP 25.4 (+2.90 수직 상승). 특히 흔한 객체($AP_c$) 점수가 19.1에서 22.4로 +3.90이나 대폭 올랐습니다.</p>
<blockquote>
<p><strong>핵심 인사이트</strong>: T5 언어 모델의 디코더 6개 레이어마다 얼어있는 CLIP 텍스트 임베딩을 매칭시켜 주는 보조 감독(Auxiliary supervision) 장치가 , 모델이 시각적 특징과 언어적 표현 간의 기초 체력(Alignment)을 다지는 데 강력한 부스터 역할을 수행했음을 입증한다.</p>
</blockquote>
</li>
</ul>
<h2 id="46-qualitative-resutls">4.6. Qualitative Resutls</h2>
<p>  <img src="https://velog.velcdn.com/images/jm_mg_se/post/e0f204ba-7b85-4b95-9364-9b85e970ba21/image.png" alt="">
  수치적인 mAP 점수만으로는 GenerateU가 고정된 어휘 제한을 뛰어넘는 능력을 온전히 설명할 수는 없다. </p>
<blockquote>
<p><strong>*&quot;As shown in Figure 5, our model can identify a more diverse range of objects compared to ground truth annotations. These visualizations not only affirm the reliability of our detection framework but also demonstrate its ability to detect a wider variety of objects, providing valuable insights into the model’s strengths.&quot;*</strong></p>
</blockquote>
<p>  Human-based GT는 사람이 직접 라벨링하여 필연적으로 누락된 객체가 많다. 반면 GenrateU는 정답에 묶여있지 않기 때문에, 오히려 Human-based GT보다 더 Dense한 식별이 가능하다.</p>
<hr>
<h1 id="5-conclusion">5. Conclusion</h1>
<p>  GenerateU는 객체 검출을 사전에 정의된 카테고리 매칭이 아닌, &#39;자율 서술형 텍스트 생성 작업&#39;으로 재구성하여 패러다임을 바꾸었다. 이를 통해 사람이 추론 단계에서 일일이 클래스 후보 목록을 주어야 했던 제약을 소거한 것이다.</p>
<p>  카테고리 이름을 아예 보지 못한 극도의 제약 속에서도 zero-shot LVIS 환경에서 기존 최고 수준의 Open-vocabulary, GLIP과 대등한 성능을 보이며, 생성형 오픈월드 시나리오의 실용성을 다진 것이다.</p>
<p>  <img src="https://velog.velcdn.com/images/jm_mg_se/post/6dc9ffe7-e245-48cb-91da-f65ed04d30ee/image.png" alt=""></p>
<p>  저자들은 MS의 Kosmos-2와 GenerateU를 가혹한 실험 환경 속에서 비교를 진행했다.</p>
<ul>
<li><p>상황 A (기본 배치): 책상 위에 휴대폰(Mobile phone)과 컵(Cup)이 서로 완전히 분리되어 따로따로 놓여 있습니다.</p>
<p>이 상황에서는 Kosmos-2와 GenerateU 모두 두 객체의 위치와 이름을 잘 식별한다.</p>
</li>
<li><p>상황 B(복잡한 배치): 사물의 배치를 바꾸어, 상황 A (기본 배치): 책상 위에 휴대폰(Mobile phone)과 컵(Cup)이 서로 완전히 분리되어 따로따로 놓여 있다.</p>
<blockquote>
<p>컵이 휴대폰 위에 겹쳐서 놓이는 가혹한 환경으로 변경되면 성능의 차이가 확연히 드러난다.</p>
</blockquote>
<p>이 상황에서 마이크로소프트의 Kosmos-2는 실제 시각 데이터보다 텍스트 문맥의 통계적 확률에 지나치게 의존한 나머지 휴대폰을 노트북(Laptop)으로 오독하는 치명적인 문맥 기반 오류를 범힌디. </p>
<blockquote>
</blockquote>
<p>반면 GenerateU는 텍스트 디코딩 전에 클래스 무관 탐지기(Class-agnostic Deformable DETR)를 통해 순수한 픽셀 영역 단위의 시각 특징을 견고하게 추출하기 때문에, 사물의 배치가 기괴하게 꼬이더라도 언어 모델의 뇌피셜에 휘둘리지 않고 두 객체를 끝까지 정확하고 일관되게 식별해 내는 뛰어난 물리적 강인성을 증명한다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰] VL-SAM: Training-Free Open-Ended Object Detection and Segmentation via Attention as Prompts]]></title>
            <link>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-VL-SAM-Training-Free-Open-Ended-Object-Detection-and-Segmentation-via-Attention-as-Prompts</link>
            <guid>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-VL-SAM-Training-Free-Open-Ended-Object-Detection-and-Segmentation-via-Attention-as-Prompts</guid>
            <pubDate>Sat, 04 Jul 2026 05:17:53 GMT</pubDate>
            <description><![CDATA[<p>source: <a href="https://arxiv.org/abs/2410.05963">Training-Free Open-Ended Object Detectino and Segmentation via Attention as Prompts</a></p>
<p>이 논문은 일반적인 <strong>open-set perception</strong>보다 더 빡센 문제를 잡습니다. 기존 open-set detection이나 segmentation은 <strong>unseen object</strong>를 다루긴 하지만, inference 시에 여전히 category 이름이 필요하기 때문이죠.</p>
<h1 id="abstract">Abstract</h1>
<p>현실에서는 어떠한 물체가 있을지 미리 모르는 경우가 많기 때문에 꽤 중요한 문제로 여겨집니다.</p>
<p>여기서 논문이 잡는 문제가 바로 <strong>Open-ended object detection</strong>입니다. 특히 중요한 조건은 </p>
<blockquote>
<p><strong>&quot;without any object categories as inputs&quot;</strong></p>
</blockquote>
<p>이라는 겁니다. 즉, <strong>텍스트 프롬프트로 <code>car</code>, <code>dog</code>, <code>chair</code>,를 찾아줘~</strong> 라고 주지 않아도 이미지 안의 미지의 객체를 찾아야 하는겁니다.</p>
<h3 id="제안-방법">제안 방법</h3>
<p>VL-SAM은 <strong>*&quot;Training-Free Framework&quot;*</strong> 입니다. 새로 학습하지 않고, 강력한 두 모델을 연결하는 겁니다.</p>
<p>잠시 <strong>*&quot;Training-Free&quot;*</strong>란 무엇인지 살펴봅시다.</p>
<blockquote>
<h3 id="training-free">Training-Free?</h3>
<p><strong>*&quot;Training-Free Framework&quot;*</strong>는 VL-SAM 자체를 새로 학습하지 않는다는 뜻입니다.
조금 더 자세히 말하자면,</p>
</blockquote>
<ul>
<li>VLM을 예로, CLIP류 모델의 가중치를 업데이트 하지 않는다.</li>
<li>SAM의 가중치도 업데이트 하지 않는다.</li>
<li>LVIS나 CODA 같은 detection/segmentation 데이터셋으로 fine-tuning하지 않는다.</li>
<li>Loss function, optimizer, backpropagation 없이 Inference 단계의 알고리즘만으로 동작한다.
<br>즉, VL-SAM은 pre-trianed VLM과 pre-trained SAM을 가져와서 그 사이를 <strong>Attention Map 기반 prompt generation</strong>으로 연결하는 방식입니다.<blockquote>
<blockquote>
<p><strong>아무 학습도 안 된 모델</strong>로 오해하지 말기 
VLM과 SAM은 이미 대규모 데이터로 pre-trained 되어 있는데, 여기서 제안하는 파이프라인 자체는 추가 학습을 하지 않는다는 점이니, <em>&#39;아무 학습도 되지 않은 것&#39;</em>과 혼동하지 맙시다.</p>
</blockquote>
</blockquote>
</li>
</ul>
<p>다시 돌아와서 <strong>강력한 두 모델</strong>에 대해서 알아봅시다.</p>
<ol>
<li><strong>VLM: Vision-Language Model</strong> 로 객체를 인식하거나 의미적으로 주목하는 능력을 가지고 있습니다.</li>
<li><strong>SAM: Segment Anything Model</strong> 로 점, 박스 같은 prompt가 주어졌을 때 객체 영역을 잘 자르는 능력을 가지고 있습니다.</li>
</ol>
<p>논문의 핵심 아이디어는 둘 사이를 <strong>&quot;attention maps as the prompts&quot;</strong> 로 연결하는 것입니다.
VLM의 Attention map을 보면 모델이 이미지의 어디를 중요하게 보고 있는지 알 수 있고, 여기서 pos/neg point를 뽑아 SAM에 넣습니다. 그러면 SAM이 해당 객체를 segmentation mask로 뽑아내는 구조인 것입니다.</p>
<h3 id="기술적-포인트">기술적 포인트</h3>
<p>Abstract가 말하는 VL-SAM은 두 가지 모듈이 중요합니다.</p>
<p><strong>첫째</strong>, <strong>Attention map generation module</strong>입니다. 단순히 한 layer나 한 head의 attention만 쓰는 것이 아닌, head aggregation 과 regularized attention flow를 사용하여 VLM의 여러 head/layer에 흩어진 attention 정보를 모으는 것입니다.</p>
<p><strong>Attentino map generation module</strong>은 더 안정적이고 객체에 더 잘 맞는 Attention map을 얻는 데에 목적이 있습니다.</p>
<p><br><strong>둘째, Prompt generation module</strong>입니다. attention map에서 pos/neg point를 반복적으로 샘플링하여 SAM에 전달하는데, SAM이 이 점들을 기반으로 대응되는 object mask를 만드는 것입니다.</p>
<p>그럼, 위 내용들을 기반으로 논문을 더 중점적으로 리뷰해보겠습니다.</p>
<hr>
<h1 id="introduction">Introduction</h1>
<p>먼저 딥러닝 기반 perception 모델이 자율주행 같은 실제 응용에서 크게 성공하였습니다. 다만, 그 성공은 대량의 labeled data가 있음에 가능했던 것인데, 이는 <strong>모델은 학습 데이터 안에서 본 객체들을 인식하고 위치를 잡는 데에 강하다는 것</strong>입니다.</p>
<p>문제는 현실 세계가 학습 데이터보다 훨씬 더 크다는 것입니다. </p>
<h4 id="문제-의식">문제 의식</h4>
<p>기존 detector/segmenter는 closed-world assumption에 기반합니다. 즉, 세상에 나올 객체 종류가 학습 데이터와 label set 안에 있다고 가정하는 것이죠.</p>
<p>물론 현실은 다릅니다.</p>
<h3 id="open-world-perception의-등장">Open-world Perception의 등장</h3>
<p>때문에 open-world perception 방법들이 등장하였습니다. 이들은 &#39;새로운 객체&#39;나 &#39;도메인 변화&#39;가 있는 환경에서도 perception을 하려는 흐름인데, 논문에서는 이를 크게 두 가지로 나눕니다.
<br><strong>&quot;open-set &amp; open-ended&quot;</strong></p>
<p>이 둘의 차이가 매우 중요한데, <strong>Open-set</strong>은 학습 때 보지 못한 객체도 다루려 하지만, inference 시점에 여전히 어떤 category 후보들을 넣어줘야 하는 경우가 많습니다. </p>
<p>예를 들어 CLIP 기반 방법은 이미지 영역과 테스트 category name 사이의 similarity를 계산하는데, 이는 <code>dog</code>, <code>traffic cone</code>, <code>box</code>, <code>animal</code>과 같은 텍스트 후보가 있어야 한다는 뜻입니다.</p>
<p>그래서 논문은 open-set 방법들이 <strong>&quot;predefined object categories&quot;</strong> 를 필요로 한다고 지적합니다. 이게 바로 VL-SAM이 해결하려는 문제입니다.</p>
<h3 id="generic-obstacle-detection도-충분하지-않다">Generic obstacle detection도 충분하지 않다.</h3>
<p>그렇다면 그냥 &quot;unknown obstacle detection&quot; 이라고 하면 어떨까요? 일부 방법은 모르는 객체를 generic obstacle로 잡으려 하지만, 모든 위험 요소가 뚜렷한 3D shape을 가지는 것은 아닙니다.</p>
<p>예를 들어 도로의 pit, 바닥의 grains 같은 것들이 있겠죠.</p>
<p>그래서 논문은 open-set 방법이 모든 상황을 처리하기 어렵다고 봅니다.</p>
<h3 id="open-ended가-필요한-이유">open-ended가 필요한 이유</h3>
<p>여기서 open-ended method가 등장합니다.
논문은 open-ended 방법이 <strong>*&quot;more general and practical&quot;*</strong> 하다고 말합니다. 바로 category와 location을 모델이 스스로 예측하기 때문이죠.</p>
<blockquote>
<h4 id="정리해봅시다">정리해봅시다.</h4>
<p>Open-set detection은 &quot;이미지에서 dog, car, cone 중 뭐가 있는가?&quot;에 가깝고
<br><strong>Open-ended detection</strong>은 &quot;이 이미지에 무엇이 있는지 찾아서 말하고, 위치까지 잡아봐&quot;에 가까운 것입니다.
<br>VL-SAM이 다루는 것은 후자로, 단순 unseen class detection이 아닌, <strong>카테고리 입력 없이 객체 발견 및 segmentation까지 하는 것</strong>이 핵심입니다.</p>
</blockquote>
<h3 id="samsegment-anyting-model의-등장">SAM(Segment Anyting Model)의 등장</h3>
<p>VLM은 특정 perception 모델보다 정확도가 떨어지고, 때로는 객체를 놓치거나 정답이 아닌 위치를 파악하곤 합니다. 하지만 SAM은 순수 비전 모델로, 다양한 도메인에서 우수한 일반화 성능을 보이죠.</p>
<p>그렇다고 SAM을 마냥 좋다고만 할 수는 없습니다. 분할된 객체에 대해서 무엇인지 카테고리 이름을 제공하지 못하고, 때로는 무관한 영역까지 분할하는 경향이 있습니다.</p>
<h3 id="논문의-제안-vl-sam-프레임워크">논문의 제안: VL-SAM 프레임워크</h3>
<p>논문은 VLM의 인식과 SAM의 정밀 위치 추정 능력을 결합하여 <strong>Open-Ended Object Detection and Segmentation</strong>을 해결하고자 합니다.</p>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/e1582d31-f016-4341-b71d-5f1760463902/image.png" alt=""></p>
<p>별도의 추가 학습은 필요하지 않는 <strong>Training-Free</strong> 방식으로, Attention Map을 중간 프롬프트로 사용하여 두 모델을 연결하는 방식입니다. 자율주행 도메인에서는 VLM이 생성하는 어텐션 맵으로 SAM의 분할을 프롬프팅 하는 것이죠.</p>
<p>더 자세한 과정은 다음과 같습니다.</p>
<ol>
<li><strong>VLM의 역할</strong>: VLM이 이미지를 보고 이미지 전체에 대한 설명을 생성하며, 다양한 객체들의 이름을 알려준다.</li>
<li><strong>어텐션 맵 생성</strong>: VLM이 특정 객체에 해당하는 어텐션 맵을 만든다.<ul>
<li>VLM의 여러 레이어와 헤드에서 나온 어텐션 정보를 <strong>헤드 통합</strong>과 <strong>정규화된 어텐션 flow</strong> 매커니즘으로 사용하여 고품질의 어텐션 맵으로 생성</li>
</ul>
</li>
<li><strong>프롬프트 생성</strong>: 어텐션 맵은 특정 객체의 위치와 중요도를 나타내는데, 가장 높은 값의 영역에서 <strong>positive point</strong>를 샘플링, 활성화가 낮은 영역에서는 <strong>negative point</strong>를 샘플링</li>
<li><strong>SAM으로 전달</strong>: 샘플링된 <strong>긍/부정 point pair</strong>가 SAM의 입력 프롬프트로 들어간다.<ul>
<li>SAM은 받은 포인트들로 정확한 분할 마스크 생성<blockquote>
<p><strong>결론적으로, VLM의 강점인 객체 인식 및 범주화 능력과 SAM의 정교한 분할 능력</strong>을 어텐션 맵으로 연결하여 학습 없이도 객체 분할이 가능한 것이다.
<br><em>누락되는 객체의 수를 줄이기 위해 SAM의 분할 결과를 사용하여 어텐션 맵에서 양성 및 음성 점을 수렴할 때까지 반복적으로 샘플링한다.</em></p>
</blockquote>
</li>
</ul>
</li>
</ol>
<hr>
<h1 id="related-work">Related work</h1>
<p>Related work은 빠르게 알아보고, <strong>3. Method</strong>로 넘어가봅시다.</p>
<h2 id="21-vision-language-model-vlm">2.1 Vision Language Model (VLM)</h2>
<p>LLM은 인간과 유사한 대화, 추론 능력은 보여주는 반면, 시각적인 처리는 한계가 많았습니다.</p>
<p>이를 극복하기 위해 VLM이 도입되어 새로운 응용 분야가 발전되어가고 있습니다.
대표적으로 LLaVA, BLIP-2와 같이 이미지 임베딩과 텍스트 임베딩을 정렬하고 융합하는 모델들이 등장했습니다.</p>
<p>하지만 기존 VLM 모델들은 SAM과 같은 특정 지각 모델(객체의 정확한 위치를 잡는다는 등..)보다는 성능이 떨어집니다.</p>
<p>때문에 본 논문에서 VLM에 일반화된 분할 모델, 즉 SAM을 사용하여 <strong>open-ended object detection 및 segmentation</strong> 을 위한 VLM의 지역화 한계를 해결하는 방법을 제안합니다.</p>
<h2 id="22-open-world-object-detection-and-segmentation">2.2 Open-World Object Detection and Segmentation</h2>
<p>CLIP의 등장과 함께 open-world 연구는 크게 두 가지 유형으로 분류됩니다.</p>
<p><strong>바로 open-set과, open-ended</strong>.</p>
<p><strong>Open-set</strong>은 추론 중에 훈련 세트에서 본 객체와 보지 못한 객체를 포함하여 재정의된 객체 범주를 입력으로 주어져야 합니다. 그와 대조적으로 <strong>Open-ended</strong>은 현재 VLM이 하는 것처럼 본 객체와 보지 못한 객체를 찾고 이름을 생성하는 것이죠.</p>
<p>텍스트로만 보면 헷갈릴 수 있으니, 표로 정리해서 확인해봅시다.</p>
<table>
<thead>
<tr>
<th align="center">개념</th>
<th align="center">Inference: Unseen 탐지 여부</th>
<th align="center">Inference시 입력 형태</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Closed-set</td>
<td align="center">불가능</td>
<td align="center">없음 (정해진 레이블 출력)</td>
</tr>
<tr>
<td align="center">Open-set</td>
<td align="center">가능</td>
<td align="center">사람이 미리 정의한 단어 목록</td>
</tr>
<tr>
<td align="center">Open-ended</td>
<td align="center">가능</td>
<td align="center">아무것도 주지 않음</td>
</tr>
</tbody></table>
<p>Open-set의 한계는 자율주행 등에서와 같이 사전에 정의하기 어려운 객체가 많아 실용성이 떨어진다는 단점이 있습니다.</p>
<p>Open-ended는 대규모 데이터셋 구축과 함께 네트워크 전체를 파인튜닝 해야하므로 막대한 비용이 드는 단점이 있습니다.</p>
<p><strong>본 연구는 VL-SAM으로, 대규모 데이터 학습 없이, 이미 잘 학습된 VLM과 SAM을 어텐션 맵으로 단순 결합하여 학습 비용이 없는(Training-free) 방식이니, 기존의 Open-ended문제를 해결</strong>합니다.</p>
<hr>
<h1 id="3-method">3. Method</h1>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/990db4f8-3a26-484e-85ab-5b0355287956/image.png" alt=""></p>
<p><strong>핵심은 바로 VLM의 어텐션 맵을 SAM의 포인트 프롬프트로 변환하는 것</strong>입니다.</p>
<h2 id="31-preliminary">3.1 Preliminary</h2>
<p>본격적인 Method를 살펴보기 전, 베이스라인 두 모델에 대해 다시 알아봅시다.</p>
<p><strong>1. SAM</strong></p>
<ul>
<li><p>구성: Image Encoder, Prompt Encoder, Mask Decoder</p>
</li>
<li><p><strong>매커니즘</strong></p>
<ul>
<li><p>이미지를 입력받아 Feature 추출, Point나 Box로 받은 프롬프트를 Prompt Encoder가 토큰으로 변환</p>
<ul>
<li>Mask Decoder 안에서 이 두 정보가 Two-way 트랜스포머로 상호작용하며 최종 분할 마스크 생성</li>
</ul>
<blockquote>
<h3 id="two-way-transformer"><strong>Two way transformer?</strong></h3>
<p>Two way transformer는 SAM의 <strong>Mask Decoder</strong> 내부의 동작 매커니즘입니다.
Image Features와 Prompt Tokens가 서로를 참조하여 양방향으로 Attention을 수행하기 때문에 붙은 이름입니다.
<br>일반적인 트랜스포머 디코더가 한쪽 방향으로 정보를 가져오는 것과 달리, SAM의 양방향 트랜스포머는 다음과 같은 형태로 상호작용합니다.</p>
</blockquote>
<h3 id="two-way-transformer의-두-가지-핵심">Two-way Transformer의 두 가지 핵심</h3>
</li>
<li><p><em>1. Prompt-to-Image Attention (Prompt가 이미지 참조)*</em></p>
<ul>
<li><strong>프롬프트 토큰이 Query</strong>, SAM Decoder가 뽑은 <strong>이미지 특징이 Key, Value</strong>가 된다.<ul>
<li>이를 통해 &quot;내가 찍은 이 점/프롬프트 가 이미지의 어떤 시각적 특징들과 연관이 되어있는지&quot;를 계산하여 프롬프트 정보를 업데이트한다.</li>
</ul>
</li>
<li><em>2. Image-to-Prompt Attention (이미지가 프롬프트 참조)*</em>
이미지 특징이 Query, 프롬프트 토큰이 Key, Value가 된다.</li>
<li>이를 통해 &quot;이미지의 각 픽셀들은 프롬프트와 얼마나 가까운 관계인지&quot; 계산하여 이미지 특징을 프롬프트 성향에 맞게 업데이트한다.
<br><strong>이를 통해 포인트 프롬프트 토큰이 이미지 전반의 기하학적 특징과 융합되어 최종적으로 매우 정밀한 객체 분할 마스킹이 가능한 것</strong>이다.<blockquote>
<blockquote>
<p>여러 정보를 섞는 것처럼 보여서 Self-Attention을 많이 하는거랑 차이가 뭐지? 싶지만, 
Self-Attention을 더 많이 하는 것과 SAM의 양방향 트랜스포머는 <strong>&quot;Q, K, V&quot;를 어디서 가져오느냐&quot;와 &quot;연산의 목적&quot;</strong>에서 결정적인 차이가 있습니다.</p>
<p>트랜스포머의 일반적인 Self-Attention은 <strong>하나의 데이터 소스</strong>에서 자기들끼리 연산하는 것입니다.</p>
<h3 id="sam의-양방향-트랜스포머-두-사람이-주고받는-대화">SAM의 양방향 트랜스포머 (두 사람이 주고받는 대화)</h3>
<p>반면, SAM의 <strong>Two-way Transformer</strong>는 이미지와 프롬프트가 서로 다른 두 개의 소스를 Cross-Attention 기법으로 번갈아 엮어주는 것입니다.</p>
<p>단순 한쪽이 일방적으로 참조하는 것이 아니라, 블록 내부에서 아래의 두 단계를 거치며 양방향으로 소통합니다.</p>
</blockquote>
</blockquote>
<h4 id="1방향-prompt-to-image-attention-2방향image-to-prompt-attention-수행">1방향: Prompt-to-Image Attention, 2방향:Image-to-Prompt Attention 수행</h4>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><strong>2. Auto-Regressive Based VLM</strong></p>
<ul>
<li><strong>구성</strong>: Image Encoder, Text Tokenizer, Projection Layers, Language Decoder</li>
<li><strong>매커니즘</strong><ul>
<li>이미지와 텍스트 토큰을 하나의 임베딩 공간으로 정렬, 합쳐서 Language Decoder에 넣기</li>
<li>Language Decoder는 <strong>Next-token prediction</strong>패러다임을 따르기 때문에, 현재 생성하는 단어 $x_t$는 이전에 생성된 모든 단어들 $(x_1, x_2, ..., x_{t-1})$에 의존한다.</li>
</ul>
</li>
</ul>
<h2 id="32-attention-map-generation">3.2 Attention Map Generation</h2>
<p>VL-SAM의 주요 아이디어는 <strong>객체의 어텐션 맵을 SAM이 분할하기 위한 프롬프트로 사용하는 것</strong>이라고 말했습니다.</p>
<p>이에 따라 고품질 어텐션 맵을 생성하는 것이 매우 중요한데요,
단순히 마지막 레이어의 어텐션을 가져다 쓰면 성능이 나오지 않아, 저자들은 두 가지 장치를 도입합니다.</p>
<h3 id="method-1-head-aggregation">Method 1. Head Aggregation</h3>
<p>VLM 디코더 내부에 수많은 트랜스포머 레이어($L$)와 헤드($H$)가 존재합니다. </p>
<p>Query와 Key를 곱하고 Casual Mask와 SoftMax를 적용하여 4차원 유사도 행렬 $S \in N \times N \times H \times L$을 얻습니다.</p>
<blockquote>
<p><strong>*&quot;During this process, we cache all queries and keys from VLM. THen, we multiply quries and keys with casual masks and SoftMax normalization to obtain similarity matrix $S \in N \times N \times H \times L$&quot;*</strong>
<br>여기서 <strong>cache</strong>한다... 이게 무엇일까요?
<br>단순 곱하는 것이 아닌, VLM의 트랜스포머 레이어들에서 생성된 <strong>쿼리와 키 벡터들을 메모리에 저장한다는 뜻</strong>입니다. 그럼, 일반적인 트랜스포머나 VLM은 저장을 하지 않는걸까요?
<br><strong>아닙니다. 일반적으로 KV Cache를 통해 저장합니다. 하지만 이 논문에서 캐시한다는 것과 일반적인 VLM모델들이 기본적으로 처리하는 방식에는 꼭 짚고 넘어가야 할 결정적인 차이가 있습니다.</strong></p>
</blockquote>
<h3 id="일반적인-vlm의-kv-cache와의-차이점">일반적인 VLM의 KV Cache와의 차이점</h3>
<p>일반적인 VLM은 문장을 생성할 때, <strong>연산의 중복을 피하기 위해</strong> Key와 Value만 캐시 합니다. 그리고 Query는 매 스텝 계산 이후 버려지는 것이죠.
<br>저자들은 나중에 특정 단어(예: &#39;pothole&#39;)가 이미지의 어느 위치에 있었는지 역추적하기 위해, 생성 단계가 다 끝난 후에도 과거에 발생했던 모든 스텝의 Query(쿼리)와 Key(키) 행렬 전체를 메모리에 명시적으로 붙잡아 두고(Cache) 활용합니다. <strong>즉, 일반적인 VLM이 필요 없어서 버리는 Query 벡터까지 싹 다 긁어모아 거대한 행렬 $S$를 구성하는 것</strong>입니다.</p>
<blockquote>
<blockquote>
<p>Transformer Attention에서 &quot;어디를 봤는가&quot;는 Q, K로 결정되고, &quot;보고 나서 무엇을 가져왔는가&quot;는 V로 결정됩니다. VL-SAM은 위치 힌트가 필요하니까 Q, K 또는 QK로 만든 Attention Weight를 봅니다. </p>
</blockquote>
</blockquote>
<ul>
<li>Q, K : Attention Weight를 만든다.</li>
<li>Attention Weight: 어디를 얼마나 봤는지 알려준다.</li>
<li>V: Attention Weight에 따라 실제 정보를 가져온다.</li>
<li>VL-SAM: 위치 prompt가 필요하므로 Attention Weight만 사용한다.</li>
</ul>
<p>각 헤드마다 중요도가 다르니, 저자들은 <strong>Mean-Max Attention Head Weights ($W$)를 계산</strong>합니다.
$$$
V = \text{Mean}(\text{Max}(S, dim=-1), dim=0)
$$$
위 식이 바로 어떤 헤드가 더 중요한지 가중치를 매기는 과정입니다.
$$$
S&#39; = \text{Mean}(S \odot W, dim=2)
$$$</p>
<p>Figure 3의 하단에는 개별 헤드 어텐션 맵들에 방금 구한 가중치를 각 곱하는 모습인데, 
이 가중치 $W$를 오리지날 유사도 행렬 $S$에 point-wise로 곱한 뒤 헤드 차원에 대해 평균을 내어 헤드 정보가 통합된 $S&#39;$를 얻습니다.
<img src="https://velog.velcdn.com/images/jm_mg_se/post/776a4f08-0545-41e7-8cda-8ad2c7af079c/image.png" alt=""></p>
<h3 id="attention-flow--attention-collapse-방지">Attention Flow &amp; Attention Collapse 방지</h3>
<p>하나의 레이어 정보만 쓰는 것이 아닌, 첫 번째 레이어부터 마지막 레이어까지 어텐션이 어떻게 흘러가는지 <strong>누적</strong>하기 위해 <strong>Attention Rollout</strong>방식을 사용합니다.</p>
<p>$$$
\bar {S&#39;}^l_{i, j} = \sum \limits_{k=1}^N (I_{i,k} + {S&#39;}^l_{i, k}) \times (I_{k, j} + \bar {S&#39;}^l_{k, j})
$$$</p>
<p>Figure 4를 보면 레이어 1의 결과($S&#39;^1$)가 레이어 2($S&#39;^2$)로 넘어가고, 이것이 최종 레이어 $L$까지 연속적으로 곱해지며 전파되는 흐름입니다.</p>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/beb65121-7810-42bf-8cea-fec758819670/image.png" alt=""></p>
<ul>
<li>VLM은 미래의 단어를 보지 못하게 막는 Casual Mask를 사용합니다. 이로 인해 Attention Rollout을 그냥 사용하면 어텐션 값이 첫 부분(Top-left corner)으로 과도하게 몰려 뭉개지는 Attention Collapse가 발생합니다. (<em>Figure 5 참고</em>)</li>
</ul>
<p>이에 따라 저자들은 <strong>Regularization Term</strong>을 하나 도입합니다.
마스킹 되지 않은 열의 길이를 $L_0$라고 할 때, 해당 열의 모든 값에 $1- \frac{(L_0 - 1)}{ L}$을 곱해줍니다. 이 덕분에 좌상단으로 어텐션이 몰리는 것을 방지하는 것이죠.</p>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/29ae5fe9-52e1-46af-9fbf-343d933eade5/image.png" alt=""></p>
<h2 id="33-sam-prompt-generation">3.3 SAM Prompt Generation</h2>
<p>정규화된 고품질 어텐션 맵을 얻긴 했지만, 여전히 FP 노이즈 픽셀들이 존재합니다.</p>
<p>이를 없애기 위해, 아래 과정을 거쳐 SAM용 포인트를 뽑습니다.</p>
<p><strong>1. Threshold Filtering:</strong> </p>
<ul>
<li>값이 너무 약하게 활성화된 영역을 쳐냅니다.</li>
</ul>
<p><strong>2. Maximum Connectivity Area 추출</strong></p>
<ul>
<li>필터링 후 남은 영역 중 가장 크게 뭉친 덩어리를 Positive Area로 지정하고, 나머지를 Negative Area로 봅니다. (PA: 객체, NA: 배경) </li>
</ul>
<p><strong>3. 포인트 샘플링</strong>: </p>
<ul>
<li>Positive Area에서 어텐션 값이 가장 강한 지점을 <strong>Positive Point</strong>, Negative Area에서 어텐션 값이 가장 약한 지점은 <strong>Negative Point</strong>로 샘플링하여 SAM에 입력할 프롬프트 한 쌍을 완성합니다.</li>
</ul>
<blockquote>
<h3 id="헷갈리지-않게-주의">헷갈리지 않게 주의</h3>
<p><strong>Positive Area는 binary 영역</strong>이고, <strong>Positive Point는 그 안의 원래 Attention 값 기준 peak 입니다.</strong></p>
</blockquote>
<pre><code>0.02 0.03 0.05 0.04
0.10 0.45 0.62 0.51
0.08 0.58 0.91 0.67
0.03 0.39 0.48 0.41</code></pre><p>이 <code>pothole</code> Attention Map이라고 해봅시다.
threshold를 <code>0.4</code>로 잡으면 </p>
<pre><code>0 0 0 0
0 1 1 1
0 1 1 1
0 0 1 1</code></pre><p>인데 이 binary connected component가 Positive Area입니다.
그런데 Positive Area 안의 원래 Attention 값은 여전히 다릅니다.
1에 해당하는 영역들 중 가장 높은 값인 <code>0.91</code>이 바로 Positive Point 입니다.</p>
<h2 id="34-iterative-refinement">3.4 Iterative Refinement</h2>
<p>여전히 SAM이 한 번에 완벽한 마스크를 만들지 못하고 경계선이 흐릿하거나 배경 노이즈를 포함할 수 있습니다.</p>
<p>저자들은 이를 위해 두 가지 <strong>Iterative</strong> 전략을 사용합니다.</p>
<ul>
<li><strong>전략 1(PerSAM 방식)</strong>: SAM이 출력한 대략적 마스크를 다음 루프 때 SAM디코더의 추가 프롬프트 입력으로 다시 넣어 정밀도를 올립니다.</li>
<li><strong>전략 2(Attention Map Update)</strong>: 생성된 분할 마스크를 이용하여 기존 어텐션 맵 $\overline{S&#39;}$를 마스킹합니다. 그리고 그 마스킹된 어텐션 맵에서 다시 3.3의 방식으로 PP, NP를 뽑아 SAM에게 전달합니다. 이 과정을 수렴할 때까지 반복한 후 NMS(Non-Maximum Suppression)으로 병합합니다.</li>
</ul>
<blockquote>
<p>사실 저는 Figure 2의 이 부분이 많이 헷갈렸는데요.
초기 단계와 이후 반복 단계로 나누어 흐름을 한 번 정리해봤습니다.</p>
</blockquote>
<pre><code class="language-text">Attention Map
-&gt; SAM Prompt Generation
-&gt; positive/negative point
-&gt; SAM Decoder
-&gt; Initial mask M0</code></pre>
<p>여기까지가 바로 <strong>초기 예측, <code>i=0</code></strong>입니다.
이 때 입력은</p>
<pre><code class="language-text">attn_map = original_object_attention_map
points = sample_pos_neg(attn_map)
mask_0 = SAM(points)</code></pre>
<p>그런데, <code>mask_0</code>이 완벽하지 않을 수 있어서 SAM Decoder output이 다시 refinement로 들어가는겁니다.</p>
<blockquote>
</blockquote>
<p><strong>전략 1 (PerSAM)방식</strong>으로 cascaded post-refinement를 쓰는 겁니다.
Pos/neg point로 만든 mask를 다시 SAM Decoder에 <strong>additional mask prompt</strong>로 넣는거죠. 설명은 위와 똑같습니다. 여기서는 그냥 <strong>처음 잡은 객체의 mask품질을 다듬을 뿐</strong>입니다.
쉽게 말해, Original Attention Map에서 point sampling하여 SAM에 넣어 Initial Mask를 얻는겁니다.</p>
<blockquote>
</blockquote>
<p>이제 점선의 Iterative Refinement를 보겠습니다.
짧게 말해서 이건 이전 mask로 Attention map을 조정하고, 다시 point sampling 하여 SAM 에 넣고 new/refined mask를 얻는 것입니다. 
<strong>SAM Decoder가 만든 mask가 최종 결과로 바로 끝나는게 아니라 다시 Attention Map / Prompt Generation 단계에 영향을 주고, 그 결과 새 Point Prompt가 SAM으로 들어가는 겁니다.</strong></p>
<h2 id="34--36-ensembles">3.4 &amp; 3.6 Ensembles</h2>
<ul>
<li><strong>Multi-scale Ensemble</strong>: VLM은 보통 $490 \times 490$ 같은 저해상도 이미지를 입력받아, 작은 객체를 잘 놓칩니다. 이를 위해 이미지를 4개의 코너로 쪼개어 각 VL-SAM을 돌린 뒤, 원본 이미지 결과와 합칩니다.</li>
<li><strong>Question-prompt Ensemble</strong>: VLM은 프롬프트에 민감하므로, VLM에게 질문 리스트를 먼저 뽑게 한 뒤, 그 질문 리스트 프롬프트로 각 VL-SAM을 실행하여 결과를 대규모로 앙상블하는 방법입니다.<blockquote>
<p><strong>이 모델의 핵심 파이프라인은 결국 VLM내부의 Attention Matrix 가공에 있습니다. VLM 소스코드를 열어서 특정 토큰의 <code>Query</code>, <code>Key</code> 행렬을 캐싱하고, Casual Mask 연산 및 정규화 방법을 텐서 연산으로 구현하는 부분이 핵심 난이도로 보입니다.</strong></p>
</blockquote>
</li>
</ul>
<blockquote>
<h2 id="how-to-design-prompt">How to design Prompt?</h2>
<p><strong>VL-SAM의 프롬프트 디자인</strong>은 추가 학습 없이 거대 멀티모달 모델(VLM)의 인식 능력과 SAM의 Localization 능력을 연결하는 이 논문의 핵심이기 때문에 본 파트에서 정리를 해보겠습니다.</p>
</blockquote>
<p>VL-SAM의 프롬프트 디자인은 크게 <strong>1)VLM을 자극하는 입력용 질문 프롬프트 디자인, 2)VLM의 출력 가공하여 SAM의 힌트로 넣는 Point 프롬프트 디자인</strong>으로 구성되어 있습니다.</p>
<blockquote>
<h3 id="vlm의-입력-단계question-prompt-ensemble">VLM의 입력 단계:Question-Prompt Ensemble</h3>
<p>VLM은 입력되는 질문 텍스트의 뉘앙스에 따라 출력하는 문장과 내부 어텐션 맵의 퀄리티가 크게 요동치는 민감성을 가집니다. 저자들은 이 문제를 해결하기 위해 <strong>VLM</strong>이 가장 선호하는 질문 <strong>10</strong>개를 스스로 생성하게 만드는 앙상블 전략을 취한 것입니다.</p>
</blockquote>
<h4 id="동작-흐름">동작 흐름</h4>
<blockquote>
<ol>
<li>질문 생성 요청: 먼저 VLM에게 Meta-prompt를 입력합니다.
 &quot;if we want you to list all possible objects in the given image, what questions should we ask? Please give 10 questions you prefer.&quot;</li>
</ol>
</blockquote>
<ol start="2">
<li>질문 리스트업: VLM은 이 요청을 받고 이미지의 문맥을 가장 잘 이끄는 10개의 커스텀 질문을 스스로 뱉습니다.<ul>
<li>e.g., &quot;Do you see any obstacle on the road?&quot;, &quot;What does the sign says?&quot; etc<blockquote>
</blockquote>
</li>
</ul>
</li>
<li><strong>병렬 쿼리 및 태그 파싱</strong>: 이 10개의 질문을 각각 독립적으로 VLM에 통과시켜서 도로 환경에 대한 풍부한 서술 문장을 얻은 뒤, 문장에서 명사 형태의 객체 태그(e.g., <code>pothole</code>, <code>car</code> )들을 파싱하여 타깃 객체로 선정합니다.<blockquote>
<blockquote>
<p>그럼 VLM에서 나온 Answer는 어떻게 사용되는걸까요?</p>
<h3 id="vlm에서-나온-answer">VLM에서 나온 Answer</h3>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/aeaefa3d-2dfe-49f5-b7e0-4f256af186a2/image.png" alt=""></p>
</blockquote>
</blockquote>
</li>
</ol>
<p><strong>Attention Map을 추출하기 위한 Query로 사용됩니다.</strong></p>
<blockquote>
<blockquote>
<ul>
<li>VLM이 답변 문장을 생성하는 도중, <strong>타깃 단어인 <code>pothole</code>에 해당하는 토큰이 생성되는 바로 그 스텝을 정확히 포착</strong>합니다.</li>
<li>이 <code>pothole</code> 토큰의 임베딩 값을 <strong>Query</strong>로 삼아 VLM 디코더 내부에 캐싱되어 있던 이미지 패트 토큰들의 <strong>Key</strong> 행렬과 행렬 곱 연산을 수행합니다.</li>
<li>이 연산을 통해 &quot;VLM이 문장 안에서 &#39;pothole&#39;이라는 단어를 뱉는 그 순간에, 이미지의 어느 픽셀들을 집중해서 쳐다보고 있었는지&quot;를 역추적하여 선명한 어텐션 맵으로 형상화할 수 있게 됩니다.<blockquote>
<p>참고로 이건 <strong>양방향 어텐션이 아니라</strong> 트랜스포머 디코더 내부의 일반적인 &#39;<strong>Casual Self-Attention</strong>의 연산 기록을 사후에 활용한 것입니다.</p>
</blockquote>
</li>
</ul>
</blockquote>
<h3 id="2-sam-입력-단계-정규화된-어텐션-기반-point-prompt-design">2. SAM 입력 단계: 정규화된 어텐션 기반 Point Prompt Design</h3>
<p>VLM이 특정 단어(e.g., <code>pothole</code> )를 생성할 때 내부에서 발생한 Query-Key 어텐션 행렬을 수학적으로 정제하여, SAM이 즉각적으로 이해할 수 있는 <strong>Positive Point</strong>와 <strong>Negative Point</strong>의 좌표 쌍으로 변환하는 핵심입니다.</p>
</blockquote>
<h4 id="1인과적-마스크에-따른-어텐션-붕괴-해결">1)인과적 마스크에 따른 어텐션 붕괴 해결</h4>
<p>단순 VLM의 마지막 레이어 어텐션을 쓰면 정보가 유실됩니다.
저자들은 전 층의 어텐션을 누적하여 전파하는 <strong>Attention Rollout</strong>을 사용한다고 했었죠.
하지만 VLM은 뒤의 단어를 보지 못하게 막는 인과적 마스크 (Casual Mask)를 쓰기 때문에, 레이어를 거칠 때마다 어텐션 가중치가 마스크의 시작점인 좌상단 구석으로 터져버리는 어텐션 붕괴가 발생합니다.</p>
<blockquote>
</blockquote>
<p>이를 제어하기 위해 저자들은 어텐션 플로우 전파 시 다음과 같은 <strong>강력한 정규화 프롬프트 가중치를 행렬에 직접 연산</strong>해 줍니다.</p>
<ul>
<li>마스킹 되지 않은 열의 유효 길이를 $L_0$, 전체 레이어 길이를 $L$라고 할 때, 해당 열의 모든 어텐션 값에 아래 가중치를 Pointwise 곱해 강제로 좌상단 쏠림을 억제합니다.<blockquote>
<p>$$$
\text{Weight} = 1- \frac{(L_0 - 1)}{ L}
$$$
이 정규화 처리를 거치고 나면, 이미지 패치 해상도($35 \times 35$)크기의 선명하고 노이즈가 억제된 타깃 객체 어텐션 맵 한 장이 완성됩니다.</p>
</blockquote>
<h4 id="2-최대-연결-영역-기반-긍정부정-점-샘플링-positivenegative-pair-sampling">2) 최대 연결 영역 기반 긍정/부정 점 샘플링 (Positive/Negative Pair Sampling)</h4>
정규화된 어텐션 맵을 원본 해상도 크기로 Interpolate 한 후, 기하학적 필터링을 통해 SAM 프롬프트용 최종 좌표를 추출합니다. </li>
<li><strong>Positive Area (객체 영역) 디자인</strong>: 어텐션 맵에서 약하게 활성화된 노이즈 영역을 제거하기 위해 특정 임계값으로 필터링을 칩니다. 그 후 남은 활성화 픽셀들 중 가장 크게 뭉쳐있는 덩어리인 최대 연결 영역(Maximum Connectivity Area)을 추출하여 이를 객체가 존재하는 &#39;Positive Area&#39;로 정의합니다.</li>
</ul>
<hr>
<h1 id="4-experiments">4. Experiments</h1>
<p>이번에는 기존 Open-set이나 Open-ended 모델들과 비교하여 얼마나 뛰어난지, 각 모듈별 역할을 잘 하는지 알아봅시다.</p>
<h2 id="41-implementation-details">4.1 Implementation Details</h2>
<p>사용된 두 가지 베이스라인 모델에 대해서 알아봅시다.</p>
<h3 id="vlm-baseline">VLM baseline</h3>
<p><strong>CogVLM-17B</strong>(EVA2-CLIP-E 이미지 인코더 + Vicuna-7B-v1.5 언어 디코더 결합)를 사용했습니다.
이미지는 $490 \times 490$ 해상도로 입력되고, $35\times 35$ 패치 사이즈 토큰으로 쪼개집니다.</p>
<p>문장 생성 시에는 텍스트 다양성을 조절하는 Temperature가 0.8, Nucleus sampling($top_p$)는 0.1 셋팅값입니다.</p>
<h3 id="sam-baseline">SAM baseline</h3>
<p>가장 체급이 크고 성능도 좋은 <strong>SAM ViT-Huge</strong>를 사용했습니다.</p>
<p>텍스트 맵핑은 VLM이 생성한 자유로운 문장에서 객체 이름을 파싱한 뒤, CLIP 텍스트 인코더로 데이터셋이 정의한 카테고리와 유사도를 계산하여 맵핑하는 구조입니다.</p>
<blockquote>
<p>*&quot;All models are infered on an 80G A800 machine.&quot;*</p>
</blockquote>
<h2 id="42-main-results">4.2 Main Results</h2>
<h3 id="lvis-dataset-결과">LVIS Dataset 결과</h3>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/58802510-8585-45a3-acfa-6c8ca54a4650/image.png" alt="">
VL-SAM은 대형 롱테일 데이터셋인 LVIS minival에서 희귀 객체 탐지 성능 $23.4\ AP_{rare}$를 기록하며, 기존 오픈엔디드 모델인 GenerateU($20.0$)를 3.4 포인트 차이로 가볍게 제쳤습니다.</p>
<p>GenerateU는 대규모 데이터셋으로 모델 전체를 무겁게 파인튜닝해야 하고 박스(Box)만 칠 수 있는 반면, VL-SAM은 추가 학습이 전혀 없는(Training-free) 상태에서 박스와 고품질 마스크(Mask)를 동시에 따낼 수 있음을 증명했습니다. 사전에 단어 목록을 쥐여주어야 하는 오픈셋(Open-Set) 모델들과 비교해도 꿀리지 않는 강력한 경쟁력을 보여줍니다.</p>
<h3 id="coda-dataset-결과">CODA Dataset 결과</h3>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/3b38237b-88fb-48cc-937c-5e9edd3da0b2/image.png" alt="">
자율주행 중 예외 상황을 다루는 CODA 벤치마크에서 기존 오픈셋 및 오픈엔디드 최고 모델들(12.6∼18.4 mAR)을 아득히 압도하며 $40.1\ \text{mAR}$이라는 압도적인 성적을 거두었습니다.</p>
<p>정답 박스를 SAM에 바로 찔러 넣었을 때의 하드웨어적 한계 상한선(Oracle) 성능이 $54.1\ \text{mAR}$인데, VL-SAM은 학습을 단 한 번도 안 하고도 이 상한선의 74.1% 수준까지 도달했습니다. </p>
<p>실제 도로 위의 위험한 미지 객체(싱크홀, 파편 등)를 잡아내는 데 있어 실용성이 엄청나다는 방증입니다.</p>
<h2 id="43-ablation-study">4.3 Ablation Study</h2>
<h3 id="main-components">Main Components</h3>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/17d36e47-9bcd-45df-ad76-74ec46b5fe3a/image.png" alt="">
VLM 마지막 층의 평균 어텐션만 쓰는 Naive 베이스라인은 앙상블을 발라도 성능이 처참하지만, 제안한 <strong>어텐션 생성 모듈(Attn Generation)을 붙이는 순간 mAR이 7.9 급상승</strong>합니다. 점 프롬프트 샘플링과 반복 정제를 추가할 때마다 각각 2.2 mAR, 1.8 mAR씩 복리로 상승합니다.</p>
<p>논문에서 제안한 각 파이프라인 단계(어텐션 정제 $\rightarrow$ 포인트 추출 $\rightarrow$ 반복 루프)가 독립적으로 작동하는 꼼수가 아니라, 성능 향상에 유기적이고 실질적인 기여를 하고 있음을 정량적으로 입증했습니다. 멀티스케일 등 앙상블 기법도 이 기본 모듈들이 받쳐줘야 제 성능을 냅니다.</p>
<h3 id="attention-generation">Attention Generation</h3>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/f66cd216-cdfe-4423-b7b2-38bd3608aa3d/image.png" alt=""></p>
<p>정규화 항 없이 단순한 기존 Attention Flow(rollout) 기법을 쓰면 Causal Mask로 인한 어텐션 붕괴가 발생해 mAR이 0.1로 수직 낙하하지만, 저자들의 핵심 치트키인 <strong>정규화(Regularization)를 먹이자마자 8.5 mAR로 기사회생</strong>합니다. 헤드 가중치(Head Weight)까지 버무리면 10.1 mAR로 정점을 찍습니다.</p>
<h3 id="model-generalization">Model Generalization</h3>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/468c6b9b-d6dd-4b6d-b37b-4dddf8dec6ee/image.png" alt="">
VLM 뼈대를 MiniGPT-4나 LLaVA로 바꾸고, SAM을 경량화 모델인 MobileSAM으로 교체해도, 모든 조합이 기존 최고 오픈엔디드 성능(18.4 mAR)을 가뿐히 상회합니다.</p>
<p>VL-SAM 프레임워크가 특정 아키텍처(CogVLM이나 SAM-Huge)에만 종속된 종속적 결과가 아니라, &quot;어떠한 VLM과 SAM을 플러그앤플레이(Plug-and-Play) 형태로 가져다 꽂아도 구조적으로 무조건 작동하는 강력한 범용 프레임워크&quot;임을 증명했습니다. 향후 더 강력한 VLM이나 경량 SAM이 나오면 학습 없이 그대로 갈아 끼워 성능을 더 올릴 수 있다는 오픈 아키텍처로서의 가치를 보여줍니다.</p>
<blockquote>
<h2 id="종합-결론">종합 결론</h2>
<p>본 연구의 핵심은 VLM의 인식 능력과 SAM의 분할 능력을 어텐션 맵의 중간 매개체로 활용하여 학습 없이 연결하는 것입니다. 
<br>이 연구 모형은 다음과 같은 방식으로 정리할 수 있겠습니다.
<br><strong>1. VLM의 인식 + SAM의 분할</strong>: LVIS 및 CODA 데이터셋에서 VL-SAM이 기존의 개방형 방법들을 능가하는 성능을 보인 것은, VLM이 객체 범주를 식별하고 SAM이 해당 객체를 정확히 분할하는 상호 보완적인 역할이 성공적으로 결합되었음을 의미합니다. 
<br>특히, SAM이 범주 정보를 제공하지 못하는 한계는 VLM의 언어 이해 능력으로 보완되고, VLM의 약한 위치 파악 능력은 SAM의 정교한 분할 능력으로 극복됩니다.
<br><strong>2. 어텐션 맵의 역할</strong>: §3에서 제안된 어텐션 맵 생성 모듈(헤드 통합, 정규화된 어텐션 흐름)은 어텐션 붕괴를 방지하고 고품질의 어텐션 맵을 생성하여 SAM 프롬프트의 효과를 극대화했지요. 
table 4에서 정규화된 어텐션 흐름이 mAR을 크게 향상시킨 것은 이 모듈이 VLM의 내부 작동을 활용하여 SAM에 의미 있는 지시를 제공하는 데 결정적이었음을 보여줍니다.
<br><strong>3. 반복적 개선 및 앙상블</strong>: §3의 반복적 개선 파이프라인과 다중 스케일/질문 프롬프트 앙상블 전략은 table 3의 절제 연구를 통해 각 요소가 성능 향상에 기여함을 알 수 있습니다. 
<br>이는 초기 어텐션 맵의 불확실성을 줄이고, 분할 결과를 정제하며, VLM의 프롬프트 민감도를 완화하여 모델의 견고성과 정확도를 높이는 데 필수적인 구성 요소임을 증명하는 것이죠.
<br><strong>결론적으로, VL-SAM은 VLM과 SAM의 개별적 한계를 극복하고, 학습 없이 Open-ended 객체 탐지 및 분할이라는 복합적 문제를 효과적으로 해결하는 통합 프레임워크를 입증한 것입니다.</strong></p>
<blockquote>
<h3 id="근데-vlm이-scene묘사를-하는-것도-결국엔-vlm이-해당-카테고리들을-제공-받아서-훈련한-것-아닌가">근데 VLM이 scene묘사를 하는 것도 결국엔 VLM이 해당 카테고리들을 제공 받아서 훈련한 것 아닌가?</h3>
<p>맞다. 근본적으로 들어가면 VLM이 학습데이터에 수많은 카테고리와 단어들을 학습한 것은 맞다.
하지만, <strong>Open-ended Object Detection 분야에서 &#39;카테고리 셋을 제공한다/안 한다&#39;라고 표현할 때는, 그 모델의 &#39;Pre-training(사전학습)&#39; 단계가 아니라 &#39;Inference(테스트/추론)&#39; 단계를 기준</strong>으로 이야기한다는 것에 주의하자.</p>
</blockquote>
</blockquote>
<blockquote>
<h3 id="한계점">한계점</h3>
<h4 id="vlm의-hallucination">VLM의 Hallucination</h4>
<p>VL-SAM은 VLM과 SAM의 결합 구조이기 때문에, VLM이 가진 고질적인 문제인 환각 문제를 그대로 받습니다. 때문에 VL-SAM도 잘못된 객체 토큰이나 어텐션 맵을 생성할 수 있는 것이죠.</p>
</blockquote>
<h4 id="posneg-point-sampling의-민감도">Pos/Neg point sampling의 민감도</h4>
<p>어텐션 맵에서 긍부정 포인트 샘플링을 하는 방식은 어텐션 맵의 품질과 임계값 설정에 크게 흔들립니다.
이 샘플링 전략의 견고성과 다양한 조건에서의 성능에 대한 추가적인 분석이나 대안적 샘플링 전략에 대한 탐색은 아직 부족합니다.</p>
<h3 id="향후-연구-방향">향후 연구 방향</h3>
<h4 id="sam의-변형-모델">SAM의 변형 모델</h4>
<p>추론 속도 문제를 SAM의 변형 모델(EfficientSAM, MobileSAM 등)을 통해 해결할 수 있습니다.
<br>또한 VLM 환각 문제를 완화하기 위한 새로운 전략의 탐색 필요성 또한 대두되는 문제입니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰] CLIP: Learning Transferable Visual Models From Natural Language Supervision]]></title>
            <link>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-CLIP-Learning-Transferable-Visual-Models-From-Natural-Language-Supervision</link>
            <guid>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-CLIP-Learning-Transferable-Visual-Models-From-Natural-Language-Supervision</guid>
            <pubDate>Wed, 01 Jul 2026 09:22:31 GMT</pubDate>
            <description><![CDATA[<p>Resource: <a href="https://arxiv.org/abs/2103.00020">Learning Transferable Visual Models From Natual Language Supervision</a></p>
<p>Vision과 Langauge를 결합한 모델, OVOD를 위해서라면 매우 자세한 분석이 필요한, 해당 Task의 근간이 되는 모델이다. </p>
<p>본 포스트에서는 하나하나 자세히 파해쳐보며 CLIP을 이해하려고 한다.</p>
<p>때문에 이번 리뷰는 조금 길고 양이 많아질 수 있다.</p>
<hr>
<h1 id="abstract">Abstract</h1>
<p>저자들은 SOTA vision system이 보통 <code>a fixed set of predetermined object categories</code>를 예측하도록 학습된다고 말한다. 즉, ImageNet처럼 미리 정해진 라벨 집합 내에서만 분류하는 방식이다.</p>
<p>이 방식은 문제가 있는데, 새로운 개념을 인식하려면 매번 추가 라벨링 데이터가 필요하다는 것이다. </p>
<p>구현 관점에서 보면 기존 supervised classifier는 <strong>마지막 classification Head가 특정 클래스 수에 묶여 있다.</strong> </p>
<p>CLIP의 대안은 이미지를 사람이 붙인 고정 클래스 라벨이 아니라, 웹에 자연스럽게 존재하는 텍스트와 함께 학습한다는 아이디어이다.
여기서 중요한 전환은 라벨이 <code>class id</code>가 아니라 <code>natural language</code>인 것이다.</p>
<p>CLIP 구현의 핵심 pre-training task로는, 이미지와 텍스트를 각각 encoder에 넣고, 같은 쌍의 image-caption은 가깝게, 다른 쌍은 멀게 만드는 contrastive learning 구조이다.</p>
<pre><code>image -&gt; image encoder -&gt; image embedding
text  -&gt; text encoder  -&gt; text embedding

같은 pair: similarity 높게
다른 pair: similarity 낮게</code></pre><p>CLIP의 성능은 구조만의 승리가 아닌, 웹 규모의 image-text supervision을 잘 먹는 학습 목표를 설계한 결과이다.</p>
<blockquote>
<p>*&quot;natural language is used to reference learned visual concepts&quot;* 
<br>이 부분이 zero-shot의 핵심이다. 예를 들어 ImageNet 분류를 할 때도 classifier Head를 새로 학습하지 않고, 클래스 이름을 문장 prompt로 바꾼다.</p>
</blockquote>
<p>이미지 embedding과 각 text embedding의 similarity를 비교해서 가장 가까운 텍스트를 예측 클래스로 삼는 식이다.</p>
<p><strong>CLIP은 단순 이미지 분류 모델이라기보다, 자연어를 인터페이스로 쓰는 범용 visual representation model에 가깝다.</strong></p>
<hr>
<h1 id="introduction">Introduction</h1>
<h2 id="1-nlp는-이미-raw-text-pre-training으로-성공했다">1. NLP는 이미 raw text pre-training으로 성공했다.</h2>
<blockquote>
<p>*&quot;Pre-training methods which learn directly from raw text have revolutionized NLP.&quot;*
<br>핵심은 &quot;raw text&quot;이다. 사람이 정답 라벨을 붙인 데이터가 아니라, 인터넷에 이미 존재하는 텍스트를 대규모로 학습해서 NLP가 발전한 것이다.</p>
</blockquote>
<p>여기서 저자들이 염두에 둔 모델들은 GPT, BERT, T5 계열이다. 이 모델들은 특정 태스크 전용 구조를 처음부터 만들기보다는, 먼저 거대한 텍스트 corpus에서 일반적인 언어 표현을 학습한다.</p>
<p>논문은 이어 <code>&quot;Task-agnostic objectives&quot;</code>를 강조한다. 예를 들어 </p>
<pre><code>다음 단어 예측: autoregressive language modeling
가려진 단어 예측: masked language modeling</code></pre><p>이런 목표는 특정 downstream task, 예를 들어 감성분석이나 번역, QA에 직접 묶여 있지 않다.</p>
<p>그런데도 대규모 학습을 하면 여러 태스크로 잘 전이된다.</p>
<p><strong>CLIP은 바로 이 질문을 vision으로 가져온다.</strong></p>
<blockquote>
<p><strong>image-text data로 pre-training을 하면, 다양한 vision task 로 zero-shot transfer가 가능할까?</strong></p>
</blockquote>
<h2 id="2-text-to-text가-준-힌트-출력-형식까지-자연어로-통일하기">2. text-to-text가 준 힌트: 출력 형식까지 자연어로 통일하기</h2>
<p>저자들은 NLP에서 <code>&quot;text-to-text&quot;</code> 인터페이스가 중요했다고 말한다. 모든 문제를 텍스트 입력, 텍스트 출력으로 바꾸면 task마다 별도 head를 만들 필요가 줄어든다.</p>
<p>이게 CLIP에서는 다음과 같이 대응된다.</p>
<pre><code>기존 vision:
image -&gt; encoder -&gt; fixed classifier head -&gt; class id

CLIP:
image -&gt; image encoder -&gt; embedding
text prompt -&gt; text encoder -&gt; embedding
similarity 비교 -&gt; prediction</code></pre><p><strong>즉, CLIP은 vision task의 출력 공간을 &#39;고정된 클래스 index&#39;가 아니라, &#39;자연어 문장&#39;으로 열어둔다.</strong> 이게 나중에 zero-shot classification의 기반이 된다.</p>
<p>ImageNet 1000-class classifier를 예로 들자면, 새로 학습하는 대신 <code>&quot;a photo of a dog&quot;</code>, <code>&quot;a photo of a truck&quot;</code>, <code>&quot;a photo of a starwberry&quot;</code> 등과 같은 텍스트를 text encoder로 넣고, 이미지와 가장 잘 맞는 문장을 고르는 방식이다.</p>
<h2 id="3-vision은-아직-imagenet식-supervised-pre-training에-묶여-있었다">3. Vision은 아직 ImageNet식 supervised pre-training에 묶여 있었다.</h2>
<p>논문은 NLP의 성공과 대비해서 vision분야를 조금은 비판적으로 본다.</p>
<p>비판 대상은 ImageNet 자체라기보다는, <strong>정해진 라벨셋에 의존하는 학습 관습</strong>이다. ImageNet은 훌륭하지만, 1000개 클래스라는 closed set이다.</p>
<p>자연어는 훨씬 더 넓은 개념 공간을 표현할 수 있지만, 기존 vision model은 라벨셋이 모델의 세계를 제한한다.</p>
<blockquote>
<p>*&quot;Could scalable pre-training methods which learn directly from web text result in a similar breakthrough in computer vision?&quot;*
<br>이 문장이 introduction의 핵심이라고 봐도 무방하다. CLIP논문 전체는 이 질문에 대한 실험적인 답변인 것이다.</p>
</blockquote>
<h2 id="4-사실-image-text-학습은-새-아이디어가-아니다">4. 사실 image-text 학습은 새 아이디어가 아니다.</h2>
<p>Mori et al., Quanttoni et al., Srivastava &amp; Salakhutdinov, Joulin et al., Li et al., 등을 언급한다.</p>
<p>즉, 이미지와 텍스트를 같이 학습하려는 시도는 전부터 꾸준히 있었다. 예를 들어 Joulin et al.은 이미지 caption의 단어를 예측하게 해서 image representation을 학습했다.</p>
<p>하지만 성능은 충분하지 않았다. 논문은 예시로 Li et al.의 zero-shot ImageNet 정확도가 <code>&quot;only 11.5%&quot;</code>라고 말한다. 당시 SOTA나 고전적 supervised 방식에 비해 너무 낮았기 때문에, 자연어 supervision은 흥미로운 proof-of-concept에 머물렀던 것이다.</p>
<h2 id="5-기존-weak-supervision의-타협">5. 기존 weak supervision의 타협</h2>
<p>여기서 논문은 Instagram hashtag, JFT-300M과 같은 대규모 weakly supervised 학습을 언급한다.</p>
<p>이런 방법들은 데이터 규모가 크고 성능도 좋았지만, 여전히 supervision이 제한되어 있었다.</p>
<p><strong>기존 모델들은 마지막에 고정된 softmax classifier를 둔다.</strong> 이러면 새로운 클래스를 자연어 즉석에서 넣을 수가 없다. CLIP의 text encoder는 이 한계를 깬다.</p>
<pre><code>Static softmax:
weight matrix shape = [num_classes, dim]
num_classes가 고정됨

CLIP zero-shot classifier:
class text를 그때그때 encoding
새로운 class description도 즉석에서 추가 가능</code></pre><h2 id="6-clip의-차별점-objective-보다-더-중요한-것은-scale의-단순화">6. CLIP의 차별점: objective 보다 더 중요한 것은 scale의 단순화</h2>
<p>기존 Natural Language Supervision 연구들은 보통 10만<del>20만 장 수준의 이미지로 실험했다. 하지만 대규모 weak supervision 연구들은 수백만</del>수십억 장의 데이터를 사용했다. CLIP은 이 간극을 메우고자 하는데, 이 때 등장하는 이름이 바로 CLIP이다.
<code>CLIP, for Contrastive Language-Image Pre-Training</code></p>
<p>CLIP의 novelty는 &quot;갑자기 완전 새로운 loss를 발명한 것&quot;이 아닌, <strong>contrastive image-text learning을 웹 규모로 밀어붙이고 zero-shot interface까지 체계화했다는 것</strong>에 가깝다.</p>
<hr>
<h3 id="figure-1이-말하고자-하는것">Figure 1이 말하고자 하는것?</h3>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/c3f48c08-01d3-4f38-b866-a06987ccd8a9/image.png" alt="">
Figure 1은 CLIP 전체 아이디어를 <strong>[학습 단계 $\rightarrow$ 분류기 생성 $\rightarrow$ zero-shot 예측]</strong> 으로 압축한 그림이다.</p>
<p>기존 이미지 분류 모델은 보통  <strong>[ image $\rightarrow$ image encoder $\rightarrow$ linear classifier $\rightarrow$ class probability ]</strong> 과정을 거친다. </p>
<p>예를 들어 ImageNet이면 마지막 classifier가 1000개 클래스에 고정된다.</p>
<p><strong>CLIP은 다르다.</strong></p>
<pre><code>image -&gt; image encoder -&gt; image embedding
text  -&gt; text encoder  -&gt; text embedding

image embedding과 text embedding의 similarity 비교</code></pre><p>즉, CLIP은 <strong>&quot;이미지 1000개 class 중 하나로 분류&quot;하도록 바로 학습하지 않고, 이미지와 자연어 설명을 같은 embedding 공간에 정렬</strong>하도록 학습한다.</p>
<h3 id="1-contrastive-pre-training">(1) COntrastive Pre-training</h3>
<p>Figure 1 의 왼쪽 패널은 학습 과정이다.
데이터셋에 이러한 pair가 있다고 가정하자.</p>
<pre><code class="language-text">I1: image 1
T1: image 1에 붙은 text

I2: image 2
T2: image 2에 붙은 text

I3: image 3
T3: image 3에 붙은 text</code></pre>
<p>예를 들어 그림에는 <code>&quot;Pepper the aussie pup&quot;</code>과 같은 caption이 보인다. 중요한 것은 이미지와 텍스트가 한 쌍이라는 것이다.</p>
<p>각각 Encoder에 들어간다.</p>
<pre><code class="language-text">I1 -&gt; Image Encoder -&gt; image embedding i1
T1 -&gt; Text Encoder  -&gt; text embedding t1</code></pre>
<p>여기서 대각선이 정답이다.</p>
<pre><code>I1·T1 = image 1과 text 1의 matching score
I2·T2 = image 2와 text 2의 matching score
I3·T3 = image 3과 text 3의 matching score</code></pre><p>나머지는 오답 pair이다.</p>
<p>CLIP은 정답 pair의 similarity는 크게, 오답 pair의 similarity는 작게 만들도록 학습한다. 이것이 바로 <strong>contrastive learning</strong>이다.</p>
<p>조금 더 직관적으로 표현해보자면 다음과 같다.</p>
<pre><code class="language-python">image_features = image_encoder(images)
text_features = text_encoder(texts)

image_features = normalize(image_features)
text_features = normalize(text_features)

logits = image_features @ text_features.T</code></pre>
<p>정답 label은 단순한데, $\text{labels} = [0, 1, 2, ..., N-1]$, batch에서 <code>image</code>의 정답 text는 <code>text i</code>이기 때문이다.</p>
<blockquote>
<pre><code class="language-text">index 0: image[0] = 강아지 사진      text[0] = &quot;a photo of a dog&quot;
index 1: image[1] = 자동차 사진      text[1] = &quot;a photo of a car&quot;
index 2: image[2] = 새 사진          text[2] = &quot;a photo of a bird&quot;
index 3: image[3] = 피자 사진        text[3] = &quot;a photo of a pizza&quot;</code></pre>
</blockquote>
<pre><code>여기서 `image[0]`의 정답 텍스트는 `text[0]`이다. `image[1]`의 정답 텍스트는 `text[1]`이고, `image[2]`의 정답 텍스트는 `text[2]`이다. ***&quot;batch에서 image i의 정답 text는 text i라는 말이 이 말이다.&quot;***</code></pre><p>image[0]의 정답 = text[0]
image[1]의 정답 = text[1]
image[2]의 정답 = text[2]
image[3]의 정답 = text[3]</p>
<pre><code>
학습 loss는 보통 양방향으로 간다.</code></pre><p>image -&gt; text: 이 이미지에 맞는 텍스트는 무엇인가?
text -&gt; image: 이 텍스트에 맞는 이미지는 무엇인가?</p>
<pre><code>구현 부분에서는 핵심이 보이는데,
```python
loss_i = cross_entropy(logits, labels)
loss_t = cross_entropy(logits.T, labels)
loss = (loss_i + loss_t) / 2</code></pre><p>CLIP은 caption을 생성하는 모델도 아니고, autoregressive하게 텍스트를 생성하는 모델도, 단어를 직접 예측하는 모델도 아니다. <strong>이미지와 텍스트가 서로 맞는지 비교하는 모델</strong>인 것이다.</p>
<h3 id="2-create-dataset-classifier-from-label-text">(2) Create Dataset Classifier From Label Text</h3>
<p>우측 상단 패널은 학습이 끝난 뒤 downstream dataset에 적용하는 과정이다.</p>
<p>예를 들어 우리가 분류하려는 클래스가 <code>plane</code>, <code>car</code>, <code>dog</code>, <code>bird</code>, 라고 해보자. </p>
<p>기존 supervised model이라면, 이 class 개수에 상응하는 classifier head를 새로 붙이고 학습해야 한다.</p>
<p>하지만 CLIP은 class name을 자연어 문장으로 바꾼다.</p>
<ul>
<li><code>&quot;a photo of a plane.&quot;</code></li>
<li><code>&quot;a photo of a car.&quot;</code></li>
<li><code>&quot;a photo of a dog.&quot;</code></li>
<li><code>&quot;a photo of a bird.&quot;</code></li>
</ul>
<p>Figure 1에서는 template이 이렇게 나온다.
<code>&quot;A photo of a {object}.&quot;</code></p>
<p>자연어로 바꾼 class name을 <code>{object}</code> 에 넣고 text encoder에 통과시킨다.</p>
<ul>
<li><code>&quot;a photo of a plane&quot; -&gt; Text Encoder -&gt; t_plane</code></li>
<li><code>&quot;a photo of a car -&gt; Text Encoder -&gt; t_car</code></li>
<li><code>&quot;a photo of a dog&quot; -&gt; Text Encoder -&gt; t_dog</code></li>
<li><code>&quot;a photo of a bird&quot; -&gt; Text Encoder -&gt; t_bird</code></li>
</ul>
<p>이 text embedding들이 곧 classifier weight처럼 작동하는데, 논문 캡션에서는 이를 text encoder가 zero-shot linear classifier를 &quot;synthesizes&quot; 한다고 표현한다.</p>
<p>전에도 언급했지만, 여기서 중요한 점은 classifier가 고정되어 있지 않다는 것이다. <strong>class를 바꾸고 싶으면 text prompt만 바꾸면 된다.</strong></p>
<ul>
<li><code>&quot;a photo of a tumor&quot;</code></li>
<li><code>&quot;a satellite photo of a harbor&quot;</code></li>
<li><code>&quot;a blurry image of a handwritten digit&quot;</code></li>
</ul>
<p>이런 식으로 새로운 class description을 넣을 수 있다. 이것이 바로 CLIP의 zero-shot 능력의 핷미이다.</p>
<h3 id="3-use-for-zero-shot-prediction">(3) Use for Zero-Shot Prediction</h3>
<p>우측 하단은 실제 예측 단계이다.</p>
<p>새로운 이미지가 들어온다고 해보자.</p>
<p>그리고 아까 만든 class text embeddings와 similarity를 계산한다.</p>
<pre><code>image · t_plane
image · t_car
image · t_dog
image · t_bird</code></pre><p>가장 높은 score를 가진 class가 바로 예측 결과이다.</p>
<p>예를 들어 그림에서는 <code>&quot;A photo of a dog.&quot;</code>이 가장 잘 맞는 텍스트로 선택되는 구조를 보여준다.</p>
<pre><code class="language-python">image_feature = image_encoder(image)
image_feature = normalize(image_feature)

logits = image_feature @ text_features.T
prediction = logits.argmax(dim=-1)</code></pre>
<p>여기서 <code>text_features.T</code>가 사실상 classifier matrix 역할을 한다.</p>
<blockquote>
<h3 id="figure-1의-진짜-의미">Figure 1의 진짜 의미</h3>
<p>Figure 1은 <strong>기존 모델은 class label을 직접 예측</strong>하지만, <strong>CLIP은 image와 text를 같은 공간에 놓고, text를 classifier로 사용한다는 것</strong>이다
<br>그래서 CLIP은 학습 때 본 class에만 국한되지 않는다. 자연어로 표현할 수 있는 개념이면 어느 정도 비교 대상이 될 수 있다.</p>
</blockquote>
<blockquote>
<h3 id="그래서-말하고자-하는건">그래서 말하고자 하는건?</h3>
<p>**CLIP은 vision model을 고정 라벨 분류기에서 벗어나게 하고, 자연어를 통해 열린 개념 공간으로 transfer할 수 있게 만든 image-text contrastive pre-training 방법이다.</p>
</blockquote>
<hr>
<h1 id="approach">Approach</h1>
<h2 id="21-natural-language-supervision">2.1. Natural Language Supervision</h2>
<blockquote>
<p>*&quot;learning perception from supervision contained in natural langauge.&quot;*
<br><code>perception</code>은 단순 classification accuracy가 아닌, 이미지 안의 object, attribute 등을 이해하는 시각적 능력 전체를 말한다. 그 perception을 사람이 정리한 class label이 아니라 <strong>자연어 안에 들어 있는 supervision으로부터 배운다는 것</strong>이다.</p>
</blockquote>
<p>예를 들어 기존 supervised classification에서는 이미지 하나가 보통 레이블은 그저 단어 <code>dog</code>와 같이 주어진다.</p>
<p>하지만 자연어 supervision에서는 이미지가 다음과 같이 존재할 수 있다.
<code>a brown dog jumping over a log in the snow.</code></p>
<p>이 문장에는 그저 <code>dog</code>보다 훨씬 더 많은 정보를 담고 있어, 자연어는 단일 class id보다 훨씬 더 풍부한 supervision이라는 것이다.</p>
<blockquote>
<h3 id="왜-natural-language-supervision-이라는-표현을-쓰지">왜 *&quot;Natural Language Supervision&quot;* 이라는 표현을 쓰지?</h3>
<p>연구진들은 이 분야의 용어가 약간은 모순된다고 말한다. 어떤 연구는 image-text pair로 학습하면서도 자기 방법을 <code>unsupervised</code>라고 부르고, 어떠한 연구는 <code>self-supervised</code>, 어떤 연구는<code>weakly supervised</code> 라고 부른다.
<br>논문에서는 이 차이를 크게 보지 않으며, 그저 이 계열의 연구들은 모두 이미지를 설명하는 텍스트를 학습 신호로 사용한다는 것이다.
<br>참고로 CLIP은 완전한 unsupervised learning이 아니다. 이미지 옆에 붙은 텍스트가 모델에게 의미를 부여하기 때문인데, 다만 ImageNet처럼 사람이 정제한 <code>1-of-N label</code>도 아니다.</p>
</blockquote>
<h3 id="기존-supervised-label과-다른-것은">기존 supervised label과 다른 것은?</h3>
<p><code>강아지 사진: label-&quot;dog&quot;</code> 이런 구조가 기존 img classification dataset인데, 이 label은 ML에 매우 편리하다. class index 하나로 바꿀 수도 있고, CEL를 걸기도 매우 쉽다.
<br>하지만 정보량이 매우 제한적인데, 이미지 안에 강아지 외에도 나무, 사람 등이 있을 수 있지만, label은 하나만 남긴다.
<br>반면 자연어는 더 지저분하지만 정보량이 풍부하다. CLIP은 이 풍부한 텍스트를 따로 처리하지 않고 그대로 학습에 사용한다.</p>
<p>저자들이 강하게 말하는 장점 중 하나는 자연어 supervision은 annotation을 꼭 <code>&quot;machine learning compatible format&quot;</code>으로 만들 필요가 없다는 것이다.</p>
<p>기존 데이터셋 구축에서는 </p>
<ul>
<li>class taxonomy 정하기</li>
<li>annotator에게 이미지를 보여주기</li>
<li>annotator가 class 고르기</li>
<li>여러 annotator의 majority vote로 gold label 만들기</li>
<li>모델은 그 label을 예측하기 </li>
</ul>
<p>위 흐름을 따르는데, 논문에서는 이 방식을 <code>&quot;1-of-N majority vote gold label&quot;</code>이라고 부른다.</p>
<p>이 방식은 깔끔할 수는 있어도 문제가 있는데,
 <strong>1. class set이 미리 정해져야 함.</strong>
 <strong>2. 새로운 class 추가하려면 다시 labeling 해야함.</strong>
 <strong>3. 이미지의 풍부한 의미가 하나의 label로 압축됨.</strong>
 <strong>4. Annotation 비용이 꽤 큼</strong></p>
<p>자연어 supervision은 이 과정을 우회한다. 웹에는 이미 이미지와 텍스트가 함께 존재한다. 웹에 존재하는 그러한 데이터는 사람이 ML 데이터셋을 만들기 위해 따로 붙인 label은 아니지만, 이미지에 대하나 의미 정보를 담고 있다.</p>
<h3 id="자연어-supervision의-강점">자연어 Supervision의 강점</h3>
<p>저자들이 논문에서 말하는 강점은 두 가지로, <strong>첫 번째는 scale이다.</strong></p>
<p>ImageNet식 annotation은 비용이 크다. 사람이 이미지를 보고 class label을 붙여야 하기 때문인데, 그저 인터넷에 대량으로 존재하는 자연어를 CLIP이 image-text pair를 supervision으로 사용한 것이다. </p>
<p>두 번째 강점은 <strong>representation을 language와 연결하는 것</strong>이다.</p>
<p>이 부분이 CLIP의 핵심인데, 저자들은 자연어로 학습하면 <strong>모델이 representation만 배우는 것이 아닌, 그 representation을 language와 연결한다는 것이다.</strong></p>
<p>일반적인 self-supervised vision model을 예로 들어보면, SimCLR, MoCo 같은 모델은 좋은 image representation을 배울 수 있다.</p>
<p>하지만 이 representation은 자연어와 직접 연결되어 있지 않아 downstream task에 쓰려면 보통 linear probe나 fine-tuning이 필요하다.</p>
<p><strong>반면 CLIP은 처음부터 image와 text를 같은 embedding space에 놓는다. 때문에 학습 이후 text가 classifier 역할을 할 수 있는 것이다.</strong></p>
<blockquote>
<p>때문에 <strong>CLIP은 representation learning과 language grounding을 동시에 한다.</strong></p>
</blockquote>
<blockquote>
<h3 id="ovod와의-연결">OVOD와의 연결</h3>
<p>OVOD에서는 정해진 class맘ㄴ detect하는 것이 목표가 아닌, 학습 때 보지 못한 class도 자연어 이름이나 설명을 통해 탐지하고 싶은 것이다.
<br>기존 detector는 보통 <strong>[region feature $\rightarrow$ fixed classifier $\rightarrow$ known classes]</strong> 구조로 이루어져 있는데, CLIP의 개념을 도입하면 다음과 같다.
<strong>[region feature $\rightarrow$ text embedding과 similarity 비교]</strong>
<br>즉, class weight을 고정 parameter로 두는 대신, text encoder가 만든 embedding을 분류기로 쓰는 것이다.
<br>다만 CLIP 자체는 image-level model로, BBOX 를 직접 예측하지는 않아, region-level detection 구조에 이식하는 방법을 사용한다.</p>
</blockquote>
<h3 id="21-이-말하고자-하는-것🔥">2.1 이 말하고자 하는 것🔥</h3>
<p><strong>CLIP이 정제된 class label 대신 웹에 존재하는 자연어를 supervision으로 사용하고, 이를 통해 visual representation을 language space와 직접 연결함으로써 scalable learning과 flexible zero-shot transfer를 가능하게 만든다.</strong></p>
<h2 id="22-creating-a-sufficiently-large-dataset">2.2 Creating a Sufficiently Large Dataset</h2>
<p> CLIP이 자연어 supervision을 제대로 검증하기 위해서는, 기존 image-text dataset으로는 너무 작거나 품질이 부족했기 때문에, 저자들은 웹 규모의 400M image-text dataset을 직접 만들었다.</p>
<p><code>MS-COCO</code>, <code>Visual Genome</code>, <code>YFCC100M</code> 데이터셋을 기존에 사용하였지만, 방금 말한 이유 등으로 인해 <strong>natural language supervision의 강점 scale</strong>을 제대로 실험할 수 없었다.</p>
<blockquote>
<p>자연어 supervision의 장점은 인터넷에 엄청난 image-text pair가 있는 것인데, COCO나 Visual Genome만 보면 그 잠재력을 과소평가한다.</p>
</blockquote>
<p>단순히 인터넷의 공개 source에서 많이 긁어온 것이 아닌, <strong>넓은 visual concept를 포함하도록 query 기반으로 수집을 진행</strong>했다. 이렇게 만들어진 400M image-text dataset을 <strong>WIT, WebImageText</strong>라고 부른다.</p>
<p>즉, 다양한 단어나 개념을 query로 두고, query가 text에 포함된 image-text pair를 수집한 것이다.</p>
<p><em>(그렇다고 한 query가 데이터셋을 과도하게 지배하지 않도록 최대 20,000 image-text pair로 제한하였다.)</em></p>
<p><strong>중요한 점은 이 query들이 학습 label은 아니다.</strong> query는 데이터 수집을 위한 장치일 뿐, 실제 학습은 여전히 image-text pair 단위로 한다.</p>
<blockquote>
<h3 id="22-의-핵심">2.2 의 핵심</h3>
<p><strong>1. COCO/Visual Genome만으로는 CLIP 논문의 scale을 재현하기 어렵다.
2. image-text pair는 많기만 하면 안 되고, text가 실제 자연어 설명이어야 한다.
3. 흔한 개념에 데이터가 쏠리지 않게 balancing 또는 sampling 전략이 필요하다.
4. query는 label이 아니라 dataset coverage를 넓히기 위한 도구다.
5. CLIP 성능은 architecture만이 아니라 WIT 같은 대규모 데이터 구축에 크게 의존한다.</strong>
<br>OVOD에서는 3번과 4번이 특히 중요한데, Open-vocabulary를 잘하기 위해서는 학습 데이터가 특정 closed category에만 몰려 있으면 안되기 때문이다. </p>
</blockquote>
<p><strong>*2.2의 핵심은 CLIP의 성능이 단순 contrastive loss에서 나온 것이 아닌, 자연어 supervision의 장점이 드러날 만큼 크고 다양한 image-text dataset을 직접 구축한 데에서 나온다는 것이다. *</strong></p>
<h2 id="23-selecting-an-efficient-pre-training-method">2.3 Selecting an Efficient Pre-Training Method</h2>
<p><strong>CLIP이 왜 caption generation이 아닌, contrastive image-text matching을 선택했을까?</strong></p>
<p>기존 방식처럼 이미지에서 caption을 직접 예측하려고 하면 너무 비싸고 어렵다. 같은 이미지에도 가능한 설명 문장이 너무 많아, 시각 개념을 배우기보다는 &quot;문장을 정확히 생성하는 문제&quot;에 computation이 많이 든다는 것이다.</p>
<p>때문에 저자들은 image CNN과 text Transformer를 함께 학습해서 caption을 예측하려 했지만, scale up이 비효율적이었다고 한다. </p>
<p>CLIP의 학습 목표는 다음과 같은데,</p>
<ul>
<li><strong>정답 image-text pair의 cosine similarity는 크게</strong></li>
<li><strong>오답 image-text pair의 cosine similarity는 작게</strong></li>
</ul>
<pre><code class="language-python">image_features = image_encoder(images)
text_features = text_encoder(texts)

image_embeddings = normalize(image_projection(image_features))
text_embeddings = normalize(text_projection(text_features))

logits = image_embeddings @ text_embeddings.T
logits = logits * exp(temperature)

labels = arange(batch_size)

loss_i = cross_entropy(logits, labels)
loss_t = cross_entropy(logits.T, labels)

loss = (loss_i + loss_t) / 2</code></pre>
<p>여기서 이전에 양방향 loss를 설명했을 때와 같이, <code>loss_i</code>는 이미지 기준으로 맞는 텍스트를 찾는 loss, <code>loss_t</code>는 텍스트 기준으로 맞는 이미지를 찾는 loss인데, 저자들은 이를 <strong>symmetric cross entropy loss</strong>라고 부른다.</p>
<p>CLIP은 꽤 단순히 설계되었는데, 저자들은 대규모 데이터셋을 사용하기 때문에 overfitting이 큰 문제가 아니라고 보고, 여러 복잡한 과정들을 제거한다.</p>
<ul>
<li><strong>ImageNet pretrained image encoder 사용 X</strong></li>
<li><strong>pretrained text encoder 사용 X</strong></li>
<li><strong>non-linear projection head 사용 X</strong></li>
<li><strong>linear projection만 사용 O</strong></li>
<li><strong>복잡한 text transformation X</strong></li>
<li><strong>image augmentation은 random square crop 정도만 사용</strong></li>
<li><strong>temperature는 하이퍼파라미터로 고정하지 않고 학습</strong></li>
</ul>
<p>때문에 CLIP은 <strong>큰 데이터 + 단순한 contrastive objective + 두 개의 encoder alignment</strong>라고 보면 되겠다.</p>
<blockquote>
<h3 id="재현-관점에서의-23-checklist-✅">재현 관점에서의 2.3 Checklist ✅</h3>
<p>*<em>1. image encoder와 text encoder를 준비한다.
2. 각각의 출력을 같은 embedding dimension으로 projection한다.
3. embedding을 L2 normalize한다.
4. batch 안의 모든 image-text similarity matrix를 만든다.
5. diagonal을 정답으로 두고 symmetric cross entropy를 건다.
6. temperature/logit scale은 학습 가능한 parameter로 둔다.
*</em></p>
<blockquote>
<p>참고로 L2 Norm을 하는 이유는 CLIP이 Embedding의 Norm(크기)가 아니라, 방향(Direction)으로 image-text 의미 정렬을 학습하게 만들기 위함이다.
<br><strong>CLIP은 &quot;벡터의 크기가 큰가?&quot;가 아닌, &quot;이미지 벡터와 텍스트 벡터가 같은 방향을 보고 있는지&quot;를 학습한다.</strong>
<br><strong>L2 Normalization은 CLIP이 embedding의 크기 꼼수가 아니라 image-text 의미 방향의 정렬을 학습하게 하고, dot-product를 코사인 유사도로 바꿔 contrastive learning을 안정화한다.</strong></p>
</blockquote>
</blockquote>
<h2 id="24-choosing-and-scaling-a-model">2.4 Choosing and Scaling a Model</h2>
<p>그렇다면 image/text encoder는 어떠한 구조로 만들었고, 어떻게 scale 하는 걸까?</p>
<p>이제 CLIP은 <strong>image encoder, text encoder</strong> 두 개로 구성된다는 것도, 두 feature를 같은 multimodal embedding space로 projection해서 유사도를 계산하는 것도 안다.</p>
<h3 id="image-encoder-resnet-vit">Image Encoder: ResNet, ViT</h3>
<p>먼저저자들은 image encoder로 ResNet과 ViT 계열을 사용한다.</p>
<p>ResNet 먼저 알아보자.</p>
<h4 id="①-resnet-계열">① ResNet 계열</h4>
<p>기본은 ResNet-50이다. 다만 원래 ResNet을 그대로 쓰지는 않고, 몇 가지를 추가한다.</p>
<ul>
<li><strong>ResNet-D 개선</strong></li>
<li><strong>anti-aliased blur pooling</strong></li>
<li><strong>attention pooling</strong></li>
</ul>
<p>여기서 가장 눈에 띄는 것은 <strong>attention pooling</strong>이다.
일반 ResNet은 마지막 feature Map을 GAP으로 하나의 vector로 만드는데, <strong>CLIP은 이 부분을 attention pooling으로 바꾼다.</strong></p>
<p>즉, 모든 spatial location을 단순 평균내는 대신, attention을 통해 더 유연하게 image representation을 만든다. <strong>CLIP이 image-text alignment를 해야하니, 단순 classification보다는 풍부한 Global representation이 더 필요했을 가능성이 있다.</strong></p>
<h4 id="②-vit-계열">② ViT 계열</h4>
<p>ViT는 이미지를 패치로 나누고, 각 패치를 토큰처럼 Transformer에 넣는 구조이다.</p>
<p>CLIP에서는 ViT구조를 거의 그대로 사용하지만, <strong>patch embedding과 position embedding을 더한 뒤 LN을 추가하는 정도의 수정만 한다.</strong></p>
<h3 id="text-encoder-transformer">Text Encoder: Transformer</h3>
<p>text encoder에서는 transformer를 사용한다.
이에 대한 디테일을 살펴보자면 다음과 같다.</p>
<ul>
<li><strong>layer: 12</strong></li>
<li><strong>width: 512</strong></li>
<li><strong>attention heads: 8</strong></li>
<li><strong>63M parameters</strong></li>
<li><strong>BPE vocabulary size 49,152</strong></li>
<li><strong>max sequence length 76</strong></li>
</ul>
<p>텍스트는 lower-cased BPE로 tokenize된다고 한다. 문장 앞뒤에는 special token을 붙인다.
<code>[SOS] text tokens [EOS]</code>
CLIP은 나지막 layerdptj <code>[EOS]</code> 토큰 위치의 activation을 text feature로 사용한다.</p>
<p>왜<code>[EOS]</code>를 쓰냐면, casual/masked self-attention 구조에서 <code>[EOS]</code>의 위치는 앞의 전체 문맥을 본 토큰이기 때문이다. <strong>때문에 문장 전체의 요약 representation처럼 사용할 수 있다.</strong></p>
<blockquote>
<h3 id="여기서-잠시-bpe가-무엇인지-😰">여기서 잠시 BPE가 무엇인지 😰...</h3>
<p>BPE는 <strong>Byte Pair Encoding</strong>으로, NLP에서 자주 사용되는 <strong>subword tokenization 방식</strong>이라고 한다.
<br>텍스트를 소문자한 뒤에, BPE 방식으로 token id sequence로 바꾼다.</p>
</blockquote>
<h4 id="bpe가-필요한-이유">BPE가 필요한 이유</h4>
<p>모델은 문자열을 그대로 이해하지 못해, 텍스트를 숫자 토큰으로 바꾼다.
<Br>가장 단순한 방법으로 단어 단위 tokenization이 있는데, 이걸 전부 완전한 단어 vocabulary에 넣으면 크기가 너무 커지기 때문이다.
  <br>BPE는 중간 지점으로, 단어를 너무 잘게 character로만 쪼개지도 않고, 완전한 단어로만 보지도 않는다. 자주 나오는 조각은 하나의 토큰으로 만들고, 회귀 단어는 작은 subword 조각들로 쪼갠다.
  <br><strong>BPE는 대충 이런 식으로 vocabulary를 만든다.</strong></p>
<pre><code>  l o w
l o w e r
n e w e s t
w i d e s t</code></pre><p>  그 다음, corpus에서 가장 자주 같이 등장하는 인접 쌍을 찾아, merge한다. </p>
<h3 id="text-encoder는-masked-self-attention-사용">Text Encoder는 masked self-attention 사용</h3>
<p>  논문은 text encoder에 masked self-attention을 사용했다고 한다. </p>
<p>  이것은 GPT류 Language Model이 미래 token을 보지 않는 attention 구조이다.</p>
<p>  다만 CLIP이 language modeling을 직접 수행한다는 것은 아니고, 나중에 pre-trained language model initialization이나 auxiliary language modeling objective를 붙일 가능성을 남겨두기 위해 이런 구조를 유지했다고 한다.</p>
<p>  <strong>즉, CLIP의 text encoder는 Transformer이지만, 학습 목표는 여전히 caption generation이 아닌, image-text contrastive learning이다.</strong></p>
<h3 id="projection-두-modality를-같은-공간으로">Projection: 두 Modality를 같은 공간으로</h3>
<p>  image encoder와 text encoder의 출력 dimension은 다를 수 있다. 때문에 각각 linear projection을 통해 같은 embedding dimension <code>d_e</code>로 보낸다.</p>
<blockquote>
<h4 id="clip에서의-linear-projection">CLIP에서의 Linear projection</h4>
<p>  img encoder와 text encoder의 출력 차원이 다음과 같다고 가정하자.</p>
</blockquote>
<ul>
<li><strong>image encoder output: 2048</strong></li>
<li><strong>text encoder output: 512</strong><blockquote>
</blockquote>
그런데 이 둘의 유사도를 계산하려면 같은 차원이어야 한다. dot product를 하려면 차원이 같아야 하므로, 둘 다 같은 <code>d_e</code>로 보내보자.
<br>때문에 CLIP은 각각 linear projection을 둔다.<pre><code class="language-python">I_f = image_encoder(I)  # [n, d_i]
T_f = text_encoder(T)   # [n, d_t]
I_e = I_f @ W_i         # [n, d_e]
T_e = T_f @ W_t         # [n, d_e]</code></pre>
논문의 Figure 3에서는 다음과 같이 나온다.<pre><code class="language-python">I_e = l2_normalize(np.dot(I_f, W_i), axis=1)
T_e = l2_normalize(np.dot(T_f, W_t), axis=1)</code></pre>
여기서 <code>W_i</code>, <code>W_t</code>가 바로 linear projection matrix이다.<blockquote>
<blockquote>
<p><code>linear</code>라는 말은 변환이 행렬곱으로 이루어진다는 말로, bias를 포함하면 NN에서는 <code>y=xW+b</code>로 표현 가능하겠다.</p>
</blockquote>
</blockquote>
</li>
</ul>
<p>  이후 L2 Norm을 하고 코사인 유사도를 계산한다.</p>
<pre><code class="language-python">  similarity = normalized_image_embedding @ normalized_text_embedding</code></pre>
<p>  <strong>여기서 중요한 점은 CLIP이 복잡한 fusion module을 쓰지 않는다는 것이다. image와 text를 중간에서 섞는 것이 아닌, 각자 encoder를 통과한 뒤 같은 공간에서 비교하는 것이다.</strong></p>
<h3 id="scaling-전략">Scaling 전략</h3>
<p>  저자들은 모델을 키울 때 image encoder와 text encoder를 똑같이 키우지 않는다.</p>
<p>  ResNet image encoder는 세 방향(<code>width</code>, <code>depth</code>, <code>resolution</code>)을 함께 키운다.</p>
<p>  이는 EfficientNet식 scaling 아이디어와 비슷한데, 모델을 키울 때 width만 늘리거나 depth만 늘리는 것보다 여러 축을 같이 늘리는 것이 더 좋다는 관점이다.</p>
<p>  <strong>반면 text encoder는 주로 width만 키운다. depth는 키우지 않는다.</strong>
  이유는 CLIP 성능이 text encoder capacity보다 image encoder capacity에 더 민감했다고 보기 때문이다. </p>
<blockquote>
<p>그 이유로 *&quot;CLIP&#39;s performance [is] less sensitive to the capacity of the text encoder&quot;*라고 언급하는데, 이 관찰은 별도의 상세 ablation table로 제시되지는 않고, 저자들의 경험적 판단으로 보인다.</p>
</blockquote>
<p>  이것은 중요한 관찰인데, <strong>CLIP에서 text는 물론 중요하지만, vision task 성능을 올리는 데에는 image encoder scale이 크게 작용했다는 뜻</strong>이다.</p>
<h2 id="25-training">2.5 Training</h2>
<p>  저자들은 총 8개의 모델을 학습한다.</p>
<h4 id="resnet-계열-5개">ResNet 계열 5개</h4>
<ul>
<li>ResNet50</li>
<li>ResNet101</li>
<li>ResNet50x4</li>
<li>ResNet50x16</li>
<li>ResNet50x64</li>
</ul>
<h4 id="vit-계열-3개">ViT 계열 3개</h4>
<ul>
<li>ViT-B/32</li>
<li>ViT-B/16</li>
<li>ViT-L/14</li>
</ul>
<p>논문에서 모든 모델은 32 Epochs로 학습했다고 한다.
  Optimizer로는 Adam을 사용했으며, decoupled weight decay를 적용했다. lr은 cosine scheduler로 감소시켰다.</p>
<p>  여기서 <strong>decoupled weight decay는 AdamW 스타일</strong>이라고 보면 된다. 일반 L2 Regularization과 다르게 weight decay를 optimizer update에서 분리해서 적용하는 방식이다.</p>
<h3 id="temperature-parameter">temperature parameter</h3>
<p>  CLIP loss에서 similarity logits은 teperature로 scaling 된다.</p>
<pre><code class="language-python">  logits = image_embedding @ text_embedding.T
logits = logits * exp(t)</code></pre>
<p>  논문에서는 temperature <code>τ</code>를 고정 hyperparameter로 두지 않고, learnable parameter로 둔다. 초기값은 0.07에 해당하도록 설정했다. </p>
<blockquote>
<h3 id="왜-learnable-temperature가-좋은가">왜 learnable temperature가 좋은가?</h3>
<p>  contrastive learning에서는 batch size, embedding quality, dataset noise에 따라 적절한 softmax sharpness가 달라질 수 있다.
  <br> <strong>temperature가 너무 낮으면</strong> 다음과 같은 가능성이 있다.</p>
</blockquote>
<ul>
<li>모델의 과확신</li>
<li>hard negative에 과민</li>
<li>학습 불안정<blockquote>
<p>반대로 <strong>temperature가 너무 높으면</strong></p>
</blockquote>
</li>
<li>positive와 negative 구분이 약함</li>
<li>gradient signal이 흐릿함</li>
<li>학습이 느려짐<blockquote>
<p>때문에 CLIP은 temperature를 고정하지 않고 학습하게 만든다. 다만 너무 커지면 불안정해질 수 있어, logit scale이 100을 넘지 않도록 clip했다고 설명한다.</p>
</blockquote>
<pre><code class="language-python">logit_scale = nn.Parameter(torch.ones([]) * np.log(1 / 0.07))
logit_scale = logit_scale.exp().clamp(max=100)</code></pre>
</li>
</ul>
<h3 id="batch-size">batch size</h3>
<p>  논문에서 가장 눈에 띄는 설정 중 하나는 <code>&quot;minibatch size of 32,768&quot;</code>이다.</p>
<p>  CLIP이 contrastive learning에서는 batch size가 중요하다. 왜냐하면 batch 안의 다른 sample들이 negative pair가 되기 때문이다.</p>
<p>  <strong>batch가 크면 클수록 한 번의 update에서 훨씬 많은 negative pair를 보게 된다. CLILP이 23,768이라는 큰 batch size를 쓴 이유도 여기있다.</strong></p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰] Beyond-Labels: Advancing Open-Vocabulary Segmentation With Vision-Language Models]]></title>
            <link>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Beyond-Labels-Advancing-Open-Vocabulary-Segmentation-With-Vision-Language-Models</link>
            <guid>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Beyond-Labels-Advancing-Open-Vocabulary-Segmentation-With-Vision-Language-Models</guid>
            <pubDate>Wed, 01 Jul 2026 03:54:20 GMT</pubDate>
            <description><![CDATA[<p>Source: <a href="https://arxiv.org/abs/2501.16769">Beyond-Labels: Advancing Open-Vocabulary Segmentation With Vision-Language Models</a></p>
<p>당분간 Open-set, Open-vocabulary, Open-ended. 이렇게 세 가지의 도메인에 대해 공부를 할 예정이다. 개념 혼동을 피하기 위해 잠시 정리해보자.</p>
<table>
<thead>
<tr>
<th align="center">분류</th>
<th align="center">Training 시 카테고리</th>
<th align="center">Inference 시 카테고리</th>
<th align="center">작동 방법 (매커니즘)</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><strong>Traditional Detection</strong><br>(YOLO, Faster R-CNN)</td>
<td align="center">Fixed $N$ Classes <br>(e.g., COCO 80)</td>
<td align="center">Only Image</td>
<td align="center"><strong>Classification</strong>: calculate probability <br>to choose one among $N$ Claases</td>
</tr>
<tr>
<td align="center"><strong>Open-Vocabulary (OVOD)</strong><br>(GLIP, OWL-ViT)</td>
<td align="center"><strong>Base $N$ Classess</strong><br> + Large Scale Image-text Pairs</td>
<td align="center">Image + Category list to find<br><code>[&#39;Drone&#39;, &#39;Truck&#39;]</code></td>
<td align="center"><strong>Alignment</strong>: Matching Image region<br> and text embedding (CLIP)</td>
</tr>
<tr>
<td align="center"><strong>Open-Set Detection</strong></td>
<td align="center">Only specific Class<br>(&#39;Unknown&#39; to rest of them)</td>
<td align="center">Image + Category list to find</td>
<td align="center">If unknown object comes in, find by user prompt</td>
</tr>
<tr>
<td align="center"><strong>Open-Ended Detection</strong><br>(VL-SAM, GenerateU)</td>
<td align="center">No fixed category</td>
<td align="center">Only Image</td>
<td align="center"><strong>Generation</strong>: See and name an object by model itself.</td>
</tr>
</tbody></table>
<h3 id="open-set-vs-open-ended">Open-set v.s Open-Ended</h3>
<table>
<thead>
<tr>
<th align="center"></th>
<th align="center">Open-set Detection</th>
<th align="center">Open-Vocabulary Detection (OVOD)</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Keyword</td>
<td align="center"><strong>Unknown</strong> category detection</td>
<td align="center"><strong>Novel Class (New word)&#39;s naming</strong></td>
</tr>
<tr>
<td align="center">Background</td>
<td align="center">To break limits of traditional statistical classification</td>
<td align="center">VLM (e.g., CLIP)</td>
</tr>
<tr>
<td align="center">When Inference</td>
<td align="center">&quot;This is unknown object I&#39;ve never learned.&quot;</td>
<td align="center">&quot;Though I&#39;ve never seen this, I&#39;m sure it is <code>dog</code> according to my vocabulary skills&quot;</td>
</tr>
<tr>
<td align="center">Limits of Voca skill</td>
<td align="center">Relatively Narrow <br></td>
<td align="center">Close to $\infin$</td>
</tr>
</tbody></table>
<h1 id="introduction">Introduction</h1>
<p>FCN, U-Net, DPT와 같은 모델들은 Segmentation작업을 위해 구축된 방대한 데이터셋에서 딥러닝 네트워크를 훈련시키는 데 큰 성공을 거두었다.</p>
<p>하지만 이러한 전통적인 기법들은 특정 카테고리에 맞춰 Classifier를 학습시킨다는 방식에 국한되었는데, 학습 단계에서 <strong>Seen Category</strong>에 대해서만 레이블을 예측할 수 있다는 것이다.</p>
<p>따라서 테스트 시에 새롭게 등장하는 <strong>Unseen Category</strong>의 객체는 감지하거나 분류할 수 없는 한계가 존재한다.</p>
<p>MoCo나 DINO와 같은 모델들은 레이블이 없는 데이터(Unlabeled data)만으로도 강력한 시각적 표현을 학습할 수 있음을 증명했다.</p>
<p>최근의 트렌드는 Vision과 Text 도메인을 결합하는 것으로, 단순 대조 학습 기법으로 훈련된 CLIP이나 ALIGN은 추가적 학습 없이도 <strong>Zero-shot</strong>방식으로 이미지 분류와 같은 새로운 작업을 수행하는 놀라운 성과를 보인다.</p>
<p>이러한 발전은 Open-vocabulary 분할, 이미지 검색, 멀티모달 추론 등 다양한 Vision langauge Task의 길을 열었다.</p>
<h3 id="beyond-labels">Beyond-Labels</h3>
<p>논문은 앞서 말한 강력한 pre-trained VLM을 사용하여, 텍스트 이름이나 설명만으로 모든 카테고리의 객체를 분할하는 Open-vocabulary의 semantic segmentation 문제를 효율적으로 해결하고자 한다.</p>
<ul>
<li><p><strong>Frozen Encoder</strong>: 세밀한(Fine-grained) 공간 정보를 포착하기 위해 Positional Encoding이 추가된 Frozen 한 self-supervised 비전 모델을 사용하여 입력 이미지를 인코딩한다. 동시에 Frozen한 언어 모델을 사용하여 카테고리 이름을 인코딩함으로써 텍스트 설명에 대한 강력한 표현을 보장한다.</p>
<ul>
<li><strong>Fourier Embedding</strong>: 이 논문의 가장 중요한 기술 중 하나다. 고차원적인 공간/주파수 특징을 추출하기 위해 푸리에 임베딩을 사용한다. 일반적인 사전 학습 Positional Embeddings을 사용하지 않고, <strong>푸리에 임베딩(빈도 기반 임베딩)에 의존</strong>하여 공간 정보를 인코딩한다. 이를 통해 일반화 성능을 높이고 일관된 Spatial Encoding을 생성한다고 한다.</li>
</ul>
</li>
</ul>
<p>두 모달리티에서 추출된 임베딩을 통합하여 이미지 영역과 텍스트 설명을 정확하게 일치시키고, 결과적으로 다양한 카테고리에 걸쳐 매끄럽게 분할을 수행하는 것이다.</p>
<blockquote>
<h3 id="fourier-embedding의-영향">Fourier Embedding의 영향</h3>
</blockquote>
<h4 id="일반적인-positional-embedding">일반적인 Positional Embedding</h4>
<p>보통 트랜스포머에서 사용하는 Learnable PE는 각 위치에 대응되는 특정 벡터를 파라미터로 가진다.
⚠️<strong>이 방식은 Discrete하여, 특정 위치에 대한 값은 고정, Spatial한 관계를 유연하게 유추하기 힘들다.</strong> 
<br>훈련 데이터에 없던 새로운 해상도의 이미지가 들어오면, 학습된 위치 정보가 완전 어긋나버리는 일반화의 한계가 발생하는 것이다.</p>
<h4 id="fourier-embedding-고주파-기반">Fourier Embedding (고주파 기반)</h4>
<ul>
<li><strong>작동방식</strong>: 특정 위치($x, y$)를 고정된 벡터로 갖는 것이 아닌, <strong>sin, cos함수를 사용하여 위치를 다차원 주파수 공간으로 매핑</strong>한다.</li>
<li><strong>핵심</strong>: 픽셀의 위치를 단순 숫자로 인식하는 것이 아닌, &quot;이 위치는 어떤 주파수를 가진 파동의 정점/저점인가?&quot;로 표현한다.
<br>푸리에 변환은 <strong>Continuous</strong>하여 공간을 파동으로 표현하기 때문에, 픽셀 사이 미세한 위치적 차이도 수학적으로 부드럽게 연결한다.</li>
</ul>
<hr>
<h3 id="그럼-pe-말고-항상-fourier-embedding을-하면">그럼 PE 말고 항상 Fourier Embedding을 하면?</h3>
<p>이론적으로 푸리에 임베딩이 더 강력하고 일반화 성능이 좋아보이지만, 역시나 Trade-off가 존재한다.</p>
<ul>
<li><strong>데이터 성격에 따른 효율성</strong>: <strong>정형 데이터</strong>- 텍스트나 간단한 분류 문제처럼 위치 정보가 결정적이지 않은 경우, 오히려 Learnable한 PE가 특정 데이터 분포에 빠르게 과적합되어 높은 정확도를 낼 경우가 있다고 한다.<ul>
<li><strong>비전/공간 데이터</strong>: Segmentation이나 NeRF처럼 <strong>공간적 연속성이 중요한 작업</strong>에서는 푸리에 임베딩이 더 유리하게 작동할 수 있다.</li>
</ul>
</li>
<li><strong>모델 설계의 복잡도</strong>:<ul>
<li>Learnable PE는 그냥 Look-up Table에서 값을 가져오면 끝이라 구현이 매우 단순하다.</li>
<li>반면, 푸리에 임베딩은 입력 좌표를 고차원으로 Projection하는 추가 연산이 필요하며, 어떤 주파수 대역을 사용할지에 따라 성능이 달라질 수 있다.(튜닝 비용 발생)</li>
</ul>
</li>
<li><strong>이미지 일반화 vs. 과적합</strong>: 
이미 고정된 특정 해상도의 데이터셋만 학습하는 환경이면, 굳이 복잡한 푸리에 임베딩 대신 PE로 좋은 성능을 낼 수 있다.</li>
</ul>
<hr>
<h3 id="그럼-rope나-alibi를-적용할-수는-없는가">그럼 RoPE나 ALiBi를 적용할 수는 없는가?</h3>
<p><strong>GEMINI : &quot;기술적으로 적용은 가능하나, 왜 굳이 푸리에 임베딩을 고집했는지에 대한 이유는 명확하다.&quot;</strong></p>
<h4 id="rope-rotary-positional-embedding">RoPE (Rotary Positional Embedding)</h4>
<ul>
<li><strong>원리</strong>: 벡터를 회전시켜 상대적 위치 관계를 인코딩한다. 주로 LLM에서 긴 문맥 처리를 위해 사용한다.</li>
<li><strong>가능성</strong>: 이미지의 2D Grid에 맞춰 RoPE를 확장하면 충분히 가능하다. 시각적 특징 맵의 패치들 사이의 상대적 거리를 매우 효과적으로 잡아낼 수 있을 것이다.<h4 id="alibi-attention-with-linear-biases">ALiBi (Attention with Linear Biases):</h4>
</li>
<li><strong>원리</strong>: 위치 인코딩을 따로 더하지 않고, 어텐션 스코어에 거리에 비례하는 페널티(Bias)를 직접 준다.</li>
<li><strong>가능성</strong>: 구현이 매우 간결, 학습이 안정적이다. 이미지 패치 간의 원거리 의존성을 제어하는 데에 강력하다.</li>
</ul>
<hr>
<h4 id="논문-밖-개인-해석">논문 밖 개인 해석</h4>
<p>그럼 왜 해당 방법들 대신 푸리에를 사용했을까?
바로 &#39;목적&#39;과 &#39;성격&#39; 때문이라고 본다.</p>
<h4 id="1-연속성continuity의-차이"><strong>1. 연속성(Continuity)&#39;의 차이</strong></h4>
<ul>
<li><strong>RoPE/ALiBi</strong>: 이들은 본질적으로 &#39;이산적&#39;인 토큰 순서를 처리하는 데에 최적화되어 있다. 물론 2D로 확장할 수는 있어도, 기본적으로 어텐션 메커니즘 내부에서 위치 관계를 조정하는 방식이다.<br><br></li>
<li><strong>푸리에 임베딩</strong>: 이미지 분할은 픽셀이라는 &#39;연속적 공간&#39;에서 일어난다. 푸리에 임베딩은 입력 그 자체를 연속적인 함수 공간으로 변환한다. 즉, 인코더가 이미지를 읽어들일 때부터 &quot;이미지가 아니라 수학적 공간&quot;으로 인지하게 만드는 효과가 있다. 이것이 픽셀 단위의 부드러운 경계를 잡는 데에 유리하다.<h4 id="2-모델의-상태-frozen"><strong>2. 모델의 상태: Frozen</strong></h4>
이 논문의 모델은 CLIP과 같은 pre-trained 모델을 Frozen한 상태에서 사용한다.</li>
<li>RoPE나 ALiBi를 적용하려면 어텐션 연산 자체를 수정하거나, 인코더의 내부 레이어에 직접 개입해야 할 수도 있다.</li>
<li>반면, <strong>푸리에 임베딩은 인코더의 외부에서 특징 맵에 단순히 Addition만 하면 된다.</strong> 동결된 인코더를 전혀 건드리지 않고 공간 정보를 주입할 수 있는 가장 효율적인 방법이다.</li>
</ul>
<hr>
<h1 id="related-work">Related Work</h1>
<p>VLM이나 Open-vocabulary를 처음 다루는 나에겐 해당 개념들이 조금은 생소하기 때문에, 관련 연구들을 보다 자세히 알아보도록 하겠다.</p>
<h3 id="semantic-segmentation-of-unseen-categories">Semantic Segmentation of Unseen Categories</h3>
<p>여기서 Open-Vocabulary와 맞닿아 있는 <strong>Zero-shot</strong> 개념이 나온다.</p>
<ul>
<li><strong>기존의 한계</strong>: 대부분의 기존 접근법들은 사전에 정의된 카테고리 집합 안에서만 작동했기 때문에, 네트워크가 이전에 알지 못한 새로운 카테고리도 분할하도록 가르치는 것은 어려운 문제이다. </li>
<li><strong>Zero-shot의 등장</strong>: 이 문제를 해결하기 위해 &#39;Zero-shot semantic segmentation&#39;이 등장하였다. 이는 추가적인 훈련 데이터 없이 &#39;단어 임베딩&#39;을 사용하여 새로운 카테고리를 인식시키려는 시도이다.</li>
</ul>
<p>이전 연구들은 크게 단어 임베딩을 통해 새로운 카테고리의 시각적 특징을 만들어내는 <strong>생성적 방식(ZS3Net, CaGNet)</strong> 과 <strong>픽셀과 카테고리 이름을 공유된 공간에 매핑하는 판별적 방식(SPNet)</strong> 으로 나누어 연구해왔다.</p>
<h3 id="pre-trained-langauge-and-vision-models">Pre-trained Langauge and Vision Models</h3>
<p>여기가 바로 VLM이 무엇인지 이해할 수 있는 파트이다.</p>
<ul>
<li><strong>Self-supervised Learning의 성공</strong>: 최근 컴퓨터 비전(MoCo, DINO 등)과 자연어 처리(BERT, GPT 등)의 분야는 데이터 스스로 정답을 찾아가며 학습하는 <strong>자기 지도 학습</strong>을 통해 큰 발전을 이루었다.</li>
<li><strong>VLM(CLIP)의 등장</strong>: 대규모 VLM인 CLIP이 최근 큰 주목을 받았다. <strong>Contrasitve Learning</strong>을 통해 방대한 이미지와 텍스트 쌍을 훈련하여, 이미지와 텍스트를 공통된 벡터 공간에 성공적으로 정렬시켰다. </li>
</ul>
<p>이 논문은 각 작업을 위해 pre-trained 모델을 fine-tuning하는 대신, 가벼운 퓨전 모듈을 사전 학습된 시각 및 언어 모델과 통합하는 더 단순한 전략을 채택한다.</p>
<h3 id="fourier-embedding-for-positional-encoding">Fourier Embedding for Positional Encoding</h3>
<p>강력한 VLM을 가져왔으니, 이미지를 픽셀 단위로 쪼개는 Segmentation에 필요한 <strong>공간 정보</strong>를 어떻게 잘 처리할 것인가에 대한 이야기이다.</p>
<ul>
<li><strong>기존 Positional Encoding의 단점</strong>: 학습된 Positional Embedding은 훈려 데이터의 분포를 벗어나면 일반화하는 데 큰 어려움을 겪는다.</li>
<li><strong>푸리에 임베딩의 장점</strong>: 위에서 알아봤던 것과 같이, PE의 대안으로 떠오른다. 푸리에 기반은 PE에 대해 연속적이고 부드러운 인코딩을 제공한다.</li>
</ul>
<hr>
<h1 id="methodology">Methodology</h1>
<p>이 논문이 풀고싶은 문제는 <strong>open-vocabulary semantic segmentation</strong>으로, 일반 segmentation처럼 정해진 클래스만 분할하는 것이 아닌, 학습 때도 보지 못한 category 이름이 들어와도 텍스트 정보를 이용하여 해당 영역을 분할하려는 문제이다.</p>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/4295c714-710f-40e1-ab09-0e339be4b504/image.png" alt="">
파이프라인은 크게 3가지 영역으로 나눌 수 있겠다.</p>
<ol>
<li><p><strong>Visual Branch</strong>: 입력 이미지 $\rightarrow$ 푸리에 임베딩 추가 $\rightarrow$ FrozenVisualt Encoder (e.g., CLIP ViT) $\rightarrow$ visual/spatial feature 추출</p>
</li>
<li><p><strong>Language Branch</strong>: 카테고리 텍스트 $\rightarrow$ Fozen Text Encoder (e.g., CLIP Text Encoder) $\rightarrow$ 언어적 개념 추출</p>
</li>
<li><p><strong>Fusion Module</strong>: 두 브렌치의 특징을 받아 트랜스포머 레이어에서 상호작용, 최종적으로 픽셀별 점수 계산</p>
</li>
</ol>
<h3 id="a-problem-formulation">A. Problem Formulation</h3>
<p>Open-vocabulary 분할을 &quot;텍스트 쿼리 기반의 픽셀 분류 문제&quot;로 정의한다.
$$$
\text{DATA}_{\text{train}} = {(\mathcal X, \mathcal Y, \mathcal U) | \mathcal X \in \mathbb R^{H \times W \times 3}, \mathcal Y \in \mathbb R^{H \times W \times |\mathcal U|}, \mathcal U \subseteq \mathcal S }</p>
<p>$$$
여기서 $\mathcal X$는 입력 이미지, $\mathcal Y$는 segmentation mask, $\mathcal U$는 이미지 안에서 관측된 category 집합, $\mathcal S$는 전체 학습 category 집합이다.</p>
<blockquote>
<p>*&quot;We aim to train a segmentation model that separates a test image into significant areas of unexplored categories.*<br>
<strong>즉, 재현할 때의 목표는 단순 PASCAL의 20개 클래스를 맞추는 것이 아닌, 학습 category 밖의 unseen category에 대해서도 텍스트 이름을 주면 mask를 만들 수 있는 구조를 재현하는 것</strong>이다.</p>
</blockquote>
<p>여기서 중요한 점은 $\mathcal Y$가 $H \times W \times |\mathcal U|$라는 점인데, 모델은 사실상 category마다 binary mask를 예측하는 형태에 가깝다 (<strong>카테고리 개수만큼의 채널이기 때문</strong>). </p>
<pre><code>Y[:, :, 0] = dog mask
Y[:, :, 1] = cat mask
이런 식으로, dog mask는 각 픽셀에 대해 
&quot;이 픽셀이 dog인가?&quot; 를 0/1 로 표현한다.</code></pre><p>마지막에 class-wise thresholding과 sigmoid를 사용하는 이유도 이와 연결된다.</p>
<h3 id="b-visual-feature-extraction">B. Visual Feature Extraction</h3>
<p>이 단계는 모델이 이미지를 &quot;어떻게 이해하는가&quot; 알 수 있다.</p>
<blockquote>
<p><strong>이미지를 patch 단위 feature sequence로 바꾸고, 각 patch에 Fourier Positional Information을 더한 뒤, visual encoder로 보낸다.</strong></p>
</blockquote>
<ol>
<li><strong>입력 처리</strong>: 이미치는 Patch 단위로 나눈다.<pre><code>ViT 방식으로, non-overlapping 2D patch 들의 집합으로 나눈다.
예를 들어 이미지가 HxW, patch size가 p이면:
</code></pre></li>
</ol>
<p>H&#39; = H / p
W&#39; = W / p
N = H&#39; * W&#39;   # N은 패치 개수</p>
<p>CLIP ViT-B/16을 쓰면 보통 p=16, 224x224로 입력이 들어온다고 할 때:</p>
<p>H&#39; = 14
W&#39; = 14
N = 196</p>
<pre><code>2. **푸리에 임베딩 추가**: 앞서 논의한 푸리에 임베딩 $f(x, y)$가 위치 정보를 보강한다.
&gt;*&quot;Fourier embeddings are used to encode positional information.&quot;*
&lt;br&gt;**즉, 일반 ViT/CLIP처럼 학습된 PE를 그대로 쓰는 대신, patch의 좌표 `(x, y)`를 sinusoidal/Fourier Feature 로 변환해서 위치 정보를 준다는 뜻**이다.


$$$
x_{patch} = \text{LinearProjection}(Patch) + f_{emb}(x, y)
$$$ 
$$$논문에서는 X_i = x_i + f_{emb}(x, y)
$$$
&gt; 여기서 중요한 점은,
$x_i$ : $i$번째 image patch embedding,&lt;br&gt; $f_{emb}(x, y)$: patch grid 위치 $(x, y)$에 대한 푸리에 임베딩
$X_i$: 위치 정보가 더해진 최종 patch embedding
&lt;br&gt;인데, Fourier Embedding이 **learned positional embedding**이 아니라는 것이다. 좌표를 sin/cos 함수로 변환해서 만들기 때문에, 이미지 크기나 위치 변하에 좀 더 부드럽게 일반화될 수 있다고 보는 것이다.
&gt;&gt; 말이 나온 김에 **Fourier Embedding의 장점을 다시 살펴보자**
1. 좌표 기반이라 해상도 변화에 대응하기 쉬움
2. sin/cos 기반이라 위치 변화가 연속적
3. patch 간 상대적/공간적 구조를 부드럽게 표현
4. segmentation처럼 dense prediction이 필요한 task에 잘 맞는다.


3. **Frozen Encoder 통과**: 
$X_i = x_i + f_{emb}(x, y)$에서 $X_i$가 encoder에 들어간다. 
즉, 각 image patch embedding `x_i`에 **Fourier positional embedding `f_emb(x, y)`를 더해서 position-aware patch embedding**을 만든다.
&lt;br&gt;그 다음 이 $X_i$가 visual encoder로 들어간다.
$$$
F_i = \text{Vis}\_Enc((X_i)) \in \mathbb R^{\mathcal H\mathcal W \times d}
$$$
여기서 $\mathcal H = H/p, \mathcal W = W/p$ 이고, $p$는 patch size이다. 
output을 엄밀히 말하면 바로 `h x w x C` Feature Map이라기보다, 먼저
``` F_i ∈ R^{h*w × d} ``` 형태의 **patch token sequence**로 나온다고 보는 것이 맞다.
&gt;추가로 &#39;frozen&#39;의 의미는 `F_i`가 고정인 것이 아니라, `Vis_Enc`의 **parameter가 학습 중 업데이트 되지 않는다.**라는 뜻이다.
&lt;br&gt;입력 이미지가 달라지면 `F_i`도 달라지지만, 그 feature를 만드는 encoder 함수 자체는 사전학습된 상태로 고정된다.


### C. Textual Feature Extraction
카테고리 이름을 segmentation에 쓸 수 있는 벡터로 바꾸는 단계이다.

Visual branch가 이미지 patch들을 feature로 바꿨다면, Textual branch는 `dog`, `cat`, `person`과 같은 category name을 CLIP text encoder에 넣어 **text feature**로 만든다.

&gt;*&quot;Semantic categories (W) are encoded using a text encoder.&quot;*
즉, **입력은 이미지가 아니라 semantic category set**이다.

예를 들어 PASCAL-5i에서 현재 평가해야 할 class가 다음과 같다고 해보자.</code></pre><p>W = {dog, cat, person, car, chair}</p>
<pre><code>이때 모델은 각 단어를 그냥 문자열로 쓰지 않고, text encoder가 이해할 수 있는 자연어 prompt로 바꾼다. 논문은 예시 prompt로 다음을 말한다.
&gt;*&quot;a picture of a category within the context.&quot;*
조금 더 구현 친화적으로 쓰자면 이렇다.
*&quot;a picture of a dog within the context&quot;*
*&quot;a picture of a cat within the context&quot;*
*&quot;a picture of a person within the context&quot;*

**왜 굳이 prompt template을 쓰냐면, CLIP은 단어 하나보다 자연어 문장 형태의 입력에서 더 안정적인 의미 표현을 만들기 때문이다.** `dog`만 넣는 것보다 `a photo of a dog`, `a picture of a dog`처럼 넣는 것이 더 CLIP pretraining과 잘 맞는다.

$$$
F_W = \text{Text}\_Enc(W) \in \mathbb R^{|W|\times d}
$$$
$W$는 입력 category들의 집합, $F_W$는 각 category에 대한 text feature matrix이다.</code></pre><p>예를 들어 class가 5개이고, CLIP embedding dimension이 512이면, </p>
<p>F_W ∈ R^{5 × 512}로, 각 행이 하나의 category vector 이다.</p>
<p>F_W[0] = dog text feature
F_W[1] = cat text feature
F_W[2] = person text feature
...</p>
<pre><code>여기서 중요한 점은 **여러 prompt를 평균낸다**는 점이다. 논문은 text encoder가 만든 output embeddings를 average한다고 설명한다. 즉, `dog`에 대해 prompt를 여러 개 썼다면, 각 prompt에서 embedding을 뽑고 평균내서 최종 `dog` embedding을 만든다.

이렇게 하면 **특정 prompt 문장 하나에 과의존하지 않고, category 의미를 조금 더 안정적으로 표현 가능하다.**

&gt; #### 🔥 Text feature의 중요성
기존 semantic segmentation에서는 마지막 classifier가 고정된 class 개수만큼 예측한다.
&lt;br&gt;하지만, 이 논문에서는 text embedding`F_W`가 사실상 **동적으로 주어지는 classifier prototype처럼 작동**한다.</code></pre><p>visual pixel feature  &lt;-&gt;  text category feature</p>
<pre><code>를 비교해서 이 픽셀이 `dog`과 얼마나 비슷한지를 계산하는 구조가 되는 것이다.
&lt;br&gt;(*나중에 decoder 이후에는 pixel-level visual feature와 text feature 사이에 코사인 유사돌르 계산한다.*)
&lt;br&gt;그래서 **Textual Feature Extraction은 단순 텍스트 인코딩 보조 단계가 아니라, open-vocabulary가 가능해지는 핵심이다.** 새로운 클래스가 들어와도 classifier head를 다시 학습하는 게 아니라, 그 class name을 text encoder에 넣어 새로운 `F_W`를 만들면 되기 때문이다.

### D. MultiModal Embedding Fusion
이미지와 텍스트가 처음으로 서로를 보며 갱신되는 단계이다.

이전까지는 두 개의 branch: Visual branch, text branch 가 따로따로 움직였다.</code></pre><p>Visual branch:  image -&gt; F_i
Text branch:    category text -&gt; F_W</p>
<pre><code>
**D. Multimodal Embedding Fusion** 부터는 이 두 개의 branch를 합쳐서 visual feature가 text category를 의식하고, text feature도 image context를 반영하도록 한다.
&gt; *&quot;To align the visual and textual information, we use MLPs.&quot;*
**즉, MLP를 먼저 써서 visual feature와 text feature의 channel dimension을 맞춘다.**

#### 1. 입력 Feature
Visual Feature는 B절에서 나온다.
$$$
F_i \in \mathbb R^{\mathcal H \mathcal W \times d}
$$$
구현 관점에서는 batch를 포함하여:
$$$
F_i : [B, N, d_v]
$$$
$$$
N = \mathcal H * \mathcal W
$$$

Text Feature는 C절에서 나온다.
$$$
F_W \in \mathbb R^{|W| \times d}
$$$
구현 관점에서는:
$$$
F_W: [K, d_t]
$$$
여기서 `K = |W|`, 즉 입력 category 개수이다. batch를 처리할 때는 보통 image batch마다 같은 category set을 복제하여 $F_W: [B, K, d_t]$처럼 맞춘다.

#### 2. MLP로 channel dimension 정렬하기 
논문은 $F_i$와 $F_W$의 채널 차원을 맞추기 위해 MLP $\theta$를 사용한다고 한다.

예를 들어 visual encoder output이 768차원이고, text encoder output이 512차원이라면, fusion module에 넣기 전에 둘은 같은 차원 `C`로 맞춰야 한다.
$\tilde {F_i}: [B, N, C]$, $\tilde {F_W}: [B, N, C]$

CLIP 계열에서는 visual/text feature가 이미 같은 embedding dimension일 수도 있겠지만, 그래도 MLP를 쓰는 이유는 단순 차원 정렬뿐 아니라 **fusion에 적합한 feature space로 projection하기 위해**서라고 볼 수 있다.

#### 3. Visual token과 Text token을 결합하기 
$$$
[F_{i\_upd}, F_{w\_upd}] = Fuse(\theta[F_i, F_w])
$$$
이 식의 핵심은 $F_i$와 $F_W$를 하나의 multimodal token sequence로 만든 뒤, fusion module에 넣는다는 것이다.

구현적으로는 보통 token dimension 방향으로 concatenate 한다고 보면 된다.
&gt; ### 🤨 token dimension 방향으로 concat이요?
쉽게 말해 **이미지 patch token들과 텍스트 category token들을 한 줄짜리 sequence로 이어 붙인다는 뜻이다.**
&lt;br&gt;예를 들어 visual feature가 다음과 같이 생겼다고 가정하자.
```F_i.shape = [B, N_img, d]```
여기서 </code></pre><p>B      = batch size
N_img  = 이미지 patch 개수, 예: 16×16 = 256
d      = embedding dimension</p>
<pre><code>텍스트 feature는 category마다 하나의 token이라고 본다면, </code></pre><p>F_w.shape = [B, N_cls, d]</p>
<pre><code>이고, 예를 들어 category가 `{dog, cat, car}`이라면, </code></pre><p>N_cls = 3</p>
<pre><code>그러면, token dimension 방향 concat은?</code></pre><p>F = torch.cat([F_i, F_w], dim=1)
이 될 것이고, 
예를 들어 보자면,
|
F_i: [B, 256, 512]
F_w: [B, 3, 512]
|
concat 결과:
F:   [B, 259, 512]</p>
<pre><code>여기서 `dim=1`이 바로 **token dimension**또는, **sequence dimension**이다.

#### 4. Transformer encoder로 multimodal interaction 
논문은 fusion model이 *&quot;multiple transformer encoder layers&quot;*를 사용한다고 한다.

중요한 점은 이것이 꼭 cross-attention 전용 모듈이라기보다는, **visual token과 text token을 합친 뒤 transformer self-attention을 적용하는 방식**에 가깝다는 것이다.

self-attention 안에서는 모든 token이 서로를 볼 수 있다.

때문에 해당 단계 이후에는 visual feature가 더이상 순수 image-only feature가 아니다. 예를 들어 `dog`, `cat`이라는 text token들은 &quot;이 patch가 dog/cat과 관련이 있는가?&quot;라는 방향으로 갱신될 수 있다.

반대로 text feature도 image context를 반영하여 갱신된다.</code></pre><p>F_i      -&gt; F_i_upd
F_W      -&gt; F_w_upd</p>
<pre><code>
#### 5. 다시 visual/text feature로 분리 
Transformer encoder를 통과한 output은 여전히 
`[B, N+K, C]` 형태이다. 이것을 앞부분과 뒷부분으로 나눈다.</code></pre><p>F_i_upd = Z_out[:, :N, :]     # updated visual features
F_w_upd = Z_out[:, N:, :]     # updated text features</p>
<pre><code>결과적으로 shape은 원래와 비슷해진다.

논문도 *&quot;fused visual and text features resemble the originals in shape&quot;*라고 설명한다. 즉, shape는 유지되지만, 내용은 서로의 modality를 참고해서 갱신된 상태이다.

&gt; ### 왜 이 단계가 중요할까? 🧐
이 fusion module이 없으면 visual feature와 text feature는 각각 frozen encoder에서 나온 독립적인 표현이다. CLIP이 이미 image-text alignment를 어느 정도 학습했지만, segmentation에서는 image-level alignment 만으로는 한참 부족하다.
&lt;br&gt;segmentation은 pixel/patch 단위로 판단해야 하기 때문이다.
&lt;Br&gt;**따라서 visual feature와 text feature가 dense prediction에 맞게 한 번 더 상호작용 해야한다. 이 역할을 하는 것이 Multimodal Embedding Fusion**이다.
&gt;&gt; **조금 더 쉽게 풀어보자면...**
  앞 단계까지는 이미지와 텍스트가 따로 놀았다.</code></pre><p>  이미지 encoder: &quot;이 사진에는 이런 모양, 질감, 위치의 patch들이 있어.&quot;
텍스트 encoder: &quot;&#39;dog&#39;는 이런 의미를 가진 단어야.&quot;</p>
<pre><code>  그런데 segmentation을 하려면, 단순 이미지 전체가 dog와 관련이 있는 것이 아니라, &quot;어느 픽셀이 dog인가?&quot;, &quot;어느 부분은 background인가?&quot;를 판별해야한다.
  &lt;br&gt;
  CLIP과 같은 VLM은 원래 이미지 전체와 텍스트 전체를 맞추는 데에 강하다. 예를 들어 이미지 한 장과 `&#39;A dog&#39;`이라는 문장이 잘 어울리는지는 잘 판단한다. **하지만, segmentation은 훨씬 더 세밀하다.**</code></pre><p>  이미지 전체와 dog가 어울린다.                 - X
  |
  왼쪽 아래 patch는 dog와 어울린다                 - O 
오른쪽 위 patch는 background와 어울린다        - O 
가운데 patch는 cat과 어울린다.                - O </p>
<pre><code>그래서 Fusion Module이 필요한 것이다.
  Fusion 전에는 visual feature가 다음과 같은 상태라고 할 수 있다.</code></pre><p>  patch 1: 털 같은 texture
patch 2: 둥근 귀 모양
patch 3: 배경 잔디
patch 4: 고양이 얼굴 일부</p>
<pre><code>  text feature는 이런 상태이다. </code></pre><p>  dog: 개라는 개념
cat: 고양이라는 개념
background: 배경이라는 개념</p>
<pre><code>  Fusion Module은 이 둘을 같이 transformer에 넣어서, 각 patch가 category text를 참고하게 만든다. 
  그러면 visual feature가 이렇게 바뀌는데..</code></pre><p>  patch 1: 털 texture + dog/cat 후보와 비교된 정보
patch 2: 귀 모양 + dog와 더 관련 있음
patch 3: 잔디 texture + background와 더 관련 있음
patch 4: 얼굴 일부 + cat과 더 관련 있음</p>
<pre><code>  즉, **단순한 visual feature가 아니라 text-aware visual feature가 된다.**
  반대로 text feature도 image를 참고해서 조금 더 현재 이미지에 맞게 조정된다.
  &lt;br&gt;정리하자면, **CLIP이 아는 &quot;dog&quot;와 이미지 속 patch들을 그냥 비교하는 것이 아니라, 현재 이미지 안에서 &quot;dog일 가능성이 있는 영역&quot;을 서로 맞춰보며 feature를 갱신하기 때문이다.


### E. The Hierarchical Visual Decoder

지금까지의 흐름을 다시 보자면, </code></pre><p>  B. Visual Feature Extraction
이미지 -&gt; patch-level visual feature F_i</p>
<p>C. Textual Feature Extraction
category text -&gt; text feature F_W</p>
<p>D. Multimodal Embedding Fusion
F_i, F_W -&gt; updated visual/text feature
          -&gt; F_i_upd, F_w_upd</p>
<pre><code>이제 **E. The Hierarchical Visual Decoder**에서는 이 $F_{i\_upd}$와 $F_{w\_upd}$를 가지고 **실제 segmentation mask를 만드는 과정**을 설명한다.
![](https://velog.velcdn.com/images/jm_mg_se/post/8ec1a3ff-68a0-43d9-8ace-c828da225d09/image.png)

  핵심은 크게 4가지 단계이다.
- **Updated visual feature를 feature grid로 변환하기**
- **decoder가 visual feature를 점진적으로 upsampling**
- **upsampled visual feature와 text feature를 코사인 유사도로 비교하기**
- **thresholding + temperature sigmoid로 최종 mask 생성하기**

즉, 이제부터는 &quot;이미지와 텍스트를 어떻게 이해했는가&quot;가 아닌, **그 이해를 어떻게 pixel-level mask로 바꾸는가?**의 문제이다.
  &gt; *&quot;The decoder gives us the visual feature map, which is progressively upsampled to match the resolution of the input image.&quot;*
  &lt;br&gt;patch-level feature는 원본 이미지보다 해상도가 낮다. 예를 들어 `224x224`이미지를 `16x16` patch로 나누면 visual feature는 `14x14` grid이다. **그런데 segmentation mask는 원본 이미지처럼 `224x224`에 가까워야 한다.**

  그래서 decoder가 필요하다.</code></pre><p>  [B, C, 14, 14]
 -&gt; decoder / upsampling
 -&gt; [B, C, 224, 224]</p>
<p>  ```</p>
<blockquote>
<p>*&quot;The upsampled visual features are compared with the textual features using cosine similarity.&quot;*
  <br><strong>즉, 각 pixel 위치의 visual feature와 각 category text feature를 비교</strong>한다.
  <br>*&quot;Using class-wise thresholding and a sigmoid with a temperature.&quot;*
  <br><strong>즉, category별 threshold와 temperature-scaled sigmoid를 사용해서 최종 binary segmentation을 만든다.</strong></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 논문 리뷰 ] CrackSSM: Reviving SSMs for Crack Segmentation via Dynamic Scanning]]></title>
            <link>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-CrackSSM-Reviving-SSMs-for-Crack-Segmentation-via-Dynamic-Scanning</link>
            <guid>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-CrackSSM-Reviving-SSMs-for-Crack-Segmentation-via-Dynamic-Scanning</guid>
            <pubDate>Thu, 18 Jun 2026 14:58:49 GMT</pubDate>
            <description><![CDATA[<p>기존의 Crack Segmentation 연구들은 최근 선형 복잡도로 장거리 의존성을 모델링할 수 있는 Mamba 구조를 채택해 왔다. 하지만 기존 방식에는 다음과 같은 치명적 한계가 있었다.</p>
<hr>
<p>균열은 일반 객체와 달리 정형화되지 않은 복잡한 형태를 가진다. 또한 도로 아스팔트와 같은 배경 속에서 파묻혀 있는 경우가 많아 전통적인 객체 탐지 기법으로는 판별하기 어렵다.</p>
<h3 id="문제의식-cnn의-한계">문제의식: CNN의 한계</h3>
<p>CNN에 기반한 초기 Crack Segmentation 모델들은 국소적 패턴에 집중하여 어느정도 합리적인 결과를 냈지만, CNN의 한계인 제한된 Receptive Field로 인해 균열의 전역적 연속성을 모델링하는 데에 어려움이 있었다.</p>
<h3 id="문제의식-트랜스포머의-한계">문제의식: 트랜스포머의 한계</h3>
<p>Transformer 기반 모델들 또한 한계가 존재하는데, 고해상도나 실시간 환경에서의 확장성이 <em>Quadratic Complexity</em>에 의해 제한되었다. (해당 복잡도는 self-attention으로 제곱에 비례하게 복잡도가 증가한다.)</p>
<p>이 두 측면에서의 단점을 보완하기 위해 SSM(space state model)이 해결책으로 제안되었다.</p>
<p>그 중 <em>Selective State Space</em> 매커니즘을 기반으로 하는 <strong>Mamba</strong>는 linear time complexity를 가진다. ($O(N)$)</p>
<blockquote>
<h3 id="기존-ssm의-한계와-selective의-중요성">기존 SSM의 한계와 Selective의 중요성</h3>
<p>기존의 선형 SSM(Linear SSM)은 시계열 데이터나 텍스트를 처리할 때 <strong>시간에 독립적인 행렬에 따라 과거의 정보를 압축하여 &#39;상태(State)&#39;로 유지</strong>했다. 이에 따른 장점과 단점은 다음과 같다.</p>
</blockquote>
<ul>
<li><strong>기존 SSM의 장점</strong>: 연속적인 시스템을 모델링하므로, RNN처럼 이전 상태만 기억하면 되어 추론 속도가 매우 빠르고 매모리가 적게 소모된다.</li>
<li><strong>기존 SSM의 단점</strong>: 입력 내용에 상관없이 <strong>항상 동일한 방식으로 정보를 축적하고 흘려보낸다.</strong> 때문에 어떠한 정보가 중요하고, 어떠한 정보가 덜 중요한지를 문맥에 맞게 Select하지 못하였다. <em>이로인해 언어 모델링처럼 맥락이 중요한 Task에서는 성능이 크게 떨어졌다.</em><h3 id="mamba의-핵심-selective-state-space">Mamba의 핵심: Selective State Space</h3>
Mamba 논문의 연구진들은 기존 SSM의 행렬들을 &quot;입력 데이터에 의존하는 함수&quot;로 만들었는데, 이것이 바로 <strong>Selective SSM</strong>이다.<Br>
트랜스포머가 Attention을 통해 단어간의 연관성을 &#39;선택적&#39;으로 보는 것처럼, Mamba는 <strong>현재 들어온 입력 단어를 보고 <em>상태 공간 행렬($B, C$)와 시간 보폭($\Delta$)</em>를 실시간으로 계산</strong>한다.
<br>중요한 정보가 들어오면, 시간 보폭($\Delta$)를 작게 설정하여 현재 정보를 강력하게 State에 반영하고 오랫동안 기억한다. 덜 중요한 정보가 들어오면 시간 보폭($\Delta$)를 크게 하거나 가중치를 줄여 정보를 필터링하고 흘려보낸다.<h3 id="그럼-이게-왜-linear-time-complexity">그럼 이게 왜 Linear Time Complexity?</h3>
논문에서 Mamba가 Linear한 Time complexity를 가진다고 하였는데, 이는 <strong>문장이 아무리 길어져도 연산량과 메모리가 그에 비례하여 완만하게만 증가하며, 동시에 아주 멀리 있는 정보도 놓치지 않고 기억할 수 있다</strong>라는 뜻이다. 이는 두 가지 구조로 가능한데, </li>
</ul>
<ol>
<li>*<em>Recurrent와 Convolution의 하이브리드 구조 *</em></li>
</ol>
<ul>
<li>학습할 때에는 전체 문장을 한 번에 계산하는 병렬 연산으로, GPU의 호환성을 극대화한다. ($O(N)$)수준의 고속 학습이다.<ul>
<li>추론할 때에는 이전 핵심 정보만 압축된 고정 크기의 State만 참조하므로, 문장의 길이가 아무리 길어져도 단어 하나를 뱉는 속도가 일정하다.</li>
</ul>
</li>
</ul>
<ol start="2">
<li><strong>Hardware-aware SRAM/HBM의 이중화</strong></li>
</ol>
<ul>
<li>Selection 매커니즘으로 입력에 따라 행렬이 계속 바뀌면 GPU 메모리 전송 속도가 느려지는 고질적 문제가 있다. Mamba는 이를 <strong>SRAM와 HBM사이의 데이터 이동을 최소화</strong>하는 커널을 설계했다고 한다. <br><strong>아니 잠시만... 이거 어디서 많이 익숙한데...</strong><br><p align="center"><img src="https://velog.velcdn.com/images/jm_mg_se/post/e85cc667-9472-49a6-a9bc-a0038db0a1c5/image.jpg" height="70%" width="70%"></p>

</li>
</ul>
<blockquote>
<p> <strong>유레카!! Flash Attention이랑 같은 아이디어인 것이다!</strong>
그런데 적용 대상이 Attention Map($O(N^2)$)이냐, SSM Scan 연산($O(N)$)이냐의 차이라고 한다.
Mamba는 이만 여기까지만 알아보고.. 이어서 계속 CrackSSM을 알아보자. (Mamba는 추후 아예 리뷰를 진행 예정이다.)</p>
</blockquote>
<p>VMamba는 Mamba를 시각 도메인으로 확장한 것인데, 2D Feature Map을 여러 공간 축을 따라 1D 시퀸스로 Flatten하는 <strong>다방향 스캐닝</strong>을 한다고 한다. 이 스캐닝 방식은 단방향 SSM보다 더 많은 공간적 맥락을 보존한다.</p>
<p>이러한 아이디어를 바탕으로 Crack Segmentation(CS)를 연구하고 있는데, <strong>SCSegamba는 대각선 형태의 뱀 모양 스캔 경로를 도입</strong>하고 균열 분석을 위한 경량 인코더에 SSM을 통합한다.</p>
<blockquote>
<h4 id="vmamba와-scsegamba의-한계">VMamba와 SCSegamba의 한계</h4>
<p>  사실 1D Sequence로 변환하기 위해 사용하는 고정된 다방향 스캐닝도 <strong>곡선 또는 단절된 균열의 경우 공간적 연속성을 방해</strong>하여 S6의 인과 모델링 능력을 약화시킨다.</p>
</blockquote>
<hr>
<blockquote>
<h3 id="여기서-가질-수-있는-질문은-다음과-같다">여기서 가질 수 있는 질문은 다음과 같다.</h3>
<p>  <strong>1. 원래 이미지의 고주파 성분을 활용하는 웨이블릿 기반 디코딩 메커니즘이 미세 균열의 상세 표현을 개선하고 노이즈를 억제하여 분할 정확도를 높일 수 있는가?</strong><br>
  <strong>2. 동적 스캐닝 및 웨이블릿 변환을 통합한 모델이 기존 SOTA 대비 더 적은 파라미터와 빠른 추론 속도로 우수한 균혈 분할 정확도를 달성할 수 있는가?</strong>
  <br>위 질문에 집중하며 논문을 읽어보자.</p>
</blockquote>
<h2 id="이론적-배경-및-연구-모형">이론적 배경 및 연구 모형</h2>
<h3 id="핵심-이론--원리">핵심 이론 &amp; 원리</h3>
<p>  본 연구는 <strong>State Space Models (SSMs)</strong>, 특히 Mamba의 S6 메커니즘을 기반으로 한다. SSM은 시퀸스 데이터 모델링에 강력하며, 선형 시간 복잡도로 Long range Dependency를 효율적으로 포착할 수 있다. </p>
<p>  그러나 2D Feature Map을 1D 시퀸스로 Flatten할 때 고정된 스캐닝 경로를 사용하면 공간적 연속성이 깨져 불규칙한 균열 패턴을 효과적으로 모델링하기 어렵다. </p>
<p>  CrackSSM은 이러한 한계를 극복하기 위해 <strong>동적 토큰 재정렬(Adaptive Token Reordering, ATR)</strong>전략을 도입하여 균열 관련 영역이 1D Sequence에서 인접하게 유지되도록 토큰 순서를 재정렬한다. </p>
<blockquote>
<h3 id="atr에-대해서-조금-더-알아보자">ATR에 대해서 조금 더 알아보자.</h3>
<p>  ATR 덕분에 Mamba의 S6 모듈은 고유의 장점인 <em>&#39;선형 연산 효율성&#39;</em>을 그대로 유지하면서도, 파편화된 균열 패턴 사이의 인과 관계를 훨씬 더 강하게 모델링하는 것이다.<br>
    재정렬을 거치고 나면, 실제 2D 이미지 공간에서 의미적으로 연결되어 있는 균열 영역의 픽셀들이 1D 시퀸스 상에서도 서로 <strong>Adjacent</strong>하게 위치한다.</p>
</blockquote>
<h3 id="이것이-dpsmdynamic-path-scanning-mamba-모듈의-핵심이다"><strong>이것이 DPSM(Dynamic Path Scanning Mamba)</strong> 모듈의 핵심이다.</h3>
<p><strong>1. Directional Response Intensities</strong>
고정된 스캔 순서가 아닌, High-level Feature로부터 방향성 응답 강도를 계산한다. 이 때 보는 4가지 방향은 Wavelet 변환의 LL, LH, HL, HH와는 다르니 주의한다.</p>
<pre><code class="language-&lt;br&gt;"></code></pre>
<table>
<thead>
<tr>
<th align="center"><center>구분</center></th>
<th align="center">DPSM의 4방향 (Encoder)</th>
<th align="center">Haar Wavelet (Decoder)</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><strong>목적</strong></td>
<td align="center">균열이 어느 각도로 흐르는가? (경로 탐색)</td>
<td align="center">어디에 픽셀 경계가 있는가? (선명도 복원)</td>
</tr>
<tr>
<td align="center"><strong>구성</strong></td>
<td align="center">수평, 수직, 대각선1, 대각선2</td>
<td align="center">LL(저주파), LH(수평), HL(수직), HH(대각선 통합)</td>
</tr>
<tr>
<td align="center"><strong>대각선</strong></td>
<td align="center">2개로 분리 (좌/우 기울기 구분)</td>
<td align="center">1개로 통합 (HH)</td>
</tr>
<tr>
<td align="center"><strong>저주파</strong></td>
<td align="center">없음 (뻗어가는 방향만)</td>
<td align="center">LL로 존재 (WGM에선 안씀)</td>
</tr>
<tr>
<td align="center">---</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center"><strong>2. Token Reordering</strong></td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center">계산된 방향성 단서들은 1D 토큰 시퀸스를 재정렬하는 데 핵심적인 가이드 역할을 한다. 의미론적으로 연관되고 공간적으로 연결된 균열 영역들이 1차원 배열 상에서도 서로 Adjacent하게 보장하도록 한다.<br></td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center">- 일반적인 모델들이 <code>[B, C, H, W]</code> 텐서를 단순 Flatten하여 <code>[B, C, L]</code> 형태로 순서대로 펴버린다면, CrackSSM은 앞서 구한 방향성 가중치를 기준으로 <code>argsort</code>같은 정렬 연산을 수행한다.<br></td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center">----</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center"><strong>3. 선형 효율성과 인과 모델링의 결합</strong></td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center">스캐닝 경로를 균열의 본질적 규조와 딱 맞게 정렬시켜, S6 모듈은 파편화된 균열 패턴들 사이의 인과적 종속성을 더 잘 포착한다.</td>
<td align="center"></td>
<td align="center"></td>
</tr>
</tbody></table>
<p>  또한 <strong>웨이블릿 변환(Haar Wavelet Transform)</strong>의 고주파 성분을 활용한다. 웨이블릿 변환은 이미지를 저주파와 고주파 성분으로 분해하여, 고주파 성분이 미세한 균열 엣지 표현에 유용하다.</p>
<blockquote>
<p>Decoder에서는 Feature Map을 Upsampling하는데, 기존의 일반적 업샘플링 방식은 얇거나 주변과의 대비가 낮은 미세한 균열의 경계선을 흐릿하게 블러처리하는 단점이 있다.<br>
  <strong>때문에 형태의 충실도를 높이고 이미지의 경계선이나 질감 등 급격하게 변하는 픽셀 정보(고주파)를 분리하기 위해 Haar Wavelet 변환을 사용했다.</strong><br></p>
</blockquote>
<h3 id="왜-dwt가-아닌-haar-wavelet-변환인가">왜 DWT가 아닌 Haar Wavelet 변환인가?</h3>
<p>기존 SOTA보다 효율적인 모델을 만드는 것이 목표이기도 하고, DWT를 쓰면 모델이 묵워진다. DWT 기법 중에서도 모델의 효율성과 균열의 형태에 가장 잘 맞는 필터를 사용한 것이다.</p>
<hr>
<h1 id="framework">Framework</h1>
<p>  CrackSSM은 세 가지 stage로 구성된다. <strong>인코딩 단계(Encoding Stage), 특징 강화 단계(Feature Enhancement Stage), 디코딩 단계(Decoding Stage)</strong>.
  <img src="https://velog.velcdn.com/images/jm_mg_se/post/2603974f-07d0-4d37-837b-eca4d77a2a6f/image.png" alt=""></p>
<h2 id="encoding-stage">Encoding Stage</h2>
<p>  인코딩 단계에서는 주로 입력 이미지에서 다중 스케일 특징을 추출한다. 특징 추출의 효율을 위해, 연구진들은 <strong>바닐라 VSS</strong> 기반 백본을 사용했다.</p>
<blockquote>
<p> <strong>바닐라 VSS</strong>는 VMamba 논문에서 제안된 아키텍처로, ResNet, Swin-T 등 비전 백본과 유사하게 총 4개의 Feature Extraction Stage로 구성되어있다. </p>
</blockquote>
<ul>
<li>입력 이미지 ($3 \times H \times W$)가 각 스테이지를 통과할 때마다 Spatial 해상도는 가로세로가 각각 절반으로 줄어들고 ($\frac{H}{2} \times \frac{W}{2}$), 특징 채널 수는 기본 채널 수 $C$를 기준으로 배수($C \rightarrow 2C \rightarrow 4C \rightarrow 8C$)로 확장된다.</li>
<li>이 과정을 통해 모델은 저수준의 정밀한 경계선 Feature부터 고수준의 풍부한 의미론적 Feature까지 다루는 <strong>멀티스케일 특징 맵의 집합$(F_1^{enc}, F_2^{enc}, F_3^{enc}, F_4^{enc})$를 계층적으로 얻는다.</strong><br>
**SS2D 매커니즘**: VSS 블록의 핵심 연산으로, 1차원 순차 데이터에 종속적이었던 기존 Mamba의 S6 알고리즘을 2D 이미지 특징 구조에 맞게 변환해 주는 가교 역할을 한다.
>>#### SS2D 매커니즘
텍스트와 달리 이미지는 사방으로 정보가 나열된 2D 평면이므로 인과적 방향성이 고정되어 있지 않다. 단순 이미지 픽셀을 좌측 상단부터 우측 하단 방향으로 일렬로 펴서 1D 시퀸스로 변환하면, **2D 평면상에서 세로축으로 바로 위아래 붙어있던 인접 픽셀들이 1D 시퀸스 상에서는 엄청나게 멀리 떨어지게 되는 공간적 연속성 파괴 문제**가 발생한다.<br><br>⚠️ **ViT의 패치화랑 헷갈리지 않도록 주의한다.** 패치화는 원본 이미지를 깍둑기로 만드는 것이지만, VSS의 Flattening은 CNN을 거친 Feature Map이며, 1x1 픽셀이다.
![](https://velog.velcdn.com/images/jm_mg_se/post/606fe9db-3cab-49fb-8e26-a19866a8aca5/image.gif)이를 해결하기 위해 VSS의 SS2D 매커니즘은 '고정된 4가지 방향의 스캐닝 경로'를 수행하여 공간 왜곡을 상쇄한다.
>>  - **스캔 1 (Horizontal Forward)**: 좌상단 $\rightarrow$ 우하단 방향으로 가로축 중심 순방향 스캔
>>  - **스캔 2 (Horizontal Backward)**: 우하단 $\rightarrow$ 좌상단 방향으로 가로축 중심 역방향 스캔
>> - **스캔 3 (Vertical Forward)**: 좌상단 $\rightarrow$우하단 방향으로 세로축 중심 순방향 스캔
>> - **스캔 4(Vertical Backward)**: 우하단 $\rightarrow$ 좌상단 방향으로 세로축 중심 역방향 스캔

</li>
</ul>
<h3 id="vss-layer">VSS Layer</h3>
<p>  VSS Layer 내부에서는 다음과 같은 연산이 이루어진다.</p>
<ul>
<li><p>SS2D는 하나의 2D Feature Map을 위 4가지 규칙에 맞춰 각기 다른 <strong>4개의 독립된 1D 토큰 시퀸스</strong>로 펼친다.</p>
</li>
<li><p>그 후, 각각의 시퀸스를 개별 <strong>S6 SSM 블록(VSS Layer 내부에 있음: 4개)</strong>에 병렬로 통과시켜 전역적 맥락을 병렬적으로 연산한다. </p>
<ul>
<li>연산이 완료되면 역순으로 시퀸스들을 다시 원래의 2D 좌표에 맞춰 복원(Unflatten)한 뒤, 하나로 병합하여 최종 Feature Map을 만든다.</li>
</ul>
<p>VSS Layer 4에서 나온 최상위 Feature Map ($F_4^{enc}$)는 의미론적 정보는 풍부하지만, 무엇이 어디에 있는지에 대한 위치 정보는 떨어진다. 이 Feature Map을 $F_{dir}$로 깎아내기 위해 두 가지 과정을 거친다.</p>
</li>
</ul>
<h2 id="enhancement-stage">Enhancement Stage</h2>
<h3 id="f_dir-f_dir을-이용한-보조-손실함수">$F_{dir}, F_{dir}&#39;$을 이용한 보조 손실함수</h3>
<p>  <code>Coord Conv</code>와 <code>DWConv</code>를 이용하여 좌표 정보를 덧입히고 채널을 4개로 압축하여, 균열이 수평, 수직, 대각선(2개) 중 어느 방향으로 뻗어 있는지 알려주는 4채널 방향성 맵 ($F_{dir}$)을 만든다.
**  - <code>Coord Conv</code> (Coordinate Convolution)*<em>: 일반적인 합성곱 (CNN)은 &#39;형태&#39;는 잘 보지만 &#39;위치&#39;는 잘 모른다는 단점이 있다. CoordConv는 입력 Feature Map에 $x, y$ 좌표 채널을 물리적으로 끼워 넣는다.
$\rightarrow$ 모델이 어느 위치에서 어느 패턴을 보고 있는지 공간적 좌표 감각을 갖게 한다.<br>
*</em>  - <code>DWConv</code> (Depth-wise Convolution): **공간 감각을 얻은 $8C$ Feature Map을 $4C$의 가볍고 효율적인 Feature Map으로 압축한다. ($F_{dir}$ 완성)</p>
<p>  *<u>이 $F_{dir}$는 하위 레이어인 Layer 1, 2, 3에 배치된 각각의 <code>DPSM Module</code>로 들어가게 된다.*</u></p>
<p>  이후 Softmax를 $F_{dir}$에 <strong>Channel-wise로 하나의 픽셀 위치에서 4개의 채널에 대해 적용한다.</strong> 즉, &quot;이 픽셀 안에서 수평일 확률, 수직일 확률을 계산하는 것이다.</p>
<p>  이 $F&#39;_{dir}$는 네트워크의 다음 레이어로 넘어가는 게 아니라, <strong>Cross-Entropy Loss 계산</strong>으로 직행한다. GT에 Sobel 커널을 씌워서 만든 진짜 방향 정답지인 $G&#39;{dir}$와 비교해서 오차를 계산한다.</p>
<blockquote>
<h4 id="dpsm에-fdir가-아닌-fdir을-넣는-이유는">DPSM에 $F&#39;<em>{dir}$가 아닌 $F</em>{dir}$을 넣는 이유는?</h4>
</blockquote>
<ol>
<li>Softmax를 채널에 대해 적용한다고 했다. <strong>균열이 교차</strong>하는 지점을 생각해보자. 가로 세로의 확률이 50:50으로, <strong>절대적 수치가 반토막</strong>난다. 
<br>토큰을 재정렬하는 DPSM은 <strong>픽셀의 응답 강도(Intensity)가 전체 이미지에서 얼마나 강한지, 절대적 신호의 세기가 필요한 것이다.</strong> 때문에 $F_{dir}$을 사용한다.   <br><br></li>
<li><strong>공간적 정렬의 기준</strong>
논문의 수식 (2)를 보면 $\hat \mathcal{P}<em>k = Sort(\mathcal{P}_k, key = F</em>{dir})$이라고 되어있다. 이 $Sort$는 $k$번째 방향에 대해 이미지 전체 픽셀들의 순위를 매긴다. 
<br>만약 확률값인 $F&#39;_{dir}$을 기준으로 $Sort$하면 전체적으로 신호가 약한 배경 픽셀이더라도 우연히 상쇄하는 신호가 더 약해서 수평 확률이 높게 찍히면 정렬 최상단으로 올라오는 오류가 발생한다.</li>
</ol>
<h3 id="dpsm-block">DPSM Block</h3>
<p>  DPSM Block을 알아보기 전에, 텐서 차원을 한 번 정리하고 넘어가자.</p>
<ul>
<li><p><strong>($F_{dir}$)</strong>: VSS Layer 4에서 만들어져, 가로세로 크기가 ($\frac{H}{32} \times \frac{W}{32}$)로 아주 작다.</p>
</li>
<li><p><strong>($F^{enc}_i$) - 현재 Feature Map</strong>: 예를 들어 Layer 1에서 넘어온 Feature Map이면 ($\frac{H}{4} \times \frac{W}{4}$)로 훨씬 크다.
이 둘이 융합되어야 하기 때문에 $F_{dir}$을 DPSM 내부에서 사용하기 직전, 현재 들어온 $F_i^{enc}$의 해상도에 맞춰 Upsampling한다. <code>F.interpolate</code>로 $x, y$의 텐서 크기를 맞추는 것이 중요하다.</p>
<p>DPSM은 동적 경로 계획 접근 방식을 사용하여 초기 고정 경로 시퀸스를 재정렬한다. 이는 4가지 주요 방향(수평, 수직, 대각선(x2))을 따라 균열이 얼마나 강하게 표현되는지 나타내는 방향성 응답 강도를 계산하여 토큰 순서를 재정렬한다. 이를 통해 공간적으로 연관된 균열 영역이 1D 시퀸스에서 인접하게 유지되어 S6의 인과 모델링 능력을 향상시킨다,</p>
<h4 id="📌-atr-adaptive-token-reordering">📌 ATR: Adaptive Token Reordering</h4>
<p>$\hat \mathcal{P}<em>k = Sort(\mathcal{P}_k, key = F</em>{dir})$, $k = 1, 2, 3, 4$</p>
</li>
<li><p>$F_{dir}$은 4개의 채널을 가지고 있다. 1단계에서 만든 4개의 시퀸스 $\mathcal{P}<em>k$에 각각 $F</em>{dir}$의 채널 하나씩을 1:1로 매칭한다.</p>
<ul>
<li>해당 채널에 들어있는 응답 강도 수치(Intensity Values)를 Key로 삼아, 1D 시퀸스의 토큰 순서를 재배열한다.</li>
</ul>
</li>
<li><p><strong>결과적으로 강한 방향성 응답을 가진 토큰들이 시퀸스 내에서 더 가깝게 모인다.</strong> 재정렬된 4개의 새로운 시퀸스는 ${\hat \mathcal{P}<em>k}^4</em>{i=1}$이라고 한다.</p>
</li>
</ul>
<h4 id="📌-s6-인과-모델링-intra-sequence-token-modeling">📌 S6 인과 모델링 (Intra-Sequence Token Modeling)</h4>
<p>${\hat \mathcal{P}<em>k}^4</em>{i=1}$를 각각 독립적인 S6블록(Mamba의 핵심 연산 모듈)에 통과시킨다.
  $$
  \bar \mathcal{P}_k = S6(\hat \mathcal{P}_k)
  $$</p>
<ul>
<li>토큰들이 의미적으로 연결되어, S6는 이전 토큰의 정보를 바탕으로 다음 토큰을 예측하는 인과 모델링(Casual Modeling)을 아주 쉽게 수행한다. 이 과정을 거쳐 <strong>강화된 시퀸스 ${\bar \mathcal{P}<em>k}^4</em>{i=4}$가 탄생한다.</strong></li>
</ul>
<h4 id="📌-spatial-restoration--merging">📌 Spatial Restoration &amp; Merging</h4>
<p>  1D Sequence 연산이 끝났으니, 다시 2D 이미지를 처리해야 한다.</p>
<ul>
<li><strong>Unflatten</strong>: S6를 통과한 1D 시퀸스들을 2단계에서 정렬했던 것의 정확한 역순으로 다시 풀고, 2D 픽셀 좌표에 맞게 매핑하여 4개의 2D 피처맵 ${F_{pi} }^4_{k=1}$를 재구성한다. </li>
<li><strong>Merge</strong>: 복원된 4개의 Feature Map을 채널 차원으로 Concat하고, Point-wise convolution을 통해 정보를 하나로 융합하여 $F_{merge}^i$를 만든다.
$$
F_{merge}^i = Pointconv(Concat(F_{p1}, F_{p2}, F_{p3}, F_{p4}))
$$</li>
</ul>
<h4 id="📌-se-block--residual">📌 SE Block &amp; Residual</h4>
<p>  마지막으로 Feature map의 퀄리티를 한 번 더 올리는 작업을 한다.</p>
<ul>
<li><p><strong>SE Block (Squeeze-and-Excitation)</strong>: $F_{merge}^i$를 SE블록에 통과시킨다. 이 모듈은 균열 검출에 중요한 특징을 담고 있는 채널의 가중치는 올리고, 불필요한 노이즈는 Squeeze 하여 채널을 Adaptive Weighting. 미세조정 한다.</p>
</li>
<li><p><strong>Residual Connection</strong>: 마지막으로 이 결과값에 처음 들어온 원본 $F_i^{enc}$를 더해주는 Residual structure를 진행한다.</p>
</li>
</ul>
<p>이 모든 과정을 거치고 나면, 모델이 균열 특징을 완벽히 잡을 수 있는 강화된 최종적인 피처맵 ${ \hat F_i^{enc} }^3_{i=1}$이 탄생한다.</p>
<hr>
<h2 id="decoding-stage">Decoding Stage</h2>
<p>  U-Net 구조를 살펴보면 디코딩이 보통 <code>Upsample</code>과 <code>Concat</code>의 반복인 것을 알 수 있는데, CrackSSM은 여기에 <strong>Haar Wavelet</strong>을 더하여 뭉개진 균열을 살려낸다. </p>
<p>디코딩에서는 총 세 가지의 데이터를 사용하여 원본 해상도를 복원한다.</p>
<ul>
<li><p><strong>$F_4^{enc}$</strong>: 인코더의 VSS Layer 4에서 출력된 최상위 Feature Map으로, 가장 낮은 해상도를 가지며, 가장 상단에 위치한 첫 번재 Upsampling Block의 입력으로 사용되어 디코딩의 시작이 된다.</p>
</li>
<li><p>${ \hat F_i^{enc} }_{i=1}^3$: 인코더의 얕은 층에서 추출된 후 DPSM을 거쳐 강화된 Feature Map들이다. Figure 2를 보면, 노란색 Upsampling 블록으로 향하는 회색 점선 화살표로 Skip Connection을 통해 Decoder의 각 해상도 단계에 전달되는 것을 알 수 있다.</p>
</li>
<li><p>$F_{hf}$: Figure 2의 좌측 상단을 보면 원본 이미지에 <strong>Haar Wavelet Transform</strong>을 적용하는 것을 볼 수 있다. 여기서 추출된 3개의 고주파 서브밴드 (LH, HH, HL)를 채널 차원으로 결합한 특징맵이다. </p>
</li>
</ul>
<h3 id="📌upsampling--wgm">📌Upsampling &amp; WGM</h3>
<p>  Figure 2의 노란색 <strong>Upsampling Block</strong> 내부에서는 해상도를 키우는 작업과 경계를 선명하게 다듬는 작업이 동시에 진행된다.</p>
<p>  <img src="https://velog.velcdn.com/images/jm_mg_se/post/3e5a1081-96c0-4135-bce5-8a77d4f79d61/image.png" alt=""></p>
<h4 id="wgm-mechanism">WGM Mechanism</h4>
<p>  단순 업샘플링으로 발생하는 경계가 뭉개지는 현상을 해결하기 위해 각 디코딩 단계마다 $F_{hf}$를 적용한다. </p>
<ol>
<li><p>원본 고주파 맵 $F_{hf}$를 현재 업샘플링 된 Feature Map의 해상도에 맞게 <strong>Downsampling</strong>한다.</p>
</li>
<li><p>이를 1x1 Conv과 Sigmoind에 통과시켜 0과 1사이의 값을 가지는 <strong>Spatial Gating Weights, $A_{wg}$)</strong>를 생성한다.
$$$
W_* = \sigma(\text{Conv}<em>{1\times 1}(\text{ReLU}(\text{BN}({\text{Conv}</em>{1\times 1}(\hat I_*^w)))))}
$$$</p>
<blockquote>
<p><em>*이 수식은 wavelet 고주파 맵을 통해 0~1사이의 가중치 맵 ($W_</em>$, 내지는 $A_{wg}$)  **를 만드는 과정이다.</p>
</blockquote>
</li>
<li><p>이 가중치를 방금 업샘플링한 Feature Map에 <strong>Element-wise 곱</strong>을 하여 실제 고주파가 존재하는 픽셀의 특징은 증폭시키고 배경 노이즈는 억제한다.
$$$
\text{F}^<em><em>{\mathcal G} = \text{Resize}(W</em></em>) \odot \text{F}_i^{dec}
$$$</p>
</li>
</ol>
<h3 id="📌-feature-fusion">📌 Feature Fusion</h3>
<p>  WGM을 거쳐 경계선이 명확해진 하향식 Feature Map은 동일한 해상도를 가진 DPSM의 출력 $\hat{F}_i^{enc}$와 결합된다.</p>
<ul>
<li>두 Feature Map은 채널 차원으로 Concat 이후, 채널 수를 조절하는 합성곱 레이어를 거쳐 다음 딩코딩 단계의 입력으로 전달된다.
$$$
\text{F}<em>{out} = \text{Conv}</em>{1\times 1}(\text{Concat}(\text{F}<em>i^{dec}, \text{F}</em>{\mathcal G}^{LH}, \text{F}<em>{\mathcal G}^{HL}, \text{F}</em>{\mathcal G}^{HH}))
$$$</li>
<li>이러한 <strong>[Upsampling $\rightarrow$ WGM Gating $\rightarrow$ Skip connection fusion]</strong> 과정은 Feature Map의 해상도가 원본 이미지 크기 ($H \times W$)로 완전 복원될 때까지 반복한다.</li>
</ul>
<h3 id="📌gro-global-re-optimization-module">📌GRO (Global Re-optimization Module)</h3>
<p>  Figure 2의 좌측에 위치한 파란색 블록으로, 최종 분할 결과를 출력하기 직전에 수행되는 전역 최적화 단계이다.</p>
<ul>
<li><strong>GRO Mechanism</strong>: 원본 해상도로 복원된 최종 디코딩 Feature Map ($F_{out}$)과, 크기 변환을 거치지 않은 원본 고주파 맵 $F_{hf}, \text{내지는} I_{hf}$ 전체 사이의 픽셀 단위 유사도를 연산한다.
$$$
\text{I}<em>{hf} = \frac{1}{3}(\hat {\text {I}}</em>{LH}^w + \hat {\text {I}}<em>{HL}^w + \hat {\text {I}}</em>{HH}^w)
$$$<blockquote>
<h4 id="f_hf-i_hf는-뭐가-다른가요">$F_{hf}, I_{hf}$는 뭐가 다른가요?</h4>
<p>$\text{I}<em>{hf}$는 논문에서 공식적으로 정의한 1차원 통합 맵이지만, $F</em>{hf}$는 <strong>딥러닝 연산과정에서 3개의 서브밴드가 합쳐진 &#39;다채널 Feature Tensor&#39;</strong> 상태를 직관적으로 설명하기 위한 개념적 표현입니다.</p>
</blockquote>
</li>
</ul>
<p>  이를 통해 디코딩된 Feature Map이 실제 이미지의 물리적 엣지 구조와 얼마나 일치하는지 <strong>전역적으로 평가</strong>하여, 객체 관련 디테일을 한 번 더 강화하고 남아있는 노이즈를 억제한다.</p>
<p>  <strong>최종 출력: *<em>GRO를 통과한 Feature Map은 마지막으로 1x1 conv와 sigmoid를 거쳐 각 픽셀이 0과 1의 확률을 갖는 *</em>Binary Segmentation Map</strong>으로 최종 출력된다.</p>
<blockquote>
<p>Decoder 구조는 Skip Connection으로 다중 스케일 특징 융합이라는 전통적인 U-Net의 틀을 따르되, wavelet 기반의 고주파 정보를 매 단계(WGM)와 최종 단계(GRO)에 주입하여 불규칙적이고 얇은 균열의 구조적 충실도를 유지하도록 설계된 것이다.</p>
</blockquote>
<h2 id="loss-function">Loss Function</h2>
<p>  CrackSSM의 최종 손실 함수는 직관적인 두 가지의 합으로 이루어져있다.
  $\mathcal L_{total} = \mathcal L_{seg} + \lambda \mathcal L_{dir}$</p>
<h3 id="segmentation-loss-mathcal-l_seg">Segmentation Loss: $\mathcal L_{seg}$</h3>
<p>  디코더를 통과한 최종 예측 결과물 ($F_{out}$)과 GT 사이의 오차를 구하는, Segmentation Task의 정석적인 손실 함수이다. 
  $$$
  \mathcal L_{seg} = \mathcal L_{BCE} + \mathcal L_{Dice}
  $$$</p>
<ul>
<li><strong>BCE Loss(Binary Cross Entropy)</strong>: 픽셀 하나하나를 독립적으로 보면서 균열인지, 배경인지 계산한다.<ul>
<li><strong>Dice Loss</strong>: 균열 데이터의 가장 치명적인 문제인 <strong>클래스 불균형</strong>을 해결한다. 보통 이미지 전체에서 균열 픽셀은 1% 남짓이고, 99%가 배경인데, 전부 배경으로 찍어서 점수가 높아지는 것을 방지하기 위해, 예측한 균열과 실제 균열이 형태적으로 얼마나 겹치는지를 위주로 채점한다.</li>
</ul>
</li>
</ul>
<h3 id="directional-auxiliary-loss-mathcal-l_dir">Directional Auxiliary Loss: $\mathcal L_{dir}$</h3>
<p>  이게 바로 $F_{dir}$를 학습 시키는 보조 손실함수이다.
  이 손실 함수가 조금 특이한데, 모델이 방향을 잘 찾도록 두지 않고, 정답지를 만들어 직접 채점한다.</p>
<ul>
<li><p><strong>진짜 방향성 정답지 ($G_{dir}&#39;$) 만들기</strong>
원본 GT에는 균열이 있다(1)는 정보만 있을 뿐, 방향성의 정보는 없다. 때문에 연구진들은 <strong>소벨 필터</strong>를 정답지에 문질러 수평, 수직, 대각선 2개의 엣지(방향성)을 수학적으로 추출한다. 이게 바로 모델이 봐야하는 방향성이 포함된 정답지 $G&#39;_{dir}$이다.</p>
<blockquote>
<h4 id="wavelet도-4개-서브밴드-만드는데-왜-굳이-sobel-filter를">Wavelet도 4개 서브밴드 만드는데, 왜 굳이 Sobel Filter를?</h4>
</blockquote>
</li>
<li><p><em>방향을 계산하는 수학적 원리*</em>와 <strong>대각선을 처리하는 방식</strong>에서 결정적인 차이가 있다. </p>
<h3 id="sobel의-원리">Sobel의 원리</h3>
<p>소벨 필터는 영상처리에서 픽셀값의 미분값을 이용해 엣지를 찾는 고전적인 방법이다.</p>
<h4 id="part-1-g_x-g_y">Part 1. $G_x, G_y$</h4>
<p>$G_x =\begin{bmatrix}   -1 &amp; 0 &amp; 1  \
-2 &amp; 0&amp; 2  \
-1 &amp; 0 &amp; 1  \ \end{bmatrix}$, $G_y =\begin{bmatrix}   -1 &amp; -2 &amp; -1  \
0 &amp; 0 &amp; 0  \
1 &amp; 2 &amp; 1  \ \end{bmatrix}$
GT 위에 이 필터들을 픽셈라다 훑으면, 각 픽셀 위치에서 가로로 얼마나 색이 변했는지 ($G_x$), 세로로 얼마나 변했는지($G_y$) 수치가 나온다.</p>
<h4 id="part-2-theta계산">Part 2. $\theta$계산</h4>
<p>$G_x, G_y$를 직각삼각형의 밑변과 높이라고 해보자. 삼각함수 아크탄젠트를 이용하여 엣지가 뻗어 나가는 <strong>정확한 각도</strong>를 다음과 같이 계산할 수 있다. <br>$$방향(Angle, \theta) = \text{arctan}(\frac{G_y}{G_x})$$</p>
<h3 id="그럼-wavelet은">그럼 Wavelet은?</h3>
<p>2D Haar Wavelet도 4개의 조각으로 분리하긴 한다. 하지만 구성이 소벨과는 약간 다른데,  </p>
<blockquote>
<ul>
<li>LL (Low-Low): 저주파 (방향성 x)</li>
<li>LH (Low-High): 수평 엣지 (고주파)</li>
<li>HL (High-Low): 수직 엣지 (고주파)</li>
<li>HH (High-High): 대각선 엣지 (고주파)
<br>웨이블릿은 LH, HL는 잘 분리하지만, <strong>대각선 정보는 HH 하나로 통합된다.</strong>
딥러닝 모델이 토큰을 DPSM에서 재정렬하려면, 균열이 <strong>오른쪽 대각선인지, 왼쪽 대각선인지 명확히 알아야 한다.</strong><br>
</li>
</ul>
</blockquote>
<h3 id="때문에-sobel-사용하는-것">때문에 Sobel 사용하는 것!</h3>
</li>
<li><p><strong>Cross-Entropy &amp; Masking</strong>
앞서 $F_{dir}$에 Softmax를 씌워 만든 확률 분포 맵 $F&#39;<em>{dir}$을 가져와, $G&#39;</em>{dir}$와 비교한다. 이 때 CE를 사용해서 가중치를 수정하도록 학습시킨다.</p>
<ul>
<li>⚠️<strong>Background Masking</strong>:  균열이 없는 아스팔트 배경은 애초에 &#39;방향&#39;이라는게 존재하지 않는다. 억지로 방향을 학습해버리면 모델이 노이즈를 학습하는것과 같아, 혼란에 빠질 수 있다.
그래서 $\mathcal L_{dir}$을 계산할 때에는 <strong>배경 픽셀의 정답을 강제로 <code>[0, 0, 0, 0]</code> 벡터로 Masking 처리한다.</strong> 오직 진짜 균열이 지나는 전경 픽셀에서만 방향성 오차를 계산하도록 만들어, 혼란을 방지한다.</li>
</ul>
</li>
</ul>
<hr>
<h2 id="experimens--results">Experimens &amp; Results</h2>
<h3 id="sota와의-비교">SOTA와의 비교</h3>
<p>  기존 CNN이나 Transformer 기반 모델들과 비교했을 때, CrackSSM은 Mamba 특유의 <strong>선형 복잡도($O(N)$)</strong> 덕분에 엄청난 효율성을 보인다.</p>
<ul>
<li><strong>파라미터와 연산량(GFLOPs)의 최소화</strong>: 트랜스포머 기반 모델들이 픽셀 수가 많아질수록 연산량이 기하급수적으로 폭발하는 반면, CrackSSM은 훨씬 적은 파라미터 수와 낮은 GFLOPs로 모델이 가볍게 구동된다.</li>
<li><strong>정확도(mIoU, F1)향상</strong>: 가벼워졌음에도 불구하고, 불규칙적인 균열의 특성을 반영한 DPSM 설계 덕분에 여러 퍼블릭 벤치마크 데이터셋에서 기존 SOTA를 뛰어넘는 분할 정확도를 달성했다.</li>
</ul>
<h2 id="ablation-study">Ablation Study</h2>
<h4 id="dpsm의-부재">DPSM의 부재</h4>
<ul>
<li><strong>결과</strong>: 방향성 가이드 ($F_{dir}$)없이 기존의 고정된 스캔만 사용했을 때, mIoU가 크게 하락했다.</li>
<li>균열이 꺾이거나 끊어진 구간에서 공간적 연속성을 잃어, S6가 균열이 이어지는 것인지 파악하지 못하고 파편화된 예측 결과를 내놓았기 때문으로 보인다.</li>
</ul>
<h4 id="wgm의-부재">WGM의 부재</h4>
<ul>
<li><strong>결과</strong>: 디코더 단계에서 WGM을 빼고 단순 Upsampling만 하였을 때, 얇은 균열의 경계선이 심각하게 뭉개졌다.</li>
<li>해상도를 억지로 픽셀 복사로 늘리는 과정에서 디테일이 손실되었고, 이를 잡아줄 wavelet이 사라지면서 선형 객체 특유의 날카로움을 잃었다.</li>
</ul>
<h4 id="gro의-부재">GRO의 부재</h4>
<ul>
<li><strong>결과</strong>: 디코더 최종단에서 GRO를 뺐을 때, 배경 픽셀에 자잘한 노이즈가 증가했다.</li>
<li>모델이 지엽적인 픽셀 분류에만 매몰되어, 전체적 윤곽을 점검하는 기능이 사라진 것이다. GRO로 인해 예측 결과가 실제 이미지의 구조적 형태와 일치하도록 꽉 잡았다는 것을 보인다.</li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>  CrackSSM은 기존 SSM의 고정 스캐닝 한계를 극복하기 위한 <strong>동적 스캐닝(DPSM)</strong>, 미세 균열 상세 복원으르 위한 <strong>웨이블릿 기반 디코딩 (WGM, GRP)</strong>라는 두 가지 핵심 이론적 접근 방식을 제시했다.</p>
<p>  결론적으로는 CraskSSM은 동적 경로 계획과 고주파 사전 지식 활용을 통해 SSM의 잠재력을 균열 분할이라는 복잡한 문제에 효과적으로 적용하고, 기존 모델의 한계를 극복하며 효율성과 정확도 모두를 잡았던 것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Mask 이미지 처리의 주의할 점]]></title>
            <link>https://velog.io/@jm_mg_se/Mask-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%B2%98%EB%A6%AC%EC%9D%98-%EC%A3%BC%EC%9D%98%ED%95%A0-%EC%A0%90</link>
            <guid>https://velog.io/@jm_mg_se/Mask-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%B2%98%EB%A6%AC%EC%9D%98-%EC%A3%BC%EC%9D%98%ED%95%A0-%EC%A0%90</guid>
            <pubDate>Tue, 16 Jun 2026 05:12:58 GMT</pubDate>
            <description><![CDATA[<p>Mask는 일반적인 이미지가 아니라 <strong>class label map</strong>이다.</p>
<p>예를 들어 Mirror Mask는 보통 </p>
<pre><code class="language-python">0 = background
255 = mirror</code></pre>
<p>혹은 전처리 후</p>
<pre><code class="language-python">0 = background
1 = mirror</code></pre>
<p>로 표현된다.</p>
<p>그런데 마스크를 일반 이미지처럼 <strong>bilinear interpolation</strong>으로 resize하면 중간값이 생긴다.</p>
<pre><code class="language-python">0과 255 사이를 부드럽게 섞는다
-&gt; 37, 82, 128, 201같은 애매한 값이 발생하는 것이다.</code></pre>
<p>이것은 segmentation label로는 맞지 않는 값이다. class가 <code>0.37</code>개, <code>0.82</code>개 이런 식으로는 존재하지 않기 때문이다.</p>
<p>그래서 mask는 neareset neighbor로 resize한다.</p>
<pre><code class="language-python">mask = cv2.resize(mask, (size, size), interpolate=cv2.INTER_NEAREST)</code></pre>
<p>nearest는 가장 가까운 픽셀 label을 그대로 가져오기 때문에 label값이 유지된다.</p>
<ul>
<li>0은 0 그대로 </li>
<li>255는 255 그래도 <ul>
<li>새로운 중간 class값이 생기지 않는다.</li>
</ul>
</li>
</ul>
<p>반대로 이미지 <code>resize</code>는 <code>INTER_AREA</code>, <code>INTER_LINEAR</code> 등을 사용해도 좋다. 이미지는 색이 연속적인 값이라 섞여도 자연스럽기 때문이다.</p>
<hr>
<p>추가로 말이 나온 김에, bilinear interpolation과 linear interpolation, nearest interpolation을 각각 비교해보자.</p>
<p><strong>bilinear-interpolation과 linear-interpolation의 차이는 이전 포스트에서 다뤄본 적이 있다.</strong>
<a href="https://velog.io/@jm_mg_se/Dilation-linear-interpolation-%EA%B7%B8%EB%A6%AC%EA%B3%A0-Bilinear-upsampling">이전 포스트 참고하기</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰 + 코드구현] Symmetry-Aware Transformer-based Mirror Detection]]></title>
            <link>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-%EC%BD%94%EB%93%9C%EA%B5%AC%ED%98%84-Symmetry-Aware-Transformer-based-Mirror-Detection</link>
            <guid>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-%EC%BD%94%EB%93%9C%EA%B5%AC%ED%98%84-Symmetry-Aware-Transformer-based-Mirror-Detection</guid>
            <pubDate>Sun, 14 Jun 2026 02:21:44 GMT</pubDate>
            <description><![CDATA[<p>기존 Mirror Detection은 거울과 비거울 영역 사이의 의미적⋅구조적 특징을 통합하거나, depth, chirality 같은 거울 속성을 추가 정보로 활용하는 방식에 집중해왔다.</p>
<blockquote>
<p><strong>chiarlity</strong>: reality와 reflected 사이의 &#39;좌우반전&#39;의 기하학적 특성으로, 글자가 뒤집히는 것을 예로 들 수 있겠다. </p>
</blockquote>
<p>반면 SATNet은 거울의 본질적 물리 현상 관찰에 집중한다. 실제 물체와 거울 속 반사 이미지는 항상 의미적(semantic) 또는 밝기(luminance) 일관성을 유지한다. 위치나 방향이 엄격히 대칭이 아니더라도 말이다. 이것을 loose symmetry(느슨한 대칭)이라고 정의하고, 이 관계를 모델링하는 것이 핵심이다.</p>
<h3 id="기존-모델-대비-차별점">기존 모델 대비 차별점</h3>
<h4 id="기존-모델들의-한계">기존 모델들의 한계</h4>
<p>MirrorNet은 경계가 불명확한 장면에서 실패하고, PMDNet은 유사서어 의미론(similarity smenatics)을 고려하지만 대칭 쌍을 검출하지 못하고 비거울 영역을 거울로 오검출하기 쉽다. SATNet은 SAAM의 대칭 어텐션으로 경계 없이도 거울 영역을 식별한다. </p>
<p>깊이 정보를 쓰는 방법들은 depth값이 비신뢰적일 때 쉽게 오도되고, chirality 기반 방법은 거울에 반사된 장면에 기하학적 chirality 단서가 없을 때 효과가 줄어든다. </p>
<hr>
<h4 id="satnet의-구조적-혁신">SATNet의 구조적 혁신</h4>
<p><strong>1. Dual-Path 구조</strong>
기존 모델들은 단일 입력 이미지에서 거울의 경계를 찾다보니, 거울 안의 반사된 객체와 거울 밖의 실제 객체간의 기하학적 연관성을 놓치기 쉬웠다.</p>
<ul>
<li><p><strong>매커니즘</strong>: SATNet은 입력 이미지$(I)$와 이를 좌우로 반전(Horizontal Flip)시킨 이미지 $(I_{flip})$을 동시에 입력받는 <strong>Dual-Path</strong> 구조를 선택하였다.</p>
</li>
<li><p><strong>혁신점</strong>: 트랜스포머 백본(Swin Transformer 등)을 통해 두 경로에서 각각 멀티스케일 Global Feature를 추출한다. 원본 이미지와 반전 이미지를 동시에 처리함으로써, 공간적으로 떨어져있는 실제 객체와 거울 속 가상 객체를 <strong>동일한 위상 혹은 비교 가능한 공간 선상에 배치</strong>하여 대칭성을 쉽게 인지할 수 있는 기반을 마련한다.</p>
</li>
</ul>
<p><strong>2. SAAM (Symmetry-Aware Attention Module)</strong>
거울에 비친 객체는 완벽한 수학적 대칭을 이루지는 않고, 각도, 거울의 프레임, 촬영 환경 등에 따라서 왜곡되거나 일부만 보인다. SATNet은 이를 Loose Symmetry 라고 정의한다. 이를 포착하기 위한 전용 Attention Module이 바로 SAAM이다.</p>
<ul>
<li><strong>매커니즘</strong>: 백본의 High-level layer에서 나온 원본 경로의 Feature Map과 반전 경로의 Feature Map을 SAAM으로 교차 입력한다. Cross-Attention을 약간 변형하여, 원본 이미지의 특정 객체 영역이 반전 이미지의 어떤 대응 영역(거울 속 반사 이미지)와 매칭되는지 Global Context 만에서 연관 가중치를 계산한다.</li>
<li><strong>혁신점</strong>: 단순 기하학적 대칭 위치를 고정해서 보는 것이 아니라, <strong>트랜스포머의 멀리 떨어진 요소 간의 연관성도 파악할 수 있는 장거리 의존성(Long-range dependency)를 활용하여 원본 객체와 거울 속 반사체의 상관관계를 픽셀 단위로 추적</strong>한다.</li>
</ul>
<p><strong>3. CFDM (Contrast and Fusion Decoder Module)</strong>
대칭성을 확인했다 하더라도, 최종 거울 Mask를 정밀하게 따내기 위해서는 거울 경계면의 시각적 이질성과 디테일을 잡아야 한다.</p>
<ul>
<li><strong>매커니즘</strong>: CFDM은 디코더 단에서 원본 경로의 특징과 반전 경로의 특징을 단순히 더하는 것이 아니라, 두 경로 간의 <strong>&#39;대조(Contrast)&#39;</strong> 정보와 <strong>&#39;융합(Fusion)&#39;</strong> 정보를 동시에 처리한다.</li>
<li><strong>혁신점</strong>: 멀티스케일(Low-to-High) Feature Map들을 거치며, 거울 내부와 외부의 시각적 차이점을 극대화하여 경계를 뚜렷하게 만들고, SAAM이 찾아낸 대칭성들을 점진적으로 결합한다(Upsampling + Refinement).  이 과정을 통해 거울의 미세한 edge까지 완벽하게 분할할 수 있는 것이다. </li>
</ul>
<hr>
<h1 id="related-work">Related Work</h1>
<h2 id="mirror-detection">Mirror Detection</h2>
<p>사실 SATNet이 Reality와 Reflected된 영역의 특정 관계를 모델링한 것이 첫 시도는 아니다.
대표적으로 MirrorNet과 PMDNet이 있는데, 이러한 방법들은 그들이 일치시키는 관계가 너무 단순하거나 너무 엄격하기 떄문에 일반적인 거울 탐지 사례에서 거의 적용할 수 없었다고 한다.</p>
<blockquote>
<h3 id="mirrornet의-한계-단순함">MirrorNet의 한계: 단순함</h3>
<p>MirrorNet과 같은 초기 모델들이 거울 안팍을 비교하는 방식은 기하학적 구조가 아닌, 주로 &#39;시각적 이질성(Contextual Contrast)&#39;에만 의존했다.</p>
</blockquote>
<ul>
<li><strong>기존 방식</strong>: 이 모델들은 거울 내부와 외부의 미세한 색상 차이, 질감의 불연속성, 혹은 조명의 반사 광도 차이를 대조하는 모듈을 사용하였다.
<br>이는 실제 물체와 거울 속의 <strong>관계(Relationship)</strong>을 보는 것이 아니라, <strong>여기는 경게선이 같고, 안쪽과 바깥쪽의 색감이 살짝 다르네?</strong> 수준으로만 특징을 비교한 것이다.<br></li>
<li><strong>실패 케이스</strong>: 거울이 매우 깨끗하고 주변 환경과 완전히 동질적으로 이어져있는 경우에는 안팎의 시각적 이질성이 거의 존재하지 않는다. (벽면 전체가 거울인 경우를 예로 들 수 있겠다.) 이 경우에 MirrorNet은 거울 안팍의 Feature가 너무 유사하다고 판단되어 거울을 전혀 잡아내지 못한다. 
즉, <strong>고차원적인 대칭 구조를 보지 못하고 단순 표면 정보만 비교했기 때문에 실패하는 것</strong>이다.<blockquote>
<h3 id="chirality-및-기하학적-대칭-모델의-한계-엄격함">Chirality 및 기하학적 대칭 모델의 한계: 엄격함</h3>
<p>이를 극복하기 위해 일부 후석 연구(SATNet 등)들은 물리적 특성인 Chirality나, 명시적인 기하학적 대칭성을 수식으로 강제하려고 했다.</p>
</blockquote>
</li>
<li><strong>기존 방식</strong>: 이미지 내에서 완벽하게 좌우가 뒤집힌 물리적 대칭 쌍이나 고정된 대칭축을 수학적으로 매칭하려고 했다.</li>
<li><strong>원인</strong>: 현실 세계에서 촬영된 거울 사진은 수학 책에 나오는 것처럼 완벽하게 정면에서 예쁘게 찍히지 않는다.<ul>
<li>거울이 비스듬하게 있으면 반사된 상이 왜곡된다.</li>
<li>카메라의 앵글에 따라 실제 물체는 크게 나오고 거울 속 물체는 작게 보일 수 있다.</li>
<li>거울 프레임에 걸려 거울 속 물체의 일부분만 잘려서 보일 수 있다.<br></li>
</ul>
</li>
<li><strong>실패 케이스</strong>: 기존의 엄격한 대칭 매칭 알고리즘은 <strong>조금만 각도가 틀어지거나 왜곡이 싱겨도 &quot;이 둘은 대칭이 아니다&quot;라고 판단</strong>한다. 즉, 현실 세계의 가변적인 기하학적 변화를 수용하지 못하는 치명적 단점이 있다.</li>
</ul>
<blockquote>
<h3 id="satnet의-해결-방법-loose-symmetry">SATNet의 해결 방법: Loose Symmetry</h3>
<p>아까부터 계속 Loose Symmetry가 나오는데, 이 부분이 바로 핵심이다.
SATNet은 기존 연구들의 &#39;너무 단순해서 놓치는 문제&#39;와 &#39;너무 엄격해서 부러지는 문제&#39; 사이에서 완벽한 절충안인 Loose Symmetry를 제안한다.<br></p>
</blockquote>
<ul>
<li><strong>Dual-Path를 통한 유연한 비교</strong>: SATNet은 원본과 반전 이미지를 동시에 입력받아 트랜스포머의 전역 어텐션(SAAM)을 통과시킨다.</li>
<li>이 어텐션 메커니즘은 고정된 픽셀 위치나 딱딱한 수식으로 대칭을 검사하지 않고, &quot;이쪽 영역에 있는 실제 의자의 고차원적 Feature가 반대 영역의 왜곡된 상과 맥락적으로 깊은 Correlation이 있다는 것을 인지하도록 한다.</li>
</ul>
<hr>
<h1 id="method">Method</h1>
<h2 id="overview">Overview</h2>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/5c9e9a8f-0f4c-4882-902d-97d45b0bf0e4/image.png" alt="">
Loose Symmetry는 두 가지 측면에서 탐지 과정에서 이점을 보인다. 
<strong>*1. loose symmetry의 존재는 거울의 존재 가능성을 암시한다. *</strong> 모델은 거울이 어디에 존재하는가를 포착하기 위해 <strong>Dual-Path</strong> 구조와 *<u>새로 제안한 SAAM(Symmetry-Aware Attention Module)</u>을 설계하여 대칭적 특징을 강화하고 뽑아낸다. </p>
<p><strong><em>2.거울 영역의 구체적 경계 구분(Localization)</em></strong>
대칭을 이루는 쌍 사이의 미세한 차이점들을 분석함으로써, <strong>이미지의 어느 부분이 실제 객체이고 어느 부분이 반사된 영역인지</strong> 짚어낼 수 있다.
모델은 이 두 번째 측면을 명확히 구분하고 세밀하게 정제하기 위해 트랜스포머 백본과 CFDM을 활용한다.</p>
<blockquote>
<h3 id="이번에-새로-도입한-saam-모듈">이번에 새로 도입한 SAAM 모듈?</h3>
<p>SAAM은 백본 네트워크의 High-level 레이어에서 추출된 원본 경로의 특징($F$)와 반전 경로의 특징($F^f$)를 입력으로 받는다.<br>
논문의 Figure 2(b)를 보면 구체적인 연산 과정을 알 수 있다.
<strong>1. Spatial Alignment</strong>: 채널 방향으로 두 경로의 특징을 합치기 전에, 뒤집혀 있는 반전 특징($F^f$)을 기하학적으로 다시 똑바로 뒤집어서 ($flip(F^f)$) 원본 이미지의 위치와 픽셀 수준에서 정렬시킨다.<br>
<strong>2. Feature Fusion ($\varphi$함수)</strong>: 정렬된 두 특징을 Concat한 후, $1\times 1$ 및 $3\times 3$ 컨볼루션과 Batch Norm, ReLU를 거쳐서 두 경로의 정보가 통합된 증강 특징 $F^c$를 생성한다.
<br>
<strong>3. Symmetry-Aware Cross-Attention</strong>: <strong>원본 특징의 강화($\hat F$)</strong>: 원본 특징 $F$를 Query로 사용하고, 융합 특징 $F^c$를 <strong>Key, Value</strong>로 사용하여 어텐션을 수행한다.
    - <strong>반전 특징의 강화 ($\hat F^f$)</strong>: 반전 특징 $F^f$를 <strong>Query</strong>로 사용하고, 동일하게 $F^c$를 <strong>Key와 Value</strong>로 설정하여 어텐션을 수행한다.
    $\hat F = ECA(Attention(F, F^c, F^c))$
    $\hat F^f = ECA(Attention(F^f, F^c, F^c))$<br>
<strong>4. ECA(Efficient Channel Attention)적용</strong>: 크로스 어텐션을 거친 후 경량화 된 채널 어텐션 모듈인 ECA를 통과시켜 채널 간의 상호작용을 한 번 더 정제한다.<br></p>
</blockquote>
<h3 id="그럼-기존과의-차이는-무엇인가">그럼 기존과의 차이는 무엇인가?</h3>
<p>기존 모델들은 이미지 한 장에서 두 가지의 장면이 얼마나 다른지, 혹은 특정 위치에 거울이 있는가? 만 보았지만, <strong>&#39;실물&#39;과 &#39;반사체&#39;를 일대일로 대조하는 어텐션 구조는 아예 없었다.</strong>
<br>
기존에는 하지 않던 <strong>&#39;원본 이미지($I$)와 &#39;좌우를 고의로 뒤집은 이미지 ($I^f$)를 동시에 넣는 Dual-Path 구조</strong>를 도입한 것이다.
또한, SAAM 안에는 일반적인 어텐션을 하지 않는다.
원본과 반전 이미지를 공간적으로 합친 증강 $F^c$를 Key, Value, 원본 특징($F$)를 Query로 던지는 이것은 <u>Attention Score자체가 원본과 반전 이미지 사이의 Loose symmetric을 찾아내는 일종의 Indicator로 작동하는 것</u>이다. </p>
<hr>
<p>입력 이미지 $I$와 뒤집한 반전 이미지 $I_f$를 공유 가중치 트랜스포머 백본에 입력하여 Multi-Scale 특징 ${F_0, ..., F_3}$와 해당 뒤집힌 특징 ${F_f^0, ...,F_f^3}$을 각각 얻는다. </p>
<p>대칭 관계를 모델링하기 위해, <strong>두 레벨의 가장 높은 두 레벨에서 특징을 선택</strong>하고, <strong>SAAM</strong>에 입력하여 $\hat F$와 $\hat F_f$를 얻는다. </p>
<p>다중 스케일 특징 ${F_i/\hat F_i}$와 뒤집힌 특징 ${F_f^i/\hat F_f^i}$를 CFDM에 입력하여 점진적으로 다른 스케일의 거친 출력 특징 $F_{out}^i$를 생성한다. (<em>위에 첨부한 [Figure 2]와 같이 CFDM은 모든 레벨에서 진행한다.</em>)</p>
<p>$F_{out}^0$을 제외한 $F_{out}^i$는 다음 디코더로 <strong>업샘플링하여 *<em>추가적인 예측 정제를 위한 *</em>참조 특징 $D_{i-1}$로 사용한다.</strong></p>
<p>동시에 각 디코더에서 Segmentation Head를 통해 예측 맵 $P_i$를 업고, 이를 실제 마스크 $M$을 통해 지도(Supervise)한다.</p>
<blockquote>
<p>디코더의 각 단계($i$)마다 $M$을 대조하여 학습시키면, 모델의 상위 레이어부터 하위 레이어까지 거울의 경계면과 대칭성 정보를 잊지 않고 <strong>점진적으로 정밀하게</strong> 마스크를 깎아 나갈 수 있게 된다.</p>
</blockquote>
<hr>
<h2 id="dual-path-structure">Dual-Path Structure</h2>
<p>대부분의 실제 환경에서 만들어지는 Loose Symmetric은 복잡한 시각적 배경 속에 숨겨져 있다. 때문에 기존의 베이스라인 모델들은 감지를 잘 하지 못하여, 연구진들은 <strong>양방향을 모두 강화하는 Dual Enhancement 방식</strong>을 제안한다.</p>
<p>데이터 증강에서 흔히 쓰이는 &#39;Horizontal Flip&#39;은 이미지 전체의 전역적 의미 구조를 변화시키지만, <strong>거울이 가진 본질적 대칭 관계는 이미지 안에서 사라지지 않고 그대로 유지</strong>된다. </p>
<p>따라서 저자들은 이 대칭적 특징을 추출하기 위해 두 개의 경로를 가진 네트워크를 도입하는데, 겉보기에는 $F$와 $F^f$가 서로 다르지만, <strong>동일한 loose symmetry 가 존재한다고 기대</strong>하는 것이다.</p>
<p>저자들은 이 둘을 concat하여 $F_C$라는 거대한 Feature Map을 만드는데, 이미지 내에서 대칭을 이루고 있던 영역들이 서로 시너지를 내며 증폭되는 원리이다.</p>
<p>$F^c = \varphi(F, \text{flip}(F^f))$
$\varphi(a_1, ..., a_n) = \sigma(\text{BN}(\psi_{3\times 3}(\psi_{1\times 1}([a_1,...,a_n]))))$</p>
<ul>
<li>$F^f$는 애초에 뒤집힌 이미지 ($I^f$)로부터 추출되었기 때문에, 원본 특징 $F$와 그대로 합치면 픽셀 위치가 맞지 않는다. 따라서 Concat을 통해Spatial Level에서 완벽하게 정렬하기 위해, 저자들은 <strong>SAAM이나 CFDM 모듈에 집어넣기 직전에 반전 특징 $F^f$를 다시 원래 방향으로 한 번 더 뒤집은 뒤 ($\text{flip}(F^f)$)와 결합</strong>한다.</li>
</ul>
<p>이 완벽한 공간적 정렬과 대칭 정보의 물리적 결합이 선행되었기 때문에, 후속 모듈인 SAAM에서 크로스 어텐션을 통해 Loose symmetric을 정밀하게 추적할 수 있게 되는 것이다.</p>
<hr>
<h2 id="symmetry-aware-attention-module">Symmetry-Aware Attention Module</h2>
<p>SAAM을 통해 이미지 내에서 거울의 존재 가능성을 나타내는 Loose symmetric을 인식하고자 한다. 
이러한 대칭 관계가 <strong>거울이 존재할 가능성을 강력히 시사</strong>하기 때문에 매우 중요하다.</p>
<p>SAAM은 <strong>두 가지 병렬 작업</strong>을 수행한다.</p>
<ul>
<li><strong>특징 강화</strong>: 입력 원본 이미지의 특징 $F$ 자체를 더욱 강력하게 강화한다.</li>
<li><strong>대칭성 모델링</strong>: 원본 이미지와 반전 이미지 사이의 상호 의존성을 모델링하여, 대칭을 인지하고 있는 정보를 확보한다.</li>
</ul>
<p>SAAM은 원본 특징 $F$, 반전 특징 $F^f$, 그리고 Dual-Path 구조에서 두 특징을 정렬하여 합친 융합 특징 $F^c$까지 <strong>총 3개의 Feature Map을 입력</strong>으로 받는다.</p>
<blockquote>
<p>$F^c$는 양쪽 경로의 특징을 모두 취합한 결과물이면서 동시에 원본 특징 $F$와 Spatial한 특징까지 일치하기 때문에, 원본 특징 $F$가 대칭 정보로 한 단계 업그레이드 된 <em>증강 표현</em>으로 취급될 수 있다.</p>
</blockquote>
<p>$\hat F = \text{ECA}(Attention(F, F^c, F^c))$
원본 특징 $F$를 Global Contextual 에 맞게 강화하기 위해, 저자들은 <strong>원본 특징 $F$를 Query로, 대칭 정보가 증강된 $F^c$를 Key, Value로</strong> 설정하여 Cross-Attention을 수행한다.</p>
<p>그 직후, 연산 효율성이 높은 채널 어텐션 모듈인, ECA를 통과시켜 채널 간의 상호작용을 정제함으로써, 최종적으로 전역 대칭 맥락이 풍부해진 원본 특징 $\hat{F}$를 얻는다.</p>
<p>$\hat F^f = \text{ECA}(Attention(F^f, F^c, F^c))$
<strong>대칭성 인지 특징 추출</strong>을 위해서는 <strong>반전 특징 $F^f$를 Query로, F^c를 Key, Value</strong>로 설정한다.</p>
<p>Query인 $F^f$는 뒤집힌 이미지에서 온 것이고, Key 인 $F^c$는 원본 이미지의 공간 방향을 따른다. </p>
<p>따라서 둘 사이의 <strong>어텐션 Score를 계산한다는 것은, 원본 이미지의 영역과 반전 이미지의 영역 사이에 &#39;Loose symmetric&#39;이 존재하는지 판별하는 지표(Indicator)로 쓰이게 됨</strong>을 의미한다</p>
<blockquote>
<p>이 과정에서 나온 출력물은 비로소 대칭성을 인지한 상태이므로 Symmetry-Aware 특징 ($\hat F^f%$)가 된다.</p>
</blockquote>
<blockquote>
<h3 id="왜-상위-두-개의-레이어에서만-적용하는가">왜 상위 두 개의 레이어에서만 적용하는가?</h3>
<p><strong>SAAM을 굳이 상위 마지막 두 개의 레이어(Scale 2, 3)에서만 진행하는 이유</strong>는 두 가지 이유가 존재한다.<Br></p>
</blockquote>
<ol>
<li><strong>딥러닝 레이어별 특징의 특성</strong></li>
<li><strong>연산 효율성 및 노이즈 방지</strong></li>
</ol>
<hr>
<h4 id="low-level-레이어">Low-level 레이어</h4>
<p>  이미지의 국소적 특징(선, 면, 질감) 같은 정밀한 기하학적 디테일은 Scale 0, Scale 1과 같은 Low-level 레이어에서 학습한다.
  <br>이 단계에서는 Receptive Field가 좁아서 이미지 반대편에 있는 실제 객체와 거울 속 객체를 연결하는 &#39;대칭 관계&#39;를 인지할 수 없다.</p>
<h4 id="high-level-레이어">High-level 레이어</h4>
<h2 id="receptive-field가-이미지-전체로-확장되며-객체의-추상적-형태-종류-global-context를-다룬다">  Receptive Field가 이미지 전체로 확장되며, 객체의 추상적 형태, 종류, Global Context를 다룬다.</h2>
<p>  저자들이 정의한 Loose Symmetry는 &#39;자잘한 픽셀의 비교&#39;가 아닌 &#39;추상적 의미가 서로 대칭을 이루는 고차원적 맥락&#39;이다.  따라서 <strong>이 관계성을 인지하는 SAAM은 고차원적인 의미 정보가 완성되는 상위 레이어에서만 작동해야 비로소 유의미한 대칭 쌍을 찾을 수 있다.</strong>
<br>
(물론 저자들이 하위 레이어에서 진행한 결과도 Ablation Study와 Table 3에서 나온다.)</p>
<hr>
<h2 id="contrast-and-fusion-decoder-module-cfdm">Contrast and Fusion Decoder Module (CFDM)</h2>
<p>  MirrorNet 연구 이후, 거울의 안팍 차이를 포착하는 <strong>CCL(Context Contrasted Local) 디코더</strong>는 Mirror Detect Network에서 일종의 <strong>표준</strong>처럼 널리 쓰여왔다.</p>
<p>  기존 모델들은 거울의 경계를 더 예쁘게 깎기 위해 Edge Extractor라는 별도의 신경망 모듈을 추가하여 함께 학습했다고 한다.</p>
<p>  저자들은 기존 방식을 확장하여 Dual-Path에서 나오는 <strong>Multiple Featues을 한 번에 다룰 수 있는 CFDM</strong>을 제안한다. CFDM은 <strong>무거운 Edge 정보를 추가로 주입하지 않음에도, Top-down 구조를 통해 Multi-level 특징을 점진적으로 정제하여 정밀한 거울 경계를 효율적으로 그린다.</strong></p>
<p>  CFDM은 디코더 층의 높이에 따라 입력받는 특징이 다르다.</p>
<ul>
<li><strong>하위 레이어 ($i=0,1$)</strong>: SAAM을 거치지 않은 일반 백본 특징인 $F_i$와 $F_i^f$를 입력받는다.</li>
<li><strong>상위 레이어($i=2, 3$)</strong>: SAAM을 거치며 대칭성이 정밀하게 모델링 된 $\hat F_i, \hat F_i^f$를 입력 받는다.</li>
</ul>
<p>어떤 층이든 상관없이, CFDM은 가장 먼저 앞서 Dual-Path에서 배웠던 융합 수식($\varphi$)을 이용하여 원본과 반전 특징이 하나로 묶인 융합 특징 $F_i^c$를 획득하며 연산을 시작한다.</p>
<hr>
<h4 id="top-down-mechanism">Top-down Mechanism</h4>
<p>  바로 위 단계의 디코더($i+1$)가 내뱉은 출력 특징($F_{i+1}^{out}$)이라고 한다. CFDM은 이 상위 스케일의 결과를 받아 3x3 Conv, BN, ReLU를 수행한 뒤, Bilinear Interpolation을 통해 해상도를 2배 키워 현재 레이어의 참조 특징인 $D_i$를 만들어낸다. </p>
<p>  즉, 상위 레이어가 찾은 거울의 대략적 위치 정보가 하위 레이어로 상속되는 과정이다.</p>
<hr>
<p>$$(\tilde{F}_i^c, \tilde{F}_i, \tilde{F}_i^f) = 
\begin{cases} 
(F_i^c, F_i, F_i^f) \oplus (D_i, D_i, D_i), &amp; i &lt; 3\
(F_i^c, F_i, F_i^f), &amp; i = 3 
\end{cases}$$
                                                     <br>
상위 레이어에서 내려온 참조 특징 $D_i$를 현재 층의 세 갈래 특징에 각각 Element-wise로 주입한다.
(최상위 층인 $i=3$은 위에서 내려온 정보가 없으니 자기 자신으로 한다.)</p>
<p>  상위 맥락이 덧칠해진 세 갈래 특징은 각각 독립적으로 <strong>CCL 모듈에 들어가서 거울 안팍의 대조적 의미를 추출</strong>하게 된다.</p>
<p>  $CCL(\tilde F_i) = \sigma (BN(f_l(\tilde F_i) - f_{gl}(\tilde F_i)))$</p>
<ul>
<li>CCL 연산의 핵심은 뺄셈($-$)이다. 국소적 특징에서 전역적 주변 문백 특징을 빼버리는 연산으로, <strong>거울 내부의 특징과 거울 외부의 특징 차이점만 극대화되어 경계선이 아주 뚜렷하게 도드라진다.</strong></li>
</ul>
<blockquote>
<h4 id="saam-cfdm-하나라도-부재한다면">SAAM, CFDM 하나라도 부재한다면?</h4>
</blockquote>
<ul>
<li>SAAM (O), CFDM (X): 대칭성은 매우 잘 찾아, 거울의 대략적 위치는 알지만, <strong>거울의 Boundary 깎는 능력이 떨어져 마스크가 뭉뚱그려진다.</strong></li>
<li>SAAM (X), CFDM (O): 거울의 경계면은 칼로 딴 것처럼 매우 선명하지만, 대칭 맥락을 모르기 때문에 <strong>거울 내부에 대칭된 객체가 있으면 그걸 거울이 아니라 일반 실제 물체인줄 알고 마스크에서 파버린다.</strong></li>
</ul>
<hr>
<h2 id="trasnformer-for-mirror-detection">Trasnformer for Mirror Detection</h2>
<p>  기존 Mirror Detection 모델들은 대부분 Multi-Scale 특징을 뽑아내기 위해 CNN을 백본으로 사용했다. 하지만 일반적인 Convolution 연산은 커널 크기의 한계로, <strong>Receptive Field의 크기가 제한적</strong>이다. 이 때문에 CNN은 <strong>이미지 내에서 멀리 떨어진 요소들 간의 관계를 파악하는 데에 한계가 있다.</strong></p>
<p>  Mirror Detect에서는 <strong>Global Information이 매우 중요하다</strong>. 거울은 대게 멀리 떨어진 풍경을 반사하며, 그 결과 <strong>&#39;실제 객체&#39;와 그에 대응하는 &#39;거울 속 반사체&#39;가 이미지 상에서 서로 아주 멀리 떨어져 배치되는 경우가 빈번하기 때문</strong>이다. 이 둘을 하나로 엮어 대칭성을 인지하려면 이미지 전체를 한눈에 조망할 수 있는 눈이 필요하다.</p>
<p>  저자는 이를 위하여 CNN 대신 <strong>Swin Transformer</strong>를 백본으로 사용한다. </p>
<p>  Swin-S 백본은 이미지를 계층적으로 처리하며 총 4가지 스케일의 Feature Map을 만든다. 이를 수식 $F_i$로 정의한다.</p>
<h3 id="loss-functions">Loss Functions</h3>
<p>  $\mathcal{L} = \sum \limits_{i=0}^3w_i \mathcal{L}_{ce}(P_i, M)$
  저자들은 단 하나의 최종 출력증만 보는 것이 아니라, 디코더의 <strong>모드느 스케일을 종합적으로</strong> 고려하도록 설계한다.</p>
<p>  디코더의 각 레이어($i$)에서 출력되는 예측맵 $P_i$와 GT $M$ 사이의 <strong>Cross Entropy Loss</strong>를 각각 계산한다.</p>
<hr>
<h1 id="experiments">Experiments</h1>
<h3 id="datasets--optimization">Datasets &amp; Optimization</h3>
<p>기존 Mirror Detect 분야에서 표준으로 쓰이는 MSD와 PMD를 사용하였다. RGB-D 기반 모델들과의 비교를 위해 depth 정보가 포함된 <strong>RGBD-Mirror</strong> 데이터셋 또한 활용한다.</p>
<p>  <strong>Adam weight decay</strong>를 사용하여 20K 이터레이션 동안 학습을 진행한다. </p>
<p>  초기 학습률은 $6 \times 10^{-4}$이며 Poly 에 따라 점차 감쇠된다. 총 학습 시간은 6시간이며, 단일 GPU에서 이미지 1장을 테스트하는 데에 걸리는 시간은 0.08초이다.</p>
<h3 id="quantitative-comparison">Quantitative Comparison</h3>
<pre><code> #### RGB 데이터셋 결과 (MSD, PMD)</code></pre><p>  <img src="https://velog.velcdn.com/images/jm_mg_se/post/e626a14f-a461-4b49-ad23-6d26ec66fa11/image.png" alt=""></p>
<ul>
<li><strong>MSD 데이터셋</strong>: IoU <strong>85.41%</strong>, $F_\beta$ <strong>0.922</strong>, MAE <strong>0.033</strong>으로, 기존 SOTA인 PMDNet보다 약 3.8% 높은 수치를 보인다.</li>
<li><strong>PMD 데이터셋</strong>: IoU <strong>69.38%</strong>, $F_\beta$ <strong>0.847</strong>, MAE <strong>0.025</strong>를 달성하여, 데이터셋을 구축했던 PMDNet이나 SANet을 제치고 새로운 SOTA를 달성한다.</li>
</ul>
<hr>
<h4 id="rgb-d-데이터셋-결과-rgbd-mirror">RGB-D 데이터셋 결과 (RGBD-Mirror)</h4>
<p>  <img src="https://velog.velcdn.com/images/jm_mg_se/post/229cb553-8410-47b8-8db6-9238a4a3253e/image.png" alt=""></p>
<ul>
<li>SATNet은 <strong>Depth 정보를 전혀 사용하지 않는 RGB 모델</strong>임에도 불구하고, 실제 depth map을 주입받아 학습한 최신 RGB-D Mirror Detect 모델보다 더 높은 성능을 기록했다.</li>
<li>IoU <strong>78.42%</strong>, $F_\beta$ <strong>0.906</strong>, MAE <strong>0.031</strong>을 기록하며, 깊이를 사용한 PDNet을 뛰어넘었다. 이는 값비싼 depth 카메라 정보 없이 단지 &#39;<strong>loose symmetry&#39;</strong>를 <strong>모델링하는 것 만으로도 공간 왜곡을 더 잘 파악할 수 있음</strong>을 증명한다.</li>
</ul>
<hr>
<h1 id="conclusions">Conclusions</h1>
<p>  저자들은 본 논문을 통해 Mirror Detect 분야에서 가장 중요한 물리적 관찰을 다시 한번 강조한다. 바로 <strong>실제 객체와 거울 속 반사체 사이에는 언제나 Loose symmetric이 형성된다는 점</strong>이며, 이것이 해당 Task에서 결정적인 역할을 한다는 것이다.</p>
<p>  이 현상을 유연하게 활용하기 위해 쌍방향 경로를 가진 <strong>SATNet</strong> 아키텍처를 제안한다. 특히 CNN의 좁은 RF를 극복하고 이미지 전체의 Long Range 맥락을 완벽히 수집하기 위해, <strong>트랜스포머 백본</strong>을 도입하였다.</p>
<hr>
<p>  하지만 SATNet이 기존 모델들을 엄청난 격차로 성능 측면에서 압도하긴 했지만, <strong>극도로 가혹하고 복잡한 환경에서는 여전히 오작동할 가능성</strong>이 있다고 시사한다.</p>
<p>  만약 방 안에 <strong>거울이 여러 개 배치되어 있어서</strong> 거울 속에 또 다른 거울이 비치거나, 실물 하나가 여러 거울에 동시에 반사되는 경우가 있다. </p>
<p>  이 때는 대칭 관계의 가중치가 기하급수적으로 복잡해지기 때문에, 모델이 대칭 쌍을 놓치고 거울 영역을 일부분만 찾아내는 <strong>불완전한 검출</strong>을 하게 된다.</p>
<hr>
<h1 id="code-implementation">Code Implementation</h1>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[Dot product, Inner product 그리고 element-wise]]></title>
            <link>https://velog.io/@jm_mg_se/Dot-product-Inner-product-%EA%B7%B8%EB%A6%AC%EA%B3%A0-element-wise</link>
            <guid>https://velog.io/@jm_mg_se/Dot-product-Inner-product-%EA%B7%B8%EB%A6%AC%EA%B3%A0-element-wise</guid>
            <pubDate>Sun, 07 Jun 2026 02:47:34 GMT</pubDate>
            <description><![CDATA[<p>선형대수를 공부하는데, 갑자기 Dot product, Inner product 그리고 element-wise가 헷갈려 정리한다.</p>
<h3 id="element-wise-product-요소별-곱">Element-wise product (요소별 곱)</h3>
<p>이건 가장 기본이 되는 연산으로, 같은 위치의 원소끼리 곱한다. 
중요한건, <strong>결과는 같은 크기의 벡터/행렬</strong>인 것이다.
$a = [1, 2, 3], b = [4, 5, 6]$
$a \odot b = [1\times 4, 2\times 5, 3\times 6] = [4, 10, 18]$</p>
<h3 id="dot-product">Dot product</h3>
<p>Dot product는 내적의 한 종류로, 스칼라를 변환한다.
Element-wise 곱을 한 다음 <strong>다 더한다. 결과는 스칼라가 나온다.</strong></p>
<p>$a \cdot b = 1 \times 4 + 2\times 5 + 3\times 6 = 4 + 10 + 18 = 32$</p>
<blockquote>
<p>Dot product는 <strong>벡터끼리</strong>의 연산이고, 항상 스칼라가 나온다.</p>
</blockquote>
<h3 id="inner-product">Inner product</h3>
<p>Inner product 또한 내적으로, Dot product의 일반화 버전이라고 보면 된다.
Inner product의 <strong>특수한 경우</strong>로, Inner product는 더 넓은 개념으로, 두 가지 조건만 만족하면 무엇이든 내적이 될 수 있다:</p>
<ul>
<li>양수성: $\langle a, a \rangle \geq 0$</li>
<li>대칭성, 선형성 등 몇 가지 성질</li>
</ul>
<p>예를 들어, 함수 공간에서의 내적은 이렇게 정의된다.</p>
<p>$\langle f, g \rangle = \int f(x) g(x), dx
$</p>
<p>이건 벡터도 아니고, &quot;곱해서 더한다&quot;는 형태도 다르지만, 내적의 성질을 만족하기 때문에 inner product이다.</p>
<p>결론: Dot product ⊂ Inner product (도트곱은 내적의 특수 케이스), Element-wise는 내적이 아니고 중간 과정에 가깝다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[optimizer의 수학적 추론]]></title>
            <link>https://velog.io/@jm_mg_se/optimizer%EC%9D%98-%EC%88%98%ED%95%99%EC%A0%81-%EC%B6%94%EB%A1%A0</link>
            <guid>https://velog.io/@jm_mg_se/optimizer%EC%9D%98-%EC%88%98%ED%95%99%EC%A0%81-%EC%B6%94%EB%A1%A0</guid>
            <pubDate>Fri, 22 May 2026 16:54:27 GMT</pubDate>
            <description><![CDATA[<h1 id="sgd-with-momentum">SGD with Momentum</h1>
<h3 id="bar-x_t--fracx_1--x_2----x_tt--를-우리는-흔히-average라고-한다">$\bar x_t = \frac{x_1 + x_2 + ... + x_t}{t}$  를 우리는 흔히 Average라고 한다.</h3>
<blockquote>
<p><strong>How to write the average in a <em>RECURSIVE FORM?
$\bar x_t =$</em></strong>  ◻$\bar x_{t-1} +$  ▵</p>
</blockquote>
<blockquote>
<h3 id="⭐-위-normal-average-공식을-사용해서">⭐ 위 Normal Average 공식을 사용해서</h3>
<p>$S_t = x_1 + x_2 + ... + x_t$ 라고 할 때,</p>
</blockquote>
<h3 id="bar-x_t--fracs_tt">$\bar x_t = \frac{S_t}{t}$</h3>
<h3 id="bar-x_t-1--fracx_1--x_2---x_t-1t-1--frac-s_t-1t-1-→-s_t-1--t-1bar-x_t-1">$\bar x_{t-1} = \frac{x_1 + x_2 + ... x_{t-1}}{t-1} = \frac {S_{t-1}}{t-1}$ → $S_{t-1} = (t-1)\bar x_{t-1}$</h3>
<h3 id="s_t--x_1--x_2---x_t-1--x_t--s_t-1--x_t">$S_t = x_1 + x_2 + ... +x_{t-1} + x_t = S_{t-1} + x_t$</h3>
<h3 id="s_t--t-1bar-x_t-1--x_t">$S_t = (t-1)\bar x_{t-1} + x_t$</h3>
<h3 id="⇒-bar-x_t--fract-1bar-x_t-1--x_tt---time-step-t-까지의-평균">⇒ $\bar x_t = \frac{(t-1)\bar x_{t-1} + x_t}{t}$  : Time step $t$ 까지의 평균</h3>
</aside>

<h2 id="recursive-form-of-average-memory-efficient-way">Recursive form of average: Memory efficient way</h2>
<ul>
<li>과거의 정보와 현재 정보를 어떤 비율로 섞을 것인가?</li>
</ul>
<h3 id="bar-x_t--beta_tbar-x_t-1--1-beta_tx_t---where-beta_t--fract-1t">$\bar x_t = \beta_t\bar x_{t-1} + (1-\beta_t)x_t$   where $\beta_t = \frac{(t-1)}{t}$</h3>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/dcfca84a-e7a4-4a73-87ab-685602193758/image.png" alt=""></p>
<ul>
<li>이렇게 시간이 지날수록, 앞의 가중치가 더 커짐 (새로들어온 정보 무시당함)</li>
</ul>
<h2 id="simple-moving-average-sma">Simple Moving Average (SMA)</h2>
<ul>
<li>Specified period 상의 값들의 평균: <em>그냥 일반적인 평균이라는거</em></li>
</ul>
<p><strong>정확히 $n$개의 데이터를 더하기 위해서 $x_{t-n+1}$ 이 분자의 마지막 항</strong></p>
<h3 id="textsmat--frac-x_t--xt-1----x_t-n1n">$\text{SMA}<em>t = \frac {x_t + x</em>{t-1} + ... + x_{t-n+1}}{n}$</h3>
<p>Time step $t$에서의 SMA인데, </p>
<ul>
<li>$n$은 window size(평균 구하는 기간) ,</li>
<li>$x_t$는 t시점에서의 Value</li>
</ul>
<h2 id="exponential-moving-average-ema">Exponential Moving Average (EMA)</h2>
<p>EMA는 <strong><em>최근 데이터에 더 많은 가중치를 준다.</em></strong></p>
<p>$\text{EMA}<em>t = \beta\text{EMA}</em>{t-1} + (1-\beta)x_t$</p>
<ul>
<li>$\beta$는 smoothing factor로, $0&lt;\beta \le 1$ 사이의 값을 가진다.</li>
</ul>
<blockquote>
<p>$\text{EMA}_{t-1}과 x_t에 대한 \text{Convex Combination}$ 이다.</p>
</blockquote>
<blockquote>
</blockquote>
<h4 id="⭐-recursive-form-of-average-에서-beta의-범위와-혼동-주의">⭐ Recursive form of average 에서 $\beta$의 범위와 혼동 주의</h4>
<p>최신 데이터를 반영하는 가중치가 <strong><em>시간</em></strong>에 따라 변하느냐, <strong><em>고정</em></strong>되어 있느냐의 차이이다.</p>
<ul>
<li>일반 평균: <strong>과거 데이터가 많이 쌓일수록 새로 들어온 데이터는 무시</strong></li>
<li>EMA: <strong>새로 들어온 데이터는 무조건 전체 평균의 일정 영향력 행사</strong></aside>

</li>
</ul>
<table>
<thead>
<tr>
<th><strong>Time</strong></th>
<th><strong>xt (sensor reading)</strong></th>
<th><strong>xˉt (EMA, β=0.5)</strong></th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>22.0</td>
<td>22.0 (initial)</td>
</tr>
<tr>
<td>2</td>
<td>22.5</td>
<td>$0.5 \cdot 22.0 + 0.5 \cdot 22.5 = 22.25$</td>
</tr>
<tr>
<td>3</td>
<td>23.0</td>
<td>$0.5 \cdot 22.25 + 0.5 \cdot 23.0 = 22.625$</td>
</tr>
<tr>
<td>4</td>
<td>22.8</td>
<td>$0.5 \cdot 22.625 + 0.5 \cdot 22.8 = 22.7125$</td>
</tr>
</tbody></table>
<blockquote>
<h3 id="recursive-form-of-average-랑-ema랑-같은-식">Recursive form of Average 랑 EMA랑 같은 식.</h3>
<p><strong>단지 $\beta$가 $\frac{t-1}{t}$ 인지, 0과 1 사이의 고정된 상수인지 따라 나뉜다.</strong></p>
</blockquote>
<h2 id="exponential-decay-in-ema">Exponential decay in EMA</h2>
<ul>
<li><strong><em>과거의 데이터가 어떻게 지수적으로 감소하며 잊혀지는가?</em></strong></li>
</ul>
<p>[일반적인 EMA 수식] : $v_t$ : <strong><em>현재 $t$ 시점에서의 EMA 값</em></strong></p>
<p>$v_t = \beta v_{t-1} + (1-\beta)x_t$</p>
<p>[ $t-1$  시점에서의 EMA: $v_{t-1}$ ]</p>
<p>$v_{t-1} = \beta v_{t-2} + (1-\beta)x_{t-1}$</p>
<p><strong>위 식 ($t-1$)시점을 현재 시점 수식에 집어넣어보자</strong> </p>
<p>$v_t = \beta (\beta v_{t-2} + (1-\beta)x_{t-1}) + (1-\beta)x_t$
$= \beta^2v_{t-2} + \beta (1-\beta)x_{t-1} + (1-\beta)x_t$ </p>
<p>이런 식으로 $\beta$의 지수가 점점 커진다.</p>
<p>무한히 반복하게 되면 </p>
<p>$v_t= \beta^tv_0 + (1-\beta)\sum\limits_{i=1}^t\beta^{t-i}x_i$</p>
<ul>
<li>$\beta^tv_0$: 맨 처음 초기값($v_0$)이 현재에 미치는 영향이다. 시간이 지나 $t$가 커지면 $\beta^t$는 거의 0이 되므로, 초기값의 영향력은 완전히 사라진다</li>
<li>$\beta^{t-i}$: 과거 시점 $i$의 데이터 $x_i$에 곱해지는 가중치이다.</li>
</ul>
<h2 id="sgd-with-momentum-1">SGD with Momentum</h2>
<ul>
<li>$\vec w_t$: $t$-step 에서의 최적화 변수</li>
<li>$\vec g_t = \vec g(\vec w_t)$ : $t-$step 에서의 Gradient 추정치</li>
</ul>
<p>$\vec m_t = \mu\ \vec m_{t-1} + \vec g_t$</p>
<ul>
<li><strong>$<em>\eta$ 는 0~1 사이의 값이기 때문에 Gradient에 더 가중치가 쏠림</em></strong></li>
</ul>
<p>$\vec w_{t+1} = \vec w_t -\eta \ \vec m_t$</p>
<hr>
<ul>
<li><strong>Higher $\mu$ : Smoother but slower to adapt</strong>
→ $\mu$가 크면 과거의 기억을 잘 가져간다. 노이즈를 다 무시해서 smooth하지만, 관성 때문에 코너를 크게 돈다. (Slower to adapt)</li>
<li><strong>lower $\mu$ : More responsive but more jittery</strong>
→ $\mu$가 작으면 새로운 기울기에 즉각 반응하여 방향을 휙휙 틈
하지만 불필요 노이즈에도 반응해서 jittery함</li>
</ul>
<blockquote>
<p><strong>$\mu$가 0이면 SGD랑 다를바가 없음</strong></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/74840ff9-f03c-4ed9-a68f-d26035f95080/image.png" alt=""></p>
<h2 id="exponential-decay-in-momentum-update">Exponential decay in Momentum update</h2>
<p>$\vec m_t = \mu \ \vec m_{t-1} + \vec g_t$</p>
<p>$\sum \limits_{k=0}^t\mu^k \vec g_{t-k}$</p>
<ul>
<li>$\mu^k$는 $k$가 커지면 커질수록 0으로 가까워짐 ($\mu : (0, 1)$)</li>
<li>$k$가 $t$일 때에는, $\mu^t \vec g_0$
→ 맨 처음 계산한 GD 효과를 죽이고, 최근 것에 가중치 올림</li>
</ul>
<blockquote>
<h4 id="ema랑-다를게-뭔데">EMA랑 다를게 뭔데?</h4>
<p>최근 데이터에 가중치 주고, 과거 데이터는 줄이는 아이디어는 동일</p>
<p><strong>가중치 합을 1로 맞추는 정규화 여부에 따른 차이가 존재함</strong></p>
<p>$v_t = (1-\mu)\sum \limits_{k=0}^t\mu^kg_{t-k}$ : EMA 수식</p>
<p>여기서는 앞에 $(1-\mu)$가 곱해져 있어서 가중치들의 총합이 1.
→ 과거 데이터를 많이 섞어도 결과값의 크기는 원래 데이터($g$)들의 평균적인 크기를 유지함 <em>(1이 되는건 등비수열의 합 공식 생각하기)</em></p>
<p>$m_t = \sum \limits_{k=0}^t\mu^kg_{t-k}$ : SGD의 모멘텀</p>
<p><strong><em>앞에 ($1-\mu$)가 없어서 가중치 총합은 $\frac{1}{1-\mu}$. 
→</em> 단순 평균이 아니라 과거 값들의 누적이 되어 스케일이 커짐</strong></p>
</blockquote>
<h1 id="adaptive-optimizers">Adaptive Optimizers</h1>
<h2 id="noisy-quadratic-model">Noisy Quadratic model</h2>
<p>$f(\vec w) = \frac{1}{2}(h_1w^2_1 + h_2w_2^2)$</p>
<ul>
<li>$h_1, h_2$는 곡률을 의미한다. (Hessian Matrix $H$ 의 고윳값)</li>
<li></li>
</ul>
<h1 id="adagrad">AdaGrad</h1>
<p><strong>AdaGrad는 ‘과거의 기울기’를 모두 기억하는 방식을 선택했다.</strong></p>
<p>$\vec h_t = \vec h_{t-1} + g_t \odot g_t$  :<br>→ <strong><em>기울기 제곱의 누적 [매 스탭 $t$ 마다 현재 기울기 $g_t$ 구하고 제곱해서 과거 누적에 더하기</em></strong></p>
<p>$\vec w_{t+1} = \vec w_t - \frac{\eta}{\sqrt{\vec h_t} + \epsilon} \odot \vec g_t$
→ 파라미터 업데이트: 누적값 $\vec h_t$를 사용해 파라미터 $\vec w$ 업데이트하기 </p>
<hr>
<p>$\vec  g_t = \frac{1}{|B_t|} \sum_{i\in B_t} \nabla f_i(\vec w_t)$ : 이건 그냥 기울기 구하는거</p>
<blockquote>
<p><strong>GD 제곱을 계속 축적시켜서 $\vec h_t$가 무한히 커져서 실제 적용되는 학습률이 0에 수렴해버려서 멈춰버림</strong></p>
</blockquote>
<ul>
<li><strong><em>AdaGrad는 Convex에서만 작동 잘 함</em></strong><ul>
<li>Non-Convex에서는 Local Minima에 빠짐</li>
</ul>
</li>
</ul>
<h1 id="rmsprop">RMSProp</h1>
<p>AdaGrad가 과거를 너무 다 기억해서 학습이 멈추는 문제가 있음
<strong><em>→ AdaGrad 수식에 EMA를 섞어서 옛 기울기는 잊도록 만든 것</em></strong></p>
<p>$\vec h_t = \beta\vec h_{t-1} + (1-\beta)\vec g_t \odot \vec g_t$</p>
<p>$\vec w_{t+1} = \vec w_t - \frac{\eta}{\sqrt{\vec h_t} + \epsilon} \odot \vec g_t$</p>
<h1 id="adam-rmsprop--momentum">Adam: RMSProp + Momentum</h1>
<p>$\vec m_t = \beta_1 \vec m_{t-1} + (1-\beta)\vec g_t$  : <strong>EMA of Gradients (1차 모멘트)</strong></p>
<p>$\vec v_t = \beta_2\vec v_{t-1} + (1-\beta_2)(\vec g_t \odot \vec g_t)$ 
→ 2차 모멘트</p>
<p>$\hat{\vec m} = \frac{\vec m_t}{1 - \beta^t_1}, \hat{\vec v} = \frac{\vec v_t}{1-\beta^t_2}$  : 편향 조정 </p>
<p>→ 학습 극초반, $t$가 작을 때 $m_t, v_t$가 0에 가깝게 계산되는 것을 막기 위함</p>
<p>$\vec w_{t+1} = \vec w_t - \frac{\eta}{\epsilon + \sqrt{\hat{\vec v}}} \odot \hat{\vec m}$ : <strong>Weight update</strong></p>
<ul>
<li>분자: 순수하게 요동치는 현재 기울기 $g_t$대신 모멘텀을 사용</li>
<li>분모: 무한히 커지는 누적합 대신, 2차 모멘트로 파라미터별로 $\eta$를 나눠줌</li>
<li>$\epsilon$: 분모가 완전히 0이 되어 폭발 방지</li>
</ul>
<h2 id="adam-bias-correction">Adam: Bias Correction</h2>
<p><strong>EMA에서 이전 시점의 평균값이 필요한데, 학습 막 시작한 단계($t=1$)일 때에는 과거 데이터가 없음</strong></p>
<p>→ $m_0, v_0$을 0벡터로 초기화하고 시작함</p>
<ul>
<li><strong><em>문제는 이 ‘0’이라는 값이 비어있다는 것이 아닌, 수학적으로 “과거 평균 기울기가 0” 이라는 잘못된 정보로 작용함</em></strong></li>
</ul>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/682a8853-ce9e-4231-8eba-f963fe7bf4cc/image.png" alt=""></p>
<p>실제 기울기는 $g_1$인데, 계산된 이동 평균 $m_1$은 실제의 10%의 값으로 되어버림</p>
<h4 id="해결-방안-bias-correction">해결 방안: Bias correction</h4>
<p>$\hat m:= \frac{m_t}{1-\beta^t_1}$ </p>
<p>분모에 있는 $t$는 단순 변수가 아닌, 지수이다. </p>
<p>→ 학습 스텝이 진행될수록 $\beta_1$을 $t$번 거듭제곱 하는 것</p>
<ul>
<li><p>학습 극초반 ($t=1$) 일 때:</p>
<p>  분모는 $1-0.9^1 = 0.1$이 된다.
  따라서 보정된 값 $\hat m_1 = \frac{0.1g_1}{0.1} = g_1$이 된다.
  <strong>정확히 실제 기울기 $g_1$로 100% 복귀되었다.</strong></p>
</li>
<li><p>학습 중반 이후($t=1000$)일 때:</p>
<p>  $\beta_1$은 1보다 작은 소수(0.9)이기 때문에, 1000번 거듭제곱을 하면 $0.9^{1000} \approx 0$으로 사실상 완전 소멸한다.
  분모는 $1-0 = 1$이 되고, 보정된 값 $\hat m_{1000} = \frac{m_{1000}}{1} = m_{1000}$ 이 된다.</p>
<blockquote>
<p>즉, <strong>데이터가 부족해서 0의 영향을 강하게 받는 극초반에는 강제로 스케일을 키워주고, 데이터가 충분히 쌓인 0의 영향력이 희석된 후반부에는 스스로 사라지는 장치이다.</strong></p>
</blockquote>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 논문 리뷰 ]: Agent Laboratory]]></title>
            <link>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Agent-Laboratory</link>
            <guid>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Agent-Laboratory</guid>
            <pubDate>Wed, 13 May 2026 10:56:16 GMT</pubDate>
            <description><![CDATA[<h1 id="agent-laboratory-llm-agents-as-ra">Agent Laboratory: LLM Agents as RA</h1>
<h2 id="what-does-agent-laboratory-do-for-you">What does Agent Laboratory do for you?</h2>
<p>Agent Laboratory는 Human Researcher를 대체하기 위한 것이 아닌, 연구 생산성을 극대화하는 Assistant 역할을 수행한다.</p>
<p>연구자는 기획과 비판적 사고에 집중하고, Agent는 코딩, 문헌 검색, 문서화 같은 반복적이고 시간 소모적인 작업을 처리하여 연구 생산성을 극대화한다. </p>
<p>로컬 컴퓨터부터 대규모 GPU 클러스터까지 다양한 컴퓨팅 환경에 맞춰 유연하게 작동한다.</p>
<h2 id="how-does-agent-laboratory-work">How does Agent Laboratory work?</h2>
<p>전체 연구 과정은 실제 인간의 논문 작성 방식과 유사하게 진행된다. 
각각의 Phase 마다 LLM으로 작동하는 특화된 Agent들이 서로 협력하고, 최적의 성과를 위해 외부 Tool들을 유기적으로 통합하여 활용한다. </p>
<h4 id="1-literature-review-관련-paper-수집-및-연구-계획-수립">(1) Literature Review: 관련 Paper 수집 및 연구 계획 수립</h4>
<h4 id="2-experimentation-mle-solver-모듈을-사용해-연구-코드를-iterative하게-개선">(2) Experimentation: <code>mle-solver</code> 모듈을 사용해 연구 코드를 Iterative하게 개선</h4>
<h4 id="3-report-writing-paper-solver-모듈을-통해-학술-논문-형태로-생성">(3) Report Writing: <code>paper-solver</code> 모듈을 통해 학술 논문 형태로 생성</h4>
<p>시스템이 모듈 형태로 설계되어 컴퓨팅 자원의 유연성을 보장한다. </p>
<p>사용자가 가진 컴퓨터 사양이 다르더라도 다양한 컴퓨팅 자원 환경을 수용하면서 고품질의 연구의 Output을 만들어낼 수 있다는 가능성을 시사한다.</p>
<h2 id="solving-ml-problems">Solving ML Problems</h2>
<p><strong>연구를 하기 위한 첫 걸음은 ML 문제들을 해결하는 능력일 것이다.</strong></p>
<p><strong>Agent Laboratory</strong>는 <code>mle-solver</code>를 사용하여 이 문제를 해결하는데, 구체적인 방식은 다음과 같다. </p>
<ul>
<li><strong>Iterative한 코드 개선:</strong> 이전 단계에서 도출된 연구 방향을 Text 형태로 입력 받은 뒤, Task Instructions, 명령어 설명, 정제된 지식 등을 바탕으로 Scoring Function에 따른 점수를 높이는 방향으로 코드를 수정한다.</li>
<li><strong>코드 수정 명령어: <code>REPLACE</code>, <code>EDIT</code></strong> 명령어를 사용하여 전체 코드 및 일부를 수정한다.</li>
<li><strong>오류 복구 및 자가 반성(Reflection):</strong> 코드가 성공적으로 컴파일 되면, 획득한 점수를 기반으로 업데이트를 수행한다. 오류가 발생하더라도 새로운 코드로 바로 넘어가지 않고, <em>최대 3번까지 스스로 오류 수정을 시도하며 각 단계마다 결과를 Reflect라고 성과를 정제</em>한다.</li>
</ul>
<blockquote>
</blockquote>
<h3 id="⭐-mle-bench-evaluation">⭐ MLE-Bench Evaluation</h3>
<p><code>mle-solver</code>의 문제 해결 능력은 Kaggle Competition을 통해 검증되었는데, OpenHands (gpt-4o), AIDE, MLAB 등 다른 AI Solver들보다 일관되게 높은 점수를 기록하며 총 4번의 메달 순위권에 돌랐다.
*<u>10개의 평가 항목 중 6개에서 <strong>Human Median 성과를 뛰어넘는</strong> 능력을 입증하였다.</u>* </p>
</aside>

<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/9241a15d-6b01-46a8-b314-b8d1becea5ac/image.png" alt=""></p>
<h2 id="writing-research-reports">Writing Research Reports</h2>
<p>두 번째 단계는 연구 보고서를 실험에 기반하여 작성하는 것이다. </p>
<p><code>paper-solver</code>를 사용하여 사람이 읽을 수 있는 학술 논문을 생성하는데, 어떻게 해당 Task를 수행하는지 알아보자.</p>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/a3344b48-3f3a-409e-aa74-f854a86492ca/image.png" alt=""></p>
<p>이 다이어그램은 <code>paper-solver</code> 툴을 사용하여 Research Report를 생성 및 정제하는 과정을 step-by-step 으로 보여준다. </p>
<h4 id="initial-report-scaffold">Initial Report Scaffold</h4>
<p>이 워크프로우는 (A): Initial Report Scaffold를 만드는 것으로 시작하는데, LM(이하 Language Mode)이 논문의 Scaffold를 <strong><code>REPLACE</code>와 LaTeX</strong> 컴파일러를 거쳐 PDF로 정상 변환되는지 확인하고, 수정을 통해 생성한다.</p>
<p>초록이 완성되면 다음 섹션으로 넘어가 내용을 덧붙이고, 다시 컴파일하여 Scaffold를 Update하는 방식으로 전체 구조가 완성될 때까지 Iterative하게 동작한다.</p>
<h4 id="arxiv-research-tool">arXiv Research Tool</h4>
<p>섹션을 작성하는 과정은 외부 지식과 단절되어 있지 않은데, Introduction이 Related Work 등 선행 연구 조사가 필수적인 섹션을 작성할 때에는, <code>arXiv research</code> 도구를 호출한다. 이를 통해 실제 arXiv DB에서 최신 paper를 검색하고, 내용을 바탕으로 사실 기반하여 작성한다.</p>
<h4 id="report-editing">Report Editing</h4>
<p>초안 뼈대가 완성되면, 내용을 다듬고 완성도를 높인다.</p>
<p>LM은 기존의 Research, outline, results, PDF report등 모두를 Prompt로 입력 받는다. </p>
<p>초기 뼈대를 잡을 때에는 전체를 수정하는 <strong><code>REPLACE</code></strong> 명령어를 사용했다면, 정교화 단계에서는 <strong><code>EDIT</code></strong>명령어를 사용한다. 
→ 기존 논문에서 수정이 필요한 특정 line만 찾아내어 정교하게 다듬는다.</p>
<blockquote>
<p><em>내용이 수정될 때마다 다시 LaTeX 컴파일러를 거쳐, 문버버 오류 등으로 컴파일 실패를 겪으면 다시 수정하고 성공할 때만 다음 평가 단계로 넘어간다.</em></p>
</blockquote>
<h4 id="paper-review">Paper Review</h4>
<p>오류 없이 컴파일 되었다면, 마지막 검증을 받는다.</p>
<p>사전에 정의된 보상 함수를 통해 논문의 질을 평가하고, 품질 보증 단계를 거치는 과정이다. </p>
<h2 id="41-evaluation-of-quality-by-language-model">4.1. Evaluation of quality by Language Model</h2>
<p>해당 파트는 [<em>Human Perception of quality by LM]</em> 대신 작성한다.</p>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/9755a242-7465-4d64-9e32-355432580585/image.png" alt=""></p>
<p>논문의 <em>4.1. Evaluation of quality by language model</em> 섹션은 3가지 다른 대형 언어 모델(gpt-4o, o1-mini, o1-preview)을 벡엔드로 사용하여 Agent Laboratory가 완전 자율모드로 생성한 연구 논문들의 품질을 <strong>인간 평가자들이</strong> 어떻게 인식하는지 자세히 분석하였다.</p>
<h3 id="평가-지표-및-모델별-성능-비교">평가 지표 및 모델별 성능 비교</h3>
<p>평가자들은 생성된 논문을 <strong><em>실험 품질, 보고서 품질, 유용성</em></strong> 세 가지 주요 기준으로 평가하였다.</p>
<ul>
<li><strong>o1-preview</strong>: 전체 모델 중 연구 보조 도구로서의 <strong><em>유용성</em></strong>과 <strong><em>보고서 품질</em></strong>에서 가장 높은 평가를 받았지만, 실험 품질은 2.9/5 점으로, o1-mini보다 약간 낮았다.</li>
<li><strong>o1-mini</strong>: <strong><em>실험 품질 부문에서 가장 높은 점수</em>를</strong> 기록하였으며, 기술적이고 실험적 측면에서 상대적으로 우수함을 보인다. 유용성과 보고서 품질 또한 준수한 평가를 받았다.</li>
<li><strong>gpt-4o</strong>: 세 모델 중 모든 지표에서 가장 낮은 평가를 받았다. 👎</li>
</ul>
<blockquote>
<p><strong>결과적으로 보고서의 작성과 전반적 유용성 측면에서는 o1-preview가 가장 적합하며, o1-mini는 실험적 결과물을 내는 데 더 강점을 보인다.</strong></p>
</blockquote>
<blockquote>
<h4 id="⭐자동화된-ai-평가와-실제-인간-평가의-괴리">⭐자동화된 AI 평가와 실제 인간 평가의 괴리</h4>
<p>논문에서는 LLM 리뷰어가 스스로 평가한 ‘자동화된 점수’와 ‘Human Reviewer’의 점수를 비교하였는데, <strong><em>자동화된 리뷰어는 논문의 품질을 인간 평가자보다 지나치게 Over-estimate하는 경향</em>이</strong> 강했다.<br>
→ 자율적 연구 에이전트의 결과물을 검증할 때 단순히 LLM의 자가 평가에 의존해서는 안되며, <strong>인간의 평가와 피드백 수반이 필연적임을 시사</strong>한다. </p>
</blockquote>
<h2 id="co-pilot-quality">Co-Pilot Quality</h2>
<p>인간 연구자가 각각의 subtask가 끝날 때마다 피드백을 제공하는 Co-Pilot 모드에서의 Agent Laboratory 성능을 평가하였다. </p>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/01011556-49bf-4ad7-9b2d-73bbe53cec58/image.png" alt=""></p>
<p>평가는 <strong>연구 보조 도구로서의 품질</strong>과 <strong>생성된 논문의 품질</strong>이라는 두 가지의 측면에서 이루어졌다. </p>
<h3 id="421-quality-as-a-tool">4.2.1. Quality as a Tool</h3>
<p>참여한 연구자들은 Agent Laboratory르르 사용한 경험에 대해 유용성 (3.5/5) , 지속 사용 의향(3.75/5) , 만족도(3.63/5) , 사용 편의성(4.0/5) 을 평가하였다.</p>
<blockquote>
<p>Co-Pilot 모드에서의 실험 품질이나 보고서 품질은 자율모드 평가 때보다 오히려 낮게 평가되었는데, 이는 <strong>연구자가 Agent를 자신의 정확한 연구 의도대로 실행하게 이끄는 과정에서 어려움을 겪었기 때문</strong>으로 보인다.</p>
</blockquote>
<h3 id="422-evaluation-of-co-pilot-generated-papers">4.2.2. Evaluation of co-pilot generated papers</h3>
<p>생성된 논문의 품질 평가는 연구자 본인의 ‘자체 평가’와 ‘외부 평가자’의 두 가지 방식으로 수행되었다.</p>
<ul>
<li><strong>자체 평가 vs. 외부 평가:</strong> 연구자들이 자신이 가이드한 논문을 직접 평가했을 때에는 4.13 / 10 점, 외부 평가자들은 동일한 논문에 4.38 / 10점을 주어 <strong>외부에서 보았을 때 논문의 품질과 중요성이 더 높게 평가되는경향</strong>을 확인하였다.</li>
<li><strong>자율모드와의 비교:</strong> 외부 평가 기준으로 볼 때, 인간이 개입한 <strong>Co-Pilot 모드로 생성된 논문은 Autonomous Mode로 생성된 논문보다 종합 점수가 평균 0.58점 높았다.</strong></li>
</ul>
<p>Referred from: <a href="https://agentlaboratory.github.io">https://agentlaboratory.github.io</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문 리뷰 + 코드 구현] ConvNeXt]]></title>
            <link>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-%EC%BD%94%EB%93%9C-%EA%B5%AC%ED%98%84-ConvNeXt</link>
            <guid>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-%EC%BD%94%EB%93%9C-%EA%B5%AC%ED%98%84-ConvNeXt</guid>
            <pubDate>Sun, 03 May 2026 16:38:23 GMT</pubDate>
            <description><![CDATA[<h1 id="introduction">Introduction</h1>
<p>2010년대 컴퓨터 비전 분야는 ResNetr과 같은 ConvNet이 지배적이었다. </p>
<p>ConvNet이 시각 인식 시스템의 기본 구성 요소로 자리잡을 수 있었던 이유는 Sliding Window 방식의 도움이 컸는데, 이는 고해상도 이미지 작업에 본질적이기 때문이다. </p>
<p>ConvNet은 다양한 컴퓨터 비전 응용 프로그램에 매우 적합한 Inductive Bias가 있는데, 이 중에서 가장 중요한 것은 객체 탐지와 같은 작업에 알맞은 translation equivariance이다. </p>
<p>Inductive Bias의 세 가지 대표 요소는 <a href="https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-%EC%BD%94%EB%93%9C-%EA%B5%AC%ED%98%84-ViT-An-Image-is-Worth-16x16-Words-Transformers-For-Image-Recognition-At-Scale">ViT논문 리뷰</a>를 참고하자. </p>
<p>한편, 자연어처리(NLP) 분야를 지배하던 Transformer 구조가 2020년 Vision Transformer(ViT)라는 이름으로 비전 분야에 도입이 되면서 큰 변화가 일어났다.</p>
<p>ViT는 이미지를 패치 단위로 나누는 초기 레이어를 제외하면 이미지 특화적인 Inductive bias를 최소화했으며, 거대한 모델 크기와 데이터셋을 바탕으로 이미지 분류에서 표준 ResNet의 성능을 크게 뛰어넘었다.</p>
<p><strong>하지만, ViT의 &#39;Global Attention&#39; 메커니즘은 Input에 대해 Quadratic 복잡도를 가지기 때문에, 고해상도 이미지를 다루는 일반적인 비전 작업의 Backbone으로 사용하기에는 계산량이 기하급수적으로 늘어나는 한계가 有.</strong></p>
<blockquote>
<p>ViT는 이미지를 패치 단위로 쪼개어 문장 속 단어처럼 취급한다.
Self-Attention은 &quot;어떤 패치를 이해하기 위해, 이미지 내의 &#39;모든&#39; 다른 패치들을 한 번씩 다 훑어보고 연관성을 계산하는 것&quot;이다. <strong>전체 패치를 다 본다고 해서 Global Attention</strong>이라고 부른다.</p>
</blockquote>
<p>이러한 ViT의 한계를 극복하기 위해 등장한 것이 Swin Transformer와 같은 Hierarchical Transformer 모델이다. </p>
<p>Swin Transformer는 <strong>Local Windows</strong> 내에서만 Attention 연산을 수행하는 Sliding Window 방식을 다시 도입하여, ConvNet과 유사한 동작을 하고, 이를 통해 다양한 비전 작업에서 뛰어난 성능을 입증했다.</p>
<blockquote>
<p>그럼 결국 Convolution의 특성을 다시 가져온 것인데.. 이 논문이 나옷것도, Local Operation에 강한 ConvNet(CNN)을 다듬는 것이 더 좋을 것이라는 주장에서 나온다. </p>
</blockquote>
<p>본 연구는 ConvNet과 Transformer 간의 아키텍처 차이를 조사하고 네트워크 성능을 비교할 때 Confounding Variables를 식별한다고 한다. </p>
<p>이를 위해 표준 ResNet-50 모델을 사용하며, Attention 모듈을 전혀 사용하지 않은 채 Swin Transformer의 구조적 특징들을 적용하며 점진적으로 네트워크를 modernize 한다고 한다. </p>
<hr>
<h1 id="modernizing-a-convnet-a-roadmap">Modernizing a ConvNEt: a Roadmap</h1>
<p>표준 ResNet-50 모델에 Attention 모듈을 하나도 추가하지 않고, Vision Transformer의 디자인 철학만 차용해서 구조를 뜯어고쳤을 때 성능은 얼마나 오르는지 살펴보자.</p>
<p>이 과정은 크게 6개의 Step으로 나눌 수 있다.</p>
<ul>
<li>Training Techniques</li>
<li>Macro Design </li>
<li>ResNeXt-ify</li>
<li>Inverted Bottleneck</li>
<li>Large Kernel Sizes</li>
<li>Micro Design<h3 id="training-techniques">Training Techniques</h3>
네트워크 아키텍처를 변경하기 전에, Transformer가 도입한 최신의 학습 기법을 먼저 ResNet-50에 적용한다.
Transformer와 유사하게 학습 Epoch를 90에서 300으로 늘리고, AdamW를 비롯하여 Mixup, Cutmix, RandAugemnt, RAndomErasing 등의 Augmentation 기법들을 도입했다. </li>
</ul>
<p>이러한 Training Techniques를 적용한 것만으로 모델 성능이 76.1%에서 78.8%로 향상되었으며, 이는 기존 ConvNet과 Transformer사이의 성능 차이 상당 부분이 Training Techniques에서 비롯됨을 알 수 있다.</p>
<hr>
<h3 id="macro-design">Macro Design</h3>
<p>네트워크의 거시적인 뼈대를 Transformer와 비슷하게 변경했다. </p>
<p>Swin Transformer는 ConvNet을 따라 각 스테이지가 다른 특징 맵 해상도를 갖는 <strong>다중 스테이지 설계</strong>를 사용하는데, 이 때 두 가지를 고려한다.</p>
<p><strong>- Stage Compute Ratio:</strong> 기존 ResNet-50의 각 스테이지 블록 개수는 (3, 4, 6, 3)이었으나, 이를 Swin Transformer 비율에 맞게 <strong>(3, 3, 9, 3)</strong>으로 조정했다.</p>
<p>*<em>- Patchify Stem으로 교체: *</em>일반적인 ViT가 이미지를 패치화 하듯, ResNet의초기 7x7 Convolution과 Max Pool 층을 4x4 크기에 stride 4를 갖는 겹치지 않는 <em>non-overlapping convolution)</em>으로 단순 교체했다.</p>
<hr>
<h3 id="resnext-ify">ResNeXt-ify</h3>
<p>일반 Convolution 대신, 채널별로 따로 연산하는 <strong>Depthwise Convolusion</strong>을 도입했다. </p>
<p>이는 Self-Attention 연산이 Spatial 차원에서만 정보를 섞고 채널 정보는 섞지 않는 특성과 수학적으로 매우 유사하다.</p>
<p>이로 인해 연산량이 크게 감소하고, 손실된 용량을 보완하기 위해 네트워크의 채널 폭을 Swin Transformer와 동일하게 64에서 96으로 확장한다.</p>
<blockquote>
<h4 id="채널-폭을-늘린-이유-depth-wise-conv--width">채널 폭을 늘린 이유 (Depth-wise Conv &amp; Width)</h4>
<p>기존 ResNet에서 쓰는 일반 Convolution은 &#39;모든 채널&#39;을 한 번에 섞어서 계산하기 때문에 연산량이 크다. 
<br>반면, 이 논문에서 도입한 <strong>Depth-wise Convolution</strong>은 각 채널을 독립적으로 계산한다. 
이는 self-attention이 채널별로 가중합(Weighted Sum)을 수행하는 것과 수학적으로 매우 유사한 성질을 가진다.
<Br>문제는 연산 방식을 이렇게 바꾸면 연산량(FLOPs)이 훅 떨어지는 대신, 모델이 학습할 수 있는 용량(Capacity)도 떨어져서 성능이 하락한다.
  그래서 ResNeXt의 핵심은 <em>그룹을 많이 쪼개는 대신, 네트워크 폭을 넓히는 것</em>이다.
<br>  즉, <strong>Depthwise Conv로 연산량을 크게 아꼈으니, 그 아낀 연산량을 투자해서 기본 채널 크기를 64에서 Swin Transformer와 같은 96으로 확장한 것</strong>이다. </p>
</blockquote>
<hr>
<h3 id="inverted-bottleneck">Inverted BottleNeck</h3>
<p>  기존 ResNet의 기본 블록인 BottleNeck 구조는 다음과 같다.</p>
<p>**  [ResNet]**
Input -&gt; 3x3 Conv -&gt; Output
  연산량이 많은 3x3 Conv를 할 때, 차원을 줄여서 병목 계산을 아끼는 것이 목적이었다.</p>
<p>  하지만, Transformer의 핵심 요소인 MLP 블록은 정반대이다. <strong>Hidden Dimension을 입력 차원보다 4배 넓게 팽창시켰다가 다시 줄이는 구조를 사용하는데, 
  연구진들은 이 아이디어를 ConvNet에 그대로 적용한다.</strong>
  <img src="https://velog.velcdn.com/images/jm_mg_se/post/765d2fc3-e914-4aa7-b072-9c3a84cb6e27/image.png" alt=""></p>
<p> *<em>(a) 는 전통적인 병목 구조로, 기존에 우리가 알던 ResNet의 기본 형태이다. *</em></p>
<ul>
<li>1x1 Conv (384 $\rightarrow$ 96 축소)</li>
<li>Depthwise 3x3 Conv (96$\rightarrow$ 96 유지</li>
<li>1x1 Conv (96 $\rightarrow$ 384 팽창)</li>
</ul>
<p>연산량이 많은 3x3 Conv를 통과시키기 전에 먼저 1x1을 사용해서 채널 차원을 384 $\rightarrow$ 96으로 연산량을 아끼고, 계산이 끝나면 다시 384로 돌려 놓는다.</p>
<p>**  (b)는 역 병목 구조(Inverted BottleNeck)을 적용한 구조**이다. 
  Transformer의 구조를 따라한 것으로, 트랜스포머의 MLP 블록은 Hidden Dimension이 입력 차원보다 4배 더 큰 특징을 가진다. </p>
<p>  이를 ConvNet에 적용하면 모래시계처럼 다이아몬드 모양인데, 이 아이디어는 ConvNet의 MobileNetV2 등에도 사용된다고 한다.</p>
<ul>
<li>1x1 Conv (96 $\rightarrow$ 384 팽창)</li>
<li>Depthwise 3x3 Conv (384 $\rightarrow$ 384 유지)</li>
<li>1x1 Conv (384 $\rightarrow$ 96 축소)</li>
</ul>
<p>처음부터 좁은 96차원으로 들어와서, 중간에 384 차원으로 <strong>4배 팽창(Inverted Bottleneck)</strong> 시킨 후, 연산을 하고 다시 96 차원으로 줄여서 내보내도록 설계가 바뀌었다.</p>
<blockquote>
<p>(a)에서는 무거운 연산 (Depthwise 3x3)을 96차원에서 했는데, (b)에서는 384 차원으로 했다. <br><br><strong>그럼 연산량이 4배 늘어나야 하는 것 아닌가?</strong>
  <br> 논문에 따르면, <strong>전체 네트워크의 연산량(FLOPs)은 오히려 5.3G에서 4.6G로 크게 감소</strong>했다.
그 이유는 <strong>잔차 연결(Shortcut Connection)</strong> 때문인데, 
  (b) 구조로 바뀌면서 블로그이 최종 출력 차원이 384에서 96으로 크게 줄어든 결과, 해상도를 줄이는 블록 Downsampling Block의 Shortcut 역할을 하는 1x1 Conv 레이어가 처리해야 할 채널 수도 384에서 96으로 크게 줄어들면서, <strong>여기서 아낀 연산량이 훨씬 큰 것</strong>이다. </p>
</blockquote>
<p><strong>(c): Depthwise Conv의 위치를 맨 위로</strong></p>
<ul>
<li>Depthwise 3x3 Conv (96 $\rightarrow$ 96)</li>
<li>1x1 Conv (96 $\rightarrow$ 384 팽창)</li>
<li>1x1 Conv (384 $\rightarrow$ 96 축소)</li>
</ul>
<p>트랜스포머 블록을 보면 항상 Spatial Info를 섞는 MSA(Attention 모듈)가 먼저 오고, 그 뒤에 차원을 넓혔다 줄이는 MLP 모듈이 따라온다. </p>
<blockquote>
<h4 id="standard-convolution">Standard Convolution</h4>
<p>  <code>standard_conv = nn.Conv2d(in_channels=96, out_channels=96, kernel_size=7, padding=3)</code>
  기본적으로 <code>groups=1</code>이 생략되어 있어, 96개의 입력 채널이 한꺼번에 연산되어 96개의 출력 채널을 만들어내기 때문에 연산량이 막대하다.</p>
</blockquote>
<h4 id="depthwise-convolution-convnext-방식">Depthwise Convolution (ConvNeXt 방식)</h4>
<p>  <code>depthwise_conv = nn.Conv2d(in_channels=96, out_channels=96, kernel_size=7, padding=3, groups=96)</code>
  <br><strong><code>groups</code>파라미터의 값을 입력 채널 수 (<code>in_channels</code>)와 같게 맞춰준다.</strong></p>
<ul>
<li><code>groups=96</code>이라고 설정하면, 파이토치는 96개의 채널을 96개의 그룹으로 분할한다.</li>
<li>결과적으로 1개의 그룹당 1개의 채널만 들어가게 된다.</li>
<li>각각의 채널이 다른 채널과 섞이지 않고 <strong>자기 자신만의 필터(가중치)를 가지고 독립적으로 연산을 수행</strong>하게 된다.</li>
</ul>
<p>  <img src="https://velog.velcdn.com/images/jm_mg_se/post/e41aafe5-10ff-4e2c-889a-d53b0f09ada0/image.png" alt=""></p>
<p>  이 순서를 그대로 ConvNet에 매핑한 것이다. 
  (b)에서는 팽창된 384 차원에서 Depthwise Conv를 했지만, (c)에서는 팽창하기 전인 좁은 96차원에서 먼저 Depthwise Conv를 해버린다.</p>
<p>  덕분에 복잡한 Spatial Mixing은 가벼운 채널(96)에서 해버리고, 단순 차원 확장/축소 연산(Channel Mixing)만 1x1 Conv에 맡길 수 있다.</p>
<p>  정리하자면, &quot;어떻게 하면 ConvNet의 블록을 Transformer의 블록 구조$\rightarrow$ 넓은 MLP)와 똑같이 맞추면서 연산량은 오히려 줄일 수 있을까?&quot; 에 대한 과정이다.</p>
<hr>
<h3 id="large-kernel-sizes">Large Kernel Sizes</h3>
<p>  Transformer의 특징인 Global Receptive Field를 ConvNet에서도 모방하기 위해 Kernel Size를 키웠다.</p>
<p>  과거 VGGNet의 등장 이후, ConvNet에서는 <strong>&quot;큰 커널 하나를 쓰는 것보다 3x3 커널을 여러 층 깊게 쌓는 것이 연산량도 적고 효율적이다.&quot;</strong> 라는 것이 Standard로 자리잡게 되었다.</p>
<p>  하지만 Transformer는 달랐다. ViT는 이미지를 한 번에 보는 능력이 있었고, 심지어 연산량을 줄인 Swin Trasnformer조차도 최소 7x7 크기의 Window 단위로 큼지막하게 이미지를 처리했다.</p>
<p>  그래서 연구진들도 3x3의 틀을 깨고, 커널 크기를 키워보자는 것이다.</p>
<p>  <strong>- Depthwise Conv 끌어올리기</strong>
  앞서 (c)에서 <code>Depthwise-Conv</code>를 블록 맨 위로 끌어올린 것을 기억 할 것이다. 사실 이것이 &#39;큰 커널&#39;을 감당하기 위한 작업이었다.</p>
<ul>
<li><p>만약 384 차원으로 4배 확장된 곳에서 7x7처럼 큰 kernel을 돌렸더라면, 연산량이 말도 안되게 폭발했을 것이다.</p>
<p>커널의 위치를 블록 맨 위로 올려서, <strong>커널 크기를 7x7로 거대하게 키워도 FLOPs는 거의 늘어나지 않고, 4.1G로 유지</strong>될 수 있던 것이다.</p>
</li>
</ul>
<p>연구진들은 Kernel Size를 3x3에서 시작해서 5x5, 7x7, 9x9, 11x11 까지 점차 늘려보며 성능을 측정했다.</p>
<blockquote>
<p><strong>결과</strong>: 커널을 키울수록 성능이 오르다가, <strong>7x7 크기에 도달했을 때 80.6%로 성능 향상이 정점을 찍었다.</strong>
  <br>그 이상으로 커널을 키워도 연산량이 아주 조금 늘어날 뿐, 성능은 더 이상 좋아지지 않았다. </p>
</blockquote>
<p>  저자들이 실험으로 찾은 최적 커널 크기가 공교롭게도 7x7인데, <strong>Swin Transformer 역시 window크기를 7x7로 흔히 설정하는 것</strong>을 보면, 순수 ConvNet도 7x7 크기의 Depthwise Convolution kernel 을 사용하면 트랜스포머의 넓은 Receptive Field와 지역적 연산 방식을 흉내낼 수 있다는 것을 보인다.</p>
<hr>
<h3 id="micro-design">Micro Design</h3>
<p>레이어 구석구석의 디테일을 Transformer의 스타일과 맞추는 작업을 해보자.</p>
<p>  이 단계에서는 총 5가지의 Micro Design이 진행된다.</p>
<ul>
<li><strong>활성화 함수 교체:</strong> ReLU $\rightarrow$ GELU</li>
<li><strong>활성화 함수 개수 최소화</strong></li>
<li>*<em>정규화 레이어 개수 최소화 *</em><ul>
<li>*<em>BatchNorm(BN) $\rightarrow$  LayerNorm(LM) 교체 *</em></li>
</ul>
</li>
<li><strong>별도의 DownSampling 레이어 도입</strong>
<img src="https://velog.velcdn.com/images/jm_mg_se/post/59cd29bc-370b-4c54-bc0a-7b5ec30c24c9/image.png" alt=""></li>
</ul>
<h4 id="--활성화-함수-교체">- 활성화 함수 교체</h4>
<p>  기존 ConvNet은 오랫동안 계산이 빠르고 단순한 <strong>ReLU</strong>를 가장 기본적으로 사용해왔다.</p>
<p>  하지만, 최신 Transformer(BERT, GPT-2, ViT 등)은 ReLU보다 곡선이 더 부드러운 <strong>GELU</strong>를 표준으로 사용한다.</p>
<p>  <img src="https://velog.velcdn.com/images/jm_mg_se/post/2871e09e-b8e1-4cb5-9414-6963d5089d5f/image.png" alt=""></p>
<p>  그래서 ConvNeXt도 Transformer를 따라서 활성화 함수를 모두 GELU로 바꿨다. (<em>다만 이 시점에서는 성능은 동일하게 80.6%로 같다.</em>)</p>
<h4 id="--활성화-함수-개수-최소화">- 활성화 함수 개수 최소화</h4>
<p>  일반적인 ConvNet(ResNet)은 1x1을 포함한 모든 Conv Layer 뒤에 활성화 함수를 꼬박꼬박 붙이는 것이 Standard이다.</p>
<p>  하지만, Transformer의 MLP블록을 보면, 선형 레이어들 사이에 <strong>활성화 함수가 딱 1개</strong>만 존재한다.</p>
<p>  연구진들은 이 점에 착안하여 블록 내에 있던 GELU를 전부 지워버리고, <strong>두 개의 1x1 Conv layer 사이에 딱 하나의 GELU만 남겼다.</strong> 
  <strong>(놀랍게도 이걸로 성능이 80.6 $\rightarrow$ 81.3%로 향상되며 Swin Transformer와 성능이 사실상 같아졌다.)</strong></p>
<h4 id="--정규화-레이어의-개수-최소화">- 정규화 레이어의 개수 최소화</h4>
<p>  활성화 함수와 마찬가지로, Transformer는 블록 내에 정규화 레이어도 훨씬 적게 사용한다.</p>
<p>  이를 반영하여 블록 안에 붙어있던 여러 개의 Batch Norm(BN) 레이어를 삭제하고, <strong>1x1 Conv 레이어들 앞에 딱 1개의 정규화 레이어만 남겼다.</strong></p>
<p>  결과적으로 81.4%로 성능이 오르며 <strong>Swin-Transformer를 뛰어 넘는다.</strong></p>
<h4 id="--batchnormbn-rightarrow-layernormln-교체">- BatchNorm(BN) $\rightarrow$ LayerNorm(LN) 교체</h4>
<p>  BatchNorn(BN)은 ConvNet의 성능을 끌어올린 공신이지만, 배치 크기에 민감하게 반응하는 등 은근히 까다롭다.</p>
<p>  반면 NLP와 Trasnformer모델들은 구조가 훨씬 단순한 LayerNorm(LN)을 주로 사용해서 뛰어난 성능을 낸다.</p>
<p>  과거에는 Original ResNet 에 LN을 그냥 넣으면 성능이 오히려 떨어졌다. 하지만 뼈대를 Transformer 친화적으로 바꾸고 LN을 도입해보니, 아무런 문제 없이 학습이 잘 되고 성능도  81.5%로 소폭 상승했다.</p>
<h4 id="--별도의-downsampling-layer-도입">- 별도의 DownSampling Layer 도입</h4>
<p>  이미지의 가로세로 해상도를 반으로 줄일 때, 기존 ResNet은 새로운 Stage가 시작되는 첫 번째 블록 안에서 3x3 Conv에 <code>stride 2</code>를 줘서 해상도를 줄였다.</p>
<p>  하지만, Swin Transformer는 Stage 사이에 <strong>해상도만 전담해서 줄이는 독립적인 레이어</strong>를 두고 있다.</p>
<p>  이를 흉내내서 ConvNeXt도 DownSampling을 블록 밖으로 분리하여 <strong>2x2 Conv (stride 2)</strong> 레이어를 별도로 만들었다.</p>
<blockquote>
<p>이렇게만 설정하면 학습이 발산하는 문제가 발생하는데, Swin-T가 하는 것처럼 <strong>해상도가 변하는 곳(DownSampling 레이어 앞, 초기 패치화 직후, 마지막 풀링 직후)마다 LN 레이어를 추가</strong>해주었다.
  <br>덕분에 학습이 완벽히 안정화 되었으며, 최종 성능 82.0%를 달성하며 실험은 성공적으로 끝난다.</p>
<blockquote>
<h4 id="pytorch-layernorm의-한계">PyTorch <code>LayerNorm</code>의 한계</h4>
<p>  파이토치로 <code>Layer Norm</code>을 사용하여모델을 구현할 때에는 텐서 차원의 충돌을 주의해야 한다. 
  <code>nn.LayerNorm</code>은 자연어처리를 위한 함수이기 때문에 Computer Vision에서 사용하는 것과 형태가 약간 다르다.
  <br></p>
</blockquote>
</blockquote>
<ul>
<li>자연어 처리에서의 데이터: <code>(B, Sequence, Embedding)</code></li>
<li>CV 에서의 데이터 형태: <code>(B, C, H, W)</code> -&gt; <code>(N, C, H, W)</code>
<Br>파이토치의 <code>nn.LayerNorm()</code>은 기본적으로 텐서의 가장 마지막 차원을 기준으로 데이터를 묶어서 평균과 분산을 구하도록 하드코딩 되어있다.<br>
`permute` 없이 그냥 `LayerNorm`을 하게 된다면 크기 불일치 분제로 에러가 발생하기 쉽다.

</li>
</ul>
<hr>
<h1 id="empirical-evaluations-on-imagenet">Empirical Evaluations on ImageNet</h1>
<h2 id="model-scaling">Model Scaling</h2>
<p>  Swin-T와 공정하게 성능을 비교하기 위해, ConvNeXt-T (Tiny)를 기본 골격으로 삼고, 각 Stage의 채널 수(C)와 블록 개수(B)를 늘려가며 ConvNeXt-S (Small), B(Base), L(Large), XL(Extra Large) 버전을 만들었다.</p>
<p>  크기를 키우는 방식은 기존 ResNet이나 Swin-T가 모델을 확장하는 방식과 완전 동일하다.</p>
<h2 id="fine-tunning">Fine-tunning</h2>
<p>  ViT나 Swin-T는 학습할 때와 테스트할 때 이미지의 해상도가 달라지면 패치 크기를 조절하거나 Position Bias 값을 새롭게 interpolate하는 번거로움이 있다.</p>
<p>  하지만 ConvNeXt는 Fully-convolutional 이기 때문에, <strong>입력 해상도가 달라져도 네트워크 구조를 뜯어고칠 필요 없이 아주 단순하게 Fine-Tunning 가능</strong>하다.</p>
<h2 id="imagenet-1k-results">ImageNet-1K Results</h2>
<p>  120만장의 이미지를 가진 ImageNet-1K의 결과이다.</p>
<ul>
<li>** Accuracy**: 모든 스케일 (T,S,B,L)에서 ConvNeXt가 비슷한 파라미터 크기를 가진 Swin-T의 정확도를 능가했다.</li>
<li><strong>Throughput</strong>: ConvNeXt-B 모델을 384x384 고해상도로 테스트했을 때 Swin-B 보다는 0.6% 높으면서 <strong>추론 속도는 12.5% 더 빨랐다.</strong><blockquote>
<p>Swin은 성능을 내기 위해 Shifted Window와 ㄱ ㅏㅌ은 특수한 모듈을 써야해서 하드웨어 친화적이지 않다.
<br>반면, ConvNeXt는 GPU 친화적인 표준 Conv 모듈만을 사용하기 때문에 실제 속도 면에서 훨씬 유리하다.</p>
</blockquote>
</li>
</ul>
<h2 id="imagenet-22k-results">ImageNet-22K Results</h2>
<p>  이 부분에서는 <strong>데이터가 많아지면 Transformer가 이길 것</strong>이라는 편견을 부순다.</p>
<ul>
<li><p>ConvNet은 이미지에 특화된 Inductive Bias가 있어서 작은 데이터에서는 좋지만, 데이터가 1천만 장 단위로 넘어가면 제약이 없는 ViT가 더 성능이 좋을 것이라는 믿음이 있었다.</p>
</li>
<li><p>1,400만장의 ImageNet-22K에서 ConvNeXt는 동급의 Swin Transformer와 성능이 같거나 더 우수했다.
ConvNeXt-XL 모델은 무료 87.8% 라는 압도적인 성능을 보이기도 했다.</p>
<blockquote>
<p>연구진들은 <strong>레이어를 지날수록 해상도가 줄어드는 Hierarchical 구조에서 실험했는데, 처음부터 끝까지 해상도가 유지되는 Vanila ViT 구조에 ConvNeXt를 끼워 넣어봤다.</strong>
<br> 실험 결과, ViT와 똑같은 형태로 뼈대를 짜고 ConvNeXt 블록을 채워도 기존 ViT와 대등한 성능을 냈다.
즉, ConvNeXt의 블록 디자인 자체가 어떤 형태의 Architecture에 가져다 붙여도 강력한 설계라는 것이다.</p>
</blockquote>
</li>
</ul>
<hr>
<h1 id="empirical-evaluation-on-downstream-tasks">Empirical Evaluation on Downstream Tasks</h1>
<p>  단순 이미지가 &#39;고양이&#39;인지, &#39;강아지&#39; 인지 맞추는 분류 작업도 중요하지만, 자율주행, 의료AI 등 실제 현장에서는 이미지 안의 Object Detection과 Segmentation 등 Downstream Task가 중요하다.</p>
<h3 id="object-detection--instance-segmentation">Object Detection &amp; Instance Segmentation</h3>
<p>  연구진들은 COCO 데이터셋을 사용하여 해당 Task의 테스트를 진행했다.</p>
<p>  이미지 안에서 물체를 찾고 픽셀 단위로 모양을 따는 Mask R-CNN과 Cascade Mask R-CNN 모델을 가져와, 그 Backbone 역할에 ConvNeXt와 Swin Transformer를 각각 넣어 비교했다.</p>
<p>  모든 Scale (T, S, B, L)에서 ConvNeXt는 Swin Transformer와 동등하거나 더 높은 성능(AP)를 달성했다. </p>
<hr>
<h1 id="코드-구현">코드 구현</h1>
<h3 id="augmentation">Augmentation</h3>
<pre><code class="language-python">    train_transform = transforms.Compose([
    # Augmentation
    transforms.RandomHorizontalFlip(p=0.5),
    transforms.RandomRotation(15),
    transforms.ColorJitter(brightness=0.2,
                           contrast = 0.2,
                           saturation = 0.2,
                           hue = 0.1),

    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])

test_transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.405], std=[0.229, 0.224, 0.225])])</code></pre>
<h3 id="warmup">Warmup</h3>
<pre><code class="language-python">from torch.optim import lr_scheduler

class LinearWarmupSteps(lr_scheduler.LambdaLR):
    def __init__(self, optimizer, warmup_steps, total_steps, last_epoch=-1):
        def lr_lambda(current_step):
            if current_step &lt; warmup_steps:
                return float(current_step) / float(max(1.0, warmup_steps))
            return max(0.0, float(total_steps - current_step) / float(max(1, total_steps - warmup_steps)))

        super().__init__(optimizer, lr_lambda, last_epoch=last_epoch)</code></pre>
<p>Epoch 0인 상태에서는 가중치가 완전히 랜덤하게 설정되어 있다. 
                                           이 때, lr을 0.001로 빠르게 설정해버리면 1. 방향을 잘못 잡아 Loss를 발산하거나 NaN에러, Local Minima에 빠지게 된다.</p>
<p>그래서 처음에는 아주 작은 lr로 훈련하다가 서서히 높히는 것이다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 논문 리뷰 ] Recurrent Convolutional Strategies for Face Manipulation Detection in Videos (CVPRW)]]></title>
            <link>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Recurrent-Convolutional-Strategies-for-Face-Manipulation-Detection-in-Videos-CVPRW</link>
            <guid>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Recurrent-Convolutional-Strategies-for-Face-Manipulation-Detection-in-Videos-CVPRW</guid>
            <pubDate>Sat, 28 Mar 2026 15:45:07 GMT</pubDate>
            <description><![CDATA[<p>딥페이크 생성 AI는 보통 영상을 통쨰로 한 번에 만들지 못하고, 영상의 프레임을 한 장씩 조작한 뒤 이어 붙인다.</p>
<p>따라서 정지된 한 장의 이미지는 완벽해 보일지 몰라도, 이 프레임들이 연속적으로 재생될 때 미세한 떨림, 픽셀의 튀는 현상, 부자연스러운 조명 변화 등이 발생하낟.</p>
<p>이 방법론은 바로 <strong>시간적 비일관성</strong>을 잡는 데에 특화되어 있다. </p>
<h1 id="introduction">Introduction</h1>
<p>최근 온라인상에서 잘못된 정보의 확산이 증가하고 있으며, 그 중에서도 <strong>얼굴 조작(Facial Manipulation)이 허위 정보 유포나 유명인의 명예를 훼손하는 수단으로 큰 주목을 받고 있다.</strong> </p>
<p>인류 사회에서 얼굴은 소통과 신원 확인의 주요 수단이기 때문에 다른 어떤 객체보다 조작의 우선적인 대상이 된다.</p>
<p>과거에는 포토샵 같은 SW 기반 수작업으로 지루하게 미디어를 조작하는 행위가 많았지만, 최근에는 <strong>GAN과 GPU의 발전으로 인해 비전문가도 기계 학습 도구를 사용하여 수작업 개입 없이 매우 사실적인 합성 콘텐츠를 쉽게 생성</strong>할 수 있게 되었다.</p>
<p>이러한 기술로 만들어진 결과물은 너무 정교해서 사람조차도 단일 이미지에서는 머리카락의 끊어짐, 얼굴의 비대칭, 부자연스러운 치아 및 배경의 불일치 같은 매우 미세한 단서로만 조작 여부를 간신히 판단할 수 있을 정도이다.</p>
<h3 id="기존-방어책의-한계--정지-이미지의-맹점">기존 방어책의 한계 : 정지 이미지의 맹점</h3>
<p>위에서 말했듯, 현재 인간이 Fake 단일 이미지 한 장을 판별할 수 있는 단서는 끊어진 머리카착, 비대칭 얼굴, 비대칭 치아 구조, 배경 불일치 등 아주 미세한 Artifact인데, 특히 머리 전체와 배경을 렌더링하는 StarGAN 같은 생성 모델에서는 이런 배경 Artifact가 두드러진다. </p>
<p>연구진들은 정지 이미지 결함을 찾는 탐지기도 중요하지만, 동영상 스트림에는 조작을 탐지할 수 있는 완전히 새롭고 중요한 특징인 <strong>시간적 일관성(Temporal Coherence)</strong>이 내재되어 있다고 강조하며 문제의 패러다임을 비디오로 전환한다.</p>
<blockquote>
<p>기존 Deep Fake 기술은 보통 Frame-by-Frame으로 조작하기 때문에 동영상 전체에 걸친 <strong>시간적 일관성(Temporal Coherence)</strong>를 보장하지 못하는 한계가 있다. 
<br></p>
</blockquote>
<h3 id="시간적-불일치-temporal-discrepancies를-어떻게-탐지할까">시간적 불일치 (Temporal discrepancies)를 어떻게 탐지할까?</h3>
<p>논문에서는 <strong>시간적 불일치(Temporal Coherence)</strong>를 효과적으로 탐지하기 위해 <strong>순환 합성곱 모델(Recurrent Convolutional Models)</strong>과 <strong>얼굴 정렬(Face Alignment)</strong>를 결합한 파이프라인을 제안한다.</p>
<h1 id="related-work">Related Work</h1>
<p>동영상 내 DeepFake 탐지 기술의 발전 과정을 세 가지로 나누어 설명한다.</p>
<h3 id="1-video-processing-with-deep-models">1. Video Processing with Deep Models</h3>
<p>논문은 비디오의 시간적 정보를 처리하기 위한 기존의 세 가지 주요 접근법을 분석한다.</p>
<ul>
<li><p><strong>Two-stream 네트워크</strong>
RGB 프레임과 Optical Flow를 각각 처리한 뒤 융합하는 방식이다. 큰 동작을 인식하는 데에는 좋지만, 딥페이크 특유의 <strong>미세한 깜빡임 같은 Artifact를 포착하는 데에는 적합하지 않다</strong>라고 지적한다.</p>
</li>
<li><p><strong>3D CNN</strong>
공간과 시간을 동시에 학습하여 풍부한 특징을 얻을 수 있지만, 학습해야할 파라미터 수가 기하급수적으로 늘어나는 단점이 있다.</p>
</li>
<li><p><strong>단일 스트림 CNN + RNN</strong>
CNN을 통해 각 프레임에서 고수준의 의미론적 특징을 추출하고, 그 위에 순환 모델(RNN)을 올려 시간적 차원의 의사 결정을 수행하는 방식이다. 
본 논문이 채택한 방식이며, 기존에는 얼굴 랜드마크 탐지나 나이 변화 예측 등에 쓰였으나, <strong>동영상 조작 탐지에 적용된 사례를 거의 없었다.</strong></p>
</li>
</ul>
<h3 id="2-face-manipulation-benchmarks">2. Face Manipulation Benchmarks</h3>
<p>과거에는 비디오 기반의 딥페이크 탐지 성능을 제대로 평가할 만한 데이터셋이 부족했다. 그러나 최근 <strong>FaceForensics(FF)</strong>와 이를 확장한 <strong>FaceForensics++(FF++)</strong> 데이터셋이 공개되면서 연구가 활발해지고 있다.</p>
<ul>
<li>FF++ 는 유튜브에서 수집한 정면 아나운서나 인터뷰 영상 등 총 1,000 개의 비디오로 구성되어 있다.</li>
<li>FF++ 는 AutoEncoder 인공지능을 활용하여 사람의 얼굴을 아예 다른 사람으로 바꾸는 <strong>DeepFake</strong>, 컴퓨터 그래픽을 기반으로 <strong>신원을 바꾸는 FaceSwap</strong>, 신원은 그대로 둔 채 표정과 포즈만 타겟 영상에 이식하는 그래픽 기반 <strong>Face2Face</strong>가 있다.</li>
</ul>
<h3 id="3-face-manipulation-detection">3. Face Manipulation Detection</h3>
<p>이미지 조작 탐지에 비해 비디오 기반 탐지 연구는 아직 초기 단계이다. 기존의 베이스라인 모델들과 연구진들의 <strong>결정적 차별점</strong>으로 세 가지 측면에서 설명한다</p>
<ul>
<li><strong>기존 베이스라인 모델들</strong> : XceptionNet을 이용한 연구, Micro한 특징과 Macro한 특징을 결합한 MesoNet 등의 선행 연구가 있다.</li>
<li>** 차별성 1** : 단순 프레임을 넣는 것이 아니라, <strong>얼굴 정렬(Face Alignment) 기법을 사용하여 얼굴의 자연스러운 움직임이 주는 교란 요인을 제거</strong>한다.</li>
<li><strong>차별성 2</strong> : 단방향이 아닌 <strong>양방향(bidirectional) 순환 모델을 활용</strong>하여 탐지 성능을 높인다.</li>
<li><strong>차별성 3</strong> : 딥페이크 탐지에만 국한되지 않고, <strong>여러 유형의 얼굴 조작(Deepfake, FaceSwap, Face2Face)을 모두 탐지</strong>할 수 있도록 실험을 확장한다.</li>
</ul>
<h1 id="method">Method</h1>
<p>연구진들은 딥페이크 비디오 탐지를 위해 과정을 두 단계로 나누어 설계하였다.</p>
<h2 id="1-face-preprocessing">1. Face Preprocessing</h2>
<p>첫 번째 과정에서는 프레임 전체에 걸쳐 시⋅공간적으로 얼굴을 고정시키는 <strong>Face Tublet</strong>을 생성하여 <strong>순환 합성곱 모델의 입력으로 사용</strong>한다. </p>
<p>이를 위해 두 가지 정렬 방식을 실험한다.</p>
<ul>
<li><strong>랜드마크 기반 정렬 (Landmark-based Alignment)</strong>
얼굴의 7개 주요 특징점을 기반으로 얼굴을 사전 정의된 기준 좌표계에 맞추는 방식이다. 2D 이동, 평면 내 회전, 크기 조절 등을 보정하는 유사성 변환(Similarity Transformation)을 수행하여 얼굴을 224x224 해상도로 Cropping 한다.</li>
<li><strong>암시적 정렬 (Spatial Transformer Network, STN)</strong> 
학습 가능한 Affine Transformation 파라미터를 사용하여 공간적 정렬을 수행하는 네트워크를 활용한다. 
Localization Net, Grid Generator, Sampler로 구성되며, 입력 이미지의 조건에 따라 네트워크 소스로 정렬 매개변수를 예측하여 얼굴의 특정 부분에 zoom 하도록 유도한다.</li>
</ul>
<h2 id="2-video-based-face-manipulation-detection">2. Video-based Face Manipulation Detection</h2>
<p>이 단계에서는 전처리된 프레임 시퀸스를 입력받아 조작 여부를 판단하며, 기존 방식들과 달리 <strong>전체 시스템을 End-to-End로 학습</strong>시키는 것이 특징이다. </p>
<p>조작 기술이 보통 프레임 단위로 적용되기 떄문에, 얼굴의 미세한 저수준의 Artifact가 프레임 간의 시간적 불일치(Temporal Discrepancies)로 나타난다는 직관에 기반한다. 
-** Backbone CNN**
각 프레임에서 시각적 특징을 추출하기 위해 ResNet과 DenseNet 아케텍처를 사용한다. 
조작으로 인해 끊어진 턱선이나 흐릿한 눈과 같은 현상은 고수준의 의미론적 특징보다는 <strong>저수준 (low-level)특징</strong>에 더 잘 나타나기 때문에, 여러 계층 구조에서 다양한 수준의 특징을 추출할 수 있는 <strong>DenseNet</strong>이 문제에 매우 적합하다.</p>
<p>Backbone 네트워크는 처음에는 진짜와 가짜를 구별하는 이진 분류를 위한 Cross-Entropy Loss를 최소화하며 단일 프레임 기반으로 사전 학습된다.</p>
<ul>
<li><strong>RNN Training Strategies</strong><ul>
<li><strong>Multi-Recurrent</strong></li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 논문 리뷰 ] The Facial Action Coding System: Principles and Applications]]></title>
            <link>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-The-Facial-Action-Coding-System-Principles-and-Applications</link>
            <guid>https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-The-Facial-Action-Coding-System-Principles-and-Applications</guid>
            <pubDate>Sat, 28 Mar 2026 15:35:16 GMT</pubDate>
            <description><![CDATA[<p><strong>안면 움직임 부호화 시스템(FACS)</strong>은 얼굴 근육의 미세한 변화를 <strong>실행 단위(Action Units)</strong>로 세분화하여 표정을 객관적으로 측정하는 전문적인 체계이다. 이 기술은 감정적인 주관성을 배제하고 <strong>근육의 움직임과 강도</strong>를 수치화함으로써, 심리학 및 임상 연구에서 신뢰할 수 있는 데이터 분석 도구로 활용된다. </p>
<p>이번에 알아볼 논문은 얼굴 근육의 미세 움직임을 객관적 지표로 분류한 시초로, 1978년에 나온 문헌으로, 굉장히 오래된 논문이지만, 미세 표정 오류 탐지 알고리즘 연구의 필수적인 근간이 되는 연구라고 볼 수 있기에 알아볼 필요성이 크다.</p>
<p>이 논문을 통해 <strong>인간의 생명 현상과 해부학적 물리 법칙</strong>까지는 완벽히 학습하지 못했다는 가정을 동반한 딥페이크 생성의 약점을 파고들어보자.</p>
<h2 id="what-is-facs">What is FACS?</h2>
<ul>
<li>FACS의 정의: <strong>얼굴 움직임 코딩 시스템(FACS, Facial Action Coding System)</strong>은 얼굴 근육의 움직임을 묘사하여 표정을 인식하고 분류하는 데 널리 사용되는 프로토콜이다.</li>
</ul>
<p>FACS는 근육 움직임에 특정 감정적 의미를 선험적으로 부여하지 않으며, 표정의 발생 빈도와 강도를 객관적으로 측정하는 데 사용됩니다.</p>
<p>즉, 표정이 전달하려는 &#39;메세지&#39;를 해석하는 대신, 얼굴에서 나타나는 <strong>&#39;행동(Facial Behaviors)&#39; 자체</strong>를 묘사하는 데에 집중한다.</p>
<h3 id="기존-코딩-시스템과의-차이">기존 코딩 시스템과의 차이</h3>
<ul>
<li>** 기존 시스템의 한계** : FACS 이전의 코딩 시스템들은 주로 표정 기저에 깔린 메시지를 파악하는 데에 초점을 맞췄다. 당시에는 감정 상태를 결정하기 위한 표준화된 시스템이 없었기 때문에, 자신만의 판단과 경험에만 의존하여 표정을 평가할 수밖에 없었다. </li>
</ul>
<p>연구진들은 이러한 접근 방식이 주관적이라고 판단하여 FACS만의 객관성을 강조하였다.</p>
<ul>
<li><strong>FACS의 객관성</strong> : FACS는 처음부터 감정적 평가(Emotional Valuation)와 분리된, <strong>표준화되고 객관적인 측정 시스템</strong>을 제공함으로써 기존 방식의 한계를 극복했다.</li>
</ul>
<blockquote>
<p>FACS 시스템 자체가 감정을 다루지 않는다고 해서 감정 연구에 쓰이지 않은 것은 아니다.
FACS 코더들이 얼굴의 움직임을 객관적으로 기록하고 나면, 이후 연구자들이 이 데이터를 바탕으로 <strong>특정 얼굴 행동이 어떤 감정적 상황이나 실험 참가자의 자기 보고(self-reports)와 어떻게 연관이 되는지 조사하는 단계에서 해석을 추가</strong>할 수 있다.</p>
</blockquote>
<h2 id="how-does-facs-works">How does FACS works?</h2>
<p>FACS는 얼굴 근육의 미세한 움직임을 세분화하고 체계적으로 분류하여 측정하는 시스템을 기반으로 한다.</p>
<p>연구진들은 얼굴의 각 개별 근육을 <strong>전기적으로 자극</strong>하고, 그 움직임을 자발적으로 복제(Replicate)하려는 시도를 통해 FACS 시스템을 구축했다.</p>
<p>FACS는 얼굴의 움직임을 신뢰성 있게 구별할 수 있는 가장 작은 단위인 <strong>Action Unit (AU)</strong>로 정의한다.
각각의 AU는 하나 이상의 근육 움직임과 직접적으로 연결되어 있다.
(2002년 기준, FACS는 27개의 얼굴 AU, 25개의 머리 및 눈 위치 코드, 그리고 28개의 기타 움직임으로 구성된다.)</p>
<blockquote>
<p><strong>부위별 AU 세분화</strong> : 27개의 얼굴 AU는 상안부와 하안부 움직임으로 나눌 수 있다</p>
</blockquote>
<ul>
<li>** 상안부(Upper Face)** : 눈썹 올리기(AU 1, 2), 눈썹 내리기(AU 4), 눈꺼풀 올리기(AU 5), 뺨 올리기(AU 6) 등이 포함된다.</li>
<li><strong>하안부 (Lower Face)</strong> : 상안부보다 더 복잡하며 수직, 수평, 사선, 안와(Orbital) 방향의 움직임을 포함한다. (예를 들어, 입꼬리를 일직선으로 아래로 당기는 것은 수직AU(15)에 해당하고, 입꼬리를 위쪽 및 바깥쪽으로 당기는 것은 사선 AU(12)에 해당한다.</li>
</ul>
<blockquote>
<p><strong>표현 강도(Intensity)에 따른 척도</strong></p>
</blockquote>
<ul>
<li>A : 간신히 보이는 Trace 수준</li>
<li>B~D : 약간(Slight), 뚜렷한(Marked), 두드러진(Pronounced), 심한(Severe), 극심한(Extreme) 수준</li>
<li>E : 최대(Maximum) 수준</li>
<li>연구자에 따라 특정 강도부터만 유의미한 코딩 값으로 포함하기도 한다.</li>
</ul>
<p>연구 목적에 따라 코더들은 두 가지 코딩 방식 중 하나를 선택한다.</p>
<ul>
<li><p><strong>포괄적 코딩(Comprehensive Coding)</strong>
영상이나 사진에 존재하는 모든 AU를 빠짐없이 코딩한다. 
탐색적 연구에 유리하지만, 시간이 많이 걸리는 단점이 있다.</p>
</li>
<li><p><strong>선택적 코딩(Selective Coding)</strong> 
사전에 수립된 가설에 따라 연구에 중요한 특정 AU만을 골라서 코딩한다. 이 방식은 분석 속도가 훨씬 빠르다.</p>
</li>
</ul>
<h2 id="reliability-of-facs">Reliability of FACS</h2>
<p>FACS 프로토콜 자체의 신뢰도를 직접적으로 조사한 연구는 사실 소수에 불과하다.</p>
<p>FACS를 사용하는 연구자들은 보통 자신의 코더들이 &#39;FACS 최종 테스트&#39;를 통과했다고 명시하며, 전체 코딩에 대한 평가자 간 신뢰도만을 보고하는 경향이 있다.
<strong>개별 액션 유닛(AU)에 대한 신뢰도는 잘 보고하지 않기 때문에, 특정 AU가 다른 것보다 신뢰성이 떨어지는지 판단하기 어렵다.</strong></p>
<p>사실 신뢰도를 측정하는 기준 자체도 복잡하다. 단순히 AU의 <strong>존채 여부</strong>뿐 아니라, <strong>발생 타이밍(언제 얼굴에 나타났는가)</strong>, <strong>강도(어느 정도인가)</strong>까지 모두 일치해야 하기 때문이다. 예를 들어, 두 명의 코더가 눈썹 안쪽을 올리는 AU1을 코딩한다면, 이 세 가지 요소에 대해 모두 의견이 일치해야 한다.</p>
<p>Sayette 연구진은 100명 이상의 참가자 비디오를 포괄적으로 코딩하여 48프레임 이상 나타난 19개의 AU에 대해 평가자 간 신뢰도를 측정했다.
그 결과, <strong>대부분의 AU에서 코더들은 0.5초 이내의 오차로 발생 여부를 파악해 내며 &#39;우수(good)&#39;에서 &#39;매우 우수(excellent)&#39; 수준의 일치도를 보였다.</strong></p>
<p>그러나 눈 가늘게 뜨기(AU 7)이나 입술 누르기(AU 22)와 같은 몇몇 AU는 신뢰도가 훨씬 낮게 나타났다. 이는 해당 움직임들이 <strong>시각적으로 매우 유사한 다른 AU와 자주 혼동되기 때문</strong>인 것으로 보인다.</p>
<h2 id="facs-in-research">FACS in Research</h2>
<h3 id="emotional-expression-in-facs">Emotional Expression in FACS</h3>
<p>연구진들은 특정 액션 유닛(AU)들의 조합이 놀람, 두려움, 행복, 슬픔, 혐오, 분노와 같은 기본적인 감정들과 자주 연관된다는 일반적인 지침을 제시한다. 
이를 통해 연구진들은 복잡한 표정을 분석하고 그 안에 담긴 감정적 의미를 평가할 수 있다.</p>
<p>사람들은 즐겁지 않은 상황에서 거짓말을 할 때 종종 미소로 진짜 감정을 숨기려 한다. 연구에 따르면, 미소로 위장한 거짓말쟁이드르이 얼굴에서는 혐오, 슬픔, 분노와 연관된 아주 미세하고 짧은 순간의 AU가 새어 나오는 것으로 나타났다.</p>
<h3 id="cross-culture-research">Cross-culture Research</h3>
<h3 id="automated-measurement">Automated Measurement</h3>
<p>수동 코딩에 소요되는 시간과 에너지를 줄이기 위해, 컴퓨터 비전 및 패턴 인식 기술을 통해 <strong>자동화된 FACS 코딩 시스템</strong>을 개발한다.</p>
<p>능동 외양 모델(AAM)과 SVM 분류기를 사용하여 얼굴 형태를 모델링하거나 얼굴 영역을 추적하여 액션 유닛과 그 강도를 탐지한다.</p>
<h2 id="conclusion">Conclusion</h2>
<p>FACS는 표정에 감정적인 라벨을 덧씌우지 않고, 개별 얼굴 근육의 움직임을 있는 그대로 묘사하여 <strong>표정의 발생 빈도와 강도를 객관적으로 측정하고 인식하는 널리 확립된 시스템</strong>이다. </p>
<p>FACS가 지닌 객관성과 신뢰성으로, 발달 연구, 비교 연구 등 광범위한 영역에서 활용 가능하며 FACS를 통해 복잡한 표정을 분석하고 AU에 담긴 검정적 의미를 평가할 수 있게 되었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ Prometheus Project ] 딥페이크 탐지 ]]></title>
            <link>https://velog.io/@jm_mg_se/Prometheus-Project-%EB%94%A5%ED%8E%98%EC%9D%B4%ED%81%AC-%ED%83%90%EC%A7%80</link>
            <guid>https://velog.io/@jm_mg_se/Prometheus-Project-%EB%94%A5%ED%8E%98%EC%9D%B4%ED%81%AC-%ED%83%90%EC%A7%80</guid>
            <pubDate>Sat, 28 Mar 2026 13:58:08 GMT</pubDate>
            <description><![CDATA[<p>딥페이크 생성 방식에는 크게 타겟과 소스를 통해 새로운 신원(Identity)를 생성하는 신원 조작(Identity Swap) 방식과 타겟이 소스를 모방하게 하는 표정 조작(Facial reenactment)가 있다.</p>
<p>이 외에 우리가 주목하고자 하는 방식은</p>
<blockquote>
<p>미세 얼굴 근육의 움직임과 시간적 일관성에 착안한 탐지 방식
으로, <strong>생리학적/생물학적 신호 기반 탐지(Physiological/Biological Signal-based Detection)</strong> 기법이다.</p>
</blockquote>
<p>생성형 AI 모델들이 이미지의 시각적 품질(픽셀의 정교함)은 완벽에 가깝게 구현하고 있지만, <strong>인간의 생명 현상과 해부학적 물리 법칙</strong>까지는 아직 완벽히 학습하지 못했다는 약점을 파고든 방식이다.</p>
<h3 id="1-미세-얼굴-근육-동역학-facial-muscle-dynamics--micro-expressions">1. 미세 얼굴 근육 동역학 (Facial Muscle Dynamics &amp; Micro-expressions)</h3>
<p>사람이 표정을 지을 때는 얼굴 피부 밑에 있는 수십 개의 근육들이 해부학적 구조에 따라 유기적으로 상호작용한다.</p>
<ul>
<li><strong>탐지 원리</strong> : 딥페이크 AI (GAN, Diffusion, etc.)는 해부학을 배운 적이 없고 그저 &#39;픽셀의 통계적 분포&#39;만 학습한다. 따라서 가짜 영상에서는 실제 사람이라면 절대 동시에 움직일 수 없는 근육들이 함께 움직이거나, 진짜 웃음에서 나타나는 눈가의 미세한 떨림(Micro-expression)이 누락되는 등 <strong>해부학적 모순</strong>이 발생한다. </li>
</ul>
<p>연구자들은 FACS(Facial Action Coding System)와 같은 도구를 이용하여 이러한 근육 움직임의 비정상 패턴을 탐지한다.</p>
<h3 id="2-시간적-비일관성-temporal-inconsistency">2. 시간적 비일관성 (Temporal Inconsistency)</h3>
<p>영상은 정지 이미지의 연속이다. 인간의 근육 움직임은 시작-최고조-감소의 부드러운 시간적 곡선을 그린다.</p>
<ul>
<li><strong>탐지 원리</strong> : 딥페이크 모델은 보통 영상을 통째로 생성하기보다 <strong>프레임 단위(Frame-by-frame)</strong>로 얼굴을 합성한 뒤 이어붙이는 방식을 많이 사용한다. 이 때문에 프레임과 프레임 사이를 분석해보면 근육의 움직임이 뚝뚝 끊기거나, 미세한 떨림(Flickering)이 발생하고, 표정의 전환 속도가 물리적으로 불가능할 만큼 빠르거나 느린 현상이 포착된다. </li>
</ul>
<h3 id="3-혈류-및-심박동-변화-rppg-remote-photoplethysmography">3. 혈류 및 심박동 변화 (rPPG: Remote Photoplethysmography)</h3>
<p>실제 사람의 심장이 뛸 때마다 얼굴로 흐르는 혈류량이 달라지며, 육안으로는 보이지 않지만 카메라 렌즈에는 잡히는 <strong>미세한 피부 색상 변화</strong>가 일어난다. </p>
<ul>
<li><p><strong>탐지 원리</strong> : 진짜 사람의 영상에서는 이 픽셀 변화를 증폭시키면 규칙적인 심장 박동(맥박) 신호를 추출할 수 있다. 하지만 딥페이크는 가짜 픽셀을 덮어씌운 것이기 때문에, 이 <strong>생리학적 맥박의 신호(rPPG)가 아예 소실되어 있거나 노이즈처럼 매우 불규칙적으로 나타난다.</strong> 
(무의식적 생리 현상 - Blinking, Gaze, Breathing 등이 있음)</p>
</li>
<li><p>초기 딥페이크는 학습 데이터에 눈을 감은 사진이 적어 눈을 비정상적으로 안깜빡이는 문제가 있었다. 모델이 발전한 지금도 &#39;양쪽 눈이 완벽히 동시에 감기는지&#39;, &#39;깜빡임의 속도와 주기가 인간의 생리적 리듬과 일치하는지&#39;, &#39;말하는 소리(Phoneme)와 입술 근육의 형태(Viseme)가 정확히 일치하는지&#39; 등을 분석하여 위조 여부를 판별한다.</p>
</li>
</ul>
<blockquote>
<p>🔥기존의 딥페이크 탐지는 얼굴 윤곽선의 블러 처리나 픽셀 깨짐과 같은 <strong>시작적 Artifact</strong>를 찾는 데에 집중했지만, 딥페이크 기술의 고도화와 함께 이런 시각적 결함은 사라지고 있다. 반면 생물학적 신호를 완벽하게 위조하려면 AI가 인간의 신경계, 혈관계, 근육계까지 모두 시뮬레이션해야 하므로 <strong>생성보다 탐지가 더 유리한 영역으로</strong> 평가받고 있다.</p>
</blockquote>
<h2 id="related-research">Related Research</h2>
<ul>
<li><a href="https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-The-Facial-Action-Coding-System-Principles-and-Applications">FACS: The Facial Action Coding System: Principles and Applications</a></li>
<li><a href="https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Recurrent-Convolutional-Strategies-for-Face-Manipulation-Detection-in-Videos-CVPRW">Recurrent Convolutional Strategies for Face Manipulation Detection in Videos.</a></li>
<li><a href="https://velog.io/@jm_mg_se/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-OpenFace-An-open-source-facial-behavior-analysis-toolkit.-2016">FakeCatcher: Detection of Synthetic Portrait Videos using Biological Signals.</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Flash Attention: CPU-GPU의 BottleNeck]]></title>
            <link>https://velog.io/@jm_mg_se/CPU-GPU%EC%9D%98-BottleNeck</link>
            <guid>https://velog.io/@jm_mg_se/CPU-GPU%EC%9D%98-BottleNeck</guid>
            <pubDate>Tue, 24 Mar 2026 17:01:54 GMT</pubDate>
            <description><![CDATA[<p>flash attention에 대해 알아보자.</p>
<p>original transformer</p>
<p>GPU 내부의 이야기</p>
<h2 id="attention의-과정">Attention의 과정</h2>
<p>Attention은 Q, K, V 세 가지 행렬로 계산한다.</p>
<blockquote>
<ol>
<li>먼저 Query와 Key를 행렬곱 한다.
이 결과가 Attention Score인데, </li>
<li>여기에 softmax를 씌워서 <strong>각 위치별 가중치</strong>를 만든다.</li>
<li>그리고, 이 가중치를 Value에 가중합(Weighted Sum)하여 최종 Attention 출력을 얻는다.</li>
</ol>
</blockquote>
<p>$\text{Attention}(Q,K,V) = \mathrm{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V$</p>
<pre><code>- Q (Query) : [N, d_k]
- K (Key) : [M, d_k]
- V (Value) : [M, d_v]</code></pre><ul>
<li>N : query 개수</li>
<li>M : key/value 개수</li>
<li>$d_k$ : Embedding Dimension</li>
</ul>
<p>(자세한 Attention 계산 과정은 생략하도록 하겠다. )</p>
<p>그럼, 크게 보았을 때 Attention 계산은 
<strong>(QK Inner Product -&gt; Softmax -&gt; Weighted sum:V)</strong> </p>
<hr>
<h2 id="gpu-메모리-구조">GPU 메모리 구조</h2>
<p><img src="https://velog.velcdn.com/images/jm_mg_se/post/30d3e51a-0cc2-457e-9a5e-d31c379008d1/image.png" alt=""></p>
<h2 id="cv2absdiff에서-나온-아이디어"><code>cv2.absdiff</code>에서 나온 아이디어</h2>
<p>HBM &lt;-&gt; SRAM 사이의 bottleneck 처럼 **OpenCV는 Numpy (CPU 동작)과 PyTorch 라이브러리 (GPU 연산) 사이의 병목을 생각하며 작업을 하자 </p>
<h4 id="참고자료">참고자료</h4>
<p><a href="https://youtu.be/4Tw_ytMYHLI?si=D447MDPMzpoWyMTs">https://youtu.be/4Tw_ytMYHLI?si=D447MDPMzpoWyMTs</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ MCATrack ] Transformation Matrix 과 Feature Extraction ]]></title>
            <link>https://velog.io/@jm_mg_se/Transformation-Matrix</link>
            <guid>https://velog.io/@jm_mg_se/Transformation-Matrix</guid>
            <pubDate>Tue, 24 Mar 2026 14:02:02 GMT</pubDate>
            <description><![CDATA[<p>MCATrack의 Magno-Motion Module의 근간이 되는 핵심 두 가지를 알아보자.</p>
<h1 id="변환-행렬-transformation-matrix란">변환 행렬 (Transformation Matrix)란?</h1>
<p>카메라가 움직이면 (Ego-motion), 화면 속의 모든 배경 픽셀들이 한꺼번에 이동한다. 
변환 행렬은 <strong>&#39;이전 프레임의 픽셀들이 현재 프레임에서 어디로 이동했는가?&#39;</strong>를 설명해주는 수학적인 &#39;지도&#39; 역할을 해주는 것이다.</p>
<blockquote>
<p><strong>- Affine 변환</strong> : 회전(Rotation), 크기 조절(Scale), 이동(Translation)을 포함한다. 행렬의 크기는 $2\times 3$이다.</p>
<blockquote>
<p>에? $3 \times 3$ 아닌가요?
수학적으로는 $3\times 3$이 맞다. 하지만 <strong>OpenCV의 효율성을 위한 &#39;생략&#39;</strong>때문에 코드에서는 $2\times 3$으로 보인다. 
어떤 점 $(x,y)$를 Affine 변환하여 새로운 점 $(x&#39;, y&#39;)$를 만드는 수식을 전개해보면 다음과 같다.
$x&#39; = a_{11}x + a_{12}y + t_x$
$y&#39; = a_{21}x + a_{22}y + t_y$
이것을 행렬 곱셈으로 표현한다면, OpenCV가 반환하는 행렬은 $2\times 3$ 행렬이 된다.
$$\left[\begin{matrix} x&#39; \ y&#39;\end{matrix}\right] = \left[\begin{matrix} a_{11} &amp; a_{12} &amp; t_x\ a_{21} &amp; a_{22} &amp; t_y \end{matrix} \right] \left[\begin{matrix} x\y\\end{matrix}\right]$$ 
<br>그런데, 아까 다중 프레임 연산을 위해 Chain Rule이 등장한다고 했는데, $2\times 3$ 행렬은 자기들끼지 곱할 수 없다. 떄문에 항상 맨 아래에 <code>[0, 0, 1]</code>을 붙여서 $3 \times 3$ 정사각형 행렬로 만든다. 
$$\left[\begin{matrix} x&#39; \ y&#39; \ 1\end{matrix}\right] = \left[\begin{matrix} a_{11} &amp; a_{12} &amp; t_x\ a_{21} &amp; a_{22} &amp; t_y \0 &amp; 0 &amp; 1\end{matrix} \right] =\left[\begin{matrix} x\y\1\end{matrix}\right]$$ </p>
</blockquote>
</blockquote>
<ul>
<li><strong>Affine의 본질</strong> : 맨 아랫줄이 무조건 <code>[0, 0, 1]</code>로 고정되어 있다. 그래서 OpenCV는 메모리와 연산 속도를 아끼기 위해 굳이 쓸모없는 아랫줄을 계산하거나 반환하지 않고 $2\times 3$만 준다. <br>(<code>cv2.warpAffine()</code>)도 이 $2\times 3$만 받아서 처리하도록 최적화되어 있다.</li>
<li><strong>Homography의 본질</strong> : 반면 Homography는 맨 아랫줄이 <code>[h31, h32, 1]</code>처럼 원근감을 계산하는 변수들로 채워져있기 때문에, <strong>생략할 수 없이 반드시 $3\times 3$이어야한다.</strong>
(<code>cv2.warpPerspective</code>)함수를 따로 써야한다.<blockquote>
</blockquote>
</li>
<li><ul>
<li><ul>
<li>Homography 변환** : 원근감(Perspective) 변화까지 포함한다. 행렬의 크기는 $3 \times 3$이다.
$t-1$ 시점의 프레임을 $t$ 시점으로 맞추기 위해 구한 행렬을 $M_{t-1\rightarrow t}$ 라고 하자. 이 행렬을 이전 이미지에 곱해주면 (Warping), 카메라가 흔들리지 않은것 처럼 배경이 고정된다.<blockquote>
<blockquote>
<p>변환 행렬은 <strong>자유도 (Degrees of Freedom, DoF)에 따라서 여러 단계로 나뉜다.</strong></p>
</blockquote>
</blockquote>
</li>
</ul>
</li>
</ul>
</li>
<li>Translation (이동, 2 DoF) : 상하좌우 이동만 한다. (단순 Panning)</li>
<li>Euclidean / Rigid (강체 변환, 3 DoF) : 이동 + <strong>회전</strong>이 추가된다. (모양과 크기 유지)</li>
<li>Similarity (유사 변환, 4 DoF) : 이동 + 회전 + 크기조절 + <strong>기울임(Shear)</strong>이 추가된다. (평행선은 유지됨)</li>
<li>Projective / Homography (호모그래피, 8 DoF) : 이 모든 것에 <strong>원근감(Perspective)</strong>가 추가된다. (평행선이 만날 수 있다.)</li>
</ul>
<h2 id="여러-프레임-mutli-frame의-정렬--행렬곱-chain-rule">여러 프레임 (Mutli-Frame)의 정렬 : 행렬곱 (Chain Rule)</h2>
<p>2개의 프레임 ($t-1, t$)는 그냥 매칭해서 구하면 되지만, 과거의 프레임들($t-2, t-3 ...$)을 모두 현재 시점 ($t$)로 가져오려면 어떻게 해야할까?</p>
<p>가장 직관적인 방법은 <strong>매번 $t$ 프레임과 과거 프레임을 직접 비교하는 것</strong>이다. 하지만 이 방법은 시간이 지날수록 카메라가 너무 많이 이동해서 공통된 배경이 사라지거나 원근이 바뀌어 매칭 자체가 실패해버린다.</p>
<p>때문에 <strong>인접한 프레임끼리만 행렬을 구한 뒤, 그것들을 곱해서(Matrix Mutiplication)</strong> 한 번에 건너뛰는 행렬을 만드는 것이다.</p>
<ul>
<li>$t-1$ 프레임을 $t$로 보내는 행렬 : $M_{t-1 \rightarrow t}$</li>
<li>$t-2$ 프레임을 $t-1$로 보내는 행렬 : $M_{t-2 \rightarrow t-1}$</li>
<li><ul>
<li>$t-2$ 프레임을 현재($t$)로 한 번에 보내는 행렬 $M_{t-2 \rightarrow t}$는 어떻게 구할까?</li>
</ul>
</li>
</ul>
<p>$M_{t-2 \rightarrow t} = M_{t-1 \rightarrow t} \times M_{t-2 \rightarrow t-1}$</p>
<p>이런 식으로 과거의 어떤 프레임이든 인접 프레임 간의 행렬들을 차례로 곱해준다면, 현재 시점으로 완벽하게 겹치도록 변환할 수 있다. 이것이 다중 프레임 정렬의 핵심이다.</p>
<h3 id="3d-공간-상의-변환-4times-4-행렬">3D 공간 상의 변환 ($4\times 4$ 행렬)</h3>
<p>현실 세계 (3D)의 어떤 점 $(X, Y, Z)$를 이동시키고 회전할 때에는, 동차 좌표계를 사용하면 벡터는 $[X, Y, Z, 1]^T$이 되고, 변환 행렬은 $4\times 4$가 된다. </p>
<p>$$\left[\begin{matrix} X&#39; \ Y&#39; \ Z&#39; \ 1\end{matrix}\right] = \left[\begin{matrix} R_{11} &amp; R_{12} &amp; R_{13}&amp;T_x\ R_{21} &amp; R_{22} &amp; R_{23}&amp;T_y \R_{31} &amp; R_{32} &amp; R_{33} &amp;T_z \ 0 &amp; 0 &amp; 0 &amp; 1\end{matrix} \right] \left[\begin{matrix} X\Y\Z\1\end{matrix}\right]$$ 
이것이 바로 3D 비전에서 다루는 절대적인 진리인데..</p>
<p>현재 내가 겪고 있는 <strong>Anti-UAV 프레임 정렬 문제</strong>는 3D 공간이 아니다. 카메라는 3D 세상을 촬영하여 깊이($Z$축)을 짓눌러버리고 <strong>2D 평면 이미지 (픽셀 좌표계)</strong>로 만든다.</p>
<p>MCATrack에서 인접 프레임 간 정렬 (Inter-frame Registration)을 수행할 때에는 3D 깊이를 알 수 없으니, 오직 2D 이미지 평면의 픽셀 $(x, y)$들이 어떻게 이동했는지만을 계산한다.</p>
<p>2D 공간의 점$(x, y)$를 동차 좌표계로 나타내면 depth-축 이 날아가고 <strong>$[x, y, 1]^T$</strong>라는 $3 \times 1$ 벡터가 된다. </p>
<p>이를 변환하려면 행렬도 당연히 $3\times 3$으로 줄어든다.</p>
<blockquote>
<h4 id="affine-변환에서-하단이-왜-0-0-1인가">Affine 변환에서 하단이 왜 [0, 0, 1]인가?</h4>
<p>호모그래피의 $3\times 3$ 행렬에서 맨 아랫줄 <strong>$[h_{31}, h_{32}, h_{33}]$</strong>은 2D 평면이 3D 공간상에서 기울어질 때 발생하는 <strong>원근 왜곡 (Perspective Distortion)</strong>을 계산하는 파라미터이다.
<br>
하지만 하늘 배경의 드론 추적에서는 원근 변화를 무시하고 평행선을 유지하는 <strong>Affine 변환</strong>을 사용하는데, 수학적으로 원근 왜곡이 없다는 것은 $h_{31}$과 $h_{32}$가 정확히 0이라는 것을 의미한다. 또한 스케일 정규화를 위해 $h_{33}$은 1이 된다. 
<br>따라서 2D Affine 변환의 동차 행렬은 반드시 아래와 같은 형태가 된다.
$$\left[\begin{matrix} x&#39; \ y&#39; \ 1\end{matrix}\right] = \left[\begin{matrix} a_{11} &amp; a_{12} &amp; t_x\ a_{21} &amp; a_{22} &amp; t_y \0 &amp; 0 &amp; 1\end{matrix} \right] =\left[\begin{matrix} x\y\1\end{matrix}\right]$$ 
이제 이 행렬 곱셈을 픽셀 좌표를 구하는 대수 방정식으로 풀어보자.</p>
</blockquote>
<ol>
<li>$x&#39; = a_{11}x + a_{12}y + t_x$</li>
<li>$y&#39; = a_{21}x + a_{22}y + t_y$</li>
<li>$1 = 0 \cdot x + 0\cdot y + 1$
<br>세 번째 수식을 보면 $1=1$이다. 
이 수식은 새로운 픽셀 좌표 $(x&#39;, y&#39;)$을 계산하는데에 아무런 쓸모가 없는 건데..
한 프레임에 수백만 개의 픽셀이 있는 상황에서 이 무의미한 연산을 수백만 번 반복하는 것은 자원 낭비이다.
<br>그래서 OpenCV의 연구원들은 메모리와 연산량을 아끼기 위해 Affine 변환에서 쓸모가 없는 <strong>맨 아랫줄을 아예 메모리에서 잘라내버렸다.</strong></li>
</ol>
<h2 id="homogeneous-coordinate-동차-좌표계-">Homogeneous Coordinate (동차 좌표계 )</h2>
<p>이론은 행렬을 곱하면 된다고 하지만, 막상 파이썬 (OpenCV)에서 Affine 변환 행렬을 2개 <code>np.dot()</code>으로 곱하려고 하면 에러가 발생한다.</p>
<p>이유는 OpenCV가 반환하는 Affine 행렬의 크기가 $2\times 3$ 이기 때문인데, 수학적으로 $2\times 3$ 끼리의 행렬곱은 불가능하다.</p>
<p>그래서 곱셈을 하기 전에 이 행렬을 <strong>$3\times 3$ 정사각형 행렬 (Homogeneous Matrix)</strong>로 만들어줘야 한다.</p>
<blockquote>
<ol>
<li>$2\times 3$ 행렬의 맨 아래에 <code>[0, 0, 1]</code>이라는 한 줄을 추가해서 $3\times 3$으로 만든다.</li>
<li>이제 $3\times 3$ 행렬끼리 곱한다. (<code>np.matmul</code>)</li>
<li>계산이 끝나면 맨 아랫줄을 다시 잘라내어 $2 \times 3$으로 만든 뒤, <code>cv2.warpAffine()</code>에 집어넣는다.</li>
</ol>
</blockquote>
<hr>
<h2 id="boundary-artifacts">Boundary Artifacts</h2>
<p>카메라가 오른쪽으로 Panning 했다고 가정해보자. 
이전 프레임을 현재 프레임에 맞추기 위해 왼쪽으로 당겨오면, <strong>원래 화면에 없던 오른쪽 가장자리 부분에는 빈 공간이</strong> 생긴다.</p>
<ul>
<li>OpenCV나 PyTorch에서는 이 빈 공간을 기본적으로 검은색(0)으로 채워버린다.</li>
<li>이 상태로 <code>cv2.absdiff(warped_prev, curr)</code>를 실행하면 현재 프레임의 오른쪽 가장자리 배경(예를 들어 하늘의 색 150) 과 검은색(0)이 빼기가 되면서, <strong>가장자리에 거대한 하얀색 노이즈</strong>가 생겨버린다. Magno-Motion 모듈은 이 거대한 노이즈를 엄청나게 빠르게 움직이는 거대한 타겟으로 생각하고 시야를 완전히 빼앗긴다.</li>
<li>변환 시 빈 공간을 검은색으로 두지 말고, <strong>가장자리 픽셀을 복사하여 늘리거나 (Replicate), 반사(Reflect)</strong>시켜줘야 한다.<br>이렇게 해야 차분(absdiff)를 했을 때 경계면이 0으로 깔끔하게 상쇄된다.<ul>
<li>OpenCV : <code>borderMode=cv2.BORDER_REPLICATE</code></li>
</ul>
</li>
</ul>
<h1 id="feature-extraction">Feature Extraction</h1>
<h2 id="특징점이란">특징점이란?</h2>
<p>카메라가 이동했을 때 두 프레임 간의 변환 행렬을 구하려면 &quot;이전 프레임의 A 픽셀이 현재 프레임의 B 픽셀로 이동했다&quot; 라는 확신이 필요하다. 
이 때 아무런 픽셀이나 잡아버리면 Aperture Problem이라는 오류에 빠지게 된다.</p>
<ul>
<li><strong>밋밋한 영역 (Flat) :</strong> 주변 픽셀이 다 똑같은 색이다. 카메라가 오른쪽으로 10픽셀을 이동했는지, 20픽셀을 이동했는지 구분할 수 없다. </li>
<li><strong>직선 영역 (Edge)</strong> : 가로로 뻗은 전선 위에서 한 점을 잡았다고 해보자. 카메라가 가로로만 움직인다면 전선은 똑같은 선으로 보이기 떄문에 이동량을 알 수 없다. </li>
<li><strong>모서리 영역 (Corner)</strong> : 가로선과 세로선이 교차하는 꼭짓점이다. 어느 방향으로 움직이든 주변 픽셀과 명암 대비가 확 달라지기 때문에 <strong>이동 방향과 거리를 100%</strong> 특정할 수 있다.<blockquote>
<p>결국 좋은 특징점은 <strong>코너 (Corner)</strong>를 의미한다.</p>
</blockquote>
</li>
</ul>
<p>구현에서 특징점 검출을 위해 <strong>ORB (Oriented FAST and Rotated BRIEF)</strong> 를 사용했다. 이는 두 가지 알고리즘의 결합인데, 빠른 속도와 회전 불변성 때문에 실무에서 많이 쓰인다. </p>
<pre><code class="language-python">import cv2

orb = cv2.ORB_create(
    nfeatures=40000, # 최대 추출 특징점 수 
    scaleFactor=1.2, # 이미지 피라미드에서 레벨 간 축소 비율
    nlevels=8, # 피라미드 레벨 수
    edgeThreshold=31, # 이미지 경계에서 Keypoint 검출하지 않는 Margin
    firstLevel=0, # 피라미드 시작 레벨
    WTA_K = 2, # BRIEF descriptor에서 사용하는 비교 픽셀 수 
    scoreType=cv2.ORB_HARRIS_SCORE, # Key Point Ranking 방식 
    patchSize=31, # descriptor 계산에 사용하는 Patch 크기
    fastThreshold=20 # FAST corner detection threshold
)</code></pre>
<blockquote>
<p><strong>STEP 1 : 코너 찾기 (FAST 알고리즘)</strong>
어떤 픽셀 $P$가 코너인지 확인하기 위해 $P$를 중심으로 원을 그리듯 주변 16개의 픽셀 밝기를 검사한다.
만약 $P$보다 &#39;확실히 더 밝거나 확실히 더 어두운&#39; 픽셀들이 연속으로 9개 이상 존재한다면, 그 점을 코너로 합격시킨다.
<br>
<strong>STEP 2: BRIEF descriptor</strong>
찾은 특징점을 다음 프레임에서 찾을 수 있도록 Descriptor를 만들어야 한다.</p>
</blockquote>
<ul>
<li>특징점 주변의 픽셀들을 무작위로 두 개씩(A, B) 짝지어 밝기를 비교한다.</li>
<li>A가 B보다 밝으면 1, 어두우면 0 이런 식으로 256번을 비교하여 256비트 이진수 문자열을 생성한다.</li>
<li>이진수로 되어 있어, 두 특징점이 같은지 비교할 때 컴퓨터의 XOR 연산(해밍거리)로 일치여부를 판별한다.<blockquote>
<blockquote>
<p><strong>주의할 점</strong></p>
</blockquote>
</blockquote>
<ul>
<li>적외선 카메라는 열을 감지하기 때문에 텍스쳐가 가시광선 카메라처럼 뚜렷하지 않고 뭉개져 보인다.</li>
<li>하늘에는 Corner가 없어서 ORB의 FAST 알고리즘이 측징점을 찾지 못하는 경우가 有</li>
<li>코너가 없으니, 자글자글한 열 노이즈나 압축 Artifact를 코너로 착각하고 특징점으로 잡아버린다. </li>
</ul>
</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>