<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>모두의 코딩</title>
    <link>https://goodteacher.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Thu, 16 Apr 2026 23:06:28 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>은서파</managingEditor>
    <item>
      <title>CLIP</title>
      <link>https://goodteacher.tistory.com/941</link>
      <description>&lt;p&gt;&lt;iframe src=&quot;https://quietjun.github.io/github-pages/ai/cnn/clip.html&quot; id=&quot;iframe_l0zyb&quot; width=&quot;100%&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
  window.addEventListener('message', function(e) {
    if(e.data.height) {
      document.getElementById('iframe_l0zyb').style.height = e.data.height + 'px';
    }
  });
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>ML,DL,LangChain/04_CNN과 이미지 생성모델</category>
      <author>은서파</author>
      <guid isPermaLink="true">https://goodteacher.tistory.com/941</guid>
      <comments>https://goodteacher.tistory.com/941#entry941comment</comments>
      <pubDate>Sun, 22 Mar 2026 23:48:19 +0900</pubDate>
    </item>
    <item>
      <title>Transformer</title>
      <link>https://goodteacher.tistory.com/940</link>
      <description>&lt;p&gt;&lt;iframe src=&quot;https://quietjun.github.io/github-pages/ai/rnn/transformer.html&quot; id=&quot;myIframe&quot; width=&quot;100%&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;script&gt;
  window.addEventListener('message', function(e) {
    if(e.data.height) {
      document.getElementById('myIframe').style.height = e.data.height + 'px';
    }
  });
&lt;/script&gt;</description>
      <category>ML,DL,LangChain/03_토큰화와 합성데이터</category>
      <author>은서파</author>
      <guid isPermaLink="true">https://goodteacher.tistory.com/940</guid>
      <comments>https://goodteacher.tistory.com/940#entry940comment</comments>
      <pubDate>Fri, 20 Mar 2026 21:11:51 +0900</pubDate>
    </item>
    <item>
      <title>RESNet-18</title>
      <link>https://goodteacher.tistory.com/939</link>
      <description>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ko&quot;&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
&lt;title&gt;ResNet-18 — 아키텍처 소개&lt;/title&gt;
&lt;link href=&quot;https://fonts.googleapis.com/css2?family=Bebas+Neue&amp;family=DM+Mono:wght@400;500&amp;family=Noto+Sans+KR:wght@300;400;500;600&amp;display=swap&quot; rel=&quot;stylesheet&quot;&gt;
&lt;style&gt;
:root {
  --bg: #f5f3ef;
  --surface: #ffffff;
  --surface2: #edeae4;
  --border: #d8d3c8;
  --text: #18160f;
  --text-sub: #6b6357;
  --red: #c0392b;
  --red-soft: #faeae8;
  --blue: #2471a3;
  --green: #1e8449;
  --orange: #d68910;
  --mono: 'DM Mono', monospace;
  --sans: 'Noto Sans KR', sans-serif;
  --display: 'Bebas Neue', sans-serif;
}
*{margin:0;padding:0;box-sizing:border-box;}
body{background:var(--bg);color:var(--text);font-family:var(--sans);font-size:15px;line-height:1.7;}

