<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>JJukE's Brain</title>
    <link>https://jjuke-brain.tistory.com/</link>
    <description>Sangjune Park in UNIST 3D Vision and Robotics Lab
AI, Programming, Paper Review etc.
Github : https://github.com/JJukE</description>
    <language>ko</language>
    <pubDate>Fri, 21 Aug 2026 09:03:41 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>JJukE</managingEditor>
    <image>
      <title>JJukE's Brain</title>
      <url>https://tistory1.daumcdn.net/tistory/4409560/attach/f55b01bbe6a04ae79c1d423128edd0e9</url>
      <link>https://jjuke-brain.tistory.com</link>
    </image>
    <item>
      <title>최신 Reinforcement Learning 관련 개념 및 용어 정리</title>
      <link>https://jjuke-brain.tistory.com/entry/Reinforcement-Learning-%EA%B4%80%EB%A0%A8-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC-%EB%B0%8F-%EA%B8%B0%EC%B4%88-%EC%8B%A4%EC%8A%B5-1</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지난 3년간 3D Vision 분야에서 연구를 하다가, 큰 그림에서의 연구 방향이 '결국에는 하드웨어를 다루는 쪽으로 갈 것이다'라는 결론을 내리고, 내 연구 주제 또한 이러한 방향으로 가야겠다는 목표를 세운 후, 새로운 연구 주제는 'Physics-based human interaction generation'로 정하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 human interaction generation은 단순히 scene이나 object를 고려한 (소프트웨어 상에서의) human motion generation이었다면, physcis-based가 들어가는 순간 물리 법칙을 고려한 시뮬레이터 상에서의 학습과 추론이 필요해진다. 따라서, supervised learning이 아닌 reinforcement learning 기반 학습 패러다임을 이해하고 구현할 필요성이 생겼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데, 학부 시절 겉핥기 식으로 배웠던 내용과 최근 관련 연구 사이에는 gap이 꽤 커서, 다시 기초를 다질 겸 최근 연구에서 쓰이고 있는 개념(특히 용어들)을 정리한 후, Deep Supervised Learning에서의 training과 달리 Reinforcement Learning에서의 training은 어떤 코드 구조를 갖고 있는지까지 간단하게 살펴보려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, 학부 때 배웠던 강화학습의 기초 이론은 다음 카테고리에 따로 정리가 되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/category/Fundamentals/Reinforcement%20Learning&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://jjuke-brain.tistory.com/category/Fundamentals/Reinforcement%20Learning&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776663333265&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;'Fundamentals/Reinforcement Learning' 카테고리의 글 목록&quot; data-og-description=&quot;Sangjune Park in UNIST 3D Vision and Robotics Lab AI, Programming, Paper Review etc. Github : https://github.com/JJukE&quot; data-og-host=&quot;jjuke-brain.tistory.com&quot; data-og-source-url=&quot;https://jjuke-brain.tistory.com/category/Fundamentals/Reinforcement%20Learning&quot; data-og-url=&quot;https://jjuke-brain.tistory.com/category/Fundamentals/Reinforcement%20Learning&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dst2fW/dJMb8XkhnY4/1x2TkdT4Y16T9v43RmxcBk/img.jpg?width=800&amp;amp;height=600&amp;amp;face=0_0_800_600,https://scrap.kakaocdn.net/dn/bvMbvT/dJMb887aQgd/8aTBGoOharhKJjogg3kip1/img.jpg?width=800&amp;amp;height=600&amp;amp;face=0_0_800_600&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/category/Fundamentals/Reinforcement%20Learning&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jjuke-brain.tistory.com/category/Fundamentals/Reinforcement%20Learning&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dst2fW/dJMb8XkhnY4/1x2TkdT4Y16T9v43RmxcBk/img.jpg?width=800&amp;amp;height=600&amp;amp;face=0_0_800_600,https://scrap.kakaocdn.net/dn/bvMbvT/dJMb887aQgd/8aTBGoOharhKJjogg3kip1/img.jpg?width=800&amp;amp;height=600&amp;amp;face=0_0_800_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;'Fundamentals/Reinforcement Learning' 카테고리의 글 목록&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Sangjune Park in UNIST 3D Vision and Robotics Lab AI, Programming, Paper Review etc. Github : https://github.com/JJukE&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jjuke-brain.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 글에서는 강화 학습의 기초 이론보다는, 최신 연구에서 활용되는 여러 강화학습 관련 개념들을 간단히 알아보고 실습해보는 내용을 다룬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Supervised Learning to Reinforcement Learning&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;기존에 연구하던 deep learning에서는 모델이 학습에 활용하는 training data가 I.I.D. (Independent and Identically Distributed)임을 가정한다. 즉, 모델이 엄격한(strict) supervision 하에 static input을 해당 target output에 맵핑하는 함수로서 역할을 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그러나, 어떤 agent가 physical simulator와 같은 dynamic하고 and temporal한 환경에 놓인다면 (즉, sequential한 환경에서는), I.I.D. 가정은 완전히 깨진다. 이 환경에서는 시간과 인과 관계(causality)가 주요 factor가 되며, agent가 택하는 action이 다음 state를 결정하면서 연속적인 feedback loop를 만들어내게 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 모델은 특정 패턴을 맞추는 데 집중하기 보다는 cumulative하고 long-term의 결과물을 최적화해야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Supervised Learning은 학업적으로 학습하고, 이를 바탕으로 표준화된 시험을 치르는 것으로 비유할 수 있다. 모델은 학습 시 수학적으로 표현된 dataset을 제공받고, 그 data에 가장 잘 맞도록 parameter를 조정한다. 이는 data mimicry로 볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하지만, Reinforcement Learning은 자전거를 타는 방법을 학습하게되는 과정으로 비유할 수 있다. 모델에게 단순히 자전거를 잘 타는 사람에 대한 text, video 등의 데이터를 주면서 학습시키는 것이 아니라, balance, momentum, gravity 등이 반영된 physical environment에서 직접 상호작용하면서 성공/실패에 따른 feedback에 따라 내부적인 policy를 조정한다. 즉, 모델 학습 시에 정확한 정답값 대신 goal이 주어지며, action에 대한 reward를 최대화하도록 내부 파라미터를 조정한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;수학적으로 RL의 학습 과정은 다음과 같이 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Markov Decision Process (MDP)&lt;/span&gt;로 모델링된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Agent는 state space \( \mathcal{S} \)의 state \(s_t\)를 관찰(observe)하고, 내부 policy \( \pi(a_t \vert s_t)\)에 따라 action space \(\mathcal{A}\)의 특정 action \(a_t\)를 실행(execute)하며, environment는 transition dynamics \(P(s_{t+1} \vert s_t, a_t)\)를 기반으로 새로운 state \(s_{t+1}\) 및 scalar reward \(\mathcal{R}(s_t, a_t)\)를 계산한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Proximal Policy Optimization (PPO)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;RL의 목적은 future rewards의 expected sum \(J(\pi_\theta)\)를 최대화하는 parameterized policy \(\pi_\theta\)를 찾는 것이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;\[J(\pi_\theta) = \mathbb{E}_{\tau \sim \pi_\theta} \left[ \sum^\infty_{t=0} \gamma^t r_t \right] \]&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 \(\tau\)는 states 및 actions의 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;trajectory(=episode, rollout)&lt;/span&gt;를, \(r_t\)는 해당 timestep \(t\)에서의 reward를, \(\gamma\)는 0과 1사이의 discount factor를 나타낸다. 1에 가까울수록 future reward의 가중치가 높아진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로, simulation environment에서 agent의 현재 policy를 수행하는 과정을 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;rollout&lt;/span&gt;이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 policy gradient method, 즉 expected reward의 gradient를 증가시키는(ascending) 방향으로 policy parameters \(\theta\)를 최적화했으나, 이는 매우 불안정하다. 매우 복잡한 simulation 환경에서, step size가 크면 policy가 parameter space의 suboptimal 지역으로 향해 회복이 불가능한(irreversible) performance collapse를 일으킬 것이고, 반대로 step size가 작으면 학습 효율이 떨어질 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 최근에는 LLM의 fine-tuning에서부터 robotics까지 다양한 분야에서 Proximal Policy Optimization (PPO) 기반의 RL을 많이 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PPO는 on-policy method, 즉 policy를 매번 업데이트 할 때마다 evaluate 및 improve시키는데, 이때 &quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;현재 데이터를 가지고, performance collapse를 일으키지 않으면서도 성능을 향상시킬 수 있는 가장 큰 optimization step은?&lt;/span&gt;&quot; 이라는 질문을 던지는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PPO 이전에 Trust Region Policy Optimization (TRPO)이라는 최적화 알고리즘이 있었다. 이는 단순히 이전 policy와 새로운 policy 간의 KL divergence (분포 차이)를 통해 제약을 걸어줌으로써 새로운 policy가 안전한 trust region에 남도록 하는 것이었다. 그러나 second-order optimization (conjugate gradient method)을 사용해야 했어서 계산량이 너무 많았고, 구현도 복잡하여 큰 architecture에 사용하기에는 적합하지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PPO는 first-order optimization을 사용함으로써 TRPO의 안정화 효과와 동시에 계산량도 줄였다. (심지어 몇몇 task에서는 TRPO의 성능을 넘기도 했다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PPO는 구현 방식에 따라 다음 두 가지로 나뉜다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;PPO-Penalty: Objective function 내에서 KL-divergence로 penalize한다.&lt;/li&gt;
&lt;li&gt;PPO-Clip: 수학적으로 clipping하여 많이 벗어나려는 새로운 policy에 대한 보상(incentive)을 제거한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근에는 우수한 신뢰성(reliability)과 간결함(simplicity) 때문에 PPO-Clip이 더 많이 쓰인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;The Actor-Critic architecture&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;PPO의 구현은 Actor-Critic 구조로 이루어져 있다. &lt;span style=&quot;color: #ee2323;&quot;&gt;하나는 decision-making, 다른 하나는 evaluation&lt;/span&gt; 용도의 두 가지 network를 사용한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Actor Network (\(\pi_\theta\)): Actor는 policy 그 자체이다. State observation을 입력받아 가능한 action에 대한 probability distribution (discrete or continuous)을 출력하는데, 이때 parameters \(\theta\)는 stochastic gradient ascent 방식으로 PPO-Clip objective를 최대화하도록 최적화된다.&lt;/li&gt;
&lt;li&gt;Critic Network (\(V_\phi\)): Critic은 action을 결정하는 대신 state를 관측하여 해당 state로부터의 expected cumulative future reward(scalar값)를 계산한다. Parameters \(\phi\)는 agent가 environment rollout 동안 경험할 rewards-to-go와의 MSE를 최소화하도록 최적화된다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특히 critic network는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Advantage Function&lt;/span&gt; \(\hat{A}_t\)를 계산하는 데 필수적이다. Advantage는 해당 state에서 특정 action이 average expected value에 비해 얼마나 좋거나 나쁜지를 결정한다. 0보다 크면 action이 critic이 예측한 것보다 좋다는 뜻으로, actor는 해당 action을 취할 확률을 높여야 하고, 0보다 작으면 그 반대이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;PPO clipping mechanism and surrogate objective&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PPO는 surrogate objective function을 활용하는데, 수식적으로 업데이트에 bound를 설정하여 새로운 policy가 이전 policy와 어느 정도 비슷하도록 하는 &lt;span style=&quot;color: #ee2323;&quot;&gt;regularizer 역할&lt;/span&gt;을 한다 (TRPO에서 trust region에 남기는 역할).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PPO가 gradient ascent로 최대화하고자 하는 objective function은 다음과 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;\[ \theta_{k+1} = \underset{\theta}{\operatorname{argmax}} \mathbb{E}_{s, a ~ \pi_{\theta_k}} \left[ L(s, a, \theta_k, \theta) \right] \]&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 \(L\)은 다음과 같은 clipping mechanism을 포함한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;\[ L(s, a, \theta_k, \theta) = \min \left( \cfrac{\pi_\theta(a \vert s)}{\pi_{\theta_k}(a \vert s)} A^{\pi_{\theta_k}}(s, a), \;\; \operatorname{clip} \left( \cfrac{\pi_\theta(a \vert s)}{\pi_{\theta_k}(a \vert s)}, 1 - \epsilon, 1 + \epsilon \right) A^{\pi_{\theta_k}}(s, a) \right) \]&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Probability ratio \(r_t(\theta)\): &lt;span style=&quot;color: #333333;&quot;&gt;\(&lt;span style=&quot;text-align: left;&quot;&gt;\cfrac{\pi_\theta(a \vert s)}{\pi_{\theta_k}(a \vert s)}\) 항은 새로운 policy와 이전 policy 간의 비율을 의미한다. 1보다 크면 새로운 policy를 더 많이, 1이면 두 policy를 동일하게 다룬다는 의미이다.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;text-align: left;&quot;&gt;Hyperparameter \(\epsilon\): 보통 0.1~0.3 정도의 작은 상수로, 한 번의 update동안 policy 변화가 얼마나 가능한지에 대한 bound이다.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;text-align: left;&quot;&gt;수학적으로 최소값을 취함으로써 stable한 학습을 진행하는데, advantage의 부호에 따라 logic이 구분된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Positive advantage (\(\hat{A}_t &amp;gt; 0\)): 이는 agent가 성공적으로 움직였다는 뜻이고, objective는 policy network가 해당 action의 확률을 높이도록 (ratio가 오르도록) 한다. 하지만, PPO는 ratio가 \(1 + \epsilon\)을 초과하면 과도하게 update되지 않도록 \((1+\epsilon) \hat{A}_t\) 값으로 clipping된다. 그런데 이 때의 advantage는 old policy로 계산된 (상수) 값이므로, gradient는 0이 되고, 따라서 업데이트 되지 않는다. 이는 곧 &lt;span style=&quot;color: #ee2323;&quot;&gt;운좋게 찾은 비정상적인 trajectory (policy parameter들을 왜곡(skew)시켜 네트워크를 불안정하게 만드는)에 대해서는 업데이트를 하지 않도록 설계된다&lt;/span&gt;는 의미이다.&lt;/li&gt;
&lt;li&gt;Negative advantage (\(\hat{A}_t &amp;lt; 0\)): 이는 agent가 잘 못움직였다는 뜻이고, objective는 policy network가 해당 action을 덜 하도록 (ratio가 내려가도록) 한다. 하지만, PPO는 마찬가지로 ratio가 \(1 - \epsilon\)보다 작아지면 업데이트하지 않는다. 이는 &lt;span style=&quot;color: #ee2323;&quot;&gt;너무 이상한 trajectory(rollout), 즉 exploratory noise에 대해서는 업데이트를 하지 않도록 설계된다&lt;/span&gt;는 의미이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PyTorch로 구현할 때, Actor-Critic object는 `step` method를 반드시 포함해야한다. step 메서드에서는 하나의 observation batch를 입력받아 actions, value estimates, log probabilities를 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Training loop는 각 epoch에서 다음과 같은 순서로 돌아간다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;현재 policy \(\pi_k\)를 실행하여 trajectories (\(\mathcal{D}_k\))를 얻는다.&lt;/li&gt;
&lt;li&gt;현재 value function \(V_{\phi_k}\)을 기반으로 reward-to-go 및 advantage estimates \(\hat{A}_t\)를 계산한다.&lt;/li&gt;
&lt;li&gt;Minibatch에 Adam optimizer로 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;여러 차례&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;Stochastic Gradient Descent를 적용하여 PPO objective를 최대화 및 Actor를 업데이트하고, rewards-to-go에 Critic을 fitting한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Imitation Learning (IL)&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;RL에서 수학적으로 완벽한 reward function을 설계하는 것은 매우 어렵다. &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Imitation Learning&lt;/span&gt;에서는 어떤 전문가(expert)의 supervision을 적당히 활용하여 이러한 단점을 보완한다. 즉, agent가 expert를 관찰(observe)하여 그 행동을 복제하려 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;IL 학습은 다음과 같이 모델링된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;States \(x \in \mathcal{X}\)와 control \(u \in \mathcal{U}\)에 대해, 모델은 a set of expert demonstrations \(\Xi = \left\{ \xi_1, \dots, \xi_D \right\}\)를 제공받는다. 이때, 각 demonstration \(\xi\)는 참(true)인 expert policy \(\pi^*\)로부터 얻은 \(\xi = \left\{ (x_0, u_0), (x_1, u_1), \dots \right\}\) 와 같은 state-control의 순서쌍으로 구성된다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서, Imitation Learning의 목적은 expert policy를 잘 모방하는 neural network policy \(\hat{\pi}^*\)를 얻는 것이다. 이때 해당 neural network는 closed-loop control law \(u_t = \pi(x_t)\) 하에서 동작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Imitation learning은 또다시 다음과 같은 두 개의 패러다임으로 나뉜다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Direct Policy Learning: 알고리즘이 supervised learning을 통해 observed states를 expert's actions로 맵핑하도록 학습한다. 예를 들어 &lt;span style=&quot;color: #ee2323;&quot;&gt;Behavior Cloning&lt;/span&gt;이나 &lt;span style=&quot;color: #ee2323;&quot;&gt;DAgger&lt;/span&gt;와 같은 학습 알고리즘이 이에 해당한다.&lt;/li&gt;
&lt;li&gt;Inverse Reinforcement Learning (IRL): Policy를 그대로 카피하지 않고, 알고리즘이 expert가 최대화하고자 하는 latent reward function을 추론한다. 그 reward function이 학습되면, RL로 agent를 학습한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 IRL의 경우 계산량이 많고 수학적으로 복잡한 경우가 많아, 우선 이 글에서는 direct policy learning 방식을 알아보고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Behavior Cloning (BC)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Behavior Cloning&lt;/span&gt;의 architecture는 supervised deep learning 기반으로, 알고리즘의 input \(X\)는 expert demonstration에서 얻은 observed state이고, target \(Y\)는 expert의 action이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;수학적으로, agent는 사전 정의된 cost function \(c(s_t, a_t)\)을 최소화하는 policy \(\pi_\theta\)를 학습한다. 이때 학습 대상이 되는 policy를 student policy라 하는데, cost function은 student policy의 output인 action이 expert의 action과 얼마나 다른지를 수식화하며, 이를 최소화하도록 모델을 최적화한다. 수식화 하면 다음과 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;\[ \hat{\pi}^* = \underset{\theta}{\operatorname{argmin}} \mathbb{E}_{s_t \sim p_\text{data}(s_t)} \left[ c(s_t, a_t) \right] \]&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Discrete action space 상에서 cost \(c(s_t, a_t)\)는 \(a_t = \pi^*(s_t)\)이면 0, 아니면 1이고, continuous control space (human motion을 예로 들면 joint angle 예측)인 경우, MSE loss가 사용될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구현 관점에서, BC는 neural network를 통해 구현할 수 있다. 즉, &lt;span style=&quot;color: #ee2323;&quot;&gt;states를 continuous actions로 맵핑할 수 있는 어떤 neural network를 활용&lt;/span&gt;하면 금방 구현이 가능하다. 또한 expert의 action을 레코딩 해둔 후, offline training이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나, &lt;span style=&quot;color: #ee2323;&quot;&gt;compounding error&lt;/span&gt;라는 치명적인 단점이 있다.&amp;nbsp;Neural network policy \(\pi_\theta\)는 expert가 관측한 states의 분포 \(p_\text{data}(o_t)\)로만 학습이 된다. 하지만 dynamic environment에서 활용할 경우, agent의 policy는 조금의 에러를 발생시킬 것이고, 다음 state에서 offline training dataset에 없던 상태를 마주할 것이다. Agent는 이러한 suboptimal state에서 어떻게 회복(recover)할지에 대한 정보가 없기 때문에, 이후 action은 훨씬 더 큰 에러를 발생시킬 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 어떤 simulator에서 휴머노이드가 걷도록 BC를 통해 학습하였고, inference 시 knee joint의 torque를 계산하는 데 작은 에러가 발생했다고 하자. Expert의 data에는 휴머노이드가 완벽하게 선 상태에서 걷는 sequence만 있을 것이므로, neural network는 이로 인해 발생한 틀어진 자세(postural imbalance)를 바로잡을 수 없다. 이러한 불균형이 이어지는 frame들에서 중첩되면서 휴머노이드는 무너지게(collapse) 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Dataset Aggregation (DAgger)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;DAgger&lt;/span&gt;는 이러한 compounding error를 해결하기 위해 interactive policy correction이라는 아이디어를 추가한 IL 알고리즘이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;특히, data distribution의 불일치(mismatch)를 제거하기 위해, training data의 state distribution \(p_\text{data}(o_t)\)는 student policy가 마주할 시뮬레이터 상의 state distribution \(p_{\pi_\theta}(o_t)\)로 강제한다. 이를 위해 offline dataset 뿐만 아니라 training loop에 사용 가능한 expert가 필요하며, 이러한 expert는 실제 agent의 sub-optimal state에서도 적절한 corrective label을 제공한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;DAgger의 algorithmic architecture는 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Initialization: Expert demonstrations 중 small initial set을 골라 baseline dataset \(\mathcal{D}\)를 만든 후, 기존 BC 방식으로 primary policy \(\pi_1\)를 학습한다.&lt;/li&gt;
&lt;li&gt;Execution and Exploration: 이후 iteration부터는 &lt;span style=&quot;color: #ee2323;&quot;&gt;dynamic environment로부터 새로운 trajectory set을 얻는다&lt;/span&gt;. Rollout 과정에서 알고리즘은 agent가 마주하는 observations의 분포 \(p_{\pi_\theta}(o_t)\)를 기록(log)한다.&lt;/li&gt;
&lt;li&gt;Expert Querying: Rollout의 각 state \(s\)마다 expert로 optimal action \(a^*\)를 querying한다. 이 과정에서 sub-optimal state에 대해서도 recover가 진행된다.&lt;/li&gt;
&lt;li&gt;Dataset Aggregation: 새롭게 라벨링된 state-action pairs \(s, a^*)\)를 main dataset \(\mathcal{D}\)에 이어붙인다. 따라서 학습이 진행됨에 따라 optimal trajectory와 recovery maneuver들이 계속 쌓이게 된다.&lt;/li&gt;
&lt;li&gt;Iterative Retraining: Policy \(\pi_{i+1}\)을 새로운 dataset으로 재학습하며, 학습된 policy가 expert policy를 근사하도록 반복한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 DAgger의 단점을 보완한 variants들은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Ensemble DAgger: 여러 neural network를 ensemble하여 expert를 언제 query할 지 정한다. Ensemble member(s) 간의 variance \(\sigma\)가 threshold \(\hat{\tau}\)를 넘으면, 즉 agent의 action과 expert action 차이가 많이 나면, demonstration을 요청하고, 낮으면 agent가 자동으로 진행하도록 함으로써 매 step 마다 network를 retraining하는 load를 줄여주는 것이다.&lt;/li&gt;
&lt;li&gt;HG-DAgger (Human-Gated DAgger): Human expert가 rollout을 모니터링 하면서 a&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;gent가 위험한 trajectory로 빠질 때&lt;span&gt; 관여한다.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;SMILe and SEARN (Stochastic Mixture Algorithms): Policy \(\pi_n\)을 이전 policy \(\pi_{n-1}\)과 새로운 policy \(\hat{\pi}_n\)의 stochastic mixture로 결정한다.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Reinforcement Learning</category>
      <category>Il</category>
      <category>imitation learning</category>
      <category>PPO</category>
      <category>reinforcement learning</category>
      <category>rl</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/251</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Reinforcement-Learning-%EA%B4%80%EB%A0%A8-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC-%EB%B0%8F-%EA%B8%B0%EC%B4%88-%EC%8B%A4%EC%8A%B5-1#entry251comment</comments>
      <pubDate>Mon, 20 Apr 2026 16:43:57 +0900</pubDate>
    </item>
    <item>
      <title>딥러닝 실험을 효율적으로 하기 위한 Hydra 사용법</title>
      <link>https://jjuke-brain.tistory.com/entry/Hydra-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 모델을 구현하여 학습시킬 때, hyperparameter에 따라 여러 번의 실험을 해주어야 한다. 이때, &quot;config.yaml&quot;라는 파일을 생성하여 학습 코드 실행에 필요한 argument들(hyperparameter 뿐만 아니라 dataset path 등 여러 설정 값들)을 관리해주면 편하게 실험을 진행할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 이렇게 설정 파일을 통해 실험을 효율적으로 할 수 있게 해주는 tool인 facebook에서 공개한 hydra라는 프레임워크의 사용법을 간단히 정리해보려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;150&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvVSwa/btsykqdMZRk/0T1krOynzwtFpK3UIlipLK/tfile.svg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvVSwa/btsykqdMZRk/0T1krOynzwtFpK3UIlipLK/tfile.svg&quot; data-alt=&quot;Hydra&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvVSwa/btsykqdMZRk/0T1krOynzwtFpK3UIlipLK/tfile.svg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvVSwa%2FbtsykqdMZRk%2F0T1krOynzwtFpK3UIlipLK%2Ftfile.svg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;225&quot; height=&quot;150&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;150&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Hydra&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://hydra.cc&quot;&gt;https://hydra.cc&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1697103610791&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Hydra | Hydra&quot; data-og-description=&quot;A framework for elegantly configuring complex applications&quot; data-og-host=&quot;hydra.cc&quot; data-og-source-url=&quot;https://hydra.cc&quot; data-og-url=&quot;https://hydra.cc/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://hydra.cc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hydra.cc&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Hydra | Hydra&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A framework for elegantly configuring complex applications&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;hydra.cc&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Hydra&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Hydra는 Configuration 파일을 다루고 관리하는 라이브러리이다. 이 라이브러리를 사용하면 Command line에서 파이썬을 실행할 때 argument parsing을 훨씬 간단하게 할 수 있다. 또한, 계층 구조로 configuration을 관리하는 것도 가능하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;사용법도 아주 쉽다. 아래 내용을 보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Quick Start Guide&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Example of config.yaml&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;딥러닝을 학습시킬 때, configuration 파일은 보통 다음과 같은 형태로 주어진다.&lt;/p&gt;
&lt;pre id=&quot;code_1697104283939&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mode: &quot;train&quot; # [&quot;train&quot;, &quot;val&quot;, &quot;test&quot;]
seed: 1
data_root_dir: &quot;[dataset_root_dir]&quot;
dev_root_dir: &quot;[dev_root_dir]&quot;
device:
  use_gpu: True
  num_workers: 16
  cudnn_benchmark: True
  cudnn_deterministic: False
distributed:
  use_ddp: False
  num_gpus: 1 # if use_ddp=False, num_gpus should be 1
data:
  dataset_dir: &quot;${data_root_dir}/...&quot;
model:
  [method_1]:
    method: [method_name]
    arch:
	  [...]
  [method_2]:
    method: [method_name]
    arch:
      [...]
  [method_3]:
    method: [method_name]
    arch:
      [...]
optimizer:
  type: [module]
  method: Adam
  lr: 0.0001
  betas: [ 0.9, 0.999 ]
  eps: 1e-08
  weight_decay: 0
scheduler:
  [module_1]:
    milestones: [400]
    gamma: 0.1
  [module_2]:
    milestones: [400]
    gamma: 0.1
train:
  batch_size: 128
  epochs: 800
test:
  batch_size: 1
  mask_flag: 200
  epochs: 500
log:
  exp_name: &quot;[exp_name]_${mode}_${now:%Y-%m-%d}/${now:%H-%M-%S}&quot;
  log_dir: &quot;${data_root_dir}/${mode}/${now:%Y-%m-%d}/${now:%H-%M-%S}&quot;
  use_wandb: False
  wandb:
    use_wandb: False
    entity: &quot;ray_park&quot; # wandb id
    project: &quot;[project_name_for_wandb]&quot;
# hydra
hydra:
  run:
    dir: ${log.log_dir}
defaults:
  # - hydra/launcher: submitit_slurm
  - override hydra/job_logging: colorlog
  - override hydra/hydra_logging: colorlog
  - _self_&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복잡해 보이지만, 각 모듈에 들어가서 hyperparameter를 하나하나씩 관리해주는 것보다 훨씬 간단하고 빠르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 대괄호([])안에 있는 것은 상황마다 달라질 수 있는 내용이고, ${mode} 와 같이 달러 표시와 중괄호 안에 있는 내용은 해당 값(위 예시에서 ${mode}는 &quot;train&quot; 값)을 가져오게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자는 CONFIG라는 클래스를 따로 만들어 Data Distributed Parallel 사용 여부에 따라 실험 전체에 필요한 argument들을 관리한다. 예시는 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1697105467001&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class CONFIG(object):
    def __init__(self, config):
        self.config = config
        if config.distributed.num_gpus &amp;gt; 1:
            self.is_master = is_master_proc(config.distributed.num_gpus)
    
    def info(self, content):
        if self.config.distributed.num_gpus &amp;gt; 1 and self.is_master:
            logging.info(content)
        elif self.config.distributed.num_gpus == 1:
            logging.info(content)
        else:
            raise NotImplementedError&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시는 hydra로부터 config 인스턴스를 받아 DDP 사용 여부에 따라 공통적으로 configuration을 적용(특히 logging해주기 위해)해주는 부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 사용할 때는 main 함수에 &quot;cfg = CONFIG(config)&quot;와 같이 선언해주어 다양한 변수를 활용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀 더 자세한 적용 사례는 깃허브(&lt;a href=&quot;https://github.com/JJukE/Skeleton&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/JJukE/Skeleton&lt;/a&gt;)를 참조하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Python file(.py)에서 실행하는 경우 - @hydra.main() decorater&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.py 파일에서 실험을 진행할 경우, main 함수 위에 decorater 및 약간의 인자만 추가해주면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1697104634333&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import hydra
import os

@hydra.main(version_base=None, config_path=&quot;[config_dir_path]&quot;, config_name=&quot;[config.yaml]&quot;)
def main(config):
    num_gpu = config.distributed.num_gpu
    ...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행하면 num_gpu 변수에는 위 config.yaml 예시에서 distributed 하위의 num_gpu에 해당하는 값(1)이 들어갈 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Jupyter notebook(.ipynb)에서 실행하는 경우 - initialize() and compose()&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Jupyter notebook에서는 decorator 함수를 사용할 수 없다. 따라서 별도로 제공하는 compose API를 사용해야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://hydra.cc/docs/1.0/experimental/compose_api/#internaldocs-banner&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://hydra.cc/docs/1.0/experimental/compose_api/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1697104874538&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Compose API | Hydra&quot; data-og-description=&quot;The compose API can compose a config similarly to @hydra.main() anywhere in the code.&quot; data-og-host=&quot;hydra.cc&quot; data-og-source-url=&quot;https://hydra.cc/docs/1.0/experimental/compose_api/#internaldocs-banner&quot; data-og-url=&quot;https://hydra.cc/docs/1.0/experimental/compose_api/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://hydra.cc/docs/1.0/experimental/compose_api/#internaldocs-banner&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hydra.cc/docs/1.0/experimental/compose_api/#internaldocs-banner&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Compose API | Hydra&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The compose API can compose a config similarly to @hydra.main() anywhere in the code.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;hydra.cc&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.py 파일에서 configuration 파일의 위치 등을 설정해주듯, jupyter notebook에서는 initialize()와 compose() 함수를 활용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1697105118130&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from hydra import compose, initialize

if __name__ == &quot;__main__&quot;:
    # context initialization
    with initialize(version_base=None, config_path=&quot;[config_file_dir]&quot;, job_name=&quot;[job_name]&quot;):
        config = compose(config_name=&quot;config.yaml&quot;, overrides=[&quot;db=mysql&quot;, &quot;db.user=me&quot;])
    
    # global initialization
    hydra.core.global_hydra.GlobalHydra().instance().clear()
    initialize(version_base=None, config_path=&quot;[config_file_dir]&quot;, job_name=&quot;[job_name]&quot;)
    config = compose(config_name=&quot;config.yaml&quot;, overrides=[&quot;db=mysql&quot;, &quot;db.user=me&quot;])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;context initialization은 with 구문 안에서만 hydra의 설정을 적용하여 &quot;config&quot;변수로 yaml파일 내용들을 불러오는 것이고, global initialization은 실행한 코드 전체(정확히 말하자면 jupyter notebook kernel이 끝나기 전까지)에 대해 hydra 설정을 계속 하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자는 global initialization으로 해주고, hydra 설정을 바꾸고 싶으면 hydra.core.global_hydra.GlobalHydra().instance().clear()를 통해 설정 값을 초기화해준 후 다른 설정을 다시 해주는 것을 선호한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Research/Implementation</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/249</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Hydra-%EC%82%AC%EC%9A%A9%EB%B2%95#entry249comment</comments>
      <pubDate>Thu, 12 Oct 2023 19:13:02 +0900</pubDate>
    </item>
    <item>
      <title>Tensor의 shape을 가독성있게 변환하는 einops 사용법</title>
      <link>https://jjuke-brain.tistory.com/entry/Tensor%EC%9D%98-shape%EC%9D%84-%EA%B0%80%EB%8F%85%EC%84%B1%EC%9E%88%EA%B2%8C-%EB%B3%80%ED%99%98%ED%95%98%EB%8A%94-einops-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인공지능 연구를 하면서 코딩을 하다보면 Numpy, PyTorch, Tensorflow 등의 tensor의 shape을 변환해주는 경우가 매우 많다. 필자의 경우 PyTorch를 가장 많이 사용하는데, reshape(), view(), squeeze() 등등 tensor shape을 변환하는 함수의 종류도 너무 다양하고, 가독성도 떨어진다. 또한 변환된(또는 변환 할) tensor의 현재 shape이 어떤지 알 수 없기 때문에 디버깅할 때에도 매우 불편하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우연히 이를 깔끔하게 해결해줄 수 있는 einops라는 라이브러리를 알게되어 자주 쓰는 함수 위주로 내용을 간단히 정리해보려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 공식 홈페이지에 가보면 document와 함께 추가적인 정보를 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://einops.rocks/&quot;&gt;https://einops.rocks/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1693569563037&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Einops&quot; data-og-description=&quot;einops Flexible and powerful tensor operations for readable and reliable code. Supports numpy, pytorch, tensorflow, jax, and others. Recent updates: 0.7.0rc1: no-hassle torch.compile, support of array api standard and more 10'000: github reports that more &quot; data-og-host=&quot;einops.rocks&quot; data-og-source-url=&quot;https://einops.rocks/&quot; data-og-url=&quot;https://einops.rocks/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://einops.rocks/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://einops.rocks/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Einops&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;einops Flexible and powerful tensor operations for readable and reliable code. Supports numpy, pytorch, tensorflow, jax, and others. Recent updates: 0.7.0rc1: no-hassle torch.compile, support of array api standard and more 10'000: github reports that more&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;einops.rocks&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;619&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcSf5n/btssSnUBoCT/adtaQT4kgOaPv6EMnvaB5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcSf5n/btssSnUBoCT/adtaQT4kgOaPv6EMnvaB5K/img.png&quot; data-alt=&quot;einops&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcSf5n/btssSnUBoCT/adtaQT4kgOaPv6EMnvaB5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcSf5n%2FbtssSnUBoCT%2FadtaQT4kgOaPv6EMnvaB5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;619&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;619&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;einops&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Installation&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1693569619677&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# with anaconda
conda install -c conda-forge einops
# with pip
pip install einops&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;유용한 함수&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;einops는 &lt;span style=&quot;color: #ee2323;&quot;&gt;문자열을 활용&lt;/span&gt;하여 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;tensor의 shape을&lt;/span&gt; 직관적이고 가독성 있게 변형해준다. pytorch나 numpy에서 제공하는 transpose, permutation, reshape, view, squeeze, unsqueeze, stack, concatenate 등의 함수를 대체할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;rearrange()&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1693569823941&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from einops import rearrange
# ex) list of 32 images with (h, w, c) = (30, 40, 3)
input_tensor = [np.random.randn(30, 40, 3) for _ in range(32)]
# list to numpy array (stack along batch axis)
output_tensor = rearrange(input_tensor, &quot;b h w c -&amp;gt; b h w c&quot;) # (32, 30, 40, 3)
# reshape (concat along height axis)
output_tensor = rearrange(input_tensor, &quot;b h w c -&amp;gt; (b h) w c&quot;) # (960, 40, 3)
# reshape (reordering)
output_tensor = rearrange(input_tensor, &quot;b h w c -&amp;gt; b c h w&quot;) # (32, 3, 30, 40)
# flatten (each image into a vector)
output_tensor = rearrange(input_tensor, &quot;b h w c -&amp;gt; b (c h w)&quot;) # (32, 3600)
# split -&amp;gt; 괄호 내의 순서는 상관 없음
output_tensor = rearrange(input_tensor, &quot;b (h1 h) (w1 w) c -&amp;gt; (b h1 w1) h w c&quot;, h1=2, w1=2) # to batch: (128, 15, 20, 3)
output_tensor = rearrange(input_tensor, &quot;b (h h1) (w w1) c -&amp;gt; b h w (c h1 w1)&quot;, h1=2, w1=2) # to channel: (32, 15, 20, 12)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;string으로 shape을 표시해줄 때 에러를 주의해야 한다. 특히 띄어쓰기는 필수적으로 지켜야 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blg798/btssUNLyAha/8uoqu6i2uYBOxMinPllTsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blg798/btssUNLyAha/8uoqu6i2uYBOxMinPllTsk/img.png&quot; data-alt=&quot;Error example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blg798/btssUNLyAha/8uoqu6i2uYBOxMinPllTsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fblg798%2FbtssUNLyAha%2F8uoqu6i2uYBOxMinPllTsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;1208&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1208&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Error example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Contiguous() 붙여줘야 하는 경우&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;일반적으로, PyTorch의 텐서의 shape을 변경해줄 때, view 함수를 사용하는 경우에는 contiguous()를 붙여주지 않으면 에러가 뜬다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;rearrange 함수의 경우 view와 비슷하게 동작하도록 pattern을 설정해줄 수 있는데, 이 때 contiguous()를 붙여주지 않으면 (DDP를 돌릴 때) warning이 뜬다. (사실 학습을 돌리는 데 큰 지장이 없지만, 느려질 수 있다는 에러 문구가 상당히 거슬린다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot_2024-05-24_19.44.41@2x.png&quot; data-origin-width=&quot;1844&quot; data-origin-height=&quot;314&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFGSdI/btsHA1cFse0/lCcZeNkhu3KrJykj2Ak8Z1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFGSdI/btsHA1cFse0/lCcZeNkhu3KrJykj2Ak8Z1/img.png&quot; data-alt=&quot;contiguous()를 붙여주지 않아 발생한 경고 문구&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFGSdI/btsHA1cFse0/lCcZeNkhu3KrJykj2Ak8Z1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFGSdI%2FbtsHA1cFse0%2FlCcZeNkhu3KrJykj2Ak8Z1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1844&quot; height=&quot;314&quot; data-filename=&quot;Screenshot_2024-05-24_19.44.41@2x.png&quot; data-origin-width=&quot;1844&quot; data-origin-height=&quot;314&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;contiguous()를 붙여주지 않아 발생한 경고 문구&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;아래 예시를 보자.&lt;/p&gt;
&lt;pre id=&quot;code_1716547789320&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = rearrange(a, &quot;(n b) h w c -&amp;gt; b h (w n) c&quot;, n=number).contiguous() # 필수!
b = rearrange(b, &quot;b h (w n) c -&amp;gt; (n b) c h w&quot;, n=number).contiguous() # 필수!

c = rearrange(c, &quot;n b h w c -&amp;gt; (n b) h w c&quot;) # 없어도 됨
d = rearrange(d, &quot;(n b) h w c -&amp;gt; n b h w c&quot;) # 없어도 됨
e = rearrange(e, &quot;(n b) p c h w -&amp;gt; n (b p) c h w&quot;, n=number) # 없어도 됨&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정확한 이유는 contigous()가 필요한 이유(메모리가 어쩌고 저쩌고..)까지 공부를 해야하는 것 같아 넘어가고, 어림 짐작 하기로는 예시의 a, b를 보면, &lt;span style=&quot;color: #ee2323;&quot;&gt;첫 번째 dimension의 일부가 세 번째 dimension의 일부로 옮겨가거나, 그 반대인 경우&lt;/span&gt;이다. 이 경우가 view와 같은 역할을 하는 경우(contiguous가 필요한 경우)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹시 또 다른 경우가 발견되거나, 정확한 이유를 알게되면 내용을 추가하도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;reduce()&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 함수는 min, max, sum, mean, prod 등의 연산을 통해 특정 축을 없애거나 차원을 줄일 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1693569955907&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from einops import reduce
x = np.random.randn(10, 20, 30, 40)

# max reduction on the first axis
y = reduce(x, &quot;b h w c -&amp;gt; h w c&quot;, &quot;max&quot;) # (20, 30, 40)

# 2d max pooling with kernel size = 2 * 2 (image processing)
y1 = reduce(x, &quot;b c (h1 h2) (w1 w2) -&amp;gt; b c h1 w1&quot;, &quot;max&quot;, h2=2, w2=2) # (10, 20, 15, 20)

# adaptive 2d max pooling to 3 * 4 grid
y2 = reduce(x, &quot;b c (h1 h2) (w1 w2) -&amp;gt; b c h1 w1&quot;, &quot;max&quot;, h1=3, w1=4) # (10, 20, 3, 4)

# global avg pooling
y3 = reduce(x, &quot;b c h w -&amp;gt; b c&quot;, &quot;mean&quot;) # (10, 20)

# mean over batch for each channel
y4 = reduce(x, &quot;b c h w -&amp;gt; () c () ()&quot;, &quot;mean&quot;) # (1, 20, 1, 1)
y5 = reduce(x, &quot;b c h w -&amp;gt; b c () ()&quot;, &quot;mean&quot;) # (10, 20, 1, 1)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;repeat()&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 함수는 특정 축이나 차원을 기준으로 값을 반복한다. 이때 순서에 유의해야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1693569976254&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from einops import repeat
# gray scale img
img = np.random.randn(30, 40)

# change to RGB
output = repeat(img, &quot;h w -&amp;gt; h w c&quot;, c=3) # (30, 40, 3)

# repaat img 2 times along height
output = repeat(img, &quot;h w -&amp;gt; (h1 h) w&quot;, h1=2) # (60, 40)

# repeat img 2 times along height, 3 times along width
output = repeat(img, &quot;h w -&amp;gt; (h1 h) (w1 w)&quot;, h1=2, w1=3) # (60, 120)

# convert each pixel to a 2*2 square (upsample)
output = repeat(img, &quot;h w -&amp;gt; (h h1) (w w1)&quot;, h1=2, w1=2) # (60, 60)

# downsampling and upsampling
output = reduce(img, &quot;(h h1) (w w1) -&amp;gt; h w&quot;, &quot;mean&quot;, h1=2, w1=2) # (15, 20)
output = repeat(output, &quot;h w -&amp;gt; (h h2) (w w2)&quot;, h2=2, w2=2) # (30, 40)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;pack(), unpack()&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 함수들은 여러 tensor를 하나의 tensor로 packing하거나 해제할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1693569986871&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from einops import pack, unpack

inputs = [np.zeros([2, 3, 5]), np.zeros([2, 3, 7, 5]), np.zeros([2, 3, 7, 9, 5])]
packed, packed_shape = pack(inputs, &quot;i j * k&quot;) # i, j, k : 순서대로 축 차원이 같은 것 -&amp;gt; i=2, j=3, k=5
packed.shape # (2, 3, 71, 5) # 세 번째 차원 축으로 packed
packed_shape # [(), (7,), (7, 9)]) # pack된 tensor 차원

inputs_unpacked = unpack(packed, packed_shape, &quot;i j * k&quot;)
original_inputs = [x.shape for x in inputs_unpacked] # original_inputs = inputs&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;parse_shape()&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 함수는 특정 shape을 다른 함수에서 활용할 수 있게 해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1693569999459&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from einops import parse_shape
# underscore : skip the dimension in parsing 
x = np.zeros([2, 3, 5, 7])
parse_shape(x, &quot;batch _ height width&quot;) # {'batch': 2, 'height': 5, 'width': 7}

# ex) used to rearrange
y = np.zeros([700])
output_tensor = rearrange(y, &quot;(b c h w) -&amp;gt; b c h w&quot;, **parse_shape(x, &quot;b _ h w&quot;)) # (2, 10, 5, 7)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;einsum()&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;einsum 함수는 tensor의 내적, 곱, 전치, 등의 연산을 (심지어 아주 복잡한 연산도) 간단하게 명시적으로 다룰 수 있는 함수이다. 사실, PyTorch, Numpy, Tensorflow 등 텐서(행렬)를 다루는 인공지능 프레임워크(라이브러리)에서 똑같이 구현되어있다(torch.einsum(), np.einsum(), tf.einsum()). Neural network에서 복잡한 텐서 연산이 자주 일어나기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;einsum은 &lt;span style=&quot;color: #ee2323;&quot;&gt;다양한 tensor 연산에 대한 notation을 통합하여 표현&lt;/span&gt;할 수 있는 Einstein summation convention을 기반으로 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 einsum은 다음과 같이 호출한다.&lt;/p&gt;
&lt;pre id=&quot;code_1694005892646&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;torch.einsum(&quot;input_labels-&amp;gt;output_labels&quot;, tensor1, tensor2, ...)
torch.einsum(&quot;ik,kj-&amp;gt;ij&quot;, A, B) # example
einops.einsum(tensor1, tensor2, ..., &quot;input_labels_with_space -&amp;gt; output_labels_with_space&quot;)
einops.einsum(A, B, &quot;i k, k j -&amp;gt; i j&quot;) # example&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;einops, numpy, tensorflow보다 개인적으로 더 자주 사용하는 PyTorch의 einsum을 기준으로 알아보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;Label이란, &lt;span style=&quot;color: #ee2323;&quot;&gt;tensor의 각 dimension&lt;/span&gt;을 나타낸다. 다른 tensor에서 같은 차원은 broadcasting(작은 행렬을 큰 행렬 shape에 맞춰주는 것) 또는 multiplication(곱)이 가능하다. 그리고&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;input에서 여러 번 등장하는 label이 output에 등장하지 않는다는 것은 해당 차원으로 summation한다&lt;/span&gt;는 의미이다. 결과 tensor의 shape은 output label로 나타낸다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;말로 설명하니 복잡한데, 쉬운 예시부터 복잡한 예시까지 살펴보자. Operation의 정의는 모두 알고 있다고 가정한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Tensor Operations with einsum()&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;trace&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \operatorname{tr}(\mathbf{A}) = \sum\limits_{i=1}^n \mathbf{A}_{ii} = \mathbf{A}_{11} + \mathbf{A}_{22} + \cdots + \mathbf{A}_{nn} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1694006799201&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;torch.einsum(&quot;ii&quot;, A)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Transpose&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{A}^T \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1694010125994&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;torch.einsum(&quot;ij-&amp;gt;ji&quot;, A)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Column-wise, row-wise summation&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{b}_j = \sum\limits_{i} \mathbf{A}_{ij} \)&lt;br /&gt;\( \mathbf{b}_i = \sum\limits_{j} \mathbf{A}_{ij} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1694010545057&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;torch.einsum(&quot;ij-&amp;gt;j&quot;, A) # column-wise sum (dim=0)
torch.einsum(&quot;ij-&amp;gt;i&quot;, A) # row-wise sum (dim=1)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Dot product&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( c = \sum\limits_{i} \sum\limits_{j} \mathbf{A}_{ij} \mathbf{B}_{ij}&amp;nbsp;\)&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1694011013163&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;c = torch.einsum(&quot;i,i-&amp;gt;&quot;, a, b) # for vectors
c = torch.einsum(&quot;ij,ij-&amp;gt;&quot;, A, B) # for matrices&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Outer product&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{C}_{ij} = \mathbf{a}_i \times \mathbf{b}_j \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1694011357895&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;C = torch.einsum(&quot;i,j-&amp;gt;ij&quot;, a, b)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Element-wise multiplication (Hadamard product)&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{C}_{ij} = \mathbf{A}_{ij} \odot \mathbf{B}_{ij} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1694011114276&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;C = torch.einsum(&quot;ij,ij-&amp;gt;ij&quot;, A, B)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Matrix-vector multiplication&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{c}_i = \mathbf{A}_{ij} \mathbf{b}_{j} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1694010693711&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;c = torch.einsum(&quot;ik,k-&amp;gt;i&quot;, A, b)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Matrix multiplication&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{C}_{ij} = \sum\limits_{k} \mathbf{A}_{ik} \mathbf{B}_{kj} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1694010771288&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;C = torch.einsum(&quot;ik,kj-&amp;gt;ij&quot;, A, B)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Batch matrix multiplication&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{C}_{ijl} = \sum\limits_{k} \mathbf{A}_{ijk} \mathbf{B}_{ikl} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1694011503407&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;C = torch.einsum(&quot;ijk,ikl-&amp;gt;ijl&quot;, A, B)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서부터는 조금 헷갈리는데, 공통 차원인 \(i\)와 \(k\) 중에서 \(k\)에 대해서만 연산을 해준다. Neural network에서의 동작을 예로 들면, \(i\)를 batch_size로 보면 된다. 즉, batch_size 축은 가만히 둔 상태에서 행렬곱 \(\mathbf{A}_{jk} \mathbf{B}_{kl}\)를 수행하는 것과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Tensor contraction&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{C}_{pstuv} = \sum\limits_{q} \sum\limits_{r} \mathbf{A}_{pqrs} \mathbf{B}_{tuqvr}&amp;nbsp;\)&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1694011718181&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;C = torch.einsum(&quot;pqrs,tuqvr-&amp;gt;pstuv&quot;, A, B)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 batch matrix multiplication보다 더 일반적인 tensor 연산이다. 차수가 다른 두 텐서 4-th order tensor \(\mathbf{A} \in \mathbb{R}^{p \times q \times r \times s}\)와 5-th order tensor \(\mathbf{B} \in \mathbb{R}^{t \times u \times q \times v \times r}\)가 있다고 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때, 두 텐서가 차원 \(q\)와 \(r\)을 공통으로 갖고 있고, 해당 차원을 따라 곱해주면 결과 matrix의 차원은 \(\mathbf{C} \in \mathbb{R}^{p \times s \times t \times u \times v}\)가 된다. output tensor는 &lt;span style=&quot;color: #ee2323;&quot;&gt;곱해줬던 차원이 사라지고, 나머지 차원을 순서대로&lt;/span&gt; 갖는다고 생각하면 쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Bilinear transformation&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{D}_{ij} = \sum\limits_{k} \sum\limits_{l} \mathbf{A}_{ik} \mathbf{B}_{jkl} \mathbf{C}_{il} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1694013634599&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;D = torch.einsum(&quot;ik,jkl,il-&amp;gt;ij&quot;, A, B, C)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세 개 이상의 tensor에 대한 연산도 쉽게 나타낼 수 있다. 먼저 \(\mathbf{A}\)와 \(\mathbf{B}\)의 공통 차원인 \(k\)가 사라지면서 남은 차원이 \(ijl\)이 되고, 그 결과 matrix와 \(\mathbf{C}\)가 공통 차원 \(l\)을 따라 곱해지면서 (\(i\)는 &lt;span style=&quot;color: #ee2323;&quot;&gt;공통 차원이지만, 곱하지는 않는다&lt;/span&gt;는 점에 주의하자! 앞에서의 batch_size와 같은 개념이다.) 결과 tensor의 차원은 \(ij\)가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Example: Attention Module&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Attention을 계산할 때, einsum을 활용하면 간단하면서도 명확하게 그 연산 과정을 알 수 있다. Multi-head attention의 이론적인 내용은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 참조하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Multi-head attention에서, query, key, value tensor가 각각 \(\mathbf{Q} \in \mathbb{R}^{b \times s_q \times n \times d}\), \(\mathbf{K} \in \mathbb{R}^{b \times s_k \times n \times d}\), \(\mathbf{V} \in \mathbb{R}^{b \times s_v \times n \times d}\)라 하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 \(b\)는 batch_size, \(s\)는 sequence length, \(n\)은 head 개수, \(d\)는 head size(dimension)를 말한다. \(d_k = d_q = d\)이므로, attention score function으로 scaled dot product를 활용할 수 있다. (표기를 간단하게 하기 위해 우선은 \(\mathbf{Q}\)와 \(\mathbf{K}\)와 \(\mathbf{V}\)를 \(d\)차원 vector로 가정한다.)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( a(\mathbf{Q}, \mathbf{K}) = \cfrac{\mathbf{Q} \mathbf{K}^\top}{\sqrt{d}} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이때, query와 \(i\)번째 key의 attention weight \(\alpha\)는 softmax를 활용하여 다음과 같이 계산한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \alpha(\mathbf{Q}, \mathbf{K}_i) = \underset{\operatorname{seq}}{\operatorname{softmax}} a(\mathbf{Q}, \mathbf{K}_i) = \cfrac{\operatorname{exp}\left(a(\mathbf{Q}, \mathbf{K}_i)\right)}{\sum\limits_{j} \operatorname{exp}\left(a(\mathbf{Q}, \mathbf{K}_j)\right)}\)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 attention module의 최종 output은 value를 weight 개념으로 간주하여 다음과 같이 계산한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( f \left( \mathbf{Q}, \{ \mathbf{K}_i, \mathbf{V}_i \}_{i=1}^m \right) = \sum\limits_{i=1}^m \alpha(\mathbf{Q}, \mathbf{K}_i) \) \mathbf{V}_i&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 batch_size, head를 고려하여 행렬로 나타내면 엄청 복잡한데, einsum을 활용하면 다음과 같이 간단 명료하게 구현할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1694015084867&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# attention score
attn = torch.einsum(&quot;bihd,bjhd-&amp;gt;bhij&quot;, q, k) * (d_head ** -0.5) # (batch_size, n_head, seq_len_query, seq_len_key)

# softmax normalization
attn = attn.softmax(dim=-1)

# weighting with values
out = torch.einsum(&quot;bhij,bjhd-&amp;gt;bihd&quot;, attn, v)

# reshape output
out = einops.rearrange(out, &quot;b s n d -&amp;gt; b s (n d)&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Terminologies
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(b\) : batch size&lt;/li&gt;
&lt;li&gt;\(i\) : sequence length of query&lt;/li&gt;
&lt;li&gt;\(j\) : sequence length of key&lt;/li&gt;
&lt;li&gt;\(h\) : number of heads&lt;/li&gt;
&lt;li&gt;\(d\) : dimension of attention (\(d_q = d_k = d_v = d\))&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Attention score \(a\) 계산 : einsum 연산 수행 과정을 직관적으로 이해해보자.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;공통 차원이면서 없어진 차원 \(d\)를 따라 연산을 수행한다.&lt;/li&gt;
&lt;li&gt;공통 차원이면서 없어지지 않은 차원을 앞으로 빼서 묶는다. ( \(\mathbf{Q}' \in \mathbb{R}^{(b \times h) \times i \times d}\), \(\mathbf{K}' \in \mathbb{R}^{(b \times h) \times j \times d}\) )&lt;/li&gt;
&lt;li&gt;묶은 차원을 batch로 생각하여 batch multiplication을 적용한다. (multiplication 하려면 \(\mathbf{K}'\)의 뒤쪽 두 차원의 순서를 바꿔주어야(transpose) 한다. 따라서 위 식에서 \( \mathbf{q} \mathbf{k}^\top\)와 같이 transpose가 들어간 것이다.&lt;/li&gt;
&lt;li&gt;결과 shape은 자연스럽게 \((b, \; h, \; i, \; j)\)가 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Softmax normalization (attention weight \(\alpha\) 계산)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마지막 dimension인 target sequence position \(j\)를 따라 softmax function을 적용하여 &lt;span style=&quot;color: #ee2323;&quot;&gt;모든 key에 대한 attention score 값의 합이 1이 되도록&lt;/span&gt; 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Value에 attention 적용 : einsum 연산 수행 과정을 직관적으로 이해해보자.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;공통 차원이면서 없어진 차원 \(j\)를 따라 연산을 수행한다.&lt;/li&gt;
&lt;li&gt;공통 차원이면서 없어지지 않은 차원을 앞으로 빼서 묶는다. (\(b \times h\))&lt;/li&gt;
&lt;li&gt;묶은 차원을 batch로 생각하여 batch multiplication을 적용한다. 이번에는 \(\alpha ' \in \mathbb{R}^{(b \times h) \times i \times j}\), \(\mathbf{V} \in \mathbb{R}^{(b \times h) \times j \times d}\)이므로 transpose 없이 연산 수행이 가능하다.&lt;/li&gt;
&lt;li&gt;연산 결과 shape이 \((b, \; h, \; i, \; d)\)인데, \(h\)와 \(i\) 차원을 transpose하여 최종 shape \((b, \; i, \; h, \; d)\)을 결정한다.&lt;/li&gt;
&lt;li&gt;attention weight의 마지막 index (key의 sequence index) \(j\)를 따라 dot product를 수행, 즉 attention weight에 value를 활용하여 weighted sum 해주는 개념이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reshape
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;(batch_size, seq_len, n_head, d_head) &amp;rarr; (batch_size, seq_len, n_head * d_head)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Research/Implementation</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/248</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Tensor%EC%9D%98-shape%EC%9D%84-%EA%B0%80%EB%8F%85%EC%84%B1%EC%9E%88%EA%B2%8C-%EB%B3%80%ED%99%98%ED%95%98%EB%8A%94-einops-%EC%82%AC%EC%9A%A9%EB%B2%95#entry248comment</comments>
      <pubDate>Fri, 1 Sep 2023 21:09:24 +0900</pubDate>
    </item>
    <item>
      <title>Score-based Generative Model 파헤치기!</title>
      <link>https://jjuke-brain.tistory.com/entry/Score-based-Generative-Model-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전까지 대표적인 생성모델인 AutoRegressive Models(ARMs), Flow-based models, Variational Auto-Encoders (VAEs), Generative Adversarial Networks(GANs)를 살펴보았다. 이번 글에서는 최근에 diffusion-based models와 함께 관심을 끌고 있는 score-based model에 대해 알아보려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 score-based model이 처음 제안된 시기는 2019년(&lt;a href=&quot;https://arxiv.org/abs/1907.05600&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Generative Modeling by Estimating Gradients of the Data Distribution&lt;/a&gt;, NeurIPS), 2021년(&lt;a href=&quot;https://arxiv.org/abs/2011.13456&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Score-based Generative Modeling through Stochastic Differential Equations&lt;/a&gt;, ICLR)으로 diffusion(2015년 &lt;a href=&quot;https://arxiv.org/abs/1503.03585&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Deep Unsupervised Learning using Nonequilibrium Thermodynamics&lt;/a&gt;, ICML, 2020년 &lt;a href=&quot;https://arxiv.org/abs/2006.11239&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Denoising Diffusion Probabilistic Models&lt;/a&gt;, NeurIPS)보다 늦지만, 개인적으로 diffusion에 가장 관심이 있기도 하고, diffusion을 이해하는 방법 중에 score-based model을 이해해야 하는 부분이 있어 먼저 다뤄보고, 마지막으로 diffusion을 다뤄볼 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고한 블로그 글은 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://yang-song.net/blog/2021/score/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://yang-song.net/blog/2021/score/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1693223267852&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Generative Modeling by Estimating Gradients of the Data Distribution | Yang Song&quot; data-og-description=&quot;Generative Modeling by Estimating Gradients of the Data Distribution This blog post focuses on a promising new direction for generative modeling. We can learn score functions (gradients of log probability density functions) on a large number of noise-pertu&quot; data-og-host=&quot;yang-song.net&quot; data-og-source-url=&quot;https://yang-song.net/blog/2021/score/&quot; data-og-url=&quot;https://yang-song.net/blog/2021/score/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bYFldq/hyTMdjq1od/fXdDDFacVmzH4409rneKbk/img.jpg?width=3370&amp;amp;height=1136&amp;amp;face=0_0_3370_1136,https://scrap.kakaocdn.net/dn/brbGsp/hyTIIFoWbt/CAvKSCuWwkrcZJsKgFKXn0/img.jpg?width=2048&amp;amp;height=1024&amp;amp;face=249_297_1769_905,https://scrap.kakaocdn.net/dn/FTJOn/hyTII6r90N/jtNGIXJYsy2g6PKZICuKW0/img.png?width=1806&amp;amp;height=562&amp;amp;face=0_0_1806_562&quot;&gt;&lt;a href=&quot;https://yang-song.net/blog/2021/score/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yang-song.net/blog/2021/score/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bYFldq/hyTMdjq1od/fXdDDFacVmzH4409rneKbk/img.jpg?width=3370&amp;amp;height=1136&amp;amp;face=0_0_3370_1136,https://scrap.kakaocdn.net/dn/brbGsp/hyTIIFoWbt/CAvKSCuWwkrcZJsKgFKXn0/img.jpg?width=2048&amp;amp;height=1024&amp;amp;face=249_297_1769_905,https://scrap.kakaocdn.net/dn/FTJOn/hyTII6r90N/jtNGIXJYsy2g6PKZICuKW0/img.png?width=1806&amp;amp;height=562&amp;amp;face=0_0_1806_562');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Generative Modeling by Estimating Gradients of the Data Distribution | Yang Song&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Generative Modeling by Estimating Gradients of the Data Distribution This blog post focuses on a promising new direction for generative modeling. We can learn score functions (gradients of log probability density functions) on a large number of noise-pertu&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yang-song.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Generative Modeling Techniques&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;686&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZB0JR/btssgqeeRJE/pT6uewzbEvUTNkltcAQkK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZB0JR/btssgqeeRJE/pT6uewzbEvUTNkltcAQkK0/img.png&quot; data-alt=&quot;Fig 1. Representative deep generative models&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZB0JR/btssgqeeRJE/pT6uewzbEvUTNkltcAQkK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZB0JR%2FbtssgqeeRJE%2FpT6uewzbEvUTNkltcAQkK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;686&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;686&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Representative deep generative models&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제까지 알아본 generative model 중, 최근까지도 자주 사용되는 모델은 Fig 1과 같다. 생성모델을 크게 나누면 likelihood를 사용하는지, 아닌지에 따라 다음과 같이 나눠볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Likelihood-based models&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;622&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LrCNm/btssuvyhBi5/LmknhC2plDDpSshIfSMUE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LrCNm/btssuvyhBi5/LmknhC2plDDpSshIfSMUE0/img.png&quot; data-alt=&quot;Fig 2. Example of likelihood-based models&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LrCNm/btssuvyhBi5/LmknhC2plDDpSshIfSMUE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLrCNm%2FbtssuvyhBi5%2FLmknhC2plDDpSshIfSMUE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;622&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;622&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Example of likelihood-based models&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Likelihood-based models는 Data의 distribution을 직접 모델링하여 학습한다. 이에는 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Autoregressive-Generative-Models&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;ARMs&lt;/a&gt;(AutoRegressive Models), &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Flow-based-Models-Normalizing-Flow&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Normalizing flows&lt;/a&gt;(Flow-based models), EBMs(Energy-Based Models), 그리고 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;VAEs&lt;/a&gt;(Variational AutoEncoders)가 포함된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 생성모델의 한계점은 엄격한 restriction이 필요하거나, likelihood를 근사하기 위한 objective에 의존적이라는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Implicit models&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;833&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dHXyPT/btssxHLt8j3/kDtA5197CkaUfEds5NaZ11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dHXyPT/btssxHLt8j3/kDtA5197CkaUfEds5NaZ11/img.png&quot; data-alt=&quot;Fig 3. Example of implicit models&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dHXyPT/btssxHLt8j3/kDtA5197CkaUfEds5NaZ11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdHXyPT%2FbtssxHLt8j3%2FkDtA5197CkaUfEds5NaZ11%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;833&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;833&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Example of implicit models&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Implicit models는 모델이 샘플링 과정에서 data의 probability distribution을 implicit하게 표현한다. 이에는 GANs (Generative Adversarial Networks)가 대표적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 모델은 Adversarial training으로 인해 학습이 불안정하고, mode collapse 문제가 발생하기 쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Score-based models&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1950&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxRFXQ/btssv0xQLjS/y5NtBJazfC4aEUwT6GWgh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxRFXQ/btssv0xQLjS/y5NtBJazfC4aEUwT6GWgh0/img.png&quot; data-alt=&quot;Fig 4. Score function (vector field) and density funciton (contours) of a mixture of two Gaussians&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxRFXQ/btssv0xQLjS/y5NtBJazfC4aEUwT6GWgh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxRFXQ%2Fbtssv0xQLjS%2Fy5NtBJazfC4aEUwT6GWgh0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;382&quot; height=&quot;372&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1950&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. Score function (vector field) and density funciton (contours) of a mixture of two Gaussians&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 두 유형과 달리, 이번 글에서 다룰 score-based model은 &lt;span style=&quot;color: #ee2323;&quot;&gt;score function을 modeling 및 estimating&lt;/span&gt;하면서 여러 generative task에 적용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Likelihood 기반 모델과 달리 계산 가능한 normalizing constant가 필요 없으며, adversarial loss에 비해 안정적인 score matching이라는 방법으로 학습한다. 또한, Normalizing flow model과 연관이 있어 정확한 likelihood 계산과 representation learning이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Score Function, Score-based Models, and Score Matching&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주어진 데이터셋 \(\left\{ \mathbf{x}_1, \mathbf{x}_2, \dots, \mathbf{x}_N \right\}\)에 대한 data distribution이 \(p(\mathbf{x})\)라고 가정하면, generative modeling은 모델의 distribution을 \(p(\mathbf{x})\)에 맞추어 새로운 data point를 샘플링하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 probability density function (pdf)는 다음과 같이 정의한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p_\theta(\mathbf{x}) = \cfrac{e^{- f_\theta(\mathbf{x})}}{Z_\theta} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Unnormalized probabilistic model(energy-based model) \(f_\theta(\mathbf{x}) \in \mathbb{R}\) : Learnable parameter \(\theta\)로 parameterize한 함수&lt;/li&gt;
&lt;li&gt;\(Z_\theta &amp;gt; 0\) : \(\theta\)에 의존하는 Normalizing constant&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이러한 모델은 maximum log-likelihood로 학습한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \underset{\theta}{\max} \sum\limits_{i=1}^N \log p_\theta (\mathbf{x}_i) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때, pdf curve 아래 면적의 합은 항상 1\(\int p_\theta(\mathbf{x}) \, d \mathbf{x} = 1\))이어야 하므로, \(p_\theta(\mathbf{x})\)가 normalized pdf여야 하는데, 일반적인 \(f_\theta(\mathbf{x})\)에 대해 normalizing constant \(Z_\theta\)는 계산이 불가능하다. Likelihood-based model에서는 \(Z_\theta\)를 계산 가능하게 만들기 위해 모델 아키텍쳐를 제한하거나(&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Autoregressive-Generative-Models&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;ARM&lt;/a&gt;에서의 causal convolution, &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Flow-based-Models-Normalizing-Flow&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Normalizing flow&lt;/a&gt;에서의 invertible network), \(Z_\theta\)를 근사(&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;VAE&lt;/a&gt;에서의 variational inference)한다. 이 과정에서 계산량이 많아진다. (자세한 과정은 각 링크를 참조하자.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Score-based model&lt;/span&gt; \(s_\theta(\mathbf{x})\)에서는 density function 대신 probability distribution \(p(\mathbf{x})\)의 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;score function&lt;/span&gt;을 정의한다. (log pdf의 gradient 개념)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \nabla_\mathbf{x} \log p(\mathbf{x}) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 모델의 objective는 \(s_\theta(\mathbf{x}) \approx \nabla_\mathbf{x} \log p(\mathbf{x})\), 즉 &lt;span style=&quot;color: #ee2323;&quot;&gt;모델이 data distribution의 (log의) gradient를 예측하는 것&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PDF를 정의할 때 등장했던 energy-based model \(f_\theta(\mathbf{x})\)로 score-based model을 parameterize할 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( s_\theta(\mathbf{x}) = \nabla_\mathbf{x} \log p_\theta(\mathbf{x}) = -\nabla_\mathbf{x} f_\theta(\mathbf{x}) - \cancel{\nabla_\mathbf{x} \log Z_\theta} = - \nabla_\mathbf{x} f_\theta(\mathbf{x}) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정에서 constant가 미분 과정에서 소거되므로, VAE 등에서 계산이 불가능했던 원흉인 &lt;span style=&quot;color: #ee2323;&quot;&gt;normalizing constant \(Z_\theta\)를 고려할 필요가 없다&lt;/span&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Score-based model을 학습할 때에는&amp;nbsp;model과 data distribution 사이의 &lt;span style=&quot;color: #ee2323;&quot;&gt;Fisher divergence&lt;/span&gt;를 활용한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbb{E}_{p(\mathbf{x})} \left[ \lVert \nabla_\mathbf{x} \log p(\mathbf{x}) - s_\theta(\mathbf{x}) \rVert_2^2 \right] \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fisher divergence는 GT data score와 score-based model의 예측 값 간의 L2 거리 개념이다. \(s_\theta(\mathbf{x})\)의 형태가 자유로우므로, 모델링이 flexible하다는 장점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Data score \(\nabla_\mathbf{x} \log p(\mathbf{x})\)를 모르므로 직접 계산을 할 수는 없으나, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;score matching&lt;/span&gt;이라는 방법으로 GT data score를 몰라도 위 식을 최소화할 수 있도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Score matching object는 dataset 기반으로 추정이 가능하며 stochastic graident descent로 최적화할 수 있다. 이는 normalizing constant를 알고 있는 상태에서의 log-likelihood based model들의 objective와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;!-- Heading 1 --&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Langevin Dynamics&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;!-- Content --&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Langevin Dynamics&lt;/span&gt;는 Fig 5와 같이 학습된 score-based model \(s_\theta(\mathbf{x}) \approx \nabla_\mathbf{x} \log p(\mathbf{x})\)를 활용하여 &lt;span style=&quot;color: #ee2323;&quot;&gt;샘플링&lt;/span&gt;하는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;langevin.gif&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DZvvj/btssqyhBMVp/zzaAhxifaBosG4RZ5yfNIk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DZvvj/btssqyhBMVp/zzaAhxifaBosG4RZ5yfNIk/img.gif&quot; data-alt=&quot;Fig 5. Using Langevin dynamics to sample from a mixture of two Gaussians&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DZvvj/btssqyhBMVp/zzaAhxifaBosG4RZ5yfNIk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/DZvvj/btssqyhBMVp/zzaAhxifaBosG4RZ5yfNIk/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;331&quot; height=&quot;331&quot; data-filename=&quot;langevin.gif&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. Using Langevin dynamics to sample from a mixture of two Gaussians&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법은 iterative하게 작동하며, Markov Chain Monte Carlo (MCMC) procedure를 사용한다.&lt;/p&gt;
&lt;!-- Equation --&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{x}_{i+1} \leftarrow \mathbf{x}_i + \epsilon \nabla_\mathbf{x} \log p(\mathbf{x}) + \sqrt{2 \epsilon} \mathbf{z}_i, \quad i = , 1, \cdots, K \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;!-- Content --&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Initialization \(\mathbf{x}_0 \sim \pi(\mathbf{x})\) : 임이의 prior distribution에서 샘플링&lt;/li&gt;
&lt;li&gt;\( \mathbf{z}_i \sim \mathcal{N}(\boldsymbol{0}, \mathbf{I})\)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정에서 Regularization을 적용하면, 과정이 반복될수록(\(\epsilon \rightarrow 0, \; K \rightarrow \infty\)) \(\mathbf{x}_K\)는 \(p(\mathbf{x})\)의 샘플에 수렴한다. 이를 통해 학습된 \(s_\theta(\mathbf{x})\)를 식에 대입하고 반복하여 샘플링을 수행한다.&lt;/p&gt;
&lt;!-- Heading 1 --&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Score-based Generative Modeling&lt;/b&gt;&lt;/h2&gt;
&lt;!-- Heading 2 --&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Naive (Unconditional) Score-based Generative Modeling&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;!-- Content --&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;777&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FCwiA/btssimPKYEs/Dl2rvZkQnC1eWcic1PYprk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FCwiA/btssimPKYEs/Dl2rvZkQnC1eWcic1PYprk/img.png&quot; data-alt=&quot;Fig 6. Learning and sampling of naive score-based model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FCwiA/btssimPKYEs/Dl2rvZkQnC1eWcic1PYprk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFCwiA%2FbtssimPKYEs%2FDl2rvZkQnC1eWcic1PYprk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;777&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;777&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 6. Learning and sampling of naive score-based model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 모델은 Fig 6과 같이 score matching으로 학습을, Langevin dynamics를 활용하여 샘플링을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 한계점이 있는데, low density 지역(data point가 많이 없는 지역)에서 추정한 score function이 부정확하다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;674&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEv9ex/btssihndlYN/3NRRCKHhxFKIQcbLAlAf71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEv9ex/btssihndlYN/3NRRCKHhxFKIQcbLAlAf71/img.png&quot; data-alt=&quot;Fig 7. Estimated scores for a mixture of two Gaussians&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEv9ex/btssihndlYN/3NRRCKHhxFKIQcbLAlAf71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEv9ex%2FbtssihndlYN%2F3NRRCKHhxFKIQcbLAlAf71%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;674&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;674&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 7. Estimated scores for a mixture of two Gaussians&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Objective를 보면 그 이유를 알 수 있다.&lt;/p&gt;
&lt;!-- Equation --&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbb{E}_{p(\mathbf{x})} \left[ \lVert \nabla_\mathbf{x} \log p(\mathbf{x}) - s_\theta(\mathbf{x}) \rVert_2^2 \right] = \int p(\mathbf{x}) \lVert \nabla_\mathbf{x} \log p(\mathbf{x}) - s_\theta(\mathbf{x}) \rVert_2^2 \, d \mathbf{x} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우변을 보면, L2 difference에 \(p(\mathbf{x})\)를 weighting하는 개념으로, data point 자체가 적을 경우 \(p(\mathbf{x})\)가 작으므로 값이 무시된다. 그리고 Langevin dynamics로 샘플링할 때 또한 첫 샘플링은 low density 지역에서 하는 경우가 많을텐데, score가 부정확하면 당연히 생성한 데이터의 quality가 매우 낮을 것이다.&lt;/p&gt;
&lt;!-- Content --&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제를 해결하기 위해 Noise perturbation을 사용한다.&lt;/p&gt;
&lt;!-- Heading 2 --&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Score-based Generative Modeling with Multiple Noise Perturbations&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;!-- Content --&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Noise perturbation&lt;/span&gt;이란, &lt;span style=&quot;color: #ee2323;&quot;&gt;data point에 perturbation을 적용한 후 score-based model을 학습&lt;/span&gt;하는 방법이다. 이 방법을 사용한 score-based model을 noise conditional score-based model \(s_\theta(\mathbf{x}, i)\)이라 한다. NCSN(Noise Conditional Score Network)으로 parameterize하며, score function은 \(\nabla_&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;\mathbf{x} \log p_{\sigma_i} (&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;\mathbf{x})\)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;673&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZRVSP/btssvYNzl4P/Qip3ORWFivV2DxX7wCV5Y0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZRVSP/btssvYNzl4P/Qip3ORWFivV2DxX7wCV5Y0/img.png&quot; data-alt=&quot;Fig 8. Estimated scores for a mixture of two Gaussians perturbed by additional Gaussian noise&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZRVSP/btssvYNzl4P/Qip3ORWFivV2DxX7wCV5Y0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZRVSP%2FbtssvYNzl4P%2FQip3ORWFivV2DxX7wCV5Y0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;673&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;673&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 8. Estimated scores for a mixture of two Gaussians perturbed by additional Gaussian noise&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 8에서와 같이, perturbation을 적용하면 data point의 분포가 더 퍼지게 되어 기존의 문제를 해결할 수 있게 된다. 하지만, perturbation을 얼마나 줄 것인가(noise의 scale)가 문제인데, 여러 scale의 noise를 동시에 적용하는 Multiple noise perturbation을 사용한다. (\(\sigma_1 &amp;lt; \sigma_2 &amp;lt; \cdots &amp;lt; \sigma_L\))&lt;/p&gt;
&lt;!-- Equation --&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p_{\sigma_i}(\mathbf{x}) = \int p(\mathbf{y}) \mathcal{N}(\mathbf{x} ; \mathbf{y}, \sigma_i^2 \mathbf{I}) \, d \mathbf{y} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Multiple Gaussian noise \(\mathcal{N}(\boldsymbol{0}, \sigma_i^2 \mathbb{I}), \; i = 1, 2, \cdots, L\)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;샘플링 할 때는 \(p(\mathbf{x})\)에서 data point \(\mathbf{x}\)를 샘플링한 후, \(\mathbf{x} + \sigma_i \mathbf{z}\)를 계산한다. 이때 \(\mathbf{z}\)는 standard Gaussian \(\mathcal{N}(\boldsymbol{0}, \mathbf{I})\)에서 샘플링한 값이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Score matching (Training) of noise conditional score-based model&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 모델의 training objective는 모든 noise\(\sigma_1, \sigma_2, \dots, \sigma_L\)에 대해 Fisher divergence의 weighted sum을 최소화하는 것이다.&lt;/p&gt;
&lt;!-- Equation --&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \sum\limits_{i=1}^L \lambda(i) \mathbb{E}_{p_{\sigma_i}(\mathbf{x})} \left[ \lVert \nabla_\mathbf{x} \log p_{\sigma_i}(\mathbf{x}) - s_\theta(\mathbf{x}, i) \rVert_2^2 \right] \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;!-- Heading 3 --&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\lambda(i) \in \mathbb{R}_{&amp;gt;0}\) : (positive) weighting function으로, 보통 \(\lambda(i) = \sigma_i^2\)로 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMfIJ9/btsslaO4xOJ/7CsPccT5DN0yAQ1MyHCfYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMfIJ9/btsslaO4xOJ/7CsPccT5DN0yAQ1MyHCfYk/img.png&quot; data-alt=&quot;Fig 9. Multiple scales of Gaussian noise (top) and jointly estimated score functions (bottom)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMfIJ9/btsslaO4xOJ/7CsPccT5DN0yAQ1MyHCfYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMfIJ9%2FbtsslaO4xOJ%2F7CsPccT5DN0yAQ1MyHCfYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;685&quot; height=&quot;418&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1220&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 9. Multiple scales of Gaussian noise (top) and jointly estimated score functions (bottom)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Annealed Langevin dynamics (Sampling) of noise conditional score-based model&lt;/b&gt;&lt;/h4&gt;
&lt;!-- Content --&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;샘플링 할 때에는 noise-conditional score-based model \(s_\theta(\mathbf{x}, i)\)를 활용하여 Langevin dynamics를 \(i = L, L-1, \cdots, 1\) 순서로 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;celeba_large.gif&quot; data-origin-width=&quot;342&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUedIU/btsswgOaJzK/ej84WVD4kKsVczSpBX0YG1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUedIU/btsswgOaJzK/ej84WVD4kKsVczSpBX0YG1/img.gif&quot; data-alt=&quot;Fig 10. Annealed Langevin dynamics (sampling)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUedIU/btsswgOaJzK/ej84WVD4kKsVczSpBX0YG1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/cUedIU/btsswgOaJzK/ej84WVD4kKsVczSpBX0YG1/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;342&quot; height=&quot;342&quot; data-filename=&quot;celeba_large.gif&quot; data-origin-width=&quot;342&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 10. Annealed Langevin dynamics (sampling)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 10과 같이, 샘플링을 진행할수록 점점 noise가 사라진다. (이는 diffusion에서 time step에 따라 denoising되는 것과 비슷하다!)&lt;/p&gt;
&lt;!-- Heading 3 --&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;NCSN Implementation&lt;/b&gt;&lt;/h4&gt;
&lt;!-- Content --&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\sigma_i\)를 geometric progression(자세한 내용은 &lt;a href=&quot;https://en.wikipedia.org/wiki/Geometric_progression&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 참조하자.)방법으로 정한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\sigma_1\)은 충분히 작게, \(\sigma_L\)은 모든 training data points 중에 가장 거리가 먼 두 data point 정도로 정한다.&lt;/li&gt;
&lt;li&gt;\(L\)은 몇 백 ~ 몇 천 정도로 정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Score-based model \(s_\theta(\mathbf{x}, i)\)는 U-Net 아키텍쳐를 사용하여 구현한다.&lt;/li&gt;
&lt;li&gt;Test 시 model의 weight에 exponential moving average를 적용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- Heading 1 --&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Score-based generative modeling with Stochastic Differential Equations (SDEs)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;!-- Content --&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Multiple noise를 일반화하여 scale 개수를 무한히 늘린다. 이러한 모델을 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;time-dependent score-based model&lt;/span&gt; \(s_\theta(\mathbf{x}, t)\)라 한다. 이때 학습 과정과 샘플링 과정을 모델링하기 위해 &lt;span style=&quot;color: #ee2323;&quot;&gt;stochastic differential equation(SDE)&lt;/span&gt;을 활용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 샘플 퀄리티를 높이고, 정확한 log-likelihood를 계산할 수 있으며, controllable generation이 가능하다. 이는 diffusion의 forward process 및 reverse process와 같은 개념이 된다. Diffusion 내용은다음 글에서 따로 다룰 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Perturbing data with an SDE (Training)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;perturb_vp.gif&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;261&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBBGuh/btssvZTfUst/35fm1yKB4RPewLGeFGsurK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBBGuh/btssvZTfUst/35fm1yKB4RPewLGeFGsurK/img.gif&quot; data-alt=&quot;Fig 11. Perturbing data&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBBGuh/btssvZTfUst/35fm1yKB4RPewLGeFGsurK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bBBGuh/btssvZTfUst/35fm1yKB4RPewLGeFGsurK/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;737&quot; height=&quot;261&quot; data-filename=&quot;perturb_vp.gif&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;261&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 11. Perturbing data&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Data에 무수히 많은 noise를 가하는 과정을 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;SDE process&lt;/span&gt;라 하고, SDE의 해를 구하는 과정이다. 이는 Fig 11과 같이 diffusion process를 연상시킨다.&lt;/p&gt;
&lt;!-- Equation --&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( d \mathbf{x} = f(\mathbf{x}, t) d t + g(t) d \mathbf{w} \)&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(f(\cdot, t) : \mathbb{R}^d \rightarrow \mathbb{R}^d\) : Drift coefficient (벡터함수)&lt;/li&gt;
&lt;li&gt;\(g(t) \in \mathbb{R}\) : Diffusion coefficient (실수함수)&lt;/li&gt;
&lt;li&gt;\(\mathbf{w}\) : Standard Brownian motion (\(d \mathbf{w}\) : noise의 극소(infinitesimal)량)&lt;/li&gt;
&lt;li&gt;해 : Random variables의 continuous collection \(\{\mathbf{x}(t)\}_{t \in [0, T]}\)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Random variable \(\mathbf{x}(t)\)는 사진에 보이는 경로의 점을 의미한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SDE는 다양하게 설정할 수 있다. 예를 들어, \(d \mathbf{x} = e^t d \mathbf{w}\)로 설정할 경우, 평균(\(f\))이 0이고, exponential하게 증가하는 variance(\(g\)) 사용하는 것을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Training objective는 다음과 같이 Fisher divergence에 time step \(t\)에 관한 항이 추가된다.&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbb{E}_{t \in \mathcal{U}(0, T)} \mathbb{E}_{p_t(\mathbf{x})} \left[ \lambda(t) \lVert \nabla_\mathbf{x} \log p_t(\mathbf{x}) - s_\theta(\mathbf{x}, t) \rVert_2^2 \right] \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\mathcal{U}(0, T)\) : Time interval \([0, T]\)에 대한 uniform distribution&lt;/li&gt;
&lt;li&gt;\(\lambda : \mathbb{R} \rightarrow \mathbb{R}{&amp;gt;0}\) : Positive weighting function
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;보통 \(\lambda(t) \propto 1/ \mathbb{E} \left[ \lVert \nabla{\mathbf{x}(t)} \log p(\mathbf{x}(t) \vert \mathbf{x}(0)) \rVert_2^2 \right]\) 으로 설정하며, time step에 따라 달라지는 score matching loss의 balance를 맞춰준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(\lambda(t) = g^2(t)\)일 때 \(\lambda\)를 likelihood weighting function이라 하고, regularity condition을 추가하면 objective는 \(p_0\)와 \(p_\theta\) 사이의 KL divergence 개념과 연결된다. 즉, KL divergence를 minimize하는 게 곧 likelihood를 maximize하는 것(likelihood-based model을 학습하는 것)과 같은 개념이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \begin{align*} &amp;amp; D_\text{KL} \left( p_0(\mathbf{x}) \Vert p_\theta(\mathbf{x}) \right) \leq \\ &amp;amp; \cfrac{T}{2} \mathbb{E}_{t \in \mathcal{U}(0, T)} \mathbb{E}_{p_t(\mathbf{x})} \left[ \lambda(t) \lVert \nabla_\mathbf{x} \log p_t(\mathbf{x}) - s_\theta(\mathbf{x}, t) \rVert_2^2 \right] + D_\text{KL} \left( p_T \Vert \pi \right) \end{align*} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 알아본 noise scale 개수가 유한할 때와 비교해보자면, \(t\)는 Noise scale 개수가 유한할 때의 \(i\)와, \(p_t(\mathbf{x})\)는 \(p_{\sigma_i}(\mathbf{x})\)와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(t=0\)일 때는 \(p_0(\mathbf{x}) = p(\mathbf{x})\)로, perturbation이 적용되지 않은 (original) data distribution이며, \(t=T\)일 때에는 terminal distribution \(p_T(\mathbf{x}) = \pi(\mathbf{x})\)으로, 계산 가능한 noise distribution (prior distribution)을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Reversing the SDE for sample generation&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;!-- Content --&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;denoise_vp.gif&quot; data-origin-width=&quot;738&quot; data-origin-height=&quot;260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/epUE90/btsshtPaFuO/92Sp81vSRZfOohsVyzpask/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/epUE90/btsshtPaFuO/92Sp81vSRZfOohsVyzpask/img.gif&quot; data-alt=&quot;Fig 12. Denoising data&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/epUE90/btsshtPaFuO/92Sp81vSRZfOohsVyzpask/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/epUE90/btsshtPaFuO/92Sp81vSRZfOohsVyzpask/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;738&quot; height=&quot;260&quot; data-filename=&quot;denoise_vp.gif&quot; data-origin-width=&quot;738&quot; data-origin-height=&quot;260&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 12. Denoising data&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;샘플링 과정은 Fig 12에서 보는 바와 같이, diffusion 모델의 reverse process와 같다. SDE도 time step \(t\)의 역순으로 푼다.&lt;/p&gt;
&lt;!-- Equation --&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( d \mathbf{x} = \left[ f(\mathbf{x}, t) - g^2(t) \nabla_\mathbf{x} \log p_t(\mathbf{x}) \right] dt + g(t) d \mathbf{w} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(dt\) : Negative infinitesimal time step&lt;/li&gt;
&lt;li&gt;\(\nabla_\mathbf{x} \log p_t(\mathbf{x})\) : \(p_t(\mathbf{x})\)의 score function&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학습된 score-based model \(s_\theta(\mathbf{x}, t) \approx \nabla_\mathbf{x} \log p_t(\mathbf{x})\)를 위 reverse SDE 식에 대입하여 샘플링을 진행한다. \(\mathbf{x}(T) \sim \pi\)에서 시작하여 \(\mathbf{x}(0)\)까지 계산할 수 있다. Reverse SDE를 푸는 자세한 과정은 &lt;a href=&quot;https://yang-song.net/blog/2021/score/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 참조하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Score-based model \(s_\theta(\mathbf{x}, t)\)이 잘 학습되었다면 \(p_\theta \approx p_0\)을 만족한다. 즉, data distribution \(p_0\)에서의 샘플과 계산을 통해 얻은 \(\mathbf{x}(0)\)이 유사하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Forward SDE, reverse SDE 전체 과정은 다음과 같이 그림으로 나타낼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1313&quot; data-origin-height=&quot;437&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHdpZ9/btsshqEICz7/nJphOzrhcvAvFqfKzrMKSK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHdpZ9/btsshqEICz7/nJphOzrhcvAvFqfKzrMKSK/img.jpg&quot; data-alt=&quot;Fig 13. Forward SDE, reverse SDE&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHdpZ9/btsshqEICz7/nJphOzrhcvAvFqfKzrMKSK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHdpZ9%2FbtsshqEICz7%2FnJphOzrhcvAvFqfKzrMKSK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1313&quot; height=&quot;437&quot; data-origin-width=&quot;1313&quot; data-origin-height=&quot;437&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 13. Forward SDE, reverse SDE&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;!-- Content --&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 13에서 흰색 선은 ODE(ordinary differential equation, 상미분방정식 )를 활용해서, 즉 forward process와 reverse process를 deterministic하게 모델링한 경우이다. Continuous한 normalizing flow로 해석해볼 수 있는데, 여기서는 자세히 다루지 않겠다. 더 자세한 내용은 &lt;a href=&quot;https://yang-song.net/blog/2021/score/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 참조하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Generative Models</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/246</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Score-based-Generative-Model-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0#entry246comment</comments>
      <pubDate>Tue, 29 Aug 2023 00:44:55 +0900</pubDate>
    </item>
    <item>
      <title>Generative Adversarial Networks (GANs) 파헤치기!</title>
      <link>https://jjuke-brain.tistory.com/entry/Generative-Adversarial-Networks-GANs-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;앞서 대표적인 심층 생성 모델인 AutoRegressive Models (ARMs), Flow-based Models와 Latent variable models 중 VAE까지 살펴보았다. 최근 내가 연구하고 있는 주제에서는 VAE, Diffusion, GAN 기반의 모델이 활발하게 이용된다. 특히 diffusion의 우수한 성능은 따로 설명이 필요 없을 정도로 유명하고(실제로 세계적인 학회에 가면 과장 조금 보태서 30~40% 정도는 diffusion 관련 논문이 쏟아지고 있다.), VAE와 GAN을 기반으로 하는 다양한 우수한 성능을 보이는 모델이 나오고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;이번 포스팅에서는 GAN을 수식과 함께 깊이있게 다뤄보려 한다. 내용은 이전 글과 마찬가지로 대부분 '&lt;a href=&quot;https://link.springer.com/book/10.1007/978-3-030-93158-2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Deep Generative Modeling&lt;/a&gt;' 책을 참고하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;Latent variable model 중 하나인 VAE는 이전에 아래 글에서 다루었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1693129801168&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Variational Auto-Encoder (VAE) 파헤치기! (1)&quot; data-og-description=&quot;목차 앞서 대표적인 심층 생성 모델인 AutoRegressive Models (ARMs), Flow-based Models 두 가지를 살펴보았다. 하지만, (적어도 내가 연구하고 있는 분야에서는) 최근에는 VAE, Diffusion, GAN 기반의 모델이 활발&quot; data-og-host=&quot;jjuke-brain.tistory.com&quot; data-og-source-url=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1&quot; data-og-url=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fecRK/hyTIMAM7KG/scGZurvV8TLOQajpcFjd21/img.png?width=800&amp;amp;height=355&amp;amp;face=0_0_800_355,https://scrap.kakaocdn.net/dn/6XJbR/hyTL4T4uxH/KK1Y6trMsAxkCmZKiQiiH0/img.png?width=800&amp;amp;height=355&amp;amp;face=0_0_800_355,https://scrap.kakaocdn.net/dn/ZWEfK/hyTIDw4EGc/ntPYQNUGWp2NcUYmPwNCck/img.png?width=2000&amp;amp;height=889&amp;amp;face=0_0_2000_889&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fecRK/hyTIMAM7KG/scGZurvV8TLOQajpcFjd21/img.png?width=800&amp;amp;height=355&amp;amp;face=0_0_800_355,https://scrap.kakaocdn.net/dn/6XJbR/hyTL4T4uxH/KK1Y6trMsAxkCmZKiQiiH0/img.png?width=800&amp;amp;height=355&amp;amp;face=0_0_800_355,https://scrap.kakaocdn.net/dn/ZWEfK/hyTIDw4EGc/ntPYQNUGWp2NcUYmPwNCck/img.png?width=2000&amp;amp;height=889&amp;amp;face=0_0_2000_889');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Variational Auto-Encoder (VAE) 파헤치기! (1)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;목차 앞서 대표적인 심층 생성 모델인 AutoRegressive Models (ARMs), Flow-based Models 두 가지를 살펴보았다. 하지만, (적어도 내가 연구하고 있는 분야에서는) 최근에는 VAE, Diffusion, GAN 기반의 모델이 활발&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jjuke-brain.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-2&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1693129780770&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Variational Auto-Encoder (VAE) 파헤치기! (2)&quot; data-og-description=&quot;목차 앞서 대표적인 심층 생성 모델인 AutoRegressive Models (ARMs), Flow-based Models 두 가지를 살펴보았다. 하지만, (적어도 내가 연구하고 있는 분야에서는) 최근에는 VAE, Diffusion, GAN 기반의 모델이 활발&quot; data-og-host=&quot;jjuke-brain.tistory.com&quot; data-og-source-url=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-2&quot; data-og-url=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fFDA2/hyTL7wvcKO/o7NZAEc9Wh5qelg8AId3XK/img.png?width=800&amp;amp;height=571&amp;amp;face=0_0_800_571,https://scrap.kakaocdn.net/dn/1xSEd/hyTIMOiNv7/eOwkIPhDwn3p0cAqpk1zck/img.png?width=800&amp;amp;height=571&amp;amp;face=0_0_800_571,https://scrap.kakaocdn.net/dn/eQ6Pw/hyTMdwHxbo/RcFZn55ipvJq79MZpU9VV0/img.png?width=2000&amp;amp;height=1429&amp;amp;face=0_0_2000_1429&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-2&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fFDA2/hyTL7wvcKO/o7NZAEc9Wh5qelg8AId3XK/img.png?width=800&amp;amp;height=571&amp;amp;face=0_0_800_571,https://scrap.kakaocdn.net/dn/1xSEd/hyTIMOiNv7/eOwkIPhDwn3p0cAqpk1zck/img.png?width=800&amp;amp;height=571&amp;amp;face=0_0_800_571,https://scrap.kakaocdn.net/dn/eQ6Pw/hyTMdwHxbo/RcFZn55ipvJq79MZpU9VV0/img.png?width=2000&amp;amp;height=1429&amp;amp;face=0_0_2000_1429');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Variational Auto-Encoder (VAE) 파헤치기! (2)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;목차 앞서 대표적인 심층 생성 모델인 AutoRegressive Models (ARMs), Flow-based Models 두 가지를 살펴보았다. 하지만, (적어도 내가 연구하고 있는 분야에서는) 최근에는 VAE, Diffusion, GAN 기반의 모델이 활발&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jjuke-brain.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, &lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;deep generative models의 분류 그림과 비교 표를 한 번 살펴보고 넘어가자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1425&quot; data-origin-height=&quot;632&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rkJb1/btsslam6HeR/oSSMaE5NPpd3QrWqsKNEW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rkJb1/btsslam6HeR/oSSMaE5NPpd3QrWqsKNEW1/img.png&quot; data-alt=&quot;Fig 1. Taxonomy of deep generative models&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rkJb1/btsslam6HeR/oSSMaE5NPpd3QrWqsKNEW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrkJb1%2Fbtsslam6HeR%2FoSSMaE5NPpd3QrWqsKNEW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;564&quot; height=&quot;250&quot; data-origin-width=&quot;1425&quot; data-origin-height=&quot;632&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Taxonomy of deep generative models&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1620&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MmBH1/btssgDKmRAN/EsN8GJJD0Odv1HbgxQ9rJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MmBH1/btssgDKmRAN/EsN8GJJD0Odv1HbgxQ9rJk/img.png&quot; data-alt=&quot;Fig 2. Comparation of deep generative models&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MmBH1/btssgDKmRAN/EsN8GJJD0Odv1HbgxQ9rJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMmBH1%2FbtssgDKmRAN%2FEsN8GJJD0Odv1HbgxQ9rJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;815&quot; height=&quot;181&quot; data-origin-width=&quot;1620&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Comparation of deep generative models&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 포스팅에서 다룰 GAN은 이전에 다룬 VAE와 latent variable model이라는 점에서 같고, 데이터, latent variable 등과 관련된 distribution을 사전에 formulate해주지 않고 implicit하게 모델링한다는 점에서 차이가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Latent Variable Models (Recap VAEs)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 latent variable model, 특히 Variational Autoencoders (VAEs)를 간단하게 다시 살펴보자. VAE의 Generative process는 아래와 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Latent sampling \( \mathbf{z} \sim p(\mathbf{z}) \)&lt;/li&gt;
&lt;li&gt;Latent로부터 새로운 observable(새로운 data point) 생성 \( \mathbf{x} \sim p_\theta(\mathbf{x} \vert \mathbf{z}) \)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Training objective는 Marginal log-likelihood function을 최대화하는 것이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \log p_\theta(\mathbf{x}) = \log \int p_\theta (\mathbf{x} \vert \mathbf{z}) p(\mathbf{z}) \, d \mathbf{z} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 문제가 하나 있는데, marginalize 과정에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;관측되지 않은 random variable을 제거&lt;/span&gt;한다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 식의 Integral은 정확한 계산이 불가능하므로, prior \(p(\mathbf{z})\)로부터 &lt;span style=&quot;color: #ee2323;&quot;&gt;Monte Carlo sampling을 통해 근사&lt;/span&gt;한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \begin{align*} \log p_\theta(\mathbf{x}) &amp;amp;= \log \int p_\theta (\mathbf{x} \vert \mathbf{z}) p(\mathbf{z}) \, d \mathbf{z} \\ &amp;amp; \approx \log \cfrac{1}{S} \sum\limits_{s=1}^S p_\theta (\mathbf{x} \vert \mathbf{z}_S) \\ &amp;amp;= \log \sum\limits_{s=1}^S \operatorname{exp}( \log p_\theta(\mathbf{x} \vert \mathbf{z}_S)) - \log S \\ &amp;amp;= \operatorname{LogSumExp}_S \{ p_\theta(\mathbf{x} \vert \mathbf{z}_S) \} - \log S \end{align*} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 Log-sum-exp function \( \operatorname{LogSumExp}_S \{ f(s) \} = \log \sum_{s=1}^S \operatorname{exp}(f(s)) \)은 미분이 가능(differentiable)한 함수이다. 그리고 보통 prior는 간단한 distribution(standard Gaussian distribution)으로 가정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Density Networks&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;366&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HAVo3/btssk1wUF1j/nvnsq9JQ9ufkbURSgDPZz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HAVo3/btssk1wUF1j/nvnsq9JQ9ufkbURSgDPZz1/img.png&quot; data-alt=&quot;Fig 3. Density networks&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HAVo3/btssk1wUF1j/nvnsq9JQ9ufkbURSgDPZz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHAVo3%2Fbtssk1wUF1j%2Fnvnsq9JQ9ufkbURSgDPZz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;748&quot; height=&quot;214&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;366&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Density networks&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 Fig 3과 같이 noise distribution \( \mathcal{N}(\boldsymbol{0}, \mathbf{I})\)에서 샘플링한 latent \(\mathbf{z}\)를 neural network에 입력하여 distribution(예를 들면 Gaussian distribution의 mean과 variance)을 decoding하는 network를 density network로 통칭한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 소개한 대로, prior distribution \(p(\mathbf{z})\)를 standard Gaussian \( \mathcal{N}(\boldsymbol{0}, \mathbf{I}) \)으로 가정했으므로, conditional likelihood \(p_\theta(\mathbf{x} \vert \mathbf{z})\)만 모델링하면 된다. 즉, 미리 모든 distribution을 수학적으로 표현(formulate)해야 한다. 이러한 deep generative model을 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;prescribed model&lt;/span&gt;이라 하며, VAE가 가장 대표적인 prescribed model이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 접근법은 Latent variable model을 이해하고 성능을 향상시키는 데 도움이 되며, prescribed model과 implicit model의 차이를 이해할 수 있다. 그러나 이 방법으로 analytical solution을 얻을 수 없고, prior에서 많은 샘플링이 필요하며, 차원의 저주(curse of dimensionality)라는 큰 문제점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 Curse of dimensionality를 해결하기 위해 VAE(prescribed model)에서는 Variational inference를 활용한다. 그런데, latent variable model의 또 다른 갈래인 implicit model에서는 likelihood 기반의 모델 대신에 implicit model을 활용한다. 그 대표적인 예가 Generative Adversarial Networks (GANs)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Implicit Modeling with Generative Adversarial Networks (GANs)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 생성 모델 학습을 할 때, log-likelihood function을 통해 하고자 하는 것은 training data와 생성된 data를 비교하는 것이다. GAN에서는 VAE에서 사용하던 KL divergence loss term 대신에 &lt;span style=&quot;color: #ee2323;&quot;&gt;다른 metric&lt;/span&gt;을 통해 비교하려 한다. 또한, 꼭 처음부터 사전 정의된 모델 (prescribed model)을 활용해야 할지에 대한 의문도 제기한다. Latent로부터 full distribution을 얻는 것이 아니라, &lt;span style=&quot;color: #ee2323;&quot;&gt;data point 하나씩&lt;/span&gt;을 얻는 implicit model을 고안한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Implicit Modeling&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uX8LB/btsshwYvk9Z/FaTaRjPCKAYEiFDtV0u590/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uX8LB/btsshwYvk9Z/FaTaRjPCKAYEiFDtV0u590/img.png&quot; data-alt=&quot;Fig 4. Generator in GANs (density network with Dirac delta function)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uX8LB/btsshwYvk9Z/FaTaRjPCKAYEiFDtV0u590/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuX8LB%2FbtsshwYvk9Z%2FFaTaRjPCKAYEiFDtV0u590%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;763&quot; height=&quot;298&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. Generator in GANs (density network with Dirac delta function)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서도 언급했듯, Fig 4에서처럼 implicit model은 data의 distribution(mean, variance)이 아닌 data point를 하나씩 생성한다. 이러한 방법으로 decoding하는 neural network를 Dirac delta function을 활용하여 수식으로 표현하자면 아래와 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p_\theta(\mathbf{x} \vert \mathbf{z}) = \delta(\mathbf{x} - \operatorname{NN}_\theta(\mathbf{z})) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 Dirac's delta function은 다음과 같이 정의된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;961&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DoAuQ/btssk05Qj8O/LUT5qkiF1xlFuQ1oyR1EJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DoAuQ/btssk05Qj8O/LUT5qkiF1xlFuQ1oyR1EJ1/img.png&quot; data-alt=&quot;Fig 5. Dirac delta function&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DoAuQ/btssk05Qj8O/LUT5qkiF1xlFuQ1oyR1EJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDoAuQ%2Fbtssk05Qj8O%2FLUT5qkiF1xlFuQ1oyR1EJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;370&quot; height=&quot;278&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;961&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. Dirac delta function&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \delta(x) = \underset{b \rightarrow 0}{\lim} \cfrac{1}{\vert b \vert \sqrt{\pi}} e^{-(x/b)^2} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Decoding 과정에서의 Dirac delta function을 보면, latent \(\mathbf{z}\)를 입력받은 neural network 결과 중에서 peak 값만 존재하게 되는 것이다. 그 peak 값이 data point 하나가 될 것이다. 실제 동작할 때에는 neural network \(\operatorname{NN}_\theta\)가 mean과 variance 대신 mean만 출력하는 것을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Marginal distribution은 Delta peak의 mixture로 표현된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p_\theta(\mathbf{x}) = \int \delta(\mathbf{x} - \operatorname{NN}_\theta(\mathbf{z})) p(\mathbf{z}) \, d \mathbf{z} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무수히 많은 &lt;span&gt;\mathbf{z}&lt;/span&gt;에 대해 peak 값을 얻다 보면, observable space에서 어떤 지역(region)은 다른 곳보다 dense하게 point 값이 많이 분포하게 될 것이다. 이것이 결국 Fig 3에서 density network의 결과였던, 모델이 생성할 때 샘플링할 distribution이 되는 것이다. 이 전반적인 과정을 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;implicit modeling&lt;/span&gt;이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 접근법의 문제점은 loss function을 계산할 수 없는 ill-defined term \( \log \delta(\mathbf{x} - \operatorname{NN}_\theta(\mathbf{z})) \)이 존재한다는 것이다. 이를 해결하기 위해 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Adversarial loss&lt;/span&gt;를 도입한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Adversarial Loss&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Adversarial loss에서 활용할 주요 용어부터 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Data point \( \mathbf{x}\) 중에서, real data(ex. dataset의 이미지)는 emperical distribution \(p_\text{data}(\mathbf{x})\)에서 샘플링한 data point이며, fake data(ex. 모델이 생성한 이미지)는 generator \(G\)가 생성한 data point이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Discriminator, generator&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Discriminator \(D\)는 data가 진짜인지, 가짜인지를 분류하는 classifier로, neural network로 parameterize한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( D : \mathcal{X} \rightarrow [0, 1] \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Generator는 noise를 입력 받아 fake data를 생성하며, 또다른 neural network로 parameterize한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( G : \mathcal{Z} \rightarrow \mathcal{X} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Objective function(Adversarial loss)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Objective function을 살펴보자. 우선 data source가 real data \(\mathbf{x} \sim p_\text{data}(\mathbf{x})\), fake data \(\mathbf{x} \sim p_\theta(\mathbf{x}) = \int G(\mathbf{z}) p(\mathbf{z}) \, d \mathbf{z} \)로 두 가지이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Discriminator는 입력 데이터가 fake이면 0, real이면 1로 예측하도록 하는 (binary) classification task를 수행한다. 따라서 binary cross-entropy loss를 활용하여 다음과 같이 나타낼 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathcal{L} = \mathbb{E}_{\mathbf{x} \sim p_\text{data}} \left[ \log D(\mathbf{x}) \right] + \mathbb{E}_{\mathbf{z} \sim p(\mathbf{z})} \left[ \log (1 - D (G(\mathbf{z})) \right] \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왼쪽 term은 real data source, 오른쪽 term은 fake data source에 해당한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Discriminator가 예측할 정답값을 \(y\)로 표현하여 좀 더 쉬운 표현으로 바꾸자면, binary cross-entropy는 다음과 같이 계산할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \operatorname{BCE} = y \log ( D(\mathbf{x})) + (1 - y) \log (1 - D(\mathbf{x})) \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Discriminator 입장에서는 BCE를 최대화&lt;/span&gt; 하는 것이 목표이다. 즉, real data를 입력받았을 때(\(y=1\)), real으로 예측(\(D(\mathbf{x}) = 1\))하고, fake data를 입력받았을 때(\(y=0\)), fake로 예측(\(D(\mathbf{x}) = 0\))해야 이상적인 discriminator이고, BCE가 최댓값이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Generator 입장에서는 BCE 값을 최소화&lt;/span&gt;해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \operatorname{BCE} = y \log ( D(\mathbf{x})) + (1 - y) \log (1 - D(G(\mathbf{z}))) \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Generator가 fake data를 생성하여 discriminator에게 넘겨줬을 때(\(y=0\)), discriminator가 real data로 판단하도록 속여야(\(D(G(\mathbf{z})) = 1)\) 이상적인 generator이고, 이 때 BCE는 최소화된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 종합하면 최종 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;adversarial loss&lt;/span&gt;는 다음과 같이 나타낼 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \underset{G}{\min} \underset{D}{\max} \, \mathbb{E}_{\mathbf{x} \sim p_\text{data}} \left[ \log D(\mathbf{x}) \right] + \mathbb{E}_{\mathbf{z} \sim p(\mathbf{z})} \left[ \log (1 - D (G(\mathbf{z})) \right] \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Adversarial이라는 이름이 붙은 이유는, generator와 discriminator가 서로 반대되는(adversarial) objective를 갖고 학습을 진행하기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학습할 때에는 min-max problem을 최적화하는 방법을 사용한다. 이때 backpropagation, stochastic gradient descent 등을 활용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;GANs&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;GAN 모델의 학습 과정은 아래 그림과 같이 나타낼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;584&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/T0mnJ/btssimg2w6s/SNWp4KwPHaLh1ZeH3WFnBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/T0mnJ/btssimg2w6s/SNWp4KwPHaLh1ZeH3WFnBk/img.png&quot; data-alt=&quot;Fig 6. Generative Adversarial Networks (GANs)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/T0mnJ/btssimg2w6s/SNWp4KwPHaLh1ZeH3WFnBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FT0mnJ%2Fbtssimg2w6s%2FSNWp4KwPHaLh1ZeH3WFnBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;584&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;584&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 6. Generative Adversarial Networks (GANs)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Implementation&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;간단한 GAN을 구현해보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저, generator와 discriminator class를 구현한다.&lt;/p&gt;
&lt;pre id=&quot;code_1693133122681&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Generator(nn.Module):
		def __init__(self, generator_net, z_size):
				super(Generator, self).__init__()
				
				# Init the generator neural network
				self.generator_net = generator_net
				# Size(dimension) of the latents
				self.z_size = z_size

		def generate(self, z):
				# Generate a sample point given z
				return self.generator_net(z)

		def sample(self, batch_size=32):
				# At first, sample the latents
				z = torch.randn(batch_size, self.z_size)
				return self.generate(z)

		def forward(self, z=None):
				if z is None:
						return self.sample()
				else:
						return self.generate(z)&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1693133145547&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Discriminator(nn.Module):
		def __init__(self, discriminator_net):
				super(Discriminator, self).__init__()
				# Init the discriminator neural net
				self.discriminator_net = discriminator_net

		def forward(self, x):
				# Just classify (apply the neural net)
				return self.discriminator_net(x)&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 클래스를 활용하여 GAN class를 구현한다.&lt;/p&gt;
&lt;pre id=&quot;code_1693133183083&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class GAN(nn.Module):
		def __init__(self, generator, discriminator, eps=1.e-5)
				super(GAN, self).__init__()
				# Init generator and discriminator
				self.generator = generator
				self.discriminator = discriminator
				
				# small epsilon value for numerical issue
				self.eps = eps

		def forward(self, x_real, reduction='avg', mode'discriminator'):
				# calculate adversarial loss
				if mode == 'generator':
						# sample fake data
						x_fake_gen = self.generator.sample(x_real.shape[0])
			
						# calculate output of discriminator for fake data (using clamp for numerical stability)
						d_fake = torch.clamp(self.discriminator(x_fake_gen), self.eps, 1. - self.eps)
						
						# loss for the generator
						loss = torch.log(1. - d_fake)

				elif mode == 'discriminator':
						# calculate outputs of discriminator for both fake and real data
						x_fake_gen = self.generator.sample(x_real.shape[0])
						d_fake = torch.clamp(self.discriminator(x_fake_gen), self.eps, 1. - self.eps)

						d_real = torch.clamp(self.discriminator(x_real), self.eps, 1. - self.eps)
						
						# final adversarial loss for the discriminator
						loss = -(torch.log(d_real) + torch.log(1. - d_fake))

				if reduction == 'sum':
						return loss.sum()
				else:
						return loss.mean()

		def sample(self, batch_size=32):
				return self.generator.sample(batch_size=batch_size)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, generator와 discriminator를 MLP로 간단히 구현하면 아래와 같이 GAN model을 구현할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1693133253402&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Generator network and Discriminator network
generator_net = nn.Sequential(nn.Linear(L, M), nn.ReLU(),
															nn.Linear(M, D), nn.Tanh())
generator = Generator(generator_net, z_size=L)

discriminator_net = nn.Sequential(nn.Linear(D, M), nn.ReLU(),
																	nn.Linear(M, 1), nn.Sigmoid())
discriminator = Discriminator(discriminator_net)

# GAN model
model = GAN(generator=generator, discriminator=discriminator)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학습을 할 때에는, discriminator와 generator를 둘 다 학습시켜야 하므로 optimizer를 두 개 사용해야 한다. Training loop를 구현해보면 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1693133317697&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for idx_batch, batch in enumerate(train_loader):
		# for Discriminator
		loss_dis = model.forward(batch, mode='discriminator')

		optimizer_dis.zero_grad()
		optimizer_gen.zero_grad()
		loss_dis.backward()
		optimizer_dis.step()

		# for Generator
		loss_gen = model.forward(batch, mode='generator')
		
		optimizer_dis.zero_grad()
		optimizer_gen.zero_grad()
		loss_gen.backward()
		optimizer_gen.step()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Generative Models</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/245</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Generative-Adversarial-Networks-GANs-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0#entry245comment</comments>
      <pubDate>Sun, 27 Aug 2023 19:48:52 +0900</pubDate>
    </item>
    <item>
      <title>Geometry와 Topology의 개념과 차이</title>
      <link>https://jjuke-brain.tistory.com/entry/Geometry%EC%99%80-Topology</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3D Vision을 연구하고 있는 입장에서, 논문을 읽다 보면 'geometry'라는 단어와 'topology'라는 단어가 자주 보인다. 둘 다 '기하학적인 개념'이라고 대충 알고 지나갔었는데, 두 개념의 차이를 조금 더 확실히 알아보고 정리해두려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Geoemtry란? Topology란?&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Geometry와 topology는 공통적으로 '공간'을 수학적으로 해석하는 개념이다. 하지만 깊이 파고들면 명확한 차이점이 있다. 우선 각각의 정의를 살펴보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Geometry(기하학)란, 공간에 존재하는 점(points), 선(lines), 면(surfaces), 각도(angles), 입체(solids) 등의 특성(properties), 치수(measurement), 서로 간의 관계(relations)를 수학적으로 다룬다. 특히, 우리에게 익숙한 distance, shape, size, position 등의 개념을 다룬다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하위 개념 몇 가지를 알아보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Point, line, and plane : Geoemtry에서의 기초적인 요소로, point는 위치(location)를, line은 두 point간의 연결을 의미한다. Plane은 평평한 surface를 의미한다.&lt;/li&gt;
&lt;li&gt;Shape and solid : Geometry에서는 2차원 shape인 사각형, 삼각형, 원 등을 다루고, 3차원 solid인 cube, sphere, pyramid 등을 다룬다.&lt;/li&gt;
&lt;li&gt;Measurement : 길이, 면적, 부피 등 shape이나 solid가 갖는 수치적인 특성을 말한다.&lt;/li&gt;
&lt;li&gt;Transformation : Translation, rotation, reflection, dilation 등 어떤 shape이나 solid의 위치나 방향을 바꾸는 것을 말한다.&lt;/li&gt;
&lt;li&gt;Property : 일치, 닮음, 대칭, 평행, 직교 등 shape이나 solid 사이의 관계를 나타낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Topology(위상수학)는 &lt;span style=&quot;color: #ee2323;&quot;&gt;연속적인 변형(continuous transformation)이 가해져도 보존되는 공간&lt;/span&gt;적 특성을 수학적으로 다룬다. 예를 들어, tearing(찢기)이나 gluing(붙이기)가 아닌, stretching(늘이기), crumpling(구기기), bending(구부리기) 등의 변형이 연속적인 변형에 속한다. 구(sphere)와 정육면체(cube)는 자르거나 붙이지 않고 변형하여 서로가 될 수 있으므로, 같은 topology(homeomorphic)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마찬가지로 하위 개념을 살펴보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Open and closed set : Topology의 기초가 되는 개념으로, topological space, topological space 등을 정의하는 데 사용된다.&lt;/li&gt;
&lt;li&gt;Continuous function : Topology에서 open set의 모든 pre-image(원상)가 open이면 연속이라고 정의한다. 여기서 pre-image는 역함수(inverse function) 정도로 이해할 수 있다.&lt;/li&gt;
&lt;li&gt;Compactness and connectedness : 모든 open cover가 한정된 subcover를 갖고 있으면 공간이 compact하다고 하고, 끊겨있는 두 개의 open set으로 나뉠 수 없을 때 공간이 연결되어있다(connected)고 정의한다.&lt;/li&gt;
&lt;li&gt;Homeomorphism : 수학적으로, 두 공간 사이에 연속적인 bijection(그리고 inverse)이 존재하면 homeomorphic하다, 즉 두 공간의 topology가 같다고 정의한다. 이는 두 공간의 topology적인 특성이 같다는 것을 의미한다.&lt;/li&gt;
&lt;li&gt;Homotopy : 두 함수 사이의 연속적인 변형(continuous deformation)의 개념이다. 어떤 함수가 다른 함수로 (연속적으로) 변형이 가능하면 두 함수는 homotopic하다고 한다.&lt;/li&gt;
&lt;li&gt;Invariants : Homeomorphic한 공간들은 서로 invariant하다고 표현한다. 대표적인 예로 Euler characteristic이 있다.&lt;/li&gt;
&lt;li&gt;Manifolds : Euclidean space와 비슷한 topological space이다. \(n\)차원 manifold의 각 점은 \(n\)차원 Euclidean space와 homeomorphic한(topological 특성이 같은) neighborhood를 가진다. 1차원 manifold에는 직선(line), 원(circle) 등이 있고, 2차원 manifold는 'surface'를 말한다. 인공지능에서 자주 등장하는 단어이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Geometry와 Topology의 차이&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;240&quot; data-origin-height=&quot;190&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5QwP5/btsroH8za4u/W6cpdEjBIgZgl00KOSyoK1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5QwP5/btsroH8za4u/W6cpdEjBIgZgl00KOSyoK1/img.jpg&quot; data-alt=&quot;Cups and donuts are same (Wikipedia)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5QwP5/btsroH8za4u/W6cpdEjBIgZgl00KOSyoK1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5QwP5%2FbtsroH8za4u%2FW6cpdEjBIgZgl00KOSyoK1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;240&quot; height=&quot;190&quot; data-origin-width=&quot;240&quot; data-origin-height=&quot;190&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Cups and donuts are same (Wikipedia)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Topology는 geometry보다 좀 &lt;span style=&quot;color: #ee2323;&quot;&gt;덜 엄격한&lt;/span&gt; 개념, 즉 기하학이 확장된 개념으로 볼 수 있다. '위상수학'(의 어려움)에 관한 얘기를 들은 적이 있는데, 위상수학에서는 도넛 모양의 입체와 머그컵이 같다고 본다는 것이다. 아마도 (수학을 전공하지 않은) 일반인은 기하학이 훨씬 익숙하기 때문에 어렵게 느껴지는 것이 아닌가 하는 생각이 든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gemoetry는 기하학적인 구조를 shape, size 등의 공간적 특성을 기준으로 구분하기 때문에 어떤 object를 구성하는 꼭지점(vertices), 모서리(edges), 면(surfaces) 등의 coordanate가 중요하지만, topology는 꼭지점 등의 &lt;span style=&quot;color: #ee2323;&quot;&gt;정확한 위치보다 이들이 어떻게 연결되어있는지가 중요&lt;/span&gt;하다.&lt;/p&gt;</description>
      <category>Studies/Knowledges</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/244</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Geometry%EC%99%80-Topology#entry244comment</comments>
      <pubDate>Thu, 17 Aug 2023 15:16:33 +0900</pubDate>
    </item>
    <item>
      <title>Variational Auto-Encoder (VAE) 파헤치기! (2)</title>
      <link>https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 대표적인 심층 생성 모델인 AutoRegressive Models (ARMs), Flow-based Models 두 가지를 살펴보았다. 하지만, (적어도 내가 연구하고 있는 분야에서는) 최근에는 VAE, Diffusion, GAN 기반의 모델이 활발하게 이용된다. 특히 diffusion의 우수한 성능은 따로 설명이 필요 없을 정도로 유명하고(실제로 세계적인 학회에 가면 과장 조금 보태서 30~40% 정도는 diffusion 관련 논문이 쏟아지고 있다.), VAE와 GAN을 기반으로 하는 다양한 우수한 성능을 보이는 모델이 나오고 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;VAE는 latent variable을 다룰 수 있다는 점에서 최근에는 생성모델 자체로 쓰이기 보다는 다양한 아키텍쳐들의 기반(base)으로 많이 사용되고 있다. 또한, diffusion은 다양한 관점에서 설명이 가능한데, VAE에서 활용되는 이론이 diffusion에서도 활용되며, 아예 diffusion을 hierarchical VAE로 보기도 한다. 따라서 책 '&lt;a href=&quot;https://link.springer.com/book/10.1007/978-3-030-93158-2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Deep Generative Modeling&lt;/a&gt;'을 참고하여 VAE에 대해 자세하게 공부하고, 정리해보려 한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이전 글에서는 VAE를 이해하는 데 필요한 기초 지식과 variational inference, ELBO 유도 과정을 자세히 살펴보았다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1691860836072&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Variational Auto-Encoder (VAE) 파헤치기! (1)&quot; data-og-description=&quot;목차 앞서 대표적인 심층 생성 모델인 AutoRegressive Models (ARMs), Flow-based Models 두 가지를 살펴보았다. 하지만, (적어도 내가 연구하고 있는 분야에서는) 최근에는 VAE, Diffusion, GAN 기반의 모델이 활발&quot; data-og-host=&quot;jjuke-brain.tistory.com&quot; data-og-source-url=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1&quot; data-og-url=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/D4owm/hyTCEICEKH/pdouETdr4ab7bKcAKQU3kk/img.png?width=800&amp;amp;height=355&amp;amp;face=0_0_800_355,https://scrap.kakaocdn.net/dn/bG3YGx/hyTCxJvQJM/sZa6hVvKSZ7kI4Shp2a4M0/img.png?width=800&amp;amp;height=355&amp;amp;face=0_0_800_355,https://scrap.kakaocdn.net/dn/bbzljX/hyTCDwcqt1/Fi7nfaIgy0pVP87wJMoGFK/img.png?width=2000&amp;amp;height=449&amp;amp;face=0_0_2000_449&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/D4owm/hyTCEICEKH/pdouETdr4ab7bKcAKQU3kk/img.png?width=800&amp;amp;height=355&amp;amp;face=0_0_800_355,https://scrap.kakaocdn.net/dn/bG3YGx/hyTCxJvQJM/sZa6hVvKSZ7kI4Shp2a4M0/img.png?width=800&amp;amp;height=355&amp;amp;face=0_0_800_355,https://scrap.kakaocdn.net/dn/bbzljX/hyTCDwcqt1/Fi7nfaIgy0pVP87wJMoGFK/img.png?width=2000&amp;amp;height=449&amp;amp;face=0_0_2000_449');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Variational Auto-Encoder (VAE) 파헤치기! (1)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;목차 앞서 대표적인 심층 생성 모델인 AutoRegressive Models (ARMs), Flow-based Models 두 가지를 살펴보았다. 하지만, (적어도 내가 연구하고 있는 분야에서는) 최근에는 VAE, Diffusion, GAN 기반의 모델이 활발&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jjuke-brain.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 VAE의 구성 요소를 간단히 정리하고, 학습 과정을 살펴보자. 그리고 간단한 구현 코드와 VAE 모델의 특징까지 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Components of VAEs&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Variational Auto-Encoders(VAE)는 &lt;span style=&quot;color: #ee2323;&quot;&gt;Stochastic encoder&lt;/span&gt; \(q_\phi(\mathbf{z} \vert \mathbf{x})\)와 &lt;span style=&quot;color: #ee2323;&quot;&gt;Stochastic decoder&lt;/span&gt; \(p(\mathbf{x} \vert \mathbf{z})\)로 구성된다. 또한, Marginal distribution (prior)는 \(p(\mathbf{z})\)로 주어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VAE의 objective는 ELBO이며, 다음과 같이 표현된다. (유도 과정은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 글&lt;/a&gt;을 참조하자.)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \log p(\mathbf{x}) \geq \underbrace{ \mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z} \vert \mathbf{x})} \left[ \log p(\mathbf{x} \vert \mathbf{z}) \right] - \mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z} \vert \mathbf{x})} \left[ \log q_\phi(\mathbf{z} \vert \mathbf{x}) - \log p(\mathbf{z}) \right]}_{\text{ELBO}} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Parameterization of Distributions&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Encoder와 decoder는 Neural network를 활용하여 parameterize한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VAE를 모델링 할 때, distribution 선택이 자유롭지만 domain에 따른 차원 등을 잘 고려해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, image의 경우 \(\mathbf{x} \in \{0, 1, \dots, 255 \}^D\)로 주어지므로, Normal distribution은 활용할 수 없다. 따라서 아래와 같이 categorical distribution을 사용해야 한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p_\theta(\mathbf{x} \vert \mathbf{z}) = \operatorname{Categorical}(\mathbf{x} \vert \theta(\mathbf{z})) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서, \(\theta(\mathbf{z}) = \operatorname{softmax}(\operatorname{NN}(\mathbf{z}))\)이며, \(\operatorname{NN}\)은 MLP, CNN, RNN 등의 neural network를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Variational posterior와 prior의 distribution은 보통 가장 간단한 형태인 Gaussian을 사용한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( q_\phi(\mathbf{z} \vert \mathbf{x}) = \mathcal{N}\left( \mathbf{z} \vert \boldsymbol{\mu}_\phi(\mathbf{x}), \boldsymbol{\Sigma}_\phi(\mathbf{x}) \right) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(\mathbf{z}) = \mathcal{N}(\mathbf{z} \vert \boldsymbol{0}, \mathbf{I}) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 \(\mathbf{z} \in \mathbb{R}^M\)는 continuous random variable로 이루어진 벡터이며, \(\boldsymbol{\mu}_\phi(\mathbf{x}), \boldsymbol{\Sigma}_\phi(\mathbf{x})\)는 neural network의 output이다. 실제 구현할 때에는 2\(M\)개의 값을 반환한다. (mean, variance 각각 \(M\)개)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래부터는 mean, variance의 표기를 간단하게 \(\mu\), \(\sigma\)로 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Reparameterization Trick&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ELBO를 통해 log-likelihood를 근사했지만, 여전히 기댓값 계산, 즉 integral 계산은 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 계산 불가능한 식을 근사하기 위한 Monte Carlo approximation(MC-approximation, 자세한 내용은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 글&lt;/a&gt; 참조)을 사용하되, &lt;span style=&quot;color: #ee2323;&quot;&gt;prior \(p(\mathbf{z})\) 대신 variational posterior \(q_\phi(\mathbf{z} \vert \mathbf{x})\)에서 샘플링&lt;/span&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법의 장점은 variational posterior가 prior보다 더 많은 probability mass를 더 작은 region에 할당하기 때문에, variance 측면에서 거의 deterministic하게 근사할 수 있다는 것이다. 그러나, approximation의 variance 문제는 여전히 존재한다. (샘플링한 \(\mathbf{z} \sim q_\phi(\mathbf{z} \vert \mathbf{x})\)를 ELBO에 대입하고 neural network \(\phi\)에 대한 gradient의 variance를 계산해보면 매우 큰 값이 나온다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제를 해결하기 위해 &lt;span style=&quot;color: #ee2323;&quot;&gt;reparameterization trick&lt;/span&gt;을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Reparameterization&lt;/span&gt;이란, 어떤 &lt;span style=&quot;color: #ee2323;&quot;&gt;random variable을 간단한 distribution에서 얻은 독립변수들의 primitive transformation으로 표현&lt;/span&gt;하는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1429&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHKO52/btsq7aaD3z1/1B0XAJWuql51vtEZb16CZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHKO52/btsq7aaD3z1/1B0XAJWuql51vtEZb16CZK/img.png&quot; data-alt=&quot;Fig 1. Reparameterization trick&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHKO52/btsq7aaD3z1/1B0XAJWuql51vtEZb16CZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHKO52%2Fbtsq7aaD3z1%2F1B0XAJWuql51vtEZb16CZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;501&quot; height=&quot;358&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1429&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Reparameterization trick&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, Gaussian random variable \(z \sim \mathcal{N}(\mu, \sigma^2)\)와 independent random variable \(\epsilon \sim \mathcal{N}(\epsilon \vert 0, 1)\)에 대해 다음이 성립한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( z = \mu + \sigma \cdot \epsilon \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, standard Gaussian에서 \(\epsilon\)을 샘플링하여 transformation을 적용하면 \(\mathcal{N}(z \vert \mu, \sigma^2)\)에서 얻은 샘플을 얻는 것과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 Fig 1에서 볼 수 있듯이 \(\epsilon \sim \mathcal{N}(\epsilon \vert 0, 1)\)을 \(sigma\)만큼 scaling하고 \(\mu\)만큼 shifting하여 원하는 샘플을 얻는 개념으로 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 VAE에서는 reparameterization trick을 어떻게 사용할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Encoder \(q_\phi(\mathbf{z} \vert \mathbf{x})\)에서 Gaussian distribution의 reparameterization을 활용하여 gradient의 variance를 크게 줄일 수 있다. Randomness가 독립적인 값인 \(\epsilon\)에서 오고, neural network라는 deterministic function에 대해 gradient를 계산하기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게다가, VAE는 stochastic gradient descent 방식으로 학습되기 때문에, 학습 중에 한 번만 \(\mathbf{z}\)를 샘플링해도 된다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;VAE Implementation (Example)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 예시와 함께 VAE의 학습이 실제로 어떻게 이루어지는지 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Encoder, Prior, and Decoder&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VAE에서 활용할 distributions는 다음과 같다고 가정하자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Encoder \( q_\phi(\mathbf{z} \vert \mathbf{x}) = \mathcal{N} \left( \mathbf{z} \vert \mu_\phi(\mathbf{x}), \sigma_\phi^2(\mathbf{x}) \right) \)&lt;/li&gt;
&lt;li&gt;Prior \( p(\mathbf{z}) = \mathcal{N}(\mathbf{z} \vert \boldsymbol{0}, \mathbf{I}) \)&lt;/li&gt;
&lt;li&gt;Decoder \( p_\theta(\mathbf{x} \vert \mathbf{z}) = \operatorname{Categorical}(\mathbf{x} \vert \theta(\mathbf{z})) \)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 input data \(\mathbf{x} \in \mathcal{X}^{D \times L}\)는 categorical distribution을 따른다고 가정하자. \(D\)는 pixel 개수 (예를 들어 224 by 224 image이면 \(D=50176\)), \(L\)은 pixel의 가능한 값 개수(예를 들어 8bit이면 0 ~ 255, 즉 256)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VAE에서 활용될 수 있는 encoder, decoder network를 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Encoder network는 다음과 같이 정의된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \begin{align*} \mathbf{x} \in \mathbf{X}^D \rightarrow &amp;amp;\operatorname{Linear}(D, 256) \rightarrow \operatorname{LeakyReLU} \rightarrow \\ &amp;amp;\operatorname{Linear}(256, 2 \cdot M) \rightarrow \operatorname{split} \rightarrow \mu \in \mathbb{R}^M, \; \log \sigma^2 \in \mathbb{R}^M \end{align*} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서, 2M개 중 M개의 값은 mean을 나타내고, 나머지 M개는 log variance 추정에 활용된다. variance는 양수여야 하는데 network가 추정하는 값은 실수이므로, log variance를 추정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Decoder network는 다음과 같이 정의된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \begin{align*} \mathbf{z} \in \mathbb{R}^M \rightarrow &amp;amp; \operatorname{Linear}(M, 256) \rightarrow \operatorname{LeakyReLU} \rightarrow \\ &amp;amp; \operatorname{Linear}(256, D \cdot L) \rightarrow \operatorname{reshape} \rightarrow \operatorname{softmax} \rightarrow \theta \in [0, 1]^{D \times L} \end{align*} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Input은 categorical distribution을 따르기 때문에, decoder network는 확률 \(D \cdot L\)개를 출력한다. Output tensor의 형태는 \(B, D, L\)로 reshape되어야 하며, 여기서 \(B\)는 batch size를 나타낸다. Softmax 함수를 통해 확률 값을 얻는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 PyTorch 코드로 작성하면 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1691864239353&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Encoder(nn.Module):
    def __init__(self, encoder_net):
        super(Encoder, self).__init__()
        self.encoder = encoder_net
    
    @staticmethod
    def reparameterization(mu, log_var):
        std = torch.exp(0.5*log_var)
        eps = torch.randn_like(std)
        return mu + std * eps
    
    def encode(self, x):
        h_e = self.encoder(x) # 2M size output
        mu_e, log_var_e = torch.chunk(h_e, 2, dim=1)
        return mu_e, log_var_e

    def sample(self, x=None, mu_e=None, log_var_e=None):
        if (mu_e is None) and (log_var_e is None):
            mu_e, log_var_e = self.encode(x)
        else:
            if (mu_e is None) or (log_var_e is None):
                raise ValueError('mu and log variance should not be None.')
				z = self.reparameterization(mu_e, log_var_e)
				return z

		def log_prob(self, x=None, mu_e=None, log_var_e=None, z=None):
				if x is not None:
						# calculate corresponding sample
						mu_e, log_var_e = self.encode(x)
						z = self.sample(mu_e=mu_e, log_var_e=log_var_e)
				else:
						if (mu_e is None) or (log_var_e is None) or (z is None):
								raise ValueError('mu, log variance, z should not be None.')
				
				return log_normal_diag(z, mu_e, log_var_e)

		def forward(self, x, type='log_prob'):
				assert type in ['encode', 'log_prob'], 'Type could be either encode or log_prob'
				
				if type == 'log_prob':
						return self.log_prob(x)
				else: # type == 'encode'
						return self.sample(x)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1691864262908&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Prior : simple standard Gaussian
class Prior(nn.Module):
		def __init__(self, L):
				super(Prior, self).__init__()
				self.L = L

		def sample(self, batch_size):
				z = torchrandn((batch_size, self.L))
				return z

		def log_prob(self, z):
				return log_standard_normal(z)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1691864277140&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Decoder(nn.Module):
		def __init__(self, decoder_net,
								 distribution='categorical', num_vals=None):
				super(Decoder, self).__init__()

				self.decoder = decoder_net
				self.distribution = distribution
				self.num_vals = num_vals

		def decode(self, z):
				h_d = self.decoder(z)
				if self.distribution == 'categorical':
						b = h_d.shape[0] # batch size
						d = h_d.shape[1] // self.num_vals # D
						h_d = h_d.view(b, d, self.num_vals) # (B,D,L)
						mu_d = torch.softmax(h_d, 2) # (B,D,L)
						return [mu_d]
				else:
						pass # we can use other distributions!

		def sample(self, z):
				outs = self.decode(z)
				if self.distribution == 'categorical':
						mu_d = outs[0] # (B,D,L)
						b, m = mu_d.shape[0], mu_d.shape[1]
						
						mu_d = mu_d.view(mu_d.shape[0], -1, self.num_vals) # (B,D,L)
						p = mu_d.view(-1, self.num_vals) # (B*D,L)
						x_new = torch.multinomial(p, num_samples=1).view(b,m) # (B*D,1) &amp;rarr; (B, D)
				else:
						pass # we can use other distributions!
				
				return x_new

		def log_prob(self, x, z):
				outs = self.decode(z)
				if self.distribution == 'categorical':
						mu_d = outs[0]
						log_p = log_categorical(x, mu_d, num_classes=self.num_vals,
																		reduction='sum', dim=-1).sum(-1)
				else:
						pass # we can use other distributions!
				
				return log_p

		def forward(self, z, x=None, type='log_prob'):
				assert type in ['decoder', 'log_prob'], 'Type should be either decode or log_prob'
				
				if type == 'log_prob':
						return self.log_prob(x, z)
				else:
						return self.sample(x)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(\mathbf{x}\) &amp;rarr; encoder &amp;rarr; bottleneck (\(\mathbf{z}\)) &amp;rarr; decoder &amp;rarr; \(\mathbf{x}\) 형태가 가능한 어떤 neural network던 encoder, decoder에 활용이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Training&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로, training objective를 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Variational posterior로부터 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;reparameterize&lt;/span&gt;하여 얻은 샘플은 다음과 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{z}_{\phi, n} = \mu_\phi(\mathbf{x}_n) + \sigma_\phi(\mathbf{x}_n) \odot \epsilon \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학습 과정에서 최소화할 loss는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;negative ELBO&lt;/span&gt;이며, 이는 다음과 같이 표현한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \begin{align*} -\operatorname{ELBO}(\mathcal{D}; \theta, \phi) = - \sum\limits_{n=1}^N &amp;amp; \log \operatorname{Categorical}(\mathbf{x}_n \vert \theta(\mathbf{z}_{\phi,n})) + \\ &amp;amp; \left[ - \log \mathcal{N}\left( \mathbf{z}_{\phi,n} \vert \mu_\phi(\mathbf{x}_n), \sigma_\phi^2(\mathbf{x}_n) \right) + \log \mathcal{N}(\mathbf{z}_{\phi,n} \vert \operatorname{0}, \mathbf{I}) \right] \end{align*} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 유도한 ELBO와 비교해보면, 결국 위 식은 encoder, decoder, prior를 distribution으로 표현한, 같은 표현이라는 것을 알 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \log p(\mathbf{x}) = \underbrace{\mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z} \vert \mathbf{x})} \left[ \log p(\mathbf{x} \vert \mathbf{z}) \right] - D_\text{KL} \left[ q_\phi(\mathbf{z} \vert \mathbf{x}) \Vert p(\mathbf{z}) \right]}_{\text{ELBO}} + \underbrace{D_\text{KL} \left[ q_\phi(\mathbf{z} \vert \mathbf{x}) \Vert p(\mathbf{z} \vert \mathbf{x}) \right]}_{\geq 0} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Training 과정은 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;입력 \(\mathbf{x}_n\)을 encoder network에 입력하여 mean \(\mu_\phi(\mathbf{x}_n)\)과 log variance \(\log \sigma_\phi^2(\mathbf{x}_n)\)을 얻는다.&lt;/li&gt;
&lt;li&gt;Reparameterization trick을 사용하여 standard Gaussian에서 얻은 \(\epsilon\)을 사용하여 \(\mathbf{z}_{\phi,n}\)을 계산한다.&lt;/li&gt;
&lt;li&gt;샘플 \(\mathbf{z}_{\phi,n}\)을 decoder network에 입력하여 probabilities \(\theta(\mathbf{z}_{\phi,n})\)을 얻는다.&lt;/li&gt;
&lt;li&gt;\(\mathbf{x}_n, \mathbf{z}_{\phi,n}\), \(\mu_\phi(\mathbf{x}_n)\), \(\log \sigma_\phi^2(\mathbf{x}_n)\)을 사용하여 ELBO, 즉 loss를 계산한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 VAE 코드는 다음과 같이 작성해볼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1691864377058&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class VAE(nn.Module):
		def __init__(self, encoder_net, decoder_net, num_vals=256,
								 L=16, likelihood_type='categorical'):
				super(VAE, self).__init__()
				
				self.encoder = Encoder(encoder_net=encoder_net)
				self.decoder = Decoder(decoder_net=decoder_net,
															 distribution=likelihood_type, num_vals=num_vals)
				self.prior = Prior(L=L)
				
				self.num_vals = num_vals
				self.likelihood_type = likelihood_type

		def forward(self, x, reduction='avg'):
				# encoder
				mu_e, log_var_e = self.encoder.encode(x)
				z = self.encoder.sample(mu_e=mu_e, log_var_e=log_var_e)

				# ELBO
				recon = self.decoder.log_prob(x, z)
				kl = (self.prior.log_prob(z) - self.encoder.log_prob(mu_e=mu_e,
							log_var_e=log_var_e, z=z)).sum(-1)

				if reduction == 'sum':
						return -(recon + kl).sum()
				else:
						return -(recon + kl).mean()

		def sample(self, batch_size=64):
				z = self.prior.sample(batch_size=batch_size)
				return self.decoder.sample(z)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Strengths and Weaknesses of the VAEs&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제까지 deep generative model 중 AutoRegressive Models(ARMs), Flow-based Models, Variational AutoEncoders(VAEs)를 알아보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VAE와 flow-based model을 비교하면, VAE는 Neural network에 invertible한 함수를 사용하지 않아도 되므로 encoder와 decoder에 어떤 아키텍쳐든 활용할 수 있다는 장점을 갖는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VAE와 ARM을 비교하면, VAE는 저차원의 data representation(latent variable)을 학습하고, control할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나, VAEs는 몇 가지 문제점을 갖고 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실제 log-likelihood와 ELBO 사이에는 차이가 있다(ELBO의 유도 과정에서 생략했던 KL divergence term). ARM, Flow-based Model에 비해서는 학습 및 평가 과정이 복잡하고, 불안정하다.&lt;/li&gt;
&lt;li&gt;Posterior collapse
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Decoder가 너무 강력해져서 latent variable \(\mathbf{z}\)를 noise로 간주해버린다. ELBO의 regularization term \( D_\text{KL} \left[ q_\phi(\mathbf{z} \vert \mathbf{x}) \Vert p(\mathbf{z}) \right] \)에 의해 encoder의 output distribution이 standard Gaussian prior에 너무 가까워진 현상이다.&lt;/li&gt;
&lt;li&gt;이에 따라 latent variable 자체가 의미가 없어지고, reconstruction 성능이 나빠지며, 생성 결과의 diversity가 떨어진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Hole problem : Aggregated posterior \( q_\phi(\mathbf{z}) = \cfrac{1}{N} \sum\limits_{n} q_\phi(\mathbf{z} \vert \mathbf{x}_n) \)과 prior \(p(\mathbf{z})\)가 서로 맞지 않아(mismatch) hole이 생기는 경우이다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Prior에서는 높은 확률이 aggregated posterior에서는 낮을 수 있다. (반대의 경우도 가능)&lt;/li&gt;
&lt;li&gt;Hole에서 샘플링한 latent variable이 비현실적이게 되고, 이것으로 decoding한 결과가 매우 낮은 quality를 가진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Out-of-distribution problem : 서로 다른 distribution을 갖는 sample은 전혀 생성하지 못하는 문제이다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 심층 생성 모델들이 공통적으로 갖고 있는 문제점이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Generative Models</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/243</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-2#entry243comment</comments>
      <pubDate>Sun, 13 Aug 2023 03:34:08 +0900</pubDate>
    </item>
    <item>
      <title>Variational Auto-Encoder (VAE) 파헤치기! (1)</title>
      <link>https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 대표적인 심층 생성 모델인 AutoRegressive Models (ARMs), Flow-based Models 두 가지를 살펴보았다. 하지만, (적어도 내가 연구하고 있는 분야에서는) 최근에는 VAE, Diffusion, GAN 기반의 모델이 활발하게 이용된다. 특히 diffusion의 우수한 성능은 따로 설명이 필요 없을 정도로 유명하고(실제로 세계적인 학회에 가면 과장 조금 보태서 30~40% 정도는 diffusion 관련 논문이 쏟아지고 있다.), VAE와 GAN을 기반으로 하는 다양한 우수한 성능을 보이는 모델이 나오고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VAE는 latent variable을 다룰 수 있다는 점에서 최근에는 생성모델 자체로 쓰이기 보다는 다양한 아키텍쳐들의 기반(base)으로 많이 사용되고 있다. 또한, diffusion은 다양한 관점에서 설명이 가능한데, VAE에서 활용되는 이론이 diffusion에서도 활용되며, 아예 diffusion을 hierarchical VAE로 보기도 한다. &lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;따라서 책 '&lt;/span&gt;&lt;a style=&quot;color: #0070d1; text-align: start;&quot; href=&quot;https://link.springer.com/book/10.1007/978-3-030-93158-2&quot;&gt;Deep Generative Modeling&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot;&gt;'을 참고하여 VAE에 대해 자세하게 공부하고, 정리해보려 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Autoregressive Models(ARMs), Flow-based Models, and Latent Variable Models&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, 앞에서도 계속 살펴봤던 deep generative models의 분류 그림과 비교 표를 한 번 살펴보고 넘어가자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1425&quot; data-origin-height=&quot;632&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Kht0t/btsqZEjUAOa/OCbeDkxGOmgRCmWCkUucj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Kht0t/btsqZEjUAOa/OCbeDkxGOmgRCmWCkUucj1/img.png&quot; data-alt=&quot;Fig 1. Taxonomy of deep generative models&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Kht0t/btsqZEjUAOa/OCbeDkxGOmgRCmWCkUucj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKht0t%2FbtsqZEjUAOa%2FOCbeDkxGOmgRCmWCkUucj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;564&quot; height=&quot;250&quot; data-origin-width=&quot;1425&quot; data-origin-height=&quot;632&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Taxonomy of deep generative models&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1620&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blWwMK/btsqZDys7BD/rlay1cSdkrhSwTYtd7l6mK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blWwMK/btsqZDys7BD/rlay1cSdkrhSwTYtd7l6mK/img.png&quot; data-alt=&quot;Fig 2. Comparation of deep generative models&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blWwMK/btsqZDys7BD/rlay1cSdkrhSwTYtd7l6mK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblWwMK%2FbtsqZDys7BD%2Frlay1cSdkrhSwTYtd7l6mK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;815&quot; height=&quot;181&quot; data-origin-width=&quot;1620&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Comparation of deep generative models&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;ARMs and Flow-based Models&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ARM과 flow-based model은 Likelihood를 직접적으로 모델링&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;(cf. implicit&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;rarr; GAN, approximation&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&amp;rarr; VAE)하므로, 학습(train)과 평가(eval)가 쉽고 안정적이라는 특징이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ARM은 Chain rule을 기반으로 \(p(\mathbf{x})\)를 factorize(인수분해)하며, 이를 통해 conditional distribution \(p(x_d \vert \mathbf{x}_{&amp;lt;d})\)를 parameterize한다. 이때 conditional independence 혹은 neural parameterization을 사용하면 식을 compact하게 표현할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 sequential하게 생성할 수밖에 없고, unsupervised 방식으로 feature를 학습하지 못한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flow-based model은 invertible transformation function을 사용하여 간단한 distribution을 복잡한 distribution으로 변형하는 방식으로 생성한다. Change of variables 식을 사용하여 marginal likelihood를 얻을 수 있으며, 일종의 directed latent variable model로 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 triangular Jacobian 계산이 가능해야 하며, log-likelihood의 평가(eval)가 효율적이어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Latent Variable Models&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지의 생성 과정을 예로 들어보자. 어떤 이미지 데이터가 있을 때 새로운 이미지를 생성하는 \(p(\mathbf{x})\)를 학습하려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 물체를 사람에게 그리라고 지시하면, 실루엣을 먼저 그린 후 크기나 형상을 그리고, 그 다음에 디테일을 추가하고, 마지막으로 배경을 그릴 것이다. 이처럼 인공지능 모델이 다룰 &lt;span style=&quot;color: #ee2323;&quot;&gt;데이터에도 실루엣, 크기, 디테일, 배경 등의 factor가 존재&lt;/span&gt;할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Generative process&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;889&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QsvLD/btsqZvHu5x9/3MouNHudEfJKAvGtGpNLv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QsvLD/btsqZvHu5x9/3MouNHudEfJKAvGtGpNLv0/img.png&quot; data-alt=&quot;Fig 3. Latent variable model and generative process. Low-dimensional manifold(2D here) is embedded in the high-dimensional space(3D here)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QsvLD/btsqZvHu5x9/3MouNHudEfJKAvGtGpNLv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQsvLD%2FbtsqZvHu5x9%2F3MouNHudEfJKAvGtGpNLv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;614&quot; height=&quot;273&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;889&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Latent variable model and generative process. Low-dimensional manifold(2D here) is embedded in the high-dimensional space(3D here)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;활용할 용어(변수)를 살펴보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( \mathbf{x} \in \mathcal{X}^D \) : High-dimensional data
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( \mathcal{X}^D \) : High-dimensional data space (Fig 3에서 data point가 존재하는 3D 공간)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;\( \mathbf{z} \in \mathcal{Z}^M \) : Low-dimensional latent variables (데이터의 hidden factors 개념)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( \mathcal{Z}^M \) : Low-dimensional manifold (Fig 3에서 2D manifold)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성이 이루어지는 과정은 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Latent variable \( \mathbf{z} \)를 샘플링한다.&lt;/li&gt;
&lt;li&gt;Latent variable \( \mathbf{z} \)를 condition으로 하는 conditional distribution에서 data point \( \mathbf{x} \)를 샘플링한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확률 개념(probability distribution)을 사용하기 때문에 완벽하게 같은 이미지를 생성하는 것은 거의 불가능하며, 이는 생성모델의 diversity 특성과 연관이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Latent Variable Models&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Latent variable \( \mathbf{z} \)를 사용하여 joint distribution을 다음과 같이 factorize한다. 위에서 언급한 generative process를 수식화한 것이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(\mathbf{x}, \mathbf{z}) = p(\mathbf{x} \vert \mathbf{z}) p(\mathbf{z}) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델을 학습할 때에는 data \( \mathbf{x} \)만 사용 가능하므로, marginalize하여 (marginal) likelihood function으로 모델링한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(\mathbf{x}) = \int p(\mathbf{x} \vert \mathbf{z}) p(\mathbf{z}) \; d \mathbf{z} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀 더 구체적으로 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목표는 주어진 data(observations) \( \mathbf{x} \)에 대해 \( p(\mathbf{x}) \)를 학습하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;449&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/14rnD/btsq2krhNfY/5obSs6fc9z9ZReIrqqkkEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/14rnD/btsq2krhNfY/5obSs6fc9z9ZReIrqqkkEK/img.png&quot; data-alt=&quot;Fig 4. Distribution of observations \(p(\mathbf{x})\), (Left) distribution of prior of the latent variables \(p(\mathbf{z})\) (Center), and the fitted \(p(\mathbf{x})\) by several transformed \(p(\mathbf{z})\) (Right)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/14rnD/btsq2krhNfY/5obSs6fc9z9ZReIrqqkkEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F14rnD%2Fbtsq2krhNfY%2F5obSs6fc9z9ZReIrqqkkEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;449&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;449&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. Distribution of observations \(p(\mathbf{x})\), (Left) distribution of prior of the latent variables \(p(\mathbf{z})\) (Center), and the fitted \(p(\mathbf{x})\) by several transformed \(p(\mathbf{z})\) (Right)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Latent variable model에서는 Fig 4와 같이 latent variable \( \mathbf{z} \)를 사용하여 이 과정을 단순화한다. 정확히 말하면 복잡한 distribution인 \( p(\mathbf{x}) \)를 직접 학습하는 대신, 관측된 data와 latent variables의 joint distribution인 \( p(\mathbf{x}, \mathbf{z}) \)를 학습한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(\mathbf{x}, \mathbf{z}) = p(\mathbf{z}) p(\mathbf{x} \vert \mathbf{z}) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( p(\mathbf{z}) \) : Prior (주로 Gaussian distribution 사용)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 식을 Fig 4의 오른쪽 그림처럼 \( p(\mathbf{z}) \)에 weight \( \mathbf{w}_i \)를 곱하여 transform함으로써 \( p(\mathbf{x}) \)를 나타낼 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(\mathbf{x}) = \int_\mathbf{z} p(\mathbf{x} \vert \mathbf{z}) p(\mathbf{z}) \, d \mathbf{z} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( p(\mathbf{x} \vert \mathbf{z}) \) : Weight \( \mathbf{w} \)의 개념&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( p(\mathbf{x}) \)는 주어진 \( \mathbf{x} \)에 가장 가까워지도록, 즉 likelihood를 maximize하도록 학습된다. \( d \mathbf{z} \), 즉 적분을 latent space 전체에 대해 계산해야 하므로 &lt;span style=&quot;color: #ee2323;&quot;&gt;intractable&lt;/span&gt;(계산이 불가능)하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Probabilistic Principal Component Analysis (pPCA)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;probabilistic Principal Component Analysis (pPCA)는 latent variable model을 확률로 가장 간단하게 모델링할 수 있는 이론이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, 모델링에 필요한 가정을 살펴보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Continuous random variables \( \mathbf{z} \in \mathbb{R}^M \), \( \mathbf{x} \in \mathbb{R}^D \)&lt;/li&gt;
&lt;li&gt;\( p(\mathbf{z}) = \mathcal{N}(\mathbf{z} \vert \boldsymbol{0}, \mathbf{I}) \) : \( \mathbf{z} \)의 distribution은 standard Gaussian&lt;/li&gt;
&lt;li&gt;\( \mathbf{x} \)와 \( \mathbf{z} \)는 Gaussian additive noise가 추가된 선형 관계
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( \mathbf{x} = \mathbf{W} \mathbf{z} + \mathbf{b} + \epsilon \), 여기서 \(\epsilon \sim \mathcal{N}(\epsilon \vert \boldsymbol{0}, \sigma^2 \mathbf{I})\)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gaussian distribution의 성질과 세 번째 가정에 따라 conditional probabiliaty \(p(\mathbf{x} \vert \mathbf{z})\)는 다음과 같이 나타낼 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(\mathbf{x} \vert \mathbf{z}) = \mathcal{N} \left( \mathbf{x} \vert \mathbf{W} \mathbf{z} + \mathbf{b}, \sigma^2 \mathbf{I} \right) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이어서, normal distribution을 따르는 두 벡터의 선형 결합 성질에 따라 \(p(\mathbf{x})\)는 다음과 같이 나타낸다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \begin{align*} p(\mathbf{x}) &amp;amp;= \int p(\mathbf{x} \vert \mathbf{z}) p(\mathbf{z}) \; d \mathbf{z} \\ &amp;amp;= \int \mathcal{N} \left( \mathbf{x} \vert \mathbf{W} \mathbf{z} + \mathbf{b}, \sigma^2 \mathbf{I} \right) \mathcal{N}(\mathbf{z} \vert \boldsymbol{0}, \mathbf{I}) \; d \mathbf{z} \\ &amp;amp;= \mathcal{N} \left( \mathbf{x} \vert \mathbf{b}, \mathbf{W} \mathbf{W}^\top + \sigma^2 \mathbf{I} \right) \end{align*} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 log-likelihood function \( \log p(\mathbf{x}) \)는 계산이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 Gaussian 성질을 활용하여 \( \mathbf{z} \)에 대한 true posterior \(p(\mathbf{z} \vert \mathbf{x})\)도 아래 식으로 계산이 가능하다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(\mathbf{z} \vert \mathbf{x}) = \mathcal{N} \left( \mathbf{M}^{-1} \mathbf{W}^\top (\mathbf{x} - \mu), \sigma^{-2} \mathbf{M} \right) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 matrix \(\mathbf{M} = \mathbf{W}^\top \mathbf{W} + \sigma^2 \mathbf{I}\)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, log-likelihood function을 최대화하는 계산 가능한 \( \mathbf{W} \)만 찾으면 \( p(\mathbf{z} \vert \mathbf{x}) \)를 계산할 수 있다. 즉, data \( \mathbf{x} \)만 주어져 있더라도 latent factors (hidden factors)를 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, pPCA를 활용한 모델링에는 치명적인 한계가 있다. 가정에서 linear dependency 대신 non-linear dependency를 가지거나, Gaussian 외의 다른 distribution을 사용하면 integral을 계산할 수 없다. 따라서 좀 더 일반적인 상황에서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;log-likelihood에 대한 근사(approximation)가 필요&lt;/span&gt;하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Variational Auto-Encoders (VAEs)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로, VAE를 이해하는 데 필요한 핵심 내용인 variational inference와 ELBO 유도 과정을 살펴보자. VAE는 nonlinear latent variable model을 모델링하기 위해 variational inference 개념을 활용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Monte Carlo approximation&lt;/span&gt;을 알아보자. MC approximation은 &lt;span style=&quot;color: #ee2323;&quot;&gt;계산이 불가능한 기댓값 계산을 근사&lt;/span&gt;하는 가장 간단한 방법이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \begin{align*} p(\mathbf{x}) &amp;amp;= \int p(\mathbf{x} \vert \mathbf{z}) p(\mathbf{z}) \; d \mathbf{z} \\ &amp;amp;= \mathbb{E}_{\mathbf{z} \sim p(\mathbf{z})} [ p(\mathbf{x} \vert \mathbf{z}) ] \\ &amp;amp;\approx \cfrac{1}{K} \sum\limits_{k} p(\mathbf{x} \vert \mathbf{z}_k) \end{align*} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Latent prior \( p(\mathbf{z}) \)에서 \( K \)개의 latents \( \mathbf{z}_k \)를 샘플링하여 근사한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 \( \mathbf{z} \in \mathbb{R}^M \)는 다차원이므로, 공간을 커버하기 위한 샘플 개수는 \( M \)의 지수함수로 증가한다. 이를 차원의 저주라고 한다. 그렇다고 너무 적게 샘플링하면 approximation이 잘 되지 않는다. 이 문제를 해결하기 위해서 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;variational inference&lt;/span&gt;를 활용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Variational inference and ELBO&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 용어를 정의하자. \( \phi \)로 parameterize된 variational distribution family \( \{q_\phi(\mathbf{z})\}_\phi \)가 있다고 하자. 예를 들어, Gaussian의 경우 mean과 variance로 parameterize되며, \( \phi = \{\mu, \sigma^2\} \)이다. Probability mass는 모든 \( \mathbf{z} \in \mathcal{Z}^M \)로 할당된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Marginal distribution에 log를 취하여 log likelihood \(\log p(\mathbf{x})\)의 lower bound를 유도해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \begin{align*} \log p(\mathbf{x}) &amp;amp;= \log \int p(\mathbf{x} \vert \mathbf{z}) p(\mathbf{z}) \; d\mathbf{z} \\ &amp;amp;= \log \int \cfrac{q_\phi(\mathbf{z})}{q_\phi(\mathbf{z})} p(\mathbf{x} \vert \mathbf{z}) p(\mathbf{z}) \; d \mathbf{z} \\ &amp;amp;= \log \mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z})} \left[ \cfrac{ p(\mathbf{x} \vert \mathbf{z}) p(\mathbf{z})}{q_\phi(\mathbf{z})} \right] \\ &amp;amp;\geq \mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z})} \log \left[ \cfrac{ p(\mathbf{x} \vert \mathbf{z}) p(\mathbf{z})}{q_\phi(\mathbf{z})} \right] \quad \quad \quad \quad \quad \quad \because \text{Jensen's inequality} \\ &amp;amp;= \mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z})} \left[ \log p(\mathbf{x} \vert \mathbf{z}) + \log p(\mathbf{z}) - \log q_\phi(\mathbf{z}) \right] \\ &amp;amp;= \mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z})} [ \log p(\mathbf{x} \vert \mathbf{z}) ] - \mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z})}[\log q_\phi(\mathbf{z}) - \log p(z\mathbf{}) ] \end{align*} \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jensen&amp;rsquo;s inequality에 따라 기댓값과 log 자리가 바뀌면 부등호가 생긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 \( q_\phi(\mathbf{z}) \) 대신 amortized variational posterior \( q_\phi(\mathbf{z} \vert \mathbf{x}) \)를 사용하여 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Evidence Lower BOund(ELBO)&lt;/span&gt;를 구할 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \log p(\mathbf{x}) \geq \underbrace{ \mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z} \vert \mathbf{x})} \left[ \log p(\mathbf{x} \vert \mathbf{z}) \right] - \mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z} \vert \mathbf{x})} \left[ \log q_\phi(\mathbf{z} \vert \mathbf{x}) - \log p(\mathbf{z}) \right]}_{\text{ELBO}} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Amortization이란 우리말로 분할 상환이라는 뜻을 갖는다. 모델 학습 시 주어진 input에 대한 distribution의 parameter를 반환하는데, stochastic한 방법으로(batch에 따라 나누어서) 진행한다고 해석해볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 따라 VAE는 &lt;span style=&quot;color: #ee2323;&quot;&gt;Stochastic encoder&lt;/span&gt; \( q_\phi(\mathbf{z} \vert \mathbf{x}) \)와 stochastic decoder \( p(\mathbf{x} \vert \mathbf{z}) \)로 구성된다. (Auto-encoder는 deterministic encoder와 decoder로 이루어진다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Log-likelihood의 lower bound는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Evidence Lower BOund (ELBO)&lt;/span&gt;로 표현하며, 다음과 같이 구성된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z} \vert \mathbf{x})} \left[ \log p(\mathbf{x} \vert \mathbf{z}) \right]\) : Reconstruction error
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;VAE를 학습한다. &amp;rarr; ELBO를 maximize한다. &amp;rarr; VAE decoder가 latent variable \(\mathbf{z}\)로부터 \(\mathbf{x}\)를 잘 샘플링하도록(잘 reconstruction하도록) 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;\(\mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z} \vert \mathbf{x})} \left[ \log q_\phi(\mathbf{z} \vert \mathbf{x}) - \log p(\mathbf{z}) \right]\) : Regularizer (기본 VAE에서는 KL divergence term에 해당)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;VAE를 학습한다. &amp;rarr; ELBO를 maximize한다. &amp;rarr; VAE encoder의 output distribution이 prior(보통 standard Gaussian)와 가까워 지도록 한다. (너무 간단해지면 오히려 posterior collapse 문제를 야기한다. Posterior collapse는 다음 글에서 간단히 다뤄볼 것이다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Different Perspective on the ELBO&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(1 = \cfrac{p(\mathbf{z} \vert \mathbf{x})}{p(\mathbf{z} \vert \mathbf{x})} = \cfrac{q_\phi(\mathbf{z} \vert \mathbf{x})}{q_\phi(\mathbf{z} \vert \mathbf{x})}\)를 곱하는 trick과 Bayes' rule을 사용해서 ELBO를 유도하는 다른 방법도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\begin{align*} \log p(\mathbf{x}) &amp;amp;= \mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z} \vert \mathbf{x})} \left[ \log p(\mathbf{x}) \right] \\ &amp;amp;= \mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z} \vert \mathbf{x})} \left[ \log \cfrac{ p(\mathbf{z} \vert \mathbf{x}) p(\mathbf{x})}{p(\mathbf{z} \vert \mathbf{x})} \right] \\ &amp;amp;= \mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z} \vert \mathbf{x})} \left[ \log \cfrac{ p(\mathbf{x} \vert \mathbf{z}) p(\mathbf{z})}{p(\mathbf{z} \vert \mathbf{x})} \right] \quad \quad \quad \quad \quad \quad \because \text{Bayes' Theorem} \\ &amp;amp;= \mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z} \vert \mathbf{x})} \left[ \log \cfrac{ p(\mathbf{x} \vert \mathbf{z}) p(\mathbf{z})}{p(\mathbf{z} \vert \mathbf{x})} \cfrac{q_\phi(\mathbf{z} \vert \mathbf{x})}{q_\phi (\mathbf{z} \vert \mathbf{x})} \right] \\ &amp;amp;= \mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z} \vert \mathbf{x})} \left[ \log p(\mathbf{x} \vert \mathbf{z}) \cfrac{ p(\mathbf{z})}{q_\phi(\mathbf{z} \vert \mathbf{x})} \cfrac{q_\phi(\mathbf{z} \vert \mathbf{x})}{p(\mathbf{z} \vert \mathbf{x})} \right] \\ &amp;amp;= \mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z} \vert \mathbf{x})} \left[ \log p(\mathbf{x} \vert \mathbf{z}) - \log \cfrac{q_\phi(\mathbf{z} \vert \mathbf{x})}{p(\mathbf{z})} + \log \cfrac{q_\phi(\mathbf{z} \vert \mathbf{x})}{p(\mathbf{z} \vert \mathbf{x})} \right] \\ &amp;amp;= \mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z} \vert \mathbf{x})} \left[ \log p(\mathbf{x} \vert \mathbf{z}) \right] - D_\text{KL} \left[ q_\phi(\mathbf{z} \vert \mathbf{x}) \Vert p(\mathbf{z}) \right] + D_\text{KL} \left[ q_\phi(\mathbf{z} \vert \mathbf{x}) \Vert p(\mathbf{z} \vert \mathbf{x}) \right] \end{align*}&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막 KL divergence term은 항상 0보다 크거나 같으므로, 위에서 유도한 ELBO와 동일한 term을 얻을 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \log p(\mathbf{x}) = \underbrace{\mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z} \vert \mathbf{x})} \left[ \log p(\mathbf{x} \vert \mathbf{z}) \right] - D_\text{KL} \left[ q_\phi(\mathbf{z} \vert \mathbf{x}) \Vert p(\mathbf{z}) \right]}_{\text{ELBO}} + \underbrace{D_\text{KL} \left[ q_\phi(\mathbf{z} \vert \mathbf{x}) \Vert p(\mathbf{z} \vert \mathbf{x}) \right]}_{\geq 0} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유도 과정을 통해 VAE의 문제점을 알아볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1070&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l3Lrs/btsqZajjVAE/S3INdUg8uV8K2oFtiUaB5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l3Lrs/btsqZajjVAE/S3INdUg8uV8K2oFtiUaB5K/img.png&quot; data-alt=&quot;Fig 5. Difference between \( \log p(\mathbf{x})\) and ELBO&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l3Lrs/btsqZajjVAE/S3INdUg8uV8K2oFtiUaB5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl3Lrs%2FbtsqZajjVAE%2FS3INdUg8uV8K2oFtiUaB5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;533&quot; height=&quot;285&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1070&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. Difference between \( \log p(\mathbf{x})\) and ELBO&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( D_\text{KL} \left[ q_\phi(\mathbf{z} \vert \mathbf{x}) \Vert p(\mathbf{z} \vert \mathbf{x}) \right] \) term은 (stochastic encoder로 parameterize되는) variational posterior \( q_\phi(\mathbf{z} \vert \mathbf{x}) \)와 실제 posterior \( p(\mathbf{z} \vert \mathbf{x}) \)의 차이, 즉 ELBO와 실제 log-likelihood의 차이를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 posterior를 알 수 없지만, KL divergence의 성질에 따라 항상 0보다 크거나 같으므로 해당 값을 무시하는데, 값이 너무 커진다면 (즉 variational posterior \(q_\phi(\mathbf{z} \vert \mathbf{x})\)에 너무 간단한 distribution을 사용한다면) VAE의 성능이 나빠진다. 이는 다음 글에서 설명할 VAE의 문제점 중 하나인 &lt;span style=&quot;color: #ee2323;&quot;&gt;posterior collapse&lt;/span&gt;와 연관된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Generative Models</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/242</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Variational-Auto-Encoder-VAE-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0-1#entry242comment</comments>
      <pubDate>Sun, 13 Aug 2023 00:05:11 +0900</pubDate>
    </item>
    <item>
      <title>맥에서 Adobe Acrobat (PDF 리더) 렉 너무 심할 경우 해결 방법</title>
      <link>https://jjuke-brain.tistory.com/entry/%EB%A7%A5%EC%97%90%EC%84%9C-Adobe-Acrobat-PDF-%EB%A6%AC%EB%8D%94-%EB%A0%89-%EB%84%88%EB%AC%B4-%EC%8B%AC%ED%95%A0-%EA%B2%BD%EC%9A%B0-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;맥에서 adobe acrobat(pro)을 활용하여 pdf를 읽거나 편집하는데, 유용한 기능이 많긴 하지만 렉이 너무 심하게 걸려서, 그 해결방법을 포스팅해보고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;재시작, 또는 개별 파일 문제&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;대부분 다른 프로그램들이 그렇듯, 프로그램을 오래, 많은 파일을 켜둔 경우에 버벅이는 경우가 있는데, 아예 껐다가(맥의 경우에는 '⌘ + Q'로) 재시작을 해보면 잘 되는 경우가 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;혹은 열어보려고 하는 pdf 파일의 용량이 너무 큰 경우가 있는데, 그 때에는 pdf 파일을 최적화해주면 해결되는 경우가 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저, 해당 파일을 연 상태에서 'File(파일) - Save as Other(다른 형식으로 저장) - Optimized PDF(최적화된 PDF)'을 선택한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-08-11 at 15.08.52@2x.png&quot; data-origin-width=&quot;1244&quot; data-origin-height=&quot;982&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCT6kP/btsqXSWzSc8/cSw6C6dKa5ZjJy6GYuBXK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCT6kP/btsqXSWzSc8/cSw6C6dKa5ZjJy6GYuBXK1/img.png&quot; data-alt=&quot;PDF file optimizing (1)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCT6kP/btsqXSWzSc8/cSw6C6dKa5ZjJy6GYuBXK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCT6kP%2FbtsqXSWzSc8%2FcSw6C6dKa5ZjJy6GYuBXK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;522&quot; height=&quot;412&quot; data-filename=&quot;CleanShot 2023-08-11 at 15.08.52@2x.png&quot; data-origin-width=&quot;1244&quot; data-origin-height=&quot;982&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;PDF file optimizing (1)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, image 등 내용물은 그대로 두고, (일반적인 상황에서) 쓸 데 없는 정보만 제거하고 싶다면, 아래와 같이 'Discard User Data (사용자 데이터 무시) 탭의 Discard hidden layer content and flatten visible layers (숨겨진 레이어 내용 및 병합된 가시 레이어 무시)'만 체크한다. 다른 항목들은 직접 살펴보면서 필요 없는 정보를 제거하여 pdf 파일의 용량을 줄여주자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1950&quot; data-origin-height=&quot;1476&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m1AAd/btsqR959S8N/bAueGBn9TYLQNLFD1e8nqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m1AAd/btsqR959S8N/bAueGBn9TYLQNLFD1e8nqk/img.png&quot; data-alt=&quot;PDF file optimizing (2)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m1AAd/btsqR959S8N/bAueGBn9TYLQNLFD1e8nqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm1AAd%2FbtsqR959S8N%2FbAueGBn9TYLQNLFD1e8nqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;612&quot; height=&quot;463&quot; data-origin-width=&quot;1950&quot; data-origin-height=&quot;1476&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;PDF file optimizing (2)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;플러그인 파일 삭제&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;재시작을 해도 해결되지 않고, 파일을 한 두개밖에 켜지 않았는데도 렉이 심하게 걸린다면, acrobat 컨텐츠 파일에 있는 플러그인 파일 몇 가지를 삭제해준다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 Adobe 프로그램을 완전히 종료(⌘ + Q)한 후, Finder에서 'Application - Adobe Acrobat DC - Adobe Acrobat' 앱 파일을 우클릭하여 앱 컨텐츠 파일을 열어보자. 필자는 Pro를 사용중인데, Pro가 아닌 Acrobat Reader를 사용하더라도 같은 방법으로 컨텐츠 파일을 살펴볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-08-11 at 15.00.34@2x.png&quot; data-origin-width=&quot;1858&quot; data-origin-height=&quot;886&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oKUGJ/btsqZuUImJR/cCDMlWDUspKVu0RNOyijh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oKUGJ/btsqZuUImJR/cCDMlWDUspKVu0RNOyijh1/img.png&quot; data-alt=&quot;Package Contents 클릭&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oKUGJ/btsqZuUImJR/cCDMlWDUspKVu0RNOyijh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoKUGJ%2FbtsqZuUImJR%2FcCDMlWDUspKVu0RNOyijh1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;753&quot; height=&quot;359&quot; data-filename=&quot;CleanShot 2023-08-11 at 15.00.34@2x.png&quot; data-origin-width=&quot;1858&quot; data-origin-height=&quot;886&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Package Contents 클릭&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로 'Contents - Plugins' 폴더로 들어가 다양한 플러그인 폴더들 중, 다음 세 가지를 삭제한다. 혹시 모르니 해당 폴더들을 다른 경로에 백업해둔 후 삭제하길 추천한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Accessibility.acroplugin&lt;/li&gt;
&lt;li&gt;Makeaccessible.acroplugin&lt;/li&gt;
&lt;li&gt;ReadOutLoud.acroplugin&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자는 이미 삭제한 후에 보여주기 위해 백업해뒀던 폴더를 다시 붙여넣어서 구성이 조금 다를 수 있으나, 폴더 명은 사진과 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2222&quot; data-origin-height=&quot;1254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9VpIM/btsqWdNgjvm/GcXiwcQ8lpUqzWYGh2J0eK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9VpIM/btsqWdNgjvm/GcXiwcQ8lpUqzWYGh2J0eK/img.png&quot; data-alt=&quot;삭제할 폴더&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9VpIM/btsqWdNgjvm/GcXiwcQ8lpUqzWYGh2J0eK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9VpIM%2FbtsqWdNgjvm%2FGcXiwcQ8lpUqzWYGh2J0eK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;732&quot; height=&quot;413&quot; data-origin-width=&quot;2222&quot; data-origin-height=&quot;1254&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;삭제할 폴더&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science, Programming/etc</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/241</guid>
      <comments>https://jjuke-brain.tistory.com/entry/%EB%A7%A5%EC%97%90%EC%84%9C-Adobe-Acrobat-PDF-%EB%A6%AC%EB%8D%94-%EB%A0%89-%EB%84%88%EB%AC%B4-%EC%8B%AC%ED%95%A0-%EA%B2%BD%EC%9A%B0-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95#entry241comment</comments>
      <pubDate>Fri, 11 Aug 2023 15:15:12 +0900</pubDate>
    </item>
    <item>
      <title>Perceiver and Perceiver IO : modality, dataset, task 등에 상관 없는 일반적인 input을 다루어 원하는 output을 내는 모델! (2)</title>
      <link>https://jjuke-brain.tistory.com/entry/Perceiver-and-Perceiver-IO-modality-dataset-task-%EB%93%B1%EC%97%90-%EC%83%81%EA%B4%80-%EC%97%86%EB%8A%94-%EC%9D%BC%EB%B0%98%EC%A0%81%EC%9D%B8-input%EC%9D%84-%EB%8B%A4%EB%A3%A8%EC%96%B4-%EC%9B%90%ED%95%98%EB%8A%94-output%EC%9D%84-%EB%82%B4%EB%8A%94%08%EB%AA%A8%EB%8D%B8-2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Multi-modal, 특히 vision-language model에 관심을 갖게 되면서 관련 논문을 찾아보던 중, task-agnostic, modality-agnostic한 다양한 input을 다룰 수 있는 모델인 Perceiver와, 이에 이어 output까지 원하는 형태로 만들 수 있는 Perceiver IO를 접하게 되었다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Multi-modal 분야 뿐만 아니라 backbone으로(혹은 아이디어를 활용하여 구조를 변형하여) 훨씬 다양하게 활용될 수 있을 것 같아 두 아키텍쳐를 다룬 논문을 읽고 그 내용을 합쳐서 정리해보려 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;먼저, Transformer의 핵심인 self-attention과 cross-attention이 여기서도 핵심 개념이기 때문에, 이를 다룬 글을 읽어보는 것을 추천한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot;&gt;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1690523004424&quot; style=&quot;background-color: #ffffff; color: #444444; text-align: start;&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Transformers in Vision - (1) Attention &amp;amp; Transformer&quot; data-og-description=&quot;Transformer가 computer vision에서 어떻게 쓰였는지, 관련 모델이 어떻게 발전하고 있는지 여러 포스팅에 걸쳐서 알아보고자 한다. 이번 포스팅에서는 가장 중요한 기초 내용인 attention과 transformer에 대&quot; data-og-host=&quot;jjuke-brain.tistory.com&quot; data-og-source-url=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; data-og-url=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cW1Jk5/hyTrNsubcZ/UrVNxjFuYkE59ONN9A6c80/img.jpg?width=800&amp;amp;height=269&amp;amp;face=0_0_800_269,https://scrap.kakaocdn.net/dn/cCVGLi/hyTrN650Wy/JTBFJ1XpL0RO2cg8VViia0/img.jpg?width=800&amp;amp;height=269&amp;amp;face=0_0_800_269,https://scrap.kakaocdn.net/dn/bv5P2q/hyTrUZtm38/PBjnjYkGxQu7ES7bsRhak0/img.png?width=1854&amp;amp;height=2656&amp;amp;face=0_0_1854_2656&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; data-source-url=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cW1Jk5/hyTrNsubcZ/UrVNxjFuYkE59ONN9A6c80/img.jpg?width=800&amp;amp;height=269&amp;amp;face=0_0_800_269,https://scrap.kakaocdn.net/dn/cCVGLi/hyTrN650Wy/JTBFJ1XpL0RO2cg8VViia0/img.jpg?width=800&amp;amp;height=269&amp;amp;face=0_0_800_269,https://scrap.kakaocdn.net/dn/bv5P2q/hyTrUZtm38/PBjnjYkGxQu7ES7bsRhak0/img.png?width=1854&amp;amp;height=2656&amp;amp;face=0_0_1854_2656');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;Transformers in Vision - (1) Attention &amp;amp; Transformer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;Transformer가 computer vision에서 어떻게 쓰였는지, 관련 모델이 어떻게 발전하고 있는지 여러 포스팅에 걸쳐서 알아보고자 한다. 이번 포스팅에서는 가장 중요한 기초 내용인 attention과 transformer에 대&lt;/p&gt;
&lt;p class=&quot;og-host&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;jjuke-brain.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고, 더 자세한 내용은 2021년 ICML에 발표된 Perceiver 논문 &quot;&lt;a style=&quot;color: #0072ff;&quot; href=&quot;http://proceedings.mlr.press/v139/jaegle21a/jaegle21a.pdf&quot;&gt;Perceiver: General Perception with Iterative Attention&lt;/a&gt;&quot;과 2022년 ICLR에 발표된 Perceiver IO 논문 &quot;&lt;a style=&quot;color: #0072ff;&quot; href=&quot;https://arxiv.org/pdf/2107.14795.pdf&quot;&gt;Perceiver IO: A General Architecture for Structured Inputs &amp;amp; Outputs&lt;/a&gt;&quot;를 참조하자.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Perceiver%EC%99%80-Perceiver-IO-modality-dataset-shape-%EB%93%B1%EC%97%90-%EC%83%81%EA%B4%80-%EC%97%86%EB%8A%94-%EC%9D%BC%EB%B0%98%EC%A0%81%EC%9D%B8-input%EA%B3%BC-output%EC%9D%84-%EB%8B%A4%EB%A3%A8%EA%B3%A0-%EC%B6%9C%EB%A0%A5%ED%95%98%EB%8A%94-%EB%AA%A8%EB%8D%B8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 글&lt;/a&gt;에서는 general input을 다루는 Perceiver를 알아보았고, 이번에는 output까지 원하는 structure로 만들어낼 수 있는 Perceiver IO를 다뤄보려 한다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #666666; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Method&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1226&quot; data-origin-height=&quot;502&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRCfD6/btsplQEVXRk/504IE3htyEm12K8ksPuXK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRCfD6/btsplQEVXRk/504IE3htyEm12K8ksPuXK0/img.png&quot; data-alt=&quot;Fig 1. Perceiver IO pipeline&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRCfD6/btsplQEVXRk/504IE3htyEm12K8ksPuXK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRCfD6%2FbtsplQEVXRk%2F504IE3htyEm12K8ksPuXK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1226&quot; height=&quot;502&quot; data-origin-width=&quot;1226&quot; data-origin-height=&quot;502&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Perceiver IO pipeline&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 글에서도 언급했듯, Perceiver IO는 read-process-write (encode-process-decode) architecture이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Read ( \( \mathbf{x} \in \mathbb{R}^{M \times C} \rightarrow \mathbf{z} \in \mathbb{R}^{N \times D} \) ) : Input을 latent space로 인코딩하는 과정 (Perceiver의 cross-attention module과 같다.)&lt;/li&gt;
&lt;li&gt;Process ( \( \mathbf{z} \rightarrow \mathbf{z}' \) ) : Latent representation을 정제(refine)하는 과정 (Perceiver의 Latent Transformer와 같다.)&lt;/li&gt;
&lt;li&gt;Write ( \( \mathbf{z} \in \mathbb{R}^{N \times D} \rightarrow \mathbf{y} \in \mathbb{R}^{O \times E} \) ) : Latent space를 디코딩하는 과정
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Read에서처럼 계산 과정과 output size를 분리하여 매우 큰 size도 출력이 가능하다!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Read와 process 과정은 각각 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Perceiver%EC%99%80-Perceiver-IO-modality-dataset-shape-%EB%93%B1%EC%97%90-%EC%83%81%EA%B4%80-%EC%97%86%EB%8A%94-%EC%9D%BC%EB%B0%98%EC%A0%81%EC%9D%B8-input%EA%B3%BC-output%EC%9D%84-%EB%8B%A4%EB%A3%A8%EA%B3%A0-%EC%B6%9C%EB%A0%A5%ED%95%98%EB%8A%94-%EB%AA%A8%EB%8D%B8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Perceiver&lt;/a&gt;의 cross-attention module 및 self-attention module과 같으므로, write 과정을 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt; Decoding&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;378&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/74g6p/btsplLjkdMB/LPA1R0rfX6L8MEi3ZVwwAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/74g6p/btsplLjkdMB/LPA1R0rfX6L8MEi3ZVwwAk/img.png&quot; data-alt=&quot;Fig 2. Decoding in Perceiver IO&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/74g6p/btsplLjkdMB/LPA1R0rfX6L8MEi3ZVwwAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F74g6p%2FbtsplLjkdMB%2FLPA1R0rfX6L8MEi3ZVwwAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;888&quot; height=&quot;378&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;378&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Decoding in Perceiver IO&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Decoding 과정은 \(\mathbf{z} \in \mathbb{R}^{N \times D} \rightarrow \mathbf{y} \in \mathbb{R}^{O \times E}\)로 나타낼 수 있다. 이때 Perceiver때와 비슷하게 cross-attention을 적용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;880&quot; data-origin-height=&quot;378&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHqQto/btsph8sSDFR/izwG7iRBEjNiC9IMJsQ9U1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHqQto/btsph8sSDFR/izwG7iRBEjNiC9IMJsQ9U1/img.png&quot; data-alt=&quot;Fig 3. Encoding in Perceiver IO (Recap)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHqQto/btsph8sSDFR/izwG7iRBEjNiC9IMJsQ9U1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHqQto%2Fbtsph8sSDFR%2FizwG7iRBEjNiC9IMJsQ9U1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;378&quot; height=&quot;162&quot; data-origin-width=&quot;880&quot; data-origin-height=&quot;378&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Encoding in Perceiver IO (Recap)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Encoding 때(Fig 3)와 달리, latent가 key \(\mathbf{k} \in \mathbb{R}^{N \times d_\text{qk}}\) 및 value \( \mathbf{v} \in \mathbb{R}^{N \times d_\text{v}} \)가 되고, 원하는 structure(shape)의 output query array를 설정하여 query \(\mathbf{q} \in \mathbb{R}^{O \times d_\text{qk}}\)로 projection한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종 output array \(\mathbf{y} \in \mathbb{R}^{O \times E}\)의 shape dimension은 \(O\)로, query와 같다. \(O, E\)는 원하는 출력 데이터의 구조(shape)에 의해 정해지는 index dimension과 channel dimension을 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Attention 계산의 복잡도를 생각해보면, Perceiver의 cross-attention(encoding) 때와 마찬가지로 latent를 활용함으로써 \(\mathcal{O}(ON)\)이 되며, 원하는 output size에 linear하게 증가한다. 따라서 복잡도가 \(O\)에 2차 비례하던 기존 Transformer에 비해 output size를 훨씬 크게 설정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Composition of the Output Query Array&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1224&quot; data-origin-height=&quot;374&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZvjsG/btspeHihamq/ZwqAPAXEQPpzk0YNSfhnU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZvjsG/btspeHihamq/ZwqAPAXEQPpzk0YNSfhnU0/img.png&quot; data-alt=&quot;Fig 4. Output query arrays corresponding to specific tasks&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZvjsG/btspeHihamq/ZwqAPAXEQPpzk0YNSfhnU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZvjsG%2FbtspeHihamq%2FZwqAPAXEQPpzk0YNSfhnU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1224&quot; height=&quot;374&quot; data-origin-width=&quot;1224&quot; data-origin-height=&quot;374&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. Output query arrays corresponding to specific tasks&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 4는 원하는 task(dataset)에 따라 output query array를 어떻게 구성하는지 보여준다. Index dimension이 \(O\)인 query로 디코더를 querying하는데, 이 query array는 output space의 구조(shape, structure)를 담아야 한다. 즉, 각 output point의 정보(spatial position, modality 등)를 포함해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해서는 해당 정보를 serialize한 후, concat하거나 더해준다. Fig 4의 예시를 통해 자세히 알아보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;간단한 output (classification에서의 category(label) 등)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 data example에 대해 같은 query를 사용할 수 있다. (즉, position encoding을 할 필요가 없다.) 따라서 Fig 4에서 Classification을 보면 '@... positions'라는 표현이 없는 것을 확인할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Spatial 혹은 sequential한 구조를 갖는 output (Text, Image 등)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Position encoding을 통해 위치(position) 정보를 나타내준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Multi-task 혹은 multimodal output (Fig 4에서 Multi-task classification 및 Multimodal autoencoding)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Task나 modality에 맞게 single query를 학습한 후에 사용한다.&lt;/li&gt;
&lt;li&gt;각 modality나 task에 해당하는 embedding(is_video, is_audio, is_label)을 concat해준다.&lt;/li&gt;
&lt;li&gt;Position encoding이 위치를 구별하듯이, network가 task나 modality를 구별하도록 학습하는 개념이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Other tasks
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Output이 input 내용을 반영하도록 query를 구성한다.&lt;/li&gt;
&lt;li&gt;Otical flow같은 경우, 2D spatial 정보(x, y) 뿐만 아니라 input feature를 포함시켰더니 성능이 좋았다고 한다.&lt;/li&gt;
&lt;li&gt;Starcraft 2의 경우, unit information을 포함시켰더니 성능이 좋았다고 한다.&lt;/li&gt;
&lt;li&gt;이와 같이, 간단한 query에 추가적인 정보를 학습하도록 해주면 더 좋은 성능을 보이는 경우가 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Decoder 코드(깃허브에 들어가보면 PerceiverClassificationDecoder, PerceiverOpticalFlowDecoder, PerceiverMultimodalDecoder 등 다양한 decoder가 있다. 그중 가장 기본적인 디코더이다.) 는 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1690526656480&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class PerceiverBasicDecoder(PerceiverAbstractDecoder):
    &quot;&quot;&quot;
    Cross-attention-based decoder. This class can be used to decode the final hidden states of the latents using a
    cross-attention operation, in which the latents produce keys and values.

    The shape of the output of this class depends on how one defines the output queries (also called decoder queries).

    Args:
        config ([*PerceiverConfig*]):
            Model configuration.
        output_num_channels (`int`, *optional*):
            The number of channels in the output. Will only be used in case *final_project* is set to `True`.
        position_encoding_type (`str`, *optional*, defaults to &quot;trainable&quot;):
            The type of position encoding to use. Can be either &quot;trainable&quot;, &quot;fourier&quot;, or &quot;none&quot;.
        output_index_dims (`int`, *optional*):
            The number of dimensions of the output queries. Ignored if 'position_encoding_type' == 'none'.
        num_channels (`int`, *optional*, defaults to 128):
            The number of channels of the decoder queries. Ignored if 'position_encoding_type' == 'none'.
        qk_channels (`int`, *optional*):
            The number of channels of the queries and keys in the cross-attention layer.
        v_channels (`int`, *optional*):
            The number of channels of the values in the cross-attention layer.
        num_heads (`int`, *optional*, defaults to 1):
            The number of attention heads in the cross-attention layer.
        widening_factor (`int`, *optional*, defaults to 1):
            The widening factor of the cross-attention layer.
        use_query_residual (`bool`, *optional*, defaults to `False`):
            Whether to use a residual connection between the query and the output of the cross-attention layer.
        concat_preprocessed_input (`bool`, *optional*, defaults to `False`):
            Whether to concatenate the preprocessed input to the query.
        final_project (`bool`, *optional*, defaults to `True`):
            Whether to project the output of the cross-attention layer to a target dimension.
        position_encoding_only (`bool`, *optional*, defaults to `False`):
            Whether to only use this class to define output queries.
    &quot;&quot;&quot;

    def __init__(
        self,
        config: PerceiverConfig,
        output_num_channels: int,
        position_encoding_type: Optional[str] = &quot;trainable&quot;,
        # The following 2 arguments are ignored if position_encoding_type == 'none':
        output_index_dims: Optional[int] = None,
        num_channels: Optional[int] = 128,
        subsampled_index_dims: Optional[int] = None,
        qk_channels: Optional[int] = None,
        v_channels: Optional[int] = None,
        num_heads: Optional[int] = 1,
        widening_factor: Optional[int] = 1,
        use_query_residual: Optional[bool] = False,
        concat_preprocessed_input: Optional[bool] = False,
        final_project: Optional[bool] = True,
        position_encoding_only: Optional[bool] = False,
        **position_encoding_kwargs,
    ) -&amp;gt; None:
        super().__init__()

        self.output_num_channels = output_num_channels
        # If `none`, the decoder will not construct any position encodings.
        # You should construct your own when querying the decoder.
        self.output_position_encodings = None
        self.position_encoding_type = position_encoding_type
        self.position_encoding_kwargs = position_encoding_kwargs
        if position_encoding_type != &quot;none&quot;:
            self.output_position_encodings, self.positions_projection = build_position_encoding(
                position_encoding_type=position_encoding_type, **position_encoding_kwargs
            )

        self.output_index_dims = output_index_dims
        self.num_channels = num_channels
        if subsampled_index_dims is None:
            subsampled_index_dims = output_index_dims
        self.subsampled_index_dims = subsampled_index_dims
        self.concat_preprocessed_input = concat_preprocessed_input
        self.final_project = final_project
        self.position_encoding_only = position_encoding_only

        # for multimodal autoencoding, we don't need the decoder cross-attention and final layer
        # so then we will set position_encoding_only to True
        if not self.position_encoding_only:
            self.decoding_cross_attention = PerceiverLayer(
                config,
                is_cross_attention=True,
                qk_channels=qk_channels,
                v_channels=v_channels,
                num_heads=num_heads,
                q_dim=num_channels,
                kv_dim=config.d_latents,
                widening_factor=widening_factor,
                use_query_residual=use_query_residual,
            )
            self.final_layer = nn.Linear(num_channels, output_num_channels) if final_project else nn.Identity()

    @property
    def num_query_channels(self) -&amp;gt; int:
        if self.position_encoding_type == &quot;none&quot;:  # Queries come from elsewhere
            raise ValueError(
                &quot;You cannot calculate number of decoder query channels when position_encoding_type is set to none&quot;
            )
        if self.position_encoding_only:
            if &quot;project_pos_dim&quot; in self.position_encoding_kwargs:
                return self.position_encoding_kwargs[&quot;project_pos_dim&quot;]
            return self.output_position_encodings.output_size()
        if self.final_project:
            return self.output_num_channels
        return self.num_channels

    def decoder_query(self, inputs, modality_sizes=None, inputs_without_pos=None, subsampled_points=None):
        if self.position_encoding_type == &quot;none&quot;:  # Queries come from elsewhere
            raise ValueError(&quot;You cannot construct decoder queries when position_encoding_type is set to none&quot;)
        if subsampled_points is not None:
            # subsampled_points are the indices if the inputs would be flattened
            # however, the inputs aren't flattened, that's why we use unravel_index
            # to get the indices for the unflattened array
            # unravel_index returns a tuple (x_idx, y_idx, ...)
            # stack to get the [n, d] tensor of coordinates
            indices = [torch.from_numpy(x) for x in np.unravel_index(subsampled_points.cpu(), self.output_index_dims)]
            pos = torch.stack(indices, dim=1)
            batch_size = inputs.shape[0]
            # Map these coordinates to [-1, 1]
            pos = -1 + 2 * pos / torch.tensor(self.output_index_dims)[None, :]
            pos = torch.broadcast_to(pos[None], [batch_size, pos.shape[0], pos.shape[1]])
            # Construct the position encoding.
            if self.position_encoding_type == &quot;trainable&quot;:
                pos_emb = self.output_position_encodings(batch_size)
            elif self.position_encoding_type == &quot;fourier&quot;:
                pos_emb = self.output_position_encodings(
                    self.output_index_dims, batch_size=batch_size, device=inputs.device, dtype=inputs.dtype, pos=pos
                )

            # Optionally project them to a target dimension.
            pos_emb = self.positions_projection(pos_emb)
            pos_emb = torch.reshape(pos_emb, [pos_emb.shape[0], -1, pos_emb.shape[-1]])
        else:
            batch_size = inputs.shape[0]
            index_dims = inputs.shape[2:]

            # Construct the position encoding.
            if self.position_encoding_type == &quot;trainable&quot;:
                pos_emb = self.output_position_encodings(batch_size)
            elif self.position_encoding_type == &quot;fourier&quot;:
                pos_emb = self.output_position_encodings(
                    index_dims, batch_size, device=inputs.device, dtype=inputs.dtype
                )

            # Optionally project them to a target dimension.
            pos_emb = self.positions_projection(pos_emb)

        if self.concat_preprocessed_input:
            if inputs_without_pos is None:
                raise ValueError(&quot;Value is required for inputs_without_pos if concat_preprocessed_input is True&quot;)
            pos_emb = torch.cat([inputs_without_pos, pos_emb], dim=-1)

        return pos_emb

    def forward(
        self,
        query: torch.Tensor,
        z: torch.FloatTensor,
        query_mask: Optional[torch.FloatTensor] = None,
        output_attentions: Optional[bool] = False,
    ) -&amp;gt; PerceiverDecoderOutput:
        # Cross-attention decoding.
        # key, value: B x N x K; query: B x M x K
        # Attention maps -&amp;gt; B x N x M
        # Output -&amp;gt; B x M x K
        cross_attentions = () if output_attentions else None

        layer_outputs = self.decoding_cross_attention(
            query,
            attention_mask=query_mask,
            head_mask=None,
            inputs=z,
            inputs_mask=None,
            output_attentions=output_attentions,
        )
        output = layer_outputs[0]

        if output_attentions:
            cross_attentions = cross_attentions + (layer_outputs[1],)

        logits = self.final_layer(output)

        return PerceiverDecoderOutput(logits=logits, cross_attentions=cross_attentions)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Perceiver IO 코드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Perceiver IO가 동작하는 과정을 전체적으로 담은 PerceiverModel 클래스를 요약한 코드를 살펴보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1690527198860&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class PerceiverModel(PerceiverPreTrainedModel):
    def __init__(
        self,
        config,
        decoder=None,
        input_preprocessor: PreprocessorType = None,
        output_postprocessor: PostprocessorType = None,
    ):
        super().__init__(config)
        self.config = config

        self.input_preprocessor = input_preprocessor
        self.output_postprocessor = output_postprocessor
        self.embeddings = PerceiverEmbeddings(config)
        self.encoder = PerceiverEncoder(
            config, kv_dim=input_preprocessor.num_channels if input_preprocessor is not None else config.d_model
        )
        self.decoder = decoder

        # Initialize weights and apply final processing
        self.post_init()

    def get_input_embeddings(self):
        return self.embeddings.latents

    def set_input_embeddings(self, value):
        self.embeddings.latents = value

    def _prune_heads(self, heads_to_prune):
        &quot;&quot;&quot;
        Prunes heads of the model. heads_to_prune: dict of {layer_num: list of heads to prune in this layer} See base
        class PreTrainedModel
        &quot;&quot;&quot;
        for layer, heads in heads_to_prune.items():
            self.encoder.layer[layer].attention.prune_heads(heads)

    @add_start_docstrings_to_model_forward(PERCEIVER_INPUTS_DOCSTRING.format(&quot;(batch_size, sequence_length)&quot;))
    @replace_return_docstrings(output_type=PerceiverModelOutput, config_class=_CONFIG_FOR_DOC)
    def forward(
        self,
        inputs: torch.FloatTensor,
        attention_mask: Optional[torch.FloatTensor] = None,
        subsampled_output_points: Optional[Dict[str, torch.Tensor]] = None,
        head_mask: Optional[torch.FloatTensor] = None,
        output_attentions: Optional[bool] = None,
        output_hidden_states: Optional[bool] = None,
        return_dict: Optional[bool] = None,
    ) -&amp;gt; Union[Tuple, PerceiverModelOutput]:
        ...
        batch_size, seq_length, _ = inputs.size()
        device = inputs.device

        ... # input preprocessing

        embedding_output = self.embeddings(batch_size=batch_size)

        encoder_outputs = self.encoder(
            ...
        )
        sequence_output = encoder_outputs[0]

        logits = None
        if self.decoder:
            if subsampled_output_points is not None:
                output_modality_sizes = {
                    &quot;audio&quot;: subsampled_output_points[&quot;audio&quot;].shape[0],
                    &quot;image&quot;: subsampled_output_points[&quot;image&quot;].shape[0],
                    &quot;label&quot;: 1,
                }
            else:
                output_modality_sizes = modality_sizes
            decoder_query = self.decoder.decoder_query(
                inputs, modality_sizes, inputs_without_pos, subsampled_points=subsampled_output_points
            )
            decoder_outputs = self.decoder(
                ...
            )
            logits = decoder_outputs.logits

            # add cross-attentions of decoder
            if output_attentions and decoder_outputs.cross_attentions is not None:
                if return_dict:
                    encoder_outputs.cross_attentions = (
                        encoder_outputs.cross_attentions + decoder_outputs.cross_attentions
                    )
                else:
                    encoder_outputs = encoder_outputs + decoder_outputs.cross_attentions
             
             ... # postprocessing

        return PerceiverModelOutput(
            logits=logits,
            last_hidden_state=sequence_output,
            hidden_states=encoder_outputs.hidden_states,
            attentions=encoder_outputs.attentions,
            cross_attentions=encoder_outputs.cross_attentions,
        )&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Vision and Language (Multimodal)</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/240</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Perceiver-and-Perceiver-IO-modality-dataset-task-%EB%93%B1%EC%97%90-%EC%83%81%EA%B4%80-%EC%97%86%EB%8A%94-%EC%9D%BC%EB%B0%98%EC%A0%81%EC%9D%B8-input%EC%9D%84-%EB%8B%A4%EB%A3%A8%EC%96%B4-%EC%9B%90%ED%95%98%EB%8A%94-output%EC%9D%84-%EB%82%B4%EB%8A%94%08%EB%AA%A8%EB%8D%B8-2#entry240comment</comments>
      <pubDate>Fri, 28 Jul 2023 15:17:24 +0900</pubDate>
    </item>
    <item>
      <title>Perceiver and Perceiver IO : modality, dataset, task 등에 상관 없는 일반적인 input을 다루어 원하는 output을 내는 모델! (1)</title>
      <link>https://jjuke-brain.tistory.com/entry/Perceiver%EC%99%80-Perceiver-IO-modality-dataset-shape-%EB%93%B1%EC%97%90-%EC%83%81%EA%B4%80-%EC%97%86%EB%8A%94-%EC%9D%BC%EB%B0%98%EC%A0%81%EC%9D%B8-input%EA%B3%BC-output%EC%9D%84-%EB%8B%A4%EB%A3%A8%EA%B3%A0-%EC%B6%9C%EB%A0%A5%ED%95%98%EB%8A%94-%EB%AA%A8%EB%8D%B8</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Multi-modal, 특히 vision-language model에 관심을 갖게 되면서 관련 논문을 찾아보던 중, task-agnostic, modality-agnostic한 다양한 input을 다룰 수 있는 모델인 Perceiver와, 이에 이어 output까지 원하는 형태로 만들 수 있는 Perceiver IO를 접하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Multi-modal 분야 뿐만 아니라 backbone으로(혹은 아이디어를 활용하여 구조를 변형하여) 훨씬 다양하게 활용될 수 있을 것 같아 두 아키텍쳐를 다룬 논문을 읽고 그 내용을 합쳐서 정리해보려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, Transformer의 핵심인 self-attention과 cross-attention이 여기서도 핵심 개념이기 때문에, 이를 다룬 글을 읽어보는 것을 추천한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1690464956855&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Transformers in Vision - (1) Attention &amp;amp; Transformer&quot; data-og-description=&quot;Transformer가 computer vision에서 어떻게 쓰였는지, 관련 모델이 어떻게 발전하고 있는지 여러 포스팅에 걸쳐서 알아보고자 한다. 이번 포스팅에서는 가장 중요한 기초 내용인 attention과 transformer에 대&quot; data-og-host=&quot;jjuke-brain.tistory.com&quot; data-og-source-url=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; data-og-url=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cW1Jk5/hyTrNsubcZ/UrVNxjFuYkE59ONN9A6c80/img.jpg?width=800&amp;amp;height=269&amp;amp;face=0_0_800_269,https://scrap.kakaocdn.net/dn/cCVGLi/hyTrN650Wy/JTBFJ1XpL0RO2cg8VViia0/img.jpg?width=800&amp;amp;height=269&amp;amp;face=0_0_800_269,https://scrap.kakaocdn.net/dn/bv5P2q/hyTrUZtm38/PBjnjYkGxQu7ES7bsRhak0/img.png?width=1854&amp;amp;height=2656&amp;amp;face=0_0_1854_2656&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cW1Jk5/hyTrNsubcZ/UrVNxjFuYkE59ONN9A6c80/img.jpg?width=800&amp;amp;height=269&amp;amp;face=0_0_800_269,https://scrap.kakaocdn.net/dn/cCVGLi/hyTrN650Wy/JTBFJ1XpL0RO2cg8VViia0/img.jpg?width=800&amp;amp;height=269&amp;amp;face=0_0_800_269,https://scrap.kakaocdn.net/dn/bv5P2q/hyTrUZtm38/PBjnjYkGxQu7ES7bsRhak0/img.png?width=1854&amp;amp;height=2656&amp;amp;face=0_0_1854_2656');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Transformers in Vision - (1) Attention &amp;amp; Transformer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Transformer가 computer vision에서 어떻게 쓰였는지, 관련 모델이 어떻게 발전하고 있는지 여러 포스팅에 걸쳐서 알아보고자 한다. 이번 포스팅에서는 가장 중요한 기초 내용인 attention과 transformer에 대&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jjuke-brain.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, 더 자세한 내용은 2021년 ICML에 발표된 Perceiver 논문 &quot;&lt;a href=&quot;http://proceedings.mlr.press/v139/jaegle21a/jaegle21a.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Perceiver: General Perception with Iterative Attention&lt;/a&gt;&quot;과 2022년 ICLR에 발표된 Perceiver IO 논문 &quot;&lt;a href=&quot;https://arxiv.org/pdf/2107.14795.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Perceiver IO: A General Architecture for Structured Inputs &amp;amp; Outputs&lt;/a&gt;&quot;를 참조하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2D 비전에서의 spatial locality와 같은 inductive bias는 학습의 효율성을 극대화한다. 그러나 large dataset으로 학습을 진행하는 경우 이러한 inductive bias를 활용한 accuracy 뿐만 아니라 flexibility도 중요하다. (inductive bias가 강한 CNN이나 RNN같은 경우, large dataset에 대해 학습시키면 오히려 성능이 제한된다. 자세한 내용은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Inductive-Bias%EB%9E%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 참조하자.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전까지는 input의 modality가 바뀌면 그것을 학습하기 위한 architecture도 바뀌었다. 예를 들어, ResNet과 ViT는 2D grid 구조의 image에, LSTM은 text 등의 sequential data에 특화되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Perceiver&lt;/span&gt;는 &lt;span style=&quot;color: #ee2323;&quot;&gt;Input data의 modality, dataset 및 크기(dimension, size, number)에 상관 없이&lt;/span&gt; 활용 가능한 transformer 기반의 모델이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본격적으로 알아보기에 앞서, 간단하게 Perceiver의 특징을 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Transformer는 공간적, 시간적 복잡도가 \(O(n^2)\)이다. &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Transformers-in-Vision-2-ViT-Swin-Transformer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;ViT&lt;/a&gt;에서는 patch로 나누는 등의 방법으로 이를 해결했지만, Perceiver는 고차원 input의 expressivity와 flexibility를 유지하면서 인지하는 방법을 제안한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Perceiver의 주요 아이디어는 &lt;span style=&quot;color: #ee2323;&quot;&gt;latent space에서&amp;nbsp;input이 통과하는 attention bottleneck을 생성&lt;/span&gt;하는 것이다. 기존 transformer와 달&lt;span style=&quot;color: #333333;&quot;&gt;리 all-to-all attention이 필요 없으므로 quadratic scaling 문제를 해결한다. 또한 network depth와 input size가 분리되어 있으므로 input size에 상관 없이 deep하게 설계할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Asymmetric attention mechanism을 사용하여 &lt;span style=&quot;color: #ee2323;&quot;&gt;Input(Byte array)을 latent bottleneck으로 distillation하는 과정을 반복&lt;/span&gt;한다. 이때, 매우 큰 입력도 받을 수 있다는 특징이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fourier feature를 통해 position encoding을 해준다. 모든 입력 데이터와 position, modality feature를 연관시킴으로써 입력 데이터의 &lt;span style=&quot;color: #ee2323;&quot;&gt;구조(spatial or temporal information)를 반영&lt;/span&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Method&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Overview&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;501&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kVafY/btspepHX2Jq/7jtEm21TzUqk9nwu6xkV1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kVafY/btspepHX2Jq/7jtEm21TzUqk9nwu6xkV1k/img.png&quot; data-alt=&quot;Fig 1. Perceiver pipeline overview&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kVafY/btspepHX2Jq/7jtEm21TzUqk9nwu6xkV1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkVafY%2FbtspepHX2Jq%2F7jtEm21TzUqk9nwu6xkV1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1630&quot; height=&quot;501&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;501&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Perceiver pipeline overview&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 활용하는 변수들을 정리해보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Byte(Input) array \(\mathbf{x} \in \mathbb{R}^{M \times C}\) : 임의의 size를 가진다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(M\) : Input array의 index dimensionality&lt;/li&gt;
&lt;li&gt;\(C\) : Input array의 channel dimensionality&lt;/li&gt;
&lt;li&gt;\(M\)과 \(C\)는 input data의 종류(dataset, modality 등)에 따라 달라진다. 예를 들어, ImageNet을 활용하는 경우 224 by 224 RGB image를 사용하므로 \(M\)은 50,176, \(C\)는 3이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Latent array \(\mathbf{z} \in \mathbb{R}^{N \times D}\) : Latent space 내에서 update되는 array이다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(N\) : Latent array의 index dimensionality&lt;/li&gt;
&lt;li&gt;\(D\) : Latent array의 channel dimensionality&lt;/li&gt;
&lt;li&gt;\(N\)과 \(D\)는 hyperparameter이다. 논문에서 \(N\)은 512, 1024 등이 쓰였고, \(D\)는 8, 16, 32, 64 등이 쓰였다.&lt;/li&gt;
&lt;li&gt;Latent array는 학습된 position encoding으로 초기화(initialize)된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;\(N \ll M\) : 당연한 얘기이지만, latent의 dimension이 input보다 훨씬 작다. 이를 통해 기존 Transformer보다 작은 복잡도를 가질 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Perceiver의 주요 구성 요소는 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Cross attention module&lt;/span&gt; : &lt;span style=&quot;color: #ee2323;&quot;&gt;Latent array와 byte(input) array를 latent array로 맵핑&lt;/span&gt;한다. 이는 Non-causal이며 mask를 사용하지 않는다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Self-attention module (Latent Transformer)&lt;/span&gt; : &lt;span style=&quot;color: #ee2323;&quot;&gt;Latent array를 latent array로 맵핑&lt;/span&gt;한다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Iterative cross-attention &amp;amp; Weight sharing&lt;/span&gt; : &quot;Cross-attention module &amp;rarr; Self-attention modules&quot; block을 반복하며, 효율을 위해 각 block의 cross-attention module끼리, self-attention module들끼리 weight를 공유한다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Position encoding&lt;/span&gt; : 기존 Transformer와 같은 방법(&lt;span style=&quot;color: #ee2323;&quot;&gt;Fourier feature position encoding&lt;/span&gt;)으로 위치 구조(language domain을 예로 들면 '어순')를 부여해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심 연산인 attention을 구현한 코드를 살펴보자. Huggingface에서 제공하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://github.com/huggingface/transformers/tree/v4.31.0/src/transformers/models/perceiver&quot;&gt;Perceiver IO 코드&lt;/a&gt;에서는 self-attention과 cross-attention을 다음 클래스로 구현하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1690525900220&quot; class=&quot;nix&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class PerceiverSelfAttention(nn.Module):
    &quot;&quot;&quot;Multi-headed {cross, self}-attention. Can be used both in the encoder as well as in the decoder.&quot;&quot;&quot;

    def __init__(
        self,
        config,
        is_cross_attention=False,
        qk_channels=None,
        v_channels=None,
        num_heads=1,
        q_dim=None,
        kv_dim=None,
    ):
        super().__init__()
        self.num_heads = num_heads
        # Q and K must have the same number of channels.
        # Default to preserving Q's input's shape.
        if qk_channels is None:
            qk_channels = q_dim
        # V's num_channels determines the shape of the output of QKV-attention.
        # Default to the same number of channels used in the key-query operation.
        if v_channels is None:
            v_channels = qk_channels
        if qk_channels % num_heads != 0:
            raise ValueError(f&quot;qk_channels ({qk_channels}) must be divisible by num_heads ({num_heads}).&quot;)
        if v_channels % num_heads != 0:
            raise ValueError(f&quot;v_channels ({v_channels}) must be divisible by num_heads ({num_heads}).&quot;)

        self.qk_channels = qk_channels
        self.v_channels = v_channels
        self.qk_channels_per_head = self.qk_channels // num_heads
        self.v_channels_per_head = self.v_channels // num_heads

        # Layer normalization
        self.layernorm1 = nn.LayerNorm(q_dim)
        self.layernorm2 = nn.LayerNorm(kv_dim) if is_cross_attention else nn.Identity()

        # Projection matrices
        self.query = nn.Linear(q_dim, qk_channels)
        self.key = nn.Linear(kv_dim, qk_channels)
        self.value = nn.Linear(kv_dim, v_channels)

        self.dropout = nn.Dropout(config.attention_probs_dropout_prob)

    def transpose_for_scores(self, x, channels_per_head):
        new_x_shape = x.size()[:-1] + (self.num_heads, channels_per_head)
        x = x.view(*new_x_shape)
        return x.permute(0, 2, 1, 3)

    def forward(
        self,
        hidden_states: torch.Tensor,
        attention_mask: Optional[torch.FloatTensor] = None,
        head_mask: Optional[torch.FloatTensor] = None,
        inputs: Optional[torch.FloatTensor] = None,
        inputs_mask: Optional[torch.FloatTensor] = None,
        output_attentions: Optional[bool] = False,
    ) -&amp;gt; Tuple[torch.Tensor]:
        hidden_states = self.layernorm1(hidden_states)
        inputs = self.layernorm2(inputs)

        # Project queries, keys and values to a common feature dimension. If this is instantiated as a cross-attention module,
        # the keys and values come from the inputs; the attention mask needs to be such that the inputs's non-relevant tokens are not attended to.
        is_cross_attention = inputs is not None
        queries = self.query(hidden_states)

        if is_cross_attention:
            keys = self.key(inputs)
            values = self.value(inputs)
            attention_mask = inputs_mask
        else:
            keys = self.key(hidden_states)
            values = self.value(hidden_states)

        # Reshape channels for multi-head attention.
        # We reshape from (batch_size, time, channels) to (batch_size, num_heads, time, channels per head)
        queries = self.transpose_for_scores(queries, self.qk_channels_per_head)
        keys = self.transpose_for_scores(keys, self.qk_channels_per_head)
        values = self.transpose_for_scores(values, self.v_channels_per_head)

        # Take the dot product between the queries and keys to get the raw attention scores.
        attention_scores = torch.matmul(queries, keys.transpose(-1, -2))

        batch_size, num_heads, seq_len, q_head_dim = queries.shape
        _, _, _, v_head_dim = values.shape
        hiddens = self.num_heads * v_head_dim

        attention_scores = attention_scores / math.sqrt(q_head_dim)

        if attention_mask is not None:
            # Apply the attention mask (precomputed for all layers in PerceiverModel forward() function)
            attention_scores = attention_scores + attention_mask

        # Normalize the attention scores to probabilities.
        attention_probs = nn.Softmax(dim=-1)(attention_scores)

        # This is actually dropping out entire tokens to attend to, which might
        # seem a bit unusual, but is taken from the original Transformer paper.
        attention_probs = self.dropout(attention_probs)

        # Mask heads if we want to
        if head_mask is not None:
            attention_probs = attention_probs * head_mask

        context_layer = torch.matmul(attention_probs, values)

        context_layer = context_layer.permute(0, 2, 1, 3).contiguous()
        new_context_layer_shape = context_layer.size()[:-2] + (hiddens,)
        context_layer = context_layer.view(*new_context_layer_shape)

        outputs = (context_layer, attention_probs) if output_attentions else (context_layer,)

        return outputs&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, init 함수에서는 query&amp;amp;key channel(둘은 같아야 dot product 연산을 할 수 있다!), value channel, Layer normalization, MLP(query, key, value network), dropout 등을 선언해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;forward에서는 latent array와 input array에 layer normalization을 적용해주고, cross-attention인지 self-attention인지에 따라 qkv attention 연산을 진행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Cross Attention Module (Encoding or Read in Perceiver IO)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;515&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BlfCg/btspfPsMhJo/JoG0dST9no9IqBked6zxOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BlfCg/btspfPsMhJo/JoG0dST9no9IqBked6zxOK/img.png&quot; data-alt=&quot;Fig 2. Cross-attention module in Perceiver pipeline&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BlfCg/btspfPsMhJo/JoG0dST9no9IqBked6zxOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBlfCg%2FbtspfPsMhJo%2FJoG0dST9no9IqBked6zxOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1630&quot; height=&quot;515&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;515&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Cross-attention module in Perceiver pipeline&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;880&quot; data-origin-height=&quot;378&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kPWfq/btspeJM7hig/WivV4FSmBcqkSRYsjrREi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kPWfq/btspeJM7hig/WivV4FSmBcqkSRYsjrREi1/img.png&quot; data-alt=&quot;Fig 3. Cross-attention module&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kPWfq/btspeJM7hig/WivV4FSmBcqkSRYsjrREi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkPWfq%2FbtspeJM7hig%2FWivV4FSmBcqkSRYsjrREi1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;699&quot; height=&quot;300&quot; data-origin-width=&quot;880&quot; data-origin-height=&quot;378&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Cross-attention module&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주요 구성 요소 중 cross-attention module부터 살펴보자. 여기서 Cross-attention은 latent array \(\mathbf{z}\)가 query network(MLP)를 거쳐(projection) query \(\mathbf{q} \in \mathbb{R}^{N \times d_\text{qk}}\), input array \(\mathbf{x}\)가 key, value network(MLP)를 거쳐 각각 key \(\mathbf{k} \in \mathbb{R}^{M \times d_\text{qk}} \), value \(\mathbf{v} \in \mathbb{R}^{M \times d_\text{v}}\)가 되고, 이러한 query, key, value에 대해 \( \mathbf{q} \neq \mathbf{k} = \mathbf{v} \)인 경우의 attention 메커니즘이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Attention score는 다음과 같이 계산한다. (자세한 내용은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 참조하자.)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \operatorname{softmax}(\mathbf{q} \mathbf{k}^\top) \mathbf{v} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; background-color: #f6e199;&quot;&gt;기존 Transformer&lt;/span&gt;의 QKV attention (Query, Key, Value attention) 계산 복잡도는 \(\mathcal{O}(M^2)\), 즉 &lt;span style=&quot;color: #ee2323;&quot;&gt;input size \(M\)에 2차로 비례(quadratically increase)&lt;/span&gt;하는데, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Perceiver&lt;/span&gt;는 latent array와 cross-attention을 해주므로 계산 복잡도가 \(\mathcal{O}(MN)\), 즉 &lt;span style=&quot;color: #ee2323;&quot;&gt;input size \(M\)에 linear&lt;/span&gt;하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Encoder의 코드를 요약하면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1690526205169&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class PerceiverEncoder(nn.Module):
    &quot;&quot;&quot;The Perceiver Encoder: a scalable, fully attentional encoder.&quot;&quot;&quot;

    def __init__(self, config, kv_dim=None):
        super().__init__()
        self.config = config

        # Construct the cross attention layer.
        self.cross_attention = PerceiverLayer(
            config,
            is_cross_attention=True,
            ...
        )

        # Construct a single block of self-attention layers.
        # We get deeper architectures by applying this block more than once.
        self_attention_layers = []
        for _ in range(config.num_self_attends_per_block):
            layer = PerceiverLayer(
                config,
                is_cross_attention=False,
                ...
            )
            self_attention_layers.append(layer)

        self.self_attends = nn.ModuleList(self_attention_layers)

    def forward(
        self,
        hidden_states: torch.Tensor,
        attention_mask: Optional[torch.FloatTensor] = None,
        head_mask: Optional[torch.FloatTensor] = None,
        inputs: Optional[torch.FloatTensor] = None,
        inputs_mask: Optional[torch.FloatTensor] = None,
        output_attentions: Optional[bool] = False,
        output_hidden_states: Optional[bool] = False,
        return_dict: Optional[bool] = True,
    ) -&amp;gt; Union[Tuple, BaseModelOutputWithCrossAttentions]:
        all_hidden_states = () if output_hidden_states else None
        all_self_attentions = () if output_attentions else None
        all_cross_attentions = () if output_attentions else None

        # Apply the cross-attention between the latents (hidden_states) and inputs:
        layer_outputs = self.cross_attention(
            ...
        )
        hidden_states = layer_outputs[0]

        # Apply the block of self-attention layers more than once:
        for _ in range(self.config.num_blocks):
            for i, layer_module in enumerate(self.self_attends):
                layer_head_mask = head_mask[i] if head_mask is not None else None

                layer_outputs = layer_module(
                    ...
                )

                hidden_states = layer_outputs[0]

        return BaseModelOutputWithCrossAttentions(
            last_hidden_state=hidden_states,
            hidden_states=all_hidden_states,
            attentions=all_self_attentions,
            cross_attentions=all_cross_attentions,
        )&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Self-attention Module (Process in Perceiver IO)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;515&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7Zyic/btso93Z22Ih/KXklAcCfdKrqyhIK4S3ijk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7Zyic/btso93Z22Ih/KXklAcCfdKrqyhIK4S3ijk/img.png&quot; data-alt=&quot;Fig 4. Self-attention module in Perceiver pipeline&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7Zyic/btso93Z22Ih/KXklAcCfdKrqyhIK4S3ijk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7Zyic%2Fbtso93Z22Ih%2FKXklAcCfdKrqyhIK4S3ijk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1630&quot; height=&quot;515&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;515&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. Self-attention module in Perceiver pipeline&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Latent Transformer는 Cross attention module의 결과인 &lt;span style=&quot;color: #ee2323;&quot;&gt;bottleneck(latent space)에 사용되는 deep transformer (latent self-attention blocks)&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;884&quot; data-origin-height=&quot;378&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Kk1ho/btso7SLuwpI/y5k3WGZlGKlYKXrjHYmGL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Kk1ho/btso7SLuwpI/y5k3WGZlGKlYKXrjHYmGL1/img.png&quot; data-alt=&quot;Fig 5. Self-attention module&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Kk1ho/btso7SLuwpI/y5k3WGZlGKlYKXrjHYmGL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKk1ho%2Fbtso7SLuwpI%2Fy5k3WGZlGKlYKXrjHYmGL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;729&quot; height=&quot;312&quot; data-origin-width=&quot;884&quot; data-origin-height=&quot;378&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. Self-attention module&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 4에서 볼 수 있듯이, &lt;span style=&quot;color: #ee2323;&quot;&gt;Depth(self-attention의 layer 개수 \(L\))와 input size \(M\)을 완전히 분리시킴으로써 input size에 상관 없이 깊은 layer를 쌓을 수&lt;/span&gt; 있게 되었다. Self-attention은 query \(\mathbf{q} \in \mathbb{R}^{N \times D}\), key \(\mathbf{k} \in \mathbb{R}^{N \times D}\), value \(\mathbf{v} \in \mathbb{R}^{N \times D}\)가 모두 같은 (\(\mathbf{q} = \mathbf{k} = \mathbf{v}\) 경우이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계산 과정은 cross-attention과 동일하다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \operatorname{softmax}(\mathbf{q} \mathbf{k}^\top) \mathbf{v} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 Latent Transformer는 &lt;span style=&quot;color: #ee2323;&quot;&gt;GPT-2 architecture&lt;/span&gt;(Transformer의 decoder 부분을 기반으로 한 architecture)를 사용하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Self-attention의 복잡도는 layer 개수 \(L\)을 고려하면 \(\mathcal{O}(LN^2)\)로 볼 수 있다. 따라서 cross-attention module 및 self-attention module을 모두 고려한 Perceiver의 최종 복잡도는 \(\mathcal{O}(MN + LN^2)\)로, input size \(M\)에 linear하게 복잡도가 증가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Iterative Cross-attention &amp;amp; Weight Sharing&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;868&quot; data-origin-height=&quot;264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dygmk1/btspiacg5QV/qQScbxXAtDG2fxziLijOmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dygmk1/btspiacg5QV/qQScbxXAtDG2fxziLijOmK/img.png&quot; data-alt=&quot;Fig 6. Iterative cross-attention and weight sharing&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dygmk1/btspiacg5QV/qQScbxXAtDG2fxziLijOmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdygmk1%2Fbtspiacg5QV%2FqQScbxXAtDG2fxziLijOmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;868&quot; height=&quot;264&quot; data-origin-width=&quot;868&quot; data-origin-height=&quot;264&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 6. Iterative cross-attention and weight sharing&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Iterative cross-attention&lt;/span&gt;이란,&amp;nbsp;Latent array로 정보를 압축하다보니 한 번의 &quot;cross-attention module, self-attention module&quot; block(cross-attention layer)은 input signal의 detail을 놓칠 수 있다. 이를 해결하기 위해 Fig 6처럼 &lt;span style=&quot;color: #ee2323;&quot;&gt;detail 정보도 학습하기 위해 cross-attention layer를 여러 개 사용&lt;/span&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Weight sharing&lt;/span&gt;이란, parameter efficiency를 위해 &lt;span style=&quot;color: #ee2323;&quot;&gt;서로 다른 cross-attention layer(self-attention module과 cross-attention module)끼리 weight를 공유하는 것&lt;/span&gt;을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cross attention 개수에 따라, cross-attention layer를 어떻게 구성하는가에 따라 performance를 비교해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1188&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dkLLad/btso8z52iFV/kRVvr5lN27NKDQTVqPrYjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dkLLad/btso8z52iFV/kRVvr5lN27NKDQTVqPrYjk/img.png&quot; data-alt=&quot;Fig 7. Performances of variant number of cross attention layers&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dkLLad/btso8z52iFV/kRVvr5lN27NKDQTVqPrYjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdkLLad%2Fbtso8z52iFV%2FkRVvr5lN27NKDQTVqPrYjk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;493&quot; height=&quot;293&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1188&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 7. Performances of variant number of cross attention layers&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Interleaved는 Fig 6처럼 cross-attention &amp;rarr; self-attention layers &amp;rarr; cross-attention &amp;rarr; self-attention layers &amp;rarr; ... 순으로 pipeline이 진행되는 것이고, at start는 시작 부분에 모든 cross-attention layer들을 적용한 후에 self-attention layers를 적용하는 것이다.&lt;/li&gt;
&lt;li&gt;첫 layer 제외한 모든 cross-attention layer의 weight은 공유된다. 처음 layer까지 공유하면 성능이 확 떨어진다고 한다. (개인적으로 이유를 분석해보자면, '처음 latent array는 input에 대한 정보가 전혀 없는 상태이므로, 첫 cross-attention layer에서는 전반적인 input의 정보를 받아들이려 할 것이고, 그 이후에는 점점 detail한 정보를 얻으려 할 것이므로'라고 생각해볼 수 있다.)&lt;/li&gt;
&lt;li&gt;Cross attention 개수가 많아질수록 성능이 좋아지지만 당연히 computational cost도 증가한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Position Encodings&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Permutation invariance and position information&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Attention은 기본적으로 permutation-invariant operation이다. 이는 input의 순서가 바뀌어도 같은 output을 반환한다. 이러한 특성 덕분에 다양한 종류의 data에 적용할 수 있으나, 특정 domain에 최적화되어있지는 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Fourier feature position encodings&lt;/span&gt;는 &lt;span style=&quot;color: #ee2323;&quot;&gt;Fourier transform 기반으로 input data의 위치 정보를 부여&lt;/span&gt;한다. 이는 기존 Transformmer에서 활용한 방식과 같고, 자세한 내용은 다음 글을 참조하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kazemnejad.com/blog/transformer_architecture_positional_encoding/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kazemnejad.com/blog/transformer_architecture_positional_encoding/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1690472592733&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Transformer Architecture: The Positional Encoding - Amirhossein Kazemnejad's Blog&quot; data-og-description=&quot;Transformer architecture was introduced as a novel pure attention-only sequence-to-sequence architecture by Vaswani et al. Its ability for parallelizable training and its general performance improvement made it a popular option among NLP (and recently CV) &quot; data-og-host=&quot;kazemnejad.com&quot; data-og-source-url=&quot;https://kazemnejad.com/blog/transformer_architecture_positional_encoding/&quot; data-og-url=&quot;https://kazemnejad.com/blog/transformer_architecture_positional_encoding/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/g0wF1/hyTrPcTOIl/tyk1YauGoHVkIjUjXwIL2K/img.jpg?width=1500&amp;amp;height=925&amp;amp;face=0_0_1500_925,https://scrap.kakaocdn.net/dn/B1Oi3/hyTrWpxYVl/iSqjEkpVKqO6Bp29kRg0rk/img.png?width=1070&amp;amp;height=517&amp;amp;face=0_0_1070_517,https://scrap.kakaocdn.net/dn/bm0bxu/hyTrNF9eqK/1XbpeReBvetfhXkolzlGf1/img.png?width=786&amp;amp;height=632&amp;amp;face=0_0_786_632&quot;&gt;&lt;a href=&quot;https://kazemnejad.com/blog/transformer_architecture_positional_encoding/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://kazemnejad.com/blog/transformer_architecture_positional_encoding/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/g0wF1/hyTrPcTOIl/tyk1YauGoHVkIjUjXwIL2K/img.jpg?width=1500&amp;amp;height=925&amp;amp;face=0_0_1500_925,https://scrap.kakaocdn.net/dn/B1Oi3/hyTrWpxYVl/iSqjEkpVKqO6Bp29kRg0rk/img.png?width=1070&amp;amp;height=517&amp;amp;face=0_0_1070_517,https://scrap.kakaocdn.net/dn/bm0bxu/hyTrNF9eqK/1XbpeReBvetfhXkolzlGf1/img.png?width=786&amp;amp;height=632&amp;amp;face=0_0_786_632');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Transformer Architecture: The Positional Encoding - Amirhossein Kazemnejad's Blog&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Transformer architecture was introduced as a novel pure attention-only sequence-to-sequence architecture by Vaswani et al. Its ability for parallelizable training and its general performance improvement made it a popular option among NLP (and recently CV)&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;kazemnejad.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Perceiver에서 fourier feature position encoding은 다음과 같이 구현되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1690528398397&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class PerceiverFourierPositionEncoding(PerceiverAbstractPositionEncoding):
    &quot;&quot;&quot;Fourier (Sinusoidal) position encoding.&quot;&quot;&quot;

    def __init__(self, num_bands, max_resolution, concat_pos=True, sine_only=False):
        super().__init__()
        self.num_bands = num_bands
        self.max_resolution = max_resolution
        self.concat_pos = concat_pos
        self.sine_only = sine_only

    @property
    def num_dimensions(self) -&amp;gt; int:
        return len(self.max_resolution)

    def output_size(self):
        &quot;&quot;&quot;Returns size of positional encodings last dimension.&quot;&quot;&quot;
        num_dims = len(self.max_resolution)
        encoding_size = self.num_bands * num_dims
        if not self.sine_only:
            encoding_size *= 2
        if self.concat_pos:
            encoding_size += self.num_dimensions

        return encoding_size

    def forward(
        self,
        index_dims: List[int],
        batch_size: int,
        device: torch.device,
        dtype: torch.dtype,
        pos: torch.FloatTensor = None,
    ) -&amp;gt; torch.FloatTensor:
        pos = _check_or_build_spatial_positions(pos, index_dims, batch_size)
        fourier_pos_enc = generate_fourier_features(
            pos,
            num_bands=self.num_bands,
            max_resolution=self.max_resolution,
            concat_pos=self.concat_pos,
            sine_only=self.sine_only,
        ).to(device=device, dtype=dtype)
        return fourier_pos_enc


def _check_or_build_spatial_positions(pos, index_dims, batch_size):
    &quot;&quot;&quot;
    Checks or builds spatial position features (x, y, ...).

    Args:
      pos (`torch.FloatTensor`):
        None, or an array of position features. If None, position features are built. Otherwise, their size is checked.
      index_dims (`List[int]`):
        An iterable giving the spatial/index size of the data to be featurized.
      batch_size (`int`):
        The batch size of the data to be featurized.

    Returns:
        `torch.FloatTensor` of shape `(batch_size, prod(index_dims))` an array of position features.
    &quot;&quot;&quot;
    if pos is None:
        pos = build_linear_positions(index_dims)
        # equivalent to `torch.broadcast_to(pos[None], (batch_size,) + pos.shape)`
        # but `torch.broadcast_to` cannot be converted to ONNX
        pos = pos[None].expand((batch_size,) + pos.shape)
        pos = torch.reshape(pos, [batch_size, np.prod(index_dims), -1])
    else:
        # Just a warning label: you probably don't want your spatial features to
        # have a different spatial layout than your pos coordinate system.
        # But feel free to override if you think it'll work!
        if pos.shape[-1] != len(index_dims):
            raise ValueError(&quot;Spatial features have the wrong number of dimensions.&quot;)
    return pos

def build_linear_positions(index_dims, output_range=(-1.0, 1.0)):
    &quot;&quot;&quot;
    Generate an array of position indices for an N-D input array.

    Args:
      index_dims (`List[int]`):
        The shape of the index dimensions of the input array.
      output_range (`Tuple[float]`, *optional*, defaults to `(-1.0, 1.0)`):
        The min and max values taken by each input index dimension.

    Returns:
      `torch.FloatTensor` of shape `(index_dims[0], index_dims[1], .., index_dims[-1], N)`.
    &quot;&quot;&quot;

    def _linspace(n_xels_per_dim):
        return torch.linspace(start=output_range[0], end=output_range[1], steps=n_xels_per_dim, dtype=torch.float32)

    dim_ranges = [_linspace(n_xels_per_dim) for n_xels_per_dim in index_dims]
    array_index_grid = meshgrid(*dim_ranges, indexing=&quot;ij&quot;)

    return torch.stack(array_index_grid, dim=-1)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;501&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kVafY/btspepHX2Jq/7jtEm21TzUqk9nwu6xkV1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kVafY/btspepHX2Jq/7jtEm21TzUqk9nwu6xkV1k/img.png&quot; data-alt=&quot;Fig 1. Perceiver pipeline overview&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kVafY/btspepHX2Jq/7jtEm21TzUqk9nwu6xkV1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkVafY%2FbtspepHX2Jq%2F7jtEm21TzUqk9nwu6xkV1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1630&quot; height=&quot;501&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;501&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Perceiver pipeline overview&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지가 Perceiver의 내용이다. 간단히 요약하자면, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Perceiver&lt;/span&gt;는 latent space 내에서 cross-attention 및 self-attention을 적용함으로써 어떤 크기, dataset, modality의 input이던 상관 없이 다룰 수 있게 되었다. 하지만, 마지막 output은 single category(label)으로, classification task에만 활용이 가능하다는 한계가 있다. 이를 해결하여 output도 원하는 structure(shape)로 출력할 수 있게 보완한 모델이 바로 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Perceiver IO&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Perceiver IO&lt;/span&gt;에서는 Perceiver의 cross-attention module(encoding), self-attention module을 그대로 사용하며, 마지막에 또 다른 cross-attention module(decoding) 과정을 추가한다. 저자는 이를 &lt;span style=&quot;color: #ee2323;&quot;&gt;read-process-write architecture&lt;/span&gt;라 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Read ( \( \mathbf{x} \in \mathbb{R}^{M \times C} \rightarrow \mathbf{z} \in \mathbb{R}^{N \times D} \) ) : Input을 latent space로 인코딩하는 과정 (Perceiver의 cross-attention module과 같다.)&lt;/li&gt;
&lt;li&gt;Process ( \( \mathbf{z} \rightarrow \mathbf{z}' \) ) : Latent representation을 정제(refine)하는 과정 (Perceiver의 Latent Transformer와 같다.)&lt;/li&gt;
&lt;li&gt;Write ( \( \mathbf{z} \in \mathbb{R}^{N \times D} \rightarrow \mathbf{y} \in \mathbb{R}^{O \times E} \) ) : Latent space를 디코딩하는 과정
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Read에서처럼 계산 과정과 output size를 분리하여 매우 큰 size도 출력이 가능하다!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 글에서는 Perceiver IO의 Write 부분부터 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Vision and Language (Multimodal)</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/239</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Perceiver%EC%99%80-Perceiver-IO-modality-dataset-shape-%EB%93%B1%EC%97%90-%EC%83%81%EA%B4%80-%EC%97%86%EB%8A%94-%EC%9D%BC%EB%B0%98%EC%A0%81%EC%9D%B8-input%EA%B3%BC-output%EC%9D%84-%EB%8B%A4%EB%A3%A8%EA%B3%A0-%EC%B6%9C%EB%A0%A5%ED%95%98%EB%8A%94-%EB%AA%A8%EB%8D%B8#entry239comment</comments>
      <pubDate>Wed, 26 Jul 2023 22:22:44 +0900</pubDate>
    </item>
    <item>
      <title>파이썬 스크립트로 blender 실행하여 3D 데이터 렌더링하기!</title>
      <link>https://jjuke-brain.tistory.com/entry/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%A1%9C-blender-%EC%8B%A4%ED%96%89%ED%95%98%EC%97%AC-%EB%A0%8C%EB%8D%94%EB%A7%81%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3D 데이터를 blender를 활용하여 2D로 렌더링(정확히 말하자면 &lt;span style=&quot;color: #ee2323;&quot;&gt;3D 데이터를 다양한 각도의 카메라를 기준으로 2D로 projection하여 이미지로 저장&lt;/span&gt;)하려는데, 데이터 양이 많아 GUI로는 작업이 불가능했다. 따라서 파이썬 코드로 3D를 2D로 렌더링 하는 방법을 기록해둔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드는 아래 깃허브를 참조했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/nv-tlabs/GET3D/tree/master/render_shapenet_data&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/nv-tlabs/GET3D/tree/master/render_shapenet_data&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1688552819530&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - nv-tlabs/GET3D&quot; data-og-description=&quot;Contribute to nv-tlabs/GET3D development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/nv-tlabs/GET3D/tree/master/render_shapenet_data&quot; data-og-url=&quot;https://github.com/nv-tlabs/GET3D&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bQ0eZm/hyTebUmne9/MZk3aX7hZnaUfh9worPdnk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/nv-tlabs/GET3D/tree/master/render_shapenet_data&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/nv-tlabs/GET3D/tree/master/render_shapenet_data&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bQ0eZm/hyTebUmne9/MZk3aX7hZnaUfh9worPdnk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - nv-tlabs/GET3D&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to nv-tlabs/GET3D development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Blender 설치&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;작업 환경은 Ubuntu 20.04이며, 도커 컨테이너에서 blender를 설치하여 작업했다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;우선 아래 링크에서 blender를 설치한다. snap으로 blender를 다운받을 수도 있지만, 코드를 돌리려니 permission error, read-only file system error 등이 발생해서 직접 zip파일을 다운받았다. github에서 2.90.0 버전 기준으로 코드를 짰다고 하여, 나도 'blender-2.90.0-linux64.tar.xz'를 다운받았다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.blender.org/download/previous-versions/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.blender.org/download/previous-versions/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1688553027556&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Previous Versions &amp;mdash; blender.org&quot; data-og-description=&quot;Your old files are safe. Every Blender release is available for download.&quot; data-og-host=&quot;www.blender.org&quot; data-og-source-url=&quot;https://www.blender.org/download/previous-versions/&quot; data-og-url=&quot;https://www.blender.org/download/previous-versions/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/oxsXV/hyTecFLeqJ/W2sS3fk9aY4FfLNAZqqpHK/img.png?width=1002&amp;amp;height=460&amp;amp;face=0_0_1002_460,https://scrap.kakaocdn.net/dn/KwnjA/hyTd9hXmWE/2dIaDV4xkhoKOCDGMiqnHK/img.png?width=1002&amp;amp;height=460&amp;amp;face=0_0_1002_460&quot;&gt;&lt;a href=&quot;https://www.blender.org/download/previous-versions/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.blender.org/download/previous-versions/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/oxsXV/hyTecFLeqJ/W2sS3fk9aY4FfLNAZqqpHK/img.png?width=1002&amp;amp;height=460&amp;amp;face=0_0_1002_460,https://scrap.kakaocdn.net/dn/KwnjA/hyTd9hXmWE/2dIaDV4xkhoKOCDGMiqnHK/img.png?width=1002&amp;amp;height=460&amp;amp;face=0_0_1002_460');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Previous Versions &amp;mdash; blender.org&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Your old files are safe. Every Blender release is available for download.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.blender.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;841&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxIJVP/btsmBxg8AQa/6dTWe1lgl3ooOWoY0xdJ0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxIJVP/btsmBxg8AQa/6dTWe1lgl3ooOWoY0xdJ0k/img.png&quot; data-alt=&quot;Download Any Blender&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxIJVP/btsmBxg8AQa/6dTWe1lgl3ooOWoY0xdJ0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxIJVP%2FbtsmBxg8AQa%2F6dTWe1lgl3ooOWoY0xdJ0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;668&quot; height=&quot;481&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;841&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Download Any Blender&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다운받은 파일의 압축을 풀면 바로 사용이 가능하다. 단, command line에서 (스크립트로) 실행하려면, 터미널에서 다음 명령어를 입력해주어야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1688553814160&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo ln -s [blender_directory]/blender /usr/local/bin/blender&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;940&quot; data-origin-height=&quot;17&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lF2ty/btsmzGznuBm/chEEHk6adBUK6NHNSJ1kH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lF2ty/btsmzGznuBm/chEEHk6adBUK6NHNSJ1kH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lF2ty/btsmzGznuBm/chEEHk6adBUK6NHNSJ1kH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlF2ty%2FbtsmzGznuBm%2FchEEHk6adBUK6NHNSJ1kH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;940&quot; height=&quot;17&quot; data-origin-width=&quot;940&quot; data-origin-height=&quot;17&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, 파이썬 스크립트를 통해 블렌더를 사용하려면 몇 가지 작업을 더 해주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 다음과 같이 bpy 패키지(blender python)를 설치해야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1688556362986&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install bpy&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, 몇 가지 라이브러리를 (로컬 또는 컨테이너 환경에서) 설치해주어야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1688556557022&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apt-get install -y libxi6 libgconf-2-4 libfontconfig1 libxrender1

cd [blender_dir]/2.90/python/bin
./python3.7m -m ensurepip
./python3.7m -m pip install numpy&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Rendering with Python&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;렌더링할 3D 데이터셋은 &lt;a href=&quot;https://shapenet.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;ShapeNetCoreV1&lt;/a&gt;로, 디렉토리 구조(일부)는 다음과 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;406&quot; data-origin-height=&quot;443&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q3J2V/btsmyWbKPeL/Q51KryeLMyyVfuoEyUwTlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q3J2V/btsmyWbKPeL/Q51KryeLMyyVfuoEyUwTlk/img.png&quot; data-alt=&quot;렌더링할 데이터셋 폴더 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q3J2V/btsmyWbKPeL/Q51KryeLMyyVfuoEyUwTlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq3J2V%2FbtsmyWbKPeL%2FQ51KryeLMyyVfuoEyUwTlk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;406&quot; height=&quot;443&quot; data-origin-width=&quot;406&quot; data-origin-height=&quot;443&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;렌더링할 데이터셋 폴더 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 &lt;a href=&quot;https://github.com/nv-tlabs/GET3D/tree/master/render_shapenet_data&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;깃허브 링크&lt;/a&gt;의 render_all.py 코드와 render_shapenet_data.py 코드를 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인의 데이터셋과 필요에 따라 코드를 적절히 수정하여 사용하면 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;render_all.py&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1688554552329&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Copyright (c) 2022, NVIDIA CORPORATION &amp;amp; AFFILIATES.  All rights reserved.
#
# NVIDIA CORPORATION &amp;amp; AFFILIATES and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION &amp;amp; AFFILIATES is strictly prohibited.

import os
import argparse

parser = argparse.ArgumentParser(description='Renders given obj file by rotation a camera around it.')
parser.add_argument(
    '--save_folder', type=str, default='./tmp',
    help='path for saving rendered image')
parser.add_argument(
    '--dataset_folder', type=str, default='./tmp',
    help='path for downloaded 3d dataset folder')
parser.add_argument(
    '--blender_root', type=str, default='./tmp',
    help='path for blender')
args = parser.parse_args()

save_folder = args.save_folder
dataset_folder = args.dataset_folder
blender_root = args.blender_root

synset_list = [
    '02958343',  # Car
    '03001627',  # Chair
    '03790512'  # Motorbike
]
scale_list = [
    0.9,
    0.7,
    0.9
]
for synset, obj_scale in zip(synset_list, scale_list):
    file_list = sorted(os.listdir(os.path.join(dataset_folder, synset)))
    for idx, file in enumerate(file_list):
        render_cmd = '%s -b -P render_shapenet.py -- --output %s %s  --scale %f --views 24 --resolution 1024 &amp;gt;&amp;gt; tmp.out' % (
            blender_root, save_folder, os.path.join(dataset_folder, synset, file, 'model.obj'), obj_scale
        )
        os.system(render_cmd)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드는 커맨드라인(터미널)에서 'save_folder'(저장할 폴더명), 'dataset_folder'(렌더링할 데이터셋 폴더명), 'blender_root'(블렌더를 다운받은 곳)를 입력받고, 각 &lt;span style=&quot;color: #ee2323;&quot;&gt;object별로 해당하는 scale에 따라 렌더링 커맨드를 입력&lt;/span&gt;해주는 파이썬 파일이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;render_shapenet.py&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1688556085440&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Copyright (c) 2022, NVIDIA CORPORATION &amp;amp; AFFILIATES.  All rights reserved.
#
# NVIDIA CORPORATION &amp;amp; AFFILIATES and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION &amp;amp; AFFILIATES is strictly prohibited.

import argparse, sys, os, math, re
import bpy
from mathutils import Vector, Matrix
import numpy as np
import json 

parser = argparse.ArgumentParser(description='Renders given obj file by rotation a camera around it.')
parser.add_argument(
    '--views', type=int, default=24,
    help='number of views to be rendered')
parser.add_argument(
    'obj', type=str,
    help='Path to the obj file to be rendered.')
parser.add_argument(
    '--output_folder', type=str, default='/tmp',
    help='The path the output will be dumped to.')
parser.add_argument(
    '--scale', type=float, default=1,
    help='Scaling factor applied to model. Depends on size of mesh.')
parser.add_argument(
    '--format', type=str, default='PNG',
    help='Format of files generated. Either PNG or OPEN_EXR')
parser.add_argument(
    '--resolution', type=int, default=512,
    help='Resolution of the images.')
parser.add_argument(
    '--engine', type=str, default='CYCLES',
    help='Blender internal engine for rendering. E.g. CYCLES, BLENDER_EEVEE, ...')

argv = sys.argv[sys.argv.index(&quot;--&quot;) + 1:]
args = parser.parse_args(argv)

# Set up rendering
context = bpy.context
scene = bpy.context.scene
render = bpy.context.scene.render

render.engine = args.engine
render.image_settings.color_mode = 'RGBA'  # ('RGB', 'RGBA', ...)
render.image_settings.file_format = args.format  # ('PNG', 'OPEN_EXR', 'JPEG, ...)
render.resolution_x = args.resolution
render.resolution_y = args.resolution
render.resolution_percentage = 100
bpy.context.scene.cycles.filter_width = 0.01
bpy.context.scene.render.film_transparent = True

bpy.context.scene.cycles.device = 'GPU'
bpy.context.scene.cycles.diffuse_bounces = 1
bpy.context.scene.cycles.glossy_bounces = 1
bpy.context.scene.cycles.transparent_max_bounces = 3
bpy.context.scene.cycles.transmission_bounces = 3
bpy.context.scene.cycles.samples = 32
bpy.context.scene.cycles.use_denoising = True


def enable_cuda_devices():
    prefs = bpy.context.preferences
    cprefs = prefs.addons['cycles'].preferences
    cprefs.get_devices()

    # Attempt to set GPU device types if available
    for compute_device_type in ('CUDA', 'OPENCL', 'NONE'):
        try:
            cprefs.compute_device_type = compute_device_type
            print(&quot;Compute device selected: {0}&quot;.format(compute_device_type))
            break
        except TypeError:
            pass

    # Any CUDA/OPENCL devices?
    acceleratedTypes = ['CUDA', 'OPENCL']
    accelerated = any(device.type in acceleratedTypes for device in cprefs.devices)
    print('Accelerated render = {0}'.format(accelerated))

    # If we have CUDA/OPENCL devices, enable only them, otherwise enable
    # all devices (assumed to be CPU)
    print(cprefs.devices)
    for device in cprefs.devices:
        device.use = not accelerated or device.type in acceleratedTypes
        print('Device enabled ({type}) = {enabled}'.format(type=device.type, enabled=device.use))

    return accelerated


enable_cuda_devices()
context.active_object.select_set(True)
bpy.ops.object.delete()

# Import textured mesh
bpy.ops.object.select_all(action='DESELECT')


def bounds(obj, local=False):
    local_coords = obj.bound_box[:]
    om = obj.matrix_world

    if not local:
        worldify = lambda p: om @ Vector(p[:])
        coords = [worldify(p).to_tuple() for p in local_coords]
    else:
        coords = [p[:] for p in local_coords]

    rotated = zip(*coords[::-1])

    push_axis = []
    for (axis, _list) in zip('xyz', rotated):
        info = lambda: None
        info.max = max(_list)
        info.min = min(_list)
        info.distance = info.max - info.min
        push_axis.append(info)

    import collections

    originals = dict(zip(['x', 'y', 'z'], push_axis))

    o_details = collections.namedtuple('object_details', 'x y z')
    return o_details(**originals)

# function from https://github.com/panmari/stanford-shapenet-renderer/blob/master/render_blender.py
def get_3x4_RT_matrix_from_blender(cam):
    # bcam stands for blender camera
    # R_bcam2cv = Matrix(
    #     ((1, 0,  0),
    #     (0, 1, 0),
    #     (0, 0, 1)))

    # Transpose since the rotation is object rotation, 
    # and we want coordinate rotation
    # R_world2bcam = cam.rotation_euler.to_matrix().transposed()
    # T_world2bcam = -1*R_world2bcam @ location
    #
    # Use matrix_world instead to account for all constraints
    location, rotation = cam.matrix_world.decompose()[0:2]
    R_world2bcam = rotation.to_matrix().transposed()

    # Convert camera location to translation vector used in coordinate changes
    # T_world2bcam = -1*R_world2bcam @ cam.location
    # Use location from matrix_world to account for constraints:     
    T_world2bcam = -1*R_world2bcam @ location

    # # Build the coordinate transform matrix from world to computer vision camera
    # R_world2cv = R_bcam2cv@R_world2bcam
    # T_world2cv = R_bcam2cv@T_world2bcam

    # put into 3x4 matrix
    RT = Matrix((
        R_world2bcam[0][:] + (T_world2bcam[0],),
        R_world2bcam[1][:] + (T_world2bcam[1],),
        R_world2bcam[2][:] + (T_world2bcam[2],)
        ))
    return RT

imported_object = bpy.ops.import_scene.obj(filepath=args.obj, use_edges=False, use_smooth_groups=False, split_mode='OFF')

for this_obj in bpy.data.objects:
    if this_obj.type == &quot;MESH&quot;:
        this_obj.select_set(True)
        bpy.context.view_layer.objects.active = this_obj
        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.mesh.split_normals()

bpy.ops.object.mode_set(mode='OBJECT')
print(len(bpy.context.selected_objects))
obj = bpy.context.selected_objects[0]
context.view_layer.objects.active = obj

mesh_obj = obj
scale = args.scale
factor = max(mesh_obj.dimensions[0], mesh_obj.dimensions[1], mesh_obj.dimensions[2]) / scale
print('size of object:')
print(mesh_obj.dimensions)
print(factor)
object_details = bounds(mesh_obj)
print(
    object_details.x.min, object_details.x.max,
    object_details.y.min, object_details.y.max,
    object_details.z.min, object_details.z.max,
)
print(bounds(mesh_obj))
mesh_obj.scale[0] /= factor
mesh_obj.scale[1] /= factor
mesh_obj.scale[2] /= factor
bpy.ops.object.transform_apply(scale=True)

bpy.ops.object.light_add(type='AREA')
light2 = bpy.data.lights['Area']

light2.energy = 30000
bpy.data.objects['Area'].location[2] = 0.5
bpy.data.objects['Area'].scale[0] = 100
bpy.data.objects['Area'].scale[1] = 100
bpy.data.objects['Area'].scale[2] = 100

# Place camera
cam = scene.objects['Camera']
cam.location = (0, 1.2, 0)  # radius equals to 1
cam.data.lens = 35
cam.data.sensor_width = 32

cam_constraint = cam.constraints.new(type='TRACK_TO')
cam_constraint.track_axis = 'TRACK_NEGATIVE_Z'
cam_constraint.up_axis = 'UP_Y'

cam_empty = bpy.data.objects.new(&quot;Empty&quot;, None)
cam_empty.location = (0, 0, 0)
cam.parent = cam_empty

scene.collection.objects.link(cam_empty)
context.view_layer.objects.active = cam_empty
cam_constraint.target = cam_empty

stepsize = 360.0 / args.views
rotation_mode = 'XYZ'

model_identifier = os.path.split(os.path.split(args.obj)[0])[1]
synset_idx = args.obj.split('/')[-3]

img_follder = os.path.join(os.path.abspath(args.output_folder), 'img', synset_idx, model_identifier)
camera_follder = os.path.join(os.path.abspath(args.output_folder), 'camera', synset_idx, model_identifier)

os.makedirs(img_follder, exist_ok=True)
os.makedirs(camera_follder, exist_ok=True)

rotation_angle_list = np.random.rand(args.views)
elevation_angle_list = np.random.rand(args.views)
rotation_angle_list = rotation_angle_list * 360
elevation_angle_list = elevation_angle_list * 30
np.save(os.path.join(camera_follder, 'rotation'), rotation_angle_list)
np.save(os.path.join(camera_follder, 'elevation'), elevation_angle_list)

# creation of the transform.json
to_export = {
    'camera_angle_x': bpy.data.cameras[0].angle_x,
    &quot;aabb&quot;: [[-scale/2,-scale/2,-scale/2],
             [scale/2,scale/2,scale/2]]
}
frames = [] 

for i in range(0, args.views):
    cam_empty.rotation_euler[2] = math.radians(rotation_angle_list[i])
    cam_empty.rotation_euler[0] = math.radians(elevation_angle_list[i])

    print(&quot;Rotation {}, {}&quot;.format((stepsize * i), math.radians(stepsize * i)))
    render_file_path = os.path.join(img_follder, '%03d.png' % (i))
    scene.render.filepath = render_file_path
    bpy.ops.render.render(write_still=True)
    # might not need it, but just in case cam is not updated correctly
    bpy.context.view_layer.update()

    rt = get_3x4_RT_matrix_from_blender(cam)
    pos, rt, scale = cam.matrix_world.decompose()

    rt = rt.to_matrix()
    matrix = []
    for ii in range(3):
        a = []
        for jj in range(3):
            a.append(rt[ii][jj])
        a.append(pos[ii])
        matrix.append(a)
    matrix.append([0,0,0,1])
    print(matrix)

    to_add = {\
        &quot;file_path&quot;:f'{str(i).zfill(3)}.png',
        &quot;transform_matrix&quot;:matrix
    }
    frames.append(to_add)

to_export['frames'] = frames
with open(f'{img_follder}/transforms.json', 'w') as f:
    json.dump(to_export, f,indent=4)&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;렌더링을 위한 코드이다. 입력 arguments는 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;views : 렌더링할 view 개수&lt;/li&gt;
&lt;li&gt;obj : 렌더링할 obj 파일 경로&lt;/li&gt;
&lt;li&gt;output_folder : 결과 저장할 폴더&lt;/li&gt;
&lt;li&gt;scale : 모델에 적용할 scaling factor&lt;/li&gt;
&lt;li&gt;format : 생성할 이미지의 파일 포맷&lt;/li&gt;
&lt;li&gt;resolution : 생성할 이미지의 해상도&lt;/li&gt;
&lt;li&gt;engine : 렌더링에 사용할 블렌더에 내장된 엔진&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드를 간단히 요약하자면, 먼저 ArgumentParser로 입력 arguments들을 할당해주고, bpy 모듈을 사용하여 렌더링 관련 setup을 해준 다음, mesh를 import하여 렌더링을 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Execute Rendering&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;터미널에 아래 명령어로 script를 실행한다.&lt;/p&gt;
&lt;pre id=&quot;code_1688560761540&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python render_all.py --save_folder [save_folder] --dataset_folder [dataset_folder] --blender_root [blender_root]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, ShapeNetV1에 적용하기 위해 다음과 같이 입력했다.&lt;/p&gt;
&lt;pre id=&quot;code_1688560904255&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python ./render_all.py save_folder ./ShapeNetCoreV1/rendered --dataset_floder ./ShapeNetCoreV1/ShapeNetCore.v1 --blender_root ~/dev/apps/blender-2.90.0-linux64/blender&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MeshLab에서 열어본 obj파일(3d 모델)과 렌더링하여 이미지로 저장한 결과는 아래와 같다. (총 24개 view)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1404&quot; data-origin-height=&quot;1417&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/t3bgn/btsmz23goFR/IH9nhhbNVnoNILTog7WdZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/t3bgn/btsmz23goFR/IH9nhhbNVnoNILTog7WdZk/img.png&quot; data-alt=&quot;3D model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/t3bgn/btsmz23goFR/IH9nhhbNVnoNILTog7WdZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ft3bgn%2Fbtsmz23goFR%2FIH9nhhbNVnoNILTog7WdZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;349&quot; height=&quot;352&quot; data-origin-width=&quot;1404&quot; data-origin-height=&quot;1417&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;3D model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2944&quot; data-origin-height=&quot;386&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cyPumO/btsmzbT3fJc/cM8rkgvC8ffcHtfTDzoHXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cyPumO/btsmzbT3fJc/cM8rkgvC8ffcHtfTDzoHXk/img.png&quot; data-alt=&quot;왼쪽부터 0, 4, 8, 12, 16, 20번째 view&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cyPumO/btsmzbT3fJc/cM8rkgvC8ffcHtfTDzoHXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcyPumO%2FbtsmzbT3fJc%2FcM8rkgvC8ffcHtfTDzoHXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2944&quot; height=&quot;386&quot; data-origin-width=&quot;2944&quot; data-origin-height=&quot;386&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;왼쪽부터 0, 4, 8, 12, 16, 20번째 view&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Research/Implementation</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/237</guid>
      <comments>https://jjuke-brain.tistory.com/entry/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%A1%9C-blender-%EC%8B%A4%ED%96%89%ED%95%98%EC%97%AC-%EB%A0%8C%EB%8D%94%EB%A7%81%ED%95%98%EA%B8%B0#entry237comment</comments>
      <pubDate>Wed, 5 Jul 2023 19:30:45 +0900</pubDate>
    </item>
    <item>
      <title>CLIP(Contrastive Language-Image Pre-training) 파헤치기!</title>
      <link>https://jjuke-brain.tistory.com/entry/CLIPContrastive-Language-Image-Pre-training%EC%9D%B4%EB%9E%80</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Multi-modal이란 여러 도메인을 사용하는 것을 말한다. 특히 NLP(language, text)분야와 CV(vision, image)분야를 넘나들며 딥러닝을 적용하는 것이 요즘 트렌드인데, image captioning, text-to-image generation, 심지어 3D Vision까지 확장하여 Scene captioning, text-to-shape generation 등 다양한 task가 등장하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 chat-GPT를 발표한 OpenAI 회사에서 2021년 ICLR 학회에 이 분야의 base로 많이 활용되는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;CLIP&lt;/span&gt;이라는 모델을 발표한 논문(&lt;a href=&quot;https://arxiv.org/abs/2103.00020&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Radford et al., Learning Transferable Visual Models From Natural Language Supervision&lt;/a&gt;)을 냈다. (2년도 지나지 않아 인용 횟수가 3500회가 넘었다!) 이에 대해 자세히 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Pre-knowledges&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저, self-supervised learning에 대해 알고있어야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;자세한 내용은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Self-Supervised-Learning#Self-supervised_Learning%EC%9D%B4%EB%9E%80?&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 참조하고, 핵심만 간단히 짚어보고 넘어가자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Self-supervised Learning&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Transformer 기반의 대형 언어 모델들의 성공 요인은 scalability이다. 즉, &lt;span style=&quot;color: #ee2323;&quot;&gt;파라미터 개수가 아주 많은 복잡한 모델&lt;/span&gt;을 통해 다양한 task에서 높은 성능을 보이고 있다. (다른 말로 expressive power가 강하다고도 한다.) 이러한 복잡한 모델을 학습시킬 때 self-supervised learning(training)을 활용한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;익숙한 supervised learning과 비교해보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Supervised learning&lt;/span&gt;은 특정 task에 대한 성능을 높이는 데 최적화되어있다. 따라서 training data에 대한 labeling에 드는 비용이 아주 크다. 그리고 이를 통해 학습한 모델은 특정(구체적인) task에만 최적화, 즉 task-specific하다는 한계가 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이에 비해 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;self-supervised learning&lt;/span&gt;은 &lt;span style=&quot;color: #ee2323;&quot;&gt;labeling되지 않은 방대한 데이터의 representation을 학습&lt;/span&gt;하도록 &lt;span style=&quot;color: #ee2323;&quot;&gt;pre-training&lt;/span&gt;을 진행하는 방법이다. 이후에 특정 task에 따라 fine-tuning 혹은 linear-probing을 거쳐 활용한다. 주요 과정은 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Pre-training for pretext task : Representation 학습 과정&lt;/li&gt;
&lt;li&gt;Transfer learning for downstream(specific) task : Fine-tuning 혹은 linear probing을 통해 특정 task에 적용하는 과정&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Pre-training&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Pretext task&lt;/span&gt;란 pre-training 과정에서 사용하는 task를 말하며, 크게 다음과 같이 나뉜다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Self-prediction : 데이터의 샘플 일부를 마스킹하고(가리고), 그것을 예측하는 task
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Autoregressive generation : Sequential data를 다루는 task (GPT에서 사용)&lt;/li&gt;
&lt;li&gt;Masked generation : Masking을 통해 일반화 성능을 높이는 방법 (BERT에서 사용)&lt;/li&gt;
&lt;li&gt;Hybrid self-prediction : 여러 방식의 pretext task를 혼합한 방식 (DALL-E에서 사용)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Contrastive Learning&lt;/span&gt; : Embedding space 상에서 비슷한 feature 쌍(positive pair)은 가깝게, 다른 feature 쌍(negative pair)은 멀게 embedding하도록 학습하는 task (CLIP에서 사용)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;875&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CyYe1/btrZ9GmR26i/wDfictjw0bAtjGycX2KPfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CyYe1/btrZ9GmR26i/wDfictjw0bAtjGycX2KPfk/img.png&quot; data-alt=&quot;Fig 1. Contrastive Learning Example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CyYe1/btrZ9GmR26i/wDfictjw0bAtjGycX2KPfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCyYe1%2FbtrZ9GmR26i%2FwDfictjw0bAtjGycX2KPfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;833&quot; height=&quot;364&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;875&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Contrastive Learning Example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Fig 1에서 강아지와 고양이 사진으로 contrastive learning의 간단한 예시를 볼 수 있다. 강아지의 오른쪽 위만 남겨둔(나머지는 마스킹한) 사진의 feature \(\theta(x^a)\)와 왼쪽 위를 남겨둔 사진의 feature \(\theta(x^+)\)는 positive pair(둘 다 강아지 사진의 일부)이므로 가깝게, \(\theta(x^a)\)와 고양이의 일부의 feature \(\theta(x^-)\)는 negative pair(서로 다른 사진의 일부)이므로 멀게 embedding하도록 학습하는 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 방법으로 모델은 representation을 학습, 즉 학습된 feature space를 얻게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Transfer Learning&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;학습한 모델을 특정 task에 활용하려면 linear probing 혹은 fine-tuning 과정을 거쳐야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Linear probing&lt;/span&gt;이란, pre-training 과정에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;학습된 weight을 모두 freeze&lt;/span&gt;한 뒤에 모델이 적절한 feature를 만들어내는지(representation을 잘 학습했는지)를 입증하는 방법이다. 즉, pre-training을 잘 했는지 평가하는 방법이라고 생각할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Fine-tuning&lt;/span&gt;은 학습한 representation(weight)을 활용하여 &lt;span style=&quot;color: #ee2323;&quot;&gt;downstream task에 맞게 좀 더 학습을 진행&lt;/span&gt;(weight을 업데이트)하는 방법이다. 간단한 예시로, BERT는 pre-training 과정에서 text를 이해하고, fine-tuning 과정에서 sentence classification, question &amp;amp; answering 등 좀 더 구체적인 downstream task에 대해 학습을 조금 더 진행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Motivation&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 self-supervised learning 방법을 통해 NLP 도메인에서는 방대한 raw text를 사용하여 BERT, GPT 등의 복잡한 모델(task-agnostic architecture)을 pre-training한 후 다양한 task에 활용하는 것이 최근의 트렌드이다. (이미 2017, 2018년에 이루어진 거라 최근이라고 하기에도 조금 지났기는 하다.)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하지만, CV 도메인에서는 2021년 당시 아직도 labeling된 (상대적으로 적은 양의)dataset을 활용했다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;'NLP에서처럼 방대한 web상의 data들을 labeling 없이 활용하여 범용적인(general) 모델을 학습할 수는 없을까?'라는 의문이 CLIP 연구의 시발점이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Related Works&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;기존에도 text로부터 image representation을 학습하려는 시도는 많았다. 대표적으로 pre-training 방식에 따라 transformer 기반의 VirTex(&lt;b&gt;Vi&lt;/b&gt;sual &lt;b&gt;r&lt;/b&gt;epresentations from &lt;b&gt;Tex&lt;/b&gt;tual annotations), masked language modeling 기반의 ICMLM (&lt;b&gt;I&lt;/b&gt;mage-&lt;b&gt;C&lt;/b&gt;onditioned &lt;b&gt;M&lt;/b&gt;asked &lt;b&gt;L&lt;/b&gt;anguage &lt;b&gt;M&lt;/b&gt;odeling), contrastive learning 기반의 ConVIRT(&lt;b&gt;Con&lt;/b&gt;trastive &lt;b&gt;VI&lt;/b&gt;sual &lt;b&gt;R&lt;/b&gt;epresentation learning from &lt;b&gt;T&lt;/b&gt;ext) 등이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;ConVIRT&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;특히 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;ConVIRT&lt;/span&gt;의 경우, 이름에서도 알 수 있듯이 CLIP의 base로 볼 수 있는 모델이다. (실제로 논문에서 CLIP은 ConVIRT의 간소화 버전이라고 언급했다.) ConVIRT 모델의 pre-training 과정을 살펴보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;711&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Lc4Be/btrZ9M1IlLt/8onP8WQ4xAACKfz3KGdIQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Lc4Be/btrZ9M1IlLt/8onP8WQ4xAACKfz3KGdIQ1/img.png&quot; data-alt=&quot;Fig 2. ConVIRT Pipeline&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Lc4Be/btrZ9M1IlLt/8onP8WQ4xAACKfz3KGdIQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLc4Be%2FbtrZ9M1IlLt%2F8onP8WQ4xAACKfz3KGdIQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;711&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;711&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. ConVIRT Pipeline&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Image encoding process&lt;/li&gt;
&lt;li&gt;Text encoding process&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Terminologies&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수들부터 살펴보면, \(\mathbf{x}_v, \mathbf{x}_u\)는 각각 image input, text input이며, \(\mathbf{v}, \mathbf{u}\)는 각각 image feature embedding, text feature embedding이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(t\)는 Stochastic (image or text) transformation function \(\mathcal{T}\)에서 샘플링한 transformation function이다. CLIP에서는 text encoding 시에는 text prompt의 문장이 하나여서 샘플링할 필요는 없으므로 사용하지 않고, image encoding 시에는 random square cropping만 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(f_v\)는 image encoder로 ResNet 50을, \(f_u\)는 text encoder로 BERT encoder를 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(g\)는 Non-linear projection로, ReLU를 사용했다. CLIP에서는 non-linear projection 대신 더 간단히 linear projection을 활용한다. (Non-linear projection 사용 시 현재 이미지의 detail에만 집중하게 된다고 한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Bidirectional loss&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;ConVIRT에서 사용하는 loss는 bidirectional loss이다. CLIP에서 거의 그대로 사용하기 때문에 아주 중요하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Bidirectional loss란 contrastive loss인데, image를 기준으로 한 image-to-text contrastive loss 혹은 text를 기준으로 한 text-to-image contrastive loss를 말한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;수식을 통해 각각을 이해해보자. 먼저 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;image-to-text contrastive loss&lt;/span&gt;는 다음과 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( l_i^{(v \rightarrow u)} = - \log \cfrac{\text{exp}\left( \left\langle \mathbf{v}_i, \mathbf{u}_i \right\rangle / \tau \right)}{\sum\limits_{k=1}^N \text{exp} \left( \left\langle \mathbf{v}_i, \mathbf{u}_k \right\rangle / \tau \right)}&amp;nbsp;\)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(i\)번째 image embedding과 positive pair인 text embedding 간의 거리를 가깝도록 해주기 위한 loss라고 생각하면 쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(\left\langle \mathbf{v}, \mathbf{u} \right\rangle = \mathbf{v}^\top \mathbf{u} / \lVert \mathbf{v} \rVert \lVert \mathbf{u} \rVert\)는 cosine similarity로, Fig 3과 같이 두 벡터가 이루는 각도에 따라 값이 정해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;610&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cB7BL9/btr0dpfUOSx/idBOOKioKhvKXVe9YOeV4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cB7BL9/btr0dpfUOSx/idBOOKioKhvKXVe9YOeV4K/img.png&quot; data-alt=&quot;Fig 3. Cosine Similarity&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cB7BL9/btr0dpfUOSx/idBOOKioKhvKXVe9YOeV4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcB7BL9%2Fbtr0dpfUOSx%2FidBOOKioKhvKXVe9YOeV4K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;699&quot; height=&quot;213&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;610&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Cosine Similarity&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(\tau\)는 temperature parameter라는 hyperparameter로, softmax 내에서의 logit의 범위를 조정해준다. 즉, 값이 커질수록 분포가 뾰족해지고, 작아질수록 분포가 완만해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Loss에 -를 붙여줌으로써(negative loss) &lt;span style=&quot;color: #ee2323;&quot;&gt;loss 값을 최소화함에 따라 \(i\)번째 image embedding과 \(i\)번째 text embedding간의 유사도는 커지고(positive pair), \(i\)번째 image embedding과 \(i\)번째를 포함한 모든 text embedding간의 유사도 합은 작아지는(negative pairs) 효과&lt;/span&gt;를 갖는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 \((\mathbf{v}_i, \mathbf{u}_i)\)를 true pair로 예측하도록 하는 classifier의 개념으로 볼 수 있다. 이럴 때 loss는 아래 식과 같은 개념으로도 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( - \log (\operatorname{softmax}(\left\langle \mathbf{v}_i, \mathbf{u}_i \right\rangle / \tau )) \text{ for } \mathbf{u}_k \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Text-to-image contrastive loss&lt;/span&gt;는 반대로 고정된 \(i\)번째 text embedding에 대해 positive pair인 image embedding을 embedding space에서 가깝도록 조정해주는 loss이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( l_i^{(u \rightarrow v)} = - \log \cfrac{\text{exp}\left( \left\langle \mathbf{u}_i, \mathbf{v}_i \right\rangle / \tau \right)}{\sum\limits_{k=1}^N \text{exp} \left( \left\langle \mathbf{u}_i, \mathbf{v}_k \right\rangle / \tau \right)} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 최종 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;bidirectional loss&lt;/span&gt;는 각 loss에 weight \(\lambda\), \(1 - \lambda\)를 적용하여 다음과 같이 나타낸다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathcal{L} = \cfrac{1}{N} \sum\limits_{i=1}^N \left( \lambda l_i^{(v \rightarrow u)} + (1 - \lambda) l_i^{(u \rightarrow v)} \right) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학습은 다음과 같은 과정으로 진행된다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;\(N\)개 input pair \((\mathbf{x}_v, \mathbf{x}_u)\)의 representation pair \((\mathbf{v}, \mathbf{u})\)를 구함&lt;/li&gt;
&lt;li&gt;Bidirectional loss를 사용하여 image-text pair로 두 modality의 joint representation(embedding) space 학습&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Natural Language Supervision&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그런데 왜 하필 text, 즉 natural language를 활용하여 학습을 할까?&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Motivation으로 돌아가보자. 범용적인 모델을 학습시킬 때 web 상의 방대한 (이미지) 데이터를 사용한다고 하였는데, 이 데이터는 natural language와 vision 정보가 함께 존재하는 경우가 대부분이기 때문이다. 즉, &lt;span style=&quot;color: #ee2323;&quot;&gt;natural language를 활용하는 경우 훨씬 다양한 representation과 supervision이 가능&lt;/span&gt;해진다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Natural language supervision이란, pre-training에서 contrastive learning을 통해 text와 image 쌍을 사용하여 image representation을 학습하는 것을 말한다. Unsupervised, self-supervised, weakly sueprvised 등 다양한 단어로 비슷한 개념을 표현하는데, 논문에서 natural language sueprvision이라는 표현을 사용했다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;특히 CLIP의 경우 데이터의 개수가 압도적으로 많다(Scalability). VirTex, ICMLM, ConVIRT 이전에는 수많은 image를 학습하긴 했으나 word representation(N-gram 등) 방식의 한계로 학습에 수 년이 걸렸고, VirTex, ICMLM, ConVIRT의 경우 며칠 만에 학습하긴 했으나 수십만개 image밖에 학습하지 못했다. 하지만 CLIP은 ConVIRT의 간소화 버전 모델을 &lt;span style=&quot;color: #ee2323;&quot;&gt;4억개의 (image, text) pair data로 학습시켜 scale이 GPT와 유사할만큼 아주 크고, 다양한 downstream task에 적용이 가능&lt;/span&gt;해졌다. Word representation의 측면에서 n-gram등 단순한 방법에 비해 deep contextual representation을 사용하면서 natural language를 supervision으로 더 쉽게 사용할 수 있었다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 web에서 얻은, (image, text) 쌍을 약간의 정제과정을 거쳐 학습에 사용한 4억개의 데이터셋의 이름은 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;WIT (WebImageText)&lt;/span&gt;이다. (GPT-2 학습에 서용했던 WebText와 비슷한 scale이다.) 하지만 애석하게도 openAI에서 이 데이터셋을 공개하지는 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Method&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;다음으로 CLIP의 pre-training 및 zero-shot transfer 과정과, encoder로 어떤 모델을 사용했는지를 좀 더 자세히 알아보자.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Overview&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;756&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oAZgL/btr0aP0eiUv/Rke3fvTHkBklb7f41gfWeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oAZgL/btr0aP0eiUv/Rke3fvTHkBklb7f41gfWeK/img.png&quot; data-alt=&quot;Fig 4. CLIP Overview&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oAZgL/btr0aP0eiUv/Rke3fvTHkBklb7f41gfWeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoAZgL%2Fbtr0aP0eiUv%2FRke3fvTHkBklb7f41gfWeK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;756&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;756&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. CLIP Overview&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학습 과정(pre-training)에서, 일반적인 image model들은 image feature extractor와 linear classifier를 jointly training하여 정답 label을 예측하지만, CLIP은 image encoder와 text encoder를 jointly training하여 알맞은 (image, text) pair를 예측한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Test 과정(linear probing)에서, CLIP은 학습된 text encoder로 target dataset의 class에 대한 description의 embedding을 얻고, 이를 통해 zero-shot prediction을 진행한다. 즉, zero-shot linear classifier 역할로 활용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Pre-Training Method&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Scaling을 위한 핵심은 training efficiency이다!&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1316&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxHnkK/btsi2f6TJm5/CP989bDJsuvEg38tdC2gpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxHnkK/btsi2f6TJm5/CP989bDJsuvEg38tdC2gpk/img.png&quot; data-alt=&quot;Fig 5. Training efficiency of CLIP in zero-shot ImageNet classification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxHnkK/btsi2f6TJm5/CP989bDJsuvEg38tdC2gpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxHnkK%2Fbtsi2f6TJm5%2FCP989bDJsuvEg38tdC2gpk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;520&quot; height=&quot;342&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1316&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. Training efficiency of CLIP in zero-shot ImageNet classification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;위 그림에서  zero-shot ImageNet classification에서 text encoder로 transformer보다 bag of words prediction이 3배, bag of wrods prediction 모델보다 bag of words contrastive 모델이 4배 더 효율적임을 알 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Comparison of various models for pre-training&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ResNeXt, Student EfficientNet 등은 1000개의 ImageNet class에 최적화되어 있으므로 pre-training에 사용하기 적절하지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 VirTex의 경우, CNN과 text transformer를 jointly learning하지만, transformer는 복잡해서 효율적으로 scaling하지 못한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 Bag of words prediction과 bag of words contrastive를 비교해 봤을 때, predictive objective를 사용할 경우에는 image에 해당하는 정확한 word를 예측하려 하므로 일반화 성능이 떨어지고, &lt;span style=&quot;color: #ee2323;&quot;&gt;contrastive objective를 사용하는 것이 image의 전반적인 내용을 담는 text를 예측하려 하므로 더 적합&lt;/span&gt;하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Generative model의 경우에는 high quality의 image representation을 얻을 수는 있으나, 같은 성능 구현을 위해서 contrastive model보다 computational cost가 한 차원 높다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Pre-training process&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;CLIP의 pre-training 과정은 ConVIRT의 간소화 버전으로 생각해볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Pseudo code와 그림으로 이해해보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1686157159080&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# image_encoder - ResNet or Vision Transformer
# text_encoder - CBOW or Text Transformer
# I[n, h, w, c] - minibatch of aligned images
# T[n, l] - minibatch of aligned texts
# W_i[d_i, d_e] - learned projection of image to embedding
# W_t[d_t, d_e] - learned projection of text to embedding
# t - learned temperature parameter (tau)

# Extract feature representations of each modality
I_f = image_encoder(I) # [n, d_i]
T_f = text_encoder(T) # [n, d_t]

# Joint multimodal embeddings
I_e = l2_normalize(np.dot(I_f, W_i), axis=1) # [n, d_e]
T_e = l2_normalize(np.dot(T_f, W_t), axis=1) # [n, d_e]

# Scaled pairwise cosine similiarities
logits = np.dot(I_e, T_e.T) * np.exp(t) # [n, n]

# Symmetric loss function
labels = np.arange(n) # [n,]
loss_i = cross_entropy_loss(logits_per_image, labels, axis=0) # image-to-text contrastive loss
loss_t = cross_entropy_loss(logits_per_text, labels, axis=1) # text-to-image contrastive loss
loss = (loss_i + loss_t) / 2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1517&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xse8w/btsi3caHkfL/cVkPRal7dNCNWt4nlCozm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xse8w/btsi3caHkfL/cVkPRal7dNCNWt4nlCozm0/img.png&quot; data-alt=&quot;Fig 6. Contrastive pre-training&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xse8w/btsi3caHkfL/cVkPRal7dNCNWt4nlCozm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxse8w%2Fbtsi3caHkfL%2FcVkPRal7dNCNWt4nlCozm0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;636&quot; height=&quot;482&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1517&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 6. Contrastive pre-training&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Input은 \(N\)개의 (image, text) pair이고, \(N \times N\)개의 가능한 (image, text) pair를 예측한다. 즉, positive 쌍이면 cosine similarity가 가깝도록, negative 쌍이면 멀도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Contrastive learning을 통해 multi-modal embedding space를 학습하는데, image encoder와 text encoder가 \(N\)개 positive pair(파란색)의 feature의 cosine similarity는 최소화하고, 나머지 \(N^2 - N\)개 negative pair(흰색)의 feature의 cosine similarity는 최대화한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Contrastive loss는 ConVIRT와 같다.  먼저 image-to-text contrastive loss는 아래와 같이 정의한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( l_i^{(v \rightarrow u)} = - \log \cfrac{\operatorname{exp}\left(\left\langle \mathbf{v}_i, \mathbf{u}_i \right\rangle \right)}{\sum\limits_{k=1}^N \operatorname{exp} \left( \left\langle \mathbf{v}_i, \mathbf{u}_k \right\rangle \right)} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\left\langle \mathbf{v}, \mathbf{u} \right\rangle = \mathbf{v}^\top \mathbf{u} / \lVert \mathbf{v} \rVert \lVert \mathbf{u} \rVert \) : Image feature \(\mathbf{v}\)와 text feature \(\mathbf{u}\)의 cosine similarity&lt;/li&gt;
&lt;li&gt;Temperature parameter \(\tau\)는 불필요하게 hyperparameter로 두지 않고, contrastive learning을 진행하면서 학습한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 loss를 최소화한다는 것의 의미는 true pair(positive pair)의 정보를 최대한 보존한다는 것과 같다. 즉, 모든 text embedding과 i번째 image embedding간의 유사도 합은 작게, i번째 text embeddig과 i번째 image embedding간의 유사도는 크게 하는 것이다. ( \(\mathbf{v}_i, \mathbf{u}_i)\)를 true pair로 예측하도록 하는 classifier 개념으로 볼 수 있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림으로 이해해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;351&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cu93IN/btsi2Swz9NL/xg3PM81KVTbVKbZE64gvK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cu93IN/btsi2Swz9NL/xg3PM81KVTbVKbZE64gvK1/img.png&quot; data-alt=&quot;Fig 7. Image-to-text contrastive loss&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cu93IN/btsi2Swz9NL/xg3PM81KVTbVKbZE64gvK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcu93IN%2Fbtsi2Swz9NL%2Fxg3PM81KVTbVKbZE64gvK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;786&quot; height=&quot;351&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;351&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 7. Image-to-text contrastive loss&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Image-to-text contrastive loss를 최소화하는 것은 query image(강아지)에 대한 feature에 대해, &lt;span style=&quot;color: #ee2323;&quot;&gt;embedding space에서 여러 text들 중 positive(true)인 pair에 해당하는 'dog'의 feature는 가깝게, 다른 text feature들은 멀게 위치시키는 과정&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Text-to-image contrastive loss는 다음과 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( l_i^{(u \rightarrow v)} = - \log \cfrac{\operatorname{exp}\left(\left\langle \mathbf{u}_i, \mathbf{v}_i \right\rangle&amp;nbsp; \right)}{\sum\limits_{k=1}^N \operatorname{exp} \left( \left\langle \mathbf{u}_i, \mathbf{v}_k \right\rangle \right)} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Image-to-text contrastive loss가 i번째 image embedding에 관한 loss(Fig 6에서의 행)였다면, text-to-image contrastive loss는 i번째 text embedding에 관한 loss(Fig 6에서의 열)를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종 loss는 다음과 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathcal{L} = \cfrac{1}{N} \sum\limits_{i=1}^N \left( \lambda l_i^{v \rightarrow u} + (1 - \lambda) l_i^{(u \rightarrow v)} \right) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Choosing Models and Scaling&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Image encoder와 text encoder에 어떤 모델을 적용할 수 있는지 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Models for image encoder&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Image encoder로는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;ResNet&lt;/span&gt;이나 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Vision Transformer(ViT)&lt;/span&gt;를 활용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1686160997043&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;_MODELS = {
    &quot;RN50&quot;: &quot;https://openaipublic.azureedge.net/clip/models/afeb0e10f9e5a86da6080e35cf09123aca3b358a0c3e3b6c78a7b63bc04b6762/RN50.pt&quot;,
    &quot;RN101&quot;: &quot;https://openaipublic.azureedge.net/clip/models/8fa8567bab74a42d41c5915025a8e4538c3bdbe8804a470a72f30b0d94fab599/RN101.pt&quot;,
    &quot;RN50x4&quot;: &quot;https://openaipublic.azureedge.net/clip/models/7e526bd135e493cef0776de27d5f42653e6b4c8bf9e0f653bb11773263205fdd/RN50x4.pt&quot;,
    &quot;RN50x16&quot;: &quot;https://openaipublic.azureedge.net/clip/models/52378b407f34354e150460fe41077663dd5b39c54cd0bfd2b27167a4a06ec9aa/RN50x16.pt&quot;,
    &quot;RN50x64&quot;: &quot;https://openaipublic.azureedge.net/clip/models/be1cfb55d75a9666199fb2206c106743da0f6468c9d327f3e0d0a543a9919d9c/RN50x64.pt&quot;,
    &quot;ViT-B/32&quot;: &quot;https://openaipublic.azureedge.net/clip/models/40d365715913c9da98579312b702a82c18be219cc2a73407c4526f58eba950af/ViT-B-32.pt&quot;,
    &quot;ViT-B/16&quot;: &quot;https://openaipublic.azureedge.net/clip/models/5806e77cd80f8b59890b7e101eabd078d9fb84e6937f9e85e4ecb61988df416f/ViT-B-16.pt&quot;,
    &quot;ViT-L/14&quot;: &quot;https://openaipublic.azureedge.net/clip/models/b8cca3fd41ae0c99ba7e8951adf17d267cdb84cd88be6f7c2e0eca1737a03836/ViT-L-14.pt&quot;,
    &quot;ViT-L/14@336px&quot;: &quot;https://openaipublic.azureedge.net/clip/models/3035c92b350959924f9f00213499208652fc7ea050643e8b385c2dac08641f02/ViT-L-14-336px.pt&quot;,
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;ResNet-50은 global average pooling 대신 attention pooling(multi-head QKV attention)을 적용하고, ViT는 거의 그대로 사용하는데, 기존에 patch와 positional encoding을 concat하는 과정에서 layer normalization을 추가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Models for text encoder&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Text encoder에는 Natural Language Supervision을 위해 조금 변형된 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;transformer&lt;/span&gt;를 활용한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Text representation으로는 lower-cased BPE(Byte Pair Encoding)를 활용하고, vocab size는 49,152, max sequence length는 76이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Scaling of image encoder and text encoder&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;성능 향상을 위해 image encoder는 ResNet의 width, depth, resolution을 늘리고, text encoder는 ResNet의 width 증가량에 비례하여 width만 늘린다.(Text encoder의 capacity는 CLIP의 성능에 큰 영향이 없다고 한다.)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Vision and Language (Multimodal)</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/220</guid>
      <comments>https://jjuke-brain.tistory.com/entry/CLIPContrastive-Language-Image-Pre-training%EC%9D%B4%EB%9E%80#entry220comment</comments>
      <pubDate>Thu, 8 Jun 2023 03:04:41 +0900</pubDate>
    </item>
    <item>
      <title>파이썬 패키지(PyPI) 만들어서 배포하기</title>
      <link>https://jjuke-brain.tistory.com/entry/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%ED%8C%A8%ED%82%A4%EC%A7%80PyPI-%EB%A7%8C%EB%93%A4%EC%96%B4%EC%84%9C-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평소 github에서 다양한 사람들의 코드를 가져다 사용할 때면 항상 나에게 맞추어 수정해야 하는 불편함이 있었다. 따라서 유용하게 사용하던 utility function 등을 나에게 맞는 코드로 짜두고, 프로젝트에서 라이브러리로 불러올 수 있게 (pip install ... 등으로 설치하여 사용할 수 있게) 특정 프로젝트 폴더를 파이썬 패키지로 만드는 방법을 알아보려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;PyPI (Python Package Index) 개념 및 회원 가입&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;PyPI는 파이썬의 패키지 저장소 개념이다. 평소 'pip install ...'으로 다운받던 패키지가 보관되는 곳으로 보면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;여기에 나만의 패키지를 만들어 업로드하려면, 우선 회원 가입부터 해야한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pypi.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://pypi.org/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1684916357174&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;PyPI &amp;middot; The Python Package Index&quot; data-og-description=&quot;The Python Package Index (PyPI) is a repository of software for the Python programming language.&quot; data-og-host=&quot;pypi.org&quot; data-og-source-url=&quot;https://pypi.org/&quot; data-og-url=&quot;https://pypi.org/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b1QJFZ/hySKtHptea/vKdrxLufKysya691kbSaQ0/img.jpg?width=300&amp;amp;height=300&amp;amp;face=0_0_300_300&quot;&gt;&lt;a href=&quot;https://pypi.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pypi.org/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b1QJFZ/hySKtHptea/vKdrxLufKysya691kbSaQ0/img.jpg?width=300&amp;amp;height=300&amp;amp;face=0_0_300_300');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;PyPI &amp;middot; The Python Package Index&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The Python Package Index (PyPI) is a repository of software for the Python programming language.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pypi.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;914&quot; data-origin-height=&quot;1472&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6bflg/btshcgfvtHp/whu8pDpDOUQmiicK1HDjVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6bflg/btshcgfvtHp/whu8pDpDOUQmiicK1HDjVK/img.png&quot; data-alt=&quot;PyPI 회원 가입 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6bflg/btshcgfvtHp/whu8pDpDOUQmiicK1HDjVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6bflg%2FbtshcgfvtHp%2Fwhu8pDpDOUQmiicK1HDjVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;441&quot; height=&quot;710&quot; data-origin-width=&quot;914&quot; data-origin-height=&quot;1472&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;PyPI 회원 가입 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;프로젝트 등록&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;우선, 겹치는 프로젝트명이 있는지 찾아보자. PyPI 사이트에서 'Search projects'란에 업로드하고자 하는 프로젝트명대로 검색해본 후, 정확히 일치하는 프로젝트 명이 없다면 등록이 가능한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;프로젝트 폴더 구성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;업로드할 프로젝트 폴더의 구조는 다음과 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-05-24 at 17.22.17@2x.png&quot; data-origin-width=&quot;1900&quot; data-origin-height=&quot;1304&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d9aBBr/btshgoYODNa/ScrnxApLrptv8nCQhErK10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d9aBBr/btshgoYODNa/ScrnxApLrptv8nCQhErK10/img.png&quot; data-alt=&quot;프로젝트 폴더 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d9aBBr/btshgoYODNa/ScrnxApLrptv8nCQhErK10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd9aBBr%2FbtshgoYODNa%2FScrnxApLrptv8nCQhErK10%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1900&quot; height=&quot;1304&quot; data-filename=&quot;CleanShot 2023-05-24 at 17.22.17@2x.png&quot; data-origin-width=&quot;1900&quot; data-origin-height=&quot;1304&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로젝트 폴더 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;루트(root) 폴더 (프로젝트 폴더명) : 꼭 PyPI에 업로드할 프로젝트의 이름일 필요는 없다.&lt;/li&gt;
&lt;li&gt;패키지 폴더명&lt;/li&gt;
&lt;li&gt;setup.py : 루트 폴더 하위에 위치해야 하고, 아래와 같은 정보를 담는다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;name : 프로젝트명 ('pip install [package_name]'에서 package_name에 해당) &amp;rarr; 업로드할 때 대소문자를 굳이 구분하지 않기 위해 위 예시에서의 &quot;JJukE&quot;가 아닌 &quot;jjuke&quot;로 변경하여 업로드하였다.&lt;/li&gt;
&lt;li&gt;version : 보통 '[주요기능추가&amp;amp;대규모변경].[작은기능추가].[버그수정]'와 같은데, 정확히 정해진 것은 아니다. 나는 우선 업로드 해둔 후에 자주 수정할 것 같아서 하위에 하나 더 추가하여 '0.0.0.1' 버전으로 명시했다.&lt;/li&gt;
&lt;li&gt;description : 프로젝트 설명&lt;/li&gt;
&lt;li&gt;author : 프로젝트 소유자 (PyPI에 가입할 때의 Username)&lt;/li&gt;
&lt;li&gt;author_email : 프로젝트 소유자의 이메일 주소 (PyPI에 가입할 때의 email)&lt;/li&gt;
&lt;li&gt;url : 프로젝트의 주소(github 주소)&lt;/li&gt;
&lt;li&gt;install_requires : 프로젝트 실행을 위해 사전에 설치할 파이썬 패키지&lt;/li&gt;
&lt;li&gt;keywords : 프로젝트 검색 시 사용되는 키워드&lt;/li&gt;
&lt;li&gt;python_requires : 최소 파이썬 설치 버전 (ex. python_requires='&amp;gt;=3.6')&lt;/li&gt;
&lt;li&gt;entry_points : 프로그램의 시작점 지정
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;위 예시와 같이 업로드할 경우, 'pip install jjuke'로 패키지를 다운로드한 경우, &quot;jjuke.main:main&quot;을 호출하는 &quot;JJukE.py&quot;를 사용자 디렉터리($HOME/.local/bin)에 생성한다.&lt;/li&gt;
&lt;li&gt;이 때, 같은 프로젝트에 포함된 모듈을 import하는 경우, 명시적으로 상대 경로를 지정해야 한다. 예를 들어, 프로젝트를 실행할 때에는 단순히 'import example'로 같은 경로의 라이브러리(exmple.py파일 등)를 사용할 수 있지만, 패키지를 다운받은 경우에는 site-packages 경로를 기준으로 라이브러리를 찾기 때문에 상대경로로(from .example import *)를 해주어야 하는 것이다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 패키지의 폴더(jjuke 폴더) 하위에는 __init__.py 파일을 추가해주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1950&quot; data-origin-height=&quot;1262&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dBBtGA/btshc40KhTc/lXFokYdGQEkGsCwk5D3J7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dBBtGA/btshc40KhTc/lXFokYdGQEkGsCwk5D3J7k/img.png&quot; data-alt=&quot;__init__.py&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dBBtGA/btshc40KhTc/lXFokYdGQEkGsCwk5D3J7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdBBtGA%2Fbtshc40KhTc%2FlXFokYdGQEkGsCwk5D3J7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1950&quot; height=&quot;1262&quot; data-origin-width=&quot;1950&quot; data-origin-height=&quot;1262&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;__init__.py&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;__init__.py 파일에는 위와 같이 사용할 모듈들과 버전을 명시해준다. 패키지의 버전을 업데이트 할 때에는 &lt;span style=&quot;color: #ee2323;&quot;&gt;setup.py에서 기입했던 버전과 __init__.py의 버전을 모두 업데이트해야&lt;/span&gt; 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;패키지 빌드 및 업로드&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;패키지를 빌드하고 업로드하기 위해 다음 명령어로 setuptools와 wheel을 설치한다.&lt;/p&gt;
&lt;pre id=&quot;code_1684917873702&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install setuptools wheel

# 또는 아나콘다 가상환경에서
conda install -c conda-forge setuptools wheel -y&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;setup.py 파일이 위치한 경로에서 다음 명령어를 실행하면 파이썬 패키지가 생성 및 빌드된다.&lt;/p&gt;
&lt;pre id=&quot;code_1684918109481&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python setup.py sdist bdist_wheel&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-05-24 at 17.48.32@2x.png&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;904&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/miWyW/btsheE1F3GH/l3XkucfIBH3KkZr4FHNcVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/miWyW/btsheE1F3GH/l3XkucfIBH3KkZr4FHNcVK/img.png&quot; data-alt=&quot;패키지 생성 및 빌드 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/miWyW/btsheE1F3GH/l3XkucfIBH3KkZr4FHNcVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmiWyW%2FbtsheE1F3GH%2Fl3XkucfIBH3KkZr4FHNcVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;230&quot; height=&quot;419&quot; data-filename=&quot;CleanShot 2023-05-24 at 17.48.32@2x.png&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;904&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;패키지 생성 및 빌드 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 후에는 위와 같이 build, dist, egg-info와 같은 폴더가 생성된다. (이후 버전을 업로드 할 때에는 setup.py의 version을 수정하고, build, dist, egg-info 폴더를 삭제해주도록 한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제, 만든 패키지를 업로드하기위해 twine 패키지를 사용한다. 먼저, twine 패키지를 다운받고,&lt;/p&gt;
&lt;pre id=&quot;code_1684918260456&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install twine&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 명령어로 패키지를 업로드한다.&lt;/p&gt;
&lt;pre id=&quot;code_1684918486307&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python -m twine upload dist/*&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PyPI의 Username과 Password를 입력하면 업로드가 완료된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1580&quot; data-origin-height=&quot;788&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BZ8bA/btshijbhJxH/iub0D12M9rDVXc8HSSvH81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BZ8bA/btshijbhJxH/iub0D12M9rDVXc8HSSvH81/img.png&quot; data-alt=&quot;업로드 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BZ8bA/btshijbhJxH/iub0D12M9rDVXc8HSSvH81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBZ8bA%2FbtshijbhJxH%2Fiub0D12M9rDVXc8HSSvH81%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1580&quot; height=&quot;788&quot; data-origin-width=&quot;1580&quot; data-origin-height=&quot;788&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;업로드 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2568&quot; data-origin-height=&quot;1928&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AnqZL/btshiaZ20YD/MM0KRlc177wjyRJKl9DsX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AnqZL/btshiaZ20YD/MM0KRlc177wjyRJKl9DsX0/img.png&quot; data-alt=&quot;업로드 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AnqZL/btshiaZ20YD/MM0KRlc177wjyRJKl9DsX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAnqZL%2FbtshiaZ20YD%2FMM0KRlc177wjyRJKl9DsX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2568&quot; height=&quot;1928&quot; data-origin-width=&quot;2568&quot; data-origin-height=&quot;1928&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;업로드 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science, Programming/Python</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/235</guid>
      <comments>https://jjuke-brain.tistory.com/entry/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%ED%8C%A8%ED%82%A4%EC%A7%80PyPI-%EB%A7%8C%EB%93%A4%EC%96%B4%EC%84%9C-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0#entry235comment</comments>
      <pubDate>Wed, 24 May 2023 18:10:09 +0900</pubDate>
    </item>
    <item>
      <title>Flow-based Models (Normalizing Flow) (2)</title>
      <link>https://jjuke-brain.tistory.com/entry/Flow-based-Models-Normalizing-Flow-2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Flow-based-Models-Normalizing-Flow&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Flow-based Models (1)&lt;/a&gt;에서 모델을 전반적으로 이해해보았다. 본 포스팅에서는 flow-based model의 예시를 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flow-based model은 &lt;span style=&quot;color: #ee2323;&quot;&gt;invertible transformation에 어떤 함수를 사용하는지&lt;/span&gt;에 따라 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Planar Flows&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Planar flow에서의 invertible transformation은 다음과 같다. (편의 상 bold체를 따로 사용하지 않고 벡터를 표현한다.)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( x = f_\theta (z) = z + u h (w^\top z + b)&amp;nbsp;\)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 식과 같이 \(\theta = (w, u, b)\)로 parameterize하고, non-linearity \(h(\cdot)\)이 non-linearity라 할 때, Jacobian의 determinant의 절댓값은 다음과 같이 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \begin{align*} \left\vert \operatorname{dete} \left( \cfrac{\partial f_\theta (z)}{\partial z} \right) \right\vert &amp;amp;= \left\vert \operatorname{det} (I + h'(w^\top z + b) u w^\top ) \right\vert \\ &amp;amp;= \left\vert 1 + h'(w^\top z + b) u^\top w \right\vert \end{align*} \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데, invertible 성질을 만족하기 위해서는 다음과 같은 두 가지 제약조건이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( h = \operatorname{tanh} (\cdot) \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( h' (w^\top z + b) u^\top w \geq -1 \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Base distribution \(\pi\)가 Gaussian distribution인 경우와 Uniform distribution인 경우, M개 (&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Flow-based-Models-Normalizing-Flow&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 글&lt;/a&gt;에서의 \(K\)) transformation 후 distribution을 시각화해보면 다음과 같은 결과를 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1270&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d0ouKi/btsbaVUbanS/QnzuTqMxskfzSOnrfrCWW0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d0ouKi/btsbaVUbanS/QnzuTqMxskfzSOnrfrCWW0/img.jpg&quot; data-alt=&quot;Fig 1. Planar Flow result on Gaussian distribution&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d0ouKi/btsbaVUbanS/QnzuTqMxskfzSOnrfrCWW0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd0ouKi%2FbtsbaVUbanS%2FQnzuTqMxskfzSOnrfrCWW0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1270&quot; height=&quot;342&quot; data-origin-width=&quot;1270&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Planar Flow result on Gaussian distribution&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1297&quot; data-origin-height=&quot;310&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dbdTHO/btsa44rs12x/vV9GjM8ki5NHJlKlNRct7k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dbdTHO/btsa44rs12x/vV9GjM8ki5NHJlKlNRct7k/img.jpg&quot; data-alt=&quot;Fig 2. Planar Flows result on uniform distribution&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dbdTHO/btsa44rs12x/vV9GjM8ki5NHJlKlNRct7k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdbdTHO%2Fbtsa44rs12x%2FvV9GjM8ki5NHJlKlNRct7k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1297&quot; height=&quot;310&quot; data-origin-width=&quot;1297&quot; data-origin-height=&quot;310&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Planar Flows result on uniform distribution&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;NICE and Real-NVP&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NICE와 Real-NVP라는 flow-based model을 알아보자. 특히 Real-NVP는 GLOW 등 좋은 성능을 보이는 다른 flow-based model들의 기본이 되는 중요한 모델이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Nonlinear Independent Components Estimation (NICE)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;NICE는 &lt;span style=&quot;color: #ee2323;&quot;&gt;additive coupling layer와 rescaling layer&lt;/span&gt; 이렇게 두 가지 invertible transformation으로 구성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Additive coupling layers&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Additive coupling layer에서는 random variable \(\mathbf{z}\)를 &lt;span style=&quot;color: #ee2323;&quot;&gt;두 subset \(\mathbf{z}_{1:d}\)와 \(\mathbf{z}_{d+1:D}\)으로&lt;/span&gt; 나눈다. 이때 \(1 \leq d &amp;lt; D\)는 랜덤으로 고른다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 layer에서는 두 가지 연산 forward mapping \( \mathbf{z} \mapsto \mathbf{x} \)와 inverse mapping \( \mathbf{x} \mapsto \mathbf{z} \)을 수행한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 forward mapping은 아래와 같이 진행된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{x}_{1:d} = \mathbf{z}_{1:d} \quad \text{identity transformation} \)&lt;br /&gt;\( \mathbf{x}_{d+1:D} = \mathbf{z}_{d+1:D} - \mathcal{M}_{\boldsymbol{\theta}} (\mathbf{z}_{1:d}) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\mathcal{M}_{\boldsymbol{\theta}}\) : \(d\)개 input units, \(D-d\)개 output units를 갖는 neural network&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 subset에 대해서는 identity transformation(그대로 transform), 두 번째 subset에 대해서는 첫 번째 subset을 입력한 neural network의 결과를 뺀 결과를 \(x\)로 맵핑하는 transformation이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 Jacobian은 다음과 같이 계산한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{J} = \cfrac{\partial \mathbf{x}}{\partial \mathbf{z}} = \begin{bmatrix} \mathbf{I}_{d \times d} &amp;amp; \boldsymbol{0}_{d \times (D-d)} \\ \cfrac{\partial \mathbf{x}_{d+1:D}}{\partial \mathbf{z}_{1:d}} &amp;amp; \mathbf{I}_{(D-d) \times (D-d)} \end{bmatrix} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jacobian은 lower triangular matrix 형태로 나오며, determinant가 1이므로 volume이 보존된다. (volume preserving transformation)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 inverse mapping은 아래와 같이 진행한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{z}_{1:d} = \mathbf{x}_{1:d} \quad \text{identity transformation} \)&lt;br /&gt;\( \mathbf{z}_{d+1:D} = \mathbf{x}_{d+1:D} + \mathcal{M}_{\boldsymbol{\theta}} (\mathbf{x_{1:d}})&amp;nbsp; \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Forward mapping에서 사용했던 neural network를 그대로 활용하여 \(\mathbf{x}\)를 \(\mathbf{z}\)로 맵핑한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NICE에서는 여러 개의 서로 다른 \(d\)값을 갖는, 즉 partition이 서로 다른 additive coupling layer들을 거친다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Rescaling layeres&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Rescaling layer는 여러 additive coupling layer를 거친 후 마지막 layer에서 동작하는 transformation이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;마찬가지로 forward mapping \( \mathbf{z} \mapsto \mathbf{x} \)와 inverse mapping \( \mathbf{x} \mapsto \mathbf{z} \)을 수행한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Forward mapping부터 살펴보자.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( x_i = s_i z_i \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(s_i\) : \(i\)번째 dimension에 대한 scaling factor&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 단순히 \(\mathbf{z}\)의 요소 각각에 scaling factor를 곱해주는 과정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jacobian도 간단하다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{J} = \operatorname{diag} (s) \)&lt;br /&gt;\( \operatorname{det} (\mathbf{J}) = \prod\limits_{i=1}^D s_i \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Inverse mapping은 자연스럽게 다음과 같이 계산한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( z_i = \cfrac{x_i}{s_i} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Real-valued Non-volume Preserving Flows (Real-NVP)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Real-NVP도 NICE와 비슷하게 &lt;span style=&quot;color: #ee2323;&quot;&gt;coupling layer와 permutation layer&lt;/span&gt; 두 가지 layer로 구성된다. 단, 이름에서 알 수 있듯이, Jacobian의 determinant가 1이 아닌, &lt;span style=&quot;color: #ee2323;&quot;&gt;non-volume preserving transformation&lt;/span&gt;을 활용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Coupling layers&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;NICE에서의 additive coupling layer와 마찬가지로, 우선 variable \(\mathbf{z}\)를 두 subset \(\mathbf{z}_{1:d}\)와 \(\mathbf{z}_{d+1:D}\)으로 나눈다. (마찬가지로 \(1 \leq d &amp;lt; D\))&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Forward mapping \(\mathbf{z} \mapsto \mathbf{x}\)는 다음과 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{x}_{1:d} = \mathbf{z}_{1:d} \quad \text{identity transformation} \)&lt;br /&gt;\( \mathbf{x}_{d+1:D} = \mathbf{z}_{d+1:D} \odot \operatorname{exp} \left( s&amp;nbsp;(\mathbf{z}_{1:d}) \right) + t&amp;nbsp;\left( \mathbf{z}_{1:d} \right) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(s(\cdot)\), \(t(\cdot)\) : 각각 &lt;span style=&quot;color: #ee2323;&quot;&gt;scaling, transition neural network&lt;/span&gt;로, \(d\)개 units을 입력받아 \(n-d\)개 units를 출력한다.&lt;/li&gt;
&lt;li&gt;\(\odot\) : Element-wise 곱(production)을 나타낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Inverse mapping \(\mathbf{x} \mapsto \mathbf{z}\)는 다음과 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{z}_{1:d} = \mathbf{x}_{1:d} \quad \text{identity transformation} \)&lt;br /&gt;\( \mathbf{z}_{d+1:D} = \left( \mathbf{x}_{d+1:D} - t ( \mathbf{x}_{1:d} ) \right) \odot \operatorname{exp} \left( - s ( \mathbf{x}_{1:d} ) \right) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jacobian과 그 determinant는 다음과 같이 계산한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{J} = \cfrac{\partial \mathbf{x}}{\partial \mathbf{z}} = \begin{bmatrix} \mathbf{I}_{d \times d} &amp;amp; \boldsymbol{0}_{d \times (D - d)} \\ \cfrac{\partial \mathbf{x}_{d+1:D}}{\partial \mathbf{x}_{1:d}} &amp;amp; \operatorname{diag} \left( \operatorname{exp} \left( s(\mathbf{x}_{1:d}) \right) \right) \end{bmatrix} \)&lt;br /&gt;\( \operatorname{det} ( \mathbf{J} ) = \prod\limits_{j=1}^{D-d} \operatorname{exp} \left( s (\mathbf{x}_{1:d} ) \right)_j = \operatorname{exp} \left( \sum\limits_{j=1}^{D-d} s ( \mathbf{x}_a )_j \right) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 경우, determinant 값이 1이 아닐수도 있다. 즉 non-preserving volume transformation이므로 더 general한 모델이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;MAF, IAF, Parallel Wavenet&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Real-NVP까지는 flow-based model에서 어떤 transformation을 사용하는가로 구분지었다. 그런데, &lt;span style=&quot;color: #ee2323;&quot;&gt;autoregressive model을 flow model처럼&lt;/span&gt; 사용할 수도 있다. 이러한 방법을 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;autoregressive flow&lt;/span&gt;라 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;아래와 같은 Gaussian autoregressive model을 복기해보자.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(\mathbf{x}) = \prod\limits_{i=1}^n p(x_i | \mathbf{x}_{&amp;lt;i}) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 conditional distribution \( p(x_i | \mathbf{x}_{&amp;lt;i}) \)는 Gaussian distirbution \(\mathcal{N} \left( \mu_i (x_1, \cdots, x_{i-1}), \operatorname{exp} \left( \alpha_i (x_1, \cdots, x_{i-1}) \right)^2 \right) \)을 따르며, \(\mu_i(\cdot)\)와 \(\alpha_i(\cdot)\)는 \(i = 1\)일 때 constant, \(i&amp;gt;1\)일 때 neural network이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;즉, autoregressive flow는 결국 &lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;standard Gaussian에서 샘플링한 \(\mathbf{z}\)를 모델이 생성한 샘플 \(\mathbf{x}\)로 맵핑하는 것이고, 이때 \(\mu_i(\cdot), \alpha_i(\cdot)\)로 parameterize한 invertible transformation을 활용&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Masked Autoregressive Flow (MAF)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;465&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwZV1d/btsa9yE35wX/IXXVNzejGsVTnuCw9kTE41/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwZV1d/btsa9yE35wX/IXXVNzejGsVTnuCw9kTE41/img.jpg&quot; data-alt=&quot;Fig 3. MAF&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwZV1d/btsa9yE35wX/IXXVNzejGsVTnuCw9kTE41/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwZV1d%2Fbtsa9yE35wX%2FIXXVNzejGsVTnuCw9kTE41%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;602&quot; height=&quot;465&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;465&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. MAF&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MAF의 forward mapping \(\mathbf{z} \mapsto \mathbf{x}\) 과정은 다음과 같다. (sequential)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(i = 1, \cdots, n\)에 대해 \( z_i \sim \mathcal{N} (0, 1)\) 샘플링&lt;/li&gt;
&lt;li&gt;\( x_1 = \operatorname{exp}(\alpha_1) z_1 + \mu_1&amp;nbsp; \)으로 두고, \(\mu_2(x_1)\)와 \(\alpha_2(x_1)\) 계산&lt;/li&gt;
&lt;li&gt;\( x_2 = \operatorname{exp}(\alpha_2) z_2 + \mu_2 \)으로 두고, \(\mu_3(x_1, x_2)\)와 \(\alpha_3(x_1, x_2)\) 계산&lt;/li&gt;
&lt;li&gt;\( \cdots\)&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 샘플링을 할 때 autoregressive하게 이전 value들을 사용하여 계산함으로써 &lt;span style=&quot;color: #ee2323;&quot;&gt;샘플링 시간이 오래걸린다&lt;/span&gt;는 특징이 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;MAF의 inverse mapping \(\mathbf{x} \mapsto \mathbf{z}\) 과정은 다음과 같다. (parallel)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 \(\mu_i\)와 \(\alpha_i\)를 계산한다. (모든 \(\mathbf{x}\)를 알고 있으므로 parallel computation 가능) &amp;rarr;&amp;nbsp;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Autoregressive-Generative-Models-2#Masked_AE_for_Distribution_Estimation_(MADE)&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;MADE 모델의 과정&lt;/a&gt;과 같다.&lt;/li&gt;
&lt;li&gt;\( z_i = (x_i - \mu_i) / \operatorname{exp} ( \alpha_i )\)로 \(\mathbf{z}\)를 구한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, MAF는 &lt;span style=&quot;color: #ee2323;&quot;&gt;샘플링을 할 때에는 autoregressisve하게(이전 value들을 사용하여) 계산해야 하기 때문에 느리지만, likelihood를 구할 때(training할 때)에는 빠르게&lt;/span&gt; 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Inverse Autoregressive Flow (IAF)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;IAF는 말그대로 MAF와 forward, inverse mapping 방법이 반대이다. 즉, MAF 수식에서 \(\mathbf{x}\)와 \(\mathbf{z}\)를 바꾸면 IAF이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;468&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dl4YQ7/btsa7sL2CXF/8aaMyfIWRJBgPRczc2w2U0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dl4YQ7/btsa7sL2CXF/8aaMyfIWRJBgPRczc2w2U0/img.jpg&quot; data-alt=&quot;Fig 4. IAF&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dl4YQ7/btsa7sL2CXF/8aaMyfIWRJBgPRczc2w2U0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdl4YQ7%2Fbtsa7sL2CXF%2F8aaMyfIWRJBgPRczc2w2U0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;602&quot; height=&quot;468&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. IAF&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IAF의 forward mapping \(\mathbf{z} \mapsto \mathbf{x}\) 과정은 다음과 같다. (parallel)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 \(i = 1, \cdots, n\)에 대해 \(z_i \sim \mathcal{N}(0, 1)\)를 샘플링한다.&lt;/li&gt;
&lt;li&gt;모든 \(\mu_i, \alpha_i\)를 계산한다.&lt;/li&gt;
&lt;li&gt;\(x_i = \operatorname{exp}(\alpha_i) z_i + \mu_i\)로 \(\mathbf{x}\)를 계산한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Inverse mapping \(\mathbf{x} \mapsto \mathbf{z}\) 과정은 다음과 같다. (sequential)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(z_1 = (x_1 - \mu_1 ) / \operatorname{exp}(\alpha_1)\)로 \( \mu_2(x_1), \alpha_2(x_1) \)을 계산한다.&lt;/li&gt;
&lt;li&gt;\(z_2 = (x_2 - \mu_2 ) / \operatorname{exp}(\alpha_2)\)로 \( \mu_3(x_1, x_2), \alpha_3(x_1, x_2)\)를 계산한다.&lt;/li&gt;
&lt;li&gt;\(\cdots\)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, &lt;span style=&quot;color: #ee2323;&quot;&gt;sampling은 빠르지만 training이 느리다&lt;/span&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Parallel Wavenet&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;MAF와 IAF처럼, 샘플링 시간과 학습 시간은 trade-off 관계이다. 그런데, Parallel Wavenet 모델에서는 knowledge distillation을 활용하여 training 시에는 MAF의 이점을, sampling 시에는 IAF의 이점을 활용한다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Training은 두 단계로 나뉜다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Teacher model (MAF)를 학습한다.&lt;/li&gt;
&lt;li&gt;Student model (IAF)를 학습한다. 이때 loss는 아래와 같은 KL divergence를 활용한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( D_\text{KL} (s, t) = \mathbb{E}_{\mathbb{x} \sim s} \left[ \log s(\mathbf{x}) - \log t(\mathbf{x}) \right] \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Objective는 다음과 같이 나타낼 수 있다.&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \underset{\boldsymbol{\theta}}{\operatorname{argmin}} D_\text{KL} \left[ t(x_i) - s(x_i) \right] \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Test(evaluation) 시에는 IAF 기반의 student model을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Generative Models</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/234</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Flow-based-Models-Normalizing-Flow-2#entry234comment</comments>
      <pubDate>Tue, 18 Apr 2023 23:16:32 +0900</pubDate>
    </item>
    <item>
      <title>Flow-based Models (Normalizing Flow) (1)</title>
      <link>https://jjuke-brain.tistory.com/entry/Flow-based-Models-Normalizing-Flow</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Autoregressive-Generative-Models-2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Autoregressive models 글&lt;/a&gt;에서 autoregressive generative model에 대해 다뤄보았다.&lt;/p&gt;
&lt;figure id=&quot;og_1681794761316&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Autoregressive (Generative) Models (2)&quot; data-og-description=&quot;목차 이전 글에 이어, autoregressive generative model에 어떤 모델이 있는지 좀 더 살펴보자. 다음은 다양한 deep generative model 의 비교 표이다. Autoencoder based ARM Autoregressive Models (ARM) vs Autoencoders (AE) Autoenco&quot; data-og-host=&quot;jjuke-brain.tistory.com&quot; data-og-source-url=&quot;https://jjuke-brain.tistory.com/entry/Autoregressive-Generative-Models-2&quot; data-og-url=&quot;https://jjuke-brain.tistory.com/entry/Autoregressive-Generative-Models-2&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/2qe9g/hySi5aGyVn/kf0Gx7f2oaPfcdrgUDcijK/img.jpg?width=800&amp;amp;height=182&amp;amp;face=0_0_800_182,https://scrap.kakaocdn.net/dn/wvJ3o/hySkXWppdl/Jv5HQkcguc3E0wA7kYiIP0/img.jpg?width=800&amp;amp;height=182&amp;amp;face=0_0_800_182,https://scrap.kakaocdn.net/dn/pd38Y/hySi5V4CYG/tLDUOvQ1X5DDAic3goHKF0/img.png?width=1888&amp;amp;height=1000&amp;amp;face=0_0_1888_1000&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Autoregressive-Generative-Models-2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jjuke-brain.tistory.com/entry/Autoregressive-Generative-Models-2&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/2qe9g/hySi5aGyVn/kf0Gx7f2oaPfcdrgUDcijK/img.jpg?width=800&amp;amp;height=182&amp;amp;face=0_0_800_182,https://scrap.kakaocdn.net/dn/wvJ3o/hySkXWppdl/Jv5HQkcguc3E0wA7kYiIP0/img.jpg?width=800&amp;amp;height=182&amp;amp;face=0_0_800_182,https://scrap.kakaocdn.net/dn/pd38Y/hySi5V4CYG/tLDUOvQ1X5DDAic3goHKF0/img.png?width=1888&amp;amp;height=1000&amp;amp;face=0_0_1888_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Autoregressive (Generative) Models (2)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;목차 이전 글에 이어, autoregressive generative model에 어떤 모델이 있는지 좀 더 살펴보자. 다음은 다양한 deep generative model 의 비교 표이다. Autoencoder based ARM Autoregressive Models (ARM) vs Autoencoders (AE) Autoenco&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jjuke-brain.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-04-17 at 18.41.24.jpg&quot; data-origin-width=&quot;1133&quot; data-origin-height=&quot;258&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbXM0t/btsaUk19JyB/CGF47stTSV85kyMb6KJ4Sk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbXM0t/btsaUk19JyB/CGF47stTSV85kyMb6KJ4Sk/img.jpg&quot; data-alt=&quot;Fig 1. Comparison of deep generative models (1)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbXM0t/btsaUk19JyB/CGF47stTSV85kyMb6KJ4Sk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbXM0t%2FbtsaUk19JyB%2FCGF47stTSV85kyMb6KJ4Sk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1133&quot; height=&quot;258&quot; data-filename=&quot;CleanShot 2023-04-17 at 18.41.24.jpg&quot; data-origin-width=&quot;1133&quot; data-origin-height=&quot;258&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Comparison of deep generative models (1)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Deep generative model들 중 이번에는 flow-based model(=normalizing flow model)을 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; Introduction&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-04-18 at 14.48.55.jpg&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;391&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdkbhk/btsa5VUPkW6/5yuZXeqUqqZXNwcUdVyBV0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdkbhk/btsa5VUPkW6/5yuZXeqUqqZXNwcUdVyBV0/img.jpg&quot; data-alt=&quot;Fig 2. Taxonomy of deep generative models&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdkbhk/btsa5VUPkW6/5yuZXeqUqqZXNwcUdVyBV0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcdkbhk%2Fbtsa5VUPkW6%2F5yuZXeqUqqZXNwcUdVyBV0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;820&quot; height=&quot;391&quot; data-filename=&quot;CleanShot 2023-04-18 at 14.48.55.jpg&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;391&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Taxonomy of deep generative models&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Autoregressive generative model의 경우, likelihood를 계산할 수 있고, long-range statistics를 학습할 수 있다는 장점을 갖지만, sampling이 느리고 feature를 학습할 방법은 없다 (lack a latent representation).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flow-based model(=Normalizing flow model)은 &lt;span style=&quot;color: #ee2323;&quot;&gt;likelihood 계산을 할 수 있으면서(\(p(\mathbf{x})\)를 직접적으로 모델링하면서) latent variable을 설계&lt;/span&gt;할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Flow-based model&lt;/span&gt;의 핵심은 &lt;span style=&quot;color: #ee2323;&quot;&gt;simple한 prior distribution으로부터 복잡한 data distribution을 모델링&lt;/span&gt;하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본격적으로 flow-based model에 대해 알아보기 이전에 다음과 같이 알아두어야 할 사전지식이 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Change of variables (in porbability)&lt;/li&gt;
&lt;li&gt;Jacobian of invertible functions&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Change of Variables Theorem in Probability Densify Function &lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Change of variables(변수 변환)를 영어로 표현해서 낯선데, 사실 고등학교 때 배운 내용이다. 다음 식을 보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( x^6 - 9 x^3 + 8 = 0\)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 식에서 x의 해를 구할 때, \(x^3 = t\)로 치환하면 다음과 같이 이차방정식으로 표현된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( t^2 - 9t + 8 = 0\)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이후 t의 해를 구하고, 그 해를 이용하여 x의 해를 구하는 방식으로 문제를 풀었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 확률 개념에 적용해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Single random variable \(z \sim \pi(z)\)에 대해, invertible한 일대일 함수 \(f\)를 가정하고, 새로운 random variable \(x = f(z)\)를 구성한다. 이때 \(x\)의 확률 분포 \(p(x)\)와 \(z\)의 분포 \(\pi(z)\)는 다음을 만족한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \int{p(x) dx} = \int \pi (z) dz = 1 \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 함수 \(f\)가 scalar &amp;rarr; scalar transformation인 경우, 다음과 같이 변수를 변환해줄 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(x) = \pi(z) \left\vert \cfrac{dz}{dx} \right\vert = \pi(f^{-1}(x)) \left\vert \cfrac{df^{-1}}{dx} \right\vert&amp;nbsp;\)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 &lt;span style=&quot;color: #ee2323;&quot;&gt;multivariable&lt;/span&gt;로 확장, 즉 함수 \(f\)가 vector &amp;rarr; vector transformation인 경우로 확장하면 다음과 같이 변수를 변환한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(\mathbf{x}) = \pi(\mathbf{z}) \left\vert \operatorname{det} \cfrac{\partial \mathbf{z}}{\partial \mathbf{x}} \right\vert = \pi( f^{-1} (\mathbf{x})) \left\vert \operatorname{det} \cfrac{\partial f^{-1}}{\partial \mathbf{x}} \right\vert \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;식의 determinant term은 chage of variables를 통해 invertible transformation \(f^{-1}\)을 적용한 후의 distribution \(\pi(\mathbf{z}\)\)를 &lt;span style=&quot;color: #ee2323;&quot;&gt;normalize&lt;/span&gt;해주는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 &lt;span style=&quot;color: #ee2323;&quot;&gt;알지 못하는 확률 분포 \(p(\mathbf{x})\)를 \(\mathbf{z}\)의 probability density function으로 표현&lt;/span&gt;해줄 수 있다. (이론상으로는 거의 대부분의 복잡한 distribution을 간단한 distribution으로 바꿀 수 있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Jacobian of Invertible Functions&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;위와 같이 \(\mathbf{x} = (x_1, \cdots, x_n) = f(\mathbf{z}) = (f_1(z), \cdots, f_n(z)) \)의 예시에서 \(f\)의 Jacobian \(\mathbf{J}_{f}\)는 다음과 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( \mathbf{J}_{f} (\mathbf{z}) = \cfrac{\partial f}{\partial \mathbf{z}} = \begin{bmatrix} \cfrac{\partial f_1}{\partial z_1} &amp;amp; \cdots &amp;amp; \cfrac{\partial f_1}{\partial z_n} \\ \vdots &amp;amp; \ddots &amp;amp; \vdots \\ \cfrac{\partial f_n}{\partial z_1} &amp;amp; \cdots &amp;amp; \cfrac{\partial f_n}{\partial z_n} \end{bmatrix} \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 \(x = f(z)\)이고, \(f\)가 invertible function이면 다음을 만족한다. (Inverse function theorem)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( \cfrac{d f^{-1}(x)}{dx} = \cfrac{d z}{d x} = \left( \cfrac{d x}{d z} \right)^{-1} = \left( \cfrac{df(z)}{dz} \right)^{-1} \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이를 Jacobian 각 항에 모두 적용하면, inverse function의 Jacobian은 다음을 만족한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{J}_{f^{-1}} (z) = \mathbf{J}_f (z)^{-1} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 분포를 알고 있는 \(\mathbf{z} \sim \pi(z) \)로부터 \(\mathbf{x}\)의 분포를 구해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수 변환과 Jacobian의 성질을 통해 다음 식을 얻을 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(\mathbf{x}) = \pi \left( \mathbf{z} = f^{-1} (\mathbf{x}) \right) \left\vert \operatorname{det} \cfrac{\partial f^{-1}}{\partial \mathbf{x}} \right\vert = \pi \left( \mathbf{z} \right) \left\vert \mathbf{J}_f (\mathbf{z}) \right\vert^{-1}&amp;nbsp;\)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 uniform distribution에 대해 invertible function \(f\)를 적용한 예시이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;435&quot; data-origin-height=&quot;555&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zQkNw/btsaTYyytJA/KKxSoMqytzZELKaGTsBoG1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zQkNw/btsaTYyytJA/KKxSoMqytzZELKaGTsBoG1/img.jpg&quot; data-alt=&quot;Fig 3. Invertible transformation and volume changes&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zQkNw/btsaTYyytJA/KKxSoMqytzZELKaGTsBoG1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzQkNw%2FbtsaTYyytJA%2FKKxSoMqytzZELKaGTsBoG1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;435&quot; height=&quot;555&quot; data-origin-width=&quot;435&quot; data-origin-height=&quot;555&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Invertible transformation and volume changes&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위쪽은 Jacobian의 determinant가 1임에 따라 volume이 보존된 bijection (volume-preserving bijection)을 나타내고, 가운데와 아래 그림은 Jacobian 값이 1보다 작은 경우 volume은 작아지지만 density가 커지고, 1보다 큰 경우에는 volume이 커지지만 density가 작아지는 경우를 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; Flow-based Models&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;본격적으로 flow-based model에 대해 알아보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Simple Prior to Complex Data Distributions&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 언급했듯, flow-based model의 핵심은 간단한 prior distribution \(p_0(\mathbf{z}_0)\)을 활용하여 복잡한 data distribution \(p(\mathbf{x})\)을 표현하는 것이다. prior distribution \(\mathbf{z}_0\)이 normal distribution \(\mathcal{N}(\mathbf{z}_0 | 0, \mathbf{I})\)을 따른다고 가정했을 때, 이를 수식으로 나타내면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( p(\mathbf{x}) = \pi \left( \mathbf{z}_0 = f^{-1} (\mathbf{x}) \right) \prod\limits_{i=1}^K \left\vert \operatorname{det} \cfrac{\partial f_i (\mathbf{z}_{i-1})}{\partial \mathbf{z}_{i-1}} \right\vert^{-1} = \pi \left( \mathbf{z}_0 = f^{-1} (\mathbf{x}) \right) \prod\limits_{i=1}^K \left\vert \mathbf{J}_{f_i} (\mathbf{z}_{i-1}) \right\vert^{-1} \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Normal distribution 하나(unimodal distribution, latent space)를 transform하여 multimodal distribution (data space)을 나타낸 예시는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;192&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mjW0l/btsaVhx1i1x/kBlmNSkVHDE8aDwMRAkymk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mjW0l/btsaVhx1i1x/kBlmNSkVHDE8aDwMRAkymk/img.jpg&quot; data-alt=&quot;Fig 4. An example of transforming a unimodal distribution to a multimodal distribution&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mjW0l/btsaVhx1i1x/kBlmNSkVHDE8aDwMRAkymk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmjW0l%2FbtsaVhx1i1x%2FkBlmNSkVHDE8aDwMRAkymk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;864&quot; height=&quot;192&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;192&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. An example of transforming a unimodal distribution to a multimodal distribution&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Flow-based model이란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1352&quot; data-origin-height=&quot;389&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9XIrj/btsa6GwwX5T/HeTwRf4T0Od8fDBLq34Ktk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9XIrj/btsa6GwwX5T/HeTwRf4T0Od8fDBLq34Ktk/img.jpg&quot; data-alt=&quot;Fig 5. Main idea of flow-based models&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9XIrj/btsa6GwwX5T/HeTwRf4T0Od8fDBLq34Ktk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9XIrj%2Fbtsa6GwwX5T%2FHeTwRf4T0Od8fDBLq34Ktk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1352&quot; height=&quot;389&quot; data-origin-width=&quot;1352&quot; data-origin-height=&quot;389&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. Main idea of flow-based models&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Flow-based model에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;sampling은 forward transformation&lt;/span&gt; \(\mathbf{z} \mapsto \mathbf{x}\)을 통해 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( \mathbf{z} \sim p_Z (\mathbf{z}), \quad \mathbf{x} = f_{\boldsymbol{\theta}} (\mathbf{z})&amp;nbsp;\)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, inference network를 따로 둘 필요 없이 &lt;span style=&quot;color: #ee2323;&quot;&gt;inverse transformation을 통해 latent representation을 추론(infer)&lt;/span&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \mathbf{z} = f_{\boldsymbol{\theta}}^{-1} (\mathbf{x}) \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flow는 \(\boldsymbol{\theta}\)로 parameterize한 invertible transformation \(f_i\)로 다음과 같이 표현할 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{x} := \mathbf{z}_K = f_K \circ \cdots \circ f_1 = f_K \left( f_{K-1} \left( \cdots \left( f_1(\mathbf{z}_0) \right) \right) \right) \triangleq f(\mathbf{z}_0) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, Gaussian 등의 &lt;span style=&quot;color: #ee2323;&quot;&gt;간단한 distribution으로 시작하여 \(K\)번의 invertible transformation을 거치는 것&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종 distribution을 \(p(\mathbf{x})\)로, \(\mathbf{z}\)에 대한 distribution을 \(\pi\)로 표시하고, log를 취해주면 다음 식을 얻는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \begin{align*} \log p(\mathbf{x}) = \log \pi_K(\mathbf{z}_K) &amp;amp;= \log \pi_{K-1}(\mathbf{z}_{K-1}) - \log \left\vert \operatorname{det} \cfrac{d f_{K}}{d \mathbf{z}_{K-1}} \right\vert \\ &amp;amp;= \log \pi_{K-2}(\mathbf{z}_{K-2}) - \log \left\vert \operatorname{det} \cfrac{d f_{K-1}}{d \mathbf{z}_{K-2}} \right\vert - \log \left\vert \operatorname{det} \cfrac{d f_K}{d \mathbf{z}_{K=1}} \right\vert \\ &amp;amp;= \cdots \\ &amp;amp;= \log \pi_{0}(\mathbf{z}_{0}) - \sum\limits_{i=1}^K \log \left\vert \operatorname{det} \cfrac{d f_{i}}{d \mathbf{z}_{i-1}} \right\vert \end{align*} \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Prior distribution을 normal distribution으로 설정하고, Jacobian으로 나타내어 정리하면 다음과 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \log p(\mathbf{x}) = \log \mathcal{N} \left( \mathbf{z}_0 = f^{-1}(\mathbf{x}) | 0, \mathbf{I} \right) - \sum\limits_{i=1}^K \log \left\vert \mathbf{J}_{f_i} (\mathbf{z}_{i-1}) \right\vert \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흥미로운 점은, 첫 번째 term \( \log \mathcal{N} \left( \mathbf{z}_0 = f^{-1}(\mathbf{x}) | 0, \mathbf{I} \right) \)이&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt; \(0\)과 \(f^{-1}(\mathbf{x}) + \text{const}\) 사이의 Mean Squared Error(MSE)&lt;/span&gt;와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gaussian distribution의 probability density function \( f(x) = \operatorname{exp} \left( - \cfrac{(x - \mu)^2}{2 \sigma^2} \right) \)에 log를 취하면 MSE \( - \cfrac{(y_i - \hat{y})^2}{2 \sigma^2} \)와 같은 형태임을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 두 번째 term \( \sum\limits_{i=1}^K \log \left\vert \mathbf{J}_{f_i} (\mathbf{z}_{i=1}) \right\vert \)을 통해 Jacobian에 의한 change of volume을 invertible transformations \(\{f_i\}\)의 &lt;span style=&quot;color: #ee2323;&quot;&gt;regularization 효과&lt;/span&gt;로 볼 수 있다. ('Normalizing flow'라는 이름이 붙은 이유이기도 하다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Deep generative model 관점에서는 이러한 invertible transformation을 어떻게 모델링할지 고민해봐야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Neural network는 flexible하며 학습이 쉽지만, 아무 neural network나 쓸 수 있는 것은 아니다. 다음과 같은 조건을 충족해야 한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Invertible transformation이어야 하므로, &lt;span style=&quot;color: #ee2323;&quot;&gt;invertible neural network&lt;/span&gt;를 사용해야 한다.&lt;/li&gt;
&lt;li&gt;위 식에서 두 번째 term, 즉 &lt;span style=&quot;color: #ee2323;&quot;&gt;logarithm of Jacobian-determinant 계산이 가능하며, 쉬워야&lt;/span&gt; 한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위  두 가지 조건을 만족하는 model을 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;normalizing flow&lt;/span&gt; 혹은 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;flow-based model&lt;/span&gt;이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Considerations when Designing Flow Models&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Flow model을 설계할 때 고려할 점이 위에서 언급한 주요한 두 가지 이유와 관련하여 몇 가지 더 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;우선, prior distribution이 간단할수록 sampling과 likelihood evaluation 계산이 효율적이다. 따라서 보통 isotropic Gaussian distirbution을 선택하는 경우가 많다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Likelihood evaluation : Evaluation of \( \mathbf{x} \mapsto \mathbf{z} \) mapping&lt;/li&gt;
&lt;li&gt;Sampling : Evaluation of \( \mathbf{z} \mapsto \mathbf{x} \) mapping&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, likelihood 계산 시에는 \(n \times n\) Jacobian matrix의 determinant를 계산해야 하는데, 계산의 복잡도는 \(O(n^3)\)이다. 즉 training loop에서 매번 계산하기에는 너무 계산량이 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 Jacobian matrix가 triangular matrix인 invertible transformation을 많이 사용한다. Triangular matrix의 determinant는 대각 성분의 곱으로 간단하게 \(O(n)\)의 복잡도로 계산이 가능하기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, transformation \(\mathbf{x}_i = f_i(\mathbf{z}) \)가 \(\mathbf{z}_{\leq i}\), 즉 이전 \(z\)에만 의존한다면, 다음과 같은 lower triangular matrix일 것이다. (이후 \(z\)에 의존하면 upper triangular matrix일 것이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \mathbf{J} = \cfrac{\partial f}{\partial \mathbf{z}} = \begin{bmatrix} \cfrac{\partial f_1 }{\partial z_1} &amp;amp; \cdots &amp;amp; 0 \\ \vdots &amp;amp; \ddots &amp;amp; \vdots \\ \cfrac{\partial f_n}{\partial z_1} &amp;amp; \cdots &amp;amp; \cfrac{\partial f_n}{\partial z_n} \end{bmatrix} \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 글에서는 Flow-based model의 예시를 살펴보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Generative Models</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/233</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Flow-based-Models-Normalizing-Flow#entry233comment</comments>
      <pubDate>Tue, 18 Apr 2023 14:51:25 +0900</pubDate>
    </item>
    <item>
      <title>Generative Model Learning (2) - Monte Carlo Estimation</title>
      <link>https://jjuke-brain.tistory.com/entry/Pre-knowledges-for-Generative-Models-2-Monte-Carlo-Estimation</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에는 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Pre-knowledges-for-Generative-Models-KL-divergence-Maximum-likelihood-Monte-Carlo-estimate&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Pre-knowledges for Generative Models (1)&lt;/a&gt; 글에 이어 Monte Carlo Estimation에 대해 다뤄보려 한다.&lt;/p&gt;
&lt;figure id=&quot;og_1681793679631&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Pre-knowledges for Generative Models (1) - KL-divergence, Maximum likelihood&quot; data-og-description=&quot;목차 이번 포스팅에서는 딥러닝 기반의 generative model의 학습 과정을 배우기 위해 필요한 기초 지식들을 정리해보려 한다. 이제까지 \(p(x)\)를 어떻게 표현할지를 알아보았는데, 이번 장에서는 어&quot; data-og-host=&quot;jjuke-brain.tistory.com&quot; data-og-source-url=&quot;https://jjuke-brain.tistory.com/entry/Pre-knowledges-for-Generative-Models-KL-divergence-Maximum-likelihood-Monte-Carlo-estimate&quot; data-og-url=&quot;https://jjuke-brain.tistory.com/entry/Pre-knowledges-for-Generative-Models-KL-divergence-Maximum-likelihood-Monte-Carlo-estimate&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/nHord/hySkV5k0VL/jTiOdPmM4NTRdkYQBKzKt1/img.jpg?width=800&amp;amp;height=264&amp;amp;face=0_0_800_264,https://scrap.kakaocdn.net/dn/bmTteu/hySi2kJIPk/t9sB2CpnURsad18ababSA0/img.jpg?width=800&amp;amp;height=264&amp;amp;face=0_0_800_264,https://scrap.kakaocdn.net/dn/OFYpW/hySkZ7KM4u/opD7SxNopxyVP31I0NJxT0/img.jpg?width=903&amp;amp;height=298&amp;amp;face=0_0_903_298&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Pre-knowledges-for-Generative-Models-KL-divergence-Maximum-likelihood-Monte-Carlo-estimate&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jjuke-brain.tistory.com/entry/Pre-knowledges-for-Generative-Models-KL-divergence-Maximum-likelihood-Monte-Carlo-estimate&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/nHord/hySkV5k0VL/jTiOdPmM4NTRdkYQBKzKt1/img.jpg?width=800&amp;amp;height=264&amp;amp;face=0_0_800_264,https://scrap.kakaocdn.net/dn/bmTteu/hySi2kJIPk/t9sB2CpnURsad18ababSA0/img.jpg?width=800&amp;amp;height=264&amp;amp;face=0_0_800_264,https://scrap.kakaocdn.net/dn/OFYpW/hySkZ7KM4u/opD7SxNopxyVP31I0NJxT0/img.jpg?width=903&amp;amp;height=298&amp;amp;face=0_0_903_298');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Pre-knowledges for Generative Models (1) - KL-divergence, Maximum likelihood&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;목차 이번 포스팅에서는 딥러닝 기반의 generative model의 학습 과정을 배우기 위해 필요한 기초 지식들을 정리해보려 한다. 이제까지 \(p(x)\)를 어떻게 표현할지를 알아보았는데, 이번 장에서는 어&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jjuke-brain.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Learning Density Estimation&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Monte Carlo Estimation&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Monte Carlo estimation은 &lt;span style=&quot;color: #ee2323;&quot;&gt;random sampling을 여러 번 하여 기댓값 계산을 근사&lt;/span&gt;하기 위해 사용한다. 딥러닝의 Stochastic Gradient Descent처럼 데이터를 여러 번 샘플링하는 개념으로 볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저, 관심있는 quantity를 random variable의 기댓값으로 표현한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( \mathbb{E}_{x \sim P} [ g(x) ] = \sum\limits_{x} g(x) P(x) \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Distribution \(P\)에서 기댓값의 입력으로 들어갈 \(\{x^{(1)}, \cdots, x^{(T)} \}\) \(T\)개를 샘플링한 후, 다음 식을 사용하여 샘플들로부터 기댓값을 추정한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( \hat{g}(x^{(1)}, \cdots, x^{(T)}) \triangleq \cfrac{1}{T} \sum\limits_{t=1}^T g(x^t) \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 sample들은 서로 독립적이며, \(P\)를 따른다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;큰 수의 법칙에 의해, \(T \rightarrow \infty\)이면 \(\hat{g}\)는 \(\mathbb{E}_P[g(x)]\)에 수렴한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 근사하게 되면 두 가지 특징을 갖게 된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Unbiased : \(\mathbb{E}_P[\hat{g}] = \mathbb{E}_P[g(x)] \)&lt;/li&gt;
&lt;li&gt;Variance reduction : \(V_P[\hat{g}] = V_P \left[ \cfrac{1}{T} \sum\limits_{t=1}^T g(x) \right] = \cfrac{ V_P[g(x)] }{T} \)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Monte Carlo Estimation and Maximum Likelihood&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Biased coin을 던지는 sinvle variable 예시를 들어보자. 가능한 결과는 heads(H)나 tails(T)이고 (\(x \in \{H,T\}\), dataset은 예를 들어 \(\mathcal{D} = \{H, H, T, H, T \}\)로 나왔다고 하자. 이 과정은 probability distribution \(P_\text{data} (x)\)을 따른다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\(x\)에 대한 모든 probability distribution, 즉 가능한 model들의 집합을 \(M\)이라 할 때, \(\mathcal{D}\)에서 코인을 100번 던졌을 때 60번 앞면(head)일 확률 \(P_\theta (x)\) \(M\)으로부터 어떻게 고를 수 있을까?&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;우선 \(P_\theta(x = H) = \theta\), \(P_\theta (x=T) = 1 - \theta\)로 둔다. Example data \(\mathcal{D} = \{H, H, T, H, T\}\)이므로, 이 데이터에 대한 likelihood는 다음과 같이 나타낼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( L(\theta | \mathcal{D}) = \theta^3 \cdot (1 - \theta)^2 \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 log를 취하면 &lt;span style=&quot;color: #ee2323;&quot;&gt;log-likelihood&lt;/span&gt;를 다음과 같이 구할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( \log L(\theta) = 3 \log(\theta) + 2 \log(1 - \theta) \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Maximum likelihood estimation(MLE)의 목표는 \(\log L(\theta^*)\)를 최대로 하는 0과 1 사이의 최적의 \(\theta\)를 찾는 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이를 autoregressive representation에 적용시켜보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Training data \(\mathcal{D} = \{ \mathbf{x}^{(1)}, \cdots, \mathbf{x}^{(m)}\}\)에 대해 다음과 같은 autoregressive model이 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( P_\theta (x) = \prod\limits_{i}^n P_\text{neural} (x_i | pa(x_i) ; \theta_i) \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 MLE를 적용하려면, 우선 likelihood function을 분해(decompose)해야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( L(\theta | \mathcal{D}) = \prod\limits_{j=1}^m P_{\theta(x^{(j)})} = \prod\limits_{j=1}^m \prod\limits_{i=1}^n P_\text{neural} \left( x_i^{(j)} | pa(x_1)^{(j)} ; \theta_i \right) \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;여기에 log를 취하면,&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( \sum\limits_{j=1}^m \sum\limits_{i=1}^n \log P_\text{neural} \left( x_i^{(j)} | pa(x_1)^{(j)} ; \theta_i \right) \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이제 \(\underset{\theta}{\operatorname{argmax}} \log L(\theta | \mathcal{D})\)를 풀기위해 아래와 같이 optimize한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Initialization : \(\theta^{(0)} \)을 랜덤하게 initialize&lt;/li&gt;
&lt;li&gt;Back propgation : \(\nabla_\theta \log L(\theta)\) 계산&lt;/li&gt;
&lt;li&gt;Weight update : \(\theta^{(t+1)} = \theta^t + \alpha_t \nabla_\theta \log L(\theta) \)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Weight update 과정을 수식으로 나타내면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \nabla_\theta \log L(\theta)=\sum\limits_{j=1}^m \sum\limits_{i=1}^n \nabla_\theta \log P_{\text {neural}} \left( x_i^{(j)} \vert pa\left(x_i\right)^{(j)} ; \theta_i\right) \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 \(m = \left\vert D \right\vert\)가 크다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \begin{align*} \nabla_\theta \log L(\theta) &amp;amp;= m \sum\limits_{j=1}^m \cfrac{1}{m} \sum\limits_{i=1}^n \nabla_\theta \log P_{\text {neural}} \left( x_i^{(j)} \vert pa\left(x_i\right)^{(j)} ; \theta_i\right) \\ &amp;amp;= m \mathbb{E}_{x^{(j)} \sim \mathcal{D}} \left[ \sum\limits_{i=1}^n \nabla_\theta \log P_{\text {neural}} \left( x_i^{(j)} \vert pa\left(x_i\right)^{(j)} ; \theta_i\right) \right] \end{align*} \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 Monte Carlo estimation을 통해 다음과 같이 근사할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \text{Sample } x^{(j)} \sim \mathcal{D}; \nabla_\theta \log L(\theta) = m \sum\limits_{i=1}^n \nabla_\theta \log P_{\text {neural}} \left( x_i^{(j)} \vert pa\left(x_i\right)^{(j)} ; \theta_i\right) \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Generative Models</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/232</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Pre-knowledges-for-Generative-Models-2-Monte-Carlo-Estimation#entry232comment</comments>
      <pubDate>Tue, 18 Apr 2023 13:55:14 +0900</pubDate>
    </item>
    <item>
      <title>Generative Model Learning (1) - KL Divergence, Maximum Likelihood</title>
      <link>https://jjuke-brain.tistory.com/entry/Pre-knowledges-for-Generative-Models-KL-divergence-Maximum-likelihood-Monte-Carlo-estimate</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 딥러닝 기반의 generative model의 학습 과정을 배우기 위해 필요한 기초 지식들을 정리해보려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제까지 \(p(x)\)를 어떻게 표현할지를 알아보았는데, 이번 장에서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;어떻게 학습할지&lt;/span&gt;를 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Learning a Generative Model&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;903&quot; data-origin-height=&quot;298&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEDCfK/btsaVd8PWhc/KDd1UlVkKszJ2N4SjXO3vK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEDCfK/btsaVd8PWhc/KDd1UlVkKszJ2N4SjXO3vK/img.jpg&quot; data-alt=&quot;Fig 1. Representation and learning of generative model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEDCfK/btsaVd8PWhc/KDd1UlVkKszJ2N4SjXO3vK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEDCfK%2FbtsaVd8PWhc%2FKDd1UlVkKszJ2N4SjXO3vK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;903&quot; height=&quot;298&quot; data-origin-width=&quot;903&quot; data-origin-height=&quot;298&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Representation and learning of generative model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Generation (Sampling) : Data \(\mathbf{x}\)의 distribution \(p(\mathbf{x})\)로부터 새로운 데이터를 샘플링 하는 것을 말한다. \(\mathbf{x}_\text{new} \sim p(\mathbf{x})\)&lt;/li&gt;
&lt;li&gt;Density estimation (Anomaly detection) : Data \(x\)가 (예시에서) 강아지처럼 보인다면 \(p(x)\)가 높을 것이고, 아니면 낮을 것이다.&lt;/li&gt;
&lt;li&gt;Unsupervised representation learning (Feature learning) : 모델이 강아지라는 data는 귀, 꼬리 등의 feature를 갖는다는 것을 학습한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;어떤 data의 분포 \(P_\text{data}\)에서 \(m\)개의 sample을 뽑은 dataset \(\mathcal{D}\)가 주어져있다고 가정하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;각 샘플은 이미지를 예로 들면 pixel intensity와 같이 random variable에 값이 배정된 형태를 말한다. 그리고 일반적으로는 이러한 data들은 서로 independent and identically distributed (IID) 조건을 만족한다고 가정한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 model family \(\mathcal{M}\)이 주어져 있고, 이 중에서 좋은 모델 \(\widehat{\mathcal{M}}\)을 학습하는 것이 목표이다. (이 모델은 distribution \(p_{\widehat{\mathcal{M}}}\)을 정의한다.)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;위 예시에서 \(\boldsymbol{\theta}\)로 parameterize된&lt;span style=&quot;background-color: #f6e199;&quot;&gt;생성모델을 학습한다&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;는 것은 model family의 data distribution을 실제 data distribution에 가깝게 만든다, 즉&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;두 data distribution간의 거리(distance) \(d(P_\text{data}, P_{\boldsymbol{theta}})\)를 줄인다&lt;/span&gt;는 의미이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하지만, 일반적으로 이는 거의 불가능하다. 그 이유는 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Data의 개수가 한정적이므로, 이를 통해서는 실제 (underlying) distribution을 근사하기 힘들다.&lt;/li&gt;
&lt;li&gt;모든 data에 대해 학습하기에는 계산량이 너무 많다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 28 by 28 (784개 pixel) 흑백 이미지가 있다고 하면, 784개의 binary variable로 이루어진 vector \(\mathbf{X}\)로 표현할 수 있다. 이때 모델이 생성할 수 있는 state(image)는 \(2^{784} \approx 10^{236}\)가지이다. 이러한 model 모두에 대해 위에서처럼 distance를 계산한다는 것은 불가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 distribution \(P_\text{data}\)를 가장 잘 근사하는 모델 \(\widehat{\mathcal{M}}\)은 어떻게 구해야할까? 이에 대한 해답은 어떤 문제이냐에 따라 달라진다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Density estimation : &lt;span style=&quot;color: #ee2323;&quot;&gt;Full distribution&lt;/span&gt;을 구하여 추후에 원하는 conditional probability를 계산하는 데 사용한다.&lt;/li&gt;
&lt;li&gt;Specific prediction task : 어떤 것을 &lt;span style=&quot;color: #ee2323;&quot;&gt;예측하기 위해 distribution을 사용&lt;/span&gt;한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Email이 spam? or not?&lt;/li&gt;
&lt;li&gt;Video의 다음 frame?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Structure or knowledge discovery : &lt;span style=&quot;color: #ee2323;&quot;&gt;Model 자체를 근사&lt;/span&gt;한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;어떤 유전자가 다른 유전자와 어떻게 상호작용하는가?&lt;/li&gt;
&lt;li&gt;암을 유발하는 인자가 무엇인가?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 중에서도 이번에는 density estimation의 경우만 다뤄볼 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Learning in Density Estimation&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Density estimation의 경우, &lt;span style=&quot;color: #ee2323;&quot;&gt;data 전체의 distribution을 구한 후, 이것을 활용하여 inference 과정에서 원하는 결과를 얻는다&lt;/span&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Fig 1에서처럼 distribution \(P_{\boldsymbol{\theta}}\)가 data distribution \(P_\text{data}\)와 최대한 가까워지도록 하고싶은 경우를 예로 들 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이를 위해 distribution간의 거리 개념인 KL-divergence를 활용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Kullback-Leibler Divergence (KL-divergence)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;KL divergence는 &lt;span style=&quot;color: #ee2323;&quot;&gt;두 distribution 간의 거리&lt;/span&gt; 개념이고, 다음과 같이 정의한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( D_{KL} (p \Vert q) = \mathbb{E}_{x \sim p} \left[ \log \cfrac{p(x)}{q(x)} \right] = \sum\limits_{x \in X} p(x) \log \cfrac{p(x)}{q(x)} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수식을 해석해보면, &lt;span style=&quot;color: #ee2323;&quot;&gt;\(p\)에서 뽑은 샘플들을 \(p\)가 아닌 \(q\)를 기반으로 설명하기 위해 추가적으로 필요한 bit 수의 기댓값&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(아래부터는 subscript를 없애고 간단히 \(D\)로 표현할 것이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KL divergence는 모든 probability distribution function \(p, q\)에 대해 \(D(p \Vert q) \geq 0\)을 만족한다. (\(0\)이면 \(p=q\)이고, 역도 성립한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의할 점은, 엄밀히 따지면 KL-divergence는 asymmetric, 즉 \(D(p \Vert q) \neq D( q \Vert p)\)이기 때문에 distance function이 아니라는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;692&quot; data-origin-height=&quot;347&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAoxer/btsaw8IET7u/vZjJQMCxrSTpfpkktLndT1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAoxer/btsaw8IET7u/vZjJQMCxrSTpfpkktLndT1/img.jpg&quot; data-alt=&quot;Fig 2. Asymmetric property of KL divergence&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAoxer/btsaw8IET7u/vZjJQMCxrSTpfpkktLndT1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAoxer%2Fbtsaw8IET7u%2FvZjJQMCxrSTpfpkktLndT1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;692&quot; height=&quot;347&quot; data-origin-width=&quot;692&quot; data-origin-height=&quot;347&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Asymmetric property of KL divergence&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림은 p(x)가 두 개의 normal distribution, q가 하나의 normal distribution이라 했을 때, q를 KL divergence를 최소화하도록 학습시킨 것이다. KL divergence에서 \(D(p \Vert q)\)인가 \(D(q \Vert p)\)인가에 따라 최적의 q가 달라진다는 것을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조금 더 자세히 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Information theory and Entropy&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;직관적인 개념인 '정보'를 수량화하려 하는데, 이를 위해서는 다음과 같은 것들을 고려해야 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일어 날 것 같은 사건(likely events)은 information이 적을 것이다. (일어날 것이라 보장된 사건은 information이 0일 것이다.)&lt;/li&gt;
&lt;li&gt;잘 일어나지 않을 것 같은 사건(less likely events)은 information이 많을 것이다.&lt;/li&gt;
&lt;li&gt;서로 독립적인 사건은 추가적인 information을 가질 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한마디로, &lt;span style=&quot;color: #ee2323;&quot;&gt;드물게 일어나는 일일수록 의미가 클 것&lt;/span&gt;이라는 개념이다. 이에 따라 사건 \(\mathbf{x} = x\)의 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;self information&lt;/span&gt;을 다음과 같이 정의한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( I(x) = - \log P(x) = \log \left( \cfrac{1}{P(x)} \right) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 '&lt;span style=&quot;background-color: #f6e199;&quot;&gt;surprise&lt;/span&gt;'라고도 한다. Log를 취하는 이유는 이 개념이 probability의 inverse 개념인데, 단순히 역수를 취했다가는 0으로 나누게될 수 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 self information은 하나의 사건만 다루는데, &lt;span style=&quot;color: #ee2323;&quot;&gt;전체 확률 분포에서&lt;span style=&quot;color: #333333;&quot;&gt;의 정보량&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;은&lt;/span&gt; (Shannon) &lt;span style=&quot;background-color: #f6e199;&quot;&gt;entropy&lt;/span&gt;라 하고, 다음과 같이 정의한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \begin{align*} H(\mathbf{x}) &amp;amp;= \mathbb{E}_{\mathbf{x} \sim P} [I(x)] \\ &amp;amp;= \sum\limits_{x} P(x) I(x) \\ &amp;amp;= - \mathbb{E}_{\mathbf{x} \sim P} [\log P(x)] \\ &amp;amp;= - \sum\limits_{x} P(x) \log \left( P(x) \right) \end{align*} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 entropy란 &lt;span style=&quot;color: #ee2323;&quot;&gt;어떤 분포에서 사건이 일어났을 때, 이 사건이 가지는 정보량(information)의 기댓값&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 단순한 binary random variable의 경우를 예로 들어보자. 보통 이 떄에는 log의 밑을 2로 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동전을 100번 던졌는데, 앞면은 90번, 뒷면은 10번이 나왔다. 이때, (H, H, T)의 surprise를 구해보자. \(P(H) = 0.9\) (앞면 - head), \(P(T) = 0.1\) (뒷면 - tail)이므로 surprise는 아래와 같이 구한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(\text{surprise} = \log_2 \cfrac{1}{0.9 \times 0.9 \times 0.1} = \log_2{1} - \left( \log_2{0.9} + \log_2{0.9} + \log_2{0.1} \right) = 3.62 \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, 이때 동전을 던질 때마다의 surprise의 평균, 즉 entropy는 \(H\)의 information \(\log_2 \left( \cfrac{1}{P(H)} \right) = 0.15 \), \(T\)의 information \(\log_2 \left( \cfrac{1}{P(T)} \right) = 3.32\)를 이용하여 다음과 같이 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( P(H) \times I(H) + P(T) \times I(T) = 0.9 \times 0.15 + 0.1 \times 3.32 = 0.467 \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Binary entropy&lt;/span&gt;의 경우 항이 두 개밖에 없으므로 다음과 같이 나타낼 수 있다. (Binary entropy loss 등 딥러닝에서 아주 자주 사용된다! Binary classification task에 활용되는 경우 binary cross entropy(BCE) loss라는 이름을 갖게 되는 것이다.)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( -P \log P - (1 - P) \log (1 - P) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;KL Divergence&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이제 다시 KL divergence로 돌아와보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( D_{KL} (p \Vert q) = \mathbb{E}_{x \sim p} \left[ \log \cfrac{p(x)}{q(x)} \right] = \sum\limits_{x \in X} p(x) \log \cfrac{p(x)}{q(x)} \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;위 KL divergence 정의를 cross entropy의 관점에서 보면,&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( D_{KL} (p \Vert q) = \underbrace{- \sum\limits_{x} p(x) \log{q(x)}}_{\text{cross entropy } H(P, Q)} - \left( \underbrace{- \sum\limits_{x} p(x) \log{p(x)}}_{\text{real information } H(P)} \right) \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;첫 번째 항은 모델이 예측한 distribution \(q\)와 실제 data의 distribution \(p\)의 cross entropy이고, 두 번째 항은 \(p\)의 entropy \( H(P) = - \sum\limits_{x} p(x) \log \left( p(x) \right)\)임을 알 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Maximum Likelihood Estimation (MLE)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;다시 density estimation 학습 과정으로 돌아와보면, 이제 우리는 모델이 추정한 probability density와 실제 데이터의 probability density에 KL-divergence를 적용하여 그 차이를 알아볼 것이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( D(P_\text{data} \Vert P_{\boldsymbol{\theta}}) = \mathbb{E}_{x \sim P_\text{data}} \left[ \log \cfrac{P_\text{data} (x)}{P_{\boldsymbol{\theta}}(x)} \right] = \sum\limits_{x} P_\text{data} (x) \cfrac{P_\text{data}(x)}{P_{\boldsymbol{\theta}}(x)} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(D(P_\text{data} | P_{\boldsymbol{\theta}}) = 0\)이면 두 distribution은 같은 distribution이며, 역도 성립한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 단순화시켜보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( D(P_\text{data} \Vert P_{\boldsymbol{\theta}}) = \mathbb{E}_{x \sim P_\text{data}} \left[ \log \cfrac{P_\text{data} (x)}{P_{\boldsymbol{\theta}}(x)} \right] = \mathbb{E}_{x \sim P_\text{data}} \left[ \log P_\text{data} (x) \right] - \underbrace{\mathbb{E}_{x \sim P_\text{data}} \left[ \log P_{\boldsymbol{\theta}} (x) \right]}_{\text{expected log-likelihood}} \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 식에서, 첫 번째 term은 \(P_{\boldsymbol{\theta}}\)에 의존하지 않는다. 따라서 &lt;span style=&quot;color: #ee2323;&quot;&gt;KL divergence를 최소화한다는 것은 두 번째 term인 log-likelihood의 기댓값을 최대화한다는 의미&lt;/span&gt;가 된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \underset{P_{\boldsymbol{\theta}}}{\operatorname{argmin}} D(P_\text{data} \Vert P_{\boldsymbol{\theta}} ) = \underset{P_{\boldsymbol{\theta}}}{\operatorname{argmin}} - \mathbb{E}_{x \sim P_\text{data}} \left[ \log P_{\boldsymbol{\theta}} (x) \right] = \underset{P_{\boldsymbol{\theta}}}{\operatorname{argmax}} \mathbb{E}_{x \sim P_\text{data}} \left[ \log P_{\boldsymbol{\theta}} (x) \right] \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 위 식을 objective function(loss function)으로 학습하기에는 두 가지 문제가 있다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Log때문에 \(x\)를 샘플링할 때 \(P_{\boldsymbol{\theta}} (x) \approx 0\)인 경우 objective의 (절댓)값이 너무 커진다.&lt;/li&gt;
&lt;li&gt;\(H(P_\text{data})\)를 무시했으므로, optimum에 얼마나 가까운지를 알 수 없다. 일반적으로 실제 data의 distribution \(P_\text{data}\)는 정확히 계산할 수 없다. (intractable)
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;즉, 기댓값 \( \mathbb{E}_{x \sim P_\text{data}} \left[ \log P_{\boldsymbol{\theta}} (x) \right] \)에서 \(P_\text{data}\)를 모르므로 계산할 수 없고, KL divergence term도 계산이 불가능하다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Approximation of expected log-likelihood with the empirical log-likelihood&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, &lt;span style=&quot;color: #ee2323;&quot;&gt;empirical log-likelihood&lt;/span&gt;로 해당 term을 근사한다. 쉽게 말하면 주어진(샘플된) dataset \(\mathcal{D}\)를 활용하여 해당 term을 근사하는 방법이다. Empirical log-likelihood는 다음과 같이 정의한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbb{E}_{\mathcal{D}} \left[ \log P_{\boldsymbol{\theta}} (x) \right] = \cfrac{1}{\left\vert \mathcal{D} \right\vert}&amp;nbsp; \sum\limits_{x \in \mathcal{D}} \log P_{\boldsymbol{\theta}} (x) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위를 활용한 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;maximum likelihood learning&lt;/span&gt;은 다음과 같이 표현할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \underset{P_{\boldsymbol{\theta}}}{\operatorname{argmax}} \cfrac{1}{\left\vert \mathcal{D} \right\vert} \sum\limits_{x \in \mathcal{D}} \log P_{\boldsymbol{\theta}} (x) \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 다음과 같이 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;data의 likelihood를 최대화&lt;/span&gt;하는 수식과 같다. (가정 : iid)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \underset{P_{\boldsymbol{\theta}}}{\operatorname{argmax}} P_{\boldsymbol{\theta}} \left( x^{(1)}, \cdots , x^{(m)} \right) = \underset{P_{\boldsymbol{\theta}}}{\operatorname{argmax}} \prod\limits_{x \in \mathcal{D}} P_{\boldsymbol{\theta}} (x) \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Generative Models</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/231</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Pre-knowledges-for-Generative-Models-KL-divergence-Maximum-likelihood-Monte-Carlo-estimate#entry231comment</comments>
      <pubDate>Mon, 17 Apr 2023 19:20:37 +0900</pubDate>
    </item>
    <item>
      <title>Autoregressive (Generative) Models (2)</title>
      <link>https://jjuke-brain.tistory.com/entry/Autoregressive-Generative-Models-2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Autoregressive-Generative-Models&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 글&lt;/a&gt;에 이어, autoregressive generative model에 어떤 모델이 있는지 좀 더 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 다양한 deep generative model 의 비교 표이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1133&quot; data-origin-height=&quot;258&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DV7Y4/btsar4TRZc0/fH3rsKU4SDKEhJV3c8ekOk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DV7Y4/btsar4TRZc0/fH3rsKU4SDKEhJV3c8ekOk/img.jpg&quot; data-alt=&quot;Fig 1. Comparison of deep generative models&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DV7Y4/btsar4TRZc0/fH3rsKU4SDKEhJV3c8ekOk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDV7Y4%2Fbtsar4TRZc0%2FfH3rsKU4SDKEhJV3c8ekOk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1133&quot; height=&quot;258&quot; data-origin-width=&quot;1133&quot; data-origin-height=&quot;258&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Comparison of deep generative models&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Autoencoder based ARM&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Autoregressive Models (ARM) vs Autoencoders (AE)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Autoencoder&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 autoencoder에 대해 간단히 알아보고 비교해보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;271&quot; data-origin-height=&quot;363&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xAynV/btsaES6i9gJ/jIPkrNAvRZOUcN8s7uGR9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xAynV/btsaES6i9gJ/jIPkrNAvRZOUcN8s7uGR9K/img.png&quot; data-alt=&quot;Fig 2. Autoencoder example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xAynV/btsaES6i9gJ/jIPkrNAvRZOUcN8s7uGR9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxAynV%2FbtsaES6i9gJ%2FjIPkrNAvRZOUcN8s7uGR9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;271&quot; height=&quot;363&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;271&quot; data-origin-height=&quot;363&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Autoencoder example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Autoencoder는 encoder \(e(\cdot)\)와 decoder \(d(e(x)) \approx x\)의 구조를 갖는다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 Fig 2에서 encoder는 \(e(\mathbf{x}) = \sigma(W_2 ( W_1 \mathbf{x} + b_1 ) + b_2)\))와 decoder \(d(h) = \sigma(Vh + c)\)로 이루어져 있고, loss function은 다음과 같이 나타낼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( \underset{W_1, W_2, b_1, b_2, V, c}{\min} \sum\limits_{x \in D} \sum\limits_{i} -x_i \log \hat{x}_i - x_i \log (1 - \hat{x}_i) \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( \underset{W_1, W_2, b_1, b_2, V, c}{\min} \sum\limits_{x \in D} \sum\limits_{i} (x_i - \hat{x}_i)^2 \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;위는 \(x\)가 binary random value일 때 사용하는 binary cross entropy(BCE) loss, 아래는 continuous random variable일 때 사용하는 L2 loss이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;보통 autoencoder를 사용하는 목적은 input과 똑같은 reconstruction 결과물을 얻는 것 보다는 encoding의 결과인 \(e(x)\)가 \(x\)를 잘 표현(representation)하는 feature이길 바라는 것이므로 (feature learning), encoder와 decoder에 constraint를 부여하게 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그렇다 해도 기본적인 형태의 autoencoder는 generative model은 아니다. 새로운 데이터를 생성하기 위해 sampling할 때 필요한&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;\(\mathbf{x}\)에 대한 distribution을 정의하는 게 아니기 때문&lt;/span&gt;이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Generative model from an autoencoder&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7bS1E/btsatU3ug03/1zW3DABWTcGQSGEHhsbXY1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7bS1E/btsatU3ug03/1zW3DABWTcGQSGEHhsbXY1/img.jpg&quot; data-alt=&quot;Fig 3. ARM vs AE&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7bS1E/btsatU3ug03/1zW3DABWTcGQSGEHhsbXY1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7bS1E%2FbtsatU3ug03%2F1zW3DABWTcGQSGEHhsbXY1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;751&quot; height=&quot;425&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. ARM vs AE&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그런데, Fig 3에서와 같이 input으로부터 데이터를 추정(estimate)한다는 점에서 FVSBN과 NADE는 autoencoder와 비슷해 보인다. 그럼 autoencoder를 generative model로 활용하려면 어떻게 해야하는 지 알아보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;우선 네트워크가 Bayesian Network (DAG structure)여야 한다. 즉, ordering이 필요하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어, Fig 3의 autoencoder를 살펴보자. Ordering이 1, 2, 3 순서라면, \(\hat{x}_1\)은 어떤 input \(x\)에도 의존하지 않는다. 즉 generation 시 input이 필요하지 않다. 그리고 \(\hat{x}_2\)는 \(x_1\)에, \(\hat{x}_3\)는 \(x_1, x_2\)에, 이런 식으로 dependency가 생길 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이때 \(n\)개 output을 내는 neural network 하나를 사용해볼 수 있다. (NADE의 경우 \(n\)번의 pass를 거치면 된다.)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Masked AE for Distribution Estimation (MADE)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;MADE는&lt;span style=&quot;color: #ee2323;&quot;&gt; masking을 활용하여 autoencoder를 generative model에 활용&lt;/span&gt;한 모델이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1888&quot; data-origin-height=&quot;1000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Nmi0J/btsaJUiALbI/l4myIDLtgdzuji3E6iPZMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Nmi0J/btsaJUiALbI/l4myIDLtgdzuji3E6iPZMK/img.png&quot; data-alt=&quot;Fig 4. Main idea of MADE&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Nmi0J/btsaJUiALbI/l4myIDLtgdzuji3E6iPZMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNmi0J%2FbtsaJUiALbI%2Fl4myIDLtgdzuji3E6iPZMK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1888&quot; height=&quot;1000&quot; data-origin-width=&quot;1888&quot; data-origin-height=&quot;1000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. Main idea of MADE&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Autoencoder를 autoregressive하게 활용하기 위해(DAG structure를 갖게 하기 위해, 즉 ordering을 부여하기 위해) masking을 하여 특정 path를 끊어준다. Fig 4에서, ordering이 \(x_2, x_3, x_1\) 순서라고 해보자. (ordering은 Fig 4에서 각 unit 안에 표시되어 있다.)&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;첫 번째 순서인 \(x_2\)의 distribution \(p(x_2)\)의 parameter를 생성하는 unit은 어떤 input에도 의존하지 않으며, \(p(x_3|x_2)\)는 input \(x_2\)에만, \(p(x_1|x_2, x_3)\)는 input \(x_2, x_3\)에 의존한다.&lt;/li&gt;
&lt;li&gt;Hidden layer에서 각 unit에 대해 \([1, n-1]\)(예시에서 n=3) 범위에서 integer를 랜덤으로 골라 해당 unit이 의존할 input을 정한다. 예를 들어, 2를 골랐으면 1(\(x_2\))과 2(\(x_3\))에 의존하게 된다.&lt;/li&gt;
&lt;li&gt;Mask를 추가하여 몇몇 path(connection)를 없앤다. Fig 4에서 \(M^{W^1}\)을 보면, 첫 번째 열(첫 번째 unit, 즉 \(x_1\))의 path는 전부 masking(0)되어있다. 따라서 오른쪽 그림처럼 \(x_1\) unit은 아무런 connection이 없는 것이다. 마찬가지로 \(x_3\)의 경우 두 번째 path가 끊겨 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 masking을 하면 \(p(x_3 | x_2)\)에 대해 Fig 4에서 빨갛게 표시한 것과 같이 Bayes network의 DAG structure를 얻을 수 있다. Bayes network의 DAG structure 예시는 아래와 같다. 자세한 내용은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Generative-ApproachNaive-Bayes-Classifier-vs-Discriminative-ApproachLogistic-Regression#Generative_Model_(Naive_Bayes_Classifier)&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 참조하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;588&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zJW78/btsamXAEtVm/VymwwPX3TKxwlUkFzbCv41/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zJW78/btsamXAEtVm/VymwwPX3TKxwlUkFzbCv41/img.jpg&quot; data-alt=&quot;Fig 5. Bayes network example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zJW78/btsamXAEtVm/VymwwPX3TKxwlUkFzbCv41/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzJW78%2FbtsamXAEtVm%2FVymwwPX3TKxwlUkFzbCv41%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;588&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;588&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. Bayes network example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;RNN based ARMs&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Autoregressive-Generative-Models&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 글&lt;/a&gt;에서 RNN으로 Autoregressive Model을 모델링하는 방법을 설명했다. &lt;span style=&quot;color: #ee2323;&quot;&gt;Autoencoder 기반 모델들은 input과 output dimension이 고정되어있지만, RNN은 임의의 length를 다룰 수 있다&lt;/span&gt;는 장점을 갖고 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그 예시를 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Character RNN&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Character RNN은 text를 다루는 RNN 기반 autoregressive generative model이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;636&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ybV7T/btsaRwVQ41i/yQUXrIhWTClzkl9ue2rSRK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ybV7T/btsaRwVQ41i/yQUXrIhWTClzkl9ue2rSRK/img.jpg&quot; data-alt=&quot;Fig 6. Character RNN&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ybV7T/btsaRwVQ41i/yQUXrIhWTClzkl9ue2rSRK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FybV7T%2FbtsaRwVQ41i%2FyQUXrIhWTClzkl9ue2rSRK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;788&quot; height=&quot;636&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;636&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 6. Character RNN&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(x_i \in \{h, e, l, o \}\)라 가정하면, one-hot encoding을 활용하여 Fig 6에서의 input layer처럼 나타낸다. 이에 따라 &quot;hello&quot;라는 문자열의 distribution은 다음과 같이 autoregressive하게 나타낼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( p( x = hello) = p(x_1 = h) p(x_2 = e | x_1 = h) \cdots p(x_5 = o | x_1 = h, \dots, x_4=l)\)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 모델은 요즘 핫한 chatGPT의 근간이 되는 모델이기도 하다. 하지만, 주어진 past data에 따라 가장 높은 확률의 다음 단어를 생성할 뿐, feqture encoding을 하는 게 아님에 주목하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;PixelRNN&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;PixelRNN은 image를 다루는 RNN 기반 autoregressive generative model이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;497&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYESmF/btsaKw9Ilxr/CKuRyLi0Px4UIyCqdTxBL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYESmF/btsaKw9Ilxr/CKuRyLi0Px4UIyCqdTxBL1/img.png&quot; data-alt=&quot;Fig 7. PixelRNN&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYESmF/btsaKw9Ilxr/CKuRyLi0Px4UIyCqdTxBL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYESmF%2FbtsaKw9Ilxr%2FCKuRyLi0Px4UIyCqdTxBL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;497&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;497&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 7. PixelRNN&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Fig 7과 같이 image를 pixel의 순서대로 다루는데, pixel conditional \(p(x_t | x_{1:t-1})\) 3개가 각각의 channel(RGB color)에 대한 piixel intensity(0 ~ 255)를 정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로는 Fig 7 가운데 그림처럼 masking을 통해 multi-scale context를 고려하고, 정확하게는 RNN variants 중 하나인 LSTM을 활용하지만, 이 포스팅에서 자세히 다루지는 않겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Pros and Cons of RNN based ARM&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이전 글에서도 설명했지만, RNN을 활용한 autoregressive generative model의 장단점을 다시 한 번 살펴보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Pros
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;임의의 lengt의 sequence에 적용이 가능하다.&lt;/li&gt;
&lt;li&gt;모든 계산 가능한 함수에 대해 RNN을 적용할 수 있다. (일반적(general)으로 사용이 가능하다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Cons
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Ordering이 필요하다.&lt;/li&gt;
&lt;li&gt;Likelihood evaluation 과정이 sequential하게 이루어진다. &amp;rarr; 학습이 매우 느리다.&lt;/li&gt;
&lt;li&gt;Generation 과정이 sequential하게 이루어진다. &amp;rarr; autoregressive model의 한계이다.&lt;/li&gt;
&lt;li&gt;Vanishing/exploding gradient problem이 존재한다. &amp;rarr; 학습이 어렵다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;CNN based ARM&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;PixelCNN&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;다음으로는 image에서 RNN보다 훨씬 많이 활용되는 CNN을 기반으로 한 autoregressive generative model을 살펴보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1117&quot; data-origin-height=&quot;276&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dOAibR/btsaRvQgekb/OpqComzC9KpcgVy25KeYOK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dOAibR/btsaRvQgekb/OpqComzC9KpcgVy25KeYOK/img.jpg&quot; data-alt=&quot;Fig 8. Main idea of PixelCNN&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dOAibR/btsaRvQgekb/OpqComzC9KpcgVy25KeYOK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdOAibR%2FbtsaRvQgekb%2FOpqComzC9KpcgVy25KeYOK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1117&quot; height=&quot;276&quot; data-origin-width=&quot;1117&quot; data-origin-height=&quot;276&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 8. Main idea of PixelCNN&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1002&quot; data-origin-height=&quot;411&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJ2QXO/btsaVgYzvXa/1W9FTimluXvIQ25bspnaZ1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJ2QXO/btsaVgYzvXa/1W9FTimluXvIQ25bspnaZ1/img.jpg&quot; data-alt=&quot;Fig 9. Convolution operation process of PixelCNN&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJ2QXO/btsaVgYzvXa/1W9FTimluXvIQ25bspnaZ1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJ2QXO%2FbtsaVgYzvXa%2F1W9FTimluXvIQ25bspnaZ1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1002&quot; height=&quot;411&quot; data-origin-width=&quot;1002&quot; data-origin-height=&quot;411&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 9. Convolution operation process of PixelCNN&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Idea는 매우 간단한데, Fig 8, 9와 같이 &lt;span style=&quot;color: #ee2323;&quot;&gt;masked convolution&lt;/span&gt;을 활용하여 주어진 context(이웃한 pixel)를 활용하여 다음 pixel을 예측하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;PixelCNN vs PixelRNN&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;다음은 PixelCNN과 기본 LSTM 기반 PixelRNN과 BiLSTM 기반 PixelRNN을 비교한 그림이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1090&quot; data-origin-height=&quot;462&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dPtHBY/btsayWBxpqu/bhJMiaxzDq7yb9SosUr2w0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dPtHBY/btsayWBxpqu/bhJMiaxzDq7yb9SosUr2w0/img.jpg&quot; data-alt=&quot;Fig 10. PixelCNN vs PixelRNNs&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dPtHBY/btsayWBxpqu/bhJMiaxzDq7yb9SosUr2w0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdPtHBY%2FbtsayWBxpqu%2FbhJMiaxzDq7yb9SosUr2w0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1090&quot; height=&quot;462&quot; data-origin-width=&quot;1090&quot; data-origin-height=&quot;462&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 10. PixelCNN vs PixelRNNs&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연산의 속도와 log-likelihood의 quality는 trade-off 관계임을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Generative Models</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/230</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Autoregressive-Generative-Models-2#entry230comment</comments>
      <pubDate>Mon, 17 Apr 2023 17:10:14 +0900</pubDate>
    </item>
    <item>
      <title>리눅스 프로세스 관련 명령어 (상태 출력, 강제 종료 등)</title>
      <link>https://jjuke-brain.tistory.com/entry/%EB%A6%AC%EB%88%85%EC%8A%A4-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EA%B4%80%EB%A0%A8-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%83%81%ED%83%9C-%EC%B6%9C%EB%A0%A5-%EA%B0%95%EC%A0%9C-%EC%A2%85%EB%A3%8C-%EB%93%B1</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPU의 메모리가 비정상적으로 차 있다거나, 어떤 프로세스를 강제로 종료시켜야 할 때가 있다. 이때 유용하게 사용할 수 있는 명령어를 살펴보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;프로세스 상태 출력 관련 명령어 (ps)&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저, 프로세스 상태를 확인하는 ps 명령어부터 알아보자. 프로세스 전체를 출력하면 너무 많으므로,&lt;span&gt;&amp;nbsp;&lt;/span&gt;grep과 함께 사용하여 특정 프로게그만 확인해볼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1680883995596&quot; class=&quot;vim&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ps -ef | grep [특정프로세스]&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;-e : 모든 프로세스를 출력한다.&lt;/li&gt;
&lt;li&gt;-f : 유닉스 스타일로 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-04-08 at 00.52.40.jpg&quot; data-origin-width=&quot;733&quot; data-origin-height=&quot;169&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/W74Uk/btr8J5sO1Ru/Pk9EkfBRalnyQeMGkJDlU0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/W74Uk/btr8J5sO1Ru/Pk9EkfBRalnyQeMGkJDlU0/img.jpg&quot; data-alt=&quot;Fig 1. ps -ef example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/W74Uk/btr8J5sO1Ru/Pk9EkfBRalnyQeMGkJDlU0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FW74Uk%2Fbtr8J5sO1Ru%2FPk9EkfBRalnyQeMGkJDlU0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;733&quot; height=&quot;169&quot; data-filename=&quot;CleanShot 2023-04-08 at 00.52.40.jpg&quot; data-origin-width=&quot;733&quot; data-origin-height=&quot;169&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. ps -ef example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 항목은 다음을 의미한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;UID : 소유자&lt;/li&gt;
&lt;li&gt;PID : 식별 번호&lt;/li&gt;
&lt;li&gt;PPID : 부모 프로세스의 PID&lt;/li&gt;
&lt;li&gt;C : 프로세스의 CPU 점유 상태&lt;/li&gt;
&lt;li&gt;STIME : 프로세스 시작 시간&lt;/li&gt;
&lt;li&gt;TTY : 프로세스가 시작된 터미널&lt;/li&gt;
&lt;li&gt;TIME : 총 사용 시간&lt;/li&gt;
&lt;li&gt;COMMAND : 프로세스를 실행한 명령어(행)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는 -aux 옵션을 활용해볼 수 있다. (-는 붙여야 하는 경우도 있고, 안붙여야 하는 경우도 있다는데, 내가 사용하는 ubuntu 20.04 LTS 기준에서는 둘 다 실행된다.)&lt;/p&gt;
&lt;pre id=&quot;code_1680883995597&quot; class=&quot;vim&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ps -aux | grep [특정프로세스]&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;(-)a : 터미널에 종속되지 않은 모든 프로세스를 출력한다. (-A : 모든 프로세스를 출력한다.)&lt;/li&gt;
&lt;li&gt;(-)u : 프로세스 소유자 (User 또는 UID)를 기준으로 출력한다.&lt;/li&gt;
&lt;li&gt;(-)x : 프로세스의 상태(STAT)를 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-04-08 at 01.02.23.jpg&quot; data-origin-width=&quot;885&quot; data-origin-height=&quot;165&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMLEvR/btr8Jp59lXj/TKJDrK8AWaiCMf4g4011X1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMLEvR/btr8Jp59lXj/TKJDrK8AWaiCMf4g4011X1/img.jpg&quot; data-alt=&quot;Fig 2. ps -aux example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMLEvR/btr8Jp59lXj/TKJDrK8AWaiCMf4g4011X1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMLEvR%2Fbtr8Jp59lXj%2FTKJDrK8AWaiCMf4g4011X1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;885&quot; height=&quot;165&quot; data-filename=&quot;CleanShot 2023-04-08 at 01.02.23.jpg&quot; data-origin-width=&quot;885&quot; data-origin-height=&quot;165&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. ps -aux example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상태(STAT)는 다음과 같이 나타난다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;S : 인터럽트 가능한 대기상태&lt;/li&gt;
&lt;li&gt;I (대문자 i) : 커널 쓰레드 유휴 상태&lt;/li&gt;
&lt;li&gt;R : 실행 중 또는 실행 가능 상태&lt;/li&gt;
&lt;li&gt;T : 작업 제어신호에 의해 멈춘 상태&lt;/li&gt;
&lt;li&gt;t : 디버거에 의해 멈춘 상태&lt;/li&gt;
&lt;li&gt;X : 죽은 프로세스 (안보이는 게 정상)&lt;/li&gt;
&lt;li&gt;Z : 좀비(defunct 상태) 프로세스
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실행이 종료되었으나 삭제되지 않은 프로세스&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;L : 락(lock)된 메모리를 갖는 페이지&lt;/li&gt;
&lt;li&gt;s : 세션 리더&lt;/li&gt;
&lt;li&gt;&amp;lt; : 높은 우선 순위&lt;/li&gt;
&lt;li&gt;N : 낮은 우선 순위&lt;/li&gt;
&lt;li&gt;l (소문자 L) : 멀티 쓰레드&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;프로세스 (강제)종료 관련 명령어 (kill)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;비정상적으로 작동하는 프로세스가 있다면 kill 명령어로 강제 종료할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이때 시그널(일반적인 리눅스 명령어의 옵션 개념)로 9를 주는데, 9가 강제 종료이고, 9를 주지 않으면 default값인 15로, 프로세스와 관련된 파일을 정리한 후에 종료한다. 15인 경우 종료되지 않는 프로세스가 남아있을 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1680884337086&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kill -9 [PID]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-04-08 at 01.20.34.jpg&quot; data-origin-width=&quot;911&quot; data-origin-height=&quot;652&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qiAPO/btr8LM0l4wT/U1kFWdIpQeDsVjyAnCic8K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qiAPO/btr8LM0l4wT/U1kFWdIpQeDsVjyAnCic8K/img.jpg&quot; data-alt=&quot;Fig 3. ps examples with grep&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qiAPO/btr8LM0l4wT/U1kFWdIpQeDsVjyAnCic8K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqiAPO%2Fbtr8LM0l4wT%2FU1kFWdIpQeDsVjyAnCic8K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;911&quot; height=&quot;652&quot; data-filename=&quot;CleanShot 2023-04-08 at 01.20.34.jpg&quot; data-origin-width=&quot;911&quot; data-origin-height=&quot;652&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. ps examples with grep&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-ef 옵션으로 jupyter 관련 프로세스를, -aux 옵션으로 python 관련 프로세스를 띄워보았다. 두 옵션 모두 두번째 열이 PID이다. 예를 들어, ps -ef에서 네 번째 ipykernel을 종료하고 싶으면 터미널에 'kill -9 199688'을 입력하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science, Programming/Git, Docker, Server, Linux</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/229</guid>
      <comments>https://jjuke-brain.tistory.com/entry/%EB%A6%AC%EB%88%85%EC%8A%A4-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EA%B4%80%EB%A0%A8-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%83%81%ED%83%9C-%EC%B6%9C%EB%A0%A5-%EA%B0%95%EC%A0%9C-%EC%A2%85%EB%A3%8C-%EB%93%B1#entry229comment</comments>
      <pubDate>Sat, 8 Apr 2023 01:14:28 +0900</pubDate>
    </item>
    <item>
      <title>Autoregressive (Generative) Models (1)</title>
      <link>https://jjuke-brain.tistory.com/entry/Autoregressive-Generative-Models</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 생성 모델 중 하나인 autoregressive model에 대해 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 다양한 deep generative model 의 비교 표이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1133&quot; data-origin-height=&quot;258&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ztv9c/btsaESlfn6Y/YvKiy9uRK70mHpxIfNzrMk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ztv9c/btsaESlfn6Y/YvKiy9uRK70mHpxIfNzrMk/img.jpg&quot; data-alt=&quot;Fig 1. Comparison of deep generative models&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ztv9c/btsaESlfn6Y/YvKiy9uRK70mHpxIfNzrMk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fztv9c%2FbtsaESlfn6Y%2FYvKiy9uRK70mHpxIfNzrMk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1133&quot; height=&quot;258&quot; data-origin-width=&quot;1133&quot; data-origin-height=&quot;258&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Comparison of deep generative models&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Autoregressive Models&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Autoregressive model&lt;/span&gt;(ARM)은 말그대로 autoregressive, 즉 &lt;span style=&quot;color: #ee2323;&quot;&gt;이전 input data를 활용하여 현재 input과 관련된 연산(modeling probability distribution)을 하는 방법&lt;/span&gt;으로 \(p(\mathbf{x})\)를 모델링한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(\mathbf{x}) = p(x_0) \prod\limits_{i=1}^D p(x_i | \mathbf{x}_{&amp;lt;i} ) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\mathbf{x}_{&amp;lt;i}\) : \(i\)번째 인덱스 이전의 \(x\)들을 말한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;이는 이미지로 따지자면 이전 픽셀 정보를 통해 주어진 픽셀을 예측하는 개념으로 볼 수 있다. 그런데 모든 \(i\)에 대해 \(p(x_i |\mathbf{x}_{&amp;lt;i})\)를 모델링하는 건 사실상 불가능하다. 그래서 이를 모델링하기 위해 아래와 같은 여러 neural network를 활용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Modeling with MLP&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 conditional model의 메모리가 한정되어있어 각 variable이 이전의 두 개 variable까지만 dependent하다고 가정하자(finite memory).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(p(\mathbf{x}) = p(x_1) p(x_2 | x_1) \prod\limits_{i=3}^D p(x_i | x_{i-1}, x_{i-2}) \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 간단히 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;MLP&lt;/span&gt;로 \(p(x_i)\)를 예측해볼 수 있다. \(\mathcal{X} = \{0, 1, \dots, 255\}\)라 하면, MLP는 아래와 같이 \(x_{i-1}, x_{i-2}\)를 input으로 받고, \(x_i\)의 categorical probability distribution \(\theta_i\)를 출력할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( [x_{i-1}, x_{i-2}] \rightarrow \operatorname{Linear}(2, M) \rightarrow \operatorname{ReLU} \rightarrow \operatorname{Linear}(M, 256) \rightarrow \operatorname{softmax} \rightarrow \theta_i \)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(M\) : hidden unit 개수&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 방법으로 non-linear하면서도 parameterization이 쉬운(학습할 weight이 적은) 모델을 고안해볼 수 있다. 하지만, memory가 한정적이라는 단점이 있다. 실제로는 &lt;span style=&quot;color: #ee2323;&quot;&gt;long-range memory가 필요&lt;/span&gt;한 경우가 매우 많다. (예를 들어, 이미지에서의 픽셀 수만 따져봐도 이전 두 개 정보로는 성능이 매우 떨어질 것이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Modeling with RNN&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 MLP 대신 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;RNN을 활용&lt;/span&gt;해볼 수 있다. 그러면 conditional distribution은 다음과 같이 모델링할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( p(x_i | \mathbf{x}_{&amp;lt;i}) = p(x_i | \operatorname{RNN}(x_{i-1}, h_{i-1})) \)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(h_i = \operatorname{RNN}(x_{i-1}, h_{i-1})\) : hidden state&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, history \(\mathbf{x}_{&amp;lt;i}\)가 계속해서 길어지므로 이에 대한 summary 개념인 hidden state \(h_i\)를 두어 이를 recursive하게 update하는 개념이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;RNN&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;RNN을 간단히 복습해보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;231&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dnzlTC/btsar22EOxU/72qYcCpJmotC7polbFw81K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dnzlTC/btsar22EOxU/72qYcCpJmotC7polbFw81K/img.jpg&quot; data-alt=&quot;Fig 2. RNN&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dnzlTC/btsar22EOxU/72qYcCpJmotC7polbFw81K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdnzlTC%2Fbtsar22EOxU%2F72qYcCpJmotC7polbFw81K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;750&quot; height=&quot;231&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;231&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. RNN&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Summary update : \(h_{t+1} = \operatorname{tanh}(W_{hh} h_t + W_{xh} x_{t+1} ) \) &amp;rarr; (time step \(t\)까지의 'summary' 개념)&lt;/li&gt;
&lt;li&gt;Prediction : \(O_{t+1} = W_{hh} h_{t+1}\) &amp;rarr; \(o_{t-1}\)으로 conditional \(p(x_t | x_{&amp;lt;i})\)의 parameter 결정&lt;/li&gt;
&lt;li&gt;Summary initialization : \(h_0 = \mathbf{b}_0\)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 long-range memory에 대해 간단하게 parameterize할 수 있으나, 다음과 같은 문제점을 갖는다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Sequential : 학습이 매우 느리다.&lt;/li&gt;
&lt;li&gt;Gradient vanishing or exploding : Weight matrix의 eigenvalue가 1보다 크거나 작은 경우 RNN이 갖는 단점으로, 결국 long-range dependency를 놓치기 쉽다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Modeling with CNN&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 단점을 해결하기 위해 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;CNN&lt;/span&gt;을 활용해볼 수 있다. 특히 sequential data를 다루기 위해서는 1차원 convolutional layer, 즉 Conv1D를 활용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;240&quot; data-origin-height=&quot;263&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WXMVg/btr8xP3QvTy/MnfnfdT6BxooZ95nCEKrbk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WXMVg/btr8xP3QvTy/MnfnfdT6BxooZ95nCEKrbk/img.jpg&quot; data-alt=&quot;Fig 3. 1D convolution example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WXMVg/btr8xP3QvTy/MnfnfdT6BxooZ95nCEKrbk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWXMVg%2Fbtr8xP3QvTy%2FMnfnfdT6BxooZ95nCEKrbk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;240&quot; height=&quot;263&quot; data-origin-width=&quot;240&quot; data-origin-height=&quot;263&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. 1D convolution example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNN을 활용하면 다음과 같은 장점이 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Parameter sharing : Kernel을 공유하므로 parameterization에 효율적이다.&lt;/li&gt;
&lt;li&gt;Parallel computation : 연산을 parallel하게 할 수 있어 효율적인 계산이 가능하다.&lt;/li&gt;
&lt;li&gt;Layer를 많이 쌓아 network를 깊게 구성할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 일반적인 Conv1D를 autoregressive model에 사용할 수는 없고, &lt;span style=&quot;color: #ee2323;&quot;&gt;causal convolution&lt;/span&gt;을 사용해야 한다. Causal이란 단어는 Conv1D layer가 이전 \(k\)개 input에 dependent하다는 의미이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;448&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9rZxI/btr8uTsFPW0/d4kk8vjjEt8Ae2T35bYY71/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9rZxI/btr8uTsFPW0/d4kk8vjjEt8Ae2T35bYY71/img.jpg&quot; data-alt=&quot;Fig 4. Causal convolution example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9rZxI/btr8uTsFPW0/d4kk8vjjEt8Ae2T35bYY71/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9rZxI%2Fbtr8uTsFPW0%2Fd4kk8vjjEt8Ae2T35bYY71%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;635&quot; height=&quot;397&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;448&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. Causal convolution example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 사진에서 첫 번째 CausalConv1D layer의 kernel size는 2이고, 두 번째와 세 번째는 각각 dilation(연산을 진행하는 간격의 개념)을 2, 3으로 적용하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CausalConv1D (A)와 (B)의 차이는 각각 \(d\)번째 variable을 포함하는지 (이전 \(k\)개에 현재 input까지 dependent한지) 아닌지이다. 당연히 위에서 주어진 conditional distribution \(d\)번째(위 식에서는 \(i\)) probability를 예측하는 데 \(x_d\)는 포함되면 안될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 원리를 WaveNet, PixelCNN 등에서 활용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Examples of Autoregressive Models&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Autoregressive model의 예시를 좀 더 자세히 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Fully Visible Sigmoid Belief Network (FVSBN)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Bernoulli 분포를 따르는 conditional variables \(X_i | X_1, \cdots, X_{i-1}\)가 있다고 하자. 그러면 \(x\)는 다음과 같이 예측해볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\(\hat{x} = p(X_i = 1 | x_{&amp;lt;i} ; \boldsymbol{\alpha}^i) = \sigma \left( \alpha_0^i + \sum\limits_{j=1}^{i-1} \alpha_j^i x_j \right) &amp;nbsp;\)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1188&quot; data-origin-height=&quot;1000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D53fL/btr8wPXmxdu/oRTFDxmHKYBmSHmkcpH2Hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D53fL/btr8wPXmxdu/oRTFDxmHKYBmSHmkcpH2Hk/img.png&quot; data-alt=&quot;Fig 5. FVSBN&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D53fL/btr8wPXmxdu/oRTFDxmHKYBmSHmkcpH2Hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD53fL%2Fbtr8wPXmxdu%2FoRTFDxmHKYBmSHmkcpH2Hk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;195&quot; height=&quot;164&quot; data-origin-width=&quot;1188&quot; data-origin-height=&quot;1000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. FVSBN&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Joint distribution \(p(x_1, \cdots, x_4)\)를 구하려면, 단순히 모든 conditional(factor)을 곱해서 구한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(p(X_1=0, X_2=1, X_3=1, X_4=0) = (1 - \hat{x}_1) \cdot \hat{x}_2 \cdot \hat{x}_3 \cdot (1 - \hat{x}_4)\)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( = (1 - \hat{x}_1) \cdot \hat{x}_2 (X_1 = 0) \cdot \hat{x}_3 (X_1 = 0, X_2 = 1) \cdot (1 - \hat{x}_4(X_1 = 0, X_2 = 1, X_3 = 1)) \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 MLP를 활용한 Autoregressive model보다 더 간단하게 logistic regression을 통해 memory limit 없이 모든 이전 condition을 활용하는 모델이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Neural Autoregressive Density Estimation (NADE)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;NADE 모델은 FVSBN의 logistic regression을 neural network(1 layer)로 바꾼 모델이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( \hat{x}_i = p(x_i | x_{&amp;lt;i}; A_i, \mathbf{c}_i, \boldsymbol{\alpha}_i, b_i) = \sigma(\boldsymbol{\alpha}_i \mathbf{h}_i + b_i )&amp;nbsp;\)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\mathbf{h}_i = \sigma(W_{\cdot , &amp;lt;i} \mathbf{x}_{&amp;lt;i} + \mathbf{c})\) : Neural network (1 layer)&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;186&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkIzpx/btr8uUZpVBj/QiMb8voPoqg3aKx8i6zgS0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkIzpx/btr8uUZpVBj/QiMb8voPoqg3aKx8i6zgS0/img.jpg&quot; data-alt=&quot;Fig 6. NADE&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkIzpx/btr8uUZpVBj/QiMb8voPoqg3aKx8i6zgS0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkIzpx%2Fbtr8uUZpVBj%2FQiMb8voPoqg3aKx8i6zgS0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;186&quot; height=&quot;312&quot; data-origin-width=&quot;186&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 6. NADE&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(W_{\cdot , &amp;lt;i}\)는 \(A_i\)에 해당하는 weight vector를 쌓은 matrix로, \(i-1\)개의 열을 갖는 matrix가 될 것이다. (반대로 \(\mathbf{x}\)는 \(i-1\)개의 행을 가질 것이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(A\)만 고려하면 \(\mathbf{h}_i\)는 각각 parameter를 \(i\)개씩 가질 것이므로, 총 복잡도는 \(1 + 2 + \cdots + n \), 즉 \(O(n^2)\)이다. 하지만 \(W\)를 통해 이전 weight vector를 공유하여 사용함으로써 n에 대해 선형 복잡도(\(O(n)\))를 갖는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-04-07 at 04.12.31.jpg&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;163&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UzKNq/btr8vIKViws/L6Q5o8txsWKsweR1HFxgNk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UzKNq/btr8vIKViws/L6Q5o8txsWKsweR1HFxgNk/img.jpg&quot; data-alt=&quot;Fig 7. Parameter sharing&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UzKNq/btr8vIKViws/L6Q5o8txsWKsweR1HFxgNk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUzKNq%2Fbtr8vIKViws%2FL6Q5o8txsWKsweR1HFxgNk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;553&quot; height=&quot;163&quot; data-filename=&quot;CleanShot 2023-04-07 at 04.12.31.jpg&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;163&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 7. Parameter sharing&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;General discrete distributions&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 random variable \(X_i\)가 binary distribution이 아니라 pixel intensity(0~255까지의 정수값)처럼 &lt;span style=&quot;color: #ee2323;&quot;&gt;discrete random variable&lt;/span&gt;이라면, \(\hat{\mathbf{x}}_i\)를 아래와 같이 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;categorical distribution&lt;/span&gt;으로 parameterize한다. 예를 들어, random variable을 \(X_i \in \{1, \cdots, K\}\)라 가정하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \hat{\mathbf{x}}_i = (p_i^1, \cdots, p_i^K) = \operatorname{softmax}(W_i \mathbf{h}_i + \mathbf{b}_i) \)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(p(x_i | x_{&amp;lt;i}) = \operatorname{Cat}(p_i^1, \cdots , p_i^K)\) : Categorical distribution&lt;/li&gt;
&lt;li&gt;\(\mathbf{h}_i = \sigma \left( W_{\cdot, &amp;lt;i} \mathbf{x}_{&amp;lt;i} + \mathbf{c} \right)\)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위(binary distribution)에서보다 일반적인 distribution을 모델링하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Real-valued Neural Autoregressive Density Estimation (RNADE)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;RNADE는 NADE의 variants 중 하나로, Gaussian distribution(즉 \(X_i\)가 &lt;span style=&quot;color: #ee2323;&quot;&gt;continuous random variable&lt;/span&gt;, 예를 들면 음성 신호 등)을 활용한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\(\hat{x}_i\)가 다음과 같이 continuous distribution을 parameterize한다고 해보자. (여러 개(\(K\))의 Gaussian을 더한 형태)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MYngc/btsar6JCawZ/qPwYhZjRAOX62Kir84DMB1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MYngc/btsar6JCawZ/qPwYhZjRAOX62Kir84DMB1/img.jpg&quot; data-alt=&quot;Fig 8. Continuous distribution example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MYngc/btsar6JCawZ/qPwYhZjRAOX62Kir84DMB1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMYngc%2Fbtsar6JCawZ%2FqPwYhZjRAOX62Kir84DMB1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;792&quot; height=&quot;224&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;224&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 8. Continuous distribution example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이때 \(p(x_i | \mathbf{x}_{&amp;lt;i})\)는 다음과 같이 모델링할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( p(x_i | x_1, \cdots, x_{i-1}) = \sum\limits_{j=1}^K \cfrac{1}{K} N(x_i ; \mu_i^j, \sigma_i^j) \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;또한 앞에서와 마찬가지로 neural network로 \(\hat{x}_i\)를 나타낼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( \mathbf{h} = \sigma(W_{\cdot, &amp;lt;i} \mathbf{x}_{&amp;lt;i} + \mathbf{c}) \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( \hat{x}_i = (\mu_i^1, \cdots , \mu_i^K, \sigma_i^1, \cdots, \sigma_i^K) = f(\mathbf{h}_i) \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 \(\hat{x}_i\)는 K개 Gaussian 각각의 평균, 표준편차 \((\mu^j, \sigma^j)\)를 정의한다. (표준편차 값을 확실히 양수로 만들기 위해 \(\operatorname{exp}\)를 취하기도 한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Generative Models</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/228</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Autoregressive-Generative-Models#entry228comment</comments>
      <pubDate>Fri, 7 Apr 2023 04:24:07 +0900</pubDate>
    </item>
    <item>
      <title>Generative Approach(Naive Bayes Classifier) vs Discriminative Approach(Logistic Regression)</title>
      <link>https://jjuke-brain.tistory.com/entry/Generative-ApproachNaive-Bayes-Classifier-vs-Discriminative-ApproachLogistic-Regression</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 포스팅에서 생성모델의 개요와 이해를 위한 기초 지식까지 알아보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 머신러닝 모델의 두 가지 종류인 &lt;span style=&quot;color: #ee2323;&quot;&gt;Naive Bayes classifier&lt;/span&gt;로 대표되는 &lt;span style=&quot;color: #ee2323;&quot;&gt;generative model&lt;/span&gt;의 접근방법과 &lt;span style=&quot;color: #ee2323;&quot;&gt;Logistic regression&lt;/span&gt;으로 대표되는 &lt;span style=&quot;color: #ee2323;&quot;&gt;discriminative model&lt;/span&gt;의 접근방법을 자세히 비교해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Introduction-to-Deep-Generative-Models&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전&lt;/a&gt;에 언급했듯, classification task에서 두 모델의 목적은 데이터 \(x\)와 class label \(y\)에 대해 posterior \(p(y|x)\)를 예측한다는 공통적인 목적을 갖고 있으나, 그 접근 방법이 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Bayes Network&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;우선 상대적으로 익숙한 logistic regression은 제쳐두고, bayes network에 대해 알아보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Bayesian Network&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Bayesian network에서는 chain rule과, (Markov property에 의한)conditional independence를 적용하여 compact한 representation을 얻는다. Chain rule, Bayes rule, conditional independence 등의 개념과 생성 모델에서의 활용은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Introduction-to-Deep-Generative-Models-2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 포스팅&lt;/a&gt;을 참고하자. 이 과정을 (계산량이 너무 큰 joint parameterization 대신)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;conditional parameterization&lt;/span&gt;이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;707&quot; data-origin-height=&quot;236&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Radsm/btr7hRXkiB9/Q3Xk49bxegin6uKqND4gyk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Radsm/btr7hRXkiB9/Q3Xk49bxegin6uKqND4gyk/img.jpg&quot; data-alt=&quot;Fig 1. Bayes network example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Radsm/btr7hRXkiB9/Q3Xk49bxegin6uKqND4gyk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRadsm%2Fbtr7hRXkiB9%2FQ3Xk49bxegin6uKqND4gyk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;707&quot; height=&quot;236&quot; data-origin-width=&quot;707&quot; data-origin-height=&quot;236&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Bayes network example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 말해, Fig 1과 같이 복잡한 모델인 결합 분포를 쉽게 표현하기 위해서 그래프(Directed Ascyclig Graph, DAG)로 표현하는데, 서로 관계가 없는 노드는 조건부 독립임을 활용하여 (소거해서) 간단히 표현해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 random variable \(x_i\)에 대해 random variable set \(\mathbf{x}_{\mathbf{A}_i}\)에 대한 distribution p(x_i \vert \mathbf{x}_{\mathbf{A}_i})를 정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선은 joint parameterization을 통해 \(p(x_1, \cdots, x_n) = \prod\limits_{i} p(x_i \vert \mathbf{x}_{\mathbf{A}_i})\)를 얻는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 chain rule으로 factorize하고, 각 factor들에 대해 conditional independence 가정(관계 없는 노드는 조건부 독립!)을 적용하여 간단한 형태를 얻는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 Bayesian network는&amp;nbsp;아래의 조건을 만족하는 directed acyclig graph \(G = (V, E)\)로 정해진다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 node \(i \in V\)의 random variable : \(x_i\)&lt;/li&gt;
&lt;li&gt;각 node \(i\)의 conditional probability distribution (CPD) : \(p(x_i \vert \mathbf{x}_{\text{Pa}(i)})\)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Parent(\(\text{Pa}\))의 node 값에 따라 conditional independent 성질을 갖게 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 따라, Bayesian network의 joint distribution은 다음과 같이 정의한다.&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(x_1, \cdots, x_n) = \prod\limits_{i \in V} p(x_i \vert \mathbf{x}_{\text{Pa}(i)}) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Example&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 다음과 같은 DAG로 나타난 Bayesian model이 있다고 해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-04-03 at 02.11.46.jpg&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;228&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NIbNt/btr7s3oQjal/ygj7FL59RHOGktsLHb5F1k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NIbNt/btr7s3oQjal/ygj7FL59RHOGktsLHb5F1k/img.jpg&quot; data-alt=&quot;Fig 2. Bayse network example (2)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NIbNt/btr7s3oQjal/ygj7FL59RHOGktsLHb5F1k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNIbNt%2Fbtr7s3oQjal%2Fygj7FL59RHOGktsLHb5F1k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;510&quot; height=&quot;228&quot; data-filename=&quot;CleanShot 2023-04-03 at 02.11.46.jpg&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;228&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Bayse network example (2)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 모델의 joint distribution을 구해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 단순히 모든 relation을 고려할 경우(연결? or not?)에는 distribution을 정하기 위해 \(2^5 - 1\)개의 parameter가 필요할 것이다. 하지만, Bayesian network의 정의(conditional independent 성질)를 활용하여 그 개수를 줄여줄 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 각 node를 (부모노드 순으로)D, I, G, S, L이라 하자. 이때 joint distribution은 정의를 활용하여 다음과 같이 나타낼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \begin{align*} &amp;amp; p(D, I, G, S, L) \\ &amp;amp;= p(D \vert \cancel{I}, \cancel{G}, \cancel{S}, \cancel{L}) p(I \vert \cancel{D}, \cancel{G}, \cancel{S}, \cancel{L}) p(G \vert D, I, \cancel{S}, \cancel{L}) p(S \vert \cancel{D}, I, \cancel{G}, \cancel{L}) p(L \vert \cancel{D}, \cancel{I} , G, \cancel{S}) \\ &amp;amp;= p(D) p(I) p(G \vert I, D) p(S \vert I) p(L \vert G) \end{align*} \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전처럼 joint distribution에 chain rule을 적용한다고 해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(p(D, I, G, S, L) = p(D) p(I | D) p( G | I, D) p(S | G, I, D) p(L | S, G, I, D)\)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역으로 Bayesian network 정의에 의한 식과 chain rule을 적용한 식을 비교해보면, 다음과 같은 conditional independency가 있음을 유추해볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( D \bot I, \; S \bot \{ D, G \} \vert I, \; L \bot \{D, I, S\} \vert G\)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 곧 Fig 2에서의 그림에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;'관계 없는 노드와는 조건부 독립'&lt;/span&gt;임을 만족한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Generative Approach vs Discriminative Approach&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;본격적으로 스팸 메일 구분 예시를 통해 Generative approach(Naive Bayes classifier)와 Discriminative approach(Logistic regression)를 비교해보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\(X_i\)는 특정 단어(word), \(X\)는 단어 집합(vocabulary), email이 스팸이면 \(Y=1\), 스팸이 아니면 \(Y=0\)이라 하자. \(i\)번째 word가 등장하면 \(X_i = 1\), 아니면 \(X_i = 0\)이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Chain rule을 사용하면 아래와 같이 나타낼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\(p(Y, \mathbf{X}) = p(\mathbf{X} | Y) p(Y) = p(Y | \mathbf{X}) p(\mathbf{X}) \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이를 Bayesian network(Directed Acyclic Graph)로 나타내면 다음과 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;210&quot; data-origin-height=&quot;169&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4lzjg/btr7Lq6oYtk/URvuioSebMozSkhbWBaAv0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4lzjg/btr7Lq6oYtk/URvuioSebMozSkhbWBaAv0/img.jpg&quot; data-alt=&quot;Fig 3. Bayesian network&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4lzjg/btr7Lq6oYtk/URvuioSebMozSkhbWBaAv0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4lzjg%2Fbtr7Lq6oYtk%2FURvuioSebMozSkhbWBaAv0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;210&quot; height=&quot;169&quot; data-origin-width=&quot;210&quot; data-origin-height=&quot;169&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Bayesian network&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종 목적인 prediction을 위해서는 \(p(Y|\mathbf{X})\)가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Generative model은 \(p(Y)\)와 \(p(\mathbf{X} | Y)\)를 둘 다 정의하고 학습한 후 Bayes rule을 통해 \(p(Y | \mathbf{X})\)를 계산해야 하지만, discriminative model은 conditional distribution \(p(Y | \mathbf{X})\)를 추정하기만 하면 된다. (p(\mathbf{X})\)는 주어졌으므로 모델링하거나, 학습하거나 사용할 필요가 없기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 \(\mathbf{X}\)가 주어졌을 때 \(Y\)의 label을 구분하는 것만으로 따졌을 때에는 (말그대로) discriminative model이 훨씬 유용하다고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조금 더 자세히 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(\mathbf{X}\)가 random vector이므로, chain rule을 사용하면 두 모델을 다음 그림과 식으로 나타낼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;382&quot; data-origin-height=&quot;181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bd6oXp/btr7Pq49b1w/Wrdq4NgWMhOMJeNPcWnUE1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bd6oXp/btr7Pq49b1w/Wrdq4NgWMhOMJeNPcWnUE1/img.jpg&quot; data-alt=&quot;Fig 4. Generative &amp;amp;amp; Discriminative model with chain rule&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bd6oXp/btr7Pq49b1w/Wrdq4NgWMhOMJeNPcWnUE1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbd6oXp%2Fbtr7Pq49b1w%2FWrdq4NgWMhOMJeNPcWnUE1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;382&quot; height=&quot;181&quot; data-origin-width=&quot;382&quot; data-origin-height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. Generative &amp;amp; Discriminative model with chain rule&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( p(Y, \mathbf{X}) = p(Y) p(X_1 | Y) p(X_2 | Y, X_1) \cdots p(X_n | Y, X_1, \cdots, X_{n-1})&amp;nbsp;\)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( p(Y, \mathbf{X}) = p(X_1) p(X_2 | X_1) p(X_3 | X_1, X_2) \cdots p(Y | X_1, \cdots, X_n) \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 두 가지 선택지가 존재한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Generative model : \(p(Y)\)는 심플하지만,&lt;span style=&quot;color: #ee2323;&quot;&gt; \(p(X_i | X_{\text{pa}(i)}, Y)\) term들을 어떻게 parameterize&lt;/span&gt;할 것인가?&lt;/li&gt;
&lt;li&gt;Discriminative model : &lt;span style=&quot;color: #ee2323;&quot;&gt;\(p(Y | \mathbf{X})\)를 어떻게 parameterize&lt;/span&gt;할 것인가?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Generative Model (Naive Bayes Classifier)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Naive Bayes classifier에서는 모든 데이터가 &lt;span style=&quot;color: #ee2323;&quot;&gt;조건부 독립&lt;/span&gt;이라고 가정하면서 식을 단순화한다. (가정 : \(X_i \bot \mathbf{X}_{1:i-1} | Y\) )&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 다음과 같이 나타낼 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(y, x_1, \cdots, x_n) = p(y) \prod\limits_{i=1}^n p(x_i | y) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-04-04 at 02.31.18.jpg&quot; data-origin-width=&quot;521&quot; data-origin-height=&quot;176&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dJZ8CK/btr7RqcKpMm/TRkIHR5nrHR8NmNnrG3nk0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dJZ8CK/btr7RqcKpMm/TRkIHR5nrHR8NmNnrG3nk0/img.jpg&quot; data-alt=&quot;Fig 5. Simplified generative model with assumption&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dJZ8CK/btr7RqcKpMm/TRkIHR5nrHR8NmNnrG3nk0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdJZ8CK%2Fbtr7RqcKpMm%2FTRkIHR5nrHR8NmNnrG3nk0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;521&quot; height=&quot;176&quot; data-filename=&quot;CleanShot 2023-04-04 at 02.31.18.jpg&quot; data-origin-width=&quot;521&quot; data-origin-height=&quot;176&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. Simplified generative model with assumption&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &lt;span style=&quot;color: #ee2323;&quot;&gt;training data로부터 parameter를 추정&lt;/span&gt;할 수 있고, &lt;span style=&quot;color: #ee2323;&quot;&gt;Bayes rule로 다음과 같이 prediction&lt;/span&gt;도 가능해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( p(Y=1 | \mathbf{X}) = \cfrac{p(Y=1, \mathbf{X})}{P(\mathbf{X})} = \cfrac{p(Y=1) \prod_{i=1}^n p(x_i | Y=1)}{\sum_{y=\{0,1\}} p(Y=y) \prod_{i=1}^n p(x_i | Y=y)} \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 분모는 discrete marginal distribution \(p(\mathbf{X})\)를 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Discriminative Model (Logistic Regression)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;200&quot; data-origin-height=&quot;150&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bp1IbF/btr7NPdKVWE/JYOhu99kn7E0KwIwZuD941/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bp1IbF/btr7NPdKVWE/JYOhu99kn7E0KwIwZuD941/img.jpg&quot; data-alt=&quot;Fig 6. Discriminative model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bp1IbF/btr7NPdKVWE/JYOhu99kn7E0KwIwZuD941/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbp1IbF%2Fbtr7NPdKVWE%2FJYOhu99kn7E0KwIwZuD941%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;200&quot; height=&quot;150&quot; data-origin-width=&quot;200&quot; data-origin-height=&quot;150&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 6. Discriminative model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Logistic regression에서는 다음과 같이 \(\boldsymbol{\alpha}\)로 parameterize된 \(\mathbf{x}\)에 대한 function을 가정한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(Y = 1 | \mathbf{x}; \boldsymbol{\alpha}) = f(\mathbf{x}, \boldsymbol{\alpha})&amp;nbsp;\)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Output 값은 0에서 1 사이여야 한다. (sigmoid activation function 등 사용)&lt;/li&gt;
&lt;li&gt;n+1개(weight n개, bias 1개)의 parameter vector \(\boldsymbol{\alpha}\)로 함수를 표현할 수 있다. (compact representation)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대표적으로 linear dependence \(z(\boldsymbol{\alpha}, \mathbf{x}) = \alpha_0 + \sum\limits_{i=1}^n \alpha_i x_i\)와 logistic function \(\sigma(z) = 1 / (1 + \operatorname{exp}^{-z})\)로 함수 \(f\)를 다음과 같이 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( p( Y = 1 | \mathbf{x}; \boldsymbol{\alpha}) = \sigma(z(\boldsymbol{\alpha}, \mathbf{x}))\)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;619&quot; data-origin-height=&quot;179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p4i3p/btr7HfcG0Hr/qgHfyDbsb3mgVO8pvxTsyK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p4i3p/btr7HfcG0Hr/qgHfyDbsb3mgVO8pvxTsyK/img.jpg&quot; data-alt=&quot;Fig 7. Decision boundary of discriminatie model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p4i3p/btr7HfcG0Hr/qgHfyDbsb3mgVO8pvxTsyK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp4i3p%2Fbtr7HfcG0Hr%2FqgHfyDbsb3mgVO8pvxTsyK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;619&quot; height=&quot;179&quot; data-origin-width=&quot;619&quot; data-origin-height=&quot;179&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 7. Decision boundary of discriminatie model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 7 예시와 같이, discriminative classifier의 경우 decision boundary(예를 들어 \(p(Y=1 | \mathbf{x}; \boldsymbol{\alpha}) &amp;gt; 0.5\) )가 선형적이다. 즉, 서로 같은 probability의 경계선이 선형으로 나타난다. 또한, 세 번째 그림을 보면 probability의 변화가 매우 급격하게, 확실하게 나타난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Analysis&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Logistic model은 Naive Bayes model과 달리 학습 데이터 간의 독립과 관련된 가정이 없으므로, 데이터가 많아질수록 더 정확해진다. 하지만 \(\mathbf{X}\)가 온전히 주어졌을 때에만 사용할 수 있고, misclassification 문제가 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 반해, generative model의 경우 몇몇 \(x_i\) 변수가 missing(unobserved)되었을 때에도 unseen variable들을 무시(marginalize)하면서 \(p(Y | \mathbf{X}_\text{evidence})\)로 계산할 수 있게 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Neural Models&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Neural model은 logistic model의 upgrade 버전으로 볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Discriminative model(logistic model)에서 \(p(Y=1 | \mathbf{x}; \boldsymbol{\alpha}) = f(\mathbf{x}, \boldsymbol{\alpha})\)라 하고, linear dependence를 적용했는데, neural model에서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;non-linear dependence&lt;/span&gt;를 적용한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\(\mathbf{h}(A, \mathbf{b}, \mathbf{x}) = f(A \mathbf{x} + \mathbf{b}) \quad \text{where } \mathbf{h} \text{ is a non-linear function} \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;즉, 아래와 같이 &lt;span style=&quot;color: #ee2323;&quot;&gt;pdf(probability density function)를 parameterize&lt;/span&gt;하는 개념이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p_\text{neural} (Y=1 | \mathbf{x}; \boldsymbol{\alpha}, A, \mathbf{b}) = \sigma (\alpha_0 + \sum_{i=1}^n \alpha_i h_i ) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;More flexible&lt;/li&gt;
&lt;li&gt;More parameters \(A, \mathbf{b}, \boldsymbol{\alpha}\)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 함수가 여러 번 반복되면 바로 neural network가 되는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;311&quot; data-origin-height=&quot;154&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yYAg1/btr7NPSo3nW/dAWPxFnL34tT3WIRzKYKp0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yYAg1/btr7NPSo3nW/dAWPxFnL34tT3WIRzKYKp0/img.jpg&quot; data-alt=&quot;Fig 8. Neural network&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yYAg1/btr7NPSo3nW/dAWPxFnL34tT3WIRzKYKp0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyYAg1%2Fbtr7NPSo3nW%2FdAWPxFnL34tT3WIRzKYKp0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;311&quot; height=&quot;154&quot; data-origin-width=&quot;311&quot; data-origin-height=&quot;154&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 8. Neural network&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Bayesian network과 비교해보자면, &quot;&lt;span style=&quot;color: #ee2323;&quot;&gt;chain rule을 사용한 모델(fully general) &amp;rarr; Bayes network(conditional independency) &amp;rarr; Neural model(functional form으로 joint distribution을 근사)&lt;/span&gt;&quot;로 이해해볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Using chain rule
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(p(x_1, x_2, x_3, x_4) = p(x_1) p(x_2 | x_1) p(x_3 | x_1, x_2) p(x_4 | x_1, x_2, x_3) \)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Bayes network
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( p(x_1, x_2, x_3, x_4) = p(x_1) p(x_2 | x_1) p(x_3 | \cancel{x_1}, x_2) p(x_4 | x_1, \cancel{x_2}, \cancel{x_3}) \)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Neural model
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( p(x_1, x_2, x_3, x_4) \approx p(x_1) p(x_2 | x_1) p_\text{neural} (x_3 | x_1, x_2) p_\text{neural} (x_4 | x_1, x_2, x_3) \)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Generative Models</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/227</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Generative-ApproachNaive-Bayes-Classifier-vs-Discriminative-ApproachLogistic-Regression#entry227comment</comments>
      <pubDate>Tue, 4 Apr 2023 03:12:59 +0900</pubDate>
    </item>
    <item>
      <title>Introduction to Deep Generative Models (2)</title>
      <link>https://jjuke-brain.tistory.com/entry/Introduction-to-Deep-Generative-Models-2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 deep generative model이 어떻게 분류되는지 high level에서 알아보고, 이러한 generative model을 공부하기 앞서 알아두어야 할 기본 지식을 간단히 복기해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Taxonomy of Deep Generative models&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Deep generative model은 학습 방식에 따라 다음과 같이 분류할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Autoregressive models (ex. PixelCNN)&lt;/li&gt;
&lt;li&gt;Flow-based models (ex. RealNVP)&lt;/li&gt;
&lt;li&gt;Latent variable models
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Implicit models (ex. GANs)&lt;/li&gt;
&lt;li&gt;Prescribed models (ex. VAEs)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Energy-based models&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Diffusion model의 경우 굳이 분류하자면 latent variable model이 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 분류에 따라 어떤 방식으로 학습을 진행하는지 간단하게 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Autoregressive Models (ARM)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Autoregressive model은 이름 그대로 autoregressive하게, 즉 &lt;span style=&quot;color: #ee2323;&quot;&gt;sequential data에 대해서 순차적으로 학습을 진행&lt;/span&gt;한다. (chain rule 사용)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;데이터 \(\mathbf{x}\)에 대한 distribution이 다음과 같이 autregressive하게 표현된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(\mathbf{x}) = p(x_0) \prod\limits_{i=1}^{D} p(x_i | \mathbf{x}_{&amp;lt;i}) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;모든 conditional disrtibution \(p(x_i | \mathbf{x}_{&amp;lt;i})\)을 모델링해야한다는 점에서 비효율적이지만, audio나 image에 대해 causal convolution의 이점을 갖는다.(likelihood를 계산할 수 있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Flow-based Models&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Flow-based model에서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;change of variables&lt;/span&gt;라는 공식을 활용하여 &lt;span style=&quot;color: #ee2323;&quot;&gt;invertible transformation \(f\)&lt;/span&gt;로 random variable의 density function을 변환한다. 이러한 방법으로 간단한 분포에서 복잡한 분포를 만들어가는 과정을 flow라 한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(\mathbf{x}) = p(\mathbf{z} = f(\mathbf{x})) \left\vert \mathbf{J}_{f(\mathbf{x})} \right\vert \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 \(\mathbf{J}\)는 (inverse 계산이 가능한) jacobian 행렬을 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Latent Variable Models&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Latent variable model에서는 저차원의(low-dimensional) latent space를 활용하여 다음과 같은 generative process를 가정한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{z} \sim p(\mathbf{z}) \)&lt;br /&gt;\( \mathbf{x} \sim p(\mathbf{x} | \mathbf{z} )\)&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Latent variable \(\mathbf{z}\)는 data에 숨겨진 특성(hidden factors)을 나타내고, generator는 \(p(\mathbf{x} | \mathbf{z})\)로 모델링된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Energy-based Models&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Energy-based model은 physics에 기반한 방법으로, 요즘은 활발히 연구되고있진 않다. Generative model들의 group을 Energy function \(E(x)\)를 정의하여 다음과 같은 Boltzmann distribution으로 모델링한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{x} = \cfrac{\operatorname{exp}\{- E(\mathbf{x}) \} }{Z} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Summary (Comparison)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Deep generative model들을 분류한 다양한 모델의 특성은 다음과 같이 표로 나타낼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;186&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMQggI/btr7iNfKz8A/iPl6KLAJbPGuoPtqu0op20/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMQggI/btr7iNfKz8A/iPl6KLAJbPGuoPtqu0op20/img.jpg&quot; data-alt=&quot;Table 1. Comparison of deep generative models&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMQggI/btr7iNfKz8A/iPl6KLAJbPGuoPtqu0op20/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMQggI%2Fbtr7iNfKz8A%2FiPl6KLAJbPGuoPtqu0op20%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;825&quot; height=&quot;186&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;186&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Table 1. Comparison of deep generative models&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Pre-knowledges&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;생성 모델을 알아보기 이전에, 이해에 필수적인 간단한 확률 통계 지식을 되짚어보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Basic Discrete Distributions&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Discrete distribution에는 대표적으로 Bernoulli distribution과 categorical distribution이 있다. 둘은 각각 '동전 뒤집기 (biased)', 'm개 면이 있는 주사위 뒤집기 (biased)'로 이해해볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 73px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;Bernoulli distribution&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;Categorical distribution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;Dimensions&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;{Heads, Tails}&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;{1, ..., m}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;Property&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;\(P(X=\text{Heads}) = p \Rightarrow P(X=\text{Tails}) = 1 - p\)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px; text-align: center;&quot;&gt;\(P(Y=i)=p_i \Rightarrow \sum\limits_{i} p_i = 1\), 즉 DOF가 i-1 (i-1개 알면 나머지 하나는 정해짐)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px; text-align: center;&quot;&gt;Expression&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px; text-align: center;&quot;&gt;\(X \sim \operatorname{Ber}(p)\)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 19px; text-align: center;&quot;&gt;\(Y \sim \operatorname{Cat}(p_1, \cdots, p_m)\)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;Sampling&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;동전 던지기&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;주사위 굴리기&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Joint Distribution&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1개 픽셀 생성(색 지정)&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;어떤 이미지에서 임의의 pixel의 color를 모델링한다고 해보자. 그러면 다음과 같은 세 가지 discrete random variable이 정의될 것이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Red channel (R) : \(\operatorname{Val}(R) = \{0, \dots, 255\}\)&lt;/li&gt;
&lt;li&gt;Green channel (G) : \(\operatorname{Val}(G) = \{0, \dots, 255\}\)&lt;/li&gt;
&lt;li&gt;Blue channel (B) : \(\operatorname{Val}(B) = \{0, \dots, 255\}\)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 픽셀에 color를 랜덤하게 생성해주려면 joint distribution \(p(R, G, B)\)에서 \((r, g, b)\)를 샘플링해야 한다. 이때, joint distribution \(p(R=r, G=g, B=b)\)를 정하기 위한 parameter의 개수는 무엇일까? (즉, 뽑을 수 있는 color의 경우의 수)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(256 \times 256 \times 256 - 1 = 16777215\) (-1은 위에서 언급한 categorical distribution의 DOF때문)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게, pixel 하나의 color를 샘플링하는 데에도 엄청나게 많은 경우의 수가 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1개 흑백 이미지 생성&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀 더 단순화시켜서, 이번에는 n개 픽셀에 대해 binary(Bernoulli) random variable \(x_1, \dots, x_n\)이 있다고 하자. Binary random variable이므로 흑백의 값을 가질 것이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\operatorname{Val}(x_i) = \{0, 1\} = \{\text{Black}, \text{White}\}\)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때, 가능한 state(image data 하나)의 경우의 수는 \(2^n\)일 것이다. 즉, n개 픽셀을 갖는 흑백 이미지 하나를 생성하기 위해 joint distribution \(p(x_1, \dots, x_n)\)을 정하기 위해 필요한 parameter 개수는 \(2^n -1\)개이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데, 만약 \(x_1, \dots, x_n\)이 서로 &lt;span style=&quot;color: #ee2323;&quot;&gt;독립(independent)이라면&lt;/span&gt;, joint distribution을 다음과 같이 나타낼 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(x_1, \dots, x_n ) = p(x_1) p(x_2) p(x_3) \cdots p(x_n) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 가능한 state 개수는 \(2^n\)으로 그대로지만, joint distribution \(p(x_1, \dots, x_n)\)을 정하기 위한 parameter 개수는 \(n\)개로 줄어든다. 그 이유는 marginal distribution \(p(x_1), p(x_2), p(x_3), \dots \)를 정하기 위해 필요한 parameter 개수가 각각 1개이기 때문이다. (Bernoulli distribution &amp;rarr; \(p(x_1 = 0) = p\)이면 \(p(x_1 = 1) = 1 - p\)이기 때문)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, \(n\)개 숫자로 \(2^n\)개 entry를 만들어낼 수 있다. 하지만, &lt;span style=&quot;color: #ee2323;&quot;&gt;independence assumption은 너무 strong&lt;/span&gt;하다. 쉽게 말하면 실제로 어떤 이미지에서 pixel의 색을 고를 때, 완전히 독립적으로 고르면 이미지가 어떤 원하는 형태로 생성될 수 없을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;conditional independence&lt;/span&gt;를 활용하여 모델을 단순화한다.(연산량을 줄인다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 event \(A, B\)가 주어진 event \(C\)에 대해 다음을 만족하면 \(A\)와 \(B\)는 conditional independent하다고 표현한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( P(A \cap B \vert C) = P(A \vert C) P(B \vert C) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 random variables \(x \in \operatorname{Val}(X), y \in \operatorname{Val}(Y), z \in \operatorname{Val}(Z)\)에 대해 다음을 만족하면 \(x\)와 \(y\)는 conditional independent하다고 한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( P(X \leq x \cap Y \leq y \vert Z = z) = P(X \leq x \vert Z = z) \cdot P(Y \leq y \vert Z = z) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 \(P(X \leq x, Y \leq y \vert Z = z)\)는 주어진 \(Z\)에 대해 \(X, Y\)의 conditional cumulative distribution function(cdf)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 간단히 \( P(X,Y | Z) = P(X | Z) P(Y | Z)\) 혹은&amp;nbsp; \(X \bot Y \vert Z\) 로 표현한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 조건부 독립을 만족할 경우(X와 Y가 Z가 주어졌을 때 독립이면) event \(Y\)는 \(Z\)가 주어졌을 때 \(X\)의 확률에 영향을 미치지 못하므로, 다음과 같은 성질을 갖는다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( P(X \vert Y, Z) = P(X \vert Z) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 성질을 통해 parameter 개수를 줄여줄 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Chain rule and Bayes' rule&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Chain rule과 Bayes' rule도 중요한 기본 개념이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Chain rule&lt;/span&gt;은 events \(S_1, \dots, S_n\)에 대해 다음 식과 같다. (\(p(S_i) &amp;gt; 0\))&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(S_1, S_2, \cdots, S_n) = p(S_1) p(S_2 \vert S_1) \cdots p(S_n \vert S_1, \cdots , S_{n-1}) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Bayes' rule&lt;/span&gt;은 event \(S_1, S_2\)에 대해 다음 식으로 표현한다. (\(p(S_1) &amp;gt; 0\) and \(p(S_2) &amp;gt; 0\))&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(S_1 \vert S_2) = \cfrac{p(S_1, S_2)}{p(S_2)} = \cfrac{p(S_2 \vert S_1) p(S_1)}{p(S_2)} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 다뤘던 '1개 흑백 이미지 생성' 예시에서, chain rule을 활용하면 joint distribution을 다음과 같이 나타낼 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(x_1, \cdots, x_n) = p(x_1) p(x_2 \vert x_1) p(x_3 \vert x_1, x_2) \cdots p(x_n \vert x_1, \cdots, x_{n-1}) \)&lt;br /&gt;\( \text{posterior} = \cfrac{\text{likelihood} \cdot \text{prior}}{\text{evidence}} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좌변의 distribution을 정하기 위한 parameter 개수는 \(2^n - 1\)개, 우변은 \(2^0 + 2^1 + 2^3 + \cdots + 2^{n-1} = 2^n - 1\)개로, parameter 개수는 줄어들지 않는다. (exponential)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, &lt;span style=&quot;color: #ee2323;&quot;&gt;chain rule을 통해 factorize한 term에 대해 conditional independence 성질을 적용하여 parameter 개수를 줄여&lt;/span&gt;줄 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델이 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Markov model&lt;/span&gt;이라 가정하자. Markov model이란, 오직 이전의 값에만 의존하는 모델로, '&lt;span style=&quot;color: #ee2323;&quot;&gt;이전 \(x\)가 주어졌을 때 그 이전의 모든 \(x\)에 대해 conditional independent하다&lt;/span&gt;'는 의미이다. 즉, \(x_{i+1} \bot x_1, \dots, x_{i-1} \vert x_i\)를 만족한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 다음과 같이 joint distribution이 단순화된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( p(x_1, \cdots, x_n) = p(x_1) p(x_2 \vert x_1) p(x_3 \vert \cancel{x_1}, x_2) \cdots p(x_n \vert \cancel{x_1}, \cancel{x_2}, \cancel{x_3}, \cdots, \cancel{x_{n-2}}, x_{n-1}) \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 parameter 개수는 \(1 + 2 + 2 + \cdots + 2 = 2n - 1\)개가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Generative Models</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/226</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Introduction-to-Deep-Generative-Models-2#entry226comment</comments>
      <pubDate>Mon, 3 Apr 2023 00:37:21 +0900</pubDate>
    </item>
    <item>
      <title>Introduction to Deep Generative Models (1)</title>
      <link>https://jjuke-brain.tistory.com/entry/Introduction-to-Deep-Generative-Models</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 카테고리에서는 Deep generative model 강의를 수강하고 주요 내용을 정리해두려 한다. 더 깊은 내용은 Jakub M. Tomczak의 'Deep Generative Modeling' 교재를 참고해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주요 내용은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Likelihood-based models
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Autoregressive generative models&lt;/li&gt;
&lt;li&gt;Flow-based models&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Latent variable models
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Variational learning&lt;/li&gt;
&lt;li&gt;Inference amortization&lt;/li&gt;
&lt;li&gt;Variational Autoencoder&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Implicit generative models
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Two sample tests, embeddings, F-divergences&lt;/li&gt;
&lt;li&gt;Generative Adversarial Networks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Diffusion Models&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Era of Deep Learning&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;몇년 전 AlphaGo에 세상이 놀라며 AI, 특히 딥러닝에 대한 관심이 아주 커졌다. 게다가 최근에는 ChatGPT가 등장하면서 그 관심과 발전 속도가 더더욱 빨라지고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 모델의 궁극적인 목표는 &lt;span style=&quot;color: #ee2323;&quot;&gt;사람처럼&lt;/span&gt; 복잡(complex)하고 체계화되지 않은(unstructured) 입력 데이터를 이해하는 것이다. 대표적인 활용 분야로는 Computer Vision, Natural Language Processing, Computational Speech, Robotics 등이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 Computer Vision 도메인을 예로 들어, '사람처럼 본다'라는 것의 의미는 무엇일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사람은 image나 video에서 직관적인 특징을 쉽게 추출한다. 이를 모방하기 위해 20여년 전부터 Caltech-101, Pascal-VOC, LabelMe, ImageNet, COCO 등 다양한 dataset(benchmark)들이 등장했고, computer vision 모델들은 이러한 dataset을 목표로 (알고리즘, gpu 등의 하드웨어, 데이터의 양 등에 힘입어) 성공적인 학습을 했다. 이러한 모델의 대표적인 예로 Mask R-CNN(2017, object detection task)이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 해당 dataset의 distribution에 국한된 학습을 한다는 한계를 갖고 있다. Intelligence는 단순히 주어진 dataset에 대한 패턴을 파악하거나 decision boundary를 생성하는 것이 아니라, 우리가 사는 세계를 모델링(modeling the world)는 것이다. 세계를 모델링하기 위해 AI 모델들의 support를 받을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Generative Models&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 분야에서의 generative model의 의미를 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Generative Modeling in Computer Graphics&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Computer Graphics에서 말하는 Generative modeling이란, 컴퓨터로 어떻게 자연스러운 이미지를 생성할 지 모델링하는 과정이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1008&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFUY83/btr7gS84idd/2nEwUKxdTV7cwhuJMlYN1K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFUY83/btr7gS84idd/2nEwUKxdTV7cwhuJMlYN1K/img.jpg&quot; data-alt=&quot;Fig 1. Generation and Inference in Computer Graphics&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFUY83/btr7gS84idd/2nEwUKxdTV7cwhuJMlYN1K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFUY83%2Fbtr7gS84idd%2F2nEwUKxdTV7cwhuJMlYN1K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1008&quot; height=&quot;380&quot; data-origin-width=&quot;1008&quot; data-origin-height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Generation and Inference in Computer Graphics&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 1에서 볼 수 있듯, high level에서 Cube, Cylinder를 정의해주었을 때 graphic(raw level)으로 생성하는 과정이 generation, graphic을 high level description으로 나타내는 과정이 inference 과정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Deep learning에서 말하는 generative model 또한 이러한 generation과 inference의 과정을 갖고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Statistical Generative Models&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Statistical generative model은 prior를 활용하여 data의 분포(probability distribution \(p(x)\))를 학습한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;198&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccpg8X/btr7gShq6J2/KNWxNK8kGW6LHiSNjkwUpk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccpg8X/btr7gShq6J2/KNWxNK8kGW6LHiSNjkwUpk/img.jpg&quot; data-alt=&quot;Fig 2. Data and prior knowledge&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccpg8X/btr7gShq6J2/KNWxNK8kGW6LHiSNjkwUpk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fccpg8X%2Fbtr7gShq6J2%2FKNWxNK8kGW6LHiSNjkwUpk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;621&quot; height=&quot;198&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;198&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Data and prior knowledge&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Deep generative model에서도 prior를 활용하지만, deep generative model은 data와 prior 중 data의 비율이 훨씬 높고, statistical generative model에서는 prior의 비율이 훨씬 많은 것으로 이해하면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Data는 training sample(example)으로 볼 수 있으며, prior knowledge는 Gaussian 등의 &lt;span style=&quot;color: #ee2323;&quot;&gt;parametric form&lt;/span&gt;, maximum likelihood 등의 &lt;span style=&quot;color: #ee2323;&quot;&gt;loss function&lt;/span&gt;, &lt;span style=&quot;color: #ee2323;&quot;&gt;optimization 알고리즘&lt;/span&gt; 등의 형태로 나타난다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;127&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcnx2B/btr7wf97tiR/Fq2v0sqFL2VF3TSrlR5z6K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcnx2B/btr7wf97tiR/Fq2v0sqFL2VF3TSrlR5z6K/img.jpg&quot; data-alt=&quot;Fig 3. Example of statistical generative model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcnx2B/btr7wf97tiR/Fq2v0sqFL2VF3TSrlR5z6K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbcnx2B%2Fbtr7wf97tiR%2FFq2v0sqFL2VF3TSrlR5z6K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;717&quot; height=&quot;127&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;127&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Example of statistical generative model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어, Fig 3에서와 같이 image \(x\)라는 data 하나를 통해 probability distribution \(p(x)\)를 얻고, 이를 여러 data에 대해 반복하여 probability \(p(\mathbf{x})\)를 얻는다. 이러한 \(p(\mathbf{x})\)에서 새로운 image를 샘플링할 수 있기 때문에 'generative'라고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Generative Model이란?&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;생성 모델(generative model)에 대해 좀 더 자세히 알아보자. Generative model은 &lt;span style=&quot;color: #ee2323;&quot;&gt;주어진 train set에 대해 같은 distribution을 갖는 새로운 sample들을 생성하는 모델&lt;/span&gt;을 말한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1056&quot; data-origin-height=&quot;273&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHWlU0/btr7mttZWuA/yqfQcU3XP4E9q2zD95K5K0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHWlU0/btr7mttZWuA/yqfQcU3XP4E9q2zD95K5K0/img.jpg&quot; data-alt=&quot;Fig 4. Generative model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHWlU0/btr7mttZWuA/yqfQcU3XP4E9q2zD95K5K0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHWlU0%2Fbtr7mttZWuA%2FyqfQcU3XP4E9q2zD95K5K0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1056&quot; height=&quot;273&quot; data-origin-width=&quot;1056&quot; data-origin-height=&quot;273&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. Generative model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 생성 모델의 목적은 &lt;span style=&quot;color: #ee2323;&quot;&gt;data의 distribution (pdf) \(p_\text{data} (x)\)를 근사하는 \(p_\text{model}(x)\)를 학습&lt;/span&gt;하고,&lt;span style=&quot;color: #ee2323;&quot;&gt; \(p_\text{model}(x)\)로부터 새로운 \(x\)를 샘플링&lt;/span&gt;하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Representation and Learning&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;생성모델의 representation과 learning에 대해 알아보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1142&quot; data-origin-height=&quot;448&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dCiBeU/btr7g7L1cWr/scjpcOL5bfRLculpcdqu80/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dCiBeU/btr7g7L1cWr/scjpcOL5bfRLculpcdqu80/img.jpg&quot; data-alt=&quot;Fig 5. Representation and Learning of Generative Model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dCiBeU/btr7g7L1cWr/scjpcOL5bfRLculpcdqu80/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdCiBeU%2Fbtr7g7L1cWr%2FscjpcOL5bfRLculpcdqu80%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1142&quot; height=&quot;448&quot; data-origin-width=&quot;1142&quot; data-origin-height=&quot;448&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. Representation and Learning of Generative Model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;실제 데이터의 분포에서 샘플링한 random variables \(\mathbf{x}_i \sim p_\text{data}\)는 아주 다양할 것이다. Fig 5 왼쪽 사진에서 볼 수 있듯이, '강아지'라는 같은 label의 데이터라 해도 각각의 생김새(종)가 다르며, 배경도 천차만별이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;학습을 위해서는 이러한 random variable들의 joint distribution을 수학적으로 모델링해야할 것인데, 이 과정을 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;representation&lt;/span&gt;이라 한다. 생성 성능을 높이기 위해서는 compact한 representation이 필요하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;또한 학습(&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Learning&lt;/span&gt;) 과정은 data distribution \(p_\text{data}\)를 근사하는, 즉 Model familty \(M\)에 속하는 parameter \(\theta\) 중에서 \(p_\text{data}\)와 가장 거리가 가까운 \(\theta\)를 찾는 과정인데, 이를 위해서는 probability distribution을 어떻게 비교할지(어떻게 거리가 가까운지 측정(measure)할지)가 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Inference&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;생성모델로 inference 할 수 있는 것은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Density estimation&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p_\theta(\mathbf{x}) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Density estimation이란, &lt;span style=&quot;color: #ee2323;&quot;&gt;datapoint \(\mathbf{x}\)가 주어졌을 때, model에 의해 정해지는 probability&lt;/span&gt;를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Sampling&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{x}_\text{new} \sim p_\theta(\mathbf{x}) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Sampling이란, &lt;span style=&quot;color: #ee2323;&quot;&gt;model의 distribution에서 새로운 datapoint를 생성하는 것&lt;/span&gt;을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Unsupervised representation learning&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unsupervised representation learning이란, &lt;span style=&quot;color: #ee2323;&quot;&gt;datapoint \(\mathbf{x}\)의 feature representation을 학습&lt;/span&gt;하는 것, 즉 data의 high level에서의 특징을 학습한다는 개념이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Discriminative vs Generative&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;머신러닝 모델은 크게 두 종류로 나뉘는데, discriminative model과 generative model이다. 두 모델의 차이점을 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Discriminative Classifiers vs Generative Classifiers&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Classification task에 한정하였을 때, classifier로서 두 모델은 각각&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;discriminative classifier와 generative classifier&lt;/span&gt;로 불린다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Prediction 과정&lt;/span&gt;은 수학적으로 입력 데이터 \(X\)와 class label \(Y\)에 대해 posterior \(P(Y|X)\)로 표현한다. (즉, prediction이란 주어진 입력 데이터에 대해 class label이 Y일 확률을 예측하는 것이다.) 두 classifier는 같은 목적으로 활용되지만 그 방법에서 차이를 보인다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;text-align: left;&quot;&gt;Discriminative classifier는 class를 구분하는&amp;nbsp;&lt;/span&gt;decision boundary를 직접적으로 모델링한다. 즉,&lt;/span&gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;\(P(Y|X)\)에 대한 함수를 가정하고, 학습 데이터 \(X\)로부터 직접 \(P(Y|X)\)를 추정&lt;/span&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 따라 &lt;span style=&quot;color: #ee2323;&quot;&gt;outlier에 강인&lt;/span&gt;하지만, &lt;span style=&quot;color: #ee2323;&quot;&gt;misclassification 문제가 존재&lt;span style=&quot;color: #333333;&quot;&gt;한다&lt;/span&gt;&lt;/span&gt;는 단점이 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이에 반해 generative classifier는 데이터셋의 각 class의 분포(패턴)를 모델링한다. 즉, \(P(Y|X)\)가 아니라 \(P(Y)\), \(P(X|Y)\)에 대한 함수를 가정하고, 학습 데이터로부터 &lt;span style=&quot;color: #ee2323;&quot;&gt;우선 \(P(Y)\)와 \(P(X|Y)\)를 추정한 후에 아래와 같이 bayes rule을 활용하여 \(P(Y|X)\)를 계산&lt;/span&gt;한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \text{posterior} = \cfrac{\text{prior} \times \text{likelihood} }{\text{evidence}} \Rightarrow P(Y|X) = \cfrac{P(Y) \cdot P(X|Y)}{P(X)} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 새로운 data를 생성할 수 있다는 특징을 갖지만, outlier에는 취약하다는 단점이 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 generative classifier(naive Bayes model)는 충분히 많은 데이터로 학습을 진행했을 때 asymptotic error(수렴한 error)가 discriminative classifier(logistic regression model)에 비해 크지만( \(\epsilon \left( h_{\text{Gen}, \infty} \right) &amp;gt; \epsilon \left( h_{\text{Dis}, \infty} \right) \) ), 충분한 학습을 위한 학습 데이터 개수가 비교적 적다(각각 \(O(\log n)\), \(O(n)\)). 이론적인 확실한 분석을 알아보려면 AI, 딥러닝 분야의 거장이신 앤드류 응 교수님과 마이클 조던 교수님의 논문 &quot;On Discriminative vs. Generative Classifiers: A comparison of Logistic Regression and Naive Bayes&quot;을 참조하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Generative model은 새로운 \(X\)를 생성한다고 했는데, 그 과정은 어떻게 진행되는지 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;384&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/752Ww/btr7msWN5sY/qgaU6dHhrH323TpyMtvpE1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/752Ww/btr7msWN5sY/qgaU6dHhrH323TpyMtvpE1/img.jpg&quot; data-alt=&quot;Fig 6. Generative model example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/752Ww/btr7msWN5sY/qgaU6dHhrH323TpyMtvpE1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F752Ww%2Fbtr7msWN5sY%2FqgaU6dHhrH323TpyMtvpE1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;384&quot; height=&quot;384&quot; data-origin-width=&quot;384&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 6. Generative model example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;input \(X\)가 주어지지 않은 상황이고, 이때 generative model은 joint distribution \(P(Y,X)\)를 모델링한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Conditional distribution을 joint distribution에 대해 써보면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(P(Y|X) = \cfrac{P(Y,X)}{P(X)}\)이고, 아래와 같은 그림으로 나타낼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;141&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8R6lK/btr7iJLmLJK/hofFe0scbqTv19KMLJNopK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8R6lK/btr7iJLmLJK/hofFe0scbqTv19KMLJNopK/img.jpg&quot; data-alt=&quot;Fig 7. Bayes rule in the example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8R6lK/btr7iJLmLJK/hofFe0scbqTv19KMLJNopK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8R6lK%2Fbtr7iJLmLJK%2FhofFe0scbqTv19KMLJNopK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;841&quot; height=&quot;141&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;141&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 7. Bayes rule in the example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 generation이란, \(P(Y|X)\)와 \(P(Y,X) (=P(Y) \cdot P(X|Y) )\)가 주어졌을 때 \(P(X)\)를 구하는 것으로 이해할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Discriminative model의 경우 \(X\)가 항상 주어지므로, \(P(X)\)를 모델링할 필요가 없다. 따라서 \(X\)의 데이터가 missing된다면(이미지 일부가 훼손되거나 주어지지 않는다면) \(P(Y|X)\)를 모델링할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;183&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bc9uDU/btr7hywmzcG/r65FmQ5JMoBMaYRdzDQy21/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bc9uDU/btr7hywmzcG/r65FmQ5JMoBMaYRdzDQy21/img.jpg&quot; data-alt=&quot;Fig 8. Limitation of discriminative model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bc9uDU/btr7hywmzcG/r65FmQ5JMoBMaYRdzDQy21/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbc9uDU%2Fbtr7hywmzcG%2Fr65FmQ5JMoBMaYRdzDQy21%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;824&quot; height=&quot;183&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;183&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 8. Limitation of discriminative model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 8에서 알 수 있듯, 사람은 noise가 조금 추가된 이미지도 고양이임을 쉽게 알아보지만, 엄격한 decision boundary를 갖는 discriminative model의 경우 missclassification의 문제가 생긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwsjGb/btr7n2RcJYD/BGCQM22F0u6cWADUv0Y220/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwsjGb/btr7n2RcJYD/BGCQM22F0u6cWADUv0Y220/img.jpg&quot; data-alt=&quot;Fig 9. Decision making example of discriminative model vs generative model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwsjGb/btr7n2RcJYD/BGCQM22F0u6cWADUv0Y220/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwsjGb%2Fbtr7n2RcJYD%2FBGCQM22F0u6cWADUv0Y220%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;830&quot; height=&quot;307&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 9. Decision making example of discriminative model vs generative model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 데이터가 주어졌을 때, discriminative model과 generative model이 x표시된 data point가 어디에 속하는지를 판단하는 과정을 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 discriminative model은 decision boundary를 통해 x표시된 지점이 &lt;span style=&quot;color: #ee2323;&quot;&gt;파란 label일 것이라고 확정&lt;/span&gt;한다. 하지만, generative model은 &lt;span style=&quot;color: #ee2323;&quot;&gt;x표시된 지점이 blue일 확률이 높지만, 동시에 x의 확률 분포 \(p(x)\)의 값이 낮다는 점도 고려&lt;/span&gt;한다. 즉, decision 자체가 확실치 않다(uncertain)는 것을 고려한다는 의미이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Conditional Generative Models&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Generative model의 이러한 decision making 과정 특성 상, label class를 조건(condition)으로 주었을 때 원하는 데이터를 생성할 수도 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( P(X|Y) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;309&quot; data-origin-height=&quot;74&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/u7Qpj/btr7n2KqqZz/52yzvflT04Kb5u16vTsMdk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/u7Qpj/btr7n2KqqZz/52yzvflT04Kb5u16vTsMdk/img.jpg&quot; data-alt=&quot;Fig 10. Conditional generation&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/u7Qpj/btr7n2KqqZz/52yzvflT04Kb5u16vTsMdk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fu7Qpj%2Fbtr7n2KqqZz%2F52yzvflT04Kb5u16vTsMdk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;309&quot; height=&quot;74&quot; data-origin-width=&quot;309&quot; data-origin-height=&quot;74&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 10. Conditional generation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 10은 class label \(Y\)로 'bedroom'이라는 condition을 주어 그에 해당하는 데이터(이미지) \(X\)를 생성하는 예시이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(Y\)에 간단한 class label 대신에 &quot;A black table with 6 chairs&quot; 등의 구체적인 caption(description)을 주어 text-to-image generation을 할 수도 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Examples of Generative Models&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Generation 관련 task에는 도메인에 따라 어떤 것이 있는지 간단하게 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Image Generation&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-04-02 at 23.43.03.jpg&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Wwv4S/btr7giOmZRs/v68r8uDAknEyGzw8Ffhhz1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Wwv4S/btr7giOmZRs/v68r8uDAknEyGzw8Ffhhz1/img.jpg&quot; data-alt=&quot;Fig. 11 Image generation examples (1)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Wwv4S/btr7giOmZRs/v68r8uDAknEyGzw8Ffhhz1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWwv4S%2Fbtr7giOmZRs%2Fv68r8uDAknEyGzw8Ffhhz1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;896&quot; height=&quot;426&quot; data-filename=&quot;CleanShot 2023-04-02 at 23.43.03.jpg&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;426&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig. 11 Image generation examples (1)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-04-02 at 23.43.41.jpg&quot; data-origin-width=&quot;932&quot; data-origin-height=&quot;430&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bB7hMR/btr7hxdbsaz/l1pr18CXh1zDaVkepNKOl1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bB7hMR/btr7hxdbsaz/l1pr18CXh1zDaVkepNKOl1/img.jpg&quot; data-alt=&quot;Fig 12. Image generation examples (2)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bB7hMR/btr7hxdbsaz/l1pr18CXh1zDaVkepNKOl1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbB7hMR%2Fbtr7hxdbsaz%2Fl1pr18CXh1zDaVkepNKOl1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;932&quot; height=&quot;430&quot; data-filename=&quot;CleanShot 2023-04-02 at 23.43.41.jpg&quot; data-origin-width=&quot;932&quot; data-origin-height=&quot;430&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 12. Image generation examples (2)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Text Generation&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;846&quot; data-origin-height=&quot;315&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgRbMB/btr7gjT4ZxB/IdmCWPdQo4buDOgEaaPw8k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgRbMB/btr7gjT4ZxB/IdmCWPdQo4buDOgEaaPw8k/img.jpg&quot; data-alt=&quot;Fig 13. Talktotransformer&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgRbMB/btr7gjT4ZxB/IdmCWPdQo4buDOgEaaPw8k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgRbMB%2Fbtr7gjT4ZxB%2FIdmCWPdQo4buDOgEaaPw8k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;846&quot; height=&quot;315&quot; data-origin-width=&quot;846&quot; data-origin-height=&quot;315&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 13. Talktotransformer&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-04-02 at 23.48.01.jpg&quot; data-origin-width=&quot;903&quot; data-origin-height=&quot;441&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WrwAD/btr7hT1Tz8v/eBCTaS0LuveCuMyTTRODuK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WrwAD/btr7hT1Tz8v/eBCTaS0LuveCuMyTTRODuK/img.jpg&quot; data-alt=&quot;Fig 14. ChatGPT&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WrwAD/btr7hT1Tz8v/eBCTaS0LuveCuMyTTRODuK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWrwAD%2Fbtr7hT1Tz8v%2FeBCTaS0LuveCuMyTTRODuK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;903&quot; height=&quot;441&quot; data-filename=&quot;CleanShot 2023-04-02 at 23.48.01.jpg&quot; data-origin-width=&quot;903&quot; data-origin-height=&quot;441&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 14. ChatGPT&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Audio Generation&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;351&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqEJTc/btr7pTzYUCX/rkTPdKmx5SnjXno8aMPl0k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqEJTc/btr7pTzYUCX/rkTPdKmx5SnjXno8aMPl0k/img.jpg&quot; data-alt=&quot;Fig 15. WaveNet&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqEJTc/btr7pTzYUCX/rkTPdKmx5SnjXno8aMPl0k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqEJTc%2Fbtr7pTzYUCX%2FrkTPdKmx5SnjXno8aMPl0k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;901&quot; height=&quot;351&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;351&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 15. WaveNet&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Image Super Resolution&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Super resolution은 이미지의 화질을 좋게 해주는 것으로, 다음과 같은 conditional generative model을 활용한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( P(\text{high resolution image} | \text{low resolution image} ) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;844&quot; data-origin-height=&quot;281&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biPR1X/btr7s4aadA5/8BaU895iBSBwGaSiTVG4jK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biPR1X/btr7s4aadA5/8BaU895iBSBwGaSiTVG4jK/img.jpg&quot; data-alt=&quot;Fig 16. SRGAN&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biPR1X/btr7s4aadA5/8BaU895iBSBwGaSiTVG4jK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiPR1X%2Fbtr7s4aadA5%2F8BaU895iBSBwGaSiTVG4jK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;844&quot; height=&quot;281&quot; data-origin-width=&quot;844&quot; data-origin-height=&quot;281&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 16. SRGAN&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Imitation Learning&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;강화학습에도 다음과 같이 conditional generative model이 활용될 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( P( \text{actions} | \text{past observations}) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Generative Models</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/225</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Introduction-to-Deep-Generative-Models#entry225comment</comments>
      <pubDate>Sat, 1 Apr 2023 19:03:55 +0900</pubDate>
    </item>
    <item>
      <title>파이썬 point_cloud_utils 라이브러리로 point cloud, mesh 다루기!</title>
      <link>https://jjuke-brain.tistory.com/entry/%ED%8C%8C%EC%9D%B4%EC%8D%AC-pointcloudutils-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC%EB%A1%9C-point-cloud-mesh-%EC%8B%9C%EA%B0%81%ED%99%94%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Trimesh, Open3d 등 다양한 point cloud 관련 라이브러리가&amp;nbsp; 있는데, 그중에서 point_cloud_utils로 point cloud를 특정 파일로 저장하여 meshlab에서 시각화하는 방법을 알아보려 한다. 시각화 할 때 어떤 라이브러리가 가장 좋다는 건 딱히 없고, 직접 사용해보면서 각각의 장단점을 파악하고 상황에 맞게 사용하면 될 듯 하다. (사실 point_cloud_utils 라이브러리는 시각화가 아니라 point cloud를 다루는 다양한 기능을 제공해주는 라이브러리이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;533&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y38Tx/btr630FpppR/lIWEkPosvZN3PumKBWsQCK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y38Tx/btr630FpppR/lIWEkPosvZN3PumKBWsQCK/img.jpg&quot; data-alt=&quot;Fig 1. Point Cloud Utils&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y38Tx/btr630FpppR/lIWEkPosvZN3PumKBWsQCK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy38Tx%2Fbtr630FpppR%2FlIWEkPosvZN3PumKBWsQCK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;894&quot; height=&quot;533&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;533&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Point Cloud Utils&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 포스팅에서 다룰 내용은 시각화에 사용할 간단한 함수들이고, github에 들어가보면 noise 생성, downsampling, mesh normal 계산, chamfer distance 계산 등 다양한 기능이 있으니 더 자세한 내용이 궁금하다면&amp;nbsp;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;깃허브&lt;/a&gt;를 참고하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Point cloud utils가 제공하는 기능들은 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#loading-meshes-and-point-clouds&quot;&gt;&lt;span&gt;Loading meshes and point clouds&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#saving-meshes-and-point-clouds&quot;&gt;&lt;span&gt;Saving meshes and point clouds&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#generating-blue-noise-samples-on-a-mesh-with-poisson-disk-sampling&quot;&gt;&lt;span&gt;Generating blue-noise samples on a mesh with Poisson-disk sampling&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#generate-random-samples-on-a-mesh&quot;&gt;&lt;span&gt;Generate random samples on a mesh&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#downsample-a-point-cloud-to-have-a-blue-noise-distribution&quot;&gt;&lt;span&gt;Downsample a point cloud to have a blue noise distribution&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#downsample-a-point-cloud-on-a-voxel-grid&quot;&gt;&lt;span&gt;Downsample a point cloud on a voxel grid&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#estimating-normals-from-a-point-cloud&quot;&gt;&lt;span&gt;Estimating normals from a point cloud&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#computing-mesh-normals-per-vertex&quot;&gt;&lt;span&gt;Computing mesh normals per vertex&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#computing-mesh-normals-per-face&quot;&gt;&lt;span&gt;Computing mesh normals per face&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#consistently-orienting-faces-of-a-mesh&quot;&gt;&lt;span&gt;Consistently orienting faces of a mesh&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#approximate-wasserstein-sinkhorn-distance-between-two-point-clouds&quot;&gt;&lt;span&gt;Approximate Wasserstein (Sinkhorn) distance between two point clouds&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#chamfer-distance-between-two-point-clouds&quot;&gt;&lt;span&gt;Chamfer distance between two point clouds&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#hausdorff-distance-between-two-point-clouds&quot;&gt;&lt;span&gt;Hausdorff distance between two point clouds&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#k-nearest-neighbors-between-two-point-clouds&quot;&gt;&lt;span&gt;K-nearest-neighbors between two point clouds&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#generating-point-samples-in-the-square-and-cube-with-lloyd-relaxation&quot;&gt;&lt;span&gt;Generating point samples in the square and cube with Lloyd relaxation&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#compute-shortest-signed-distances-to-a-triangle-mesh-with-fast-winding-numbers&quot;&gt;&lt;span&gt;Compute shortest signed distances to a triangle mesh with fast winding numbers&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#compute-closest-points-on-a-mesh&quot;&gt;&lt;span&gt;Compute closest points on a mesh&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#deduplicating-point-clouds-and-meshes&quot;&gt;&lt;span&gt;Deduplicating point clouds and meshes&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#removing-unreferenced-mesh-vertices&quot;&gt;&lt;span&gt;Removing unreferenced mesh verrtices&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#calculating-face-areas-of-a-mesh&quot;&gt;&lt;span&gt;Calculating face areas of a mesh&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#smoothing-a-mesh&quot;&gt;&lt;span&gt;Smoothing a mesh&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#computing-connected-components&quot;&gt;&lt;span&gt;Computing connected componentes&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#decimating-a-triangle-mesh&quot;&gt;&lt;span&gt;Decimating a triangle mesh&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#making-a-mesh-watertight&quot;&gt;&lt;span&gt;Making a mesh watertight&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#ray-mesh-intersection&quot;&gt;&lt;span&gt;Ray/Mesh intersection&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#ray-surfel-intersection&quot;&gt;&lt;span&gt;Ray/Surfel intersection&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#computing-curvature-on-a-mesh&quot;&gt;&lt;span&gt;Computing curvature on a mesh&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;a href=&quot;https://github.com/fwilliams/point-cloud-utils#computing-a-consistent-inside-and-outside-for-a-triangle-soup&quot;&gt;&lt;span&gt;Computing a consistent inside/outside for a triangle soup&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;point_cloud_utils and MeshLab Installation&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;point_cloud_utils는 터미널에서 다음 명령어로 설치한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1680176594252&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install point-cloud-utils
conda install point_cloud_utils -c conda-forge # 아나콘다 가상환경 사용하는 경우&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 MeshLab은 &lt;a href=&quot;https://www.meshlab.net/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;에서 다운받을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Useful Functions and Classes&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Load 관련 함수&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Load 관련된 함수들은 다음과 같다. PLY, STL, OFF, OBJ, 3DS, VRML 2.0, X3D, COLLADA 등 다양한 포맷(확장자)의 mesh 파일을 읽어올 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1680178019114&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Load vertices and faces for a mesh
v, f = pcu.load_mesh_vf(&quot;path/to/mesh&quot;)

# Load vertices and per-vertex normals
v, n = pcu.load_mesh_vn(&quot;path/to/mesh&quot;)

# Load vertices, per-vertex normals, and per-vertex-colors
v, n, c = pcu.load_mesh_vnc(&quot;path/to/mesh&quot;)

# Load vertices, faces, and per-vertex normals
v, f, n = pcu.load_mesh_vfn(&quot;path/to/mesh&quot;)

# Load vertices, faces, per-vertex normals, and per-vertex colors
v, f, n, c = pcu.load_mesh_vfnc(&quot;path/to/mesh&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;v : vertices&lt;/li&gt;
&lt;li&gt;f : faces&lt;/li&gt;
&lt;li&gt;n : 각 vertice의 normal&lt;/li&gt;
&lt;li&gt;c : 각 vertice의 color&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Save 관련 함수&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Save 관련된 함수들은 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1680180545121&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;v, f, n, c = pcu.load_mesh_vfnc(&quot;input_mesh.ply&quot;)

# Save vertices
pcu.save_mesh_v(&quot;path/to/mesh&quot;, v)

# Save mesh vertices and faces
pcu.save_mesh_vf(&quot;path/to/mesh&quot;, v, f)

# Save mesh vertices and per-vertex normals
v, n = pcu.save_mesh_vn(&quot;path/to/mesh&quot;, v, n)

# Save mesh vertices, per-vertex normals, and per-vertex-colors
v, n, c = pcu.save_mesh_vnc(&quot;path/to/mesh&quot;, v, n, c)

# Save mesh vertices, faces, and per-vertex normals
v, f, n = pcu.save_mesh_vfn(&quot;path/to/mesh&quot;, v, f, n)

# Save vertices, faces, per-vertex normals, and per-vertex colors
v, f, n, c = pcu.save_mesh_vfnc(&quot;path/to/mesh&quot;, v, f, n, c)&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;아래에서 설명할 TriangleMesh object 자체를 저장하거나 좀 더 구체적인 vertex, face 관련 정보를 주어 원하는 경로에 저장할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1680180219833&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import point_cloud_utils as pcu

pcu.save_triangle_mesh(&quot;[path to save mesh]&quot;, v=[position of vertices],
						f=[face indices], vn=[vertex normals], fn=[face normals])
                        
triangle_mesh_object.save(&quot;[path to save mesh]&quot;) # directly save pcu.TriangleMesh object&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;TriangleMesh class&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;TriangleMesh는 좀 더 복잡한 정보를 포함하는 mesh class이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;TriangleMesh 클래스로 인스턴스를 생성하게 되면 mesh의 vertices, faces와 관련된 다음과 같은 정보를 담을 수 있다. 모든 데이터는 numpy array이다. 없으면 안되는 정보는 required로 표시하였다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;vertex_data
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;positions [V, 3] :&amp;nbsp;점의 위치 (required)&lt;/li&gt;
&lt;li&gt;normals [V, 3] : 각 점의 normal&lt;/li&gt;
&lt;li&gt;texcoords [V, 2] : 각 점의 uv coordinate&lt;/li&gt;
&lt;li&gt;tex_ids [V,] : 각 점이 해당하는 texture(Triangle.textures)에 대한 index&lt;/li&gt;
&lt;li&gt;colors [V, 4] : 각 점의 RBGA color (값 범위 : 0.0 ~ 1.0)&lt;/li&gt;
&lt;li&gt;radius [V,] : 각 점의 반지름&lt;/li&gt;
&lt;li&gt;quality [V,] : 각 점의 quality measure&lt;/li&gt;
&lt;li&gt;flags [V,] : 각 점의 32bit 정수 flag&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;face_data
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;vertex_ids [F, 3] : 각 점(TriangleMesh.vertex_data.positions)이 해당하는 face의 index (required)&lt;/li&gt;
&lt;li&gt;normals [F, 3], colors [F, 4], quality [F,], flags [F,] : 각 face의 normal, RBGA color, quality measure, flag&lt;/li&gt;
&lt;li&gt;wedge_colors [F, 3, 4], wedge_normals [F, 3, 3], wedge_texcoords [F, 3, 2], wedge_tex_ids [F, 3] : 각 wedge의 RBGA color, normal, uv coordinate, texture index&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;textures : mesh에 사용되는 image file paths (list) (required)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Example with ShapeNet dataset&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Dataset Preparation&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;ShapeNet이라는 3D pointcloud 데이터셋을 시각화해볼 것이다. 준비단계를 건너뛰고 바로 'visualization with point_cloud_utils'로 넘어가도 상관없다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 dataset을 가져올 dataset.py를 작성한다.&lt;/p&gt;
&lt;pre id=&quot;code_1680176991302&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import os
import random
from copy import copy
import torch
from torch.utils.data import Dataset, DataLoader
import numpy as np
import h5py
from tqdm.auto import tqdm

class ShapeNetCore(Dataset):

    GRAVITATIONAL_AXIS = 1
    
    def __init__(self, path, cates, split, scale_mode, transform=None):
        super().__init__()
        assert isinstance(cates, list), '`cates` must be a list of cate names.'
        assert split in ('train', 'val', 'test')
        assert scale_mode is None or scale_mode in ('global_unit', 'shape_unit', 'shape_bbox', 'shape_half', 'shape_34')
        self.path = path
        if 'all' in cates:
            cates = cate_to_synsetid.keys()
        self.cate_synsetids = [cate_to_synsetid[s] for s in cates]
        self.cate_synsetids.sort()
        self.split = split
        self.scale_mode = scale_mode
        self.transform = transform

        self.pointclouds = []
        self.stats = None

        self.get_statistics()
        self.load()

    def get_statistics(self):

        basename = os.path.basename(self.path)
        dsetname = basename[:basename.rfind('.')]
        stats_dir = os.path.join(os.path.dirname(self.path), dsetname + '_stats')
        os.makedirs(stats_dir, exist_ok=True)

        if len(self.cate_synsetids) == len(cate_to_synsetid):
            stats_save_path = os.path.join(stats_dir, 'stats_all.pt')
        else:
            stats_save_path = os.path.join(stats_dir, 'stats_' + '_'.join(self.cate_synsetids) + '.pt')
        if os.path.exists(stats_save_path):
            self.stats = torch.load(stats_save_path)
            return self.stats

        with h5py.File(self.path, 'r') as f:
            pointclouds = []
            for synsetid in self.cate_synsetids:
                for split in ('train', 'val', 'test'):
                    pointclouds.append(torch.from_numpy(f[synsetid][split][...]))

        all_points = torch.cat(pointclouds, dim=0) # (B, N, 3)
        B, N, _ = all_points.size()
        mean = all_points.view(B*N, -1).mean(dim=0) # (1, 3)
        std = all_points.view(-1).std(dim=0)        # (1, )

        self.stats = {'mean': mean, 'std': std}
        torch.save(self.stats, stats_save_path)
        return self.stats

    def load(self):

        def _enumerate_pointclouds(f):
            for synsetid in self.cate_synsetids:
                cate_name = synsetid_to_cate[synsetid]
                for j, pc in enumerate(f[synsetid][self.split]):
                    yield torch.from_numpy(pc), j, cate_name
        
        with h5py.File(self.path, mode='r') as f:
            for pc, pc_id, cate_name in _enumerate_pointclouds(f):

                if self.scale_mode == 'global_unit':
                    shift = pc.mean(dim=0).reshape(1, 3)
                    scale = self.stats['std'].reshape(1, 1)
                elif self.scale_mode == 'shape_unit':
                    shift = pc.mean(dim=0).reshape(1, 3)
                    scale = pc.flatten().std().reshape(1, 1)
                elif self.scale_mode == 'shape_half':
                    shift = pc.mean(dim=0).reshape(1, 3)
                    scale = pc.flatten().std().reshape(1, 1) / (0.5)
                elif self.scale_mode == 'shape_34':
                    shift = pc.mean(dim=0).reshape(1, 3)
                    scale = pc.flatten().std().reshape(1, 1) / (0.75)
                elif self.scale_mode == 'shape_bbox':
                    pc_max, _ = pc.max(dim=0, keepdim=True) # (1, 3)
                    pc_min, _ = pc.min(dim=0, keepdim=True) # (1, 3)
                    shift = ((pc_min + pc_max) / 2).view(1, 3)
                    scale = (pc_max - pc_min).max().reshape(1, 1) / 2
                else:
                    shift = torch.zeros([1, 3])
                    scale = torch.ones([1, 1])

                pc = (pc - shift) / scale

                self.pointclouds.append({
                    'pointcloud': pc,
                    'cate': cate_name,
                    'id': pc_id,
                    'shift': shift,
                    'scale': scale
                })

        # Deterministically shuffle the dataset
        self.pointclouds.sort(key=lambda data: data['id'], reverse=False)
        random.Random(2020).shuffle(self.pointclouds)

    def __len__(self):
        return len(self.pointclouds)

    def __getitem__(self, idx):
        data = {k:v.clone() if isinstance(v, torch.Tensor) else copy(v) for k, v in self.pointclouds[idx].items()}
        if self.transform is not None:
            data = self.transform(data)
        return data&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 dataset class를 사용하여 dataset instance를 생성해준 후, dataloader를 만들어준다.&lt;/p&gt;
&lt;pre id=&quot;code_1680177140592&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dataset_instance = ShapeNetCore(path=dataset_path, cates=categories,
                                split='train', scale_mode='shape_unit', transform=None)

train_loader = DataLoader(dataset=dataset_instance,
                          batch_size=8,
                          shuffle=False)

data = next(iter(train_loader)) # dataset class의 __getitem__을 통해 가져온 data&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Data가 dictionary 형태로 저장되어 있는데, key를 출력해보면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;823&quot; data-origin-height=&quot;72&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqDPGk/btr64lpe16I/auW8I7tCrN3I0Y5RmSWSQK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqDPGk/btr64lpe16I/auW8I7tCrN3I0Y5RmSWSQK/img.jpg&quot; data-alt=&quot;Fig 2. Keys of ShapeNet Data&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqDPGk/btr64lpe16I/auW8I7tCrN3I0Y5RmSWSQK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdqDPGk%2Fbtr64lpe16I%2FauW8I7tCrN3I0Y5RmSWSQK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;823&quot; height=&quot;72&quot; data-origin-width=&quot;823&quot; data-origin-height=&quot;72&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Keys of ShapeNet Data&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Batch size가 8이므로, point cloud를 제외한 각 데이터를 출력한 결과는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;840&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beN7Sl/btr64l3RdIY/HZADCzTNZDyMKqFx87CzF1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beN7Sl/btr64l3RdIY/HZADCzTNZDyMKqFx87CzF1/img.jpg&quot; data-alt=&quot;Fig 3. Data Example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beN7Sl/btr64l3RdIY/HZADCzTNZDyMKqFx87CzF1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeN7Sl%2Fbtr64l3RdIY%2FHZADCzTNZDyMKqFx87CzF1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;825&quot; height=&quot;840&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;840&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Data Example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Visualization with point_cloud_utils and MeshLab&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 본격적으로 point cloud를 시각화해보자. 다음과 같이 라이브러리를 import해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1680177614232&quot; class=&quot;elm&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import point_cloud_utils as pcu&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 코드를 통해 dataloader로 불러온 point들을 vertices로 주어서 ply파일에 저장한다.&lt;/p&gt;
&lt;pre id=&quot;code_1680182590989&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import point_cloud_utils as pcu

for i in range(len(data['pointcloud'])):
    pc = data['pointcloud'][i].detach().cpu().numpy()
    triangle_mesh_obj = pcu.TriangleMesh()
    triangle_mesh_obj.VertexData.positions = pc
    triangle_mesh_obj.save(&quot;/root/data_sj/DPMPC/ShapeNet_examples/{}.ply&quot;.format(i))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;batch size가 8이므로 다음과 같이 8개의 ply파일이 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;454&quot; data-origin-height=&quot;322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/culaJ2/btr60GIi64y/iWXebybF5NROOv60BP9iak/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/culaJ2/btr60GIi64y/iWXebybF5NROOv60BP9iak/img.jpg&quot; data-alt=&quot;Fig 4. Saved .ply files&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/culaJ2/btr60GIi64y/iWXebybF5NROOv60BP9iak/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FculaJ2%2Fbtr60GIi64y%2FiWXebybF5NROOv60BP9iak%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;454&quot; height=&quot;322&quot; data-origin-width=&quot;454&quot; data-origin-height=&quot;322&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. Saved .ply files&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 파일들을 MeshLab에서 열어보면 다음과 같이 point cloud를 시각화해볼 수 있다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;236&quot; data-origin-height=&quot;322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dpH6RJ/btr60FQdqph/3uuR5LHrsjeDyQFCK0t43K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dpH6RJ/btr60FQdqph/3uuR5LHrsjeDyQFCK0t43K/img.jpg&quot; data-alt=&quot;Fig 5. Chair visualization example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dpH6RJ/btr60FQdqph/3uuR5LHrsjeDyQFCK0t43K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdpH6RJ%2Fbtr60FQdqph%2F3uuR5LHrsjeDyQFCK0t43K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;236&quot; height=&quot;322&quot; data-origin-width=&quot;236&quot; data-origin-height=&quot;322&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. Chair visualization example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Research/Implementation</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/224</guid>
      <comments>https://jjuke-brain.tistory.com/entry/%ED%8C%8C%EC%9D%B4%EC%8D%AC-pointcloudutils-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC%EB%A1%9C-point-cloud-mesh-%EC%8B%9C%EA%B0%81%ED%99%94%ED%95%98%EA%B8%B0#entry224comment</comments>
      <pubDate>Thu, 30 Mar 2023 21:58:28 +0900</pubDate>
    </item>
    <item>
      <title>npy, npz 파일 다루기!</title>
      <link>https://jjuke-brain.tistory.com/entry/npy-npz-%ED%8C%8C%EC%9D%BC-%EB%8B%A4%EB%A3%A8%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;Numpy 라이브러리를 사용하여 array를 다룰 때, 해당 array를 저장하거나 저장된 array를 불러와야 하는 경우가 있다. 이와 관련하여 npy, npz 확장자의 파일이 무엇인지, 자주 활용하는 함수는 무엇인지 알아보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;.npy, .npz 파일이란?&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'.npy' 확장자, '.npz' 확장자를 갖는 파일은 Numpy 라이브러리에서 읽고 쓸 수 있는 바이너리 파일이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npy파일은 1개의 ndarray, npz는 여러 개의 ndarray를 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;&lt;b&gt;유용한 함수 및 예제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;numpy array(ndarray)를 읽고 쓰는 것과 관련된 함수는 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;save(file_path, numpy_arr, &amp;hellip;) : numpy_arr를 .npy 포맷으로 file_path에 저장&lt;/li&gt;
&lt;li&gt;savez(file_path, args, *kwds) : args와 kwgs에 여러 배열을 입력하여 .npz포맷으로 file_path에 저장&lt;/li&gt;
&lt;li&gt;savez_compressed(file_path, args, *kwds) : savez와 동일하지만, 데이터를 압축&lt;/li&gt;
&lt;li&gt;load(file_path, &amp;hellip;) : .npy 파일 혹은 .npz 파일을 읽어옴&lt;/li&gt;
&lt;li&gt;close() : 불러온 ndarray 파일 object를 메모리에서 지움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시와 함께 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Save and Load&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 npy 파일, 즉 ndarray 하나를 저장하고 불러올 때의 예시이다.&lt;/p&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;import numpy as np

x = np.array([0, 1, 2, 3, 4, 5])

# save to example.npy file
np.save('/root/dev/example', x)

# load
loaded_npy = np.load('/root/dev/example.npy')
print(loaded_npy)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;481&quot; data-origin-height=&quot;308&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dIwNCc/btr6sthWAiS/NXHRvWtTBq8bScrfGSVRMk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dIwNCc/btr6sthWAiS/NXHRvWtTBq8bScrfGSVRMk/img.jpg&quot; data-alt=&quot;Fig 1. npy save and load result&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dIwNCc/btr6sthWAiS/NXHRvWtTBq8bScrfGSVRMk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdIwNCc%2Fbtr6sthWAiS%2FNXHRvWtTBq8bScrfGSVRMk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;481&quot; height=&quot;308&quot; data-origin-width=&quot;481&quot; data-origin-height=&quot;308&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. npy save and load result&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로 mpz 파일, 즉 여러 개의 ndarray를 저장하고 불러올 때의 예시이다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;import numpy as np

x = np.array([0, 1, 2, 3, 4, 5])
y = np.array([6, 7, 8, 9, 10, 11])

# save to example2.npz file
np.savez('/root/dev/example2', name1=x, name2=y) # name should be given!

# load
loaded_npz = np.load('/root/dev/example2.npz')
print(loaded_npz['name1']) # x
print(loaded_npz['name2']) # y&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;723&quot; data-origin-height=&quot;370&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGhE3y/btr6qNntKx4/JVTjTsD0t1NfNqO6nBe6ck/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGhE3y/btr6qNntKx4/JVTjTsD0t1NfNqO6nBe6ck/img.jpg&quot; data-alt=&quot;Fig 2. npz save and load result&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGhE3y/btr6qNntKx4/JVTjTsD0t1NfNqO6nBe6ck/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGhE3y%2Fbtr6qNntKx4%2FJVTjTsD0t1NfNqO6nBe6ck%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;723&quot; height=&quot;370&quot; data-origin-width=&quot;723&quot; data-origin-height=&quot;370&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. npz save and load result&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 불러온 npz파일에 어떤 array가 들어있는 지 (이름을) 모른다면, 다음과 같이 직접 key를 print한다. (단순히 print(loaded_npz.keys())로는 key 내용이 출력되는 게 아니라 'KeysView'라는 object만 출력된다.)&lt;/p&gt;
&lt;pre id=&quot;code_1682307144964&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for key in loaded_npz.keys():
    print(key)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Close&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npy는 ndarray 자체를 가져오기 때문에 필요 없지만, npz 파일에서 object를 불러오고 사용한 이후에는 메모리 효율 관리를 위해 'close()' 함수로 닫아주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;닫은 이후에는 인덱싱이 불가능해진다!&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;loaded_npz.close()
loaded_npz['name1'] # &amp;rarr; Error: 'NoneType' object has no attribute 'open'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1110&quot; data-origin-height=&quot;431&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFto6A/btr6yaPS7lT/96WqbIT9RYunKJW9MJdBJ1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFto6A/btr6yaPS7lT/96WqbIT9RYunKJW9MJdBJ1/img.jpg&quot; data-alt=&quot;Fig 3. NpzFile object close result&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFto6A/btr6yaPS7lT/96WqbIT9RYunKJW9MJdBJ1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFto6A%2Fbtr6yaPS7lT%2F96WqbIT9RYunKJW9MJdBJ1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1110&quot; height=&quot;431&quot; data-origin-width=&quot;1110&quot; data-origin-height=&quot;431&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. NpzFile object close result&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science, Programming/Python</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/223</guid>
      <comments>https://jjuke-brain.tistory.com/entry/npy-npz-%ED%8C%8C%EC%9D%BC-%EB%8B%A4%EB%A3%A8%EA%B8%B0#entry223comment</comments>
      <pubDate>Tue, 28 Mar 2023 14:04:13 +0900</pubDate>
    </item>
    <item>
      <title>리눅스(맥, 우분투 등) 터미널에서 유용하게 쓰이는 명령어 모음</title>
      <link>https://jjuke-brain.tistory.com/entry/%EB%A7%A5-%ED%84%B0%EB%AF%B8%EB%84%90%EC%97%90%EC%84%9C-%EC%9C%A0%EC%9A%A9%ED%95%98%EA%B2%8C-%EC%93%B0%EC%9D%B4%EB%8A%94-%EB%AA%85%EB%A0%B9%EC%96%B4-%EB%AA%A8%EC%9D%8C</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;맥북과 우분투 터미널에서 유용하게 쓰이는 명령어(리눅스 명령어)를 정리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세한 설명보다는 자주 잊어버리는 명령어를 찾기 쉽게 간단히 정리하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;&amp;nbsp;파일 및 디렉토리 관련&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657689947418&quot; class=&quot;jboss-cli&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ls
ls -a
ls -l
ls -al # a, l 순서 상관 x&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;폴더나 파일의 목록을 출력한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;-a : 숨겨진 파일이나 디렉토리를 모두 표시한다.&lt;/li&gt;
&lt;li&gt;-l : 파일이나 폴더의 설명을 함께 출력한다.&lt;/li&gt;
&lt;li&gt;-al : a 옵션과 l 옵션을 함께 적용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순 목록 출력 뿐만 아니라, 특정 폴더에 포함된 파일이나 디렉토리의 개수를 다음 명령어를 통해 출력해볼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1706506096182&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ls -l [dir_path] | grep ^- | wc -l # number of files
ls -l [dir_path] | grep ^d | wc -l # number of directories(folders)

# example
ls -l /root/dev/jjuke | grep ^- | wc -l # /root/dev/jjuke 폴더의 파일 개수&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657689977293&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd [경로]
cd ..
cd ~
cd -&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 디렉토리(경로)에 진입한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;cd .. : 현재 디렉토리에서 상위 디렉토리로 이동한다.&lt;/li&gt;
&lt;li&gt;cd ~ : 사용자 홈 디렉토리로 이동한다.&lt;/li&gt;
&lt;li&gt;cd - : 전에 있었던 디렉토리로 이동한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 'cd + 공백' 후 tab을 누르면 경로가 자동완성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657690090296&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;rm [삭제파일 or 삭제 디렉토리]
rm -r [삭제파일 or 삭제 디렉토리]
rm -f [삭제파일 or 삭제 디렉토리]
rm -rf [삭제파일 or 삭제 디렉토리]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;폴더나 파일을 삭제한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;rm -r [삭제파일 or 삭제 디렉토리] : 하위 경로의 파일을 삭제한다.&lt;/li&gt;
&lt;li&gt;rm -f [삭제파일 or 삭제 디렉토리] : 강제로 삭제한다.&lt;/li&gt;
&lt;li&gt;rm -rf [삭제파일 or 삭제 디렉토리] : r, f 옵션 모두 적용&lt;/li&gt;
&lt;li&gt;rm -v [삭제파일 or 삭제 디렉토리] : 삭제 후 결과를 보여준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657690375840&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cp [복사할 디렉토리/파일] [복사될 디렉토리/파일]
cp -r [복사할 디렉토리/파일] [복사될 디렉토리/파일]
cp -f [복사할 디렉토리/파일] [복사될 디렉토리/파일]
cp -rf [복사할 디렉토리/파일] [복사될 디렉토리/파일]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;폴더나 파일을 복사한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;cp -r [복사할 디렉토리/파일] [복사될 디렉토리/파일] : 하위 디렉토리까지 모두 복사한다.&lt;/li&gt;
&lt;li&gt;cp -f [복사할 디렉토리/파일] [복사될 디렉토리/파일] : 복사될 파일(디렉토리)이름이 이미 존재할 경우, 강제로 덮어쓴다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657690490847&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mv [옵션] [이동할 파일1] [이동할 파일2] ... [이동될 경로]
mv * [이동될 경로]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일을 이동시킨다. (f 옵션은 위와 같으며, 폴더를 이동할 시 하위의 모든 파일 및 폴더도 같이 옮겨진다.)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;* : 현 위치의 모든 파일을 이동시킨다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657689715851&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pwd&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 디렉토리의 위치를 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657689777956&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mkdir [생성할 디렉토리명]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 디렉토리(폴더)를 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657689795288&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;touch [생성할파일명]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 파일을 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657689815055&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cat [파일명]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일의 내용을 터미널에 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657689756353&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wget [다운로드url]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Web Get의 약어로, 웹 상의 파일을 다운받을 때 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1659342267707&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;find [경로] [옵션] [파일명]
find / -name '*.txt' # root에서부터 검색해서 확장자가 txt인 모든 파일 검색
find / -name 'test*' # 파일명이 test로 시작하는 모든 파일 검색
find / -name 'test' # 파일명이 test인 모든 파일 검색
find -name 'test' # 경로 입력하지 않을 시 해당 디렉토리부터 하위 디렉토리에서 검색&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원하는 파일을 찾는 명령어이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;응용하면 다음과 같이 유용하게 활용해볼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1709207629488&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;find /path/to/root -type d -name &quot;*specific_name.txt&quot; -exec rm -r {} +
find /path/to/root -type f -name &quot;*specific_name.txt&quot; -exec rm {} +
find /path/to/root -type f -name &quot;*.zip&quot; -exec unzip {} \;

find /path/to/root -type f -name &quot;*specific_name.txt&quot; | wc -l # 하위에서 전부 찾음
ls /path/to/root | grep &quot;specific_name.txt&quot; | wc -l # 해당 디렉토리에서만 찾음&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 두 명령어는 [/path/to/root]의 하위에서 &quot;specific_name&quot;이라는 이름이 포함된 폴더 혹은 &quot;specific_name.txt&quot;라는 이름이 포함된 파일을 찾아 해당 폴더나 파일을 지우는 명령어이고, 세 번째 명령어는 압축을 해제하는 명령어이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 명령어들은 각각 순서대로 해당 파일명을 갖는 파일을 path 하위에서 전부 찾거나, 해당 path에서만 찾아 개수를 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-exec 옵션은 찾은 파일이나 폴더에 대해 어떠한 명령어를 실행해주겠다는 의미이고, {}는 찾은 파일 혹은 폴더의 path이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 리눅스에서 \;는 unzip이라는 명령어를 여러 번 수행한다는 의미이고, +는 명령어에 찾은 path를 여러 번 argument로 준다는 의미이다. 예를 들어, 현재 폴더에 &quot;a.zip&quot;, &quot;b.zip&quot;, &quot;c.zip&quot;, &quot;a.txt&quot;, &quot;b.txt&quot;, c.txt&quot; 파일이 있다면 각각 다음과 같은 명령이 실행된다.&lt;/p&gt;
&lt;pre id=&quot;code_1713431893882&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# find . -type f -name &quot;.zip&quot; unzip {} \;
unzip a.zip
unzip b.zip
unzip c.zip

# find . -type f -name &quot;.zip unzip {} +
unzip a.zip b.zip c.zip # error!

# find . -type f -name &quot;.txt&quot; rm {} +
rm a.txt b.txt c.txt # remove multiple files&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;&amp;nbsp;터미널 관련&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657689543380&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;clear&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터미널의 내용을 모두 지우는 명령어이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1658459574178&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;command \
continue1 \
continue2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어가 길어질 경우, '\'를 사용하여 줄바꿈을 할 수 있다. 위 세 줄은 모두 하나의 명령어로 인식한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 폴더명 또는 파일명에 공백이 포함되는 경우에는 경로 자체를 '' 또는 &quot;&quot;로 묶어주거나, '\ + 공백'으로 공백을 입력해줄 수 있다. 공백 자체가 터미널에서는 명령어의 일부로 인식하기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1658463331470&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;| # 명령과 명령을 연결
; # 여러 명령을 연결
&amp;amp;&amp;amp; # 앞에서부터 순차적으로 실행
|| # 앞에서부터 순차적으로 실행&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터미널에서 다중 명령어의 종류는 위와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'|'는 두 명령 중 왼쪽 명령의 실행 결과를 오른쪽 명령어의 입력으로 전달하는 것이며, ';'는 연결된 명령을 왼쪽부터 차례대로 (여러 개) 실행하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 '&amp;amp;&amp;amp;'는 명령 실행에 실패할 경우 뒷 명령어를 실행하지 않지만(and), '||'는 반대로 명령 실행에 성공할 때 뒷 명령어를 실행하지 않는다.(or)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657689561746&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;history
history | grep [검색할 단어]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;history는 이전에 사용한 명령어들을 순서대로 확인하는 명령어이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'grep'이라는 명령어와 함께 사용하여 특정 단어를 사용했던 명령어 중에서 찾을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;


&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;&amp;nbsp;서버 관련&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657690864189&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ssh [사용자 계정]@[원격지 ip] -p[포트] # 원격지 접속
exit # 접속 해제 (logout)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원격 서버 접속과 로그아웃 명령어이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-p 옵션을 통해 원격 호스트에 연결할 포트를 지정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657691266107&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo adduser [계정 이름] # user 생성
sudo usermod -aG docker [계정 이름] # docker 사용 권한 등록
sudo passwd [계정 이름] # 계정 비밀번호 변경
sudo deluser [계정 이름] # 해당 계정 삭제&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;adduser를 통해 유저 생성을 해줄 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;usermod 명령어는 계정에 sudo 권한을 주는 명령어인데, 계정 생성 시 기본 그룹이 sudo이다. 대표적인 옵션은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;-d : 사용자의 홈 디렉토리 변경한다.&lt;/li&gt;
&lt;li&gt;-m : 홈 디렉토리 변경 시 기존 파일 및 디렉토리를 옮겨준다. (-d와 함께 쓰인다.)&lt;/li&gt;
&lt;li&gt;-g : 사용자의 그룹을 변경한다.&lt;/li&gt;
&lt;li&gt;-c : 사용자의 간단한 정보를 입력하거나 변경한다.&lt;/li&gt;
&lt;li&gt;-G : 추가로 다른 그룹에 속하게 한다.&lt;/li&gt;
&lt;li&gt;-a : -G와 같이 많이 사용하며, 2차 그룹을 지정(추가)한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657692430743&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sftp -P[포트번호] [계정 이름]@[ip주소] # SFTP 접속 - port option이 대문자 P임에 유의!
get [파일 이름 또는 경로] # 로컬 경로에 파일을 다운받음
put [파일 이름] # 로컬에서 파일 업로드
mget [파일 이름 또는 경로 1] [파일 이름 또는 경로 2] ... # 다수 파일 다운로드
mput [파일 이름 또는 경로 1] [파일 이름 또는 경로 2] ... # 다수 파일 업로드
ls # 접속한 sftp의 파일 목록
!ls # 로컬 서버의 파일 목록
![명령어] # 로컬 서버에서 실행&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sftp SSH File Transfer Protocol (FTP)으로, 서버에 대한 보안 연결을 만드는 과정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연결을 진행한 후, get 등의 명령어를 통해 파일 업로드 / 다운로드 등의 작업을 진행할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 로컬이란, sftp 접속 명령을 실행했던 곳을 말하며, 경로는 접속 명령 당시의 경로가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;&amp;nbsp;파일 및 디렉토리 관리 (다운로드, 압축, 디스크 관리 등)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1658390240275&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wget [option] ... [URL] ...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--머릿말 끝--&gt;&lt;!--소제목1--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;wget은 'web get'의 약어로, 웹 상의 파일을 다운로드 받을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자주 사용하는 옵션은 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;-c : 다운로드 중단된 파일을 이어서 받는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 파일을 다운받기 위해서는 txt파일 내에 URL 여러 개를 입력하여 저장한 후, 아래와 같은 명령어를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1658391006592&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vim download_list.txt # 다른 방법으로도 txt파일 생성 가능
URL1
URL2
URL3
URL4

# txt파일 저장 후
wget -i download_list.txt&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 vim 사용법은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Docker-SSH-Visual-Studio-Code%EB%A1%9C-%EC%9E%91%EC%97%85-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0?category=865140#2._Dockerfile_%EB%A7%8C%EB%93%A4%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 참조하자. (또는 'vim 사용법'이라고 구글링하면 쉽게 배워볼 수 있을 것이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스에서 파일을 압축할 때에는 tar 명령어를 사용하며, 결과 파일의 확장자는 tar 또는 tar.gz가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tar은 엄밀히 말하면 단순히 파일들을 묶어주는(아카이빙) 역할을 한다. 따라서 묶은 파일들의 용량이 줄어들지 않는다. 이에 반해 tar.gz 확장자로 압축하게 되면 gzip을 통해 압축까지 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 확장자가 '.tar.gz'인 파일로 압축할 때에는 '-zcvf', 해당 파일을 해제할 때에는 '-zxvf' 옵션을 많이 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1658459094026&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;tar [옵션] [압축 결과 파일명] [압축할 폴더명(경로)]
tar [옵션] [파일명]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;옵션은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;-c : 파일을 tar로 묶어 생성한다.&lt;/li&gt;
&lt;li&gt;-x : 기존 tar 파일의 압축을 해제한다.&lt;/li&gt;
&lt;li&gt;-v : 압축 또는 해제할 때 과정을 화면에 출력한다.&lt;/li&gt;
&lt;li&gt;-f : 파일 이름을 지정한다.&lt;/li&gt;
&lt;li&gt;-C : 파일 경로를 지정한다.&lt;/li&gt;
&lt;li&gt;-z : gzip으로 압축 또는 해제한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;압축할 폴더명은 절대 경로를 사용해주기보다, &quot;cd&quot; &lt;span style=&quot;color: #ee2323;&quot;&gt;명령어로 압축할 폴더의 상위 폴더까지 가서 명령어를 입력&lt;/span&gt;해주는 것이 편하다.&lt;/p&gt;
&lt;pre id=&quot;code_1707724911133&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# tar 압축하기 (./example &amp;rarr; ./example.tar)
tar -cvf example.tar example
# tar 압축 풀기(./example.tar &amp;rarr; ./example)
tar -xvf example.tar

# tar.gz로 압축하기 (./example &amp;rarr; ./example.tar.gz)
tar -zcvf example.tar.gz example
# tar.gz 압축파일 풀기 (./example.tar.gz &amp;rarr; ./example)
tar -zxvf example.tar.gz&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원하는 경로에 압축을 풀고 싶을 경우, 아래와 같이 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1667837181432&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;tar -zxvf tarfile.tar.gz -C ./testdir/ # ./testdir 경로에 압축 풀기&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1666327221048&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;df -h # 전체 디스크의 남은 용량
du -sh [directory path] # 특정 경로가 차지하는 용량
du -sh&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원하는 directory가 차지하는 용량으라 사람이 보기 쉽게 정렬하여 알려준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 디렉토리 용량을 알고싶으면 아무것도 입력하지 않거나 directory path에 '.'을 입력해주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science, Programming/Git, Docker, Server, Linux</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/124</guid>
      <comments>https://jjuke-brain.tistory.com/entry/%EB%A7%A5-%ED%84%B0%EB%AF%B8%EB%84%90%EC%97%90%EC%84%9C-%EC%9C%A0%EC%9A%A9%ED%95%98%EA%B2%8C-%EC%93%B0%EC%9D%B4%EB%8A%94-%EB%AA%85%EB%A0%B9%EC%96%B4-%EB%AA%A8%EC%9D%8C#entry124comment</comments>
      <pubDate>Mon, 27 Mar 2023 15:44:04 +0900</pubDate>
    </item>
    <item>
      <title>협업을 위한 Git branch 사용법</title>
      <link>https://jjuke-brain.tistory.com/entry/%ED%98%91%EC%97%85%EC%9D%84-%EC%9C%84%ED%95%9C-Git-branch-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
      <description>&lt;pre id=&quot;code_1748841183641&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout -b existing_branch # local에 existing_branch라는 branch 생성
git pull origin existing_branch # remote repository의 exiting_branch의 내용물을&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연구를 하다보면 필연적으로 협업을 하게 되는데, git을 활용하면 main branch를 나누어 팀원들이 각자 branch를 파서 맡은 부분을 구현하고, main에 merge하는 것(합치는 것)이 안전하다. (개발을 할 때에는 issue를 다루기 위해 사용하기도 하는데, 이는 gitflow를 다루 때 자세히 알아보기로 한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 브랜치를 만들고, 로컬에서 기본 브랜치를 설정 및 변경하는 방법을 알아보려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Git branch 주요 명령어&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1678768931346&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git branch&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 명령어는 다양한 옵션을 통해 branch 생성, 제거, 상태 확인 등을 할 수 있는 명령어이다. (remote repository 브랜치의 생성은 경우 github에서 'new branch'를 눌러 더 직관적으로 할 수 있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무 옵션을 주지 않으면 '-l'이 생략된 것으로, &lt;span style=&quot;color: #ee2323;&quot;&gt;로컬의 branch 정보&lt;/span&gt;(remote repository의 branch 정보가 아님에 유의하자!)를 보여준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;393&quot; data-origin-height=&quot;63&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dbNyk5/btr3Qx0XODB/H2MxQkdwKAcNBvnrlIX0xk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dbNyk5/btr3Qx0XODB/H2MxQkdwKAcNBvnrlIX0xk/img.jpg&quot; data-alt=&quot;Fig 1. git branch result&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dbNyk5/btr3Qx0XODB/H2MxQkdwKAcNBvnrlIX0xk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdbNyk5%2Fbtr3Qx0XODB%2FH2MxQkdwKAcNBvnrlIX0xk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;393&quot; height=&quot;63&quot; data-origin-width=&quot;393&quot; data-origin-height=&quot;63&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. git branch result&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;옵션에 따른 다양한 명령어를 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;-v&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1678769005844&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git branch -v&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬 branch들의 마지막 커밋 내역을 보여준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;-r&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1678769232895&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git branch -r&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Remote repository&lt;/span&gt;의 branch 정보를 보여준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;-a (★★★)&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1678769273530&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git branch -a&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Local, remote repository의 모든 branch 정보를 보여준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Local branch는 이름만, remote branch는 'remotes/origin/...'와 같은 형식으로 표시된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Merge된 branch, merge되지 않은 branch 표시&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1678769789253&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git branch --merged
git branch --no-merged&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;merge된(--merged)/merge되지 않은(-no-merged) 브랜치를 표시한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;브랜치 생성, 이동, 이름 변경&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1678769444906&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git branch [로컬브랜치명]
git push origin [리모트브랜치명]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'로컬브랜치명'에 해당하는 &lt;span style=&quot;color: #ee2323;&quot;&gt;새로운 branch를 로컬에 생성&lt;/span&gt;한다. Remote branch는 push 명령어로 생성할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1678769604720&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout [로컬브랜치명]
git checkout -b [로컬브랜치명]
git checkout -b [로컬브랜치명] [리모트브랜치명]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 기본적으로, (이미 생성된) '로컬브랜치명' 브랜치로 이동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-b 옵션을 줄 경우, 생성과 동시에 해당 branch로 이동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'리모트브랜치명'도 입력해줄 경우, remote repository의 해당 브랜치와 연결된 '로컬브랜치명' 브랜치를 로컬에 생성하고, 이동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, A, B 컴퓨터에서 main 브랜치로만 작업을 하다가, A 컴퓨터에서 'ex'라는 branch를 새로 만들고, 이와 연결된 'example'이라는 remote branch를 생성했다고 하자. 즉, A 컴퓨터에서의 local branch는 'main', 'ex'이고, remote branch는 'main', 'example'이다. 이때, B 컴퓨터에서는 &lt;b&gt;git branch -a&lt;/b&gt; 명령어를 쳐보면 'ex'라는 로컬 브랜치는 물론, 'example'이라는 remote branch도 뜨지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 &lt;span style=&quot;color: #ee2323;&quot;&gt;B 컴퓨터도 A 컴퓨터와 같은 환경이 되기 위해&lt;/span&gt;서는, &lt;b&gt;git remote update&lt;/b&gt;로 remote branch 상황을 업데이트 해준 후, &lt;b&gt;git checkout -b ex remotes/origin/example&lt;/b&gt; 명령어를 실행하면 A 컴퓨터와 같은 세팅이 된다. (remote branch -a로 확인해보면, 정확한 remote branch의 이름에는 &quot;remotes/origin/&quot;이 들어간다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1678769911052&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git branch -m [변경할 브랜치명] [변경될 브랜치명]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬의 '변경할 브랜치명' 브랜치를 '변경될 브랜치명' 브랜치로 이름을 변경한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;옵션으로 -M을 사용할 경우, 기존에 동일한 이름의 branch가 있어도 덮어쓴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;현재 브랜치에서 commit하지 않은 변경 사항을 새로운 branch로 옮겨 작업하고 싶을 때&lt;/span&gt;가 있다. 그럴 때는 아래와 같이 stash 명령어를 사용한다. stash는 마무리하지 않은 작업을 스택에 잠시 저장하는 명령어이다. 완료하지 않은 일을 commit하지 않고 나중에 stash pop 명령어로 꺼내올 수 있는데, 이를 이용하여 다른 브랜치로 변경 사항을 옮길 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1711563953947&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git stash --include-untracked
git checkout -b [다른 로컬 브랜치]
git stash pop&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;--include-untracked는 track되지 않은 파일, 즉 새로 생성된 파일까지 모두 스택에 저장하는 옵션이다. 옵션을 주지 않으면 새 파일은 옮겨지지 않고 수정된 파일만 저장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;checkout으로 '다른 로컬 브랜치'를 생성한 후 이동하며, 그곳에서 stash pop을 통해 스택에 저장된 변경 사항을 불러온다. 기존 로컬 브랜치에는 변경 사항이 사라지게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;브랜치 삭제&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1678769995754&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git branch -d [로컬브랜치명]
git push origin -d [리모트브랜치명]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬 브랜치 혹은 리모트 브랜치를 삭제한다. 로컬 브랜치의 경우, 아직 commit merge를 하지 않았다면 삭제되지 않는데, 이때 -D 옵션으로 강제 삭제할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Remote와 local branch 연결&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;로컬의 branch와 remote repository의 branch의 연결과 관련된 명령어를 알아보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1678770354088&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git fetch origin&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원격 저장소(origin)의 변경 사항을 확인한다. 사실 git &lt;span style=&quot;color: #ee2323;&quot;&gt;pull 명령어는 git fetch와 git merge가 합쳐진 명령어&lt;/span&gt;이다. 즉 변경 사항(최신 데이터)을 복사하여 로컬 git에 가져온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원격 저장소에 변경 사항이 존재하는 상황에서 pull을 바로 실행할 경우, 현재 브랜치와 작업 복사본의 파일이 변경되는 동시에 새로 작업한 내용은 손실될 수 있다. 따라서 fetch로 변경 사항을 먼저 확인한 후에 pull을 실행하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1712069978316&quot; class=&quot;inform7&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;git branch -u origin/[리모트브랜치명] [로컬브랜치명]
git branch --set-upstream-to origin/[리모트브랜치명]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬의 '로컬브랜치명' 브랜치(혹은 현재 로컬 브랜치)가 'origin' remote repository의 '리모트브랜치명' 브랜치를 트래킹하도록 설정한다. 쉽게 말해 local 브랜치를 remote 브랜치와 연결해주는 과정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, local에서 새로운 branch &quot;test_branch&quot;를 생성하고, 같은 이름의 branch를 remote에도 생성한 후, 연결하려면 아래의 순서대로 명령어를 입력한다.&lt;/p&gt;
&lt;pre id=&quot;code_1712069410299&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout -b test_branch # 로컬 브랜치 &quot;test_branch&quot; 생성 후 해당 브랜치로 이동
git push origin test_branch # 리모트 브랜치 &quot;test_branch&quot; 생성
git branch --set-upstream-to origin/test_branch # 현재 브랜치(&quot;test_branch&quot;)를 리모트 브랜치 &quot;test_branch&quot;와 연결&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 예시는 다음과 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot_2024-04-02_23.47.37@2x.png&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;1094&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qrXBV/btsGjCLcZuj/5FCyHs4uvR7RTNjFuv4BV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qrXBV/btsGjCLcZuj/5FCyHs4uvR7RTNjFuv4BV1/img.png&quot; data-alt=&quot;Fig 2. Result of the connection between local branch and remote branch&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qrXBV/btsGjCLcZuj/5FCyHs4uvR7RTNjFuv4BV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqrXBV%2FbtsGjCLcZuj%2F5FCyHs4uvR7RTNjFuv4BV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1306&quot; height=&quot;1094&quot; data-filename=&quot;Screenshot_2024-04-02_23.47.37@2x.png&quot; data-origin-width=&quot;1306&quot; data-origin-height=&quot;1094&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Result of the connection between local branch and remote branch&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로, 이미 존재하는 remote repository의 existing_branch를 local branch로 가져오려면, 아래 순서대로 명령어를 입력해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1748841668987&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git checkout -b existing_branch # 'existing_branch'라는 이름의 로컬 브랜치 생성
git pull origin existing_branch # remote repository의 'existing_branch'의 내용 pull
git branch -u origin/existing_branch existing_branch # 생성한 로컬 브랜치가 remote branch를 track하도록 설정
git branch -v # 확인&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;브랜치 병합&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt; 브랜치의 내용을 서로 병합하고싶은 경우가 있다. (local에서 병합 후 remote에는 내용이 변경된 branch에서 push만 해주면 되므로, 로컬에서의 병합만 다루도록 한다.)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;일반적으로는 다른 branch들에서 작업한 내용을 main에 병합하는 경우가 많다. 예를 들어,&lt;/p&gt;
&lt;pre id=&quot;code_1737612016544&quot; class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;git checkout main # 병합 &quot;받을&quot; branch로 이동
git merge ex # 작업한 branch&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;와 같이, main branch에 작업한 내용을 옮기는 경우가 많다. push해주면 remote branch에도 적용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science, Programming/Git, Docker, Server, Linux</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/221</guid>
      <comments>https://jjuke-brain.tistory.com/entry/%ED%98%91%EC%97%85%EC%9D%84-%EC%9C%84%ED%95%9C-Git-branch-%EC%82%AC%EC%9A%A9%EB%B2%95#entry221comment</comments>
      <pubDate>Tue, 14 Mar 2023 14:18:13 +0900</pubDate>
    </item>
    <item>
      <title>3D Representation Learning Techniques - GAN, AE, VAE, VQ-VAE, Normalizing Flow, Diffusion</title>
      <link>https://jjuke-brain.tistory.com/entry/3D-Representation-Learning-Techniques</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/3D-Shape-Representations-and-Representation-Learning-Techniques-Point-Mesh-Voxel-and-GAN-AE-VQ-VAE-in-3D&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 포스팅&lt;/a&gt;에서 3차원 공간에 존재하는 물체의 shape을 표현하는 다양한 방법을 알아보았다. 이번에는 shape generation 등의 3D Vision task에서 이러한 representation을 학습하는 다양한 방법, 대표적인 모델을 간단히 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Generative Adversarial Networks (GAN)&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;GAN은 discriminator, generator를 경쟁적으로 training하여 target data의 embedding을 학습시킨다. Generator는 discriminator를 속여 진짜같은 이미지를 만들어내고, discriminator는 진짜 이미지와 generator가 생성한 이미지 중 무엇이 진짜인지를 구별한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;GAN을 여러 방법으로 보완한 Deep conv GAN, Conditional Adversarial Network 등이 존재한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;GAN에서 사용한 loss function 등 좀 더 자세한 내용은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/KL-Divergence-Loss%EC%99%80-Reconstruction-Loss&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 참조하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;3D 도메인에서는 GAN으로 voxel 형태의 object를 생성하거나, parameterization plane들을 활용하여 topological sphere shape을 생성한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 가장 큰 문제점은 GAN 모델의 학습은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;unstable&lt;/span&gt;하다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Auto-encoder based Models&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Auto-encoder는 encoder와 decoder로 구성되는 모델로, 이를 기반으로 한 다양한 모델들이 representation 학습에 자주 사용된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;(Variational) Auto-Encoder&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저, auto-encoder(AE)와 variational auto-encoder(VAE)의 차이를 알아보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfjsaj/btrXMTi6qOi/dUFwULXCcKerikcNtoAAr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfjsaj/btrXMTi6qOi/dUFwULXCcKerikcNtoAAr0/img.png&quot; data-alt=&quot;Fig 1. Auto-encoder (AE) Structure (in 2D)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfjsaj/btrXMTi6qOi/dUFwULXCcKerikcNtoAAr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcfjsaj%2FbtrXMTi6qOi%2FdUFwULXCcKerikcNtoAAr0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1248&quot; height=&quot;307&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Auto-encoder (AE) Structure (in 2D)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Encoder : Input data의 feature를 뽑는다.&lt;/li&gt;
&lt;li&gt;Decoder : Feature로부터 input과 비슷한 data를 복원(reconstruction)한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1268&quot; data-origin-height=&quot;594&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BR6HC/btrXQgcMtcY/Ykkzwp2JHoyt3PdNlUoUjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BR6HC/btrXQgcMtcY/Ykkzwp2JHoyt3PdNlUoUjk/img.png&quot; data-alt=&quot;Fig 2. Variational Auto-encoder (VAE) Structure (in 2D)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BR6HC/btrXQgcMtcY/Ykkzwp2JHoyt3PdNlUoUjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBR6HC%2FbtrXQgcMtcY%2FYkkzwp2JHoyt3PdNlUoUjk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1268&quot; height=&quot;594&quot; data-origin-width=&quot;1268&quot; data-origin-height=&quot;594&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Variational Auto-encoder (VAE) Structure (in 2D)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Encoder : Input data의 latent variable의&amp;nbsp; 모수(parameter), 즉 mean, variance를 구한다.&lt;/li&gt;
&lt;li&gt;Reparameterization Trick : Encoder의 결과를 바로 decoder에 입력하면 AE와 같이 input에 대해 하나의 output만 나올 것이다. (Reconstruction) 하지만 &lt;span style=&quot;color: #ee2323;&quot;&gt;VAE는 generative model&lt;/span&gt;로, data의 분포에서 하나를 뽑아 새로운 data를 생성하는 역할을 수행한다. 따라서 encoder에서 얻은 분포에서 sampling을 진행해야 하는데, 단순히 sampling하면 backpropagation을 할 수 없으므로, reparameterization trick을 사용한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단순 sampling : \( z^{i,l} \sim \mathcal{N}(\mu_i, \sigma_i^2 \mathbf{I}) \)&lt;/li&gt;
&lt;li&gt;Reparameterization trick : \( z^{i,l} = \mu_i + \sigma_i^2 \odot \epsilon, \quad \text{where } \epsilon \sim \mathcal{N}(0, \mathbf{I}) \)&lt;/li&gt;
&lt;li&gt;같은 distrbution이지만 reparameterization trick을 사용할 경우 backpropagation 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Decoder : 샘플링한 latent variable에서 새로운 image 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀 더 자세한 내용은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/KL-Divergence-Loss%EC%99%80-Reconstruction-Loss#Loss_Function_of_VAE&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 참조하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;(Variational) auto-encoder로 representation을 학습하는 다양한 모델이 있다. 실제로 3D shape learning에서도 auto-encoder를 활용한 다양한 모델이 있는데, 대표적인 예로 3d-encoder-predictor CNN, Compositional VAE, AtlasNet, DeepSDF가 이에 해당한다. (엄밀히 말하자면 DeepSDF는 auto-encoder가 아닌 auto-decoder이기는 하다.)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Vector Quantized Variational Auto-Encoder (VQ-VAE)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;VQ-VAE는 Vector Quantization을 통해 VAE에서 일반적으로 발생하는 문제점인 posterior collapse(powerful한 autoregressive decoder 사용 시 latent가 무시되는 현상)를 해결한 모델이다. 이를 알아보기 이전에 vector quantization에 대한 이해가 필요하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;378&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NAO4w/btrW7TbmiKM/4rvrgSWi50EEOb17l30BjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NAO4w/btrW7TbmiKM/4rvrgSWi50EEOb17l30BjK/img.png&quot; data-alt=&quot;Fig 3. Quantization&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NAO4w/btrW7TbmiKM/4rvrgSWi50EEOb17l30BjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNAO4w%2FbtrW7TbmiKM%2F4rvrgSWi50EEOb17l30BjK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;479&quot; height=&quot;302&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;378&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Quantization&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Quantization(양자화)이란, Fig 3에서와 같이 실수 전체 집합(N개, 파란색)에 해당하는 값들을 유한한 집합(K개, 빨간색)의 값으로 변환하는 개념이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Vector quantization은 '\(N\)개 특징 벡터 집합 \(\mathbf{x}\)를 \(K\)개 특징 벡터 집합 \(\mathbf{y}\)로 맵핑하는 함수 \(f\)'로 생각해볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;722&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k038z/btrW4EsfgMv/TyfwZyPjQML2Z5hre7LYG0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k038z/btrW4EsfgMv/TyfwZyPjQML2Z5hre7LYG0/img.jpg&quot; data-alt=&quot;Fig 4. VQ-VAE&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k038z/btrW4EsfgMv/TyfwZyPjQML2Z5hre7LYG0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk038z%2FbtrW4EsfgMv%2FTyfwZyPjQML2Z5hre7LYG0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;811&quot; height=&quot;357&quot; data-origin-width=&quot;722&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. VQ-VAE&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;VQ-VAE는 Fig 4에서 볼 수 있듯, \(K\)개의 embedding vector로 이루어진 embedding space(=codebook)를 갖는다. 각 embedding vector의 차원은 \(D\)이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Encoder의 output \(z_e(x)\) 역시 \(D\)차원이며, 맵핑을 위해 다음과 같은 posterior categorical distribution을 생성한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( q(z=k \vert x) = \begin{cases} 1 &amp;amp; \quad \text{for } k = \underset{j}{\operatorname{argmin}} \lVert z_e(x) - e_j \rVert_2 \\ 0 &amp;amp; \quad \text{otherwise} \end{cases} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, encoder의 output이 embedding vector 중 가장 가까운 index에 해당하는 값은 1, 다른 값은 0이 되는 것이다. 이후 \(e_k\)로 맵핑된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Decoder는 더 간단하다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( z_q(x) = e_k, \quad \text{where } k = \underset{j}{\operatorname{argmax}} \lVert z_e(x) - e_j \rVert_2 \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Decoder에서는 방금 encoder의 output \(z_e(x)\)와 가장 가까웠던 \(e_k\)를 입력으로 주어 이미지를 복원한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VQ-VAE의 동작 방식을 예로 들어서 설명하자면, 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-01-25 at 01.38.15.jpg&quot; data-origin-width=&quot;980&quot; data-origin-height=&quot;524&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkGVv4/btrWZXFTjYO/J4Z7zrvH2v6n3UaC6knKhk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkGVv4/btrWZXFTjYO/J4Z7zrvH2v6n3UaC6knKhk/img.jpg&quot; data-alt=&quot;Fig 5. VQ-VAE Operation Example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkGVv4/btrWZXFTjYO/J4Z7zrvH2v6n3UaC6knKhk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkGVv4%2FbtrWZXFTjYO%2FJ4Z7zrvH2v6n3UaC6knKhk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;746&quot; height=&quot;399&quot; data-filename=&quot;CleanShot 2023-01-25 at 01.38.15.jpg&quot; data-origin-width=&quot;980&quot; data-origin-height=&quot;524&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. VQ-VAE Operation Example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 5에서 빨간색으로 표시한 discrete code가 \(e_k\)에 해당하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Loss는 다음과 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \log (p(x \vert q(x))) + \lVert \operatorname{sg}[z_e(x)] - e \rVert_2^2 + \beta \lVert z_e(x) - \operatorname{sg}[e] \rVert_2^2 \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( \log (p(x \vert q(x)))\) : Reconstruction loss&lt;/li&gt;
&lt;li&gt;\( \operatorname{sg}\) (Stop Gradient) : 해당 term은 weight update를 하지 않음&lt;/li&gt;
&lt;li&gt;\( \lVert \operatorname{sg}[z_e(x)] - e \rVert_2^2 \) : Codebook alignment loss &amp;rarr; embedding vector \(e\) (예시에서의 \(e_k\))가 해당하는 encoder 출력 \(z_e(x)\)와 가까워지도록 함&lt;/li&gt;
&lt;li&gt;\( \lVert z_e(x) - \operatorname{sg}[e] \rVert_2^2 \) : Codebook commitment loss &amp;rarr; encoder 출력 \(z_e(x)\)가 embedding vector \(e\)와 가까워지도록 함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VQ-VAE 학습 시에는 \(z\)가 uniform prior라고 가정하는데, 학습 후에는 \(z\)에 autoregressive distribution을 적용하여 다양한 generation task에 VQ-VAE를 활용할 수 있다. 예를 들어, \(z\)에 PixelCNN을 사용하여 image를 생성하거나, WaveNet을 사용하여 audio를 생성할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Flow-based Generative Models&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;AE, VAE, Normalizing flow model의 공통점은 likelihood를 기반(loss)으로 학습을 진행한다는 점이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;특히 VAE의 경우에는 변분 추론(Variational inference)을 통해 계산이 어려운 (latent variable의) posterior \(p(\mathbf{z} \vert \mathbf{x})\)를 계산이 쉬운 \(q(\mathbf{z} \vert \mathbf{x})\)로 근사한다. (자세한 내용은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/KL-Divergence-Loss%EC%99%80-Reconstruction-Loss#Loss_Function_of_VAE&quot;&gt;링크&lt;/a&gt;를 참조하자.)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;VAE에서는 \(q(\mathbf{z})\)를 가장 간단한 분포인 정규분포로 정하는데, normalizing flow model에서는 정규분포 대신에 &lt;span style=&quot;color: #ee2323;&quot;&gt;복잡한 확률 분포를 모델링&lt;/span&gt;하도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Normalizing Flow&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Normalizing flow&lt;/span&gt;란, &lt;span style=&quot;color: #ee2323;&quot;&gt;단순한 형태의 gaussian \(\mathbf{z}\)에 invertible 연산 \(f\)를 적용하여 복잡한 확률 분포 \(p(\mathbf{x})\)를 모델링하는 방법&lt;/span&gt;이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;555&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rv4Js/btrXK7aTZgG/sAHopfMR7TtND8nFkdMa51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rv4Js/btrXK7aTZgG/sAHopfMR7TtND8nFkdMa51/img.png&quot; data-alt=&quot;Fig 6. Normalizing Flow&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rv4Js/btrXK7aTZgG/sAHopfMR7TtND8nFkdMa51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frv4Js%2FbtrXK7aTZgG%2FsAHopfMR7TtND8nFkdMa51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;555&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;555&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 6. Normalizing Flow&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 6에서 flow는 연산 \(f\)를 거치는 각각의 step을 말하고, normalizing flow는 위 그림 전체의 과정을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Change of Variables Theorem&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Single random variable \(z\)에 대해, \(z \sim \pi(z)\)라 하고, invertible 일대일 함수 \(f\)를 통해 새로운 random variable \(x = f(z)\)를 구성한다고 하자. 이때 \(x\)의 확률 분포 \(p(x)\)는 다음과 같이 정의할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( \int p(x) dx = \int \pi(z) dz = 1 \)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(x) = \pi (z) \left\vert \cfrac{dz}{dx} \right\vert = \pi (f^{-1} (x)) \left\vert \cfrac{d f^{-1}}{dx} \right\vert = \pi (f^{-1}(x)) \left\vert (f^{-1})^\prime (x) \right\vert \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Multivariable일 경우, 다음과 같이 구한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \mathbf{z} \sim \pi(\mathbf{z}), \quad \mathbf{x} = f(\mathbf{z}), \quad \mathbf{z} = f^{-1} (\mathbf{x}) \)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p(\mathbf{x}) = \pi (\mathbf{z}) \left\vert \operatorname{det} \cfrac{d \mathbf{z}}{d \mathbf{x}} \right\vert = \pi (f^{-1}(\mathbf{x})) \left\vert \operatorname{det} \cfrac{df^{-1}}{d \mathbf{x}} \right\vert \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 알지 못하는 확률 분포 \(p(\mathbf{z})\)를 \(\mathbf{z}\)의 확률밀도함수로 표현 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Normalizing Flow&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이제 주어진 간단한 분포 \(p_0(z_0)\)로부터 복잡한 분포 \(p_k(z_k)\)를 모델링해보자. Change of variables theorem을 그대로 활용하면 다음과 같이 나타낼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( \mathbf{z}_{i-1} \sim p_{i-1}(\mathbf{z}_{i-1}) \mathbf{z}_i = f_i (\mathbf{z}_{i-1}), \quad \text{where } \mathbf{z}_{i-1} = f_i^{-1} (\mathbf{z}_i) \)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p_i(\mathbf{z}_i) = p_{i-1} (f_i^{-1}(\mathbf{z}_i)) \left\vert \operatorname{det} \cfrac{d f^{-1}}{d \mathbf{z}_i} \right\vert \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 \(p_i(\mathbf{z}_i)\) 식을 \(\mathbf{z}_{i-1}\)에 대한 식으로 나타내어 &lt;span style=&quot;color: #ee2323;&quot;&gt;이전 distribution으로 복잡한 분포를 모델링(flow 과정)&lt;/span&gt;하는 수식을 만들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \begin{align*} p_i(\mathbf{z}_i) &amp;amp;= p_{i-1} (f_i^{-1}(\mathbf{z}_i)) \left\vert \operatorname{det} \cfrac{d f^{-1}}{d \mathbf{z}_i} \right\vert \\ &amp;amp;= p_{i-1}(\mathbf{z}_{i-1}) \left\vert \operatorname{det} \left( \cfrac{d f_i}{d \mathbf{z}_{i-1}} \right)^{-1} \right\vert \quad \quad \because \text{Inverse function theorem} \\ &amp;amp;= p_{i-1}(\mathbf{z}_{i-1}) \left\vert \operatorname{det} \cfrac{d f_i}{d \mathbf{z}_{i-1}} \right\vert^{-1} \quad \quad \because \text{property of Jacobians of invertible func} \end{align*} \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 위 유도과정에서는 다음 두 가지 개념을 이용했다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Inverse function theorem
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(y = f(x)\)이고,&amp;nbsp;\(f\)가 invertible function이라면,&lt;/li&gt;
&lt;li&gt;\( \cfrac{d f^{-1}(y)}{dy} = \cfrac{d x}{d y} = \left( \cfrac{d y}{d x} \right)^{-1} = \left( \cfrac{df(x)}{dx} \right)^{-1} \)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Jacobian of invertible functions
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( \operatorname{det}(\mathbf{M}) \operatorname{det}(\mathbf{M}^{-1}) = \operatorname{det}(\mathbf{M} \times \mathbf{M}^{-1}) = \operatorname{det}(\mathbf{I}) = 1 \)이므로&lt;/li&gt;
&lt;li&gt;\( \operatorname{det}(\mathbf{M}^{-1}) = (\operatorname{det}(\mathbf{M}))^{-1} \)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 식에 log를 취하면 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \log p_i(\mathbf{z}_i) = \log p_{i-1} (\mathbf{z}_{i-1}) - \log \left( \operatorname{det} \cfrac{d f_i}{d \mathbf{z}} \right) \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 과정을 K번 반복하면 \(\mathbf{z}_K\), 즉 \(\mathbf{x}\)의 분포를 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \mathbf{x} = \mathbf{z}_K = f_K \circ f_{K-1} \circ \cdots \circ f_1(\mathbf{z}_0) \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \begin{align*} \log p(\mathbf{x}) = \log \pi_K(\mathbf{z}_K) &amp;amp;= \log \pi_{K-1}(\mathbf{z}_{K-1}) - \log \left\vert \operatorname{det} \cfrac{d f_K}{d \mathbf{z}_{K-1}} \right\vert \\ &amp;amp;= \log \pi_{K-2}(\mathbf{z}_{K-2}) - \log \left\vert \operatorname{det} \cfrac{d f_{K-1}}{d \mathbf{z}_{K-2}} \right\vert - \log \left\vert \operatorname{det} \cfrac{d f_K}{d \mathbf{z}_{K-1}} \right\vert \\ &amp;amp;= \cdots \\ &amp;amp;= \log \pi_0(\mathbf{z}_0) - \sum\limits_{i=1}^K \log \left\vert \operatorname{det} \cfrac{d f_i}{d \mathbf{z}_{i-1}} \right\vert \end{align*} \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 정의한 \(\log p(\mathbf{x})\)를 활용하여 학습 데이터셋 \(\mathcal{D}\)에 대한 negative log-likelihood(NLL) loss를 정의할 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathcal{L}(\mathcal{D}) - \cfrac{1}{\left\vert \mathcal{D} \right\vert} \sum\limits_{ \mathbf{x} \in \mathcal{D}} \log p(\mathbf{x}) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Flow-based generative model&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ClKuz/btrXSw7v4cF/JKSEqnv9EukAoCJeZu9UB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ClKuz/btrXSw7v4cF/JKSEqnv9EukAoCJeZu9UB0/img.png&quot; data-alt=&quot;Fig 7. GAN, VAE and Flow-based Generative Model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ClKuz/btrXSw7v4cF/JKSEqnv9EukAoCJeZu9UB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FClKuz%2FbtrXSw7v4cF%2FJKSEqnv9EukAoCJeZu9UB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1550&quot; height=&quot;800&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;800&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 7. GAN, VAE and Flow-based Generative Model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GAN과 VAE는 데이터를 학습할 때 데이터 \(\mathbf{x}\)의 분포를 implicit하게 학습한다. 하지만, flow-based generative model의 경우에는 normalizing flow(flow \(f\)와 inverse flow \(f^{-1}\))를 통해 &lt;span style=&quot;color: #ee2323;&quot;&gt;데이터 분포를 explicit하게 학습&lt;/span&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, normalizing flow를 적용하기 위해서는 다음과 같은 조건을 충족해야 한다. (실제로 이 조건들을 충족하기가 쉽지 않다.)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;연산 \(f\)의 inverse 계산&lt;/span&gt;이 가능해야 한다.&lt;/li&gt;
&lt;li&gt;Jacobian determinant의 계산이 가능해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flow-based generative model에는 대표적으로 RealNVP, Glow 등의 모델이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;373&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eI9Gnq/btrXOkgwHym/hem6UQ4pEUvwV8Gtcd6Jmk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eI9Gnq/btrXOkgwHym/hem6UQ4pEUvwV8Gtcd6Jmk/img.jpg&quot; data-alt=&quot;Fig 8. Inference and Generation Process of RealNVP&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eI9Gnq/btrXOkgwHym/hem6UQ4pEUvwV8Gtcd6Jmk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeI9Gnq%2FbtrXOkgwHym%2Fhem6UQ4pEUvwV8Gtcd6Jmk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;710&quot; height=&quot;373&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;373&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 8. Inference and Generation Process of RealNVP&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 8은 RealNVP의 inference, generation 과정을 나타낸다. RealNVP는 고차원에서의 determinant, Jacobian 계산의 효율성을 위해 invertible function(transformation)에 '(affine) &lt;span style=&quot;color: #ee2323;&quot;&gt;coupling layer&lt;/span&gt;'를 사용한다. Affine coupling layer에서 input의 반은 target distribution으로 맵핑하고, 나머지 반은 그대로 둔다. 이를 통해 inverse, determinant 계산이 가능하면서도 모델의 flexibility를 높여준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Diffusion Models&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Diffusion model은 data에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;noise를 조금씩 더해가며 완전한 noise로 만드는 forward process(=diffusion process)&lt;/span&gt;와 반대로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;noise로부터 조금씩 복원해가면서 data를 만들어내는 reverse process&lt;/span&gt;로 이루어진다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3832&quot; data-origin-height=&quot;1348&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/po391/btrXaE6JulF/kySUnF5IK06AZ2u7QPbOLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/po391/btrXaE6JulF/kySUnF5IK06AZ2u7QPbOLK/img.png&quot; data-alt=&quot;Fig 9. Diffusion Model Overview&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/po391/btrXaE6JulF/kySUnF5IK06AZ2u7QPbOLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpo391%2FbtrXaE6JulF%2FkySUnF5IK06AZ2u7QPbOLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3832&quot; height=&quot;1348&quot; data-origin-width=&quot;3832&quot; data-origin-height=&quot;1348&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 9. Diffusion Model Overview&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Architecture of Diffusion&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\(\mathbf{x}_0\)는 실제 data, \(\mathbf{x}_T\)는 최종 noise, 그 사이 \(t\) 시점의 \(\mathbf{x}_t\)는 데이터에 noise가 더해진 상태의 latent variable으로 볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 forward process는 \(q\), reverse process는 \(p\)이고, \(p\)를 학습함으로써 noise \(\mathbf{x}_T\)에서 data \(\mathbf{x}_0\)를 복원하는 과정(image generation)을 학습한다. 수학적으로는 실제 data의 분포 \(p(\mathbf{x}_0)\)를 찾아내는 것이 목적이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;언뜻 봤을 때 위의 flow-based generative model의 normalizing flow와 비슷해 보이는데, flow-based model과 diffusion model은 공통적으로 간단한 distribution을 target distribution으로 바꾸려 하지만, 그 방식이 다르다. Flow-based model에서는 invertible function(transformation)을 사용하는 반면, diffusion에서는 그럴 필요는 없다. Diffusion model에서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;target distribution을 가능한 가깝게 근사하는 것&lt;/span&gt;이 목적이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Reverse process \(p\)를 곧바로 모델링하기는 힘들기 때문에, 학습된 Gaussian transition을 활용한 Markov chain 형태로 \(p\)를 근사한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( p_\theta (\mathbf{x}_{0:T}) := p(\mathbf{x}_T) \prod\limits_{t=1}^T p_\theta(\mathbf{x}_{t-1} \vert \mathbf{x}_t), \quad p_\theta(\mathbf{x}_{t-1} \vert \mathbf{x}_t) := \mathcal{N}(\mathbf{x}_{t-1}; \boldsymbol{\mu}_\theta (\mathbf{x}_t, t), \boldsymbol{\Sigma}_\theta (\mathbf{x}_t, t))&amp;nbsp;\)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\boldsymbol{\mu}_\theta, \boldsymbol{\Sigma}_\theta\) : Learnable parameters&lt;/li&gt;
&lt;li&gt;Starting point (noise의 분포) : \(p(\mathbf{x}_T) = \mathcal{N}(\mathbf{x}_T; \boldsymbol{0}, \mathbf{I}) \)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Forward process \(q\)의 정보를 활용해서 reverse process를 학습하기 때문에, 이 과정의 분포도 알아야 한다. Data에 Gaussian noise를 조금씩 더하는 Markov chain 형태이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( q(\mathbf{x}_{1:T} \vert \mathbf{x}_0) := \prod\limits_{t=1}^T q(\mathbf{x}_t \vert \mathbf{x}_{t-1}), \quad q(\mathbf{x}_t \vert \mathbf{x}_{t-1}) := \mathcal{N}(\mathbf{x}_t ; \sqrt{1 - \beta_t} \mathbf{x}_{t-1}, \beta_t \mathbf{I} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\beta_1, \dots, \beta_T\) : Variance schedule &amp;rarr; reparameterization을 통해 학습 또는 constant(hyperparameter)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 같이 forward process(diffusion process)를 표현하게 되면 data가 주어졌을 때 임의의 times step \(t\)에서의 data \(\mathbf{x}_t\)를 sampling할 수 있다. data \(\mathbf{x}_0\)가 주어졌을 때, \(\mathbf{x}_t\)의 분포를 다음과 같이 구할 수 있기 때문이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( q(\mathbf{x}_t \vert \mathbf{x}_0) = \mathcal{N}(\mathbf{x}_t; \sqrt{\bar{\alpha}_t} \mathbf{x}_0, (1 - \bar{\alpha}_t) \mathbf{I} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\alpha_t = 1 - \beta_t\)&lt;/li&gt;
&lt;li&gt;\(\bar{\alpha}_t = \prod_{i=1}^t \alpha_i\)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Loss of Diffusion&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Diffusion model의 목적은 앞에서도 언급했듯이 실제 data의 분포 \(p(\mathbf{x}_0)\)를 찾는 것이다. 따라서 이 분포의 likelihood를 최대화(negative log likelihood를 최소화)하는 것이 목적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \mathbb{E}[- \log p_\theta(\mathbf{x}_0)] \leq \mathbb{E}_q \left[ - \log \cfrac{p_\theta(\mathbf{x}_{0:T}}{q(\mathbf{x}_{1:T} \vert \mathbf{x}_0)} \right] = \mathbb{E}_q \left[ - \log p(\mathbf{x}_T) - \sum\limits_{t \geq 1} \log \cfrac{p_\theta(\mathbf{x}_{t-1} \vert \mathbf{x}_t)}{q(\mathbf{x}_t \vert \mathbf{x}_{t-1})} \right] =: L \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부등호 증명은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://arxiv.org/pdf/2006.11239.pdf&quot;&gt;논문&lt;/a&gt;을 참조하고, 등호는 Markov property에 의해 성립한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀 더 식을 정리하면 아래와 같이 Gaussian 분포 간의 KL divergence 형태로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;loss function&lt;/span&gt;을 변형할 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbb{E}_q \left[ \underbrace{D_{\text{KL}} ( q(\mathbf{x}_T \vert \mathbf{x}_0) \Vert p(\mathbf{x}_T))}_{L_T} + \sum\limits_{t &amp;gt; 1} \underbrace{D_\text{KL} (q(\mathbf{x}_{t-1} \vert \mathbf{x}_t, \mathbf{x}_0) \Vert p_\theta (\mathbf{x}_{t-1} \vert \mathbf{x}_t))}_{L_{t-1}} \underbrace{- \log p_\theta (\mathbf{x}_0 \vert \mathbf{x}_1)}_{L_0} \right] \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(L_T\) : \(p\)가 생성하는 noise \(\mathbf{x}_T\)와 \(q\)가 (data \(\mathbf{x}_0\)가 주어졌을 때) 생성하는 noise \(\mathbf{x}_T\) 간의 KL divergence&lt;/li&gt;
&lt;li&gt;\(L_{t-1}\) : reverse process \(p\)와 forward process \(q\)의 KL divergence
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(q(\mathbf{x}_{t-1} \vert \mathbf{x}_t, \mathbf{x}_0)\) term이 갑자기 어떻게 도출됐는지는 논문을 참조하자.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;\(L_0\) : Latent \(\mathbf{x}_1\)로부터 data \(\mathbf{x}_0\)를 추정하는 negative likelihood&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지가 2D image generation에서 좋은 성능을 나타냈던 diffusion model에 대한 간략한 설명이다. 이를 보완한 DDPM, D3PM 등 다양한 변형 모델들이 있는데, 기회가 된다면 추후에 따로 다뤄보도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;299&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JPaw3/btrXbErK1eh/qgvLNGGdqYuUPiZiBC2av0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JPaw3/btrXbErK1eh/qgvLNGGdqYuUPiZiBC2av0/img.jpg&quot; data-alt=&quot;Fig 10. Diffusion Point Cloud Architecture&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JPaw3/btrXbErK1eh/qgvLNGGdqYuUPiZiBC2av0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJPaw3%2FbtrXbErK1eh%2FqgvLNGGdqYuUPiZiBC2av0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;767&quot; height=&quot;299&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;299&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 10. Diffusion Point Cloud Architecture&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3D domain에서는 Fig 10과 같이 diffusion을 직접적으로 point cloud generation에 활용한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://openaccess.thecvf.com/content/CVPR2021/papers/Luo_Diffusion_Probabilistic_Models_for_3D_Point_Cloud_Generation_CVPR_2021_paper.pdf&quot;&gt;diffusion point cloud model&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;등이 있고, diffusion의 개념을 활용하여 shape generation task 등에 적용한 다양한 연구가 진행되고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Knowledges</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/219</guid>
      <comments>https://jjuke-brain.tistory.com/entry/3D-Representation-Learning-Techniques#entry219comment</comments>
      <pubDate>Thu, 2 Feb 2023 01:33:29 +0900</pubDate>
    </item>
    <item>
      <title>3D Shape Representations - Point Cloud, Mesh, Voxel, SDF, Occupancy</title>
      <link>https://jjuke-brain.tistory.com/entry/3D-Shape-Representations-and-Representation-Learning-Techniques-Point-Mesh-Voxel-and-GAN-AE-VQ-VAE-in-3D</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터 비전 분야라고 하면 보통 2D image에서 물체를 탐지하는 등의 패턴 파악을 떠올린다. 하지만 3D 비전에서는 이미지가 아닌 더 다양한 형태로 3D 객체(object)나 장면(scene), 또는 형상(shape)을 표현한다. 이렇게 다양한 표현 방법에 따라 이를 학습하는 딥러닝 모델도 여러 종류가 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 3차원 공간에 존재하는 object, scene, 특히 물체의 shape(surface)을 어떻게 표현하는지를 알아보려 한다. 이렇게 표현한 3D representation을 어떻게 학습하는지도 이어서 다룰 것인데, 이 포스팅과 연관하여 읽어보길 추천한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Representations for 3D Shape Learning&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;3D Shape을 학습하기 위해 데이터를 표현하는 방법은 크게 다음과 같이 나눠볼 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Point-based methods&lt;/li&gt;
&lt;li&gt;Mesh-based methods&lt;/li&gt;
&lt;li&gt;Voxel-based methods&lt;/li&gt;
&lt;li&gt;Implicit methods&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각을 간단히 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Point-based Representation&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Point cloud는 3차원 공간 상에 존재하는 &lt;span style=&quot;color: #ee2323;&quot;&gt;점을 통해 3차원 데이터를 표현&lt;/span&gt;하는 방법이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1198&quot; data-origin-height=&quot;954&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tHJkL/btrWVKgcsXz/ifqbzZLVQkivEpieYgKk01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tHJkL/btrWVKgcsXz/ifqbzZLVQkivEpieYgKk01/img.png&quot; data-alt=&quot;Fig 1. Point Cloud Example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tHJkL/btrWVKgcsXz/ifqbzZLVQkivEpieYgKk01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtHJkL%2FbtrWVKgcsXz%2FifqbzZLVQkivEpieYgKk01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;507&quot; height=&quot;404&quot; data-origin-width=&quot;1198&quot; data-origin-height=&quot;954&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Point Cloud Example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;다양한 센서가 제공하는 raw data와의 매칭이 잘 되는 3D representation으로, 3D learning(shape classification, semantic segmentation 등)에 적용하기 적합하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Point cloud를 활용하여 3D learning을 수행하는 대표적인 모델은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Pointcloud-related-Architectures-1-PointNet-PointNet&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;PointNet&lt;/a&gt;, &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Pointcloud-related-Models-2-PointNet&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;PointNet++&lt;/a&gt; 등이 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;PointNet은 point cloud를 직접적으로 활용하는 모델로, max pooling function으로 global shape feature를 뽑는데, 이러한 기능은 point generation task에서도 encoder로 많이 활용된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 모양(topology)을 표현하는 데에는 한계가 있다. 점으로 데이터를 표현할 뿐, 틈이 없는(닫혀있는) surface(shape)를 나타내기에는 적절하지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Mesh-based representation&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Mesh는 shape을 나타내기 위해 사전에 정의된 &lt;span style=&quot;color: #ee2323;&quot;&gt;삼각형, 사각형 등의 template&lt;/span&gt;이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;619&quot; data-origin-height=&quot;638&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NBCri/btrW7UOQONn/YRfX9tt51pq4Bbay3tYW3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NBCri/btrW7UOQONn/YRfX9tt51pq4Bbay3tYW3k/img.png&quot; data-alt=&quot;Fig 2. Mesh Example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NBCri/btrW7UOQONn/YRfX9tt51pq4Bbay3tYW3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNBCri%2FbtrW7UOQONn%2FYRfX9tt51pq4Bbay3tYW3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;385&quot; height=&quot;397&quot; data-origin-width=&quot;619&quot; data-origin-height=&quot;638&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Mesh Example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 사전에 정의된 template을 mesh로 사용하여 object class를 표현하는 방법은 shape generation task에서 좋은 성능을 보인다. 하지만, shape을 고정된 mesh 형태로밖에 표현하지 못한다는 단점이 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 한계를 보완하기 위해 2D plane을 morphing(변형)하여 3D surface를 표현하는 방법을 사용한다. 하지만 이 방법도 surface parameterization(3D shape의 surface와 2D domain 간의 연결)을 어떻게 하는가에 따라 성능이 좌우되고, parameterization 알고리즘은 input mesh의 quality와 cutting 방법에 따라 성능이 좌우된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-01-24 at 23.56.21.jpg&quot; data-origin-width=&quot;995&quot; data-origin-height=&quot;155&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PQmLQ/btrW6pIkjZM/Gp2eHrtJkfMt3Iiv7Qj3h0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PQmLQ/btrW6pIkjZM/Gp2eHrtJkfMt3Iiv7Qj3h0/img.jpg&quot; data-alt=&quot;Fig 3. Shape Generation Approaches of AtlasNet&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PQmLQ/btrW6pIkjZM/Gp2eHrtJkfMt3Iiv7Qj3h0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPQmLQ%2FbtrW6pIkjZM%2FGp2eHrtJkfMt3Iiv7Qj3h0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;995&quot; height=&quot;155&quot; data-filename=&quot;CleanShot 2023-01-24 at 23.56.21.jpg&quot; data-origin-width=&quot;995&quot; data-origin-height=&quot;155&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Shape Generation Approaches of AtlasNet&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Parameterization을 딥러닝 네트워크로 하는 방법이 바로 AtlasNet(&lt;a href=&quot;https://openaccess.thecvf.com/content_cvpr_2018/html/Groueix_A_Papier-Mache_Approach_CVPR_2018_paper.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Thibault Groueix et al., 'A Papier-Mache Approach to Learning 3D Surface Generation&lt;/a&gt;)이다. 이 모델의 한계점은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;복잡한 형태를 나타내기 위해서는 여러 plane이 필요하다.&lt;/li&gt;
&lt;li&gt;생성된 surface patch가 붙어있지 않다. 즉, shape이 닫혀있지 않다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Voxel-based Representation&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Voxel은 2D 이미지에서의 픽셀과 같이 &lt;span style=&quot;color: #ee2323;&quot;&gt;3D 공간을 3D grid로&lt;/span&gt; 나눈 것이다. 이를 통해 3차원 형상을 나타내면 다음과 같이 나타난다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;175&quot; data-origin-height=&quot;213&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beKPgE/btrWU6DAZUE/dWUdEnggs7an6bpnByuVo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beKPgE/btrWU6DAZUE/dWUdEnggs7an6bpnByuVo1/img.png&quot; data-alt=&quot;Fig 4. Voxel Example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beKPgE/btrWU6DAZUE/dWUdEnggs7an6bpnByuVo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeKPgE%2FbtrWU6DAZUE%2FdWUdEnggs7an6bpnByuVo1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;175&quot; height=&quot;213&quot; data-origin-width=&quot;175&quot; data-origin-height=&quot;213&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. Voxel Example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 4에서도 볼 수 있듯이, voxel 기반으로 형상을 표현하면 저해상도(low resolution, \(128^3\) 이하)만 다룰 수 있다. 즉, 미세한 shape을 표현하지 못한다. Octree-based methods(OctNet 등)에서 \(512^3\) resoultion까지 다뤘으나, 이 정도의 해상도로는 미세한 shape을 표현하기에 부족하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 voxel과 SDF를 혼합한 방법이 활용되기도 했다. (SDF에 대한 자세한 내용은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Signed-Distance-Function-SDF&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 참조하자. 아주 간단하다!) Truncated SDF(TSDF)를 사용하여 noisy한 depth map을 3D model로 맵핑하는 방법이다. 하지만 voxel의 특성상 discrete하므로, memory가 부족하고, 마찬가지로 저해상도밖에 다루지 못한다. 관련하여 Wavelet transform-based methods, dimensionality reduction technique 등을 통해 보완하는 방법도 고안되었으나, 이러한 방법들은 shape을 다루기보다 scene을 다루는 데 더 최적화되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Implicit representations (SDF, Occupancy)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Implicit representation&lt;/span&gt;이란 3D shape을 point, mesh, voxel이 아닌 &lt;span style=&quot;color: #ee2323;&quot;&gt;어떤 함수를 통해 표현한 것&lt;/span&gt;을 말한다. 함수로 표현하므로 연속적(continuous)이고, smooth하게 형상을 표현할 수 있다.&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;DeepSDF&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;DeepSDF에서는 function으로 &lt;span style=&quot;color: #ee2323;&quot;&gt;continuous SDF&lt;/span&gt;를 사용한다. SDF는 공간 상의 각각의 점을 가장 가까운 surface까지의 거리로 나타내는 함수이다. (자세한 설명은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Signed-Distance-Function-SDF&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 참조하자. 아주 쉽다!)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;1045&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b83C28/btrW77Ocjsq/7r5kT9SMVxg9sNro0sVBak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b83C28/btrW77Ocjsq/7r5kT9SMVxg9sNro0sVBak/img.png&quot; data-alt=&quot;Fig 5. DeepSDF&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b83C28/btrW77Ocjsq/7r5kT9SMVxg9sNro0sVBak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb83C28%2FbtrW77Ocjsq%2F7r5kT9SMVxg9sNro0sVBak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;464&quot; height=&quot;313&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;1045&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. DeepSDF&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 5에서 볼 수 있듯, &lt;span&gt;surface는 값이 0인 점들의 집합으로 표현해볼 수 있다. (SDF는 부호를 고려(binary)하여 어떤&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;3D point가 shape 밖에 있으면 +, 안에 있으면 - 값을 갖는다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;딥러닝 네트워크로 이러한 continuous SDF를 예측하는데, point나 voxel을 입력받아 SDF 값(scalar)을 출력한다. GT SDF 값과 예측한 SDF 값의 차이를 loss로 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Occupancy Network&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Occupancy Network는 function으로 &lt;span style=&quot;color: #ee2323;&quot;&gt;binary function&lt;/span&gt;, 즉 &lt;span style=&quot;color: #333333;&quot;&gt;각 점이 shape의 안에 있는지(occupy되었는지), 밖에 있는지만 나타낸다&lt;/span&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;여기서는 딥러닝 네트워크로 binary function을 예측하는데, input 지점이 occupancy인지 예측하는 binary scalar를 출력한다. (classifier)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;856&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y0bgo/btrXM3Go9XZ/STWPx1sPd8ihqw6hbQbHLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y0bgo/btrXM3Go9XZ/STWPx1sPd8ihqw6hbQbHLK/img.png&quot; data-alt=&quot;Fig 6. 3D Representations (Ours - Occupancy Networks)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y0bgo/btrXM3Go9XZ/STWPx1sPd8ihqw6hbQbHLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy0bgo%2FbtrXM3Go9XZ%2FSTWPx1sPd8ihqw6hbQbHLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;668&quot; height=&quot;369&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;856&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 6. 3D Representations (Ours - Occupancy Networks)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Knowledges</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/217</guid>
      <comments>https://jjuke-brain.tistory.com/entry/3D-Shape-Representations-and-Representation-Learning-Techniques-Point-Mesh-Voxel-and-GAN-AE-VQ-VAE-in-3D#entry217comment</comments>
      <pubDate>Thu, 2 Feb 2023 01:32:46 +0900</pubDate>
    </item>
    <item>
      <title>Pointcloud-related Models (2) - PointNet++</title>
      <link>https://jjuke-brain.tistory.com/entry/Pointcloud-related-Models-2-PointNet</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[&lt;a href=&quot;https://proceedings.neurips.cc/paper/2017/hash/d8bf84be3800d12f74d8b05e9b89836f-Abstract.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;논문 링크&lt;/a&gt;, &lt;a href=&quot;https://github.com/charlesq34/pointnet2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Github 링크&lt;/a&gt;]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Pointcloud-related-Architectures-1-PointNet-PointNet&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 포스팅&lt;/a&gt;에서 Point cloud 데이터를 직접적으로 다루는 최초의 모델인 PointNet 논문을 리뷰해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 이를 보완한 PointNet++ 모델을 제안한 논문 'Charles Ruizhongtai et al., PointNet++: Deep Hierarchical Feature Learing on Point Sets in a Metric Space'를 리뷰해보려 한다. Point를 직접적으로 다루는 모델의 원리를 공부해보기 위해 선택한 논문이므로 experiment에 대한 상세한 설명은 뺐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Motivation&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;PointNet은 point cloud data를 직접적으로 입력받아 point 각각의 feature와 global feature를 구한다. 이를 합하여 segmentation task를 수행하는데, local structure를 잘 잡아내지는 못한다. 즉, point 일부가 생성하는 미세한 패턴을 파악하거나 일반화하는 성능에서는 한계를 보인다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;CNN의 경우에는 locality principle이 존재하여, &lt;span style=&quot;color: #ee2323;&quot;&gt;작은 부분(local)부터 점차 큰 scale의 feature를 포착&lt;/span&gt;한다. 즉, 초기에는 neuron의 receptive field가 작고, layer를 거칠수록 receptive field가 커진다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 개념을 PointNet에 적용한 모델이 바로 PointNet++ 모델이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Overview&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;707&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eELWcL/btrW2tRvFYZ/NQ6aHUSI8KTMpTl83BWeK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eELWcL/btrW2tRvFYZ/NQ6aHUSI8KTMpTl83BWeK0/img.png&quot; data-alt=&quot;Fig 1. PointNet++ Architecture&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eELWcL/btrW2tRvFYZ/NQ6aHUSI8KTMpTl83BWeK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeELWcL%2FbtrW2tRvFYZ%2FNQ6aHUSI8KTMpTl83BWeK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;788&quot; height=&quot;359&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;707&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. PointNet++ Architecture&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PointNet++의 가장 큰 특징은 계층적으로 feature를 잡아낸다는 것이다. (Hierarchical feature learning)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떻게 hiearchical feature learning을 구현했는지 알아보자.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Input point set을 조금씩 겹치도록 나누어 각각에 PointNet을 적용한다.&lt;/li&gt;
&lt;li&gt;Point 간의 distance를 고려하며, scale을 증가시키면서 local feature를 학습한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 부분적인(local) feature를 잘 잡아내고, layer를 거칠수록 feature의 범위가 커지게 된다. 또한 여러 scale의 feature를 학습하므로 robustness도 증가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Two Issues of Designing PointNet++&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 PointNet++를 설계하기 위해서는 두 가지를 고려해야 한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Point set을 어떻게 나눌 것인가?&lt;/li&gt;
&lt;li&gt;Point set 혹은 local feature를 어떻게 학습할 것인가?&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Local feature learner&amp;nbsp; &amp;rarr; PointNet&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저, 각 layer에서 feature를 학습하는 모델로는 PointNet을 활용한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-01-24 at 01.31.29.jpg&quot; data-origin-width=&quot;168&quot; data-origin-height=&quot;173&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcJNIn/btrWTJIljkB/cQMI00Y4iWVw7kgwGrF5VK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcJNIn/btrWTJIljkB/cQMI00Y4iWVw7kgwGrF5VK/img.jpg&quot; data-alt=&quot;Fig 2. Use PointNet as a Local Feature Learner&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcJNIn/btrWTJIljkB/cQMI00Y4iWVw7kgwGrF5VK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcJNIn%2FbtrWTJIljkB%2FcQMI00Y4iWVw7kgwGrF5VK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;168&quot; height=&quot;173&quot; data-filename=&quot;CleanShot 2023-01-24 at 01.31.29.jpg&quot; data-origin-width=&quot;168&quot; data-origin-height=&quot;173&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Use PointNet as a Local Feature Learner&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;CNN에서 window 크기에 따라 이미지를 부분으로 나눈 후, 해당 window에서 local feature를 계산하듯이, PointNet++에서는 point set을 특정 기준으로 나눈 후, 그 subset들에 PointNet을 통해 local feature를 계산한다. 이때, CNN에서처럼 local feature learner(PointNet)의 &lt;span style=&quot;color: #ee2323;&quot;&gt;weight는 공유가 가능&lt;/span&gt;하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Overlapping partitioning&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 처음 layer에서 PointNet을 적용하기 전에 &lt;span style=&quot;color: #ee2323;&quot;&gt;point set을 일정 기준을 갖고 subset으로 나눠주어야&lt;/span&gt; 할 것인데, 이때 사용하는 방법이 바로 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;opverlapping partitioning&lt;/span&gt;이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-01-24 at 01.34.40.jpg&quot; data-origin-width=&quot;141&quot; data-origin-height=&quot;196&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oUdgf/btrWSwvGCMo/YDexHQuDfI6OGsipWYh9ik/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oUdgf/btrWSwvGCMo/YDexHQuDfI6OGsipWYh9ik/img.jpg&quot; data-alt=&quot;Fig 3. Partitions before Applying PointNet&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oUdgf/btrWSwvGCMo/YDexHQuDfI6OGsipWYh9ik/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoUdgf%2FbtrWSwvGCMo%2FYDexHQuDfI6OGsipWYh9ik%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;141&quot; height=&quot;196&quot; data-filename=&quot;CleanShot 2023-01-24 at 01.34.40.jpg&quot; data-origin-width=&quot;141&quot; data-origin-height=&quot;196&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Partitions before Applying PointNet&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 partition이란, Euclidean space(3차원 공간)에서의 구를 말하며, centroid 위치(location)와 크기(scale) 등으로 정의한다. Overlapping partitioning에서는 두 parameter를 다음과 같이 정한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Location of centroid : Farthest Point Sampling (FPS) 알고리즘을 적용한다.&lt;/li&gt;
&lt;li&gt;Scale : Point set의 특성 상, &lt;span style=&quot;color: #ee2323;&quot;&gt;영역마다 density가 다르다&lt;/span&gt;는 점을 고려하여 적절한 scale로, 조금씩 겹치도록 partition을 정해야 한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CNN에서는 kernel size가 작을수록(미세한 local feature를 잡아낼수록) 성능이 높아지지만, PointNet++에서는 구의 지름이너무 작아질 경우 속한 point의 개수가 너무 적어 성능이 떨어진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Volumetric CNN과 PointNet++를 비교해봤을 때, volumetric CNN은 고정된 voxel grid를 사용하지만, PointNet++에서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;input data의 특성과 metric을 둘 다 고려한, 유연한 receptive field를 사용&lt;/span&gt;하기 때문에 더 효율적이고, 효과적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Method&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;PointNet++가 어떤 방법으로 동작하는지 자세히 알아보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;707&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eELWcL/btrW2tRvFYZ/NQ6aHUSI8KTMpTl83BWeK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eELWcL/btrW2tRvFYZ/NQ6aHUSI8KTMpTl83BWeK0/img.png&quot; data-alt=&quot;Fig 1. PointNet++ Architecture&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eELWcL/btrW2tRvFYZ/NQ6aHUSI8KTMpTl83BWeK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeELWcL%2FbtrW2tRvFYZ%2FNQ6aHUSI8KTMpTl83BWeK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;788&quot; height=&quot;359&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;707&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. PointNet++ Architecture&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;설명을 위해 사용할 용어는 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\mathcal{X} = (M, d) \) : Euclidean space \(\mathbb{R}^n\)의 discrete metric space &amp;rarr; 쉽게 생각해서 3D object point cloud 혹은 3D scene point cloud
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(M \subset \mathbb{R}^n\) : Point set (density가 일정하지 않음)&lt;/li&gt;
&lt;li&gt;\(d\) : Distance&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;\(f\) : Objective function &amp;rarr; PointNet의 universal continuous set function
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Input : \(\mathcal{X}\) 및 point 별 추가적인 feature(x, y, z 좌표 이외의 feature)&lt;/li&gt;
&lt;li&gt;Output : \(\mathcal{X}\)와 관련된 semantic 정보
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Classification &amp;rarr; \(\mathcal{X}\)의 label&lt;/li&gt;
&lt;li&gt;Segmentation &amp;rarr; Point 각각의 semantic label&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;PointNet (Review)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;PointNet을 간단하게 복습해보자. PointNet은 주어진 point cloud(unordered set \(\{x_1, x_2, \dots, x_n \}, \; \text{where } x_i \in \mathbb{R}^d \))에 대해 다음 set function(point를 vector로 맵핑하는 함수 \(f : \mathcal{X} \rightarrow \mathbb{R}\))을 근사하는 모델이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( f(x_1, x_2, \dots, x_n) = \gamma \left( \underset{i=1, \dots, n}{\max} \{h(x_i)\} \right) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\gamma, h\) : 서로 다른 MLP network, 특히 \(h\)의 결과는 각 point의 spatial encoding&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 set function(max pooling function)은 input point의 순서에 invariant하고, 어떠한 continuous set function도 근사가 가능하다는 특징을 갖는다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 앞에서도 언급했듯이, 다양한 scale에서의 local context를 잡아내는 능력은 부족하다. 따라서 hierarchical feature learning 방법으로 이 한계를 해결해보고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Hierarchical Feature Learning (Set Abstraction)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;PointNet에서는 전체 point set에 대해 max pooling 연산 한 번만 진행했으나, PointNet++에서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;point set을 (계층을 지날 때마다 점점 커지는) partition으로 나누어 점점 넓은 지역에서의 local feature를 학습&lt;/span&gt;한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;1060&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B4pNP/btrWRWIaLRx/DCo7XvtjNFUAD72S0JuXjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B4pNP/btrWRWIaLRx/DCo7XvtjNFUAD72S0JuXjK/img.png&quot; data-alt=&quot;Fig 4. Hierarchical Point Set Feature Learning&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B4pNP/btrWRWIaLRx/DCo7XvtjNFUAD72S0JuXjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB4pNP%2FbtrWRWIaLRx%2FDCo7XvtjNFUAD72S0JuXjK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;622&quot; height=&quot;425&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;1060&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. Hierarchical Point Set Feature Learning&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Fig 4는 이러한 hierarchical feature learning 과정을 보여준다. Set abstraction 부분이 각 계층(hierarchy)에서 scale에 따른 local feature를 얻는 과정이다. 당연히 계층을 지날수록 element 수는 줄어들 것(\(N &amp;gt; N_1 &amp;gt; N_2\))이고, scale(partition의 범위)은 커질 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Set abstraction level(첫 번째)안에서 point를 처리하는 과정(&lt;span style=&quot;color: #ee2323;&quot;&gt;sampling layer &amp;rarr; grouping layer &amp;rarr; PointNet layer&lt;/span&gt;)을 자세히 알아보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Shape of input matrix : \(N \times (d + C)\)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(N\) : Point 개수&lt;/li&gt;
&lt;li&gt;\(d\) : Coordinates 차원&lt;/li&gt;
&lt;li&gt;\(C\) : Point feature의 차원&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Shape of output matrix : \(N^\prime \times (d + C^\prime)\)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(N^\prime\) : Subsampling된 point set의 개수&lt;/li&gt;
&lt;li&gt;\(d\) : Coordinates 차원&lt;/li&gt;
&lt;li&gt;\(C^\prime\) : 새로운 point feature의 차원&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. Sampling layer&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Sampling layer는 input point들로부터 point set을 골라내는 과정, 즉 partition의 centroid를 정의하는 과정이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이때 Farthest Point Sampling(FPS) 알고리즘을 사용하여 주어진 input points \(\{x_1, x_2, \dots, x_n\}\)에 대해 subset \(\{x_{i_1}, x_{i_2}, \dots, x_{i_m}\}\)을 고른다. 여기서 \(x_{i_j}\)는 set \(\{x_{i_1}, x_{i_2}, \dots, x_{i_{j-1}}\}\)을 제외하고 남은 점 중에서 모든 set과의 거리가 가장 먼 점을 말한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1045&quot; data-origin-height=&quot;1000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SnnuW/btrW0O9r1G0/kI0uaza2o5hqoNwwdY6gpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SnnuW/btrW0O9r1G0/kI0uaza2o5hqoNwwdY6gpk/img.png&quot; data-alt=&quot;Fig 5. 'i'th iteration of FPS&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SnnuW/btrW0O9r1G0/kI0uaza2o5hqoNwwdY6gpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSnnuW%2FbtrW0O9r1G0%2FkI0uaza2o5hqoNwwdY6gpk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;451&quot; height=&quot;432&quot; data-origin-width=&quot;1045&quot; data-origin-height=&quot;1000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. 'i'th iteration of FPS&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNN을 적용할 때에는 data 분포에 상관 없이 공간을 나누지만, FPS를 사용할 경우 data 분포에 따라 receptive field를 생성하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. Grouping layer&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Grouping layer는 centroid 주변의 점들을 묶어 partition(local region set)을 구성하는 단계이다. 이를 거치면서 input shape \(N \times (d + C)\)이 \(N^\prime \times K \times (d + C)\)로 바뀌게 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이때 \(K\)는 각 centroid point와 grouping된 주변(이웃) 점의 개수이다. parition에 따라 \(K\)가 다른데, PointNet layer에 의해 같은 차원의 feature vector로 맵핑된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1043&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFfbEi/btrWTJVPMHA/F92klAL43Y85ABYI3k9Nq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFfbEi/btrWTJVPMHA/F92klAL43Y85ABYI3k9Nq1/img.png&quot; data-alt=&quot;Fig 6. Grouping process&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFfbEi/btrWTJVPMHA/F92klAL43Y85ABYI3k9Nq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFfbEi%2FbtrWTJVPMHA%2FF92klAL43Y85ABYI3k9Nq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;429&quot; height=&quot;447&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1043&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 6. Grouping process&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Grouping을 하기 위한 알고리즘에는 kNN(k Nearest Neighbor) searching algorithm(고정된 이웃 점 개수 찾음)이나 ball query(query point에 대해 반지름 이내의 point들을 찾음) 등이 있는데, PointNet++에서는 region scale이 고정되고, 그 고정된 공간에 대한 feature를 뽑을 수 있는 ball query 방법을 주로 사용한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;CNN은 Manhattan distance(kernel size)로 정해진 크기의 local region을 가지는데 반해, PointNet++에서의 partition은 point set이 metric space(3차원 공간)에 존재하므로 이웃 점은 metric distance로 정의된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. PointNet layer&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이제 PointNet을 사용하여 각 local region의 feature를 뽑는다. Input shape은 \(N^\prime \times K \times (d + C)\), output (feature) shape은 \(N^\prime \times (d + C^\prime)\)이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;과정은 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Relative coordinate : Local region(partition)에 포함된 점들의 coordinate를 &lt;span style=&quot;color: #ee2323;&quot;&gt;centroid 기준의 local frame으로 변환&lt;/span&gt;한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\mathbf{x}_i^{(j)} = \mathbf{x}_i^{(j)} - \hat{\mathbf{x}}^{(j)}, \; \text{for } i=1, 2, \dots, K \; \text{and } j = 1, 2, \dots, d\)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\hat{\mathbf{x}}\) : Centroid의 coordinate&lt;/li&gt;
&lt;li&gt;\(K\) : Partition(local region)에 포함된 point 개수 (centroid 제외)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이 과정을 통해 local region 내에서의 point 간의 관계를 포착할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;PointNet을 적용하여 local region의 feature를 얻는다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Robust Feature Learning&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;앞서 언급했듯, point set의 특징은 &lt;span style=&quot;color: #ee2323;&quot;&gt;같은 부피의 공간에 일정한 밀도로 point가 존재하지 않는다&lt;/span&gt;는 것이다. (Non-uniform sampling density)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 feature learning이 어렵다. 예를 들면, 점이 dense한 곳에서 얻은 feature는 sparse한 곳에 사용할 수 없을 것이다. 즉 sparse point cloud에 대해 학습한 모델은 미세한 local structure를 인지할 수 없을 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이를 해결하기 위해 PointNet++에서는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;(density) adaptive PointNet layer&lt;/span&gt;를 사용한다. 이는 &lt;span style=&quot;color: #ee2323;&quot;&gt;point density에 따라 다양한 abstraction level을 사용하여 여러 scale의 feature를 뽑고, 이를 결합&lt;/span&gt;하는 방법이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;즉, 위에서 설명했던 abstraction level에서는 단일 scale에 대한 grouping과 feature extaction을 진행했는데, 실제로 PointNet++에서는 non-uniform sampling density 문제를 해결하기 위해 abstraction level 각각에서 여러 scale에 대한 feature를 뽑고 local point density를 고려하여 그것을 결합한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-01-24 at 14.38.13.jpg&quot; data-origin-width=&quot;837&quot; data-origin-height=&quot;606&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VBBXc/btrWSvqecPt/01oe9hwHxpUn9TicJWr1t1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VBBXc/btrWSvqecPt/01oe9hwHxpUn9TicJWr1t1/img.jpg&quot; data-alt=&quot;Fig 7. Multi-Scale Grouping (MSG, a) and Multi-Resolution Grouping (MRG, b)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VBBXc/btrWSvqecPt/01oe9hwHxpUn9TicJWr1t1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVBBXc%2FbtrWSvqecPt%2F01oe9hwHxpUn9TicJWr1t1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;584&quot; height=&quot;423&quot; data-filename=&quot;CleanShot 2023-01-24 at 14.38.13.jpg&quot; data-origin-width=&quot;837&quot; data-origin-height=&quot;606&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 7. Multi-Scale Grouping (MSG, a) and Multi-Resolution Grouping (MRG, b)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 7과 같이 Adaptive PointNet layer에는 grouping과 combining 방식에 따라 MSG, MRG 두 가지 종류가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;MSG(Multi-Scale Grouping)&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Multi-Scale Grouping(MSG)&lt;/span&gt;이란, &lt;span style=&quot;color: #ee2323;&quot;&gt;다양한 scale의 local region에 대해 grouping layer를 적용한 후에 PointNet layer로 각각의 scale에 대한 feature를 뽑은 후 concat&lt;/span&gt;하는 방법이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;424&quot; data-origin-height=&quot;204&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4MHvz/btrWUGLBUqJ/YD8Ky24gWVCmSwQgXVHlK1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4MHvz/btrWUGLBUqJ/YD8Ky24gWVCmSwQgXVHlK1/img.jpg&quot; data-alt=&quot;Fig 8. Random point dropout&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4MHvz/btrWUGLBUqJ/YD8Ky24gWVCmSwQgXVHlK1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4MHvz%2FbtrWUGLBUqJ%2FYD8Ky24gWVCmSwQgXVHlK1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;424&quot; height=&quot;204&quot; data-origin-width=&quot;424&quot; data-origin-height=&quot;204&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 8. Random point dropout&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Training 시에는 instance마다 input point를 랜덤하게 dropout하는 &lt;span style=&quot;color: #ee2323;&quot;&gt;random input dropout&lt;/span&gt; 기법을 사용한다. 이는 training point set마다 다른 비율로 dropout을 적용하여 다양한 density의 training set에 대해 학습을 진행하는 효과를 얻기 위해서이다. (기존 dropout과 마찬가지로 test 시에는 dropout을 적용하지 않는다.)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하지만, 이 방법의 경우 모든 partition의 centroid에 대해 PointNet을 적용해야 하므로 &lt;span style=&quot;color: #ee2323;&quot;&gt;computational cost가 높다&lt;/span&gt;는 단점이 있다. 특히 초반 단계에서는 centroid(partition)가 매우 많으므로 계산량이 아주 높다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;MRG(Multi-Resolution Grouping)&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Multi-Resolution Grouping(MRG)&lt;/span&gt;이란, 어떤 level(layer) \(L_i\)에서의 region(partition)에 대한 feature를 아래 두 vector를 concat하여 얻는 방법을 말한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;이전 level \(L_{i-1}\)의 각 subregion(partition)에 대한 feature의 summarization vector&lt;/li&gt;
&lt;li&gt;모든 raw point에 PointNet을 적용하여 얻은 feature&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Concat 시에 weight을 부여하는데, local region이 &lt;span style=&quot;color: #ee2323;&quot;&gt;sparse한 경우&lt;/span&gt;에는 subregion은 더 sparse하기 때문에 &lt;span style=&quot;color: #ee2323;&quot;&gt;2번 벡터에 높은 weight&lt;/span&gt;을 부여하고, local region이 &lt;span style=&quot;color: #ee2323;&quot;&gt;dense한 경우&lt;/span&gt;에는 이전 level에서 더 detail한 정보를 제공하므로(더 높은 resolution을 처리하므로) &lt;span style=&quot;color: #ee2323;&quot;&gt;1번 벡터에 높은 weight&lt;/span&gt;을 부여한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법은 첫 단계에서 large scale의 feature를 뽑지 않기 때문에 계산량 측면에서 효율적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Point Feature Propagation for Segmentation&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;672&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czXlVS/btrW38s4rIy/aAzFEWwmDoKWuOgSiX2YP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czXlVS/btrW38s4rIy/aAzFEWwmDoKWuOgSiX2YP1/img.png&quot; data-alt=&quot;Fig 9. Feature Propagation for Segmentation&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czXlVS/btrW38s4rIy/aAzFEWwmDoKWuOgSiX2YP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczXlVS%2FbtrW38s4rIy%2FaAzFEWwmDoKWuOgSiX2YP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1550&quot; height=&quot;672&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;672&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 9. Feature Propagation for Segmentation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PointNet에서와 마찬가지로, segmentation task를 수행하기 위해서는 모든 point 각각에 대한 segment label score가 필요하다. 따라서 &lt;span style=&quot;color: #ee2323;&quot;&gt;subsampling했던 point feature를 원래의 point로 전파(propagate)하는 과정이 필요&lt;/span&gt;하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Feature propagation 과정의 핵심은 interpolation과 skip link concatenation이며, original point set의 feature를 얻을 때까지 반복적으로 이루어진다. Hierarchical propagation 과정과 반대로, input point feature shape은 \(N_l \times (d + C)\), output point feature 개수는 \(N_{l-1} (\text{where } N_l \leq N_{l-1})\)이라 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Fig 9에서 보듯, feature learning(hiearchical propagation) 시 set abstraction 횟수와 feature propagation 반복 횟수가 같을 것이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Interpolation&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Interpolation이란, &lt;span style=&quot;color: #ee2323;&quot;&gt;\(L_l\) level에서 \(N_l\)개 point의 feature value들에 interpolation을 적용하여 \(L_{l-1}\) level의 \(N_{l-1}\)개 point의 feature value를 계산&lt;/span&gt;하는 방법이다. 여러 interpolation 방법 중 K Nearest Neighbors 기반의 inverse distance weighted average를 사용한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( f^{(j)}(x) = \cfrac{\sum_{i=1}^k w_i(x) f_i^{(j)}}{\sum_{i=1}^k w_i(x)} \quad \text{where } w_i(x) = \cfrac{1}{d(x, x_i)^p}, \; j = 1, \dots, C \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Default로 \(p = 2, k = 3\)을 적용했다. 즉, 2차 inverse distance를 사용하였고, \(L_l\) level에서 point 3개에 대해 interpolation을 적용한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Experiments&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 결과 위주로 간단히 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Shape Classification&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Fig 10은 ModelNet40(3D object classification task에서 사용하는 dataset)에 대한 성능 비교 결과이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;438&quot; data-origin-height=&quot;205&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsqqFX/btrWXjCl5SD/h734qqhkG00jwDE2zo8oJ0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsqqFX/btrWXjCl5SD/h734qqhkG00jwDE2zo8oJ0/img.jpg&quot; data-alt=&quot;Fig 10. ModelNet40 Shape Classification Results&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsqqFX/btrWXjCl5SD/h734qqhkG00jwDE2zo8oJ0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsqqFX%2FbtrWXjCl5SD%2Fh734qqhkG00jwDE2zo8oJ0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;438&quot; height=&quot;205&quot; data-origin-width=&quot;438&quot; data-origin-height=&quot;205&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 10. ModelNet40 Shape Classification Results&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PointNet(vanilla)는 Transformation network를 사용하지 않은, 즉 PointNet++의 hieararchical network에서 abstraction level 한 번만 적용한 것과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PointNet과 비교했을 때, hierarchical architecture를 적용한 결과 3D object classification 성능이 더 좋아졌음을, CNN 기반 방법인 MVCNN보다 point set 기반 방법이 성능이 더 좋음을 알 수 있다. (마지막 행에서 normal information이란, input point feature로 face normal을 추가한 것이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;473&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GUvM3/btrW2uQHeR1/CJZh0D9pxzuxPbDqf9eR20/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GUvM3/btrW2uQHeR1/CJZh0D9pxzuxPbDqf9eR20/img.jpg&quot; data-alt=&quot;Fig 11. Advantage of Density Adaptive Strategy&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GUvM3/btrW2uQHeR1/CJZh0D9pxzuxPbDqf9eR20/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGUvM3%2FbtrW2uQHeR1%2FCJZh0D9pxzuxPbDqf9eR20%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;473&quot; height=&quot;244&quot; data-origin-width=&quot;473&quot; data-origin-height=&quot;244&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 11. Advantage of Density Adaptive Strategy&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 11은 sampling density variation(non-uniform density)에도 강인한지를 알려주는 실험 결과이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Density adaptive PointNet layer를 사용한 방법(MSG+DP &amp;rarr; Multi-Scale Grouping + random input Dropout, MRG+DP &amp;rarr; Multi-Resolution Grouping + random input Dropout)이 아주 robust함을 알 수 있다. SSG는 Single Scale Grouping의 줄임말로, adaptive PointNet layer를 사용하지 않은 버전이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Semantic (Scene) Segmentation&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Scene에 대한 labeling을 진행한 결과도 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;539&quot; data-origin-height=&quot;177&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCX8TX/btrWUdQf6yZ/GKwqu5jjAD7RRKAkoZ2kH1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCX8TX/btrWUdQf6yZ/GKwqu5jjAD7RRKAkoZ2kH1/img.jpg&quot; data-alt=&quot;Fig 12. ScanNet Labeling Accuracy&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCX8TX/btrWUdQf6yZ/GKwqu5jjAD7RRKAkoZ2kH1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCX8TX%2FbtrWUdQf6yZ%2FGKwqu5jjAD7RRKAkoZ2kH1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;539&quot; height=&quot;177&quot; data-origin-width=&quot;539&quot; data-origin-height=&quot;177&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 12. ScanNet Labeling Accuracy&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3DCNN은 voxel 기반의 CNN을 활용하는 모델이다. 꽤 큰 성능 변화가 일어났음을 알 수 있다. Voxel 기반 방법과 비교했을 때에는 (point cloud에서 직접적으로 학습하기 때문에)quantization error의 영향을 덜 받고, data distribution에 따라 sampling을 진행하므로 성능이 좋아졌을 것이고, PointNet과 비교했을 때에는 hierarchical architecture를 통해 다양한 크기의 object를 더 잘 이해함으로써 성능이 좋아졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, adaptive PointNet layer를 통해 non-uniform density 특성에도 강인한(Fig 12의 파란 색과 노란 색의 차이가 확 줄어든) 모습을 보였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;471&quot; data-origin-height=&quot;284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4i41T/btrWXjbhofq/X3JrSnj5T7i4SoH7Nk2jQ1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4i41T/btrWXjbhofq/X3JrSnj5T7i4SoH7Nk2jQ1/img.jpg&quot; data-alt=&quot;Fig 13. ScanNet Labeling Results&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4i41T/btrWXjbhofq/X3JrSnj5T7i4SoH7Nk2jQ1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4i41T%2FbtrWXjbhofq%2FX3JrSnj5T7i4SoH7Nk2jQ1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;471&quot; height=&quot;284&quot; data-origin-width=&quot;471&quot; data-origin-height=&quot;284&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 13. ScanNet Labeling Results&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 13을 통해 PointNet도 방의 전체적인 모습은 잘 포착을 하지만, detail한 가구들은 PointNet++에 비해 잘 포착해내지 못함을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Point Set Classification in Non-Euclidean Metric Space&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;PointNet++는 Euclidean space가 아닌 point set에 대해서도 잘 동작한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;276&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s2NAs/btrWVJ2oCa1/NRjgCyFXxVMwYWfJhSETCK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s2NAs/btrWVJ2oCa1/NRjgCyFXxVMwYWfJhSETCK/img.jpg&quot; data-alt=&quot; Fig 14. Example of Non-rigid Shape Classification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s2NAs/btrWVJ2oCa1/NRjgCyFXxVMwYWfJhSETCK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs2NAs%2FbtrWVJ2oCa1%2FNRjgCyFXxVMwYWfJhSETCK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;488&quot; height=&quot;276&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;276&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt; Fig 14. Example of Non-rigid Shape Classification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Non-rigid shape classification을 잘 수행하는 모델은 왼쪽(말)과 오른쪽(말)이 pose는 달라도 같은 category이고, 왼쪽(말)과 가운데(고양이)가 비슷한 pose를 취하고 있으나 다른 category임을 구분할 수 있어야 한다. 이는 &lt;span style=&quot;color: #ee2323;&quot;&gt;intrinsic structure&lt;/span&gt;를 잘 학습하는지를 알아보는 task이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-01-24 at 16.24.30.jpg&quot; data-origin-width=&quot;616&quot; data-origin-height=&quot;157&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dwecwq/btrW6pBj9vo/jVD7naZCscbTLPlivwLiY0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dwecwq/btrW6pBj9vo/jVD7naZCscbTLPlivwLiY0/img.jpg&quot; data-alt=&quot;Fig 15. SHREC15 Non-rigid Shape Classification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dwecwq/btrW6pBj9vo/jVD7naZCscbTLPlivwLiY0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdwecwq%2FbtrW6pBj9vo%2FjVD7naZCscbTLPlivwLiY0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;616&quot; height=&quot;157&quot; data-filename=&quot;CleanShot 2023-01-24 at 16.24.30.jpg&quot; data-origin-width=&quot;616&quot; data-origin-height=&quot;157&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 15. SHREC15 Non-rigid Shape Classification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 15는 SHREC15 dataset을 통해 이러한 non-rigid shape classification 성능을 비교한 결과이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번의 경우 이제까지 알아본 PointNet++에서처럼 Euclidean metric space를 기반으로(XYZ coordinate만 input으로 사용하여) point feature를 얻은 것이고, 이는 pose의 영향을 많이 받기 때문에 성능이 현저히 떨어짐을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 2번은 Euclidean metric space를 기반으로 intrinsic feature를 얻은 방법, 3번은 Geodesic distance를 기반으로 intrinsic feature를 얻은 방법이다. (자세한 방법은 논문을 참고하자.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DeepGM도 3번과 비슷하게 geodesic moment를 shape feature로 활용하는 SOTA 방법이다. 하지만 PointNet++가 더 좋은 성능을 보임을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Research/Paper Review &amp;amp; Implementation</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/216</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Pointcloud-related-Models-2-PointNet#entry216comment</comments>
      <pubDate>Sun, 22 Jan 2023 16:58:01 +0900</pubDate>
    </item>
    <item>
      <title>Pointcloud-related Models (1) - PointNet</title>
      <link>https://jjuke-brain.tistory.com/entry/Pointcloud-related-Architectures-1-PointNet-PointNet</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[&lt;a href=&quot;https://openaccess.thecvf.com/content_cvpr_2017/html/Qi_PointNet_Deep_Learning_CVPR_2017_paper.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;논문 링크&lt;/a&gt;, &lt;a href=&quot;https://github.com/charlesq34/pointnet&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Github 링크&lt;/a&gt;]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3D Vision에서는 pointcloud 데이터를 자주 다룬다. 최초로 이 데이터를 직접적으로 다루는 모델인 PointNet을 제안한 논문 'Charles R. et al., PointNet: Deep Learning on Point Sets for 3D Classification and Segmentation' 논문을 리뷰해보려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Motivation&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;기존에 3D data를 어떻게 표현(representation)할 것인가에 따라 다음과 같이 다양한 학습 방법이 있었다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Volumetric CNN : 3D Voxel로 표현된 3D representation을 다룸&lt;/li&gt;
&lt;li&gt;Multiview CNN : 3D point cloud나 shape을 2D image로 변환한 후 2D convolutional network 적용&lt;/li&gt;
&lt;li&gt;Spectral CNN : Mesh에 spectral CNN을 적용&lt;/li&gt;
&lt;li&gt;Feature-based Deep Neural Network : 3D data를 vector로 변환한 후 학습&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히, convolutional architecture의 경우 image에서의 2d grid, space에서의 3d voxel grid 등 &lt;span style=&quot;color: #ee2323;&quot;&gt;규칙적인 input data format&lt;/span&gt;이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lA1sV/btrWQXNXYzP/6r8Zjrlky1eY0AY23oC4Hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lA1sV/btrWQXNXYzP/6r8Zjrlky1eY0AY23oC4Hk/img.png&quot; data-alt=&quot;Fig 1. Pixel Grid vs Voxel Grid&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lA1sV/btrWQXNXYzP/6r8Zjrlky1eY0AY23oC4Hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlA1sV%2FbtrWQXNXYzP%2F6r8Zjrlky1eY0AY23oC4Hk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;850&quot; height=&quot;254&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;254&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Pixel Grid vs Voxel Grid&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, point cloud나 mesh와 같은 3D geometric data는 규칙적인 format이 없으므로 voxel grid 등으로 데이터를 변형하여 딥러닝 모델의 input으로 주었다. 이러한 방법은 불필요하게 큰 volume을 렌더링해야 하고, data의 특성을 모호하게 한다는 단점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;PointNet&lt;/span&gt;은 이러한 과정 없이 &lt;span style=&quot;color: #ee2323;&quot;&gt;point cloud를 직접적으로 input representation으로 사용하는 딥러닝 네트워크&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;PointNet이 고려해야 할 point cloud의 특성은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Mesh의 불규칙성과 복잡성을 피해야 하며, 간단하고 통합된 구조여야 한다.&lt;/li&gt;
&lt;li&gt;Point set의 특성 반영해야 한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Permutation invariant : 순서가 바뀌어도 network 계산 결과는 같아야 한다. (point set은 unordered set이다.)&lt;/li&gt;
&lt;li&gt;Transformation invariant : 강체의 병진운동(translation), 회전운동(rotation)에도 결과는 같아야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b41qeU/btrWRXzA2Zi/MtXi38XyAkggoztrmp0tkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b41qeU/btrWRXzA2Zi/MtXi38XyAkggoztrmp0tkK/img.png&quot; data-alt=&quot;Fig 2. PointNet Architecture (classification task, segmentation task)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b41qeU/btrWRXzA2Zi/MtXi38XyAkggoztrmp0tkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb41qeU%2FbtrWRXzA2Zi%2FMtXi38XyAkggoztrmp0tkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1203&quot; height=&quot;440&quot; data-origin-width=&quot;1203&quot; data-origin-height=&quot;440&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. PointNet Architecture (classification task, segmentation task)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PointNet은 대표적으로 3D classification, 3D segmetnation task에 사용하며, point cloud 자체를 입력으로 받아 classification task(Fig 2의 1번)인 경우에는 input point cloud의 class label을 예측하고, segmentation task(Fig 2의 2번)에서는 point 각각의 segment 혹은 part label을 예측한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PointNet은 다음과 같은 특징을 갖는다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Simplicity : 초기 단계에서 각 point는 독립적으로 처리된다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Transform invariant : Transform도 point마다 독립적으로 적용되므로, rigid/affine transformation 적용이 쉽다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Permutation invariant : Input point들의 순서가 바뀌어도 feature 결과는 바뀌지 않는다.&lt;/li&gt;
&lt;li&gt;연속적인 어떤 set function이든 근사할 수 있다.&lt;/li&gt;
&lt;li&gt;Summarization : Point cloud를 sparse한 key points(object의 skeleton)로 축약한다.&lt;/li&gt;
&lt;li&gt;Stability(Robustness) : Input이 조금 변하거나, outlier 혹은 missing이 조금 생겨도 좋은 성능을 보인다.&lt;/li&gt;
&lt;li&gt;Efficiency and Powerful : shape classification, part segmentation, scene segmentation 등 다양한 task에 대해 기존 SOTA 모델들보다 훨씬 빠르고, 성능도 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Method&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Properties of Point Sets&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Point는 Euclidean space에 놓여있으므로, 다음과 같은 특성을 갖는다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Unordered : Point set 내의 point들은 순서가 없다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;따라서 \(N\)개의 point를 다루는 network의 경우, \(N!\)가지의 permutation(순서)에 대해 같은 representation을 학습해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Interaction among points : 이웃하는 point 간의 연관성이 '거리'의 개념을 기준으로 정해진다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가까운 point끼리의 local structure와 그 local structure간의 상호작용을 포착해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Transformation invariance : Point set에 translation, rotation 등이 생겨도 point set을 학습한 representation은 똑같아야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;PointNet Architecture&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;전체적인 PointNet 구조는 아래와 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1189&quot; data-origin-height=&quot;440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOFRvw/btrWRX7rGxX/EYcyKq6Ir0klij1vhI9Tr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOFRvw/btrWRX7rGxX/EYcyKq6Ir0klij1vhI9Tr0/img.png&quot; data-alt=&quot;Fig 3. PointNet Architecture Overview&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOFRvw/btrWRX7rGxX/EYcyKq6Ir0klij1vhI9Tr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOFRvw%2FbtrWRX7rGxX%2FEYcyKq6Ir0klij1vhI9Tr0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1189&quot; height=&quot;440&quot; data-origin-width=&quot;1189&quot; data-origin-height=&quot;440&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. PointNet Architecture Overview&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Input&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;PointNet의 input은 앞서 말한대로 &lt;span style=&quot;color: #ee2323;&quot;&gt;3D points&lt;/span&gt;이다. Implementation 관점에서 봤을 때, point의 위치(x, y, z 좌표값)로 주어진다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;적용할 task에 따라 object classification task인 경우에는 shape에서 샘플링한 point cloud, part semantic segmentation task인 경우 단일 object의 point cloud, object semantic segmentation task인 경우 3D scene의 point cloud가 주어질 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Output&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Output의 경우, classification task의 output은 해당 object의 class 개수(\(k\)) 만큼의 score vector일 것이고, semantic segmentation인 경우 point 개수 \(n\), semantic category 개수 \(m\)개에 대해 \(n \times m\)개의 score를 구하여 모든 point 각각이 어떤 semantic category에 해당하는지를 예측할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Pipeline&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Classification과 segmentation task의 차이에 따라 뒷단에서 point feature를 어떻게 활용하는지만 바뀐다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1189&quot; data-origin-height=&quot;440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkT04g/btrWRDg46Ac/FkMgBVKDlE5EPyLeoVpqC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkT04g/btrWRDg46Ac/FkMgBVKDlE5EPyLeoVpqC0/img.png&quot; data-alt=&quot;Fig 4. PointNet Pipeline&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkT04g/btrWRDg46Ac/FkMgBVKDlE5EPyLeoVpqC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkT04g%2FbtrWRDg46Ac%2FFkMgBVKDlE5EPyLeoVpqC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1189&quot; height=&quot;440&quot; data-origin-width=&quot;1189&quot; data-origin-height=&quot;440&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. PointNet Pipeline&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;\(N\)개 point를 입력받는다.&lt;/li&gt;
&lt;li&gt;Input transformation, feature transformation을 적용하여 &lt;span style=&quot;color: #ee2323;&quot;&gt;local point feature&lt;/span&gt;를 얻는다.&lt;/li&gt;
&lt;li&gt;MLP와 max pooling을 통해 &lt;span style=&quot;color: #ee2323;&quot;&gt;global point feature&lt;/span&gt;를 얻는다.&lt;/li&gt;
&lt;li&gt;Task에 따라 다음 과정으로 나뉜다. (Fig 2 참고)
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Classification task : Global feature를 MLP에 입력하여&lt;span style=&quot;color: #333333;&quot;&gt; k개 class에 대한 score를&lt;/span&gt; 구한다.&lt;/li&gt;
&lt;li&gt;Segmentation task : &lt;span style=&quot;color: #ee2323;&quot;&gt;Local feature와 global feature를 연결&lt;/span&gt;(concat)하고, MLP를 거쳐 n개 point들의 segmentation score를 구한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Key Modules of PointNet&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;PointNet에서의 핵심은 max pooling layer, local feature와 global feature의 연결, 그리고 joint alignment network 두 개(input transformation, feature transformation)이다. 각각을 자세하게 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Max pooling layer&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;PointNet에서는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;max pooling&lt;/span&gt;을 통해 point의 정보를 합친다. Max pooling은 symmetric function이므로 permutation invariant와 robustness를 구현할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;즉, max pooling을 사용함으로써 &lt;span style=&quot;color: #ee2323;&quot;&gt;input point의 순서가 바뀌어도 뽑히는 feature는 변하지 않고, input이 조금 변해도 robust&lt;/span&gt;하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;908&quot; data-origin-height=&quot;810&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Be27t/btrWRRlZbwi/AraBkBUbCtOKOk0JCClEQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Be27t/btrWRRlZbwi/AraBkBUbCtOKOk0JCClEQk/img.png&quot; data-alt=&quot;Fig 5. Three Approacehs to achieve order invariance&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Be27t/btrWRRlZbwi/AraBkBUbCtOKOk0JCClEQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBe27t%2FbtrWRRlZbwi%2FAraBkBUbCtOKOk0JCClEQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;545&quot; height=&quot;486&quot; data-origin-width=&quot;908&quot; data-origin-height=&quot;810&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. Three Approacehs to achieve order invariance&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;사실 permutation invariance를 구현하기 위한 방법은 sorting, sequential model, symmetric function 등 여러가지가 있는데, 그중 가장 성능도 좋고, point cloud라는 input을 다루기에 가장 적합한 것이 max pooling이었다. 그 증명 과정은 논문을 참고하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;374&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lpulr/btrWWsrJs47/7QkOmndfRw0ipJAzzwT5Kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lpulr/btrWWsrJs47/7QkOmndfRw0ipJAzzwT5Kk/img.png&quot; data-alt=&quot;Fig 6. Result of Three Approaches&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lpulr/btrWWsrJs47/7QkOmndfRw0ipJAzzwT5Kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flpulr%2FbtrWWsrJs47%2F7QkOmndfRw0ipJAzzwT5Kk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;493&quot; height=&quot;292&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;374&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 6. Result of Three Approaches&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Aggregation of Local and Gobal information&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Semantic segmentation task를 수행할 때, PointNet에서 얻은 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;local feature와 global feature를 연결&lt;/span&gt;(concat)하는 과정이 있다. 이는 segmentation 과정에서 두 가지 정보를 모두 활용해야 하기 때문이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Max pooling의 결과는 point set 전체적인(global) 정보를 담는 vector이다. Classification task에서는 간단히 SVM이나 MLP classifier를 활용하여 task를 진행할 수 있으나, segmentation은 &lt;span style=&quot;color: #ee2323;&quot;&gt;point 각각이(local) 어떤 segmentic category에 해당하는지 알아야&lt;/span&gt; 하므로 local feature와 global feature가 모두 필요하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1JAee/btrWX4c3TYH/s8zxftplyzjpYITrKwntOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1JAee/btrWX4c3TYH/s8zxftplyzjpYITrKwntOk/img.png&quot; data-alt=&quot;Fig 7. Segmentation Network of PointNet&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1JAee/btrWX4c3TYH/s8zxftplyzjpYITrKwntOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1JAee%2FbtrWX4c3TYH%2Fs8zxftplyzjpYITrKwntOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;680&quot; height=&quot;220&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 7. Segmentation Network of PointNet&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이전 과정에서 local feature의 shape은 \((n,64)\), global feature의 shape은 \((n,1024)\)였다. 이를 point 개수를 보존하며 \((n,1088)\)의 vector로 연결한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이후에 이를 MLP에 태워 point별 feature를 다시 뽑아 &lt;span style=&quot;color: #ee2323;&quot;&gt;network가 각 point의 local 정보(geometry)와 global 정보(semantic)를 모두 다루도록&lt;/span&gt; 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Joint Alignment Networks (Input Transformation and Feature Transformation)&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1189&quot; data-origin-height=&quot;440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkT04g/btrWRDg46Ac/FkMgBVKDlE5EPyLeoVpqC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkT04g/btrWRDg46Ac/FkMgBVKDlE5EPyLeoVpqC0/img.png&quot; data-alt=&quot;Fig 4. PointNet Pipeline&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkT04g/btrWRDg46Ac/FkMgBVKDlE5EPyLeoVpqC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkT04g%2FbtrWRDg46Ac%2FFkMgBVKDlE5EPyLeoVpqC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1189&quot; height=&quot;440&quot; data-origin-width=&quot;1189&quot; data-origin-height=&quot;440&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. PointNet Pipeline&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;469&quot; data-origin-height=&quot;141&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUvkXj/btrWXjBq7Xh/5VC7gMWb5ba4CudGOJj64K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUvkXj/btrWXjBq7Xh/5VC7gMWb5ba4CudGOJj64K/img.png&quot; data-alt=&quot;Fig 8. Joint Alignment Networks&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUvkXj/btrWXjBq7Xh/5VC7gMWb5ba4CudGOJj64K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUvkXj%2FbtrWXjBq7Xh%2F5VC7gMWb5ba4CudGOJj64K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;526&quot; height=&quot;158&quot; data-origin-width=&quot;469&quot; data-origin-height=&quot;141&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 8. Joint Alignment Networks&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Joint alignment network&lt;/span&gt;란, PointNet에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;feature를 뽑기 전에 모든 input point set을 canonical space로 정렬해주는 network&lt;/span&gt;를 말한다. 이는 spatial transformer에서 sampling과 interpolation을 통해 2D image를 정렬한 아이디어를 차용한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;input transformation&lt;/span&gt;부터 알아보자. T-Net(Transformation Network)을 사용하는데, 이미지에서보다 point cloud에 적용하는 게 훨씬 간단하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;T-Net은 affine transformation matrix를 예측하는 네트워크이다. 즉, point set이 canonical space에 비해 얼마나 translation, rotation했는지를 예측하는 네트워크이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로 feature transformation에서는 또다른 T-Net을 활용한다. Input transformation 이후에 한 번 feature를 뽑는데, 여기에 T-Net을 한 번 더 적용하여 feature transformation matrix를 예측한다. 즉, feature space가 얼마나 transform되었는지를 예측한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 spatial space(3D)보다 feature space(64D)에서의 transformation matrix의 차원이 훨씬 높으므로 optimization이 어려워지는데, 이를 해결하기 위해 &lt;span style=&quot;color: #ee2323;&quot;&gt;loss에 regularization term을 추가&lt;/span&gt;해준다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathcal{L}_\text{reg} = \lVert \mathbf{I} - \mathbf{A}\mathbf{A}^\top \rVert_F^2&amp;nbsp; \)&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\mathbf{A}\) : T-Net이 예측한 feature alignment matrix&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 loss를 통해 optimize한다는 것은 feature transformation(alignment) matrix가 orthogonal matrix가 되도록 학습시키는 개념이다. 이를 통해 optimization 과정이 stable해지고, 모델 성능이 더 좋아진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;425&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qBOvI/btrWQ40xGsu/EgVlAd2BUzdCP9tpc2R8P1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qBOvI/btrWQ40xGsu/EgVlAd2BUzdCP9tpc2R8P1/img.png&quot; data-alt=&quot;Fig 9. Effects of Input Transform and Feature Transform&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qBOvI/btrWQ40xGsu/EgVlAd2BUzdCP9tpc2R8P1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqBOvI%2FbtrWQ40xGsu%2FEgVlAd2BUzdCP9tpc2R8P1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;379&quot; height=&quot;196&quot; data-origin-width=&quot;425&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 9. Effects of Input Transform and Feature Transform&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Experiments&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;505&quot; data-origin-height=&quot;351&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BIFfI/btrWRytoFug/QsQCK3NGWjRu0jm2yEYGQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BIFfI/btrWRytoFug/QsQCK3NGWjRu0jm2yEYGQK/img.png&quot; data-alt=&quot;Fig 10. Critical Points and Upper Bound Shape&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BIFfI/btrWRytoFug/QsQCK3NGWjRu0jm2yEYGQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBIFfI%2FbtrWRytoFug%2FQsQCK3NGWjRu0jm2yEYGQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;505&quot; height=&quot;351&quot; data-origin-width=&quot;505&quot; data-origin-height=&quot;351&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 10. Critical Points and Upper Bound Shape&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 10의 결과에서 색상은 depth를 나타내고, critical points란 global shape feature를 결정하는 점, 즉 이 점들이 없어지지만 않는다면 결과가 바뀌지 않는 점들을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Upper-bound shape이란, noise가 존재해도 결과가 바뀌지 않는 최대 범위를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;3D Object Part Segmentation, Semantic Segmentation&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;257&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bc6muL/btrWRj4hsd8/Ea4KKIE3AoUVjr1ZMd8hsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bc6muL/btrWRj4hsd8/Ea4KKIE3AoUVjr1ZMd8hsK/img.png&quot; data-alt=&quot;Fig 11. Object Part Segmentation Results&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bc6muL/btrWRj4hsd8/Ea4KKIE3AoUVjr1ZMd8hsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbc6muL%2FbtrWRj4hsd8%2FEa4KKIE3AoUVjr1ZMd8hsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;676&quot; height=&quot;384&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;257&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 11. Object Part Segmentation Results&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 11은 object part segmentation 결과이다. 한 물체가 주어졌을 때, 그 물체의 부분을 나눠주는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;447&quot; data-origin-height=&quot;275&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpzZJC/btrWX537GuY/CxXMSNtKAhniHwu4kLceUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpzZJC/btrWX537GuY/CxXMSNtKAhniHwu4kLceUK/img.png&quot; data-alt=&quot;Fig 12. Semantic Segmentation of Given Scene&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpzZJC/btrWX537GuY/CxXMSNtKAhniHwu4kLceUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpzZJC%2FbtrWX537GuY%2FCxXMSNtKAhniHwu4kLceUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;658&quot; height=&quot;405&quot; data-origin-width=&quot;447&quot; data-origin-height=&quot;275&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 12. Semantic Segmentation of Given Scene&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 12는 semantic segmentation 결과로, 주어진 scene에서 point별로 해당하는 category를 나누는 작업이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이외에도 Model retrieval from point cloud (주어진 point(query shape)과 shape feature가 비슷한 shape을 고르는 task), shape correspondence (주어진 두 shape의 critical point set 간의 correspondence 계산) 등 다양한 task에 활용될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음에는 이를 보완한 PointNet++ 모델을 제안한 논문을 리뷰해볼 것이다.&lt;/p&gt;</description>
      <category>Research/Paper Review &amp;amp; Implementation</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/198</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Pointcloud-related-Architectures-1-PointNet-PointNet#entry198comment</comments>
      <pubDate>Sun, 22 Jan 2023 16:53:19 +0900</pubDate>
    </item>
    <item>
      <title>Signed Distance Function (SDF)</title>
      <link>https://jjuke-brain.tistory.com/entry/Signed-Distance-Function-SDF</link>
      <description>&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SDF(Signed Distance Function, or Signed Distance Field)는 Graphics 분야에서 렌더링 시 외곽선이 깔끔하게 나오지 않는 문제를 해결하기 위해 사용되는 개념이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동시에 3D Vision 분야에서 scene reconstruction, surface generation 등의 task를 진행할 때 3D geometry를 나타내는 데 활용되는 기초 개념이어서 따로 공부하고 정리해두려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;What is SDF?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Signed Distance Function in Mathematics&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Signed distance function&lt;/span&gt;의 수학적인 정의는 metric space에 포함된 set \(\omega\)(어떤 구역)에 대한 주어진 point \(x\)의 (부호가 있는) orthogonal distance이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( f(x) = \begin{cases} d(x, \partial \Omega) &amp;amp; \quad \text{if } x \in \Omega \\ -d(x, \partial \Omega) &amp;amp; \quad \text{if } x \in \Omega^c \end{cases} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\partial \Omega\) : 공간 상의 구역 \(\Omega\)의 boundary&lt;/li&gt;
&lt;li&gt;\( d(x, \partial \Omega) := \underset{y \in \partial \Omega}{\operatorname{inf}} d(x,y) \)&lt;/li&gt;
&lt;li&gt;\(\text{inf} \) : infimum(하한)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1011&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/w9eFv/btrV5NdgHBj/Ba2Tn7sfjRTYjSfWiHMKk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/w9eFv/btrV5NdgHBj/Ba2Tn7sfjRTYjSfWiHMKk1/img.png&quot; data-alt=&quot;Fig 1. Set \(\Omega\) and the graph of its Signed Distance Function&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/w9eFv/btrV5NdgHBj/Ba2Tn7sfjRTYjSfWiHMKk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fw9eFv%2FbtrV5NdgHBj%2FBa2Tn7sfjRTYjSfWiHMKk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;389&quot; height=&quot;393&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1011&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Set \(\Omega\) and the graph of its Signed Distance Function&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, &lt;span style=&quot;color: #ee2323;&quot;&gt;어떤 점이 정해진 구역 안(+) 또는 밖(-)으로 얼마나 떨어져있는지를 나타내는 함수&lt;/span&gt;이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(Omega\)가 Euclidean space \(\mathbb{R}^n\)내의 구역이라면, SDF는 거의 모든 곳에서 미분이 가능하고, gradient는 다음 eikonal equation을 만족한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \lvert \nabla f \rvert = 1 \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, boundary 상에서 Signed distance function \(f\)의 gradient는 (inward) normal vector를 나타낸다. (따라서 SDF는 미분 가능한 normal vector field라고 볼 수 있다.)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \nabla f(x) = N(x) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(N\) : inward normal vector field&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전까지는 2차원 기준으로 x좌표값과 y좌표값을 통해 도형을 정의했다면, SDF를 활용할 때에는 한 점과 도형(boundary) 사이의 거리로 도형을 정의할 수 있게된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Signed Distance Function in Graphics and Computer Vision&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Computer vision 분야에서 shape modeling에 SDF를 활용할 때에는 반대로 &lt;span style=&quot;color: #ee2323;&quot;&gt;안쪽을 -, 바깥쪽을 +로&lt;/span&gt; 사용한다. 이유가 궁금해서 &lt;a href=&quot;https://ieeexplore.ieee.org/document/368173&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;논문&lt;/a&gt;에서 살펴보았는데, 3D geometry에 적용할 때 'SDF의 gradient 방향을 surface 바깥방향의 normal vector가 되도록 하기 위해'라고 이해하면 되겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(사실 전문 분야가 아니라서, 논문을 꼼꼼히 읽어보진 못했다. 이를 위해서 sign의 정의를 반대로 한건지, 정의를 반대로 했더니 normal vector가 우연히 바깥쪽이 된건지는 정확하지 않다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 영상은 3D geometry에 사용되는 SDF를 잘 설명해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;338&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUSqxg/btrV679YYOk/5ht8sU6zkwayfsiUIKWVIk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUSqxg/btrV679YYOk/5ht8sU6zkwayfsiUIKWVIk/img.gif&quot; data-alt=&quot;Fig 2. SDF in CV &amp;amp;amp; Graphics&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUSqxg/btrV679YYOk/5ht8sU6zkwayfsiUIKWVIk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bUSqxg/btrV679YYOk/5ht8sU6zkwayfsiUIKWVIk/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;579&quot; height=&quot;326&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;338&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. SDF in CV &amp;amp; Graphics&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;(영상 출처 : &lt;a href=&quot;https://www.cineversity.com/vidplaylist/372083_default_playlist/volumetric_workflow_what_are_signed_distance_fields_sdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 3D geometry의 절단면의 boundary는 SDF \(f(x) = 0\)인 점들의 집합으로볼 수 있고, 확장하면 모든 surface도 \(f(x)=0\)인 점의 집합일 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 아래와 같은 등고선(contour) 형태로 geometry를 나타낼 수 있다. 이렇게 surface(shape)를 등고선 형태로 나타내는 방법을 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;level-set method&lt;/span&gt;라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;969&quot; data-origin-height=&quot;553&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqynVA/btrV5nMLtxY/10f54xVxqmD5kyR2LWSSkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqynVA/btrV5nMLtxY/10f54xVxqmD5kyR2LWSSkk/img.png&quot; data-alt=&quot;Fig 3. Contour of 3D geometry&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqynVA/btrV5nMLtxY/10f54xVxqmD5kyR2LWSSkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqynVA%2FbtrV5nMLtxY%2F10f54xVxqmD5kyR2LWSSkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;613&quot; height=&quot;350&quot; data-origin-width=&quot;969&quot; data-origin-height=&quot;553&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Contour of 3D geometry&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 2와 3을 종합적으로 고려해보면, SDF의 &lt;span style=&quot;color: #ee2323;&quot;&gt;1차 미분(gradient)은 surface의 normal vector&lt;/span&gt;, &lt;span style=&quot;color: #ee2323;&quot;&gt;2차 미분은 surface의 곡률&lt;/span&gt;을 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Knowledges</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/215</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Signed-Distance-Function-SDF#entry215comment</comments>
      <pubDate>Thu, 12 Jan 2023 23:50:39 +0900</pubDate>
    </item>
    <item>
      <title>Transformer and Self-Supervised Learning</title>
      <link>https://jjuke-brain.tistory.com/entry/Self-Supervised-Learning</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Transformer를 활용한 (비교적 최신의) 대표적인 언어 모델에는 BERT, GPT 등이 있고, vision 분야에 활용한 예로는 ViT, Swin Transformer 등이 있다. BERT를 이해하기 위해서는 self-supervised training에 대해 이해해볼 필요가 있다. (특히, CLIP과 같이 text와 vision domain에 걸쳐 학습을 진행하는 multi-modal 모델을 이해할 때에도 이 개념이 활용된다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Self-attention과 transformer의 기초 내용을 먼저 숙지하고 self-supervised training을 이해해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1671954308974&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Transformers in Vision - (1) Attention &amp;amp; Transformer&quot; data-og-description=&quot;Transformer가 computer vision에서 어떻게 쓰였는지, 관련 모델이 어떻게 발전하고 있는지 여러 포스팅에 걸쳐서 알아보고자 한다. 이번 포스팅에서는 가장 중요한 기초 내용인 attention과 transformer에 대&quot; data-og-host=&quot;jjuke-brain.tistory.com&quot; data-og-source-url=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; data-og-url=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/byKWrs/hyQ1c1XMLX/EhEnKaEc4h4uJMGlk02nu1/img.jpg?width=800&amp;amp;height=269&amp;amp;face=0_0_800_269,https://scrap.kakaocdn.net/dn/rMlAV/hyQ1cVcjgd/ZQzYBxYF04MM97s7xN7zt1/img.jpg?width=800&amp;amp;height=269&amp;amp;face=0_0_800_269,https://scrap.kakaocdn.net/dn/cdMhgT/hyQ1mjdkwu/guMO5ZKKmKgkBPGcXN2MB0/img.jpg?width=627&amp;amp;height=932&amp;amp;face=0_0_627_932&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/byKWrs/hyQ1c1XMLX/EhEnKaEc4h4uJMGlk02nu1/img.jpg?width=800&amp;amp;height=269&amp;amp;face=0_0_800_269,https://scrap.kakaocdn.net/dn/rMlAV/hyQ1cVcjgd/ZQzYBxYF04MM97s7xN7zt1/img.jpg?width=800&amp;amp;height=269&amp;amp;face=0_0_800_269,https://scrap.kakaocdn.net/dn/cdMhgT/hyQ1mjdkwu/guMO5ZKKmKgkBPGcXN2MB0/img.jpg?width=627&amp;amp;height=932&amp;amp;face=0_0_627_932');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Transformers in Vision - (1) Attention &amp;amp; Transformer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Transformer가 computer vision에서 어떻게 쓰였는지, 관련 모델이 어떻게 발전하고 있는지 여러 포스팅에 걸쳐서 알아보고자 한다. 이번 포스팅에서는 가장 중요한 기초 내용인 attention과 transformer에 대&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jjuke-brain.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Transformer&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Transformer를 간단히 복기해보자. Task는 'I did not submit the assignment'라는 영어 문장을 한국어로 변역하는 machine translation이라 하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1714&quot; data-origin-height=&quot;860&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cy2l4p/btrUCjcDQCA/YX9xre9JqmSaXhik87DLsk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cy2l4p/btrUCjcDQCA/YX9xre9JqmSaXhik87DLsk/img.jpg&quot; data-alt=&quot;Fig 1. Transformer in Machine Translation&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cy2l4p/btrUCjcDQCA/YX9xre9JqmSaXhik87DLsk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcy2l4p%2FbtrUCjcDQCA%2FYX9xre9JqmSaXhik87DLsk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;840&quot; height=&quot;421&quot; data-origin-width=&quot;1714&quot; data-origin-height=&quot;860&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Transformer in Machine Translation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Self-attention 계산은 Fig 1에서와 같이 각 encoder와 decoder의 multi-head attention 모듈과 masked multi-head attention 모듈에서 수행한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;기본 self-attention은 아래와 같은 수식으로 계산된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( f(\mathbf{x}, \{ ( \mathbf{x}_i, \mathbf{x}_i \}_{i=1}^n ) = \sum\limits_{i=1}^n \alpha (\mathbf{x}, \mathbf{x}_i) \mathbf{x}_i \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;입력한 문장 'I did not submit the assignment' 각각의 단어를 처리하는데, 모든 단어와 각 단어의 관련성을 계산하는 과정이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Multi-head self-attention은 아래와 같이 여러 head에 각각의 weight을 두어 self-attention을 여러 번 계산한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( \mathbf{h}_m = f(\mathbf{W}_m^{(q)} \mathbf{x}, \{ \mathbf{W}_m^{(k)} \mathbf{x}_i, \mathbf{W}_m^{(v)} \mathbf{x}_i \}_{i=1}^n ) = \sum\limits_{i=1}^n \alpha ( \mathbf{W}_m^{(q)} \mathbf{x}, \mathbf{W}_m^{(k)} \mathbf{x}_i ) \mathbf{W}_m^{(v)} \mathbf{x}_i \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;query, key, value에 해당하는 weight에 따라 중요한 token을 계산한다. 이러한 weight을 optimize함으로써 학습을 진행할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Multi-head attention vs Masked multi-head attention&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Transformer는 RNN 기반 모델과 달리 모든 시점의 입력을 입력받는다. 따라서 \(t\)까지의 정보만 가지고 \(t+1\) 시점을 예측하고자 할 때, decoder에서 일반적인 multi-head attention을 사용하면 이후 입력까지 모두 아는 상태와 같아진다. 따라서 Transformer의 decoder에서는 미래의(아직 알지 못한다고 가정하는)입력 부분은 '\(-\inf\)'로 마스킹하여 multi-head attention을 계산하는 Masked multi-head attention을 사용한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;좀 더 깊은 내용이 궁금하다면 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 참조하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 주목할 점은, 일반적인 self-attention은 모든 input token을 사용하기 때문에 parrallel computation이 가능하지만, masked self-attention은 가려진 부분을 사용할 수 없으므로 parrallel computation이 불가능하다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Advanced Transformers&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Transformer 기반의 모델은 아래와 같다. 보통은 encoder 부분이나 decoder 부분 하나만 사용한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Encoder Part of Transformer (Bidirectional Transformer)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;BERT (Devlin et al., ACL 2019)&lt;/li&gt;
&lt;li&gt;ViT (Dosovitskiy., ICLR 2021)&lt;/li&gt;
&lt;li&gt;TokenGT (Kim et al., NeurIPS 2022)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Decoder Part of Transformer (Masked self-attention 활용)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GPT (Radford et al., 2019; Brown et al., NeurIPS 2020)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 domain에서 사용된 transformer의 예시는 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;NLP
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;BERT, GPT&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CV
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Vision Transformer&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Graph
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Graph Transformer&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reinforcement Learning
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Decision Transforemer&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Design Principles of Transformer in DL&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Transformer가 항상 다른 기본적인 모델(CNN, RNN 등)보다 좋은 성능을 나타내는 건 아니다. Inductive bias가 적기 때문이다. Inductive bias의 개념은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Inductive-Bias%EB%9E%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 참조하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;CNN, GNN, RNN 등보다 inductive bias가 적으므로 dataset 양이 적은 경우 성능이 좋지 않다. (design principle이 적다.)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;823&quot; data-origin-height=&quot;623&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/E1nvV/btrUDirbRel/PnF5uOPgDLUK6uK25ZkLOk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/E1nvV/btrUDirbRel/PnF5uOPgDLUK6uK25ZkLOk/img.jpg&quot; data-alt=&quot;Fig 2. Expressive models require more data&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/E1nvV/btrUDirbRel/PnF5uOPgDLUK6uK25ZkLOk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FE1nvV%2FbtrUDirbRel%2FPnF5uOPgDLUK6uK25ZkLOk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;605&quot; height=&quot;458&quot; data-origin-width=&quot;823&quot; data-origin-height=&quot;623&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Expressive models require more data&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;따라서, Fig 2와 같이 매우 적은 데이터로는 traditional ML(Random Forest 등)을, 그보다 조금 더 많다면 inductive bias가 높은 딥러닝 모델(CNN, GNN, RNN 등)을, 매우 많은 데이터를 갖고 있다면 Transformer 기반 모델(BERT, ViT 등)을 사용하는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Self-supervised Learning이란?&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;현재 Transformer 기반의 모델이 큰 성공을 거두고 있는 주된 요인은, scalability, 즉 아주 큰(복잡한) 모델을 통해 다양한 task에서 높은 성능을 보인다(expressive power가 강함)는 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그런데 앞서 Transformer가 제대로 역량을 발휘하기 위해서는 방대한 데이터가 필수적으로 필요하다고 하였다. 매번 방대한 데이터로 크기가 큰 모델을 학습시키는 것은 비효율적이므로, 거대한 규모의 &lt;span style=&quot;color: #ee2323;&quot;&gt;self-supervised (pre)training&lt;/span&gt;을 통해 이 문제를 해결하였다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;일반적인 supervised learning은 특정 task에 대한 성능을 높이는 데에 최적화되어있으나, training data에 대해서 사람이 직접 labeling을 해주어야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Self-supervised learning&lt;/span&gt;은 사람이 아닌 &lt;span style=&quot;color: #ee2323;&quot;&gt;data가 supervision signal을 제공&lt;/span&gt;하도록 하는 unsupervised learning의 일종이다. 좀 더 정확히 말하자면, labeling되지 않은 data에 대해서 task를 정하여 data의 representation을 학습(모델 스스로 supervision을 생성하여 supervised 방식으로 학습)하는 방식이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이때 정한 task를 pretext task라 한다. &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Pretext task&lt;/span&gt;는 self-supervised 모델이 학습하는 task로, 이를 통해 &lt;span style=&quot;color: #ee2323;&quot;&gt;downstream task에서 활용될 representation을 학습&lt;/span&gt;하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Pretext Tasks&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Pretext task는 크게 다음과 같이 나누어진다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Self-prediction : 데이터 샘플 내에서 일부를 masking하고, 그것을 predict(혹은 reconstruct)하는 task
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Autoregressive generation : Sequential data를 다루는 task (ex. GPT)&lt;/li&gt;
&lt;li&gt;Masked generation : Random masking을 통해 일반화 성능을 높이는 task (ex. BERT)&lt;/li&gt;
&lt;li&gt;Innate relationship prediction : Rotation 등의 transformation에도 데이터의 본질은 유지되는 image에서 주로 사용하는 task&lt;/li&gt;
&lt;li&gt;Hybrid self-prediction : 여러 방식의 pretext task를 혼합한 task (ex. DALL-E)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Contrastive Learning : Embedding space 상에 비슷한 데이터의 feature는 가깝게, 다른 feature는 멀게 embedding하도록 학습하는 task&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Pretext task의 좀 더 구체적인 예시를 몇 가지 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Position Prediction&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;997&quot; data-origin-height=&quot;515&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KUXU3/btrUyhGCaUJ/2Fpz1SOPbGYRjTBtfwRNz0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KUXU3/btrUyhGCaUJ/2Fpz1SOPbGYRjTBtfwRNz0/img.jpg&quot; data-alt=&quot;Fig 3. Pretext Example (1) - Position Prediction (Context Prediction)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KUXU3/btrUyhGCaUJ/2Fpz1SOPbGYRjTBtfwRNz0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKUXU3%2FbtrUyhGCaUJ%2F2Fpz1SOPbGYRjTBtfwRNz0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;810&quot; height=&quot;418&quot; data-origin-width=&quot;997&quot; data-origin-height=&quot;515&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Pretext Example (1) - Position Prediction (Context Prediction)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지에서 3 * 3 = 9개의 image patch를 가져와 중간 patch와 비교했을 때 다른 1개 patch의 위치가 어디인지 예측하는 pretext task이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Rotation Prediction&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1112&quot; data-origin-height=&quot;639&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uMtxw/btrUCh0gLGx/GmV4nKdPKTthAnaI5vfx6K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uMtxw/btrUCh0gLGx/GmV4nKdPKTthAnaI5vfx6K/img.jpg&quot; data-alt=&quot;Fig 4. Pretext Example (2) - Rotation Prediction&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uMtxw/btrUCh0gLGx/GmV4nKdPKTthAnaI5vfx6K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuMtxw%2FbtrUCh0gLGx%2FGmV4nKdPKTthAnaI5vfx6K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1112&quot; height=&quot;639&quot; data-origin-width=&quot;1112&quot; data-origin-height=&quot;639&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. Pretext Example (2) - Rotation Prediction&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지가 \(0^\circ, 90^\circ, 180^\circ, 270^\circ\) 중 얼마나 회전한 이미지인지를 예측(4-class classification)하는 pretext task이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Contrastive Learning&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1577&quot; data-origin-height=&quot;691&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c3opDW/btrUurwNK78/QKuChUL8sLFAkhlzc72l50/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c3opDW/btrUurwNK78/QKuChUL8sLFAkhlzc72l50/img.jpg&quot; data-alt=&quot;Fig 5. Pretext Example (3) - Contrastive Learning&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c3opDW/btrUurwNK78/QKuChUL8sLFAkhlzc72l50/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc3opDW%2FbtrUurwNK78%2FQKuChUL8sLFAkhlzc72l50%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1577&quot; height=&quot;691&quot; data-origin-width=&quot;1577&quot; data-origin-height=&quot;691&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. Pretext Example (3) - Contrastive Learning&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Contrastive learning은 representation space 상에서 어떤 기준 데이터(anchor)와 &lt;span style=&quot;color: #ee2323;&quot;&gt;비슷한 데이터(positive sample)는 가까이, 다른 데이터(negative sample)는 멀리 feature가 존재하도록 학습&lt;/span&gt;하는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이외에도 Image domain에서는 colorization, generative modeling 등, video domain에서는 tracking, frame sequence 등, control(RL) domain에서는 goal generation 등의 다양한 pretext task가 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Self-supervised learning pipeline&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Self-supervised learning의 과정은 다음과 같이 이루어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. Pre-training&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Label이 없는 데이터를 사용하여 연구자가 정한 &lt;span style=&quot;color: #ee2323;&quot;&gt;pretext task로 representation을 학습&lt;/span&gt;한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이때, 데이터를 적절히 변형하여 이를 supervision으로 사용한다. (label과는 다른 개념이다.)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1237&quot; data-origin-height=&quot;223&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OozDj/btrUunHVIpy/GXPWy7GVIEYxNqonC4fQF1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OozDj/btrUunHVIpy/GXPWy7GVIEYxNqonC4fQF1/img.jpg&quot; data-alt=&quot;Fig 6. Pre-training Example with Rotation Prediction&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OozDj/btrUunHVIpy/GXPWy7GVIEYxNqonC4fQF1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOozDj%2FbtrUunHVIpy%2FGXPWy7GVIEYxNqonC4fQF1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1237&quot; height=&quot;223&quot; data-origin-width=&quot;1237&quot; data-origin-height=&quot;223&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 6. Pre-training Example with Rotation Prediction&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 6과 같이 pretext task로 rotation prediction task를 사용하였다고 해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. Transfer Learning&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Pre-trained model을 사용하여 &lt;span style=&quot;color: #ee2323;&quot;&gt;downstream task에 대해 (linear) probing 혹은 fine-tuning&lt;/span&gt;을 진행한다. 두 방법은 transfer 방식에 따라 나뉜다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;linear probing&lt;/span&gt;이란, &lt;span style=&quot;color: #ee2323;&quot;&gt;사전 학습된 weight(parameter)는 모두 freeze한 상태로 downstream task에서 feature가 적절한지를 입증(모델을 평가)&lt;/span&gt;하는 방법이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-12-25 at 19.31.38.jpg&quot; data-origin-width=&quot;924&quot; data-origin-height=&quot;232&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bu78n7/btrUCjjv40y/oCrMlVfDl1cNF4sXZvcVRk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bu78n7/btrUCjjv40y/oCrMlVfDl1cNF4sXZvcVRk/img.jpg&quot; data-alt=&quot;Fig 7. Linear Probing&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bu78n7/btrUCjjv40y/oCrMlVfDl1cNF4sXZvcVRk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbu78n7%2FbtrUCjjv40y%2FoCrMlVfDl1cNF4sXZvcVRk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;924&quot; height=&quot;232&quot; data-filename=&quot;CleanShot 2022-12-25 at 19.31.38.jpg&quot; data-origin-width=&quot;924&quot; data-origin-height=&quot;232&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 7. Linear Probing&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이는 pre-training 과정, 즉 representation 학습이 잘 되었는지를 평가하는 개념이다. weight update를 하지 않으므로 과정이 매우 빠르다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;fine-tuning&lt;/span&gt;이란, &lt;span style=&quot;color: #ee2323;&quot;&gt;구체적인 downstream task에 pre-training 과정에서 학습한 representation을 활용하고, weight(parameter)를 좀 더 학습&lt;/span&gt;시키는 개념이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;911&quot; data-origin-height=&quot;256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuEOsE/btrUt00DL6w/iRwgIkkWVhfV4usknWMQVk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuEOsE/btrUt00DL6w/iRwgIkkWVhfV4usknWMQVk/img.jpg&quot; data-alt=&quot;Fig 8. Fine-tuning&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuEOsE/btrUt00DL6w/iRwgIkkWVhfV4usknWMQVk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuEOsE%2FbtrUt00DL6w%2FiRwgIkkWVhfV4usknWMQVk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;911&quot; height=&quot;256&quot; data-origin-width=&quot;911&quot; data-origin-height=&quot;256&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 8. Fine-tuning&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Pretraining for Representation Learning in NLP&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;실제 NLP domain에서 transformer와 self-supervised learning을 어떻게 활용했는지 알아보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;545&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/edXfNz/btrUDg733Kq/MPpz2eXcc7REucMjkIPdE0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/edXfNz/btrUDg733Kq/MPpz2eXcc7REucMjkIPdE0/img.jpg&quot; data-alt=&quot; Fig 9. ELMo vs GPT vs BERT&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/edXfNz/btrUDg733Kq/MPpz2eXcc7REucMjkIPdE0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FedXfNz%2FbtrUDg733Kq%2FMPpz2eXcc7REucMjkIPdE0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;784&quot; height=&quot;522&quot; data-origin-width=&quot;819&quot; data-origin-height=&quot;545&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt; Fig 9. ELMo vs GPT vs BERT&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;위 Fig 9의 세 모델 모두 NLP에서 매우 좋은 성능을 낸 유명한 모델인데, 구조적인 차이가 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;ELMo라는 모델은 bidirectional LSTM모델을 pre-training하였다. 하지만 linear probing을 통해 학습하였으므로 특정 task에만 한정적으로 사용할 수 있는 모델이다. (task-specific architecture)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;GPT는 context가 왼쪽에서 오른쪽으로만, 즉 undirectional한 transformer decoder를 pre-training하였다. 하지만, fine-tuning을 통해 task에 상관없이 일반적으로 사용할 수 있는 모델이다. (task-agnostic architecture)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;BERT(Bidirectional Encoder Representations from Transformers)는 이름에서도 알 수 있듯, bidirectional RNN의 개념을 사용하여 GPT에 bidirectional 개념을 추가한 모델이다.(Bidirectional의 개념을 사용한 것이지, RNN을 사용한 것은 아님에 주의하자. 대표적인 Transformer 기반 모델이다.) Bidirectional RNN을 사용하면 sequence 양쪽에서의 정보(즉, 과거와 미래의 정보)를 모두 사용할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;GPT는 transformer decoder 기반(masked self-attention), BERT는 transformer encoder 기반(self-attention)이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;BERT도 GPT처럼 fine-tuning을 사용하지만, pre-training 방식, 즉 pretext task가 조금 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Pre-training of BERT&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;BERT를 pre-train할 때 MLM과 NSP를 사용한다. 위에서 pretext task의 분류를 설명할 때 잠깐 언급했는데, 조금 더 구체적으로 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Masked Language Modeling (MLM)&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Masked language modeling은 &lt;span style=&quot;color: #ee2323;&quot;&gt;context를 양방향으로(bidirectionally) 인코딩&lt;/span&gt;하기 위해 사용하는 pretext task이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1604&quot; data-origin-height=&quot;362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rwFMz/btrUuwY2uqP/nUGqq8r5wIO0H7NuKLdkMK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rwFMz/btrUuwY2uqP/nUGqq8r5wIO0H7NuKLdkMK/img.jpg&quot; data-alt=&quot; Fig 10. Masked Language Modeling&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rwFMz/btrUuwY2uqP/nUGqq8r5wIO0H7NuKLdkMK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrwFMz%2FbtrUuwY2uqP%2FnUGqq8r5wIO0H7NuKLdkMK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1604&quot; height=&quot;362&quot; data-origin-width=&quot;1604&quot; data-origin-height=&quot;362&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt; Fig 10. Masked Language Modeling&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Fig 10과 같이 Transformer encoder에 &lt;span style=&quot;color: #ee2323;&quot;&gt;일부 token을 랜덤하게 마스킹&lt;/span&gt;한 데이터를 입력하고, 그 &lt;span style=&quot;color: #ee2323;&quot;&gt;token을 예측&lt;/span&gt;하도록 하는 task를 진행한다. 예측할 때 모델이 양방향 context(앞, 뒤 문맥을 모두 활용)를 활용하게 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Distribution-shift를 피하기 위해 noisy label(다른 token)도 사용한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;MLM은 BERT 모델의 핵심으로, 성능을 끌어올린 주된 성공 요인이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Next Sequence Prediction (NSP)&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Next sequence prediciton은 &lt;span style=&quot;color: #ee2323;&quot;&gt;문장(sequence)의 논리적 관계(logical relations)를 이해하도록&lt;/span&gt; 하기 위한 pretext task이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;방법은 간단하다. BERT에 text 쌍(2개)을 입력한 후, binary classification을 통해 두 text 간에 연결관계가 있다면 True, 없으면 False를 출력하도록 학습시킨다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Pre-training 과정에서 MLM에 대한 loss function과 NSP에 대한 loss function을 결합하여 &lt;span style=&quot;color: #ee2323;&quot;&gt;multi-task learning&lt;/span&gt;을 진행한다. (실험적으로 downstream task에 따라 둘 다 사용했을 때가 좋은 경우도 있고, MLM만 사용했을 때 좋은 경우도 있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Fine-tuning of BERT&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 fine-tuning 방법을 알아보자. Pre-training 과정에서는 unlabeled data로 학습하지만, fine-tuning 과정에서는 구체적인 &lt;span style=&quot;color: #ee2323;&quot;&gt;downstream task 종류에 따라 적은 양의 labeled data를 활용하여 parameter를 좀 더 tuning&lt;/span&gt;한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1639&quot; data-origin-height=&quot;395&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xyz5b/btrUuQJ4we0/83wNnJrpCWh89o2kOuF8hk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xyz5b/btrUuQJ4we0/83wNnJrpCWh89o2kOuF8hk/img.jpg&quot; data-alt=&quot;Fig 11. Fine-tuning methods corresponding to downstream tasks&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xyz5b/btrUuQJ4we0/83wNnJrpCWh89o2kOuF8hk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxyz5b%2FbtrUuQJ4we0%2F83wNnJrpCWh89o2kOuF8hk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1639&quot; height=&quot;395&quot; data-origin-width=&quot;1639&quot; data-origin-height=&quot;395&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 11. Fine-tuning methods corresponding to downstream tasks&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Linear Probing vs Fine-Tuning&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Distribution shift가 발생한 경우에는 fine-tuning보다 linear probing이 더 좋다. 우선 distribution shift를 간단히 이해해보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;흔히 supervised learning에서 input \(X\)와 output \(Y\)가 있을 때, training data는 수학적으로 joint distribution \(P(X, Y)\)로 표현되고, 머신러닝 모델은 수식 \(P(Y|X)\)를 모델링한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이때 joint distribution \(P(X, Y)\)는 conditional probability를 사용하여 \(P(Y|X) P(X) \)와 \(P(X|Y) P(Y)\)로 표현 가능하다. 여기서 \(P(X)\)는 input의 probability density, \(P(Y)\)는 output의 probability density를 뜻한다. 이에 따라 data distribution shift의 종류인 &lt;span style=&quot;color: #ee2323;&quot;&gt;Covariate shift, Label shift, Concept drift&lt;/span&gt;를 다음과 같이 정의할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Covariate shift : \(P(X)\)가 바뀌는데도 \(P(Y|X)\)가 그대로인 것
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;즉 input distribution이 바뀌는데도 ML 모델이 그대로인 경우&lt;/li&gt;
&lt;li&gt;독립변수들의 covariate(공변량)의 분포가 변하는 현상이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Label shift (Prior shift) : \(P(Y)\)가 바뀌는데도 \(P(X|Y)\)는 그대로인 것
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;output distribution이 바뀌었는데도 주어진 output을 구할 때의 input distribution이 그대로인 경우&lt;/li&gt;
&lt;li&gt;Covariate shift의 반대 상황으로, 서로 관련이 많음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Concept drift (Posterior shift) : \(P(Y|X)\)가 바뀌는데도 \(P(X)\)는 그대로인 것
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ML 모델이 바뀌는데도 input distribution이 그대로인 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;자세한 내용은 &lt;a href=&quot;https://huyenchip.com/2022/02/07/data-distribution-shifts-and-monitoring.html#data-shifts&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크(영문)&lt;/a&gt;를 참조하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;복잡하게 얘기했는데, 단순히 요약하자면 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;data distribution shift&lt;/span&gt;란 &lt;span style=&quot;color: #ee2323;&quot;&gt;dataset의 distribution이 바뀌어 out-of-distribution error가 생기는 현상&lt;/span&gt;을 말한다. 여기서 out-of-distribution 데이터란 학습 데이터의 분포와 다른 분포를 갖는 데이터를 의미한다. 예를 들어, CIFAR-10 데이터(in-distribution)로 학습한 모델의 입장에서 SVHN 데이터는 out-of-distribution이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-12-26 at 00.52.42.jpg&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0G0M2/btrUvWXy6zw/nkbbTleFiJlW6eBilyDT5k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0G0M2/btrUvWXy6zw/nkbbTleFiJlW6eBilyDT5k/img.jpg&quot; data-alt=&quot;Fig 12. OOD Error of Linear Probing and Fine-tuning&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0G0M2/btrUvWXy6zw/nkbbTleFiJlW6eBilyDT5k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0G0M2%2FbtrUvWXy6zw%2FnkbbTleFiJlW6eBilyDT5k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;395&quot; height=&quot;536&quot; data-filename=&quot;CleanShot 2022-12-26 at 00.52.42.jpg&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;640&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 12. OOD Error of Linear Probing and Fine-tuning&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Fine-tuning은 distribution shift에 취약하다. Fig 12와 같이 Linear probing은 weight을 정해두지만, fine-tuning은 weight을 update하므로 feature distortion이 생길 수 있기 때문이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;기존의 fine-tuning에서는 random하게 head를 initialize하는데, 위와 같은 문제점을 해결하기 위해 &lt;span style=&quot;color: #ee2323;&quot;&gt;linear probing의 head initialization을 사용하고, feature를 refine하는 데 fine-tuning을 진행&lt;/span&gt;한다. 이를 &lt;span style=&quot;color: #ee2323;&quot;&gt;LP-FT&lt;/span&gt;(Linear Probing then Fine Tuning)라 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;975&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcgQ17/btrUwpk2uPS/LSkKnpovkvmuck0dBivz01/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcgQ17/btrUwpk2uPS/LSkKnpovkvmuck0dBivz01/img.jpg&quot; data-alt=&quot;Fig 13. Improving Fine-tuning with LP-FT (출처 : Fine-Tuning, can Distroy Pretrained Features and Underperform Out-of-Distribution, Kumar et al., ICLR 2022)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcgQ17/btrUwpk2uPS/LSkKnpovkvmuck0dBivz01/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcgQ17%2FbtrUwpk2uPS%2FLSkKnpovkvmuck0dBivz01%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;771&quot; height=&quot;380&quot; data-origin-width=&quot;975&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 13. Improving Fine-tuning with LP-FT (출처 : Fine-Tuning, can Distroy Pretrained Features and Underperform Out-of-Distribution, Kumar et al., ICLR 2022)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Knowledges</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/212</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Self-Supervised-Learning#entry212comment</comments>
      <pubDate>Sun, 25 Dec 2022 20:34:33 +0900</pubDate>
    </item>
    <item>
      <title>딥러닝 기초 - RNN (2)</title>
      <link>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-RNN-2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자주 잊어버리는 딥러닝 기초 내용을 여러 포스팅에 걸쳐 간단하게 정리해보려 한다. 다룰 내용은 크게 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Elements of ML&lt;/li&gt;
&lt;li&gt;Multi-layer Perceptron&lt;/li&gt;
&lt;li&gt;Model Selection&lt;/li&gt;
&lt;li&gt;CNN&lt;/li&gt;
&lt;li&gt;GNN&lt;/li&gt;
&lt;li&gt;RNN&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-RNN-1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 글&lt;/a&gt;에 이어 RNN의 단점을 보완한 LSTM과 GRU에 대해 알아볼 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 RNN의 feed-forward 수식과 single unit 그림은 다음과 같다. (activation function은 tanh 대신 다른 것을 사용할 수 있다.)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{h}_t = f_{w_h} (\mathbf{x}_t, \mathbf{h}_{t-1}) \)&lt;br /&gt;\( \mathbf{o}_t = g_{w_o} (\mathbf{h}_t) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;817&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vlmce/btrTxIlSVKg/8mkE2mkVfbDMTCYU3lsAuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vlmce/btrTxIlSVKg/8mkE2mkVfbDMTCYU3lsAuK/img.png&quot; data-alt=&quot;Fig 1. RNN&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vlmce/btrTxIlSVKg/8mkE2mkVfbDMTCYU3lsAuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvlmce%2FbtrTxIlSVKg%2F8mkE2mkVfbDMTCYU3lsAuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;429&quot; height=&quot;274&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;817&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. RNN&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 글에서도 언급했듯, RNN의 문제점은 Long-term dependency가 떨어진다는 것이다. 예를 들어, 문장을 입력으로 받는다고 했을 때, 문장이 길어지면 마지막 단어가 첫 단어의 영향을 거의 받지 않게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 해결한것이 LSTM이고, LSTM을 간소화한 것이 GRU이다. 각각을 자세히 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Long-Short Term Memory (LSTM)&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;LSTM에서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;여러가지 gate와 memory cell&lt;/span&gt;이라는 개념을 사용하여 연산이 이루어진다. 특히, memory cell을 사용하여 초기의 input 정보까지도 저장하여 끝까지 영향을 줄 수 있도록 하였다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;LSTM의 feed-forward 과정의 수식과 single unit을 살펴보자.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{H}_t = \mathbf{O}_t \odot \tanh (\mathbf{C}_t) \)&lt;br /&gt;\( \mathbf{C}_t = \mathbf{F}_t \odot \mathbf{C}_{t-1} + \mathbf{I}_t \odot \tilde{\mathbf{C}}_t \)&lt;br /&gt;\( \tilde{\mathbf{C}}_t = \tanh (\mathbf{X}_t \mathbf{W}_{xc} + \mathbf{H}_{t-1} \mathbf{W}_{hc} + \mathbf{b}_c) \)&lt;br /&gt;\( \mathbf{I}_t = \sigma (\mathbf{X}_t \mathbf{W}_{xi} + \mathbf{H}_{t-1} \mathbf{W}_{hi} + \mathbf{b}_i) \)&lt;br /&gt;\( \mathbf{F}_t = \sigma (\mathbf{X}_t \mathbf{W}_{xf} + \mathbf{H}_{t-1} \mathbf{W}_{hf} + \mathbf{b}_f) \)&lt;br /&gt;\( \mathbf{O}_t = \sigma (\mathbf{X}_t \mathbf{W}_{xo} + \mathbf{H}_{t-1} \mathbf{W}_{ho} + \mathbf{b}_o) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( \mathbf{I}_t, \mathbf{F}_t, \mathbf{O}_t \) : Input gate, Forget gate, Output gate&lt;/li&gt;
&lt;li&gt;\( \mathbf{C}_t, \tilde{\mathbf{C}}_t \) : Memory cell, Candidate memory cell&lt;/li&gt;
&lt;li&gt;\( \mathbf{H}_t \) : Hidden state&lt;/li&gt;
&lt;li&gt;\( \odot\) : Hadamard product (elment-wise 곱)&lt;/li&gt;
&lt;li&gt;\( \sigma \) : Activation function을 갖는 fully connected layer&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1003&quot; data-origin-height=&quot;608&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwqFcr/btrTzdeG6nZ/FiBzHbzxVT2ufqgfUytiO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwqFcr/btrTzdeG6nZ/FiBzHbzxVT2ufqgfUytiO0/img.png&quot; data-alt=&quot;Fig 2. LSTM&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwqFcr/btrTzdeG6nZ/FiBzHbzxVT2ufqgfUytiO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwqFcr%2FbtrTzdeG6nZ%2FFiBzHbzxVT2ufqgfUytiO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;577&quot; height=&quot;350&quot; data-origin-width=&quot;1003&quot; data-origin-height=&quot;608&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. LSTM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Memory cell state는 long-term dependency를 부여하는 핵심이며, 정보를 계속해서 흐르게 해준다. Input, forget gate에 영향을 받으며, output gate와 함께 hidden state를 결정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Input gate는 data를 언제, 얼마나 읽을지를 결정하고, forget gate는 어떤 정보를 버릴지 정하며, output gate는 어떤 정보를 hidden state로 넘길지 정한다. (Sigmoid activation function을 통해 0~1 사이의 값을 내보낸다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Gated Recurrent Units (GRU)&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;GRU는 LSTM의 long-term dependency 성능을 유지하면서 복잡한 구조를 좀 더 단순화한 모델이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;마찬가지로 수식과 그림을 통해 이해해보자.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{H}_t = \mathbf{Z}_t \odot \mathbf{H}_{t-1} + (1 - \mathbf{Z}_t) \odot \tilde{\mathbf{H}}_t \)&lt;br /&gt;\( \tilde{\mathbf{H}}_t = \tanh(\mathbf{X}_t \mathbf{W}_{xh} + (\mathbf{R}_t \odot \mathbf{H}_{t-1} ) \mathbf{W}_{hh} + \mathbf{b}_h ) \)&lt;br /&gt;\( \mathbf{R}_t = \sigma(\mathbf{X}_t \mathbf{W}_{xr} + \mathbf{H}_{t-1} \mathbf{W}_{hr} + \mathbf{b}_r ) \)&lt;br /&gt;\( \mathbf{Z}_t = \sigma (\mathbf{X}_t \mathbf{W}_{xz} + \mathbf{H}_{t-1} \mathbf{W}_{hz} + \mathbf{b}_z ) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( \mathbf{H}_t, \tilde{\mathbf{H}}_t \) : Hidden state, Candidate hidden state&lt;/li&gt;
&lt;li&gt;\( \mathbf{R}_t, \mathbf{Z}_t \) : Reset gate, update gate&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;849&quot; data-origin-height=&quot;555&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPODR8/btrTy3J3NVK/bIQ6ssE8JhZKrRNYjbesI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPODR8/btrTy3J3NVK/bIQ6ssE8JhZKrRNYjbesI0/img.png&quot; data-alt=&quot;Fig 3. GRU&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPODR8/btrTy3J3NVK/bIQ6ssE8JhZKrRNYjbesI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPODR8%2FbtrTy3J3NVK%2FbIQ6ssE8JhZKrRNYjbesI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;402&quot; height=&quot;263&quot; data-origin-width=&quot;849&quot; data-origin-height=&quot;555&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. GRU&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GRU에서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;cell state와 hidden state&lt;/span&gt;를 hidden state \(\mathbf{H}\)로 합쳤고, update gate \(\mathbf{Z}\)로 LSTM의 &lt;span style=&quot;color: #ee2323;&quot;&gt;forget gate와 input gate&lt;/span&gt; 개념을 합쳐 hidden state(cell state)에 어떤 정보를 얼마나 반영해줄지를 고려한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LSTM과 GRU 이외에도 hidden state의 앞, 뒤로, 즉 정보를 양방향으로 전달할 수 있는 bidirectional RNN도 존재한다. 이는 최근 GPT와 함께 아주 좋은 성능을 내고 있는 BERT 모델의 기초 개념이다. (단, bidirectional RNN을 무턱대고 사용하다간 오히려 나쁜 성능을 보일 수 있으며, 학습 속도가 매우 느리므로 유의해서 사용해야 한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Fundamentals/AI Fundamentals</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/211</guid>
      <comments>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-RNN-2#entry211comment</comments>
      <pubDate>Wed, 14 Dec 2022 03:23:58 +0900</pubDate>
    </item>
    <item>
      <title>딥러닝 기초 - RNN (1)</title>
      <link>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-RNN-1</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자주 잊어버리는 딥러닝 기초 내용을 여러 포스팅에 걸쳐 간단하게 정리해보려 한다. 다룰 내용은 크게 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Elements of ML&lt;/li&gt;
&lt;li&gt;Multi-layer Perceptron&lt;/li&gt;
&lt;li&gt;Model Selection&lt;/li&gt;
&lt;li&gt;CNN&lt;/li&gt;
&lt;li&gt;GNN&lt;/li&gt;
&lt;li&gt;RNN&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 RNN에 대해 간략히 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Recurrent Neural Network(RNN)는 sequential data를 다루는 데 특화된 딥러닝 네트워크이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Sequential Data&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Sequential data에는 다음과 같은 종류가 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Time-series data&lt;/li&gt;
&lt;li&gt;Text data&lt;/li&gt;
&lt;li&gt;Reinforcement learning/planning (control problem)&lt;/li&gt;
&lt;li&gt;Image frames in video&lt;/li&gt;
&lt;li&gt;Music, speech, dialogue ...&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흔하지는 않지만, image data 또한 pixel의 sequential data로 생각해볼 수 있다. Sequential model인 transformer가 최근 vision 분야에서도(뿐만 아니라 머신러닝 전반적으로) 많이 사용되고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Sequential data를 다루기 어려운 이유는 &lt;span style=&quot;color: #ee2323;&quot;&gt;길이가 일정하지 않기&lt;/span&gt; 때문이다. 입력의 길이가 일정하지 않아 weight, bias가 정해져야 하는 MLP를 사용할 수 없다. (parameter를 공유하는 CNN은 1d convolution 연산을 통해 사용 가능하다. 단, 마지막 layer에서 Fully Connected Layer를 사용할 수 없다는 문제점이 있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 sequential data는 non-i.i.d.이다. 즉, 순서가 매우 중요하여 &lt;span style=&quot;color: #ee2323;&quot;&gt;순서를 바꾸면 완전히 다른 data&lt;/span&gt;가 된다. (GNN은 permutation invariance 성질을 가지므로 사용이 불가능하다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Principles(Inductive Biases) in RNN&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;RNN은 sequentiality, temporal invariance라는 principle을 갖는다. (inductive bias이기도 하다.)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Sequentiality&lt;/span&gt;는 non-i.i.d. data를 다루기 위해 &lt;span style=&quot;color: #ee2323;&quot;&gt;순차적으로 입력을 다루어야 한다는 성질&lt;/span&gt;을 말한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어, 문장을 입력으로 주었을 때 문장의 단어(token)는 순차적으로 다룬다. (위에서도 언급했듯, 순서를 바꾸면 의미가 완전히 바뀐다.)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Temporal Invariance&lt;/span&gt;는 &lt;span style=&quot;color: #ee2323;&quot;&gt;sequence의 순서가 바뀌어도 결과는 바뀌지 않는다&lt;/span&gt;는 의미이다. 여기서 temporal(time) 개념은 sequence의 순서 개념으로, NLP에서 문장의 순서이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어, 현재 문장을 이해하는 데 과거의 문장의 의미는 영향이 없다. 따라서 문장의 순서를 바꾸는 건 결과에 영향을 주지 않는다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;282&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DUS2r/btrTlsvInv5/upFU4ESpmyI3YUkEaScaKk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DUS2r/btrTlsvInv5/upFU4ESpmyI3YUkEaScaKk/img.jpg&quot; data-alt=&quot;Fig 1. Spatial Invariance in CNN vs Temporal Invariance in RNN&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DUS2r/btrTlsvInv5/upFU4ESpmyI3YUkEaScaKk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDUS2r%2FbtrTlsvInv5%2FupFU4ESpmyI3YUkEaScaKk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;509&quot; height=&quot;257&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;282&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Spatial Invariance in CNN vs Temporal Invariance in RNN&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 1에서와 같이, CNN에서는 동일한 parameter를 공유하는 filter가 공간적으로 독립적으로 움직이면서 정보를 추출해내므로 spatial invariance 성질을 가졌는데, RNN에서는 시간적으로 t-1에서의 연산과 t에서의 연산이 동일한 parameter를 갖고 독립적으로 연산하므로 서로 영향을 주지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Recurrent Neural Network (RNN)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Sequential data를 다루기 위한 가장 간단한 모델로부터, RNN까지 알아보면서 RNN의 주요 개념을 알아보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;conditionally independent model&lt;/span&gt;은 각 &lt;span style=&quot;color: #ee2323;&quot;&gt;시간 마다 독립적으로 input에 대한 연산&lt;/span&gt;을 수행한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-12-11 at 21.26.47.jpg&quot; data-origin-width=&quot;319&quot; data-origin-height=&quot;275&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HTLJe/btrTmYulyvy/TWawQKTkIK3QAfs8bW5kTK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HTLJe/btrTmYulyvy/TWawQKTkIK3QAfs8bW5kTK/img.jpg&quot; data-alt=&quot;Fig 2. Conditionally Independent Model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HTLJe/btrTmYulyvy/TWawQKTkIK3QAfs8bW5kTK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHTLJe%2FbtrTmYulyvy%2FTWawQKTkIK3QAfs8bW5kTK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;319&quot; height=&quot;275&quot; data-filename=&quot;CleanShot 2022-12-11 at 21.26.47.jpg&quot; data-origin-width=&quot;319&quot; data-origin-height=&quot;275&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Conditionally Independent Model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{o}_t = f_{w_o} (\mathbf{x}_t) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 모델로는 sequentiality를 갖는 데이터를 다룰 수 없다. 순서 정보를 반영하지 못하기 때문이다. (달리 말하면, 순서가 바뀌어도 output이 똑같기 때문이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 이전 데이터의 정보를 반영하기 위해 autoregressive model을 고안했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Autoregressive model&lt;/span&gt;은 정해진 길이의 sequential data를 input으로 받아 &lt;span style=&quot;color: #ee2323;&quot;&gt;이전의 정보를 현재 연산에 반영&lt;/span&gt;해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;369&quot; data-origin-height=&quot;264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vq6BC/btrTigQltHw/bEmJUKtzVb5oTdqDZtzfQ1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vq6BC/btrTigQltHw/bEmJUKtzVb5oTdqDZtzfQ1/img.jpg&quot; data-alt=&quot;Fig 3. Autoregressive Model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vq6BC/btrTigQltHw/bEmJUKtzVb5oTdqDZtzfQ1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvq6BC%2FbtrTigQltHw%2FbEmJUKtzVb5oTdqDZtzfQ1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;369&quot; height=&quot;264&quot; data-origin-width=&quot;369&quot; data-origin-height=&quot;264&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Autoregressive Model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{o}_t = f_{w_o} (\mathbf{x}_t, \mathbf{x}_{t-1}, \dots, \mathbf{x}_{t-l} \)&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(l\) : data의 (고정된) 길이&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 text 등을 다루기 위해서는 long-term dependency(단어가 멀리 떨어져 있어도 정보를 반영할 수 있어야 함)를 반영해줄 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;hidden state를 활용하여&lt;/span&gt; 이전 data의 정보를 계속적으로 반영&lt;/span&gt;하는 latent autoregressive model을 고안했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Latent autoregressive model&lt;/span&gt;은 &lt;span style=&quot;color: #ee2323;&quot;&gt;hidden state를 활용하여 long-term dependency를 반영&lt;/span&gt;(다양한 길이의 sequence 다룸)하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-12-11 at 21.40.05.jpg&quot; data-origin-width=&quot;428&quot; data-origin-height=&quot;362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lZu2W/btrTg3xqX7L/UMDyFffVBq5mhneS3Dyvpk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lZu2W/btrTg3xqX7L/UMDyFffVBq5mhneS3Dyvpk/img.jpg&quot; data-alt=&quot;Fig 4. Latent Autoregressive Model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lZu2W/btrTg3xqX7L/UMDyFffVBq5mhneS3Dyvpk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlZu2W%2FbtrTg3xqX7L%2FUMDyFffVBq5mhneS3Dyvpk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;419&quot; height=&quot;354&quot; data-filename=&quot;CleanShot 2022-12-11 at 21.40.05.jpg&quot; data-origin-width=&quot;428&quot; data-origin-height=&quot;362&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. Latent Autoregressive Model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{h}_t = f_{w_h} (\mathbf{x}_t, \mathbf{h}_{t-1}) \)&lt;br /&gt;\( \mathbf{o}_t = g_{w_o} (\mathbf{h}_t) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\mathbf{h}\) : hidden state로, 이전 시간까지의 모든 input 정보를 갖고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;recurrent neural network(RNN)&lt;/span&gt;는 latent autoregressive model에 &lt;span style=&quot;color: #ee2323;&quot;&gt;learnable parameter를 추가&lt;/span&gt;한 모델이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{h}_t = \phi({W_{hx} \mathbf{x}_t + W_{hh} \mathbf{h}_{t-1} + b_h)&amp;nbsp; \)&lt;br /&gt;\( \mathbf{o}_t = W_{oh} \mathbf{h}_t + b_o \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때, layer 별로 \(W_{hx}, W_{hh}, W_{oh} \)는 &lt;span style=&quot;color: #ee2323;&quot;&gt;서로 다른 시간(step)에 따라 공유&lt;/span&gt;된다. (마치 CNN에서 서로 다른 pixel 위치에 따라 kernel paramter를 공유한 것과 같은 개념이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Backpropagation Through Time&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;RNN에서의 backpropagation 과정을 수식으로 알아보면서 RNN의 문제점을 알아보자. 간단히 표현하기 위해 latent autoregressive model 수식을 사용한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{h}_t = f_{w_h} (\mathbf{x}_t, \mathbf{h}_{t-1}) \)&lt;br /&gt;\( \mathbf{o}_t = g_{w_o} (\mathbf{h}_t) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;전체 loss function은 다음과 같이 나타낼 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathcal{L}(x, y, w_h, w_o) = \sum\limits_{t=1}^T l(y_t, o_t) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(x, y\) : 각각 input, 정답 sequence&lt;/li&gt;
&lt;li&gt;\(w_h, w_o\) : 각각 hidden state, output의 update에 사용되는 weight&lt;/li&gt;
&lt;li&gt;\(y_t, o_t\) : 각각 시간 t에서의 정답과 output&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(w_h\)에 대한 gradient를 구해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Chain rule에 의해,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \begin{align*} \cfrac{\partial \mathcal{L}(x, y, w_h, w_o)}{\partial w_h} &amp;amp;= \sum\limits_{t=1}^T \cfrac{\partial l(y_t, o_t)}{\partial w_h} \\ &amp;amp;= \sum\limits_{t=1}^T \cfrac{l(y_t, o_t)}{\partial o_t} \cfrac{\partial o_t}{\partial w_h} \\ &amp;amp;= \sum\limits_{t=1}^T \cfrac{\partial l(y_t, o_t)}{\partial o_t} \cfrac{\partial g(h_t, w_h)}{\partial w_h} \quad \because o_t = g(h_t), \; h_t = f_{w_h}(\cdots) \\ &amp;amp;= \sum\limits_{t=1}^T \cfrac{\partial l(y_t, o_t)}{\partial o_t} \cfrac{\partial g(h_t, w_h)}{\partial h_t} \cfrac{\partial h_t}{\partial w_h}&amp;nbsp;\end{align*} \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서, 함수의 입력으로 함수가 들어갈 때의 편미분 \( \cfrac{\mathrm{d} f(y(x), x)}{\mathrm{d} x} = \cfrac{\partial f}{\partial y} \cdot \cfrac{\partial y}{\partial x} + \cfrac{\partial f}{\partial x} \)에 의해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \cfrac{h_t}{w} = \cfrac{\partial f(x_t, h_{t-1}, w)}{\partial w} + \cfrac{\partial f(x_t, h_{t-1}, w)}{\partial h} \cfrac{h_{t-1}}{\partial w} \)인데, 식에서 \(\cfrac{\partial{h_{(t-\dots)}}}{\partial w}\) 부분이 반복된다. 따라서 이 식을 반복적으로 적용하면 최종 gradient는 다음과 같이 나타낼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \cfrac{\partial h_t}{\partial w_h} = \cfrac{\partial f(x_t, h_{t-1}, w_h)}{\partial w_h} + \sum\limits_{i=1}^{t-1} \left( \prod\limits_{j=i+1}^t \cfrac{\partial f(x_j, h_{j-1}, w_h)}{\partial h_{j-1}} \right) \cfrac{\partial f(x_i, h_{i-1}, w_h)}{\partial w_h} \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 주목할 부분은 \( \prod \left( \cdots \right) \)부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 backpropagation 과정을 모두 사용하는 경우를 full backpropagation through time이라 하는데, 만약 sequence가 길어지게 되면 \( \cfrac{\partial f(x_j, h_{j-1}, w_h)}{\partial h_{j-1}} \) term이 많이 곱해질 것이고, 이 term의 &lt;span style=&quot;color: #ee2323;&quot;&gt;norm(크기)이 1보다 작을 경우 gradient vanishing, 1보다 클 경우 gradient explode가 발생&lt;/span&gt;할 것이다. 따라서 학습이 매우 느리고 어렵다는 단점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 다음과 같은 방법으로 이 문제를 해결한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Truncated BPTT : Gradient cutting이라고도 하며, 특정 time step 이후로는 sum을 하지 않는다. 즉, 위 식에서 \(\sum\limits_{i=1}^{t-1}\)이 아닌 \(\sum\limits_{i=t-k}^{t-1}\)을 사용한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이로 인해 모델은 long-term보다는 short-term dependency의 영향을 더 많이 받게 된다.&lt;/li&gt;
&lt;li&gt;PyTorch에서는 'detach'로 구현한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Randomized BPTT&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는 gradient clipping을 사용하여 gradient explosion 현상을 막아줄 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \mathbf{g} \leftarrow \min \left( 1, \cfrac{\xi}{\lVert \mathbf{g} \rVert} \right) \mathbf{g} \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Fundamentals/AI Fundamentals</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/210</guid>
      <comments>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-RNN-1#entry210comment</comments>
      <pubDate>Sun, 11 Dec 2022 22:11:36 +0900</pubDate>
    </item>
    <item>
      <title>딥러닝 기초 - GNN</title>
      <link>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-RNN</link>
      <description>&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자주 잊어버리는 딥러닝 기초 내용을 여러 포스팅에 걸쳐 간단하게 정리해보려 한다. 다룰 내용은 크게 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Elements of ML&lt;/li&gt;
&lt;li&gt;Multi-layer Perceptron&lt;/li&gt;
&lt;li&gt;Model Selection&lt;/li&gt;
&lt;li&gt;CNN&lt;/li&gt;
&lt;li&gt;GNN&lt;/li&gt;
&lt;li&gt;RNN&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 강의에서는 보통 위 내용 중 GNN을 뺀 나머지 내용에 대해 다룬다. (적어도 내가 접했던 딥러닝 강의들은 그러했다.) 머신러닝 기초(regression, classification), MLP, CNN, RNN, Generative model 등..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, graph 데이터를 다루는 GNN 또한 기본적인 내용은 알아둘 필요가 있다. 그 이유를 GNN이 갖는 inductive bias와 관련하여 이 포스팅에서 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Graph Data&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;일반적인 '함수의 그래프'와 같이 데이터를 시각적으로 표현하는 것과 달리, Computer Science에서 graph는 데이터를 표현하는 하나의 구조이다. 기본적으로 이 구조는 \(\mathcal{G} = \{\mathcal{V}, \mathcal{E}\} \)로 표현하며, 이 식의 의미는 그래프는 '노드(node, vertex)와 노드 사이를 잇는 엣지(edge)로 이루어진다'라는 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Node&lt;/span&gt;는 보통 &lt;span style=&quot;color: #ee2323;&quot;&gt;entity, object, instance 등&lt;/span&gt;을 나타낸다. 예를 들어, 어떤 scene에서의 object, 논문들 간의 인용 관계를 나타낸 citation graph에서는 paper가 이에 해당한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Edge&lt;/span&gt;는 &lt;span style=&quot;color: #ee2323;&quot;&gt;두 node 간의 관계(relationship)&lt;/span&gt;를 나타낸다. 위와 같은 맥락으로, scene에서 object 간의 위치관계(object 1은 object 2의 오른쪽에 위치한다), 인용 관계(paper 1에서 paper 2를 인용하였다) 등을 나타낸다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Node, edge 이외에도 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;property&lt;/span&gt;가 존재하는데, 이는 &lt;span style=&quot;color: #ee2323;&quot;&gt;node에 대한 특성&lt;/span&gt;을 나타낸다. Scene에서 해당 object의 색상, texture 등을 예로 들 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Scene을 나타낼 때 image로 나타냈을 때와 graph로 나타냈을 때의 차이점을 살펴보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Image는 grid space, 즉 pixel을 통해 정해진 크기의 boundary 내에서 정보를 표현한다. 이에 반해 graph는 scene에 등장하는 object를 node로, node 간의 관계를 edge로 표현한다. 따라서 graph는 image에 비해 어떠한 '&lt;span style=&quot;color: #ee2323;&quot;&gt;관계 정보(relationship information)&lt;/span&gt;'를 표현하고, 다루기에 적합하다. (Image에서는 grid간의 관계는 표현할 수 있겠으나, object 간의 relationship을 표현하려면 segmentation 등의 추가적인 과정을 거쳐야 한다.)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;필자가 vision 분야에 관심이 많아서 이와 관련하여 graph data를 설명했는데, 사실 graph는 scene에 대한 정보보다는 social network, molecule structure 등에 더 많이 사용된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;703&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzexG6/btrTQxxj8FA/jxgu66xeQxcNguNHY4bFz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzexG6/btrTQxxj8FA/jxgu66xeQxcNguNHY4bFz1/img.png&quot; data-alt=&quot;Fig 1. Graph Data - Social Network&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzexG6/btrTQxxj8FA/jxgu66xeQxcNguNHY4bFz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzexG6%2FbtrTQxxj8FA%2Fjxgu66xeQxcNguNHY4bFz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;685&quot; height=&quot;470&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;703&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Graph Data - Social Network&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-12-17 at 02.53.41.jpg&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;321&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CYKbe/btrTQeSh1Yv/BEY1EVsIleZJkQ3KmQNpz0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CYKbe/btrTQeSh1Yv/BEY1EVsIleZJkQ3KmQNpz0/img.jpg&quot; data-alt=&quot;Fig 2. Graph Data - Molecules&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CYKbe/btrTQeSh1Yv/BEY1EVsIleZJkQ3KmQNpz0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCYKbe%2FbtrTQeSh1Yv%2FBEY1EVsIleZJkQ3KmQNpz0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;938&quot; height=&quot;321&quot; data-filename=&quot;CleanShot 2022-12-17 at 02.53.41.jpg&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;321&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Graph Data - Molecules&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Graph theory에서 그래프 구조를 나타낼 때 사용하는 표현은 다음과 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathcal{G} = ( \mathcal{V}, \mathcal{E}) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\mathcal{V}\) : node(vertice)들의 집합&lt;/li&gt;
&lt;li&gt;\(\mathcal{E}\) : edge(arc)들의 집합
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\((u,v) \in \mathcal{E}\) : node \(u\)와 node \(v\)를 잇는 edge
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;undirected : 방향성이 없는 경우 (symmetric relation)&lt;/li&gt;
&lt;li&gt;directed : 방향성이 있는 경우 (asymmetric relation)&lt;/li&gt;
&lt;li&gt;Weighted edge : connectivity에 강도가 존재하는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Graph Representation&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 graph data를 나타내기 위한 방법은 여러가지가 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 가장 단순한 방법으로 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;adjacency matrix&lt;/span&gt;가 있다. 이는 Fig 2와 같이 행렬을 사용하여, (undirected, non-weigted edge라 가정했을 때) \(i\)번째 node와 \(j\)번째 node가 연결되면 해당 요소 \(\mathbf{A}_{ij} = \mathbf{A}_{ji} = 1\), 아니면 \(0\)의 값을 갖는 행렬이다. 이는 수학적으로 그래프를 표현하기 위해 가장 일반적으로 많이 사용하는 방법이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하지만, adjacency matrix로 graph 구조를 나타낼 경우 비효율적이라는 단점이 있다.&amp;nbsp;Adjacency matrix는 매우 &lt;span style=&quot;color: #ee2323;&quot;&gt;sparse&lt;/span&gt;하다. 즉, 실제 데이터를 생각해보면 node끼리 연결되어있지 않은 경우가 대부분이므로, 몇 없는 연결관계를 나타내기 위해 object 개수 \(n\)에 대해 \(n^2\)만큼의 memory가 필요하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;따라서, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;adjacency list&lt;/span&gt;라는 방법으로 edge(node 간 연결성)을 표현해줄 수 있다. \([(u, v), (x, y), \dots]\)와 같이, 두 node 간의 edge를 tuple 형태로 표현해주는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 (구현 단계에서) DGL(Deep Graph Library)에서는 graph를 adjacency list로 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, node와 edge는 사용자가 지정한 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;feature&lt;/span&gt;를 가질 수 있다. 이는 node나 edge의 구체적인 특성을 수학적으로(벡터로) 나타낸 개념이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Tasks in Graph Structured Data&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Graph data를 활용한 task는 크게 다음과 같이 나눌 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Graph-level task
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예시 : graph에 ring 구조가 포함되어 있는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Node-level task
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예시 : 각 node의 label은 무엇인가?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Edge-level task
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예시 : 두 entity 간의 관계는 무엇인가?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Principles in Graph Data&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 graph data를 다루는 딥러닝 네트워크인 GNN은 permutation invariance라는 inductive bias를 갖고 있다. GNN의 inductive bias와 관련하여 graph data가 갖는 성질을 알아보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저, 기본적으로 graph data를 다루는 GNN은 entity 간의 &lt;span style=&quot;color: #ee2323;&quot;&gt;relationship 정보가 보존&lt;/span&gt;되어야 한다. 이전 글을 복기해보면, CNN에서는 locality를 가지는데, 이로 인해 pixel 각각에 대한 정보(pixel들 간의 정보)를 잃을 수 있었다. 하지만 graph에서는 주어진 &lt;span style=&quot;color: #ee2323;&quot;&gt;node간의 정보는 계속해서 유지&lt;/span&gt;된다는 특성을 갖는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로, Graph data는 permutation equivariance라는 성질을 갖는다. 여기서 permutation은 node(또는 node feature)의 순서가 바뀜을 의미하고, invariance는 순서가 바뀌어도 결과가 같음을, equivariance는 순서가 바뀌었을 때 결과도 같이 바뀜을 의미한다. 서로 다른 두 개념이 어떻게 graph data와 GNN에 존재하는지 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Permutation Invariance&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \phi(\pi \mathbf{x}) = \phi(\mathbf{x}) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 \(\pi\)는 permutation, 즉 순서가 바뀌는 것을 의미한다. (즉, node 순서가 바뀌어도 output은 그대로이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 graph \(\mathcal{g}_1\)과 &lt;span style=&quot;color: #ee2323;&quot;&gt;동일한 구조&lt;/span&gt;를 가졌지만 노드의 순서가 바뀐 \(\mathcal{g}_2 = \pi \mathcal{g}_1\)가 있을 때, GNN 결과 embedding은 같다. 이것이 바로 GNN이 갖는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;permutation invariance&lt;/span&gt; 성질이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Permutation Equivariance&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \phi(\pi \mathbf{x}) = \pi \phi(\mathbf{x}) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 식은 node 순서가 바뀌었을 때 output의 순서도 바뀜을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1270&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EhfJj/btrTR8QK2Ds/zSoYlnnOd3kTboeyU2cUak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EhfJj/btrTR8QK2Ds/zSoYlnnOd3kTboeyU2cUak/img.png&quot; data-alt=&quot;Fig 3. Permutation Equivariance&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EhfJj/btrTR8QK2Ds/zSoYlnnOd3kTboeyU2cUak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEhfJj%2FbtrTR8QK2Ds%2FzSoYlnnOd3kTboeyU2cUak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;673&quot; height=&quot;424&quot; data-origin-width=&quot;1270&quot; data-origin-height=&quot;800&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Permutation Equivariance&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림과 같이, graph data에서 node 순서가 바뀌었을 때 node feature의 순서도 (adjacency matrix가 바뀜과 함께) 바뀌게 된다. 이러한 성질을 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;permutation equivariance&lt;/span&gt;라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GNN 과정에서의 두 개념을 CNN에서와 비교해보며 이해해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1935&quot; data-origin-height=&quot;876&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dJmBaI/btrTSMUc60z/mEO9iVHdhIqEYKkGdeKEO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dJmBaI/btrTSMUc60z/mEO9iVHdhIqEYKkGdeKEO1/img.png&quot; data-alt=&quot;Fig 4. GNN Process&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dJmBaI/btrTSMUc60z/mEO9iVHdhIqEYKkGdeKEO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdJmBaI%2FbtrTSMUc60z%2FmEO9iVHdhIqEYKkGdeKEO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;725&quot; height=&quot;328&quot; data-origin-width=&quot;1935&quot; data-origin-height=&quot;876&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. GNN Process&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GNN은 permutation equivariant function과 permutation invariant function으로 이루어져 있다. Fig 4에서 GNN 과정을 나타내고 있는데, node A의 embedding을 얻는 게 GNN의 최종 목표라 가정하자. (마지막 회색 원을 node A의 embedding이라 생각해보자.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Permutation invariant function은 GNN의 최종 목표인 target node의 embedding을 뽑을 때와 관련된 개념이다. &lt;span style=&quot;color: #ee2323;&quot;&gt;node의 순서가 어떻게 바뀌던 간에 그 구조는 똑같으므로 같은 정보를 포함하게 될 것&lt;/span&gt;임을 의미한다. (예를 들어, Fig 4의 그림에서 node의 labeling이 Fig 3에서처럼 바뀐다고 해도 graph의 구조(node의 연결 관계)를 나타내는 정보는 변하지 않는다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;layer 간의 연산에서는 permutation equivariant function이 사용되는데, 이는 graph data의 성질과 관련된 것이다. node 순서가 바뀜에 따라, Fig 3에서처럼 그 결과 node embedding의 순서도 같이 바뀌는 것을 의미한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이를 이해하기 위해서는 message passing의 개념을 이해해야 한다. Message passing 개념과 GNN 관련 더 깊은 내용은 &lt;a href=&quot;https://jjuke-brain.tistory.com/category/Studies/ML%20with%20Graphs&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Machine Learning with ML 강의 내용을 정리한 카테고리&lt;/a&gt;를 참조하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Fundamentals/AI Fundamentals</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/209</guid>
      <comments>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-RNN#entry209comment</comments>
      <pubDate>Sun, 11 Dec 2022 20:46:29 +0900</pubDate>
    </item>
    <item>
      <title>딥러닝 기초 - CNN</title>
      <link>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-CNN</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자주 잊어버리는 딥러닝 기초 내용을 여러 포스팅에 걸쳐 간단하게 정리해보려 한다. 다룰 내용은 크게 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Elements of ML&lt;/li&gt;
&lt;li&gt;Multi-layer Perceptron&lt;/li&gt;
&lt;li&gt;Model Selection&lt;/li&gt;
&lt;li&gt;CNN&lt;/li&gt;
&lt;li&gt;GNN&lt;/li&gt;
&lt;li&gt;RNN&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNN은 이미지 데이터를 주로 다루는 딥러닝 네트워크로, 컴퓨터 비전 분야에서 많이 쓰인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNN의 개념을 간단히 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Image Data&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이전까지(MLP까지)는 data point \(\mathbf{x} \in \mathbb{R}^d\), 즉 단순히 d차원의 1d 텐서의 데이터를 다루었다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하지만, 이미지 데이터 \(\mathbf{x} \in \mathbb{R}^{H \times W \times C}\)는 보통 3차원 텐서 형태이다. (높이, 너비, 채널)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;높이와 너비 만큼의 픽셀을 갖고, 각 픽셀은 0~255의 값(혹은 이를 normalize하여 0부터 1 사이의 값)을 갖는 &lt;span style=&quot;color: #ee2323;&quot;&gt;grid 구조&lt;/span&gt;이다. 이것이 보통 Red, Green, Blue (RGB) 3개의 채널 형태로 쌓여있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;735&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bv2OFe/btrTKrqkKXm/EzKLgyiKKWypUvRc7KNTMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bv2OFe/btrTKrqkKXm/EzKLgyiKKWypUvRc7KNTMk/img.png&quot; data-alt=&quot;Fig 1. Image Data Structure&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bv2OFe/btrTKrqkKXm/EzKLgyiKKWypUvRc7KNTMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbv2OFe%2FbtrTKrqkKXm%2FEzKLgyiKKWypUvRc7KNTMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;396&quot; height=&quot;380&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;735&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Image Data Structure&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Computer Vision Tasks&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Computer Vision은 이러한 이미지를 처리하는 다양한 task를 해결하는 분야이다. 대표적으로 Semantic segmentation, classification(+ localization), object detection, instance segmentation 등이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;841&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GNSBY/btrTKrqkLZk/Scr2g21R0xMP0NKk23vZJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GNSBY/btrTKrqkLZk/Scr2g21R0xMP0NKk23vZJ1/img.png&quot; data-alt=&quot;Fig 2. Computer Vision Tasks&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GNSBY/btrTKrqkLZk/Scr2g21R0xMP0NKk23vZJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGNSBY%2FbtrTKrqkLZk%2FScr2g21R0xMP0NKk23vZJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;665&quot; height=&quot;437&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;841&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Computer Vision Tasks&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Semantic segmetation은 어떤 object인지는 상관 없이, 각 pixel이 어떤 카테고리에 속하는지를 나타내는 task이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Classification이란, 관심있는 하나의 object가 어떤 class에 속하는지를 구분하고, localization은 그 object의 위치까지 파악하는 task이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Object detection은 여러 object가 어떤 class에 속하는지를 (보통 위치와 함께) 구분하는 task이다. Instance segmentation은 object 중에서도 각 개체(instance)를 pixel별로 구분해주는 task이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Principles(Inductive Biases) in CNN&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;CNN에서는 두 가지 원리를 만족한다. 이를 CNN이 갖는 inductive bias라고도 하며, inductive bias에 대한 자세한 내용은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Inductive-Bias%EB%9E%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;를 참조하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저, inductive bias가 (거의) 없는 MLP로 이미지 데이터를 처리한다고 해보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-12-16 at 02.13.34.jpg&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/psCai/btrTKKJYF7s/wGvEQDSOCJWBczFRkekUsK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/psCai/btrTKKJYF7s/wGvEQDSOCJWBczFRkekUsK/img.jpg&quot; data-alt=&quot;Fig 3. MLP dealing with Image Data&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/psCai/btrTKKJYF7s/wGvEQDSOCJWBczFRkekUsK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpsCai%2FbtrTKKJYF7s%2FwGvEQDSOCJWBczFRkekUsK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;730&quot; height=&quot;269&quot; data-filename=&quot;CleanShot 2022-12-16 at 02.13.34.jpg&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. MLP dealing with Image Data&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;MLP는 모든 pixel에 대해 parameter가 따로 존재하여 곱 연산을 수행한다. 따라서 memory가 비효율적으로 많이 필요하고, optimization이 힘들며, overfitting할 가능성이 높아진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 반해, CNN이 이미지 데이터를 다루기에 최적화된 이유는 아래와 같은 inductive bias를 만족하기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Locality Principle&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;682&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boMIef/btrTKbHZ4jn/jtr0WxMO3YxxEGWj3KZlvK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boMIef/btrTKbHZ4jn/jtr0WxMO3YxxEGWj3KZlvK/img.jpg&quot; data-alt=&quot;Fig 4. Locality Principle of CNN&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boMIef/btrTKbHZ4jn/jtr0WxMO3YxxEGWj3KZlvK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboMIef%2FbtrTKbHZ4jn%2Fjtr0WxMO3YxxEGWj3KZlvK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;474&quot; height=&quot;414&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;682&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. Locality Principle of CNN&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;CNN에서 convolution 연산의 핵심인 kernel(=filter)의 사이즈는 이미지의 사이즈보다 훨씬 작다. 즉, &lt;span style=&quot;color: #ee2323;&quot;&gt;kernel size만큼 연산을 수행하므로, kernel size보다 멀리 떨어진 pixel간에는 서로 관련이 없어진다&lt;/span&gt;. 이를 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;locality&lt;/span&gt;라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Spatial (Translation) Invariance&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-12-16 at 02.20.27.jpg&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;370&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dk1lCA/btrTKJxv0Og/MnM9jGndFRY0mkQ7mjFhmk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dk1lCA/btrTKJxv0Og/MnM9jGndFRY0mkQ7mjFhmk/img.jpg&quot; data-alt=&quot;Fig 5. Spatial Translation Invariance of CNN&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dk1lCA/btrTKJxv0Og/MnM9jGndFRY0mkQ7mjFhmk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdk1lCA%2FbtrTKJxv0Og%2FMnM9jGndFRY0mkQ7mjFhmk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;684&quot; height=&quot;268&quot; data-filename=&quot;CleanShot 2022-12-16 at 02.20.27.jpg&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;370&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. Spatial Translation Invariance of CNN&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Object detection을 예로 들면, object가 어떻게 생겼는지는 object의 위치와는 관련이 없다. 즉, &lt;span style=&quot;color: #ee2323;&quot;&gt;object의 위치가 바뀌어도 object를 알아보는 데에는 전혀 지장이 없다&lt;/span&gt;. Fig 4에서의 강아지와 Fig 5에서의 강아지는 위치가 바뀌었는데, 사진에 강아지가 존재한다는 사실은 똑같다. 이를 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;spatial invariance&lt;/span&gt;라 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;kernel(=filter)을 통해 연산을 진행할 때, kernel을 옮겨가며 (같은 parameter를 공유하면서) 모든 pixel에 대해 연산을 진행하게 된다.&amp;nbsp; Fig 4에서는 \(h_i\) 부분의 patch에서 결과값이 높게 나왔다면, 이번에는 \(h_2\) 부분의 patch에서 결과값이 높게 나올 것이다. 따라서 CNN을 사용하면 강아지가 사진의 왼쪽 위에 있던, 가운데에 있떤, 오른쪽에 있던 상관없이 강아지를 인식할 수 있게 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Convolution Operation&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Convolution 연산이 진행되는 과정을 좀 더 알아보자. Convolution 연산(Pooling 포함)은 딥러닝 관점에서의 feature extraction(특징 추출)이다. convolution 연산을 여러 번 진행하면 이미지의 특징을 뽑은 map (feature map)을 얻게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;2D Convolution&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 간단하게 Channel이 1인 경우, 즉 2D convolution 연산을 이해해보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-12-16 at 02.25.10.jpg&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;345&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bj0i0l/btrTKLhOWvl/9SdKrvoCj3i7xpOBPtdhK0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bj0i0l/btrTKLhOWvl/9SdKrvoCj3i7xpOBPtdhK0/img.jpg&quot; data-alt=&quot;Fig 6. 2D Convolution&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bj0i0l/btrTKLhOWvl/9SdKrvoCj3i7xpOBPtdhK0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbj0i0l%2FbtrTKLhOWvl%2F9SdKrvoCj3i7xpOBPtdhK0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;329&quot; data-filename=&quot;CleanShot 2022-12-16 at 02.25.10.jpg&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;345&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 6. 2D Convolution&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( [f*g](i,j) = \sum\limits_{p,q} f(p,q) g(i + p, j + q) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(*\)는 convolution 연산기호이다. 간단히 설명해보면, filter가 pixel 크기에 맞춰 곱하고 그 결과를 모두 더한 값이 output이 되는 것이다. 위 그림을 예로 들면, '75' 부분의 pixel에 대해 연산을 진행하면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(0 \times -1 + 0 \times -2 + 75 \times -1 + \dots&amp;nbsp;+ 75 \times 2 + 80 \times 1 = 155\)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, output의 같은 부분에 155라는 값이 할당되는 것이다. 이 과정을 모든 pixel에 대해 반복한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서, filter(kernel)은 일반적으로 1보다 큰 사이즈(height * width)를 가지므로,&amp;nbsp; 연산을 진행할수록 결과 size가 점점 작아진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정확하게는 결과의 shape은 kernel size \((k_h, k_w)\)에 따라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( (h_{out}, w_{out}) = \left( h_{in} - k_h + 1, w_{in} - k_w + 1 \right) \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Padding&lt;/span&gt;은 이를 막아주는 역할을 한다. 만약 위 그림과 같이 \(3 \times 3\) filter를 사용할 때, padding size \(p=1\)로 둔다면, 이는 이미지 가장자리 부분에 0(보통 zero padding)을 추가하는 효과를 갖는다. 따라서 convolution 연산을 진행해도 output dimension이 줄어들지 않는다. (정보를 축약해주는 역할은 'pooling' 연산에서 따로 진행한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Striding&lt;/span&gt;을 통해 convolution 연산이 진행되는 step을 정해줄 수 있다. stride가 1이면 한 칸씩 kernel이 진행하고, 2면 두 칸씩 진행하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stride \(s\), padding \(p\)를 고려한 output shape은 다음 식으로 계산할 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( (h_{out}, w_{out}) = \left( \left \lfloor{\cfrac{h_{in} - k_h + 2 p_h}{s_h}} \right \rfloor + 1, \left \lfloor{\cfrac{w_in - k_w + 2 p_w}{s_w} } \right \rfloor + 1 \right) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 예시는 \((5 \times 5)\)이미지에 대해 \((3 \times 3)\) kernel과 \((1 \times 1)\) zero padding을 사용하고, stride \(2\)로 convolution operation을 적용한 예시이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;291&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZVx7S/btrTLFBlgQS/yFQrjUrjMkHZgpXon3yOX1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZVx7S/btrTLFBlgQS/yFQrjUrjMkHZgpXon3yOX1/img.jpg&quot; data-alt=&quot;Fig 7. Convolution Example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZVx7S/btrTLFBlgQS/yFQrjUrjMkHZgpXon3yOX1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZVx7S%2FbtrTLFBlgQS%2FyFQrjUrjMkHZgpXon3yOX1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;477&quot; height=&quot;248&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;291&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 7. Convolution Example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;3D Convolution&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;RGB 이미지는 red, green, blue의 3개 채널을 갖는다고 하였다. 따라서 위와 같은 2d convolution을 한 차원 확장하여 3개 채널에 대해 서는 3개로 확장된 kernel로 연산을 진행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-12-16 at 02.52.38.jpg&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;373&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lfqWJ/btrTMguyNIZ/x6N80bN6Xe1QH6KpltrJkk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lfqWJ/btrTMguyNIZ/x6N80bN6Xe1QH6KpltrJkk/img.jpg&quot; data-alt=&quot;Fig 8. 3D Convolution (Multiple Channels)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lfqWJ/btrTMguyNIZ/x6N80bN6Xe1QH6KpltrJkk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlfqWJ%2FbtrTMguyNIZ%2Fx6N80bN6Xe1QH6KpltrJkk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;661&quot; height=&quot;373&quot; data-filename=&quot;CleanShot 2022-12-16 at 02.52.38.jpg&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;373&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 8. 3D Convolution (Multiple Channels)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서, 만약 3D kernel을 여러개 사용하여 같은 input에 대해 여러 번 convolution 연산을 진행한다면, output의 shape도 3차원으로 만들 수 있다. 즉, input shape은 \((h_{in}, w_{in}, c_{in})\), output shape은 \((h_{out}, w_{out}, c_{out})\) 형태가 될 것이고, 이때 사용한 kernel은 \((k_h \times k_w)\) kernel \(c_{out}\)개를 사용한 결과일 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;492&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cLwmO2/btrTKrqldmh/Xnlm0tbi80qT7lb6HKgNu1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cLwmO2/btrTKrqldmh/Xnlm0tbi80qT7lb6HKgNu1/img.jpg&quot; data-alt=&quot;Fig 9. Convolution Operation (Weights &amp;amp;amp; Biases)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cLwmO2/btrTKrqldmh/Xnlm0tbi80qT7lb6HKgNu1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcLwmO2%2FbtrTKrqldmh%2FXnlm0tbi80qT7lb6HKgNu1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;562&quot; height=&quot;492&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;492&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 9. Convolution Operation (Weights &amp;amp; Biases)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데, 연산의 kernel에 사용한 모든 grid의 값들은 parameter이다. 특히, neural network 관점에서 \((k_h, k_w)\) size의 kernel은 weight가 되고, bias term(scalar 값)이 하나씩 (총 \(c_{out}\)개)추가된다. 즉, convolutional layer에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;parameter의 개수&lt;/span&gt;는 \( (k_h \times k_w \times c_{in} + 1) \times c_{out}\)개가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Pooling&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Convolution 후에는, pooling을 진행한다. Pooling의 역할은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Aggregate information : 정보를 합쳐(축약해)준다.&lt;/li&gt;
&lt;li&gt;Downsampling : Feature map의 resolution을 줄여준다.&lt;/li&gt;
&lt;li&gt;Parameter-free operator : 학습할 parameter는 없다. (Pooling 자체를 학습하지 않는다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대표적인 pooling 방법은 max pooling, average pooling이 있으며, 주로 max pooling을 많이 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Modern CNNs&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;CNN 기반의 다양한 네트워크가 등장했는데, LeNet, AlexNet, VGG, Inception, ResNet, DensNet 등이 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;모든 내용을 알아보기는 길어지니, 특정 모델에서 사용한 특별한 방법들에 대해 간단히 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;\(1\times1\) Convolution Layer&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\(1\times1\) Convolution layer는 2014년 ImageNet challenge에서 구글이 제안한 Inception이라는 모델에서 사용된 개념으로, 말 그대로&lt;span style=&quot;color: #ee2323;&quot;&gt; \(1\times 1\) kernel(당연히 kernel 개수는 input의 channel과 같음)을 사용한 convolution 연산&lt;/span&gt;을 진행하는 layer이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-12-16 at 03.15.38.jpg&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;182&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uDb2I/btrTLKvUz6z/it9tOZS5m9xZSP3WQAU4UK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uDb2I/btrTLKvUz6z/it9tOZS5m9xZSP3WQAU4UK/img.jpg&quot; data-alt=&quot;Fig 10. 1 by 1 Convolution Layer&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uDb2I/btrTLKvUz6z/it9tOZS5m9xZSP3WQAU4UK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuDb2I%2FbtrTLKvUz6z%2Fit9tOZS5m9xZSP3WQAU4UK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;525&quot; height=&quot;182&quot; data-filename=&quot;CleanShot 2022-12-16 at 03.15.38.jpg&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;182&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 10. 1 by 1 Convolution Layer&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 Output의 size는 input과 똑같이 그대로 보존되지만, channel 수, 즉 &lt;span style=&quot;color: #ee2323;&quot;&gt;dimension을 줄이기 위해&lt;/span&gt; 사용되었다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Skip Connection&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Skip connection은 Microsoft에서 제안한 ResNet에서 사용된 방법으로, CNN 뿐만 아니라 다양한 분야에서 유용하게 사용되는 방법이다. 무작정 layer를 쌓아 모델을 깊게 설계하면 오히려 overfitting되거나 optimization이 힘들어지는 문제가 생긴다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;324&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUc9B9/btrTIsp6eRP/CcIyXCbPd5iaHG4TeaWS10/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUc9B9/btrTIsp6eRP/CcIyXCbPd5iaHG4TeaWS10/img.jpg&quot; data-alt=&quot;Fig 11. Normal Conv (left) vs Conv with Skip Connection (right)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUc9B9/btrTIsp6eRP/CcIyXCbPd5iaHG4TeaWS10/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUc9B9%2FbtrTIsp6eRP%2FCcIyXCbPd5iaHG4TeaWS10%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;656&quot; height=&quot;324&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;324&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 11. Normal Conv (left) vs Conv with Skip Connection (right)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하지만, &lt;span style=&quot;color: #ee2323;&quot;&gt;input을 보존한 채로 layer의 결과와 더한 후에 activation funciton을 거쳐 최종 output을 낸다&lt;/span&gt;면 훨씬 깊은 layer를 쌓을 수 있게 되고, 따라서 모델의 성능을 안정적으로 끌어올릴 수 있게 된다. 이를 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;skip connection&lt;/span&gt;이라 한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( f(\mathbf{x}) = g(\mathbf{x}) + \mathbf{x} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Fundamentals/AI Fundamentals</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/208</guid>
      <comments>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-CNN#entry208comment</comments>
      <pubDate>Sun, 11 Dec 2022 20:46:03 +0900</pubDate>
    </item>
    <item>
      <title>딥러닝 기초 - Model Selection</title>
      <link>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Model-Selection</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자주 잊어버리는 딥러닝 기초 내용을 여러 포스팅에 걸쳐 간단하게 정리해보려 한다. 다룰 내용은 크게 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Elements of ML&lt;/li&gt;
&lt;li&gt;Multi-layer Perceptron&lt;/li&gt;
&lt;li&gt;Model Selection&lt;/li&gt;
&lt;li&gt;CNN&lt;/li&gt;
&lt;li&gt;GNN&lt;/li&gt;
&lt;li&gt;RNN&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Model Selection&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞선 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-2-Elements-of-ML&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;포스팅&lt;/a&gt;에서 머신러닝의 고질적인 문제중 하나로 overfitting, underfitting 문제와 data mismatch 문제를 언급했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Training error를 낮추기 위해 \( \underset{\mathbf{w}}{\min} \mathcal{L} (\mathcal{M}(\mathbf{w}), \mathcal{D}_{\text{train}}) \)로 optimization을 진행하고, training error와 test error 간의 차이를 줄이기 위해 \( \underset{\mathbf{w}}{\min} \mathcal{L} \left( \mathcal{M}(\mathbf{w}), \mathcal{D}_{\text{test}} \right)\) 또는 \(p_{\text{train}} \approx p_{\text{test}} \)와 같은 generalization 과정을 거친다고 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 overfitting을 피하면서 모델을 잘 학습시키는 방법과 좋은 모델을 고르기 위한 여러 방법들을 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Data Augmentation&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝의 효과를 보기 위해서는 엄청난 수의 데이터가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-12-11 at 02.21.58.jpg&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;551&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bg8pf0/btrThHUzLgu/Wa6pkfBqqpF9VgM4Chrcok/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bg8pf0/btrThHUzLgu/Wa6pkfBqqpF9VgM4Chrcok/img.jpg&quot; data-alt=&quot;Fig 1. Data Size and Model Performances&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bg8pf0/btrThHUzLgu/Wa6pkfBqqpF9VgM4Chrcok/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbg8pf0%2FbtrThHUzLgu%2FWa6pkfBqqpF9VgM4Chrcok%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;481&quot; height=&quot;338&quot; data-filename=&quot;CleanShot 2022-12-11 at 02.21.58.jpg&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;551&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Data Size and Model Performances&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 데이터가 조금 적다고 해도, 현재 갖고있는 &lt;span style=&quot;color: #ee2323;&quot;&gt;데이터에 transition, rotation, cropping, flipping 등을 적용하여 데이터 수를 늘리&lt;/span&gt;는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;data augmentation&lt;/span&gt;을 통해 해결할 수 있다. 실제로 data 부족 문제를 해결하기 위한 가장 좋은 방법이 이 방법이다. 딥러닝에도 잘 맞고, network의 hyperparameter를 튜닝하는 것보다 훨씬 간단하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 한 가지 주의할 점은 데이터에 대한 &lt;span style=&quot;color: #ee2323;&quot;&gt;domain knowledge가 필요&lt;/span&gt;하다. 예를 들어, 숫자 손글씨 데이터가 부족하다고 하여 무턱대고 rotation을 통해 데이터를 늘렸다가는 모델이 6과 9를 구분하지 못할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Weight Decay (L2 Regularization)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Weight decay&lt;/span&gt;는 overfitting을 줄일 수 있는 또다른 방법이다. 아래와 같이 loss function에 weight decay term(weight parameter의 L2 norm의 제곱)을 추가한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathcal{L}(\boldsymbol{\theta}, \mathcal{D}_{\text{train}}) + \lambda \lVert \boldsymbol{\theta} \rVert_2^2 \)&lt;br /&gt;\( \text{Gradient descenet} : \mathbf{w} \leftarrow \mathbf{w} - \eta \nabla_{\mathbf{w}} (\mathcal{L} + \lambda \lVert \mathbf{w} \rVert_2^2) = (1 - \eta \lambda)\mathbf{w} - \eta \nabla_{\mathbf{w}} \mathcal{L} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\lambda\) : Weight decay coefficient&lt;/li&gt;
&lt;li&gt;\(\lambda \lVert \boldsymbol{\theta} \rVert_2^2\) : Weight decay term&lt;/li&gt;
&lt;li&gt;\(\eta\) : learning rate&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수식에서 볼 수 있듯이, weight decay를 길게 적용할수록(coefficient가 커질수록) weight parameter의 영향이 작아진다(vanishing). Weight decay는 optimizer 선언 시에 argument로 간단하게 적용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Dropout&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Dropout&lt;/span&gt;은 &lt;span style=&quot;color: #ee2323;&quot;&gt;training 시에 hidden variable간의 연결의 일부를 끊음&lt;/span&gt;으로써 overfitting을 막는 방법이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;455&quot; data-origin-height=&quot;254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GPFy4/btrTg4vX68Q/PqkakThTYkU4oI8jCXR5f1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GPFy4/btrTg4vX68Q/PqkakThTYkU4oI8jCXR5f1/img.jpg&quot; data-alt=&quot;Fig 2. Dropout&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GPFy4/btrTg4vX68Q/PqkakThTYkU4oI8jCXR5f1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGPFy4%2FbtrTg4vX68Q%2FPqkakThTYkU4oI8jCXR5f1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;376&quot; height=&quot;210&quot; data-origin-width=&quot;455&quot; data-origin-height=&quot;254&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Dropout&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \tilde{w}_{ij}^{(l)} = \begin{cases} &amp;amp; 0 \quad \text{with probability } p \\ &amp;amp; w_{ij}^{(l)} \quad \text{with probability } 1-p \end{cases} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Prediction(Evaluation) 시에는 dropout을 적용하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점은 학습이 stochastic해지고, 수렴을 방해하여 학습 시간이 늘어날 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Early Stopping&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Early stopping&lt;/span&gt;이란, &lt;span style=&quot;color: #ee2323;&quot;&gt;training 과정에서 loss를 살펴보면서 모델이 overfitting되기 이전에 (최적의 상태일 때) 학습을 중단&lt;/span&gt;하는 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;학습 도중에는 test dataset을 사용하면 안되므로 &lt;span style=&quot;color: #ee2323;&quot;&gt;cross validation이 필요&lt;/span&gt;하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;간단하면서도 효과적이라는 장점이 있으나, 학습 과정에 대한 heuristic이 어느 정도 필요하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Label Smoothing&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Classification task에서는 overfitting과 관련된 &lt;span style=&quot;color: #ee2323;&quot;&gt;over-confidence problem&lt;/span&gt;이 존재한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Label Smoothing을 통해 이를 해결할 수 있는데, label smoothing이란 one-hot vector(해당하는 건 1, 나머지는 모두 0)로 라벨을 부여하기 보다 &lt;span style=&quot;color: #ee2323;&quot;&gt;smoothed label(0에서 1 사이의 값 중에 해당하는 class에 높은 값을 부여하고, 나머지 class는 낮은 값 부여, 즉 극단적이지 않게 smoothing)을 적용&lt;/span&gt;하는 방법이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \tilde{y} = (1 - \epsilon) y + \cfrac{\epsilon}{C} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\epsilon\) : hyperparameter for label smoothing&lt;/li&gt;
&lt;li&gt;\(y\) : one-hot vector&lt;/li&gt;
&lt;li&gt;\(C\) : number of classes&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법은 부족한 data에 대해 효과가 아주 좋고, 라벨링이 잘못된 데이터에 대해서도 강인하다는 장점을 갖지만, classification task에 한정적으로 적용할 수 있다는 단점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;K-fold Cross Validation&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이제까지 알아본 hyperparameter 이외에도 epoch(학습 총 반복) 횟수, learning rate(gradient를 따라 한 step에 얼마나 갈 것인가), mini-batch size(stochastic gradient descent에서), layer 개수, activation function, hidden variable의 차원 등 여러 hyperparameter가 존재한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 다양한 hyperparameter에 따라 모델의 성능이 달라지는데, 이중 최선의 모델을 선택하려면 어떻게 해야 할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전까지 연구자들은 test(evaluation) 성능에 따라 best model을 선정했다. 하지만 이는 robust하지 않다. 고정된 test set을 통해 모델의 성능을 검증하고 hyperparameter를 수정하게 되면 결국 test set에 overfitting되는 결과를 낳기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 해결하기 위한 것이 cross validation이다. &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Cross validation&lt;/span&gt;이란, &lt;span style=&quot;color: #ee2323;&quot;&gt;training 과정에서 training dataset을 training dataset + validation dataset으로 분리한 뒤, validation dataset을 사용하여 검증&lt;/span&gt;하는 방법이다. Evaluation은 test dataset으로 최종적으로 진행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 중에서도 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;k-fold cross validation&lt;/span&gt;은 &lt;span style=&quot;color: #ee2323;&quot;&gt;training data를 k개의 fold로 나누어 각 fold별로 한 번씩 validation에 사용하고, 나머지는 training에 사용하는 과정을 k번 반복&lt;/span&gt;하는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1020&quot; data-origin-height=&quot;626&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rxBsU/btrTihac6tx/5a7YUEkme64BGqTPPJYHrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rxBsU/btrTihac6tx/5a7YUEkme64BGqTPPJYHrK/img.png&quot; data-alt=&quot;Fig 3. K-fold Cross Validation&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rxBsU/btrTihac6tx/5a7YUEkme64BGqTPPJYHrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrxBsU%2FbtrTihac6tx%2F5a7YUEkme64BGqTPPJYHrK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;598&quot; height=&quot;367&quot; data-origin-width=&quot;1020&quot; data-origin-height=&quot;626&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. K-fold Cross Validation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과정을 좀 더 자세히 살펴보자.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;전체 데이터셋을 training dataset과 test dataset으로 나눈다.&lt;/li&gt;
&lt;li&gt;Training dataset을 k개 fold로 나눈다.&lt;/li&gt;
&lt;li&gt;k개 fold에 대해 다음을 반복한다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 fold를 validation dataset으로 사용하고, 나머지 fold들을 training dataset으로 사용한다.&lt;/li&gt;
&lt;li&gt;Training dataset으로 모델을 학습하고(training) validation dataset으로 평가한다(validation).&lt;/li&gt;
&lt;li&gt;Performance measure(accuracy 등)를 측정한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;k개의 performance measure의 평균을 학습 모델의 성능으로 둔다.&lt;/li&gt;
&lt;li&gt;Test dataset에 대해 평가를 진행한다(evaluation).&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;K-fold cross validation 이외에도 bootstrapping, deep ensemble 등의 방법으로 최선의 모델을 선택할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Other Methods for Stable Learning&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이외에도 overfitting을 막거나, 학습의 안정성과 효율을 높이는 다양한 방법이 있다. 간단하게 하나씩 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Batch Normalization&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;L2 regularization(weight decay)은 위에서 overfitting을 방지하기 위한 방법 중 하나라 하였다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Optimization 시 loss 값을 줄이면서 가중치도 최소화시키는 방향으로 학습을 하기 때문에, 튀는 가중치 값이 보정되어 정규화(regularize)된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이와 비슷하게, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;batch normalization&lt;/span&gt;은 &lt;span style=&quot;color: #ee2323;&quot;&gt;신경망의 깊이가 깊어졌을 때, hidden layer의 weight와 연산하는 과정에서 출력값이 들쑥날쑥해져 제대로된 학습이 이루어지지 않는 문제점을 해결&lt;/span&gt;해준다. Batch 뿐만 아니라 weight, layer normalization도 있다. 수식으로 나타내면 다음과 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \text{BN}(\mathbf{x}) = \gamma \odot \cfrac{\mathbf{x} - \hat{\boldsymbol{\mu}}_{\mathcal{B}}}{\hat{\boldsymbol{\sigma}}} + \boldsymbol{\beta} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\gamma\) : Scaling coefficient (backpropagation을 통해 학습 가능)&lt;/li&gt;
&lt;li&gt;\(\boldsymbol{\beta}\) : Offsets (Shift parameter, backpropagation을 통해 학습 가능)&lt;/li&gt;
&lt;li&gt;\(\hat{\boldsymbol{\mu}}_{\mathcal{B}}\) : Mini-batch의 sample mean&lt;/li&gt;
&lt;li&gt;\(\hat{\boldsymbol{\sigma}}_{\mathcal{B}}\) : Mini-batch의 sample variance&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떻게 batch normalization이 효과를 보는지는 정확하지 않다. (논문에서는 'covariate shift' 개념으로 설명하고 있는데, 정확하지 않고, 다른 설명도 정확히 증명된 것이 없다고 한다.)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Fundamentals/AI Fundamentals</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/207</guid>
      <comments>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Model-Selection#entry207comment</comments>
      <pubDate>Sun, 11 Dec 2022 02:50:06 +0900</pubDate>
    </item>
    <item>
      <title>Inductive Bias란?</title>
      <link>https://jjuke-brain.tistory.com/entry/Inductive-Bias%EB%9E%80</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝에 대해 깊이있게 배우고, 논문을 읽어보다 보니 종종 inductive bias라는 개념이 등장하는데, 확실한 이해를 위해 이 개념을 정리해두려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;말로만 간단히 설명하다보니 헷갈릴 수 있는데, CNN, RNN, GNN을 다룬 다음 포스팅에서 그림과 함께 이해해보면 의미를 정확히 파악할 수 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-CNN&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;CNN&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-RNN&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;GNN&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-RNN-1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;RNN&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Inductive Bias란?&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Inductive bias&lt;/span&gt;의 정의는 &lt;span style=&quot;color: #ee2323;&quot;&gt;학습 주체(컴퓨터)가 본 적 없는 input에 대해 output을 예측할 때 사용하는 가정&lt;/span&gt;을 말한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;머신러닝의 최종 목표는 generalization, 즉 학습 데이터로 학습시킨 모델이 본 적 없는 데이터에 대해서도 예측(prediction, approximation)을 잘 해내는 것이다. 본 적 없는 상황을 예측하기 위해서는 학습된 가정 이외에 추가적인 가정이 필요한데, 이것이 바로 inductive bias이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Inductive bias는 input과 output 간의 관계를 나타내는가에 따라 아래와 같이 크게 두 가지로 나뉜다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Relational Inductive Bias&lt;/li&gt;
&lt;li&gt;Non-relational Inductive Bias&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Inductive Bias in FCN, CNN, RNN, GNN&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Inductive Bias가 대표적인 딥러닝 네트워크에서 어떻게 활용되는지 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 네트워크의 inductive bias 특성에 따라 그 네트워크가 특정 task에, 특정 data를 다루는 데 왜 특화되어있는지를 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;876&quot; data-origin-height=&quot;170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckLvTT/btrTiWDW8UZ/kPz1Dkw0gqoTdmYEcCNgW1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckLvTT/btrTiWDW8UZ/kPz1Dkw0gqoTdmYEcCNgW1/img.jpg&quot; data-alt=&quot;Fig 1. Comparation of DL Networks&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckLvTT/btrTiWDW8UZ/kPz1Dkw0gqoTdmYEcCNgW1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckLvTT%2FbtrTiWDW8UZ%2FkPz1Dkw0gqoTdmYEcCNgW1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;876&quot; height=&quot;170&quot; data-origin-width=&quot;876&quot; data-origin-height=&quot;170&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Comparation of DL Networks&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, 가장 기본이 되는 네트워크인 Fully Connected Neural Network (FCN), 쉽게 말해 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;MLP&lt;/span&gt;에서는 보통 &lt;span style=&quot;color: #ee2323;&quot;&gt;inductive bias가 없다(매우 약하다)&lt;/span&gt;고 표현한다. 모든 입력 elements가 출력 elements와 연결되어 있어 영향을 주기 때문이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Inductive Bias in CNN&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이미지를 다루는 모델에서는 Convolutional Neural Network(CNN)을 많이 사용한다. CNN이 이미지 관련 task(Classification, Object Detection, Semantic Segmantation 등)에 강점을 보이는 이유는 &lt;span style=&quot;color: #ee2323;&quot;&gt;이미지 데이터의 특성과 관련 있는 inductive bias를 갖기 때문&lt;/span&gt;이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;CNN은 filter(kernel)가 입력 이미지의 일부(locality 개념)를 sliding하면서 연산을 진행한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 &lt;span style=&quot;color: #ee2323;&quot;&gt;locality 및 translation invariance&lt;/span&gt;라는 inductive bias를 갖는다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Locality : Image data의 경우, relation이 서로 가까운 값들 사이에 존재한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Filter(kernel)의 크기는 입력인 이미지의 크기보다 훨씬 작다. 즉, 특정 pixel에 대해 convolution 계산을 할 때, 작은 일부를 계산하게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Spatial(spatial translation) invariance : Input이 바뀌어도 관계가 유지된다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Object detection task를 예를 들어보자. Filter가 이미지 전체에 대해 sliding하면서 같은 parameter를 공유(parameter sharing)하므로, object가 이미지의 어떤 위치에 있던(어떻게&amp;nbsp; translate되던) 해당 위치에서 convolution 연산 결과 값이 커진다. 따라서 object의 위치를 정상적으로 인지할 수 있게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Inductive Bias in RNN&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Sequential data&lt;/span&gt;를 다루는 모델에서는 Recurrent Neural Network(RNN)을 많이 사용한다. CNN이 공간적인 개념의 indcutive bias를 갖는다면, RNN은 시간적인 개념과 관련된 &lt;span style=&quot;color: #ee2323;&quot;&gt;temporal invariance&lt;/span&gt;라는 inductive bias를 갖는다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Sequentiality : sequential data는 입력 token의 순서가 바뀌면 출력이 달라진다. (입력이 처리될 때의 특징)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;입력 token은 시간 순서대로(sequentially) 하나씩 처리된다. RNN은 non-i.i.d. data(token 각각이 독립적이지 않음, 즉 단어의 순서가 바뀌면 의미가 달라짐)를 다루는데, 입력 token의 순서를 고려하여 출력과 관련시켜야(relaiton) 할 것이다.&lt;/li&gt;
&lt;li&gt;간단한 예를 들면, 문장 내에서 단어의 순서가 바뀌면 당연히 말의 의미도 바뀐다.&lt;/li&gt;
&lt;li&gt;Bidirectional RNN의 경우 해당 bias는 줄어든다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Temporal(time translation) invariance : 입력이 들어오는 순서가 바뀌어도 RNN의 출력은 바뀌지 않는다. (입력 index의 특징)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;토큰을 hidden state로 처리하기 전까지는 이전 토큰에는 관여하지 않는다.&lt;/li&gt;
&lt;li&gt;예를 들어, i번째 입력되는 문장을 이해하는 데에는 이전 문장의 의미가 영향이 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Inductive Bias in GNN&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;GNN은 graph data를 다루는 딥러닝 네트워크이다. 상반된 개념으로 생각할 수도 있는데, graph data는 permutation equivariance 성질을, GNN은 permutation invariance라는 inductive bias를 갖는다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Permutation Equivariance
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Graph data에서 node의 순서가 바뀌면 결과 feature(다음 layer의 embedding)도 같은 순서로 바뀌게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Permutation Invariance
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GNN의 결과, node의 순서가 바뀌어도 graph 구조(node와 node 간의 관계를 나타내는 구조)는 동일하기 때문에 output은 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Knowledges</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/205</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Inductive-Bias%EB%9E%80#entry205comment</comments>
      <pubDate>Sun, 11 Dec 2022 01:40:28 +0900</pubDate>
    </item>
    <item>
      <title>딥러닝 기초 - Multi-layer Perceptron (MLP) (2)</title>
      <link>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Multi-layer-Perceptron-MLP-2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;자주 잊어버리는 딥러닝 기초 내용을 여러 포스팅에 걸쳐 간단하게 정리해보려 한다. 다룰 내용은 크게 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Elements of ML&lt;/li&gt;
&lt;li&gt;Multi-layer Perceptron&lt;/li&gt;
&lt;li&gt;Model Selection&lt;/li&gt;
&lt;li&gt;CNN&lt;/li&gt;
&lt;li&gt;GNN&lt;/li&gt;
&lt;li&gt;RNN&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Backpropagation and Gradient&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-3-Multi-Layer-Perceptron-MLP&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 글&lt;/a&gt;에 이어 Backpropagation과 Gradient에 대해 알아보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;딥러닝에서는 loss function을 통해 모델이 예측한 값과 실제 값 간의 차이를 구하고, 이를 줄이기 위해 &lt;span style=&quot;color: #ee2323;&quot;&gt;gradient descent&lt;/span&gt;라는 방법을 사용한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;220&quot; data-origin-height=&quot;241&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dlN4Lo/btrTixX6TWC/azi72ufdxK5BAk1X9gt1r1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dlN4Lo/btrTixX6TWC/azi72ufdxK5BAk1X9gt1r1/img.png&quot; data-alt=&quot;Fig 1. Loss Function Exaple&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dlN4Lo/btrTixX6TWC/azi72ufdxK5BAk1X9gt1r1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdlN4Lo%2FbtrTixX6TWC%2Fazi72ufdxK5BAk1X9gt1r1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;220&quot; height=&quot;241&quot; data-origin-width=&quot;220&quot; data-origin-height=&quot;241&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Loss Function Exaple&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Gradient descent란, Fig 1과 같이 loss function을 나타냈을 때, gradient(경사)를 따라 loss 가장 작은 곳(optimal point)을 찾아 가는 방법이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이를 위해서는 gradient를 계산해야 할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Backpropagation&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\(x, y, z\)에 대한 다음 함수의 gradient를 구한다고 해보자.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( f(x, y, z) = x \sqrt{\text{exp}\left(-\cfrac{\sin z}{y^2}\right)}&amp;nbsp; \)&lt;br /&gt;\( \nabla{f} = (\partial_x f, \partial_y f, \partial_z f) = ? \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접 계산하는 게 가장 좋겠지만, 계산이 느리다. 특히 MLP는 layer가 여러 개일 텐데, layer가 깊어질수록 계산 시간이 기하급수적으로 늘어날 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다고 작은 값 \(\epsilon\)에 대해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(\nabla{f} = \left( \frac{f(x+\epsilon, y, z) - f(x, y, z)}{\epsilon}, \frac{f(x, y+\epsilon, z) - f(x, y, z)}{\epsilon}, \frac{f(x, y, z+\epsilon) - f(x, y, z)}{\epsilon} \right) \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 difference method를 사용하면, layer를 거치면서 error가 너무 많이 쌓이게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, gradient 계산 시 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;backpropagation(역전파) 알고리즘&lt;/span&gt;을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(x=5, y=2, z=3\)이 주어졌을 때, \(f(x, y, z)\)의 값은 computation graph를 사용하여 다음과 같이 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2136&quot; data-origin-height=&quot;576&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DiJ7S/btrTgq7dXqU/Kkb3HJa1rqqOlKtyiCgV90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DiJ7S/btrTgq7dXqU/Kkb3HJa1rqqOlKtyiCgV90/img.png&quot; data-alt=&quot;Fig 2. Computation Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DiJ7S/btrTgq7dXqU/Kkb3HJa1rqqOlKtyiCgV90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDiJ7S%2FbtrTgq7dXqU%2FKkb3HJa1rqqOlKtyiCgV90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;808&quot; height=&quot;218&quot; data-origin-width=&quot;2136&quot; data-origin-height=&quot;576&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Computation Graph&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정은 forward propagation이라 한다. MLP에서 output을 구하는 과정과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 반대로 계산하면 &lt;span style=&quot;color: #ee2323;&quot;&gt;각각의 편미분 값을 구하여 최종적으로 gradient를 구할 수&lt;/span&gt; 있는데, 이를 backpropagation 과정이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, \(x\)에 대한 편미분 값을 구하는 과정을 보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2180&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/16T6T/btrTgImgyZL/3ScVyKlJgDI3xqy3vQvzO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/16T6T/btrTgImgyZL/3ScVyKlJgDI3xqy3vQvzO1/img.png&quot; data-alt=&quot;Fig 3. Backpropagation Process (1)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/16T6T/btrTgImgyZL/3ScVyKlJgDI3xqy3vQvzO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F16T6T%2FbtrTgImgyZL%2F3ScVyKlJgDI3xqy3vQvzO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2180&quot; height=&quot;593&quot; data-origin-width=&quot;2180&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Backpropagation Process (1)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(\cfrac{\partial(ab)}{\partial a} = b\)이므로, Fig 3의 computation graph를 통해 \(\cfrac{\partial f}{\partial x} = 1 \times 0.9825\)임을 쉽게 알 수 있다. (chain rule 때문에 1 * 0.9825인데, 자세한 내용은 y, z에 대해 구할 때 생각하자.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2199&quot; data-origin-height=&quot;574&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b01aDu/btrTgHAUgfn/AZ29cbENBe24ZnzXnED3s0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b01aDu/btrTgHAUgfn/AZ29cbENBe24ZnzXnED3s0/img.png&quot; data-alt=&quot;Fig 4. Backpropagation Process (2)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b01aDu/btrTgHAUgfn/AZ29cbENBe24ZnzXnED3s0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb01aDu%2FbtrTgHAUgfn%2FAZ29cbENBe24ZnzXnED3s0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;906&quot; height=&quot;236&quot; data-origin-width=&quot;2199&quot; data-origin-height=&quot;574&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. Backpropagation Process (2)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로, \(y\)와 \(z\)의 편미분 계산 과정을 보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공통적으로 \( \cfrac{\partial(\sqrt{a})}{\partial a} = \cfrac{1}{2\sqrt{a}} \)에서 0.5089, \(\cfrac{(\text{exp}(a))}{\partial a} = \text{exp}(a)\)에서 0.9653, \(\cfrac{\partial(-a)}{\partial a} = -1\)에서 -1로 계산된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, \(y\)방향에서 \(\cfrac{\partial(a/b)}{\partial b} = \cfrac{-a}{b^2}\)에서 -0.0088, \(\cfrac{\partial(a^2)}{\partial a} = 2a\)에서 4를 구할 수 있고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(z\)방향에서 \(\cfrac{\partial(a/b)}{\partial a} = \cfrac{1}{b}\)에서 0.25, \(\cfrac{\partial(\sin(a))}{\partial a} = \cos(a)\)에서 -0.9899를 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Computation graph를 사용하여 최종적으로 편미분 값을 구하기 위해서는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;chain rule&lt;/span&gt;을 사용해야 한다. Computation graph에서 중간에 계산된(거치는 경로) 값들을 각각 \(x_1, y_1, y_2, \dots, y_6, z_1, z_2, \dots, z_6\)이라 하면, 다음과 같이 위에서 구한 각 편미분 값들의 곱으로 나타낼 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \cfrac{\partial f}{\partial x} = \cfrac{\partial x_1}{\partial x} \cfrac{\partial f}{\partial x_1} \)&lt;br /&gt;\( \cfrac{\partial f}{\partial y} = \cfrac{\partial y_1}{\partial y} \cfrac{\partial y_2}{\partial y_1} \cdots \cfrac{\partial f}{\partial y_6} \)&lt;br /&gt;\( \cfrac{\partial f}{\partial z} = \cfrac{\partial z_1}{\partial z} \cfrac{\partial z_2}{\partial z_1} \cdots \cfrac{\partial f}{\partial z_6} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \therefore \cfrac{\partial f}{\partial x} = 1 \times 0.9825 = 0.9825, \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \cfrac{\partial f}{\partial y} = 1 \times 5 \times 0.5089 \times 0.9653 \times (-1) \times (-0.0088) \times 4 = 0.0865, \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \cfrac{\partial f}{\partial x} = 1 \times 5 \times 0.5098 \times 0.9653 \times (-1) \times 0.25 \times (-0.9899) = 0.6079 \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로, pytorch에서 'torchviz'라는 모듈을 통해 computation graph를 시각화해볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Instability of Gradients&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;딥러닝의 parameter update 과정에서 최종 gradient는 hidden variable(layer)들의 gradient의 곱이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( \mathbf{h}^{(k+1)} = f_k(\mathbf{h}^k) \overset{\text{multi-layer}}{\Rightarrow} y = f_L \circ \cdots \circ f_1(\mathbf{x}) \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( \partial_{\boldsymbol{\theta}} y = \partial_{\boldsymbol{\theta}} \mathbf{h}^l \prod\limits_{k=l+1}^L \partial_{\mathbf{h}^{k-1}} \mathbf{h}^k \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;따라서, 만약 activation function으로 sigmoid 함수를 사용한다면, 모든 gradient의 값이 0에서 1 사이이므로 &lt;span style=&quot;color: #ee2323;&quot;&gt;여러 번 곱하면서 최종 gradient가 0에 가까워지는 현상&lt;/span&gt;이 발생한다. 이를 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;gradient vanishing problem&lt;/span&gt;이라 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;반대로, &lt;span style=&quot;color: #ee2323;&quot;&gt;각 layer의 gradient 값들이 커지면서 최종 gradient 값이 발산&lt;/span&gt;해버리는 문제를 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;gradient explosion problem&lt;/span&gt;이라 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;보통 gradient explosion은 gradient clipping(gradient 값이 threshold 이상으로 올라가지 않도록 조절)으로 쉽게 해결이 가능하지만, gradient vanishing은 해결하기 힘들다. Gradient vanishing problem 해결을 위해서는 hidden layer에서는 &lt;span style=&quot;color: #ee2323;&quot;&gt;sigmoid 대신 ReLU&lt;/span&gt;를 활성 함수로 사용하거나, 적절한 &lt;span style=&quot;color: #ee2323;&quot;&gt;weight initialization&lt;/span&gt;을 해주거나, &lt;span style=&quot;color: #ee2323;&quot;&gt;batch normalization&lt;/span&gt;이나 l&lt;span style=&quot;color: #ee2323;&quot;&gt;ayer normalization&lt;/span&gt;을 적용해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;모델을 학습시킬 때 gradient vanishing 혹은 explosion이 발생하였는지를 확인하기 위해서는 matplotlib, tensorboard, wandb 등을 통해 학습 및 평가 과정을 그려보아야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1320&quot; data-origin-height=&quot;466&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oate6/btrTheebmgK/ChYhUGNoLhdgL49Fq30rBK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oate6/btrTheebmgK/ChYhUGNoLhdgL49Fq30rBK/img.jpg&quot; data-alt=&quot;Fig 5. Gradient Explosion Examples (matplotlib)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oate6/btrTheebmgK/ChYhUGNoLhdgL49Fq30rBK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Foate6%2FbtrTheebmgK%2FChYhUGNoLhdgL49Fq30rBK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;812&quot; height=&quot;287&quot; data-origin-width=&quot;1320&quot; data-origin-height=&quot;466&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. Gradient Explosion Examples (matplotlib)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;275&quot; data-origin-height=&quot;183&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVfMNO/btrTmvrOfIs/Fif9YcdmunUqFTEkDwJ4E1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVfMNO/btrTmvrOfIs/Fif9YcdmunUqFTEkDwJ4E1/img.jpg&quot; data-alt=&quot;Fig 6. Gradient Vanishing Example (Tensorboard)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVfMNO/btrTmvrOfIs/Fif9YcdmunUqFTEkDwJ4E1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVfMNO%2FbtrTmvrOfIs%2FFif9YcdmunUqFTEkDwJ4E1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;275&quot; height=&quot;183&quot; data-origin-width=&quot;275&quot; data-origin-height=&quot;183&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 6. Gradient Vanishing Example (Tensorboard)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Multi-Layer Perceptron (MLP)&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;MLP는 말 그대로 perceptron 여러 층으로 구성된 모델을 말한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \text{MLP}(\mathbf{x}; \boldsymbol{\theta}) := f(\mathbf{h}^{(L)} \circ \cdots \circ \mathbf{h}^{(1)}, \quad \text{where } l \in \{ 1, \dots, L \} \)&lt;br /&gt;\( \mathbf{h}^{(l)} := \varphi(\mathbf{w}^{(l)} \mathbf{h}^{(l-1)} + \mathbf{b}^{(l)}), \; \mathbf{h}^{(0)} = \mathbf{x} \in \mathbb{R}^d \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(l\) : layer index&lt;/li&gt;
&lt;li&gt;\(\boldsymbol{\theta} \) : parameters (\([ \mathbf{w}^{(l)}, \mathbf{b}^{(l)}]_{l=1}^L\))&lt;/li&gt;
&lt;li&gt;\(\mathbf{h}^{(l)}\) : \(l\)번째 layer의 hidden vector&lt;/li&gt;
&lt;li&gt;\(\varphi\) : activation function &amp;rarr; activation function에는 learnable parameter가 없음&lt;/li&gt;
&lt;li&gt;\(\mathbf{w}^{(l)}\) : weight parameter (matrix)&lt;/li&gt;
&lt;li&gt;\(\mathbf{b}^{(l)}\) : bias parameter (vector)&lt;/li&gt;
&lt;li&gt;\(\mathbf{x}\) : input vector&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MLP에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;parameter 개수&lt;/span&gt;는 다음과 같이 구할 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \lvert \boldsymbol{\theta} \rvert \approx \sum\limits_{l=1}^L \text{dim}(\mathbf{h}^{(l)}) \cdot [\text{dim}(\mathbf{h}^{(l-1)}) + 1] \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Properties of MLP&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;MLP는 다음과 같은 특성을 갖고 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구현이 간단하다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Inductive bias&lt;/span&gt;가 없다. (Inductive bias가 적당히 있어야 특정 task에 유용하다. Inductiva bias에 대한 설명은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Inductive-Bias%EB%9E%80&quot;&gt;다음 글&lt;/a&gt;을 참고하자.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Fully connected : layer가 너무 dense해서 차원의 저주(curse of dimension)에 취약하다.&lt;/li&gt;
&lt;li&gt;Computational cost가 너무 높다. (계산 시간 너무 오래 걸림, 메모리 부족)&lt;/li&gt;
&lt;li&gt;Overparameterization에 의해 overfitting되는 경향이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Universal Approximation Theorem (UAT)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Universal Approximation Theorem은 딥러닝의 꽃으로 불릴 만큼 중요한 이론이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Sigmoid activation function을 가지면서, 하나의 hidden layer를 갖는 feed-forward neural network는 적절한 weights만 주어진다면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;어떤 함수든 근사화 할 수 있다&lt;/span&gt;는 이론이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Width(뉴런 개수)에 따라 임의의 연속 함수를 근사할 수 있고, depth(layer 개수)에 따라 임의의 integrable function(적분 가능한 함수, 불연속이어도 상관 없음)을 근사할 수 있다. 단, integrable function이 \(f:\mathbb{R}^n \rightarrow \mathbb{R}^m\)일 때, 근사하려면 network의 width가 \(\max\{n+1, m\}\)보다 커야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Fundamentals/AI Fundamentals</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/204</guid>
      <comments>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Multi-layer-Perceptron-MLP-2#entry204comment</comments>
      <pubDate>Sat, 10 Dec 2022 20:44:55 +0900</pubDate>
    </item>
    <item>
      <title>딥러닝 기초 - Multi-Layer Perceptron (MLP) (1)</title>
      <link>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-3-Multi-Layer-Perceptron-MLP</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;자주 잊어버리는 딥러닝 기초 내용을 여러 포스팅에 걸쳐 간단하게 정리해보려 한다. 다룰 내용은 크게 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Elements of ML&lt;/li&gt;
&lt;li&gt;Multi-layer Perceptron&lt;/li&gt;
&lt;li&gt;Model Selection&lt;/li&gt;
&lt;li&gt;CNN&lt;/li&gt;
&lt;li&gt;GNN&lt;/li&gt;
&lt;li&gt;RNN&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Non-linear Models&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이전 포스팅에서 살펴본 모델들은 data를 예측하거나 분류할 때 linear function을 이용하였다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어, binary classification task가 주어졌다고 하자. binary classification이란 두 가지를 분류(예를 들어 사진이 강아지, 고양이 둘 중 무엇인가?)하는 task이다. 이 경우, classification 모델의 학습 과정은 &lt;span style=&quot;color: #ee2323;&quot;&gt;데이터의 두 class(강아지, 고양이)를 나누는 decision boundary(hyperplane)을 찾는 과정&lt;/span&gt;으로 볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;492&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rsQsB/btrThx5wuIP/meJmOGeSsGBFPVq3vpXvE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rsQsB/btrThx5wuIP/meJmOGeSsGBFPVq3vpXvE0/img.png&quot; data-alt=&quot;Fig 1. Example of Binary Classificaiton&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rsQsB/btrThx5wuIP/meJmOGeSsGBFPVq3vpXvE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrsQsB%2FbtrThx5wuIP%2FmeJmOGeSsGBFPVq3vpXvE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;212&quot; height=&quot;207&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;492&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Example of Binary Classificaiton&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 1은 hyperplane이 직선인 간단한 경우이다. Output을 one-hot vector로 표현하여 데이터의 차원이 고차원인 (예를 들어, 데이터 \(\mathbf{x}\)의 요소가 \(x_1, x_2, x_3\)인) 경우에도 위와 같이 나타낼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데, 만약 deision boundary가 nonlinear하다면 어떨까? 다음 그림을 보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;704&quot; data-origin-height=&quot;506&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDOEsD/btrThe6dvG1/JbVKryJj6zg3jDMaCTEei1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDOEsD/btrThe6dvG1/JbVKryJj6zg3jDMaCTEei1/img.png&quot; data-alt=&quot;Fig 2. Non-linear Decision Boundary&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDOEsD/btrThe6dvG1/JbVKryJj6zg3jDMaCTEei1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDOEsD%2FbtrThe6dvG1%2FJbVKryJj6zg3jDMaCTEei1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;304&quot; height=&quot;219&quot; data-origin-width=&quot;704&quot; data-origin-height=&quot;506&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. Non-linear Decision Boundary&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 경우, 위 데이터 feature를 맵핑하여 hyperplane 하나로 나뉠 수 있도록 데이터를 나타낸 공간을 변형(transform)해주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, &lt;span style=&quot;color: #ee2323;&quot;&gt;linear function은 이러한 맵핑을 할 수 없다&lt;/span&gt;. (linear transform은 affine transform이기 때문이다. 더 자세한 설명은 이 포스팅의 수준을 넘어서므로 궁금하다면 따로 검색해보도록 하자.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;From Linear to Nonlinear&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;370&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x5rPW/btrTk3a75f6/q16sNjwc1KVEzCDYBWtSP0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x5rPW/btrTk3a75f6/q16sNjwc1KVEzCDYBWtSP0/img.jpg&quot; data-alt=&quot;Fig 3. Manifold(Mapping)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x5rPW/btrTk3a75f6/q16sNjwc1KVEzCDYBWtSP0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fx5rPW%2FbtrTk3a75f6%2Fq16sNjwc1KVEzCDYBWtSP0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;342&quot; height=&quot;444&quot; data-origin-width=&quot;370&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Manifold(Mapping)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시의 데이터를 분류하는 함수를 찾기 위해서는 Fig 3와 같이 고차원 공간의 manifold를 찾아 맵핑해주어야 한다. 이러한 과정을 manifold learning이라 하고, 이를 위해 &lt;span style=&quot;color: #ee2323;&quot;&gt;multi-layer perceptron&lt;/span&gt;을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;XOR Problem and Non-linear Activation Function&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1164&quot; data-origin-height=&quot;392&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dkVjQD/btrTiVq4Ehh/mDoTKvjF28GwI8yPN63lIk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dkVjQD/btrTiVq4Ehh/mDoTKvjF28GwI8yPN63lIk/img.jpg&quot; data-alt=&quot;Fig 4. OR gate and XOR gate&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dkVjQD/btrTiVq4Ehh/mDoTKvjF28GwI8yPN63lIk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdkVjQD%2FbtrTiVq4Ehh%2FmDoTKvjF28GwI8yPN63lIk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;750&quot; height=&quot;253&quot; data-origin-width=&quot;1164&quot; data-origin-height=&quot;392&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. OR gate and XOR gate&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Pereptron은 linear function이다. 이러한 linear function을 여러 번 사용한다고 해도 절대 Fig 4에서와 같은 XOR 문제를 해결할 수는 없다. 다음 예시를 살펴보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;435&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqUeqD/btrTh58B5H7/HA0EjgKBD6mFJ6Usp0hHr0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqUeqD/btrTh58B5H7/HA0EjgKBD6mFJ6Usp0hHr0/img.jpg&quot; data-alt=&quot;Fig 5. MLP example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqUeqD/btrTh58B5H7/HA0EjgKBD6mFJ6Usp0hHr0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqUeqD%2FbtrTh58B5H7%2FHA0EjgKBD6mFJ6Usp0hHr0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;609&quot; height=&quot;321&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;435&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. MLP example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;각 layer에서 일어나는 연산을 수식으로 표현해보면 아래와 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( h_j = \sum\limits_{i} w_{ij}^{(1)} x_i = \mathbf{w}_j^{(1)} \mathbf{x} \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;\( o_k = \sum\limits_{j} w_{jk}^{(2)}\mathbf{h} \)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;두 함수를 합성해보아도 &lt;span style=&quot;color: #ee2323;&quot;&gt;결국 선형 함수이므로, 결국 non-linearity를 갖지 못한다&lt;/span&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, 아래와 같이&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;nonlinear activation function \(\varphi\)를 사용&lt;/span&gt;하여 &lt;span&gt;비선형성을 부여할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;\( h_j = \varphi \left( \sum\limits_{i} w_{ij}^{(1)} x_i \right) = \varphi ( \mathbf{w}_j^{(1)} \mathbf{x}) \)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;\( o_k = \sum\limits_{j} w_{jk}^{(2)} h_j = \mathbf{w}_k^{(2)} \mathbf{h} \)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Activation function에 자주 활용되는 함수는 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1673&quot; data-origin-height=&quot;536&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8eh3M/btrThOTwXMp/WsAZHvkYNoTtx84HeR1BzK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8eh3M/btrThOTwXMp/WsAZHvkYNoTtx84HeR1BzK/img.jpg&quot; data-alt=&quot;Fig 6. Activation Functions&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8eh3M/btrThOTwXMp/WsAZHvkYNoTtx84HeR1BzK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8eh3M%2FbtrThOTwXMp%2FWsAZHvkYNoTtx84HeR1BzK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1673&quot; height=&quot;536&quot; data-origin-width=&quot;1673&quot; data-origin-height=&quot;536&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 6. Activation Functions&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Activation function의 결과, ReLU는 0 이상의 값, Sigmoid는 0에서 1 사이의 값, Hyperbolic Tangent는 -1에서 1사이의 값을 가지므로, task와 상황에 따라 적절히 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Stochastic Gradient Descent Optimization&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Optimization 방법 중 하나인 Stochastic Gradient Descent (SGD) optimization에 대해 알아보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;SGD optimization은 weight(+bias)를 update하는 방법 중 하나로, 확률적으로 &lt;span style=&quot;color: #ee2323;&quot;&gt;mini-batch를 뽑아 gradient descent를 진행&lt;/span&gt;하는 방법이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( (\mathbf{w}, b) \leftarrow (\mathbf{w}, b) - \cfrac{\eta}{\lvert \mathcal{B} \rvert} \sum\limits_{i \in \mathcal{B}} \partial_{(\mathbf{w}, b)} l^{(i)}(\mathbf{w}, b) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\leftarrow\)의 의미 : iterative(반복적) update&lt;/li&gt;
&lt;li&gt;\(\eta\) : learning rate&lt;/li&gt;
&lt;li&gt;\( \mathcal{B} \) : mini-batch&lt;/li&gt;
&lt;li&gt;\(\partial_{(\mathbf{w}, b)} l^{(i)} (\mathbf{w}, b)\) (\(= \nabla_{\boldsymbol{\theta}} \mathcal{L}(\boldsymbol{\theta})\)) : gradient&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저, gradient descent란, loss function의 최솟값에 다다르기 위해 gradient(경사) 방향으로 반복적으로 하강하는 방법이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;모든 batch에 대해 gradient descent를 진행하는 batch gradient descent보다 mini-batch를 뽑는 경우 다음과 같은 이점이 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Memory의 resource&lt;/span&gt;를 아낄 수 있다.&lt;/li&gt;
&lt;li&gt;Non-convex optimization을 다룰 수 있다. 즉, &lt;span style=&quot;color: #ee2323;&quot;&gt;local optima에 빠지는 문제를 해결&lt;/span&gt;할 수 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Mini-batch를 샘플링할 때마다 매번 조금씩 다른 그래프가 생성되기 때문이다.&lt;/li&gt;
&lt;/ul&gt;
&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-12-11 at 03.19.32.jpg&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;469&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sjcB0/btrTihgZuZb/SPPk07J30mgClboBjUlM0k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sjcB0/btrTihgZuZb/SPPk07J30mgClboBjUlM0k/img.jpg&quot; data-alt=&quot;Fig 7. SGD Optimization Example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sjcB0/btrTihgZuZb/SPPk07J30mgClboBjUlM0k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsjcB0%2FbtrTihgZuZb%2FSPPk07J30mgClboBjUlM0k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;465&quot; height=&quot;330&quot; data-filename=&quot;CleanShot 2022-12-11 at 03.19.32.jpg&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;469&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 7. SGD Optimization Example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Fundamentals/AI Fundamentals</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/203</guid>
      <comments>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-3-Multi-Layer-Perceptron-MLP#entry203comment</comments>
      <pubDate>Sat, 10 Dec 2022 20:15:07 +0900</pubDate>
    </item>
    <item>
      <title>딥러닝 기초 - Elements of ML</title>
      <link>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-2-Elements-of-ML</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;자주 잊어버리는 딥러닝 기초 내용을 여러 포스팅에 걸쳐 간단하게 정리해보려 한다. 다룰 내용은 크게 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Elements of ML&lt;/li&gt;
&lt;li&gt;Multi-layer Perceptron&lt;/li&gt;
&lt;li&gt;Model Selection&lt;/li&gt;
&lt;li&gt;CNN&lt;/li&gt;
&lt;li&gt;GNN&lt;/li&gt;
&lt;li&gt;RNN&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 머신 러닝이 무엇이며, 주요 구성 요소는 어떤 것이 있는지 알아볼 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;What is ML?&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Mitchell이 1997년에 내린 머신러닝의 정의는 다음과 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;A computer program is said to learn from experience \(E\) with respect to some class of tasks \(T\) and performance measure \(P\), if its performance at tasks in \(T\), as measured by \(P\), improves with experience \(E\).&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이를 풀어써보면, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;머신러닝&lt;/span&gt;이란 task \(T\)와 성능 지표 \(P\)에 대해 경험 \(E\)를 함으로써 학습을 하는 컴퓨터 프로그램이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 task \(T\)에는 classification, regression, machine translation 등이 포함되고, performance measure \(P\)는 accuracy, error, perplexity, log-likelihood, 즉 흔히 알고 있는 loss function이 될 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Experience \(E\)는 supervised/unsupervised/self-supervised, reinforcement 등이며, 이에 따라 ML의 종류가 바뀌게 된다. (supervised learning 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Three Ingredients of ML Algorithms&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;머신러닝 알고리즘을 구현하기 위해 필요한 세 가지 중요한 요소가 있는데 Data(\(D\)), Model(\(M\)), Loss Function(\(L\))이다. 각각을 자세히 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Data \(\mathcal{D}\)&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Image, graph, text, video 등을 data라 하고, 각각에 따라 다음과 같은 특징이 서로 다르다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Dimension (차원)&lt;/li&gt;
&lt;li&gt;Data Structure (데이터의 구조)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 이미지는 픽셀 grid의 구조를 가지며, 보통 (Width, Height, Depth)의 차원을 갖는다. 이에 반해 그래프 데이터는 node, edge로 이루어진 구조를 가지며, adjacency matrix 등으로 표현한다. 이러한 데이터의 표현을 data representation이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Model \(\mathcal{M}\)&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;머신러닝 모델은 학습을 하는 주체이며, 함수들의 collection이다. Linear model, SVM, decision tree, neural neworks 등이 있으며, 아래와 같은 특징을 갖는다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Input/output&lt;/li&gt;
&lt;li&gt;Functions with different parameters&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델을 이루고 있는 함수의 parameter를 최적화(optimize)하는 것이 곧 학습이며, 머신 러닝의 목표이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Loss Fucntion \(\mathcal{L}\)&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;위에서도 언급했듯, loss function은 성능의 지표를 나타내기 위한 함수이다. 예를 들어 L1-loss, L2-loss, cross-entropy 등이 있으며, 다음과 같은 특징이 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Optimal point(최적점)들에서 최적의 성능을 달성해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝에서는 Gradient descent 알고리즘을 사용하여 최적점을 찾는데, 이때 gradient를 구하기 위해 loss function을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;ML Examples&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Regression&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시는 집의 면적, 지어진 연도에 따른 가격을 예측하는 regression task이다. 각 요소는 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(T\) : Regression&lt;/li&gt;
&lt;li&gt;\(P\) : Mean-squared error (MSE)&lt;/li&gt;
&lt;li&gt;\(E\) : Supervised learning&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1472&quot; data-origin-height=&quot;646&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/G33FD/btrThlc0weg/HdLMU5DCGa8ms510afCxB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/G33FD/btrThlc0weg/HdLMU5DCGa8ms510afCxB0/img.png&quot; data-alt=&quot;Fig 1. ML Example (1) - Regression&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/G33FD/btrThlc0weg/HdLMU5DCGa8ms510afCxB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FG33FD%2FbtrThlc0weg%2FHdLMU5DCGa8ms510afCxB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;632&quot; height=&quot;277&quot; data-origin-width=&quot;1472&quot; data-origin-height=&quot;646&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. ML Example (1) - Regression&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Data와 model은 Fig 1.에 표현되어 있고, loss는 아래와 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathcal{L} = \cfrac{1}{N} \sum\limits_{i=1}^N \lVert \mathbf{y}_i - \hat{\mathbf{y}}_i \rVert_2^2 = \cfrac{1}{N} \sum\limits_{i=1}^N \sum\limits_{d=1}^D \lvert y_i^{(d)} - \hat{y}_i^{(d)} \rvert^2 \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Image Classification&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;다음으로, 손글씨(숫자) 이미지를 분류하는 task를 예시로 알아보자. 마찬가지로 머신러닝의 요소로 표현해보면 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(T\) : classification&lt;/li&gt;
&lt;li&gt;\(P\) : accuracy&lt;/li&gt;
&lt;li&gt;\(E\) : Supervised learning&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1975&quot; data-origin-height=&quot;673&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHgVnM/btrTkgaCoeK/vaRnVih0fSA8ODj9opXfoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHgVnM/btrTkgaCoeK/vaRnVih0fSA8ODj9opXfoK/img.png&quot; data-alt=&quot;Fig 2. ML Example (2) - Image Classification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHgVnM/btrTkgaCoeK/vaRnVih0fSA8ODj9opXfoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHgVnM%2FbtrTkgaCoeK%2FvaRnVih0fSA8ODj9opXfoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;722&quot; height=&quot;246&quot; data-origin-width=&quot;1975&quot; data-origin-height=&quot;673&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 2. ML Example (2) - Image Classification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Fundamental Problem of ML&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;머신러닝에서는 다음과 같은 근본적인 문제점이 존재한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Generalization Performance&lt;/li&gt;
&lt;li&gt;Data Mismatch&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각이 무엇이고, 어떻게 해결할 수 있는지 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Generalization Performance&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저, overfitting과 underfitting에 대해 알아보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;머신러닝 모델은 학습을 위해 크게 두 가지 error를 줄어야 한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \text{optimization} : \underset{\mathbf{w}}{\min} \mathcal{L}\left( \mathcal{M}(\mathbf{w}) \mathcal{D}_{\text{train}} \right) \)&lt;br /&gt;\( \text{generalization} : \underset{\mathbf{w}}{\min} \mathcal{L} \left( \mathcal{M}(\mathbf{w}), \mathcal{D}_{\text{test}} \right) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Optimization은 &lt;span style=&quot;color: #ee2323;&quot;&gt;training 시의 error를 줄이는 개념&lt;/span&gt;이고, generalization은 본 적 없는(test) 데이터에 대해 모델을 적용해 보았을 때에도 잘 동작하는지, 즉, &lt;span style=&quot;color: #ee2323;&quot;&gt;training error와 test error의 차이가 작도록&lt;/span&gt; 하는 개념이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1222&quot; data-origin-height=&quot;416&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NANVe/btrTg3p7t7X/MgH5aqxnv96PYwvnDm2qU0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NANVe/btrTg3p7t7X/MgH5aqxnv96PYwvnDm2qU0/img.jpg&quot; data-alt=&quot;Fig 3. Underfitting vs Overfitting&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NANVe/btrTg3p7t7X/MgH5aqxnv96PYwvnDm2qU0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNANVe%2FbtrTg3p7t7X%2FMgH5aqxnv96PYwvnDm2qU0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;825&quot; height=&quot;281&quot; data-origin-width=&quot;1222&quot; data-origin-height=&quot;416&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 3. Underfitting vs Overfitting&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fig 3에서 왼쪽 그림은 학습이 덜 된 상황이다. Model의 capacity가 부족하여 training data에 대해 error가 크다. 이를 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;underfitting&lt;/span&gt;된 경우라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면, 오른쪽 그림은 training data에 학습을 너무 많이 해서, training data에는 잘 맞지만 test data(새로운 데이터)에 대해서는 일반화 성능이 좋지 않은 경우로, 이러한 경우 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;overfitting&lt;/span&gt;되었다고 표현한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종 목적은 당연히 모델이 새로운 데이터에 대해 예측을 잘 하는, 즉 generalization performance가 좋아지도록 하는 것이다. 이를 위해서는 적절하게 모델의 capacity(weight의 차원, 개수 등)를 설정해주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;446&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qGSIk/btrTgqMT16Y/WNu6qf7zpmApR1a0JGhOi0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qGSIk/btrTgqMT16Y/WNu6qf7zpmApR1a0JGhOi0/img.jpg&quot; data-alt=&quot;Fig 4. Generalization Performance&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qGSIk/btrTgqMT16Y/WNu6qf7zpmApR1a0JGhOi0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqGSIk%2FbtrTgqMT16Y%2FWNu6qf7zpmApR1a0JGhOi0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;632&quot; height=&quot;308&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;446&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 4. Generalization Performance&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해 &lt;span style=&quot;color: #ee2323;&quot;&gt;학습 과정에서 training data를 training용과 validation용으로 쪼개&lt;/span&gt;어, k-fold validation을 수행해준다. 주로 data의 개수가 부족한 경우에 사용하며, 총 k개의 fold로 나누고, 각 fold를 validation으로 k번 학습을 진행하여 성능을 측정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;624&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biaHe1/btrThekTnbN/Tx0j82Ne5FO7ocjmHtjMpK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biaHe1/btrThekTnbN/Tx0j82Ne5FO7ocjmHtjMpK/img.jpg&quot; data-alt=&quot;Fig 5. K-fold Validation&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biaHe1/btrThekTnbN/Tx0j82Ne5FO7ocjmHtjMpK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiaHe1%2FbtrThekTnbN%2FTx0j82Ne5FO7ocjmHtjMpK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;628&quot; height=&quot;399&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;624&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 5. K-fold Validation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 test data는 별개의 data로, 원래 목적대로 evaluation에만 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Data Mismatch&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;만약 근본적으로 training data와 test data의 분포가 맞지 않는 경우에는 model의 적절한 capacity를 찾는 것은 일반화 성능에 별로 도움이 되지 못한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;따라서, training error와 test error의 차이를 줄이기 위해서는 data generating 과정에서 두 데이터의 분포를 맞춰주는 과정이 필요하다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \text{optimization} : \underset{\mathbf{w}}{\min} \mathcal{L}\left( \mathcal{M}(\mathbf{w}) \mathcal{D}_{\text{train}} \right) \)&lt;br /&gt;\( \text{generalization} : \underset{\mathbf{w}}{\min} \mathcal{L} \left( \mathcal{M}(\mathbf{w}), \mathcal{D}_{\text{test}} \right) \)&lt;br /&gt;\( \text{generalization} : p_{train} \approx p_{test} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 모델이 강아지를 학습하도록 하기 위해 학습 데이터를 준비했는데, 배경이 모두 잔디밭이라면, 배경이 물이고, 헤엄치고 있는 강아지는 강아지로 구분하지 않을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Fundamentals/AI Fundamentals</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/202</guid>
      <comments>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-2-Elements-of-ML#entry202comment</comments>
      <pubDate>Sat, 10 Dec 2022 19:46:57 +0900</pubDate>
    </item>
    <item>
      <title>딥러닝 기초 - Introduction</title>
      <link>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-1-Introduction</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;자주 잊어버리는 딥러닝 기초 내용을 여러 포스팅에 걸쳐 간단하게 정리해보려 한다. 다룰 내용은 크게 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Introduction (딥러닝이란?)&lt;/li&gt;
&lt;li&gt;Elements of ML&lt;/li&gt;
&lt;li&gt;Multi-layer Perceptron&lt;/li&gt;
&lt;li&gt;Model Selection&lt;/li&gt;
&lt;li&gt;CNN&lt;/li&gt;
&lt;li&gt;GNN&lt;/li&gt;
&lt;li&gt;RNN&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;What is Deep Learning?&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;딥러닝(Deep Learning, DL)은 머신 러닝(Machine Learning, ML)의 일종이고, 머신러닝은 인공지능(AI)에 포함된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;세 가지 개념을 간단히 표현해보면 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Artificial Intelligence : 사람의 지능이나 행동 패턴을 모방하도록 하는 것을 말한다.&lt;/li&gt;
&lt;li&gt;Machine Learning : 컴퓨터가 데이터로부터 학습할 수 있도록 하는 technique이다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이때, 컴퓨터는 복잡한 rule 없이 학습한다.&lt;/li&gt;
&lt;li&gt;데이터셋으로부터 모델을 학습시키는 방법이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Deep Learning : 인간의 뇌(특히 뉴런)를 모방한 network로 머신 러닝을 수행하는 technique이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사람들은 AlphaGo, ImageNet Challenge 등을 통해 특정 분야에서 딥러닝 모델이 사람보다 뛰어난 성능을 보이면서부터 주목을 받기 시작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재에는 사람의 고유한 능력으로, 컴퓨터가 절대 할 수 없었던 것처럼 여겨졌던 상상을 하고, 그것을 그려내는 모델 등이 나오면서 주목을 받고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뿐만 아니라, 의학(medical AI), 자율주행(autonomous driving), 단백질 구조 예측(protein prediction) 등 많은 분야에서 딥러닝 모델을 기반으로 연구가 이루어지고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Preview&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;'딥러닝 기초' 시리즈에서 알아볼 개념을 표로 간단히 나타내면 아래와 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;876&quot; data-origin-height=&quot;170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRfLGo/btrTlsok1h7/ykIxni8GdFKq1PyKvA2cOK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRfLGo/btrTlsok1h7/ykIxni8GdFKq1PyKvA2cOK/img.jpg&quot; data-alt=&quot;Fig 1. Preview&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRfLGo/btrTlsok1h7/ykIxni8GdFKq1PyKvA2cOK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRfLGo%2FbtrTlsok1h7%2FykIxni8GdFKq1PyKvA2cOK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;876&quot; height=&quot;170&quot; data-origin-width=&quot;876&quot; data-origin-height=&quot;170&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Fig 1. Preview&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'Fully connected'는 'MLP', 'Convolutional'은 'CNN', 'Recurrent'는 'RNN', 'Graph network'는 'GNN'에서 자세히 알아볼 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금은 'CNN은 image data, GNN은 graph data, RNN은 sequential data를 다룬다.' 정도만 기억해두자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Fundamentals/AI Fundamentals</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/201</guid>
      <comments>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-1-Introduction#entry201comment</comments>
      <pubDate>Sat, 10 Dec 2022 18:45:19 +0900</pubDate>
    </item>
    <item>
      <title>Recall, Precision, ROC, Top-k Recall(Recall at k) 개념 정리</title>
      <link>https://jjuke-brain.tistory.com/entry/Recall-Precision-ROC-Top-k-Recall</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;논문에서 classification 관련 evaluation을 진행할 때, top-k recall(recall at k, R@k) 등의 형태로 recall이라는 metric을 많이 사용한다. 항상 헷갈리는 precision, recall 및 이와 관련된 개념을 정리해보고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Evaluation Metrics for Classification&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Classification task를 평가할 때에는 보통 두 가지 경우로 나누어 평가한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Multi-class classification&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;multi-class classification&lt;/span&gt;의 경우에는 다음 식으로 간단히 accuracy를 계산할 수 있다. 하지만 data가 imbalance할 경우, accuracy가 높다고 무조건 좋은 것은 아니므로 주의해야 한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \cfrac{1 \left[ \text{argmax}(\hat{\mathbf{y}}^{(i)} = \mathbf{y}^{(i)} \right]}{N} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Binary Classification&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로, class가 두 개인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;binary classification&lt;/span&gt;의 경우에는 다음과 같은 metric이 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Classification threshold에 영향을 받는 metrics (prediction 값 결과의 범위가 \([0, 1]\)인 경우, 0.5를 threshold로 사용한다.)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Accuracy&lt;/li&gt;
&lt;li&gt;Precision/Recall&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Classification threshold에 영향을 받지 않는 metrics
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ROC AUC&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Binary Classification에 사용되는 metric들을 각각 자세히 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;(1) Accuracy, Precision(P), Recall(R), F1 Score&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Binary classification 결과 다음과 같은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;confusion matrix&lt;/span&gt;를 얻었다고 해보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;482&quot; data-origin-height=&quot;371&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNaTrk/btrS5N7i5ew/d5mWiUiKECgfmCZ0rDyWK0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNaTrk/btrS5N7i5ew/d5mWiUiKECgfmCZ0rDyWK0/img.jpg&quot; data-alt=&quot;Confusion matrix after binary classification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNaTrk/btrS5N7i5ew/d5mWiUiKECgfmCZ0rDyWK0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNaTrk%2FbtrS5N7i5ew%2Fd5mWiUiKECgfmCZ0rDyWK0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;445&quot; height=&quot;343&quot; data-origin-width=&quot;482&quot; data-origin-height=&quot;371&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Confusion matrix after binary classification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 accuracy, precision, recall, f1 score는 각각 다음과 같이 구한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Accuracy : 일반적인 정확도이다. 전체 데이터 중 맞게 분류한 data의 비율이다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( \cfrac{\text{TP} + \text{TN}}{\text{TP} + \text{TN} + \text{FP} + \text{FN}} = \cfrac{\text{TP} + \text{TN}}{\lvert \text{Dataset} \rvert} \)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Precision (P) :&lt;span&gt; &lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;모델이 positive로 예측한 것 중 진짜 positive인 data의 비율&lt;/span&gt;을 말한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( \cfrac{\text{TP}}{\text{TP} + \text{FP}} \)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Recall (R) :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;실제로 positive인 것 중 모델이 positive로 예측한 data의 비율&lt;/span&gt;을 말한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( \cfrac{\text{TP}}{\text{TP} + \text{FN}} \)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;F1 score :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Precision과 Recall의 조화 평균(작은 값의 영향이 더 큼)로 계산한 정확도&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;개념이다. (F-score @ 1)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( \cfrac{2 P R}{P + R} \)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;(2) ROC(Reciever Operating Characteristic) Curve, ROC AUC(Area Under the ROC Curve)&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;ROC curve&lt;/span&gt;는 binary classifier의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;classification threshold의 변화에 따른 TPR(Recall)과 FPR의 trade-off 관계&lt;/span&gt;를 파악하기 위한 curve이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;클래스 별로 분포가 다를 때(imbalance data일 때), accuracy의 단점을 해결한 분류 성능 지표이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1151&quot; data-origin-height=&quot;1000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0X6ob/btrSZ2ZV2EV/wQaMIwZSoCWgpSx8osXCJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0X6ob/btrSZ2ZV2EV/wQaMIwZSoCWgpSx8osXCJK/img.png&quot; data-alt=&quot;ROC Curve&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0X6ob/btrSZ2ZV2EV/wQaMIwZSoCWgpSx8osXCJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0X6ob%2FbtrSZ2ZV2EV%2FwQaMIwZSoCWgpSx8osXCJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;556&quot; height=&quot;483&quot; data-origin-width=&quot;1151&quot; data-origin-height=&quot;1000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ROC Curve&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;TPR (True Positive Rate, Recall) : 실제 positive data 중 positive로 예측한 data의 비율
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( \cfrac{\text{TP}}{\text{TP} + \text{FN}} \)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;FPR (False Positive Rate) : 실제 negative data 중 positive로 예측한 data의 비율
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( \cfrac{\text{FP}}{\text{FP} + \text{TN}} \)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;점선은 random classifier의 성능을 나타낸다. 즉 점선에서 멀수록 좋은 binary classifier이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;ROC AUC&lt;/span&gt;는 ROC curve 아래의 면적을 나타낸다. 이는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;random으로 positive 데이터와 negative 데이터를 하나씩 골랐을 때, classifier가 제대로 분류할 확률&lt;/span&gt;이다. 이상적인 경우 AUC = 1('ㄱ'자 형태의 그래프), 최악의 경우 AUC = 0.5(점선)이다. 완전히 랜덤으로 positive/negative를 분류할 때(최악일 때) 0.5, negative는 negative로, positive는 positive로 분류할 때 1의 값을 보일 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Top-k recall(Recall@k) &amp;amp; Top-k precision(Precision@k)&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Recall at k(Recall@k), &lt;span&gt;Precision at k(Precision@k)&lt;/span&gt;&amp;nbsp;개념은 추천시스템에서 많이 사용하는 evaluation metric이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;위에서 언급했듯, binary classification metric으로써의 recall과 precision의 정의는 다음과 같았다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Recall : 실제 positive 중 positive로 예측한 비율&lt;/li&gt;
&lt;li&gt;Precision : 실제 positive 중 진짜 positive의 비율&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Recall at k, Precision at k in Recommender Systems&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;'at k'라는 개념이 추가되었을 때, 추천시스템에서의 'recall at k'와 'precision at k'의 정의는 다음과 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \text{Recall@k} = \cfrac{\text{relevant recommended items}}{\text{all the possible relevant items}} \)&lt;br /&gt;\( \text{Precision@k} = \cfrac{\text{relevant recommended items}}{\text{total recommended items}} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;320&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brlYpY/btrS5A1tzaU/UQVy0jNt4ZmV73X3PfyNq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brlYpY/btrS5A1tzaU/UQVy0jNt4ZmV73X3PfyNq0/img.png&quot; data-alt=&quot;Precision at k and Recall at k Example (by https://blog.nerdfactory.ai/2021/09/23/recommend-system-classification-metric-1.html)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brlYpY/btrS5A1tzaU/UQVy0jNt4ZmV73X3PfyNq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrlYpY%2FbtrS5A1tzaU%2FUQVy0jNt4ZmV73X3PfyNq0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;320&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;320&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Precision at k and Recall at k Example (by https://blog.nerdfactory.ai/2021/09/23/recommend-system-classification-metric-1.html)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예시와 함께 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Top-k recall은 &lt;span style=&quot;color: #ee2323;&quot;&gt;모델이 k개 추천했을 때(k=5), 사용자가 관심있는(possible relevant) 모든 품목(A,B,C,H,I,J) 중 모델이 추천하기도 한(relevant recommended) 품목(A,B,C)의 비율&lt;/span&gt;이고, top-k precision은 &lt;span style=&quot;color: #ee2323;&quot;&gt;모델이 추천한(recommended) 품목 k개(5) 중 사용자가 관심도 있는(relevant recommended) 품목(A,B,C)의 비율&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 Recall at k (Recall@5)는 다음과 같이 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \text{Recall@5} = \cfrac{\text{relevant &amp;amp; recommended}}{\text{all possible relevant}} = \cfrac{3}{6} = 0.5 \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Precision at k(Precision@5)는 다음과 같이 구한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\( \text{Precision@5} = \cfrac{\text{relevant &amp;amp; recommended}}{\text{total recommended}} = \cfrac{3}{5} = 0.6 \)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Recall at k in Scene Graph (example)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Recall@k를 활용한 &lt;span&gt;Scene graph prediction network(SGPN)의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;evaluation 과정을 해석해보자. (&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-2021-ICCV-Graph-to-3D-End-to-End-Generation-and-Manipulation-of-3D-Scenes-Using-Scene-Graphs-3#Evaluation_Protocol&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;논문 분석 링크&lt;/a&gt;)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Scene graph는 \(\{Subject, Predicate, Object\}\) triplet으로 이루어지는데, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;ground-truth scene graph와 예측한 scene graph를 비교&lt;/span&gt;하기 위해 top-k recall을 사용한다. 그 결과의 예시는 다음과 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;957&quot; data-origin-height=&quot;294&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPw2Zz/btrS42K2Nqp/ZM2bSHkvDhi2IN53FaKU41/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPw2Zz/btrS42K2Nqp/ZM2bSHkvDhi2IN53FaKU41/img.jpg&quot; data-alt=&quot;Graph-to-3D model Shape Evaluation&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPw2Zz/btrS42K2Nqp/ZM2bSHkvDhi2IN53FaKU41/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPw2Zz%2FbtrS42K2Nqp%2FZM2bSHkvDhi2IN53FaKU41%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;957&quot; height=&quot;294&quot; data-origin-width=&quot;957&quot; data-origin-height=&quot;294&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Graph-to-3D model Shape Evaluation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;위 표의 'Recall Objects'열을 예로 들어보면, Top 1, Top 5, Top 10에 대한 여러 모델의 값들이 나열되어 있다. Top 10인 경우 Top-k recall의 개념을 적용하여 해석해보면, Top-k recall object란 모델이 k개(k=10)를 예측했을 때, GT scene graph의 &lt;span style=&quot;color: #ee2323;&quot;&gt;(실제) object 중 예측을 잘 한(맞춘) object의 비율&lt;/span&gt;로 해석해볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이는 predicate, triplet에도 마찬가지로 적용할 수 있으며, triplet은 (subject, predicate, object)가 모두 맞는 경우를 따지므로 전체적으로 값이 작아짐을 볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Knowledges</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/200</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Recall-Precision-ROC-Top-k-Recall#entry200comment</comments>
      <pubDate>Wed, 7 Dec 2022 14:55:16 +0900</pubDate>
    </item>
    <item>
      <title>Transformers in Vision (2) - ViT, Swin Transformer</title>
      <link>https://jjuke-brain.tistory.com/entry/Transformers-in-Vision-2-ViT-Swin-Transformer</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Transformer가 computer vision에서 어떻게 쓰였는지, 관련 모델이 어떻게 발전하고 있는지 여러 포스팅에 걸쳐서 알아보고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Computer vision domain에서 Transformer를 사용하는 대표적인 아키텍쳐는 Vision Transformer(ViT, &lt;a href=&quot;https://arxiv.org/abs/2010.11929&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale, Alexy et al., 2021&lt;/a&gt;)이고, 이를 보완한 것이 Swin Transformer(&lt;a href=&quot;https://openaccess.thecvf.com/content/ICCV2021/html/Liu_Swin_Transformer_Hierarchical_Vision_Transformer_Using_Shifted_Windows_ICCV_2021_paper.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Swin Transformer: Hierarchical Vision Transformer Using Shifted Windows, Liu et al., 2021&lt;/a&gt;)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Computer vision에서의 두 Transformer-based 모델을 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기초 내용인 Attention과 Transformer는 아래 글을 참조하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1669711877261&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Transformers in Vision - (1) Attention &amp;amp; Transformer&quot; data-og-description=&quot;Transformer가 computer vision에서 어떻게 쓰였는지, 관련 모델이 어떻게 발전하고 있는지 여러 포스팅에 걸쳐서 알아보고자 한다. 이번 포스팅에서는 가장 중요한 기초 내용인 attention과 transformer에 대&quot; data-og-host=&quot;jjuke-brain.tistory.com&quot; data-og-source-url=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; data-og-url=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cAHnQD/hyQJy5XQ6h/KTs5ONWiCA6nt7YCiPN4c0/img.jpg?width=800&amp;amp;height=269&amp;amp;face=0_0_800_269,https://scrap.kakaocdn.net/dn/cWJYrL/hyQJBBDmwy/y4LdCuVjBTKttvlnEj3kN1/img.jpg?width=800&amp;amp;height=269&amp;amp;face=0_0_800_269,https://scrap.kakaocdn.net/dn/Jv7nC/hyQJxMLRLC/64lqjTsBUDcGJLNwMKJnE0/img.jpg?width=627&amp;amp;height=932&amp;amp;face=0_0_627_932&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cAHnQD/hyQJy5XQ6h/KTs5ONWiCA6nt7YCiPN4c0/img.jpg?width=800&amp;amp;height=269&amp;amp;face=0_0_800_269,https://scrap.kakaocdn.net/dn/cWJYrL/hyQJBBDmwy/y4LdCuVjBTKttvlnEj3kN1/img.jpg?width=800&amp;amp;height=269&amp;amp;face=0_0_800_269,https://scrap.kakaocdn.net/dn/Jv7nC/hyQJxMLRLC/64lqjTsBUDcGJLNwMKJnE0/img.jpg?width=627&amp;amp;height=932&amp;amp;face=0_0_627_932');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Transformers in Vision - (1) Attention &amp;amp; Transformer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Transformer가 computer vision에서 어떻게 쓰였는지, 관련 모델이 어떻게 발전하고 있는지 여러 포스팅에 걸쳐서 알아보고자 한다. 이번 포스팅에서는 가장 중요한 기초 내용인 attention과 transformer에 대&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jjuke-brain.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;ViT (Vision Transformer)&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;2021년 ICLR 학회에서 발표된 'An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale' 논문에서 제안한 Vision Transformer는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;이미 NLP에서는 보편화된 transforemr 개념을 computer vision 분야에 적용하는 방법&lt;/span&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;당시 computer vision 분야에서는 여전히 CNN 기반 아키텍쳐가 여전히 주류를 이루었다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그런데 이 논문에서는 CNN없이 오직 transformer만 사용하는데, &lt;span style=&quot;color: #ee2323;&quot;&gt;image를 여러 patch로 나누어 각 patch를 NLP의 token(sequence)을 다루듯이 transformer를 적용&lt;/span&gt;한다. Image classification task에서 기존 방법들보다 훨씬 적은 computational cost로 (당시에) 최고 성능을 달성했다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;원리를 간단히 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-11-29 at 18.16.31.jpg&quot; data-origin-width=&quot;783&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TCQnn/btrSs0szQad/GKJ2eiGOHQbAYxvd6xZpYk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TCQnn/btrSs0szQad/GKJ2eiGOHQbAYxvd6xZpYk/img.jpg&quot; data-alt=&quot;Figure 1. ViT Model Overview&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TCQnn/btrSs0szQad/GKJ2eiGOHQbAYxvd6xZpYk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTCQnn%2FbtrSs0szQad%2FGKJ2eiGOHQbAYxvd6xZpYk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;783&quot; height=&quot;418&quot; data-filename=&quot;CleanShot 2022-11-29 at 18.16.31.jpg&quot; data-origin-width=&quot;783&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 1. ViT Model Overview&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Image를 정해진 크기의 patch로 나눈다.&lt;/li&gt;
&lt;li&gt;Linear하게 embedding한 후,&lt;/li&gt;
&lt;li&gt;Position embedding을 추가한다.&amp;nbsp;(Image classification task의 경우, 학습 가능한 classification token을 sequence에 추가해준다.)&lt;/li&gt;
&lt;li&gt;위 결과 sequence를 Transformer encoder에 입력해준다.&lt;/li&gt;
&lt;li&gt;(Image classification task를 수행하는 경우) MLP head를 거쳐 class를 예측하도록 한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Method&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;저자들은 최대한 원래의 Transformer와 가까운 방법으로 모델을 설계했다. Transformer의 '간단하면서 scalable한 setup, 효율적인 구현'이라는 장점을 최대한 활용하기 위해서이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Patch Embedding and Position Embedding&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-11-29 at 18.16.31.jpg&quot; data-origin-width=&quot;783&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNx03D/btrSsRJgJ60/BrV1lRiuTsg8aDxiCKTyBK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNx03D/btrSsRJgJ60/BrV1lRiuTsg8aDxiCKTyBK/img.jpg&quot; data-alt=&quot;Figure 2. Patch Embedding and Position Embedding&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNx03D/btrSsRJgJ60/BrV1lRiuTsg8aDxiCKTyBK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNx03D%2FbtrSsRJgJ60%2FBrV1lRiuTsg8aDxiCKTyBK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;783&quot; height=&quot;418&quot; data-filename=&quot;CleanShot 2022-11-29 at 18.16.31.jpg&quot; data-origin-width=&quot;783&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 2. Patch Embedding and Position Embedding&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Patch embedding&lt;/span&gt;에 대해 알아보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;NLP에서의 Transformer는 token embedding인 1D sequence를 입력으로 받는데, &lt;span style=&quot;color: #ee2323;&quot;&gt;이미지는 2D이므로 이를 reshape하여 2D patch의 sequence로&lt;/span&gt; 만든다. 또한 모든 layer에서 latent vector size가 일정하므로, &lt;span style=&quot;color: #ee2323;&quot;&gt;patch를 flatten한 후 일정 차원(/(D\))으로 맵핑&lt;/span&gt;시켰다. (이때의 linear projection은 학습 가능한 parameter이다.) 그 결과가 바로 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;patch embedding&lt;/span&gt;이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;BERT의 token에서처럼 patch embedding에 학습 가능한 embedding을 추가한다. 이에 따라 &lt;span style=&quot;color: #ee2323;&quot;&gt;Transformer encoder의 결과 벡터는 image representation의 역할&lt;/span&gt;을 할 수 있게 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Position embedding&lt;/span&gt;은 위치 정보를 보존하기 위해 patch embedding에 추가되는 임베딩이다. 굳이 2D position embedding을 사용해도 큰 성능 개선이 없어서 1D (learnable) position embedding을 사용한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 Patch embedding과 Position embedding이 결합한 형태의 embedding이 Transformer encoder의 입력으로 주어지게 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Pre-training과 fine-tuning 과정에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;classification head&lt;/span&gt;가 Transformer encoder의 결과 벡터에 attach되는데, 이떄 classification head는 pre-training의 경우에는 hidden layer가 하나인 MLP, fine-tuning의 경우에는 linear layer 하나인 MLP이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;전형적으로 ViT는 &lt;span style=&quot;color: #ee2323;&quot;&gt;큰 dataset에서 pre-train하여 작은 downstream task에 fine-tuning을 거쳐 적용&lt;/span&gt;한다. Fine-tuning을 통해 pre-training에서보다 큰 해상도의 이미지를 다룰 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;(같은 patch size에서) 이미지의 해상도가 클수록 sequence length가 커질텐데, ViT는 memory만 충분하다면 sequence length에 제한이 없다. 하지만, pre-training에서의 position embedding이 의미가 없어진다. 따라서 원래 이미지에서의 위치에 따라 pre-training했던 position embedding에 &lt;span style=&quot;color: #ee2323;&quot;&gt;2D interpolation을 적용&lt;/span&gt;한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Resolution adjustment와 patch extraction은 이미지의 2차원 구조와 관련된 유일한 inductive bias이므로 중요하다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Transformer Encoder&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-11-29 at 18.16.31.jpg&quot; data-origin-width=&quot;783&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c03zqg/btrSmZJkpk5/hEsk4k61f6mXKZbdO9ZkT0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c03zqg/btrSmZJkpk5/hEsk4k61f6mXKZbdO9ZkT0/img.jpg&quot; data-alt=&quot;Figure 3.&amp;amp;amp;nbsp; Transformer Encoder&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c03zqg/btrSmZJkpk5/hEsk4k61f6mXKZbdO9ZkT0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc03zqg%2FbtrSmZJkpk5%2FhEsk4k61f6mXKZbdO9ZkT0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;783&quot; height=&quot;418&quot; data-filename=&quot;CleanShot 2022-11-29 at 18.16.31.jpg&quot; data-origin-width=&quot;783&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 3.&amp;amp;nbsp; Transformer Encoder&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Transformer encoder는 &lt;span style=&quot;color: #ee2323;&quot;&gt;Multi-head Self-Attention(MSA)과 MLP block&lt;/span&gt;으로 구성된다. 또한 모든 block 앞에는 LayerNorm(LN)이 적용되고, 뒤에는 residual connection이 적용된다. (MLP는 두 layer와 GELU non-linearity로 이루어진다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Inductive Bias&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Vision Transformer는 image task에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;CNN보다 inductive bias가 훨씬 적다&lt;/span&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;CNN에서는 locality와 2차원적인 neighborhood structure, 그리고 translation equivariance가 모델 전체에 걸쳐서 각 layer에 부여된다. 하지만 ViT의 경우 &lt;span style=&quot;color: #ee2323;&quot;&gt;MLP layer에서만 locality와 translation equivariance&lt;span style=&quot;color: #333333;&quot;&gt;가 있&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;고&lt;/span&gt;, &lt;span style=&quot;color: #ee2323;&quot;&gt;self-attention layer에서는 globality&lt;/span&gt;를 갖는다. (2차원 neighborhood structure는 image를 patch로 splitting할 때와 fine-tuning에서 매우 조금만 존재한다.)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;게다가 position embedding 과정에서 patch의 2D 위치 정보를 전혀 반영하지 못하고, patch간의 모든 spatial relation은 처음부터(from scratch) 학습된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Hybrid Architecture&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Image patch를 단순히 나누어 사용하는 대신에 CNN의 feature map으로 input sequence를 만들어낼 수 있다. 이를 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;hybrid model&lt;/span&gt;이라 하는데, 여기서는 patch embedding 과정에서 patch를 CNN feature map에서 추출한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이외 과정은 위에서 설명한 것과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Results&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;146&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oQmfD/btrSqMClP0V/XhtdU3HJ6n4rKuBz2aqLr1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oQmfD/btrSqMClP0V/XhtdU3HJ6n4rKuBz2aqLr1/img.jpg&quot; data-alt=&quot;Table 1. Details of Vision Transformer Model Variants&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oQmfD/btrSqMClP0V/XhtdU3HJ6n4rKuBz2aqLr1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoQmfD%2FbtrSqMClP0V%2FXhtdU3HJ6n4rKuBz2aqLr1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;146&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;146&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Table 1. Details of Vision Transformer Model Variants&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Table 1과 같이 ViT도 BERT(NLP에서 좋은 성능을 나타내는 transformer 기반 모델)와 마찬가지로 configuration을 갖고 있다. 다양한 ViT를 나타내기 위해 다음과 같은 표기법을 사용한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ViT-L/16 : &quot;Large&quot; variant with \(16 \times 16\) input patch size&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Transformer의 sequence length는 patch size의 제곱에 반비례한다는 사실에 주목하자. 즉, &lt;span style=&quot;color: #ee2323;&quot;&gt;patch size가 작을수록 computational cost가 높아진다&lt;/span&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;278&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2aLhb/btrSq9xjonb/FAoubiCsGcXn9fTU1r9mo1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2aLhb/btrSq9xjonb/FAoubiCsGcXn9fTU1r9mo1/img.jpg&quot; data-alt=&quot;Table 2. Comparison to SoTA&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2aLhb/btrSq9xjonb/FAoubiCsGcXn9fTU1r9mo1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2aLhb%2FbtrSq9xjonb%2FFAoubiCsGcXn9fTU1r9mo1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;921&quot; height=&quot;278&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;278&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Table 2. Comparison to SoTA&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Table 2에서는 ResNet, EfficientNet과 ViT를 비교한 표이다. 값은 3번의 fine-tuning을 실행하여 정확도의 평균과 표준편차의 평균을 나타낸 값이다. 각 열에서의 JFT, I21k, BiT-L, Noisy Student는 각 모델에 대해 pre-training을 진행할 때 사용한 데이터셋이고, 이러한 모델들로 ImageNet, CIFAR, Oxford, VTAB 등의 데이터셋에 대해 classification을 진행했다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;모든 모델은 TPUv3 하드웨어로 학습했으며,  TPUv3-core-days는 '하루동안 학습에 사용된 core 수 * 학습 시간'을 나타낸다. 예를 들어, ImageNet-21k 데이터셋으로 pre-train한 ViT-L/16 모델은 TPUv3 8코어로 약 30일정도(곱하면 약 240) 학습했다고 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그리고, ViT는 inductive bias가 CNN에 비해 훨씬 약하다고 하였으므로, pre-training 시에 아주 큰 데이터셋을 사용해야 한다. 얼마나 큰 데이터셋을 사용해야 Vision Transformer가 ResNet보다 좋아지는지에 대한 실험 결과를 살펴보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;446&quot; data-origin-height=&quot;306&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmtqHY/btrStQ4BQso/cVfXxqHPj2OKDr2Xe44Wc1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmtqHY/btrStQ4BQso/cVfXxqHPj2OKDr2Xe44Wc1/img.jpg&quot; data-alt=&quot;Figure 4. Linear few-shot evaluation on ImageNet versus pre-training size&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmtqHY/btrStQ4BQso/cVfXxqHPj2OKDr2Xe44Wc1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmtqHY%2FbtrStQ4BQso%2FcVfXxqHPj2OKDr2Xe44Wc1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;446&quot; height=&quot;306&quot; data-origin-width=&quot;446&quot; data-origin-height=&quot;306&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 4. Linear few-shot evaluation on ImageNet versus pre-training size&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Figure 4는 JFT-300M 데이터셋에서 일정 수만큼의 데이터를 샘플링한 subset으로 pre-training을 진행한 후, ImageNet 데이터에 대해 fine-tuning하여 few-shot accuracy를 구한 결과이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;서로 학습 시간이 비슷했던 ViT-B/32와 ResNet50, 그리고 ViT-L/16과 ResNet152x2를 비교해보면 pre-training 데이터 수가 많아질수록 ViT의 성능이 더 좋아짐을 볼 수 있다. 즉, &lt;span style=&quot;color: #ee2323;&quot;&gt;작은 데이터셋에서는 convolutional inductive bias가 더 유용하지만, 데이터수가 많아지면 데이터에서 직접적으로 관련 pattern을 학습하는 것이 더 유용하다&lt;/span&gt;고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Vision Transformer가 학습하는 원리&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Vision Transformer가 이미지를 처리하는 방법을 이해하기 위해, 모델이 학습하는 과정에서의 representation을 분석해보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;363&quot; data-origin-height=&quot;247&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Skzam/btrSqlkPnBA/n0DlcgL3ATeLMhRCE1pZEK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Skzam/btrSqlkPnBA/n0DlcgL3ATeLMhRCE1pZEK/img.jpg&quot; data-alt=&quot;Figure 5. Filters of the initial linear embedding of RGB values (ViT-L/32)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Skzam/btrSqlkPnBA/n0DlcgL3ATeLMhRCE1pZEK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSkzam%2FbtrSqlkPnBA%2Fn0DlcgL3ATeLMhRCE1pZEK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;363&quot; height=&quot;247&quot; data-origin-width=&quot;363&quot; data-origin-height=&quot;247&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 5. Filters of the initial linear embedding of RGB values (ViT-L/32)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Figure 5는 patch들을 Linear projection하여 저차원 공간으로 맵핑할 때, 학습된 embedding filter의 top principal component(주성분)이다. Component들은 patch들이 갖는 미세한 구조의 저차원 representation에 대한 기저 함수(basis function)와 닮아 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;275&quot; data-origin-height=&quot;250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsF8Gs/btrSnEFbFy4/mezIP6X2CqHngji7Ou0BrK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsF8Gs/btrSnEFbFy4/mezIP6X2CqHngji7Ou0BrK/img.jpg&quot; data-alt=&quot;Figure 6. Similarity of position embeddings (ViT-L/32)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsF8Gs/btrSnEFbFy4/mezIP6X2CqHngji7Ou0BrK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsF8Gs%2FbtrSnEFbFy4%2FmezIP6X2CqHngji7Ou0BrK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;275&quot; height=&quot;250&quot; data-origin-width=&quot;275&quot; data-origin-height=&quot;250&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 6. Similarity of position embeddings (ViT-L/32)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Projection 이후에는 patch representation에 position embedding이 추가된다고 하였다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Figure 6은 모델이 position embedding의 유사성에서 (이미지 내에서의) 거리를 인코딩하는 방법을 학습한다는 것을 보여준다. 즉, &lt;span&gt;모델이 Position embedding을 학습하게 되면 위치가 &lt;span style=&quot;color: #ee2323;&quot;&gt;가까운 patch일수록 비슷한 position embedding&lt;/span&gt;을 갖게 된다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;1D position embedding을 사용하는데도 2D image topology에 대한 representation을 학습한다. (그림에서 행, 열의 구조가 나타난다. 즉, 같은 행이나 열의 patch는 비슷한 position embedding을 갖는다.)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;249&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dtVWBq/btrSrtCiuHg/Qpa5b0lIITsA1aOdjkHMek/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dtVWBq/btrSrtCiuHg/Qpa5b0lIITsA1aOdjkHMek/img.jpg&quot; data-alt=&quot;Figure 7. Size of attended area by head and network depth&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dtVWBq/btrSrtCiuHg/Qpa5b0lIITsA1aOdjkHMek/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdtVWBq%2FbtrSrtCiuHg%2FQpa5b0lIITsA1aOdjkHMek%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;250&quot; height=&quot;249&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;249&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 7. Size of attended area by head and network depth&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Self-attention 덕분에 ViT는 가장 낮은 layer에서도 이미지 전체에 대한 정보를 통합한다. Figure 7의 Attention distance는 CNN에서의 receptive field size와 같은 개념이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 head들은 0번째 layer에서 이미 이미지 대부분에 attend한다. (예를 들어 Head 1은 0번째 layer에서 평균 attention distance가 아주 높다.) 반면 다른 head들(빨강, 진갈색 등)은 낮은 layer에서 작은 attention distance를 갖는데, 이러한 head들은 CNN의 convolutional layer와 같은 역할을 할 것으로 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Network가 깊어지면서 attention distance가 전체적으로 오르는데, 이는 곧 Figure 8과 같이 모델이 이미지를 분류하는 데 관련된 부분에 더 집중(attends to)한다는 것을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;238&quot; data-origin-height=&quot;405&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwA6y4/btrStzolWSj/ORvMXe6cNwe2VHKxFUMmmK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwA6y4/btrStzolWSj/ORvMXe6cNwe2VHKxFUMmmK/img.jpg&quot; data-alt=&quot;Figure 8. Representative examples of attention from the output token to the input space&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwA6y4/btrStzolWSj/ORvMXe6cNwe2VHKxFUMmmK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwA6y4%2FbtrStzolWSj%2FORvMXe6cNwe2VHKxFUMmmK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;238&quot; height=&quot;405&quot; data-origin-width=&quot;238&quot; data-origin-height=&quot;405&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 8. Representative examples of attention from the output token to the input space&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Swin Transformer&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;2021년 ICCV 학회에서 발표된 'Swin Transformer: Hierarchical Vision Transformer Using Shifted Windows'논문에서 제안한 Swin Transformer는&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;'shifted window'라는 개념을 사용하여 hierarchical representation을 계산하는 Vision Transformer&lt;/span&gt;이다. 이를 통해 Transformer를 image에서의 pixel에 적용할 때와 text에서의 word에 적용할 때의 차이를 극복하고자 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Vision vs Language for Transformer&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;컴퓨터비전 분야와 자연어 처리 분야에서 Transformer를 적용할 때, 기본 요소가 서로 다르다. 자연어 처리에서는 기본 요소가 word token이며, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;scale&lt;/span&gt;이 고정되어 있다. 하지만 컴퓨터 비전에서는 resolution에 따라 이미지의 size(scale)가 바뀌므로 attention을 적용할 때 문제가 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 두 분야에서는&lt;span style=&quot;background-color: #f6e199;&quot;&gt; resolution&lt;/span&gt;이 다르다. Text의 단어들에 비해 image에서의 pixel의 해상도가 훨씬 높아서, self-attention의 계산 복잡도가 image size의 제곱에 비례하므로 pixel-level의 dense prediction에 적용하기가 매우 힘들다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Swin Transformer의 특징&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Swin Transformer는 컴퓨터 비전 도메인의 다양한 task에 적용할 수 있는 &lt;span style=&quot;color: #ee2323;&quot;&gt;Transformer 기반의 general backbone 아키텍쳐&lt;/span&gt;이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;545&quot; data-origin-height=&quot;317&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boVsnB/btrSHNnlhGY/dmYIMGAv2xbFv55mfpkJ90/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boVsnB/btrSHNnlhGY/dmYIMGAv2xbFv55mfpkJ90/img.jpg&quot; data-alt=&quot;Figure 9. Swin Transformer vs ViT&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boVsnB/btrSHNnlhGY/dmYIMGAv2xbFv55mfpkJ90/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboVsnB%2FbtrSHNnlhGY%2FdmYIMGAv2xbFv55mfpkJ90%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;545&quot; height=&quot;317&quot; data-origin-width=&quot;545&quot; data-origin-height=&quot;317&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 9. Swin Transformer vs ViT&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;위에서 언급한 두 가지 문제점을 다음 방법으로 해결하였다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Scale 문제 : Hierarchical feature map으로 구성하여 해결
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Transformer layer가 깊어짐에 따라 작은 patch부터 점진적으로 patch size를 키워 간다. (Figure 9에서의 회색 line)&lt;/li&gt;
&lt;li&gt;FPN(Feature Pyramid Networks)이나 U-Net을 사용하여 dense prediction을 할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Resolution 문제 : Shifted window 방법으로 해결
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Image를 windows(빨간색 line)로 나누고, self-attention을 각 window에 대해 계산한다.&lt;/li&gt;
&lt;li&gt;각 window의 patch 개수는 고정되므로, 계산 복잡도는 image size에 &lt;span style=&quot;color: #ee2323;&quot;&gt;선형&lt;/span&gt;이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Figure 9의 (b)에서 볼 수 있듯, ViT는 유일한 resolution의 feature map만 제공하고, 계산 복잡도가 image size의 제곱에 비례한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Shifted Window&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Shifted window approach는 두 연속된 self-attention layer 간에 window를 이동시키는 방법으로, Swin Transformer의 주요 design 요소이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled.jpeg&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b86k2b/btrSHiVKlOX/xcL8u4pL5LDbWyedOr6KEk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b86k2b/btrSHiVKlOX/xcL8u4pL5LDbWyedOr6KEk/img.jpg&quot; data-alt=&quot;Figure 10. Shifted Window&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b86k2b/btrSHiVKlOX/xcL8u4pL5LDbWyedOr6KEk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb86k2b%2FbtrSHiVKlOX%2FxcL8u4pL5LDbWyedOr6KEk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;541&quot; height=&quot;208&quot; data-filename=&quot;Untitled.jpeg&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;208&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 10. Shifted Window&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Figure 10에서 Layer \(l\)에서는 ViT에서와 같이 일반적으로 window partitioning을 진행한다. Layer \(l+1\)에서는 이 window를 이동시킨 것으로, 이 결과를 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;shifted window partitioning&lt;/span&gt;이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 window에서 나누어졌던 부분이 shifted window에서 계산되므로 &lt;span style=&quot;color: #ee2323;&quot;&gt;layer간의 connection&lt;/span&gt;이 생기고, 이에 따라 modeling power가 대폭 강화된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, window 내의 모든 query patch들이 같은 key set을 공유하는데, 이에 따라 memory access가 가능해진다. (기존 sliding window 기반의 self-attention 방법은 query pixel마다 서로 다른 key set을 가져 hardware에서 계산 시 low latency 문제가 있었다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 모든 MLP 아키텍쳐에서 유효한 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 Swin Transformer는 컴퓨터 비전과 자연어 처리를 통합한 아키텍쳐로, visual &amp;amp; textual signal의 joint modeling이나 두 도메인의 knowledge를 공유하는 modeling을 가능하게 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Method&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Overall Architecture&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Swin Transformer의 전체적인 구조는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled.jpeg&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;255&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPn0vY/btrSHNgW6sn/JMH66e4xemQCIppIlOuZqk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPn0vY/btrSHNgW6sn/JMH66e4xemQCIppIlOuZqk/img.jpg&quot; data-alt=&quot;Figure 11. Architecture of Tiny Version of Swin Transformer (Swin-T)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPn0vY/btrSHNgW6sn/JMH66e4xemQCIppIlOuZqk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPn0vY%2FbtrSHNgW6sn%2FJMH66e4xemQCIppIlOuZqk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;828&quot; height=&quot;255&quot; data-filename=&quot;Untitled.jpeg&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;255&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 11. Architecture of Tiny Version of Swin Transformer (Swin-T)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Architecture의 동작 과정을 자세히 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-12-02 at 15.51.38.jpg&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;255&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mambP/btrSIPE7ssD/9R8I9yjvn6dY1vtm2Kcth1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mambP/btrSIPE7ssD/9R8I9yjvn6dY1vtm2Kcth1/img.jpg&quot; data-alt=&quot;Figure 12. Input ~ 1st stage&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mambP/btrSIPE7ssD/9R8I9yjvn6dY1vtm2Kcth1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmambP%2FbtrSIPE7ssD%2F9R8I9yjvn6dY1vtm2Kcth1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;828&quot; height=&quot;255&quot; data-filename=&quot;CleanShot 2022-12-02 at 15.51.38.jpg&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;255&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 12. Input ~ 1st stage&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. input RGB image를 받아 겹치지 않는 patch로 나눈다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViT와 동일한 방법으로 patch를 나눈다. 각 patch는 token으로 간주하고, feature는 pixel의 RGB 값들을 연결(concatenate)한 형태이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Patch size를 \(4 \times 4\)라 하면, 각 patch의 feature dimension은 \( 4 \times 4 \times 3 = 48\)일 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 feature에 &lt;span style=&quot;color: #ee2323;&quot;&gt;linear embedding layer&lt;/span&gt;를 적용하여 임의의 dimension \(C\) (channel)로 projection한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 후, &lt;span style=&quot;color: #ee2323;&quot;&gt;Swin Transformer block&lt;/span&gt;은 token의 resolution을 \(\left( \cfrac{H}{4} \times \cfrac{W}{4} \right) \)로 유지시키면서 self-attention을 계산한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-12-02 at 15.51.38.jpg&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;255&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nqWN5/btrSIPSDRst/6Y8CL3ngwywBQcreOV0Gpk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nqWN5/btrSIPSDRst/6Y8CL3ngwywBQcreOV0Gpk/img.jpg&quot; data-alt=&quot;Figure 13. 2nd Stage ~ Last Stage&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nqWN5/btrSIPSDRst/6Y8CL3ngwywBQcreOV0Gpk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnqWN5%2FbtrSIPSDRst%2F6Y8CL3ngwywBQcreOV0Gpk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;828&quot; height=&quot;255&quot; data-filename=&quot;CleanShot 2022-12-02 at 15.51.38.jpg&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;255&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 13. 2nd Stage ~ Last Stage&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. Hierarchical representation을 적용한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Patch Merging Layer&lt;/span&gt;는 network가 깊어짐에 따라 token 개수를 줄이는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1990&quot; data-origin-height=&quot;1000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p91v4/btrSJxjFqRG/GSZ0hn8i1dbeXkCESsHek1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p91v4/btrSJxjFqRG/GSZ0hn8i1dbeXkCESsHek1/img.png&quot; data-alt=&quot;Figure 14. Patch feature concatenation&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p91v4/btrSJxjFqRG/GSZ0hn8i1dbeXkCESsHek1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp91v4%2FbtrSJxjFqRG%2FGSZ0hn8i1dbeXkCESsHek1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;508&quot; height=&quot;255&quot; data-origin-width=&quot;1990&quot; data-origin-height=&quot;1000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 14. Patch feature concatenation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-12-02 at 20.11.44.jpg&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;580&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brubaK/btrSHNnLfZB/QrUEGs61qR2GfOxe4H0fI0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brubaK/btrSHNnLfZB/QrUEGs61qR2GfOxe4H0fI0/img.jpg&quot; data-alt=&quot;Figure 15. Hiearachical Representation&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brubaK/btrSHNnLfZB/QrUEGs61qR2GfOxe4H0fI0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrubaK%2FbtrSHNnLfZB%2FQrUEGs61qR2GfOxe4H0fI0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;403&quot; height=&quot;353&quot; data-filename=&quot;CleanShot 2022-12-02 at 20.11.44.jpg&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;580&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 15. Hiearachical Representation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(2 \times 2\)개의 이웃 patch의 feature를 연결(concatenate)한 \(4C\)차원의 feature에 linear layer를 적용한다. 따라서 patch(token, Figure 15에서 회색 outline)의 개수가 \(4 \times 4\)에서 \(2 \times 2\)가 되며, patch의 차원은 \(2C\)가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 Figure 15에서 빨간 outline은 window이고, 같은 개수(그림에서는 \(4 \times 4 = 16\))의 patch를 갖는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에 Swin Transformer Block을 적용하여 feature transformation을 수행한다. 마찬가지로 resolution은 \(\left( \cfrac{H}{8} \times \cfrac{W}{8} \right)\)을 유지한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 Stage(Patch Merging Layer + Swin Transformer Block)를 총 3번 반복하면 resolution은 \(\left( \cfrac{H}{4} \times \cfrac{W}{4} \right) \rightarrow \left( \cfrac{H}{8} \times \cfrac{W}{8} \right) \rightarrow \left( \cfrac{H}{16} \times \cfrac{W}{16} \right) \rightarrow \left( \cfrac{H}{32} \times \cfrac{W}{32} \right) \)가 된다. (전체 pixel 수는 일정하므로 channel이 늘어나게 된다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 hierarchical representation은 CNN 기반인 VGG, ResNet 등의 feature map resolution과 같다. 즉, CNN처럼 Swin Transformer를 backbone으로 활용하여 다양한 컴퓨터 비전 task에 적용이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Swin Transformer Block을 간단히 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;410&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brmuBu/btrSHMoUAEy/WY8vvqNDorVtJZ5keae49K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brmuBu/btrSHMoUAEy/WY8vvqNDorVtJZ5keae49K/img.jpg&quot; data-alt=&quot;Figure 16. Transformer Block in ViT vs Two Successive Swin Transformer Blocks&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brmuBu/btrSHMoUAEy/WY8vvqNDorVtJZ5keae49K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrmuBu%2FbtrSHMoUAEy%2FWY8vvqNDorVtJZ5keae49K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;410&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;410&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 16. Transformer Block in ViT vs Two Successive Swin Transformer Blocks&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Figure 16에서 볼 수 있듯, Swin Transformer Block의 내부 구조는 기존 ViT의 MSA(Multi-Head self-attention) 모듈을 shifted window 기반의 W-MSA와 SW-MSA로 대체하였다. &lt;span style=&quot;background-color: #f6e199;&quot;&gt;W-MSA&lt;/span&gt;는 shift되기 이전의 regular partitioned window에서의 self-attention 모듈이고, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;SW-MSA&lt;/span&gt;는 shifted partitioned window에서의 self-attention 모듈이다. (다른 layer는 동일하다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Shifted Window based Self-attention&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터 비전에서의 기존 transformer 기반 아키텍쳐는 global self-attention을 사용하였다. 하지만 위에서 언급했듯이, 계산 복잡도가 image size의 제곱에 비례하여 고해상도 이미지 처리나 dense prediction이 불가능한 문제점이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 해결하기 위해 도입한 shifted window partitioning에 대해 자세히 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. Self-attention in non-overlapped windows&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Self-attention의 계산 복잡도를 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;겹치지 않게 나눈 windows에 대해 self-attention을 계산하는데, 만약 각 window가 \(M \times M\)개의 patch를 갖는다면, MSA 모듈과 W-MSA 모듈의 계산 복잡도는 다음과 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \Omega (\text{MSA}) = 4hwC^2 + 2(hw)^2C \)&lt;br /&gt;\( \Omega (\text{W-MSA}) = 4hwC^2 + 2M^2hwC \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( \Omega (\text{MSA}) \) : image의 size를 나타내는 \(hw\)에 대한 2차식 (quadratic)&lt;/li&gt;
&lt;li&gt;\( \Omega (\text{W-MSA}) \) : \(M\)이 고정되었을 때, \(hw\)에 대한 1차식 (linear)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. Shifted Window partitioning in successive blocks&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Window들 간의 connection이 잘 되어 있을수록 modeling power가 강해지는데, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;shifted window partitioning&lt;/span&gt;은 &lt;span style=&quot;color: #ee2323;&quot;&gt;연속된 Swin Transformer Block의 partitioning 설정을 바꿔줌으로써 connection을 강화&lt;/span&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled.jpeg&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b86k2b/btrSHiVKlOX/xcL8u4pL5LDbWyedOr6KEk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b86k2b/btrSHiVKlOX/xcL8u4pL5LDbWyedOr6KEk/img.jpg&quot; data-alt=&quot;Figure 10. Shifted Window&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b86k2b/btrSHiVKlOX/xcL8u4pL5LDbWyedOr6KEk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb86k2b%2FbtrSHiVKlOX%2FxcL8u4pL5LDbWyedOr6KEk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;541&quot; height=&quot;208&quot; data-filename=&quot;Untitled.jpeg&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;208&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 10. Shifted Window&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시한 번 Figure 10을 보면, Layer \(l\)에서는 regular window partitioning을 진행하며, Layer \(l+1\)에서는 window들을 \((\lfloor\frac{M}{2}\rfloor, \lfloor\frac{M}{2}\rfloor)\)만큼 옮긴(shift) window들을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연속된 Swin Transformer block에서는 shifted windows를 사용하여 다음과 같이 계산을 진행한다. Swin Transformer Block 그림과 함께 이해해보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-12-02 at 21.15.34.jpg&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;840&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6Sp7q/btrSHiaOW5v/ALn3p683L0TtYWITlHU5Q0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6Sp7q/btrSHiaOW5v/ALn3p683L0TtYWITlHU5Q0/img.jpg&quot; data-alt=&quot;Figure 17. Self-attention Computation in Swin Transformer Blocks&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6Sp7q/btrSHiaOW5v/ALn3p683L0TtYWITlHU5Q0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6Sp7q%2FbtrSHiaOW5v%2FALn3p683L0TtYWITlHU5Q0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;444&quot; height=&quot;472&quot; data-filename=&quot;CleanShot 2022-12-02 at 21.15.34.jpg&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;840&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 17. Self-attention Computation in Swin Transformer Blocks&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \hat{\mathbf{z}}^l = \text{W-MSA} (\text{LN}(\mathbf{z}^{l-1} )) + \mathbf{z}^{l-1} \)&lt;br /&gt;\( \mathbf{z}^l = \text{MLP} (\text{LN} (\hat{\mathbf{z}}^l)) + \hat{\mathbf{z}}^l \)&lt;br /&gt;\( \hat{\mathbf{z}}^{l+1} = \text{SW-MSA} (\text{LN} (\mathbf{z}^l)) + \mathbf{z}^l \)&lt;br /&gt;\( \mathbf{z}^{l+1} = \text{MLP} ( \text{LN}( \hat{\mathbf{z}}^{l+1} )) + \hat{\mathbf{z}}^{l+1} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(\hat{\mathbf{z}}^l\) : Block \(l\)의 W-MSA, SW-MSA 모듈의 output feature&lt;/li&gt;
&lt;li&gt;\(\mathbf{z}^l\) : Block \(l\)의 MLP 모듈의 output feature&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. Efficient batch computation for shifted configuration&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Shifted window partitioning의 문제점은 Figure 10에서 볼 수 있듯 window를 옮기는 과정에서 \(h, w\)를 따라 가각가 하나씩 &lt;span style=&quot;color: #ee2323;&quot;&gt;window의 개수가 늘어나고&lt;/span&gt;(\((\lceil \frac{h}{M} \rceil \times \lceil \frac{c}{M} \rceil) \rightarrow (\lceil \frac{h}{M} \rceil + 1) \times (\lceil \frac{c}{M} \rceil + 1)\)), &lt;span style=&quot;color: #ee2323;&quot;&gt;가장자리 부분의 window의 크기는 \(M \times M\)보다 작아진다&lt;/span&gt;는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 해결하기위한 단순한 방법으로는 작은 window에 padding을 적용하여 \(M \times M\)으로 사이즈를 맞춰주고, attention 계산 시에는 padding된 값을 masking(계산하지 않음)하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 이 방법은 window 개수가 적은 경우에는 계산량이 많이 늘어난다. Figure 10을 예로 들면, \(2 \times 2\)개의 window에서 \(3 \times 3\)개의 window로, 계산량이 2.25배가 늘어난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;efficient batch computation&lt;/span&gt; 방법을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-12-02 at 17.07.35.jpg&quot; data-origin-width=&quot;545&quot; data-origin-height=&quot;148&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NxbiJ/btrSJxjOZUg/jtmwL0C47zsJIMP0umUDZk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NxbiJ/btrSJxjOZUg/jtmwL0C47zsJIMP0umUDZk/img.jpg&quot; data-alt=&quot;Figure 18.&amp;amp;nbsp;Efficient Batch Computation Approach for Self-attention&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NxbiJ/btrSJxjOZUg/jtmwL0C47zsJIMP0umUDZk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNxbiJ%2FbtrSJxjOZUg%2FjtmwL0C47zsJIMP0umUDZk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;719&quot; height=&quot;195&quot; data-filename=&quot;CleanShot 2022-12-02 at 17.07.35.jpg&quot; data-origin-width=&quot;545&quot; data-origin-height=&quot;148&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Figure 18.&amp;nbsp;Efficient Batch Computation Approach for Self-attention&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, &lt;span style=&quot;color: #ee2323;&quot;&gt;왼쪽 위 방향으로 cyclic-shift&lt;/span&gt;(\(M \times M\) 사이즈의 window가 가장자리에 오도록 옮기는 것)를 진행한다. 그러면 Figure 18에서의 A, B, C와 같이 feature map과 겹치지 않는 sub-windows가 생기는데, &lt;span style=&quot;color: #ee2323;&quot;&gt;masking을 통해 sub-window들은 계산하지 않는다&lt;/span&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 후 반대 방향으로 reverse cyclic-shift를 하여 같은 방법으로 계산하면 계산된 batched window는 regular window의 크기와 같아진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 효율적으로, low latency(실험으로 증명)로 계산을 진행할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;4. Relative position bias&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Self-attention을 계산할 때, 각 head에서 similarity를 계산하는 과정에 relative position bias \(B \in \mathbb{R}^{M^2 \times M^2} \)를 적용한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \text{Attention}(Q, K, V) = \text{SoftMax}(QK^\top / \sqrt{d} + B)V \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(Q, K, V \in \mathbb{R}^{M^2 \times d} \) : query, key, value matrices&lt;/li&gt;
&lt;li&gt;\(d\) : query, key의 dimension&lt;/li&gt;
&lt;li&gt;\(M^2\) : window 하나에 있는 patch의 수&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Bias term이 없거나 position embedding만 사용하는 경우보다 성능이 훨씬 향상되었고, 이는 실험으로 증명되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, Pre-train된 relative position bias를 bi-cubic interpolation을 사용하여 window size에 따라 다르게 조정하여 사용이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Architecture Variants&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;BERT, ViT 등과 마찬가지로 Swin Transformer 또한 크기에 따라 다양한 모델이 존재한다. (window size \(M = 7\), query dimension \(d = 32\), 각 MLP의 expansion layer \(\alpha = 4\)로 고정)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Swin-T (Tiny version) : \(C=96, \text{layer numbers} = \{2, 2, 6, 2\}\)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모델 size : ResNet-50, DeiT-S와 비슷 (base의 0.25배)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Swin-S (Small version) : \(C=96, \text{layer numbers} = \{2, 2, 18, 2\}\)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모델 size : ResNet-101과 비슷 (base의 0.5배)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Swin-B (Base) : \(C=96, \text{layer numbers} = \{2, 2, 18, 2\}\)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모델 size : ViT-B/DeiT-B와 비슷&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Swin-L (Large version) : \(C=192, \text{layer numbers} = \{2, 2, 18, 2\}\)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모델 size : base의 2배&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\(C\)는 first stage의 hidden layer의 channel 수이고, 이론적인 계산 복잡도(FLOPs)를 기준으로 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;649&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/orwUq/btrSISaUnRR/uvajODLENJv87IgsYi4CS1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/orwUq/btrSISaUnRR/uvajODLENJv87IgsYi4CS1/img.jpg&quot; data-alt=&quot;Table 1. Comparison of different backbones&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/orwUq/btrSISaUnRR/uvajODLENJv87IgsYi4CS1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2ForwUq%2FbtrSISaUnRR%2FuvajODLENJv87IgsYi4CS1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;553&quot; height=&quot;649&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;649&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Table 1. Comparison of different backbones&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Knowledges</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/196</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Transformers-in-Vision-2-ViT-Swin-Transformer#entry196comment</comments>
      <pubDate>Tue, 29 Nov 2022 19:07:51 +0900</pubDate>
    </item>
    <item>
      <title>PyTorch, 딥러닝 코딩 관련 유용한 함수와 팁 모음!</title>
      <link>https://jjuke-brain.tistory.com/entry/PyTorch-%EA%B4%80%EB%A0%A8-%EC%9C%A0%EC%9A%A9%ED%95%9C-%ED%95%A8%EC%88%98</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 상황에서 사소하지만 유용한 함수들을 필요할 때마다 찾아 보기 번거로워 이 포스팅에 정리해보려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나씩 찾을 때마다 내용을 늘릴 예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;PyTorch에 있는 유용한 함수&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Numpy의 array, PyTorch의 tensor 생략 없이 전체 출력하기&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1669121624503&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys

# numpy
import numpy as np
np.set_printoptions(threshold=sys.maxsize)

# pytorch
import torch
torch.set_printoptions(threshold=sys.maxsize)&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;.py, .ipynb tip&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;보통 깃허브의 딥러닝 코드는 py파일로 올라와있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 분석을 하거나, 새로운 모델을 개발할 때는 개인적으로는 jupyter lab에서 변수를 출력해가며 개발하는 것이 훨씬 편해서 두 방법 사이를 오가며 코딩할 때의 팁을 정리해본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Jupyter lab에서 argparse 사용&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;py파일로 정리된 딥러닝 코드를 실행할 때에는 terminal에서 변수를 받아 실행한다. 이떄 활용하는 것이 argparse인데, jupyter lab에서 argparse를 그대로 활용하기 위해서는 아주 간단한 수정 하나만 해주면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;우선 argparse 모듈을 사용하기 위해서는 다음과 같이 import해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1676960697267&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import argparse&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 py파일에서는 다음과 같이 argument들을 정의해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1672213195011&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# argparse in .py
parser = argparse.ArgumentParser()

parser.add_argument('--argname1', type=..., default=... help=...)
parser.add_argument('--argname2', type=..., default=... help=...)
parser.add_argument('--argname3', type=..., default=... help=...)
parser.add_argument('--argname4', type=..., default=... help=...)
parser.add_argument('--argname5', type=..., default=... help=...)
parser.add_argument('--argname6', type=..., default=... help=...)
...
parser.add_argument('--argname11', type=..., default=... help=...)
parser.add_argument('--argname12', type=..., default=... help=...)

args = parser.parse_args()&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;단순히 parse_args()에 'args=[]'라는 인자만 추가해주면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1672213274507&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# argparser in jupyter lab(notebook)
parser = argparse.ArgumentParser()

parser.add_argument('--argname1', type=..., default=... help=...)
parser.add_argument('--argname2', type=..., default=... help=...)
parser.add_argument('--argname3', type=..., default=... help=...)
parser.add_argument('--argname4', type=..., default=... help=...)
parser.add_argument('--argname5', type=..., default=... help=...)
parser.add_argument('--argname6', type=..., default=... help=...)
...
parser.add_argument('--argname11', type=..., default=... help=...)
parser.add_argument('--argname12', type=..., default=... help=...)

args = parser.parse_args(args=[])

# in the next cell
args.argname1 = ...
args.argname2 = ...
args.argname3 = ...
args.argname4 = ...
args.argname5 = ...
args.argname6 = ...
...
args.argname11 = ...
args.argname12 = ...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Argument들을 입력해주기 위해서 .py에서는 터미널에서 입력해주지만, jupyter lab(notebook)에서는 다음 셀에서 필요한 argument를 직접 입력해주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 아래에서 args.argname으로 사용되는 다양한 변수를 하나하나 고칠 필요가 없어진다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Research/Pytorch</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/195</guid>
      <comments>https://jjuke-brain.tistory.com/entry/PyTorch-%EA%B4%80%EB%A0%A8-%EC%9C%A0%EC%9A%A9%ED%95%9C-%ED%95%A8%EC%88%98#entry195comment</comments>
      <pubDate>Tue, 22 Nov 2022 21:55:03 +0900</pubDate>
    </item>
    <item>
      <title>Docker, SSH, Visual Studio Code로 작업 환경 구축하기</title>
      <link>https://jjuke-brain.tistory.com/entry/Docker-SSH-Visual-Studio-Code%EB%A1%9C-%EC%9E%91%EC%97%85-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;도커의 컨테이너 환경을 로컬 환경처럼 사용할 수 있는 작업 환경을 구축하는 방법을 기록하고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--머릿말 시작--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. CUDA 버전 찾기&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--머릿말 끝--&gt;&lt;!--소제목1--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CUDA(Computed Unified Device Architecture)란, &lt;span&gt;그래픽 용도로만 사용하던 GPU를 병렬 계산에 사용할 수 있도록 해주는 소프트웨어이다.&lt;/span&gt; C, C++언어를 기반으로 짜여있고, tensorflow, pytorch 등의 프레임워크를 설치하기 이전에 CUDA를 설치할 필요가 있다. 연구자들이 쉽게 딥러닝에 사용할 수 있도록 오픈하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 cuDNN이란, CUDA Deep Neural Network Library의 약자로, forward/backward convolution 연산, pooling 연산, normalization 연산, activation 등 딥러닝 연산을 진행하기 위한 소프트웨어이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 사용자는 nvidia driver, CUDA, CUDNN만 설치하면 GPU를 활용하여 딥러닝을 구현할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, 'nvidia-smi' 명령어를 활용하여 해당 gpu에 맞는 nvidia driver를 설치하고, 사용 가능한 CUDA 버전을 찾아보자. (Ubuntu 기준)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1659165444669&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nvidia-smi&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;319&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bW6cH3/btrIA1n4pbt/5fHKOHQgDUvgKBEn4DQ5U1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bW6cH3/btrIA1n4pbt/5fHKOHQgDUvgKBEn4DQ5U1/img.png&quot; data-alt=&quot;nvidia-smi&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bW6cH3/btrIA1n4pbt/5fHKOHQgDUvgKBEn4DQ5U1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbW6cH3%2FbtrIA1n4pbt%2F5fHKOHQgDUvgKBEn4DQ5U1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;712&quot; height=&quot;319&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;319&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;nvidia-smi&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어는 대표적으로 다음의 정보를 담고 있다. (훨씬 많은 정보를 담고 있지만, 여기선 CUDA 버전에 집중하자.)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Driver Version: GPU에 맞는 nvidia driver의 버전 (설치된 버전)&lt;/li&gt;
&lt;li&gt;CUDA Version: nvidia driver에 맞는 (추천하는) CUDA 버전
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;설치된 CUDA 버전이 아니라, '추천하는' CUDA 버전&lt;/span&gt;임에 유의하자.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Nvidia driver 별 지원 가능한 CUDA 버전은 다음 링크에서 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#cuda-major-component-versions&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#cuda-major-component-versions&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;765&quot; data-origin-height=&quot;914&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6dWRt/btrIBUPMytq/97Euyoz2Cw9yQnk6EWq671/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6dWRt/btrIBUPMytq/97Euyoz2Cw9yQnk6EWq671/img.png&quot; data-alt=&quot;CUDA Version&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6dWRt/btrIBUPMytq/97Euyoz2Cw9yQnk6EWq671/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6dWRt%2FbtrIBUPMytq%2F97Euyoz2Cw9yQnk6EWq671%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;578&quot; height=&quot;691&quot; data-origin-width=&quot;765&quot; data-origin-height=&quot;914&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CUDA Version&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예시처럼 만약 nvidia-smi 명령어에서 driver 버전이 '430.34'라면, CUDA 버전은 10.1 이하 버전만 설치가 가능할 것이다. (그래서 nvidia-smi 명령어 결과에서 추천 CUDA 버전을 10.1로 제안한 것이다!)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, CUDA 버전에 따라 사용 가능한 PyTorch 버전이 정해져 있으므로, 다음을 참고하여 버전을 맞춰주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pytorch.org/get-started/previous-versions/&quot;&gt;https://pytorch.org/get-started/previous-versions/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1666075070898&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;PyTorch&quot; data-og-description=&quot;An open source machine learning framework that accelerates the path from research prototyping to production deployment.&quot; data-og-host=&quot;pytorch.org&quot; data-og-source-url=&quot;https://pytorch.org/get-started/previous-versions/&quot; data-og-url=&quot;https://www.pytorch.org&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pI0Oe/hyQfkTtjXD/2ARB2xsupS9ei4XDGM2Kx0/img.png?width=2500&amp;amp;height=2500&amp;amp;face=0_0_2500_2500&quot;&gt;&lt;a href=&quot;https://pytorch.org/get-started/previous-versions/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pytorch.org/get-started/previous-versions/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pI0Oe/hyQfkTtjXD/2ARB2xsupS9ei4XDGM2Kx0/img.png?width=2500&amp;amp;height=2500&amp;amp;face=0_0_2500_2500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;PyTorch&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;An open source machine learning framework that accelerates the path from research prototyping to production deployment.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pytorch.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 다음 Docker Hub에서 CUDA 버전을 찾는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://hub.docker.com/r/nvidia/cuda/tags&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://hub.docker.com/r/nvidia/cuda/tags&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1657692979505&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Docker Hub&quot; data-og-description=&quot;&quot; data-og-host=&quot;hub.docker.com&quot; data-og-source-url=&quot;https://hub.docker.com/r/nvidia/cuda/tags&quot; data-og-url=&quot;https://hub.docker.com/r/nvidia/cuda/tags&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://hub.docker.com/r/nvidia/cuda/tags&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hub.docker.com/r/nvidia/cuda/tags&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Docker Hub&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;hub.docker.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CUDA 이미지파일명은 다음의 의미를 갖는다. 예를 들어, '&lt;span style=&quot;color: #ee2323;&quot;&gt;11.3.0-cudnn8-devel-ubuntu18.04&lt;/span&gt;'라는 이미지 파일이 있다면,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;11.3.0 : CUDA의 버전으로, 사용하려는 GPU, nvidia driver, pytorch 버전 등에 따라 다르다. (이전 예시에서와는 다른 GPU를 사용해서 11.3 버전을 예시로 들 것이다.)&lt;/li&gt;
&lt;li&gt;cudnn8 : cudnn 버전&lt;/li&gt;
&lt;li&gt;devel : CUDA 설치 level (이미지의 사이즈 &amp;rarr; base &amp;lt; runtime &amp;lt; devel)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;base가 가장 가볍지만, nvcc 명령어가 필요한 고급 기능은 devel에서만 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ubuntu18.04 : OS 버전&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--머릿말 시작--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Dockerfile 만들기&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;다음으로, 도커 파일을 만들어보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;/home/sangjune/dev/mydocker 경로를 예시로 들 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 명령어로 vim을 사용하여 파일을 만든다. (nano를 사용해도 된다.) vim이란, 터미널을 통해 텍스트를 편집할 수 있는 에디터의 개념이다. 맥의 경우 터미널에서 간단히 다음과 같이 파일을 생성할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 vim 관련 명령어를 간단히 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;i를 눌러 입력모드로 전환할 수 있으며, esc를 누른 후 명령모드로 전환 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령모드에서 명령어는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657694627653&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 삽입 모드(i)에서
:w # 저장
:q # 종료
:q! # 강제종료
:wq # 저장 및 종료
:wq! # 저장 및 종료

# visual 모드(v)에서
v # 블록 지정
V # 줄 단위 블록
d # 블록 지정 된 부분 지우기
y # 블록 복사
yy 또는 Y # 커서가 위치한 한 줄 복사
p # 현재 커서에 붙여넣기

# 명령 모드(esc)에서
gg 또는 1G # 문서의 맨 처음으로 이동
G # 문서의 맨 마지막 행으로 이동

h # 왼쪽으로 이동
l # 오른쪽으로 이동
j # 아래행으로 이동
k # 위 행으로 이동

w 또는 W # 다음 단어의 첫 글자로 이동
b 또는 B # 이전 단어의 첫 글자로 이동
e 또는 E # 단어의 마지막 글자로 이동

^ # 그행의 첫 글자로 이동
$ # 그 행의 마지막 글자로 이동

{ # 이전 문단으로 이동
} # 다음 문단으로 이동

H # 커서를 화면 맨 위로 이동
M # 커서를 화면 중안으로 이동
L # 커서를 화면 최하단으로 이동&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Dockerfile이라는 파일을 만들기 위해, 터미널에 다음과 같이 입력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657694217383&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vim Dockerfile&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1034&quot; data-origin-height=&quot;136&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVoY2z/btrHdygRz1B/Uv6A0cMwCCJwKRzbkdh150/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVoY2z/btrHdygRz1B/Uv6A0cMwCCJwKRzbkdh150/img.png&quot; data-alt=&quot;Dockerfile 생성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVoY2z/btrHdygRz1B/Uv6A0cMwCCJwKRzbkdh150/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVoY2z%2FbtrHdygRz1B%2FUv6A0cMwCCJwKRzbkdh150%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;624&quot; height=&quot;82&quot; data-origin-width=&quot;1034&quot; data-origin-height=&quot;136&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Dockerfile 생성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이어서 아래의 스크립트를 입력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다운받은 이미지 파일에 따라 'nvidia/cuda:11.3.0-cudnn8-devel-ubuntu18.04' 부분만 수정해주면 되며, 스크립트를 통해 git, g++, ffmpeg 등의 주요 프로그램과 miniconda, openssh-server를 설치할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657694692746&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM nvidia/cuda:11.3.0-cudnn8-devel-ubuntu18.04

# software installation
RUN apt update

# basic
RUN apt install -y --no-install-recommends \
    nano tmux wget iputils-ping git g++ net-tools curl zip unzip ffmpeg

# miniconda (https://github.com/ContinuumIO/docker-images/blob/master/miniconda3/debian/Dockerfile)
RUN apt install -y --no-install-recommends \
    bzip2 \
    ca-certificates \
    libglib2.0-0 \
    libsm6 \
    libxext6 \
    libxrender1 \
    mercurial \
    openssh-client \
    procps \
    subversion
ENV PATH /opt/conda/bin:$PATH
ARG CONDA_VERSION=py39_4.10.3
RUN set -x &amp;amp;&amp;amp; \
    UNAME_M=&quot;$(uname -m)&quot; &amp;amp;&amp;amp; \
    if [ &quot;${UNAME_M}&quot; = &quot;x86_64&quot; ]; then \
    MINICONDA_URL=&quot;https://repo.anaconda.com/miniconda/Miniconda3-${CONDA_VERSION}-Linux-x86_64.sh&quot;; \
    SHA256SUM=&quot;1ea2f885b4dbc3098662845560bc64271eb17085387a70c2ba3f29fff6f8d52f&quot;; \
    elif [ &quot;${UNAME_M}&quot; = &quot;s390x&quot; ]; then \
    MINICONDA_URL=&quot;https://repo.anaconda.com/miniconda/Miniconda3-${CONDA_VERSION}-Linux-s390x.sh&quot;; \
    SHA256SUM=&quot;1faed9abecf4a4ddd4e0d8891fc2cdaa3394c51e877af14ad6b9d4aadb4e90d8&quot;; \
    elif [ &quot;${UNAME_M}&quot; = &quot;aarch64&quot; ]; then \
    MINICONDA_URL=&quot;https://repo.anaconda.com/miniconda/Miniconda3-${CONDA_VERSION}-Linux-aarch64.sh&quot;; \
    SHA256SUM=&quot;4879820a10718743f945d88ef142c3a4b30dfc8e448d1ca08e019586374b773f&quot;; \
    elif [ &quot;${UNAME_M}&quot; = &quot;ppc64le&quot; ]; then \
    MINICONDA_URL=&quot;https://repo.anaconda.com/miniconda/Miniconda3-${CONDA_VERSION}-Linux-ppc64le.sh&quot;; \
    SHA256SUM=&quot;fa92ee4773611f58ed9333f977d32bbb64769292f605d518732183be1f3321fa&quot;; \
    fi &amp;amp;&amp;amp; \
    wget &quot;${MINICONDA_URL}&quot; -O miniconda.sh -q &amp;amp;&amp;amp; \
    echo &quot;${SHA256SUM} miniconda.sh&quot; &amp;gt; shasum &amp;amp;&amp;amp; \
    if [ &quot;${CONDA_VERSION}&quot; != &quot;latest&quot; ]; then sha256sum --check --status shasum; fi &amp;amp;&amp;amp; \
    mkdir -p /opt &amp;amp;&amp;amp; \
    sh miniconda.sh -b -p /opt/conda &amp;amp;&amp;amp; \
    rm miniconda.sh shasum &amp;amp;&amp;amp; \
    ln -s /opt/conda/etc/profile.d/conda.sh /etc/profile.d/conda.sh &amp;amp;&amp;amp; \
    echo &quot;. /opt/conda/etc/profile.d/conda.sh&quot; &amp;gt;&amp;gt; ~/.bashrc &amp;amp;&amp;amp; \
    echo &quot;conda activate base&quot; &amp;gt;&amp;gt; ~/.bashrc &amp;amp;&amp;amp; \
    find /opt/conda/ -follow -type f -name '*.a' -delete &amp;amp;&amp;amp; \
    find /opt/conda/ -follow -type f -name '*.js.map' -delete &amp;amp;&amp;amp; \
    /opt/conda/bin/conda clean -afy

# @option: SSH server
RUN apt install -y --no-install-recommends openssh-server

# limit password quality
RUN apt install -y libpam-pwquality

RUN echo 'PASS_MIN_LEN 8' &amp;gt;&amp;gt; /etc/login.defs
RUN echo 'PermitRootLogin yes' &amp;gt;&amp;gt; /etc/ssh/sshd_config

RUN apt clean
RUN rm -rf /var/lib/apt/lists/*

RUN echo 'alias ca=&quot;conda activate&quot;' &amp;gt;&amp;gt; /root/.bashrc
RUN echo 'conda activate' &amp;gt;&amp;gt; /root/.bashrc

WORKDIR /root/dev

# entry script
COPY entry.sh /entry.sh
RUN chmod +x /entry.sh
ENTRYPOINT [ &quot;/entry.sh&quot; ]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저장한 후 같은 방법으로 mydocker 디렉토리 내에 'entry.sh' 파일을 생성하여 다음과 같이 작성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 스크립트는 컨테이너가 실행될 때 작동하며, sleep infinity 부분은 컨테이너가 자동으로 종료되는 것을 방지해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657694860876&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash

# service ssh start

# If you have any other scripts to run everytime the conatiner started then you can attach the script here.
# ...

sleep infinity&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSH를 통해 container에 직접 접속하기 위해서 service ssh start를 입력해준다. 필자는 보안때문에 위와 같이 주석처리하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세한 정보는 다음 &lt;a href=&quot;https://github.com/Kitsunetic/dockerenv-public&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;github&lt;/a&gt;을 참조하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--머릿말 시작--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Build Docker Image&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저, 이미지 파일을 pull해야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1659438929147&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker pull [image_file]&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;보통 태그로 검색을 하게 되면 친절하게 pull command를 가르쳐준다. 그것을 그대로 복사해서 터미널에서 실행해주면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;결과는 'docker images'라는 명령어를 통해 pull된 이미지 파일을 확인해볼 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;도커 이미지를 빌드하기 위해 다음 명령어를 실행한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657695007308&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd /home/user/dev/mydocker

# docker build 명령어 -&amp;gt; docker build [옵션] [Dockerfile 경로]
docker build -t [이름]/[image 파일명]:[image 파일 버전] .&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--머릿말 끝--&gt;&lt;!--소제목1--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;점(.)을 빼먹지 않도록 유의하자! 점은 모든 파일을 빌드하겠다는 의미를 갖는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 다음과 같이 입력하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2218&quot; data-origin-height=&quot;1276&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lJXUa/btrHdbfbwUE/kyKVVKnPvmvA9onplPjyQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lJXUa/btrHdbfbwUE/kyKVVKnPvmvA9onplPjyQk/img.png&quot; data-alt=&quot;example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lJXUa/btrHdbfbwUE/kyKVVKnPvmvA9onplPjyQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlJXUa%2FbtrHdbfbwUE%2FkyKVVKnPvmvA9onplPjyQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2218&quot; height=&quot;1276&quot; data-origin-width=&quot;2218&quot; data-origin-height=&quot;1276&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker build 명령어에서 -t 옵션은 저장소 이름, 이미지 이름, 태그를 설정해준다. 따라서 [저장소 이름]/[이미지 이름]:[태그] 형식에 맞추어 작성해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--머릿말 시작--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. Docker Image 실행 (Container 생성)&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;내 경우 연구실의 서버를 사용한다. Container 내부에는 git, g++, python, conda 등의 프로그램만 저장되고, 데이터셋이나 소스코드 등 용량이 큰 파일들은 컨테이너를 가볍게 유지하기 위해 서버 공간에 저장한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;서버에 저장된 소스코드와 데이터셋에는 'docker run'의 '-v' 옵션을 통해 접근할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;1) Docker Run 명령어&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;docker run 명령어에 대해 간략히 정리해보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;docker run은 이미지 파일로 컨테이너를 생성하는 명령어이며, 다음 형식을 갖는다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657695669568&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker run [옵션] [이미지] [명령] [매개 변수]

# 예시
# docker run -d -it --name containername imagename bash&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--머릿말 끝--&gt;&lt;!--소제목1--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자주 사용하는 옵션은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;-i : 표준 입력을 활성화하여 컨테이너와 연결되어있지 않아도 표준 입력을 유지한다. 보통 이 옵션을 사용하여 bash에 명령을 입력한다.&lt;/li&gt;
&lt;li&gt;-t : TTY 모드를 적용한다. Bash를 사용할 수 있게 해준다. 이 옵션이 없으면 명령을 입력할 수는 있지만, 셀이 표시되지 않는다.&lt;/li&gt;
&lt;li&gt;--name : 컨테이너의 이름을 설정한다. ('docker ps'에서 표시되는 컨테이너명)&lt;/li&gt;
&lt;li&gt;-d, --detach : detach모드(또는 데몬 모드), 컨테이너가 백그라운드로 실행된다.&lt;/li&gt;
&lt;li&gt;-p : 호스트(서버)와 컨테이너의 포트를 연결한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;형식 : -p [호스트 포트]:[컨테이너 포트]&lt;/li&gt;
&lt;li&gt;예시 (SSH, Jupyter 등 호스트(서버)에 외부에서 컨테이너 포트를 통해 접근할 수 있도록)&lt;/li&gt;
&lt;li&gt;-p 11111:8888&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;-v : 데이터 볼륨을 설정한다. 호스트, 컨테이너의 디렉토리를 연결(마운트)하여 파일을 컨테이너에 저장하지 않고 호스트에 바로 저장한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;형식 : -v [host 폴더]:[container 폴더]&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;-u : 컨테이너가 실행될 리눅스 사용자의 계정 이름 또는 UID를 설정한다.&lt;/li&gt;
&lt;li&gt;-e : 컨테이너 내에서 사용하는 환경 변수를 설정한다. 보통 설정 값이나 비밀번호를 전달할 때 사용한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예시 : time zone 설정&lt;/li&gt;
&lt;li&gt;-v /etc/localtime:/etc/localtime&lt;/li&gt;
&lt;li&gt;-e TZ=Asia/Seoul&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;--link : 컨테이너끼리 연결한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예시 : --link=&quot;container_name:container_nickname&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;--restart : 컨테이너 종료 시, 재시작 방식을 설정한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예시 (호스트(서버) 재부팅 시 자동으로 컨테이너 재실행)&lt;/li&gt;
&lt;li&gt;--restart unless-stopped&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;--gpus : 컨테이너에서 호스트(서버)의 Nvidia GPU를 사용할 수 있도록 설정한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예시 (모든 gpu 사용)&lt;/li&gt;
&lt;li&gt;--gpus all&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;--ipc : 공유 메모리를 설정한다. (큰 batch size에서 OOM 에러가 나는 것을 방지해준다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 다음과 같이 진행했다. 역슬래시 '\'는 줄바꿈을 위해 입력했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1659443662134&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker run --gpus all -id \
--name dq_sangjune \
-v /data/sangjune:/root/dev \
--ipc host \
--restart unless-stopped \
-p 18201:22 \
-p 28201:8888 \
sangjune/cuda-miniconda-ssh:11.3.0-ver0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막에 'sangjune/cuda-miniconda-ssh'가 image name, '11.3.0-ver0'이 image tag이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 명령어를 통해 도커 컨테이너가 제대로 생성되었는지 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657697843178&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker ps -a&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--머릿말 시작--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. VSCode ssh 보안 옵션 설정&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;VSCode와 연동하여 ssh 접속을 한다면, -p 옵션으로 포트를 열었다고 해서 SSH 접속을 바로 할 수 있는 것은 아니다. ssh 접속을 할 때마다 비밀번호를 쳐주어야 하는데, docker container를 사용한다면 서버 접속 시 한 번, container 접속 시 한 번씩 매번 쳐주어야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;vscode의 ssh configure에 public key를 등록해놓고 이 과정을 간소화할 수 있다. 하지만 등록을 위해서는 보안설정을 해주어야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;SSH public / private key를 생성하여 보안 설정을 하는 과정을 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;1) 키 생성&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;호스트(서버)가 아닌 로컬 환경(클라이언트, 즉 컴퓨터나 데스크탑)의 터미널에서 키를 생성한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657698114969&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ssh-keygen -t rsa&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--머릿말 끝--&gt;&lt;!--소제목1--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-t 옵션은 어떤 암호화 방식을 사용할 것인지를 설정하는 옵션이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일 위치를 지정(기본 위치로 사용하는 경우 그냥 enter를 친다.)하고, 비밀번호를 적용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차 비밀번호(passphrase)는 더 안전하게 옵션을 걸고싶을 경우 사용한다. &lt;span style=&quot;color: #ee2323;&quot;&gt;연결할 때마다 비밀번호를 입력하는 게 귀찮아서 이 과정을 진행하는데, 굳이 2차 비밀번호를 걸 필요는 없다&lt;/span&gt;. enter로 넘어가자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;910&quot; data-origin-height=&quot;92&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kS9iD/btrHaUx72UL/RJxPZoeHTGqhpCY2YRYpHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kS9iD/btrHaUx72UL/RJxPZoeHTGqhpCY2YRYpHk/img.png&quot; data-alt=&quot;키 생성 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kS9iD/btrHaUx72UL/RJxPZoeHTGqhpCY2YRYpHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkS9iD%2FbtrHaUx72UL%2FRJxPZoeHTGqhpCY2YRYpHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;653&quot; height=&quot;66&quot; data-origin-width=&quot;910&quot; data-origin-height=&quot;92&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;키 생성 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지정한 위치에 '.ssh'라는 디렉토리가 생기고, 그 하위에 id_rsa, id_rsa.pub, known_hosts 파일이 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;id_rsa는 개인(private) 키로, 비밀번호를 담고 있는 파일이며, id_rsa.pub은 공용(public) 키로, 서버나 컨테이너 내부에 등록되어서 id_rsa를 갖고 있는 유저의 접속을 통과시켜주는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;2) 서버에 public key 등록&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;로컬의 터미널에서 다음 명령어를 통해 id_rsa.pub의 내용을 출력한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657698740015&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd ~/.ssh
cat id_rsa.pub&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음, 서버에 접속한다. (새 터미널 창에서 진행한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657698929297&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ssh [계정이름]@[ip주소] -p[포트번호]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버의 home 경로에서 '~/.ssh/authorized_keys'파일을 생성하여 출력했던 'id_rsa.pub'의 내용물을 복사하여 authorized_keys 파일에 붙여넣고 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 '~'는 home 경로의 예약어이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657699030328&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mkdir ~/.ssh
vim ~/.ssh/authorized_keys&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1669909094471&quot; class=&quot;routeros&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vim이 깔려있지 않는 경우 아래 명령어로 받을 수 있음
apt-get update
apt-get install vim&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 id_rsa 파일을 갖는 클라이언트에서는 해당 서버에 바로 접속할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6. VSCode를 통해 로컬과 서버 및 컨테이너 연결&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;1) Remote - SSH 패키지 설치&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저, Visual Studio Code의 확장 탭에서 'Remote - SSH' 패키지를 설치한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;508&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cM1T43/btrHdwjnaBM/lKz3FFovslKqenmjjGDMYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cM1T43/btrHdwjnaBM/lKz3FFovslKqenmjjGDMYk/img.png&quot; data-alt=&quot;remote - SSH 패키지 설치&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cM1T43/btrHdwjnaBM/lKz3FFovslKqenmjjGDMYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcM1T43%2FbtrHdwjnaBM%2FlKz3FFovslKqenmjjGDMYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;488&quot; height=&quot;438&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;508&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;remote - SSH 패키지 설치&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--머릿말 끝--&gt;&lt;!--소제목1--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치가 완료되면 다음과 같이 왼쪽 하단에 '&amp;gt;&amp;lt;' 모양의 remote 버튼이 생긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;372&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uHjBa/btrHaYAVliS/3nuKnjgmj8971pj3ZUCaNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uHjBa/btrHaYAVliS/3nuKnjgmj8971pj3ZUCaNK/img.png&quot; data-alt=&quot;remote 버튼&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uHjBa/btrHaYAVliS/3nuKnjgmj8971pj3ZUCaNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuHjBa%2FbtrHaYAVliS%2F3nuKnjgmj8971pj3ZUCaNK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;510&quot; height=&quot;275&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;372&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;remote 버튼&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;2) Remote-access 설정&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;remote 버튼을 눌러 'SSH 구성 파일 열기 &amp;rarr; .../config'파일을 선택하여, 다음과 같은 형식으로 설정해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1254&quot; data-origin-height=&quot;334&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEFc4V/btrHbVxdgXz/vJJm4g8bvxozcFUPzTw7Yk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEFc4V/btrHbVxdgXz/vJJm4g8bvxozcFUPzTw7Yk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEFc4V/btrHbVxdgXz/vJJm4g8bvxozcFUPzTw7Yk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEFc4V%2FbtrHbVxdgXz%2FvJJm4g8bvxozcFUPzTw7Yk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;631&quot; height=&quot;168&quot; data-origin-width=&quot;1254&quot; data-origin-height=&quot;334&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657701793218&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Host [nickname for this remote connection]
	HostName [Server IP]
    Port [The exposed port when you choosed in 'docker run']
    User [user name]
    IdentityFile [The full path of your 'id_rsa' file. Security configuration]
    PasswordAuthentication no&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1320&quot; data-origin-height=&quot;331&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RAELL/btrHd2hPZX7/DAWdRmqlsmBqgWAPFex0ak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RAELL/btrHd2hPZX7/DAWdRmqlsmBqgWAPFex0ak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RAELL/btrHd2hPZX7/DAWdRmqlsmBqgWAPFex0ak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRAELL%2FbtrHd2hPZX7%2FDAWdRmqlsmBqgWAPFex0ak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;737&quot; height=&quot;185&quot; data-origin-width=&quot;1320&quot; data-origin-height=&quot;331&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원격 연결이 완료된 후 자동완성 기능 등을 이용하려면 Python 확장 프로그램을 설치해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--머릿말 시작--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7. Conda&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;예시에서 docker build로 만든 이미지에는 miniconda가 깔려있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;기본으로 base environment가 실행되고, 아래 명령어를 통해 새로운 환경을 만들 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;가상환경을 생성하는 과정은 다음 글을 참조하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EC%95%84%EB%82%98%EC%BD%98%EB%8B%A4-%EA%B0%80%EC%83%81%ED%99%98%EA%B2%BD-%EA%B4%80%EB%A0%A8-%EB%AA%85%EB%A0%B9%EC%96%B4-%EB%AA%A8%EC%9D%8C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jjuke-brain.tistory.com/entry/%EC%95%84%EB%82%98%EC%BD%98%EB%8B%A4-%EA%B0%80%EC%83%81%ED%99%98%EA%B2%BD-%EA%B4%80%EB%A0%A8-%EB%AA%85%EB%A0%B9%EC%96%B4-%EB%AA%A8%EC%9D%8C&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1671783302453&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;아나콘다 가상환경 관련 명령어 모음!&quot; data-og-description=&quot;아나콘다를 사용하면서 가상환경을 생성, 삭제하는 등의 명령어들을 정리해보려 한다. 하나하나 필요할 때마다 검색하기 귀찮아서, 기본적인 것부터 지속적으로 명령어를 쓸 때마다 정리해둘 &quot; data-og-host=&quot;jjuke-brain.tistory.com&quot; data-og-source-url=&quot;https://jjuke-brain.tistory.com/entry/%EC%95%84%EB%82%98%EC%BD%98%EB%8B%A4-%EA%B0%80%EC%83%81%ED%99%98%EA%B2%BD-%EA%B4%80%EB%A0%A8-%EB%AA%85%EB%A0%B9%EC%96%B4-%EB%AA%A8%EC%9D%8C&quot; data-og-url=&quot;https://jjuke-brain.tistory.com/entry/%EC%95%84%EB%82%98%EC%BD%98%EB%8B%A4-%EA%B0%80%EC%83%81%ED%99%98%EA%B2%BD-%EA%B4%80%EB%A0%A8-%EB%AA%85%EB%A0%B9%EC%96%B4-%EB%AA%A8%EC%9D%8C&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/HhrBV/hyQZELqJnT/oXdNTCSkXQQIYwFEHEbhk1/img.png?width=800&amp;amp;height=200&amp;amp;face=0_0_800_200,https://scrap.kakaocdn.net/dn/8SbXS/hyQZKx6zao/cDNdmKcCq2pLtykWgS7hrK/img.png?width=800&amp;amp;height=200&amp;amp;face=0_0_800_200,https://scrap.kakaocdn.net/dn/b0PGL8/hyQZIfZ73D/ROhn5OvsapcSuyAe55Zln1/img.png?width=220&amp;amp;height=220&amp;amp;face=0_0_220_220&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EC%95%84%EB%82%98%EC%BD%98%EB%8B%A4-%EA%B0%80%EC%83%81%ED%99%98%EA%B2%BD-%EA%B4%80%EB%A0%A8-%EB%AA%85%EB%A0%B9%EC%96%B4-%EB%AA%A8%EC%9D%8C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jjuke-brain.tistory.com/entry/%EC%95%84%EB%82%98%EC%BD%98%EB%8B%A4-%EA%B0%80%EC%83%81%ED%99%98%EA%B2%BD-%EA%B4%80%EB%A0%A8-%EB%AA%85%EB%A0%B9%EC%96%B4-%EB%AA%A8%EC%9D%8C&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/HhrBV/hyQZELqJnT/oXdNTCSkXQQIYwFEHEbhk1/img.png?width=800&amp;amp;height=200&amp;amp;face=0_0_800_200,https://scrap.kakaocdn.net/dn/8SbXS/hyQZKx6zao/cDNdmKcCq2pLtykWgS7hrK/img.png?width=800&amp;amp;height=200&amp;amp;face=0_0_800_200,https://scrap.kakaocdn.net/dn/b0PGL8/hyQZIfZ73D/ROhn5OvsapcSuyAe55Zln1/img.png?width=220&amp;amp;height=220&amp;amp;face=0_0_220_220');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;아나콘다 가상환경 관련 명령어 모음!&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;아나콘다를 사용하면서 가상환경을 생성, 삭제하는 등의 명령어들을 정리해보려 한다. 하나하나 필요할 때마다 검색하기 귀찮아서, 기본적인 것부터 지속적으로 명령어를 쓸 때마다 정리해둘&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jjuke-brain.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1657702199807&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda create ...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--머릿말 끝--&gt;&lt;!--소제목1--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;1) 가상환경에 설치된 패키지 파일 옮기기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;정확하게 말하자면, 패키지 파일들을 'requirements.txt'에 옮겨 두었다가, 새로운 가상환경에서 그 파일을 사용하여 패키지를 다운받는 과정이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저, 아래 명령어로 requirements.txt 파일을 생성한다. pip 또는 conda 둘 다 가능하다.&lt;/p&gt;
&lt;pre id=&quot;code_1668601677783&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip freeze &amp;gt; requirements.txt&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1668601290357&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda list --export &amp;gt; requirements.txt&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, 다음 명령어로 requirements.txt 파일에 쓰인 패키지들을 받을 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1668601841349&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install --yes -r requirements.txt&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1668601864619&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda install --yes --file requirements.txt&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 중요한 pytorch는 requirements.txt에서 지워주고 원하는 버전을 따로 받는 것이 좋다. 버전이 바뀌면 골치아프기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 pip로 다운받은 패키지도 있고, conda로 받은 패키지도 있어서, pip로는 'requirements_pip.txt', conda로 'requirements_conda.txt'를 생성하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 requirements_pip.txt에서 conda로 받았던 것을 지워주고 pip로 requirements_pip.txt 파일을 통해 패키지를 받고, pip로 받은 패키지를 requirements_conda.txt에서 제외시켜준 후에 패키지를 받았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 requirements_pip.txt에서 pip로 받았는지, conda로 받았는지가 명확하게 구분되기 때문이다. requirements_pip.txt의 예시는 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1020&quot; data-origin-height=&quot;639&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LtPL8/btrRnO2cFgA/w5YfpD3HkKvqYgtRvclZ2K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LtPL8/btrRnO2cFgA/w5YfpD3HkKvqYgtRvclZ2K/img.jpg&quot; data-alt=&quot;requirements_pip.txt&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LtPL8/btrRnO2cFgA/w5YfpD3HkKvqYgtRvclZ2K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLtPL8%2FbtrRnO2cFgA%2Fw5YfpD3HkKvqYgtRvclZ2K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1020&quot; height=&quot;639&quot; data-origin-width=&quot;1020&quot; data-origin-height=&quot;639&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;requirements_pip.txt&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는 다음 명령어를 통해 yaml파일로 현재 아나콘다 갓아환경을 export할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1681029953223&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;conda env export &amp;gt; [filename].yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 보통 'environment.yaml'이라고 저장하는 편이다. 그 결과는 아래와 같이 나타난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;423&quot; data-origin-height=&quot;793&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lfXG6/btr8KIrnJ48/w43SHgHK8DQPemyX6Uk5lK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lfXG6/btr8KIrnJ48/w43SHgHK8DQPemyX6Uk5lK/img.jpg&quot; data-alt=&quot;environment.yaml&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lfXG6/btr8KIrnJ48/w43SHgHK8DQPemyX6Uk5lK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlfXG6%2Fbtr8KIrnJ48%2Fw43SHgHK8DQPemyX6Uk5lK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;423&quot; height=&quot;793&quot; data-origin-width=&quot;423&quot; data-origin-height=&quot;793&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;environment.yaml&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--머릿말 시작--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8. 작업 환경 이전&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;기존에 작업하던 환경을 다른 컴퓨터나 서버로 옮길 때 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;1) 본인이 수정한 Container를 image로 Commit&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;본인의 docker container를 이미지 파일로 저장하려면 다음 과정을 거친다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;실행중이라면 컨테이너를 종료한다.&lt;/li&gt;
&lt;li&gt;종료된 도커 컨테이너의 ID를 'docker ps -a' 명령어를 통해 확인한다.&lt;/li&gt;
&lt;li&gt;아래 commit 명령을 입력하여 컨테이너 이미지를 생성한다. 이때 image_name에 본인 github id 혹은 유저이름이 들어가야 본인 docker hub에 push할 수 있다.
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;예를 들어 'docker commit test_container jjuke/image_name'&lt;/li&gt;
&lt;li&gt;혹시 이를 까먹고 그냥 image_name으로 commit했다면, 'docker image tag image_name user_id/image_name'으로 tag를 붙여서 다시 저장해준다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;'docker images' 명령어를 통해 생성된 이미지를 확인한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1657702466787&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker commit [container_name] [image_name]&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;참고로, 콜론 뒤에는 태그를 설정할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1766&quot; data-origin-height=&quot;316&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcFpZq/btrHdJ3Y5wk/sK1yITS3kjYpdyFuMz3md1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcFpZq/btrHdJ3Y5wk/sK1yITS3kjYpdyFuMz3md1/img.png&quot; data-alt=&quot;commit example&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcFpZq/btrHdJ3Y5wk/sK1yITS3kjYpdyFuMz3md1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdcFpZq%2FbtrHdJ3Y5wk%2FsK1yITS3kjYpdyFuMz3md1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;120&quot; data-origin-width=&quot;1766&quot; data-origin-height=&quot;316&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;commit example&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;자신의 docker hub에 저장하려면 docker에 로그인해준 후, 다음과 같이 이미지를 push해준다. (앞서 언급했듯 image_name은 'user_name/image_name' 형식이다.)&lt;/p&gt;
&lt;pre id=&quot;code_1680886174432&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker login
docker push [image_name]&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 21px;&quot;&gt;2) docker image를 tar파일로 저장&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;docker build나 commit으로 만들어진 이미지 파일은 일반적으로 docker hub 등에 push되고, 이를 다시 pull하여 받는 방식으로 사용한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;하지만, docker 이미지를 이러한 방식을 거치지 않고 이동해야할 때가 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이를 위해서는 docker image를 '.tar'파일로 저장한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;또는 .tar.gz 파일로 저장하면 시간은 좀 더 걸리지만, 용량이 1/3 수준으로 줄어든다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;관련 명령어는 아래와 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;[docker save]&lt;/p&gt;
&lt;pre id=&quot;code_1657705664408&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker save [image_name] -o [file_name]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!--머릿말 끝--&gt;&lt;!--소제목1--&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-o 옵션으로 저장할 파일명을 지정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker save docker_practice:220713 -o /path/to/the/file.tar&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker save docker_practice:220713 | gzip &amp;gt; /path/to/the/file.tar.gz&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 .tar 또는 .tar.gz 파일을 sftp 명령어나 FileZilla 등의 프로그램을 써서 다른 서버로 옮긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[tar 파일 로드]&lt;/p&gt;
&lt;pre id=&quot;code_1657706415094&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# .tar
docker load -i /path/to/the/file.tar

# .tar.gz
docker load &amp;lt; /path/to/the/file.tar.gz&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;load 후에는 'docker run'을 통해 실행시킬 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Server 사용 시 로컬에서 jupyter lab 켜는 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Jupyter lab을 실행하기 전, 처음 jupyter lab을 켜면 token을 입력하라는 창이 나오는데, 다음 명령어를 통해 아예 원하는 비밀번호를 설정해주는 것이 편하다. (마찬가지로 jupyter notebook은 lab을 notebook으로 바꾸면 명령어는 동일하다.)&lt;/p&gt;
&lt;pre id=&quot;code_1672155748187&quot; class=&quot;verilog&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;jupyter lab --generate-config
jupyter lab password
# 이후 password 입력&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;추가로, 현재 anaconda 가상환경에 대한 kernel 명을 설정해주면 가상환경이 여러 개인경우, jupyter lab 환경 안에서 원하는 가상환경을 사용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1672156027196&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python -m ipykernel install --user --name [가상환경 이름] --display-name &quot;[주피터 환경에서 보일 이름]&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;서버를 사용할 경우, 단순히 'jupyter lab'만 입력할 때 서버 컴퓨터에서 jupyter lab이 시작된다. 이때는 다음과 같은 방법으로 로컬에서 작업할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1664269757464&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;jupyter lab --port 8888 --ip 0.0.0.0 --allow-root&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jupyter notebook도 마찬가지 명령어를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부에서 접속하기 위해 ip를 '0.0.0.0'(현재 ip)으로 설정하고, allow-root라는 옵션을 부여하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'[서버의_노드_주소]:[서버에서_잡았던_노드]/lab'을 검색창에 치면 바로 실행 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 예시에서 docker run할 때 '-p 28201:8888'로 잡아줬으므로, 노드의 주소가 n12345라 하면 'n12345:28201/lab'을 주소창에 치면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;그리고 처음 컨테이너에 접속했을 경우, 다음을 통해 git 설정을 등록해주어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1664463227483&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git config --global user.name &quot;[git 유저 이름]&quot;
git config --global user.email &quot;[git 이메일 주소]&quot;
git config --global http.postBuffer 52428800 # 최대 업로드 가능 파일 용량 50MB로 설정 (default: 1MB)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science, Programming/Git, Docker, Server, Linux</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/125</guid>
      <comments>https://jjuke-brain.tistory.com/entry/Docker-SSH-Visual-Studio-Code%EB%A1%9C-%EC%9E%91%EC%97%85-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0#entry125comment</comments>
      <pubDate>Tue, 22 Nov 2022 19:57:44 +0900</pubDate>
    </item>
    <item>
      <title>VSCode에서 github 연동하고 편하게 버전 관리하기! (private repository 포함)</title>
      <link>https://jjuke-brain.tistory.com/entry/VSCode%EC%97%90%EC%84%9C-github-%EC%97%B0%EB%8F%99%ED%95%98%EA%B3%A0-%ED%8E%B8%ED%95%98%EA%B2%8C-%EB%B2%84%EC%A0%84-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Github에 새로운 repository를 연동할 때마다 검색하면서 trouble shooting 하는 것이 귀찮아서 자주 진행하는 과정을 정리해보려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git의 개념과 필수 명령어들에 대한 설명은 다음 글을 참조하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Git-%EA%B8%B0%EB%B3%B8-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC-feat-%EC%83%9D%ED%99%9C%EC%BD%94%EB%94%A9&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jjuke-brain.tistory.com/entry/Git-%EA%B8%B0%EB%B3%B8-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC-feat-%EC%83%9D%ED%99%9C%EC%BD%94%EB%94%A9&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1669109683594&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Git 기본 명령어 정리 (feat. 생활코딩)&quot; data-og-description=&quot;Git을 사용하면서 버전 관리를 어떻게 하는지 명령어들을 간단하게 정리해보고자 한다. 먼저, 버전 관리를 어떻게 시작하는지에 관한 명령어이다. pwd : 현재 디렉토리를 보여준다. cd : change directo&quot; data-og-host=&quot;jjuke-brain.tistory.com&quot; data-og-source-url=&quot;https://jjuke-brain.tistory.com/entry/Git-%EA%B8%B0%EB%B3%B8-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC-feat-%EC%83%9D%ED%99%9C%EC%BD%94%EB%94%A9&quot; data-og-url=&quot;https://jjuke-brain.tistory.com/entry/Git-%EA%B8%B0%EB%B3%B8-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC-feat-%EC%83%9D%ED%99%9C%EC%BD%94%EB%94%A9&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/byrUNd/hyQE8lBb8B/48egPRYRnsd37pYKUCFzm0/img.png?width=800&amp;amp;height=334&amp;amp;face=0_0_800_334,https://scrap.kakaocdn.net/dn/bb95k4/hyQE4jboUQ/C7buAb8XDz8O6DypVIVArK/img.png?width=800&amp;amp;height=334&amp;amp;face=0_0_800_334,https://scrap.kakaocdn.net/dn/elT28u/hyQE5bj476/w3iXmOfUYhHhTXsKLqMj1K/img.png?width=220&amp;amp;height=220&amp;amp;face=0_0_220_220&quot;&gt;&lt;a href=&quot;https://jjuke-brain.tistory.com/entry/Git-%EA%B8%B0%EB%B3%B8-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC-feat-%EC%83%9D%ED%99%9C%EC%BD%94%EB%94%A9&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jjuke-brain.tistory.com/entry/Git-%EA%B8%B0%EB%B3%B8-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC-feat-%EC%83%9D%ED%99%9C%EC%BD%94%EB%94%A9&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/byrUNd/hyQE8lBb8B/48egPRYRnsd37pYKUCFzm0/img.png?width=800&amp;amp;height=334&amp;amp;face=0_0_800_334,https://scrap.kakaocdn.net/dn/bb95k4/hyQE4jboUQ/C7buAb8XDz8O6DypVIVArK/img.png?width=800&amp;amp;height=334&amp;amp;face=0_0_800_334,https://scrap.kakaocdn.net/dn/elT28u/hyQE5bj476/w3iXmOfUYhHhTXsKLqMj1K/img.png?width=220&amp;amp;height=220&amp;amp;face=0_0_220_220');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Git 기본 명령어 정리 (feat. 생활코딩)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Git을 사용하면서 버전 관리를 어떻게 하는지 명령어들을 간단하게 정리해보고자 한다. 먼저, 버전 관리를 어떻게 시작하는지에 관한 명령어이다. pwd : 현재 디렉토리를 보여준다. cd : change directo&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jjuke-brain.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Remote repository 생성&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이 부분은 local에서 작업 중인 repository(폴더)가 이미 있는 상태에서 github의 새로운 remote repository를 파서 연동하는 과정이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저, github에서 로그인 후 'Repositories'탭에 들어가 새로운 remote repository를 생성해준다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-11-22 at 18.37.56.jpg&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;805&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWQiM2/btrRNVHHVpQ/ff3RMarotXECW0GsIw09vk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWQiM2/btrRNVHHVpQ/ff3RMarotXECW0GsIw09vk/img.jpg&quot; data-alt=&quot;Create New Repository&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWQiM2/btrRNVHHVpQ/ff3RMarotXECW0GsIw09vk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWQiM2%2FbtrRNVHHVpQ%2Fff3RMarotXECW0GsIw09vk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;811&quot; height=&quot;401&quot; data-filename=&quot;CleanShot 2022-11-22 at 18.37.56.jpg&quot; data-origin-width=&quot;1630&quot; data-origin-height=&quot;805&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Create New Repository&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때, README file은 굳이 추가하지 않는다. 추가하는 경우, 로컬과 연결할 때 README 파일 때문에 pull을 해줘야 하는데, 그러면 로컬의 폴더의 기존 내용은 날아가므로 새로운 폴더를 만들어 git 설정을 해준 후에 내용을 복붙해주는 귀찮은 과정을 거쳐야 한다. 차라리 빈 repository에 로컬과 연결을 해준 후에 README파일을 나중에 추가해주는 것이 훨씬 간단하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(무엇보다, 빈 내용으로 만들어야 quick setup 설명이 뜨는데, 이것에 따르는 게 가장 간단하다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;980&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p5dqd/btrROsrHkfn/hzW8y9sDmQHqYJg1xH8Y2K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p5dqd/btrROsrHkfn/hzW8y9sDmQHqYJg1xH8Y2K/img.jpg&quot; data-alt=&quot;Create New Repository (2)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p5dqd/btrROsrHkfn/hzW8y9sDmQHqYJg1xH8Y2K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp5dqd%2FbtrROsrHkfn%2FhzW8y9sDmQHqYJg1xH8Y2K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;669&quot; height=&quot;708&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;980&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Create New Repository (2)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로 생성한 빈 repository에 들어가보면 다음과 같은 quick setup 도움말이 뜬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1314&quot; data-origin-height=&quot;719&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kOvee/btrRTt3j3PB/MY4gxlGkGYZabMg9bbRkC1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kOvee/btrRTt3j3PB/MY4gxlGkGYZabMg9bbRkC1/img.jpg&quot; data-alt=&quot;(Help) Quick Setup&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kOvee/btrRTt3j3PB/MY4gxlGkGYZabMg9bbRkC1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkOvee%2FbtrRTt3j3PB%2FMY4gxlGkGYZabMg9bbRkC1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1314&quot; height=&quot;719&quot; data-origin-width=&quot;1314&quot; data-origin-height=&quot;719&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(Help) Quick Setup&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도움말 중에서 '...or create a new repository on the command line'에 주목하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Local과 remote repository 연결&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;다음으로 본인 컴퓨터, 혹은 서버, 또는 도커 컨테이너 내의 local repository와 github의 remote repository를 연결해주는 과정이 필요하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 로컬(vscode)에서 'Terminal-New Terminal' 선택 혹은 단축키 'ctrl + shift + ~'을 눌러 터미널을 켜고, 원하는 path로 들어간다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;연습 삼아 컨테이너 내의 'open3d_data'라는 폴더와 연동을 해볼 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;379&quot; data-origin-height=&quot;60&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lMBRf/btrRRvuwUiV/MSIxSHe0jHj1wy846Edook/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lMBRf/btrRRvuwUiV/MSIxSHe0jHj1wy846Edook/img.jpg&quot; data-alt=&quot;연동을 원하는 폴더로 들어가기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lMBRf/btrRRvuwUiV/MSIxSHe0jHj1wy846Edook/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlMBRf%2FbtrRRvuwUiV%2FMSIxSHe0jHj1wy846Edook%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;379&quot; height=&quot;60&quot; data-origin-width=&quot;379&quot; data-origin-height=&quot;60&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;연동을 원하는 폴더로 들어가기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;여기서 도움말에 적힌대로 (README 생성은 제외하고) initialize, commit, branch 설정, remote 추가, push 순으로 진행한다.&lt;/p&gt;
&lt;pre id=&quot;code_1669111146221&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git init
git add .
git commit -m &quot;[commit message]&quot;
git branch -M main # master가 아님에 유의!
git remote add [remote name] [remote url] # name은 보통 'origin'으로 설정함
git push -u [remote name] main&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;git init : 현재 디렉토리에 '.git' 폴더를 생성한다. .git에는 git 버전 관리를 진행하기 위한 설정 등이 포함되어 있다.&lt;/li&gt;
&lt;li&gt;git add . : 모든 변화 상황(처음 initialize 후이므로 현재 디렉토리의 (.git 제외) 모든 내용)을 staging area라는 공간에 추가한다. 만약 폴더 내용이 없다면 '.' 대신에 도움말에서처럼 README 파일을 생성해주어도 된다.&lt;/li&gt;
&lt;li&gt;branch -M main : 연결할 remote repository의 branch를 설정한다. repository를 생성했을 때, default branch는 main이므로 branch를 여러 개 만들고싶지 않다면 main으로 설정해주면 된다. (예전에는 master였다.)&lt;/li&gt;
&lt;li&gt;git remote add [remote name] [remote url] : remote url 주소의 remote repository를 remote name이라는 이름으로 추가한다. remote name는 보통 'origin'으로 설정한다.&lt;/li&gt;
&lt;li&gt;git push -u [remote name] main : 바로 위에서 remote name으로 설정한 remote repository의 main branch에 staging area의 내용을 올린다. -u는 --set-upstream과 같은 옵션으로, 해당 remote repository를 default로 설정하여 다음부터는 git push만 해주어도 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;854&quot; data-origin-height=&quot;375&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rq2Z2/btrRR7NsIOy/uCIe9Dzbh8bttKcD7Ku8ak/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rq2Z2/btrRR7NsIOy/uCIe9Dzbh8bttKcD7Ku8ak/img.jpg&quot; data-alt=&quot;Result&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rq2Z2/btrRR7NsIOy/uCIe9Dzbh8bttKcD7Ku8ak/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frq2Z2%2FbtrRR7NsIOy%2FuCIe9Dzbh8bttKcD7Ku8ak%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;854&quot; height=&quot;375&quot; data-origin-width=&quot;854&quot; data-origin-height=&quot;375&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Result&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VSCode와 github를 처음 연동한다면, 설정해주어야 할 것이 있다. (위 명령어를 하다 보면 추가 설정이나 로그인을 요구할 것이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, 'git config ...' 관련하여 아이디와 닉네임을 입력하라는 문구가 뜬다면, github 아이디와 닉네임을 기입하면 간단히 해결된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데, github의 아이디와 비밀번호를 입력하여 로그인을 하다가 'authentication failed'라는 에러를 마주친다면, github의 비밀번호가 아닌 token을 입력해주어야 한다. 이 token은 다음과 같은 과정으로 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. github의 오른쪽 위에 본인 프로필을 클릭 - 'Settings'를 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-11-22 at 20.03.49.jpg&quot; data-origin-width=&quot;1653&quot; data-origin-height=&quot;628&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YNSEw/btrROqHziha/oFE1taVLmUB66qVdh80ya0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YNSEw/btrROqHziha/oFE1taVLmUB66qVdh80ya0/img.jpg&quot; data-alt=&quot;Profile-Settings&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YNSEw/btrROqHziha/oFE1taVLmUB66qVdh80ya0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYNSEw%2FbtrROqHziha%2FoFE1taVLmUB66qVdh80ya0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1653&quot; height=&quot;628&quot; data-filename=&quot;CleanShot 2022-11-22 at 20.03.49.jpg&quot; data-origin-width=&quot;1653&quot; data-origin-height=&quot;628&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Profile-Settings&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 왼쪽 탭에서 'Developer Settings - Personal access tokens'에 들어가고, 'Generate new token'버튼을 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-11-22 at 20.06.04.jpg&quot; data-origin-width=&quot;1642&quot; data-origin-height=&quot;486&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GOHpx/btrRSsDRLy5/9N81T2vMULbVkrAkUxfNl1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GOHpx/btrRSsDRLy5/9N81T2vMULbVkrAkUxfNl1/img.jpg&quot; data-alt=&quot;Generate new token&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GOHpx/btrRSsDRLy5/9N81T2vMULbVkrAkUxfNl1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGOHpx%2FbtrRSsDRLy5%2F9N81T2vMULbVkrAkUxfNl1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1642&quot; height=&quot;486&quot; data-filename=&quot;CleanShot 2022-11-22 at 20.06.04.jpg&quot; data-origin-width=&quot;1642&quot; data-origin-height=&quot;486&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Generate new token&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Token을 생성하는 창에서 허용 범위를 체크해주고, 만료일을 선택한다. 필자는 귀찮아서 전체 체크, 만료일은 없이 생성했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 생성된 token을 복사하여 VSCode에서의 로그인 시 비밀번호로 사용한다. 이때, 생성된 token은 다시 볼 수 없으므로 본인만 알 수 있는 메모장 등에 기입해둔다. 혹시 창을 지나쳤다면 다시 token을 생성해주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지 진행하면 VSCode 왼쪽에 'source control' 탭에서 손쉽게 버전관리를 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-11-22 at 19.41.43.jpg&quot; data-origin-width=&quot;453&quot; data-origin-height=&quot;591&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dGiWQx/btrRStbGHSw/uyzrZlOBrYvw0mpwgBrtb1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dGiWQx/btrRStbGHSw/uyzrZlOBrYvw0mpwgBrtb1/img.jpg&quot; data-alt=&quot;Source Control in VSCode&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dGiWQx/btrRStbGHSw/uyzrZlOBrYvw0mpwgBrtb1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdGiWQx%2FbtrRStbGHSw%2FuyzrZlOBrYvw0mpwgBrtb1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;439&quot; height=&quot;573&quot; data-filename=&quot;CleanShot 2022-11-22 at 19.41.43.jpg&quot; data-origin-width=&quot;453&quot; data-origin-height=&quot;591&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Source Control in VSCode&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 github의 repository로 돌아가보면, 다음과 같이 로컬에 있던 변경 사항이 repository에 잘 push되었음을 확인해볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1658&quot; data-origin-height=&quot;831&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YrN2m/btrRQjBcdQO/VGzJ146Ro0kRwemKPIJ2y0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YrN2m/btrRQjBcdQO/VGzJ146Ro0kRwemKPIJ2y0/img.jpg&quot; data-alt=&quot;Github Result&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YrN2m/btrRQjBcdQO/VGzJ146Ro0kRwemKPIJ2y0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYrN2m%2FbtrRQjBcdQO%2FVGzJ146Ro0kRwemKPIJ2y0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1658&quot; height=&quot;831&quot; data-origin-width=&quot;1658&quot; data-origin-height=&quot;831&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Github Result&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Source Control in VSCode&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;VSCode에서는 별도 extension 설치 없이도 source control을 지원한다. 일단 한 번 위 과정을 거쳤다면 터미널에서의 명령어를 기억할 필요 없이 직관적이고 쉽게 변경 사항에 대한 add, commit, push를 할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;VSCode 상에서 README.md 파일을 만들어보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;357&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dVpwtr/btrRRvBp7On/myJQUwuk4ifpY94Hqfp4k1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dVpwtr/btrRRvBp7On/myJQUwuk4ifpY94Hqfp4k1/img.jpg&quot; data-alt=&quot;Create New File&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dVpwtr/btrRRvBp7On/myJQUwuk4ifpY94Hqfp4k1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdVpwtr%2FbtrRRvBp7On%2FmyJQUwuk4ifpY94Hqfp4k1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;418&quot; height=&quot;357&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;357&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Create New File&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;README.md 파일을 생성하여 아래와 같은 문구를 입력하고, 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;94&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AzSvD/btrRTEw1slj/R1J4MxeX6pWm2Zd1aYAiEK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AzSvD/btrRTEw1slj/R1J4MxeX6pWm2Zd1aYAiEK/img.jpg&quot; data-alt=&quot;README.md&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AzSvD/btrRTEw1slj/R1J4MxeX6pWm2Zd1aYAiEK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAzSvD%2FbtrRTEw1slj%2FR1J4MxeX6pWm2Zd1aYAiEK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;436&quot; height=&quot;94&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;94&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;README.md&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그다음&amp;nbsp; VSCode의 Source control 탭에 들어가보면, 다음과 같이 'Changes'에 README.md가 떠있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-11-22 at 19.48.30.jpg&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUxqFt/btrRTDSpBEd/ZVyD6aZ5BJFvKILv5LDrXk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUxqFt/btrRTDSpBEd/ZVyD6aZ5BJFvKILv5LDrXk/img.jpg&quot; data-alt=&quot;Changes&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUxqFt/btrRTDSpBEd/ZVyD6aZ5BJFvKILv5LDrXk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUxqFt%2FbtrRTDSpBEd%2FZVyD6aZ5BJFvKILv5LDrXk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;439&quot; height=&quot;512&quot; data-filename=&quot;CleanShot 2022-11-22 at 19.48.30.jpg&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;512&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Changes&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Changes 쪽에 마우스 커서를 대면 +모양의 'Stage all changes'라는 버튼이 뜨는데, 이를 클릭하자. 이 과정은 'git add' 명령어와 같은 과정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;509&quot; data-origin-height=&quot;520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3zO6I/btrRQ5CTKaM/DnetHGf7FS5tmuVtPg8AOk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3zO6I/btrRQ5CTKaM/DnetHGf7FS5tmuVtPg8AOk/img.jpg&quot; data-alt=&quot;add&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3zO6I/btrRQ5CTKaM/DnetHGf7FS5tmuVtPg8AOk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3zO6I%2FbtrRQ5CTKaM%2FDnetHGf7FS5tmuVtPg8AOk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;418&quot; height=&quot;427&quot; data-origin-width=&quot;509&quot; data-origin-height=&quot;520&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;add&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 'Staged Changes'에 추가한 내용이 올라가게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로는 원하는 commit message를 Message 칸에 입력하고, Commit 버튼을 누른다. 이는 'git commit -m &quot;[Messages]&quot;'명령어와 같은 과정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-11-22 at 19.52.13.jpg&quot; data-origin-width=&quot;513&quot; data-origin-height=&quot;532&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwjH6L/btrROsk4HeP/H7pkwK97jlpZykRl2r2ae1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwjH6L/btrROsk4HeP/H7pkwK97jlpZykRl2r2ae1/img.jpg&quot; data-alt=&quot;commit&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwjH6L/btrROsk4HeP/H7pkwK97jlpZykRl2r2ae1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwjH6L%2FbtrROsk4HeP%2FH7pkwK97jlpZykRl2r2ae1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;513&quot; height=&quot;532&quot; data-filename=&quot;CleanShot 2022-11-22 at 19.52.13.jpg&quot; data-origin-width=&quot;513&quot; data-origin-height=&quot;532&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;commit&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Commit 버튼을 누르면 Sync Changes 버튼이 생성되는데, 그 버튼을 누르면 github remote repository로 push가 된다. 이는 'git push'명령어와 같은 과정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-11-22 at 19.53.59.jpg&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5dpgz/btrROJfRUT3/kEW79knHK1falRrb3z16J0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5dpgz/btrROJfRUT3/kEW79knHK1falRrb3z16J0/img.jpg&quot; data-alt=&quot;push&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5dpgz/btrROJfRUT3/kEW79knHK1falRrb3z16J0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5dpgz%2FbtrROJfRUT3%2FkEW79knHK1falRrb3z16J0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;488&quot; height=&quot;518&quot; data-filename=&quot;CleanShot 2022-11-22 at 19.53.59.jpg&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;518&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;push&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Push 이후에 github 저장소에 돌아가보면 다음과 같이 README.md 파일이 추가되어 있음을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-11-22 at 19.55.24.jpg&quot; data-origin-width=&quot;1653&quot; data-origin-height=&quot;750&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0aeng/btrRQjnJGB4/kkmMu0yxWVJJ5g3YG1i6M1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0aeng/btrRQjnJGB4/kkmMu0yxWVJJ5g3YG1i6M1/img.jpg&quot; data-alt=&quot;Github Result&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0aeng/btrRQjnJGB4/kkmMu0yxWVJJ5g3YG1i6M1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0aeng%2FbtrRQjnJGB4%2FkkmMu0yxWVJJ5g3YG1i6M1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1653&quot; height=&quot;750&quot; data-filename=&quot;CleanShot 2022-11-22 at 19.55.24.jpg&quot; data-origin-width=&quot;1653&quot; data-origin-height=&quot;750&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Github Result&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Private repository 연동하기&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Private repository는 보안이 강화되어 https(url)를 통한 push, pull, clone 등이 제한된다. 따라서 작업하는 공간(예를 들어 로컬, 서버, 서버의 컨테이너 등)에서 SSH key를 생성하여 github 계정에 등록한 후에 사용해야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;맥이나 ubuntu의 로컬에서 작업한다고 가정한다. (서버나 컨테이너 등에서도 똑같은 방식으로 할 수 있다.)&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;우선, 이전에 만들어둔 적이 있는 경우에는 존재하는 파일을 그대로 사용할 수 있다. (있는 상태에서 keygen을 하게 되면 기존 파일을 덮어쓰므로 기존에 연결해두었던 곳에서 에러가 발생할 수 있으니 유의하자.)&lt;/p&gt;
&lt;pre id=&quot;code_1672758732194&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd ~/.ssh
ls&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'id_rsa', 'id_rsa.pub' 등의 파일이 없다면 key를 생성해주자.&lt;/p&gt;
&lt;pre id=&quot;code_1672758878923&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ssh-keygen -t rsa&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;key를 저장할 경로, passphrase(2차 비밀번호) 등을 입력하라고 나오는데, 원하면 해당 경로 또는 2차 비밀번호를 입력해준다. 그냥 엔터를 누르면 기본 경로('~/.ssh/id_rsa')에 2차 비밀번호 없이 만들어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ls를 실행해보면 'id_rsa', 'id_rsa.pub'이라는 파일이 생성되었을 것이다. 여기서 id_rsa는 개인(private) 키로, 비밀번호를 담고 있는 파일이며, id_rsa.pub은 공용(public) 키로, 외부에 등록되어 id_rsa를 갖는 유저의 접속을 통과시켜주는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인키는 보안 상 절대 공개되면 안되는 중요한 파일이다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 명령어를 통해 id_rsa.pub(공개 키)의 내용을 출력하고, 해당 내용을 복사해두자.&lt;/p&gt;
&lt;pre id=&quot;code_1672759167138&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cd ~/.ssh
cat id_rsa.pub&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 복사한 내용을 github 계정에 등록해주자. Github에 로그인한 후, profile 클릭 - settings에 들어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왼쪽 탭에서 'SSH and GPG keys'를 클릭하고, 'new SSH key' 버튼을 클릭한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;721&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8ouqE/btrVfkcrflW/aBos1VYrrLrzk0W61xcst1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8ouqE/btrVfkcrflW/aBos1VYrrLrzk0W61xcst1/img.jpg&quot; data-alt=&quot;new SSH key&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8ouqE/btrVfkcrflW/aBos1VYrrLrzk0W61xcst1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8ouqE%2FbtrVfkcrflW%2FaBos1VYrrLrzk0W61xcst1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;831&quot; height=&quot;566&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;721&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;new SSH key&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 원하는 Title을 입력하고, 'Key'부분에 아까 복사해뒀던 로컬의 id_rsa.pub 내용을 붙여넣고 SSH Key를 추가해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 다시 로컬에서 ssh를 사용하여 접속해보자. (본인의 github 아이디가 아니라 git@github.com을 입력해야 한다!)&lt;/p&gt;
&lt;pre id=&quot;code_1672759630477&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ssh -T git@github.com&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;914&quot; data-origin-height=&quot;128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ujGnB/btrVhS7CMS4/O3Vm1CHERH1kKgYKk10RSK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ujGnB/btrVhS7CMS4/O3Vm1CHERH1kKgYKk10RSK/img.jpg&quot; data-alt=&quot;연결 성공&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ujGnB/btrVhS7CMS4/O3Vm1CHERH1kKgYKk10RSK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FujGnB%2FbtrVhS7CMS4%2FO3Vm1CHERH1kKgYKk10RSK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;914&quot; height=&quot;128&quot; data-origin-width=&quot;914&quot; data-origin-height=&quot;128&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;연결 성공&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매번 접속할 때마다 패스워드를 입력하기 귀찮다면 ssh-agent에 키를 등록하자. ssh-agent는 백그라운드에서 ssh 인증 정보를 관리하는 agent이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 ssh-agent가 실행되어있는지 확인한다. (사실은 ssh-agent에 등록된 ssh 키 목록을 출력하는 명령어이다.)&lt;/p&gt;
&lt;pre id=&quot;code_1672759894965&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ssh-add -l&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'Connection refused' 에러가 발생하면 실행되어있지 않은 상태이고, ssh 키 목록 혹은 'The agent has no identities'라는 메시지가 뜨면 ssh-agent가 실행된 상태이다. ssh-agent를 실행하는 방법은 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1672760020113&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;eval &quot;$(ssh-agent -s)&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 ssh-add 명령어로 키를 등록한다.&lt;/p&gt;
&lt;pre id=&quot;code_1672760050711&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ssh-add ~/.ssh/id_rsa&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 push, clone 등을 할 때 패스워드를 물어보지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 SSH를 사용할 경우에는 remote에 추가해줄 때 다음과 같이 입력한다.&lt;/p&gt;
&lt;pre id=&quot;code_1672760384538&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git remote add [name] [ssh]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[name]에는 보통 'origin'을, [ssh]에는 repository에서 얻을 수 있는 ssh 주소를 입력한다. SSH 주소는 (git@github.com:사용자이름/repository이름) 형식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 로컬에서 처음으로 git initialze부터 push까지 진행한다고 해보자. ('origin'에 'git@github.com:jjuke/private_repo.git'이라는 ssh 주소의 원격 저장소에 연결하는 경우)&lt;/p&gt;
&lt;pre id=&quot;code_1677855701690&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git init
git add .
git commit -m &quot;First commit for private repo&quot;
git branch -M main # master가 아님에 유의!
git remote add origin git@github.com:jjuke/private_repo.git
git push -u origin main&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-01-04 at 00.41.11.jpg&quot; data-origin-width=&quot;909&quot; data-origin-height=&quot;256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c3fg4t/btrVfjLsZHc/HFHdFPKPIk4SXKikmw6vA1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c3fg4t/btrVfjLsZHc/HFHdFPKPIk4SXKikmw6vA1/img.jpg&quot; data-alt=&quot;Private repository에 git push 성공!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c3fg4t/btrVfjLsZHc/HFHdFPKPIk4SXKikmw6vA1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc3fg4t%2FbtrVfjLsZHc%2FHFHdFPKPIk4SXKikmw6vA1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;909&quot; height=&quot;256&quot; data-filename=&quot;CleanShot 2023-01-04 at 00.41.11.jpg&quot; data-origin-width=&quot;909&quot; data-origin-height=&quot;256&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Private repository에 git push 성공!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Git 활용 시 유용한 팁&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;이미&amp;nbsp;push된&amp;nbsp;파일&amp;nbsp;gitignore&amp;nbsp;적용하는&amp;nbsp;방법&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;git을 활용하여 프로젝트를 관리하다보면 아무 생각 없이 remote repository에 add, commit, push한 후에 &quot;아, 맞다. 이건 빼야하는데&quot; 라고 생각하며 복잡하게 수정해준 후에 다시 push해주는 귀찮은 과정을 거치곤 했다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그 대신에 간단하게 cache를 지워 다음과 같이 gitignore를 적용시켜줄 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1685001357486&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# .gitignore에 해당 파일(혹은 폴더) 추가 후
# 1. cache 제거
git rm --cached [무시할파일] # 파일인 경우
git rm -r --cached [무시할폴더] # 폴더인 경우

# 2. add &amp;amp; commit &amp;amp; push
git add .
git commit -m &quot;[message]&quot;
git push&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer Science, Programming/Git, Docker, Server, Linux</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/194</guid>
      <comments>https://jjuke-brain.tistory.com/entry/VSCode%EC%97%90%EC%84%9C-github-%EC%97%B0%EB%8F%99%ED%95%98%EA%B3%A0-%ED%8E%B8%ED%95%98%EA%B2%8C-%EB%B2%84%EC%A0%84-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0#entry194comment</comments>
      <pubDate>Tue, 22 Nov 2022 19:56:30 +0900</pubDate>
    </item>
    <item>
      <title>Transformers in Vision - (1) Attention &amp;amp; Transformer</title>
      <link>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Transformer가 computer vision에서 어떻게 쓰였는지, 관련 모델이 어떻게 발전하고 있는지 여러 포스팅에 걸쳐서 알아보고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 가장 중요한 기초 내용인 attention과 transformer에 대해 알아볼 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Transformer는 흔히 딥러닝의 기초라고 말하는 CNN, RNN 등과 같이 neural network 중 하나인데, 조금 다른 형태를 갖는다. 이 구조와 동작 원리를 이해하기 위해 필요한 개념이 attention이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;book-toc&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차&lt;/p&gt;
&lt;ul id=&quot;toc&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;/ul&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 대표적인 neural network인 CNN, GNN, RNN의 inductive bias를 정리해보자. &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Inductive bias&lt;/span&gt;란, &lt;span style=&quot;color: #ee2323;&quot;&gt;딥러닝 모델이 본 적 없는 데이터에 대해서도 좋은 성능을 보이도록(일반화 성능이 좋도록) 하는 추가적인 가정(additional assumption)의 집합&lt;/span&gt;이다. 좀 더 쉽게 말하자면, 모델이 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;본 적 없는 데이터를 입력받았을 때 그 데이터에 대한 예측을 하기 위해 갖고 있는,&lt;/span&gt; 학습 과정에서 습득하는 것이 아닌 아키텍쳐(CNN, RNN, MLP 등)가 본질적으로 갖고 있는 특성&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Inductive bias에는 크게 relational inductive bias와 non-relational inductive bias가 있는데, 일반적인 inductive bias는 relational inductive bias를 말한다. Relational inductive bias는 &lt;span style=&quot;color: #ee2323;&quot;&gt;입력 element와 출력 element 간의 관계에 대한 inudctive bias&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 알아본 대표적인 neural network들의 inductive bias는 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Convolutional Neural Networks (CNN)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Locality Principle : Image 전체가 아닌 kernel(filter) size 만큼의 patch(일부)만 고려한다.&lt;/li&gt;
&lt;li&gt;Spatial Invariance : Image 내에서 object의 위치가 변해도(ex. translation) 결과는 바뀌지 않는다. (Translation equivalence)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Graph Neural Networks (GNN)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Permutation Invariance : Node의 순서가 바뀌어도 output(node embedding, graph embedding 등)은 그대로이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reccurent Neural Network (RNN)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Sequentiality : 순서(element)가 바뀌었을 때, output이 바뀌는 것을 고려한다. 예를 들어, 단어의 관점에서 단어의 순서가 바뀌었을 때 문장의 의미가 바뀐다.&lt;/li&gt;
&lt;li&gt;Temporal Invariance : 순서(이 때에는 sequence data의 index를 말함)가 바뀌어도 output이 바뀌지 않는다. 예를 들어, 문장의 관점에서, 문장의 위치가 바뀌어도 문장의 의미는 변하지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 학습 데이터가 이미지 데이터인 경우, CNN을 활용하게 되면 spatial invariance 덕분에 새로운 데이터에서는 object가 어떤 위치에 있던 간에 detection을 수행할 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Enoder-Decoder Architecture&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Sequence-to-sequence problem(예를 들어 기계 번역)을 다룰 때, input data와 output data의 length는 정해져있지 않다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 데이터를 다루는 데 효율적인 것은 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;encoder-decoder 아키텍쳐&lt;/span&gt;이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Encoder : 다양한 length의 sequence를 입력으로 받아 어떤 state를 출력한다.&lt;/li&gt;
&lt;li&gt;Decoder : encoding된 결과인 &lt;span style=&quot;color: #ee2323;&quot;&gt;state와&lt;/span&gt; target sequence의 &lt;span style=&quot;color: #ee2323;&quot;&gt;context&lt;/span&gt;를 입력으로 받아 subsequent result(target sequence)를 예측(생성)한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1244&quot; data-origin-height=&quot;186&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4Lr1w/btrRH6BSLNm/afw5KSBV3e1WpbgNFjUj11/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4Lr1w/btrRH6BSLNm/afw5KSBV3e1WpbgNFjUj11/img.jpg&quot; data-alt=&quot;Encoder-Decoder Architecture&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4Lr1w/btrRH6BSLNm/afw5KSBV3e1WpbgNFjUj11/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4Lr1w%2FbtrRH6BSLNm%2Fafw5KSBV3e1WpbgNFjUj11%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;840&quot; height=&quot;126&quot; data-origin-width=&quot;1244&quot; data-origin-height=&quot;186&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Encoder-Decoder Architecture&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 state는 input의 정보를 압축한(compressed information) 개념으로 볼 수 있다. 즉, encoder는 data compression을 수행한다고 볼 수 있다. 이렇게 state가 포착하는 information을 feature information이라 하고, encoding 과정은 아래와 같이 수식으로 나타낼 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \underset{\theta}{\min} \lVert \mathbf{x} - f_\theta (\mathbf{x}) \rVert \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1047&quot; data-origin-height=&quot;456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4jaf9/btrRMbvDx2T/cdev0sXvbpeRJK7QnI17U1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4jaf9/btrRMbvDx2T/cdev0sXvbpeRJK7QnI17U1/img.jpg&quot; data-alt=&quot;Denoising&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4jaf9/btrRMbvDx2T/cdev0sXvbpeRJK7QnI17U1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4jaf9%2FbtrRMbvDx2T%2Fcdev0sXvbpeRJK7QnI17U1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;752&quot; height=&quot;328&quot; data-origin-width=&quot;1047&quot; data-origin-height=&quot;456&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Denoising&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, decoder는 state에 noise를 추가하여 subsequent result를 출력하는데, 이 최종 결과를 주어진 sequence와 비교하여 그 차이를 줄이는 것이 encoder-decoder architecture의 목적이다. 이렇게 최종 결과와 입력의 차이를 줄여나가는 과정을 denoising이라 하고, 아래 수식으로 표현한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \underset{\theta}{\min} \lVert \mathbf{x} - f_\theta (\mathbf{x} + \text{noise} ) \rVert \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, input이 &quot;My name is Sangjune Park.&quot;(영어)를 &quot;제 이름은 박상준입니다.&quot;(한국어)로 해석하는 machine translation task에서 encoder-decoder architecture는 아래와 같은 과정으로 동작한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Encoder : 입력 문장을 state(feature)로 인코딩한다. 여기서는 state가 semantic information을 포착한다.&lt;/li&gt;
&lt;li&gt;Decoder : Feature를 사용하여 해석된 문장을 생성한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;RNN-based Encoder-Decoder&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀 더 자세히 알아보자. RNN(LSTM, GRU 포함) 기반의 encoder-decoder 아키텍쳐를 살펴보면, encoder에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;모든 time step의 input sequence&lt;/span&gt;를 입력으로 받아 hidden state로 변형한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{h}_t = f(\mathbf{x}_t, \mathbf{h}_{t-1} ) \)&lt;br /&gt;\( \mathbf{c} = q(\mathbf{h}_1, \cdots, \mathbf{h}_T ) \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(q\) : (모든 time step의) hidden state를 context로 mapping하는 함수&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, decoder에서는 이전 hidden state와 context를 입력으로 받아 새로운 state를 만든다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{s}_\tau = g (y_{\tau - 1}, \mathbf{c}, \mathbf{s}_{\tau - 1} ) \)&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;462&quot; data-origin-height=&quot;251&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kA42L/btrRMKxwS7V/Q24hZTyFhOFzaSJSdDckck/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kA42L/btrRMKxwS7V/Q24hZTyFhOFzaSJSdDckck/img.jpg&quot; data-alt=&quot;RNN-based Encoder-Decoder Architecture&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kA42L/btrRMKxwS7V/Q24hZTyFhOFzaSJSdDckck/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkA42L%2FbtrRMKxwS7V%2FQ24hZTyFhOFzaSJSdDckck%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;462&quot; height=&quot;251&quot; data-origin-width=&quot;462&quot; data-origin-height=&quot;251&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;RNN-based Encoder-Decoder Architecture&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;말로 설명하면 같은 state를 말하는 듯 하지만, encoder에서의 state와 decoder에서의 state는 다르다. (h와 s가 같은 것이 바로 RNN이다!) 위 그림에서와 같이 encoder에서 생성한 hidden state 정보를 포함하는 'context'로 decoder의 state를 update하는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서의 context는 모든 time step에 대한 state를 똑같이 고려했지만, transformer에서는 주의를 기울일 만한 hidden state에 더 weight를 주어(attention 개념)서 context를 형성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;box-sizing: border-box; margin-bottom: 5px; border-right-width: 0px; word-spacing: 3px; margin-top: 5px; border-bottom: #698be2 2px solid; border-left: #698be2 12px solid; letter-spacing: 1px; line-height: 1.5; border-top-width: 0px; margin-right: 0px; border-image: initial; padding: 3px 5px 3px 5px;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Self-attention and Transformer&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Attention&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로, 사람은 주어진 이미지에서 object가 어떤 class인지 예측할 때, 특정 부위를 통해 특징을 구별하고, class를 예측한다. 예를 들어, 다음 사진에 나온 동물이 어떤 동물인지 맞혀보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;329&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYsYOu/btrRK2FHg2X/9knl2FVux5SZ51iJ0J5DL0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYsYOu/btrRK2FHg2X/9knl2FVux5SZ51iJ0J5DL0/img.jpg&quot; data-alt=&quot;What is this animal?&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYsYOu/btrRK2FHg2X/9knl2FVux5SZ51iJ0J5DL0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYsYOu%2FbtrRK2FHg2X%2F9knl2FVux5SZ51iJ0J5DL0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;786&quot; height=&quot;265&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;329&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;What is this animal?&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사람은 위 사진의 빨간 box와 같이, '큰 눈', '뾰족한 귀', '동그란 발' 등의 특정 부위에 더 주의(attention)를 기울인다(prioritize). 이를 통해 효과적으로 object를 인식하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 모델링한 것이 바로 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;attention module&lt;/span&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Attention은 input에 대한 '&lt;span style=&quot;color: #ee2323;&quot;&gt;pooling&lt;span style=&quot;color: #333333;&quot;&gt;'(with bias alignment)으&lt;/span&gt;&lt;/span&gt;로 설계가 가능하다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Attention layer에 입력으로 들어오는 요소들은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Query : volitional cue \( \mathbf{q} \in \mathbb{R}^{d_q} \)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;현재 (관심 있는) element의 representation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Keys : list of cues \(\mathbf{k} \in \mathbb{R}^{d_k} \)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Context(input sequence) 안에 있는 element들의 representation (Element 각각이 query와 얼마나 관련있는지 구하기 위한 값)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Values : Feature representation \( \mathbf{v} \in \mathbb{R}^{d_v} \)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Context(input sequence)에 있는 element들의 representation (Element 각각을 나타내는 값으로, attention layer의 결과를 구하기 위해 최종적으로 weighted sum을 하는데, 이 때 weight가 query와의 관련성을 나타내는 attention score)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-11-21 at 15.59.22.jpg&quot; data-origin-width=&quot;611&quot; data-origin-height=&quot;347&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOBhnm/btrRHC8NUZk/GZyaNQqpxxvNWFToc4ctd1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOBhnm/btrRHC8NUZk/GZyaNQqpxxvNWFToc4ctd1/img.jpg&quot; data-alt=&quot;Attention Module&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOBhnm/btrRHC8NUZk/GZyaNQqpxxvNWFToc4ctd1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOBhnm%2FbtrRHC8NUZk%2FGZyaNQqpxxvNWFToc4ctd1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;611&quot; height=&quot;347&quot; data-filename=&quot;CleanShot 2022-11-21 at 15.59.22.jpg&quot; data-origin-width=&quot;611&quot; data-origin-height=&quot;347&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Attention Module&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 attention mechanism은 &lt;span&gt;주어진 query에 대해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;attention pooling(attention weight를 사용한 pooling)&lt;/span&gt;을 통해 representation feature 중에서 bias selection을 한다. 이 과정을 수식으로 나타내면 다음과 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( f \left( \mathbf{q}, \left\{ (\mathbf{k}_i, \mathbf{v}_i \right\}_{i=1}^m \right) = \sum\limits_{i=1}^m \alpha (\mathbf{q}, \mathbf{k}_i) \mathbf{v}_i \)&lt;br /&gt;\( \alpha (\mathbf{q}, \mathbf{k}_i) = \text{softmax} \left( a(\mathbf{q}, \mathbf{k}_i) \right) = \cfrac{\text{exp}\left( a(\mathbf{q}, \mathbf{k}_i) \right)}{\sum\limits_{j=1}^m \text{exp} \left( a(\mathbf{q}, \mathbf{k}_j) \right)} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\(a\) : &lt;span style=&quot;color: #ee2323;&quot;&gt;attention scoring function&lt;/span&gt;으로, query \(\mathbf{q}\)가 i번째 key \(\mathbf{k}_i\)와 얼마나 비슷한지를 나타내는 weight이다. Attention scoring function에 활용되는 함수는 아래와 같다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Additive pooling&lt;/li&gt;
&lt;li&gt;Scaled dot product&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;\(\alpha\) : &lt;span style=&quot;color: #ee2323;&quot;&gt;attention weight&lt;/span&gt;로, 총 m개의 key 중에서 i번째 key와 얼마나 비슷한지(관련 있는지)를 0~1 사이의 값으로 나타낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, query와 i번째 key가 얼마나 비슷한지 attention weight를 구하고, i번째 value를 곱한 값들을 모두 더하여 output을 구하는 것이 일반적인 attention mechanism이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Attention scoring function (\(a\))에 활용하는 함수를 좀 더 자세히 살펴보자.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Additive Pooling ( \(d_k \neq d_q\)일 때 사용)&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \begin{align*} a(\mathbf{q}, \mathbf{k}) &amp;amp;= \left\langle \mathbf{w}, \text{tanh}(\mathbf{W}_q \mathbf{q} + \mathbf{W}_k \mathbf{k} ) \right\rangle \\ &amp;amp;= \left\langle \mathbf{w}, \text{tanh}([\mathbf{W}_q, \mathbf{W}_k] [\mathbf{q}, \mathbf{k}]) \right\rangle \end{align*} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\( \mathbf{w} \in \mathbb{R}^{d_h} \)&lt;/li&gt;
&lt;li&gt;\( \mathbf{W}_q \in \mathbb{R}^{d_h \times d_q} \)&lt;/li&gt;
&lt;li&gt;\( \mathbf{W}_k \in \mathbb{R}^{d_h \times d_k} \)&lt;/li&gt;
&lt;li&gt;대괄호 (\([]\))는 concatenation을 뜻한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 attention scoring function은 LSTM의 memory gate와 비슷한 형태를 갖고 있다. 여기서 \(a\)는 learnable attention weight이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Scaled Dot-product (\(d_k = d_q = d\)인 경우 사용 가능)&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( a(\mathbf{q}, \mathbf{k}) = \cfrac{\left\langle \mathbf{q}, \mathbf{k} \right\rangle}{\sqrt{d}} \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Key와 query의 차원이 같은 경우에는 단순히 그 차원으로 normalize한 dot product(inner product)를 사용할 수 있다. 여기서는 a가 learnable parameter가 아니고, \(\mathbf{q, k}\)가 정해지면 값이 정해진다.(deterministic)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Bahdanau Attention and Self-attention&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;위에서 알아본 RNN 기반 encoder-decoder 아키텍쳐에서는 decoder의 각 step에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;모든 input을 인코딩한 context&lt;/span&gt; \(\mathbf{c}\)를 사용했다. 이것을 attention 식에 대입해보면, context는 다음과 같이 구한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{c}_\tau = \sum\limits_{t=1}^T \alpha (\mathbf{s}_{\tau - 1}, \mathbf{h}_t) \mathbf{h}_t \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Attention mechanism에서의 식과 비교해보면, \(\mathbf{s}_{\tau - 1}\)이 query, \(\mathbf{h}_t\)는 key이자 value라는 것을 알 수 있다. 이 방법은 decoder의 계산 과정에 attention을 적용한 것이며, encoder에는 attention을 사용하지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-11-21 at 16.26.34.jpg&quot; data-origin-width=&quot;681&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dZoeWY/btrRKLjVf3u/VkWZPbkgnWPMGzhplXt1vK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dZoeWY/btrRKLjVf3u/VkWZPbkgnWPMGzhplXt1vK/img.jpg&quot; data-alt=&quot;Bahdanau Attention&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dZoeWY/btrRKLjVf3u/VkWZPbkgnWPMGzhplXt1vK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdZoeWY%2FbtrRKLjVf3u%2FVkWZPbkgnWPMGzhplXt1vK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;640&quot; height=&quot;293&quot; data-filename=&quot;CleanShot 2022-11-21 at 16.26.34.jpg&quot; data-origin-width=&quot;681&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Bahdanau Attention&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Encoder에 attention을 적용하기 위해서는 self-attention 개념을 알아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Self-attention&lt;/span&gt;이란, &lt;span style=&quot;color: #ee2323;&quot;&gt;attention mechanism에서의 query, key, value 모두에 input sequence \(\mathbf{x}\)를 적용하는 것&lt;/span&gt;이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( f \left( \mathbf{q}, \left\{ ( \mathbf{k}_i, \mathbf{v}_i ) \right\}_{i=1}^m \right) = \sum\limits_{i=1}^m \alpha (\mathbf{q}, \mathbf{k}_i)\mathbf{v}_i \)&lt;br /&gt;\( \rightarrow \; f \left( \mathbf{x}, \left\{ ( \mathbf{x}_i, \mathbf{x}_i ) \right\}_{i=1}^n \right) = \sum\limits_{i=1}^n \alpha (\mathbf{x}, \mathbf{x}_i)\mathbf{x}_i \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, 이러한 &lt;span style=&quot;color: #ee2323;&quot;&gt;self-attention을 multi-head로, 즉 서로 다른 m개의 weight들에 대해 진행하는 것&lt;/span&gt;을 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;multi-head attention (MHA)&lt;/span&gt;라 한다. 이 과정은 각 head에 대해서 &lt;span style=&quot;color: #ee2323;&quot;&gt;병렬 계산이 가능&lt;/span&gt;하다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{h}_m = f \left( \mathbf{W}_m^{(q)} \mathbf{x}, \left\{ \mathbf{W}_m^{(k)} \mathbf{x}_i, \mathbf{W}_m^{(v)} \mathbf{x}_i \right\}_{i=1}^n \right) = \sum\limits_{i=1}^n \alpha \left( \mathbf{W}_m^{(q)} \mathbf{x}, \mathbf{W}_m^{(k)} \mathbf{x}_i \right) \mathbf{W}_m^{(v)} \mathbf{x}_i \)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Comparing CNN, RNN, and Self-attention&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;CNN, RNN, Self-attention을 computational complexity(CC), sequential operations(SO), maximum path lengths(MPL)에 대해 비교해보자. 각 metric은 다음과 같은 개념을 갖는다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CC : 계산량&lt;/li&gt;
&lt;li&gt;SO : 높을수록 parallel computation에 부적합함. 즉, 낮을수록 GPU 계산에 적합함&lt;/li&gt;
&lt;li&gt;MPL : 높을수록 long-range dependency를 낮춤 (RNN의 이러한 단접을 보완한 것이 LSTM, GRU)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2022-11-21 at 16.42.01.jpg&quot; data-origin-width=&quot;1308&quot; data-origin-height=&quot;339&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bq3e9T/btrRK1Uxyhj/XhDXQITV80Mwx2Oz5pEZu0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bq3e9T/btrRK1Uxyhj/XhDXQITV80Mwx2Oz5pEZu0/img.jpg&quot; data-alt=&quot;CNN vs RNN vs Self-attention&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bq3e9T/btrRK1Uxyhj/XhDXQITV80Mwx2Oz5pEZu0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbq3e9T%2FbtrRK1Uxyhj%2FXhDXQITV80Mwx2Oz5pEZu0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1308&quot; height=&quot;339&quot; data-filename=&quot;CleanShot 2022-11-21 at 16.42.01.jpg&quot; data-origin-width=&quot;1308&quot; data-origin-height=&quot;339&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CNN vs RNN vs Self-attention&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Self-attention은 병렬 계산과 sequential modeling에 최적화되어있는 반면, &lt;span style=&quot;color: #ee2323;&quot;&gt;input sequence가 길어짐에 따라 계산 속도가 확연히 느려진다&lt;/span&gt;는 단점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Positional Encoding&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Self-attention은 permutation invariant 성질을 갖는다. 왜냐하면 attention weight를 구하는 과정에서 softmax를 사용하는데, softmax는 순서가 바뀌어도 결과가 같기 때문이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이에 따라 sequence의 순서 정보(sequentiality)를 줄 수가 없는데, 이를 해결하기 위해 positional encoding을 사용한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Positional encoding&lt;/span&gt;이란, &lt;span style=&quot;color: #ee2323;&quot;&gt;self-attention에 위치(순서) 정보를 주기 위한 개념&lt;/span&gt;이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;입력 sequence \(\mathbf{x}_i\)에 다음과 같은 positional encoding \(\mathbf{P}\)를 적용한다. (아래는 'attention is all you need' 논문에서 제안한 방법이고, task에 따라 다른 방법을 적용할 수도 있다.)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;\( \mathbf{x}_i \rightarrow \mathbf{P}(\mathbf{x}_i) = \begin{cases} x_j + \sin \left( \cfrac{i}{10000^{j/d}} \right) &amp;amp; \quad \text{where } j \text{ is even} \\ x_j + \cos \left( \cfrac{i}{10000^{(j-1)/d}} \right) &amp;amp; \quad \text{where } j \text{ is odd} \end{cases} &amp;nbsp;\)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;box-sizing: border-box; font-family: Arial, 돋움, Dotum, AppleGothic, sans-serif; border-width: 0px 0px 2px 10px; word-spacing: 3px; border-bottom-style: solid; border-bottom-color: #01DFA5; padding: 3px 5px; border-left-style: solid; border-left-color: #01DFA5; margin: 5px 0px; letter-spacing: 1px; line-height: 1.5; border-image: initial;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-size: 21px;&quot;&gt;&lt;b&gt;Transformer&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;결국 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;Transformer&lt;/span&gt;는 RNN 기반 encoder, decoder를 전혀 사용하지 않고, &lt;span style=&quot;color: #ee2323;&quot;&gt;attention module을 encoder에도 적용한 아키텍쳐&lt;/span&gt;이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CleanShot 2023-07-25 at 15.48.50@2x.png&quot; data-origin-width=&quot;1854&quot; data-origin-height=&quot;2656&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEkMJw/btsoYVtCTn9/5EetBHPC7r7hzhaVTNsQgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEkMJw/btsoYVtCTn9/5EetBHPC7r7hzhaVTNsQgk/img.png&quot; data-alt=&quot;Transformer Architecture&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEkMJw/btsoYVtCTn9/5EetBHPC7r7hzhaVTNsQgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEkMJw%2FbtsoYVtCTn9%2F5EetBHPC7r7hzhaVTNsQgk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;669&quot; height=&quot;958&quot; data-filename=&quot;CleanShot 2023-07-25 at 15.48.50@2x.png&quot; data-origin-width=&quot;1854&quot; data-origin-height=&quot;2656&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Transformer Architecture&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Transformer에는 크게 5가지 구성요소가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. Positional Encoding&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Positional encoding은 Transformer의 부족한 inductive bias를 보완해주는 역할을 한다. Transformer는 input sequence의 정확한 위치(RNN의 time step)를 알 수가 없는데, 이를 positional encoding을 통해 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. Multi-head Self-attention&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Decoder에서 첫 multi-head attention layer는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;masked multi-head attention&lt;/span&gt;을 이용한다. 이는 transformer의 경우 전체 time step 모두를 입력으로 받기 때문에, self-attention score 값을 행렬로 계산할 때 query의 시점보다 미래의 key 값 또한 곱해져 계산이 되기 때문에(행렬의 대각선 윗부분), 이 부분을 사용하면 미래를 이미 알고있는 것이 되어버린다. 이를 막기 위해 아래와 같이 행렬의 대각선 윗 부분 계산 값을 무시하는 과정(making)을 거친다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmgyEu/btrRMKLlGVd/VilfuyhGMTiEYbFLn0Iaok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmgyEu/btrRMKLlGVd/VilfuyhGMTiEYbFLn0Iaok/img.png&quot; data-alt=&quot;Masked self-attention 계산 과정, 출처 :&amp;amp;amp;nbsp;https://aimb.tistory.com/182&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmgyEu/btrRMKLlGVd/VilfuyhGMTiEYbFLn0Iaok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmgyEu%2FbtrRMKLlGVd%2FVilfuyhGMTiEYbFLn0Iaok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;763&quot; height=&quot;228&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;382&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Masked self-attention 계산 과정, 출처 :&amp;amp;nbsp;https://aimb.tistory.com/182&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;329&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bk8yE3/btrRMWLC8ml/ktS6U7lR1Gei5n6z1PDwz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bk8yE3/btrRMWLC8ml/ktS6U7lR1Gei5n6z1PDwz0/img.png&quot; data-alt=&quot;Masking example, 출처 :&amp;amp;amp;nbsp;https://wikidocs.net/156986&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bk8yE3/btrRMWLC8ml/ktS6U7lR1Gei5n6z1PDwz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbk8yE3%2FbtrRMWLC8ml%2FktS6U7lR1Gei5n6z1PDwz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;526&quot; height=&quot;220&quot; data-origin-width=&quot;787&quot; data-origin-height=&quot;329&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Masking example, 출처 :&amp;amp;nbsp;https://wikidocs.net/156986&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;b&gt;3. Multi-head Cross-attention&lt;/b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LRLwT/btsoU7BoHJi/o24fZxQsBmPuf6X8Kx3d2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LRLwT/btsoU7BoHJi/o24fZxQsBmPuf6X8Kx3d2K/img.png&quot; data-alt=&quot;Cross attention in Transformer&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LRLwT/btsoU7BoHJi/o24fZxQsBmPuf6X8Kx3d2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLRLwT%2FbtsoU7BoHJi%2Fo24fZxQsBmPuf6X8Kx3d2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;794&quot; height=&quot;425&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Cross attention in Transformer&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cross-attention이란, 서로 다른 두 개의 sequence를 다루는 attention module이다. 즉, 위 그림처럼 key와 value의 sequence와 query의 sequence가 다를 때의 attention 모듈이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. Residual Connection + Layer Normalization&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5. Positionwise FeedForward Network&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 component에 대한 자세한 설명은 &lt;a href=&quot;https://jjuke-brain.tistory.com/entry/%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-2017-NIPS-Attention-is-All-You-Need-aka-Transformer-2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Attention is all you need 리뷰&lt;/a&gt; 내용을 참조하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Studies/Knowledges</category>
      <author>JJukE</author>
      <guid isPermaLink="true">https://jjuke-brain.tistory.com/193</guid>
      <comments>https://jjuke-brain.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D-%EA%B8%B0%EC%B4%88-Attention-Transformer#entry193comment</comments>
      <pubDate>Mon, 21 Nov 2022 15:36:51 +0900</pubDate>
    </item>
  </channel>
</rss>