<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dust_potato.log</title>
        <link>https://velog.io/</link>
        <description>ML/AI Engineer</description>
        <lastBuildDate>Thu, 16 Apr 2026 08:44:50 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>dust_potato.log</title>
            <url>https://velog.velcdn.com/images/dust_potato/profile/1173308e-4863-420a-aeef-abbe115e269c/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. dust_potato.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dust_potato" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[RAG Dense Retrieval - Embedding model의 이해 ]]></title>
            <link>https://velog.io/@dust_potato/RAG-Dense-Retrieval-Embedding-model%EC%9D%98-%EC%9D%B4%ED%95%B4</link>
            <guid>https://velog.io/@dust_potato/RAG-Dense-Retrieval-Embedding-model%EC%9D%98-%EC%9D%B4%ED%95%B4</guid>
            <pubDate>Thu, 16 Apr 2026 08:44:50 GMT</pubDate>
            <description><![CDATA[<h1 id="ragretrieval-augmented-generation란-무엇인가">RAG(Retrieval-Augmented Generation)란 무엇인가?</h1>
<blockquote>
<p>LLM이 &quot;모르는 것&quot;을 알게 만드는 기술</p>
</blockquote>
<hr>
<h2 id="목차">목차</h2>
<ol>
<li><a href="#1-rag%EA%B0%80-%EC%99%9C-%ED%95%84%EC%9A%94%ED%95%9C%EA%B0%80">RAG가 왜 필요한가?</a></li>
<li><a href="#2-rag%EC%9D%98-%EA%B5%AC%EC%A1%B0">RAG의 구조</a></li>
<li><a href="#3-rag%EC%97%90%EC%84%9C-embedding-model%EC%9D%98-%EC%97%AD%ED%95%A0">RAG에서 Embedding Model의 역할</a></li>
<li><a href="#4-retrieval--sparse-vs-dense-retrieval">Retrieval — Sparse vs Dense Retrieval</a></li>
<li><a href="#5-embedding-model%EC%9D%80-%EA%BC%AD-%EA%B0%99%EC%9D%80-%EB%AA%A8%EB%8D%B8%EC%9D%84-%EC%8D%A8%EC%95%BC-%ED%95%A0%EA%B9%8C">Embedding Model은 꼭 같은 모델을 써야 할까?</a></li>
<li><a href="#6-%EC%9E%84%EB%B2%A0%EB%94%A9-%EB%AA%A8%EB%8D%B8%EC%9D%98-%EB%91%90-%EA%B0%80%EC%A7%80-%EC%9D%B8%EC%BD%94%EB%94%A9-%EB%B0%A9%EC%8B%9D">임베딩 모델의 두 가지 인코딩 방식</a></li>
<li><a href="#7-%EC%9D%B4%EC%A0%84-%EB%AA%A8%EB%8D%B8-vs-%EC%B5%9C%EC%8B%A0-embedding-model-%EB%B9%84%EA%B5%90">이전 모델 vs 최신 Embedding Model 비교</a></li>
</ol>
<hr>
<h2 id="1-rag가-왜-필요한가">1. RAG가 왜 필요한가?</h2>
<p>ChatGPT나 Claude 같은 LLM(대형 언어 모델)은 방대한 양의 텍스트로 사전 학습되어 있습니다. 하지만 이 모델들에게는 치명적인 한계가 두 가지 있습니다.</p>
<p><strong>첫째, 지식의 시간적 한계입니다.</strong> 학습 데이터에 포함된 시점까지의 정보만 알고 있습니다. 어제 발표된 뉴스나 오늘 업데이트된 사내 문서는 알 수 없습니다.</p>
<p><strong>둘째, 사내 비공개 정보를 모릅니다.</strong> 우리 회사의 내부 규정, 제품 매뉴얼, 고객 데이터는 공개 인터넷에 없기 때문에 학습된 적이 없습니다.</p>
<p>이 두 문제를 해결하기 위해 등장한 것이 <strong>RAG(Retrieval-Augmented Generation)</strong>입니다. 쉽게 말해, LLM이 답변하기 전에 <strong>관련 문서를 먼저 찾아서(Retrieval)</strong> 참고하게 만드는 방식입니다. 인터넷 검색 기능이 없는 사람에게 참고 자료를 쥐어주는 것과 같습니다.</p>
<hr>
<h2 id="2-rag의-구조">2. RAG의 구조</h2>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/6b49f90e-7920-434e-bf0c-514516f26121/image.png" alt="">
RAG는 크게 두 개의 파이프라인으로 나뉩니다. <strong>오프라인에서 미리 처리하는 인덱싱 파이프라인</strong>과 <strong>사용자 요청이 들어올 때 실시간으로 동작하는 쿼리 처리 파이프라인</strong>입니다.</p>
<h3 id="인덱싱-파이프라인-오프라인-사전-처리">인덱싱 파이프라인 (오프라인, 사전 처리)</h3>
<p>사용자의 질문이 들어오기 전, 검색 가능한 형태로 문서를 미리 가공해두는 단계입니다.</p>
<pre><code>문서 (PDF, 텍스트, 웹 등)
  ↓
청킹 (Chunking) — 문서를 적절한 크기로 분할
  ↓
인코딩 (Encoding) — 각 청크를 숫자 벡터로 변환
  ↓
벡터 DB — 변환된 벡터를 데이터베이스에 저장</code></pre><p><strong>청킹(Chunking)</strong> 은 긴 문서를 LLM이 처리하기 적합한 크기로 잘라내는 과정입니다. 너무 짧으면 문맥이 끊기고, 너무 길면 검색 정확도가 낮아집니다. 일반적으로 256~512 토큰 단위로 나누며, 문단 경계나 문장 단위를 기준으로 나누기도 합니다.</p>
<p><strong>인코딩(Encoding)</strong> 은 텍스트를 고차원의 숫자 벡터로 변환하는 과정입니다. 이 벡터는 텍스트의 &#39;의미&#39;를 수치로 표현한 것으로, 의미가 비슷한 텍스트끼리는 벡터 공간에서 가까운 위치에 놓이게 됩니다.</p>
<p><strong>벡터 DB</strong> 는 이렇게 만들어진 수백만 개의 벡터를 저장하고, 빠르게 유사도 검색을 수행할 수 있는 특수한 데이터베이스입니다. 대표적으로 Pinecone, Weaviate, Qdrant, FAISS 등이 있습니다.</p>
<h3 id="쿼리-처리-파이프라인-온라인-실시간">쿼리 처리 파이프라인 (온라인, 실시간)</h3>
<p>사용자가 질문을 입력하는 순간부터 시작됩니다.</p>
<pre><code>사용자 쿼리 입력
  ↓
인코딩 (쿼리를 벡터로 변환)
  ↓
검색 (벡터 DB에서 유사한 청크 탐색)
  ↓
리랭킹 (검색 결과의 관련도를 재정렬)
  ↓
프롬프트 조합 (원본 쿼리 + 검색된 컨텍스트)
  ↓
LLM 응답 생성
  ↓
최종 응답 반환</code></pre><p><strong>리랭킹(Reranking)</strong> 은 벡터 검색이 반환한 수십 개의 후보 문서 중, 실제로 질문에 가장 유용한 문서를 다시 정렬하는 과정입니다. 벡터 유사도만으로는 놓치는 미묘한 관련성을 Cross-Encoder 등의 모델로 보완합니다.</p>
<p><strong>프롬프트 조합</strong> 단계에서는 사용자의 원래 질문과 검색된 문서 조각들을 하나의 프롬프트로 합칩니다. 예를 들면 아래와 같은 형태입니다.</p>
<pre><code>[시스템]
다음 문서를 참고하여 질문에 답변하세요.

[참고 문서]
(검색된 청크 1) ...
(검색된 청크 2) ...

[사용자 질문]
우리 회사 환불 정책이 어떻게 되나요?</code></pre><p>LLM은 이 프롬프트를 받아, 자신의 사전 학습 지식과 제공된 문서를 함께 참고하여 정확한 답변을 생성합니다.</p>
<hr>
<h2 id="3-rag에서-embedding-model의-역할">3. RAG에서 Embedding Model의 역할</h2>
<p>Embedding Model(임베딩 모델)은 RAG의 핵심 부품입니다. 텍스트를 숫자 벡터로 변환하는 이 모델이 없으면 RAG 자체가 동작하지 않습니다.</p>
<p>임베딩 모델이 하는 일을 직관적으로 이해하려면, <strong>지도 위에 단어를 찍는다</strong>고 생각해보세요.</p>
<ul>
<li>&quot;고양이&quot;와 &quot;강아지&quot;는 지도 위에서 서로 가까운 곳에 찍힙니다.</li>
<li>&quot;고양이&quot;와 &quot;주식&quot;은 아주 먼 곳에 찍힙니다.</li>
<li>&quot;애플은 쿠퍼티노에 본사를 뒀다&quot;는 &quot;아이폰 만드는 회사는 어디야?&quot;와 가까운 곳에 찍힙니다.</li>
</ul>
<p>이 &#39;지도&#39;가 바로 벡터 공간입니다. RAG에서 임베딩 모델은 두 번 사용됩니다.</p>
<table>
<thead>
<tr>
<th>시점</th>
<th>역할</th>
</tr>
</thead>
<tbody><tr>
<td>인덱싱 시 (오프라인)</td>
<td>문서 청크들을 벡터로 변환하여 DB에 저장</td>
</tr>
<tr>
<td>쿼리 처리 시 (실시간)</td>
<td>사용자 쿼리를 벡터로 변환하여 DB에서 유사 벡터 탐색</td>
</tr>
</tbody></table>
<p>결국 &quot;질문 벡터와 가장 가까운 문서 벡터를 찾는 것&quot;이 RAG 검색의 본질입니다. 임베딩 모델의 품질이 곧 검색 품질을 결정하는 이유가 여기에 있습니다.</p>
<hr>
<h2 id="4-retrieval--sparse-vs-dense-retrieval">4. Retrieval — Sparse vs Dense Retrieval</h2>
<p>문서를 검색하는 방법에는 크게 두 가지 접근이 있습니다. 오래된 방식인 <strong>Sparse Retrieval</strong>과, 딥러닝 기반의 <strong>Dense Retrieval</strong>입니다.</p>
<h3 id="sparse-retrieval-희소-검색">Sparse Retrieval (희소 검색)</h3>
<p>대표적인 알고리즘은 <strong>BM25</strong>입니다. 검색 엔진(예: Elasticsearch)에서 오랫동안 사용해온 방식으로, 단어의 <strong>출현 빈도</strong>를 기반으로 문서의 관련도를 계산합니다.</p>
<p><strong>동작 원리:</strong> 질문에 포함된 단어가 문서에 얼마나 자주, 얼마나 독특하게 등장하는지를 점수로 계산합니다.</p>
<p><strong>장점:</strong></p>
<ul>
<li>빠르고 가볍습니다.</li>
<li>&quot;GPT-4o&quot; 같은 정확한 고유명사 검색에 강합니다.</li>
<li>별도의 GPU가 필요 없습니다.</li>
</ul>
<p><strong>단점:</strong></p>
<ul>
<li>단어가 일치해야만 검색됩니다. &quot;아이폰 만드는 회사&quot;를 검색하면 &quot;애플&quot;이 적힌 문서를 찾지 못할 수 있습니다.</li>
<li>동의어, 패러프레이징에 취약합니다.</li>
</ul>
<h3 id="dense-retrieval-밀집-검색">Dense Retrieval (밀집 검색)</h3>
<p>임베딩 모델을 사용해 텍스트를 벡터로 변환한 뒤, <strong>벡터 간 코사인 유사도</strong>로 관련성을 판단합니다.</p>
<p><strong>동작 원리:</strong> 단어의 일치가 아닌, 문장의 <strong>의미적 유사성</strong>을 기반으로 검색합니다.</p>
<p><strong>장점:</strong></p>
<ul>
<li>단어가 다르더라도 의미가 같으면 찾아냅니다.</li>
<li>문맥 이해가 필요한 복잡한 질문에 강합니다.</li>
</ul>
<p><strong>단점:</strong></p>
<ul>
<li>임베딩 모델 학습 및 추론에 컴퓨팅 자원이 필요합니다.</li>
<li>&quot;GPT-4o-mini&quot; 같은 정확한 키워드 검색에서는 오히려 BM25보다 부정확할 수 있습니다.</li>
</ul>
<h3 id="실전에서는--hybrid-retrieval">실전에서는? — Hybrid Retrieval</h3>
<p>현업에서는 두 방법을 함께 쓰는 <strong>Hybrid Retrieval</strong>이 일반적입니다. BM25로 키워드 매칭을 하고, Dense Retrieval로 의미 유사도를 계산한 뒤, 두 점수를 합산(RRF 등)하여 최종 순위를 결정합니다. 각 방법의 약점을 서로 보완하는 방식입니다.</p>
<hr>
<h2 id="5-embedding-model은-꼭-같은-모델을-써야-할까">5. Embedding Model은 꼭 같은 모델을 써야 할까?</h2>
<p>기본적으로는 그렇습니다. 하지만 비대칭 검색에서는 예외가 있습니다.</p>
<p>Dense Retrieval 시스템은 텍스트를 숫자로 변환하는 <strong>Bi-Encoder(이중 인코더)</strong> 구조를 기반으로 합니다. 이때 사용되는 두 가지 핵심 모델인 질의용 모델과 문서용 모델은 다음과 같은 역할을 수행합니다.</p>
<h3 id="1-질의용-모델-query-encoder">1. 질의용 모델 (Query Encoder)</h3>
<p>사용자가 입력한 질문(Query)을 벡터 공간의 한 점으로 변환하는 모델입니다.</p>
<ul>
<li><strong>역할:</strong> 질문의 의도와 핵심 키워드를 파악하여 벡터로 수치화합니다.</li>
<li><strong>특징:</strong> 검색 시점에 실시간으로 동작하며, 짧은 문장 형태의 입력을 처리하는 데 최적화되어 있습니다.</li>
</ul>
<h3 id="2-문서용-모델-documentpassage-encoder">2. 문서용 모델 (Document/Passage Encoder)</h3>
<p>방대한 양의 지식 문서(Document)를 벡터로 변환하여 데이터베이스에 미리 저장하는 모델입니다.</p>
<ul>
<li><strong>역할:</strong> 각 문서의 의미적 맥락을 요약하여 벡터 공간에 좌표를 찍어둡니다.</li>
<li><strong>특징:</strong> 시스템 구축 단계에서 미리 대량의 데이터를 인코딩(Indexing)하며, 긴 텍스트의 정보를 압축하는 능력이 중요합니다.</li>
</ul>
<h3 id="3-왜-두-모델의-기반이-같아야-할까요">3. 왜 두 모델의 &#39;기반&#39;이 같아야 할까요?</h3>
<p>질의용 모델과 문서용 모델은 <strong>같은 벡터 평면(Embedding Space) 위에서 대화해야 하기 때문</strong>입니다.</p>
<p>비유하자면, 두 사람이 같은 지도를 쓰지 않으면 서로의 위치를 비교할 수 없는 것과 같습니다. 서울 지도 위의 좌표를 뉴욕 지도 위의 좌표와 비교하는 건 아무 의미가 없습니다.</p>
<ul>
<li><strong>대칭형(Symmetric) 검색:</strong> 질문과 문서의 형식이 비슷할 때 사용하며, 보통 하나의 임베딩 모델이 두 역할을 모두 수행합니다.</li>
<li><strong>비대칭형(Asymmetric) 검색:</strong> &quot;질문은 짧고 문서는 길다&quot;는 현실적인 차이를 극복하기 위해, 모델 내부적으로 질의와 문서에 대해 서로 다른 접두사(Instruction)를 붙여 처리하기도 합니다. 예를 들어, 질문에는 <code>query:</code> 를, 문서에는 <code>passage:</code> 를 붙여 같은 모델 내에서도 인코딩 방식을 최적화합니다.</li>
</ul>
<p>결론적으로, 두 모델은 동일한 가중치를 공유하는 하나의 모델이거나, 최소한 동일한 데이터셋으로 함께 학습되어 <strong>동일한 차원의 벡터 공간을 공유하는 쌍</strong>이어야만 정상적인 검색이 가능합니다.</p>
<hr>
<h2 id="6-임베딩-모델의-두-가지-인코딩-방식">6. 임베딩 모델의 두 가지 인코딩 방식</h2>
<p>임베딩 모델에서의 Instruction(지시어)은 모델에게 &quot;지금 들어오는 문장을 어떤 용도로 처리해라&quot;라고 명시하는 일종의 &#39;태그&#39;입니다. 크게 두 가지 방식이 있습니다.</p>
<h3 id="방식-1-일반적인-방식-symmetric">방식 1. 일반적인 방식 (Symmetric)</h3>
<p>별도의 지시어 없이 문장만 입력하는 방식입니다.</p>
<pre><code>질문:  오늘 날씨 어때?          → (모델 입력) → 벡터 생성
문서:  서울의 오늘 날씨는 맑음입니다. → (모델 입력) → 벡터 생성</code></pre><p>모델은 들어온 문장의 &#39;의미&#39;만 보고 벡터를 만듭니다.</p>
<h3 id="방식-2-지시어를-쓰는-방식-asymmetric--instruction-based">방식 2. 지시어를 쓰는 방식 (Asymmetric / Instruction-based)</h3>
<p>최근 성능이 좋은 모델들(예: BGE, E5 등)은 질문과 문서의 성격이 다르다는 점을 활용하기 위해 특정 단어를 앞에 붙여서 학습합니다.</p>
<pre><code>질문용 입력: query: 오늘 날씨 어때?
문서용 입력: passage: 서울의 오늘 날씨는 맑음입니다.</code></pre><p><strong>왜 굳이 이렇게 할까요?</strong></p>
<p>질문은 보통 &quot;짧고 궁금한 상태&quot;이고, 문서는 &quot;길고 정보를 담고 있는 상태&quot;입니다. 모델에게 &quot;이 문장은 질문이니까 답을 찾기 적합한 위치에 점을 찍어줘&quot;라고 명확히 가이드를 주면, 단순히 문장만 넣었을 때보다 검색 정확도(Similarity)가 비약적으로 올라가기 때문입니다.</p>
<p>즉, 질문과 문서에 &quot;프롬프트가 다르다&quot;는 것은 우리가 LLM과 대화하듯 내용을 바꾸는 게 아니라, 모델이 질문용 벡터와 문서용 벡터를 더 정교하게 구분해서 만들 수 있도록 <strong>정해진 머리말(prefix)을 붙여준다</strong>는 뜻입니다.</p>
<blockquote>
<p>💡 사용하려는 모델의 공식 문서에 &quot;Queries should be prefixed with...&quot; 같은 문구가 있다면, 이 지시어를 반드시 지켜야 제 성능이 나옵니다.</p>
</blockquote>
<h3 id="지시어instruction-사용-예시--bge-모델">지시어(Instruction) 사용 예시 — BGE 모델</h3>
<p>가장 대표적인 모델인 BGE(Beijing General Embedding) 모델을 예로 들면 다음과 같습니다.</p>
<p><strong>문서 저장 시 (Indexing):</strong> 별도의 지시어 없이 문장만 넣습니다.</p>
<pre><code>입력: 임베딩 모델은 텍스트를 고차원 벡터로 변환하는 기술입니다.</code></pre><p><strong>질문 시 (Retrieval):</strong> 모델에게 &#39;검색을 위한 질문&#39;임을 명시합니다.</p>
<pre><code>입력: Represent this sentence for searching relevant passages: 임베딩 모델이 뭐야?</code></pre><p>이렇게 하면 모델은 질문 벡터를 만들 때 &quot;이건 답을 찾기 위한 단서다&quot;라는 점을 인지하고, 정보가 담긴 문서 벡터와 더 잘 결합되도록 수치화합니다.</p>
<hr>
<h2 id="7-이전-모델-vs-최신-embedding-model-비교">7. 이전 모델 vs 최신 Embedding Model 비교</h2>
<p>가장 큰 차이는 &#39;문맥 이해의 깊이&#39;와 &#39;검색 목적의 최적화&#39;입니다.</p>
<table>
<thead>
<tr>
<th>구분</th>
<th>이전 모델 (예: BERT 기본형)</th>
<th>최신 모델 (BGE, E5, Mistral-7B-v0.2 등)</th>
</tr>
</thead>
<tbody><tr>
<td>학습 데이터</td>
<td>주로 위키피디아 등 일반 텍스트</td>
<td>질문-답변 쌍(QA Pair) 대량 학습</td>
</tr>
<tr>
<td>문맥 파악</td>
<td>단어의 의미적 유사성에 집중</td>
<td>질문과 답변 사이의 연관성에 집중</td>
</tr>
<tr>
<td>입력 길이</td>
<td>보통 512 토큰 내외</td>
<td>8,192 토큰 이상의 긴 문서 처리 가능</td>
</tr>
<tr>
<td>지시어 처리</td>
<td>없음 (모든 문장을 동일하게 처리)</td>
<td>지시어에 따라 벡터 생성 방식 조절 가능</td>
</tr>
<tr>
<td>성능 (MTEB)</td>
<td>점수가 낮거나 특정 언어에 편중</td>
<td>다양한 언어·작업에서 압도적 성능 (SOTA)</td>
</tr>
</tbody></table>
<h3 id="핵심-개선-포인트">핵심 개선 포인트</h3>
<p><strong>비대칭 검색(Asymmetric Retrieval) 최적화</strong></p>
<p>예전 모델은 &#39;사과&#39;와 &#39;포도&#39;처럼 비슷한 단어가 들어간 문장을 가깝게 배치하는 데 그쳤다면, 최신 모델은 &quot;아이폰 만드는 회사 어디야?&quot;라는 질문과 &quot;애플은 쿠퍼티노에 본사를 둔...&quot;이라는 답변 문서를 가깝게 배치하는 능력이 월등합니다.</p>
<p><strong>Contrastive Learning (대조 학습)</strong></p>
<p>&quot;이 질문의 답은 이거야(Positive)&quot;와 &quot;이건 전혀 상관없는 문서야(Negative)&quot;를 명확히 구분하도록 훈련되어 검색 정확도가 높습니다.</p>
<p><strong>다국어 성능</strong></p>
<p>E5나 BGE-M3 같은 모델은 한국어를 포함한 수십 개의 언어를 동시에 지원하며, 언어가 달라도 의미가 같으면 가깝게 배치합니다.</p>
<hr>
<h2 id="마치며">마치며</h2>
<p>RAG는 단순히 &quot;LLM에 문서를 붙여주는 것&quot;이 아닙니다. 인덱싱 전략, 청킹 방법, 임베딩 모델 선택, 검색 방식(Sparse/Dense/Hybrid), 리랭킹까지 — 각 단계를 얼마나 잘 설계하느냐에 따라 최종 답변 품질이 크게 달라집니다.</p>
<p>특히 <strong>임베딩 모델의 선택과 지시어 사용</strong>은 실무에서 가장 놓치기 쉬운 부분이면서, 동시에 검색 품질에 즉각적인 영향을 주는 요소입니다. RAG 시스템을 구축할 때 꼭 챙겨보시길 권장합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[수강후기] 글또X유데미 【한글자막】 Docker & Kubernetes : 실전 가이드]]></title>
            <link>https://velog.io/@dust_potato/%EC%88%98%EA%B0%95%ED%9B%84%EA%B8%B0-%EA%B8%80%EB%98%90X%EC%9C%A0%EB%8D%B0%EB%AF%B8-%E3%80%90%ED%95%9C%EA%B8%80%EC%9E%90%EB%A7%89%E3%80%91-Docker-Kubernetes-%EC%8B%A4%EC%A0%84-%EA%B0%80%EC%9D%B4%EB%93%9C</link>
            <guid>https://velog.io/@dust_potato/%EC%88%98%EA%B0%95%ED%9B%84%EA%B8%B0-%EA%B8%80%EB%98%90X%EC%9C%A0%EB%8D%B0%EB%AF%B8-%E3%80%90%ED%95%9C%EA%B8%80%EC%9E%90%EB%A7%89%E3%80%91-Docker-Kubernetes-%EC%8B%A4%EC%A0%84-%EA%B0%80%EC%9D%B4%EB%93%9C</guid>
            <pubDate>Sun, 12 May 2024 11:30:11 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/dust_potato/post/bafa091a-1b23-4fe9-8452-56072f8b399e/image.png" alt=""></p>