/* ── HEADER ── */
header{background:var(--text);color:#f5f3ef;padding:56px 64px 44px;position:relative;overflow:hidden;}
header::after{content:'18';position:absolute;right:40px;top:-20px;font-family:var(--display);font-size:280px;color:rgba(255,255,255,0.04);line-height:1;pointer-events:none;}
.h-tag{font-family:var(--mono);font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:rgba(255,255,255,.38);margin-bottom:14px;}
header h1{font-family:var(--display);font-size:80px;letter-spacing:2px;line-height:1;color:#f5f3ef;}
header h1 em{color:var(--red);font-style:normal;}
.h-sub{font-size:15px;color:rgba(255,255,255,.5);font-weight:300;margin-top:14px;max-width:560px;line-height:1.8;}
.h-badges{display:flex;gap:10px;margin-top:22px;flex-wrap:wrap;}
.h-badge{font-family:var(--mono);font-size:11px;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.11);border-radius:4px;padding:5px 12px;color:rgba(255,255,255,.5);}
.h-badge b{color:var(--red);}

/* ── MAIN ── */
main{max-width:1160px;margin:0 auto;padding:60px 48px;display:grid;gap:52px;}

/* ── LABELS ── */
.sec-label{font-family:var(--mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--red);margin-bottom:8px;}
.sec-title{font-family:var(--display);font-size:34px;letter-spacing:1px;color:var(--text);margin-bottom:24px;}

/* ── STAT CARDS ── */
.stat-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;}
.stat-card{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:22px 18px;transition:transform .2s,box-shadow .2s;cursor:default;}
.stat-card:hover{transform:translateY(-3px);box-shadow:0 8px 24px rgba(0,0,0,.08);}
.stat-card.dark{background:var(--text);border-color:var(--text);}
.stat-num{font-family:var(--display);font-size:44px;line-height:1;color:var(--text);}
.stat-card.dark .stat-num{color:#f5f3ef;}
.stat-unit{font-family:var(--mono);font-size:11px;color:var(--text-sub);margin-top:4px;}
.stat-card.dark .stat-unit{color:rgba(245,243,239,.45);}
.stat-desc{font-size:12px;color:var(--text-sub);margin-top:10px;line-height:1.6;}
.stat-card.dark .stat-desc{color:rgba(245,243,239,.4);}

/* ── DEGRADATION PROBLEM ── */
.problem-grid{display:grid;grid-template-columns:1fr 1fr;gap:32px;background:var(--surface);border:1px solid var(--border);border-left:4px solid var(--red);border-radius:8px;padding:32px;}
.problem-title{font-family:var(--display);font-size:22px;letter-spacing:.5px;margin-bottom:12px;}
.problem-body{font-size:13px;color:var(--text-sub);line-height:1.85;}
.problem-body strong{color:var(--text);}
.bar-chart{display:flex;flex-direction:column;gap:10px;margin-top:6px;}
.bar-row{display:flex;align-items:center;gap:10px;}
.bar-label{font-family:var(--mono);font-size:11px;color:var(--text-sub);width:110px;flex-shrink:0;}
.bar-track{flex:1;height:20px;background:var(--surface2);border-radius:3px;overflow:hidden;}
.bar-fill{height:100%;border-radius:3px;width:0;transition:width 1.2s cubic-bezier(.4,0,.2,1);}
.bar-val{font-family:var(--mono);font-size:11px;width:44px;text-align:right;flex-shrink:0;}

/* ── SKIP CONNECTION ── */
.skip-grid{display:grid;grid-template-columns:1fr auto;gap:40px;align-items:center;background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:32px 36px;}
.skip-text p{font-size:14px;color:var(--text-sub);line-height:1.85;margin-bottom:14px;}
.formula{background:var(--surface2);border:1px solid var(--border);border-radius:6px;padding:14px 20px;font-family:var(--mono);font-size:16px;text-align:center;margin-top:4px;}
.formula em{color:var(--red);font-style:normal;font-weight:500;}

/* ── ARCHITECTURE INTERACTIVE ── */
.arch-outer{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:32px;}
.arch-scroll{overflow-x:auto;padding-bottom:8px;}
.arch-flow{display:flex;align-items:flex-end;gap:0;min-width:960px;padding:16px 0;}

.arch-block{display:flex;flex-direction:column;align-items:center;gap:8px;cursor:pointer;position:relative;}
.arch-body{border-radius:6px;padding:10px 8px;text-align:center;min-width:70px;transition:transform .2s,box-shadow .2s;border:2px solid transparent;}
.arch-block:hover .arch-body,.arch-block.active .arch-body{transform:translateY(-4px);box-shadow:0 8px 20px rgba(0,0,0,.12);}
.arch-block.active .arch-body{outline:3px solid var(--red);outline-offset:2px;}
.arch-bname{font-family:var(--mono);font-size:10px;font-weight:500;line-height:1.3;}
.arch-bsize{font-family:var(--mono);font-size:9px;opacity:.6;margin-top:2px;}
.arch-label{font-family:var(--mono);font-size:9px;color:var(--text-sub);text-align:center;max-width:80px;line-height:1.4;}

.arch-arrow{width:18px;height:2px;background:var(--border);position:relative;flex-shrink:0;align-self:center;margin-bottom:28px;}
.arch-arrow::after{content:'';position:absolute;right:-1px;top:-4px;border:5px solid transparent;border-left-color:var(--border);}

/* block colour themes */
.b-img{background:#e8f4fb;border-color:#2471a3 !important;color:#1a4f6e;}
.b-conv{background:#fef5e7;border-color:#d68910 !important;color:#7e5009;}
.b-layer{background:#fbeee6;border-color:#c0392b !important;color:#7b241c;}
.b-pool{background:#e9f7ef;border-color:#1e8449 !important;color:#145a32;}
.b-out{background:var(--text);border-color:var(--text) !important;color:#f5f3ef;}

.layer-group{display:flex;flex-direction:column;align-items:center;gap:5px;}
.layer-tag{font-family:var(--mono);font-size:9px;background:var(--red);color:white;border-radius:3px;padding:2px 7px;}
.layer-inner{border:2px dashed #c0392b;border-radius:6px;padding:7px 9px;background:rgba(192,57,43,.04);display:flex;flex-direction:column;gap:3px;}
.mini-blk{background:var(--red-soft);border:1px solid #c0392b;border-radius:4px;padding:4px 7px;font-family:var(--mono);font-size:9px;color:#7b241c;text-align:center;min-width:66px;}
.skip-blk{background:#fff8f8;border:1px dashed #e8a89e;border-radius:4px;padding:3px 7px;font-family:var(--mono);font-size:8px;color:#b07070;text-align:center;min-width:66px;}

/* detail panel */
.detail-panel{margin-top:24px;background:var(--surface2);border:1px solid var(--border);border-radius:8px;padding:0;overflow:hidden;transition:max-height .4s ease;max-height:0;}
.detail-panel.open{max-height:400px;}
.detail-inner{padding:24px 28px;}
.detail-title{font-family:var(--display);font-size:20px;letter-spacing:.5px;margin-bottom:14px;color:var(--text);}
.detail-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;}
.detail-item{background:var(--surface);border:1px solid var(--border);border-radius:6px;padding:12px 14px;}
.detail-key{font-family:var(--mono);font-size:10px;color:var(--text-sub);letter-spacing:.06em;text-transform:uppercase;}
.detail-val{font-family:var(--mono);font-size:13px;color:var(--text);margin-top:4px;}
.detail-hint{font-family:var(--mono);font-size:11px;color:var(--text-sub);margin-top:12px;padding-top:12px;border-top:1px solid var(--border);}

/* ── RESIDUAL BLOCK SIMULATOR ── */
.resblock-outer{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:32px;}
.resblock-controls{display:flex;gap:10px;margin-bottom:24px;flex-wrap:wrap;}
.rb-btn{font-family:var(--mono);font-size:11px;padding:6px 14px;border:1.5px solid var(--border);border-radius:4px;background:var(--surface);color:var(--text-sub);cursor:pointer;transition:all .15s;}
.rb-btn:hover{border-color:var(--red);color:var(--red);}
.rb-btn.active{background:var(--red);border-color:var(--red);color:white;}

.resblock-viz{display:flex;align-items:center;gap:0;justify-content:center;padding:16px 0;min-width:700px;overflow-x:auto;}
.rb-node{display:flex;flex-direction:column;align-items:center;gap:6px;}
.rb-box{border-radius:6px;padding:10px 14px;text-align:center;font-family:var(--mono);font-size:11px;font-weight:500;min-width:110px;transition:all .3s;border:2px solid transparent;}
.rb-box.active-node{transform:scale(1.05);box-shadow:0 6px 20px rgba(0,0,0,.12);}
.rb-sublabel{font-family:var(--mono);font-size:9px;color:var(--text-sub);}

.rb-arrow{width:28px;height:2px;background:var(--border);position:relative;flex-shrink:0;align-self:center;margin-bottom:4px;}
.rb-arrow::after{content:'';position:absolute;right:-1px;top:-4px;border:5px solid transparent;border-left-color:var(--border);}
.rb-arrow.red-arr{background:var(--red);}
.rb-arrow.red-arr::after{border-left-color:var(--red);}

.skip-path{display:flex;flex-direction:column;align-items:center;gap:4px;margin-bottom:4px;}
.skip-line-h{height:2px;background:var(--red);border-radius:2px;}
.skip-label-txt{font-family:var(--mono);font-size:9px;color:var(--red);}

.rb-calc{background:var(--surface2);border:1px solid var(--border);border-radius:6px;padding:14px 18px;margin-top:16px;font-family:var(--mono);font-size:12px;line-height:1.9;color:var(--text);}
.rb-calc-step{padding:3px 0;border-bottom:1px solid var(--border);}
.rb-calc-step:last-child{border-bottom:none;}
.rb-calc-step.highlight{color:var(--red);font-weight:500;}
.rb-play-btn{font-family:var(--mono);font-size:12px;padding:7px 16px;border:none;border-radius:4px;background:var(--red);color:white;cursor:pointer;margin-top:12px;transition:opacity .15s;}
.rb-play-btn:hover{opacity:.85;}

/* ── LAYER TABLE ── */
.layer-table-wrap{background:var(--surface);border:1px solid var(--border);border-radius:8px;overflow:hidden;}
table{width:100%;border-collapse:collapse;font-size:13px;}
thead tr{background:var(--text);}
th{font-family:var(--mono);font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:rgba(245,243,239,.7);padding:13px 18px;text-align:left;font-weight:400;}
td{padding:11px 18px;border-bottom:1px solid var(--border);font-family:var(--mono);font-size:12px;}
tr:last-child td{border-bottom:none;}
tr:hover td{background:var(--surface2);}
tr.tr-highlight td{font-weight:500;}
tr.tr-highlight td:first-child{color:var(--red);}
.tag{display:inline-block;background:var(--red-soft);color:var(--red);border-radius:3px;padding:1px 7px;font-size:10px;}
.tag-b{background:#e8f4fb;color:var(--blue);}

/* ── COMPARISON ── */
.compare-wrap{background:var(--surface);border:1px solid var(--border);border-radius:8px;overflow:hidden;}
.compare-filter{display:flex;gap:8px;padding:16px 20px;border-bottom:1px solid var(--border);flex-wrap:wrap;}
.cf-btn{font-family:var(--mono);font-size:11px;padding:5px 12px;border:1.5px solid var(--border);border-radius:4px;background:var(--surface);color:var(--text-sub);cursor:pointer;transition:all .15s;}
.cf-btn:hover,.cf-btn.active{background:var(--text);border-color:var(--text);color:#f5f3ef;}
.compare-body table{width:100%;}
.bar-cell{position:relative;padding:11px 18px;}
.inline-bar{height:6px;border-radius:3px;margin-top:4px;transition:width .8s ease;}

/* ── TAKEAWAYS ── */
.takeaway-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;}
.takeaway-card{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:24px;border-top:3px solid;}
.tk-num{font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;margin-bottom:10px;}
.tk-title{font-family:var(--display);font-size:19px;letter-spacing:.5px;margin-bottom:10px;}
.tk-body{font-size:13px;color:var(--text-sub);line-height:1.8;}

/* ── FOOTER ── */
footer{border-top:1px solid var(--border);padding:28px 64px;display:flex;justify-content:space-between;font-family:var(--mono);font-size:11px;color:var(--text-sub);}

/* ── ANIM ── */
@keyframes fadeUp{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}
.fade-in{opacity:0;animation:fadeUp .5s ease forwards;}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;header&gt;
  &lt;div class=&quot;h-tag&quot;&gt;Deep Learning Architecture · CVPR 2016&lt;/div&gt;
  &lt;h1&gt;Res&lt;em&gt;Net&lt;/em&gt;-18&lt;/h1&gt;
  &lt;p class=&quot;h-sub&quot;&gt;Residual Learning으로 Degradation Problem을 해결한 18층 합성곱 신경망.&lt;br&gt;Skip Connection이 어떻게 깊은 학습을 가능하게 하는지 단계별로 살펴봅니다.&lt;/p&gt;
  &lt;div class=&quot;h-badges&quot;&gt;
    &lt;span class=&quot;h-badge&quot;&gt;&lt;b&gt;18&lt;/b&gt; layers&lt;/span&gt;
    &lt;span class=&quot;h-badge&quot;&gt;&lt;b&gt;11.7M&lt;/b&gt; parameters&lt;/span&gt;
    &lt;span class=&quot;h-badge&quot;&gt;&lt;b&gt;69.8%&lt;/b&gt; Top-1 ImageNet&lt;/span&gt;
    &lt;span class=&quot;h-badge&quot;&gt;ILSVRC 2015 우승 계열&lt;/span&gt;
  &lt;/div&gt;
&lt;/header&gt;

&lt;main&gt;

  &lt;!-- 1. STATS --&gt;
  &lt;section class=&quot;fade-in&quot; style=&quot;animation-delay:.05s&quot;&gt;
    &lt;div class=&quot;sec-label&quot;&gt;Overview&lt;/div&gt;
    &lt;div class=&quot;stat-grid&quot;&gt;
      &lt;div class=&quot;stat-card dark&quot;&gt;
        &lt;div class=&quot;stat-num&quot;&gt;18&lt;/div&gt;
        &lt;div class=&quot;stat-unit&quot;&gt;Layers&lt;/div&gt;
        &lt;div class=&quot;stat-desc&quot;&gt;가중치를 가진 합성곱·완전연결 레이어 수&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class=&quot;stat-card&quot;&gt;
        &lt;div class=&quot;stat-num&quot;&gt;11.7M&lt;/div&gt;
        &lt;div class=&quot;stat-unit&quot;&gt;Parameters&lt;/div&gt;
        &lt;div class=&quot;stat-desc&quot;&gt;학습 가능한 파라미터 — VGG-16의 약 1/12 수준&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class=&quot;stat-card&quot;&gt;
        &lt;div class=&quot;stat-num&quot;&gt;1.8G&lt;/div&gt;
        &lt;div class=&quot;stat-unit&quot;&gt;FLOPs&lt;/div&gt;
        &lt;div class=&quot;stat-desc&quot;&gt;단일 추론에 필요한 부동소수점 연산 횟수&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class=&quot;stat-card&quot;&gt;
        &lt;div class=&quot;stat-num&quot;&gt;69.8%&lt;/div&gt;
        &lt;div class=&quot;stat-unit&quot;&gt;Top-1 Accuracy&lt;/div&gt;
        &lt;div class=&quot;stat-desc&quot;&gt;ImageNet 1000-class 단일 크롭 기준&lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/section&gt;

  &lt;!-- 2. DEGRADATION PROBLEM --&gt;
  &lt;section class=&quot;fade-in&quot; style=&quot;animation-delay:.1s&quot;&gt;
    &lt;div class=&quot;sec-label&quot;&gt;핵심 문제 의식&lt;/div&gt;
    &lt;div class=&quot;sec-title&quot;&gt;왜 깊게 쌓으면 오히려 나빠졌는가?&lt;/div&gt;
    &lt;div class=&quot;problem-grid&quot;&gt;
      &lt;div&gt;
        &lt;div class=&quot;problem-title&quot;&gt;Degradation Problem&lt;/div&gt;
        &lt;p class=&quot;problem-body&quot;&gt;레이어를 단순히 쌓기만 하면 일정 깊이부터 &lt;strong&gt;훈련 오차가 오히려 증가&lt;/strong&gt;하는 현상이 나타났습니다. 과적합이 아닌, 최적화 자체가 어려워지는 문제였습니다.&lt;br&gt;&lt;br&gt;이에 대한 해결책으로 잔차(residual: F(x))만 학습하도록 구조를 재설계했습니다. 만약 아무것도 배울 게 없다면 F(x) = 0이 되어 입력이 그대로 통과합니다.&lt;br&gt;&lt;br&gt;잔차란 목표 출력 H(x)에서 입력 x를 뺀 차이, 즉 &lt;strong&gt;F(x) = H(x) − x&lt;/strong&gt; 입니다. 레이어가 정답 전체를 처음부터 학습하는 대신, 현재 입력에서 &lt;strong&gt;얼마나 바뀌어야 하는지의 차이만&lt;/strong&gt; 학습하면 되므로 최적화가 훨씬 쉬워집니다.&lt;/p&gt;
      &lt;/div&gt;
      &lt;div&gt;
        &lt;p style=&quot;font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-sub);margin-bottom:10px;&quot;&gt;CIFAR-10 Test Error (%)&lt;/p&gt;
        &lt;div class=&quot;bar-chart&quot; id=&quot;barChart&quot;&gt;
          &lt;div class=&quot;bar-row&quot;&gt;
            &lt;span class=&quot;bar-label&quot;&gt;Plain-20&lt;/span&gt;
            &lt;div class=&quot;bar-track&quot;&gt;&lt;div class=&quot;bar-fill&quot; data-w=&quot;66&quot; style=&quot;background:#27ae60;&quot;&gt;&lt;/div&gt;&lt;/div&gt;
            &lt;span class=&quot;bar-val&quot; style=&quot;color:#27ae60&quot;&gt;8.75%&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class=&quot;bar-row&quot;&gt;
            &lt;span class=&quot;bar-label&quot;&gt;Plain-56 ↑깊어짐&lt;/span&gt;
            &lt;div class=&quot;bar-track&quot;&gt;&lt;div class=&quot;bar-fill&quot; data-w=&quot;85&quot; style=&quot;background:var(--red);&quot;&gt;&lt;/div&gt;&lt;/div&gt;
            &lt;span class=&quot;bar-val&quot; style=&quot;color:var(--red)&quot;&gt;13.5%&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class=&quot;bar-row&quot;&gt;
            &lt;span class=&quot;bar-label&quot;&gt;ResNet-20&lt;/span&gt;
            &lt;div class=&quot;bar-track&quot;&gt;&lt;div class=&quot;bar-fill&quot; data-w=&quot;62&quot; style=&quot;background:#2471a3;&quot;&gt;&lt;/div&gt;&lt;/div&gt;
            &lt;span class=&quot;bar-val&quot; style=&quot;color:#2471a3&quot;&gt;8.0%&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class=&quot;bar-row&quot;&gt;
            &lt;span class=&quot;bar-label&quot;&gt;ResNet-56 ↑깊어짐&lt;/span&gt;
            &lt;div class=&quot;bar-track&quot;&gt;&lt;div class=&quot;bar-fill&quot; data-w=&quot;44&quot; style=&quot;background:#2471a3;&quot;&gt;&lt;/div&gt;&lt;/div&gt;
            &lt;span class=&quot;bar-val&quot; style=&quot;color:#2471a3&quot;&gt;6.0%&lt;/span&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;p style=&quot;font-size:12px;color:var(--text-sub);margin-top:10px;font-family:var(--mono);&quot;&gt;Plain은 깊을수록 악화 → ResNet은 깊을수록 개선&lt;/p&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/section&gt;

  &lt;!-- 3. SKIP CONNECTION --&gt;
  &lt;section class=&quot;fade-in&quot; style=&quot;animation-delay:.15s&quot;&gt;
    &lt;div class=&quot;sec-label&quot;&gt;핵심 아이디어&lt;/div&gt;
    &lt;div class=&quot;sec-title&quot;&gt;Skip Connection&lt;/div&gt;
    &lt;div class=&quot;skip-grid&quot;&gt;
      &lt;div class=&quot;skip-text&quot;&gt;
        &lt;p&gt;일반 네트워크는 레이어가 출력 &lt;strong&gt;H(x)&lt;/strong&gt;를 직접 학습합니다. ResNet은 이를 &lt;strong&gt;F(x) + x&lt;/strong&gt; 형태로 분리하여, 레이어가 &lt;em&gt;잔차 F(x)&lt;/em&gt;만 학습하도록 합니다.&lt;/p&gt;
        &lt;p&gt;입력 &lt;strong&gt;x&lt;/strong&gt;는 레이어를 건너뛰어 출력에 직접 더해집니다. 이 경로를 &lt;em&gt;shortcut connection&lt;/em&gt;이라 합니다. 채널 수가 달라지는 경우 1×1 Conv로 차원을 맞춥니다(projection shortcut).&lt;/p&gt;
        &lt;div class=&quot;formula&quot;&gt;output = &lt;em&gt;F(x)&lt;/em&gt; + x &amp;nbsp;→&amp;nbsp; ReLU&lt;/div&gt;
        &lt;div style=&quot;margin-top:14px;background:var(--surface2);border:1px solid var(--border);border-radius:6px;padding:14px 18px;font-size:13px;color:var(--text-sub);line-height:1.85;&quot;&gt;
          &lt;strong style=&quot;color:var(--text);font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;&quot;&gt;Projection Shortcut&lt;/strong&gt;&lt;br&gt;
          shortcut은 x를 그대로 더하는 구조입니다. 그런데 레이어가 깊어지면서 채널 수가 변하면(예: 64 → 128) F(x)와 x의 크기가 달라져 덧셈이 불가능해집니다. 이때 shortcut에 &lt;strong style=&quot;color:var(--text);&quot;&gt;1×1 Conv&lt;/strong&gt;를 적용해 채널 수만 맞춰줍니다. 공간(가로·세로)은 그대로 두고 채널만 변환하는 가장 작은 커널입니다.
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;svg viewBox=&quot;0 0 200 280&quot; width=&quot;200&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; style=&quot;flex-shrink:0&quot;&gt;
        &lt;defs&gt;
          &lt;marker id=&quot;arr&quot; markerWidth=&quot;7&quot; markerHeight=&quot;7&quot; refX=&quot;5&quot; refY=&quot;3&quot; orient=&quot;auto&quot;&gt;&lt;path d=&quot;M0,0 L0,6 L7,3z&quot; fill=&quot;#aaa&quot;/&gt;&lt;/marker&gt;
          &lt;marker id=&quot;arrRed&quot; markerWidth=&quot;7&quot; markerHeight=&quot;7&quot; refX=&quot;5&quot; refY=&quot;3&quot; orient=&quot;auto&quot;&gt;&lt;path d=&quot;M0,0 L0,6 L7,3z&quot; fill=&quot;#c0392b&quot;/&gt;&lt;/marker&gt;
        &lt;/defs&gt;
        &lt;!-- Input --&gt;
        &lt;rect x=&quot;65&quot; y=&quot;8&quot; width=&quot;70&quot; height=&quot;30&quot; rx=&quot;5&quot; fill=&quot;#e8f4fb&quot; stroke=&quot;#2471a3&quot; stroke-width=&quot;1.5&quot;/&gt;
        &lt;text x=&quot;100&quot; y=&quot;27&quot; text-anchor=&quot;middle&quot; font-family=&quot;DM Mono,monospace&quot; font-size=&quot;11&quot; fill=&quot;#1a4f6e&quot;&gt;Input x&lt;/text&gt;
        &lt;!-- arrow down --&gt;
        &lt;line x1=&quot;100&quot; y1=&quot;38&quot; x2=&quot;100&quot; y2=&quot;58&quot; stroke=&quot;#aaa&quot; stroke-width=&quot;1.5&quot; marker-end=&quot;url(#arr)&quot;/&gt;
        &lt;!-- conv1 --&gt;
        &lt;rect x=&quot;55&quot; y=&quot;58&quot; width=&quot;90&quot; height=&quot;30&quot; rx=&quot;5&quot; fill=&quot;#fef5e7&quot; stroke=&quot;#d68910&quot; stroke-width=&quot;1.5&quot;/&gt;
        &lt;text x=&quot;100&quot; y=&quot;77&quot; text-anchor=&quot;middle&quot; font-family=&quot;DM Mono,monospace&quot; font-size=&quot;10&quot; fill=&quot;#7e5009&quot;&gt;Conv 3×3, ReLU&lt;/text&gt;
        &lt;!-- arrow --&gt;
        &lt;line x1=&quot;100&quot; y1=&quot;88&quot; x2=&quot;100&quot; y2=&quot;108&quot; stroke=&quot;#aaa&quot; stroke-width=&quot;1.5&quot; marker-end=&quot;url(#arr)&quot;/&gt;
        &lt;!-- conv2 --&gt;
        &lt;rect x=&quot;55&quot; y=&quot;108&quot; width=&quot;90&quot; height=&quot;30&quot; rx=&quot;5&quot; fill=&quot;#fef5e7&quot; stroke=&quot;#d68910&quot; stroke-width=&quot;1.5&quot;/&gt;
        &lt;text x=&quot;100&quot; y=&quot;127&quot; text-anchor=&quot;middle&quot; font-family=&quot;DM Mono,monospace&quot; font-size=&quot;10&quot; fill=&quot;#7e5009&quot;&gt;Conv 3×3&lt;/text&gt;
        &lt;!-- arrow to add --&gt;
        &lt;line x1=&quot;100&quot; y1=&quot;138&quot; x2=&quot;100&quot; y2=&quot;168&quot; stroke=&quot;#aaa&quot; stroke-width=&quot;1.5&quot; marker-end=&quot;url(#arr)&quot;/&gt;
        &lt;!-- ADD --&gt;
        &lt;circle cx=&quot;100&quot; cy=&quot;181&quot; r=&quot;13&quot; fill=&quot;white&quot; stroke=&quot;#c0392b&quot; stroke-width=&quot;2&quot;/&gt;
        &lt;text x=&quot;100&quot; y=&quot;186&quot; text-anchor=&quot;middle&quot; font-family=&quot;DM Mono,monospace&quot; font-size=&quot;15&quot; fill=&quot;#c0392b&quot; font-weight=&quot;bold&quot;&gt;+&lt;/text&gt;
        &lt;!-- shortcut --&gt;
        &lt;path d=&quot;M100 23 Q28 23 28 181 L87 181&quot; fill=&quot;none&quot; stroke=&quot;#c0392b&quot; stroke-width=&quot;2&quot; stroke-dasharray=&quot;5,3&quot; marker-end=&quot;url(#arrRed)&quot;/&gt;
        &lt;text x=&quot;18&quot; y=&quot;105&quot; text-anchor=&quot;middle&quot; font-family=&quot;DM Mono,monospace&quot; font-size=&quot;9&quot; fill=&quot;#c0392b&quot; transform=&quot;rotate(-90 18 105)&quot;&gt;shortcut x&lt;/text&gt;
        &lt;!-- relu --&gt;
        &lt;line x1=&quot;100&quot; y1=&quot;194&quot; x2=&quot;100&quot; y2=&quot;218&quot; stroke=&quot;#aaa&quot; stroke-width=&quot;1.5&quot; marker-end=&quot;url(#arr)&quot;/&gt;
        &lt;rect x=&quot;70&quot; y=&quot;218&quot; width=&quot;60&quot; height=&quot;26&quot; rx=&quot;4&quot; fill=&quot;#e9f7ef&quot; stroke=&quot;#1e8449&quot; stroke-width=&quot;1.5&quot;/&gt;
        &lt;text x=&quot;100&quot; y=&quot;234&quot; text-anchor=&quot;middle&quot; font-family=&quot;DM Mono,monospace&quot; font-size=&quot;11&quot; fill=&quot;#145a32&quot;&gt;ReLU&lt;/text&gt;
        &lt;!-- output --&gt;
        &lt;line x1=&quot;100&quot; y1=&quot;244&quot; x2=&quot;100&quot; y2=&quot;262&quot; stroke=&quot;#aaa&quot; stroke-width=&quot;1.5&quot; marker-end=&quot;url(#arr)&quot;/&gt;
        &lt;text x=&quot;100&quot; y=&quot;275&quot; text-anchor=&quot;middle&quot; font-family=&quot;DM Mono,monospace&quot; font-size=&quot;11&quot; fill=&quot;#6b6357&quot;&gt;Output H(x)&lt;/text&gt;
      &lt;/svg&gt;
    &lt;/div&gt;
  &lt;/section&gt;

  &lt;!-- 4. ARCHITECTURE INTERACTIVE --&gt;
  &lt;section class=&quot;fade-in&quot; style=&quot;animation-delay:.2s&quot;&gt;
    &lt;div class=&quot;sec-label&quot;&gt;전체 구조&lt;/div&gt;
    &lt;div class=&quot;sec-title&quot;&gt;ResNet-18 Architecture&lt;/div&gt;
    &lt;p style=&quot;font-size:13px;color:var(--text-sub);margin-bottom:20px;font-family:var(--mono);&quot;&gt;각 블록을 클릭하면 상세 정보를 확인할 수 있습니다.&lt;/p&gt;
    &lt;div class=&quot;arch-outer&quot;&gt;
      &lt;div class=&quot;arch-scroll&quot;&gt;
        &lt;div class=&quot;arch-flow&quot; id=&quot;archFlow&quot;&gt;

          &lt;!-- Input --&gt;
          &lt;div class=&quot;arch-block&quot; data-id=&quot;input&quot; onclick=&quot;showDetail('input')&quot;&gt;
            &lt;div class=&quot;arch-body b-img&quot;&gt;
              &lt;div class=&quot;arch-bname&quot;&gt;Image&lt;/div&gt;
              &lt;div class=&quot;arch-bsize&quot;&gt;224×224×3&lt;/div&gt;
            &lt;/div&gt;
            &lt;span class=&quot;arch-label&quot;&gt;RGB 입력&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class=&quot;arch-arrow&quot;&gt;&lt;/div&gt;

          &lt;!-- Conv1 --&gt;
          &lt;div class=&quot;arch-block&quot; data-id=&quot;conv1&quot; onclick=&quot;showDetail('conv1')&quot;&gt;
            &lt;div class=&quot;arch-body b-conv&quot; style=&quot;min-width:76px;&quot;&gt;
              &lt;div class=&quot;arch-bname&quot;&gt;Conv1&lt;/div&gt;
              &lt;div class=&quot;arch-bsize&quot;&gt;7×7, 64, s2&lt;/div&gt;
              &lt;div class=&quot;arch-bsize&quot;&gt;BN · ReLU&lt;/div&gt;
              &lt;div class=&quot;arch-bsize&quot; style=&quot;border-top:1px solid #d68910;margin-top:4px;padding-top:4px;&quot;&gt;MaxPool s2&lt;/div&gt;
            &lt;/div&gt;
            &lt;span class=&quot;arch-label&quot;&gt;112→56×56×64&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class=&quot;arch-arrow&quot;&gt;&lt;/div&gt;

          &lt;!-- Layer 1 --&gt;
          &lt;div class=&quot;arch-block&quot; data-id=&quot;layer1&quot; onclick=&quot;showDetail('layer1')&quot;&gt;
            &lt;div class=&quot;layer-group&quot;&gt;
              &lt;span class=&quot;layer-tag&quot;&gt;Layer 1 ×2&lt;/span&gt;
              &lt;div class=&quot;layer-inner&quot;&gt;
                &lt;div class=&quot;mini-blk&quot;&gt;Conv 3×3, 64&lt;/div&gt;
                &lt;div class=&quot;mini-blk&quot;&gt;Conv 3×3, 64&lt;/div&gt;
                &lt;div class=&quot;skip-blk&quot;&gt;↩ skip&lt;/div&gt;
                &lt;div class=&quot;mini-blk&quot;&gt;Conv 3×3, 64&lt;/div&gt;
                &lt;div class=&quot;mini-blk&quot;&gt;Conv 3×3, 64&lt;/div&gt;
                &lt;div class=&quot;skip-blk&quot;&gt;↩ skip&lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;span class=&quot;arch-label&quot;&gt;56×56×64&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class=&quot;arch-arrow&quot;&gt;&lt;/div&gt;

          &lt;!-- Layer 2 --&gt;
          &lt;div class=&quot;arch-block&quot; data-id=&quot;layer2&quot; onclick=&quot;showDetail('layer2')&quot;&gt;
            &lt;div class=&quot;layer-group&quot;&gt;
              &lt;span class=&quot;layer-tag&quot;&gt;Layer 2 ×2&lt;/span&gt;
              &lt;div class=&quot;layer-inner&quot;&gt;
                &lt;div class=&quot;mini-blk&quot;&gt;Conv 3×3, 128&lt;/div&gt;
                &lt;div class=&quot;mini-blk&quot;&gt;Conv 3×3, 128&lt;/div&gt;
                &lt;div class=&quot;skip-blk&quot;&gt;↩ skip 1×1&lt;/div&gt;
                &lt;div class=&quot;mini-blk&quot;&gt;Conv 3×3, 128&lt;/div&gt;
                &lt;div class=&quot;mini-blk&quot;&gt;Conv 3×3, 128&lt;/div&gt;
                &lt;div class=&quot;skip-blk&quot;&gt;↩ skip&lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;span class=&quot;arch-label&quot;&gt;28×28×128&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class=&quot;arch-arrow&quot;&gt;&lt;/div&gt;

          &lt;!-- Layer 3 --&gt;
          &lt;div class=&quot;arch-block&quot; data-id=&quot;layer3&quot; onclick=&quot;showDetail('layer3')&quot;&gt;
            &lt;div class=&quot;layer-group&quot;&gt;
              &lt;span class=&quot;layer-tag&quot;&gt;Layer 3 ×2&lt;/span&gt;
              &lt;div class=&quot;layer-inner&quot;&gt;
                &lt;div class=&quot;mini-blk&quot;&gt;Conv 3×3, 256&lt;/div&gt;
                &lt;div class=&quot;mini-blk&quot;&gt;Conv 3×3, 256&lt;/div&gt;
                &lt;div class=&quot;skip-blk&quot;&gt;↩ skip 1×1&lt;/div&gt;
                &lt;div class=&quot;mini-blk&quot;&gt;Conv 3×3, 256&lt;/div&gt;
                &lt;div class=&quot;mini-blk&quot;&gt;Conv 3×3, 256&lt;/div&gt;
                &lt;div class=&quot;skip-blk&quot;&gt;↩ skip&lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;span class=&quot;arch-label&quot;&gt;14×14×256&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class=&quot;arch-arrow&quot;&gt;&lt;/div&gt;

          &lt;!-- Layer 4 --&gt;
          &lt;div class=&quot;arch-block&quot; data-id=&quot;layer4&quot; onclick=&quot;showDetail('layer4')&quot;&gt;
            &lt;div class=&quot;layer-group&quot;&gt;
              &lt;span class=&quot;layer-tag&quot;&gt;Layer 4 ×2&lt;/span&gt;
              &lt;div class=&quot;layer-inner&quot;&gt;
                &lt;div class=&quot;mini-blk&quot;&gt;Conv 3×3, 512&lt;/div&gt;
                &lt;div class=&quot;mini-blk&quot;&gt;Conv 3×3, 512&lt;/div&gt;
                &lt;div class=&quot;skip-blk&quot;&gt;↩ skip 1×1&lt;/div&gt;
                &lt;div class=&quot;mini-blk&quot;&gt;Conv 3×3, 512&lt;/div&gt;
                &lt;div class=&quot;mini-blk&quot;&gt;Conv 3×3, 512&lt;/div&gt;
                &lt;div class=&quot;skip-blk&quot;&gt;↩ skip&lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;span class=&quot;arch-label&quot;&gt;7×7×512&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class=&quot;arch-arrow&quot;&gt;&lt;/div&gt;

          &lt;!-- AvgPool + FC --&gt;
          &lt;div class=&quot;arch-block&quot; data-id=&quot;head&quot; onclick=&quot;showDetail('head')&quot;&gt;
            &lt;div class=&quot;arch-body b-pool&quot; style=&quot;min-width:76px;&quot;&gt;
              &lt;div class=&quot;arch-bname&quot;&gt;AvgPool&lt;/div&gt;
              &lt;div class=&quot;arch-bsize&quot;&gt;Global&lt;/div&gt;
              &lt;div class=&quot;arch-bsize&quot; style=&quot;border-top:1px solid #1e8449;margin-top:4px;padding-top:4px;&quot;&gt;FC 1000&lt;/div&gt;
              &lt;div class=&quot;arch-bsize&quot;&gt;Softmax&lt;/div&gt;
            &lt;/div&gt;
            &lt;span class=&quot;arch-label&quot;&gt;512 → 1000&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class=&quot;arch-arrow&quot;&gt;&lt;/div&gt;

          &lt;!-- Output --&gt;
          &lt;div class=&quot;arch-block&quot; data-id=&quot;out&quot; onclick=&quot;showDetail('out')&quot;&gt;
            &lt;div class=&quot;arch-body b-out&quot;&gt;
              &lt;div class=&quot;arch-bname&quot; style=&quot;color:#f5f3ef;&quot;&gt;Class&lt;/div&gt;
              &lt;div class=&quot;arch-bsize&quot;&gt;1000-way&lt;/div&gt;
            &lt;/div&gt;
            &lt;span class=&quot;arch-label&quot;&gt;분류 결과&lt;/span&gt;
          &lt;/div&gt;

        &lt;/div&gt;
      &lt;/div&gt;

      &lt;!-- Detail Panel --&gt;
      &lt;div class=&quot;detail-panel&quot; id=&quot;detailPanel&quot;&gt;
        &lt;div class=&quot;detail-inner&quot;&gt;
          &lt;div class=&quot;detail-title&quot; id=&quot;detailTitle&quot;&gt;&lt;/div&gt;
          &lt;div class=&quot;detail-grid&quot; id=&quot;detailGrid&quot;&gt;&lt;/div&gt;
          &lt;div class=&quot;detail-hint&quot; id=&quot;detailHint&quot;&gt;&lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/section&gt;

  &lt;!-- 5. RESIDUAL BLOCK SIMULATOR --&gt;
  &lt;section class=&quot;fade-in&quot; style=&quot;animation-delay:.25s&quot;&gt;
    &lt;div class=&quot;sec-label&quot;&gt;Residual Block 시뮬레이터&lt;/div&gt;
    &lt;div class=&quot;sec-title&quot;&gt;F(x) + x 데이터 흐름&lt;/div&gt;
    &lt;p style=&quot;font-size:13px;color:var(--text-sub);margin-bottom:20px;font-family:var(--mono);&quot;&gt;임의 입력값을 설정하고 ▶ 버튼으로 각 레이어를 단계별로 통과시켜 보세요.&lt;/p&gt;
    &lt;div class=&quot;resblock-outer&quot;&gt;
      &lt;div style=&quot;display:flex;gap:16px;align-items:flex-start;flex-wrap:wrap;&quot;&gt;
        &lt;div&gt;
          &lt;div style=&quot;font-family:var(--mono);font-size:10px;color:var(--text-sub);letter-spacing:.1em;text-transform:uppercase;margin-bottom:8px;&quot;&gt;입력값 x 설정&lt;/div&gt;
          &lt;div style=&quot;display:flex;gap:8px;align-items:center;flex-wrap:wrap;&quot; id=&quot;inputPickers&quot;&gt;
            &lt;!-- generated by JS --&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div style=&quot;margin-left:auto;display:flex;gap:8px;align-items:flex-end;&quot;&gt;
          &lt;button class=&quot;rb-play-btn&quot; id=&quot;rbPlayBtn&quot; onclick=&quot;rbStep()&quot;&gt;▶ 다음 단계&lt;/button&gt;
          &lt;button class=&quot;rb-play-btn&quot; style=&quot;background:var(--surface2);color:var(--text-sub);border:1px solid var(--border);&quot; onclick=&quot;rbReset()&quot;&gt;↺ 초기화&lt;/button&gt;
        &lt;/div&gt;
      &lt;/div&gt;

      &lt;div style=&quot;overflow-x:auto;margin-top:24px;&quot;&gt;
        &lt;div class=&quot;resblock-viz&quot; id=&quot;rbViz&quot;&gt;&lt;/div&gt;
      &lt;/div&gt;

      &lt;div class=&quot;rb-calc&quot; id=&quot;rbCalc&quot;&gt;
        &lt;div style=&quot;font-family:var(--mono);font-size:10px;color:var(--text-sub);letter-spacing:.1em;text-transform:uppercase;margin-bottom:8px;&quot;&gt;단계별 연산 로그&lt;/div&gt;
        &lt;div id=&quot;rbLog&quot;&gt;▶ 다음 단계 버튼을 눌러 데이터 흐름을 추적하세요.&lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/section&gt;

  &lt;!-- 6. LAYER TABLE --&gt;
  &lt;section class=&quot;fade-in&quot; style=&quot;animation-delay:.3s&quot;&gt;
    &lt;div class=&quot;sec-label&quot;&gt;레이어 상세 명세&lt;/div&gt;
    &lt;div class=&quot;sec-title&quot;&gt;Layer-by-Layer&lt;/div&gt;
    &lt;div class=&quot;layer-table-wrap&quot;&gt;
      &lt;table&gt;
        &lt;thead&gt;
          &lt;tr&gt;
            &lt;th&gt;Stage&lt;/th&gt;&lt;th&gt;출력 크기&lt;/th&gt;&lt;th&gt;구성&lt;/th&gt;&lt;th&gt;파라미터 수&lt;/th&gt;&lt;th&gt;비고&lt;/th&gt;
          &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
          &lt;tr&gt;&lt;td&gt;conv1&lt;/td&gt;&lt;td&gt;112×112×64&lt;/td&gt;&lt;td&gt;7×7, 64, stride 2 · BN · ReLU&lt;/td&gt;&lt;td&gt;9,408&lt;/td&gt;&lt;td&gt;&lt;span class=&quot;tag tag-b&quot;&gt;초기 특징 추출&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;tr&gt;&lt;td&gt;maxpool&lt;/td&gt;&lt;td&gt;56×56×64&lt;/td&gt;&lt;td&gt;3×3 MaxPool, stride 2&lt;/td&gt;&lt;td&gt;—&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;tr&gt;&lt;td&gt;layer1&lt;/td&gt;&lt;td&gt;56×56×64&lt;/td&gt;&lt;td&gt;[3×3, 64] × 2 블록 × 2회&lt;/td&gt;&lt;td&gt;147,456&lt;/td&gt;&lt;td&gt;&lt;span class=&quot;tag&quot;&gt;skip: identity&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;tr&gt;&lt;td&gt;layer2&lt;/td&gt;&lt;td&gt;28×28×128&lt;/td&gt;&lt;td&gt;[3×3, 128] × 2 블록 × 2회&lt;/td&gt;&lt;td&gt;525,312&lt;/td&gt;&lt;td&gt;&lt;span class=&quot;tag&quot;&gt;skip: 1×1 proj&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;tr&gt;&lt;td&gt;layer3&lt;/td&gt;&lt;td&gt;14×14×256&lt;/td&gt;&lt;td&gt;[3×3, 256] × 2 블록 × 2회&lt;/td&gt;&lt;td&gt;2,099,200&lt;/td&gt;&lt;td&gt;&lt;span class=&quot;tag&quot;&gt;skip: 1×1 proj&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;tr class=&quot;tr-highlight&quot;&gt;&lt;td&gt;layer4&lt;/td&gt;&lt;td&gt;7×7×512&lt;/td&gt;&lt;td&gt;[3×3, 512] × 2 블록 × 2회&lt;/td&gt;&lt;td&gt;8,390,656&lt;/td&gt;&lt;td&gt;&lt;span class=&quot;tag&quot;&gt;전체 파라미터 72%&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;tr&gt;&lt;td&gt;avgpool&lt;/td&gt;&lt;td&gt;1×1×512&lt;/td&gt;&lt;td&gt;Global Average Pooling&lt;/td&gt;&lt;td&gt;—&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
          &lt;tr&gt;&lt;td&gt;fc&lt;/td&gt;&lt;td&gt;1000&lt;/td&gt;&lt;td&gt;Linear(512 → 1000)&lt;/td&gt;&lt;td&gt;513,000&lt;/td&gt;&lt;td&gt;&lt;span class=&quot;tag tag-b&quot;&gt;분류 출력&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
        &lt;/tbody&gt;
      &lt;/table&gt;
    &lt;/div&gt;
  &lt;/section&gt;

  &lt;!-- 7. MODEL COMPARISON INTERACTIVE --&gt;
  &lt;section class=&quot;fade-in&quot; style=&quot;animation-delay:.35s&quot;&gt;
    &lt;div class=&quot;sec-label&quot;&gt;모델 비교&lt;/div&gt;
    &lt;div class=&quot;sec-title&quot;&gt;ResNet 패밀리 &amp; 주요 모델&lt;/div&gt;
    &lt;div class=&quot;compare-wrap&quot;&gt;
      &lt;div class=&quot;compare-filter&quot;&gt;
        &lt;span style=&quot;font-family:var(--mono);font-size:10px;color:var(--text-sub);align-self:center;letter-spacing:.1em;text-transform:uppercase;margin-right:4px;&quot;&gt;정렬 기준&lt;/span&gt;
        &lt;button class=&quot;cf-btn active&quot; onclick=&quot;sortTable('acc',this)&quot;&gt;Top-1 정확도&lt;/button&gt;
        &lt;button class=&quot;cf-btn&quot; onclick=&quot;sortTable('params',this)&quot;&gt;파라미터 수&lt;/button&gt;
        &lt;button class=&quot;cf-btn&quot; onclick=&quot;sortTable('layers',this)&quot;&gt;레이어 수&lt;/button&gt;
      &lt;/div&gt;
      &lt;div class=&quot;compare-body&quot;&gt;
        &lt;table id=&quot;compareTable&quot;&gt;
          &lt;thead&gt;
            &lt;tr&gt;
              &lt;th&gt;모델&lt;/th&gt;&lt;th&gt;Layers&lt;/th&gt;&lt;th&gt;Parameters&lt;/th&gt;&lt;th&gt;Top-1 Acc&lt;/th&gt;&lt;th&gt;Skip&lt;/th&gt;&lt;th&gt;특징&lt;/th&gt;
            &lt;/tr&gt;
          &lt;/thead&gt;
          &lt;tbody id=&quot;compareTbody&quot;&gt;&lt;/tbody&gt;
        &lt;/table&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/section&gt;

  &lt;!-- 8. TAKEAWAYS --&gt;
  &lt;section class=&quot;fade-in&quot; style=&quot;animation-delay:.4s&quot;&gt;
    &lt;div class=&quot;sec-label&quot;&gt;핵심 요약&lt;/div&gt;
    &lt;div class=&quot;takeaway-grid&quot;&gt;
      &lt;div class=&quot;takeaway-card&quot; style=&quot;border-top-color:var(--red);&quot;&gt;
        &lt;div class=&quot;tk-num&quot; style=&quot;color:var(--red);&quot;&gt;01 · 이론적 기여&lt;/div&gt;
        &lt;div class=&quot;tk-title&quot;&gt;잔차 학습&lt;/div&gt;
        &lt;div class=&quot;tk-body&quot;&gt;Degradation 문제를 F(x) = H(x) − x 재정의로 해결. 100층 이상 네트워크 학습의 길을 열었습니다.&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class=&quot;takeaway-card&quot; style=&quot;border-top-color:var(--blue);&quot;&gt;
        &lt;div class=&quot;tk-num&quot; style=&quot;color:var(--blue);&quot;&gt;02 · 실용적 강점&lt;/div&gt;
        &lt;div class=&quot;tk-title&quot;&gt;경량 백본&lt;/div&gt;
        &lt;div class=&quot;tk-body&quot;&gt;11.7M 파라미터로 전이학습(Transfer Learning) 백본으로 가장 널리 사용되며, 엣지 디바이스에도 적합합니다.&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class=&quot;takeaway-card&quot; style=&quot;border-top-color:var(--green);&quot;&gt;
        &lt;div class=&quot;tk-num&quot; style=&quot;color:var(--green);&quot;&gt;03 · 후속 영향&lt;/div&gt;
        &lt;div class=&quot;tk-title&quot;&gt;현대 CNN의 기반&lt;/div&gt;
        &lt;div class=&quot;tk-body&quot;&gt;ResNeXt, DenseNet, EfficientNet 등 이후 등장한 대부분의 CNN 아키텍처가 Skip Connection 개념을 계승합니다.&lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/section&gt;

&lt;/main&gt;

&lt;footer&gt;
  &lt;span&gt;ResNet-18 · CVPR 2016&lt;/span&gt;
  &lt;span&gt;학생 대상 소개 자료 · Deep Learning Architecture&lt;/span&gt;
&lt;/footer&gt;

&lt;script&gt;
// ── ARCH DETAIL DATA ─────────────────────────────────
const DETAILS = {
  input: {
    title: 'Input Image',
    items: [
      {k:'크기', v:'224 × 224 × 3'},
      {k:'채널', v:'R · G · B'},
      {k:'픽셀값 범위', v:'0 ~ 255 (정규화 후 ~1)'},
    ],
    hint: 'ImageNet 기준 224×224 크기. 실제로는 다양한 크기를 Resize·Crop 전처리 후 입력합니다.'
  },
  conv1: {
    title: 'Conv1 + MaxPool',
    items: [
      {k:'커널 크기', v:'7 × 7'},
      {k:'출력 채널', v:'64'},
      {k:'Stride', v:'2 → 112×112'},
      {k:'MaxPool', v:'3×3, stride 2 → 56×56'},
      {k:'파라미터', v:'9,408'},
      {k:'뒤따르는 연산', v:'BatchNorm + ReLU'},
    ],
    hint: '큰 7×7 커널로 초기 저수준 특징(엣지·색상)을 빠르게 추출하고, MaxPool로 해상도를 1/4로 줄입니다.'
  },
  layer1: {
    title: 'Layer 1 — 2 × Residual Block',
    items: [
      {k:'블록 수', v:'2개'},
      {k:'채널 수', v:'64'},
      {k:'출력 크기', v:'56 × 56 × 64'},
      {k:'Skip 유형', v:'Identity (차원 동일)'},
      {k:'파라미터', v:'147,456'},
      {k:'Stride', v:'1 (해상도 유지)'},
    ],
    hint: '채널 수가 변하지 않으므로 shortcut이 그대로 더해집니다 (identity shortcut).'
  },
  layer2: {
    title: 'Layer 2 — 2 × Residual Block',
    items: [
      {k:'블록 수', v:'2개'},
      {k:'채널 수', v:'128 (64→128)'},
      {k:'출력 크기', v:'28 × 28 × 128'},
      {k:'Skip 유형', v:'Projection (1×1 Conv)'},
      {k:'파라미터', v:'525,312'},
      {k:'Stride', v:'2 (첫 블록, 해상도 ½)'},
    ],
    hint: '채널이 64→128로 변하고 해상도가 절반이 되므로, shortcut에 1×1 Conv를 적용해 차원을 맞춥니다.'
  },
  layer3: {
    title: 'Layer 3 — 2 × Residual Block',
    items: [
      {k:'블록 수', v:'2개'},
      {k:'채널 수', v:'256 (128→256)'},
      {k:'출력 크기', v:'14 × 14 × 256'},
      {k:'Skip 유형', v:'Projection (1×1 Conv)'},
      {k:'파라미터', v:'2,099,200'},
      {k:'Stride', v:'2 (첫 블록, 해상도 ½)'},
    ],
    hint: '중간 수준 특징(형태·패턴)을 담당합니다. 파라미터가 급격히 증가하기 시작합니다.'
  },
  layer4: {
    title: 'Layer 4 — 2 × Residual Block',
    items: [
      {k:'블록 수', v:'2개'},
      {k:'채널 수', v:'512 (256→512)'},
      {k:'출력 크기', v:'7 × 7 × 512'},
      {k:'Skip 유형', v:'Projection (1×1 Conv)'},
      {k:'파라미터', v:'8,390,656'},
      {k:'비중', v:'전체의 약 72%'},
    ],
    hint: '고수준 추상 특징(객체 전체)을 학습합니다. ResNet-18 파라미터의 72%가 이 레이어에 집중됩니다.'
  },
  head: {
    title: 'Global AvgPool + FC',
    items: [
      {k:'AvgPool', v:'7×7 → 1×1 (공간 평균)'},
      {k:'Flatten', v:'512-dim 벡터'},
      {k:'FC', v:'Linear(512 → 1000)'},
      {k:'활성화', v:'Softmax'},
      {k:'파라미터', v:'513,000'},
      {k:'출력', v:'1000개 클래스 확률'},
    ],
    hint: 'Global AvgPool은 MaxPool 대비 공간 정보를 부드럽게 집약하며, 과적합을 줄이는 효과가 있습니다.'
  },
  out: {
    title: '분류 결과',
    items: [
      {k:'출력 형태', v:'[1000] 확률 벡터'},
      {k:'합계', v:'모든 확률 합 = 1.0'},
      {k:'예측', v:'argmax → 클래스 인덱스'},
      {k:'예시', v:'&quot;고양이&quot; = 0.87'},
    ],
    hint: 'ImageNet 1000개 클래스 중 가장 높은 확률 값의 클래스를 최종 예측으로 출력합니다.'
  }
};

let activeBlock = null;
function showDetail(id) {
  const panel = document.getElementById('detailPanel');
  const d = DETAILS[id];
  if (activeBlock === id) {
    panel.classList.remove('open');
    document.querySelector(`[data-id=&quot;${id}&quot;]`).classList.remove('active');
    activeBlock = null;
    return;
  }
  if (activeBlock) document.querySelector(`[data-id=&quot;${activeBlock}&quot;]`)?.classList.remove('active');
  activeBlock = id;
  document.querySelector(`[data-id=&quot;${id}&quot;]`).classList.add('active');
  document.getElementById('detailTitle').textContent = d.title;
  document.getElementById('detailGrid').innerHTML = d.items
    .map(i=&gt;`&lt;div class=&quot;detail-item&quot;&gt;&lt;div class=&quot;detail-key&quot;&gt;${i.k}&lt;/div&gt;&lt;div class=&quot;detail-val&quot;&gt;${i.v}&lt;/div&gt;&lt;/div&gt;`)
    .join('');
  document.getElementById('detailHint').textContent = '  ' + d.hint;
  panel.classList.add('open');
  setTimeout(() =&gt; panel.scrollIntoView({behavior:'smooth', block:'nearest'}), 100);
}

// ── BAR CHART ANIM ───────────────────────────────────
function animateBars() {
  document.querySelectorAll('.bar-fill').forEach(el =&gt; {
    el.style.width = el.dataset.w + '%';
  });
}
const barObs = new IntersectionObserver(entries =&gt; {
  if (entries[0].isIntersecting) { animateBars(); barObs.disconnect(); }
}, {threshold: 0.4});
barObs.observe(document.getElementById('barChart'));

// ── RESIDUAL BLOCK SIMULATOR ─────────────────────────
const RB_STEPS = [
  {label:'Input x', desc:'입력 텐서 x가 블록에 진입합니다. 이 값이 shortcut으로도 분기됩니다.', color:'#e8f4fb', border:'#2471a3', textColor:'#1a4f6e'},
  {label:'Conv 3×3\nBN · ReLU', desc:'첫 번째 합성곱. 커널이 이미지를 슬라이딩하며 특징을 추출하고, BatchNorm·ReLU로 정규화합니다.', color:'#fef5e7', border:'#d68910', textColor:'#7e5009'},
  {label:'Conv 3×3\nBN', desc:'두 번째 합성곱. 이 단계에서는 ReLU를 아직 적용하지 않습니다. (add 이후에 적용)', color:'#fef5e7', border:'#d68910', textColor:'#7e5009'},
  {label:'F(x) + x\n(Add)', desc:'Conv 결과 F(x)에 shortcut으로 온 원래 입력 x를 더합니다. 이것이 Residual Learning의 핵심입니다.', color:'#fbeee6', border:'#c0392b', textColor:'#7b241c'},
  {label:'ReLU', desc:'덧셈 후 ReLU 활성화. 음수값을 0으로 만들어 비선형성을 부여합니다.', color:'#e9f7ef', border:'#1e8449', textColor:'#145a32'},
  {label:'Output H(x)', desc:'최종 출력 H(x) = F(x) + x. 다음 블록의 입력이 됩니다.', color:'#e8f4fb', border:'#2471a3', textColor:'#1a4f6e'},
];

let rbCurrentStep = -1;
let rbInputVals = [3, 1, 2];

function buildInputPickers() {
  const wrap = document.getElementById('inputPickers');
  wrap.innerHTML = '';
  rbInputVals.forEach((v, i) =&gt; {
    const label = document.createElement('div');
    label.style.cssText = 'display:flex;flex-direction:column;align-items:center;gap:4px;';
    label.innerHTML = `
      &lt;span style=&quot;font-family:var(--mono);font-size:9px;color:var(--text-sub);&quot;&gt;x[${i}]&lt;/span&gt;
      &lt;input type=&quot;number&quot; value=&quot;${v}&quot; min=&quot;-9&quot; max=&quot;9&quot; step=&quot;1&quot;
        style=&quot;width:52px;height:34px;text-align:center;font-family:var(--mono);font-size:14px;
               border:1.5px solid var(--border);border-radius:4px;background:var(--surface);color:var(--text);&quot;
        onchange=&quot;rbInputVals[${i}]=parseInt(this.value)||0;rbReset();&quot;&gt;
    `;
    wrap.appendChild(label);
  });
}

function buildRbViz() {
  const viz = document.getElementById('rbViz');
  viz.innerHTML = '';

  // shortcut arc (rendered as top row)
  const container = document.createElement('div');
  container.style.cssText = 'display:flex;flex-direction:column;align-items:center;gap:8px;width:100%;';

  // Skip line row
  const skipRow = document.createElement('div');
  skipRow.style.cssText = 'display:flex;align-items:center;width:100%;padding:0 35px;';
  skipRow.innerHTML = `
    &lt;div style=&quot;display:flex;align-items:center;gap:0;width:100%;&quot;&gt;
      &lt;div style=&quot;width:12px;height:12px;border-top:2px dashed #c0392b;border-left:2px dashed #c0392b;border-radius:2px 0 0 0;&quot;&gt;&lt;/div&gt;
      &lt;div style=&quot;flex:1;height:2px;background:repeating-linear-gradient(to right,#c0392b 0,#c0392b 5px,transparent 5px,transparent 9px);&quot;&gt;&lt;/div&gt;
      &lt;div style=&quot;font-family:var(--mono);font-size:9px;color:#c0392b;padding:0 8px;white-space:nowrap;&quot;&gt;shortcut x&lt;/div&gt;
      &lt;div style=&quot;flex:1;height:2px;background:repeating-linear-gradient(to right,#c0392b 0,#c0392b 5px,transparent 5px,transparent 9px);&quot;&gt;&lt;/div&gt;
      &lt;div style=&quot;width:0;height:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:8px solid #c0392b;&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
  `;

  // Main flow row
  const flowRow = document.createElement('div');
  flowRow.style.cssText = 'display:flex;align-items:center;gap:0;';

  RB_STEPS.forEach((step, i) =&gt; {
    const node = document.createElement('div');
    node.style.cssText = 'display:flex;flex-direction:column;align-items:center;gap:5px;';
    node.innerHTML = `
      &lt;div id=&quot;rbnode_${i}&quot; style=&quot;
        border-radius:6px;padding:10px 14px;text-align:center;
        font-family:var(--mono);font-size:11px;font-weight:500;min-width:100px;
        background:${step.color};border:2px solid ${step.border};color:${step.textColor};
        transition:all .3s;white-space:pre-line;line-height:1.5;
      &quot;&gt;${step.label}&lt;/div&gt;
      &lt;div id=&quot;rbval_${i}&quot; style=&quot;font-family:var(--mono);font-size:10px;color:var(--text-sub);min-height:16px;&quot;&gt;&lt;/div&gt;
    `;
    flowRow.appendChild(node);
    if (i &lt; RB_STEPS.length - 1) {
      const arr = document.createElement('div');
      arr.style.cssText = 'width:24px;height:2px;background:var(--border);position:relative;flex-shrink:0;margin-bottom:18px;';
      arr.innerHTML = `&lt;div style=&quot;position:absolute;right:-1px;top:-4px;border:5px solid transparent;border-left-color:var(--border);&quot;&gt;&lt;/div&gt;`;
      flowRow.appendChild(arr);
    }
  });

  viz.appendChild(skipRow);
  viz.appendChild(flowRow);
}

function rbReset() {
  rbCurrentStep = -1;
  buildRbViz();
  document.getElementById('rbLog').innerHTML = '▶ 다음 단계 버튼을 눌러 데이터 흐름을 추적하세요.';
  document.getElementById('rbPlayBtn').textContent = '▶ 다음 단계';
}

// Simulated F(x): simple linear transform for demo
function simulateStep(step) {
  const x = rbInputVals;
  const sumX = x.reduce((a,b)=&gt;a+b,0);
  switch(step) {
    case 0: return `[${x.join(', ')}]`;
    case 1: {
      const fx1 = x.map(v =&gt; Math.round(v * 0.8 + 0.5));
      return `[${fx1.join(', ')}]  (×0.8 + bias ≈ Conv)`;
    }
    case 2: {
      const fx2 = x.map(v =&gt; Math.round(v * 0.6 - 0.3));
      return `[${fx2.join(', ')}]  (×0.6 − bias ≈ F(x))`;
    }
    case 3: {
      const fx = x.map(v =&gt; Math.round(v * 0.6 - 0.3));
      const added = fx.map((v,i) =&gt; v + x[i]);
      return `F(x)+x = [${fx.join(',')}] + [${x.join(',')}] = [${added.join(', ')}]`;
    }
    case 4: {
      const fx = x.map(v =&gt; Math.round(v * 0.6 - 0.3));
      const added = fx.map((v,i) =&gt; v + x[i]);
      const relu = added.map(v =&gt; Math.max(0, v));
      return `ReLU([${added.join(',')}]) = [${relu.join(', ')}]`;
    }
    case 5: {
      const fx = x.map(v =&gt; Math.round(v * 0.6 - 0.3));
      const added = fx.map((v,i) =&gt; v + x[i]);
      const relu = added.map(v =&gt; Math.max(0, v));
      return `H(x) = [${relu.join(', ')}]`;
    }
  }
}

function rbStep() {
  rbCurrentStep++;
  if (rbCurrentStep &gt;= RB_STEPS.length) { rbCurrentStep = 0; buildRbViz(); }

  // highlight current node
  RB_STEPS.forEach((_, i) =&gt; {
    const el = document.getElementById(`rbnode_${i}`);
    if (!el) return;
    if (i === rbCurrentStep) {
      el.style.transform = 'translateY(-4px) scale(1.04)';
      el.style.boxShadow = `0 8px 20px rgba(0,0,0,.15)`;
      el.style.outline = '3px solid var(--red)';
      el.style.outlineOffset = '2px';
    } else if (i &lt; rbCurrentStep) {
      el.style.transform = '';
      el.style.boxShadow = '';
      el.style.outline = '';
      el.style.opacity = '0.55';
    } else {
      el.style.transform = '';
      el.style.boxShadow = '';
      el.style.outline = '';
      el.style.opacity = '1';
    }
    if (i &lt;= rbCurrentStep) {
      const valEl = document.getElementById(`rbval_${i}`);
      if (valEl) valEl.textContent = simulateStep(i);
    }
  });

  const step = RB_STEPS[rbCurrentStep];
  const logEl = document.getElementById('rbLog');
  logEl.innerHTML = `
    &lt;div style=&quot;font-family:var(--mono);font-size:11px;color:var(--text-sub);margin-bottom:4px;&quot;&gt;
      Step ${rbCurrentStep + 1} / ${RB_STEPS.length}
    &lt;/div&gt;
    &lt;div style=&quot;font-size:13px;color:var(--text);line-height:1.8;&quot;&gt;${step.desc}&lt;/div&gt;
    &lt;div style=&quot;font-family:var(--mono);font-size:12px;color:#2471a3;margin-top:8px;&quot;&gt;${simulateStep(rbCurrentStep)}&lt;/div&gt;
  `;

  if (rbCurrentStep === RB_STEPS.length - 1) {
    document.getElementById('rbPlayBtn').textContent = '↺ 처음부터';
  }
}

// ── COMPARISON TABLE ─────────────────────────────────
const CMP_DATA = [
  {name:'AlexNet',     layers:8,  params:61,   acc:57.2, skip:false, note:'딥러닝 부흥의 시작점'},
  {name:'VGG-16',      layers:16, params:138,  acc:71.6, skip:false, note:'단순 3×3 conv 반복'},
  {name:'ResNet-18',   layers:18, params:11.7, acc:69.8, skip:true,  note:'경량 · 전이학습 최적'},
  {name:'ResNet-34',   layers:34, params:21.8, acc:73.3, skip:true,  note:'ResNet-18 심화'},
  {name:'ResNet-50',   layers:50, params:25.6, acc:76.1, skip:true,  note:'Bottleneck 블록 도입'},
  {name:'ResNet-101',  layers:101,params:44.5, acc:77.4, skip:true,  note:'대용량 특징 학습'},
  {name:'ResNet-152',  layers:152,params:60.2, acc:78.6, skip:true,  note:'ILSVRC 2015 우승'},
];

let sortKey = 'acc';
let sortAsc = false;

function sortTable(key, btn) {
  sortKey = key;
  document.querySelectorAll('.cf-btn').forEach(b=&gt;b.classList.remove('active'));
  btn.classList.add('active');
  renderTable();
}

function renderTable() {
  const maxAcc = Math.max(...CMP_DATA.map(d=&gt;d.acc));
  const maxParams = Math.max(...CMP_DATA.map(d=&gt;d.params));
  const sorted = [...CMP_DATA].sort((a,b) =&gt; {
    const av = sortKey==='acc'?a.acc : sortKey==='params'?a.params : a.layers;
    const bv = sortKey==='acc'?b.acc : sortKey==='params'?b.params : b.layers;
    return sortAsc ? av-bv : bv-av;
  });
  const tbody = document.getElementById('compareTbody');
  tbody.innerHTML = sorted.map(d =&gt; {
    const isTarget = d.name === 'ResNet-18';
    const accPct = (d.acc / maxAcc * 100).toFixed(0);
    const paramPct = (d.params / maxParams * 100).toFixed(0);
    return `&lt;tr${isTarget?' style=&quot;background:#fdf8f7;&quot;':''}&gt;
      &lt;td style=&quot;font-weight:${isTarget?'600':'400'};color:${isTarget?'var(--red)':'inherit'}&quot;&gt;${d.name}&lt;/td&gt;
      &lt;td&gt;${d.layers}&lt;/td&gt;
      &lt;td class=&quot;bar-cell&quot;&gt;
        &lt;div&gt;${d.params}M&lt;/div&gt;
        &lt;div class=&quot;inline-bar&quot; style=&quot;width:${paramPct}%;max-width:120px;background:#d68910;opacity:.5;&quot;&gt;&lt;/div&gt;
      &lt;/td&gt;
      &lt;td class=&quot;bar-cell&quot;&gt;
        &lt;div&gt;${d.acc}%&lt;/div&gt;
        &lt;div class=&quot;inline-bar&quot; style=&quot;width:${accPct}%;max-width:120px;background:${isTarget?'var(--red)':'#2471a3'};opacity:.7;&quot;&gt;&lt;/div&gt;
      &lt;/td&gt;
      &lt;td&gt;${d.skip ? '&lt;span style=&quot;color:var(--green);font-weight:600;&quot;&gt;✓&lt;/span&gt;' : '&lt;span style=&quot;color:#bbb&quot;&gt;✗&lt;/span&gt;'}&lt;/td&gt;
      &lt;td style=&quot;color:var(--text-sub);font-size:12px;&quot;&gt;${d.note}&lt;/td&gt;
    &lt;/tr&gt;`;
  }).join('');
}

// ── SCROLL ANIMATIONS ────────────────────────────────
const fadeObs = new IntersectionObserver(entries =&gt; {
  entries.forEach(e =&gt; {
    if (e.isIntersecting) {
      e.target.style.opacity = '1';
      e.target.style.transform = 'translateY(0)';
    }
  });
}, {threshold: 0.08});
document.querySelectorAll('.fade-in').forEach(el =&gt; {
  el.style.transform = 'translateY(16px)';
  fadeObs.observe(el);
});

// ── BOOT ─────────────────────────────────────────────
buildInputPickers();
buildRbViz();
renderTable();
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</description>
      <category>ML,DL,LangChain/04_CNN과 이미지 생성모델</category>
      <author>은서파</author>
      <guid isPermaLink="true">https://goodteacher.tistory.com/939</guid>
      <comments>https://goodteacher.tistory.com/939#entry939comment</comments>
      <pubDate>Wed, 18 Mar 2026 17:52:40 +0900</pubDate>
    </item>
    <item>
      <title>CNN</title>
      <link>https://goodteacher.tistory.com/938</link>
      <description>&lt;p&gt;&lt;iframe src=&quot;https://quietjun.github.io/github-pages/ai/cnn/cnn.html&quot; id=&quot;iframe_rg2ek&quot; width=&quot;100%&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
  window.addEventListener('message', function(e) {
    if(e.data.height) {
      document.getElementById('iframe_rg2ek').style.height = e.data.height + 'px';
    }
  });
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>ML,DL,LangChain/04_CNN과 이미지 생성모델</category>
      <author>은서파</author>
      <guid isPermaLink="true">https://goodteacher.tistory.com/938</guid>
      <comments>https://goodteacher.tistory.com/938#entry938comment</comments>
      <pubDate>Wed, 18 Mar 2026 17:10:05 +0900</pubDate>
    </item>
    <item>
      <title>List Comprehension</title>
      <link>https://goodteacher.tistory.com/937</link>
      <description>&lt;p&gt;파이썬의 &lt;strong&gt;리스트 컴프리헨션(List Comprehension)&lt;/strong&gt;은 기존 리스트나 반복 가능한 객체(Iterable)를 바탕으로 새로운 리스트를 간결하게 생성하는 문법입니다.&lt;/p&gt;
&lt;p&gt;자바의 &lt;code&gt;Stream API&lt;/code&gt;에서 &lt;code&gt;.map().filter().collect(Collectors.toList())&lt;/code&gt;를 한 줄로 줄여놓은 것과 매우 유사합니다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;1. 기본 문법&lt;/h3&gt;
&lt;p&gt;가장 기본적인 형태는 반복문만 사용하는 것입니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# [표현식 for 항목 in 반복가능객체]
squares = [x**2 for x in range(5)]

# 결과: [0, 1, 4, 9, 16]&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;표현식(Expression):&lt;/strong&gt; 새로운 리스트에 담길 값 (위 예제에선 &lt;code&gt;x**2&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;항목(Item):&lt;/strong&gt; 반복 객체에서 꺼내온 개별 요소 (&lt;code&gt;x&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;반복가능객체(Iterable):&lt;/strong&gt; 소스가 되는 객체 (&lt;code&gt;range(5)&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;2. 조건을 추가할 때 (Filtering)&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;if&lt;/code&gt;문을 사용하여 특정 조건에 맞는 데이터만 골라낼 수 있습니다. 자바 스트림의 &lt;strong&gt;&lt;code&gt;.filter()&lt;/code&gt;&lt;/strong&gt; 역할입니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# [표현식 for 항목 in 반복가능객체 if 조건문]
even_numbers = [x for x in range(10) if x % 2 == 0]

# 결과: [0, 2, 4, 6, 8]&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;작동 순서:&lt;/strong&gt; &lt;code&gt;range&lt;/code&gt;에서 하나씩 꺼냄 -&amp;gt; &lt;code&gt;if&lt;/code&gt; 조건 검사 -&amp;gt; 참이면 리스트에 추가.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;3. 조건을 변경할 때 (If-Else / Mapping)&lt;/h3&gt;
&lt;p&gt;값에 따라 다른 결과를 넣고 싶을 때는 &lt;code&gt;if-else&lt;/code&gt; 문을 &lt;strong&gt;표현식 자리(앞쪽)&lt;/strong&gt;에 씁니다. 이는 파이썬의 &lt;strong&gt;삼항 연산자&lt;/strong&gt; 문법을 활용하는 것입니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# [참일때값 if 조건문 else 거짓일때값 for 항목 in 반복가능객체]
result = [&amp;quot;Pass&amp;quot; if score &amp;gt;= 60 else &amp;quot;Fail&amp;quot; for score in [50, 80, 45, 90]]

# 결과: [&amp;#39;Fail&amp;#39;, &amp;#39;Pass&amp;#39;, &amp;#39;Fail&amp;#39;, &amp;#39;Pass&amp;#39;]&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;주의:&lt;/strong&gt; 필터링용 &lt;code&gt;if&lt;/code&gt;는 맨 뒤에 오지만, 값을 선택하는 &lt;code&gt;if-else&lt;/code&gt;는 반드시 맨 앞에 와야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;4. 중첩 반복문 (Nested For Loop)&lt;/h3&gt;
&lt;p&gt;리스트 안에 여러 개의 &lt;code&gt;for&lt;/code&gt;문을 사용할 수 있습니다. 왼쪽에서 오른쪽 순서로 중첩됩니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# 2차원 리스트(행렬)를 1차원으로 풀기 (Flatten)
matrix = [[1, 2], [3, 4], [5, 6]]
flatten = [val for row in matrix for val in row]

# 결과: [1, 2, 3, 4, 5, 6]

# 위 코드는 아래의 일반 for문과 동일하게 작동합니다.
# for row in matrix:
#     for val in row:
#         flatten.append(val)&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3&gt;5. 중첩 리스트 생성 (Nested Comprehension)&lt;/h3&gt;
&lt;p&gt;리스트 안에 또 다른 리스트 컴프리헨션을 넣을 수 있습니다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# 3x3 행렬 만들기
matrix = [[j for j in range(3)] for i in range(3)]

# 결과: [[0, 1, 2], [0, 1, 2], [0, 1, 2]]&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3&gt;6. 다른 데이터 타입도 가능합니다&lt;/h3&gt;
&lt;p&gt;문법 구조는 비슷하지만 괄호의 종류에 따라 결과 데이터 타입이 달라집니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Set 컴프리헨션:&lt;/strong&gt; 중복 제거가 필요할 때&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;{x % 3 for x in range(10)} # 결과: {0, 1, 2}&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dict 컴프리헨션:&lt;/strong&gt; 키-값 쌍을 만들 때&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;{x: x**2 for x in range(3)} # 결과: {0: 0, 1: 1, 2: 4}&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generator 표현식:&lt;/strong&gt; 메모리를 아끼기 위해 (소괄호 사용)&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;gen = (x**2 for x in range(1000000)) # 당장 리스트를 만들지 않고 대기함&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;  실무적인 조언&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;가독성 우선:&lt;/strong&gt; 컴프리헨션이 너무 길어지거나 중첩이 3단계 이상 넘어가면 일반 &lt;code&gt;for&lt;/code&gt;문으로 작성하는 것이 동료(혹은 미래의 나)를 위한 길입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;디버깅:&lt;/strong&gt; 컴프리헨션 내부는 중단점(Breakpoint)을 찍기 어렵습니다. 로직이 복잡하면 별도의 함수로 빼서 호출하는 방식을 권장합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;성능:&lt;/strong&gt; 일반 &lt;code&gt;append&lt;/code&gt; 방식보다 리스트 컴프리헨션이 내부적으로 더 빠르게 최적화되어 작동합니다. 단순 생성/필터링 작업에는 적극적으로 사용하세요.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Java 개발자라면?&lt;/strong&gt;&lt;br&gt;&lt;code&gt;list.stream().filter(x -&amp;gt; x &amp;gt; 5).map(x -&amp;gt; x * 2).collect(Collectors.toList())&lt;/code&gt;&lt;br&gt;이 구문을 보실 때마다&lt;br&gt;&lt;code&gt;[x * 2 for x in list if x &amp;gt; 5]&lt;/code&gt; 를 떠올리시면 됩니다!&lt;/p&gt;</description>
      <category>Python</category>
      <author>은서파</author>
      <guid isPermaLink="true">https://goodteacher.tistory.com/937</guid>
      <comments>https://goodteacher.tistory.com/937#entry937comment</comments>
      <pubDate>Sun, 15 Mar 2026 07:16:13 +0900</pubDate>
    </item>
    <item>
      <title>LLM의 Role 정리</title>
      <link>https://goodteacher.tistory.com/936</link>
      <description>&lt;p&gt;&lt;iframe src=&quot;https://quietjun.github.io/github-pages/ai/rag/roles.html&quot; id=&quot;iframe_k3lbm&quot; width=&quot;100%&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
  window.addEventListener('message', function(e) {
    if(e.data.height) {
      document.getElementById('iframe_k3lbm').style.height = e.data.height + 'px';
    }
  });
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>ML,DL,LangChain/03_토큰화와 합성데이터</category>
      <author>은서파</author>
      <guid isPermaLink="true">https://goodteacher.tistory.com/936</guid>
      <comments>https://goodteacher.tistory.com/936#entry936comment</comments>
      <pubDate>Sat, 14 Mar 2026 07:08:06 +0900</pubDate>
    </item>
    <item>
      <title>LLM 샘플링 파라미터</title>
      <link>https://goodteacher.tistory.com/935</link>
      <description>&lt;p&gt;&lt;iframe src=&quot;https://quietjun.github.io/github-pages/ai/rag/llmsampling.html&quot; id=&quot;iframe_vod76&quot; width=&quot;100%&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
  window.addEventListener('message', function(e) {
    if(e.data.height) {
      document.getElementById('iframe_vod76').style.height = e.data.height + 'px';
    }
  });
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>ML,DL,LangChain/03_토큰화와 합성데이터</category>
      <author>은서파</author>
      <guid isPermaLink="true">https://goodteacher.tistory.com/935</guid>
      <comments>https://goodteacher.tistory.com/935#entry935comment</comments>
      <pubDate>Sat, 14 Mar 2026 06:52:32 +0900</pubDate>
    </item>
    <item>
      <title>RNN vs LSTM</title>
      <link>https://goodteacher.tistory.com/933</link>
      <description>&lt;p&gt;&lt;iframe src=&quot;https://quietjun.github.io/github-pages/ai/rnn/lstm.html&quot; id=&quot;myIframe&quot; width=&quot;100%&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;script&gt;
  window.addEventListener('message', function(e) {
    if(e.data.height) {
      document.getElementById('myIframe').style.height = e.data.height + 'px';
    }
  });
&lt;/script&gt;</description>
      <category>ML,DL,LangChain/03_토큰화와 합성데이터</category>
      <author>은서파</author>
      <guid isPermaLink="true">https://goodteacher.tistory.com/933</guid>
      <comments>https://goodteacher.tistory.com/933#entry933comment</comments>
      <pubDate>Fri, 13 Mar 2026 15:34:41 +0900</pubDate>
    </item>
    <item>
      <title>RNN &amp;amp; Seq2Seq 시각화</title>
      <link>https://goodteacher.tistory.com/932</link>
      <description>&lt;iframe id=&quot;myIframe&quot; src=&quot;https://quietjun.github.io/github-pages/ai/rnn/rnn.html&quot; width=&quot;100%&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;/iframe&gt;

&lt;script&gt;
  window.addEventListener('message', function(e) {
    if(e.data.height) {
      document.getElementById('myIframe').style.height = e.data.height + 'px';
    }
  });
&lt;/script&gt;</description>
      <category>ML,DL,LangChain/03_토큰화와 합성데이터</category>
      <author>은서파</author>
      <guid isPermaLink="true">https://goodteacher.tistory.com/932</guid>
      <comments>https://goodteacher.tistory.com/932#entry932comment</comments>
      <pubDate>Fri, 13 Mar 2026 10:44:26 +0900</pubDate>
    </item>
    <item>
      <title>WordPieceTokenizer</title>
      <link>https://goodteacher.tistory.com/931</link>
      <description>&lt;iframe src=&quot;https://quietjun.github.io/github-pages/ai/rnn/wordpiecetokenizer.html&quot; id=&quot;myIframe&quot; width=&quot;100%&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
  window.addEventListener('message', function(e) {
    if(e.data.height) {
      document.getElementById('myIframe').style.height = e.data.height + 'px';
    }
  });
&lt;/script&gt;</description>
      <category>ML,DL,LangChain/03_토큰화와 합성데이터</category>
      <author>은서파</author>
      <guid isPermaLink="true">https://goodteacher.tistory.com/931</guid>
      <comments>https://goodteacher.tistory.com/931#entry931comment</comments>
      <pubDate>Thu, 12 Mar 2026 23:03:48 +0900</pubDate>
    </item>
  </channel>
</rss>