<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>JAsmine_log</title>
        <link>https://velog.io/</link>
        <description>Everyday Research &amp; Development</description>
        <lastBuildDate>Sat, 07 Mar 2026 09:59:25 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>JAsmine_log</title>
            <url>https://velog.velcdn.com/images/jasmine_s2/profile/39938fae-87c0-4ea6-9771-c06d1d7fb762/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. JAsmine_log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jasmine_s2" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[anaconda] Conda environment export ]]></title>
            <link>https://velog.io/@jasmine_s2/anaconda-Conda-environment-export</link>
            <guid>https://velog.io/@jasmine_s2/anaconda-Conda-environment-export</guid>
            <pubDate>Sat, 07 Mar 2026 09:59:25 GMT</pubDate>
            <description><![CDATA[<h1 id="conda-환경-내보내기-export">Conda 환경 내보내기 (export)</h1>
<pre><code># conda 전체 환경 → environment.yml
conda env export -n myenv &gt; myenv_environment.yml
</code></pre><pre><code># pip 패키지만 → requirements.txt
conda run -n myenv pip list --format=freeze &gt; myenv_requirements.txt</code></pre><h1 id="기존-환경-가져오기-import">기존 환경 가져오기 (import)</h1>
<pre><code># environment.yml로 conda 환경 생성
conda env create -f myenv_environment.yml</code></pre><pre><code># 이미 만든 환경에 pip 패키지만 설치할 때
conda activate myenv
pip install -r myenv_requirements.txt</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[AI] 실험 Cache]]></title>
            <link>https://velog.io/@jasmine_s2/AI-%EC%8B%A4%ED%97%98-Cache</link>
            <guid>https://velog.io/@jasmine_s2/AI-%EC%8B%A4%ED%97%98-Cache</guid>
            <pubDate>Sat, 07 Feb 2026 02:12:34 GMT</pubDate>
            <description><![CDATA[<h1 id="실험-cache">실험 Cache</h1>
<p>같은 계산을 중간 결과를 저장해 두고, 같은 계산을 반복하지 않는다.</p>
<p>머신러닝 실험에서는 다음 항목에서 사용될 수 있고, 이런것들이 매번 반복되면 매우 비효율적이다.</p>
<ul>
<li>데이터 로딩</li>
<li>임베딩 계산</li>
<li>cross-validation 결과</li>
<li>hyperparameter 평가 결과</li>
</ul>
<h1 id="중요성">중요성</h1>
<p>다음의 문제 상황에 cache를 적용 해 볼 수 있다.</p>
<h2 id="cache-없는-경우">cache 없는 경우:</h2>
<ul>
<li>파라미터 하나 바꿀 때마다</li>
<li>임베딩 다시 계산</li>
<li>retrieval 다시 수행</li>
<li>Cross Validation 다시 수행</li>
</ul>
<p>이로 인해서, 실험 하나 돌리는 데 몇 시간~며칠이 소요된다.</p>
<p>또한,</p>
<ul>
<li>실험 재현 어려움</li>
<li>튜닝/ablation 불가능</li>
</ul>
<h2 id="cache의-기본-철학">cache의 기본 철학</h2>
<blockquote>
<p>“변하지 않는 것은 무조건 저장하고 재사용한다.”
일반적으로:</p>
</blockquote>
<ul>
<li>하이퍼파라미터에 따라 바뀌는 것 → cache ❌</li>
<li>데이터/모델/설정이 같으면 결과 동일 → cache ⭕</li>
</ul>
<h2 id="cache-적용">Cache 적용</h2>
<h3 id="1-데이터-split">(1) 데이터 split</h3>
<ul>
<li>train / val / test 인덱스</li>
<li>Stratified CV fold 인덱스<pre><code>splits/
├── train_idx.npy
├── val_idx.npy
└── cv_folds.pkl</code></pre></li>
</ul>
<h3 id="2-전처리-결과">(2) 전처리 결과</h3>
<ul>
<li>토큰화 결과</li>
<li>정규화된 feature</li>
<li>필터링된 데이터</li>
</ul>
<h3 id="3-임베딩--특징-벡터-가장-중요">(3) 임베딩 / 특징 벡터 (가장 중요)</h3>
<ul>
<li>encoder가 같으면 항상 동일</li>
<li>계산 비용 큼<pre><code>embeddings/
├── encoderA.npy
├── encoderB.npy</code></pre><h3 id="4-hyperparameter-실험-결과">(4) hyperparameter 실험 결과</h3>
</li>
<li>각 설정 → validation score</li>
<li>grid / random search 결과</li>
</ul>
<pre><code>tuning_results.csv</code></pre><h1 id="cache-설계-핵심-패턴">Cache 설계 핵심 패턴</h1>
<ul>
<li>Key = “결과에 영향을 주는 설정” 이기 때문에, Cache 파일 이름이나 key에는 반드시 포함하고, 이름만으로 뭘로 만든 건지 알 수 있어야 함</li>
<li>dataset : 이름</li>
<li>split : seed</li>
<li>encoder: 이름</li>
<li>주요 : hyperparameter</li>
</ul>
<p>예:</p>
<pre><code>cache/
 ├── embed_pubhealth_encoder=bge_base.npy
 ├── retr_pubhealth_encoder=bge_base_top100.pkl</code></pre><h2 id="가장-단순한-cache-코드-패턴">가장 단순한 cache 코드 패턴</h2>
<blockquote>
<p>이 패턴으로 실험 속도 체감이 완전 달라진 것을 알 수 있음</p>
</blockquote>
<pre><code class="language-python">import os
import pickle

def load_or_compute(path, compute_fn):
    if os.path.exists(path):
        with open(path, &quot;rb&quot;) as f:
            return pickle.load(f)
    else:
        result = compute_fn()
        with open(path, &quot;wb&quot;) as f:
            pickle.dump(result, f)
        return result


#사용 예:

embeddings = load_or_compute(
    &quot;cache/embeddings_encoderA.pkl&quot;,
    lambda: compute_embeddings(data, encoderA)
)</code></pre>
<h2 id="hyperparameter-tuning--cache-조합">Hyperparameter Tuning + Cache 조합</h2>
<p>튜닝할 때는: 
중간 결과를 cache, 점수 계산만 반복
튜닝 비용이 N배 → 1배 + α</p>
<p>예:</p>
<ul>
<li>임베딩: cache</li>
<li>retrieval: cache</li>
<li>scoring만 반복<pre><code>embedding (1회)
→ retrieval (1회)
→ scoring (N회)</code></pre></li>
</ul>
<h1 id="cache-vs-재현성">Cache vs 재현성</h1>
<p>(논문 관점)</p>
<p>Cache를 잘 쓰면:</p>
<ul>
<li>동일 실험 완전 재현 가능</li>
<li>seed 고정 가능</li>
<li>실험 로그 명확</li>
</ul>
<h1 id="주의사항-⚠️">주의사항 ⚠️</h1>
<h3 id="하면-안되는-것">하면 안되는 것</h3>
<ul>
<li>설정을 바꾸었는데 cache 재사용</li>
<li>파일 이름에 seed/encoder 안 넣음</li>
<li>cache 무효화 기준 없음</li>
</ul>
<h3 id="해결-방안">해결 방안:</h3>
<ul>
<li>설정 hash 사용</li>
<li>config 기반 key 생성</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AI] Stratified]]></title>
            <link>https://velog.io/@jasmine_s2/AI-Stratified</link>
            <guid>https://velog.io/@jasmine_s2/AI-Stratified</guid>
            <pubDate>Fri, 06 Feb 2026 08:01:43 GMT</pubDate>
            <description><![CDATA[<h1 id="stratified">Stratified</h1>
<p>Stratified(계층화)는 데이터 클래스 비율은 그대로 유지하면서 데이터를 나누는 방법이다.
보통, train / validation / test 분할이나 cross-validation에서 사용한다.</p>
<h2 id="중요성">중요성</h2>
<h3 id="문제-상황">문제 상황</h3>
<p>전체 데이터 100개이면서, 클래스 분포가 아래와 같다면,</p>
<ul>
<li>Class A: 90개</li>
<li>Class B: 10개</li>
</ul>
<p>이걸 random split으로 아무생각 없이 분할하면,
train에는 B가 <em>거의 없고</em>
validation에는 B가 <em>아예 없을 수도</em> 있다.</p>
<p>그래서,</p>
<ul>
<li>모델이 B를 전혀 못 배우거나,</li>
<li>평가 결과가 완전히 왜곡된다 !</li>
</ul>
<h2 id="핵심-아이디어">핵심 아이디어</h2>
<p>Strified는 각 분할(train/val/test)에서 클래스 비율을 전체 데이터와 최대한 동일하게 유지하자는 것이 메인 아이디어 이다.</p>
<blockquote>
<p>특히 불균형 데이터에서 필수적으로 적용이 필요하다 !</p>
</blockquote>
<p>위의 예시에 그대로 적용한다면, 데이터 split은 각각 다음과 같이 적용되어야 한다.</p>
<ul>
<li>train: A 90%, B 10%</li>
<li>validation: A 90%, B 10%</li>
<li>test: A 90%, B 10%</li>
</ul>
<h2 id="stratified를-쓰나">Stratified를 쓰나?</h2>
<ul>
<li>분류 문제(classification)</li>
<li>클래스 불균형이 있는 데이터</li>
<li>성능 비교가 중요한 실험 (논문, 벤치마크)</li>
<li>❗ 회귀(regression)에는 타깃이 연속값이기때문에 stratify 기준이 애매해져 보통은 사용하지 않음</li>
</ul>
<h2 id="코드-예제">코드 예제</h2>
<h3 id="①-stratified-traintest-split">①: Stratified Train/Test Split</h3>
<pre><code class="language-python">scikit-learn
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(
    X, y,
    test_size=0.2,
    stratify=y,      # 핵심
    random_state=42
)</code></pre>
<p><code>stratify=y</code>로 설정하여, train/test 모두에서
y의 클래스 비율을 유지할 수 있다.</p>
<h3 id="②-stratified-k-fold-교차검증">②: Stratified K-Fold (교차검증)</h3>
<p>각 fold마다 클래스 비율 동일하게 설정할 수 있다.</p>
<pre><code class="language-python">from sklearn.model_selection import StratifiedKFold

skf = StratifiedKFold(
    n_splits=5,
    shuffle=True,
    random_state=42
)

for train_idx, val_idx in skf.split(X, y):
    X_train, X_val = X[train_idx], X[val_idx]
    y_train, y_val = y[train_idx], y[val_idx]</code></pre>
<h3 id="grid-search--stratified-실전-활용">Grid Search + Stratified (실전 활용)</h3>
<p>분류 문제에서 하이퍼파라미터 튜닝을 수행할 때는 Stratified CV(cross validation)가 각 검증 분할에서 클래스 비율을 유지하기 위해 표준처럼 사용된다.</p>
<pre><code class="language-python">from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression

grid = GridSearchCV(
    LogisticRegression(),
    param_grid={&quot;C&quot;: [0.1, 1.0, 10.0]},
    cv=StratifiedKFold(n_splits=5),
    scoring=&quot;accuracy&quot;
)

grid.fit(X_train, y_train)</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AI] Hyperparameter Tuning : 실험]]></title>
            <link>https://velog.io/@jasmine_s2/AI-Hyperparameter-Tuning-%EC%8B%A4%ED%97%98</link>
            <guid>https://velog.io/@jasmine_s2/AI-Hyperparameter-Tuning-%EC%8B%A4%ED%97%98</guid>
            <pubDate>Fri, 06 Feb 2026 07:10:15 GMT</pubDate>
            <description><![CDATA[<h1 id="hyperparameter">Hyperparameter</h1>
<p>앞서 말했듯이, 모델의 성능은 하이퍼파라미터(hyperparameters)에 따라서 크게 달라진다. 머신러닝과 딥러닝에서 가장 대표적인 튜닝방법들을 소개한다.</p>
<h2 id="hyperparameter-운영-원칙">Hyperparameter 운영 원칙</h2>
<blockquote>
<ul>
<li>튜닝은 train/validation dataset 에서만 수행</li>
<li>test set은 최종 평가에만 사용 </li>
<li>탐색 범위와 방법을 명확히 기록</li>
<li>과도한 튜닝은 과적합으로 보일 수 있음</li>
</ul>
</blockquote>
<h2 id="1-grid-search-격자-탐색">1. Grid Search (격자 탐색)</h2>
<ul>
<li>미리 정의한 하이퍼파라미터 후보 값들의 모든 조합을 전부 실험하는 방식.</li>
<li>가장 단순하고 확실한 방법</li>
</ul>
<h4 id="예시">예시</h4>
<p>learning rate ∈ {0.001, 0.01, 0.1}
batch size ∈ {16, 32}
→ 총 3 × 2 = 6가지 조합</p>
<h4 id="장점">장점</h4>
<p>구현이 단순하고 직관적
재현성이 높음
논문에서 가장 많이 사용됨</p>
<h4 id="단점">단점</h4>
<p>파라미터 수가 많아질수록 계산 비용 급증
불필요한 조합까지 모두 실험</p>
<h4 id="언제-사용">언제 사용?</h4>
<p>파라미터 수가 적을 때 (1~3개)
탐색 범위가 작을 때</p>
<h2 id="2-random-search-무작위-탐색">2. Random Search (무작위 탐색)</h2>
<p>정의된 범위 내에서 무작위로 하이퍼파라미터 조합을 샘플링해 평가. Grid search의 효율적인 대안.</p>
<h4 id="특징">특징</h4>
<p>Grid Search보다 효율적인 경우가 많음
제한된 횟수만 실험 가능</p>
<h4 id="장점-1">장점</h4>
<p>고차원 파라미터 공간에서 효율적
계산 예산을 직접 제어 가능</p>
<h4 id="단점-1">단점</h4>
<p>최적 조합을 보장하지 않음
결과 변동성 존재</p>
<h4 id="언제-사용-1">언제 사용?</h4>
<p>파라미터가 많을 때
계산 자원이 제한적일 때</p>
<h2 id="3-sequential--heuristic-tuning">3. Sequential / Heuristic Tuning</h2>
<p>한 번에 하나의 파라미터만 조정하며 점진적으로 좋은 값을 찾음. 현실적으로 가장 많이 사용됨</p>
<h4 id="예시-1">예시</h4>
<p>learning rate 고정 → batch size 탐색
batch size 고정 → dropout 탐색</p>
<h4 id="장점-2">장점</h4>
<p>구현과 해석이 매우 쉬움
실무와 논문에서 가장 흔히 사용됨</p>
<h4 id="단점-2">단점</h4>
<p>전역 최적해를 놓칠 수 있음
파라미터 간 상호작용 고려 어려움</p>
<h4 id="언제-사용-2">언제 사용?</h4>
<p>빠른 실험이 필요할 때
탐색 공간이 비교적 명확할 때</p>
<h2 id="4-bayesian-optimization">4. Bayesian Optimization</h2>
<p>이전 실험 결과를 바탕으로 다음에 시도할 파라미터를 확률적으로 선택함. 고급·고비용 상황용</p>
<h4 id="대표-기법">대표 기법</h4>
<p>Gaussian Process
Tree-structured Parzen Estimator (TPE)</p>
<h4 id="장점-3">장점</h4>
<p>실험 횟수 대비 효율적
고비용 모델에 적합</p>
<h4 id="단점-3">단점</h4>
<p>구현 복잡
작은 문제에는 과한 경우도 있음</p>
<h4 id="언제-사용-3">언제 사용?</h4>
<p>실험 비용이 매우 클 때
파라미터 공간이 넓을 때</p>
<h2 id="5-hyperband--early-stopping-기반-탐색">5. Hyperband / Early Stopping 기반 탐색</h2>
<p>성능이 낮은 설정은 조기에 중단하고, 유망한 설정에만 자원을 집중하는 방식.</p>
<h4 id="장점-4">장점</h4>
<p>계산 자원 절약
대규모 실험에 적합</p>
<h4 id="단점-4">단점</h4>
<p>구현 및 설정 복잡
결과 해석이 어려울 수 있음</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AI] Hyperparameter]]></title>
            <link>https://velog.io/@jasmine_s2/AI-Hyperparameter</link>
            <guid>https://velog.io/@jasmine_s2/AI-Hyperparameter</guid>
            <pubDate>Fri, 06 Feb 2026 07:01:29 GMT</pubDate>
            <description><![CDATA[<h1 id="hyperparamer">Hyperparamer</h1>
<p>머신러닝 모델을 학습 할 때, 여러 값들을 설정한다.
이 설정값들은 파라미터와 하이퍼파라미터 두 종류로 나눌 수 있다.</p>
<ul>
<li><strong>하이퍼파라미터(hyperparameter)</strong> : 사람이 미리 정해주는 값</li>
<li>파라미터(parameter) : 학습을 통해 자동으로 배우는 값</li>
</ul>
<h2 id="parameter-vs-hyperparameter">Parameter vs Hyperparameter</h2>
<h3 id="파라미터parameter">파라미터(parameter)</h3>
<ul>
<li>모델이 데이터로부터 직접 학습하는 값</li>
<li>학습 과정에서 자동으로 업데이트됨<blockquote>
<p>학습 결과물</p>
</blockquote>
<h4 id="예시">예시</h4>
</li>
<li>선형 회귀의 가중치(weight)</li>
<li>신경망의 가중치와 편향</li>
<li>임베딩 벡터 값</li>
</ul>
<h3 id="하이퍼파라미터-hyperparameter">하이퍼파라미터 (hyperparameter)</h3>
<ul>
<li>학습 이전에 사람이 설정하는 값</li>
<li>학습 과정에서 자동으로 바뀌지 않음</li>
<li>모델이 어떻게 학습할지를 결정<blockquote>
<p>학습 규칙</p>
</blockquote>
<h4 id="예시-1">예시</h4>
</li>
<li>학습 관련<ul>
<li>learning rate</li>
<li>batch size</li>
<li>optimizer 종류 (SGD, Adam 등)</li>
<li>epoch 수</li>
</ul>
</li>
<li>모델 구조 관련<ul>
<li>레이어 수</li>
<li>히든 유닛 수</li>
<li>dropout 비율</li>
</ul>
</li>
<li>선택 / 추론 관련<ul>
<li>threshold</li>
<li>temperature</li>
</ul>
</li>
</ul>
<h4 id="하이퍼파라미터의-중요성">하이퍼파라미터의 중요성</h4>
<p>같은 모델과 데이터를 사용해도, 하이퍼파라미터에 따라 결과가 완전히 달라지기 때문이다.</p>
<p>예를 들어:</p>
<ul>
<li>learning rate가 너무 크면 → 발산</li>
<li>너무 작으면 → 학습이 매우 느림</li>
<li>batch size가 크면 → 안정적이지만 일반화가 떨어질 수 있음<blockquote>
<p>하이퍼파라미터는 모델의 <code>성능</code>, <code>안정성</code>, <code>학습 속도</code>에 영향을 준다.</p>
</blockquote>
</li>
</ul>
<h3 id="하이퍼파라미터를-정하는-방법">하이퍼파라미터를 정하는 방법</h3>
<p>하이퍼파라미터는 모델을 학습할 때 자동으로 결정되지 않아서, 다음 방법들을 사용해 <code>hyperparameter tuning</code> 과정을 거친다.</p>
<ul>
<li>경험 기반 설정</li>
<li>Grid Search</li>
<li>Random Search</li>
<li>Bayesian Optimization</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AI] Ablation Study]]></title>
            <link>https://velog.io/@jasmine_s2/AI-Ablation-Study</link>
            <guid>https://velog.io/@jasmine_s2/AI-Ablation-Study</guid>
            <pubDate>Fri, 06 Feb 2026 04:30:10 GMT</pubDate>
            <description><![CDATA[<h1 id="ablation">Ablation</h1>
<p>전체 파이프라인을 고정하고, 제안하는 요소를 하나씩 제거하거나 단순화하여 성능 변화를 확인</p>
<h2 id="방법">방법</h2>
<h2 id="공통-규칙★">공통 규칙$^★$</h2>
<ol>
<li><strong>한 번에 한 가지만 바꾸기</strong> (나머지 고정)</li>
<li><strong>Full 모델이 항상 포함돼야 한다</strong></li>
<li><strong>성능뿐 아니라 비용(시간/메모리)도 같이</strong> 분석하여 설득력 증가</li>
</ol>
<h3 id="1-구성요소-제거-ablation-leave-one-out">1) 구성요소 제거 ablation (leave-one-out)</h3>
<p>각 요소가 “필수인지” 보여주는 정석적인 방법
만약 제안 방법이 A+B+C 라면:</p>
<ul>
<li><strong>Full</strong>: A+B+C</li>
<li><strong>w/o A</strong>: B+C</li>
<li><strong>w/o B</strong>: A+C</li>
<li><strong>w/o C</strong>: A+B</li>
</ul>
<h3 id="2-단계별-단순화-ablation-progressive-build-up">2) 단계별 단순화 ablation (progressive build-up)</h3>
<p>특정 부분을 더하여 +x%, 그 다음은 +y%”가 되어, 기여가 명확히 보여줌.
<code>기본</code> → 점차적으로 <code>추가</code>하여 쌓는방식:</p>
<ul>
<li><strong>Base</strong>: 기존 baseline</li>
<li><strong>Base + A</strong></li>
<li><strong>Base + A + B</strong></li>
<li><strong>Base + A + B + C (Full)</strong></li>
</ul>
<h3 id="3-대체교체-ablation">3) 대체(교체) ablation</h3>
<p>“왜 이 설계가 좋은지”를 보여줄 수 있음
제안하는 모듈의 선택지를 교체:</p>
<ul>
<li>scoring 함수: <strong>cosine / dot / learned / heuristic</strong>로 교체</li>
<li>tie-break 규칙: <strong>on/off</strong>로 교체</li>
</ul>
<h3 id="4-하이퍼파라미터-민감도sensitivity">4) 하이퍼파라미터 민감도(sensitivity)</h3>
<p>“우리 방법 튜닝에 과하게 의존하지 않음”을 보여줌 
모델이 특정 값에만 의존하는지 확인:</p>
<ul>
<li>alpha, beta, tempertature, threshold, weight 등</li>
<li>보통 각 파라미터 후보는 <strong>2~5개</strong> 정도로 바꾸어보고, 한 그래프 내에서 표현</li>
</ul>
<h3 id="5-데이터상황별-ablation-slice-analysis">5) 데이터/상황별 ablation (slice analysis)</h3>
<p>해석성이 높아져 논문의 완성도가 높아짐.
전체 평균만 분석한 것이 아니라, “어느 부분에서 좋아지는지” 알 수 있음:</p>
<ul>
<li>input 길이: short, medium, long</li>
<li>input/case 난이도, 카테고리</li>
<li>model 종류별</li>
<li>noisy 포함 여부</li>
</ul>
<h2 id="설계-및-구현">설계 및 구현</h2>
<blockquote>
<p>보통 “처음 설계할 때부터 ablation을 염두하고 모듈화”하고,
구현은 “full pipeline에 <strong>옵션</strong>으로 <strong>끄고 켜는(on/off)</strong> 방식”으로,
개별적인 것이 아니라 <strong>설계 + 구현</strong>을 함께 하는 구조</p>
</blockquote>
<h3 id="이상적인-방법-대부분">이상적인 방법 (대부분)</h3>
<h4 id="설계">설계</h4>
<ul>
<li><p>파이프라인을 <strong>모듈 단위</strong>로 쪼갬</p>
<ul>
<li>Query</li>
<li>Retrieval</li>
<li>Encoder</li>
<li>Reranking</li>
<li>Selection</li>
</ul>
</li>
<li><p>각 모듈은 <strong>독립적으로 교체</strong>할 수 있도록 인터페이스 고정</p>
</li>
</ul>
<h3 id="일반적인-구현-방식">일반적인 구현 방식$^*$</h3>
<p>full pipeline은 하나로 보며, <strong>flag / config로 분기</strong>함.</p>
<pre><code class="language-text">full_pipeline(
  use_encoder_ensemble = True,
  use_rerank = True,
  use_weighting = True
)</code></pre>
<p>Ablation은:</p>
<ul>
<li>w/o rerank → <code>use_rerank=False</code></li>
<li>w/o ensemble → <code>use_encoder_ensemble=False</code></li>
<li>simple rerank → <code>rerank_mode=&quot;cosine&quot;</code></li>
</ul>
<h3 id="full-코드--수정본-여러-개-거의-❌">“full 코드 + 수정본 여러 개” (거의 ❌)</h3>
<ul>
<li>코드 중복</li>
<li>버그 위험</li>
<li>재현 불가</li>
<li>reviewer 질문 대응 불가</li>
</ul>
<p>해당 내용을 논문에 작성한다면,</p>
<blockquote>
<p>“We disable component X while keeping the rest identical.”</p>
</blockquote>
<h3 id="이미-full-pipeline이-있다면">이미 full pipeline이 있다면?</h3>
<h4 id="보통">보통:</h4>
<p>코드 <strong>“수정”보다는  “옵션 추가”</strong>.</p>
<ol>
<li>full pipeline을 <strong>기준선</strong>으로 둠</li>
<li>각 구성요소에 <strong>bypass 경로</strong> 추가<ul>
<li>rerank skip</li>
<li>encoder single로 고정</li>
</ul>
</li>
<li>scoring/selection 단계에서 <strong>대체 로직</strong>만 추가</li>
</ol>
<h3 id="구현-체크리스트-일반적인-기준">구현 체크리스트 (일반적인 기준)</h3>
<p>Ablation이 용이한 파이프라인:</p>
<ul>
<li><input disabled="" type="checkbox"> 각 단계가 함수/클래스로 분리돼 있음</li>
<li><input disabled="" type="checkbox"> 입력/출력 형태가 고정돼 있음</li>
<li><input disabled="" type="checkbox"> 내부 state 공유 없음</li>
<li><input disabled="" type="checkbox"> scoring / selection이 분리돼 있음</li>
<li><input disabled="" type="checkbox"> config 파일 or argparse로 제어 가능</li>
</ul>
<h3 id="논문-작성-문구">논문 작성 문구</h3>
<ul>
<li>예시</li>
</ul>
<blockquote>
<p>All ablation studies are conducted by disabling or replacing individual components in the full pipeline, while keeping the rest of the system unchanged.</p>
</blockquote>
<blockquote>
<p>We implement ablation settings by selectively bypassing specific modules within the same implementation to ensure consistent experimental conditions.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AI] 논문 비교 실험]]></title>
            <link>https://velog.io/@jasmine_s2/AI-%EB%85%BC%EB%AC%B8-%EB%B9%84%EA%B5%90-%EC%8B%A4%ED%97%98</link>
            <guid>https://velog.io/@jasmine_s2/AI-%EB%85%BC%EB%AC%B8-%EB%B9%84%EA%B5%90-%EC%8B%A4%ED%97%98</guid>
            <pubDate>Fri, 06 Feb 2026 03:47:01 GMT</pubDate>
            <description><![CDATA[<p>보통 논문 비교하는 부분 작성할 때, 어떻게 가져다가 쓸까? 
내가 구현한 코드의 특정부분만 교체하는걸까??</p>
<h1 id="비교-실험-기본-원칙-reviewer-시점">비교 실험 기본 원칙 (Reviewer 시점)</h1>
<p>비교 실험헤서 reviewer가 보는건 <code>이 성능 차이가 정말 제안하는 방법</code>덕분인가? 인지이다. 그래서 다른 부분들은 최대한 고정하고 비교하고 싶은 요소만 최소한으로 바꾸어 비교한다.</p>
<h2 id="일반적인-방법">일반적인 방법</h2>
<h3 id="부분-교체-방식-가장-정석">“부분 교체 방식” (가장 정석)</h3>
<p>내가 파이프라인을 구현한 상태라면, 제안하는 방법에 기존(비교군) 방법을 넣어 해당 부분만 변경한다.</p>
<h4 id="예시">예시</h4>
<p>RAG 파이프라인을 기준으로 삼는다면, RAG는 보통 query를 통해 retriever가 관련 있는 문서를 검색해온다. 이 후, 선택된 문서를 통해 정답을 생성한다. 이 과정에서  기존 query의 reformulation, 검색된 문서를 pooling, reranking방법 적용, reader(답변 생성) 등을 적용하여 더 나은 답변을 도출하도록 한다.
만약, reranking 부분만 교체하고 싶다면 아래에서 reranking 방법만 교체한다.</p>
<pre><code class="language-text">Query
 → Query
 → Retrieval (same retriever)
 → Reranking / Selection Method
 → Answer / Evaluation</code></pre>
<p>이 구조에서:</p>
<ul>
<li>Query 동일</li>
<li>Retriever (FAISS 동일)<ul>
<li>encoder 교체<ul>
<li>Baseline: Bert</li>
<li>Prior work A : RoBerta</li>
<li>Prior work B : T5</li>
</ul>
</li>
</ul>
</li>
<li>Top-K 동일</li>
<li>Reranking 동일<ul>
<li><strong>Ours: Ourproposed method</strong></li>
</ul>
</li>
</ul>
<p>그러면 review는 <strong>encoder</strong> 만 교체했다고 알 수 있다.</p>
<h2 id="전체-파이프라인-비교">전체 파이프라인 비교</h2>
<p>전체 파이프라인을 고치는 것은 주의해야할 부분이다. 
비교대상이 아래와 같은 시스템 레벨 논문이라면, </p>
<ul>
<li>“End-to-end RAG framework”</li>
<li>“Joint retrieval + generation optimization”</li>
</ul>
<blockquote>
<p>각 논문에서 제안한 다음 사항등을 유지해야한다.</p>
<ul>
<li><strong>동일 세팅</strong></li>
<li><strong>동일 데이터셋</strong></li>
<li><strong>동일 metrics</strong></li>
</ul>
</blockquote>
<p>그러나 이런 경우에는 </p>
<ul>
<li>retriever가 달라서 그런 거 아닐지</li>
<li>encoder 차이 여부</li>
</ul>
<h2 id="related-work-문단-작성">Related Work 문단 작성</h2>
<p>작성한 Related work는 비교 실험으로 이어진다.</p>
<ul>
<li>예시 문장 :<blockquote>
<p>Unlike prior approaches that rely on a single, fixed encoder for document ranking, our method considers multiple encoder representations during the document selection process.</p>
</blockquote>
</li>
</ul>
<h2 id="주의할-점">주의할 점<code>!</code></h2>
<p>❌ 다른 사람의 논문 결과를 숫자 그대로 가져와서는 안된다.
왜냐하면, 아래와 같은 이슈로 reviewer에게 공격당할 수 있으며,
“This is not comparable.” !</p>
<ul>
<li>dataset split 다름</li>
<li>retriever 다름</li>
<li>metric 정의 다름</li>
</ul>
<p>❌ baseline을 약하게 잡기
비교할 수 있는 baseline을 잘 구성하여 넣는다
예를 들면, BM25사용이 당연한 것인데, 왜 비교군을 들어가지 않았는지 질문을 할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AI] Pytorch Derivative, Partial derivative and Gradient]]></title>
            <link>https://velog.io/@jasmine_s2/AI-Pytorch-Derivative-Partial-derivative-and-Gradient</link>
            <guid>https://velog.io/@jasmine_s2/AI-Pytorch-Derivative-Partial-derivative-and-Gradient</guid>
            <pubDate>Thu, 05 Feb 2026 04:57:33 GMT</pubDate>
            <description><![CDATA[<h1 id="derivative">Derivative</h1>
<p>$$
f&#39;(x) = \lim_{h \to 0} \frac{f(x+h) - f(x)}{h}
$$</p>
<p>함수 $f(x) = x^2$에 대해:
$$
\frac{df}{dx} = 2x
$$
$x=3$일 때:
$$
\frac{df}{dx}\bigg|_{x=3} = 2 \cdot 3 = 6
$$</p>
<pre><code class="language-python">import torch

# 1변수 함수: f(x) = x^2
x = torch.tensor(3.0, requires_grad=True)
y = x ** 2

# 미분 계산
y.backward()
print(f&quot;f(x) = x^2, x=3일 때&quot;)
print(f&quot;df/dx = {x.grad}&quot;)  # 2*3 = 6
</code></pre>
<h1 id="partial-derivative">Partial derivative</h1>
<p>다변수 함수 $f(x, y)$에서 $x$에 대한 편미분:
$$
\frac{\partial f}{\partial x} = \lim_{h \to 0} \frac{f(x+h, y) - f(x, y)}{h}
$$
$y$는 상수로 취급합니다.</p>
<p>함수 $f(x, y) = x^2 + 3xy + y^2$에 대해:
$$
\frac{\partial f}{\partial x} = 2x + 3y
$$
$$
\frac{\partial f}{\partial y} = 3x + 2y
$$</p>
<p>$(x, y) = (2, 3)$일 때:
$$
\frac{\partial f}{\partial x}\bigg|<em>{(2,3)} = 2(2) + 3(3) = 13
$$
$$
\frac{\partial f}{\partial y}\bigg|</em>{(2,3)} = 3(2) + 2(3) = 12
$$</p>
<pre><code class="language-python"># 2변수 함수: f(x, y) = x^2 + 3xy + y^2
x = torch.tensor(2.0, requires_grad=True)
y = torch.tensor(3.0, requires_grad=True)

z = x**2 + 3*x*y + y**2

# 편미분 계산
z.backward()

print(f&quot;\nf(x,y) = x^2 + 3xy + y^2, x=2, y=3일 때&quot;)
print(f&quot;∂f/∂x = {x.grad}&quot;)  # 2x + 3y = 2*2 + 3*3 = 13
print(f&quot;∂f/∂y = {y.grad}&quot;)  # 3x + 2y = 3*2 + 2*3 = 12</code></pre>
<h1 id="gradient">Gradient</h1>
<p>$n$변수 함수 $f(x_1, x_2, \ldots, x_n)$의 그래디언트는 모든 편미분을 벡터로 모은 것:
$$
\nabla f = \begin{bmatrix} 
\frac{\partial f}{\partial x_1} \ 
\frac{\partial f}{\partial x_2} \ 
\vdots \ 
\frac{\partial f}{\partial x_n} 
\end{bmatrix}
$$</p>
<p>그래디언트는 함수가 가장 빠르게 증가하는 방향을 나타냄</p>
<p>함수 $f(x_1, x_2, x_3) = x_1^2 + 2x_2^2 + 3x_3^2$에 대해:
$$
\nabla f = \begin{bmatrix} 
\frac{\partial f}{\partial x_1} \ 
\frac{\partial f}{\partial x_2} \ 
\frac{\partial f}{\partial x_3} 
\end{bmatrix} = \begin{bmatrix} 
2x_1 \ 
4x_2 \ 
6x_3 
\end{bmatrix}
$$</p>
<p>$(x_1, x_2, x_3) = (1, 2, 3)$일 때:
$$
\nabla f\bigg|_{(1,2,3)} = \begin{bmatrix} 
2(1) \ 
4(2) \ 
6(3) 
\end{bmatrix} = \begin{bmatrix} 
2 \ 
8 \ 
18 
\end{bmatrix}
$$</p>
<pre><code class="language-python"># 다변수 함수의 그래디언트
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)

# f(x1, x2, x3) = x1^2 + 2*x2^2 + 3*x3^2
f = x[0]**2 + 2*x[1]**2 + 3*x[2]**2

f.backward()

print(f&quot;\nf(x) = x1^2 + 2*x2^2 + 3*x3^2&quot;)
print(f&quot;Gradient ∇f = {x.grad}&quot;)  # [2*x1, 4*x2, 6*x3] = [2, 8, 18]</code></pre>
<h1 id="application">Application</h1>
<ul>
<li><code>requires_grad=True</code>: 이 텐서에 대해 그래디언트를 계산하겠다는 표시</li>
<li><code>.backward()</code>: 자동 미분 수행</li>
<li><code>.grad</code>: 계산된 그래디언트 확인</li>
<li>Gradient는 모든 편미분을 모은 벡터로, 함수가 가장 빠르게 증가하는 방향을 나타냄</li>
</ul>
<pre><code class="language-python">import torch

# 신경망 파라미터 최적화 예제
# f(w, b) = (w*x - y)^2 (손실 함수)

w = torch.tensor(0.5, requires_grad=True)
b = torch.tensor(0.0, requires_grad=True)

# 데이터
x = torch.tensor(2.0)
y_true = torch.tensor(5.0)

# Forward pass
y_pred = w * x + b
loss = (y_pred - y_true) ** 2

# Backward pass (그래디언트 계산)
loss.backward()

print(f&quot;\n최적화 예제:&quot;)
print(f&quot;예측값: {y_pred.item()}&quot;)
print(f&quot;손실: {loss.item()}&quot;)
print(f&quot;∂L/∂w = {w.grad}&quot;)
print(f&quot;∂L/∂b = {b.grad}&quot;)

# 그래디언트를 이용한 파라미터 업데이트
learning_rate = 0.01
with torch.no_grad():
    w -= learning_rate * w.grad
    b -= learning_rate * b.grad

print(f&quot;업데이트된 w: {w.item()}&quot;)
print(f&quot;업데이트된 b: {b.item()}&quot;)</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AI] Pytorch with Scala, Vector, Matrix]]></title>
            <link>https://velog.io/@jasmine_s2/AI-Pytorch-with-Scala-Vector-Matrix</link>
            <guid>https://velog.io/@jasmine_s2/AI-Pytorch-with-Scala-Vector-Matrix</guid>
            <pubDate>Thu, 05 Feb 2026 02:02:35 GMT</pubDate>
            <description><![CDATA[<h1 id="torch">torch</h1>
<p>PyTorch의 텐서(tensor) 연산을 위한 핵심 모듈</p>
<h2 id="차원별-구조">차원별 구조</h2>
<p><img src="https://velog.velcdn.com/images/jasmine_s2/post/842a1a08-51cf-47c8-92ff-6b32eb315ebc/image.png" alt="">
<img src="https://velog.velcdn.com/images/jasmine_s2/post/d2fda233-6746-4c64-9820-8d5c28f70db8/image.png" alt="">
(자료 : <a href="https://wikidocs.net/233963">https://wikidocs.net/233963</a>)</p>
<h3 id="스칼라-0차원-텐서">스칼라 (0차원 텐서)</h3>
<ul>
<li>단일 숫자 값<pre><code class="language-python">import torch
</code></pre>
</li>
</ul>
<p>scalar = torch.tensor(3.14)
print(scalar.shape)  # torch.Size([])
print(scalar.dim())  # 0</p>
<pre><code>
### Vector (1차원 텐서)
- 숫자들의 1차원 배열

```python
vector = torch.tensor([1, 2, 3, 4])
print(vector.shape)  # torch.Size([4])
print(vector.dim())  # 1</code></pre><h3 id="matrix-2차원-텐서">Matrix (2차원 텐서)</h3>
<ul>
<li>숫자들의 2차원 배열<pre><code class="language-python"></code></pre>
</li>
</ul>
<p>matrix = torch.tensor([[1, 2, 3],
                       [4, 5, 6]])
print(matrix.shape)  # torch.Size([2, 3])
print(matrix.dim())  # 2</p>
<pre><code>
### Tensor (3차원 이상)
- 더 높은 차원의 배열
- 이미지, 비디오 데이터 등

```python
tensor_3d = torch.randn(2, 3, 4)  # (배치, 높이, 너비)
print(tensor_3d.shape)  # torch.Size([2, 3, 4])</code></pre><h2 id="주요-연산">주요 연산</h2>
<h3 id="vector-연산">Vector 연산</h3>
<pre><code class="language-python">v1 = torch.tensor([1.0, 2.0, 3.0])
v2 = torch.tensor([4.0, 5.0, 6.0])

# 내적 (dot product)
dot = torch.dot(v1, v2)  # 1*4 + 2*5 + 3*6 = 32

# 원소별 곱셈
elementwise = v1 * v2  # [4, 10, 18]
</code></pre>
<h3 id="matrix-연산">Matrix 연산</h3>
<pre><code class="language-python">
A = torch.tensor([[1.0, 2.0],
                  [3.0, 4.0]])
B = torch.tensor([[5.0, 6.0],
                  [7.0, 8.0]])

# 행렬 곱셈
C = torch.mm(A, B)
# 또는 C = A @ B

# 전치 (transpose)
A_T = A.T</code></pre>
<h2 id="applications">Applications</h2>
<p>이러한 구조를 통해 딥러닝에서 효율적인 수치 계산과 자동 미분이 가능함</p>
<ul>
<li>Scala    (0 dim) : 손실값(loss), 학습률(learning rate) 등</li>
<li>Vector   (1 dim) : 단일 데이터 샘플의 특징(feature), 편향(bias)</li>
<li>matrix   (2 dim) : 가중치(weights), 배치 데이터(batch)</li>
<li>Tensor  (3+ dim) : 이미지(height×width×channel), 배치 이미지(batch×height×width×channel)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AI] Experiment Setting]]></title>
            <link>https://velog.io/@jasmine_s2/AI-Experiment-Setting</link>
            <guid>https://velog.io/@jasmine_s2/AI-Experiment-Setting</guid>
            <pubDate>Wed, 04 Feb 2026 07:50:00 GMT</pubDate>
            <description><![CDATA[<h1 id="random-seed★">Random seed$^★$</h1>
<ul>
<li>가장 중요<pre><code class="language-python">import random, numpy as np, torch
</code></pre>
</li>
</ul>
<p>def set_seed(seed):
    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)</p>
<pre><code>torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False</code></pre><pre><code>- 고정해야 하는 것:
  - weight init
  - data shuffle
  - client sampling
  - augmentation


# Dataset split 고정
- 매번 새로 생성 ❌
```python
random_split(dataset, [train, test])</code></pre><pre><code class="language-python">generator = torch.Generator().manual_seed(seed)
random_split(dataset, [train, test], generator=generator)</code></pre>
<ul>
<li>split 결과를 파일로 저장</li>
<li>train.txt / test.txt 식으로 고정</li>
</ul>
<h1 id="dataloader-설정">DataLoader 설정</h1>
<pre><code class="language-python">DataLoader(
    dataset,
    shuffle=True,
    worker_init_fn=seed_worker,
    generator=g
)</code></pre>
<pre><code class="language-python">def seed_worker(worker_id):
    worker_seed = torch.initial_seed() % 2**32
    np.random.seed(worker_seed)
    random.seed(worker_seed)</code></pre>
<ul>
<li>num_workers &gt; 0 이면 꼭 필요함</li>
</ul>
<h1 id="cuda-deterministic-모드">CUDA deterministic 모드</h1>
<pre><code class="language-python">torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False</code></pre>
<h1 id="모델-초기화-방식-고정">모델 초기화 방식 고정</h1>
<ul>
<li><p>❌</p>
<pre><code class="language-python">model = Net()  # 내부에서 random init</code></pre>
</li>
<li><p>⭕ seed 먼저 설정하면,</p>
<pre><code class="language-python">set_seed(seed)
model = Net()</code></pre>
</li>
</ul>
<h1 id="환경-고정">환경 고정</h1>
<ul>
<li>예시
OS: Ubuntu 22.04
Python: 3.10
PyTorch: 2.1.0
CUDA: 12.1
GPU: RTX 3090</li>
</ul>
<pre><code class="language-python">pip freeze &gt; requirements.txt</code></pre>
<h1 id="코드-버전-고정">코드 버전 고정</h1>
<pre><code class="language-python">git commit -m &quot;exp alpha=1 seed=44&quot;</code></pre>
<h1 id="실험-로그로-저장">실험 로그로 저장</h1>
<ul>
<li>config 저장<pre><code class="language-python">{
&quot;seed&quot;: 44,
&quot;alpha&quot;: 1,
&quot;rounds&quot;: 1000
}</code></pre>
</li>
<li>argparse dump<pre><code class="language-python">json.dump(vars(args), f)</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Remote] Cursor & VS Code 의 SSH Remote 설정  ]]></title>
            <link>https://velog.io/@jasmine_s2/Remote-Cursor-VS-Code-%EC%9D%98-SSH-Remote-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@jasmine_s2/Remote-Cursor-VS-Code-%EC%9D%98-SSH-Remote-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Wed, 21 Jan 2026 06:04:19 GMT</pubDate>
            <description><![CDATA[<h1 id="ssh-remote">SSH Remote</h1>
<p>linux 서버 구축하고 사용하고 있었는데, GUI로는 너무 느려서 VS Code와 Cursor로 ssh remote 연결해서 사용하기로했다</p>
<p>기본적으로 사용 방법이 같아서, 동일하게 실행해서 editor만 본인이 원하는 대로 설정하면 된다!</p>
<h2 id="server-설정-ubuntu-2404">Server 설정 (Ubuntu 24.04)</h2>
<blockquote>
<ol>
<li>openssh-server 설치</li>
<li>ssh 서비스 실행</li>
<li>계정 생성</li>
<li>SSH 키 등록(안해도 실행되긴 했음)</li>
<li>방화벽에서 22번 허용</li>
</ol>
</blockquote>
<h3 id="openssh-설치-및-실행">OpenSSH 설치 및 실행</h3>
<pre><code>sudo apt update
sudo apt install -y openssh-server</code></pre><h3 id="ssh-서비스-상태-확인">SSH 서비스 상태 확인</h3>
<ul>
<li>실행 상태 확인<pre><code>sudo systemctl status ssh</code></pre></li>
<li>disable(red color)로 되어 있으면, 아래 명령어 실행</li>
</ul>
<pre><code>sudo systemctl enable ssh
sudo systemctl start ssh
# sudo systemctl restart ssh
</code></pre><h3 id="ip--hostname-확인">IP &amp; Hostname 확인</h3>
<pre><code>ip a
# 또는
hostname -I</code></pre><h3 id="server-계정account-확인">Server 계정(account) 확인</h3>
<pre><code>whoami
# 또는
cat /etc/passwd</code></pre><ul>
<li>필요하면 새로 추가<pre><code>sudo adduser yourname
sudo usermod -aG sudo yourname</code></pre></li>
</ul>
<h3 id="ufw-확인">ufw 확인</h3>
<pre><code>sudo ufw allow ssh
sudo ufw allow 22/tcp
sudo ufw reload
# sudo systemctl restart ssh</code></pre><ul>
<li>만약에 포트가 안열려 있거나 하면 아래 내용 확인<pre><code>ss -ntl | grep :22</code></pre><pre><code>LISTEN 0 128 0.0.0.0:22 # port가 열려 있는 경우</code></pre></li>
</ul>
<h2 id="clientlocal-설정">Client(Local) 설정</h2>
<h3 id="server-연결상태-확인">Server 연결상태 확인</h3>
<ul>
<li>cmd 에서<pre><code>ping 192.168.205.69</code></pre></li>
</ul>
<h3 id="vs-code-설정-cursor동일">VS Code 설정 (Cursor동일)</h3>
<ol>
<li>Extensions → <code>Remote - SSH</code> 검색해서 설치</li>
<li><code>F1</code> → <code>Remote-SSH: Connect to Host</code> 선택 후,</li>
<li>blank에 아래 내용 입력: <pre><code>server_account@192.168.0.IP </code></pre></li>
<li>연결되면, password 입력</li>
<li>나중에 연결 설정 수정할 때 <code>nano ~/.ssh/config</code>로 들어가서, 필요시 수정<pre><code>Host lab-server
 HostName {192.168.0.IP}
 User {server_account}
 IdentityFile ~/.ssh/id_ed25519</code></pre></li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ML] Bi-Encoder and Cross-Encoder]]></title>
            <link>https://velog.io/@jasmine_s2/ML-Bi-Encoder-and-Cross-Encoder</link>
            <guid>https://velog.io/@jasmine_s2/ML-Bi-Encoder-and-Cross-Encoder</guid>
            <pubDate>Mon, 05 Jan 2026 10:39:58 GMT</pubDate>
            <description><![CDATA[<h1 id="encoder">Encoder</h1>
<p>Encoder는 어떤 정보를 압축 하거나, 변형하여 특정 형태로 만들어 내는 것을 말함
ML에서는 다양한 Encoder가 있고, Bi-Encoder와 Cross-Encoder 가 있음</p>
<h2 id="bi-encoder">Bi-encoder</h2>
<h3 id="1단계">1단계:</h3>
<ul>
<li>질문과 문서를 각각 따로 인코딩
질문 → [0.2, 0.8, 0.1, ...]  벡터1
문서A → [0.3, 0.7, 0.2, ...]  벡터2
문서B → [0.9, 0.1, 0.5, ...]  벡터3
문서C → [0.25, 0.75, 0.15, ...] 벡터4</li>
</ul>
<h3 id="2단계">2단계:</h3>
<ul>
<li>인코딩(임베딩)한 내용을 기반으로 코사인 유사도 계산
질문 vs A = 0.85
질문 vs B = 0.32
질문 vs C = 0.78</li>
</ul>
<h3 id="결과">결과</h3>
<ul>
<li>A &gt; C &gt; B 순위</li>
<li>문서 A, B, C의 벡터를 미리 만들어 두고 새로운 질문만 인코딩 하여 비교 가능 </li>
</ul>
<h2 id="cross-encoder">Cross-encoder</h2>
<h3 id="1단계-1">1단계</h3>
<ul>
<li>질문과 답을 쌍(pair)으로 함께 입력
입력1: [CLS] 질문 A [SEP] 답변 A → 0.92점
입력2: [CLS] 질문 A [SEP] 답변 B → 0.05점
입력3: [CLS] 질문 A [SEP] 답변 C → 0.81점</li>
</ul>
<h3 id="결과-1">결과</h3>
<ul>
<li>A &gt; C &gt; B 순위
<code>장점</code>: &quot;파이썬&quot;과 &quot;Python&quot;, &quot;파일 읽기&quot;와 &quot;open() 함수&quot; 등의 단어의 <code>관계</code>를 직접 비교하며 판단해서 더 정확함
<code>단점</code>: 매번 3번 인코딩해야 함. 문서가 100만개면 100만번 새로 인코딩하여 연산</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[NLP] Tokenizer]]></title>
            <link>https://velog.io/@jasmine_s2/NLP-Tokenizer</link>
            <guid>https://velog.io/@jasmine_s2/NLP-Tokenizer</guid>
            <pubDate>Thu, 20 Nov 2025 01:49:25 GMT</pubDate>
            <description><![CDATA[<h1 id="tokenizer">Tokenizer</h1>
<p><strong>BPE, WordPiece, Unigram(=SentencePiece Unigram)</strong> 세 가지 토크나이저를 <strong>같은 코퍼스</strong>, <strong>같은 문장</strong>으로 비교</p>
<h2 id="python-예제">Python 예제</h2>
<ul>
<li>BPE vs WordPiece vs Unigram 비교</li>
</ul>
<pre><code class="language-python">from tokenizers import Tokenizer, models, trainers, pre_tokenizers

# --------------------------
# 1. 샘플 코퍼스 준비
# --------------------------
corpus = [
    &quot;Machine learning is fascinating.&quot;,
    &quot;Deep learning models improve with data.&quot;,
    &quot;Large language models are powerful.&quot;,
    &quot;Tokenization affects model performance.&quot;
]

# ==========================
# 2. BPE Tokenizer
# ==========================
bpe_tokenizer = Tokenizer(models.BPE())
bpe_tokenizer.pre_tokenizer = pre_tokenizers.Whitespace()

bpe_trainer = trainers.BpeTrainer(
    vocab_size=60,
    special_tokens=[&quot;[PAD]&quot;, &quot;[UNK]&quot;, &quot;[CLS]&quot;, &quot;[SEP]&quot;]
)
bpe_tokenizer.train_from_iterator(corpus, bpe_trainer)

# ==========================
# 3. WordPiece Tokenizer
# ==========================
wp_tokenizer = Tokenizer(models.WordPiece(unk_token=&quot;[UNK]&quot;))
wp_tokenizer.pre_tokenizer = pre_tokenizers.Whitespace()

wp_trainer = trainers.WordPieceTrainer(
    vocab_size=60,
    special_tokens=[&quot;[PAD]&quot;, &quot;[UNK]&quot;, &quot;[CLS]&quot;, &quot;[SEP]&quot;]
)
wp_tokenizer.train_from_iterator(corpus, wp_trainer)

# ==========================
# 4. Unigram Tokenizer (SentencePiece Unigram)
# ==========================
uni_tokenizer = Tokenizer(models.Unigram())
uni_tokenizer.pre_tokenizer = pre_tokenizers.Whitespace()

uni_trainer = trainers.UnigramTrainer(
    vocab_size=60,
    special_tokens=[&quot;[PAD]&quot;, &quot;[UNK]&quot;, &quot;[CLS]&quot;, &quot;[SEP]&quot;]
)
uni_tokenizer.train_from_iterator(corpus, uni_trainer)

# --------------------------
# 5. 비교 문장
# --------------------------
text = &quot;Tokenization improves language models&quot;

print(&quot;=== BPE ===&quot;)
print(bpe_tokenizer.encode(text).tokens)

print(&quot;\n=== WordPiece ===&quot;)
print(wp_tokenizer.encode(text).tokens)

print(&quot;\n=== Unigram ===&quot;)
print(uni_tokenizer.encode(text).tokens)</code></pre>
<hr>
<h2 id="결과">결과</h2>
<pre><code>=== BPE ===
[&#39;To&#39;, &#39;k&#39;, &#39;en&#39;, &#39;i&#39;, &#39;z&#39;, &#39;at&#39;, &#39;i&#39;, &#39;o&#39;, &#39;n&#39;, &#39;i&#39;, &#39;m&#39;, &#39;p&#39;, &#39;r&#39;, &#39;o&#39;, &#39;v&#39;, &#39;e&#39;, &#39;s&#39;, &#39;l&#39;, &#39;an&#39;, &#39;g&#39;, &#39;u&#39;, &#39;age&#39;, &#39;models&#39;]

=== WordPiece ===
[&#39;T&#39;, &#39;##o&#39;, &#39;##k&#39;, &#39;##e&#39;, &#39;##n&#39;, &#39;##i&#39;, &#39;##z&#39;, &#39;##at&#39;, &#39;##i&#39;, &#39;##o&#39;, &#39;##n&#39;, &#39;i&#39;, &#39;##m&#39;, &#39;##p&#39;, &#39;##r&#39;, &#39;##o&#39;, &#39;##v&#39;, &#39;##e&#39;, &#39;##s&#39;, &#39;l&#39;, &#39;##a&#39;, &#39;##n&#39;, &#39;##g&#39;, &#39;##u&#39;, &#39;##a&#39;, &#39;##g&#39;, &#39;##e&#39;, &#39;model&#39;, &#39;##s&#39;]

=== Unigram ===
[&#39;T&#39;, &#39;o&#39;, &#39;k&#39;, &#39;e&#39;, &#39;ni&#39;, &#39;z&#39;, &#39;ati&#39;, &#39;o&#39;, &#39;n&#39;, &#39;i&#39;, &#39;m&#39;, &#39;p&#39;, &#39;r&#39;, &#39;o&#39;, &#39;v&#39;, &#39;e&#39;, &#39;s&#39;, &#39;l&#39;, &#39;a&#39;, &#39;ng&#39;, &#39;u&#39;, &#39;a&#39;, &#39;g&#39;, &#39;e&#39;, &#39;model&#39;, &#39;s&#39;]</code></pre><h2 id="세-방식-비교표">세 방식 비교표</h2>
<h3 id="핵심-비교-요약">핵심 비교 요약</h3>
<table>
<thead>
<tr>
<th>항목</th>
<th>BPE</th>
<th>WordPiece</th>
<th>Unigram (SentencePiece)</th>
</tr>
</thead>
<tbody><tr>
<td><strong>학습 방식</strong></td>
<td>자주 등장하는 byte pair 병합</td>
<td>확률 기반 최대 우도 서브워드 조합</td>
<td>전체 단어 분해 후보 세트를 만들고 확률적으로 최적화</td>
</tr>
<tr>
<td><strong>서브워드 분해 특징</strong></td>
<td>직관적, 병합 기반</td>
<td>&#39;##&#39; 접두사로 subword 표시</td>
<td>가장 가능성 높은 조합 선택 (probabilistic)</td>
</tr>
<tr>
<td><strong>OOV 처리</strong></td>
<td>잘 처리함</td>
<td>잘 처리함</td>
<td>가장 강함 (여러 분해 후보 중 선택)</td>
</tr>
<tr>
<td><strong>장점</strong></td>
<td>빠르고 직관적</td>
<td>안정적, BERT류에서 사용</td>
<td>소형 vocab으로도 강력, 다양한 분해 가능</td>
</tr>
<tr>
<td><strong>단점</strong></td>
<td>일부 비직관적 분해 발생</td>
<td>deterministic이라 변화 적음</td>
<td>학습 난이도 약간 높음</td>
</tr>
<tr>
<td><strong>대표 모델</strong></td>
<td>GPT 계열</td>
<td>BERT, RoBERTa</td>
<td>SentencePiece(알파벳/한글 다 지원), T5</td>
</tr>
</tbody></table>
<hr>
<h2 id="tokenization-비교">Tokenization 비교</h2>
<h3 id="bpe">BPE</h3>
<blockquote>
<p>자주 등장하는 쌍을 계속 합쳐 나감</p>
</blockquote>
<pre><code>Token | ization | im | prove | s | language | models</code></pre><h3 id="wordpiece">WordPiece</h3>
<blockquote>
<p>접두사 <code>##</code>로 “중간 조각” 표시</p>
</blockquote>
<pre><code>Token | ##ization | im | ##proves | language | models</code></pre><h3 id="unigram">Unigram</h3>
<blockquote>
<p>여러 후보 중 가장 확률 높은 조합을 선택</p>
</blockquote>
<pre><code>Token | ization | impro | ves | language | models</code></pre><h2 id="tokenizer-결과-요약">Tokenizer 결과 요약</h2>
<h3 id="1-bpe-결과"><strong>1) BPE 결과</strong></h3>
<pre><code>[&#39;To&#39;, &#39;k&#39;, &#39;en&#39;, &#39;i&#39;, &#39;z&#39;, &#39;at&#39;, ...]</code></pre><p>✔ <strong>자주 등장하는 문자 쌍만 병합됨</strong>
✔ 코퍼스가 너무 작아서 대부분 <strong>문자 단위 토큰</strong>
✔ 단어 내부에서 <strong>빈번한 조합만 조금씩 합쳐짐</strong>
→ BPE의 본질: <strong>통계적으로 자주 나오는 조합부터 합친다</strong></p>
<hr>
<h3 id="2-wordpiece-결과"><strong>2) WordPiece 결과</strong></h3>
<pre><code>[&#39;T&#39;, &#39;##o&#39;, &#39;##k&#39;, &#39;##e&#39;, &#39;##n&#39;, ...]</code></pre><p>✔ 대부분 <strong>문자 단위</strong>
✔ WordPiece는 “OOV를 피하도록” 가장 작은 단위로 나누는 경향
✔ 뒤에 붙은 <code>##</code>는 <strong>이전 토큰의 연속(subword)</strong>
→ WordPiece의 본질: <strong>안정적이고 규칙적인 분해, 항상 단어 시작/중간 구분 유지</strong></p>
<hr>
<h3 id="3-unigram-결과-의미"><strong>3) Unigram 결과 의미</strong></h3>
<pre><code>[&#39;T&#39;, &#39;o&#39;, &#39;k&#39;, &#39;e&#39;, &#39;ni&#39;, &#39;z&#39;, &#39;ati&#39;, ...]</code></pre><p>✔ <strong>확률 기반 선택 모델 → 가장 가능성이 높은 subword 선택</strong>
✔ 그래서 문자 단위 + 2~3글자 subword가 섞여 있음
✔ 다양한 분해 후보 중 “전체 문장의 우도를 최대로 만드는 조합” 선택
→ Unigram의 본질: <strong>확률적으로 가장 자연스러운 분해 선택 (가장 flexible)</strong></p>
<hr>
<h2 id="요약">요약</h2>
<ul>
<li><strong>BPE는 자주 나오는 조합을 합치고</strong>,</li>
<li><strong>WordPiece는 규칙적으로 글자를 잘게 나누고</strong>,</li>
<li><strong>Unigram은 확률적으로 가장 자연스러운 subword를 선택한다.</strong></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[NLP] max_length vs. token?]]></title>
            <link>https://velog.io/@jasmine_s2/NLP-maxlength-vs.-token</link>
            <guid>https://velog.io/@jasmine_s2/NLP-maxlength-vs.-token</guid>
            <pubDate>Mon, 17 Nov 2025 00:53:44 GMT</pubDate>
            <description><![CDATA[<h2 id="max_length-vs-token">max_length vs. token?</h2>
<blockquote>
<p>Text(input) : &quot;<code>인공지능은 정말 재미있어요</code>!&quot;</p>
</blockquote>
<ul>
<li>max_length: 15글자</li>
<li>tokens: 약 8-12개 (모델마다 상이)</li>
</ul>
<table>
<thead>
<tr>
<th>구분</th>
<th>maxlength</th>
<th>token</th>
</tr>
</thead>
<tbody><tr>
<td>단위</td>
<td>문자(character) 개수</td>
<td>의미 단위 조각</td>
</tr>
<tr>
<td>사용처</td>
<td>HTML 입력 필드</td>
<td>AI 모델 (GPT, Claude 등)</td>
</tr>
<tr>
<td>측정</td>
<td>정확히 글자 수</td>
<td>언어/단어에 따라 다름</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AI] K-fold 교차 검증(K-fold cross-validation)]]></title>
            <link>https://velog.io/@jasmine_s2/AI-K-fold-%EA%B5%90%EC%B0%A8-%EA%B2%80%EC%A6%9DK-fold-cross-validation</link>
            <guid>https://velog.io/@jasmine_s2/AI-K-fold-%EA%B5%90%EC%B0%A8-%EA%B2%80%EC%A6%9DK-fold-cross-validation</guid>
            <pubDate>Wed, 01 Oct 2025 01:16:40 GMT</pubDate>
            <description><![CDATA[<h1 id="k-fold-교차-검증k-fold-cross-validation">K-fold 교차 검증(K-fold cross-validation)</h1>
<blockquote>
<p>K-fold 교차 검증은 모델의 일반화 성능을 신뢰성 있게 측정하는 중요한 표준 도구</p>
</blockquote>
<p>머신러닝에서 데이터셋을 K개의 하위 집합(폴드)으로 나누어 반복적으로 학습과 평가를 수행하는 대표적인 검증 기법이다. 전체 데이터를 K개로 나눈 뒤, 각 폴드가 한 번씩 검증 세트로 사용되고 나머지 폴드는 학습 세트로 사용되어 총 K번의 학습-검증이 이루어짐</p>
<h2 id="k-fold-구조와-과정">K-Fold 구조와 과정</h2>
<ul>
<li>주어진 전체 데이터가 K개로 고르게 분할</li>
<li>반복적으로, 한 폴드를 검증 세트로, 나머지 K-1개 폴드를 학습 세트로 사용</li>
<li>각 반복(iteration)마다 모델이 학습되고 평가</li>
<li>마지막에는 K번 평가 결과의 평균이 최종 모델의 성능 지표로 활용</li>
</ul>
<h2 id="주요-특징과-활용">주요 특징과 활용</h2>
<ul>
<li>데이터가 적거나 불균형한 경우에도 일반적인 검증보다 더 신뢰성 있게 모델 성능을 평가할 수 있음</li>
<li>K 값은 데이터 크기와 상황에 따라 정하며, 일반적으로 5~10을 많이 사용</li>
<li>불균형 데이터셋에는 계층적 분할(Stratified K-Fold)을 적용해 폴드별 클래스 분포를 일정하게 할 수 있음</li>
</ul>
<h2 id="예시-코드-python-scikit-learn">예시 코드 (Python, scikit-learn)</h2>
<ul>
<li>이 코드는 데이터를 5개 폴드로 섞어서 분할하고, 각 폴드마다 학습 및 평가를 반복<pre><code class="language-python">from sklearn.model_selection import KFold
</code></pre>
</li>
</ul>
<p>kf = KFold(n_splits=5, shuffle=True, random_state=42)
for train_idx, test_idx in kf.split(X):
    X_train, X_test = X[train_idx], X[test_idx]
    y_train, y_test = y[train_idx], y[test_idx]
    # 모델 학습 및 평가</p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[AI] Macro vs. Micro metrics]]></title>
            <link>https://velog.io/@jasmine_s2/AI-Macro-vs.-Micro-metrics</link>
            <guid>https://velog.io/@jasmine_s2/AI-Macro-vs.-Micro-metrics</guid>
            <pubDate>Tue, 30 Sep 2025 05:08:31 GMT</pubDate>
            <description><![CDATA[<h2 id="macro-vs-micro">Macro vs Micro</h2>
<p>Macro, macro는 기본적으로 실제 대비 예측을 어떻게 헀는지 평가를 위한 지표들로,</p>
<ul>
<li><code>Macro</code>는 라벨끼리 모아서 성능을 평가한 후, n개의 라벨이 얻은 예측값(T or P)를 계산 라벨별 메트릭(P, R, F1, A)을 평균 낸 것</li>
<li><code>Micro</code>는 라벨을 구분하지 않고 전체 예측한 값(T or P)를 모두 모아서 메트릭(P, R, F1, A)로 계산한 것</li>
<li><code>Label-wise</code> 평가는 라벨로만 예측한 값에 대해 메트릭(P, R, F1,A)를 계산한것</li>
</ul>
<h3 id="micro-metrics-마이크로-메트릭">Micro Metrics (마이크로 메트릭)</h3>
<ul>
<li><strong>정의</strong>: 모든 토큰을 하나로 합쳐서 계산</li>
<li><strong>토큰 예시</strong>: <pre><code>문장: &quot;John Smith lives in New York&quot;
토큰: [&quot;John&quot;, &quot;Smith&quot;, &quot;lives&quot;, &quot;in&quot;, &quot;New&quot;, &quot;York&quot;]
라벨: [&quot;B-PERSON&quot;, &quot;I-PERSON&quot;, &quot;O&quot;, &quot;O&quot;, &quot;B-LOCATION&quot;, &quot;I-LOCATION&quot;]
예측: [&quot;B-PERSON&quot;, &quot;I-PERSON&quot;, &quot;O&quot;, &quot;O&quot;, &quot;B-LOCATION&quot;, &quot;I-LOCATION&quot;]
실제: [&quot;B-PERSON&quot;, &quot;I-PERSON&quot;, &quot;O&quot;, &quot;O&quot;, &quot;B-LOCATION&quot;, &quot;I-LOCATION&quot;]
</code></pre></li>
</ul>
<p>→ 모든 엔티티 토큰(B-PERSON, I-PERSON, B-LOCATION, I-LOCATION)을 합쳐서 전체적으로 TP/FP/FN을 계산</p>
<pre><code>- **계산 방식**: 전체 TP, FP, FN을 합산 후 계산
- **특징**: 
  - 빈도가 높은 클래스(예: O)의 영향이 큼
  - 전체적인 모델 성능을 반영
  - 데이터 불균형에 민감
- **용도**: 전체적인 모델 성능 평가
- **공식**:</code></pre><p>Micro Precision = 전체 TP / (전체 TP + 전체 FP)
Micro Recall = 전체 TP / (전체 TP + 전체 FN)
Micro F1 = 2 × (Micro Precision × Micro Recall) / (Micro Precision + Micro Recall)</p>
<pre><code>
### Macro Metrics (매크로 메트릭)
- **정의**: 각 클래스별로 계산한 후 평균
- **토큰 예시**:</code></pre><p>  문장: &quot;John Smith lives in New York&quot;
  토큰: [&quot;John&quot;, &quot;Smith&quot;, &quot;lives&quot;, &quot;in&quot;, &quot;New&quot;, &quot;York&quot;]
  라벨: [&quot;B-PERSON&quot;, &quot;I-PERSON&quot;, &quot;O&quot;, &quot;O&quot;, &quot;B-LOCATION&quot;, &quot;I-LOCATION&quot;]</p>
<p>  예측: [&quot;B-PERSON&quot;, &quot;I-PERSON&quot;, &quot;O&quot;, &quot;O&quot;, &quot;B-LOCATION&quot;, &quot;I-LOCATION&quot;]
  실제: [&quot;B-PERSON&quot;, &quot;I-PERSON&quot;, &quot;O&quot;, &quot;O&quot;, &quot;B-LOCATION&quot;, &quot;I-LOCATION&quot;]</p>
<p>  → 각 라벨별로 개별 계산:
    B-PERSON: TP=1, FP=0, FN=0 → F1=1.0
    I-PERSON: TP=1, FP=0, FN=0 → F1=1.0<br>    B-LOCATION: TP=1, FP=0, FN=0 → F1=1.0
    I-LOCATION: TP=1, FP=0, FN=0 → F1=1.0
    O: TP=2, FP=0, FN=0 → F1=1.0</p>
<pre><code>→ Macro F1 = (1.0 + 1.0 + 1.0 + 1.0 + 1.0) / 5 = 1.0</code></pre><pre><code>- **계산 방식**: 클래스별 Precision/Recall/F1의 평균
- **특징**:
  - 모든 클래스에 동일한 가중치
  - 클래스 불균형에 덜 민감
  - 소수 클래스의 성능도 동일하게 반영
- **용도**: 클래스 불균형 상황에서 공정한 평가
- **공식**:</code></pre><p>  Macro Precision = (P1 + P2 + ... + Pn) / n
  Macro Recall = (R1 + R2 + ... + Rn) / n
  Macro F1 = (F1_1 + F1_2 + ... + F1_n) / n</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[NLP] NER 측정 방법(Token-level or Entity level)]]></title>
            <link>https://velog.io/@jasmine_s2/NLP-NER-%EC%B8%A1%EC%A0%95-%EB%B0%A9%EB%B2%95Token-level-or-Entity-level</link>
            <guid>https://velog.io/@jasmine_s2/NLP-NER-%EC%B8%A1%EC%A0%95-%EB%B0%A9%EB%B2%95Token-level-or-Entity-level</guid>
            <pubDate>Sat, 06 Sep 2025 06:15:01 GMT</pubDate>
            <description><![CDATA[<h1 id="ner">NER</h1>
<h2 id="ner-측정-방법">NER 측정 방법</h2>
<p><strong>Token-level F1</strong>: 각 토큰(단어)별로 라벨이 맞는지 확인
<strong>Entity-level F1</strong>: 전체 엔티티 단위로 완전히 맞는지 확인</p>
<h2 id="예시">예시</h2>
<p><strong>문장</strong>: <code>&quot;김철수는 서울에서 삼성전자에 다닌다&quot;</code></p>
<p><strong>정답 라벨:</strong></p>
<pre><code>김철수는 → B-PER I-PER O
서울에서 → B-LOC O
삼성전자에 → B-ORG I-ORG O
다닌다 → O</code></pre><p><strong>모델 예측:</strong></p>
<pre><code>김철수는 → B-PER O O        # &quot;김철수&quot; 중 &quot;철수&quot;를 놓침
서울에서 → B-LOC O         # &quot;서울&quot; 정확히 맞춤
삼성전자에 → B-ORG I-ORG O   # &quot;삼성전자&quot; 정확히 맞춤
다닌다 → O</code></pre><h2 id="점수-계산-비교">점수 계산 비교</h2>
<h3 id="token-level-f1-계산">Token-level F1 계산</h3>
<ul>
<li>전체 토큰: 8개</li>
<li>맞은 토큰: 6개 (김, 서울, 삼성, 전자, 나머지 O들)</li>
<li><strong>정확도가 높게 나옴</strong> (75%)</li>
</ul>
<h3 id="entity-level-f1-계산">Entity-level F1 계산</h3>
<ul>
<li>전체 엔티티: 3개 (김철수, 서울, 삼성전자)</li>
<li>완전히 맞은 엔티티: 2개 (서울, 삼성전자만)</li>
<li><strong>정확도가 낮게 나옴</strong> (67%)</li>
</ul>
<h2 id="설명">설명</h2>
<p><strong>Token-level</strong>은 부분적으로라도 맞으면 점수를 줌</p>
<ul>
<li>&quot;김철수&quot; 중 &quot;김&quot;만 맞춰도 1점</li>
<li>실제로는 이름을 제대로 인식 못했는데 점수가 나옴</li>
</ul>
<p><strong>Entity-level</strong>은 엔티티 전체가 완벽해야 점수를 줌  </p>
<ul>
<li>&quot;김철수&quot; 전체를 다 맞춰야만 1점</li>
<li>실제 사용 시나리오와 더 가까움</li>
</ul>
<h2 id="지표별-활용">지표별 활용</h2>
<p><strong>Token-level F1</strong></p>
<ul>
<li>모델 학습 과정에서 <code>세밀한 성능 분석</code></li>
<li>토큰 단위 정확도가 중요한 연구</li>
</ul>
<p><strong>**Entity-level F1</strong> </p>
<ul>
<li><code>실제 서비스에서 사용할 때</code> (PII 마스킹, 정보 추출 등)</li>
<li>엔티티를 완전히 찾아야 하는 실용적인 평가</li>
</ul>
<h2 id="지표별-수식">지표별 수식</h2>
<p><strong>Token-level F1</strong>
각 토큰별로 TP, FP, FN을 계산:</p>
<pre><code>Precision = TP / (TP + FP)
Recall = TP / (TP + FN)
F1 = 2 × (Precision × Recall) / (Precision + Recall)</code></pre><p><strong>Entity-level F1</strong>
전체 엔티티 span으로 TP, FP, FN 계산:</p>
<pre><code>Precision = 정확히 맞춘 엔티티 수 / 예측한 엔티티 수
Recall = 정확히 맞춘 엔티티 수 / 실제 엔티티 수
F1 = 2 × (Precision × Recall) / (Precision + Recall)</code></pre><h2 id="📊-실제-성능-차이">📊 실제 성능 차이</h2>
<p>Entity-level이 더 엄격해서 점수가 낮게 나오는 게 일반적
보통 같은 모델이라도:</p>
<ul>
<li>Token-level F1: 85-95%</li>
<li>Entity-level F1: 75-85%</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[NER] BIO Tagging]]></title>
            <link>https://velog.io/@jasmine_s2/NER-BIO-Tagging</link>
            <guid>https://velog.io/@jasmine_s2/NER-BIO-Tagging</guid>
            <pubDate>Sat, 06 Sep 2025 05:12:32 GMT</pubDate>
            <description><![CDATA[<h1 id="bio-tagging">BIO Tagging</h1>
<blockquote>
<p><strong>BIO Tagging은 개체명 인식(NER)</strong>이나 시퀀스 라벨링에서 개체의 시작과 내부를 구분해 문장의 구조를 기계가 이해할 수 있도록 도와주는 방법</p>
</blockquote>
<h2 id="개념">개념</h2>
<p><strong>자연어 처리(NLP)</strong>에서 토큰 단위로 개체(entity)의 범위를 표시하는 대표적인 방식
이름 그대로 B–I–O 세 가지 태그를 사용</p>
<h2 id="개체">개체</h2>
<p>텍스트 안에서 특정한 의미적 범주로 구분되는 단위
BIO 태그에서 객체란 <strong>NER이 식별하려는 엔티티 클래스(개체)</strong></p>
<ul>
<li>사람 이름(Person)</li>
<li>조직(Organization)</li>
<li>지명(Location)</li>
<li>날짜/시간(Time)</li>
<li>기타 도메인 특화 엔티티 (예: 질병명, 약품명, 법률 용어 등)</li>
</ul>
<h2 id="태그">태그</h2>
<h4 id="b-begin">B (Begin):</h4>
<ul>
<li>개체의 <code>시작</code>을 의미 </li>
<li>예를 들어, &quot;뉴욕&quot;이라는 지명이 나오면 &quot;뉴&quot;는 B-LOC으로 태깅</li>
</ul>
<h4 id="i-inside">I (Inside):</h4>
<ul>
<li>개체의 <code>내부</code>(계속 이어지는 부분)를 의미</li>
<li>&quot;뉴욕&quot;의 &quot;욕&quot;은 I-LOC으로 태깅</li>
</ul>
<h4 id="o-outside">O (Outside):</h4>
<ul>
<li>어떤 개체에도 <code>속하지 않는</code> 일반 단어를 의미</li>
</ul>
<h2 id="예시-문장">예시 문장:</h2>
<ul>
<li>&quot;나는 뉴욕에 갔다&quot;</li>
<li>토큰별 BIO 태깅:<ul>
<li>나는 → O</li>
<li>뉴 → B-LOC</li>
<li>욕 → I-LOC</li>
<li>에 → O</li>
<li>갔다 → O</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[AI] Loss function]]></title>
            <link>https://velog.io/@jasmine_s2/AI-Loss-function</link>
            <guid>https://velog.io/@jasmine_s2/AI-Loss-function</guid>
            <pubDate>Sat, 06 Sep 2025 05:05:17 GMT</pubDate>
            <description><![CDATA[<h1 id="loss-function">Loss function</h1>
<h2 id="정리">정리</h2>
<h3 id="개념">개념</h3>
<ul>
<li>모델이 예측한 값과 실제 정답 사이의 차이를 수치고 계산하는 함수</li>
<li>값이 작을수록 모델이 예측을 잘 했다는 의미이며, </li>
<li>이 값을 최소화하도록 학습하는 것을 <strong>최적화</strong>(=optimization)라고 함  </li>
</ul>
<h2 id="카테고리별-loss-function">카테고리별 Loss function</h2>
<h3 id="카테고리별-loss-function-요약">카테고리별 Loss function 요약</h3>
<ul>
<li><strong>회귀</strong>: MSE, MAE, Huber, Log-Cosh</li>
<li><strong>분류</strong>: Cross Entropy, NLL, Hinge, Focal, Label Smoothing</li>
<li><strong>임베딩</strong>: Cosine, Contrastive, Triplet, InfoNCE</li>
<li><strong>검출·세그멘테이션</strong>: IoU, Dice, Tversky, GIoU/DIoU/CIoU</li>
</ul>
<hr>
<h3 id="1-회귀-regression">1. 회귀 (Regression)</h3>
<h4 id="1-mean-squared-error-mse">(1) Mean Squared Error (MSE)</h4>
<p>$$
L_{\text{MSE}} = \frac{1}{n}\sum_{i=1}^n (y_i - \hat{y}_i)^2
$$</p>
<ul>
<li>연속값 예측 기본 손실, 이상치에 민감.</li>
</ul>
<h4 id="2-mean-absolute-error-mae">(2) Mean Absolute Error (MAE)</h4>
<p>$$
L_{\text{MAE}} = \frac{1}{n}\sum_{i=1}^n |y_i - \hat{y}_i|
$$</p>
<ul>
<li>이상치에 강건, gradient 일정.</li>
</ul>
<h4 id="3-huber-loss-smooth-l1">(3) Huber Loss (Smooth L1)</h4>
<p>$$
L_\delta(y, \hat{y}) = 
\begin{cases} 
\frac{1}{2}(y-\hat{y})^2, &amp; |y-\hat{y}| \leq \delta \
\delta |y-\hat{y}| - \tfrac{1}{2}\delta^2, &amp; \text{otherwise}
\end{cases}
$$</p>
<ul>
<li>작은 오차는 MSE, 큰 오차는 MAE처럼 동작.</li>
</ul>
<h4 id="4-log-cosh-loss">(4) Log-Cosh Loss</h4>
<p>$$
L(y, \hat{y}) = \sum_{i=1}^n \log\left(\cosh(\hat{y}_i - y_i)\right)
$$</p>
<ul>
<li>MSE와 비슷하지만 이상치에 덜 민감.</li>
</ul>
<hr>
<h3 id="2-분류-classification">2. 분류 (Classification)</h3>
<h4 id="1-cross-entropy-loss">(1) Cross Entropy Loss</h4>
<p>$$
L_{\text{CE}} = - \sum_{i=1}^C y_i \log(\hat{p}_i)
$$</p>
<ul>
<li>가장 널리 쓰이는 분류 손실. Softmax와 함께 사용.</li>
</ul>
<h4 id="2-negative-log-likelihood-nll">(2) Negative Log Likelihood (NLL)</h4>
<p>$$
L_{\text{NLL}} = - \log \hat{p}(y)
$$</p>
<ul>
<li>단일 정답 클래스의 확률을 직접 penalize. (Softmax+NLL = CE)</li>
</ul>
<h4 id="3-hinge-loss">(3) Hinge Loss</h4>
<p>$$
L_{\text{hinge}} = \sum_{i=1}^n \max(0, 1 - y_i \hat{y}_i)
$$</p>
<ul>
<li>마진 기반 학습 (SVM에서 사용).</li>
</ul>
<h4 id="4-focal-loss">(4) Focal Loss</h4>
<p>$$
L_{\text{FL}} = - \alpha (1 - \hat{p}_t)^\gamma \log(\hat{p}_t)
$$</p>
<ul>
<li>어려운 샘플에 집중, 클래스 불균형 대응.</li>
<li>$p_t = \hat{p}(y)$.</li>
</ul>
<h4 id="5-label-smoothing-cross-entropy">(5) Label Smoothing Cross Entropy</h4>
<p>$$
L = - \sum_{i=1}^C \big( (1-\epsilon) y_i + \tfrac{\epsilon}{C} \big) \log(\hat{p}_i)
$$</p>
<ul>
<li>모델의 과도한 확신 방지.</li>
</ul>
<h3 id="3-임베딩--metric-learning">3. 임베딩 / Metric Learning</h3>
<h4 id="1-cosine-embedding-loss">(1) Cosine Embedding Loss</h4>
<p>$$
L = \begin{cases}
1 - \cos(x_1, x_2), &amp; y = 1 \
\max(0, \cos(x_1, x_2) - m), &amp; y = -1
\end{cases}
$$</p>
<ul>
<li>같은 쌍(positive)은 가깝게, 다른 쌍(negative)은 멀게.</li>
</ul>
<h4 id="2-contrastive-loss">(2) Contrastive Loss</h4>
<p>$$
L = (1-y) \frac{1}{2} D^2 + y \frac{1}{2} \max(0, m-D)^2
$$</p>
<ul>
<li>$D = |x_1 - x_2|$, $y=0$ 같은 클래스, $y=1$ 다른 클래스.</li>
</ul>
<h4 id="3-triplet-loss">(3) Triplet Loss</h4>
<p>$$
L = \max(0, d(a,p) - d(a,n) + \alpha)
$$</p>
<ul>
<li>Anchor–Positive는 가깝게, Anchor–Negative는 멀게.</li>
</ul>
<h4 id="4-infonce-loss">(4) InfoNCE Loss</h4>
<p>$$
L = - \log \frac{\exp(\text{sim}(x, x^+)/\tau)}{\sum_{j=1}^N \exp(\text{sim}(x, x_j)/\tau)}
$$</p>
<ul>
<li>Contrastive Learning에서 자주 사용, 여러 negative 대비 positive를 구분.</li>
</ul>
<hr>
<h3 id="4-객체-검출-·-세그멘테이션-detection--segmentation">4. 객체 검출 · 세그멘테이션 (Detection &amp; Segmentation)</h3>
<h4 id="1-iou-loss-jaccard-loss">(1) IoU Loss (Jaccard Loss)</h4>
<p>$$
L_{\text{IoU}} = 1 - \frac{|y \cap \hat{y}|}{|y \cup \hat{y}|}
$$</p>
<ul>
<li>박스/영역 겹침을 최적화.</li>
</ul>
<h4 id="2-dice-loss">(2) Dice Loss</h4>
<p>$$
L_{\text{Dice}} = 1 - \frac{2|y \cap \hat{y}|}{|y| + |\hat{y}|}
$$</p>
<ul>
<li>class imbalance에 강건.</li>
</ul>
<h4 id="3-tversky-loss">(3) Tversky Loss</h4>
<p>$$
L = 1 - \frac{|y \cap \hat{y}|}{|y \cap \hat{y}| + \alpha |y \setminus \hat{y}| + \beta |\hat{y} \setminus y|}
$$</p>
<ul>
<li>FP/ FN 비중 조절 가능 (Dice의 일반화).</li>
</ul>
<h4 id="4-giou--diou--ciou-loss">(4) GIoU / DIoU / CIoU Loss</h4>
<p>(Detection bounding box 용 개선된 IoU)</p>
<p>$$
L_{\text{GIoU}} = 1 - IoU + \frac{|C - (A \cup B)|}{|C|}
$$</p>
<ul>
<li>$C$: 두 박스를 포함하는 최소 영역.</li>
<li>위치 정렬과 수렴 속도를 개선.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[NLP] NER(Named Entity Recognition, 개체명 인식)]]></title>
            <link>https://velog.io/@jasmine_s2/NLP-NERNamed-Entity-Recognition-%EA%B0%9C%EC%B2%B4%EB%AA%85-%EC%9D%B8%EC%8B%9D</link>
            <guid>https://velog.io/@jasmine_s2/NLP-NERNamed-Entity-Recognition-%EA%B0%9C%EC%B2%B4%EB%AA%85-%EC%9D%B8%EC%8B%9D</guid>
            <pubDate>Tue, 02 Sep 2025 23:52:34 GMT</pubDate>
            <description><![CDATA[<h1 id="ner란">NER란?</h1>
<p>－ <strong>NER</strong>은 문장에서 사람, 장소, 조직, 시간, 숫자 등 <strong>의미 있는 단위(개체, Entity)</strong>를 찾아내고 분류하는 작업
－ <code>&quot;이 문장 속에서 중요한 이름이나 값은 뭐지?&quot;</code>를 기계가 알아보게 하는 것</p>
<h2 id="예시">예시</h2>
<p><strong>문장</strong>: 
－ <code>**&quot;스티브 잡스는 1976년에 애플을 공동 창업했다.&quot;**</code></p>
<p><strong>NER 결과</strong>:</p>
<ul>
<li>스티브 잡스 → <code>PER</code> (사람, Person)</li>
<li>1976년 → <code>DATE</code> (날짜/시간, Date)</li>
<li>애플 → <code>ORG</code> (조직, Organization)</li>
</ul>
<h2 id="대표적인-태그-세트">대표적인 태그 세트</h2>
<p>NER 시스템은 보통 <strong>사전 정의된 개체 유형</strong>을 예측한다. 
예:</p>
<ul>
<li><code>PER</code> : 인물(Person)</li>
<li><code>LOC</code> : 위치(Location)</li>
<li><code>ORG</code> : 조직(Organization)</li>
<li><code>DATE</code> : 날짜(Date)</li>
<li><code>TIME</code> : 시간(Time)</li>
<li><code>MONEY</code> : 금액(Money)</li>
<li><code>PERCENT</code> : 퍼센트(Percent)</li>
</ul>
<p>데이터셋에 따라 더 세분화되기도 하고, 단순히 PER/LOC/ORG만 쓰는 경우도 있다.</p>
<h2 id="어떻게-작동할까">어떻게 작동할까?</h2>
<p>NER은 보통 <strong>시퀀스 라벨링(sequence labeling)</strong> 문제로 다룹니다.
즉, 문장을 토큰 단위로 쪼개서 각 토큰에 BIO 같은 라벨을 붙이는 방식이에요.</p>
<ol>
<li>입력 문장을 토큰화 (예: &quot;스티브&quot;, &quot;잡스&quot;, &quot;는&quot;, ...)</li>
<li>각 토큰에 대해 <code>B-PER</code>, <code>I-PER</code>, <code>O</code>, <code>B-ORG</code> 등 라벨을 예측</li>
<li>연속된 토큰을 합쳐 하나의 개체로 인식</li>
</ol>
<h2 id="ner-모델">NER 모델</h2>
<p>NER은 전통적으로 <strong>CRF(Conditional Random Field)</strong> 같은 통계적 모델을 썼지만,
최근에는 <strong>딥러닝 기반</strong>이 많이 쓰인다:</p>
<ul>
<li><strong>BiLSTM-CRF</strong> : 양방향 LSTM + CRF</li>
<li><strong>BERT 기반 NER</strong> : 사전학습 언어모델을 fine-tuning</li>
<li><strong>GPT 계열 모델</strong> : instruction 기반으로 NER 수행 가능</li>
</ul>
<h2 id="응용-분야">응용 분야</h2>
<ul>
<li><strong>챗봇</strong> : 사용자 입력에서 이름/날짜/장소 추출</li>
<li><strong>검색엔진</strong> : 쿼리에서 중요한 개체 뽑아 검색 개선</li>
<li><strong>문서 요약</strong> : 문서 속 인물, 사건, 날짜 자동 추출</li>
<li><strong>의료/법률 텍스트 분석</strong> : 질병명, 약품명, 법률명 등 인식</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>