<p>해당 글은 글또 X 유데미 협업을 통해 수강 후기 작성을 대가로 강의를 무료로 듣고 남기는 후기 글입니다!</p>
<h1 id="유데미-소개">유데미 소개</h1>
<p>Udemy는 개발, 디자인, 자기계발, 비즈니스, 건강 및 피트니스 등 다양한 주제에 대한 강의를 제공하는 플랫폼입니다.</p>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/9d95040b-c302-44d7-afc9-d6629fdd319f/image.png" alt=""></p>
<p>한국 강사분들만 강의를 제작하시는 건 아니고 주로 외국인 강사분들의 강의가 대다수인데
한글 자막을 제공하는 강의도 있습니다.</p>
<p>제가 고른 강의는 <a href="https://www.udemy.com/course/docker-kubernetes-2022/?couponCode=UPGRADE02223">【한글자막】 Docker &amp; Kubernetes : 실전 가이드</a> 입니다.</p>
<p>사실 업무를 하면서 도커와 쿠버네티스를 깊이 사용할 일은 거의 없는데, 당시 모델 학습 환경 구축용으로 docker를 사용하면서 컨테이너의 크기가 300G, 400G를 넘기는 일이 많았습니다. 
구글링을 통한 해결방법을 따라하다가 도커 데몬을 다시 실행해야 하는 일을 겪고 나서 왜 이런일이 생기는지에 대해 도커의 원리부터 알아보기 위해 이 강의를 들었습니다. </p>
<h2 id="강의에서-제공하는-내용">강의에서 제공하는 내용</h2>
<p>강의는 총 16개 섹션으로 구성됩니다. 
<img src="https://velog.velcdn.com/images/dust_potato/post/dd850ad2-a2e3-498d-9a6d-c07eff6b63f2/image.png" alt="">
<img src="https://velog.velcdn.com/images/dust_potato/post/bb04b00b-5e92-49de-a504-21c3027625ff/image.png" alt=""></p>
<p>시각하기를 제외하고 9개는 docker에 대해 다룬 후에 쿠버네티스를 다룹니다. 
저는 당장은 쿠버네티스를 업무에서 사용할 일이 아예 없어서 이 부분은 수강하지 않았습니다.  </p>
<h2 id="강의를-통해-얻어가고자-한-내용">강의를 통해 얻어가고자 한 내용</h2>
<p>강의를 듣기 전 제가 알아가고자 했던 내용은 아래와 같습니다. </p>
<ul>
<li>도커, 컨테이너 동작 원리</li>
<li>도커 내부에 내가 -v 옵션으로 마운트한 코드가 남아있는 건지?</li>
<li>컨테이너 크기가 왜 미친듯이 커질까? - 특히 docker.root 아래 overlay2 디렉토리 
<img src="https://velog.velcdn.com/images/dust_potato/post/b5694fdb-31c5-4089-8bea-544f1a5880cb/image.png" alt="273G를 차지하는 docker.root"></li>
</ul>
<h2 id="강의-수강-후기">강의 수강 후기</h2>
<p>총 16개의 섹션에 252개의 강의가 있는 만큼 하나의 섹션이 여러개의 세부적인 강의로 나누어져 디테일하게 설명을 해주십니다. </p>
<p>또 함께 제공되는 실습 코드가 있어서 강의 수강 후 혼자 실습을 해보며 따라가기 좋습니다. </p>
<p>제가 평소 업무를 하면서 도커를 사용하는 방식은
필요한 이미지 docker hub 에서 pull, 컨테이너 생성, 컨테이너 안에서 학습/테스트 진행 정도로 사용하고 있어서
도커 관련해서는 아주 기본적인 활용법만 아는 상태였습니다. </p>
<p>이 강의를 통해 가장 얻어가고 싶었던것은 도커 원리의 이해와 제가 겪고있는 문제의 해결이었는데요. 
일단 도커,컨테이너의 동작 원리와 방식은 강의를 통해 제대로 알 수 있었으며 
평소에 궁금했던 의문에 대한 답도 얻을 수 있었고
명확한 원인과 해결방법을 찾지는 못했지만 원리의 이해를 통해 제가 겪는 문제도 우회적으로 해결할 수 있었습니다. </p>
<p>문제 해결 부분에 대해 조금 더 구체적으로 설명하자면, 
저는 docker 이미지는 터미널에서 받고 이후 container를 띄우고 개발환경을 셋팅하는 것은 모무 vscode 에 container를 attach해서 사용합니다. 
계속 컨테이너 크기가 커지길래 docker diff 명령어를 활용해서 어떤 레이어가 쌓이는지를 봤는데 vscode 관련 레이어가 굉장히 많이 쌓여있는 것을 발견했습니다. </p>
<p>그래서 터미널에서 모든 환경 설정까지 완료하고 tmux를 사용해서 jupyter lab을 백그라운드로 띄워 사용하니 컨테이너 크기가 커지지 않는 것을 발견했습니다. </p>
<p>강의에서 도커, 컨테이너가 레이어로 구성되어 있다는 것, 컨테이너의 레이어가 언제 추가되는지, 이를 확인할 수 있는 명령어는 무엇인지 등을 알게되어 이 문제의 원인을 발견할 수 있었습니다. </p>
<p>vscode를 사용하면서도 도커 컨테이너의 크기를 작게 유지하는 방법은 찾지 못했지만, 
일단은 일이 너무 바쁜데 컨테이너를 붙잡고 있지 않아도 된다는 점에 감사하며,, 제대로 된 해결방법은 추후에 또 찾을 수 있을 것 같습니다. </p>
<h3 id="강의-수강을-추천드리는-분들">강의 수강을 추천드리는 분들</h3>
<p>그래서, 다음과 같은 분들께 이 강의를 추천드립니다!</p>
<ul>
<li>도커에 대해 잘 모르시는 분들, </li>
<li>저처럼 아주 기본적인 사용 방법만 아는 분들</li>
<li>도커를 활용하며 문제를 겪었지만 제대로된 원리를 몰라 해결하지 못한 분들
도커와 컨테이너의 동작 원리 및 활용법을 배우기 좋은 강의입니다. </li>
</ul>
<p>다만 도커에 대해서 아무것도 모르고 시작하면 이해가 어려워 
강의를 이해하기 위해 구글링 하는 시간이 더 길어질 수 있으니 한번이라도 겉핥기로 사용하신 분들께 이 강의를 추천합니다. </p>
<h1 id="유데미-사용-후기">유데미 사용 후기</h1>
<p>글또와 유데미에서 제공해주신 소중한 기회를 통해 이번에 처음으로 유데미를 사용해봤는데요.</p>
<p>유데미는 해외 강사님의 강의까지 제공해주시다보니 강의 선택의 폭이 매우 넓은 점이 좋았습니다.
이번 수강을 계기로 유데미에 제가 찾는 내용의 강의가 있는지 많이 찾아보고 추가결제를 한 강의도 있네요!</p>
<p>꾸준한 학습을 도와주는 학습도구가 있다는 점도 좋았습니다.
<img src="https://velog.velcdn.com/images/dust_potato/post/b95bb75d-752e-470d-a9a9-e3bf7946a288/image.png" alt=""></p>
<p>보시는 것처럼 저도 등록을 해놨는데요.
내가 매주 지정한 시간에 강의를 듣겠다고 캘린더에 지정을 해놓으면, 내 캘린더에 해당 일정을 가져올 수 있고 알림을 받을 수 있습니다.</p>
<p>강의를 듣다보면 게을러져 중간에 포기하거나 수강을 건너뛰는 경우가 생기는데, 이런 기능을 제공해주니 꾸준히 강의를 수강하는데에 도움이 되었습니다.</p>
<p>유데미를 사용해보지 않으신 분들은 내가 찾는 주제의 강의가 있나 탐색해보시길 추천드려요!</p>
<blockquote>
<p><a href="https://www.udemy.com">https://www.udemy.com</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[LLaMA: Open and Efficient Foundation Language Models 요약 리뷰 ]]></title>
            <link>https://velog.io/@dust_potato/LLaMA-Open-and-Efficient-Foundation-Language-Models-%EC%9A%94%EC%95%BD-%EB%A6%AC%EB%B7%B0</link>
            <guid>https://velog.io/@dust_potato/LLaMA-Open-and-Efficient-Foundation-Language-Models-%EC%9A%94%EC%95%BD-%EB%A6%AC%EB%B7%B0</guid>
            <pubDate>Mon, 08 Apr 2024 08:10:17 GMT</pubDate>
            <description><![CDATA[<h1 id="background">Background</h1>
<ul>
<li><p>Instruction Tuning 이란 </p>
<p>Instruction Tuning은 자연어 처리(NLP) 분야에서 사용되는 모델 훈련 방식 중 하나로, 모델이 특정 지시(instruction)를 따르는 방식으로 행동하도록 학습하는 과정입니다. 이 방법은 모델에게 명시적인 지시사항을 기반으로 특정 작업을 수행하도록 하는데 초점을 맞추며, 이를 통해 모델의 다양한 NLP 태스크에 대한 유연성과 적응성을 향상시킵니다.</p>
<ul>
<li><p>Instruction Tuning의 핵심 포인트:</p>
<ul>
<li>지시사항 기반 학습: 
모델은 사람이 이해할 수 있는 자연어 지시사항을 받고, 이에 따라 적절한 반응을 생성하는 방식으로 학습됩니다. 예를 들어, &quot;이 문장을 요약해라&quot;, &quot;이 질문에 답해라&quot;와 같은 지시를 받았을 때 모델이 해당 태스크를 수행하도록 합니다.<ul>
<li>다양한 태스크에 대한 일반화: 
Instruction Tuning을 통해 학습된 모델은 하나의 모델로 다양한 NLP 태스크를 처리할 수 있게 됩니다. 즉, 태스크별로 별도의 모델을 학습시키는 대신, 하나의 모델이 다양한 지시사항을 이해하고 수행할 수 있습니다.</li>
<li>효율성과 유연성 향상: 
모델이 지시사항을 이해하고 수행하는 방식으로 학습함으로써, 새로운 태스크나 약간 다른 형식의 태스크에 대해 모델을 빠르게 적응시킬 수 있습니다.</li>
</ul>
</li>
</ul>
</li>
<li><p>Instruction Tuning의 예시:</p>
<p>OpenAI의 GPT-3와 같은 대규모 언어 모델은 다양한 지시사항에 기반한 태스크 수행 능력을 보여주며, 이는 Instruction Tuning과 유사한 방식으로 다양한 지시에 대응할 수 있는 능력을 모델에 부여합니다. 예를 들어, 사용자가 &quot;이 이메일을 정중한 답장 형태로 요약해 줘&quot;라고 지시할 경우, 모델은 이메일 내용을 요약하고 정중한 어조로 답장을 생성할 수 있습니다.</p>
<p>Instruction Tuning은 특히 다양한 형태의 입력과 요구사항에 대응할 수 있는 범용 NLP 모델을 개발하는 데 있어 중요한 접근 방식으로 자리잡고 있으며, 모델의 실용성과 활용 범위를 크게 넓히는 데 기여합니다.</p>
</li>
</ul>
</li>
<li><p>이미지-텍스트 쌍 데이터와 instruction following 데이터의 차이</p>
<p>이미지-텍스트 쌍 데이터와 instruction following 데이터는 머신 러닝, 특히 자연어 처리(NLP)와 컴퓨터 비전 분야에서 사용되는 두 가지 다른 유형의 데이터입니다. 각각은 다른 목적과 구조를 가지고 있으며, AI 모델을 훈련시키기 위한 다른 종류의 정보를 제공합니다.</p>
<ul>
<li><p>이미지-텍스트 쌍 데이터</p>
<p>이미지-텍스트 쌍 데이터는 각 이미지에 해당하는 설명이나 캡션을 포함하는 데이터셋입니다. 이러한 데이터셋은 주로 이미지 설명 생성(Image Captioning), 시각적 질문 응답(Visual Question Answering, VQA), 이미지 검색 및 자동 태깅 등의 작업에 사용됩니다. 목적은 모델이 이미지의 시각적 내용을 이해하고, 이를 토대로 관련 텍스트를 생성하거나, 주어진 텍스트 질문에 대해 이미지를 분석하여 답변하는 능력을 개발하는 것입니다.</p>
</li>
<li><p>Instruction Following 데이터</p>
<p>Instruction following 데이터는 AI 모델이 특정 지시사항이나 명령을 따르도록 하는 작업을 위해 설계된 데이터입니다. 이 데이터 유형은 모델에게 주어진 지시를 이해하고, 해당 지시에 따라 적절한 작업을 수행하도록 요구합니다. 이러한 작업에는 지시에 따른 이미지 생성, 지시에 기반한 텍스트 생성, 지시에 따른 행동 수행(로봇 제어 등) 등이 포함될 수 있습니다. 목적은 모델이 자연어로 된 지시사항을 이해하고, 이를 토대로 특정 작업을 수행하는 능력을 개발하는 것입니다.</p>
</li>
<li><p>차이점</p>
<ul>
<li>용도와 목적: 
이미지-텍스트 쌍 데이터는 주로 이미지의 내용을 기반으로 텍스트를 생성하는 작업에 사용되며, 모델이 시각적 정보를 어떻게 이해하고 언어로 표현하는지에 초점을 맞춥니다. 반면, instruction following 데이터는 모델이 주어진 지시사항을 이해하고, 그에 따른 적절한 작업을 수행하는 능력을 개발하는 데 사용됩니다.</li>
<li>데이터 구조: 
이미지-텍스트 쌍 데이터는 이미지와 이에 대응하는 텍스트(설명, 캡션 등)로 구성됩니다. instruction following 데이터는 지시사항(텍스트 형태)과 이를 수행하기 위한 정보(이미지, 텍스트, 또는 기타 형태)로 구성될 수 있습니다.</li>
<li>응용 분야: 
이미지-텍스트 쌍 데이터는 이미지 캡셔닝, 시각적 질문 응답 등의 시각-언어 작업에 주로 사용되며, instruction following 데이터는 자연어 이해, 로봇 제어, 생성적 작업 등 더 다양한 분야에 적용될 수 있습니다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h1 id="llama">LLaMA</h1>
<p>paper | code | demo | project page </p>
<h2 id="motivation">Motivation </h2>
<p>기존의 scaling low 법칙은 모델의 파라미터가 많을 수록 성능이 좋을 것이라는 가정하에 특정 training compute budget 내에서 dataset과 모델 크기를 scaling 했음 </p>
<p>그러나 이런 연구는 inference budget은 고려하지 않았음. </p>
<p>inference compute budget을 고려했을 때, 가장 최고의 성능은 큰 모델에서 나오는게 아니라 작은 모델을 더 많은 데이터로 학습시켰을 때 였음 (Jordan Hoffmann, , 2022. Training compute-optimal large language models.)</p>
<p>따라서 논문의 목표는 일반적으로 사용되는 것보다 더 많은 토큰에 대해 훈련함으로써 다양한 inference budget에서 가능한 최상의 성능을 달성하는 일련의 언어 모델을 훈련하는 것. </p>
<p>Chinchilla, PaLM, GPT-3와 다르게 오픈 데이터만을 사용함 </p>
<h2 id="takeaways">Takeaways</h2>
<ul>
<li>Datasets
open dataset 활용
<img src="https://velog.velcdn.com/images/dust_potato/post/4c2e67b1-a9dc-471a-bbd8-51e825f1e17d/image.png" alt=""></li>
</ul>
<ul>
<li><p>Tokenizer
byte-pair encoding (BPE) algorithm </p>
<blockquote>
<p>LLM에서 tokenizer의 역할
LLM(Long Language Models)에서 tokenizer는 텍스트 데이터를 모델이 처리할 수 있는 형태로 변환하는 역할을 합니다. 기본적으로, 대규모 언어 모델은 텍스트를 직접적으로 이해하거나 처리할 수 없기 때문에, 텍스트를 모델이 처리할 수 있는 숫자 형태로 변환하는 과정이 필요합니다. 이 과정을 토큰화(tokenization)라고 하며, 여기서 tokenizer는 이러한 변환 작업을 담당하는 구성 요소입니다.</p>
<p>Tokenizer의 주요 역할:</p>
</blockquote>
<p>텍스트 분할: Tokenizer는 주어진 텍스트를 작은 단위인 토큰(token)으로 분할합니다. 토큰은 단어, 서브워드(subword), 문자 등 다양한 형태가 될 수 있습니다. 이 과정에서 공백, 구두점 등을 기준으로 텍스트를 나누기도 하며, 보다 세분화된 단위로 나누기 위해 서브워드 토큰화 방법을 사용하기도 합니다.</p>
<blockquote>
</blockquote>
<p>토큰 인덱싱: 분할된 토큰을 모델이 이해할 수 있는 숫자로 변환하는 과정입니다. Tokenizer는 사전(vocabulary)을 사용하여 각 토큰에 고유한 숫자 ID를 할당합니다. 이 ID는 모델이 토큰의 의미를 학습하고 처리하는 데 사용됩니다.</p>
<blockquote>
</blockquote>
<p>텍스트 전처리: 토큰화 과정에서 텍스트를 정규화(소문자화, 불필요한 공백 제거 등)하고, 특수 토큰(시작 토큰, 종료 토큰 등)을 추가하는 등의 전처리 작업을 수행합니다. 이는 모델이 텍스트를 보다 효율적으로 처리하고, 문맥을 올바르게 이해하는 데 도움을 줍니다.</p>
<blockquote>
</blockquote>
<p>입력 형식 준비: LLM은 특정 길이의 입력을 요구하기 때문에, tokenizer는 텍스트를 모델의 입력 길이에 맞게 조정합니다. 이는 텍스트를 잘라내거나(padding) 필요한 경우 패딩(padding)을 추가하여 입력 길이를 조정합니다.</p>
<blockquote>
</blockquote>
<p>Tokenizer는 LLM을 포함한 다양한 NLP 모델에서 필수적인 구성 요소로, 텍스트 데이터를 모델이 이해하고 학습할 수 있는 형식으로 변환하는 핵심적인 역할을 합니다.</p>
<blockquote>
<p>BPE란 ? </p>
</blockquote>
<p>BPE(Byte Pair Encoding)는 자연어 처리(NLP) 분야에서 사용되는 토큰화(tokenization) 방법 중 하나로, 특히 서브워드(subword) 토큰화에 사용됩니다. BPE의 핵심 아이디어는 말뭉치(corpus) 내에서 가장 빈번하게 등장하는 바이트 쌍(byte pairs) 또는 문자 쌍을 반복적으로 병합하여, 빈도수가 높은 문자열을 하나의 새로운 토큰으로 만드는 것입니다. 이 방법은 초기에 데이터 압축 분야에서 사용되었지만, 나중에 NLP에서 효율적인 토큰화 방법으로 널리 채택되었습니다.</p>
<blockquote>
</blockquote>
<p>BPE 토큰화 과정:</p>
<blockquote>
</blockquote>
<p>초기 사전 구축: 모든 단어를 문자의 시퀀스로 분해하고, 각 단어의 끝에 특수 문자(예: </w>)를 추가하여 단어의 경계를 명시합니다. 이때, 모든 문자(또는 바이트)를 초기 토큰으로 간주하고, 각 토큰의 빈도수를 계산합니다.</p>
<blockquote>
</blockquote>
<p>가장 빈번한 쌍 병합: 말뭉치 전체에서 가장 자주 등장하는 인접한 토큰(문자 또는 문자열) 쌍을 찾아 하나의 토큰으로 병합합니다. 이 과정은 미리 정한 횟수만큼 또는 사전의 크기가 특정 크기에 도달할 때까지 반복됩니다.</p>
<blockquote>
</blockquote>
<p>사전 업데이트: 병합된 새 토큰을 사전에 추가하고, 다음 반복에서 사용할 수 있도록 합니다.</p>
<blockquote>
</blockquote>
<p>토큰화: 학습된 BPE 사전을 사용하여 새로운 텍스트를 토큰화합니다. 이때, 사전에 있는 가장 긴 문자열부터 매칭하여 토큰으로 분리합니다.</p>
<blockquote>
</blockquote>
<p>BPE의 장점:
OOV(Out-Of-Vocabulary) 문제 완화: BPE는 단어를 서브워드 단위로 분해할 수 있기 때문에, 학습 데이터에 없는 새로운 단어가 등장해도 서브워드 단위로 처리할 수 있어 OOV 문제를 효과적으로 줄일 수 있습니다.
효율적인 어휘 관리: BPE는 빈도수가 높은 서브워드를 동적으로 선택하기 때문에, 모델이 처리해야 할 어휘의 크기를 효율적으로 관리할 수 있습니다.
언어의 형태학적 정보 포착: 서브워드 단위로 텍스트를 분해함으로써, 단어의 형태학적인 특성을 일정 부분 포착할 수 있으며, 이는 특히 유사한 형태를 가진 단어들 사이의 관계 학습에 도움을 줍니다.</p>
<blockquote>
</blockquote>
<p>BPE는 GPT, BERT와 같은 현대의 대규모 언어 모델에서 널리 사용되는 토큰화 방법 중 하나로, 효율적인 텍스트 처리와 모델의 성능 향상에 기여하고 있습니다.</p>
</li>
</ul>
<p>Overall, our entire training dataset contains roughly 1.4T tokens after tokenization</p>
<ul>
<li>Architecture
transformer 기반 
다른 LLM논문에서 영감을 얻어 수정함,  영감을 얻은 논문은 [] 표시로 표시 
Pre-normalization [GPT3]
training stability를 개선하기 위해 transformer sub-layer의 input을 normalize 함 
Root Mean Square Layer Normalization(RMSNorm) 사용 </li>
</ul>
<blockquote>
</blockquote>
<p><a href="http://dmqm.korea.ac.kr/activity/seminar/364">http://dmqm.korea.ac.kr/activity/seminar/364</a> 
<a href="https://kwonkai.tistory.com/144">https://kwonkai.tistory.com/144</a>
Batch Norm : mini batch 의 feature 별로 , channel 별로 
Layer Norm : mini batch의 sample 별로 </p>
<blockquote>
<p>RMS Layer Norm : 
motivation : RNN 계열 모델에서 Layer Norm 의 expensive computational cost 
how 
LN의 역할 두가지 
re-centering invariance : enables the model to be insensitive to shift noises on both inputs and weights (입력과 가중치 모두에서 shift noise에 둔감할 수 있도록)
re-scaling invariance : keeps the output representations intact when both inputs and weights are randomly scaled (입력과 가중치가 무작위로 scale 될 때 output 출력을 그대로 유지)
LN의 성공요인은 re-scaling invariance 가 더 큰 역할을 했다고 봄, 이유는 안읽어봄 
그래서 summed input을 RMS로 나누어 normalize 함 
평균 빼는 건 없앴는데 그래도 괜찮다고 함
<img src="https://velog.velcdn.com/images/dust_potato/post/07754152-e3f8-401b-bf42-76945376e5cf/image.png" alt=""><img src="https://velog.velcdn.com/images/dust_potato/post/42604650-cb5f-4474-a1ee-0f94a468321c/image.png" alt="">
contribution
Extensive experiments on several tasks using diverse network architectures show that RMSNorm achieves comparable performance against LayerNorm but reduces the running time by 7%∼64% on different models.</p>
</blockquote>
<ul>
<li><p>SwiGLU activation function [PaLM]
non-linearity by the SwiGLU activation function
<img src="https://velog.velcdn.com/images/dust_potato/post/364f7e74-39a5-4f16-8abb-675da49ec5e8/image.png" alt=""></p>
<p>Paper : <a href="https://arxiv.org/pdf/2002.05202v1.pdf">https://arxiv.org/pdf/2002.05202v1.pdf</a></p>
<p>PaLM 에서 사용한 4d 대신 2/3 4d 사용</p>
</li>
<li><p>Rotary Embeddings [GPTNeo]
absolute positional embeddings을 제거하고 대신 rotary positional embeddings (RoPE) 사용</p>
</li>
</ul>
<blockquote>
<p>Absolute Positional Embeddings과 Rotary Positional Embeddings (RoPE)는 트랜스포머 모델에서 위치 정보를 다루는 두 가지 다른 접근 방식입니다. 트랜스포머 모델은 시퀀스 데이터를 처리할 때, 시퀀스 내 각 요소의 위치 정보가 중요한 역할을 합니다. 위치 정보는 모델이 단어의 순서와 문맥을 이해하는 데 도움을 주며, 이를 통해 더 정확한 언어 이해와 생성이 가능해집니다.</p>
</blockquote>
<p><strong>Absolute Positional Embeddings</strong>
Absolute Positional Embeddings는 트랜스포머 모델의 초기 버전에서 사용된 방식으로, 각 위치에 고유한 임베딩을 할당하여 위치 정보를 제공합니다. 이 임베딩은 입력 시퀀스의 각 토큰과 함께 모델에 입력되며, 모델이 시퀀스 내에서 각 토큰의 위치를 인식할 수 있도록 합니다.
이 방식의 단점은 고정된 길이의 위치 임베딩을 미리 정의해야 하기 때문에, 모델이 처리할 수 있는 최대 시퀀스 길이가 제한된다는 점입니다.
<strong>Rotary Positional Embeddings (RoPE)</strong>
RoPE는 상대적 위치 정보를 기반으로 하는 더 유연한 방식입니다. RoPE는 각 토큰의 위치 정보를 해당 토큰의 임베딩에 직접 회전(rotation)을 적용함으로써 인코딩합니다. 이 회전은 토큰 간의 상대적 위치 관계를 보존하며, 모델이 이러한 관계를 통해 시퀀스 내에서의 위치를 추론할 수 있게 합니다.
RoPE의 핵심 이점은 위치 임베딩이 입력 시퀀스와 별도로 학습되거나 저장될 필요가 없다는 것입니다. 대신, 위치에 따라 토큰 임베딩에 회전을 적용하여 위치 정보를 동적으로 표현합니다. 이 방식은 모델이 처리할 수 있는 시퀀스의 길이에 대한 제한을 완화하고, 더 긴 시퀀스에 대한 일반화 능력을 향상시킬 수 있습니다.
<strong>RoPE 사용의 장점</strong>
길이 제한 완화: 모델이 처리할 수 있는 시퀀스 길이에 대한 제약이 줄어듭니다.
동적 위치 정보: 시퀀스 내에서의 상대적 위치 정보를 효과적으로 모델링하여, 문맥 이해력을 강화할 수 있습니다.
유연성과 일반화: 다양한 길이의 시퀀스에 대해 모델이 더 잘 일반화할 수 있도록 돕습니다.</p>
<blockquote>
</blockquote>
<p>RoPE는 특히 긴 문서나 대화, 혹은 시계열 데이터와 같이 긴 시퀀스를 처리해야 하는 경우에 유용하며, 트랜스포머 모델의 효율성과 유연성을 크게 향상시킬 수 있습니다.</p>
<ul>
<li>Optimizer
AdamW 
We use a cosine learning rate schedule, such that the final learning rate is equal to 10% of the maxi- mal learning rate.
Efficient Optimization
activation checkpointing : backward pass 과정에서 recompute 되는 activation 을 줄임 
Linear layer 의 output 처럼 계산 비용이 비싼 activation을 저장해놓음 (pytorch autograd를 사용하지 않고 transformer layer의 backward pass 직접 구현)
이 과정의 이익을 최대한으로 하기 위해 model and sequence parallelism 이 사용하는 메모리 사용량을 줄임
네트워크를 통한 computation of activations and the communication between GPUs (all_reduce operations로 인해)를 최대한 overlap.
65B 매개변수 모델을 훈련할 때 코드는 80GB의 RAM이 있는 2048 A100 GPU에서 약 380개의 token/sec/GPU를 처리
이는 1.4T 토큰이 포함된 데이터 세트를 통해 훈련하는 데 약 21일이 걸린다는 것을 의미</li>
</ul>
<ul>
<li><ol start="4">
<li>Instruction Finetuning 파트
아주 적은 양의 fiuetuning 만으로도 massive multitask language understanding benchmark, or MMLU 에서 점수가 아주 잘나오는 것을 발견</li>
</ol>
</li>
</ul>
<h2 id="contribution">Contribution</h2>
<ul>
<li>6.7B ~ 65.2B까지 다양한 크기의 LLM 제작</li>
<li>LLaMA-13B outperforms GPT-3 while being more than 10× smaller, and LLaMA-65B is competitive with Chinchilla-70B and PaLM-540B.
(모델의 크기가 작아도 기존의 크기가 매우 큰 모델보다 더 좋은 성능을 낼 수 있음 을 보임  )</li>
<li>publicly available data만 사용해도 sota 성능을 낼 수 있음을 보임</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Paper Review] YOLO-World: Real-Time Open-Vocabulary Object Detection 리뷰 ]]></title>
            <link>https://velog.io/@dust_potato/Paper-Review-YOLO-World-Real-Time-Open-Vocabulary-Object-Detection-%EB%A6%AC%EB%B7%B0</link>
            <guid>https://velog.io/@dust_potato/Paper-Review-YOLO-World-Real-Time-Open-Vocabulary-Object-Detection-%EB%A6%AC%EB%B7%B0</guid>
            <pubDate>Sun, 11 Feb 2024 09:46:39 GMT</pubDate>
            <description><![CDATA[<p><strong>REF</strong>
<a href="https://jiho-ml.com/weekly-nlp-34/">https://jiho-ml.com/weekly-nlp-34/</a>
<a href="https://openmmlab.medium.com/dive-into-yolov8-how-does-this-state-of-the-art-model-work-10f18f74bab1">https://openmmlab.medium.com/dive-into-yolov8-how-does-this-state-of-the-art-model-work-10f18f74bab1</a>
<a href="https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/modules/block.py#L205">https://github.com/ultralytics/ultralytics/blob/main/ultralytics/nn/modules/block.py#L205</a></p>
<blockquote>
<p>YOLO-World: Real-Time Open-Vocabulary Object Detection 리뷰 </p>
</blockquote>
<p>DEMO : <a href="https://huggingface.co/spaces/stevengrove/YOLO-World">https://huggingface.co/spaces/stevengrove/YOLO-World</a></p>
<p>PAPER : <a href="https://arxiv.org/pdf/2401.17270.pdf">https://arxiv.org/pdf/2401.17270.pdf</a> / <a href="https://www.semanticscholar.org/reader/37c112454a236ab91c9c6b5cc165a6c3251e9206">https://www.semanticscholar.org/reader/37c112454a236ab91c9c6b5cc165a6c3251e9206</a></p>
<p>MODEL &amp; CODE  : <a href="https://github.com/AILab-CVC/YOLO-World?tab=readme-ov-file">https://github.com/AILab-CVC/YOLO-World?tab=readme-ov-file</a></p>
<h2 id="background">BACKGROUND</h2>
<ul>
<li>yolo series - yolov8 </li>
<li>multi modal </li>
<li>open valcabulary obejct detetion</li>
<li>region-text matching </li>
<li>clip, Glip, G-dino</li>
<li>online / offline vocabulary </li>
</ul>
<h2 id="related-work">Related work</h2>
<h3 id="open-vocabulary-object-detection">Open-Vocabulary Object Detection</h3>
<p>to detect objects beyond the predefined categories 를 목적으로 한 연구 분야 </p>
<p>초기 셋팅 : training detectors on the base classes and evaluating the novel (unknown) classes </p>
<p>novel object 에 대한 detector의 성능을 알아보려 했지만 제한된 데이터 셋으로 학습했기 때문에 여전히 일반화 성능 떨어짐 </p>
<p>최근 연구 : grounding 멀티모달 학습을 함 </p>
<ul>
<li><p>GLIP - phrase grounding 을 기반으로 open-vocabulary detection을 위한  pretrained framework 제안하고 zero-shot 평가 </p>
</li>
<li><p>Groungind DINO  - grounded pre-training을 cross-modality fusion을 통해 detection transformers 에 통합 </p>
</li>
<li><p>DETCLIP, DETCLIPv2, GLIPv2 와같은 연구 - large-scale image-text pairs로 학습된 pre-trained detectors사용, region-text matching 을 통한 image-text datasets 사용으로 일반화 성능 향상을 도모</p>
<p>그러나 이런 연구는 ATSS, DINO, SWIN-T 와 같은 매우 큰 백본을 사용하여 high computationl demands, deplyment 가 어려운 문제가 있음</p>
<p>→ YOLO-WORLD 제안 :  aiming for efficient open-vocabulary object detection with real-time inference and easier downstream application deployment
<img src="https://velog.velcdn.com/images/dust_potato/post/305dd8cf-a337-416a-8501-150fe2523e11/image.png" alt=""></p>
</li>
</ul>
<blockquote>
<p>Grounding 이란?
Grounding이란, 사람 사이에 효과적인 소통을 위해 필수적인 공통 된 이해와 기반을 다지는 과정을 뜻합니다.
예를 들면 “비가 오네&quot;라는 말을 듣고 고개를 끄덕이거나 “빗물이 떨어진다”라고 의역을 하는 것도 grounding의 한 방법이죠. 다른 배우가 “싫어. 지금 화창한데?”라고 하면 함께 세계관을 형성하지 못하고 연극의 흐름을 깨겠죠. 반면 “우산이 없으니 편의점에서 사자.&quot;라고 대답하면 비가 오고 있다는 제안을 우산이 없다는 말로 수용하고 우산을 사야된다라는 정보를 제공하기 때문에 적절한 “Yes, and-”식 대사가 됩니다.
기냥 large scale 데이터로 학습한 pre-trained 모델 만든다는 말인듯 ?? </p>
</blockquote>
<p>OD에서의 Grounding이란 객체의 위치를 추론하는 것을 말함 </p>
<h2 id="abstract">ABSTRACT</h2>
<p>yolo 는 많이 쓰이고 있으나 미리 라벨링이 된 데이터로 지도 학습하는 모델은 open-senario 에서의 활용도가 떨어짐 </p>
<p>이를 해결하기 위해 vision-language modeling 과 pretraining on large scale dataset을 통해 open vocabulary detection 수행</p>
<h2 id="contribution">CONTRIBUTION</h2>
<ul>
<li>On the challenging LVIS dataset, YOLO-World achieves 35.4 AP with 52.0 FPS on V100, which outperforms many state-of-the-art methods in terms of both accuracy and speed.</li>
<li>Re-parameterizable Vision- Language Path Aggregation Network (RepVL-PAN)</li>
<li>region-text contrastive loss to facilitate the interaction be- tween visual and linguistic information.</li>
</ul>
<h2 id="method">METHOD</h2>
<h3 id="31-pre-training-formulation-region-text-pairs">3.1. Pre-training Formulation: Region-Text Pairs</h3>
<p>기존 : YOLO series 는 각 카테고리 기준으로 라벨링된 bounding box 가 있는 instance annotations 학습</p>
<p>논문 : instance annotations → resgion-text pairs 로 refomulate</p>
<ul>
<li>각 region B(bounding box)는 상응하는 text T 를 가짐</li>
<li>T 는  category name, noun phrases, or object description 이 될 수 있음</li>
<li>이미지 I와 텍스트 T(명사 집합)를 모두 입력으로 채택하고 예측된 상자 와 해당 객체 임베딩을 출력</li>
</ul>
<h3 id="32-model-architecture">3.2. Model Architecture</h3>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/efa5d8d6-ef7f-49fc-9237-1c76d3eab365/image.png" alt=""></p>
<p>구성 : YOLO detector, a Text Encoder, and a Re-parameterizable Vision-Language Path Aggregation Network (RepVL-PAN)</p>
<p>처리 과정 : 
먼저 text가 입력으로 들어오면,  Text Encoder가 text를 embedding으로 만듬 
YOLO detector에 있는 Image encoder가 입력 이미지를 multi scale features로 만듬
RepVL-PAN으로  image features 와 text embeddings을 fusion해서 text and image representation을 모두 활용</p>
<p>구성요소를 하나씩 보면 </p>
<ul>
<li><p>YOLO Detector</p>
<ul>
<li>YOLOv8 을 base 로 개발</li>
<li>YOLOv8 :<ul>
<li>Darknet backbone as the image encoder</li>
<li>a path aggregation network (PAN) for multi-scale feature pyramids,</li>
<li>head for bounding box regression and object embeddings.</li>
</ul>
</li>
</ul>
</li>
<li><p>Text Encoder</p>
<ul>
<li>Transformer text encoder pre-trained by CLIP</li>
<li>CLIP text encoder 가 text-only language encoder 보다 더 나은 visual-semantic capability </li>
</ul>
</li>
<li><p>Text Contrastive Head</p>
<ul>
<li>yolov8 에서 사용한 decoupled head with two 3×3 convs 사용</li>
<li>object-text similarity(classification head 에서 나온 obejct embedding e 와 text encoder에서 나온 text embedding t 의 유사도 )를 계산하는 text contrastive head 제안 </li>
<li>stabilizing the region-text training을 위해  obejct embedding e 와 text embedding t 에 L2-Norm 적용 후 affine transformation </li>
</ul>
</li>
<li><p>Training with Online Vocabulary</p>
<ul>
<li>학습하는 동안은 4개의 이미지를 포함하는 mosaic sample에 대해 online vocabulary T 를 구성함 </li>
<li>모자이크 이미지에 포함된 모든 positive nouns를 샘플링하고 해당 데이터 셋에서 일부 negative nouns를 무작위로 샘플링</li>
<li>각 모자이크 샘플의 어휘는 최대 M개의 명사를 포함하며, M은 기본값으로 80개</li>
</ul>
</li>
<li><p>Inference with Offline Vocabulary</p>
<ul>
<li>효율성을 위해 offline voabulary 를 사용하여 prompt-then-detect strategy 제시</li>
<li>사용자가 캡션이나 카테고리를 포함하는 custom 프롬프트를 정의하면, text encoder로 offline vocabulary embedding을 포함하는 offline text embedding 생성<img src="https://velog.velcdn.com/images/dust_potato/post/9256f37b-79af-43ee-b578-e9bf0753138b/image.png" alt=""></li>
<li>각 입력에 대한 계산을 피할 수 있으며 필요에 따라 어휘를 유연하게 조정 가능</li>
</ul>
</li>
</ul>
<h3 id="33-re-parameterizable-vision-language-pan">3.3. Re-parameterizable Vision-Language PAN</h3>
<p>yolov8 에서 사용된대로 csp network의 p3,p4,p5 layer에서 나온 image feature c3,c4,c5 사용</p>
<p>추론 시에는 offline vocabulary embeddings can be re-parameterized 
<img src="https://velog.velcdn.com/images/dust_potato/post/a5dccbfa-bf22-4772-8fd0-e254f278dc77/image.png" alt=""></p>
<p>open-vocabulary capability 에서의 vision-semantic representation을 improve하고 image-text embedding 상호작용을 강화하기 위해 아래 모듈 제안 </p>
<ul>
<li>Text-guided CSPLayer (T-CSPLayer)</li>
<li>Image-Pooling Attention (I-Pooling Attention)</li>
</ul>
<p>하나씩 자세히 보면 </p>
<ul>
<li><p>Text-guided CSPLayer (T-CSPLayer)
<img src="https://velog.velcdn.com/images/dust_potato/post/f6c0c043-599f-4268-a92b-e25bb2ca85e0/image.png" alt=""></p>
<ul>
<li>yolov8 에서 사용된 CSP layer( c2f layer) 에서 concat 하기 전 -  text embedding W와 image feature X 를 max-sigmoid attention을 거친 다음 concat <blockquote>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/8798f46c-ae57-4f58-a782-ef57189caef8/image.png" alt="">
yolov5 의 c3 layer  와 yolov8 c2f layer 
c3 : 3개의 convlayer로 구성된 csp bottleneck layer 
c2f : 3개의 conv layer로 구성된 fast implementation csp bottleneck layer
c2f layer 는 skip connection 과 split 갯수가 늘어남 </p>
</blockquote>
</li>
</ul>
</li>
<li><p>Image-Pooling Attention</p>
<ul>
<li>To enhance the text embed- dings with image-aware information, image feature 를 Image-Pooling Attention으로 aggregation 
<img src="https://velog.velcdn.com/images/dust_potato/post/3f955e14-3f21-4e67-a752-74823349bfee/image.png" alt=""></li>
<li>c3, c4, c5 multi scale feature에 3x3 max pooling을 적용한 뒤 total of 27 patch tokens을 가진 embedding을 text embedding과 MHCA </li>
</ul>
</li>
</ul>
<h3 id="34-pre-training-schemes">3.4. Pre-training Schemes</h3>
<p>on large-scale detection, grounding, and image-text datasets.</p>
<p><strong>Learning from Region-Text Contrastive Loss.</strong>
모자이크 샘플 이미지 I 와 텍스트 T가 주어지면 , YOLO-Worldsms K개의 object predictions와 Annotaions를 출력</p>
<p>yolov8 에서 사용한 TOOD의 task-aligned label assignment 를 사용하여 prediction 과 GT를 매칭하였고
text index를 classification label로 활용하려 각 positive prediction을 assign </p>
<p>Loss functions : 
이 vocabulary를 기반으로 object-text (region-text) 간의 유사도와 object-text assignments간의 cross-entropy region-text contrastive loss L_con을 구성
bounding box regression을 위한 IOU loss , distributed focal loss 추가 </p>
<p>최종 Loss: 
<img src="https://velog.velcdn.com/images/dust_potato/post/4be6ddc0-ccf1-4c65-843f-62fed7cda146/image.png" alt="">
람다_I는 indicator factor : input Image가 detection 또는 grounding data면 1, image-text data면 0 
image-text 데이터에서온 이미지면 contrastive loss 만 학습해서 멀모 데이터를 배우게 끔, detection 데이터면 검출 기능을 배우도록
image-text datasets은 noisy box 를 가지고 있다고 간주해서(수도 라벨링으로 생성했기 때문에) regression loss는 정확한 bounding box를 가졌을 때만 계산되도록 함</p>
<p><strong>Pseudo Labeling with Image-Text Data.</strong>
pre-training을 할 때 image-text pairs 를 바로 사용하는게 아니라, region-text pair를 자동으로 생성하는 automatic labeling 기법을 제안함 </p>
<p><strong>수도 라벨링 3단계</strong></p>
<ol>
<li><p>extract noun phrase
n-gram algorithm 을 사용하여 text 에서 noun phrase(명사구)를 추출</p>
</li>
<li><p>pseudo labeling
 GLIP 과 같은 pre-trained open-vocabulary detector를 사용하여 각 이미지마다 주어진 명사구에 대해 pseudo boxes를 생성하고 region-text 쌍을 만듬</p>
</li>
<li><p>filtering
 pre-trained CLIP 을 사용하여 image-text pairs and region-text pairs의 relevance (관련성)를 평가하고 low-relevance를 가진 pseudo annotation과 image를 filtering ,
 추가적으로 NMS를 사용해서 중복 bounding box도 filtering 함 
 이 방법으로 CC3M 데이터로부터 246k의 이미지와 821k pseudo anntations를 만듬</p>
<p>자세한 내용 appendix 참고 </p>
</li>
</ol>
<h2 id="4-experiments">4. Experiments</h2>
<p>pre-training it on large-scale dataset 에서의 effectiveness와 fine tuning의 성능 평가를 위해 
LVIS benchmark and COCO benchmark에서 zero shot 성능 평가 </p>
<h3 id="41-implementation-details">4.1. Implementation Details</h3>
<p><a href="https://github.com/open-mmlab/mmyolo">MMYOLO</a>, <a href="https://www.semanticscholar.org/paper/MMDetection%3A-Open-MMLab-Detection-Toolbox-and-Chen-Wang/c2c083df88e88223e1a411e61040b94c233b1b63">MMDetection</a> 상에서 구현 
three variants of YOLO-World  : small, medium, large 
<a href="https://www.semanticscholar.org/paper/Learning-Transferable-Visual-Models-From-Natural-Radford-Kim/6f870f7f02a8c59c3e23f407f3ef00dd1dcf8fc4">open-source CLIP</a> 의 pretrained weight을 text encoder로 활용
속도 측정 : NVIDIA V100 GPU without extra acceleration mechanisms, e.g., FP16 or TensorRT</p>
<h3 id="42-pre-training">4.2. Pre-training</h3>
<p><strong>Experimental Setup.</strong>
pre-training stage</p>
<ul>
<li>optimizer : AdamW </li>
<li>lr0 : 2e-3, weight decay : 0.05</li>
<li>pretrained 100epoch with 32 v100 total bs 512</li>
<li>data aug : follow yolov8 : color augmentation, random affine, random flip, and mosaic with 4 images for data augmentation.</li>
<li>text encoder :  frozen during pre-training</li>
<li>data: 아래 표에 표시된 데이터+pseudo labeled CC3M 
<img src="https://velog.velcdn.com/images/dust_potato/post/3cb8fff2-2d52-4081-a663-c579273921a7/image.png" alt=""></li>
</ul>
<p><strong>zero shot evaluation</strong> 
LVIS benchmark에서의 최근 SOTA 연구들 : <a href="https://www.semanticscholar.org/paper/Grounding-DINO%3A-Marrying-DINO-with-Grounded-for-Liu-Zeng/c3e5a20b844c042d2174263d2fd5b30d8cc8f0b0">Groudning DINO</a>, <a href="https://www.semanticscholar.org/paper/DetCLIP%3A-Dictionary-Enriched-Visual-Concept-for-Yao-Han/667bb464a348b2bc85e7a8e8159b948498850ec7">DetCLIP</a>, <a href="https://www.semanticscholar.org/paper/DetCLIPv2%3A-Scalable-Open-Vocabulary-Object-via-Yao-Han/2394feb97b9ec16f6eb61907b40764bd03672971">DetCLIPv2</a>, <a href="https://www.semanticscholar.org/paper/GLIPv2%3A-Unifying-Localization-and-Vision-Language-Zhang-Zhang/49b5ffebdbcbd683010a2558a19eaa9b21cd8c34">GLIPv2</a> 과 비교 </p>
<p>The experimental results also demonstrate that small models, e.g., YOLO-World-S with 13M parameters, can be used for vision-language pre-training and obtain strong open-vocabulary capabilities.
<img src="https://velog.velcdn.com/images/dust_potato/post/2407718a-e581-4d63-b112-ca8389070e03/image.png" alt=""></p>
<h3 id="44-fine-tuning-yolo-world">4.4. Fine-tuning YOLO-World</h3>
<p>pre-training 효과를 보기 위해 COCO dataset and LVIS dataset을 fine tuning 시켜 성능 확인 , 자세한 training setup 논문 참고 
coco dataset fine tuning 할 때는 RepVL-PAN 제거했음 : COCO 데이터 세트의 vocabulary 크기가 작다는 점을 고려하여 TensorRT를 사용한 추가 가속화를 하기 위해서
yolo-world large 모델이 이전 yolo 시리즈보다 더 나은 성능을 보임 
<img src="https://velog.velcdn.com/images/dust_potato/post/917a49e4-1720-47be-a98d-c86431a5fdc6/image.png" alt="">
<img src="https://velog.velcdn.com/images/dust_potato/post/29cd74ce-2efc-4abc-acbc-852e01c52c19/image.png" alt=""></p>
<h3 id="5-conclusion">5. Conclusion</h3>
<p>open-vocabulary capability를 real world application에서 활용하기 위해 real time 추론과 efficiency 향상을 목적으로 한 논문</p>
<ul>
<li>RepVL-PAN을 통해 기존의 yolo 를 vision-languge yolo로 확장했고 </li>
<li>효과적인 pre-training scheme을 제안함. </li>
<li>실험을 통해 소형 모델에 대한 vision-language pre-training의 효과를 보였음</li>
</ul>
<blockquote>
</blockquote>
<p>4.3 Ablation Experiments 논문 참고  - pretraining yolo-world의 성능,  proposed RepVL-PAN 의 성능, 다른 text encoder를 사용했을 때의 성능비교
4.4 Open-Vocabulary Instance Segmentation 논문 참고
4.6. Visualizations 논문 참고</p>
<h3 id="데모-사용해보기">데모 사용해보기</h3>
<p>DEMO : <a href="https://huggingface.co/spaces/stevengrove/YOLO-World">https://huggingface.co/spaces/stevengrove/YOLO-World</a></p>
<p>인풋으로 이미지와 검출하고자 하는 객체를 prompt로 넣으면 됨
<img src="https://velog.velcdn.com/images/dust_potato/post/f3ed6794-0908-4859-929f-15e70aae7f56/image.png" alt="">
단추까지 잡는 모습,,,
<img src="https://velog.velcdn.com/images/dust_potato/post/51cb21fc-a1ab-475c-9bd5-d9edac805c73/image.png" alt=""><img src="https://velog.velcdn.com/images/dust_potato/post/21fb8479-f994-4607-bc42-91ab40a68ded/image.png" alt="">
멀티모달로 학습이 되어서 같은 이미지를 넣어도 prompt를 바꿔서 넣으면 내가 검출하고자 하는 디테일한 객체를 조절가능 
cup을 prompt로 넣었을 때는 이미지 안의 모든 컵을 검출하지만, 이미지 안에서 핵심이 되는 컵을 찾고자 하는 prompt로 넣었을 때는 이미지의 앞에 위치한 컵 하나만 검출하는 것을 볼 수 있다. 
멀티모달 짱짱맨 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 수강후기] 유데미 【한글자막】 OpenAI API 마스터하기: GPT-4의 무한한 창의성 끌어내기]]></title>
            <link>https://velog.io/@dust_potato/%EC%88%98%EA%B0%95%ED%9B%84%EA%B8%B0-%EC%9C%A0%EB%8D%B0%EB%AF%B8-%E3%80%90%ED%95%9C%EA%B8%80%EC%9E%90%EB%A7%89%E3%80%91-OpenAI-API-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EA%B8%B0-GPT-4%EC%9D%98-%EB%AC%B4%ED%95%9C%ED%95%9C-%EC%B0%BD%EC%9D%98%EC%84%B1-%EB%81%8C%EC%96%B4%EB%82%B4%EA%B8%B0</link>
            <guid>https://velog.io/@dust_potato/%EC%88%98%EA%B0%95%ED%9B%84%EA%B8%B0-%EC%9C%A0%EB%8D%B0%EB%AF%B8-%E3%80%90%ED%95%9C%EA%B8%80%EC%9E%90%EB%A7%89%E3%80%91-OpenAI-API-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EA%B8%B0-GPT-4%EC%9D%98-%EB%AC%B4%ED%95%9C%ED%95%9C-%EC%B0%BD%EC%9D%98%EC%84%B1-%EB%81%8C%EC%96%B4%EB%82%B4%EA%B8%B0</guid>
            <pubDate>Mon, 08 Jan 2024 02:00:16 GMT</pubDate>
            <description><![CDATA[<p>해당 글은 글또 X 유데미 협업을 통해 수강 후기 작성을 대가로 강의를 무료로 듣고 남기는 후기 글입니다! </p>
<h1 id="유데미-소개"><a href="https://www.udemy.com/">유데미</a> 소개</h1>
<p>Udemy는 개발, 디자인, 자기계발, 비즈니스, 건강 및 피트니스 등 다양한 주제에 대한 강의를 제공하는 플랫폼입니다. </p>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/b94a4585-9ac0-4d64-a122-0a0fa0e8aed7/image.png" alt=""></p>
<p>한국 강사분들만 강의를 제작하시는 건 아니고 주로 외국인 강사분들의 강의가 대다수인데 
한글 자막을 제공하는 강의도 있습니다. </p>
<p>여러 강의 중 제가 선택한 강의는 <strong><a href="https://www.udemy.com/course/mastering-openai-korean/?couponCode=UPGRADE02223">[한글자막] OpenAI API 마스터하기: GPT-4의 무한한 창의성 끌어내기</a></strong> 인데, 
chabot 형식의 chatGPT 외에 GPT api를 사용할 수 있다는 사실만 알고 
공부를 해본 경험이 없어서 한번쯤은 사용법과 동작방식을 공부할 필요를 느껴 해당 강의를 선택했습니다. </p>
<p>저희 팀의 자연어 파트에서는 GPT를 사용하여 업무를 하고 있기도 했고, 
요즘 논문을 보면 대규모 Multi Modal 모델을 사용해서 데이터를 제작하는 경우가 많아서 나도 나중에 해봐야지~ 생각했는데 마침 이미지 입력까지 지원하는 GPT4가 나왔더라구요! 
강의에서 GPT4 내용을 포함하고 있다고 해서 해당 강의를 선택하기도 했습니다. </p>
<h3 id="강의에서-제공하는-내용">강의에서 제공하는 내용</h3>
<p>전체 섹션은 18개로 구성되어 있고 각 세션의 주제는 아래와 같습니다. 
<img src="https://velog.velcdn.com/images/dust_potato/post/651f3d7c-c1ac-495b-95ae-aefce1fe6d75/image.png" alt="">
실제로 강의에서 제공하는 내용은 아래와 같습니다.<img src="https://velog.velcdn.com/images/dust_potato/post/49e59fc4-4bd3-4fdd-a323-806716dd8537/image.png" alt=""></p>
<ul>
<li>유료 사용을 위한 openAI token 생성하기</li>
<li>Transformer에 대한 아주아주 기본적인 지식</li>
<li>babbage, curie, ada, davinci, GPT-3.5-turbo, GPT4 차이, 비용, 성능</li>
<li>GPT api의 기본 매개변수와 각 역할, 사용 방법 </li>
<li>각종 프로젝트 - 색 팔레트 생성기, 코드 자동 검토기, 감정 분석 프로젝트, 스포티파이 재생 목록 생성기 등</li>
<li>추천기, 검색 시스템 빌드 : 임베딩 - 영화 추천기</li>
<li>openAI 에서 제공하는 다른 API - DALLE2, stable diffusion(경쟁사), Whisper(Audio to Text)</li>
</ul>
<h3 id="강의를-통해-얻어가고자-한-내용">강의를 통해 얻어가고자 한 내용</h3>
<p>아래는 제가 강의를 듣기 전 해당 강의를 통해 얻어가기를 기대한 내용입니다. </p>
<ul>
<li>ChatGPT 동작 원리</li>
<li>Prompt Engineering 방법</li>
<li>GPT를 활용한 문제 해결 방법 - 특히 시간이 많이 들고 쓸데없는 일을 자동화/효율화하는 것</li>
<li>GPT가 어디에 사용될 수 있는지 탐험하고 내가 겪고 있는 이슈를 해결하는데에 GPT를 접목시킬 수 있는 역량 </li>
</ul>
<hr>
<h2 id="개인적으로-느낀-강의-장단점">개인적으로 느낀 강의 장단점</h2>
<h3 id="장점">장점</h3>
<ul>
<li>openAI의 GPT API를 한번도 사용해본 적 없는 사람이 들으면 입문 하기 매우 좋은 강의</li>
<li>강사님이 평소에도 GPT API를 사용하시는 분이셔서 강의 중간중간에 저는 이렇게 사용합니다~ 식의 팁을 주셔서 좋음</li>
<li>개인적인 생각 : 강사님이 코드를 짜는 과정이 아주 빠르고 효율적인데(원하는 기능, 동작 방식에 맞게 전체적인 틀을 짜고 작은 부분을 채워나가는 방식) 그 과정을 함께 볼 수 있어서 좋음 (다 짜여진 코드를 한줄 한줄 설명하는 것이 아니라 강의에서 실시간으로 설명하면서 코드를 구현함)</li>
<li>GPT API를 사용하기 전 아주 기본적인 매개변수 역할과 사용법을 이해할 수 있음</li>
<li>특히 각종 토이 프로젝트를 통해 GPT API의 다양한 활용법을 알 수 있음</li>
</ul>
<h3 id="단점">단점</h3>
<ul>
<li>다른 강의 플랫폼에 비해 강의-번역사-관리-수강생의 파이프라인을 타다보니 강사와의 소통이 원활하지 않음</li>
<li>구체적인 질의응답을 하려면 디스코드에서 물어보라며 디스코드 가입을 권유하는데, 이 때문인지 강의 내에 다른 수강생들의 질의응답이 많지 않음 </li>
<li>GPT API 가 워낙 빠르게 업데이트 되고 있다보니 강의 시점이 불과 몇개월 전인데도 레거시로 강의하게 되는 아쉬움 </li>
<li>강사님이 참고하시는 링크를 각 강의에 달아줬으면 좋겠다 </li>
<li>강사님께서는 프로젝트를 선택 수강할 수 있다고하지만 후반의 프로젝트에서는 이전 프로젝트에서 사용한 라이브러리, 함수, 기능을 사용하기 때문에 그냥 다 듣는 걸 추천 </li>
</ul>
<h3 id="전체-후기">전체 후기</h3>
<p>해당 강의는 openAI API의 소개와 GPT API의 기본적인 사용법과 사용처에 대해 소개하는 강의입니다. </p>
<p>강의를 들으며 특히 좋았던 내용은 비용과 관련한 부분을 자세히 다뤄주신다는 것이었습니다. 
매개변수를 설명할 때도 해당 매개변수의 역할만 설명하고 끝내는게 아니라, 해당 매개변수의 변화가 비용에 어떤 영향을 가져오는지 말씀해주십니다. 
또한 tiktoken 과 같이 예상 비용을 미리 계산해볼 수 있는 기능을 소개해주셔서 실 사용을 고려하시는 분들께 도움이 많이 될 듯 합니다. </p>
<p>제가 가장 좋았던 세션은 임베딩, 임베딩으로 GPT-4 강화하기 세션인데요, 
LLM의 가장 큰 문제인 아래 두가지의 내용을 모두 다룰 수 있는 기능이었습니다.  </p>
<ol>
<li>학습에 사용한 데이터의 기간까지만 답변할 수 있다는 점 (만약 학습 데이터가 22년12월까지의 데이터라면, 23년 이후의 사건에 대해서는 알지 못하는 점)</li>
<li>Hallucination(사실이 아닌 내용을 마치 옳은 것처럼 말하는 것) </li>
</ol>
<p>아마 GPT하면 프롬프트 엔지니어링을 떠올리는 분들이 많을텐데, 
내가 원하는 결과를 얻기 위한 디테일한 프롬프트 엔지니어링 방법을 고민하시는 분들이라면 
이 강의보다는 다른 자료를 찾아보시는게 좋을 듯 합니다. </p>
<p>저는 해당 강의를 통해 강의를 듣기 전 얻어가고자 하는 내용들을 모두 얻을 수 있어서 만족스러운 강의였습니다!~ </p>
<h3 id="강의-수강을-추천드리는-분들">강의 수강을 추천드리는 분들</h3>
<p>그래서, 다음과 같은 분들께 이 강의를 추천드립니다! </p>
<ul>
<li>GPT 또는 openAI API 자체에 처음 입문하시는 분들 </li>
<li>GPT 는 chatGPT만 사용해봤고, API 사용 경험은 없으신 분들</li>
<li>GPT 라는 걸 어디에서 활용할 수 있는지 궁금한 분들</li>
</ul>
<hr>
<h2 id="유데미-사용-후기">유데미 사용 후기</h2>
<p>글또와 유데미에서 제공해주신 소중한 기회를 통해 이번에 처음으로 유데미를 사용해봤는데요. </p>
<p>유데미는 해외 강사님의 강의까지 제공해주시다보니 강의 선택의 폭이 매우 넓은 점이 좋았습니다. 
이번 수강을 계기로 유데미에 제가 찾는 내용의 강의가 있는지 많이 찾아보고 추가결제를 한 강의도 있네요! </p>
<p>꾸준한 학습을 도와주는 학습도구가 있다는 점도 좋았습니다. <img src="https://velog.velcdn.com/images/dust_potato/post/5bf51047-8780-4851-bcdf-155f5c55e469/image.png" alt="">
보시는 것처럼 저도 등록을 해놨는데요.
내가 매주 지정한 시간에 강의를 듣겠다고 캘린더에 지정을 해놓으면, 내 캘린더에 해당 일정을 가져올 수 있고 알림을 받을 수 있습니다. </p>
<p>강의를 듣다보면 게을러져 중간에 포기하거나 수강을 건너뛰는 경우가 생기는데, 이런 기능을 제공해주니 꾸준히 강의를 수강하는데에 도움이 되었습니다. </p>
<p>유데미를 사용해보지 않으신 분들은 내가 찾는 주제의 강의가 있나 탐색해보시길 추천드려요! 
&gt;&gt; <a href="https://www.udemy.com">https://www.udemy.com</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[일상] 글또 9기의 시작과 일상 주저리~]]></title>
            <link>https://velog.io/@dust_potato/%EC%9D%BC%EC%83%81-%EA%B8%80%EB%98%90-9%EA%B8%B0%EC%9D%98-%EC%8B%9C%EC%9E%91%EA%B3%BC-%EC%9D%BC%EC%83%81-%EC%A3%BC%EC%A0%80%EB%A6%AC</link>
            <guid>https://velog.io/@dust_potato/%EC%9D%BC%EC%83%81-%EA%B8%80%EB%98%90-9%EA%B8%B0%EC%9D%98-%EC%8B%9C%EC%9E%91%EA%B3%BC-%EC%9D%BC%EC%83%81-%EC%A3%BC%EC%A0%80%EB%A6%AC</guid>
            <pubDate>Sun, 10 Dec 2023 14:51:55 GMT</pubDate>
            <description><![CDATA[<p>시작했다! 글또! 
2년 전 취준생 시절 알게 된 글또..
글또를 시작한 이후로 (내 글쓰기 실력과는 별개로) 누군가의 블로그를 읽고 감탄하고,, 
개발자들끼리 모여 일상을 나누고 모각공을 하는 것이 일상 속에 깊이 자리 잡았다. </p>
<p>횟수를 따지면 1년에 몇 번 되지는 않으니 일상,,이라기보다는 내 마음에 자리 잡았다고 하는 것이 맞는 표현일듯싶다. </p>
<p>글또 8기가 끝난 후 이번 기수가 시작하기까지 약 3달 정도의 텀이 있었다. 
소속감이 없어져서 그런가 왠지 허해져서 (+광고 메시지를 받아) 다른 회고 플랫폼에서 매주 회고를 작성하기도 해봤다. </p>
<p>결론부터 말하자면 해당 플랫폼에서 얻을 수 있는 즐거움도 컸지만 글또만큼 인상 깊지는 않았다.
동질감이 없어서 그런지 새로운 사람들을 만나서 대화가 물 흐르듯 진행되지는 않았고 석 달이라는 짧은 시간 동안 사람들과 친해지기도 쉽지는 않았다. </p>
<p>&gt; 내 글을 다시 읽다가 느낀 건데, 다른 회고 모임에서 짜릿한 즐거움을 느끼지 못했던 건 해당 플랫폼의 문제라기보다는 내 문제인 것 같다. 
이번년도에 개인적으로도 힘든 일이 많고 업무도 잘 안 풀려서 좀 쳐져 있었는데 그런 나의 상황 때문에 모임을 열심히 즐기지 못했기도 하고, 지금 그때를 생각하면 즐거움보다는 힘든 감정이 먼저 생각나서 그런듯하다. 
실제로 나는 해당 회고 플랫폼을 친구에게 적극 추천하기도 했다. 
사설은 이쯤에서 생략하고...</p>
<p>**글또에서 가장 인상 깊었던 점은 두 가지 정도인데, </p>
<ol>
<li>기본 참여비가 없는 무료 커뮤니티라는 것. (성윤님께 무한한 감사..)</li>
<li>개발자들을 만나 커피챗을 하면 직무가 달라도 시간 가는 줄 모르고 N 시간 동안 대화할 수 있는 점!! **</li>
</ol>
<p>특히 두 번째 특징에 대해서,, 
나이를 먹을수록 가치관이 뚜렷해지고 인간관계에서의 맺고 끊음도 분명해지다 보니 
새로운 사람을 만나 어릴 때 친구처럼 친해지기라든가,,각자의 고민을 나누고 상대방의 고민에 대해 진심으로 공감하고 해결 방법을 함께 찾아보기는 쉽지 않은 것 같다. </p>
<p>글또는 직업이 같은 사람들이 글쓰기라는 공통의 관심사를 가지고 모여있고, 
글또에 참여하시는 분들이 커리어 욕심이 있는, 흔히 말하는 갓생사는 분들이셔서 더 대화도 잘 통하고 함께 어떤 활동을 하기도 좋은 환경인 듯하다. </p>
<p>글또를 하면서 업무 가치관과 행동력, 커리어를 만들어나가는 과정이 멋있는 분들을 많이 뵙다 보면 자극을 받아, 천성이 게으른 나를 그나마 움직이게 하는 원동력이 되기도 한다. </p>
<p>비록 지금도 마감 직전 글을 쓰고 있지만,,, 
글또가 아니었다면 주말을 통으로 유튜브를 보는 데 사용했을 게 뻔하다! 
집에만 오면 내 몸뚱이와 정신력은 오프되어 최대한 열심히 쉬려고 하는데, 
그 와중에 날 일어나게 하는 건 아마 </p>
<p>이 커뮤니티를 사업화하지 않고 이끄시는 성윤님께서
<strong>글 쓰는 것에 관심이 있는 개발자들이 글을 더 잘 쓰게 하고 글 쓰는 습관을 만드는 것을 목표로 모임을 시작했는데, 글을 못 쓰는 대가로 돈을 버는 사업구조를 만들고 싶지는 않았다</strong>고 말씀하신 게 내 마음속 어딘가에서 긍정적인 부담감과 책임감이 된 것 같다. </p>
<p>이번 기수에 참여하며 다짐한 내용은 세 가지이다. </p>
<ul>
<li>글 쓰는 시간 체크해보기 </li>
<li>자리 잡았다 공부하지 말고 가지고 있는 소재에 대해 공부를 한 후 글쓰기</li>
<li>퇴고 없이 글 올리지 않기 </li>
</ul>
<p>언제나 다짐을 모두 지키지 못한 채로 글또 활동을 마무리했지만 ... 
그래도 다짐을 지키려고 노력하는 과정이 있다. ㅋ ㅋㅋ ㅎㅎ</p>
<p>이번 기수에는 인원도 더 많아지고 강의 제공이나 소모임도 엄청나게 많아서 기대된다. 
글또 활동에 열심히 참여할 수 있게 다른 일은 최대한 안 벌려놔야지. </p>
<p>9기도 화이팅.
올해 액땜했으니까 글또 시작과 함께 내년에는 행복한 일이 많았으면 좋겠다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Paper review] DECOUPLING REPRESENTATION AND CLASSIFIER FOR LONG-TAILED RECOGNITION]]></title>
            <link>https://velog.io/@dust_potato/Paper-review-DECOUPLING-REPRESENTATION-AND-CLASSIFIER-FOR-LONG-TAILED-RECOGNITION</link>
            <guid>https://velog.io/@dust_potato/Paper-review-DECOUPLING-REPRESENTATION-AND-CLASSIFIER-FOR-LONG-TAILED-RECOGNITION</guid>
            <pubDate>Tue, 12 Sep 2023 00:09:31 GMT</pubDate>
            <description><![CDATA[<p><a href="https://arxiv.org/pdf/1910.09217.pdf">DECOUPLING REPRESENTATION AND CLASSIFIER FOR LONG-TAILED RECOGNITION, ICLR 2020</a>
<a href="https://github.com/facebookresearch/classifier-balancing">official code </a></p>
<h1 id="background">Background</h1>
<ul>
<li>long-tail distribution
<img src="https://velog.velcdn.com/images/dust_potato/post/7fc87d85-2ec1-4c9e-8f87-cfe334ab25d4/image.png" alt=""></li>
</ul>
<p>long-tail distribution 이란 위 그림과 같이 class 갯수의 분포가 극명하게 차이나는 데이터셋을 말함. 갯수가 많은 class를 head class, 적은 class를 tail class 라고 하는데, head class 의 갯수는 적고 tail class의 갯수가 많아서 분포 그래프를 그려봤을 때 긴 꼬리가 달린듯 하여 long-tail 이라고 부름.
이런 데이터의 decision boundary는 head class(dominant class)에 편향되게 학습되고, 따라서 tail class에서는 극심한 성능 저하가 일어남. </p>
<h1 id="abstract">Abstract</h1>
<ul>
<li>long-tail distribution (이하 LTD) dataset은 class imbalance 를 어떻게 해결할 것인지가 이슈였음. 본 논문에서는 representation learning과 classification을 분리하여 2 stage 로 학습하는 전략을 통해 LTD dataset에서 성능을 향상시킴</li>
<li>ImageNet-LT, Places-LT and iNaturalist와 같은 long-tailed dataset 에서 SOTA 달성</li>
</ul>
<h1 id="related-work--motivation">Related Work &amp; Motivation</h1>
<p>이전까지는 LTD dataset을 다루기 위해 loss re-weighting, data re-sampling, or transfer learning from head to tail-classes 와 같은 연구가 진행됨. </p>
<ul>
<li>Class-balanced Losses (loss re-weighting)
Focal loss와 같이 class의 분포에 따라 loss의 가중치를 조절하여 weight 학습을 다르게 하는 방법.
affinity measure을 사용하여 head class, tail class 의 분류 영역을 조절하여 각 class의 cluster 중심이 균일한 간격과 거리에 있도록 하는 방법이나<br>속한 데이터 개수가 작은 few-shot class가 더 넓은 margin을 가지게끔 하는 LDAM Loss 도 있음<img src="https://velog.velcdn.com/images/dust_potato/post/86e37791-2055-4bff-a0ec-32eedba63eaa/image.png" alt=""></li>
</ul>
<ul>
<li><p>Data distribution re-balancing (data re-sampling)
balanced data distribution을 얻기 위해 data를 re-sampling하는 방법.
갯수가 적은 class의 data를 늘리는 over sampling, 갯수가 많은 class의 data를 삭제하는 under sampling, 각 class의 갯수에 의거한 class-balanced sampling 방법이 있다. </p>
</li>
<li><p>transfer learning from head to tail-classes
데이터가 풍부한 head class에서 학습한 특징을 tail class로 전이하여 학습하는 방법.
transferring the intra-class variance(class 내 분산 전이),   transferring semantic deep features와 같은 방법이 있는데, 이런 방법은 feature transfer를 위한 복잡한 memory module을 설계해야함.
<img src="https://velog.velcdn.com/images/dust_potato/post/7da04b15-aff4-46c0-a696-4a8d17921943/image.png" alt=""></p>
</li>
</ul>
<p>위의 연구들은 모두 데이터의 representation을 추출하는 backbone 학습과 데이터의 decision boundary를 학습하는 classifier를 함께 학습함. (joint learning)
그러나 joint learning은 모델이 data representation을 잘 학습해서 성능이 잘 나오는지, 아니면 classifier가 decision boundary를 잘 조정하여 class imabalance 문제를 해결했기 때문에 성능이 잘 나오는지 확인할 수 없음. </p>
<p>따라서 저자들은 이를 확인하기 위해 joint learning을 (1)representation learning (2)classification 두 가지로 나누어 진행함. 
<strong>(1) representation learning</strong> 
다양한 sampling strategies를 사용하여 모델을 학습시킴
<strong>(2) classification</strong> 
representations 학습 이후, classifier를 통해 decision boundary를 조정함. 이때 classifier만 재훈련하는 방법, 재훈련 없이 representation을 사용하여 nearest class mean classifier로 교체하는 방법, classifier 가중치 정규화와 같은 방법을 사용함.</p>
<p>실험의 결과는 다음과 같음. </p>
<ul>
<li>decoupled learning이 LTD dataset recignition에서 좋은 성능을 보임</li>
<li>classifier 재훈련 없이 representation을 이용해 decision boundary를 조정하는 것이 LTD dataset 인식에 효과가 있다는 실험 결과</li>
<li>ResNeXt과 같은 standard network에  decoupled learning을 적용했을 때  이전 연구 (different sampling strategies, new loss designs and other complex modules)보다 LTD에서 더 좋은 성능을 보임 </li>
<li>OLTR(representation learning에서는 instance-balanced sampling을 사용하여 학습하고 이후  class-balanced sampling을 사용하여 fine tuning하는 방법), LDAM(few-shot class의 decision boundary를 확장하는 label-distribution-aware margin loss 제안)과 같이 추가적인 메모리를 필요로 하는 sampling, balanced loss 를 사용한 방법과 비교했을 때 decoupled learning은 추가적인 memory module 없이 높은 성능을 달성함</li>
</ul>
<h1 id="methods---learning-representations-for-long-tailed-recognition">Methods :  LEARNING REPRESENTATIONS FOR LONG-TAILED RECOGNITION</h1>
<ul>
<li>Notation 
논문에서 사용할 notation을 먼저 설명.<ul>
<li>$\text { Let } X=\left{x_i, y_i\right}, i \in{1, \ldots, n}$ : training set<ul>
<li>${x_i, y_i}$ : data point, label</li>
</ul>
</li>
<li>${N_j}$ : class ${j}$에 해당하는 sample 갯수<ul>
<li>$n=\sum_{j=1}^C n_j$ : traing sample의 총 갯수 ($C$ : class의 총 갯수)</li>
<li>class index : 각 class에 속하는 sample의 개수가 많은 순서대로 정렬</li>
<li>long-tail setting에 의해 $n_1 \gg n_C$</li>
</ul>
</li>
<li>$f(x ; \theta)= z$ : x의 representation</li>
<li>$\tilde{y}$ : classifier $g$가 예측한 값</li>
<li>$g(z)=\boldsymbol{W}^{\top} z+\boldsymbol{b}$ : a linear classifier</li>
</ul>
</li>
</ul>
<ul>
<li><p>Sampling strategies
네가지의 sampling strategies를 사용함.
$$
p_j=\frac{n_j^q}{\sum_{i=1}^C n_i^q}
$$
$p_j$ : class j에 속하는 sample이 뽑힐 확률
$q$ : 0과 1사이의 값으로, sampling stratgy를 조절하는 인자 </p>
<ul>
<li><p>Instance-balanced sampling</p>
<ul>
<li>q=1</li>
<li>training set 의 모든 sample이 뽑힐 확률이 같음. </li>
<li>class j에 속하는 sample이 뽑힐 확률은 class의 cardinality $n_j$와 같음  </li>
</ul>
</li>
<li><p>Class-balanced sampling</p>
<ul>
<li>q=0.</li>
<li>모든 class는 뽑힌 확률이 모두 같음 ($p_j = \frac{1}{C}$)</li>
<li>2 stage sampling strategy라고도 볼 수 있는데, 우선 class가 uniform하게 선택되고, class에 속하는 instance를 uniform하게 선택함</li>
</ul>
</li>
<li><p>Square-root sampling</p>
<ul>
<li>앞의 두가지 방법의 혼합</li>
<li>q=1/2</li>
</ul>
</li>
<li><p>Progressively-balanced sampling</p>
<ul>
<li>위의 모든 방법을 조합함</li>
<li>처음 학습 할 때는 instance-balanced sampling을 사용하고 학습이 진행됨에 따라  class-balanced sampling을 사용하는 방법</li>
<li>$p_j^{\mathrm{PB}}(t)=\left(1-\frac{t}{T}\right) p_j^{\mathrm{IB}}+\frac{t}{T} p_j^{\mathrm{CB}}$.  </li>
<li>${t}$ : current epoch, ${T}$ : total epoch
<img src="https://velog.velcdn.com/images/dust_potato/post/b589d5a7-e1e5-4ace-a00e-b6c7c767743e/image.png" alt=""></li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li>Loss re-weighting strategies
imbalanced data를 위한 Loss re-weighting functions은 많은 연구가 되어 왔지만 훈련 및 재현이 어렵고, dataset-specific한 하이퍼 파라미터 튜닝이 필요하기 때문에 모든 loss를 테스트하진 못했고 몇가지를 테스트한 결과를 첨부함</li>
</ul>
<p>또한 properly balanced classifier가 latest loss re-weighting approaches보다 좋지는 앉지만 동등한 성능을 낸다는 것을 실험으로 보임 </p>
<h1 id="methods--classification-for-long-tailed-recognition">Methods : CLASSIFICATION FOR LONG-TAILED RECOGNITION</h1>
<p>Representation learning에서 사용된 classifier은 $W,b$로 구성된 linear classifier : $g(z)=\boldsymbol{W}^{\top} z+\boldsymbol{b}$
(다른 classifier도 실험함)
이 섹션에서는 다른 sampling strategy를 사용하여 fine tuning을 통해 classifier의 decision boundary를 조정하거나  non-parametric nearest class mean classifiers를 사용하는 방법, 추가적인 학습 없이 classifier weights 을 재조정하는 네가지 방법을 소개함. 그리고 이들은 classifier을 재조정하지 않은 Joint learning scheme과 비교됨.</p>
<ul>
<li><p>Classifier Re-training (cRT)</p>
<ul>
<li>class-balanced sampling을 사용하여 classifier를 재학습하는 방법.</li>
<li>representations는 고정하고 randomly re-initialize된 linear classifier를 적은 epoch 학습함</li>
</ul>
</li>
<li><p>Nearest Class Mean classifier (NCM)</p>
<ul>
<li>training set의 feature representation의 mean을 계산하여 cosine similarity(또는 Euclidean distance)  on L2 normalized mean features 를 사용하여 nearest neighbor search 를 수행</li>
<li>cosine similarity는 정규화를 통해 weight imbalance problem을 완화함</li>
</ul>
</li>
<li><p>τ -normalized classifier (τ -normalized)</p>
<ul>
<li>Instance-balanced sampling을 이용한 joint learning (representation learning+classifier learning) 이후, classifier의 각 weight의 norm $\rVert{w_j}\rVert$가 class에 속하는 sample의 수 $n_j$와 연관성이 있음을 발견.</li>
<li>class-balanced sampling을 이용한 classifier fine tuning 이후, classifier weights의 norm이 더욱 비슷해짐을 발견<br><img src="https://velog.velcdn.com/images/dust_potato/post/5ef1953e-8ed1-4e84-a082-d0d44dad91d7/image.png" alt=""></li>
<li>따라서, classifier re-training을 거치지 않고, 단순히 이 norm 값들만 재조정해준다면 비슷한 효과가 있지 않을까? 라는 생각으로 class imbalance를 완화하고자 함. 
$$
\widetilde{w_i}=\frac{w_i}{\left|w_i\right|^\tau}
$$<blockquote>
<p>$w_j$ : class j에 상응하는 classifier weights
$\widetilde{w_j}$ : 조정한 weights
$\tau$ : hyper-parameter controlling the “temperature” of the normalization, 0이면 no scaling, 1이면 일반 L2 norm 
$\left|\cdot \right|$ : L2 norm
논문에서는 validation set을 통해 $\tau$를 탐색함</p>
</blockquote>
</li>
</ul>
</li>
</ul>
<ul>
<li>Learnable weight scaling (LWS)<ul>
<li>τ -normalization의 일종으로, 각 class에 해당하는 weight의 magnitude를 조정하는 방법
$$
\widetilde{w_i}=f_i * w_i, \text{where} f_i = \frac{1}{\left|w_i\right|^\tau}
$$</li>
<li>representation과 classifier를 모두 고정하고 class-balanced sampling을 통해  scaling factor $f_i$ 만 학습함.</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/29f5b880-9127-403f-9a6d-dbcc71ba567b/image.png" alt=""> </p>
<blockquote>
<p>Table 6 :classifier 비교 표 </p>
</blockquote>
<h1 id="experiments">Experiments</h1>
<ul>
<li><p>setup</p>
<ul>
<li>Datasets
  large-scale long-tailed datasets : Places-LT, ImageNet-LT,  iNaturalist 2018 사용</li>
<li>Evaluation Protocol
  top-1 accuracy를 사용했으며, 모든 class (All), 100장 이상 image를 포함한 class (Many-shot), 20~100장의 image를 포함한 class (Medium-shot), 20장 이하의 image를 포함한 class (Few-shot)로 분류하여 결과를 report</li>
<li>Implementation
PyTorch를 이용했으며, ResNet, ResNext 등을 backbone으로 사용. Representation learning stage에서는 90 epoch, cRT나 LWS 등 classifier의 학습이 필요한 경우에는 10 epoch동안 훈련시킴</li>
</ul>
</li>
<li><p>SAMPLING STRATEGIES AND DECOUPLED LEARNING
<img src="https://velog.velcdn.com/images/dust_potato/post/669805ff-5147-4ce1-ba6f-7d8d712911b4/image.png" alt="">
Method에서 소개한 네가지의 sampling stratgy와 네가지 classifier 대체 전략을 사용한 실험 결과. 분석 결과는 다음과 같다.</p>
<ul>
<li><strong>Sampling matters when training jointly</strong>
<img src="https://velog.velcdn.com/images/dust_potato/post/5dc44a0b-adfb-482b-b9bd-24af7d0d5acc/image.png" alt="">
joint training에서는 medium- and fewshot classes 에서 progressively-balanced sampling이 좋은 성능을 내는 반면 many-shot classes에서는  instancebalanced sampling이 좋은 성능을 냄.
즉 더 나은 sampling staragy를 쓸수록 성능이 향상되었으며 지금까지의 연구방향과 일치함</li>
<li><strong>Joint or decoupled learning?</strong>
many-shot case를 제외하고 Decoupled method를 사용하는 것이 항상 더 좋은 결과를 보임
decoupled learning의 효과를 증명하기 위해 backbone 과 linear classifier의 범위를 바꾸어가며 실험해본 결과 only retraining the linear classifier
and fixing the representation 일 때 가장 좋은 성능을 보임<br><img src="https://velog.velcdn.com/images/dust_potato/post/6b89b5f1-d20d-4df8-8e8e-b6536ad35101/image.png" alt=""></li>
<li><strong>Instance-balanced sampling gives the most generalizable representations</strong>
모든 decoupled methods중에서, 의외로 instance balanced sampling 을 사용했을 때 성능이 잘 나옴. 이는 &quot;high-quality representations를 학습하는 데에 class imbalance가 큰 영향을 미치지 않을 수 있다&quot;는 것을 의미함.</li>
</ul>
</li>
</ul>
<ul>
<li><p>HOW TO BALANCE YOUR CLASSIFIER?
<img src="https://velog.velcdn.com/images/dust_potato/post/669805ff-5147-4ce1-ba6f-7d8d712911b4/image.png" alt="">Fig1 을 다시 보면, Training 과정이나, data imbalance 해소를 위한 추가적인 sampling strategy의 사용을 필요로 하지 않는 NCM과  τ-norm이 cRT와 비슷하거나 더 높은 성능을 보임 (many shot case에서만 큰 성능하락이 있음)
이러한 성능 향상은 decision boundary를 재조정하면서 얻은 이익일 것으로 예상함
<img src="https://velog.velcdn.com/images/dust_potato/post/1712e843-1fdd-4b33-98ef-efc0fb20a8d7/image.png" alt="">
위의 그래프를 보면 joint classifier의 weight class 분포에 상응함을 볼 수 있는데, 이는 class 갯수가 많을 수록 classifier가 larger magnitude를 가짐을 의미함.
이는  feature space에서 wider decision boudary를 형성하여 데이터가 많은 class에서는 좋은 성능을, 적은 class에서는 낮은 성능을 냄 (아래 Fig4 참고)</p>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/8c7ca75b-d539-4e2e-a7ac-6610a519c46c/image.png" alt=""></p>
<blockquote>
<p>Fig 4: classifier가 decision boundary에 미치는 영향.
$w_i, w_j$ : class i,j의 weights
$C_i$ : feature space에서 class i에 속하는 classfication cone(?)
$m_i$ : class i의 feature mean
(1) τ 가 0일때 τ -normalized classifier : 큰 weight을 가질수록 decision boundary도 넓게 형성
(2) τ 가 1일때 τ -normalized classifier : 서로 다른 class에 대한 decision boundary가 조금 더 balanced 하게 형성
(3) NCM with cosine-similarity : decision boundary가 class weight와 independent하게 형성됨
(4) NCM with Euclidean-similarity : decision boundary가 feature space를Voronoi cells로 분할함</p>
</blockquote>
<p>따라서 τ -normalized classifiers에서 τ 가 커질수록, many-shot accuracy가 급격히 감소했으며 few-shot accuracy가 급격히 증가함
<img src="https://velog.velcdn.com/images/dust_potato/post/ec904cc2-5014-45b8-be65-80a7777d7f7f/image.png" alt=""></p>
</li>
<li><p>COMPARISON WITH THE STATE-OF-THE-ART ON LONG-TAILED DATASETS
<img src="https://velog.velcdn.com/images/dust_potato/post/d817e270-d5a8-4baf-96e5-9121ab8bbef3/image.png" alt="">
<img src="https://velog.velcdn.com/images/dust_potato/post/9a3249c1-90bb-4feb-a76d-419f2a6e1d6f/image.png" alt=""></p>
</li>
</ul>
<h1 id="conclusions">Conclusions</h1>
<ul>
<li>long-tailed recognition에서 representation and classifier를 분리하는 decoupled methods 제안</li>
<li>Representation과 classifier의 joint learning과, 다양한 decoupled method를 비교함</li>
<li>Joint learning의 경우 sampling strategy가 유의미한 영향을 끼쳤으나, 무작위 추출인 instance-balanced sampling이 가장 generalizable representation을 학습할 수 있었으며 복잡한 loss나, memory unit 등 없이도 classifier weight의 re-balancing 이후에 SOTA 성능을 보임</li>
</ul>
<h3 id="ref">Ref</h3>
<p><a href="https://arxiv.org/pdf/2110.04596.pdf">Deep Long-Tailed Learning: A Survey</a>
<a href="https://bo-10000.tistory.com/109">복만님 paper review : [딥러닝 논문리뷰] Decoupling Representation and Classifier for Long...</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ONNX란? (1) - 기본 설명과 원리, 한계점, PyTorch to ONNX 예시]]></title>
            <link>https://velog.io/@dust_potato/ONNX%EB%9E%80-1-%EA%B8%B0%EB%B3%B8-%EC%84%A4%EB%AA%85%EA%B3%BC-%EC%9B%90%EB%A6%AC</link>
            <guid>https://velog.io/@dust_potato/ONNX%EB%9E%80-1-%EA%B8%B0%EB%B3%B8-%EC%84%A4%EB%AA%85%EA%B3%BC-%EC%9B%90%EB%A6%AC</guid>
            <pubDate>Mon, 19 Jun 2023 10:21:13 GMT</pubDate>
            <description><![CDATA[<p><strong>Ref</strong>
<a href="https://github.com/onnx/onnx/tree/main">ONNX github</a>
<a href="https://onnx.ai/about.html">ONNX homepage</a>
<a href="https://onnx.ai/onnx/intro/index.html">ONNX 1.15.0 documentation</a>
<a href="https://pytorch.org/docs/master/onnx.html">PyTorch Docs - torch.onnx
</a>
<a href="https://www.yes24.com/Product/Goods/106549364?gclid=CjwKCAjw-b-kBhB-EiwA4fvKrIcwV6s2MyvPJyYZVuoibZF-86rrwcMR1YGCByRtlQ5-mJRngqjPihoCX2gQAvD_BwE">도서:실전 파이토치 딥러닝 프로젝트</a>
<a href="https://yunmorning.tistory.com/17">블로그:PyTorch 모델 ONNX로 export 하기 </a></p>
<h3 id="onnx란"><a href="https://onnx.ai/about.html">ONNX</a>란?</h3>
<p>Open Neural Network Exchange의 약자로 ML model을 표현하기 위한 open standard format이다. 즉 Tensorflow, Pytorch와 같이 다른 framework에서 개발된 모델을 서로 호환되게 사용할 수 있게끔 만들어진 ecosystem이다. ONNX는 특히 inferencing 에 필요한 기능에 집중한다.</p>
<ul>
<li>ONNX의 장점 </li>
</ul>
<ol>
<li><p>Framework Interoperability
ONNX의 설명에도 나와있듯이 특정 환경에서 생성된 모델을 다른 환경으로 import하여 자유롭게 사용을 할 수 있다.</p>
</li>
<li><p>Shared Optimization
HW vendor(가속기와 같은 HW 제조업체)의 입장에서 ONNX와 같은 프레임워크 간 공유되는 포맷이 존재하면, 하드웨어 설계시 ONNX representation을 기준으로 최적화를 하면 되기 때문에 효율적이다.</p>
</li>
</ol>
<p>neural network는 dataflow graphs를 통해 계산을 수행한다. 
일부 프레임워크(예: CNTK, Caffe2, Theano 및 TensorFlow)는 정적 그래프(static graphs)를 사용하는 반면 다른 프레임워크(예: PyTorch 및 Chainer)는 동적 그래프(dynamic graphs)를 사용한다. 
그러나 이들은 모두 개발자가 최적화된 방식으로 그래프를 처리하는 실행 시간과 계산 그래프를 쉽게 구성할 수 있는 인터페이스를 제공한다. 그래프는 개발자의 소스 코드의 특정 의도를 포착하는 Intermediate Representation(=IR, 중간 표현) 역할을 하며, 특정 장치(CPU, GPU, FPGA 등)에서 실행되는 최적화 및 번역에 도움이 된다.</p>
<p>이 중 어떤 프레임워크를 선택하느냐는 빠른 학습시간, 복잡한 네트워크 아키텍쳐 지원, 모바일 장치에서의 추론 등 어떤 요구사항을 가지고 있느냐에 따른 선택이다. 
하지만 모든 상황에서 단 하나의 프레임워크를 사용할 수 없기 때문에 프레임워크 전환에 따른 오버헤드가 있다. 
ONNX(Open Neural Network Exchange) 형식은 이 강력한 생태계를 구축하는 데 도움이 되는 공통 IR이다.</p>
<h3 id="open-neural-network-exchange-intermediate-representation-onnx-ir">Open Neural Network Exchange Intermediate Representation (ONNX IR)</h3>
<p>어떻게 다른 framework에서 개발된 모델들을 통합할 수 있을까? </p>
<p>ONNX는 계산 그래프의 공통 표현을 제공하여 프레임워크마다 다르게 만들어지는 computation graph를 통합한다. 이를 Open Neural Network Exchange Intermediate Representation (ONNX IR)이라고 한다. 
<a href="https://github.com/onnx/onnx/blob/main/docs/IR.md">ONNX IR의 큰 구성요소</a>는 아래와 같다. </p>
<ol>
<li>A definition of an extensible computation graph model.</li>
<li>Definitions of standard data types.</li>
<li>Definitions of built-in operators.</li>
</ol>
<p>1과 2가 함께 ONNX IR을 구성한다. 
built-in operators는 set of primitive operators와 functions으로 나누어진다.
functions은 다른 연산자 및 함수를 사용하여 sub graph로 만들어진 연산자를 의미한다.</p>
<p>각 computation data flow graph 는 비순환 그래프를 형성하는 노드 목록으로 구조화된다. 노드에는 하나 이상의 입력과 하나 이상의 출력이 있다. 각 노드는 연산자에 대한 호출이다. 그래프에는 목적, 작성자 등을 문서화하는 데 도움이 되는 메타데이터도 있다. 연산자는 그래프 외부에서 구현되지만, 내장된 연산자 세트는 프레임워크 간에 이식할 수 있다. ONNX를 지원하는 모든 프레임워크는 해당 데이터 유형에 대한 이러한 연산자 구현을 제공한다.</p>
<h3 id="pytorch-모델-onnx로-export-하기">PyTorch 모델 ONNX로 export 하기</h3>
<p>PyTorch 모델을 ONNX 그래프로 export 하는 과정을 도식화한 그림이다.
<img src="https://velog.velcdn.com/images/dust_potato/post/45634d58-d087-4a97-856a-59bf6a748092/image.png" alt=""></p>
<ol>
<li>PyTorch 모델과 example input을 인자로 하여 torch.onnx.export 함수를 호출하면, PyTorch의 JIT 컴파일러인 TorchScript를 통해서 trace 혹은 script를 생성한다. Trace나 script는 PyTorch의 nn.Module을 상속하는 모델의 forward 함수에서 실행되는 코드들에 대한 IR (Intermediate Representation)을 담고 있다. 쉽게 설명하면 forward propagation 시에 호출되는 함수 및 연산들에 대한 최적화된 그래프가 만들어진다.</li>
<li>생성된 trace / script (PyTorch IR)는 ONNX exporter를 통해서 ONNX IR로 변환되고 여기에서 한 번 더 graph optimization이 이루어진다.</li>
<li>최종적으로 생성된 ONNX 그래프는 .onnx 포맷으로 저장된다.</li>
</ol>
<blockquote>
<p>TorchScript란?
PyTorch의 just-in-time 컴파일러.
pyTorch는 수학연산을 바로 실행하는 eager-mode로 동작하기 때문에, 중간결과를 메모리에 쓰고 읽으면서 하나씩 실행하면 추론하는데까지 대기시간이 걸린다. 이 문제를 해결하기 위해 PyTorch의 JIT Compiler인 TorchScript를 사용한다. 
TorchScript는 모델을 컴파일하여 전체 모델에 대해 하나의 정적 그래프를 만든다. 
TorchScript를 사용하면 python의 GIL을 제거하여 멀티스레드를 사용할 수 있게 하는 등의 최적화를 하고 C++과 같은 포맷으로 직렬화할 수 있다. </p>
</blockquote>
<ul>
<li>Example: AlexNet from PyTorch to ONNX
AlexNet을 alexnet.onnx로 변환하는 예시이다. 먼저 torch.onnx.export를 통해 model을 trace하고, traced model을 다시 export하는 과정이다. <pre><code class="language-python">import torch
import torchvision
</code></pre>
</li>
</ul>
<p>dummy_input = torch.randn(10, 3, 224, 224, device=&quot;cuda&quot;)
model = torchvision.models.alexnet(pretrained=True).cuda()</p>
<h1 id="providing-input-and-output-names-sets-the-display-names-for-values">Providing input and output names sets the display names for values</h1>
<h1 id="within-the-models-graph-setting-these-does-not-change-the-semantics">within the model&#39;s graph. Setting these does not change the semantics</h1>
<h1 id="of-the-graph-it-is-only-for-readability">of the graph; it is only for readability.</h1>
<p>#</p>
<h1 id="the-inputs-to-the-network-consist-of-the-flat-list-of-inputs-ie">The inputs to the network consist of the flat list of inputs (i.e.</h1>
<h1 id="the-values-you-would-pass-to-the-forward-method-followed-by-the">the values you would pass to the forward() method) followed by the</h1>
<h1 id="flat-list-of-parameters-you-can-partially-specify-names-ie-provide">flat list of parameters. You can partially specify names, i.e. provide</h1>
<h1 id="a-list-here-shorter-than-the-number-of-inputs-to-the-model-and-we-will">a list here shorter than the number of inputs to the model, and we will</h1>
<h1 id="only-set-that-subset-of-names-starting-from-the-beginning">only set that subset of names, starting from the beginning.</h1>
<p>input_names = [ &quot;actual_input_1&quot; ] + [ &quot;learned_%d&quot; % i for i in range(16) ]
output_names = [ &quot;output1&quot; ]</p>
<p>torch.onnx.export(model, dummy_input, &quot;alexnet.onnx&quot;, verbose=True, input_names=input_names, output_names=output_names)</p>
<pre><code>alexnet.onnx 파일을 binary protocol buffer를 포함하는데, protocol buffer는 네트워크의 구조와 모델의 파라미터 정보를 담고 있다. 
export 시 verbose=True로 두면 human-readable한 모델의 정보를 출력할 수 있다. 

```python
# These are the inputs and parameters to the network, which have taken on
# the names we specified earlier.
graph(%actual_input_1 : Float(10, 3, 224, 224)
      %learned_0 : Float(64, 3, 11, 11)
      %learned_1 : Float(64)
      %learned_2 : Float(192, 64, 5, 5)
      %learned_3 : Float(192)
      # ---- omitted for brevity ----
      %learned_14 : Float(1000, 4096)
      %learned_15 : Float(1000)) {
  # Every statement consists of some output tensors (and their types),
  # the operator to be run (with its attributes, e.g., kernels, strides,
  # etc.), its input tensors (%actual_input_1, %learned_0, %learned_1)
  %17 : Float(10, 64, 55, 55) = onnx::Conv[dilations=[1, 1], group=1, kernel_shape=[11, 11], pads=[2, 2, 2, 2], strides=[4, 4]](%actual_input_1, %learned_0, %learned_1), scope: AlexNet/Sequential[features]/Conv2d[0]
  %18 : Float(10, 64, 55, 55) = onnx::Relu(%17), scope: AlexNet/Sequential[features]/ReLU[1]
  %19 : Float(10, 64, 27, 27) = onnx::MaxPool[kernel_shape=[3, 3], pads=[0, 0, 0, 0], strides=[2, 2]](%18), scope: AlexNet/Sequential[features]/MaxPool2d[2]
  # ---- omitted for brevity ----
  %29 : Float(10, 256, 6, 6) = onnx::MaxPool[kernel_shape=[3, 3], pads=[0, 0, 0, 0], strides=[2, 2]](%28), scope: AlexNet/Sequential[features]/MaxPool2d[12]
  # Dynamic means that the shape is not known. This may be because of a
  # limitation of our implementation (which we would like to fix in a
  # future release) or shapes which are truly dynamic.
  %30 : Dynamic = onnx::Shape(%29), scope: AlexNet
  %31 : Dynamic = onnx::Slice[axes=[0], ends=[1], starts=[0]](%30), scope: AlexNet
  %32 : Long() = onnx::Squeeze[axes=[0]](%31), scope: AlexNet
  %33 : Long() = onnx::Constant[value={9216}](), scope: AlexNet
  # ---- omitted for brevity ----
  %output1 : Float(10, 1000) = onnx::Gemm[alpha=1, beta=1, broadcast=1, transB=1](%45, %learned_14, %learned_15), scope: AlexNet/Sequential[classifier]/Linear[6]
  return (%output1);
}</code></pre><p>모델이 성공적으로 변환이 되었으면, onnx 라이브러리를 설치하고 아래와 같이 실행할 수 있다.</p>
<pre><code class="language-python">import onnx

# Load the ONNX model
model = onnx.load(&quot;alexnet.onnx&quot;)

# Check that the model is well formed
onnx.checker.check_model(model)

# Print a human readable representation of the graph
print(onnx.helper.printable_graph(model.graph))</code></pre>
<p>이렇게 exported model은 ONNX Runtime(multiple platform, hardware에서 high performance를 내도록 하는 inference engine)을 통해 onnx뿐 아니라 onnx가 지원하는 많은 runtime애서도 실행이 가능하다. 
<img src="https://velog.velcdn.com/images/dust_potato/post/5da51c05-931f-4e5a-a909-46217c0fee93/image.png" alt=""><img src="https://velog.velcdn.com/images/dust_potato/post/fce3f124-fc73-4acc-b95c-ca39e92f6a1b/image.png" alt=""></p>
<h3 id="tracing-vs-scripting">Tracing vs Scripting</h3>
<p>torch.onnx.export()는 torch.nn.Module이 아닌 torch.jit.ScriptModule 형식의 model이 필요하다. 따라서 위에서 언급한 PyTorch 자체 JIT 컴파일러인 TorchScript로 1차 변환을 해야하는데, 이때 컴파일 방법이 Tracing mode, Scripting mode 두가지이다. 
만약 모델이 ScriptModule이 아니라면, export()는 기본적으로 tracning을 사용한다. </p>
<p>Tracing : torch.onnx.export()를 호출하면 torch.jit.trace()를 통해 주어진 args로 모델이 동작하는 과정을 기록한다. 주어진 input에 따라 동작하는 operations를 기록하기 때문에, 만약 input이 달라지거나 모델 안에 if와 같은 dynamic behavior가 존재하면 Trace는 dynamic flow를 export할 수 없다.</p>
<p>Scripting : Script는  dynamic control flow를 보존하고 input size가 달라져도 되도록 torch.jit.script()를 통해 model을 compile하여 ScriptModule을 만든다. 
Script를 사용해도 export를 할 때 args가 필요하지만, 이는 example output을 만들기위해서만 사용된다. </p>
<table>
<thead>
<tr>
<th align="center">Trace</th>
<th align="center">Script</th>
</tr>
</thead>
<tbody><tr>
<td align="center">더미 입력 필요</td>
<td align="center">더미 입력 필요 없음</td>
</tr>
<tr>
<td align="center">더미 입력을 모델에 전달해 정해진 일련의 수학 연산을 기록함</td>
<td align="center">파이토치 코드 내부의 nn.Module 콘텐츠를 조사해 토치스트립트 코드/그래프를 생성함</td>
</tr>
<tr>
<td align="center">모델 순전파 내에 여러 제어 흐름(if-else)를 처리할 수 없음</td>
<td align="center">모든 종류의 제어흐름을 처리하는 데 유용함</td>
</tr>
<tr>
<td align="center">모델이 <a href="https://pytorch.org/docs/stable/jit_unsupported.html">토치스크립트에서 지원하지 않는 파이토치 기능</a>을 포함하고 있어도 작동함</td>
<td align="center">모델이 <a href="https://pytorch.org/docs/stable/jit_unsupported.html">토치스크립트에서 지원하지 않는 파이토치 기능</a>을 포함하지 않을 때만 작동할 수 있음</td>
</tr>
</tbody></table>
<h3 id="avoiding-pitfalls">Avoiding Pitfalls</h3>
<ul>
<li>Avoid NumPy and built-in Python types
Torch.Tensor가 아니라 Numpy와 Python type을 사용하면, tracing 시에 상수로 변환된다. 이는 의도한 것과 다른 결과를 만들게 된다. 
따라서 numpy 보다는 torch에서 제공하는 함수를 사용하고, 모델 내에 Tensor를 python built-in number로 변경하는 torch.Tensor.item()과 같은 함수는 사용하지 않는 것이 좋다. <pre><code class="language-python"># Bad! Will be replaced with constants during tracing.
x, y = np.random.rand(1, 2), np.random.rand(1, 2)
np.concatenate((x, y), axis=1)
</code></pre>
</li>
</ul>
<h1 id="good-tensor-operations-will-be-captured-during-tracing">Good! Tensor operations will be captured during tracing.</h1>
<p>x, y = torch.randn(1, 2), torch.randn(1, 2)
torch.cat((x, y), dim=1)</p>
<h1 id="bad-yitem-will-be-replaced-with-a-constant-during-tracing">Bad! y.item() will be replaced with a constant during tracing.</h1>
<p>def forward(self, x, y):
    return x.reshape(y.item(), -1)</p>
<h1 id="good-y-will-be-preserved-as-a-variable-during-tracing">Good! y will be preserved as a variable during tracing.</h1>
<p>def forward(self, x, y):
    return x.reshape(y, -1)</p>
<pre><code>- Avoid Tensor.data
Tensor.data는 부정확한 ONNX graph를 만들 수 있기 때문에 torch.Tensor.detach()를 사용해야 한다. 

- Avoid in-place operations when using tensor.shape in tracing mode
tracing mode에서는 tensor의 shape 또한 tensor로 trace 되며, 같은 메모리를 share 한다. 이는 최종 output이 기대했던 것과 다르게 만들어질 수 있기 때문에 operation을 다시 작성해야한다.
```python
class Model(torch.nn.Module):
  def forward(self, states):
      batch_size, seq_length = states.shape[:2]
      real_seq_length = seq_length
      real_seq_length += 2
      return real_seq_length + seq_length</code></pre><p>위와 같은 모델은 tracing mode에서 real_seq_length와 seq_length가 같은 메모리를 공유하기 때문에 값이 rewrite된다. 따라서 아래와 같이 처리를 해주어야 한다. </p>
<pre><code class="language-python">real_seq_length = real_seq_length + 2</code></pre>
<h3 id="limitations">Limitations</h3>
<ul>
<li><p>Types
Torch.Tensor만을 지원한다. numeric types, tuples, lists Tensor만이 모델의 input과 output이 될 수 있다. </p>
<ul>
<li><p>tracing
Dict나 str이 input으로 사용되면 tracing 시에 constant value로 해석된다.
dict로 반환된 output은 key는 제거되고 flattened sequence of its values만 남는다. 
str으로 반환된 모든 output은 제거된다.</p>
</li>
<li><p>scripting
tuples이나 lists를 포함하는 특정 operation들은 ONNX의 nested sequences 에 대한 제한적인 지원으로 인해 scripting mode에서 동작하지 않는다. tracing mode에서는 nested sequences는 자동으로 flatten된다.</p>
</li>
</ul>
</li>
<li><p>Differences in Operator Implementations
operator의 서로 다른 구현으로 인해 다른 runtime에서 동작하는 exported model은 다른 결과를 도출한다. 이 차이는 수치적으로 매우 작긴하지만, 작은 차이도 중요한 상황에서는 문제가 될 수 있다.</p>
</li>
<li><p>Unsupported Tensor Indexing Patterns
Export할 수 없는 Tensor indexing pattern이 있다. 아래와 같은 패턴이 포함된 모델을 export할 때 문제가 있다면 최신 opset_version을 사용하고 있는지 다시 체크해야한다. </p>
<ul>
<li>Reads / Gets
Tensor를 읽을 때 아래와 같이 음수를 포함하는 패턴은 지원되지 않는다<pre><code class="language-python"># Tensor indices that includes negative values.
data[torch.tensor([[1, 2], [2, -3]]), torch.tensor([-2, 3])]
# Workarounds: use positive index values.</code></pre>
</li>
</ul>
</li>
</ul>
<ul>
<li><p>Writes / Sets
Tensor를 쓸 때 아래와 같이 2차원 이상의 Multiple tensor, not consecutive한 Multiple tensor, 음수 포함, Implicit broadcasting을 포함하는 패턴은 지원하지 않는다.</p>
<pre><code class="language-python"># Multiple tensor indices if any has rank &gt;= 2
data[torch.tensor([[1, 2], [2, 3]]), torch.tensor([2, 3])] = new_data
# Workarounds: use single tensor index with rank &gt;= 2,
#              or multiple consecutive tensor indices with rank == 1.
# Multiple tensor indices that are not consecutive
data[torch.tensor([2, 3]), :, torch.tensor([1, 2])] = new_data
# Workarounds: transpose `data` such that tensor indices are     consecutive.

# Tensor indices that includes negative values.
data[torch.tensor([1, -2]), torch.tensor([-2, 3])] = new_data
# Workarounds: use positive index values.

# Implicit broadcasting required for new_data.
data[torch.tensor([[0, 2], [1, 1]]), 1:3] = new_data
# Workarounds: expand new_data explicitly.
# Example:
#   data shape: [3, 4, 5]
#   new_data shape: [5]
#   expected new_data shape after broadcasting: [2, 2, 2, 5]</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[YOLOv6, YOLOv6 - v3.0 리뷰]]></title>
            <link>https://velog.io/@dust_potato/YOLOv6-YOLOv6-v3.0-%EB%A6%AC%EB%B7%B0</link>
            <guid>https://velog.io/@dust_potato/YOLOv6-YOLOv6-v3.0-%EB%A6%AC%EB%B7%B0</guid>
            <pubDate>Sun, 07 May 2023 14:22:50 GMT</pubDate>
            <description><![CDATA[<p><strong>Ref</strong>
<a href="https://arxiv.org/pdf/2304.00501v1.pdf">Yolo survey Paper</a>
<a href="https://leedakyeong.tistory.com/entry/Object-Detection-YOLO-v1v6-%EB%B9%84%EA%B5%902">Object-Detection-YOLO-v1v6</a>
<a href="https://learnopencv.com/yolov6-object-detection/">yolov6-object-detection</a>
<a href="https://gaussian37.github.io/dl-concept-quantization/#post-training-quantization%EA%B3%BC-quantization-aware-training-%EB%B9%84%EA%B5%90-1">딥러닝의 Quantization (양자화)와 Quantization Aware Training</a>
<a href="https://silhyeonha-git.tistory.com/3">IoU 종류</a>
각종 Reference 논문 본문에 링크함</p>
<p>이 글은 object detection 에 대한 기본적인 이해가 있으신 분들을 위한(?) 글입니다. </p>
<ul>
<li>Yolo 1~4 까지의 내용을 접해보신 분</li>
<li>1stage detector와 2stage detector의 차이를 알고 계시는 분</li>
<li>Anchor Based와 Anchor Free detector의 차이를 알고 계시는 분</li>
</ul>
<p>전체적인 요약과 내용은 <a href="https://arxiv.org/pdf/2304.00501v1.pdf">Yolo survey Paper</a>를 참고했으며, 자세한 내용은 각 논문을 직접 읽어본 내용입니다. </p>
<h1 id="yolov6-yolov6-v30의-main-changes">YOLOv6, YOLOv6-v3.0의 Main Changes</h1>
<h2 id="yolo-v6">YOLO v6</h2>
<p>2022, <a href="https://arxiv.org/abs/2209.02976">https://arxiv.org/abs/2209.02976</a>
2022년 9월, Meituan Vision AI Department 에서 논문을 공개했다.
v4,v5와 비슷하게 다양한 크기의 모델을 공개했으며,
당시 트렌드인 anchor point base 방법론을 따라 Anchor를 사용하지 않는 Anchor-Free 모델이다.</p>
<h3 id="main-changes">Main Changes</h3>
<ul>
<li><p><strong>A new backbone based on RepVGG</strong></p>
<ul>
<li>Backbone : 이전 yolo backbone보다 higher parallelism을 자랑하는 EfficientRep 사용 </li>
<li>Neck : RepBlocks으로 강화된 PAN 사용 (더 큰 모델의 경우 CSPStackRep 블록을 사용)</li>
<li>Head : Efficient Decoupled Head 사용 (from YOLOX)</li>
</ul>
</li>
<li><p><strong>New classification and regression losses.</strong></p>
<ul>
<li>classification : VariFocal loss </li>
<li>regression : SIoU / GIoU loss</li>
</ul>
</li>
<li><p><strong>Label assignment</strong> using the Task alignment learning approach introduced in <a href="https://www.semanticscholar.org/reader/7438524bf00d7c5a22cb8799797f57c3a794b220">TOOD.</a></p>
</li>
<li><p><strong>A self-distillation strategy</strong> for the regression and classification tasks</p>
</li>
<li><p><strong>A quantization scheme</strong> for detection using RepOptimizer and channel-wise distillation that helped to achieve a faster detector.</p>
</li>
</ul>
<h2 id="yolo-v6---v30">YOLO v6 - v3.0</h2>
<p>2023, <a href="https://arxiv.org/pdf/2301.05586.pdf">YOLOv6 v3.0: A Full-Scale Reloading</a>
Yolo v7, v8 이후인 2023 년 1월에 v3.0이 나왔다.
<img src="https://velog.velcdn.com/images/dust_potato/post/3fb5b28d-1e9a-4be3-92e5-decf3c49eccb/image.png" alt="">다른 모델들과 비교했을 때 정확도와 속도 측면에서 모두 나은 성능을 보인다. </p>
<h3 id="main-changes-1">Main Changes</h3>
<ul>
<li>Renew the neck of the detector with a <strong>Bi-directional Concatenation (BiC)</strong></li>
<li><strong>Anchor-Aided Training (AAT)</strong></li>
<li><strong>Deepen YOLOv6</strong> to have another stage in the backbone and the neck</li>
<li><strong>New self-distillation strategy</strong>, in which the heavier branch for DFL is taken as an <strong>Enhanced Auxiliary Regression Branch</strong></li>
</ul>
<h1 id="yoolv6-자세한-설명">Yoolv6 자세한 설명</h1>
<p><strong>[Main Changes 1] A new backbone based on RepVGG</strong></p>
<blockquote>
<p>Backbone Background - <a href="https://arxiv.org/abs/2101.03697">RepVGG</a>
  ResNet, DenseNet과 같은 multi-branch network는 높은 정확도를 보이지만 parallism은 줄어들고 inference time이 증가한다. 반면 VGG 와 같은 single-path model들은 적은 메모리 사용량, 높은 infererece 효율을 보인다.<img src="https://velog.velcdn.com/images/dust_potato/post/defc3df1-e97c-4f2b-8a09-77863529ffc5/image.png" alt="">RepVGG는 training time에는 ResNet 과 같이 multi-branch 로 구성되는 반면 inference time 에는 structural re-parameterization 기법을 통해 3x3 Conv layer, ReLU로만 구성된 single-path model을 만들어서 inference time을 줄였다.<img src="https://velog.velcdn.com/images/dust_potato/post/235a58fe-7973-40eb-a9a5-1083f4ab5b76/image.png" alt=""><img src="https://velog.velcdn.com/images/dust_potato/post/9611328e-6d28-4987-8c5d-5d6d8e8b9eac/image.png" alt=""> 논문에서는 identity를 degraded 1x1 Conv , 1x1 Conv를 degraded 3x3 Conv로 간주한다. 
  Parameter 관점에서 보면 수식 정리에 따라 3x3 Conv Layer를 거치고 BN을 거치는 과정은 하나의 3x3 Kernel 과 bias를 가지는 Conv Layer로 변환할 수 있다. Identity도 마찬가지로 1x1 Kernel과 bias를 가지는 Conv로 변환한다. 따라서 위 (1) 수식을 정리하면 하나의 3x3 Kernel, 두개의 1x1 Kernel, 세개의 bias vector로 변환할 수 있어서 구조적으로 Single Path를 만들 수 있다. (Structural re-Parameterization)</p>
</blockquote>
<ul>
<li><p>Backbone - EfficientREP
RepVGG는 작은 network에서는 inference time을 크게 증가시키지 않으면서 좋은 feature representation 능력을 가지고 있으나, 큰 네트워크에서는 single path로 인해  parameter와 computation cost가 크게 증가하는 단점이 있다.(Residual Connection을 없앴으므로)
따라서 작은 네트워크에서는 RepBlock을, 큰 네트워크에서는 CSPStackRep block을 사용했다.</p>
<h2 id="cspstackrep-block은-3개의-1x1-conv-layer와-두-쌍의-repconvinference에-사용되는-repblock을-말함와-relu로-이루어진-sub-block으로-이루어져-있다-residual-connection을-사용하며-csp-connection을-통해-computation-cost가-크게-증가하지-않는-선에서-accuracy를-향상시켰다-accuracy와-speed-간의-trade-off-를-고려"><img src="https://velog.velcdn.com/images/dust_potato/post/5d2745af-bca0-4cc5-873b-75ef96482df5/image.png" alt=""> CSPStackRep block은 3개의 1x1 Conv layer와 두 쌍의 RepConv(inference에 사용되는 RepBlock을 말함)와 ReLU로 이루어진 sub-block으로 이루어져 있다. Residual connection을 사용하며 CSP connection을 통해 computation cost가 크게 증가하지 않는 선에서 accuracy를 향상시켰다. (accuracy와 speed 간의 trade-off 를 고려)</h2>
<blockquote>
<p>Neck Background - <a href="https://arxiv.org/pdf/1803.01534.pdf">PAN</a>
PAN은 bottom-up path augmentation을 통해  lower layers feature 정보를 top layer까지 효과적으로 전달하여 localization 성능을 높인다. <img src="https://velog.velcdn.com/images/dust_potato/post/bbf796d2-d0ae-4c89-a6a3-0646f624b6d0/image.png" alt=""> low level feature는 객체의 texture, pattern, edge 와 같은 local feature를, high level feature는 이미지 전체의 context와 같은 global feature 정보를 담고 있다. 따라서 FPN과 같이 low level, high level feture 정보를 잘 섞어주어야 모델이 다양한 정보를 토대로 예측을 잘 할 수 있다.
PAN 구조가 특히 localization 성능을 높이는데 기여한 이유도 마찬가지로 edge에 대한 정보를 가진 local feature 를 잘 활용했기 때문에 객체의 위치를 조정하는 localization 성능을 높일 수 있는 것이다. 
FPN과 비교하면(그림에서 빨간 점선) low layer feature를 top layer로 보낼 때 
FPN은 100개 이상의 layer를 지나야 하는데 PAN은 FPN에 extra bottom-up pathway shortcut을 추가하여 10개 이하의 layer만 지나면 된다.</p>
</blockquote>
</li>
<li><p>Neck - RepPAN(RepBlocks으로 강화된 PAN)
YOLO v4, v5 에서 사용된 PAN이 v6의 base가 되었고, 위에서 설명한 이유로 작은 모델에는 RepBlock을, 큰 모델에는 CSPStackRep을 사용하였고 이를 YOLO v6에서는 Rep-PAN이라고 칭한다.</p>
</li>
<li><p>Efficient DeCoupled Head
<img src="https://velog.velcdn.com/images/dust_potato/post/7ff8714b-2822-41ee-b4fb-3cc471d57fcc/image.png" alt="">2021년에 나온 YOLOR에서 사용된 기법으로, 이전에는 Classification branch와 Regression branch가 parameter를 공유했으나 classification confidence와 localization accuracy 간의 misalignment가 있을 수 있어 두 branch를 각각 다른 head로 분리했고, 그 결과 AP가 1.1 상승하고 학습할 때 수렴도 더 빨랐다고 한다. </p>
<hr>
<p><strong>[Main Changes 2] New classification and regression losses.</strong></p>
<blockquote>
<p>Classification Loss Background - <a href="https://www.semanticscholar.org/paper/Focal-Loss-for-Dense-Object-Detection-Lin-Goyal/79cfb51a51fc093f66aac8e858afe2e14d4a1f20">Focal loss</a>
Focal loss 는 모델의 weight update를 조절하여 class imbalance의 문제를 완화하는 loss이다. 
Detector의 최적화에서 classifier의 성능을 높이는 것은 중요한 부분이다. 전통적으로 classification loss에는 cross-entropy를 사용했는데, CE loss는 가중치를 업데이트 할 때 hard/easy sample 또는 positive/negative sample 모두 동일한 비율로 가중치를 업데이트 시킨다. 
1-stage detecter의 경우 사람이 미리 정의한 anchor box를 사용하지 않고 이미지 전체에서 모델에 feed할 input bounding box를 뽑아내므로 전체 박스중에서 배경(negative sample)이 차지하는 비율이 클 수 밖에 없다. 이는 class 간의 imbalance를 야기하고, 자연스럽게 모델은 더 많이 학습한 배경만을 쉽게 분류하게 된다. 이렇게 되었을 때 배경을 easy sample, 객체를 hard sample이라고 부른다. 
이는 1-stage detector 뿐 아니라 class-imbalance가 심한 데이터인 경우에 어느 모델에서나 일어나는 문제이다. 
우리의 목적은 모델이 배경이 아닌 객체를 더 잘 분류하게 만드는 것이므로 easy sample일 경우에는 loss에 가중치를 적게 주고, hard sample인 경우에는 loss에 가중치를 크게 주어 hard sample을 학습할 때에 모델의 weight가 더 많이 업데이트되도록 하였다.
이 loss가 바로 Focal loss이다. <img src="https://velog.velcdn.com/images/dust_potato/post/d6fd9fea-b4ca-499f-b1ac-283c6e1cd06d/image.png" alt="">$P_t$ : model’s estimated probability for the class with $y$=1
$\gamma$ : focusing parameter, loss become CE loss when $\gamma$ = 0
$(1-P_t)^\gamma$ : modulating factor 
class confidence score인 $P_t$가 0.5 이상으로 클수록(높은 정확도를 가지고 잘 분류되었을 때) factor는 0에 가까워지고 loss에 대한 가중치도 작아진다. </p>
</blockquote>
</li>
<li><p><em>Classification Loss - <a href="https://www.semanticscholar.org/reader/14c3510e4f4b370d5cd0420037406024533f4b6f">VariFocal Loss</a>*</em>
YOLO v6 연구자들은 Focal Loss, Quality Focal Loss , VariFocal Loss,  Poly Loss와 같은 다양한 Loss를 실험해보고 가장 성능이 좋은 VFL을 선택했다. 
VFL도 Focal Loss에서 출발했기 때문에 기본 아이디어는 같다. 
<img src="https://velog.velcdn.com/images/dust_potato/post/74aa4965-49d6-41f8-8b93-9593d5c0ef73/image.png" alt="">
FL과의 차이점은 Loss의 구성요소인데, VFNet 논문에서는 bounding box classification과 regression을 동시에 수행하기 위해 단순히 class confidence score만 구하는 것이 아니라 GT와의 IOU를 고려한 IoU-aware classification score(IACS)를 측정했다. 
P는 예측된 IACS값. q는 target IOU score. (positive sample인 경우 GT와의 IOU, negative sample인 경우 0) 
q=0일 때만 (negative sample일 때만) loss 앞의 $P^\gamma$를 사용하여 가중치 업데이트가 적게 일어나게 한다. </p>
</li>
</ul>
<p>   <strong>Regression Loss - <a href="https://www.semanticscholar.org/paper/SIoU-Loss%3A-More-Powerful-Learning-for-Bounding-Box-Gevorgyan/406b457cf2dc9a62417b05b755ef5434df0a4d33">SIoU</a> / <a href="https://www.semanticscholar.org/paper/Generalized-Intersection-Over-Union%3A-A-Metric-and-a-Rezatofighi-Tsoi/889c81b4d7b7ed43a3f69f880ea60b0572e02e27">GIoU</a> loss</strong>
  기존의 Regression Loss로는 L1 Loss가 사용되었는데, L1 loss는 bounding box의 생김새에 따른 GT와의 겹침 정도(IoU)가 달라도 같은 값을 내어놓는 문제로 인해 IOU를 이용하는 IoU-series Loss가 많이 연구되었다. 
Yolo v6에서는 GIoU, CIoU, SIoU를 실험한 결과 YOLOv6-N and YOLOv6-T에는 SIoU를, 나머지 모델에는 GIoU를 사용한다.
    - SIoU (SCYLLA-IoU)
    Angle, Distance, Shape, IoU 를 모두 고려한 metric
   - GIoU (Generalized IoU)
   IoU는 두박스가 겹치지 않을 때 언제나 0의 값을 가지므로 두박스의 거리가 얼마나 가까운지 정보를 알 수 없고, 영역에 따른 겹침 정도만 파악하기 때문에 박스가 겹쳐진 모양 또한 파악할 수 없다는 단점이 있어 이를 극복하기 위해 GIoU 제안. 
   GIoU는 Predict bounding box와 GT를 모두 포함하는 박스 중 가장 작은 box인 Convex object C를 이용한다. $C\backslash (A\cup B)$는 C에서 A와 B의 영역의 합을 뺀다는 것을 의미하고 전체 IoU에서 이 값을 빼서 loss를 계산한다. <img src="https://velog.velcdn.com/images/dust_potato/post/256d9226-e7ad-4866-8cb6-635166c165d9/image.png" alt=""><img src="https://velog.velcdn.com/images/dust_potato/post/baacf2be-6e3d-4c41-94c4-0663ffcb8a7a/image.png" alt=""></p>
<hr>
<p>  <strong>[Main Changes 4] A self-distillation</strong>
  knowledge distillation 이란, teacher model 과 student model 두 모델을 사용하는데, teacher model은 student model을 학습할 때 사용된다. 미리 학습된 teacher model의 예측 값이 GT와 함께 soft label로 사용되는 방법이다. 
  Computation Cost를 증가시키지 않고 model의 정확도를 향상시키기 위해 teacher model과 student model의 KL-divergence를 최소화하는 knowledge distillation technique을 사용했다. 이때 teadcher model이 그대로 stdent model로 사용되지만 pre-train을 했기 때문에 self-distillation이라고 말한다. 
  Regression and Classification tasks 모두에 적용하는데, Regression task를 위해서는 <a href="https://www.semanticscholar.org/reader/da60e046aac895b5775ed34bde45beb86aad0fe8">DFL(Distribution Focal Loss)</a>을 사용한다. 
  DFL은 GFL의 한 종류인데, GFL(Generalized Focal Los)은 original FL이 category label이 discrete할 때만 사용이 가능하기 때문에 continuous value를 가진 target도 예측할 수 있도록 한 Loss이다. 
  기존의 Focal Loss는 binary classification 문제에서 사용되며, 이 문제에서는 두 개의 클래스 중 하나를 선택하는 것이다. 이때 선택되지 않은 클래스는 무시하고, 선택된 클래스의 확률값을 최대화한다. 하지만 object detection과 같은 문제에서는 continuous value를 가진 target을 예측해야 한다. 예를 들어, bounding box regression에서는 바운딩 박스의 좌표값(x, y, w, h)이 continuous value를 가진다.
GFL은 이러한 continuous value를 가진 target을 예측하기 위해 다음과 같은 방식을 사용한다. 먼저, object detection 모델은 bounding box의 좌표값(x, y, w, h)을 예측하게 되고, 이때 예측값과 실제값(target)의 차이를 계산한다. 이 차이를 IoU(Intersection over Union)로 변환한 다음, 이 값을 GFL에서는 continuous value로 사용한다. 이렇게 변환된 값을 사용하여 Focal Loss와 유사한 방식으로 Loss를 계산한다.</p>
<p>  DFL은 Focal Loss와 Cross Entropy Loss를 결합한 형태로, 클래스 간 불균형 문제를 해결하고 분류 성능을 향상시키는 데 도움을 준다.
DFL은 Focal Loss와 Cross Entropy Loss의 가중치를 조정하는 방식으로 동작한다. Focal Loss는 높은 확률을 가진 예측값에 대해 더 큰 가중치를 부여하고, Cross Entropy Loss는 모든 클래스에 대해 동일한 가중치를 부여한다. DFL은 이 두 가지 손실 함수를 결합하여 높은 확률을 가진 클래스에 대해서만 Focal Loss의 가중치를 적용하는 방식으로 동작한다.
이 논문에서는 Teacher 모델과 Student 모델을 학습시키고, DFL을 적용하여 높은 확률을 가진 클래스에 대해 더 큰 가중치를 부여하여 분류 성능을 향상시켰다.</p>
<hr>
<p>  <strong>[Main Changes 5] A quantization scheme</strong>
  더 빠른 detecter를 만들기 위해 Post-training quantization(PTQ)과 quantization-aware training (QAT) 두가지 방법을 사용하여 실험을 진행했다. 
  PTQ는 작은 calibration data set 만을 사용해서 학습이 완료된 후에 model 의 weight를 quantize 하는 방법이고, QAT는 training set을 사용해서 학습 도중에 quantize 하였을 때를 시뮬레이션하여 최적의 weight를 구하는 것과 동시에 quantization을 하는 방법이다. QAT는 주로 distillation과 함께 사용한다. </p>
<pre><code>  - [RepOptimizer](https://www.semanticscholar.org/reader/0ac18b85c2abfe6669acfccec016d56d60a5ccdf)(PTQ)</code></pre><p>  Yolo v6는 re-parameterization block을 많이 사용했기 때문에 기존의 PTQ 방법을 적용하면 정확도의 하락이 너무 커서 RepOptimizer로 문제를 완화한다.
  RepOptimizer는 기존의 역전파 기반 최적화 알고리즘과는 달리, 파라미터를 새로운 형태로 변환한 후 최적화를 수행하는 방법이다.
RepOptimizer는 네트워크의 파라미터를 RepVGG와 같은 간단한 형태로 변환한다. 이렇게 하면 네트워크의 파라미터 수를 줄일 수 있으며, 모델의 일반화 성능을 향상시킬 수 있다. 변환된 파라미터에 대한 최적화는 기존의 역전파 기반 최적화 알고리즘과 동일하게 수행된다.
  - [channel-wise distillation]
  (<a href="https://www.semanticscholar.org/paper/Channel-wise-Knowledge-Distillation-for-Dense-Shu-Liu/237c2d518b79678f7332a4243f57a285711a4c37)(QAT)">https://www.semanticscholar.org/paper/Channel-wise-Knowledge-Distillation-for-Dense-Shu-Liu/237c2d518b79678f7332a4243f57a285711a4c37)(QAT)</a>
  PTQ의 정확도 하락을 보완하기 위해 QAT 기법 적용
<img src="https://velog.velcdn.com/images/dust_potato/post/50109cce-8d34-4715-b945-731e75c9f01a/image.png" alt=""></p>
<h3 id="architect">Architect</h3>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/7ae893b9-45ef-4892-89dd-2b339d8e81f2/image.png" alt=""></p>
<h3 id="result">result</h3>
<table>
<thead>
<tr>
<th>모델</th>
<th>사용 데이터 셋</th>
<th>GPU</th>
<th>AP</th>
<th>AP50</th>
<th>FPS</th>
</tr>
</thead>
<tbody><tr>
<td>YOLOv6-L</td>
<td>MS COCO dataset test-dev 2017</td>
<td>NVIDIA Tesla T4</td>
<td>52.5%</td>
<td>70%</td>
<td>50</td>
</tr>
<tr>
<td>Evaluated on MS COCO dataset test-dev 2017, YOLOv6-L achieved an AP of 52.5% and AP50 of 70% at around 50 FPS on an NVIDIA Tesla T4.</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody></table>
<h1 id="yolov6-v30-자세한-설명">Yolov6-v3.0 자세한 설명</h1>
<p><strong>[Main Changes 1] Bi-directional Concatenation (BiC)</strong>
  Detector의 neck을 BiC로 대체한다.
  세개의 인접한 layer의 feature map을 inregrate하기 위해 Bi-directional Concatenation(BiC) module을 제안한다. <img src="https://velog.velcdn.com/images/dust_potato/post/fe63b08b-5bd2-46d4-8d1a-9f9db7e1344b/image.png" alt=""> 이는 PAN의 top-down path에서 오는 feature인 $P_i$에 backbone의 $C_{i-1}$번째 layer에서 나온 low-level feature를 추가로 fusion 한다. 이렇게 하면 더 정확한 localizatoin signal을 얻을 수 있다.</p>
<p>  <a href="https://github.com/ultralytics/yolov5/releases/tag/v6.1">YOLOv5 release v6.1</a>에서 사용한 <a href="https://github.com/ultralytics/yolov5/pull/4420">SPPF</a> block을 CSP-like version인 SimCSPSPPF Block으로 간소화한다. SimCSPSPPF는 representational ability, 즉 표현력을 강화한 방법이다. 
  <img src="https://velog.velcdn.com/images/dust_potato/post/522dae9f-4118-478b-a07f-28e5282270df/image.png" alt="">
 SPPF는 SPP (Spatial Pyramid Pooling)의 변형으로
SPP는 입력 이미지를 여러 사이즈의 그리드로 분할하고, 각 그리드 영역에서 최대 풀링 연산을 수행하여 공간적인 정보를 추출하는 방법이다. 이를 통해 입력 이미지의 크기와 무관하게 동일한 크기의 특성 맵을 얻을 수 있다.</p>
<p>반면, SPPF는 SPP에서 추가적으로 특성 맵의 크기를 줄이는 기능을 수행한다. <a href="https://github.com/ultralytics/yolov5/pull/4420/commits/91580c2a03d70494bb9a0f23cdad8aa8175b52a4">이를 위해 SPP 후에 1x1 크기의 컨볼루션 연산을 적용하고, 이를 반복적으로 수행한다</a>. 이 과정을 통해 특성 맵의 크기를 줄이면서도 공간적인 정보를 보존할 수 있다.</p>
<p>따라서, SPPF는 SPP와 비슷한 기능을 수행하지만 특성 맵의 크기를 줄이는 추가적인 기능을 가지고 있다.</p>
<p>SimCSPSPPF에서 찾을 수 있는 CSPNet의 특징은 input에서 갈라져서 1x1 Conv 를 거쳐 마지막에 Concat되는 Connection 이다.</p>
<hr>
<p>  <strong>[Main Changes 2] Anchor-Aided Training (AAT)</strong>
  Inference efficiency에 영향을 주지 않으면서 Anchor-Based와 Anchor-Free paradigms의 장점을 모두 가져가기 위해 Anchor-Aided Training을 적용한다. 
  Yolov6-n에서 Anchor-Free와 Anchor-Based 기법을 비교했을 때 Anchor-Based에서 더 좋은 성능을 냈다. AAT는 Anchor-Based 에서 오는 성능 향상을 위해 학습을 할 때 Anchor-Based를 사용하는 보조브랜치를 함께 학습한다. Inference할 때는 보조 브랜치를 제거하여 속도 감소를 피한다.<img src="https://velog.velcdn.com/images/dust_potato/post/468c8d33-6c21-4a48-829f-a81a6484d6c6/image.png" alt=""></p>
<hr>
<p>  <strong>[Main Changes 3] Deepen YOLOv6</strong>
  Backbone과 Neck에 stage를 추가하여 모델의 깊이를 깊게한다. 이를 통해 high-resolution input으로 들어오는 COCO dataset에서 SOTA를 달성했다. </p>
<hr>
<p>  <strong>[Main Changes 4] New self-distillation strategy  : Enhanced Auxiliary Regression Branch</strong>
  YOLOv6의 small model의 성능을 높이기 위해 새로운 self-distillation을 제안한다. 학습중에는 regression branch의 DFL을 enhanced auxiliary regression branch로 바꾸어 사용하고 inference 시에는 속도를 위해 제거한다.<br>  전체 loss는 $L_{t o t a l}=L_{d e t}+\alpha L_{K D}$ 로 구성되며 KD를 조절하는 파라미터인 $\alpha$는 teacher model에서 오는 soft label과 student model 에서 오는 hard label을 dinamically하게 적용하기 위해 cosine weight decay를 사용한다. 
  이 때 DFL은 regression branch를 위해 extra parameter가 필요한데, 이는 inference time을 증가시키는 원인이 된다.
  이를 피하기 위해 본 논문에서는 Decoupled Localization Distillation (DLD) 를 제안한다. DFL을 통합하기 위헤 heavy auxiliary enhanced regression branch를 제안했다. Self-distillation 과정에서 student model은 naive regression branch와 enhanced regression branch를 동시에 사용하는 반면 teacher model은  auxiliary branch만 사용한다. 
  naive regression branch는 오직 hard-label로만 학습되고, auxiliary branch는 teacher model에서 오는 soft label로 학습된 signal과 hard label 모두를 사용하여 학습된다.
  Distillation 이후에 naive regression branch 유지되고 auxiliary branch는 제거된다. 이 방법으로 Distillation 에서 inference efficiency에 영향을 주지 않고 DFL을 사용할 수 있다. </p>
<h3 id="architect-1">Architect</h3>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/2413df41-da18-4056-91e4-9800646dfaa9/image.png" alt=""></p>
<h3 id="result-1">result</h3>
<table>
<thead>
<tr>
<th>모델</th>
<th>사용 데이터 셋</th>
<th>GPU</th>
<th>AP</th>
<th>AP50</th>
<th>FPS</th>
</tr>
</thead>
<tbody><tr>
<td>YOLOv6-L6</td>
<td>MS COCO dataset 2017 val</td>
<td>NVIDIA Tesla T4</td>
<td>57.2%</td>
<td>74.5%</td>
<td>29(TRT, bs32)</td>
</tr>
<tr>
<td>Evaluated on MS COCO dataset 2017 val, YOLOv6-L6 achieved an AP of 57.2% and AP50 of 74.5% at around 29 FPS on an NVIDIA Tesla T4 in the same environment with TensorRT.</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody></table>
<h1 id="전체-요약">전체 요약</h1>
<p>Yolov6과 Yolov6-v3.0 에서 정확도를 향상시키면서도 inference 속도를 증가하지 않기 위한 많은 기법이 소개 되었는데, 
이를 (1)학습 정확도를 높이기 위한 방법과 (2)Inference 속도 증가를 막는 기법으로 나누어 생각해보면 다음과 같다. 
(1) 학습 
BackBone으로 EfficientRep Block, Neck으로 Rep Bi-PAN, PAN에서 BiC Module 사용하는데,
v3.0에서 Backbone과 Neck에 Stage 추가하여 깊이를 깊게 함
기본적으로 Anchor-Free 모델이지만 Anchor-Based Branch 추가한 AAT 기법으로 학습
Cls 에 VariFocal Loss , Reg 에 SIoU / GIoU loss 사용
Label assignment using the Task alignment learning approach / v3.0 ATSS 적용 </p>
<p>(2) Inference
BackBone, Neck에 모두 Re-Parameterization 사용 
Self-distillation 사용 
PTQ, QAT 모두 적용한 모델(nano, small)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[논문리뷰] Bridging the Gap Between Anchor-based and Anchor-free Detection via Adaptive Training Sample Selection , CVPR 2020]]></title>
            <link>https://velog.io/@dust_potato/%EB%85%BC%EB%AC%B8%EB%A6%AC%EB%B7%B0-Bridging-the-Gap-Between-Anchor-based-and-Anchor-free-Detection-via-Adaptive-Training-Sample-Selection-CVPR-2020</link>
            <guid>https://velog.io/@dust_potato/%EB%85%BC%EB%AC%B8%EB%A6%AC%EB%B7%B0-Bridging-the-Gap-Between-Anchor-based-and-Anchor-free-Detection-via-Adaptive-Training-Sample-Selection-CVPR-2020</guid>
            <pubDate>Sun, 26 Mar 2023 06:07:42 GMT</pubDate>
            <description><![CDATA[<p><a href="https://arxiv.org/abs/1912.02424">Bridging the Gap Between Anchor-based and Anchor-free Detection via Adaptive Training Sample Selection</a></p>
<p>code : <a href="https://github.com/sfzhang15/ATSS">https://github.com/sfzhang15/ATSS</a></p>
<h1 id="intro">Intro</h1>
<p>Object Detection 에서 사용되는 모델은 크게 YOLO, SSD 같은 1-stage 모델과 Faster-RCNN과 같은 2-stage 모델로 나누어집니다.
둘의 차이는 box를 detection 하는 과정에서 region proposal network (RPN) 을 사용하지 않는지(1 stage), 사용하는지(2 stage) 여부입니다. </p>
<p>Object Detection 분야의 모델을 나누는 또 다른 기준은 anchor의 사용 여부입니다.
anchor란 특정 aspect ratio를 가진 object를 탐지하기 위해 다양한 크기와 비율로 &quot;미리 정의해놓은&quot; bounding box를 의미합니다. </p>
<p>anchor를 사용하는 대표적인 모델은 YOLO v1입니다. <img src="https://velog.velcdn.com/images/dust_potato/post/c11d4664-a942-419b-8135-10ff24f3d9b7/image.png" alt=""></p>
<p>객체의 크기, 비율 등 객체의 특징에 해당하는 B개의 anchor box를 사람이 디자인합니다.
이미지 전체를 SxS grid로 나누고, 각 grid에서 디자인한 B개의 anchor box에 해당하는 feature를 뽑아 network에 input으로 넣어주는 방식입니다. 
이를 여러 개의 anchor를 tiling한다고도 하는데, 
각기 다른 가로, 세로, 비율을 가진 anchor box들을 이미지의 각 위치마다 anchor box를 놓는 것을 의미합니다.
이후 모델이 각 anchor box 마다 객체일 확률, 배경일 확률, 위치 (class probability, bounding box offsets)등 을 예측하고 각 anchor box의 모양과 위치를 세부적으로 조절합니다. 
<img src="https://velog.velcdn.com/images/dust_potato/post/48f99be3-6433-4e6e-906a-bd9d53fd5bf2/image.png" alt=""></p>
<h2 id="anchor-based-detection-의-한계">anchor-based detection 의 한계</h2>
<p>이렇게 hand-crafted anchor를 사용하면 학습 데이터에 있어서는 높은 정확도를 보이는 장점이 있지만 명확한 단점 또한 존재합니다. </p>
<ul>
<li><p>anchor box 디자인 
학습 데이터 안에 포함된 객체의 특징을 파악하여 사람이 직접 box를 디자인하기 때문에 데이터가 바뀔때마다 매번 box를 설계해야합니다. </p>
</li>
<li><p>높은 computation cost
다양한 크기와 비율을 가진 객체를 탐지하기 위해 보통 2개 이상의 anchor를 사용하는데, 그에 따라 각 anchor에서 만들어내는 feature가 많아져서 computation cost가 커지게됩니다. </p>
</li>
<li><p>낮은 inductive bias
학습데이터 안에 포함되지 않은 특징을 가진 새로운 데이터를 예측할 때, 해당 데이터는 미리 설계한 anchor box로는 예측 성능이 매우 떨어지게 됩니다. </p>
</li>
</ul>
<p>위와 같은 한계점으로 인해 anchor box를 사용하지 않는 모델을 연구하게 됩니다. </p>
<h2 id="anchor-free-detection">anchor-free detection</h2>
<p>anchor를 사용하지 않는다면 어떻게 객체를 detection 할 수 있을까요?
anchor free 모델은 미리 정의한 anchor 없이 바로 object를 탐지하는데, 
Keypoint-based method 와 Center-based method 의 두가지 방법이 있습니다. </p>
<ul>
<li><p>Keypoint-based method
먼저 여러 개의 미리 정의되거나 자체 학습된 Keypoint를 찾은 다음 객체의 공간 범위를 제한하는 방법<img src="https://velog.velcdn.com/images/dust_potato/post/25bfe719-6582-477e-843b-6a0fa8f14fcd/image.png" alt="">     </p>
<h5 id="reppoints-cvpr-2019">[RepPoints, CVPR 2019]</h5>
</li>
<li><p>Center-based method
객체의 중심점 또는 영역을 사용하여 양의 값을 정의한 다음 양의 값에서 객체 경계까지의 네 가지 거리를 예측하는 방법<img src="https://velog.velcdn.com/images/dust_potato/post/c4d6b1a2-0636-42ff-b993-062f19a319f5/image.png" alt=""></p>
<h5 id="fcos-iccv-2019">[FCOS, ICCV 2019]</h5>
<p>[이 논문이 연구된 이유/배경]
그동안은 detection 분야에서 Anchor-base 모델을 사용하는 것이 높은 정확도를 보장하기 때문에 정답처럼 여겨졌지만, FPN과 FOCAL loss 의 등장으로 Anchor-Free 모델의 연구도 활발하게 진행됩니다. </p>
<p>오늘 리뷰할 논문인 Bridging the Gap Between Anchor-based and Anchor-free Detection via Adaptive Training Sample Selection (이하 ATSS) 은 Anchor-based 방법론과 Anchor-free 방법론의 성능 차이를 야기하는 핵심 원인이 무엇인지 찾고, 찾은 원인을 기반으로 성능 차이를 줄이는 방법(ATSS)을 제안합니다. </p>
</li>
</ul>
<h1 id="background">Background</h1>
<ul>
<li><p><strong><a href="https://arxiv.org/pdf/1612.03144.pdf">FPN</a></strong>
Feature Pyramid Network. 보다 다양한 크기의 객체를 탐지하기 위해 network의 마지막 layer에서 나온 feature만 사용하는 것이 아니라, 각 layer에서 나온 모든 feature를 사용합니다. 
<img src="https://velog.velcdn.com/images/dust_potato/post/0ab2820e-4968-4045-8fd1-0ab57291188d/image.png" alt=""></p>
</li>
<li><p><strong><a href="https://arxiv.org/pdf/1708.02002v2.pdf">FOCAL loss</a></strong>
1 stage detector의 경우 RoI pooling 과정이 없어 class imbalance 문제가 심각합니다. 이미지 안에서 object가 차지하는 영역은 적고 배경이 차지하는 영역이 크다면 negative anchor box의 갯수가 positive anchor box의 갯수보다 훨씬 많아져 학습에 방해가 됩니다. 배경은 객체에 비해 쉽게 구분되기 때문에 학습에 중요한 부분이 아닌데, 차지하는 비율이 커서 loss, gradient를 계산할 때 배경의 영향이 커지게 됩니다.</p>
<p>이를 해결하기 위해 분류하기 어려운 케이스(여기서는 객체)일 때 loss 계산 시 더 큰 가중치를 주고, 쉽게 분류할 수 있는 경우(배경)는 작은 가중치를 주는 방법입니다.</p>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/7d639e52-52f6-402d-b1ea-404af148027b/image.png" alt=""></p>
</li>
<li><p><strong>왜 FPN, Focal loss의 등장으로 anchor free 모델의 연구가 활발히 진행되는지</strong> 
FPN과 Focal loss의 장점은 다양한 feature를 사용하고, RPN을 사용하지 않는 방법론에서 객체 탐지의 정확도를 높여주는 기법이므로 anchor가 사라져서 오는 정확도의 하락을 해당 기법들로 보완하였습니다. </p>
</li>
<li><p><strong>FCOS</strong>
Anchor-free , Center-based method 에 속하는 모델입니다.
<img src="https://velog.velcdn.com/images/dust_potato/post/35c8f624-4997-42b6-ab3b-5b4a560d4bb9/image.png" alt="">
CNN으로만 구성된 네트워크입니다.
feature map의 모든 픽셀마다 GT 박스 안에 포함되면 해당 물체로 classification합니다.
해당 위치로부터 bonding box 경계까지의 거리를 regression 합니다. 
주요 특징은 다음과 같습니다. </p>
<ul>
<li>FPN : 겹친 물체 detection</li>
<li>Center-ness branch : 중심으로 부터 거리가 가까운 Prediction 만을 사용</li>
</ul>
</li>
</ul>
<h1 id="abstract">Abstract</h1>
<p>해당 논문에서는 Anchor-based와 Anchor-free 방법론간의 성능 차이를 야기하는 핵심적인 차이가 
positive, negative sample을 어떻게 정의하는지에 따라 달렸다는 것을 보여줍니다.</p>
<p>즉 학습을 하며  positive, negative sample 의 정의를 똑같이 하면
box or point regression 을 어떻게 하느냐와는 상관없이 최종적인 detection 성능에서도 차이가 적다는 것입니다. </p>
<p>이는 근래의 detector 들 성능에는 positive and negative training samples을 어떻게 select 하느냐가 핵심임을 뜻합니다.</p>
<p>따라서 이 논문에서는 Adaptive Training Sample Selection (ATSS) 를 제안합니다.
ATSS 는 객체의 통계적 특징에 따라 positive, negative sample을 자동으로 결정하게 하는 기법입니다. </p>
<h1 id="contribution">Contribution</h1>
<ul>
<li>Anchor-Based 와 Anchor-Free detector 의 핵심 차이는 positive and negative training samples을 어떻게 정의하는지 임을 밝힘</li>
<li>Adaptive Training Sample Selection (ATSS) 를 제안</li>
<li>ATSS 를 통해 50.7 AP 로 SOTA 달성 </li>
<li>Obejct detection를 위해 이미지의 위치별로 여러 anchor를 tiling 할 필요성에 대한  실험 진행 (그럴 필요 없다고 말함)<blockquote>
<p> anchor를 tiling?
여러개의 anchor를 tiling한다.<br><img src="https://velog.velcdn.com/images/dust_potato/post/d270ce0d-af34-43d1-889e-42435fb60a40/image.png" alt="">
특정 aspect ratio를 가진 object를 탐지하기 위해 우리는 미리 가로, 세로, 비율이 정의된 bounding box를 가지고 있고, 이를 anchor box라고 한다. 
각기 다른 가로, 세로, 비율을 가진 anchor box들을 이미지의 각 위치마다 anchor box를 놓는 것을 의미한다. 
이후 모델이 각 anchor box 마다 객체일 확률, 배경일 확률, 위치 등을 예측하고 각 anchor box의 모양과 위치를 세부적으로 조절해나간다. </p>
</blockquote>
</li>
</ul>
<h1 id="experiment">Experiment</h1>
<p>Anchor-Based detector로는 RetinaNet, center-based Anchor-Free detector로는 FCOS를 가지고 실험을 진행합니다.
두 모델을 선택한 이유는 FCOS 논문에서 anchor based인 RetinaNet 보다 좋은 성능을 냈는데, 
아래 세가지의 차이 중 어떤것이 더 좋은 성능을 내도록 했는지 분석해보고자 두 모델을 선택했습니다.</p>
<table>
<thead>
<tr>
<th align="center">Differenece</th>
<th align="center">RetinaNet</th>
<th align="center">FCOS</th>
</tr>
</thead>
<tbody><tr>
<td align="center">(1) The number of anchors tiled per location</td>
<td align="center">tiles several anchor boxes per location</td>
<td align="center">tiles one anchor point per location</td>
</tr>
<tr>
<td align="center">(2) The definition of positive and negative samples</td>
<td align="center">resorts to the Intersection over Union (IoU) for positives and negatives</td>
<td align="center">utilizes spatial and scale constraints to select samples</td>
</tr>
<tr>
<td align="center">(3) The regression starting status</td>
<td align="center">regresses the object bounding box from the preset anchor box</td>
<td align="center">locates the object from the anchor point. (anchor point = center of an anchor box in RetinaNet)</td>
</tr>
</tbody></table>
<h2 id="exp1---inconsistency-removal">Exp1 - Inconsistency Removal</h2>
<p>이 실험은 위의 3가지 차이 중 (1) The number of anchors tiled per location를 분석한 실험입니다. 몇 개의 anchor box를 사용하느냐가 두 기법의 핵심 차이라면 기존에 두개 이상의 anchor를 사용하는 RetinaNet은 anchor box의 갯수를 FCOS와 동일하게 했을 때 
두 기법의 성능차이가 작아야 할 것입니다.
FCOS 논문에서 FCOS가 RetinaNet보다 더 나은 성능을 보입니다. 
그 이유를 분석하기 위해 FCOS에 적용한 기법을 RetinaNet에도 적용해봅니다. 
RetinaNet은 FCOS에서 Anchor Points를 하나만 사용하는 것처럼 anchor box 하나만 사용합니다. </p>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/e6a312d2-8432-4fd4-be66-dfc9c23d058d/image.png" alt="">
위의 테이블은 FCOS 논문에서 가져온 것인데, FCOS 와 RetinaNet의 minival AP_large 가 47.4% vs. 48.9%로 FCOS가 더 높습니다.</p>
<ol>
<li><p>GroupNormalization</p>
</li>
<li><p>GIOU regression loss function </p>
</li>
<li><p>Limiting positive samples in the ground-truth box : GT Box안 쪽에 속하는 sample들만 positive sample candidate로 보는 것</p>
</li>
<li><p>Centerness branch :  foreground를 검출할때 foreground라고 예측한 지점이 실제 ground truth 박스 기준으로 얼마나 center에 가깝냐를 예측하는 기법</p>
</li>
<li><p>Adding a trainable scalar for each level feature pyramid : 객체의 크기를 예측할때 learnable한 scalar 값을 이용
<img src="https://velog.velcdn.com/images/dust_potato/post/a3a3662c-6296-44e9-9f1a-fd369b9ef289/image.png" alt="">
ATSS논문에서는 이 기법들을 RetinaNet에 적용해봤을 때 AP가 32.5에서 37 까지 올라 FCOS와 0.8만큼의 작은 차이가 나는 것을 확인했습니다. </p>
<p>이처럼 위의 기법들은 anchor based 방법론에도 적용할 수 있는 것이어서, anchor-based 와 anchor-free methods의 핵심 차이점이 아닌 것을 의미합니다. </p>
</li>
</ol>
<h2 id="exp2---essential-difference">Exp2 - Essential Difference</h2>
<p>이제 두 방법론에서 남은 차이점은 두가지입니다. </p>
<ul>
<li>classification subtask - the way to define positive and negative samples</li>
<li>regression subtask - the regression starting from an anchor box or an anchor point</li>
</ul>
<h3 id="classification">Classification</h3>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/e4f7176d-6d74-4e18-9d15-e758583eb788/image.png" alt="">위의 그림 (a)을 보면 RetinaNet은 각 다른 pyramid level 로부터 온 박스들의 p/n을 나누는데에 IOU를 사용합니다.
처음에는 각 object의 best anchor box와 IOU 가 $\theta_p$보다 큰 박스들은 positive, IOU가 $\theta_n$ 보다 작은 박스는 negative로 간주합니다.</p>
<p>(b)를 보면 FCOS는  각 다른 pyramid level 로부터 온 포인트의 positive/negative를 나누는데에 spatial and scale constraints 를 사용합니다.</p>
<blockquote>
<p>spatial constraint : anchor point 가 ground truth bounding box 안에 포함되면 Positive Sample, 안되면 Negative Sample (= 해당 샘플이 object인지 여부)</p>
</blockquote>
<p>scale constraint :  Feature Pyramid Level 별로 서로 다른 크기의 Annotation을 할당하기 때문에, 사전에 정의한 Scale과 Annotation의 크기가 맞지 않는 Pyramid Level에선 모두 Negative Sample로 할당 (= 해당 샘플이 box의 크기를 결정하는지)</p>
<p>처음에는 ground-truth box안에 있는 포인트들을 candidate positive sample로 두고, candidate로부터 final positive를 구하는데, 이 때 각 pyramid level 마다 정의된 scale range를 기준으로 크기가 맞으면 positive, unselected anchor points 는 negative samples가 됩니다.</p>
<p>정리하면
두 방법 모두 spatial, scale dimension 정보를 활용하는데 
FCOS는 spatial - scale 순으로 순차적으로 사용하고 , RetinaNet은 IOU 비교를 통해 동시에 사용합니다. 
따라서 두 방법은 서로 다른 positive and negative sample을 만들게 됩니다. </p>
<h3 id="regression">Regression</h3>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/6c6177e9-a9f8-4038-8003-b535549801b3/image.png" alt="">
positive/negative sample이 정해졌으면 positive sample로 부터 박스의 구체적인 위치를 regression 합니다. </p>
<p>(b) RetinaNet은 anchor box와 GT box 간의 4개의 offset을 통해 위치를 찾고, </p>
<p>(c) FCOS는 anchor point로 부터 GT box 네 변까지의 거리를 통해 위치를 찾습니다. </p>
<p>즉 regression starting status가 RetinaNet은 box, FCOS는 point 입니다. </p>
<h3 id="exp2-result">Exp2 Result</h3>
<p>classification 에서의 define positive and negative sample,
regression 에서의 regression starting status
를 합쳐 두 방법을 비교해본 결과 테이블입니다. 
<img src="https://velog.velcdn.com/images/dust_potato/post/34a1603d-45b5-45b7-939f-727f716d57d6/image.png" alt=""></p>
<p>regression starting status  : RetinaNet 처럼 Box를 사용하느냐, FCOS 처럼 Point를 사용하느냐 에 따른 score는 큰 차이가 나지 않지만 </p>
<p>define positive and negative sample : positive, negative sample을 정의할 때 IOU를 사용하느냐, Spatial and Scale Constraint를 사용하느냐 에 따른 차이는 큰 것을 볼 수 있습니다. </p>
<p><strong>따라서 definition of positive and negative samples이 anchor-based and anchor-free detectors 간의 핵심적인 차이라고 주장합니다.</strong></p>
<h1 id="adaptive-training-sample-selectionatss">Adaptive Training Sample Selection(ATSS)</h1>
<p>Object Detector를 학습시킬 때 
첫번째, classification 단계에서 positive, negative sample을 구분하고
두번째, regression 단계에서 positive sample을 사용해서 위치를 예측합니다. </p>
<p>앞선 실험을 통해 첫번째 단계가 중요함을 알았기 때문에 <strong>&quot;how to define positive and negative training samples&quot;를 결정하는 ATSS 를 제안</strong>합니다. </p>
<p>ATSS는 hp를 거의 사용하지 않고 object의 통계적인 특성에 따라 automatically 하게 positive, negative sample을 구분합니다.</p>
<h2 id="algorithm">Algorithm</h2>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/d578d380-e1e1-4395-a276-e82264fba48d/image.png" alt="">
(1) pyramid level 을 돌면서 GT의 center와 anchor의 center가 가장 가까운(L2 distance) k 개의 anchor 후보를 선정합니다.</p>
<p>(2) (1)에서 뽑은 anchor box 후보들과 GT 와의 IOU를 계산합니다.</p>
<p>(3) (2)에서 계산한 IOU의 평균과 표준편차를 계산합니다. </p>
<p>(4) (1)에서 뽑은 anchor box 와 GT의 IOU 가 후보 anchor들의 평균 + 표준편차 이상이면 Positive, 미만이면 Negative 로 간주합니다 </p>
<blockquote>
<p>평균과 표준편차를 이용하는 것의 의미
<img src="https://velog.velcdn.com/images/dust_potato/post/58449457-a821-4b8f-9848-50c61d01210e/image.png" alt="">그림 3(a)에 표시된 것처럼 평균이 높으면 high-quality candidate가 있으며 IoU threshold가 높을 것으로 예상
표준편차가 크면 pyramid level 에서 어떤 layer 가 해당 object를 탐지하는데에 적합한지 알 수 있다.</p>
</blockquote>
<p>따라서 평균 + 표준편차는
object를 잘 탐지하는 pyramid level 에서 나온 후보 anchor 중 high-quality anchor를 positive로 뽑는다는 의미</p>
<h2 id="atss의-장점">ATSS의 장점</h2>
<ul>
<li><p>Maintaining fairness between different objects
여기서, IoU 가 정규분포를 따른다고 가정해보면, 
평균(IoUs) + 표준편차(IoUs) 이상의 IoU를 갖는 sample은 뽑힌 sample들 중에서
약 상위 16%에 속하는 sample들을 high-quality sample로 보고, positive sample로 판단하는 것으로 이해할 수 있습니다.</p>
<p>IoU가 정규분포를 따르지 않는다고 해도, 
각 object 가 0.2 * kL 개의 positive sample을 가지고 있는 것이고 이들은 scale, aspect ratio, location 과 무관합니다.</p>
<p>이와는 다르게 RetinaNet과 FCOS의 전략은 더 큰 객체에 대해 훨씬 더 Positive sample을  갖는 경향이 있어 서로 다른 객체간에 불공평 함을 초래합니다.</p>
</li>
<li><p>Keeping near hyperparameter-free
ATSS 알고리즘에서는 몇개의 후보 positive anchor box를 선택할지를 결정하는 k 만이 hyperparameter 로 사용됩니다. </p>
<p>K의 값에 따른 성능을 측정한 결과 너무 작거나(3) 큰(19) 값을 제외하고 7~17사이의 값에서는 성능이 다 비슷한 결과를 보입니다.
<img src="https://velog.velcdn.com/images/dust_potato/post/ef029a85-0993-411d-b068-32a17c07177d/image.png" alt=""> 이러한 결과로 저자는 제안하는 label assignment 방법이 almost hyperparameter-free하다고 주장합니다.</p>
</li>
</ul>
<p><b></b>
ATSS 를 사용했을 때 RetinaNet과 FCOS에서 모두 좋은 성능을 보입니다.<img src="https://velog.velcdn.com/images/dust_potato/post/992927fe-2d76-4d5c-a8df-325566e7930b/image.png" alt=""></p>
<p>anchor scale과 aspect ratio에 따른 실험 결과 또한 큰 차이가 없습니다. 이는 ATSS가 다른 anchor setting 이 달라져도 robust 하다는 것을 의미합니다.<img src="https://velog.velcdn.com/images/dust_potato/post/d6dac99e-7fc2-4ba3-8358-9728f020d0fc/image.png" alt=""></p>
<h1 id="conclusion">Conclusion</h1>
<p>object detection 에서 one-stage anchor-based 와 center-based anchor-free detectors의 핵심 차이는 
<strong>the definition of positive and negative training samples</strong> 입니다. </p>
<p>이를 위해 객체의 통계적 특징을 기준으로 adaptive 하게 positive sample을 정의하는 ATSS 기법 제안하여 성능을 향상시키고 두 방법론 간의 gap을 줄일 수 있었습니다.</p>
<hr>
<p>Reference
<a href="https://arxiv.org/pdf/1506.02640v5.pdf">YOLOv1 (You Look Only Once) Paper</a>
<a href="https://arxiv.org/abs/1904.11490">RepPoints: Point Set Representation for Object Detection, CVPR 2019</a>
<a href="https://arxiv.org/pdf/1904.01355.pdf">FCOS: Fully Convolutional One-Stage Object Detection, ICCV 2019</a>
<a href="https://www.mathworks.com/help/vision/ug/anchor-boxes-for-object-detection.html">anchor tiling : anchor-boxes-for-object-detection</a>
<a href="https://arxiv.org/pdf/1612.03144.pdf">FPN</a>
<a href="https://arxiv.org/pdf/1708.02002v2.pdf">FocalLoss</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[글쓰는 개발자 모임 - 글또 8기를 시작하는 다짐글🙂]]></title>
            <link>https://velog.io/@dust_potato/%EA%B8%80%EC%93%B0%EB%8A%94-%EA%B0%9C%EB%B0%9C%EC%9E%90-%EB%AA%A8%EC%9E%84-%EA%B8%80%EB%98%90-8%EA%B8%B0%EB%A5%BC-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-%EB%8B%A4%EC%A7%90%EA%B8%80</link>
            <guid>https://velog.io/@dust_potato/%EA%B8%80%EC%93%B0%EB%8A%94-%EA%B0%9C%EB%B0%9C%EC%9E%90-%EB%AA%A8%EC%9E%84-%EA%B8%80%EB%98%90-8%EA%B8%B0%EB%A5%BC-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-%EB%8B%A4%EC%A7%90%EA%B8%80</guid>
            <pubDate>Sun, 12 Feb 2023 04:57:16 GMT</pubDate>
            <description><![CDATA[<h2 id="글또란"><a href="https://www.notion.so/zzsza/ac5b18a482fb4df497d4e8257ad4d516">글또</a>란?</h2>
<p>글쓰는 또라이가 세상을 바꾼다의 준말. 
다양한 직군의 개발자들이 모여 각자의 직군에서 얻을 수 있는 내용을 토대로 글을 작성하는 커뮤니티이다. 
본질적으로는 글이라는 매개체로 모였지만 활동을 하면서 서로의 가치관, 고민, 성장방법, 취미를 공유할 수 있어 글 이외에도 많은 즐거움을 찾을 수 있다. </p>
<p>글또는 6기부터 참여해왔었고, 6기 때와 비교하면 나에게도 글또에도 많은 변화가 있었다. 
이번 글의 제목도 6기를 참여하며 작성했던 <a href="https://velog.io/@dust_potato/%EA%B8%80%EC%93%B0%EB%8A%94-%EA%B0%9C%EB%B0%9C%EC%9E%90-%EB%AA%A8%EC%9E%84-%EA%B8%80%EB%98%90-6%EA%B8%B0%EB%A5%BC-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-%EB%8B%A4%EC%A7%90%EA%B8%80">다짐글</a>의 제목과 똑같이 써보았다. </p>
<p>약 2년 간 글을 쓰고 있으니 나름의 꾸준함을,,, 갖추었나? </p>
<p>나의 꾸준함의 기준에는 퀄리티도 포함이 된다. 
내 스스로도 만족할 수 없고, 글을 보는 타인에게도 뭔가를 줄 수 없는 글을 많이 쓰는 것 보다는 
(그게 지식이든, 깨달음이든, 즐거움이든)
글의 내용도 풍부하고 형식도 깔끔한 글 몇개 정도를 작성하는 것이 더 &quot;꾸준하다&quot;라고 스스로 평가한다.</p>
<h2 id="8기-참여의-목표">8기 참여의 목표</h2>
<p><a href="https://velog.io/@dust_potato/2022%EB%85%84-%ED%9A%8C%EA%B3%A0-AI-Engineer%EB%A1%9C%EC%84%9C-%EC%B2%AB-%EC%A7%81%EC%9E%A5-%EC%A0%81%EC%9D%91%EA%B8%B0%EC%99%80-%EB%A9%98%ED%86%A0%EB%A7%81-%EC%9D%B4%EC%95%BC%EA%B8%B0">2022년을 회고하는 글</a>에서 2023년의 목표 중 하나로 
<strong>글 쓰는 습관 들이고 가독성과 형식 발전 시키기</strong> 를 작성했다. </p>
<p>2년간 글을 썼지만 올해 목표가 글에 대한 발전을 말하는 것을 보면 
나는 내 기준에 만족하도록 꾸준하지는 못했나보다. </p>
<p>목표 달성을 위해 구체적인 실행계획을 세워보려한다.</p>
<p>그동안의 참여 경험을 생각해보면 <strong>좋은 글을 쓰는 데에 방해되는 두가지 요소</strong>가 있다.</p>
<p>첫번째는** 글감 찾기. **
두번째는** 시간 내기.**</p>
<p>마감주가 다가오면 <code>이번주는 무슨 글을 쓰나,,</code> 고민하다가 겨우 주제를 생각해내곤 했다.
주제가 생각이 안나면 급하게 논문을 읽은 후에 라인 바이 라인으로 줄줄줄 번역해놓고 
<code>논문을 리뷰해봤습니다 ^^</code> 로 글을 제출하곤 했다.</p>
<p>시간에 대해서는 <code>이 주제로 글을 작성하면 참 좋겠다~</code> 라고 주제를 생각해놓고 
현생이 바빠지면 가장 먼저 글 작성을 후순위로 미뤄버렸다. </p>
<p>그래서 이번 기수에는 글을 작성할 글감을 미리 계획해놓고 
평소에 시간을 빼서 (마감주에 급박하게 말고) 글을 작성해보려 한다. </p>
<h3 id="글감">글감</h3>
<ul>
<li>Detection 관련 글<ul>
<li>최신 연구 논문, 동향 공부하고 정리</li>
</ul>
</li>
<li>경량화 관련 글<ul>
<li>onnx, TensorRT 실습 및 사용 방법 </li>
<li>2022 탑티어 학회 경량화 분야 논문 읽고 리뷰</li>
<li>업무에 적용가능한 경량화 기법 논문 찾아 읽고 리뷰</li>
</ul>
</li>
<li>도서 리뷰<ul>
<li>나를 바꾸는 아주 작은 습관의 힘</li>
<li>빠르게 실패하기</li>
</ul>
</li>
<li>추천 시스템 관련 백그라운드에 대한 글</li>
<li>실험 무결성 증명 및 분석에 대한 실습 글</li>
</ul>
<p>작성해놓고 보니 모든 주제가 엄청난 시간을 투자해서 공부해야하는 주제들 뿐이다.
이게 맞나 싶지만 지금 내가 공부를 해야할 때이긴 하니까 이게 맞다.
당장 내일부터 다음주 글을 작성해야 하니 이제 약속은 그만 잡아야겠다.</p>
<h3 id="시간">시간</h3>
<p>8기에서는 2주라는 글 작성시간 동안 
<strong>1주 반 (10일 정도)은 글을 작성하는 시간,
나머지 사나흘은 스스로 글을 피드백해보고 수정하는 시간</strong>으로 삼으려 한다. </p>
<p>모든 글이 공부가 선행되어야 하는 주제이니, 
글을 작성하는 10일 중에서도 <strong>7일 정도는 주제에 대해 공부하고 나머지 3일동안 글을 작성</strong>해보면 될듯 하다.</p>
<p>라고 세부 계획을 세워본다... 
계획을 세우면서도 이거 지키라고 세우는 계획맞나,,ㅎ 라는 생각이 들면 
스스로도 지킬 생각이 없는 거 맞나? </p>
<p>잠깐 시뮬레이션을 돌려봤는데, 이 계획에서 가장 중요한 것은
전 주에 미리 다음주 주제를 정하고 정했으면 <strong>일단 공부를 시작하는 것</strong> 인 것 같다.</p>
<h2 id="마무리">마무리</h2>
<p>최근에 친구들과 여행을 다녀왔는데, 여행 기간 사흘 내내 내가 핸드폰을 본 시간이 채 두시간도 안되었다는 걸 여행이 끝나고 깨달았다. </p>
<p>평소에 당장 눈 앞에 닥친 할일이 없으면 핸드폰부터 꺼내들고 시간을 하릴없이 낭비했는데,
여행을 가서는 당장 눈 앞에 할일이 보이고, 친구들도 다들 힘든 와중에 일하는 모습을 보니 
폰이고 나발이고 계속 일을 찾아 했던것 같다. </p>
<p>저걸 깨닫고 (ㅋ사실 알고 있었지만 생생한 실제사례를 경험하고) 
<code>시간나자마자 핸드폰을 들지말고 머릿속에 나열된 할 일을 해야겠다!</code> 고 생각했다.</p>
<p>생각이 들자마자 다음 날은 재택근무가 끝난 후 폰을 들고 침대로 다이빙하지 않고 
바로 옷을 갈아입고 헬스장에 갔다. 개운했다 !</p>
<p>갑자기 이 얘길 하는 이유는 글또 8기 내내 
저 간단해 보이는 
<strong>글 쓰는 습관 들이고 가독성과 형식 발전 시키기</strong>
라는 목표를 제대로 달성하려면 일단 하는 것!이 핵심이 될 듯해서 ... </p>
<p>8기가 끝날때쯤도 운동 후 느꼈던 개운함을 느낄 수 있도록 해야겠다! </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Luna: Linear Unified Nested Attention 요약 리뷰]]></title>
            <link>https://velog.io/@dust_potato/Luna-Linear-Unified-Nested-Attention-%EC%9A%94%EC%95%BD-%EB%A6%AC%EB%B7%B0</link>
            <guid>https://velog.io/@dust_potato/Luna-Linear-Unified-Nested-Attention-%EC%9A%94%EC%95%BD-%EB%A6%AC%EB%B7%B0</guid>
            <pubDate>Mon, 02 Jan 2023 05:54:25 GMT</pubDate>
            <description><![CDATA[<h2 id="luna-linear-unified-nested-attention-neurips-2021"><a href="https://proceedings.neurips.cc//paper/2021/file/14319d9cfc6123106878dc20b94fbaf3-Paper.pdf">Luna: Linear Unified Nested Attention, NeurIPS 2021</a></h2>
<p><a href="https://github.com/XuezheMax/fairseq-apollo">github</a></p>
<h2 id="contribution">Contribution</h2>
<ul>
<li>Luna: Linear Unified Nested Attention 제안 <ul>
<li>두개의 중첩된 linear attention 함수로 softmax attention 을 대체함</li>
<li>time and space complexity 를 linear 하게 만듬</li>
<li>long-context sequence modeling, neural machine translation and
masked language modeling for large-scale pretraining 세 개의 sequence modeling 파트에서 좋은 성능을 기록함<img src="https://velog.velcdn.com/images/dust_potato/post/8577ed7b-f11b-4fda-ae4c-7127e29b36c4/image.png" alt=""></li>
</ul>
</li>
</ul>
<h2 id="abstract">Abstract</h2>
<h3 id="motivation">Motivation</h3>
<ul>
<li>Transformer 모델의 softmax attention(full attention)으로 인한 quadratic complexity problem을 해결하기 위함</li>
</ul>
<h3 id="method">Method</h3>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/07239f40-2f20-40b7-8b51-f553df10da33/image.png" alt=""></p>
<ul>
<li><p>Luna attention : linear unified nested attention
regulat attention function을  linear efficiency를 가진 두 개의 nested atention으로 분리
how?</p>
<ul>
<li>original query and context input sequences 대신 fixed (constant) length를 가진 extra input 사용</li>
<li>Packed and Unpacked attention</li>
</ul>
<ol>
<li><p>Packed attention : first attention. context sequence C 를 fixed length extra input sequence P 와 attention 하여 fixed-length sequence $Y_P$를 생성. 이때 사용하는 attention 은 regular attention function임. 
$$
Y_P = Attn(P, C)
$$
P의 길이는 fixed length l이고, 기존 context sequence C의 길이는 m이라고 하면 packed attention의 시간 복잡도는 $O(lm)$이며, l이 상수이기 때문에 m에 의존함. output $Y_P$의 길이는 P와 같은 l.</p>
</li>
<li><p>Unpacked attention : second attention. packed attention의 output을 다시 original query sequence X의 길이와 동일하게 만들어줌. 
$$
Y_X = Attn(X, Y_P) 
$$
X의 길이는 n이고, $Y_P$의 길이가 l이기 때문에 unpacked attention 시간 복잡도는 $O(ln)$이며, l이 상수이기 때문에 n에 의존함.</p>
</li>
<li><p>Encoding Contextual Information in P
Extra input sequence P는 어디서 왔을까. 
1, 2의 수식을 합치면 $Y_X, Y_P = LunaAttn(X, P, C)$ 이 되는데, LunaAttn을 여러개 쌓아서 multiple layer를 만들고 이전 layer에서 나온 Y_P 를 P로 사용.(이렇게 해해야 C의 contexual information을 이용할 수 있기 때문에) 
첫번째 layer에서의 P는 learnable positional embedding을 사용함.</p>
</li>
</ol>
</li>
<li><p>architecture of each Luna layer
$$
\begin{aligned}
Y_X, Y_P &amp; =\operatorname{LunaAttn}(X, P, C) \
X_A, P_A &amp; =\operatorname{LayerNorm}\left(Y_X+X\right), \text { LayerNorm }\left(Y_P+P\right) \
X^{\prime}, P^{\prime} &amp; =\operatorname{LayerNorm}\left(\operatorname{FFN}\left(X_A\right)+X_A\right), P_A
\end{aligned}
$$
$X^{\prime}, P^{\prime}$ 은 Luna Layer의 두개의 output. </p>
</li>
</ul>
<h2 id="take-a-home-message">Take a home message</h2>
<p>두개의 linear unified nested attention 구조로 성능을 좋게 유지하면서 attention function의 time complexity 를 linear하게 만들 수 있음.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2022년 회고 - AI Engineer로서 첫 직장 적응기와 멘토링 이야기]]></title>
            <link>https://velog.io/@dust_potato/2022%EB%85%84-%ED%9A%8C%EA%B3%A0-AI-Engineer%EB%A1%9C%EC%84%9C-%EC%B2%AB-%EC%A7%81%EC%9E%A5-%EC%A0%81%EC%9D%91%EA%B8%B0%EC%99%80-%EB%A9%98%ED%86%A0%EB%A7%81-%EC%9D%B4%EC%95%BC%EA%B8%B0</link>
            <guid>https://velog.io/@dust_potato/2022%EB%85%84-%ED%9A%8C%EA%B3%A0-AI-Engineer%EB%A1%9C%EC%84%9C-%EC%B2%AB-%EC%A7%81%EC%9E%A5-%EC%A0%81%EC%9D%91%EA%B8%B0%EC%99%80-%EB%A9%98%ED%86%A0%EB%A7%81-%EC%9D%B4%EC%95%BC%EA%B8%B0</guid>
            <pubDate>Thu, 29 Dec 2022 05:55:01 GMT</pubDate>
            <description><![CDATA[<h2 id="글-개요">글 개요</h2>
<p>2022년을 되돌아보며 내가 했던 일과 고민을 정리하고 내년을 계획하는 글.</p>
<h2 id="2022년">2022년</h2>
<p>2022년은 정말 바쁘고 또 바쁘게 산 해였다. 성장에 대한 욕심이 있어서 일도 공부도 해볼 수 있는 건 다 해보려고 했다. 그러다보니 시간 관리나 공부 깊이에 대한 아쉬움도 남지만 이 부분은 2023년에 보완해볼 수 있을 것 같다. </p>
<p>2022년에 내가 한 일들을 되돌아 보면,,</p>
<ul>
<li>AI Engineer로 취업</li>
<li>부스트캠프 AI Tech 4기 멘토 </li>
<li>AI 경량화 스터디 참여</li>
<li>글또 7기 참여 </li>
<li>하고 싶었던 취미 도전</li>
</ul>
<h3 id="ai-engineer로-취업">AI Engineer로 취업</h3>
<p>2021년 말에 SI 기업에 합격하여 1월부터 일을 하고 있었다. 다만 AI 직군이 아니었고, SI 기업의 특성 상 요청이 들어오면 그 일을 해결만해주었다.
어떤 서비스를 도맡아 개발하며 개선점을 찾는다든가, 내가 직접 기능을 구현한다든가 하는 일은 할 수 없었다. 
OJT 기간부터 지라 티켓이 할당되어 아무것도 모르는 내가 관련 담당자들과 연락하며 티켓을 쳐내는 일을 반복하다보니 큰 회의감이 들었다.
내 일에 대한 욕심도, 책임감도 없어졌고 빠르게 이직을 결심했던 것 같다. 
(사실 신입 취업이니 이직이라고 말하기도 애매하긴 하다.)</p>
<p>당시 내가 원하는 이커머스 기업의 AI Enginner에 서류합격을 한 상태였고, 면접을 포기하지 않고 진행한 결과 합격! 을 하게 되었다.
현재 회사는 po들, 개발자들과 함께 서비스에 대해 고민하고, 해당 서비스는 어떤 데이터, 모델, 학습 방법을 사용해야 할까를 토의하며 내가 개발하는 서비스에 대한 애착을 키울 수 있는 곳이다. 
또 AI 직군이다 보니 내가 배울 수 있는 점이 많아서 사수를 붙잡고 미친듯이 질문하며 일을 하고 있다. </p>
<p>입사한 후 해본일을 정리해보면 다음과 같다. </p>
<ul>
<li>논문 읽고 모델 프로토타이핑</li>
<li>데이터 수집 및 라벨링 방법에 대한 가이드를 제공</li>
<li>프로덕션 시스템에서 실행할 수 있도록 모델 최적화</li>
<li>문제 해결을 위한 가설 제시 및 검증 수행</li>
<li>서비스 요구사항 고려하여 모델 성능에 대한 메트릭 정의 및 측정</li>
</ul>
<p>물론 지금은 이 일을 팀 개발자 분들의 도움을 받아 시도해보고, 개선해보는 과정이지만 
취업 전 꿈꿔왔던 일을 해볼 수 있음에 감사하고, 아쉬운 점은 앞으로 보완해나가면 될 것이다. </p>
<h3 id="부스트캠프-ai-tech-4기-멘토">부스트캠프 AI Tech 4기 멘토</h3>
<p>부스트캠프 AI Tech 4기에 CV 분야 멘토로 참여했다. 
AI를 공부하는 멘티들을 만나 기술에 대한 피드백, 취업과 진학에 대한 고민 상담, 그 외 개발자에게 필요한 스킬이나 전공 지식, 현업 업무 경험을 공유드리는 일이다.
개인적으로 누군가에게 도움이 되는 일을 하고자하는 목표가 있었어서
퇴근 후 가장 많은 시간과 애정을 쏟은 일이다. </p>
<p>멘토링을 하며 참 많은 고민을 했다. </p>
<ul>
<li>기술 멘토링을 위한 공부 </li>
<li>듣는 사람이 이해하기 쉬운 자료를 만들고 설명하는 방법</li>
<li>고민에 대한 해결책을 원하는 분들과의 고민상담을 하며 <ul>
<li>부드러운 커뮤니케이션 방법</li>
<li>지쳐있는 감정도 위로하고, 원하는 해결책도 제시할 수 있는 방법</li>
<li>(내가 해결할 수 없는 방안의 경우) 포기보다는 본인이 (스스로 원하는대로) 해결할 수 있도록 유도하는 방법</li>
<li>갈등 상황에서 멘토가 중재할 수 있는 방법</li>
</ul>
</li>
</ul>
<p>회사에서는 아무것도 모르는 막내인 내가 멘티들에게는 먼저 어떤 것을 성취한 사람이 되어 나의 경험과 깨달음, 지식을 공유한다는 괴리가 날 힘들게도 했었다. 
하지만 그 감정에 빠져있기 보다는 괴리를 메꾸기위해 더 미친듯이 공부하고 
멘티들의 입장에서 생각하며 그들에게 필요한게 뭘까 고민하고 준비하는데에 시간을 썼다. 
내게 도움을 구하는 분들께 부끄럽지 않으려고 노력하는 시간이 힘들기보다 행복했다!</p>
<p>그럼에도 지칠때는 부족한 내게 멘티분들이 전하는 한마디가 정말 큰 힘이 되었고,,, 나도 누군가에게 감사인사를 전하는 일은 절대 미루지 말아야겠다고 생각했다. 
<img src="https://velog.velcdn.com/images/dust_potato/post/dd82b201-86c5-46c4-8c0a-4717ca8cb886/image.png" alt=""></p>
<h3 id="ai-경량화-스터디-참여">AI 경량화 스터디 참여</h3>
<p>회사에서 모델 최적화를 진행하면서 모델 경량화에 대한 지식을 키우고자 스터디에 참여했다! 
스터디에 대단한 분들이 많아서 ,, 내가 그들이 하는 말을 10%라도 이해하려면 공부에 많은 시간을 할애해야 했다. 
이 부분에 있어서는 위의 두가지 일만해도 바빠서 내 공부를 하지 못했다는 아쉬움이 남는다. 
그래도 없는 시간 쪼개서 쫌쫌따리 <a href="https://velog.io/@dust_potato/WIL-EfficientVIT">논문도 읽고 글도 썼다</a>! 
<img src="https://velog.velcdn.com/images/dust_potato/post/2fb498b1-f2bb-49d4-bc3b-a41787590997/image.png" alt=""></p>
<p>2023년에는 경량화 관련 논문도 더 많이 읽고 실습도 해보면서 경험을 얻어가려고 한다. </p>
<h3 id="글또-7기-참여">글또 7기 참여</h3>
<p>글또 6기에 이어 7기에도 참여했다.
2022년에는 글또가 끝나고나서도 글을 작성해서 총 16개의 글을 썼다! 
아무리 바쁘고 지쳐도 글을 써야한다는 부담감은 있어야 글을 꾸준히 쓸 수 있다. 
회사 업무를 하며 배운 점, 읽은 논문, 읽은 책, 경량화 공부를 하며 쓴 글 다양한 주제에 대해 글을 썼다. </p>
<p>이번 기수에는 글또를 하며 개발자분들과의 커피챗과 글또콘이라는 컨퍼런스도 진행했다. 
커피챗은 나와 같은 AI Resercher, Engineer분들을 만나 얘기를 나누었는데, 
공통점도 많고 그들의 목표와 삶의 방식을 들으며 깨달은 점도 많아 참 즐거운 시간이었다.</p>
<p>글또콘에서도 다른 직군 개발자 분들이 Airflow 도입 후기, Test 코드 개발 방법, 개발 서적 리뷰 방법과 같은 흥미로운 발표를 준비해주셨다. 
그 중 개발 서적 리뷰 방법에 대한 발표를 듣고, 개발 서적은 아니지만 <a href="https://velog.io/@dust_potato/%EB%8F%84%EC%84%9C-%EB%A6%AC%EB%B7%B0-DEEP-WORK-%EB%94%A5-%EC%9B%8C%ED%81%AC">도서리뷰를 배운대로 써보기도 했다</a>. (ㅋㅋ 그분의 발표에 비하면 너무나 부족한 형식과 내용이지만,, 이렇게 또 하나를 배워간다는게 의미가 있다!)
<img src="https://velog.velcdn.com/images/dust_potato/post/33f0bb07-a960-48ec-a88f-c9ad337df962/image.png" alt=""></p>
<h3 id="하고-싶었던-취미-도전">하고 싶었던 취미 도전</h3>
<p>어릴 때 부터 춤추는 걸 좋아했지만,, 
항상 취미보다는 공부와 일을 우선시하는 성격이라 취미는 자꾸 미루고 미뤄왔었다.
취업을 하고 춤 학원에 등록해서 황금같은 주말마다 학원에 가서 춤을 배우는 시간을 가졌다. </p>
<p>두시간 미친듯이 흔들고 나면(ㅋㅋㅋ) 그 시간동안은 아무 생각도 안할 수 있고, 스트레스도 풀 수 있었다. 사실 학원에 초등학생 친구들이 참 많아서 그 속에서 혼자 춤 춘다는게 민망하고 부끄럽기도 했지만 ,,,ㅋㅋㅋ 부끄러움 보다 즐거움이 커서 후회하지 않는 도전이다! </p>
<h2 id="2022년에-얻은-것-깨달은-것">2022년에 얻은 것, 깨달은 것</h2>
<ul>
<li>여러가지 도전을 해보며,, 이전에는 도전하는 것이 설렘보단 두려움이 컸다면 
지금은 그 전에는 해보지 못한 맵을 경험한다고 생각하니 두렵지 않다. 도전하는 것도, 나이를 먹는 것도 즐겁다! </li>
<li>내 선택에 대한 모든 책임은 내가 져야한다. </li>
<li>일과 개인적인 공부는 방향이 같아야 더 효과적으로 성장할 수 있다. </li>
<li>누군가에게 내 경험을 전달할 때 이 경험이 절대 정답이 아니며 정답은 스스로 찾아야한다는 걸 꼭 상기시켜주자.</li>
</ul>
<h2 id="2023년에-해보고-싶은-것">2023년에 해보고 싶은 것</h2>
<ul>
<li><p>공부</p>
<ul>
<li>모델 경량화</li>
<li>모델 서빙 (MlOps-fastapi, mlflow, airflow 등)</li>
<li>추천 시스템</li>
<li>케글 대회 도전</li>
</ul>
</li>
<li><p>일 하면서 받는 선배 개발자분들의 도움 줄이기
(목표는 사수의 도움없이 하나의 완전한 기능 완성하기)</p>
</li>
<li><p>글 쓰는 습관 들이고 가독성과 형식 발전 시키기</p>
</li>
<li><p>퀄리티 있는 멘토링 자료 제작, 보완 / 피플 매니지먼트/멘토링 방법에 대한 공부</p>
</li>
<li><p>새로운 취미 개발해서 도전해보기!</p>
</li>
<li><p>책 여섯권 이상 읽기! </p>
</li>
<li><p>꾸준한 운동!!</p>
</li>
</ul>
<hr>
<p>여러모로 배운점이 많은 2022년이다! 
올해 얻은 걸 더욱 발전시킬 수 있는, 더 좋은 사람이 될 수 있는 2023년이 되길 바란다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[tensorflow2 딥러닝 모델에서 효율적인 입력 파이프라인 만들기]]></title>
            <link>https://velog.io/@dust_potato/tensorflow2-data-pipeline-multi-threading-using-.map-function</link>
            <guid>https://velog.io/@dust_potato/tensorflow2-data-pipeline-multi-threading-using-.map-function</guid>
            <pubDate>Thu, 22 Dec 2022 08:46:31 GMT</pubDate>
            <description><![CDATA[<p>tensorflow2 multi threading을 사용해서 효율적인 data pipeline을 구축하자! 
이 게시물은 tensorflow로 모델을 학습하기 전까지 사용되는 data pipeline 최적화에 대해서만 얘기하며, multi gpu 학습에 대해서는 논하지 않는다. </p>
<p>이미지를 처리하는 학습 파이프라인의 경우, 모델에 이미지를 넣기 전에 시간이 오래 걸리는 전처리를 해야하는 경우가 있다. 
예시 파이프라인 )</p>
<blockquote>
<ol>
<li>이미지 불러오기(image decoding)</li>
<li>이미지 전처리(image preprocessing)</li>
<li>이미지 벡터라이제이션(image vectorization)</li>
<li>모델 학습/예측 (model train/inference)</li>
<li>예측 결과 후처리 (vector postprocessing)</li>
<li>예측 결과 데이터베이스에 업로드 (upload to database)</li>
</ol>
</blockquote>
<p>이 경우 이미지를 하나씩 불러와서 모델에 넣기까지의 과정을 순차적으로 처리한다면 시간이 굉장히 오래 걸릴 것이다. </p>
<p>만약 전처리 과정이 미니배치를 통한 vectorization을 하지 못하고 꼭 한 장씩만 초리해야 한다면,,,
이미지 한 장당 전처리 과정이 0.3초가 걸리고, 이미지 갯수가 100만개라면 이미지 디코딩과 후처리, 모델 예측 시간을 제외하더라도 5000분, 83시간이 걸린다. (...)</p>
<p>이미지 전처리만 3일이 걸리는 상황을 피하려면 multi threading과 vectorization을 적절히 사용하면 시간을 단축할 수 있다. 
아래에서는 내가 어떻게 기존의 알고리즘을 .map, .batch function를 사용하여 변경했는지 예시를 적을 것이다. 
(글을 읽기 전 <a href="https://www.tensorflow.org/guide/data_performance?hl=ko">tensorflow 입력 파이프라인 빌드에 대한 설명 </a>을 참고하면 좋다.)
tf.data.experimental.CsvDataset 을 사용했다. </p>
<h2 id="사용-함수-설명">사용 함수 설명</h2>
<ol>
<li><p>.map(func, num_parallel_calls=tf.data.AUTOTUNE)
map 함수의 num_parallel_calls인자 설정해주기.
num_parallel_calls는 map으로 전달해준 함수를 처리하는데에 몇개의 thread를 사용할 것인지 정해준다. 사용자가 임의로 32,64 와 같이 숫자를 정해줄 수도 있고, tf.data.AUTOTUNE을 사용할 수도 있다. 
tf.data.AUTOTUNE으로 설정하면 tf.data 런타임이 실행 시에 동적으로 값을 조정하도록 만든다. (시스템이 알아서 최적의 thread 갯수를 찾아준다는 말)</p>
</li>
<li><p>.batch
batch 함수는 원하는 수대로 배치로 묶어준다. 배치로 묶는다는 것(vectorization)의 의미는 N 차원의 벡터로 나타낼 수 있는 데이터라면 어떤 함수를 N개의 데이터에 한꺼번에 처리할 수 있다는 것이다. 
예를 들어 jpeg 이미지 데이터를 64배치로 묶는다면 해당 벡터의 차원은 (tf 기준) (64, height, width, 3) 으로 나타낼 수 있다. 
사람이 해석하기에는 이 벡터가 &quot;3차원으로 이루어진 height, width 크기의 64개의 이미지&quot;로 해석되지만, 벡터 계산의 입장으로 보면 그냥 (64, height, width, 3) 의 shape을 가진 행렬을 계산하는 것과 같다. 
따라서 한번에 처리해도 관계없는 normalization(((image / 255.0) - mean) / std)과 같은 처리는 vectorization을 거친 후에 적용하는 것이 시간이 절약된다.</p>
</li>
<li><p>.prefetch
프로듀서(데이터를 생성하는 작업)와 컨슈머(학습, 인퍼런스와 같이 데이터를 소비하는 작업)을 병렬화한다. (컨슈머가 작업할 때 프로듀서가 가만히 기다리는게 아니라 동시에 데이터를 가져온다는 말)
prefetch 함수도 map과 마찬가지로 tf.data.AUTOTUNE을 인자로 전달하여 multi-thread로 돌아가도록 할 수 있다. </p>
</li>
<li><p>.interleave
이 함수는 tf.data.experimental.CsvDataset에서는 제공하지 않아 사용하지 못했다. (글 작성 시기 : 2022.12)</p>
<blockquote>
</blockquote>
<p><a href="https://www.tensorflow.org/api_docs/python/tf/data/experimental/make_csv_dataset">tf.data.experimental.make_csv_dataset</a> 을 사용하면 num_parallel_reads 인자를 통해 interleaving 할 수 있다. </p>
</li>
</ol>
<p>여러개의 데이터를 읽어와야 하는 경우 tf.data.AUTOTUNE을 사용하여 multi threading을 통해 읽어올 수 있다. </p>
<p>정리하면 다음과 같다.</p>
<blockquote>
<ul>
<li>multi threading : num_parallel_calls=tf.data.AUTOTUNE</li>
</ul>
</blockquote>
<ul>
<li>batch : 매핑 벡터화(mapping vectorization)</li>
<li>prefetch : 프로듀서, 컨슈머 작업 오버랩</li>
<li>interleave : 데이터 추출 병렬화</li>
</ul>
<h2 id="기존-알고리즘">기존 알고리즘</h2>
<ul>
<li><p>이미지 한장씩 처리할 수 밖에 없는 이미지 전처리 과정 </p>
<ul>
<li><p>이미지 디코딩, 전처리, 정규화(normalize)를 하나의 함수 안에서 진행</p>
</li>
<li><p>전처리에서 python for문으로 처리하는 과정 (매우 느림)</p>
</li>
<li><p>tensor를 np.array(tensor) 로 바꾸어 numpy 제공 함수 사용 (tensor &lt;-&gt; numpy 전환, numpy array 매번 생성)</p>
</li>
<li><p>동일 함수에서 이미지 normalize 진행 (normalize도 한장씩 해야 됨)</p>
<pre><code class="language-python">def tf_numpy_preprocess(path):
    def numpy_fn(_path):
        1. JPEG_manager.jpeg_decode_from_path로 이미지 디코딩
      2. 이미지 전처리 함수 호출 

    tf_tensor_list = tf.numpy_function(numpy_fn,
                                          [path], 
                                          [tf.float32, tf.string])
    return tf_tensor_list
</code></pre>
</li>
</ul>
<p>tfdataset = tf.data.experimental.CsvDataset(&#39;path&#39;, [&#39;None&#39;])
tfdataset = tfdataset.map(tf_numpy_preprocess, num_parallel_calls=tf.data.AUTOTUNE)
tfdataset = tfdataset.repeat(1)
tfdataset = tfdataset.prefetch(batch_size)
tfdataset = tfdataset.batch(batch_size, drop_remainder=False)</p>
</li>
</ul>
<h2 id="변경-알고리즘">변경 알고리즘</h2>
<ul>
<li>이미지 디코딩, 전처리, 정규화를 담당하는 세개의 함수 구현<ul>
<li>tf_image_decoding</li>
<li>tf_preprocess</li>
<li>image_normalization</li>
</ul>
</li>
<li>전처리에서 python for문으로 처리하는 과정 없애고 tf 에서 제공하는 함수 사용</li>
<li>tensor &lt;-&gt; numpy 변환 과정 없이 tensor로만, 기존 numpy 함수도 tf에서 제공하는 함수 사용 </li>
<li>map, prefetch, batch 적절히 사용해서 multi thread, vetorization</li>
</ul>
<pre><code class="language-python">def map_decorator(func):
    def wrapper(image, path):
        # 자동 그래프가 메서드를 컴파일하지 못하도록 tf.py_function을 사용
        return tf.py_function(
            func,
            inp=(image, path),
            Tout=(tf.float32, tf.string)
        )
    return wrapper


def tf_image_decoding(path):
    1. tf.io.decode_jpeg로 이미지 디코딩

    return [image, path]

@map_decorator
def tf_preprocess(image, _path):
    1. 이미지 전처리 함수 호출

    return image, _path


@map_decorator
def image_normalization(image,path):
    image = tf.cast(image, tf.float32)
    return ((image / 255.0) - mean) / std, path

tfdataset = tf.data.experimental.CsvDataset(&#39;path&#39;, [&#39;none&#39;])\
                    .map(tf_image_decoding, num_parallel_calls=tf.data.AUTOTUNE)\
                    .map(tf_preprocess, num_parallel_calls=tf.data.AUTOTUNE)\
                    .batch(batch_size, drop_remainder=False)\
                    .map(image_normalization, num_parallel_calls=tf.data.AUTOTUNE)\
                    .repeat(1)\
                    .prefetch(batch_size)</code></pre>
<h2 id="ref">Ref</h2>
<p><a href="https://www.tensorflow.org/guide/data_performance?hl=ko">https://www.tensorflow.org/guide/data_performance?hl=ko</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[WIL - EfficientVIT]]></title>
            <link>https://velog.io/@dust_potato/WIL-EfficientVIT</link>
            <guid>https://velog.io/@dust_potato/WIL-EfficientVIT</guid>
            <pubDate>Sun, 27 Nov 2022 08:24:03 GMT</pubDate>
            <description><![CDATA[<h2 id="vision-transformer-연구흐름">Vision Transformer 연구흐름</h2>
<ul>
<li>VIT(patch 개수 n에 따라 #operation quadratic하게 늘어나는 단점)
VIT는 특히 training data size, model size가 클 때 global information, long-range interactions를 얻는 것은 CNN보다 뛰어난 성능을 보인다. </li>
</ul>
<h3 id="background">Background</h3>
<ul>
<li><p>Review of Linear Attention in NLP
우리가 잘 알고있는 Attention의 수식을 보면 다음과 같다.
$$
O_i=\sum_{j=1}^N \frac{\operatorname{Sim}\left(Q_i, K_j\right)}{\sum_{j=1}^N \operatorname{Sim}\left(Q_i, K_j\right)} V_j, \quad \text { where } Q=x W_Q, K=x W_K, V=x W_V
$$
${\operatorname{Sim}\left(Q_i, K_j\right)}$ 의 Similarity 함수로 Softmax(exp)를 사용하면 그 수식을 softmax attention이라고 부른다. </p>
<p>$A(Q, K, V)=\operatorname{softmax}\left(\frac{Q K^T}{\sqrt{d_k}}\right) V$<br>t시점의 디코더의 은닉상태 Q(Query) 벡터와 모든 시점의 인코더의 은닉상태 K(Key) 벡터를 dot product(내적) 하여 유사도를 구하는 과정이 있다. 
따라서 이 attention의 시간복잡도는 input sequence 길이인 n을 제곱한 $O(n^2)$이 된다. </p>
<p><strong>Linear Attention의 장점</strong>
Similarity 함수로 ReLU와 같은 kernel fuction을 사용하면 Linear Attention이라고 부른다.
$$
\operatorname{Sim}(Q, K)=\phi(Q) \phi(K)^T
$$
이 때의 Attention 수식은 아래처럼 정리할 수 있다. 
$$
O_i=\frac{\sum_{j=1}^N\left(\phi\left(Q_i\right) \phi\left(K_j\right)^T\right) V_j}{\phi\left(Q_i\right) \sum_{j=1}^N \phi\left(K_j\right)^T}=\frac{\sum_{j=1}^N \phi\left(Q_i\right)\left(\phi\left(K_j\right)^T V_j\right)}{\phi\left(Q_i\right) \sum_{j=1}^N \phi\left(K_j\right)^T}=\frac{\phi\left(Q_i\right)\left(\sum_{j=1}^N \phi\left(K_j\right)^T V_j\right)}{\phi\left(Q_i\right)\left(\sum_{j=1}^N \phi\left(K_j\right)^T\right)} \text {. }
$$
이렇게 정리가 되면 $\left(\sum_{j=1}^N \phi\left(K_j\right)^T V_j\right)$ 과  $(\sum_{j=1}^N \phi\left(K_j\right)^T)$ 를 한번씩만 계산하고 재사용하면 되기 때문에 시간복잡도와 메모리 사용이 O(N)으로 줄어든다. (sequence의 길이 n이 d보다 작을 때)
<img src="https://velog.velcdn.com/images/dust_potato/post/e30a9cb3-e40d-4a65-8a53-f74931fe0f3f/image.png" alt="Attention is all you need(https://arxiv.org/pdf/1706.03762.pdf)">  </p>
<h6 id="httpsarxivorgpdf170603762pdf--attention-all-you-need-2017-vaswani-et-al"><a href="https://arxiv.org/pdf/1706.03762.pdf">https://arxiv.org/pdf/1706.03762.pdf</a> : Attention All You Need (2017) Vaswani et al.</h6>
</li>
</ul>
<h3 id="related-work">Related Work</h3>
<ul>
<li>Vision Transformer</li>
</ul>
<ul>
<li>Efficient Vision Transformer</li>
</ul>
<blockquote>
<p>[Efficient Transformer]
<strong>&lt;attention module의 complexity를 줄이자! 는 논문&gt;</strong>
<a href="https://arxiv.org/abs/2103.14030">Swin Transformer, 2021</a>
이미지를 window로 나누어 local window 내에서만 self-attention을 수행함
[PVT(Pyramid Vision Transformer)](Pyramid Vision Transformer)
Spatial Reduction Attention(SRA) : attention 전에 key, value의 spatial 사이즈를 줄이는 방법
<a href="https://arxiv.org/abs/1801.04381">MobileVIT V2, 2018</a>, <a href="https://arxiv.org/abs/2006.04768v3">Linformer, 2020</a>
token을 projection해서 차원을 줄이는 방법
<a href="https://proceedings.neurips.cc//paper/2021/file/14319d9cfc6123106878dc20b94fbaf3-Paper.pdf">Luna: Linear Unified Nested Attention</a>
NLP - Machine Translation 분야에서 나온 논문이긴 한데 좋은 성능(<a href="https://paperswithcode.com/dataset/lra">LRA score</a>)을 보였으며, 이런 접근도 가능하다는 걸 보이기 위해 첨부함 
<img src="https://velog.velcdn.com/images/dust_potato/post/14964699-931f-4580-9ea8-84b4ac26b1fd/image.png" alt="">
linear unified nested attention - attention을 두번 겹쳐서 수행하여 Q, K의 사이즈를 다르게 해서 $O(N^2)$의 시간 복잡도를 linear하게 만듬.</p>
</blockquote>
<p>X-former 시리즈
Performer - <a href="https://arxiv.org/abs/2009.14794v4">https://arxiv.org/abs/2009.14794v4</a>
Linformer - <a href="https://arxiv.org/abs/2006.04768v3">https://arxiv.org/abs/2006.04768v3</a>
Reformer - <a href="https://arxiv.org/abs/2001.04451v2">https://arxiv.org/abs/2001.04451v2</a>
Mobileformer - <a href="https://arxiv.org/abs/2108.05895v3">https://arxiv.org/abs/2108.05895v3</a></p>
<h2 id="efficientvit"><a href="https://arxiv.org/pdf/2205.14756.pdf">EfficientVIT</a></h2>
<p>EfficientViT: Enhanced Linear Attention for
High-Resolution Low-Computation Visual Recognition</p>
<h3 id="1-abstract">1. Abstract</h3>
<p>Input resolution에 따라 computational complexity가 quadratic하게 증가하는 VIT (softmax attention을 사용하기 때문)
Swin, PVT와 같은 방법은 비용을 줄이기 위해 local window 내의 softmax attention을 제한하거나 key/value tensor의 resolution을 작게 만들었지만 이는 VIT의 이점인 global feature extraction의 성능도 제한해버린다. </p>
<blockquote>
<p>softmax attention을 제한 ?? 
Swin Transformer의 경우 window 단위로 self attention을 진행하기 때문에 complexity가 image size에 대해 linear하다. </p>
</blockquote>
<p>따라서 본 논문에서 제안하는 EfficientVIT는 다음의 방법을 제안한다. </p>
<ul>
<li>local feature extraction ability를 향상시키기 위해 softmax attention 대신 linear attention with depthwise convolution 사용
이를 통해 EffinientVIT는 linear computational complexity안에서 global and local feature extraction capability를 유지한다. 
이를 통해 COCO 에서 EfficientDet-D1과 비교했을 때 2.4 AP while having 27.9% fewer MACs인 <strong>42.6 AP with 4.4G MACs</strong> 달성했다. 등등</li>
</ul>
<h3 id="2-introduction">2. Introduction</h3>
<p>low-resolution &amp; high-computation region에서는 VIT가 좋은 성능을 보이지만, <strong>high-resolution &amp; low-computation scenarios에서는 CNN보다 성능이 떨어진다.</strong> 
<img src="https://velog.velcdn.com/images/dust_potato/post/cd170cd2-71d8-481a-a7d7-bfc8b12253fc/image.png" alt="">Figure 1의 왼쪽 그래프가 COCO dataset에서 VIT-based, CNN-based one-stage detector들을 비교한 것이다. 둘 사이에 160G MACs의 큰 차이가 있다.</p>
<p>이런 차이가 나는 이유는 VIT에서 computational bottle neck을 유발하는 softmax attention module 때문인데, 이 모듈의 computational cost는 input resolution이 커짐에 따라 quadratically하게 증가하기 때문이다.</p>
<p>이를 해결하기 위한 가장 정확한 첫번째 방법은 input resolution을 줄이는 것이지만, 자율주행이나 의료 이미지 프로세싱과 같은 분야는 high-resolution이 필수적이다. 위 사진의 맨 오른쪽 사진이 Cityscapes dataset에서의 mobileNetV2의 input resolution에 따른 성능(mIOU)차이를 보여준다.<br>input resolution을 1024x2048에사 512x1024로 줄였을 때, 성능은 12%(8.5 mIOU)하락한다. model의 사이즈를 늘리는 것으로는 MACs가 3.6배 증가했음에도 불구하고 input resolution을 증가시킨 것만큼의 performance는 나오지 않는다. </p>
<p>두번째 방법은 softmax attention을 할 때 fixed-size local windows를 사용하여 attention scope을 제한하거나, key/value tensor dimension을 줄이는 방법도 있다. 하지만 이러한 방법은 VIT의 가장 큰 장점인 non-local attention capability(the global receptive field)를 감소시켜서 large-kernel CNN보다 안좋은 예측을 하게된다. </p>
<p>그래서 이 논문에서는 EfficientDet보다 COCO map 3.8이 높으면서 MAC은 더 적고 , YOLOX와 비교했을때는 67.2% 의 computional cost를 감소한 모델인 EfficientVIT를 제안한다. 
이는 이전 논문들처럼 softmax attention을 제한하여 사용하지 않고, linear attention(<a href="https://arxiv.org/abs/2006.16236">Transformers are RNNs: Fast Autoregressive Transformers with Linear Attention, 2020)</a>을 사용한다. 
linear attention의 가장 큰 장점은 softmax attention과 같이 $N^2$의 attention map을 유지하는 것이다. 하지만 matrix multiplication 과정에서 전체 attention map을 계산하지 않도록 하여 linear computational complexity를 가지고 softmax attention의 global feature extraction capacity를 유지한다. </p>
<p>Linear Attention의 장점은 두가지가 있다.</p>
<ul>
<li>Softmax Attention과 마찬가지로  $N^2$의 attention map을 사용한다는 것인데, matrix multiplication의 associative property를 활용해서 전체 attention map을 명시적으로는 계산하지 않게하여 계산복잡도를 linear하게 유지하면서 softmax attention의 global feature extraction capacity를 유지한다. </li>
<li>Softmax를 사용하지 않아 mobile에서 사용하기에 좋다. </li>
</ul>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/3a5a3e89-db16-4d4e-b12f-dc8403d1b950/image.png" alt=""> Figure2의 맨 왼쪽 그래프를 보면 비슷한 MACs 일 때 Linear attention은 softmax attention에 비해 3.3~4.5배까지 빨라진다. (MAC를 맞추기 위해 linear attention을 사용할 때는 multi-head의 갯수를 늘렸다.)</p>
<p>그러나 linear attention은 바로 적용하는 것은 단점이 있다. 이전 연구들에서 linear attention 과 softmax attention 간의 큰 performance gap을 보였다. Figure5 중간 그래프를 보면 ImageNet top1 acc이 linear attention을 사용했을 때 1.4% 감소한다.
<img src="https://velog.velcdn.com/images/dust_potato/post/0c3dfd90-7d3a-47ed-923b-9f8b71f8b5b6/image.png" alt=""></p>
<p>두 attention의 차이는 linear attention은 non-linear attention score normalization scheme이 부족하다는 것이다. linear attention이 local pattern에서 만들어진 high attentention score에 attention 분포를 집중시킬수 없게하여 local feature extraction capacity를 떨어뜨린다. 이는 attention map을 시각화한 아래의 사진에서도 볼 수 있다.<img src="https://velog.velcdn.com/images/dust_potato/post/0c29d6c9-dabe-463a-a2a8-4a2c026d7bea/image.png" alt=""></p>
<blockquote>
<p>non-linear attention score normalization? 
attention score를 얻고 softmax 를 취해 attention distribution을 얻는 과정,,, softmax가 아닌 ReLU 사용시 음수값은 0이 되어 attention 분포의 표현력이 제한된다는 말인듯 </p>
</blockquote>
<p>따라서 이 논문에서는 linear attention의  low complexity and low hardware latency를 살리기 위해 각 FFN layer의 사이에 depthwise convolution을 넣은 enhance linear attention구조를 제안한다. 
(근데 구체적으로 어떻게 했는지는 논문에서 안알려줌(코드 공개도 안함))</p>
<p>기존의 mobile VIT 모델(<a href="https://paperswithcode.com/paper/mobile-former-bridging-mobilenet-and">Mobile-former</a>, <a href="https://paperswithcode.com/paper/mobilevit-light-weight-general-purpose-and">MobileVIT</a>, <a href="https://paperswithcode.com/paper/nasvit-neural-architecture-search-for">NASVIT</a>)들은 parameter size와 MAC를 감소시키는 것에 집중했지만 이 논문에서는 mobile device에서의 latency를 감소시키는 것에 집중했다. 따라서 앞선 모델들과 달리 complicated dependency, hardware inefficient operations가 없다. </p>
<ul>
<li>contribution 요약<ul>
<li>ViT architecture를 사용한 high-resolution low-computation visual recognition 연구. Linear Attentiond이 Softmax Attention의 대안이며 하드웨어 친화적이라는 것을 밝혔다.</li>
<li>enhanced linear attention 제안하여 linear attention의 약점인 local feature extraction을 보완. </li>
<li>EfficientViT based on our enhanced linear attention 제안. (COCO object detection, Cityscapes semantic segmentation, ImageNet classification)에서 nas나 kd같은 add-on technique 없이 CNN-based models( (e.g., EfficientDet, SegFormer, EfficientNet))보다 높은 성능을 기록.</li>
</ul>
</li>
</ul>
<h3 id="3-method">3. Method</h3>
<ul>
<li><p><strong>Enhancing Linear Attention with Depthwise Convolution</strong>
linear attention 이 softmax attention보다 computational complexity and hardware latency는 뛰어나지만, NLP, Vision 태스크 모두에서 성능이 떨어진다는 연구가 있었다. 
이 원인을 local feature extraction capacity라고 생각했다. Softmax attention과 linear attention을 사용했을 때 attention score를 시각화해보면
linear attention을 사용했을 때 local pattern에서 만들어지는 high attention scores 에 집중하지 못하는 것을 볼 수 있다. 
<img src="https://velog.velcdn.com/images/dust_potato/post/73338943-28f3-47ca-82e3-54030d8583e4/image.png" alt="">이를 해결하기 위해 local feature axtraction에 큰 강점을 갖는 depthwise convolution을 FFN layer사이에 끼워넣어 computational overhead를 크게 발생시키지 않으면서 linear attention의 local feature extraction capacity를 보완했다. </p>
</li>
<li><p><strong>Building Block</strong>
<img src="https://velog.velcdn.com/images/dust_potato/post/f55a6b4b-100d-42f7-a3e3-17e6d54821df/image.png" alt="">
FFN layer with depthwise convolution의 블록구조는 위 Figure2의 맨 오른쪽과 같다. EfficientVIT에서는 이전 연구(<a href="https://arxiv.org/abs/2103.14030">SwinTransformer</a>, <a href="https://arxiv.org/abs/2106.04803">CoatNet</a>)들과 다르게 relative position bias를 사용하지 않았다. relative position bias는 모델의 성능을 향상시키지만, resolution이 달라지면 성능차이가 크게 난다. 이를 제거하여 EfficientVIT는 input resolution에 flexible하게 했다. </p>
<blockquote>
<p>relative position bias?
VIT에서의 positional encoding(PE)을 말함. <a href="https://paperswithcode.com/paper/segformer-simple-and-efficient-design-for">Segformer, NeurIPS 2021</a> 논문에서 resolution of PE는 고정되어 있기 때문에 test 시의 input resolution이 train에 사용한 resolution과 다르면 성능이 하락한다고 하며 A novel positional-encoding-free and hierarchical Transformer encoder 제안.</p>
</blockquote>
<p>또한 low-computation CNN 이전 연구들과 다르게, downsampling blocks을 위한 extra downsampling shortcut을 추가했다. 각 shortcut은 average pooling과 1x1 convolution을 한다. 이를 통해 학습을 안정화시키고 성능을 높였다. </p>
</li>
</ul>
<ul>
<li><p>Macro Architecture
<img src="https://velog.velcdn.com/images/dust_potato/post/b0c164e7-2b9f-4c3e-9007-b205e39173c7/image.png" alt="">EfficientVIT의 구조는 input stem과 4 stage로 이루어져있다. 최근 연구(<a href="https://arxiv.org/abs/2106.04803">CoatNet</a>, <a href="https://arxiv.org/abs/2104.01136">Levit</a>, <a href="https://arxiv.org/abs/2106.14881">Early convolutions help transformers see better</a>)들에서 early stage에서 convolution을 사용하는 것이 VIT에 더 낫다는 것을 보였으므로, enhanced linear layer를 stage3에서 시작한다. </p>
<p>efficient backbone의 hyper parameter는 <a href="https://arxiv.org/abs/1801.04381">MBConv(=MobileNetV2)</a>에서 사용한 ratio e를 그대로 사용(FFN도 e=4 그대로 사용), kernel size k=5 (input stem 제외).</p>
<blockquote>
<p>e?</p>
</blockquote>
<p>activation function 모든 레이어에 Hard Swish 사용. 
그림에서 P2, P3, P4는 feature pyramid를 위한 output feature. 
detection을 위해서는 YoloX를 사용, segmentation을 위해서는 <a href="https://arxiv.org/abs/1902.04502">Fast-SCNN</a>처럼 P2와 P4dmd fusion한 뒤 몇개의 convolution layer로 이루어진 lightweight head에 전달.
classification을 위해서는 <a href="https://arxiv.org/pdf/1905.02244v5.pdf">MobileNetV3</a>처럼 P4를 lightweight head에 전달.</p>
</li>
</ul>
<blockquote>
<p>요즘 VIT 연구는 trfmer+CNN이 아니라 CNN+ trfmer다? 
<a href="https://arxiv.org/abs/2106.04803">CoatNet</a>,<a href="https://arxiv.org/abs/2104.01136">Levit</a>, <a href="https://arxiv.org/abs/2106.14881">Early convolutions help transformers see better</a>
들에서 early stage에서 convolution을 사용하는 것이 VIT에 더 낫다는 것을 보였다. 
이유는 ? </p>
<blockquote>
<p><del>Transformer는 초기의 Input이 raw image patches에 대한 feature map의 sequence로 들어가게 된다.
하지만 hybrid model에서는 patch embedding이 특정 backbone model에 의해서 추출된 CNN feature map을 기반으로 적용된다. (원래 이미지에 대해 size가 줄어들고, 응축된 정보를 갖는다.)</del></p>
</blockquote>
</blockquote>
<h3 id="4-experiments">4. Experiments</h3>
<ul>
<li><p>Dataset 
COCO object detection, Cityscapes semantic segmentation, ImageNet classification</p>
</li>
<li><p>Model Architecture
build model around 400M MACs under a 224x224 input resolution
detailed configuration : C0=16, C1=24, C2=48, C3=96, C4=192; L1=2, L2=3, L3=5, L4=2</p>
</li>
<li><p>COCO object detection
<img src="https://velog.velcdn.com/images/dust_potato/post/2f75929e-bd7a-4a68-9fd3-f2ec6837ed06/image.png" alt=""></p>
</li>
<li><p>Cityscapes semantic segmentation
<img src="https://velog.velcdn.com/images/dust_potato/post/72d61c1f-f6df-488e-a0e3-6b1374e065ce/image.png" alt=""></p>
</li>
<li><p>ImageNet classification
<img src="https://velog.velcdn.com/images/dust_potato/post/aca1c435-e9dc-47de-9542-62a78a4d395e/image.png" alt=""></p>
</li>
</ul>
<h3 id="5-conclusion">5. Conclusion</h3>
<p>enhanced linear attention 구조를 통해
high-resolution low-computation visual recognition에서 비교적 적은 MAC와 더 좋은 성능을 달성함 </p>
<h4 id="ablation-study">Ablation Study</h4>
<p>enhanced linear attention의 효과를 알아보기 위해 ImageNet에서의 Top1 Acc을 측정했을 때, 0.3의 성능 향상을 보였으며 mobile device에서의 latency도 2.3배 빨랐다. 
<img src="https://velog.velcdn.com/images/dust_potato/post/da80f2f8-aef4-4809-8d5b-d05fbce4f2d2/image.png" alt=""></p>
<h3 id="6-discussion">6. Discussion</h3>
<hr>
<p>Limitations of Paper</p>
<ul>
<li>Latency data 부족하여 제대로 된 결과분석 불가</li>
<li>Limited Novelty : Depthwise Convolution with FFN</li>
<li>Unfair Comparison<ol>
<li>Data Augmentation</li>
<li>HardSwish Activation </li>
<li>MAC vs #Params , What to optimize?</li>
</ol>
</li>
</ul>
<blockquote>
<ul>
<li>Latency data 부족하여 제대로 된 결과분석 불가, batch size도 1로 둠.
On Qualcomm Snapdragon 855 CPU, EfficientViT runs 3×faster than EfficientNet while providing higher ImageNet accuracy</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li>Limited Novelty : Depthwise Convolution with FFN
FFN에 Depthwise 를 섞은게 어떤 의미일까?<blockquote>
<p>seq len(spatial) * hidden dim(channel)
FFN은 각 tocken의 channel을 독립적으로 섞음. 여기에 Depthwise를 섞는다는 말은 각 patch tocken의 channl정보를 섞을 때 spatial 하게 옆에 있는 tocken 정보를 본다는 말 아닐까? </p>
</blockquote>
</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li>Unfair Comparison - 1. Data augmeantation
VIT는 inductive bias가 부족해서 augmentation 많이 해야한다?는 연구? 
<del>-&gt; 각 논문마다 적용한 augmeatation 정도가 달라 절대적 비교가 어렵다. 
논문 신뢰도의 문제라기보단 그냥 연구흐름을 파악하는 것에 집중하자.</del> </li>
</ul>
</blockquote>
<blockquote>
<ul>
<li>Unfair Comparison - 2. HardSwish Activation
hard swish function을 쓰면 왜 좋을까<blockquote>
<p>mobile CPU에서 inference를 하게 되면 swish를 쓰는 것보다 hard swish를 쓰는게 latency 측면에서 훨씬 효율적입니다. sigmoid를 계산하는게 꽤나 비싸기 때문에 이를 linear 연산들로 근사한 hard swish가 더 빠릅니다. 이는 MobileNetV3 논문에서 잘 설명해주고 있으니 참고하시면 되겠습니다. (<a href="https://arxiv.org/abs/1905.02244">https://arxiv.org/abs/1905.02244</a>)</p>
</blockquote>
</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li><p>Unfair Comparison - 3. MAC vs #Params , What to optimize?
Experiments의 표를 보다보면,, 성능은 향상했는데 정작 Parameter 수는 늘어나는 것을 볼 수 있다... (semantic segmentation에서 SegFormer와 비교하는데 MAC는 62.8G -&gt; 19.1G 로 줄었지만 param수는 3.8M -&gt; 6.5M으로 늘었다든가 하는,,,) </p>
<p>Efficient AI 연구에서는 어떤 metric을 optimize 해야할까? </p>
<blockquote>
<p>너무나 당연히 case-by-case로 달라집니다. task, model, target HW, target performance 에 따라 달라질 수 있겠네요. 예를 들어 MCU처럼 SRAM이나 Flash memory가 극도로 부족한 환경에서는 params나 peak memory usage를 줄여서 느리더라도 돌아갈 수 있게 만드는게 중요할 것이고, GPU 기반으로 실제 서비스를 운영하는 상황인데 메모리는 넉넉하다고 하면 MACs를 줄여서 빠르게 만드는게 좋겠죠. 목표가 있고, 현재 상태를 분석하면 무엇을 줄여야하는지 정해진다고 봅니다. 당연히 둘다 줄일 수 있는게 best 겠고요.</p>
</blockquote>
</li>
</ul>
</blockquote>
<blockquote>
<p>현업에서 모바일에 임배드 할 수 있다고 한다면 혹시 모델의 크기 (param 수 혹은 용량)와 latency (혹은 대략적인 FLOPs)가 어느 정도면 모바일에 임배드할 수 있다고 주장할 수 있을까요? + MAC(=Flop)과 Parameter 수와 latency는 호응 가능한 metric일까? </p>
<blockquote>
<p>모바일 기종에 따라 엄청 다릅니다. 갤럭시와 아이폰만 해도 성능 차이가 꽤 나고, 갤럭시 중에서도 S9과 S22 뭐 이렇게 비교하면 성능차이가 어마어마합니다. RAM 크기는 기종에 따라 다르지만 보통 수 GB는 되기 때문에 그 안에 들어오면 어떻게든 올릴 수 있기는 할겁니다. (다른 앱들과 함께 안정적으로 동작시킬 수 있는지는 다른 얘기입니다.) 
latency는 또 case-by-case일텐데요, 애초에 real-time을 요구하는 서비스라면 40ms 정도는 되어야겠고, 이번에 아이폰에 업데이트된 누끼 따주는 segmentation 모델같은건 real-time까지는 필요하지 않으니 좀더 여유가 있을겁니다. FLOPs는 기종, 모델이 달라지면 latency로 translate하기 정말 어렵습니다.</p>
</blockquote>
</blockquote>
<h2 id="ref">Ref</h2>
<p><a href="https://deepseow.tistory.com/34">Vision Transformer의 이해와 Swin Transformer</a>
<a href="https://github.com/sjquan/2022-Study/discussions/28">2022 경량화 스터디 질답</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[파이콘 한국 2022 후기!]]></title>
            <link>https://velog.io/@dust_potato/%ED%8C%8C%EC%9D%B4%EC%BD%98-%ED%95%9C%EA%B5%AD-2022-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@dust_potato/%ED%8C%8C%EC%9D%B4%EC%BD%98-%ED%95%9C%EA%B5%AD-2022-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Sun, 02 Oct 2022 03:46:30 GMT</pubDate>
            <description><![CDATA[<h1 id="pycon-2022"><a href="https://2022.pycon.kr/">PYCON 2022</a></h1>
<p>Do Anything with Python
한국의 파이썬 개발자들이 지식을 공유하고 만남을 갖기 위한 장이다. 올해는 온/오프라인이 동시에 열렸다!
글또에서 얼리버드 타켓 구매기간이라고 알려주셔서, 내 첫 오프라인 행사를 다녀왔다 ㅎㅎ
오프라인 행사에 참여한 후기를 자세히 적어보겠다!
<img src="https://velog.velcdn.com/images/dust_potato/post/8c3a315c-2c90-461b-a2e6-a8954c6577aa/image.jpg" alt=""> <img src="https://velog.velcdn.com/images/dust_potato/post/a1564687-b860-4675-b8df-cc8d962a6c17/image.jpg" alt=""> 입장 팔찌와 세컷 사진 ㅎㅎ </p>
<h2 id="파이써니스타들의-강의발표를-듣고">파이써니스타들의 강의(발표)를 듣고</h2>
<p>파이콘 한국 2022 발표 주제와 영상은 <a href="https://2022.pycon.kr/program/talk-schedule">이 링크</a> 에서 확인할 수 있다! 
듣고 싶은 강의가 너무나 많았지만, 꼭 들어야 겠다는 강의를 뽑은 게 </p>
<blockquote>
<p>11:20 : (1) Serverless Python Web Services(15분)
(점심)
1:35 - (2) 잘될 연구 떡잎(15분)
1:55 - (1) 클릭한번 object detection model(30분)
2:35 - (2) 어린이를 위한 파이썬 교육용 서버리스 주피터 노트북 앱(30분)
3:15 - (2) Elastic Stack에서 PyTorch 자연어 처리 모델 (30분)
3:50 - (2) 모바일 네트워크 속 파이썬(15분)
4:10 - (1) Practical usage of python ecosystem(30분)</p>
</blockquote>
<p>ㅋㅋ 요렇게 정리를 했다. 이 중 몇개는 못들었지만,,,온라인으로도 발표를 즐길 수 있게 준비를 너무나 잘해주셔서 못들은 발표는 유튜브에서 보면 되니까 문제없다! 
강의를 듣고 느낀점을 간단히 적어보겠다! 강의의 구체적인 내용은 영상에서 확인할 수 있고, 이 글에서는 내가 느낀점 위주로 적을 것이다! </p>
<h3 id="openreview-분석-리뷰어들은-잘-될-연구의-떡잎을-알아볼까">Openreview 분석: 리뷰어들은 잘 될 연구의 떡잎을 알아볼까?</h3>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/0b099796-74a7-4b0c-bb96-519fa5be8a15/image.jpg" alt=""></p>
<p>OpenReview의 ICLR 컨퍼런스 리뷰 데이터와 Google Scholar에서의 논문 인용 데이터간의 상관관계를 분석해서 리뷰어들이 과연 잘 될 연구(이 분석에서는 잘된다=인용수로 정의함)에 좋은 리뷰를 남겼는지를 분석한 발표였다. 
결론은 &quot;아니다&quot;였다. 인상깊었던 점은 결과에 대한 원인을 3가지 이유로 파악해보고 해당 원인이 맞는지에 대한 추가 분석까지 진행한 점이었다. 사실 논문의 신뢰성을 파악할 때 잘 모르겠으면 피인용수를 봐라라고는 많이 얘기하는데 리뷰와 상관관계까지 분석할 생각까지는 못했다. 논문 생태계(?)를 잘 알고계신 분이구나 싶었고, 나도 논문을 읽기만 하지말고 언젠가 멋진 논문을 쓰겠다는 목표를 가지고 관심있게 살펴봐야겠다고 다짐했다.</p>
<h3 id="practical-usage-of-python-ecosystem-to-build-the-ai-model-to-fight-with-sars-cov-2-through-predictive-analytics-from-droplet-spread-dataset">Practical usage of python ecosystem to build the AI model to fight with SARS-CoV-2 through predictive analytics from droplet spread dataset</h3>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/37e1d66f-0f6f-4929-8ed0-99cda34c0c87/image.jpg" alt=""></p>
<p>공기 중의 비말이 퍼지는 데이터를 사용해서 코로나 감염 확률을 예측하는 모델을 만든 발표였다. 
전체 과정에서 pandas, scipy, tensorflow, jupyter notebook 등 python library를 야무지게 사용하셨는데, 이 중에 데이터를 필터링할 때 Scipy의 peak detection in series data 사용하고, 다른 라이브러리에서도 필요한 기능을 쏙쏙 골라 잘 사용했다. </p>
<p>이 발표를 보고 느낀 점은 각 라이브러리마다 어떤 기능이 있는지를 잘 알아야 연구를 효율적으로 진행할 수 있다는 것이다. 
얼마전 회사에서도 다른 팀에서 요청한 기능을 우리팀 시니어가 두시간 만에 완성한 일이 있었다. 
해당 업무의 핵심 기술은 open cv의 한 기능을 사용했는데, 이게 있는지 몰랐다면 어떤 기능을 써야할지 생각해보고 리서치 또는 구현을 하는데에 시간을 투자했어야 했을 것이다. 하지만 울 팀 시니어는 암튼 알고 있었던 것,,,
라이브러리를 구글링 없이도 완벽하게 코딩하는 것 보다는 해당 라이브러리에 어떤 기능이 있는지 알아둬야 야무지게 써먹을 수 있겠다는 생각을 했다. </p>
<h3 id="어린이를-위한-파이썬-교육용-서버리스-주피터-노트북-앱-만들기">어린이를 위한 파이썬 교육용 서버리스 주피터 노트북 앱 만들기</h3>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/eb634b71-2700-4511-85c1-779685205593/image.jpg" alt=""></p>
<p>말 그대로 어린이에게 파이썬을 교육하기 위한 앱을 만드는 발표였다. 
각 라이브러리가 어떤 커널을 사용하고... 어떻게 빌드가 되고... 각 패키지들을 바이너리로 써도 되는지, 안되는지 등 완전 밑단까지 분석(?)해서 환경 설정하고 개발......하시던데  난 평소에 이런거 신경도 안썼어서 거의 못알아들었다. 
되면 되고 오류나면 구글링해서 대충 해결만 했지 커널단까지 분석할 생각도 안했는데 난 가짜개발자라는 생각이 들었고 강의를 못알아듣는 내가 부끄러웠다. 좀 더 딥하게 제대로 공부하고 일해야겠다는 다짐을 했다.</p>
<h3 id="클릭-한번으로-만드는-object-detection-model">클릭 한번으로 만드는 Object Detection Model</h3>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/5b99d563-65f6-4e55-a5a6-f09aff0afae8/image.jpg" alt=""></p>
<p>모델의 준비기간이 서비스 요청을 따라갈수 없을때 빠르게 Object Detection Model을 만든 경험에 대한 발표이다.빠르게 만든거치고는 data augmentation이 상당히 고퀄이었다.
객체 증강도 하고, 여백도 자르고, Contour로 외곽선도 살리고, Augmentation한 객체와 실제 객체와의 차이를 최소화하려고 3d transform도 적용...
암튼 간단히 모델 개발 한거 치고는 할거는 다 한거여서 내 기준의 간단한것과 line^^ 기준의 간단한 것은 참 다르구나 느꼈으며.... 내 실력의 한계를 또 느꼈다.</p>
<p>파이콘 후기 이런거 쳐보면 모든 분들이 내 부족함을 느꼈다는 얘기를 하시던데,, 너무 공감이 됐다 ㅋㅋㅋ 
종종 이런 행사에 참여해서 다른 사람들은 어떤 방식으로 개발하는지 알아보는게 내 공부에 대한 약간의 경각심을 줘서 다시 공부할 수 있는 의지를 불태우기에 좋은 것 같다 ㅎㅎ</p>
<h2 id="파이콘-참여-기업과의-대화">파이콘 참여 기업과의 대화</h2>
<p>파이콘에 많은 기업이 참여해서 채용관련 부스도 운영하고, 그냥 개발 얘기를 가볍게 나눌 수 있도록 자리도 마련되어 있었는데, 그 중 몇개의 기업과 대화를 하고 느낀 후기이다. </p>
<p>기업 요기요랑 화해랑 대화를 해봤는데  다들 애자일 개발 방식을 활용하고 있었다.
특히 요기요의 경우 애자일과 관련하여 목표 및 기간을 설정하고 프로젝트의 방향을 재설정하는 것만을 담당으로 하는 역할이 po처럼 있었음. 애자일 헌터?? 라고 불렀나 이름이 기억이 안나네. 암튼...그래서 신기했다. 
회의도 2주에 한번씩 스프린트로 진행하고, 코드 리뷰도 굉장히 열심히 한다고 했다.
수평적인 대화와 투명한 토의를 위해 이런 방식을 사용한다고 했는데 좋은거 같다. </p>
<p>다만 조직이 커지면 애자일 방식은 조금 부담이 있지 않냐고 여쭤봤더니 
그러면 팀을 다시 스쿼드로 나누어서 애자일로 진행되도록 한다고 하셨다. </p>
<p>암튼 이 대화를 마치고 화해의 백엔드 개발자 분과도 얘기를 나눠봤는데 요기요와 마찬가지로 애자일 방식을 사용하고 팀 내에 디자이너, 기획자, 개발자 등이 하나의 &quot;팀단위-스쿼드&quot; 를 이루어서 개발을 진행한다고 한다.</p>
<p>많은 회사들이 전통적인 워터폴 방식의 업무환경을 벗어나고 있다는 걸 느꼈다. 우리 회사도 이거 관련해서 요즘 말이 많았다. 아직도 여러 시도를 하며 개선중인데 조직원이 많다보니 결정은 나지 않는 상태이다. 뭐가 좋은진 나도 모르겠다,,, 각각의 장단점이 있기에,,, 그냥 애자일로 개발하는 회사는 저렇게 일을하는구나~ 를 알 수 있는 좋은 기회였다. </p>
<p>원티드랩과도 얘기를 나눠봤는데, 개발자들의 채용과 커리어를 위한 서비스를 굉장히 많이 고민하시도라,,, 흠 비즈니스 분석의 중요성을 누구보다 잘 알고있으나..... 탑다운 방식의 업무환경을 겪다보니 이게 의미가 있나 싶기도 하고. 이건 좀 핑계긴한데. 회사 비즈니스 영역이 크다보니까 비즈니스 분석을 하기가 쉽지않다....라는 핑계 ㅋ 로 사용자들에게 어떻게해야 편리한 서비스를 제공할까는 고민을 아예 안했는데, 개발자분들이 그렇게 고민하시는 거 보니까 생각이 많아졌다.
암튼 지금 당장은 내가 업무를 배우고 실력을 키우는 것이 가장 중요하다고 생각하지만, 나중에는 저런 고민도 꼭 필요하다고 생각해서 이 대화가 굉장히 뜻깊게 다가왔다. </p>
<h2 id="파이콘-꿀팁">파이콘 꿀팁!</h2>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/9f054935-b506-4553-b62b-88a25a7f52e2/image.jpg" alt="">
파이썬과 관련한 꿀팁!  을 메모지에 적어 화이트보드에 붙이는 행사를 했다. 누가 엑셀 파일은 pd.DataFrame으류 읽어와라...라고 쓰셨길래 <a href="https://medium.com/towards-data-science/its-time-to-say-goodbye-to-pd-read-csv-and-pd-to-csv-27fbc74e84c5">며칠전 medium 에서 읽은 글</a>이 생각나서 
속도가 더 빠른 DataTable 라이브러리도 사용해보셔요 ㅎㅎ 라고 가벼운 마음으로 댓글을 달았다.</p>
<p>근데 앞에 나와서 발표하라고 시켜서 했는데...사용 경험도 없고, 원리도 모르고, 그냥 medium에서 본글 공유하는 생각으로 써봤다. 고 말하는데 나 리서쳐 맞냐... 좀 부끄러웠다. 이게 왜 빠른지 분석을 해보든가...직접 써보고 진짜 빠른게 맞는지 확인을 해보든가 할걸 ㅜ 너무 민망했다. </p>
<h2 id="전체적인-느낀점">전체적인 느낀점</h2>
<p>파이콘인 만큼 모두 파이썬 유저였는데, D.jango, fastapi 등 파이썬 기반의 기술스택을 많이 사용하셨다. 내가 경험이라도 있으면 이것저것 여쭤봤을텐데... 내 파이썬 경험은 ML/AI에 한정되어 있어서 아쉬웠다.
사실 난 아직 AI 분야에서도 내가 너무나 부족해서 다른 것을 공부할 여유가 없는데...
암튼 연차가 좀 쌓이면 이런것도 공부해서 파이콘에서 모든 발표를 이해할 수 있는 수준이 됐으면 좋겠다. </p>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/95c7f7b6-1c8a-4059-a404-b66636703d3b/image.jpg" alt="">그리고 돈이 아깝지 않은 파이콘 굿즈!!! 파이썬 티셔츠가 젤 맘에든다 하하하 !! Do Anything with python!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[도서 리뷰] DEEP WORK, 딥 워크]]></title>
            <link>https://velog.io/@dust_potato/%EB%8F%84%EC%84%9C-%EB%A6%AC%EB%B7%B0-DEEP-WORK-%EB%94%A5-%EC%9B%8C%ED%81%AC</link>
            <guid>https://velog.io/@dust_potato/%EB%8F%84%EC%84%9C-%EB%A6%AC%EB%B7%B0-DEEP-WORK-%EB%94%A5-%EC%9B%8C%ED%81%AC</guid>
            <pubDate>Sun, 04 Sep 2022 14:04:25 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/dust_potato/post/1e148d17-0837-48fe-81b2-dac6d2e4576b/image.png" alt="">
<strong>딥 워크 : 인지능력을 한계까지 밀어붙이는 완전한 집중의 상태에서 수행하는 직업적 활동. 딥 워크는 새로운 가치를 창출하고, 능력을 향상시키며, 따라하기 어렵다.</strong></p>
<h2 id="서두">서두</h2>
<p>저는 고등학교 2학년 때부터 스마트 폰을 없애고 인터넷이 되지 않는 2G 핸드폰을 사용했습니다. 인터넷으로 모든 인터넷 서핑과 엄청난 양의 동영상과 SNS 활동을 할 수 있었던 스마트 폰은 제겐 없어서는 안 될 존재였지만, 좋은 성적을 위해서는 없어야만 하는 존재이기도 했습니다. </p>
<p>학생때는 강제로라도 인터넷과 저를 분리할 수 있었으나, 직장인이 된 지금은 아침에 일어나서 잠이 들기 직전까지 손에서 스마트 폰을 놓지 못하는 사람이 되었습니다. 스마트 폰과 친하게 지낼 수록 일이나 공부에 오랜 시간 몰두하는 집중력도 점점 떨어졌습니다. </p>
<p>스마트 폰을 꺼놓고 온전히 업무에 집중하면 이해하려고 하는 논문을 내 것으로 만들고, 프로젝트에 필요한 기능을 엄청난 생산성과 함께 구현할 수 있다는 것을 저는 알고 있습니다. 저자는 이메일, SNS와 같은 네트워크 도구가 지식 노동자들의 집중력을 저하시키며, 이러한 산<strong>만한 정신상태가 지속되면 딥 워크를 수행하는 능력이 영구적으로 약화된다</strong>고 말합니다. </p>
<p><strong>일에 몰두하는 능력은 점점 희귀해지고 동시에 우리 경제에서 가치는 점점 높아지고 있습니다. 이 능력을 가진 소수는 성공할 것이라는 딥 워크 가설</strong>에 따라, 이 책에서는 몰입을 위한 전략을 소개합니다. </p>
<h2 id="책의-내용">책의 내용</h2>
<p>책은 1부와 2부로 나뉘어져 있습니다. 1부에서는 
딥 워크 가설이 사실임을 밝힙니다. 2부에서는 딥 워크를 위한 구체적인 방법을 제시합니다. </p>
<p>1부는 저자가 말한 것처럼 딥 워크가 삶에 있어서 얼마나 가치있고, 얼만큼의 생산성을 가져다주는지를 딥 워크를 통해 성공한 사람들의 예로 설명합니다. 시간이 없고, 이미 몰입과 집중의 중요성을 알고 있는 분이라면 1부는 넘어가도 된다고 말씀드리고 싶습니다. </p>
<p>2부에서는 다양한 삶의 방식을 예시로 들며 본인에게 맞는 딥 워크 방식을 찾을 수 있도록 가르쳐줍니다. 저자는 크게 네가지의 방법을 제시했는데, 첫번째는 딥 워크 습관을 개발하기 위해 몰두하는 것, 두번째는 산만함을 극복하기 위해 무료함을 받아들이는 것, 세번째는 소셜 미디어를 끊는 것, 네번째는 피상적 작업(딥 워크와 반대되는, 작은 가치를 생산하며 따라하기 쉬운 작업들)을 차단하는 것입니다. </p>
<h2 id="강한-집중력을-기르려면-훈련이-필요하다">강한 집중력을 기르려면 훈련이 필요하다</h2>
<p>이 책에서 가장 공감한 말입니다. 대다수의 사람들은 집중을 &quot;방법과 효용은 알지만 의욕이 없어서 무시하는 습관&quot;으로 여기는 경우가 많습니다.** 즉 의욕만 있으면 금세 집중할 수 있다고 생각합니다. 하지만 여기에는 집중의 어려움과 &quot;정신적 근육&quot;을 강화하는 데 필요한 오랜 수련이 빠져 있습니다.**</p>
<p>책의 2부 중 무료함을 받아들여라 파트에서는 이처럼 산만함에 중독된 두뇌를 오랜시간 집중할 수 있도록 훈련하는 방법을 제시합니다. </p>
<p>저자는 일주일 중 하루 동안 인터넷을 쓰지 않는 인터넷 안식일처럼 가끔 산만함에서 벗어나 집중하는 시간을 정할 것이 아니라,
가끔 집중에서 벗어나 산만함을 허용하는 시간을 정할 것을 제안합니다. </p>
<p>일주일에 하루만 몸에 좋은 식사를 한다고 건강해지지 않듯이, 우리 두뇌 또한 딥워크를 위해서는 꾸준한 집중력 강화 훈련이 필요하기 때문입니다.</p>
<p>일상생활에서 5분만 시간이 나도 스마트폰을 집어드는 제게 집중력을 향상하기 위한 적합한 해결책입니다.</p>
<h2 id="이런-사람들에게-추천합니다">이런 사람들에게 추천합니다</h2>
<p><strong>스마트폰 중독에서 벗어나 중요한 일에 오랜시간 집중하고자 하는 분들께 추천드립니다.</strong></p>
<p>스마트폰 없이는 일상생활이 불가능한 분들, 꼭 해야하는 일임에도 집중하지 못해 업무에 지장이 있으신 분들이라면 이 책을 통해 딥 워크의 중요성을 상기하고 두뇌를 훈련시키기 위한 방법을 얻어가는 것을 추천드립니다. </p>
<h3 id="개인적인-감상">개인적인 감상</h3>
<p>이 책의 전반적인 부분에서 딥 워크를 통해 성공한 사람들의 예시를 정말 많이 설명합니다. 끊임없이 예를 듭니다... 개인적으로는 책의 중반부부터는 사람 이름이 나오면 몇 문단을 건너뛰고 핵심문장만을 찾아 읽었습니다.</p>
<p>다양한 비유와 구체적인 실제 사례를 통한 교훈을 좋아하시는 분들이라면 책을 즐겁게 읽을 수 있을 듯 합니다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Context-Aware Visual Compatibility Prediction(CVPR 2019) 리뷰]]></title>
            <link>https://velog.io/@dust_potato/Context-Aware-Visual-Compatibility-PredictionCVPR-2019-%EB%A6%AC%EB%B7%B0</link>
            <guid>https://velog.io/@dust_potato/Context-Aware-Visual-Compatibility-PredictionCVPR-2019-%EB%A6%AC%EB%B7%B0</guid>
            <pubDate>Sun, 07 Aug 2022 10:28:49 GMT</pubDate>
            <description><![CDATA[<p><a href="https://arxiv.org/pdf/1902.03646v2.pdf">Context-Aware Visual Compatibility Prediction(CVPR 2019)</a></p>
<h2 id="abstract">Abstract</h2>
<p>compatibility 예측시 visual feature뿐 아니라 context도 고려함 (context는 논문에서 정의)
context를 고려하여 gnn으로 product embedding 생성 → 다른 metric learning처럼 pairwise하게 비교하지 않는다.
fitb : 96.9 / comp : 0.99 로 SOTA 달성</p>
<h2 id="intro">Intro</h2>
<ul>
<li><p>Issue &amp; Motivation
item들을 pairwise하게(독립적으로) 비교하면 최종적인 final prediction은 각 item을 독립적으로 비교한 후 모아놓은 것이다.
이 방법은 context를 고려하지 않기 때문에 주어진 clothing pair에 대해 항상 같은 예측을 하게된다.
Compatibility는 패션 감각과 트렌드가 변하면 함께 변하기 때문에 항상 같은 예측을 하는것은 문제가 있다.</p>
</li>
<li><p>Solution &amp; How
함께 입었을 때 어울리는 옷들에 대한 &quot;context&quot;를 정의하여 compatibility 예측시 visual feature와 context를 함께 고려하도록 했다.<img src="https://velog.velcdn.com/images/dust_potato/post/879a5739-8e7a-42f5-a9dd-a978a38a85ea/image.png" alt=""></p>
<p>clothing item은 노드로, item들간의 compatibility 관계는 간선으로 해서 graph표현→ product embedding을 neighbors에 conditioning(?)함으로써 robust한 representation을 얻고 정확한 compatibility 예측 가능 </p>
</li>
</ul>
<h2 id="proposed-method">proposed method</h2>
<p><strong>graph auto-encoder (GAE) :  **
**encoder가 불완전한 그래프를 입력으로 받아서 각 node의 embedding을 생성한다.
생성된 embedding은 decoder가 그래프의 missing edge를 예측할 때 사용된다.</strong>
<img src="https://velog.velcdn.com/images/dust_potato/post/ca8622f0-defc-4597-80de-beb726f39427/image.png" alt="">
G = (V,E)를 undirected graph 라고 할 때 각 노드는 feature vector를 의미한다. 
$X = {x_0, x_1, ... ,x_{n-1}}$ 는 $R^{(NxF)}$ 행렬(그래프의 모든 노드의 feature를 가진다)이다.
$X_(i,:)$ = 하나의 노드의 feature , ex)$X_{(i,0)}, X_{(i,1)}, ..., X_{(i,N-1)}$ 은 i 번째 노드의 feature를 의미한다. 
그래프는 $A \in  R^{(NxN)}$ 의 인접행렬로 표현되며, $A_{(i,j)}$ 의 값이 1인 경우는 두 노드가 연결되어 있음을 뜻한다. (0일 경우 연결 안됨)</p>
<p>모델의 목표는 encoding function H = $f_{enc}(X,A)$ 와 decoding fucntion A = $f_{dec}(H)$를 학습하는 것이다. 
인코더는 인접행렬 A를 참고하여 initial feature X를 새로운 표현인 H (Nx F&#39;) 행렬로 변환한다.
새로운 행렬은 초기 행렬 X와 똑같이 i번째 row가 i번째 노드의 정보를 가진다.
디코더는 인접행렬을 재구성하기 위해 새로운 representation H를 사용한다. 
이 전체 과정을 input feature를 new space로 보내는 encoding으로 볼 수 있는데, 두 point간의 거리가 둘 사이에 edge가 있을지 없을지의 확률로 해석될 수 있다. 그리고 디코더가 각 노드의 feature를 활용하여 그 확률을 계산해서 item i,j 의 compatibility를 구한다.</p>
<p>이 때 인코더는 Graph Convolutional Network이며, 디코더는 pairs of products (i; j) 의 compatibility score를 예측하는 metric을 학습한다. </p>
<p>Encoder와 Decoder의 동작과정을 자세히 살펴보자.</p>
<ul>
<li><strong>Encoder</strong></li>
<li><em>the model computes item embeddings depending on their connections.*</em>
single node i의 입장에서 보면 인코더는 initial visual feature x를 h로 변환한다.  CNN feature extractor에 의해 생성된 initial feature는 item이 어떻게 생겼는지-모양,색상,사이즈와 같은 vision informataion을 담고 있다. 하지만 논문에서는 <strong>product의 속성 뿐만 아니라 encoder에 의해 생생성된 다른 item들간의 호환성과 같은 구조적인 정보(structural information)도 필요하다. 즉 item 그 자체의 정보 + 해당 노드와 연결된 이웃노드들에 대한 정보</strong>가 필요하다. 후자는 인코더에 의해 생성되기 때문에 <strong>new representation</strong>이라고 칭한다. </li>
</ul>
<p>따라서 Encoder는 특정 node h_i 주변에 있는 neighbourhood를 모으는(aggregate) 함수이다. 이 함수는 GCN(Graph Convolutional Network)으로 구현된다. GCN의 final value h_i는 GCN의 각 hidden layer에 의해 생성된 값의 composition이다. 
$$
\vec{z}<em>{i}^{(l+1)}=\operatorname{ReLU}\left(\vec{z}</em>{i}^{(l)} \Theta_{0}^{(l)}+\sum_{j \in \mathcal{N}<em>{i}} \frac{1}{\left|\mathcal{N}</em>{i}\right|} \vec{z}<em>{j}^{(l)} \Theta</em>{1}^{(l)}\right)
$$</p>
<ul>
<li>Paper capture
<img src="https://velog.velcdn.com/images/dust_potato/post/51307f6c-4817-4bb7-bce3-64ac802b44e0/image.png" alt="">
GCN은 위와 같은 Graph Convolution 연산을 여러번(Multi layer) 진행한다.<blockquote>
<p>$Z^{(l)}$ : l번째 layer의 Hiddin state이며, $Z^0 = X$ (그래프 노드의 initial feature) 이다.
$A$ : A + I_N으로, 인접행렬(A)에 자기 자신으로의 연결(I_N)을 추가한 것이다.
$D$ : Dii = Aij 의 summation으로, 각 노드의 degree를 나타내는 대각행렬이다.
$\Theta$ : l번째 layer의 학습가능한 parameter이다. 
$ReLU$ : 비선형 함수인 ReLU를 사용했다. </p>
</blockquote>
</li>
</ul>
<p>Context information 은 neighbourhood의 depth를 나타내는 parameter S에 의해 controll된다. s가 의미하는 바는 특정 노드에서 s개의 edge를 연결해서 갈 수 있는 노드가 있을 때 그 깊이를 s라고 한다. 
논문에서는 바로 인접한 이웃의 정보만 사용하도록 S=1로 설정했다. </p>
<p><strong>GCN은 인접행렬을 입력으로 이용하여 어떤노드들이 연결되어 있는지에 대한 정보를 직접적으로 이용하고, 이를 통해 product간의 context = 즉 compatibility 정보를 효과적으로 학습할 수 있다.</strong></p>
<p>최종적으로 인접행렬 A에 적용되는 정규화 기법은 확률 p_drop을 사용하여 행렬 A의 일부 노드의 모든 incident edges(?)를 무작위로 제거한다.
이 기법의 목적은 두가지 인데, 
(1) 그래프 구조에 약간의 변화를 주어 noise에 robust하도록 한다. 
(2) 모델로 하여금 이웃이 없는 노드에 대해 잘 동작하도록 학습해서 low relational information 인 경우에도 robust하게 한다.</p>
<ul>
<li><strong>Decoder</strong>
<strong>the decoder uses item embeddings from encoder to compute the compatibility between item pairs</strong>
Decoder는 두 노드가 연결될 확률을 계산하는 함수이다. metric learning 과 같이 두 item간의 silmilarity, compatibility를 학습하는게 목표.
metric learning에서의 일반적인 공식은 두개의 n차원 벡터사이의 거리를 뜻하는 함수를 학습한다. 마찬가지로 논문에서도 item pair 의 comaptibility를 학습하길 원했고, 함수의 outdit은 0,1 사이의 확률값이다.</li>
</ul>
<p>두 노드 h_i,h_j 의 representation(encoder가 생성)이 주어지면, decoder는 두 노드가 연결될 확률 p를 계산한다.
$$
p=\sigma\left(\left|\vec{h}<em>{i}-\vec{h}</em>{j}\right| \vec{\omega}^{T}+b\right)
$$
절댓값을 쓰는 이유는 d(h_i, h_j) , d(h_j, h_i) 가 같도록 decoder를 symmetric하게 하기 위해서.</p>
<h2 id="training">Training</h2>
<p>학습과정은 다음과 같다. </p>
<ol>
<li>인접행렬 A의 edge를 무작위로 삭제하여 불완전한 인접행렬 A_hat을 얻는다. 삭제된 set of edge는 E+라고 표시하고 원해 연결되어 있던 edge이기 때문에 posotive edge라고 부른다.</li>
<li>set of negative edge E-(노드 (i,j)가 연결되어 있지 않음을 뜻함)를 무작위로 생성한다. </li>
<li>모델은 E_train = (E+, E-) : positive, negative edges를 모두 학습한다. </li>
<li>주어진 불완전한 인접행렬 A_hat 과 initial feature X 를 통해 디코더는 E_train에 정의된 edge를 예측한다. 모델은 예측된 edge와 GT edge 의 cross entropy loss를 minimize하도록 optimize 되는데, 이때 E+
는 1, E- 는 0 이 되도록 한다. </li>
</ol>
<p>Compatibility 계산 알고리즘은 아래와 같다. <img src="https://velog.velcdn.com/images/dust_potato/post/69814bed-35ba-425b-bdc1-ca656b2785f4/image.png" alt=""></p>
<h2 id="experiment">Experiment</h2>
<ul>
<li><p>Tasks
<img src="https://velog.velcdn.com/images/dust_potato/post/87687ed4-603a-4988-a05a-372302f368c7/image.png" alt=""> 
주어진 fashion outfit의 N개 set item을 ${{o1, . . . , oN−1}}$ 로, 두 노드 i,j의 edge를 $e_{i,j}$로 표기한다.  </p>
<ul>
<li><p>FITB
(c) edge prediction : partial outfit question {c0, ... ,cM-1} , 모든 i, j 에 대해 모델이 item pairs (oi, cj)간의 확률을 예측한다. 각 j에 대한 score는 $\sum_{i=0}^{N-1} e_{i, j}$으로 계산되며, 가장 높은 score를 가지는 item이 fitb의 예측이다. </p>
</li>
<li><p>Compatibility Predict
(d) edge prediction : 모델이 모든 가능한 item pair간의 모든 edge에 대해 확률을 예측한다. 이는 각 outfit에 대해 N(N-1)/2 번의 확률을 예측하는 것을 의미한다. 
compatibility score는 $\frac{2}{N(N-1)} \sum_{i=0}^{N-1} \sum_{j=i+1}^{N-1} e_{i, j}$  :  모든 pairwise edge확률의 평균이다. </p>
</li>
</ul>
</li>
<li><p>Evaluation by neighbourhood size
<img src="https://velog.velcdn.com/images/dust_potato/post/376dd057-459f-43f5-ab31-c859d4175a74/image.png" alt="">
노드 i의 k-neighbourhood 를 i 부터 시작해서 BFS로 k번 이내에 방문할 수 있는 노드라고 해보자. 각 item 주변의 relational structure의 영향을 평가하기 위해 k를 바꿔가며 test했다. </p>
</li>
<li><p><em>k=0일 때(이웃 정보를 안쓸 때) 부터 늘려가면서 evaluation 했다. 학습때는 모든 가능한 edge를 사용했다. *</em></p>
</li>
</ul>
<h2 id="results--conclusion">Results &amp; Conclusion</h2>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/d906e6c9-14a1-4f82-934e-2b1a64189bf9/image.png" alt="">Polyvore 데이터를 사용했을 때는 k가 15일 때 이전 논문의 방법론에 비해 가장 높은 score를 달성했다. 
FashionGen 데이터를 사용했을 때도 k가 30일때 score가 가장 높다.</p>
<ul>
<li>Context matters
<img src="https://velog.velcdn.com/images/dust_potato/post/a425b288-4624-48a2-b753-1bbf7bc79bdf/image.png" alt=""></li>
</ul>
<p>Context정보가 Compatibility 예측에 얼마나 중요한 영향을 미치는지 Polyvore 예시로 본다. 
6(a) : original context if the trousers, 신발도 제대로 된걸로 뽑힘, 그런데 trousrs에 매칭되는 context를 다른 옷들로 바꿨을 때, 
6(b) 처럼 다른 신발을 예측한다. 즉 논문에서 제안한 방법론으로 노드의 연결상태(context)가 바뀌면 예측 또한 바뀔 수 있다.</p>
<h2 id="take-a-home-message">Take a home Message</h2>
<p>fashion compatibility 예측분야에서 graph 모델을 통해 fashion item간의 관계를 표현하는 것이 compatibility 예측 성능에 도움이 된다.</p>
<h2 id="comment">Comment</h2>
<p>해당 논문에서 제안한 방법론은 하나의 outfit을 구성하는 item들을 연결하여 그래프를 구성하고, 이 연결상태를 context로 사용한다. </p>
<p>따라서 노드의 연결이 많을수록, 즉 하나의 outfit을 구성하는 item이 다른 outfit에도 사용이 되는 중복현상이 많을수록 그래프가 표현하는 context가 풍부해지고, 그에 따라 predict 성능도 향상한다.</p>
<p>이는 데이터셋을 제작할 때부터 중복 item이 많아야 성능의 향상을 기대할 수 있다는 말이므로, 어떤 데이터를 사용하는지가 성능에 중요한 이슈이다. </p>
<p>또한 예측 시 모델이 참고하는 context의 hop을 조절하는 파라미터 k가 15정도로 상당히 큰데, 이 때 해당 그래프가 모두 메모리에 올라와 있어야 하므로 메모리도 충분히 확보되어야 한다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SAT: self-adaptive training for fashion compatibility prediction 리뷰]]></title>
            <link>https://velog.io/@dust_potato/SAT-self-adaptive-training-for-fashion-compatibility-prediction-%EB%A6%AC%EB%B7%B0</link>
            <guid>https://velog.io/@dust_potato/SAT-self-adaptive-training-for-fashion-compatibility-prediction-%EB%A6%AC%EB%B7%B0</guid>
            <pubDate>Sun, 24 Jul 2022 06:58:48 GMT</pubDate>
            <description><![CDATA[<h1 id="outfit-recommendation">outfit recommendation</h1>
<p>쇼핑을 하다보면 어떤 옷을 골랐을 때 내가 고른 옷과 어울리는 다른 옷도 추천해주는 경험을 해본 적이 있을 것이다. 
<img src="https://velog.velcdn.com/images/dust_potato/post/77586ba4-9a35-46e7-9573-fc9397b7a345/image.png" alt=""> 사진 출처 : <a href="https://www.ssfshop.com/Maison-Kitsun%C3%A9/GM0022042097906/good?dspCtgryNo=SFMA41A01&amp;brandShopNo=&amp;brndShopId=&amp;keyword=&amp;leftBrandNM=&amp;utag=ref_cat:SFMA41A01$set:1$$dpos:2">SSF몰</a></p>
<p>상의, 하의는 물론 모자, 가방, 신발까지 추천해주는 이 서비스는 보통 인공지능을 학습시켜 추천해주는데, 자칫 잘못하면 엉뚱한 추천을 해주어 서비스의 퀄리티가 낮아질 수 있다.
제품이 기본적으로 가지고 있는 카테고리(아우터, 티셔츠, 팬츠, 가방, 신발 등), 기장, 색상과 같은 정보가 있어도, 이러한 정보에서 모델이 상품의 시각적 정보를 파악하기는 쉽지 않다.</p>
<p>따라서 요즘 인공지능을 사용한 outfit recommendation system은 이미지와 텍스트를 함께 활용하며, 패션 아이템들간의 호환성(compatibility, 잘 어울리는지)을 판단하기 위해 고객이 함께 구매한 상품, 전문가(패션 디자이너)의 패션구성, 소셜미디어 사진에서 사람들의 의상까지 데이터로 활용해야 한다. </p>
<p>이렇듯 모델이 사람이 보기에도 &quot;잘 어울리는&quot; 룩을 추천하기 위해서는 일반화를 위해 많은 데이터가 필요하고, 
상품의 카테고리나 이미지만을 사용해서는 좋은 결과를 낼 수 없다.(다만 Graph 모델로 이미지만을 사용해서 좋은 결과를 낸 논문이 있다.)</p>
<p>오늘 리뷰할 논문은 추천이 까다로운 패션 아이템들을 학습할 때에 사용할 수 있는 기법에 대해 연구한 논문이다. </p>
<h2 id="background">background</h2>
<ul>
<li><p>triplet loss
<img src="https://velog.velcdn.com/images/dust_potato/post/ea403552-2a09-4b5c-80d6-9baff0e0632a/image.png" alt="">
사진출처 : <a href="https://arxiv.org/pdf/1503.03832.pdf">FaceNet</a>
논문에 대해 이해하려면 먼저 triplet loss에 대해 이해해야 한다. 
Triplet loss는 baseline인 anchor를 positive, negative input들과 비교하는 인공 신경 네트워크에 대한 손실 함수 (loss function)이다. </p>
</li>
<li><p><em>anchor input과 positive input 사이의 거리는 최소화 되야하며, negative input과의 거리는 최대가 되어야 한다.*</em>
보통 워드 임베딩 (word embeddings)에서 유사성을 학습하는 데 사용되며, 유클리디안 거리를 사용한다.
<img src="https://velog.velcdn.com/images/dust_potato/post/786e9cf3-26e8-44ff-b8e1-fbbb8c5b96df/image.png" alt=""></p>
<blockquote>
<p>A : anchor input
P : A와 같은 class에 속하는 positive input
N : A와 다른 class에 속하는 negative input 
$\alpha$ : positive , negative pair간의 margin
f : embedding</p>
</blockquote>
</li>
<li><p>미리(함께) 읽으면 좋은 논문</p>
<ul>
<li><p>[1]-<a href="https://arxiv.org/abs/1707.05691">Learning Fashion Compatibility with Bidirectional LSTMs (2017)</a>
bi-LSTM을 사용하여 fashion compatibility 연구 수행, visual-semantic embedding (이미지와 텍스트 데이터를 함께 embedding) 제안</p>
</li>
<li><p>[2]-<a href="https://arxiv.org/abs/1803.09196">Learning Type-Aware Embeddings for Fashion Compatibility (2018)</a>
SiameseNet을 사용하여 fashion compatibility 연구 수행 , (1) 에서 발전하여 type-aware embedding space( : item type(e.g. top, bottom, shoes) 별 image embedding을 학습) 를 사용하는 end to end 학습법 제안</p>
<h1 id="sat-self-adaptive-training-for-fashion-compatibility-prediction"><a href="https://arxiv.org/abs/2206.12622">SAT: self-adaptive training for fashion compatibility prediction</a></h1>
</li>
</ul>
</li>
</ul>
<h2 id="abstract">abstract</h2>
<ul>
<li>hard items(비슷한 색상, 질감, 패턴을 가졌으나 미관 또는 계절적 이유로 incompatible한 items) 학습에 집중</li>
<li>각 outfit 마다 Difficulty score(DS) 정의</li>
<li>self-adaptive triplet loss (SATL) 제안 → DS에 따라 weights 를 결정</li>
<li>simple conditional similarity network 제안</li>
</ul>
<h2 id="method">method</h2>
<p>self-adaptive training (SAT) model은 <strong>CNN에 hard sample을 더 많이(가중치를 통해) 학습시키는 방법</strong>이다. 
key-insight는 <strong>positive sample(Dn)과 negative sample(Dp)간 embedding distance는 margin보다 클것이다 라는 가정</strong>을 통해 <strong>거리가 margin보다 작은 hard item에 대해서는 더 큰 가중치를 주어 학습</strong>을 시킨다. </p>
<h2 id="model-architecture-and-training">Model Architecture and Training</h2>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/d66d776d-dbe5-44c8-b29e-216d3449ab1c/image.png" alt=""></p>
<h3 id="학습-방법">학습 방법</h3>
<p>우리가 이미지 $x_i$를 가지고 있다고 가정했을 떄, trplet loss input $\left(x_{i}^{(u)}, x_{n}^{(v)}, x_{p}^{(v)}\right)$ 이 만들어진다, </p>
<blockquote>
<p>u, v : image types
xi, xp → positive pair / xi, xn → negative pair </p>
</blockquote>
<p>(1) triplet input $\left(x_{i}^{(u)}, x_{n}^{(v)}, x_{p}^{(v)}\right)$를 VGG13에 넣어 general features (Fxi(u), Fxn(v), Fxp(v))얻는다.</p>
<p>(2) general feature를 type-specific embedding space M(u,v) 에 projection → 목표는 M 안에서 Fxi(u), Fxp(v) 간의 거리$\left|P^{u \rightarrow(u, v)}\left(F_{x_{i}}^{(u)}\right)-P^{v \rightarrow(u, v)}\left(F_{x_{p}}^{(v)}\right)\right|_{2}$가 작아지게 하는 것</p>
<blockquote>
<p>type-specific embedding space 란?</p>
</blockquote>
<ul>
<li>motivation 
논문[1]처럼 이미지 type에 상관없이 general embedding space를 하나만 사용할 경우 두가지 문제 발생</li>
<li><em>compresses variation*</em> : outfit이 compatible하지 않은데도 embedding space에서 거리가 가까우면 matching되는 문제</li>
<li><em>improper triangles*</em> : a가 b와 매치, b와 c가 매치되면 a 는 무조건 c 와 매치될 수 밖에 없음(stemming from using a single embedding)</li>
<li>method
두 종류의 embedding space 사용<ol>
<li>이미지 similarity 측정을 위한 general embedding space</li>
<li>두 아이템간의 compatibility를 계산하기 위한 type-aware embedding space</li>
</ol>
</li>
</ul>
<p>(3) compatibility 
이때 compatibility는 아래 수식으로 계산된다. 
$$
d_{i, j}^{(u, v)}=\left|F_{x_{i}}^{(u)} \odot \mathbf{w}^{(u, v)}-F_{x_{j}}^{(v)} \odot \mathbf{w}^{(u, v)}\right|_{2}
$$</p>
<blockquote>
<p>j : type이 v인 이미지 중 랜덤으로 선택
$x_j$ : 주어진 이미지 $x_i$와 compatible
할 수도, incompatible할 수도 있다. </p>
</blockquote>
<p>(4) loss 는 triplet loss of the input($L_{comp}$), self-adaptive triplet loss($L_{SATL}$), similarity loss of the general features($L_{sim}$) 가 있다. </p>
<h3 id="triplet-loss-of-the-inputl_comp">triplet loss of the input($L_{comp}$)</h3>
<p>$$
L_{\text {comp }}=\max \left{0, d_{i, p}^{(u, v)}-d_{i, n}^{(u, v)}+\mu\right}
$$</p>
<blockquote>
<p>$\mu$ : margin</p>
</blockquote>
<p>$L_{comp}$는 positive pair 와 negative pair 간 거리에 margin(in paper : 0.3)을 더한 값과,  0 중에 큰 값을 택한다. </p>
<h3 id="self-adaptive-triplet-lossl_satl">self-adaptive triplet loss($L_{SATL}$):</h3>
<p>$$
L_{S A T L}=L_{c o m p} \cdot \mathbf{W},
$$
SATL은 triplet loss of input($L_{comp}$) 에 가중치를 곱한 값이다. </p>
<p>데이터는 color compatible, pattern compatible, or style compatible하게 레이블링 되었지만, 이는 표준(기준)이 아니다. 따라서 type-specific embedding space $M^{(u,v)}$ 안에서 positive pair distance ($d_{i, p}^{(u, v)}$) 와 negative pair distance 의 차이는 margin보다 커야한다. 만약 그렇지 않다면 이는 hard sample로 간주한다. </p>
<p>hard sample을 잘 학습시키기 위해, 논문에서는 각각의 outfit마다 DS(Difficulty Score)를 정의한다. 
$$
D S_{i}=\max \left{0, d_{i, p}^{(u, v)}-d_{i, n}^{(u, v)}+\mu\right}
$$</p>
<p>이후 학습된 weight parameter인 $w_{DS_i}$를 each triplet loss에 assign한다. 이렇게 하면 최종 weight matrix는 다음과 같다. </p>
<p>$$
W_i = DS_i \cdot w_{DS_i}
$$</p>
<p>different triplet inputs에 different weights 을 assign함으로서 각 triplet input의 DS가 사용되어 모델이 hard items의 compatibility를 더 잘 학습할 수 있으며, input의 특징을 더 잘 나타내는 embedding space를 생성한다. </p>
<h3 id="similarity-loss-of-the-general-featuresl_sim">similarity loss of the general features($L_{sim}$)</h3>
<p>$$
L_{s i m}=\max \left{0, D_{p}-D_{n 1}+\mu\right}+\max \left{0, D_{p}-D_{n 2}+\mu\right} \text {, }
$$</p>
<blockquote>
<p>$D_{p}=\left|F_{x_{p}}^{(v)}-F_{x_{n}}^{(v)}\right|<em>{2}$ : type이 같은 positive와 negative간 general featutes의 거리
,
$D</em>{n1}=\left|F_{x_{p}}^{(v)}-F_{x_{i}}^{(u)}\right|<em>{2}$ : type v인 positive input의 general feature와 type u인 input image general feature간 거리
,
$D</em>{n 2}=\left|F_{x_{n}}^{(v)}-F_{x_{i}}^{(u)}\right|_{2}$. type v인 negative input의 general feature와 type u인 input image general feature간 거리</p>
</blockquote>
<h3 id="type-aware-loss">type-aware loss</h3>
<p>$$
L_{\text {type-aware }}=L_{S A T L}+\lambda_{1} L_{\text {sim }}+\lambda_{2} L_{l_{1}}+\lambda_{3} L_{l_{2}},
$$</p>
<blockquote>
<p>$\lambda_{1}=5 \times 10^{-5}, \lambda_{2-3}=5 \times 10^{-4}$ </p>
</blockquote>
<h2 id="experiment--conculsion">experiment &amp; conculsion</h2>
<p>실험의 셋팅은 [2] Siamese-Net 논문에서와 같은데, 대략적으로는 다음과 같다.
popular compatibility prediction and fill-in-the-blank (FITB) tasks
VGG13 [15] pre-trained on ImageNet [16] was adopted as our backbone CNN model
The embedding size is 128, the margin µ is 0.3, and the minibatch size is 128
initial learning rate to 5 × 10−5
Since there are no ground truth negative images for each outfit, we randomly sample a set of negative images that have the same category as the positive image similar to [2].</p>
<h3 id="fitb와-compatibility-accuracy">FITB와 Compatibility accuracy</h3>
<p>outfit recommendation에서 아이템을 추천하는 방법은 여러가지가 있는데, 대표적인 것이 <strong>FITB(Fill In The Blank)</strong>와 <strong>Compatibility prediction</strong>이다. 
<img src="https://velog.velcdn.com/images/dust_potato/post/e5c1e47e-07d6-488e-a350-ee0a8460ed5c/image.png" alt=""> 사진 출처 : <a href="https://arxiv.org/pdf/1707.05691.pdf">Learning Fashion Compatibility with Bidirectional LSTMs</a>
먼저 FITB는 다른 카테고리(아우터, 상의, 하의, 가방)에 속하는 아이템은 모두 구성이 되어있을 때, 비어있는 카테고리(신발) 에 어떤 아이템이 가장 잘 어울리는지 추천하는 것이다. </p>
<p>Compatibility prediction은 구성되어 있는 outfit 모음이 잘 어울리는지 정도를 점수로 예측하는 것이다. </p>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/cfc0dccd-31e6-40c7-bf1c-dea3457aa0f7/image.png" alt="">FITB 정확도와 Compatibility 정확도를 비교했을 때 SAT가 상위권에 있음을 보인다. 
<img src="https://velog.velcdn.com/images/dust_potato/post/d592c97b-4116-4fb1-89cd-7932a06b9574/image.png" alt="">SATL의 영향을 알아보기 위한 ablation study에서도 SATL을 사용했을 때  FITB and compatibility accuracy가 더 높아졌다.
<img src="https://velog.velcdn.com/images/dust_potato/post/921f97ee-e3c4-414f-aeb2-8b174aa5190e/image.png" alt="">
검정박스가 GT, (a)행의 빨간 박스는 SATL을 사용하지 않았을 때의 예측, (b)행의 초록박스가 SATL을 사용했을 때의 예측이다. SATL을 사용했을 때의 예측이 모두 GT와 동일하다는 결과.</p>
<h2 id="take-home-message">take-home message</h2>
<p><strong>hard item을 고려한 self-adaptive triplet loss를 통해 outfit compatibility 성능을 향상시킬 수 있다.</strong></p>
<p>논문에서 기여한 점은 </p>
<p>단점은 이미지 데이터와 그에 해당하는 description 텍스트 데이터까지 있어야한다는 것. 
또한 compatibility score 계산 시 embedding feature를 pairwise하게 비교한다.
item들을 pairwise하게(독립적으로) 비교하면 최종적인 final prediction은 각 item을 독립적으로 비교한 후 모아놓은 것이다.
이 방법은 context를 고려하지 않기 때문에 주어진 clothing pair에 대해 항상 같은 예측을 하게된다.
Compatibility는 패션 감각과 트렌드가 변하면 함께 변하기 때문에 항상 같은 예측을 하는것은 문제가 있다.</p>
<p>이를 해결한 논문이 Context-Aware Visual Compatibility Prediction(cvpr 2019) 이다. 다음엔 이 논문을 리뷰해보겠다.</p>
<hr>
<p>ref 
<a href="https://en.wikipedia.org/wiki/Triplet_loss">https://en.wikipedia.org/wiki/Triplet_loss</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Pytorch torch.nn.init 과 Tensorflow tf.keras.Innitializers 비교 ]]></title>
            <link>https://velog.io/@dust_potato/Pytorch-torch.nn.init-%EA%B3%BC-Tensorflow-tf.keras.Innitializer-%EB%B9%84%EA%B5%90</link>
            <guid>https://velog.io/@dust_potato/Pytorch-torch.nn.init-%EA%B3%BC-Tensorflow-tf.keras.Innitializer-%EB%B9%84%EA%B5%90</guid>
            <pubDate>Sun, 10 Jul 2022 14:47:02 GMT</pubDate>
            <description><![CDATA[<h1 id="글을-쓰게-된-이유">글을 쓰게 된 이유</h1>
<p>그동안은 회사에서 tensorflow를 사용해왔다. 공개된 weight, 코드가 pytorch인 경우가 많고, 이때 회사에서 구현한 api에서 pytorch도 사용할 수 있도록 포팅을 하고 있다. 
요구사항은 다음과 같다. </p>
<ul>
<li>인자만 바꾸면 pytorch와 tensorflow를 선택해서 쓸 수 있게 기존에 구현된 tensorflow의 인자에 맞추어 pytorch 함수 구현</li>
<li>학습 시 최대한 같은 결과가 나올 수 있게 구현</li>
</ul>
<p>Linear Layer, Conv Layer 등 Layer를 생성하는 함수를 구현하는 과정에서 tensorflow와 pytorch의 Layer Weight Innitialization 방법이 달라 이를 맞추며 공부한 내용이다.</p>
<h1 id="weight-initialization">Weight Initialization?</h1>
<p>pytorch 사용자라면<a href="https://github.com/clovaai/CRAFT-pytorch/blob/master/basenet/vgg16_bn.py"> 아래와 같은 코드</a>를 본적이 있을 것이다. </p>
<pre><code class="language-python">import torch
import torch.nn as nn
import torch.nn.init as init
from torchvision import models
from torchvision.models.vgg import model_urls

def init_weights(modules):
    for m in modules:
        if isinstance(m, nn.Conv2d):
            init.xavier_uniform_(m.weight.data)
            if m.bias is not None:
                m.bias.data.zero_()
        elif isinstance(m, nn.BatchNorm2d):
            m.weight.data.fill_(1)
            m.bias.data.zero_()
        elif isinstance(m, nn.Linear):
            m.weight.data.normal_(0, 0.01)
            m.bias.data.zero_()

class vgg16_bn(torch.nn.Module):
    def __init__(self, pretrained=True, freeze=True):
        super(vgg16_bn, self).__init__()
        model_urls[&#39;vgg16_bn&#39;] = model_urls[&#39;vgg16_bn&#39;].replace(&#39;https://&#39;, &#39;http://&#39;)
        vgg_pretrained_features = models.vgg16_bn(pretrained=pretrained).features
        self.slice1 = torch.nn.Sequential()
        self.slice2 = torch.nn.Sequential()
        self.slice3 = torch.nn.Sequential()
        self.slice4 = torch.nn.Sequential()
        self.slice5 = torch.nn.Sequential()
        for x in range(12):         # conv2_2
            self.slice1.add_module(str(x), vgg_pretrained_features[x])
        for x in range(12, 19):         # conv3_3
            self.slice2.add_module(str(x), vgg_pretrained_features[x])
        for x in range(19, 29):         # conv4_3
            self.slice3.add_module(str(x), vgg_pretrained_features[x])
        for x in range(29, 39):         # conv5_3
            self.slice4.add_module(str(x), vgg_pretrained_features[x])

        # fc6, fc7 without atrous conv
        self.slice5 = torch.nn.Sequential(
                nn.MaxPool2d(kernel_size=3, stride=1, padding=1),
                nn.Conv2d(512, 1024, kernel_size=3, padding=6, dilation=6),
                nn.Conv2d(1024, 1024, kernel_size=1)
        )

        if not pretrained:
            init_weights(self.slice1.modules())
            init_weights(self.slice2.modules())
            init_weights(self.slice3.modules())
            init_weights(self.slice4.modules())

...</code></pre>
<p>Layer를 만들고, init_weights 함수를 통해 Layer의 weight를 어떤 분포를 가지도록 초기화하는 것이다. 이러한 가중치 초기화는 왜 필요한 것일까? </p>
<p>최적화(optimization) 에서 가중치의 초깃값에 따라 local minimum에 빠지느냐 global minimum을 찾느냐가 결정되기도 한다. 아무리 좋은 optimzer를 쓰더라도 가중치의 초깃값을 잘못 설정하면 global minimum에 수렴하기가 쉽지 않다.
딥러닝 모델은 거대한 feature space를 가지고 있기 때문에 올바른 초기값을 설정하는 것은 어렵다. 그래서 조금 다른 목적으로 사용된다.</p>
<p>forward시 에는 전달되는 값이 너무 너무 작아지거나 커지지 않도록
backward시 에는 gradient값이 너무 작아지거나(gradient vanishing) 너무 커지지 않도록(gradient exploding)
가중치의 값을 적절히 초기화를 해야한다. 
또한 활성화함수(activation function)이 선형인지, 비선형인지에 따라 다른 분포로 초기화를 해야한다.
(보다 자세한 설명은 <a href="https://velog.io/@dust_potato/U-stage-DAY-6-DL-Basic-1#%EC%8B%A0%EA%B2%BD%EB%A7%9Dneural-networks">이 글</a>이 도움이 될 것이다.)</p>
<p>초기화를 하는데에는 다양한 분포가 사용된다. 이 글에서는 많은 분포를 다 다루지는 않고, lecun uniform과 lecun normal을 중점적으로 다룰 것이다. </p>
<h1 id="두-라이브러리의-weight--bias-initialzation-비교">두 라이브러리의 Weight &amp; bias initialzation 비교</h1>
<p>큰 차이점 두가지는 분포의 이름과 초기화 방법이다. </p>
<ul>
<li><p>이름
pytorch 사용자들에게 <code>Xavier Uniform/Normal</code>로 사용되는 분포는 tensorflow에서는 <code>Glorot Uniform/Normal</code> 이며, Kaiming He가 제안한 He 분포 또한 pytorch에서는 <code>Kaiming Uniform/Normal</code>인 반면 tensorflow에서는 <code>He Uniform/Normal</code> 이다. 자세한 비교는 아래 표에서.</p>
</li>
<li><p>방법
tensorflow도 pytorch처럼 일단 Layer instance를 만든 후에 module을 인자로 전달하여 초기화를 할까? tensorflow는 Layer를 생성할 때 원하는 분포를 인자로 전달하면 weight, bias가  해당 분포를 가지도록 초기화되어 Layer를 만들 수 있다. </p>
<h2 id="tfkerasinnitializer"><a href="https://www.tensorflow.org/api_docs/python/tf/keras/initializers">tf.keras.Innitializer</a></h2>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/40031ec8-b3f2-4981-b222-e89ac1c31910/image.png" alt=""></p>
</li>
</ul>
<pre><code class="language-python"># Usage in a Keras layer:
initializer = tf.keras.initializers.GlorotUniform()
layer = tf.keras.layers.Dense(3, kernel_initializer=initializer)

# Usage2 in a Keras layer:
layer = tf.keras.layers.Dense(3, kernel_initializer=&#39;glorot_uniform&#39;)</code></pre>
<p>tensorflow는 위의 코드처럼 layer 생성시 initializer 또는 string 인자를 전달하면 초기화가 가능하다.</p>
<h2 id="torchnninit"><a href="https://pytorch.org/docs/stable/nn.init.html">torch.nn.init</a></h2>
<p><img src="https://velog.velcdn.com/images/dust_potato/post/335fc022-0eb5-4226-9bcf-0b80d57add09/image.png" alt="">
pytorch는 nn.init.분포 함수에 인자로 weight를 전달한다. </p>
<h2 id="각-initialization-algorithm-표로-정리">각 initialization algorithm 표로 정리</h2>
<table>
<thead>
<tr>
<th>Tensorflow</th>
<th>Pytorch</th>
</tr>
</thead>
<tbody><tr>
<td>constant</td>
<td>constant_</td>
</tr>
<tr>
<td>glorot_normal</td>
<td>xavier_normal_</td>
</tr>
<tr>
<td>glorat_uniform</td>
<td>xavier_uniform_</td>
</tr>
<tr>
<td>he_normal</td>
<td>kaiming_normal_</td>
</tr>
<tr>
<td>he_uniform</td>
<td>kaiming_uniform_</td>
</tr>
<tr>
<td>identity</td>
<td>eye_</td>
</tr>
<tr>
<td>lecun_normal</td>
<td>None</td>
</tr>
<tr>
<td>lecun_uniform</td>
<td>None(default)</td>
</tr>
<tr>
<td>ones</td>
<td>ones_</td>
</tr>
<tr>
<td>orthogonal</td>
<td>orthogonal_</td>
</tr>
<tr>
<td>random_normal</td>
<td>normal_</td>
</tr>
<tr>
<td>random_uniform</td>
<td>uniform_</td>
</tr>
<tr>
<td>truncated_normal</td>
<td>trunc_normal_</td>
</tr>
<tr>
<td>variance_scailing</td>
<td>None</td>
</tr>
<tr>
<td>zeros</td>
<td>zeros_</td>
</tr>
</tbody></table>
<h3 id="lecun-distribution">Lecun distribution</h3>
<p>위의 표에서 lecun_uniform, lecun_normal 은 뭘까. 
초기 CNN인 lenet으로 유명한 Yann Lecun 교수님의 1998년 페이퍼에서 제안된 기법이다. 기본적으로 uniform distribution 혹은 normal distribution에서 추출한 랜덤 값으로 웨이트를 초기화 시키되, 이 확률 분포를 <code>fan in</code>값으로 조절하자는 아이디어.</p>
<blockquote>
<p>fan_in : 해당 레이어에 들어오는 input tensor의 차원 크기
fan_out : fan out은 레이어가 출력하는 output tensor의 크기</p>
</blockquote>
<ul>
<li>1000 x 200 크기의 FC 레이어의 fan in은 1000, fan out은 200</li>
<li>Conv Layer의 fan in:  receptive field x input channel, fan out: receptive field x output channel
(receptive field : 전체 인풋에서 해당 커널이 얼만큼 인식하는 지)</li>
</ul>
<p>수식은 다음과 같다. 
<img src="https://velog.velcdn.com/images/dust_potato/post/3e0b2851-3657-481b-bda8-2f51c339e539/image.png" alt=""></p>
<blockquote>
<p>** tensorflow 설명**
<code>lecun uniform</code> : Draws samples from a uniform distribution within [-limit, limit], where limit = sqrt(3 / fan_in) (fan_in is the number of input units in the weight tensor).
<code>lecun normal</code> : Draws samples from a truncated normal distribution centered on 0 with stddev = sqrt(1 / fan_in) where fan_in is the number of input units in the weight tensor.</p>
</blockquote>
<h1 id="pytorch에서-어떻게-tensorflow-처럼-동작하도록-할까---코드">pytorch에서 어떻게 tensorflow 처럼 동작하도록 할까 - 코드</h1>
<p>그러면 tensorflow에는 lecun_uniform, lecun_normal 이 있는데 pytorch는 없으니 
pytorch를 사용할 때 <code>kernel_initializer = &#39;lecun_uniform&#39;</code>, <code>kernel_initializer = &#39;lecun_normal&#39;</code>인자를 받아도 tensorflow와 똑같이 초기화가 되도록 구현해보자.</p>
<h2 id="init_weights-function">init_weights function</h2>
<p>모든 분포의 경우마다 if문으로 나누는 코드는,,, 해석은 편하지만 매우 귀찮다. 
그 대신 Layer의 종류(Linear, Conv...)에 상관없이</p>
<ol>
<li>인자로 tensorflow initializer string 인자가 들어오면 </li>
<li>torch.nn.init 에 해당하는 이름으로 바꾸고(없을 경우 새로 구현 or NotImplemented Error)</li>
<li>getattr 로 불러와서 partial로 다시 함수로 만든다.<pre><code class="language-python"># how to get init func 
import torch.nn.init as init
from functools import partial
</code></pre>
</li>
</ol>
<p>init_weight_func = partial(getattr(init, &#39;uniform_&#39;))</p>
<pre><code>이렇게 하면 init\_weight\_func 이 torch.nn.init.uniform_ 함수가 된다. 

```python
import torch
import torch.nn as nn
import torch.nn.init as init
import torch.nn.functional as F

# Tensorflow initializer to Pytorch init
tfInitilizer2Torch = {&#39;constant&#39; : &#39;constant_&#39;,
                      &#39;glorot_uniform&#39; : &#39;xavier_uniform_&#39;,
                      &#39;glorot_normal&#39; : &#39;xavier_normal_&#39;,
                      생략...,
                      }

def init_weights(module, kernel_initializer, bias_initializer,**kwargs):
    # 1
    weight_initializer = tfInitilizer2Torch[kernel_initializer]
    bias_initializer = tfInitilizer2Torch[bias_initializer]

    # 2
    if weight_initializer == None or bias_initializer == None:
        raise NotImplementedError(&#39;Not Implemented in Pytorch&#39;)
    # 3
    init_weight_func = partial(getattr(init, weight_initializer))
    init_weight_func(module.weight.data, **kwargs)</code></pre><p>이렇게만 코드를 짜면 lecun_uniform, lecun_normal 분포는 처리가 안되니,,, 따로 함수를 작성해주도록 하자. 
lecun 분포는 fan_in, fan_out 계산이 필요하다. </p>
<h2 id="get-fan_in">get fan_in</h2>
<p>torch.nn.init을 보면 <a href="https://pytorch.org/docs/stable/_modules/torch/nn/init.html#calculate_gain">_calculate_fan_in_and_fan_out 함수</a>가 있다. 코드는 다음과 같다. </p>
<pre><code class="language-python">def _calculate_fan_in_and_fan_out(tensor):
    dimensions = tensor.dim()
    if dimensions &lt; 2:
        raise ValueError(&quot;Fan in and fan out can not be computed for tensor with fewer than 2 dimensions&quot;)

    num_input_fmaps = tensor.size(1)
    num_output_fmaps = tensor.size(0)
    receptive_field_size = 1
    if tensor.dim() &gt; 2:
        # math.prod is not always available, accumulate the product manually
        # we could use functools.reduce but that is not supported by TorchScript
        for s in tensor.shape[2:]:
            receptive_field_size *= s
    fan_in = num_input_fmaps * receptive_field_size
    fan_out = num_output_fmaps * receptive_field_size

    return fan_in, fan_out</code></pre>
<p>분포 함수 내에서 사용방법은 다음과 같다. </p>
<pre><code class="language-python">def xavier_uniform_(tensor: Tensor, gain: float = 1.) -&gt; Tensor:
    r&quot;&quot;&quot;Fills the input `Tensor` with values according to the method
    described in `Understanding the difficulty of training deep feedforward
    neural networks` - Glorot, X. &amp; Bengio, Y. (2010), using a uniform
    distribution. The resulting tensor will have values sampled from
    :math:`\mathcal{U}(-a, a)` where

    .. math::
        a = \text{gain} \times \sqrt{\frac{6}{\text{fan\_in} + \text{fan\_out}}}

    Also known as Glorot initialization.

    Args:
        tensor: an n-dimensional `torch.Tensor`
        gain: an optional scaling factor

    Examples:
        &gt;&gt;&gt; w = torch.empty(3, 5)
        &gt;&gt;&gt; nn.init.xavier_uniform_(w, gain=nn.init.calculate_gain(&#39;relu&#39;))
    &quot;&quot;&quot;
    fan_in, fan_out = _calculate_fan_in_and_fan_out(tensor)
    std = gain * math.sqrt(2.0 / float(fan_in + fan_out))
    a = math.sqrt(3.0) * std  # Calculate uniform bounds from standard deviation

    return _no_grad_uniform_(tensor, -a, a)</code></pre>
<p><code>nn._calculate_fan_in_and_fan_out</code> 으로 가져다쓰면 된다.</p>
<h2 id="lecun-uniform">lecun uniform</h2>
<p>Dense Layer (<a href="https://pytorch.org/docs/stable/generated/torch.nn.Linear.html#torch.nn.Linear">Linear Layer</a>)를 기준으로 pytorch는 nn.Linear를 생성하면 자동으로 lecun uniform으로 초기화가 된다. (tensorflow는 Linear, Con2d 모두 디폴트가 weight:glorot_uniform, bias:zeros)
<img src="https://velog.velcdn.com/images/dust_potato/post/cd42d6e8-0a0a-40dd-9a4d-48b5e14eb0d4/image.png" alt="">tensorflow와 다른점은 분자가 $\sqrt{3}$ 이라는 것,,, 아래처럼 작성하면 tensorflow와 같게 동작할 것이다.</p>
<pre><code class="language-python">import math 
if isinstance(module, nn.Linear):
  if weight_initializer == &#39;lecun_uniform&#39;:
      module.weight.data = module.weight.data * math.sqrt(3)</code></pre>
<p>하지만 요구사항은 Layer 에 상관없이 동작하도록 하는 것이므로 그냥 함수를 작성해준다.</p>
<h2 id="전체-코드">전체 코드</h2>
<pre><code class="language-python">def lecun_uniform_(tensor, is_weight :bool, **kwargs):
    init_func = partial(getattr(init, &#39;uniform_&#39;))
    fan_in, _ = init._calculate_fan_in_and_fan_out(tensor)
    limit = math.sqrt(3 / fan_in)
    kwargs[&#39;a&#39;] = -limit
    kwargs[&#39;b&#39;] = limit
    init_func(tensor, **kwargs)

def lecun_normal_(tensor, is_weight :bool, **kwargs):
    init_func = partial(getattr(init, &#39;normal_&#39;))
    fan_in, _ = init._calculate_fan_in_and_fan_out(tensor)
    kwargs[&#39;std&#39;] = 1/fan_in
    init_func(tensor, **kwargs) # std = var value

def init_weights(module, kernel_initializer = &#39;glorot_uniform&#39;, bias_initializer = &#39;zeros&#39;,**kwargs):
    생략...

    if weight_initializer == &#39;lecun_uniform&#39;:
        lecun_uniform_(tensor, True, **kwargs)
    elif weight_initializer == &#39;lecun_normal&#39;:
        lecun_normal_(tensor, True, **kwargs)

    생략...
</code></pre>
<h1 id="결론-및-생각해봐야-할-점">결론 및 생각해봐야 할 점</h1>
<p>weight initialization시 tensorflow와 pytorch의 차이점에 대해 비교해보고 서로 같게 동작하려면 어떻게 해야할지 알아보았다. 다만 이글에서는 오로지 분포를 인자로 받아 코드가 돌아가게끔 하는것에 집중했지만,,, (또한 회사 코드를 그대로 올리면 안되니 아이디어용 수도코드에 가깝다, 실제로 동작하게 하려면 많이 수정해야 함)</p>
<p>가중치 초기화를 더 깊게 파고들려면 activation function과의 관계도 신경써야하고 인자의 값 또한 고려해야한다. (nonlinearity와 gain, nn.init.calculate_gain 함수는 뭔지 등)</p>
<p>그리고 <a href="https://discuss.pytorch.org/t/why-the-default-negative-slope-for-kaiming-uniform-initialization-of-convolution-and-linear-layers-is-5/29290">이런 글</a>도 있다... 
pytorch의 Conv2d Layer 초기화는 kaiming uniform을 사용하는데, 그 때 negative slope(gain 인자)의 디폴트 값은 $\sqrt{5}$이다. 그런데 이게 왜 $\sqrt{5}$인지 아무도 모른다는 이야기 ^.^,,,, magic number 라고도 불리던데,,, 뭔가 흥미로운 주제라 알아봐야겠다.
<a href="https://adityassrana.github.io/blog/theory/2020/08/26/Weight-Init.html">관련된 블로그 글1</a>
<a href="https://github.com/pytorch/pytorch/issues/15314">관련된 이슈2</a>
<a href="https://discuss.pytorch.org/t/why-the-default-negative-slope-for-kaiming-uniform-initialization-of-convolution-and-linear-layers-is-5/29290">관련된 이슈3</a></p>
<hr>
<p>참고 
<a href="https://yeomko.tistory.com/40">갈아먹는 딥러닝 기초 [2] weight initialization</a></p>
]]></description>
        </item>
    </channel>
</rss>