<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>minjung-s.log</title>
        <link>https://velog.io/</link>
        <description>안녕나는민정</description>
        <lastBuildDate>Thu, 09 Jun 2022 16:21:27 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>minjung-s.log</title>
            <url>https://images.velog.io/images/minjung-s/profile/b6687f89-0980-406a-9402-1225a353fd3e/social.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. minjung-s.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/minjung-s" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[논문리뷰]StyleGAN : A Style-Based Generator Architecture for Generative Adversarial Networks]]></title>
            <link>https://velog.io/@minjung-s/%EB%85%BC%EB%AC%B8%EB%A6%AC%EB%B7%B0StyleGAN-A-Style-Based-Generator-Architecture-for-Generative-Adversarial-Networks</link>
            <guid>https://velog.io/@minjung-s/%EB%85%BC%EB%AC%B8%EB%A6%AC%EB%B7%B0StyleGAN-A-Style-Based-Generator-Architecture-for-Generative-Adversarial-Networks</guid>
            <pubDate>Thu, 09 Jun 2022 16:21:27 GMT</pubDate>
            <description><![CDATA[<p>이번에 리뷰할 논문은  2019 CVPR에 발표된 &quot;<a href="https://arxiv.org/abs/1812.04948">A Style-Based Generator Architecture for Generative Adversarial Networks</a>&quot;입니다. 흔히 <strong>StyleGAN</strong>으로 불리는 모델입니다. 논문에서 제안된 style-based generator만으로 기본적인 discriminator나 loss에도 robust하게 동작할 수 있습니다. 
<em>PGGAN을 baseline으로 사용하였기 때문에, 결과실험을 할때에는 PGGAN의 discriminator에 WGAN-GP를 사용하였고, 일부 데이터셋에서는 non-saturation loss와 R1 regularization을 사용하였습니다.</em></p>
<p>image synthesis task에서 정말 많이 등장하는 모델인데요, PGGAN,Style transfer 등 사전지식을 필요로하는 논문입니다. Style transfer에서 흔히 사용되는 AdaIN에 대한 포스팅을 먼저 보시고, 본 포스팅을 보시는 것을 추천드립니다.</p>
<h1 id="motivation">Motivation</h1>
<h1 id="contribution">Contribution</h1>
<blockquote>
<ol>
<li>본 논문에서 제안된 <strong>style-based generator</strong>로 고해상도 이미지를 높은 퀄리티로 생성합니다.</li>
<li>Disentanglement를 측정하는 지표 두가지를 제안합니다.</li>
<li>1024x1024 고해상도 사람얼굴 데이터셋 &quot;FFHQ&quot; 발표</li>
</ol>
</blockquote>
<h1 id="style-based-generator">Style-based generator</h1>
<p>앞서 말씀드렸듯이, StlyeGAN논문에서는 Discriminator나 loss에 관한 설명은 자세하게 나와있지 않고 <strong>style-based generator</strong>에 대한 설명이 대부분입니다. Style-based generator를 사용한 GAN구조를 StyleGAN이라고 합니다. generator를 제외한 다른 부분은 대체로 PGGAN의 구조를 그대로 사용합니다.(discriminator&amp;loss)</p>
<blockquote>
<p><strong>PGGAN</strong>
baseline으로 사용된 PGGAN을 간단하게 설명하자면, 학습과정에서 layer를 추가하는 방식의 고해상도 이미지 생성에 잘 동작하는 GAN model입니다.</p>
</blockquote>
<figure>
    <img src="https://images.velog.io/images/minjung-s/post/dadb3dc0-0b8e-461e-8f06-2dbeece3e392/image.png">   
    <figcaption><span style="color:#A9A9A9">출처 :https://towardsdatascience.com/explained-a-style-based-generator-architecture-for-gans-generating-and-tuning-realistic-6cb2be0f431</span></figcaption>
</figure>
고해상도 이미지는 high dimension이기 때문에, Generator보다 Discriminator학습이 쉬워집니다. real과 fake를 너무 구분하기 쉽다는 의미입니다. 또한 메모리 제약과 같은 computation 문제도 있습니다.
PGGAN은 이를 해결하기 위해 <b>학습을 하면서 4x4 reolution부터 1024x1024까지 점차 키워나갑니다.</b> (Discriminator와 Generator 모두) 4x4와 같은 low resolution에서는 large scale의 feature들을 학습하고, high resolution으로 갈수록 세부적인 feature들을 학습하게 됩니다. 이렇게 <b>점진적으로 layer를 추가하면서 학습하기 때문에 안정적으로 high resolution image를 만들 수 있습니다.</b><br>
<del>WGAN_GP에 대한 내용은 "WGAN,WGAN-GP"포스팅을 참고하시기 바랍니다.</del>

<figure>
    <img src="https://images.velog.io/images/minjung-s/post/d90ca61b-9f62-471a-8895-dadcf12bce3a/image.png">출처 : StyleGAN paper</span></figcaption>
</figure>


<p>style-based generator는 크게 두가지 network로 이루어져있습니다. </p>
<ul>
<li><strong>1. Mapping Network</strong></li>
<li><strong>2. Synthesis Network</strong></li>
</ul>
<p><em>본 논문은 baseline인 PGGAN의 generator에 StyleGAN의 사용된 기능을 추가하면서 비교합니다.</em></p>
<figure>
    <img src="https://images.velog.io/images/minjung-s/post/ee84f98c-307c-4981-8cda-a0546a54805c/image.png">   
    <figcaption><span style="color:#A9A9A9">출처 :StyleGAN paper</span></figcaption>
</figure>



<h2 id="1-mapping-network">1. Mapping Network</h2>
<p>baseline인 PGGAN의 문제는 세부적인 attribute를 조절하지 못한다는 것입니다. 이 단점을 해결하기 위해 latent sapce $Z$(Gaussian)에서 samping한 $z$를 intermediate latent space $W$의 $w$로 mapping해주는 <strong>non-linear mapping network</strong>를 사용합니다.</p>
<figure>
    <img src="https://images.velog.io/images/minjung-s/post/559b4f8c-d798-4f8e-844b-227dfa92094f/image.png">   
    <figcaption><span style="color:#A9A9A9">출처 :https://towardsdatascience.com/explained-a-style-based-generator-architecture-for-gans-generating-and-tuning-realistic-6cb2be0f431</span></figcaption>
</figure>

<p>이 mapping network는 8-layer MLP로 구성되고, 512차원 <strong>z</strong>를 512차원 <strong>w</strong>로 mapping해주는 역할을 합니다. 이러한 mapping network를 사용하는 이유는 feature들의 <strong>disentanglement</strong>를 보장하기 위해서 입니다. <span style="color:#A9A9A9">factor of variation become <strong>more linear</strong></span></p>
<p>이와같이 구조는 간단한데요, 이 mapping network가 쓰이는 이유를 알아보겠습니다. </p>
<h3 id="disenstanglement란">Disenstanglement란?</h3>
<p>entanglement를 직역하면 &#39;꼬여있다&#39;라는 의미입니다. 반대로 disentanglement는 &#39;잘 분리되어있다&#39;로 해석할 수 있습니다. GAN에서 사용되는 disentanglement도 어떤 attribute를 잘 나눌 수 있는 것을 의미합니다.
논문에서 말하듯, disentanglement에서는 많은 정의가 있습니다. &#39;각 attribute가 잘 분리 된다&#39;, &#39;content와 style이 잘 분리된다&#39;등 범용적으로 쓰이는 표현입니다. <strong>disentanglement의 공통된 정의는 &quot;latent space가 linear subspace로 구성된 다&quot;는 것 입니다.</strong>
<span style="color:#A9A9A9">There are various definitions for disentanglement, but a common goal is a <strong>latent space that consists of linear subspaces</strong>, each of which controls one factor of variation.</span></p>
<figure>
    <img src="https://images.velog.io/images/minjung-s/post/298e92de-f8d1-4f8e-beef-617519c0f311/image.png">   
    <figcaption><span style="color:#A9A9A9">출처 :coursera - Build Basic Generative Adversarial Networks (GANs), 'Challenges with Controllable Generation'</span></figcaption>
</figure>

<p>만약 random vector $z$로부터 생성한 이미지가 왼쪽의 수염이 없는 여자라고 할 때, 수염을 추가하고싶고 $z_1$축을 조절하여 수염을 추가할 수 있는 random vector를 찾았다고 가정해보겠습니다. 이 여성의 그림에 수염을 추가할 수 있을까요? 
물론 가능합니다. 그러나, 기존의 GAN같이 entangle되어있다면 오랜쪽 아래의 수염을 가진 남성의 사진이 나오게 됩니다. 즉 수염을 추가한 것 뿐만 아니라 다른 feature들이 동시에 변한 것입니다. 이는 수염이라는 feature에 다른 feature들이 correlated되어있기 때문입니다. </p>
<figure>
    <img src="https://images.velog.io/images/minjung-s/post/0aacd44e-9378-471b-9c0c-cdfd60524901/image.png">   
    <figcaption><span style="color:#A9A9A9">출처 :coursera - Build Basic Generative Adversarial Networks (GANs), 'Challenges with Controllable Generation'</span></figcaption>
</figure>

<p>수염(beard)를 조작하였을 때, 이 특징과 연관된 &#39;머리&#39;,&#39;눈매&#39;등이 함께 바뀌는 것을 보면 이들은 서로 entangle되어있다라고 할 수 있습니다. 내가 원하는 feature들 이외에 나머지는 고정한 상태로 조작하고 싶다면, 축을 disentangle하게 만들면 됩니다. 
(모든 attribute를 disentangle하게 하는 것은 거의 불가능하지만, 최대한 less entanglement하도록 만들 수 있겠죠)</p>
<p><span style="color:#CD2E57">그렇다면 왜 latent space $W$에서 바로 이미지를 생성하는 것이 아닌, intermediate latent space $W$로 mapping해야 할까요??</span></p>
<figure>
    <img src="https://images.velog.io/images/minjung-s/post/e1dee4b7-3dea-4ac3-86a8-6c74a7b0f9ff/image.png">   
    <figcaption><span style="color:#A9A9A9">출처 :StyleGAN paper</span></figcaption>
</figure>

<p>위 그림의 $(a)$를 실제 데이터의 분포라고 하고 가로축은 성별에 대한 축, 세로축은 머리길이에 대한 축이라고 하겠습니다.
<img src="https://images.velog.io/images/minjung-s/post/e6367b47-18f4-4bbc-b53c-5c4d5b497ea0/image.png" alt="">
만약 &quot;머리가 짧은 남성&quot;에서 &quot;머리가 긴 여성&quot;으로 interpolation을 점점 수행한다면, 남성에서 여성으로 성별이 바뀌면서 머리가 점점길어지는 양상을 확인할 수 있습니다. <span style="color:#A9A9A9"><em>머리가 긴 남성은 데이터셋에 존재하지 않는다고 가정하여 위와같은 모양입니다.</em></span> 
만약 interpolation과정에서 성별이나 머리길이에 상관없는 feature들이 갑자기 나타난다면 <strong>space가 linear하지 않다는 의미입니다. 즉, entangle되어있다는 것이죠</strong></p>
<p>기존 GAN모델들은 latent space가 데이터의 분포를 따라야 합니다. 따라서 Gaussian 또는 Uniform을 latent space로 하여 sampling하게 됩니다. <span style="color:#A9A9A9">PGGAN은 Gaussian에서 sampling합니다</span> </p>
<p>  $(b)$는 PGGAN의 경우입니다. 데이터의 분포를 Gaussian으로 가정하기 때문에, $Z$ space는 원래의 분포가 Gaussian에 맞춰 구부러져 모델링될 것입니다. 때문에 원래 분포보다 뒤틀림이 생기고, 보다 engtangle될 수 밖에 없습니다.</p>
<p>  $(c)$의 경우는 이러한 entanglement를 방지하고자, mapping network를 통해 imediate latent space로 한번 보내서 less entangle하게 만듭니다. latent space $Z$보다 less entangle한 imediate latent space $W$에서 이미지를 생성하게되어 style을 interpolation하는 과정에서 더 linear하게 동작할 수 있습니다.</p>
<h2 id="synthesis-network">Synthesis Network</h2>
<p>mapping network를 통해 sampling한 $z$ vector를 $w$ vector로 만들었습니다. 이제 $w$ vector로 이미지를 synthesis하는 방법을 알아보겠습니다. </p>
<p>PGGAN는 4x4부터 1024x1024까지, 총 9개의 layer가 있는 progressive growing구조입니다. 낮은 resolution의 layer에서는 얼굴형이나 피부색, 머리 스타일 같은 대략적인 특징을 만들고, 높은 resolution으로 갈 수록 머리 색이나 세부적이고 세밀한 특징을 만들게 됩니다. 이러한 동작으로 고화질의 이미지를 잘 생성할 수 있는 것입니다. StyleGAN에서도 이 progressive growing 구조를 유지하여 고화질의 이미지를 만들어냅니다.</p>
<p>synthesis network는 4x4부터 1024x1024 resolution feature map을 만드는 <strong>총 9개의 style block</strong>으로 이루어져있습니다. 마지막에는 RGB로 바꿔주는 layer가 있어 이미지 channel에 맞춰줍니다. Style block의 input은 전 style block의 output인 featuremap입니다. 하나의 style block당 두번의 convolution을 진행합니다. </p>
<p>Style block의 세부 구조는 크게 세가지로 나누어 설명드리겠습니다.</p>
<h3 id="1-style-modules-adain">1) Style Modules (AdaIN)</h3>
<p><img src="https://images.velog.io/images/minjung-s/post/08a26598-fd08-4964-ab68-9ebc160324e1/image.png" alt="">
mapping network로 만들어진 <em>w</em>는 affine transform을 거쳐 style vector로 변합니다. A는 &quot;learned affine transform&quot;<span style="color:#A9A9A9"> (fully connected layer)</span> 으로 학습되는 parameter입니다. convolution 다음에 들어가기 때문에 총 18번 들어가게 됩니다. A로 스타일 벡터 $y_i = [y_{s,i},y_{b,i}]$를 만들고 AdaIN의 style scaling factor와 style bias factor의 역할을 하게 됩니다.  </p>
<blockquote>
<p><strong>AdaIN</strong>은 content 이미지 $x$에 style 이미지 $y$의 스타일을 입힐 때 사용하는 normalization으로, style transfer에 거의 공식적으로 사용됩니다.
먼저 content 이미지를 정규화 합니다. style 이미지에 affine transform을 하여 style scaling factor $\sigma(y)$와 style bias factor $\mu(y)$를 얻습니다. 정규화된 content이미지는 이에 맞춰 scaling되고 bias가 더해집니다.
Adaptive Instance Normalization인만큼 Instance Normalization에서 style factor들이 적용된 것입니다. AdaIN역시 IN과 동일하게 instance(각 이미지), channel별로 normalize됩니다.
style 이미지에 적용되는 affine transform은 학습됩니다.(learned)</p>
</blockquote>
<figure>
    <img src="https://images.velog.io/images/minjung-s/post/9dbfad20-fd17-43de-a74c-444eb74201b7/image.png">   
    <figcaption><span style="color:#A9A9A9">출처 :AdaIN paper</span></figcaption>
</figure>

<p>기존 AdaIn과 비교하면, convolution을 거친 featuremap이 AdaIN의 content이미지의 역할이고 $w$가 style이미지의 역할입니다. feature map은 statistic하게 normalization되고 w으로 부터 나온 scaling factor와 곱해지고, bais factor가 더해집니다. normalize연산은 AdaIN,IN과 동일하게 당연히 channel specific하게 진행됩니다.</p>
<h3 id="2-constant-input">2) Constant input</h3>
<p>style-based generator는 $w$를 입력으로 받기 때문에, 더이상 PGGAN이나 다른 GAN과 같이 $z$에서 convolution연산을 하지 않아도 됩니다. 때문에 synthesis network는 4x4x512 contant tensor에서 부터 시작합니다. </p>
<figure>
    <img src="https://images.velog.io/images/minjung-s/post/a9e1734c-ca12-46c7-9e3d-ad37d4f17813/image.png">   
    <figcaption><span style="color:#A9A9A9">출처 :https://towardsdatascience.com/explained-a-style-based-generator-architecture-for-gans-generating-and-tuning-realistic-6cb2be0f431</span></figcaption>
</figure>

<p>뒤에 말씀드리겠지만, random한 noise에서 시작하는 것보다 contant에서 시작하는 것이 더욱 성능이 좋았습니다. 
_<span style="color:#696969">이유에 대한 본 논문에 나와있지 않지만, disenstangle한 $w$를 사용하기 때문에 entangle된 $z$를 사용하는 것을 피하는 효과가 아닐까 합니다..</span>_</p>
<h3 id="3-stochastic-variation">3) Stochastic variation</h3>
<p>Progressive growing구조와 AdaIN으로 고해상도의 이미지를 생성할 수 있습니다. 여기에 세부적인 attribute를 추가하기 위해 Noise를 추가해줍니다. </p>
<figure>
    <img src="https://images.velog.io/images/minjung-s/post/4755f80b-a96d-46dc-8407-fbdfade833fb/image.png">   
    <figcaption><span style="color:#A9A9A9">출처 :https://towardsdatascience.com/explained-a-style-based-generator-architecture-for-gans-generating-and-tuning-realistic-6cb2be0f431</span></figcaption>
</figure>
Gaussian에서 sampling한 nosie를 Convolution의 output인 featuremap에 더해줍니다(sum) B block을 통해 featuremap 사이즈에 맞게 변형됩니다. B 역시 학습되는 parameter입니다.

<p>이를 통해 <strong>stochastic variation</strong>을 추가할 수 있습니다. 여기서 Stochastic variation이란 머리카락의 배치이나 모공, 주근깨 같이 아주 세밀하고 때에 따라 달라지는 특징들을 말합니다. </p>
<figure>
    <img src="https://images.velog.io/images/minjung-s/post/02b2470d-d54e-4f87-a5a2-5f302c6c03d2/image.png">   
    <figcaption><span style="color:#A9A9A9">출처 :StyleGAN paper</span></figcaption>
</figure>
이러한 Noise추가는 stochastic variation에만 영향을 주고, Styleblock과 AdaIN으로 만드는 high-level attribute에는 영향을 주지 않습니다.



<h2 id="properties-of-the-style-based-generator">Properties of the style-based generator</h2>
<h3 id="style-mixing">Style mixing</h3>
<p>StyleGAN의 특징 중 하나는 <strong>localization</strong>입니다. 여기서 의미하는 localization은 style의 특정 subset을 변경하는 것이 이미지의 특정 부분을 변경하는데 효과를 낸다는 의미입니다. <strong>즉, layer의 특정한 부분을 바꾸는 것이 이미지 어떤 부분을 바꾸는 것에 영향을 줍니다.</strong>
StyleGAN의 progressive growing 구조의 장점을 앞에서 언급하였습니다. mapping network로 만들어진 $w$는 synthesis network의 모든 layer에 적용될 style을 표현하도록 학습합니다. 낮은 resolution의 Style block에서는 symentic한 정보를 만들고 높은 resolution으로 갈 수록 세밀한 attribute에 영향을 준다는 것이었습니다. 이 성질을 이용하여 <strong>style의 localized network(Synthesis network의 block)을 조절하여 (scale-specific 수정) 이미지를 생성할 때 style attribute를 조절</strong>하는 것이 가능합니다. </p>
<p>예를 들어, 서로 다른 $w_1$과 $w_2$를 sampling하여 (from $z_1,z_2$) 4x4부터 32x32까지의 style block에는 $w_1$을 사용하고, 64x64부터 1024x1024의 style block에는 $w_2$을 사용하는 것입니다. 4x4부터 32x32 resolution에서 얼굴형, 안경의 유무를 만들고 그러한 특성들은 $w_1$을 따릅니다. 64x64부터 1024x1024 resolution에서는 머리색 피부톤과 같은 세밀한 특징을 만들어내어 그러한 특징은 $w_2$에서 영향을 받게 되는 것입니다. </p>
<figure>
    <img src="https://images.velog.io/images/minjung-s/post/6034d50f-10bc-42a0-8eb9-1c59a48f0ca5/image.png">   
    <figcaption><span style="color:#A9A9A9">출처 :StyleGAN paper</span></figcaption>
</figure>

<p>위 표는, $w_A$로만 만든 source A와 $w_B$로만 만든 source B가 있을 때, 각 $w_A,w_B$를 어느 resolution에서 cross over하여 style을 합성하는지에 따른 결과입니다. </p>
<ul>
<li>Coarse style : coarse resolution ($4^2$ - $8^2$)→ high level aspects (ex. pose, general hair style, face shape, eyeglasses) 전반적인, 큰 정보</li>
<li>Middle style : middle resolution ($16^2$ - $32^2$) → smaller scale facial features, hair style,eyes open/closed from B</li>
<li>Fine style : fine resolution ($64^2$ - $1024^2$) → hair color, 피부톤 같은 세밀한 정보</li>
</ul>
<p>fine resolution에서 cross over한다면, 전반적인 style은 source A를 따르고 머리색이나 세밀한 부분들같은 fine style는 source B를 담아 생성된 결과를 볼 수 있습니다.</p>
<h4 id="span-stylecolorcd2e57mixing-regularizationspan"><span style="color:#CD2E57"><strong>mixing regularization</strong></span></h4>
<p>mixing regularization은 style mixing으로 만든 이미지도 discriminator에 &quot;fake&quot;로 넣어주는 기법입니다. mixing regularization을 사용하면 각 style이 더 잘 localization되어 <strong>다른 style에 correlation되지 않도록 합니다.</strong></p>
<figure>
    <img src="https://images.velog.io/images/minjung-s/post/231de064-ed6a-4d54-8403-143dd5d57a6d/image.png">   
    <figcaption><span style="color:#A9A9A9">출처 :StyleGAN paper</span></figcaption>
</figure>

<p>위 표는 style mixing으로 생성한 image를 training시에 반영할 비율과 (하나의 latent code에서 만든 fake image와 style mixing으로 만든 generated image의 비율), 이미지를 생성할 때 몇개의 latent code로 style mixing을 하는지에 대한 FID 결과비교 입니다. 표에서 볼 수 있듯 mixing regularization을 하였을 때 성능이 확연히 좋은것을 확인할 수 있습니다.</p>
<h3 id="stochastic-variation">Stochastic variation</h3>
<p>Noise로 stochastic variation을 만들 때, B block을 거쳐 resolution마다 더해지기 때문에 scale-specific하게 stochastic variation을 수정할 수 있습니다. noise도 layer의 resolution에 따라 Coarse noise와 Fine noise로 나뉩니다.</p>
<ul>
<li>Course noise : 세기가 강한 머리의 곱슬거림,appearance of larger background features</li>
<li>Fine nosie :세밀한 곱슬거림, finer background detail, 모공<figure>
  <img src="https://images.velog.io/images/minjung-s/post/dd794332-b82e-4707-82b5-7f2f264c4fed/image.png">   
  <figcaption><span style="color:#A9A9A9">출처 :StyleGAN paper</span></figcaption>
</figure>

</li>
</ul>
<p>(a) 모든 layer에 noise
(b) No noise → stochastic variation control 불가. 머리카락 같은 정보의 디테일이 많이 떨어지는 것을 확인할 수 있다.
(c) fine noise → 세밀한 강도의 stochastic variation
(d) coarse noise →강한 강도의 stochastic variation</p>
<p>결론적으로 mixing을 통해 w는 global한 feature를 noise는 확률적인 feature를 조절할 수 있습니다. </p>
<h2 id="disentanglement-measurement-method">Disentanglement measurement method</h2>
<p>contribution에서 언급했던것 처럼, 본 논문에서는 disentanglement를 측정할 수 있는 두가지 지표를 제안합니다.</p>
<h3 id="1-perceptural-path-length-l">1. Perceptural Path Length $l$</h3>
<p>두개의 vector를 interpolation할 때 부드럽게 바뀌는지 측정하는 지표입니다. 앞서 언급했듯이, disentangle되어있다면 어떤 두 벡터를 samlping하여 interpolation을 진행할 때 자연스럽게 변화하는 양상을 보여야 합니다. 즉, 두 z를 interpolation할 때 결과 image의 semantic정보가 급격하게 변화한다면 entangled, smooth하게 변화한다면 disentanglement (less entanglement)하다고 할 수 있습니다.</p>
<p>논문에 &quot;a perceptually-based pairwise image distance&quot;라고 표현되어있는데, 어렵지 않습니다. 두 개의 $z_1,z_2$로 생성한 이미지를 VGG16을 통과시켜 embedding시킨 뒤, 두 embedding vector의 차이를 계산하는 것입니다.</p>
<p>disentanglement를 비교하기 위해 $Z$ space에서 sampling한 경우와 $W$ space에서 sampling한 경우로 나누었습니다.
$z,w$를 각각 다른 방식으로 interpolation합니다.</p>
<ul>
<li><p>latent pace $Z$
<img src="https://images.velog.io/images/minjung-s/post/691f32c8-db6e-4031-af45-ffc16e409b57/image.png" alt="">$z$는 shpherical linear interpolation(구면선형보간법)을 합니다.</p>
</li>
<li><p>intermediate latent space $W$
<img src="https://images.velog.io/images/minjung-s/post/a6875a4a-e927-47a5-906f-753b6db83991/image.png" alt="">$w$는 linear interpolation(선형보간법)을 합니다.</p>
</li>
</ul>
<p><img src="https://images.velog.io/images/minjung-s/post/c4d6417d-3668-48b5-8748-821af47756c9/image.png" alt="">
$lerp(f(z_1),f(z_2);t)$의 의미는 $z_1,z_2$을 직선으로 이어(linear) 의 중간에 t의 지점을 sampling한다는 의미입니다. <em>이해를 쉽게하기 위해 t지점이라고 했지만, $z_1~z_2$사이를 t와 (1-t)의 비율로 나눈 지점을 의미합니다.</em>
$slerp(f(z_1),f(z_2);t)$은 $z_1,z_2$을 기준으로 포물선을 만들어 중간에 t의 지점을 sampling한다는 의미입니다.</p>
<p><strong><span style = "color:#CD2E57">왜 latent space의 disentanglement를 측정할 때, $Z$와 $W$가 서로 다른 보간법을 사용할 까요??</span></strong>
논문에서는 &quot;$W$는 normalize하지 않기 때문에 linear interpolation을 수행한다&quot;라고만 언급되어있습니다. 이 이상의 설명은 다른 포스팅에서 찾아보기 힘
$Z$는 normalize되어 구면선형보간(Spherical Linear Interpolation)을 사용하는 것인데요, 왜 $Z$ space에서는 구면을 따라 interpolation을 할까요??</p>
<p>$Z$ space는 Gaussian으로 normalize됩니다. 2차원을 예시로 들자면</p>
<p>  구면선형보간 선형보간
  style mixing을 사용하지 않을 때가 더 좋다. style mixing은 style간의 uncorrelation을 없애도록 2개 이상의 w로 만드는 것
  2. 선형적으로 얼마나 잘 분류되는지 측정
  선형분류기를 학습한 뒤 선형분류기에 의해 서로다른 binary한 특징이 얼마나 잘 구분되는지 측정하였습니다. 선형분류기를 학습하여 latent vector가 얼마나 선형적인 sub-space에 존재하는지 확인할 수 있습니다.
  latent space의 point가 linear 하이퍼프레인에 의해 잘 분류될 수 있는지를 보는 것 입니다.
  celebA로 보조네트워크를 학습합니다. 40개의 binary한 정보
  stylegan으로 w에서 200000개의 이미지를 생성하고 분류모델에 집어넣고 confidence가 높은 10만개 이미지들만 남깁니다. 
  (latent space를 가로지르는 선형분류기)
  conditional 엔트로피값을 측정합니다. 입력 벡터 X가 주어졌을 때 트루클래스에 대한 entropy가 얼마나 높은지를 측정하는 것 입니다. x가 트루클래스로 분류되기 위해 feature가 얼마나 부족한지, 트루클래스로 분류되기 ㅇ위해 필요한 feature의 양을 나타냅니다. entropy가 낮을수록 선형적으로 분류가 잘 된다고 생각하시면 됩니다. 
  basline을 사용하던, stylegna을 사용하던 항상w를 사용하여 interpolation하 ㄹ때가 disentangle이 보다 보장되어있다라고 생각할 수 있습니다. w가 
  latent space</p>
<figure>
    <img src="https://images.velog.io/images/minjung-s/post/6070bdc6-7556-4d7f-ac9e-645f00647e08/image.png">   
    <figcaption><span style="color:#A9A9A9">출처 :StyleGAN paper</span></figcaption>
</figure>  

<ul>
<li>A : PGGAN. </li>
<li>B : PGGAN에서 interpolation method를 바꿔 bilinear up/down sampling, longer training, tuned hyperparameters해서 성능을 끌어올린 버전</li>
<li>C : mapping network, AdaIN → the network no longer benefits from feeding the latent code into the first convolution layer.</li>
<li>D : removing tranditional ipnut layer, 4x4x512 constant tensor input → AdaIN만으로도 스타일을 잘 전달할 수 있다.</li>
<li>E : noise input(B block)</li>
<li>F : mining regularization</li>
</ul>
<p>결과를 보면 고화질의 퀄리티 높은 이미지가 생성되는 것을 확인할 수 있습니다. 논문에서 잘 생성된 결과 이미지를 sampling하기 위해서 <strong>truncation trick</strong>을 썻다고 나와있습니다.</p>
<h4 id="span-stylecolorcd2e57truncation-trickspan"><span style="color:#CD2E57"><strong>Truncation trick</strong></span></h4>
<p><strong>truncation trick이란?</strong> : GAN을 학습완료한 뒤, 학습된 분포에서 좀 더 잘 나온 이미지들을 sampling하는 trick입니다. 예를 들어 사람얼굴에 대한 데이터셋의 분포라면 사람 얼굴 이미지는 대부분 평균에 몰려있을 것이고, 평균에서 멀어질수록 사람 얼굴과는 거리가 먼 이상한 이미지 일 것입니다. GAN으로 학습된 분포 역시 target distribution에 맞춰 학습되었을 것이기 때문에, 학습된 분포의 평균에서 sampling하면 좋은 퀄리티의 이미지를 생성할 수 있을것입니다. 
가능하면 density가 높은 곳에서 부터 뽑는 것이 퀄리티 좋은 이미지가 나올테니까, 하나의 latent vector가 latent space에서 중간에 가까운 값이 될 수 있도록 잘라내기(trucation)를 수행해서 결과를 얻도록 만드는 것입니다.  <strong>즉 $w$의 중간값을 찾아서 그 중간값 주변에서 sampling하는 것입니다.</strong>
StyleGAN에서는 $W$ space에 맞추어져있지만, $Z$ space에서 이미지를 바로 생성하는 다른 GAN에서는 $z$에 적용할 수 있습니다.
$$\bar{w} = E_{z∼P (z)}[f(z)]$$ <br>$w&#39; = \bar{w} + ψ(w − \bar{w})$</p>
<p>ψ값dl 0에 가까울수록 평균이미지로 가는 것이고 ψ가 1이면 truncation을 하지 않은 것 입니다. ψ를 -값으로 한다면, ψ를 +값으로 하여 samlping한 이미지에서 나타나는 high-level attribute들의 (often) 반대로 나타나는 것을 확인할 수 있습니다. 
_<span style="color:#696969">안경,나이,머리길이 등 가끔 성별도 해당됩니다. 아주 재미있는 현상인것같네요</span>_</p>
<p><em>(퀄리티 좋은 이미지를 sampling하기 위한 trick이므로, metric으로 결과비교(FID)할 때에는 이 트릭사용하지 않습니다.)</em></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[StyleGAN2 : Analyzing and Improving the Image Quality of StyleGAN]]></title>
            <link>https://velog.io/@minjung-s/%EB%85%BC%EB%AC%B8%EB%A6%AC%EB%B7%B0StyleGAN2-Analyzing-and-Improving-the-Image-Quality-of-StyleGAN</link>
            <guid>https://velog.io/@minjung-s/%EB%85%BC%EB%AC%B8%EB%A6%AC%EB%B7%B0StyleGAN2-Analyzing-and-Improving-the-Image-Quality-of-StyleGAN</guid>
            <pubDate>Thu, 09 Jun 2022 16:20:59 GMT</pubDate>
            <description><![CDATA[<p>이번에 리뷰할 논문은 2020 CVPR에 발표된 <a href="https://arxiv.org/abs/1912.04958">&quot;Analyzing and Improving the Image Quality of StyleGAN&quot;</a>입니다. 2019년 CVPR에 나온 StyleGAN의 후속 논문으로, StyleGAN2라고 불립니다. StyleGAN의 문제점을 해결하고, 생성되는 이미지의 quality와 model의 training performance를 높인 모델입니다.</p>
<h1 id="stylegan의-한계">StyleGAN의 한계</h1>
<p>본 논문에서는 Synthesis network의 latent space인 intermediate latent space $W$에 초점을 맞추어 진행됩니다.<br>기존 StyleGAN에서 생성한 이미지들의 두가지 문제점을 지적합니다.</p>
<ul>
<li>water droplet artifact</li>
<li>phase artifact</li>
</ul>
<h1 id="removing-normalization-artifacts">Removing normalization artifacts</h1>
<p>StyleGAN의 문제점 중 하나는 &quot;water droplet artifact&quot;를 만들어 낸다는 것이었습니다. 
water droplet이란 생성된 이미지에 나타나는 물방울모양의 노이즈를 말합니다.
<img src="https://images.velog.io/images/minjung-s/post/1cd94898-c7c0-411e-b639-909f09cb086c/image.png" alt="">
위에 사진에서 볼 수 있듯 결과적으로 생성된 이미지에서는 두드러지지 않지만, featuremap을 보시면 이상한 노이즈를 발견할 수 있습니다. 이는 중간 featuremap에서부터 나타나는데, 64x64 resolution layer에서 부터 high resolution이 될수록 두드러집니다.</p>
<p>원인은 synthesis network에서 $w$의 style을 입히는 과정인 <strong>AdaIN</strong>에 있습니다. AdaIN에서 각 featuremap을 자신의 mean,variance로 normalization하게 됩니다. <strong>이는 featuremap간의 상대적인 차이를 고려하지 못하는 문제가 생기게 됩니다.</strong>
본 논문에서는 이러한 점이 water droplet의 원인이라고 가정하고, normalization과정을 없애고 water droplet이 사라지는것을 확인함으로써 본 가설이 맞음을 확인했습니다. </p>
<h2 id="1-generator-architecture-reviseited">1. Generator architecture reviseited</h2>
<p><img src="https://images.velog.io/images/minjung-s/post/57f62cfb-7d80-4338-951c-48d0ff577f78/image.png" alt="">
기존 StyleGAN의 synthesis network를 보면 (b)같은 그림입니다. <strong>AdaIN</strong>의 과정은 다음과 같습니다. 전 featuremap이 자신의 mean,variance로 <strong>normalization</strong>되고, A에서는 $w$에서 learnable affine transform으로 scaling factor와 bias를 뽑아 normalize된 featuremap에 각각 곱해지고 더해져 (AdaIN <strong>modulation</strong>) style을 입힙니다. Stochastic variation을 의한 Noise (B block)와 convolution의 bias는 style block안에서 더해지게 됩니다. 
<strong>StyleGAN2에서는 (c) featuremap을 mean과 variance로 normalize하지 않고, variance로 나누기만 해도 충분하다고 말합니다.</strong> 또한, bias와 Noise는 style magnitue와 반비례하게 영향을 주기 때문에, <strong>bias와 Noise를 style block밖으로 빼버립니다.</strong> 
<em>We observe that more predictable results are obtained by moving these operations outside the style block, where they operate on normalized data.</em> </p>
<h2 id="2-instance-normalization-revisited">2. Instance normalization revisited</h2>
<p>다음 단계로는 normalization을 제거하여 water droplet의 문제를 해결하고 FID를 향상시킬 수 있습니다. <del>(하지만, 다음 과정처럼 normalization을 제거한다면 Style mixing을 할 때는 scale-specific하게 control한다는 장점은 사라집니다.)</del>
<img src="https://images.velog.io/images/minjung-s/post/dc02f2ff-329c-44fe-ad19-724433bbc45c/image.png" alt="">
바로 전 단계 (c)에서는 modulation(std로 나누고, scaling factor 곱&amp;bias더하기),convolution, normalization(std로 나누기)과정을 거쳤습니다. 
<img src="https://images.velog.io/images/minjung-s/post/0038b536-7538-43f5-95c2-ec0874304a76/image.png" alt="">
<strong>modulation :</strong> 이제 std로 나누지 않습니다! 즉 <strong>normalization을 하지 않습니다.</strong> 대신 A에서 넘어온 scaling factor를 convolution weight에 곱하여 scaling을 진행합니다. ($s_i$: i번째 input featuremap의 scaling factor, j : out featuremap, k : spatial footpring of convolution =receptive field)
<img src="https://images.velog.io/images/minjung-s/post/390c4fab-d043-49b9-8739-73f4ee333b3f/image.png" alt="">
<strong>demodulation :</strong> 다음으로 weight를 L2norm으로 scaling하고(std), 각 출력 featuremap j를 1/(j의 표준편차)로 scaling해줍니다.</p>
<p>s를 이용하여 단일 convloutional layer의 가중치를 수정해주는 방향으로 style block을 구성하였습니다. featuremap을 normalization하는 것이 아니라 <strong>convolution weight를 normalization</strong>하는 것 입니다. 결과적으로 waterdroplet을 제거하면서 완전한 controllabillity를 갖추게 되었습니다.</p>
<p>Our method offers excellent controllability by mixing styles at different scales, similar to StyleGAN. Due to weight demodulation, the effects of each style are well localized in the generator</p>
<h1 id="image-quality-and-generator-smoothness">Image quality and generator smoothness</h1>
<p>GAN의 metric으로 FID와 precision&amp;recall이 있습니다. 하지만, 아래 그림과 같이 FID와 P&amp;R의 값으로 생성이미지를 평가하기에 한계가 있습니다.</p>
<blockquote>
<p>precision : 생성된 이미지 중 실제 이미지 분포에 들어가는 이미지들/생성된 이미지들 (fidelity와 연관)
recall : 실제 이미지 중 생성된 이미지 분포에 들어가는 이미지들/실제 이미지들 (diversity와 연관)</p>
</blockquote>
<p><img src="https://images.velog.io/images/minjung-s/post/84d24d5e-b122-44c7-ae29-dd53260c4919/image.png" alt="">
이 지표들은 shape보다는 texture에 더 focusing하기 때문에, 아래와 같이 FID와 P&amp;R값이 같다고 하여 동일한 생성성능을 보여주지 않습니다.
StyleGAN에서 제안된 Perceptual Path Length(PPL)이 적합한데, 단순히 PPL을 낮추는 방향으로 학습을 하는 것은 zero-recall이 될 수 있으므로 smoother generator mapping을 위해 새로운 regularizer를 도입합니다. </p>
<h2 id="1-lazy-regularization">1. Lazy regularization</h2>
<p>이는 단순히 regularization term을 main loss(WGAN아니고 BCE썼네... non saturating logistic loss(GAN loss) with R1)보다 드물게 학습에 사용하는 것을 의미합니다. 논문의 C는 16minibatch마다 한번 regularization term을 고려한 경우입니다. </p>
<h2 id="2-path-length-regularization">2. Path length regularization</h2>
<p>PPL은  intermediate latent space의 perceptual smothness를 나타내는 것이었고, 이는 이미지 품질에 관련있다는 것을 알아냈었습니다. 이 PPL을 generator loss의 regularization term으로 추가합니다.
a</p>
<p><em>$W$space에서의 고정된 사이즈의 변화가 이미지에서 고정된 변화로 나타나야 합니다. PPL이 intermediate latent space에서의 disentanglement를 측정하는 metric이었습니다. image space에서 변화와 intermediate latent space에서의 변화량을 관찰하여 VGG16의 embedding값으로 비교하였습니다.</em></p>
<h1 id="progressive-growing-revisited">Progressive growing revisited</h1>
<p>기존 StyleGAN의 progressive growing 구조는 각 resolution이 독립적이기 때문에 다음 그림과 같은 문제를 발생시킵니다. 
<img src="https://images.velog.io/images/minjung-s/post/5a8e493c-0a5f-48bc-890c-623ddadba4e0/image.png" alt="">
<em>사진설명</em>
Progressive의 장점은 살리면서 Phase artifact를 해결하기 위해 세가지 구조로 실험을 해보았습니다.
<img src="https://images.velog.io/images/minjung-s/post/2ae6e91d-dcb3-43a8-8368-6231647c9a93/image.png" alt=""></p>
<ul>
<li>MSG-GAN : generator와 discriminator의 resolution을 맞춰서 skip connection
<img src="https://images.velog.io/images/minjung-s/post/16d1693d-623a-4374-b35d-eb0dacaee3cb/image.png" alt=""></li>
<li>Input/output skips : 다른 resolution의 RGB output을 upsampling/downsampling해서 sum하는 구조. 각 resolution의 영향을 주는 구조</li>
<li>Residual nets : residual block
<img src="https://images.velog.io/images/minjung-s/post/465acb17-ad3a-4469-8276-fe377828cfbf/image.png" alt="">
Figure7에서 나오는 구조는 generator가 첫 번째 저해상도 이미지가 고해상도 레이어에 영향을 받지 않고 출력할 수 있게 만들고, 학습이 진행되면서 나중엔 고해상도에 집중하게 한다. <h1 id="projection-of-image-to-latent-space">Projection of image to latent space</h1>
</li>
</ul>
<ol>
<li><p>최적화 과정에서 latent code에 ramped-down noise를 더했다. 더 복잡한 latent space를 탐색하게 하려고.</p>
</li>
<li><p>generator에 입력되는 stochastic noise 값도 정규화(regularize)시켜서 신호 간의 간섭을 막도록, 최적화했다.</p>
</li>
</ol>
<p>마지막으로, 이는 잠재 공간으로 투영하는 방법으로 분석한 결과이다. 히스토그램은 LPIPS 거리 분포를 보여주는데, 이는 실제 이미지와 잠재 공간으로 투영한 후 생성자(Generator)에 한번 다시 통과한 이미지 사이의 거리이다. 히스토그램은 실제 이미지와 StyleGAN, StyleGAN2의 결과를 보여주고 시각화한다. (실제 이미지 또한 인공적으로 잠재 공간으로 떨어졌다.)</p>
<p> StyleGAN2가 StyleGAN과 실제 이미지보다 잠재 공간에서 더 잘 투영됨을 볼 수 있다. 이는 아마도 PPL을 위한 regularization term을 통한 잠재 공간의 매끄러움(smoothing) 때문일 것이다. 아래 그림은 다음 과정을 거친 실제 이미지와 재구성된 이미지(reconstruction images)를 보여준다. 실제 이미지 -&gt; 잠재 공간에 투영 -&gt; 생성자(Generator). StyleGAN에선, 재구성된 이미지(reconstruction images)가 몇몇 장소에서 실제 이미지와 다른 특징 몇 가지를 지녔지만 StyleGAN2에선 꽤 잘 재구성된 것을 볼 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[GNN] Graph Representation Learning : Deep Walk, node2vec, TransE, Graph Embedding]]></title>
            <link>https://velog.io/@minjung-s/GNN-Graph-Representation-Learning-Deep-Walk-node2vec</link>
            <guid>https://velog.io/@minjung-s/GNN-Graph-Representation-Learning-Deep-Walk-node2vec</guid>
            <pubDate>Fri, 05 Mar 2021 10:50:04 GMT</pubDate>
            <description><![CDATA[<p>본 포스팅은 Stanford CS244W fall 2019 : Machine Learning with Graphs의 7강 <a href="https://www.youtube.com/watch?v=4PTOhI8IWTo&amp;t=293s">&quot;Graph Representation Learning&quot;</a> 강의내용을 토대로 작성되었습니다.
<br></p>
<blockquote>
<h1 id="contents">Contents</h1>
<ol start="0">
<li>Intro</li>
</ol>
</blockquote>
<ol>
<li>Embedding Nodes</li>
<li>Random Walk Approaches to Node Embeddings</li>
<li>Translating Embeddings for Modeling Multi-relation Data</li>
<li>Embedding Entire Graphs</li>
</ol>
<h1 id="0intro">0.Intro</h1>
<p>이번 강의는 graph domain에서의 representation learning에 대해 알아보겠습니다.</p>
<p><strong>representation learning</strong>이란, 어떤 task를 수행하기에 적절하게 데이터의 representation을 변형하는 방법을 학습하는 것입니다. 즉 어떤 task를 더 쉽게 수행할 수 있는 표현을 만드는 것입니다. Raw data에 많은 feature engineering과정을 거치지 않고 데이터의 구조를 학습하는 것으로, 딥러닝 아키텍처의 핵심요소라고 할 수 있습니다. 입력 데이터의 최적의 representation을 결정해주고 이 잠재된 representation을 찾는 것을 representation learning 또는 feature learning이라고 부릅니다.</p>
<p><img src="https://images.velog.io/images/minjung-s/post/2fdf2e9e-a895-41b9-96ab-d265900b0b7a/image.png" alt=""></p>
<p>grpah에서의 representation learning 역시 같은 의미입니다.
graph의 node $u$를 mapping function $f$를 통해 Latent space(=embedding space)로 embedding할 수 있습니다. graph의 feature representation(=embedding)을 통해 다양한 task를 효과적으로 수행할 수 있습니다. 이때 효과적인 representation이란, task에 specific하지 않고 다양한 task에도 적용할 수 있는 representation을 의미합니다.
<br>
<br>
<strong>그렇다면 왜 graph를 Embedding해야 할까요??</strong>
<img src="https://images.velog.io/images/minjung-s/post/680005c6-e219-4f72-8fd4-4b70b2dca1a9/image.png" alt="">
graph의 인접행렬(Adjacency Matrix)는 각 column이 node를 의미하기 때문에 sparse하고 크기 매우 큽니다. 인접행렬을 그대로 다루기에는 computation 측면에서 문제가 있습니다. 그렇기 때문에 grpah의 각 node를 low-dimension으로 mapping할 필요가 있습니다. Adjacency Matrix의 dimension보다 dimension이 낮은 <strong>Latent Dimension</strong>으로 embedding하여 computation의 효과를 얻을 수 있습니다. 각 node를 embedding하는 것이기 때문에 <strong>node별 representation이 가능</strong>합니다. 
단, 각 column이 node를 나타내는 adjacency matirx와는 다르게, latent demension에서 나타낼 수 있는 embedding matrix의 column은 각 node를 나타내지는 않습니다. latent demension의 축들은 node가 아닌 node간의 상관관계와 같은 graph의 정보를 의미하는 feature가 됩니다. 즉, <strong>Adjacency matrix의 그래프 정보를 Latent Dimension으로 encoding하고, node representation을 만들어내는 것입니다. **
graph의 정보를 담았기 때문에,</strong> latent space상에서 나타내지는 node간의 similarity은 실제 graph에서의 node간의 similarty라고 볼 수 있습니다. **
<img src="https://images.velog.io/images/minjung-s/post/a9b80277-7ae6-4872-a845-bb577404900f/image.png" alt="">
위 그림은 grpah를 2D latent space로 embedding한 예시입니다. 앞서 말씀드린것 처럼 각 node를 latent space에 mapping할 수 있고, latent space의 축은 node를 의미하는 것이 아닌 그래프의 정보를 담고있다고 이해할 수 있습니다.
<br>
<br>
*<em>그렇다면 기존 Deep Learning에서 사용하는 network들로 embedding을 할 수 있을까요?? *</em>
결론부터 말씀드리자면 사용할 수 없습니다.
CNN은 고정된 크기의 이미지나 그리드에 적용할 수 있고, RNN이나 Word2Vec은 텍스트나 시퀀스 데이터에 적용됩니다.
하지만, graph는 이러한 데이터들보다 훨씬 복잡합니다. 이미지나 그리드처럼 특정 차원에 표현될 수 없고, 가끔 차원이 변동되고 multi-modal feature를 갖기도 합니다. 따라서 graph를 embedding하기 위해서는 graph만의 방식을 적용합니다.
<br>
<br></p>
<h1 id="2-embedding-nodes">2. Embedding Nodes</h1>
<p>이제 graph의 node들을 embedding하는 방법에 대해 알아보겠습니다.</p>
<ul>
<li>graph $G$</li>
<li>vertex set $V$</li>
<li>adjacency matrix $A$ (assume binary)</li>
</ul>
<p>node feature나 그 외 정보들은 사용되지 않습니다. <em>(이하 Encoding은 Embedding과 같은 의미입니다.)</em>
<img src="https://images.velog.io/images/minjung-s/post/f436eb8f-89d0-45a8-a377-000331433112/image.png" alt="">
encoding의 목적은 <span style = "color:red"><strong>embedding space상에서의 similarity와 원본 graph의 similarity최대한 동일하게 만드는 것</strong></span>입니다.
<strong>embedding space상의 두 vector의 similarity는 dot product $z_v^Tz_u$</strong>로 측정할 수 있습니다.</p>
<blockquote>
<p>The dot product is proportional to both the cosine and the lengths of vectors. </p>
</blockquote>
<p>과정은 다음과 같습니다.
1). <strong>Define <code>encoder</code></strong> -&gt; 각 node를 low-dimentional vecotr로 mapping(embedding)하는 방법 정의 
$z_{node} = ENC(node)$
2). <strong>Define a node <code>similarity function</code></strong> -&gt; 원본 graph의 node간 유사도를 측정하는 함수를 정의 
$similarity(u,v)$
3). <strong>Optimize the parameters of the encoder so that 
$similarity(u,v) \approx z_v^Tz_u$</strong></p>
<h2 id="1-encoder">1) Encoder</h2>
<h3 id="shallow-encoding">Shallow Encoding</h3>
<p><strong><code>shallow encoder</code></strong> :encoding is just an embedding-lookup
$ENC(v)=Zv$
<img src="https://images.velog.io/images/minjung-s/post/1638265c-4a76-4359-81bf-ac8e05c3aec7/image.png" alt=""></p>
<ul>
<li>$Z\in \mathbb{R}^{d\times|V|}$ : matrix. 각 column이 node embedding</li>
<li>$v\in \mathbb{I}^{|V|}$ : indicator vector. node $v$를 지정하는 column과 만나는 element는 1, 그 외에는 0인 vector</li>
</ul>
<p>$similarity(u,v) \approx z_v^Tz_u$을 optimize하며 $Z$를 학습시킵니다. shallow encoding으로 각 node를 개별적으로 representation할 수 있습니다. </p>
<p>shallow encoding 외에도 <strong><code>DeepWalk</code></strong>,** <code>node2vec</code><strong>,</strong><code>TransE</code>**등으로 Embedding할 수 있습니다.</p>
<p>다음 파트 _2. Random Walk Approaches to Node Embeddings_에서 상세히 다루겠습니다.</p>
<h2 id="2-similarity-function">2) Similarity Function</h2>
<p><img src="https://images.velog.io/images/minjung-s/post/413ba596-33b9-46b9-859b-d1eb6eb2d34e/image.png" alt="">
node similarity를 어떤기준으로 정의할지 결정해야 합니다. 예시는 다음과 같습니다. </p>
<ul>
<li>두 노드의 연결관계</li>
<li>공유하는 node(neighbor)</li>
<li>structural role의 유사성</li>
<li>등등</li>
</ul>
<p>이 역시 encoding방법에 따른 similarity fucntion을 _2. Random Walk Approaches to Node Embeddings_에서 자세히 설명드리겠습니다.</p>
<br>

<p><strong>3) Optimization</strong>도 <em>2. Random Walk Approaches to Node Embeddings</em> 에서 자세히 설명드리겠습니다. <em>강의 순서가 뒤죽박죽하군요</em></p>
<h1 id="2-random-walk-approaches-to-node-embeddings">2. Random Walk Approaches to Node Embeddings</h1>
<p>_paper refenece : 
Perozzi et al.2014 :<a href="https://arxiv.org/abs/1403.6652">DeepWalk: Online Learning of Social Representations</a>
Grover et al.2016 : <a href="https://arxiv.org/abs/1607.00653">node2vec: Scalable Feature Learning for Networks</a>
_</p>
<p>paper reference에서 알 수 있듯, <strong><code>DeepWalk</code></strong>, <strong><code>node2vec</code></strong>에 관련된 node embedding방법을 상세하게 다뤄보겠습니다.</p>
<h2 id="random-walk">Random Walk</h2>
<p><strong><code>Random Walk</code></strong>란, 말 그대로 node 위를 random하게 걸어다니는 것을 말합니다. 그래프의 특정한 시작점에서 random하게 neighbor들을 선택해서 나가는데, 그 point의 sequnce를 random walk라고 합니다. 걸어간 발자취를 나열한 것이라고 생각할 수 있습니다.
<img src="https://images.velog.io/images/minjung-s/post/1f1869da-841e-47d3-9273-42642e80d028/image.png" alt="">
예를 들어, 위의 그림에서 노란색 point가 시작점으로 주어지고 4걸음을 간다는 parameter가 주어진다면 [1,3,2,8,11]이 random walk가 될 수 있습니다. 3걸음을 간다고하면 [5,8,11,12]가 될 수 있습니다. 
이러한 random walk는 parameter를 주고 <strong>sampling</strong>한다고 표현합니다.
<br>
<br></p>
<h3 id="random-walk-embedding-deep-walk">Random-walk Embedding (Deep Walk)</h3>
<blockquote>
<p><strong>$z_u^Tz_v \approx$ probability that $u$ and $v$ co-occur on a random walk over the network</strong></p>
</blockquote>
<p><strong>$z_u^Tz_v$를 &quot;network 전체의 random walk에서 $u$와 $v$가 함께 발생할 확률&quot;로 근사</strong>할 수 있습니다. 왜냐하면 $z_u$와 $z_v$의 similarity가 높다면 latent space상에 가깝게 위치할 것이고, 이는 node $u$와 $v$의 similarity가 높다는 의미이므로 random walk에서 동시에 발견될 확률이 높기 때문입니다.
<br>
Random-walk Embedding의 과정은 다음과 같습니다.</p>
<ul>
<li>1.어떤 random walk strategy R을 사용하여 <strong>node u에서 출발하여 node v에 방문할 확률 $P_R(v|u)$ 을 추정</strong>합니다.
<img src="https://images.velog.io/images/minjung-s/post/97958f18-8315-4d78-824f-bda877abd200/image.png" alt=""></li>
<li><ol start="2">
<li>이 <strong>$P_R(v|u)$를 encoding하기 위해 embedding을 최적화</strong>시킵니다.
여기서 두 $z$의 similarity인 dot product는 $cos(\theta)$과 같고, 이는 random walk similarity로 볼 수 있습니다.
<img src="https://images.velog.io/images/minjung-s/post/6271961f-f1a4-4d6e-8616-26d13aa1d3f3/image.png" alt=""><br>
<br>

</li>
</ol>
</li>
</ul>
<p><strong><span style = "color:red">그렇다면 왜 Random Walks를 사용할까요??</span></strong></p>
<ul>
<li><strong>Expressivity</strong> : Local과 Higher-order neighborhood 정보를 함께 고려하는 node similarity를 유동적으로 정의내릴 수 있습니다. 
_한국어로 풀어쓰니까 의미전달이 직관적이지 않네요... 강의자료에는 &quot;Flexible stochastic definition of node similarity that incorporates both local and higher-order neightborhood information&quot;라고 명시되어있습니다. _</li>
<li><strong>Efficiency</strong> : 학습할 때, 모든 node쌍을 고려할 필요 없이, 오직 random walk에 함께 발견될 쌍들만을 고려하면 됩니다. 
이는 그래프의 크기가 클수록 더 두드러지는 장점입니다. (ex. real social graph)<br>
<br>
### Random Walk Optimization
다시 graph domain에서의 **Unsupervised Feature Learning**의 의미를 생각해봅십다.
목표는 유사성을 보존하는 d-dimension의 latent space에서의 node embedding을 찾는 것이었습니다. 실제 graph에서 가깝다면 latent space상에서도 가깝도록 embedding해야 합니다. 
그렇다면 **node $u$가 주어질 때, node의 주변, neighbor를 어떻게 정의**할 수 있을까요? 다음과 같이 정의됩니다.

</li>
</ul>
<blockquote>
<p>$N_R(u)$ : random walk strategy $R$로부터 얻을 수 있는 $u$의 neighborhood</p>
</blockquote>
<p>graph $G=(V,E)$가 있을 때, feature learning의 목표는 <strong>mapping function $z:u \rightarrow \mathbb{R}^d$를 학습</strong>하는 것입니다. 이때 <strong>Objective function</strong>은 다음과 같습니다.</p>
<blockquote>
<p><strong>Log-likelihood objective</strong>
$max_z \sum_{u \in V}^{}{logP(N_R(u)|z_u)}$
Given node $u$, we want to learn feature representations that are predictive of the
nodes in its neighborhood $N_R(u)$</p>
</blockquote>
<p>node의 neighborhood를 예측하는 방향으로 feature representation을 학습합니다.
<br></p>
<p>Random Walk의 Optimization 과정을 정리해보겠습니다.</p>
<h4 id="random-walk-optimization">Random Walk Optimization</h4>
<ul>
<li><ol>
<li>graph의 각 node에서 정해진 짧은 길이만큼의 random walk를 수행합니다 
(using some strategy $R$)</li>
</ol>
</li>
<li><ol start="2">
<li>각 node의 neighborhood $N_R(u)$를 수집합니다. 
($N_R(u)$ : the multiset of nodes visited on random walks starting from $u$)</li>
</ol>
</li>
<li><ol start="3">
<li>node $u$가 주어질 때, 그 node의 neighborhood $N_R(u)$를 잘 예측하는 방향으로 node를 embedding합니다.
$max_z \sum_{u \in V}^{}{logP(N_R(u)|z_u)}$</li>
</ol>
</li>
</ul>
<blockquote>
<p><strong>loss function</strong>
$L = \sum_{u \in V}\sum_{v \in N_R(u)}-log(P(v|z_u)$</p>
</blockquote>
<p><strong><span style = "color:#1E90FF">intuition</span></strong> Random walk가 동시에 발생(co-occurrrence)할 likelihood를 maximize할 수 있도록 embedding을 최적화
이때 $p(v|z_u)$는 vector representation이 <strong>softmax를</strong> 거친 후의 값입니다.
$P(v|z_u) = {{exp(z_u^Tz_v)}\over{\sum_{u \in V}exp(z_u^Tz_v)}}$
<em>softmax를 사용하는 이유는 node $u$와 가장 유사도가 높은 node $v$를 얻기 위함입니다.
$\sum_iexp(x_i) \approx max_iexp(x_i)$</em></p>
<p><img src="https://images.velog.io/images/minjung-s/post/6f8125a3-e548-4515-8882-ea5f7c0f0338/image.png" alt=""><strong>Optimizing random walk embeddings =
Finding embeddings $z_u$ that minimize $L$</strong>
정리하면 위와 같습니다. grpah의 모든 node에 대해, 각 node의 neighborhood가 random walk시에 동시에 발견될 확률을 높도록 embedding을 학습합니다.</p>
<p><strong><span style="color:red">하지만, 이 naive한 과정은 compuation 측면에서 매우 expensive하다는 단점이 있습니다.</span></strong>
<img src="https://images.velog.io/images/minjung-s/post/5c7dc004-f4f2-40d5-a657-0cd06b82c4f4/image.png" alt="">
softmax의 normalization term $\sum_{u \in V}exp(z_u^Tz_v)$이 원인입니다. log안에 있는 ${exp(z_u^Tz_v)}\over{\sum_{u \in V}exp(z_u^Tz_v)}$부분을 근사하여 이 문제를 해결합니다. 이때 <strong>Negative Sampling</strong>이 사용됩니다.</p>
<h4 id="negative-sampling">Negative Sampling</h4>
<p>위에서 설명한 loss fuction의 log안의 함수를 다음과 같이 근사합니다.
<img src="https://images.velog.io/images/minjung-s/post/1f52e372-0cd4-4e7d-a7c4-4543d94812c5/image.png" alt="">
모든 node를 고려하여 normalize한 기존의 loss는 expensive했기 때문에, random으로 Negative sampling한 k개의 <strong>negative samples $n_i$</strong>에 대해서만 normalize합니다. w2v에서 전체 corpus에서 빈도가 높은 단어를 negative sample로 sampling하였듯이, <strong>node의 degree가 높은 node를 negative sample로 사용합니다.</strong></p>
<p>negative sample의 개수 $k$가 갖는 의미는 다음과 같습니다.</p>
<ul>
<li>Higher $k$ gives more robust estimates</li>
<li>Higher $k$ correspond to higher bias on negative events </li>
</ul>
<p>실제로는 $k$는 5~20으로 설정합니다.
<br><br>
지금까지 randome walk로 node를 embedding하는 방법에 대해 알아보았습니다. 
random walk는 지정한 시작점에서 고정된 길이 &quot;<strong>fixed size</strong>&quot;를 조건으로 시행됩니다. 하지만 이러한 조건때문에 한계가 있습니다. 
만약, 두 노드의 structural role이 비슷하지만 멀리 떨어져있는 경우라면 어떨까요?? 실제로 두 node는 유사하지만, <strong>random walk는 고정된 사이즈로만 노드주변을 보기 때문에 random walk embdding방식으로는 이 유사성을 담지 못할것입니다.</strong> 이러한 경우 node의 similarity를 담도록 latent space에 embedding한다&quot;라는 node embedding의 가장 큰 목적에 맞지 않습니다. 또한 random하게 보기 때문에, <strong>graph의 전체 structure를 고려하지 못한다는 단점</strong>도 있습니다.
<br><br>
이 단점을 보완한 <strong>node2vec</strong>에 대해 알아보겠습니다.</p>
<h2 id="node2vec">node2vec</h2>
<p><strong><code>Deep Walk</code></strong>의 단점을 보완한 <strong><code>node2vec</code></strong>에 대해 알아보겠습니다.
이 역시 graph의 node를 embedding하는 방식이기 때문에, node2vec의 목표는 다양한 task에 적용가능하도록 (downstream task에 상관없이) graph에서 node의 neighborhood간의 유사성을 latent space (feature space)상에서도 유지하는 것입니다. node2vec은 maximum likellihood optimization문제로 접근합니다. </p>
<blockquote>
<p><strong>Abstract</strong>
네트워크의 node와 edge에 대해서 prediction task를 수행하는 것은 feature engineering 측면에서 많은 노력이 소요된다. 최근의 연구들에서는 reprsentation learning 측면에서 feature 자체를 학습하여 이 측면에서 많은 혁신들이 있었으나, network에서 파악되는 connectivity pattern에 대해서는 제대로 학습하지 못한다는 한계를 가지고 있다. 따라서, 이를 해결하기 위해서 network의 이러한 feature를 학습할 수 있는 프레임워크인 node2vec을 제시하였다. <strong>node2vec에서는 network의 node들의 관계(neighborhood)를 우도(likelihood)를 최대화할 수 있는 low-dimensional(저차원) 피쳐 공간을 학습시켰다</strong>. 실제로 기존의 존재하는 데이터들을 대상으로 수행을 해봤는데 괜찮은 결과가 나왔다.</p>
</blockquote>
<blockquote>
<p>** Recap : word2vec**</p>
</blockquote>
<ul>
<li>skipgram : 중심단어(center word)로 주변단어(context word)를 예측
<img src="https://images.velog.io/images/minjung-s/post/07375f5e-b88c-4264-8106-b9d57a6acb52/image.png" alt="">
가정 : 실제 문장들에서 비슷한 위치에 있는 word들은 embedding space에서도 비슷한 위치에 있을것이다.
따라서 중심단어(c)가 주어졌을 때 주변단어(o)가 나타날 확률(아래식)을 최대화 하면 됩니다.
$P(o|c)= {{exp(u_o^Tv_c}\over{\sum_{w=1}{W}exp(u_w^Tv_c)}}$
graph에서는 특정 node가 주어졌을 때 그 node의 neighborhood가 나타날 확률을 최대화 하면 되겠네요!</li>
</ul>
<p>random하게 neighbor를 보아서 graph 전체 structure를 고려하지 못한 Deep Walk의 단점을 개선하기 위해, node2vec에서는 기존의 randomwalk를 사용하지 않습니다.</p>
<p><strong>node2vec key idea</strong>
use flexible, biased random walk that can trade off between <strong><span style="color:red">local</span></strong> and <strong><span style="color:blue">global</span></strong> views of the network<img src="https://images.velog.io/images/minjung-s/post/8a6889fb-1860-4538-a5d9-6d5f0ccbd558/image.png" alt=""></p>
<p>특정 node $u$의 neighborhood$N_R(u)$는 DFP와 BFS로 정의할 수 있습니다.</p>
<ul>
<li><strong><span style="color:red">$N_{BFS}(u)$ : </span></strong> <strong><span style="color:red">local</span></strong> 영역으로 neighborhood 지정 (microscopic view)
(위 그림 예시: if size of $N_{R}(u)$ = 3 $\rightarrow$ $N_{BFS}(u)={s_1,s_2,s_3}$)</li>
<li><strong><span style="color:blue">$N_{DFS}(u)$ : </span></strong> <strong><span style="color:blue">Global</span></strong> 영역으로 neighborhood 지정 (macroscopic view)
(위 그림 예시: if size of $N_{R}(u)$ = 3 $\rightarrow$ $N_{DFS}(u)={s_4,s_5,s_6}$)</li>
</ul>
<p>node2vec에서는 <strong><code>Biased 2nd-order random walk</code></strong>를 사용합니다.</p>
<ul>
<li>1st-order random walk : node to node </li>
<li>2nd-order random walk : edge to edge</li>
</ul>
<p>biased fixed-length random walk는 두가지 parameter를 정의해야 합니다.</p>
<ul>
<li><strong>return parameter</strong> $p$ : 이전 node로 돌아갈 가능성을 계산하는 parameter. 주변을 잘 탐색하는지 
$p$가 낮을수록 <strong><span style="color:red">BFS</span></strong> like walk (좁은 지역 고려)</li>
<li><strong>in-out parameter</strong> $q$ : DFS와 BFS의 비율. random walk가 얼마나 새로운 곳을 잘 탐색하는지
$q$가 낮을수록 <strong><span style="color:blue">DFS</span></strong> like walk (넓은 지역 고려)</li>
</ul>
<blockquote>
<p><em><strong>example</strong></em><img src="https://images.velog.io/images/minjung-s/post/bb9b44f9-4707-4303-bca1-f6330974094c/image.png" alt="">
$(s_1,w)$의 경로로 이동하여 지금 $w$인 상태
node $w$의 neighborhood로 $s_1,s_2,s_3$만 가능합니다.
$s_2$는 $s_1$과 $w$의 공통 이웃,
$s_3,s_4$는 $s_1$으로부터 멀어지는 방향입니다.
<img src="https://images.velog.io/images/minjung-s/post/be913b79-4256-47cd-bcf2-7a96f4ee057b/image.png" alt="">
$p$가 낮을 수록 좁은 지역을 보고 $q$가 낮을수록 넓은 지역을 봅니다.</p>
</blockquote>
<h3 id="node2vec-algorithm">node2vec algorithm</h3>
<ol>
<li>예시와 같이 random walk probability를 계산합니다.</li>
<li>grpah의 각 node $u$에 대해 길이 $l$만큼의 random walk를 합니다.</li>
<li>node2vec을 SGD로 최적화합니다.</li>
</ol>
<p>node embedding의 대표적인 두가지 방법 <strong><code>Deep Walk</code></strong>와 <strong><code>node2vec</code></strong>을 배워보았습니다. 이러한 embedding을 통해 graph의 정보를 최대한 보존하면서 computation 효과를 볼 수 있었습니다.
graph의 node $u_i$들을 latent space로 임베딩한 embedding vector $z_i$들은 어디에 사용될 수 있을까요?? 
기존 머신러닝에서 데이터를 임베딩(ex. 차원축소)하여 clustering, classification을 할 수 있듯 graph domain에서도 많은 task를 수행할 수 있습니다.</p>
<ul>
<li>Clustering / Community Detection</li>
<li>Node classification</li>
<li>Link prediction</li>
<li>etc</li>
</ul>
<h1 id="3-translating-embedding-for-modeling-multi-relational-data">3. Translating Embedding for Modeling Multi-relational Data</h1>
<p>이제 <strong><code>Knowledge Graph(KG)</code></strong>의 node들을 embedding할 수 있는 <strong><code>TransE</code></strong>에 대해 배워보겠습니다.</p>
<h2 id="knowledge-graph">Knowledge Graph</h2>
<p>knowledge graph에서는 node를 <strong>entitie</strong>, link <strong>relation이라고</strong> 합니다. 한 KG의 relation에는 많은 종류가 있을 수 있습니다. KG에서의 link는 종류마다 갖는 의미가 다 다릅니다.
<img src="https://images.velog.io/images/minjung-s/post/2286bb19-e6bb-4d9e-ac6a-eba80f37cc46/image.png" alt=""></p>
<blockquote>
<p>The knowledge graph represents a collection of *<em>interlinked descriptions of entities *</em>– objects, events or concepts. Knowledge graphs put data in context via linking and semantic metadata and this way provide a framework for data integration, unification, analytics and sharing.</p>
</blockquote>
<p><img src="https://images.velog.io/images/minjung-s/post/cf7beab6-a7d6-4a13-8053-3e2725d2acc6/image.png" alt="">
KG의 이어지지 않은 entitie(node)의 relation(link)를 예측하는 KG completion (=link prediction)에 대한 연구가 활발합니다.
<strong><span style = "color:#1E90FF">intuition</span></strong>  : KG의 local&amp;global pattern을 잘 학습하는 link prediction model을 만들고자합니다.
downstream task : link prediction은 학습된 패턴을 사용하여 관심 node와 그 외 모든 node간의 relationship을 일반화함으로써 수행됩니다.</p>
<h2 id="transe">TransE</h2>
<blockquote>
<p><strong>Abstract</strong>
지금 우리가 해결할 문제는 구성요소와 관계들을 저차원의 벡터 공간으로 임베딩 시키는 것이고, 무엇보다 지식 그래프의 기반이 되고 학습하기 쉬운 장점을 가지는 것을 목표로 한다. 이에 TransE 라는 모델을 제시하는데 이 모델은 relationship(관계)를 저차원의 임베딩된 구성요소간 translations(전환) 으로 해석한다는 것이 핵심이다.</p>
</blockquote>
<p>knowledge graph를 embedding하는 <strong><code>TransE</code></strong>에서는 KG의 두 node(entity)의 관계를 triplet으로 표현합니다. 
<strong><em><code>h (head entity), l (relation), t (tail entity) → (h,l,t)</code></em></strong>
<img src="https://images.velog.io/images/minjung-s/post/72b51043-ab37-4b0c-9f34-23347f359d73/image.png" alt="">
먼저 Entitie(node)들을 <strong>entitiy space $R^k$</strong>에 embedding하고, 각 Entitie $e$을 mapping function $M_r$을 통해 relation space로 mapping합니다.
TransE model을 통해 KG의 relation이 embedding space상에서 의미를 갖도록 합니다.
이때 핵심은 $(h,l,t)$가 성립한다면, $h + l\approx t$가 성립한다는 점입니다.
즉 embedding된 tail entity $t$는 임베딩 된 head entity $h$와 realtionship 과 관련된 벡터 $l$과의 합과 가까이 위치한다는 의미입니다.</p>
<ul>
<li>$h,t \in E$(set of entities), $l \in L$(set of relationships)</li>
<li>임베딩 벡터의 차원 : $\mathbb{R}^k$(k : hyperparameter)</li>
<li>energy of triplet : $d(h+l,t)$ ($d$:dissimilarity measure,주로 $L_1,L_2-norm$</li>
<li>marginary hyperparameter : $\gamma$
$\mathcal{L}=\sum_{(h,l,t) \in S}\sum_{(h&#39;,l,t&#39;) \in S&#39;<em>{(h,l,t)}} [\gamma _ d(h+l,t)-d(h&#39;+l,t&#39;)]$
$S&#39;</em>{(h,l,t)}= { (h&#39;,l,t)|h&#39;\in E } \cup { (h,l,t&#39;)|t&#39;\in E }$</li>
</ul>
<p>$S&#39;<em>{(h,l,t)}$은 corrupted triplet입니다. 이때 corrupted는 노이즈가 추가된 상태라는 의미입니다. 위 수식에서 알 수 있듯이 head entity나 tail entity에 변화가 있는 상태입니다. $S&#39;</em>{(h,l,t)}$는 실제 KG에는 없는 triplet입니다.
loss $\mathcal{L}$를 mimimize하므로, training triplet $(h,l,t)$의 energy(dissimilariy)는 작게하고 corrupted traiplet$(h&#39;,l,t&#39;)$의 energy(dissimilarity)는 크도록 학습한다는 의미입니다.</p>
<ol>
<li>먼저 Entitie(node)들을 <strong>entitiy space $R^k$</strong>에 embedding합니다.</li>
<li>각 Entitie $e$을 mapping function $M_r$을 통해 relation space로 mapping합니다.</li>
<li>각 Relation(link)들은</li>
</ol>
<p>학습 과정은 다음과 같습니다.<img src="https://images.velog.io/images/minjung-s/post/8f29c2fe-f157-47f4-9f1e-2336e7cd6f75/image.png" alt=""></p>
<p>1) relation set의 $l$에 대해 uniform distribution을 따르게 하고 정규화를 시킵니다.
2) entitiy set의 $e$에 대해 uniform distribution을 따르게 하고 정규화를 시킵니다.
3) triaining triplet set $S$에서 batch size만큼의 triplet을 뽑아 $S_{batch}$를 구성하고, $T_{batch}$를 공집합으로 초기화합니다.
4) $S_batch$에 대한 corrupted triplet을 만들어 $T_batch$에 원소로 넣어줍니다.
5) 구성된 $S_{batch}$와 $T_{batch}$로 loss를 mimize하는 방향으로 임베딩을 업데이트합니다.
6) 2)~5)를 반복합니다.</p>
<p><strong><code>TransE</code></strong>는 KG에서 entities간의 관계를 잘 반영하고 기존 SE model보다 최적화가 간단합니다. 2-way interactions를 표현하는데 있어 강점이 있지만, 3-way dependencies를 표현하는데는 약점을 가집다. 또한 1-to-1 이상의 , 1-to-N, N-to-1 관계를 포함하는데 TransE는 부적합할 수 있습니다.
<br></p>
<h1 id="4-embedding-entire-graphs">4. Embedding Entire Graphs</h1>
<p>이전까지는 node를 embedding하는 방법을 배웠습니다. 
이번 파트에서는 Graph $G$를 embedding하는 방법을 배워보겠습니다.
전체 graph 뿐만 아니라 전체 graph의 sub-graph를 한 point를 embedding할 수 있습니다. 
<img src="https://images.velog.io/images/minjung-s/post/8908cb84-1686-42cd-85b2-7ae0e65f34d3/image.png" alt="">
 (sub)graph embedding을 통해 &quot;Toxic molecules, non-toxic molecules 분류&quot;, &quot;anomalous graph 분류&quot;등을 할 수 있습니다.</p>
<p> 다음으로 (sub)grpah를 embedding하는 몇가지 approach를 알아보겠습니다.</p>
<blockquote>
<p><strong>Approach 1</strong>
(sub)graph $G$의 각 node를 embedding하고(ex.Deep Walk, node2vec...) 그 embedding값을 모두 더하거나 평균을 내어 graph embedding을 할 수 있습니다.
sum : $z_g= \sum_{v \in G}z_v$
avg : $z_g= {{1}\over{# ; of; node}}\sum_{v \in G}z_v$</p>
</blockquote>
<blockquote>
<p><strong>Approach 2</strong>
(sub)graph를 대표하는 <strong>virtual node (super-node)</strong>를 만들고, 그 node를 embedding값을 (sub)graph의  embedding으로 사용할 수 있습니다.
<img src="https://images.velog.io/images/minjung-s/post/a7f3fd76-291f-40c1-95fa-66821083db72/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><strong>Approach 3 : Anonymous Walks Embeddings</strong>
<img src="https://images.velog.io/images/minjung-s/post/4e328983-e8ec-4447-9393-fa991c367ab8/image.png" alt="">
<strong>Anonymous Walk</strong>는 random walk를 하는데 어느 node를 지나왔느냐가 아닌, 지나온 순서를 고려하는 random walk입니다. random walk를 진행하고 그 발자취의 순서(index)를 Anonymous Walk라고 합니다.
Anonymous Walk의 결과로 embedding하는 것을 Anonymous Walks Embeddings이라고 합니다.</p>
</blockquote>
<h1 id="reference">Reference</h1>
<ul>
<li><a href="http://snap.stanford.edu/class/cs224w-2019/slides/07-noderepr.pdf">CS244W fall 2019 : Machine Learning with Graphs의 7강 &quot;Graph Representation Learning&quot;</a></li>
<li>데이터 괴짜님 <a href="https://data-weirdo.github.io/data/2020/09/28/data-graph-07.graph_representation_learning/">CS224W - 07.Graph Representation Learning</a></li>
<li>frhyme님 <a href="https://frhyme.github.io/machine-learning/node2vec/">node2vec은 무엇인가?</a></li>
<li>Sukwon Tun님 <a href="https://sukwonyun.github.io/%EC%A7%80%EC%8B%9D%EA%B7%B8%EB%9E%98%ED%94%84/TransE/">[지식그래프] (TransE) Translating Embeddings for Modeling Multi-relational Data</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[딥러닝]Optimization Algorithm (최적화 알고리즘) ]]></title>
            <link>https://velog.io/@minjung-s/Optimization-Algorithm</link>
            <guid>https://velog.io/@minjung-s/Optimization-Algorithm</guid>
            <pubDate>Tue, 01 Dec 2020 14:54:03 GMT</pubDate>
            <description><![CDATA[<p>이번 포스팅은 Neural Network를 빠르게 훈련시키는 <strong>최적화 알고리즘</strong>에 관한 내용입니다. 딥러닝은 크기가 큰 데이터의 경우 잘 작동하는데, 데이터의 크기가 클수록 훈련 속도는 느려집니다. 
이런 경우 효율성을 높이기 위한 최적화 알고리즘을 잘 선택해야 합니다.
여러가지 최적화 알고리즘의 개념에 대해 알아보고 tensorflow 코드로 구현해 보았습니다.</p>
<h1 id="1-gradient-descent-algorithm-경사하강법">1. Gradient Descent Algorithm (경사하강법)</h1>
<h2 id="gradient-descent">Gradient Descent</h2>
<blockquote>
<p>경사 하강 법(Gradient Descent Algorithm)이란, 네트워크의 parameter들을 θ (-&gt;$W,b$)라고 했을 때, Loss function $J(θ)$의 optima(Loss funtion의 최소화)를 찾기 위해 파라미터의 기울기(gradient) $∇θJ(θ)$ (즉, $dW$와 $db$)를 이용하는 방법입니다. </p>
</blockquote>
<p>Gradient Descent에서는 $\theta$ 에 대해 gradient의 반대 방향으로 일정 크기만큼 이동해내는 것을 반복하여 Loss function $J(θ)$ 의 값을 최소화하는 파라미터 $W,b$를 찾습니다. 한 iteration에서의 변화 식은 다음과 같습니다.</p>
<blockquote>
<p><strong>Gradient Descent Algorithm</strong>
$
W = W - \alpha dW \
b = b - \alpha db
$
$\alpha$ : learning rate</p>
</blockquote>
<p>Gradient Descent Algorithm은 한 iteration에서 다룰 데이터 크기에 따라 세가지로 나눌 수 있습니다.
<img src="https://images.velog.io/images/minjung-s/post/a5ccfeaf-9ab5-4a6e-bc88-6064ef5deb31/image.png" alt=""></p>
<ul>
<li>Batch Gradient Desencet (BGD) :전체 데이터 셋에 대한 에러를 구한 뒤 기울기를 한번만 계산하여 모델의 parameter 를 업데이트 하는 방법</li>
<li>Stochastic Gradient Descent (SGD) : 임의의 하나의 데이터에 대해서 에러를 구한 뒤 기울기를 계산하여, 모델의 parameter 를 업데이트 하는 방법</li>
<li>Mini-batch Gradient Descent (MGD): 전체 데이터셋에서 뽑은 Mini-batch의 데이터에 대해서 각 데이터에 대한 기울기를 구한 뒤, 그것의 평균 기울기를 통해 모델의 parameter 를 업데이트 하는 방법</li>
</ul>
<h2 id="mini-batch-gradient-desecent">Mini-batch gradient desecent</h2>
<p>앞서 말했듯이 <strong>Batch Gradient Descent (BGD)</strong>란, 학습 한 번에 모든 데이터셋에 대한 기울기를 구하는 것 입니다.
반면, <strong>Mini-batch Gradient Descent (MGD)</strong>란, 학습 한 번에 데이터셋의 일부에 대해서만 기울기를 구하는 것을 의미합니다. 즉 전체 데이터에 대한 기울기가 아닌, mini-batch로 나누어 기울기를 구하여 역전파하여 웨이트를 업데이트 하는 것 입니다.
만약 훈련데이터가 5,0000,000개가 있다고 가정해보겠습니다.
$X \in (n_x, 5,000,000),Y \in (1, 5,000,000)$
$$ 
X = [ x^{(1)},x^{(2)} ,...,x^{(10,000)},....,x^{(5,000,000)}]\ 
Y = [ y^{(1)},y^{(2)} ,...,y^{(10,000)},....,y^{(5,000,000)}] 
$$</p>
<p>이때 min-batch의 크기를 1,000으로 잡는다면
$
X^{{1}} = [ x^{(1)},x^{(2)} ,...,x^{(1000)}]
Y^{{1}} = [ y^{(1)},y^{(2)} ,...,y^{(1000)}]$
$
X^{{2}} = [ x^{(1,001)},x^{(1,002)} ,...,x^{(2,000)}]Y^{{2}} = [ y^{(1,001)},y^{(1,002)} ,...,y^{(2,000)}]$
...
$X^{{5,000}} = [ x^{(4,999,001)},x^{(4,999,002)} ,...,x^{(5,000,000)}] \
Y^{{5,000}} = [ y^{(4,999,001)},y^{(4,999,002)} ,...,y^{(5,000,000)}]$
으로 각 mini-batch set은 $X^{{t}} \in (n_x, 1000),Y^{{t}} \in (1, 1000)$이고 각 mini-batch는 1000쌍의 x,y로 이루어지며, 총 mini-batch set은 5,000개가 됩니다.
이때 훈련은 다음과 같이 진행됩니다.
<img src="https://images.velog.io/images/minjung-s/post/df91399e-615a-4de2-9166-b770768eb69d/image.png" alt="">
mini-batch의 데이터의 기울기를 모두 구하여 평균한 후, 가중치 업데이트를 진행합니다.
이 한 for문이 모두 돌았을 때, <strong>즉 (전체 데이터 수)/(mini-batch size) = 5,000,000/1000 = 5,000번의 iteration이 완료되는 것이 1epoch</strong>입니다. 
gradient를 묶어서 계산하기 때문에 BGD보다 훨씬 빠릅니다.</p>
<h2 id="understanding-mini-batch-gradient-descent">Understanding mini-batch gradient descent</h2>
<p>gradient descent를 사용하기 위해서는 batch의 크기(mini-batch size)를 선택해야 합니다.</p>
<blockquote>
<p>전체 데이터가 m개 일 때</p>
</blockquote>
<ul>
<li>mini-batch size = m  -&gt; Batch Gradient Descent</li>
<li>mini-batch size = 1  -&gt; Stochastic Gradient Descent</li>
<li>mini-batch size = n &lt; m  -&gt; Mini-batch Gradient Descent</li>
</ul>
<p><img src="https://images.velog.io/images/minjung-s/post/2f893f70-2a52-4b1d-bdbb-447d6d595923/image.png" alt="">
<strong>BGD</strong>는 전체 데이터에 대하여 오차를 계산하기 때문에 minimum에 안정적으로 수렴합니다. 하지만, 한 번의 iteration마다 모든 학습 데이터를 사용하므로 학습이 오래 걸립니다.</p>
<ul>
<li>장점 : loss가 안정적으로 수렴 (cost function의 optimal로 안정적으로 수렴)</li>
<li>단점 : 한 iteration에 모든 데이터셋을 사용하기 때문에 학습이 오래 걸린다. 
local optimal을 빠져나오기 힘들다.</li>
</ul>
<p><strong>SGD</strong>는 한번의 iteration마다 한개의 sample로 gradient descent하는 것이기 때문에, 거의 항상 global minimum에 도달합니다. BGD보다 noisy한 이유는, 어떤 샘플은 minimum으로 가는 좋은 샘플일 수도 있고 어떤 샘플은 minimum으로 가기 어려운 샘플일 수도 있기 때문입니다. 또한, SGD의 가장 큰 단점은 벡터화 과정에서 속도가 매우 느리다는 것입니다. 데이터 하나씩 처리하는 방식이기 때문에 매우 비효율적입니다.</p>
<ul>
<li>장점 : local minimum에 빠질 위험이 적다.</li>
<li>단점 : Optimal을 찾지 못할 가능성이 있다. 
다른 알고리즘에 비해 속도가 느리다. (뒤에서 Momentum,RMSprop,Adam과 비교하여 설명하겠습니다.)</li>
</ul>
<p><strong>MGD</strong>는 한 번의 iteration마다 n(1&lt;n&lt;m)개의 데이터를 사용하기 때문에 BGD와 SGD의 장점을 합친 알고리즘입니다. MGD를 사용하 때는 mini-batch size를 잘 설정해야 합니다.</p>
<blockquote>
<p><strong>mini-batch size 설정</strong></p>
</blockquote>
<ul>
<li>small training set (대략 m &lt; 2000) -&gt; BGD사용</li>
<li>Typical mini-batch size : <ol>
<li>64, 128, 256, 512컴퓨터는 2진수로 계산되기 때문에 <strong>batch size는 대체로 2의n승으로 설정</strong></li>
<li><strong>$X^{{t}}, Y^{{t}}$가 GPU/CPU에 모두 들어가게 설정</strong>(mini-batch쌍이 GPU/CPU 메모리에 들어가지 않는다면 성능은 더 악화됩니다.)</li>
</ol>
</li>
</ul>
<h3 id="코드-구현">코드 구현</h3>
<pre><code class="language-python">#python
weight[i] += - learning_rate * gradient

#tensorflow 2.x
tf.keras.optimizers.SGD(lr = 0.001)</code></pre>
<h1 id="2-momentum-algorithm-모멘텀">2. Momentum Algorithm (모멘텀)</h1>
<h2 id="exponentially-weighted-averages지수-가중-평균">Exponentially weighted averages(지수 가중 평균)</h2>
<p>Momentum 알고리즘을 이해하기 위해서는 <strong>지수 가중 평균(Exponentially Weighted Average)</strong>(=지수 이동 평균)을 이해해야 합니다.</p>
<blockquote>
<p>지수 가중 평균(=지수 이동 평균)이란, <strong>데이터의 이동 평균을 구할 때, 오래된 데이터가 미치는 영향을 지수적으로 감쇠(exponential decay) 하도록 만들어 주는 방법</strong>입니다.</p>
</blockquote>
<p>예를 들어, 런던의 일일 평균 날씨를 그래프로 나타내보았습니다.
<img src="https://images.velog.io/images/minjung-s/post/e31cc85b-4769-4be1-a07b-8d787a1f4493/image.png" alt="">
이 데이터는 nosiy하기 때문에 트랜드를 산출하기 위해서는 어떻게 해야 할까요?
(moving average)
단순히 전후 몇일간의 평균으로만 계산한다면(Moving Average) 오래된 데이터의 영향과 최신 데이터의 영향이 비슷해져 버리므로 우리가 원하는 추세를 나타낼 수 없을 것입니다.
이를 보완하기 위해 Weight를 부여하는 방식이 도입되었는데, 시간이 흐름에 따라 지수적으로 감쇠하도록 설계한 것이 지수 가중 평균입니다.</p>
<p>일단 $v_0 =0$으로 초기값을 설정합니다.
다음으로, 일 별로 모든 값을 평균화 합니다. value로 나오는 값을 0.9의 weight로 곱하고 0.1을 더한뒤, 그 날의 온도를 곱해줍니다.
$$
v_1 = 0.9v_0 + 0.1\theta_1 \
v_2 = 0.9v_1 + 0.1\theta_2 \
...\
v_n = 0.9v_{n-1} + 0.1\theta_n
$$
v라는 날에 대한 공식의 일반화는 <strong>0.9(이전날짜v) + 0.1(그날의 온도)</strong>입니다.
<img src="https://images.velog.io/images/minjung-s/post/75407124-6524-4d98-ab13-9b17a27853b6/image.png" alt="">
위 그래프의 빨간색 선이 지수 가중 평균 방식으로 구한  일별 날짜의 온도의 이동평균으로 나타낸 그래프입니다. </p>
<blockquote>
<p><strong>지수 가중 평균 식</strong>
$v_t = \beta v_{t-1} + (1- \beta)\theta_t$
<em>( $0\leq \beta\leq1$, $\theta$:새로운 데이터, $v$:현재의 경향)</em></p>
</blockquote>
<p>위 지수 가중 평균의 식을 보면,
$v_t = \beta {\beta v_{t-2} + (1- \beta)\theta_{t-1}} + (1- \beta)\theta_t$이고, $v_{t-2}$앞에 0~1사이의$\beta$값이 곱해지므로, <strong>오래된 데이터일수록 현재의 경향에 미치는 영향이 줄어든다</strong>는 것을 알 수 있습니다.
<span style="color:red">예전 데이터는 $\beta^n$으로 지수적으로 빠르게 감소하게 되기 때문에, <strong>지수적(Exponetially) 감쇠</strong>라고 부릅니다.</span></p>
<h3 id="지수-가중-평균의-근사">지수 가중 평균의 근사</h3>
<blockquote>
<p><strong>지수 가중 평균의 근사 식</strong>
$v_t  \approx 1/(1-\beta)$ </p>
</blockquote>
<p><strong>$v_t$는 $1/(1-\beta)$일의 데이터의 평균을 사용하여 근사</strong>합니다
예를들어 
<span style="color:red">$\beta = 0.9$</span>이면, 이전 10일의 온도의 평균이 그날의 $v$이고<span style="color:red">(빨간색 그래프)</span>
<span style="color:green">$\beta = 0.98$</span>이면, 이전 50일의 온도의 평균이 그날의 $v$이고<span style="color:green">(초록색그래프)</span>
<span style="color:#ffcc00">$\beta = 0.5$</span>이면, 이전 2일의 온도의 평균이 그날의 $v$입니다.<span style="color:#ffcc00">(노란색 그래프)</span>
<img src="https://images.velog.io/images/minjung-s/post/2c3cfbf5-7bc9-4999-94d9-0fdd4fa2571f/image.png" alt=""><img src="https://images.velog.io/images/minjung-s/post/50962411-9ef8-4e23-a9fa-eeb029b5e7e9/image.png" alt=""></p>
<ul>
<li><span style="color:green">$\beta = 0.98$</span>의 경우$\beta$값이 1에 가까워, 많은 날을 고려하기 때문에 더 부드러운 그래프 모양이 나옵니다. 또한 더 큰 범위의 온도로 평균치를 구하기 때문에 그래프가 오른쪽으로 이동하였습니다.
이 경우, 이전 데이터$v_{t-n}$에 <span style="color:green">$\beta = 0.98$</span>의 큰 가중을 적용하고, 현재 데이터$\theta$에 <span style="color:green">$1-\beta = 0.02$</span>라는 작은 가중을 적용합니다. 최신 데이터보다는 과거의 데이터에 대한 비중이 큽낟. </li>
<li><span style="color:#ffcc00">$\beta = 0.5$</span>의 경우 훨씬 더 작은 범위의 평규치를 구하게 됩니다. 데이터가 더 noisy하고, 이상점에서 훨씬 취약하게 도비니다. 하지만, 기온변화를 빠르게 반영하게 됩니다. 
$\beta$에 따라 과거 데이터의 비중을 고려하는 이 공식을 <strong>지수 가중 평균 Exponentially weighted (moving) average</strong>라고 합니다.</li>
</ul>
<h3 id="바이어스-보정-bias-correction">바이어스 보정 (Bias Correction)</h3>
<p>지수 가중 평균을 이용한 추정은 초기 구간에 오차가 있습니다. 
머신러닝에서는 지수 가중 평균을 구현할 때 초기 구간을 기다린 후 사용하기 때문에 바이어스 보정을 신경쓰지 않습니다. 
하지만, 초기 구간의 바이어스를 신경쓴다면 바이어스 보정을 사용해야 합니다. 바이어스 보정은, 기존$v_t$에서 $1-\beta^t$를 나누어 주면 됩니다.</p>
<blockquote>
<p>$v_{t(bias correction)} \= v_{t} / (1-\beta^t) \= {\beta v_{t-1} + (1- \beta)\theta_t}/(1-\beta^t)$</p>
</blockquote>
<h2 id="gradient-descent-with-momentum">Gradient descent with momentum</h2>
<p>이제, 위에서 학습한 지수 가중 평균(Expoentially Weighted Average)을 적용해 보겠습니다. (이하 &quot;가중 평균&quot;이라고 표현된 것은 지수 가중 평균을 의미합니다.)</p>
<blockquote>
<p>모멘텀 알고리즘이란, Gradient descent에서 <strong>기울기(gradient)의 가중 평균치를 산출하여 weight를 업데이트</strong>하는 것입니다. Momentum을 사용함으로써, <strong>속도가 빠르고 SGD가 over shooting,diverging 되는 것을 방지하며 locla minimum 탈출이 가능</strong>합니다.</p>
</blockquote>
<p>모멘텀(Momentum=Gradient descent with momentum)은 일반적인 Gradient Descent 알고리즘보다 빠르게 동작합니다. </p>
<p>앞서 말해듯, SGD(또는 MGD)는 다음과 같이 동작하게 됩니다.
<img src="https://images.velog.io/images/minjung-s/post/0866fd5d-969d-49a1-bb0f-2a32f135bdb7/image.png" alt="">
위 그래프의 변동폭은 learning rate를 나타냅니다. 만약 learning rate를 작게한다면 학습속도가 너무 느리고, learning rate를 크게한다면 over shooting이나 diverging의 위험성이 있습니다. 따라서, opimal로 향하기 위해서는 가로축으로는 빠르게 전진해야하고, 세로축으로는 천천히 진행되어야 합니다. 
weight의 derivative($dW$)에 대한 가중 평균치 <strong>velocity($v$)</strong>를 구해 이 문제를 해결합니다.</p>
<blockquote>
<p><strong>기존 Gradient Descent Algorithm</strong>
$
W = W - \alpha dW \
b = b - \alpha db
$</p>
</blockquote>
<blockquote>
<p><strong><span style="color:red">Momentum Algorithm</span></strong>
$
v_{<em>{dW}} = \beta v</em>{<em>{dW}} + (1-\beta)dW \
v</em>{<em>{db}} = \beta v</em>{<em>{db}} + (1-\beta)db \
W = W - \alpha v</em>{<em>{dW}} \
b = b - \alpha v</em>{_{db}}
$
($v$)는 velocity를 라고 하고, $dW$는 acceleration입니다.</p>
</blockquote>
<p>총 두개의 하이퍼파라미터가 있습니다. $\alpha$와 $\beta$입니다.
$\alpha$는 learning reate이고, $\beta$는 <strong>momentum</strong>입니다. 지난 몇개의 기울기 강하의 평균치를 사용할 것인지에 대한 파라미터입니다. _(지수 가중 평균의 $\beta$. 머신러닝에서는 바이어스 보정은 거의 사용하지 않습니다.) _
주로 $\beta = 0.9$로 사용합니다.(지난 10개의 기울기 강하의 평균치 사용)</p>
<blockquote>
<p><strong><span style="color:red">대부분 $(1-\beta)$을 1로 근사</span>하여,
$v_{<em>{dW}} = \beta v</em>{<em>{dW}} + dW$
  $v</em>{<em>{db}} = \beta v</em>{_{db}} + db$
  로 사용합니다.</strong></p>
</blockquote>
<p>위와 같은 momentum algorithm은 경사 하강(Gradient descent)를 smooth하게 만들어주어 over shooting, diverging을 막아줍니다.</p>
<h2 id="코드">코드</h2>
<pre><code class="language-python">#python
v = beta * v - learning_rate * gradient
weight[i] += v

#tensorflow 2.x
tf.keras.optimizers.SGD(lr = 0.1, momentum = 0.9)</code></pre>
<h1 id="3-rmsprop-algorithm">3. RMSprop Algorithm</h1>
<p>RMSprop은 Root Mean Square Propatation의 약자입니다. 이 알고리즘 역시 기울기 강하의 속도를 증가시키는 알고리즘 입니다.</p>
<blockquote>
<p><strong>기존 Gradient Descent Algorithm</strong>
$
W = W - \alpha dW \
b = b - \alpha db
$</p>
</blockquote>
<blockquote>
<p><strong><span style="color:red">RMSprop Algorithm</span></strong>
$
S_{<em>{dW}} = \beta_2 S</em>{<em>{dW}} + (1-\beta_2)dW^2 \
S</em>{<em>{db}} = \beta_2 S</em>{<em>{db}} + (1-\beta_2)db^2 \
W = W - \alpha {dW}/\sqrt{S</em>{<em>{dW}} + \epsilon} \
b = b - \alpha {dW}/\sqrt{S</em>{_{db}} + \epsilon} 
$</p>
</blockquote>
<p> Momentum algorithm과 마찬가지로 <strong>지수 이동 평균</strong>이 적용되었습니다.
<img src="https://images.velog.io/images/minjung-s/post/cae8106f-4c46-4a1f-a84a-162392846426/image.png" alt="">
앞서 말해듯, SGD(또는 MGD)는 다음과 같이 동작하게 되고, 안정적으로 opimal로 향하기 위해서는 가로축으로 빠르게 전진해야하고 세로축으로는 천천히 진행되어야 합니다. 
(위 그림에서 명료성을 위해 가로축을 $dW$,세로축을 $db$라고 하겠습니다.)
가로축을 빠르게 이동하고 싶다면 $dW$을 작게하여 $\sqrt{S_{<em>{dW}}}$를 크게할 수 있고,
세로축을 빠르게 이동하고 싶다면 $db$을 크게하여 $\sqrt{S</em>{_{db}}}$를 작게할 수 있습니다.
이는 하이퍼 파라미터인 $\beta_2$로 조절할 수 있습니다.</p>
<h2 id="코드-1">코드</h2>
<pre><code class="language-python">#python
beta2 = beta2 * s + (1 - beta2) * gradient**2
weight[i] += -learning_rate * gradient / (np.sqrt(s) + e)

#tensorflow 2.x
tf.keras.optimizers.RMSprop(learning_rate=0.001,rho=0.9) //rho가 beta_2</code></pre>
<h1 id="4-adam-optimization-algorithm">4. Adam Optimization Algorithm</h1>
<p>아담(Adam)은 Adaptive Moment Estimation의 약자입니다. 모멘텀과 RMSprop을 섞어놓은 최적화 알고리즘 입기 때문에, 딥러닝에서 가장 흔히 사용되는 최적화 알고리즘 입니다. </p>
<p><strong><span style="color:red">Adam Optimization Algorithm</span></strong>
먼저 초기화를 진행하고, Momentum과 RMSprop에서 사용한 $v$와 $S$를 지정해줍니다..
$$
v_{<em>{dW}} = 0,S</em>{<em>{dW}} = 0,
v</em>{<em>{db}} = 0,S</em>{_{db}} = 0
$$</p>
<p>$$
v_{<em>{dW}} = \beta_1 v</em>{<em>{dW}} + (1-\beta_1)dW \
v</em>{<em>{db}} = \beta_1 v</em>{<em>{db}} + (1-\beta_1)db 
$$
$$
S</em>{<em>{dW}} = \beta_2 S</em>{<em>{dW}} + (1-\beta_2)dW^2 \
S</em>{<em>{db}} = \beta_2 S</em>{<em>{db}} + (1-\beta_2)db^2 
$$
또한, Momentum에서 소개한 Bias correction을 해주어야 합니다.
$$
v</em>{<em>{dW}}^{biascorr} = v</em>{<em>{dW}}/ (1-\beta^t) \
v</em>{<em>{db}}^{biascorr} = v</em>{<em>{db}}/ (1-\beta^t) \
S</em>{<em>{dW}}^{biascorr} = S</em>{<em>{dW}}/ (1-\beta^t) \ 
S</em>{<em>{db}}^{biascorr} = S</em>{<em>{db}}/ (1-\beta^t) \ 
$$
마지막으로 Momentum과 RMSprop의 가중치 업데이트 방식을 모두 사용하여 가중치 업데이트를 진행합니다.
$$
W = W - \alpha {v</em>{<em>{dW}}^{biascorr}}/\sqrt{S</em>{<em>{dW}}^{biascorr} + \epsilon} \
b = b - \alpha {v</em>{<em>{db}}^{biascorr}}/\sqrt{S</em>{_{db}}^{biascorr} + \epsilon} 
$$</p>
<blockquote>
<p>Adam의 하이퍼 파라미터
$\alpha$ : learning rate<br>$\beta_1$ : 1차 moment, 대부분 0.9  ($dw$의 지수 가중 평균 계산 )
$\beta_2$ : 2차 moment, 논문에서는 0.99 ($dw^2$과 $db^2$의 지수 가중 평균 계산)
$\epsilon$ : 논문에서는 0.10^{-8} (성능에 거의 영향 X)</p>
</blockquote>
<h2 id="코드-2">코드</h2>
<pre><code class="language-python"># tensorflow2.x
tf.keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.99, epsilon=None)</code></pre>
<h1 id="5-opimization-problem-solving">5. Opimization problem solving</h1>
<h2 id="learning-rate-decay">Learning rate decay</h2>
<blockquote>
<p>Learning rate decay란, <strong>learning rate $\alpha$를 천천히 줄여나가는 것</strong>입니다.</p>
</blockquote>
<p>크기가 큰 $\alpha$를 유지한다면, 학습은 빠르지만 optima 부근에서 맴돌 뿐 정확히 수렴하기 어렵습니다.
크기가 작은 $\alpha$를 유지한다면, 학습이 매우 느릴 것입니다.
Learning rate decay를 사용하면 처음에는 learning rate $\alpha$를 하여 빠르게 학습을 진행하고, $\alpha$값이 점차 작아지면서 optima 부근의 매우 좁은 범위까지 집입할 수 있게 됩니다.</p>
<blockquote>
<p><strong>Learning rate decay method 1</strong>
$
\alpha = (1/{1+decay-rate<em>epoch-num})</em>\alpha_0
$</p>
</blockquote>
<blockquote>
<p><strong>Learning rate decay method 2 (exponential decay)</strong>
$
\alpha = (decay-rate)^{epoch-num}<em>\alpha_0
\alpha = (k/\sqrt{epoch-num})</em>\alpha_0
$</p>
</blockquote>
<p>$\alpha_0$와 decay_rate모두 하이퍼 파라미터 입니다.</p>
<h2 id="local-minimum">Local minimum</h2>
<p>Loss function의 global minimum을 빠르고 정확하게 찾는 것이 최적화의 목적입니다.
<img src="https://images.velog.io/images/minjung-s/post/2b7d5d0a-52b8-47b5-b03d-e72ec297e1d0/image.png" alt="">
딥러닝 초기에는 최적화 알고리즘이 발달하지 않아 <strong>local minimum</strong>에 빠질 위험성이 있었습니다.
하지만 현재는 최적화 이론이 많이 발달하였고 고차원 공간에서 정의되는 Loss function에 대해 <strong>local minimum에 빠질 확률은 매우 작습니다</strong>. local minimum에 빠진다는 것은, 네트워크를 구성하는 모든 파라미터가 모두 local minimum에 빠져야하는데 아주 희박한 확률이기 때문입니다. 따라서 local minimum은 대부분 고려하지 않습니다.</p>
<h2 id="plateau">Plateau</h2>
<p>Plateau 현상이란, Loss function에 평지(Plateau)가 생겨 기울기가 0에 가까워져 loss가 업데이트 되지 않는 현상을 말합니다. 이 경우는 local minimum에 비해 일어날 확률이 높습니다. </p>
<p><img src="https://images.velog.io/images/minjung-s/post/affe546c-e6f3-4697-8717-336e69090b9f/optimization.gif" alt="">
위 그래프에서 알 수 있듯 SGD는 Plateau에 취약합니다. 이 현상을 고려한다면, SGD가 아닌 RMSprp, Adam 등과 같은 Opimizer를 사용하는 것이 적절합니다.</p>
<p>reference : 
<a href="https://www.coursera.org/learn/deep-neural-network/home">https://www.coursera.org/learn/deep-neural-network/home</a>
<a href="http://www.datamarket.kr/xe/index.php?mid=board_jPWY12&amp;page=2&amp;document_srl=66086">http://www.datamarket.kr/xe/index.php?mid=board_jPWY12&amp;page=2&amp;document_srl=66086</a>
<a href="http://shuuki4.github.io/deep%20learning/2016/05/20/Gradient-Descent-Algorithm-Overview.html">http://shuuki4.github.io/deep%20learning/2016/05/20/Gradient-Descent-Algorithm-Overview.html</a>
<a href="https://twinw.tistory.com/247">https://twinw.tistory.com/247</a>
<a href="https://wjddyd66.github.io/dl/NeuralNetwork-(3)-Optimazation2/">https://wjddyd66.github.io/dl/NeuralNetwork-(3)-Optimazation2/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Google GCP]Professional Machine Learning Engineer Sample Questions 풀이]]></title>
            <link>https://velog.io/@minjung-s/Professional-Machine-Learning-Engineer-Sample-Questions</link>
            <guid>https://velog.io/@minjung-s/Professional-Machine-Learning-Engineer-Sample-Questions</guid>
            <pubDate>Thu, 19 Nov 2020 13:15:33 GMT</pubDate>
            <description><![CDATA[<p><a href="https://docs.google.com/forms/d/e/1FAIpQLSeYmkCANE81qSBqLW0g2X7RoskBX9yGYQu-m1TtsjMvHabGqg/viewform">Professional Machine Learning Engineer Sample Questions</a>
본 문제들은 Google GCP Machine Learning Engineer 자격증 준비를 위한 예제문제입니다.</p>
<h2 id="1-you-work-for-a-textile-manufacturer-and-have-been-asked-to-build-a-model-to-detect-and-classify-fabric-defects-you-trained-a-machine-learning-model-with-high-recall-based-on-high-resolution-images-taken-at-the-end-of-the-production-line-you-want-quality-control-inspectors-to-gain-trust-in-your-model-which-technique-should-you-use-to-understand-the-rationale-of-your-classifier">1. You work for a textile manufacturer and have been asked to build a model to detect and classify fabric defects. You trained a machine learning model with high recall based on high resolution images taken at the end of the production line. You want quality control inspectors to gain trust in your model. Which technique should you use to understand the rationale of your classifier?</h2>
<p><img src="https://images.velog.io/images/minjung-s/post/9433766d-e6c3-4fbe-ade1-a0c15dc57297/image.png" alt=""></p>
<ul>
<li><input disabled="" type="checkbox"> A. Use K-fold cross validation to understand how the model performs on different test datasets.</li>
<li><input disabled="" type="checkbox"> B. Use the Integrated Gradients method to efficiently compute feature attributions for each predicted image.</li>
<li><input disabled="" type="checkbox"> C. Use PCA (Principal Component Analysis) to reduce the original feature set to a smaller set of easily understood features.</li>
<li><input disabled="" type="checkbox"> D. Use k-means clustering to group similar images together, and calculate the Davies-Bouldin index to evaluate the separation between clusters.</li>
</ul>
<h3 id="정답">정답</h3>
<p><strong>B. Integrated Gradients를 사용하여 이미지 예측을 위한 feature attribution을 효율적으로 계산</strong></p>
<p>본 문제는 image classifier의 성능을 평가할 수 있는 보기를 고르는 문제입니다. Integrated Gradients를 이용하면 이미지 입력의 어떤 pixel값들이 출력을 결정하는데 크게 기여하는지 알 수 있습니다. 입력 이미지의 pixel식별은 이미지 분류로 이어지기 때문에 B가 정답입니다. (GCP에서 사용가능)</p>
<p><img src="https://images.velog.io/images/minjung-s/post/76f9c3d1-cb2d-4fcc-85c5-0bc664070789/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/minjung-s/post/7f9cb948-c2c4-483e-ae4b-dd883819573b/image.png" alt="">
[refrenece : <a href="http://isukorea.com/blog/home/waylight3/281">http://isukorea.com/blog/home/waylight3/281</a>]</p>
<h3 id="오답">오답</h3>
<p>A → K-folde cross validation은 모델의 예측에 대한 설명력이 없습니다.</p>
<p>C → PCA는 높은 차원의 데이터셋의 차원을 축소 하지만 시나리오에 추가적인 이점이 없습니다.</p>
<p>D → Clustering은 분류 모델이 예측한 이유에 대한 인사이트가 없습니다.</p>
<h2 id="2-you-need-to-write-a-generic-test-to-verify-whether-dense-neural-network-dnn-models-automatically-released-by-your-team-have-a-sufficient-number-of-parameters-to-learn-the-task-for-which-they-were-built-what-should-you-do">2. You need to write a generic test to verify whether Dense Neural Network (DNN) models automatically released by your team have a sufficient number of parameters to learn the task for which they were built. What should you do?</h2>
<p><img src="https://images.velog.io/images/minjung-s/post/867d0501-d834-4d50-81af-cd1943681286/image.png" alt=""></p>
<ul>
<li><input disabled="" type="checkbox"> A. Train the model for a few iterations, and check for NaN values.</li>
<li><input disabled="" type="checkbox"> B. Train the model for a few iterations, and verify that the loss is constant.</li>
<li><input disabled="" type="checkbox"> C. Train a simple linear model, and determine if the DNN model outperforms it.</li>
<li><input disabled="" type="checkbox"> D. Train the model with no regularization, and verify that the loss function is close to zero.</li>
</ul>
<h3 id="정답-1">정답</h3>
<p><strong>D. 정규화 없이 모델을 훈련시키고 loss가 0에 가까워지는지 확인합니다.</strong></p>
<p>parameter가 충분하여 설명력이 있다면 loss가 감소해야 합니다.</p>
<h3 id="오답-1">오답</h3>
<p>C → 단순히 선형 모델보다 결과가 좋다고 해서 비선형 데이터 표현을 학습하기에 충분한 parameter가 있다고 보장할 수 없습니다. </p>
<h2 id="3-your-team-is-using-a-tensorflow-inception-v3-cnn-model-pretrained-on-imagenet-for-an-image-classification-prediction-challenge-on-10000-images-you-will-use-ai-platform-to-perform-the-model-training-what-tensorflow-distribution-strategy-and-ai-platform-training-job-configuration-should-you-use-to-train-the-model-and-optimize-for-wall-clock-time">3. Your team is using a TensorFlow Inception-v3 CNN model pretrained on ImageNet for an image classification prediction challenge on 10,000 images. You will use AI Platform to perform the model training. What TensorFlow distribution strategy and AI Platform training job configuration should you use to train the model and optimize for wall-clock time?</h2>
<p><img src="https://images.velog.io/images/minjung-s/post/86c35756-fba9-41b7-8003-87a7cdb22bb2/image.png" alt=""></p>
<ul>
<li><input disabled="" type="checkbox"> A. Default Strategy; Custom tier with a single master node and four v100 GPUs.</li>
<li><input disabled="" type="checkbox"> B. One Device Strategy; Custom tier with a single master node and four v100 GPUs.</li>
<li><input disabled="" type="checkbox"> C. One Device Strategy; Custom tier with a single master node and eight v100 GPUs.</li>
<li><input disabled="" type="checkbox"> D. Central Storage Strategy; Custom tier with a single master node and four v100 GPUs.</li>
</ul>
<h3 id="정답-2">정답</h3>
<p><strong>D. Central Storage Strategy; Custom tier with a single master node and four v100 GPUs.</strong></p>
<p>D → [<a href="https://www.tensorflow.org/guide/distributed_training#centralstoragestrategy">Distributed training with Tensorflow</a>]</p>
<p>본 문제는 분산처리가 가능한 작업 구성에 대한 문제입니다. 분산처리가 되는 Strategy가 D밖에 없습니다.</p>
<pre><code class="language-jsx">central_storage_strategy = tf.distribute.experimental.CentralStorageStrategy()</code></pre>
<h3 id="오답-2">오답</h3>
<p>A,B,C → 모두 단일 장치 구성입니다.</p>
<h2 id="4-you-work-on-a-team-where-the-process-for-deploying-a-model-into-production-starts-with-data-scientists-training-different-versions-of-models-in-a-kubeflow-pipeline-the-workflow-then-stores-the-new-model-artifact-into-the-corresponding-cloud-storage-bucket-you-need-to-build-the-next-steps-of-the-pipeline-after-the-submitted-model-is-ready-to-be-tested-and-deployed-in-production-on-ai-platform-how-should-you-configure-the-architecture-before-deploying-the-model-to-production">4. You work on a team where the process for deploying a model into production starts with data scientists training different versions of models in a Kubeflow pipeline. The workflow then stores the new model artifact into the corresponding Cloud Storage bucket. You need to build the next steps of the pipeline after the submitted model is ready to be tested and deployed in production on AI Platform. How should you configure the architecture before deploying the model to production?</h2>
<p><img src="https://images.velog.io/images/minjung-s/post/72d71afa-eefd-4d78-9edb-95a238e01994/image.png" alt=""></p>
<ul>
<li><input disabled="" type="checkbox"> A. Deploy model in test environment -&gt; Validate model -&gt; Create a new AI Platform model version</li>
<li><input disabled="" type="checkbox"> B. Validate model -&gt; Deploy model in test environment -&gt; Create a new AI Platform model version</li>
<li><input disabled="" type="checkbox"> C. Create a new AI Platform model version -&gt; Validate model -&gt; Deploy model in test environment</li>
<li><input disabled="" type="checkbox"> D. Create a new AI Platform model version - &gt; Deploy model in test environment -&gt; Validate model</li>
</ul>
<h3 id="정답-3">정답</h3>
<p><strong>A. 테스트 환경에서 모델 배포 → 모델 유효성 검사 → 새 AI 플랫폼 모델 버전 만들기</strong></p>
<p>모델이 테스트 환경에서 배포된 수 유효성 검사를 할 수 있고, 프로덕션에 배포되기 전 릴리스 버전이 설정되기 때문에 정확합니다.</p>
<h3 id="오답-3">오답</h3>
<p>B → 테스트 환경에 배포 전에 유효성 검사를 할 수 없습니다.</p>
<p>C → 모델이 검증되기 전에 릴리스 후보에 대한 모델 버전이 설정되기 때문에 X</p>
<p>D → 테스트 환경에 배포전에 유효성 검사 X, 모델 검증 전 릴리스 버전 설정 X</p>
<h2 id="5-you-work-for-a-maintenance-company-and-have-built-and-trained-a-deep-learning-model-that-identifies-defects-based-on-thermal-images-of-underground-electric-cables-your-dataset-contains-10000-images-100-of-which-contain-visible-defects-how-should-you-evaluate-the-performance-of-the-model-on-a-test-dataset">5. You work for a maintenance company and have built and trained a deep learning model that identifies defects based on thermal images of underground electric cables. Your dataset contains 10,000 images, 100 of which contain visible defects. How should you evaluate the performance of the model on a test dataset?</h2>
<p><img src="https://images.velog.io/images/minjung-s/post/98696357-a681-456a-b0a7-08a9b203378e/image.png" alt=""></p>
<ul>
<li><input disabled="" type="checkbox"> A. Calculate the Area Under the Curve (AUC) value.</li>
<li><input disabled="" type="checkbox"> B. Calculate the number of true positive results predicted by the model.</li>
<li><input disabled="" type="checkbox"> C. Calculate the fraction of images predicted by the model to have a visible defect.</li>
<li><input disabled="" type="checkbox"> D. Calculate the Cosine Similarity to compare the model’s performance on the test dataset to the model’s performance on the training dataset.</li>
</ul>
<h3 id="정답-4">정답</h3>
<p><strong>A. AUC값을 계산한다.</strong></p>
<p> AUC는 선택된 임계 분류임계 값에 관계없이 모델의 예측 품질을 측정합니다.</p>
<p><img src="https://images.velog.io/images/minjung-s/post/417bff30-9f15-43d0-a931-a89f8b1e4b11/image.png" alt=""></p>
<h3 id="오답-4">오답</h3>
<p>B → 10,000개 중에 100개만 결함입니다. 단순히 TP를 계산하는 것은 의미가 없습니다. </p>
<p><img src="https://images.velog.io/images/minjung-s/post/4b25b0dd-0d6d-4066-8e34-35ef23f040b7/image.png" alt=""></p>
<p>C → 단순히 결함이 있는 이미지의 비율을 계산하는 것은 모델의 정확성을 판단하는데 관련이 없습니다.</p>
<p>D → Cosine Similarity는 거리기반 모델(ex.KNN)에서 유용합니다. image classification 모델의 성능을 확인하는데 적절하지 않습니다.</p>
<h2 id="6-you-work-for-a-manufacturing-company-that-owns-a-high-value-machine-which-has-several-machine-settings-and-multiple-sensors-a-history-of-the-machines-hourly-sensor-readings-and-known-failure-event-data-are-stored-in-bigquery-you-need-to-predict-if-the-machine-will-fail-within-the-next-3-days-in-order-to-schedule-maintenance-before-the-machine-fails-which-data-preparation-and-model-training-steps-should-you-take">6. You work for a manufacturing company that owns a high-value machine which has several machine settings and multiple sensors. A history of the machine’s hourly sensor readings and known failure event data are stored in BigQuery. You need to predict if the machine will fail within the next 3 days in order to schedule maintenance before the machine fails. Which data preparation and model training steps should you take?</h2>
<p><img src="https://images.velog.io/images/minjung-s/post/c15cfa73-dea3-4334-8386-83436fb319b4/image.png" alt=""></p>
<ul>
<li><input disabled="" type="checkbox"> A. Data preparation: Daily max value feature engineering with DataPrep; Model training: AutoML classification with BQML</li>
<li><input disabled="" type="checkbox"> B. Data preparation: Daily min value feature engineering with DataPrep; Model training: Logistic regression with BQML and AUTO_CLASS_WEIGHTS set to True</li>
<li><input disabled="" type="checkbox"> C. Data preparation: Rolling average feature engineering with DataPrep; Model training: Logistic regression with BQML and AUTO_CLASS_WEIGHTS set to False</li>
<li><input disabled="" type="checkbox"> D. Data preparation: Rolling average feature engineering with DataPrep; Model training: Logistic regression with BQML and AUTO_CLASS_WEIGHTS set to True</li>
</ul>
<h3 id="정답-5">정답</h3>
<p>** D. 데이터 준비→DataPrep을 사용한 롤릴 평균 기능 엔지니어링**</p>
<p><strong>모델학습 → BQML 및 AUTO_CLASS_WEIGHTS가 TRUE로 설정된 로지스틱 회귀</strong></p>
<p><strong>DataPrep</strong> : rolling average == moving average == 이동평균</p>
<p><img src="https://images.velog.io/images/minjung-s/post/e7c1c58a-80e6-4a25-a6b7-8cb6db615435/image.png" alt=""></p>
<p>[이동평균 예시 출처 : <a href="https://www.investopedia.com/terms/s/sma.asp">https://www.investopedia.com/terms/s/sma.asp</a>]</p>
<p>데이터의 잡음과 변동을 고려하였을 때, min/max 보다 이동평균이 추세를 나타내기에 적절합니다.</p>
<p><strong>Model training</strong> : BQML을 사용하면 BigQuery에서 표준 SQL 쿼리를 사용하여 머신러닝 모델을 만들고 실행할 수 있습니다.</p>
<p>&#39;auto_class_weights=TRUE&#39; 옵션은 <strong>학습 데이터에서 클래스 라벨의 균형을 맞춥니다.</strong> 기본적으로 학습 데이터는 가중치가 더해지지 않습니다. <strong>학습 데이터 라벨의 균형이 맞지 않는 경우 모델은 가장 인기 있는 라벨 클래스에 더 가중치를 둬서 예측하도록 학습할 수 있습니다.</strong> </p>
<p>센서 데이터의 이동 평균을 사용하고 BQML , AUTO_CLASS_WEIGHTS의 매개 변수를 사용하여 가중치의 균형을 맞추기 때문에 정확합니다.</p>
<p><a href="https://cloud.google.com/dataprep/docs">Dataprep by Trifacta documentation</a></p>
<p><a href="https://cloud.google.com/bigquery-ml/docs">BigQueryML documentation</a> </p>
<h3 id="오답-5">오답</h3>
<p>A,B → DataPrep이 적절하지 않습니다.</p>
<p>C → 모델 학습이 불균형 데이터 세트에 대한 클래스 레이블의 균형을 맞추지 않기 때문에 C는 올바르지 않습니다.</p>
<h2 id="7-you-are-an-ml-engineer-at-a-media-company-you-need-to-build-an-ml-model-to-analyze-video-content-frame-by-frame-identify-objects-and-alert-users-if-there-is-inappropriate-content-which-google-cloud-products-should-you-use-to-build-this-project">7. You are an ML engineer at a media company. You need to build an ML model to analyze video content frame-by-frame, identify objects, and alert users if there is inappropriate content. Which Google Cloud products should you use to build this project?</h2>
<p><img src="https://images.velog.io/images/minjung-s/post/4d0d6390-c6d1-445b-9ac2-472a21aab9ee/image.png" alt=""></p>
<ul>
<li><input disabled="" type="checkbox"> A. Pub/Sub, Cloud Function, Cloud Vision API</li>
<li><input disabled="" type="checkbox"> B. Pub/Sub, Cloud IoT, Dataflow, Cloud Vision API, Cloud Logging</li>
<li><input disabled="" type="checkbox"> C. Pub/Sub, Cloud Function, Video Intelligence API, Cloud Logging</li>
<li><input disabled="" type="checkbox"> D. Pub/Sub, Cloud Function, AutoML Video Intelligence, Cloud Logging</li>
</ul>
<h3 id="정답-6">정답</h3>
<p><strong>C. Pub / Sub, Cloud Function, Video Intelligence API, Cloud Logging</strong></p>
<p>Video Intelligence API는 부적절한 구성 요소를 찾을 수 있고 기타 구성 요소는 실시간 처리 및 알림 요구 사항을 충족합니다.</p>
<h3 id="오답-6">오답</h3>
<p>A → 경고 및 알림 기능이 없습니다.</p>
<p>B → 동영상에 적절하지 않습니다.</p>
<p>D → AutoML Video Intelligence는 맞춤 설정의 경우에만 사용해야합니다.</p>
<h2 id="8-you-work-for-a-large-retailer-you-want-to-use-ml-to-forecast-future-sales-leveraging-10-years-of-historical-sales-data-the-historical-data-is-stored-in-cloud-storage-in-avro-format-you-want-to-rapidly-experiment-with-all-the-available-data-how-should-you-build-and-train-your-model-for-the-sales-forecast">8. You work for a large retailer. You want to use ML to forecast future sales leveraging 10 years of historical sales data. The historical data is stored in Cloud Storage in Avro format. You want to rapidly experiment with all the available data. How should you build and train your model for the sales forecast?</h2>
<p><img src="https://images.velog.io/images/minjung-s/post/7d1efa67-5dbb-4c82-a45b-d10705ee3665/image.png" alt=""></p>
<ul>
<li><input disabled="" type="checkbox"> A. Load data into BigQuery and use the ARIMA model type on BigQuery ML.</li>
<li><input disabled="" type="checkbox"> B. Convert the data into CSV format and create a regression model on AutoML Tables.</li>
<li><input disabled="" type="checkbox"> C. Convert the data into TFRecords and create an RNN model on TensorFlow on AI Platform Notebooks.</li>
<li><input disabled="" type="checkbox"> D. Convert and refactor the data into CSV format and use the built-in XGBoost algorithm on AI Platform Training.</li>
</ul>
<h3 id="정답-7">정답</h3>
<p>** A. BigQuery에 데이터를 로드하고 BigQueryML에서 ARIMA모델 유형을 사용합니다.** </p>
<p>BigQuery ML은 빠르고 신속한 실험을 위해 설계되었으며 통합 쿼리를 사용하여 Cloud Storage에서 직접 데이터를 읽을 수 있기 때문에 A가 정확합니다. ARIMA는 주식예측처럼 시계열 데이터를 예측할 때 사용되는 모델입니다.</p>
<h3 id="오답-7">오답</h3>
<p>B → AutoML Tables은 빠른 반복 및 빠른 실험에 적합하지 않습니다. 데이터 처리나 하이퍼파라미터튜닝을 하지 않더라도 모델을 만드는 데에 최소 1시간이 소요됩니다.</p>
<p>C → custom TF 모델을 짜려면 데이터 처리와 하이퍼파라미터 튜닝이 필요하기 때문에 적절하지 않습니다.</p>
<p>D → AI Platform을 사용하려면  CSV 구조로 데이터를 사전 처리해야하는데,  시간이 오래 걸릴 수 있으므로 빠른 반복에 적합하지 않습니다.</p>
<h2 id="9-you-need-to-build-an-object-detection-model-for-a-small-startup-company-to-identify-if-and-where-the-companys-logo-appears-in-an-image-you-were-given-a-large-repository-of-images-some-with-logos-and-some-without-these-images-are-not-yet-labelled-you-need-to-label-these-pictures-and-then-train-and-deploy-the-model-what-should-you-do">9. You need to build an object detection model for a small startup company to identify if and where the company’s logo appears in an image. You were given a large repository of images, some with logos and some without. These images are not yet labelled. You need to label these pictures, and then train and deploy the model. What should you do?</h2>
<p><img src="https://images.velog.io/images/minjung-s/post/6aca44f8-cdb5-4ee5-a252-6ad51465ca40/image.png" alt=""></p>
<ul>
<li><input disabled="" type="checkbox"> A. Use Google Cloud’s Data Labelling Service to label your data. Use AutoML Object Detection to train and deploy the model.</li>
<li><input disabled="" type="checkbox"> B. Use Vision API to detect and identify logos in pictures and use it as a label. Use AI Platform to build and train a convolutional neural network.</li>
<li><input disabled="" type="checkbox"> C. Create two folders: one where the logo appears and one where it doesn’t. Manually place images in each folder. Use AI Platform to build and train a convolutional neural network.</li>
<li><input disabled="" type="checkbox"> D. Create two folders: one where the logo appears and one where it doesn’t. Manually place images in each folder. Use AI Platform to build and train a real time object detection model.</li>
</ul>
<h3 id="정답-8">정답</h3>
<p>** A. Google Cloud의 데이터 라벨링 서비스를 사용하여 데이터에 라벨을 지정합니다. AutoML Object Detection을 사용하여 모델을 학습시키고 배포합니다.**</p>
<p><a href="https://cloud.google.com/ai-platform/data-labeling/docs">AI Platform Data Labeling Service documentation</a></p>
<p><a href="https://cloud.google.com/vision/automl/object-detection/docs">Could AutoML Vision Object Detection documentation</a></p>
<h3 id="오답-8">오답</h3>
<p>B → Vision API는 소규모 스타트업 회사 로고에 작동되지 않을 수 있습니다.</p>
<p>C→ 수동으로 라벨링하는 작업은 시간이 오래걸립니다.</p>
<p>D→ object detection으로 라벨링하는 것은 정확하지 않습니다. 또한 real time object detection은 이미지보다 비디오에서 객체를 감지하도록 설계되었습니다.</p>
<h2 id="10-you-work-for-a-large-financial-institution-that-is-planning-to-use-dialogflow-to-create-a-chatbot-for-the-companys-mobile-app-you-have-reviewed-old-chat-logs-and-tagged-each-conversation-for-intent-based-on-each-customers-stated-intention-for-contacting-customer-service-about-70-of-customer-inquiries-are-simple-requests-that-are-solved-within-10-intents-the-remaining-30-of-inquiries-require-much-longer-and-more-complicated-requests-which-intents-should-you-automate-first">10. You work for a large financial institution that is planning to use Dialogflow to create a chatbot for the company’s mobile app. You have reviewed old chat logs and tagged each conversation for intent based on each customer’s stated intention for contacting customer service. About 70% of customer inquiries are simple requests that are solved within 10 intents. The remaining 30% of inquiries require much longer and more complicated requests. Which intents should you automate first?</h2>
<p><img src="https://images.velog.io/images/minjung-s/post/f9217ab6-eb36-450c-ae08-2071fccdcb40/image.png" alt=""></p>
<ul>
<li><input disabled="" type="checkbox"> A. Automate a blend of the shortest and longest intents to be representative of all intents.</li>
<li><input disabled="" type="checkbox"> B. Automate the more complicated requests first because those require more of the agents’ time.</li>
<li><input disabled="" type="checkbox"> C. Automate the 10 intents that cover 70% of the requests so that live agents can handle the more complicated requests.</li>
<li><input disabled="" type="checkbox"> D. Automate intents in places where common words such as “payment” only appear once to avoid confusing the software.</li>
</ul>
<p><strong>정답 : C. 라이브 에이전트가 더 복잡한 요청을 처리할 수 있도록 요청의 70%를 처리하는 10개의 인텐트를 자동화합니다.</strong></p>
<p><em>인텐트 : 어플리케이션 구성요소 간에 작업 수행을 위한 정보를 전달하는 역할</em></p>
<p>Diagoflow : Google의 챗봇 플랫폼</p>
<p><a href="https://cloud.google.com/dialogflow/docs/">Diagoflow documentation</a></p>
<p><a href="https://medium.com/@jwlee98/gcp-dialogflow-%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EA%B0%84%EB%8B%A8-%EC%B1%97%EB%B4%87-%EB%A7%8C%EB%93%A4%EA%B8%B0-514ea25e4961">[GCP]Dialogflow 를 이용한 간단 챗봇 만들기</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자료구조]스택(Stack), 큐(Queue) 알아보기]]></title>
            <link>https://velog.io/@minjung-s/stack-queue</link>
            <guid>https://velog.io/@minjung-s/stack-queue</guid>
            <pubDate>Thu, 19 Nov 2020 02:23:24 GMT</pubDate>
            <description><![CDATA[<h1 id="스택stack">스택(Stack)</h1>
<p>스택과 큐는 프로그래밍이라는 개념이 탄생할 때부터 사용된 가장 고전적인 자료구조 중 하나입니다. 그중 스택은 거의 모든 애플리케이션을 만들 때 사용되는 자료구조입니다.</p>
<ul>
<li>스택(Stack) : 후입선출 = <strong>LIFO</strong> = Last-In-First-Out</li>
</ul>
<p>스택은 가장 나중에 들어간 것이 가장 먼저 빠져나옵니다.<br>아래 그림으로 보시면 빠르게 이해되실것입니다.
<img src="https://images.velog.io/images/minjung-s/post/d0be15eb-0acf-4ffb-8e6d-ad76a5aae050/image.png" alt="">
1-&gt;2-&gt;3 순으로 데이터가 삽입되었다면, LIFO는 3-&gt;2-&gt;1 순으로 빠져나가게 됩니다.</p>
<p>스택은 같은 구조와 크기의 자료를 정해진 방향으로만 쌓을 수 있고, tot으로 정한 곳을 통해서만 접근할 수 있습니다.
top은 가장 위에 있는 자료 즉, 가장 최근에 들어온 자료를 가르키고 있으며 새로 삽입되는 자료는 top이 가리키는 자료의 위에 쌓이게 됩니다.
스택에서 삭제는 top을 통해서만 가능합니다.
스택에서 top을 통해 <strong>삽입/추가 하는 연산을 push</strong>, top을 통해 <strong>삭제/제거 하는 연산을 pop</strong>이라고 합니다.</p>
<h1 id="큐queue">큐(Queue)</h1>
<ul>
<li>큐(Queue) : 선입선출 = <strong>FIFO</strong> = Firs-In-First-Out
큐는 가장 먼저 들어간 것이 가장 먼저 빠져나옵니다.
1-&gt;2-&gt;3 순으로 데이터가 삽입되었다면, FIFO는 1-&gt;2-&gt;3 순으로 빠져나가게 됩니다.
<img src="https://images.velog.io/images/minjung-s/post/33d7ed44-1a9b-4659-9413-70b7e1dcadae/image.png" alt="">
정해진 한 곳(top)애서 삽입,삭제가 이루어지는 스택과 달리
큐는 한쪽 끝에서 삽입작업이, 다른 쪽 끝에서 삭제 작업이 수행됩니다.
삭제 연산만 하는 곳을 <strong>front</strong>, 삽입 연산만 하는 곳을 <strong>rear</strong>라고 합니다.</li>
<li><em>rear*</em>에서 이루어지는 <strong>삽입 연산을 enQueue</strong>, <strong>front</strong>에서 이루어지는 <strong>삭제 연산을 deQueue</strong>라고 합니다.</li>
</ul>
<h1 id="리스트list에서-스택과-큐">리스트(list)에서 스택과 큐</h1>
<p>파이썬은 스택 자료형을 별도로 제공하지 않지만, <strong>리스트</strong>가 스택의 모든 연산을 지원합니다.
리스트는 큐의 연산도 지원하지만, 효율적으로 연산을 수행하기 위해서는 <strong>데크</strong>라는 별도의 자료형을 사용해야 좋은 성능을 낼 수 있습니다. 굳이 성능을 고려하지 않는다면 <strong>리스트</strong>로 스택과 큐의 모든 연산을 할 수 있습니다.</p>
<table>
<thead>
<tr>
<th align="center">연산</th>
<th align="center">시간 복잡도</th>
<th align="center">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="center">a.append(data)</td>
<td align="center">O(1)</td>
<td align="center"><strong>스택.큐의 &quot;추가&quot;</strong> 리스트의 <strong>*마지막에 요소를 추가</strong>한다.</td>
</tr>
<tr>
<td align="center">a.pop()</td>
<td align="center">O(1)</td>
<td align="center"><strong>스택의 &quot;추출&quot;</strong> 리스트의 <strong>마지막 요소를 추출</strong>한다.</td>
</tr>
<tr>
<td align="center">a.pop(0)</td>
<td align="center">O(n)</td>
<td align="center"><strong>큐의 &quot;추출&quot;</strong> 리스트의 <strong>첫번째 요소를 추출</strong>한다. 이 경우 전체 복사가 필요하므로 O(n)의 시간 복잡도가 필요하다. 따라서 큐의 연선은 데크(deque)를 권장한다.</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘/Python] leetcode 316. Remove Duplicate Letter (중복 문자 제거)]]></title>
            <link>https://velog.io/@minjung-s/remove-duplicate-letter</link>
            <guid>https://velog.io/@minjung-s/remove-duplicate-letter</guid>
            <pubDate>Thu, 19 Nov 2020 01:32:06 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<blockquote>
<p><a href="https://leetcode.com/problems/remove-duplicate-letters/">leetcode 316. Remove Duplicate Letter</a>
Given a string s, remove duplicate letters so that every letter appears once and only once. You must make sure your result is the smallest in lexicographical order among all possible results.</p>
</blockquote>
<p>중복된 문자를 제외하고 사전식 순서(Lexicogaphical Order)로 나열하는 문제입니다.</p>
<pre><code class="language-python">#예시
Input: s = &quot;cbacdcbc&quot;
Output: &quot;acdb&quot;</code></pre>
<h1 id="풀이">풀이</h1>
<pre><code class="language-python">&quot;&quot;&quot;
Runtime: 24 ms, faster than 98.89% of Python3 online submissions for Remove Duplicate Letters.
Memory Usage: 14.2 MB, less than 33.32% of Python3 online submissions for Remove Duplicate Letters.
&quot;&quot;&quot;
import collections

class Solution:
    def removeDuplicateLetters(self, s: str) -&gt; str:
        counter, seen, stack = collections.Counter(s), set(), []

        for char in s :
            counter[char] -= 1
            if char in seen :
                continue
            while stack and char &lt; stack[-1] and counter[stack[-1]] &gt; 0:
                seen.remove(stack.pop())
            stack.append(char)
            seen.add(char)

        return &#39;&#39;.join(stack)
</code></pre>
<p>s = &quot;cbacdcbc&quot; 라면,
counter는 Counter({&#39;c&#39;: 4, &#39;b&#39;: 2, &#39;a&#39;: 1, &#39;d&#39;: 1})이고,
seen은 비어있는 set(), stack은 비어있는 리스트 []입니다.</p>
<p>반복문을 통해 s의 맨 처음 글자부터 보게되고, 해당 문자의 counter[char]에 해당하는 빈도수를 1 감소시킵니다.</p>
<pre><code class="language-python"> while stack and char &lt; stack[-1] and counter[stack[-1]] &gt; 0:
        seen.remove(stack.pop())</code></pre>
<p>현재 문자 char가 stack에 쌓여있는 문자(이전문자 stack[-1])보다 앞선 문자이고, stack에 쌓여있는 문자가 뒤에 남아있다면(counter[stack[-1]]&gt;0)
쌓아둔 걸 없앱니다.</p>
<pre><code class="language-python">if char in seen :
    continue</code></pre>
<p>위와같이 조건문으로 char이 앞에서 이미 stack에 쌓여있는지 확인하여, 이미 처리된 문자를 스킵합니다.</p>
<p><img src="https://images.velog.io/images/minjung-s/post/36d59f4e-e4de-4f0b-89c6-de48640f2f27/image.png" alt=""></p>
<p>최종적으로 사전식 순서에 맞게 스택한 리스트 stack을 문자열로 반환합니다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘/Python]leetcode - 622.Design Circular Queue (원형 큐 디자인)]]></title>
            <link>https://velog.io/@minjung-s/circular-queue</link>
            <guid>https://velog.io/@minjung-s/circular-queue</guid>
            <pubDate>Tue, 17 Nov 2020 05:21:05 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<blockquote>
<p><a href="https://leetcode.com/problems/design-circular-queue/">원형 큐를 디자인 하라 (상세link)</a></p>
</blockquote>
<h1 id="풀이">풀이</h1>
<blockquote>
<p>큐 Queue -&gt; FIFO구조 </p>
</blockquote>
<ul>
<li>enQueue : 삽입 (존재하는 요소들의 맨 뒤에 삽입)</li>
<li>deQueue : 제거,추출 (FIFO이므로 맨 처음 추가된 요소부터 first-out)</li>
</ul>
<p>원형 큐(Circular Queue = 링버퍼 Ring Buffer)는 FIFO구조를 지니고, 마지막 위치가 시작위치에 연결되어있습니다. </p>
<p><img src="https://images.velog.io/images/minjung-s/post/5aef0354-c744-4067-ad00-0fa4bfb982c7/image.png" alt=""></p>
<p>기존의 큐는 공간이 꽉 차게 되면 더이상 요소를 추가할 수 가 없었습니다. deQueue로 앞쪽 요소가 빠져나가 공간이 생겨도 그쪽으로는 추가할 수가 없었습니다. 
그래서 앞쪽에 공간이 남아있다면 아래 그림처럼 동그랗게 연결해 앞쪽으로 추가할 수 있도록 재활용 가능한 구조가 바로 원형 큐입니다.
<img src="https://images.velog.io/images/minjung-s/post/fa4f7290-9302-49e0-938e-3000494ab317/image.png" alt="">
동작하는 원리는 투 포인터와 비슷합니다. enQueue하여 요소를 삭제할 자리, deQueue하여 요소를 추가할 자리를 따로 저장하면 됩니다. enQueue()를 하게 되면 rear 포인터가 앞으로 이동하고, deQueue()를 하게 되면 front포인터가 앞으로 이동합니다. 이렇게 enQueue와 deQueue를 반복하게 되면 서로 동그랗게 연결되어 있기 때문에 투 포인터가 빙글빙글 돌면서 이동하는 구조가 됩니다. 
만약 rear 포인터와 front 포인터가 같은 위치를 가르키게 된다면 여유공간이 없는 상황으로 공간 부족 에러를 발생시킵니다.</p>
<p>이제 파이썬으로 구현한 코드로 자세한 설명을 해보겠습니다.
아래 코드에서 <strong><span style="color:#33bbff">p1이 rear포인터</span>를, <span style="color:#ff4d4d">p2가 front 포인터</span>를 의미합니다.</strong></p>
<h3 id="원형-큐의-enqueue">원형 큐의 enQueue</h3>
<pre><code class="language-python">def enQueue(self, value: int) -&gt; bool:
        &quot;&quot;&quot;
        Insert an element into the circular queue. Return true if the operation is successful.
        &quot;&quot;&quot;
        if self.q[self.p2] is None:
            self.q[self.p2] = value #rear이 가르키는 자리에 value삽입
            self.p2 = (self.p2 +1) % self.maxlen # 다음 자리로 p2포인터 이동. 길이가 넘어가면 나머지 연산자를 이용하여 한바퀴 돌아서 자리찾기
            return True
        else
            return False</code></pre>
<p>rear 포인터 p2 위치에 값을 넣고, 포인터를 한 칸 앞으로 이동합니다. 단 전체 길이만큼 나머지 연산을 하여 포인터의 위치가 전체 길이를 벗어나지 않게 합니다.
만약 p2가 가르키는 값이 None이 아니라면 다른 요소가 있는 공간이 꽉 찬 상태이거나 비정상적인 경우이므로 False를 리턴합니다.</p>
<h3 id="원형-큐의-dequeue">원형 큐의 deQueue</h3>
<pre><code class="language-python">def deQueue(self) -&gt; bool:
        &quot;&quot;&quot;
        Delete an element from the circular queue. Return true if the operation is successful.
        &quot;&quot;&quot;
        if self.q[self.p1] is None:
            return False #이미 내보낼것이 없는 상태 -&gt;False
        else:
            self.q[self.p1] = None #삭제
            self.p1 = (self.p1+1) % self.maxlen
            return True</code></pre>
<p>front 포인터 p1의 위치에 None을 넣어 삭제하고, 포인터를 한 칸 앞으로 이동한다.
다음으로 나머지 연산으로 최대 길이를 넘지 않도록 한다.</p>
<h3 id="전체-코드">전체 코드</h3>
<p>원형 큐 class의 함수들입니다.</p>
<ul>
<li>enQueue : rear 포인터가 지정한 위치에 요소 삽입</li>
<li>deQueue : front 포인터가 지정한 위치에 요소 삭제</li>
<li>Front : 큐의 맨 처음 요소를 반환 </li>
<li>Rear : 큐의 맨 마지막 요소를 반환 (큐에는 없는 기능이지만, 투포인터 이기 때문에 쉽게 구현 가능)</li>
<li>isEmpty : 비어있는 상황이면 True를 반환</li>
<li>isFull :  여유공간이 없는 상황이면 True를 반환</li>
</ul>
<pre><code class="language-python"># https://leetcode.com/problems/design-circular-queue/submissions/
&quot;&quot;&quot;
Runtime: 60 ms, faster than 96.87% of Python3 online submissions for Design Circular Queue.
Memory Usage: 14.5 MB, less than 54.38% of Python3 online submissions for Design Circular Queue.
&quot;&quot;&quot;
class MyCircularQueue:

    def __init__(self, k: int):
        &quot;&quot;&quot;
        Initialize your data structure here. Set the size of the queue to be k.
        &quot;&quot;&quot;
        self.q = [None] * k
        self.maxlen = k
        self.p1 = 0
        self.p2 = 0


    def enQueue(self, value: int) -&gt; bool:
        &quot;&quot;&quot;
        Insert an element into the circular queue. Return true if the operation is successful.
        &quot;&quot;&quot;
        if self.q[self.p2] is None:
            self.q[self.p2] = value #rear이 가르키는 자리에 value삽입
            self.p2 = (self.p2 +1) % self.maxlen # 다음 자리로 p2포인터 이동. 길이가 넘어가면 나머지 연산자를 이용하여 한바퀴 돌아서 자리찾기
            return True
        else
            return False


    def deQueue(self) -&gt; bool:
        &quot;&quot;&quot;
        Delete an element from the circular queue. Return true if the operation is successful.
        &quot;&quot;&quot;
        if self.q[self.p1] is None:
            return False #이미 내보낼것이 없는 상태 -&gt;False
        else:
            self.q[self.p1] = None #삭제
            self.p1 = (self.p1+1) % self.maxlen
            return True


    def Front(self) -&gt; int:
        &quot;&quot;&quot;
        Get the front item from the queue.
        &quot;&quot;&quot;
        # p1이 가르키는 맨앞의 요소를 반환
        return -1 if self.q[self.p1] is None else self.q[self.p1]


    def Rear(self) -&gt; int:
        &quot;&quot;&quot;
        Get the last item from the queue.
        &quot;&quot;&quot;
        # 맨 뒤의 요소를 반환 (p2는 이미 뒤에 삽입될 자리를 가르키고 있기 때문에 p2-1이 맨 뒤의 요소를 가르키고 있습니다.)
        return -1 if self.q[self.p2 -1] is None else self.q[self.p2 -1] 


    def isEmpty(self) -&gt; bool:
        &quot;&quot;&quot;
        Checks whether the circular queue is empty or not.
        &quot;&quot;&quot;
        # p1,p2가 가르키는 자리가 같고, 그 안의 요소가 존재하지 않는다면 큐는 비어있습니다.
        return self.p1 == self.p2 and self.q[self.p1] is None


    def isFull(self) -&gt; bool:
        &quot;&quot;&quot;
        Checks whether the circular queue is full or not.
        &quot;&quot;&quot;
        # p1,p2가 가르키는 자리가 같고, 그 안의 요소가 존재하면 공간이 다 찬것입니다.
        return self.p1 == self.p2 and self.q[self.p1] is not None



# Your MyCircularQueue object will be instantiated and called as such:
obj = MyCircularQueue(k)
param_1 = obj.enQueue(value)
param_2 = obj.deQueue()
param_3 = obj.Front()
param_4 = obj.Rear()
param_5 = obj.isEmpty()
param_6 = obj.isFull()</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘/Python]leetcode - 20.Valid Parentheses (유효한 괄호)]]></title>
            <link>https://velog.io/@minjung-s/valid-parentheses</link>
            <guid>https://velog.io/@minjung-s/valid-parentheses</guid>
            <pubDate>Tue, 17 Nov 2020 03:07:57 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<blockquote>
<p><a href="https://leetcode.com/problems/valid-parentheses/">leetcode 20. Valid Parentheses</a>
Given a string s containing just the characters 
&#39;(&#39;, &#39;)&#39;, &#39;{&#39;, &#39;}&#39;, &#39;[&#39; and &#39;]&#39;, determine if the input string is valid.
An input string is valid if:</p>
</blockquote>
<ul>
<li>Open brackets must be closed by the same type of brackets.</li>
<li>Open brackets must be closed in the correct order.</li>
</ul>
<p>괄호로 된 입력값이 올바른지 판별하는 문제입니다.
열린 괄호는 동일한 유형의 괄호로 닫아야하고, 올바른 순서로 닫아야합니다.</p>
<h1 id="풀이">풀이</h1>
<pre><code class="language-python">class Solution:
    def isValid(self, s: str) -&gt; bool:
        stack = []
        table ={
            &#39;)&#39;: &#39;(&#39;,
            &#39;}&#39;: &#39;{&#39;,
            &#39;]&#39;: &#39;[&#39;
        }

        for char in s :
            if char not in table:
                stack.append(char)
            elif not stack or table[char] != stack.pop():
                return False
        return len(stack) == 0</code></pre>
<p>입력받은 문자열을 반복문으로 돌며 여는 괄호를 만날 때는 스택에 푸시push한다. 닫는 괄호를 만날 때 스택에서 팝pop하여 괄호 쌍이 맞는지 확인하면, 괄호의 순서와 열린 괄호와 닫힌 괄호의 유형이 같은지 확인할 수 있다.
예를 들어</p>
<pre><code class="language-python">input: s = &quot;{[]}&quot;</code></pre>
<p>입력 s가 다음과 같을 때, &#39;{&#39; -&gt; &#39;[&#39; -&gt; &#39;]&#39; -&gt; &#39;}&#39;순서로 반복문을 돕니다.</p>
<pre><code class="language-python">첫번째, 두번째 반복에서 {와 [는 if char not in table:의 조건에 걸려 stack에 append됩니다. 
stakc = [&#39;{&#39;, &#39;[&#39;]

세번째 반복에서 char = &#39;]&#39;이고, table[&#39;]&#39;] = &#39;[&#39;이다. stack.pop()을 하면 stack의 가장 마지막 요소인 &#39;[&#39;가 반환되면 삭제된다.(stack = [&#39;{&#39;]) 따라서 table[char] = stack.pop().

네번째 반복에서 char = &#39;}&#39;이고, table[&#39;}&#39;] = &#39;{&#39; == stack.pop() = &#39;{&#39;이므로 elif에 걸리지 않고 stack은 pop되어 stack =[]이 된다.

마지막 return 에서 len(stack) == 0이 True를 반환하게 된다.</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘/Python] 연결리스트,리스트 변환 ]]></title>
            <link>https://velog.io/@minjung-s/node2list</link>
            <guid>https://velog.io/@minjung-s/node2list</guid>
            <pubDate>Tue, 17 Nov 2020 02:19:05 GMT</pubDate>
            <description><![CDATA[<p>연결리스트는 시작 또는 끝 지점에 아이템을 추가하거나 삭제,추출하는 작업에는 O(1)에 가능하다. <strong>삽입, 삭제</strong>를 할 때는 연결리스트를 이용하는 것이 적절하고 <strong>탐색</strong>을 할 때는 리스트를 사용하는 것이 적절하다.
또한 리스트는 연산을 쉽게 할 수 있기 때문에, 시간복잡도 문제가 없다면 연결리스트 형태로 입력을 준 경우에는 리스트로 변환해서 쉽게 작업을 수행할 수 있다.</p>
<p>연결리스트를 리스트로 <strong>(node2list)</strong> 변환하고, 리스트를 연결리스트로 <strong>(ㅣlist2node)</strong> 변환하는 코드를 작성해보았다.</p>
<pre><code class="language-python">class Solution:
    def node2list(self, node1: ListNode) -&gt; List: #linked list -&gt; list
        list1 = []
        while node1 != None :
            list1.append(node1.val)
            node1 = node1.next
        return list1

    def list2node(self, list1: List) -&gt; ListNode:
        result_node = ListNode()

        for i,num in enumerate(list1):
            if i == 0 :
                result_node.val = num
            else :
                node = result_node
                while node.next != None:
                    node = node.next
                node.next = ListNode(num)
        return result_node


    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -&gt; ListNode:
        #예제 : 2 두 수의 덧셈 (2 Add Two Numbers) [leetcode](https://leetcode.com/problems/add-two-numbers/)
        node1 = l1
        node2 = l2 

        #linked list -&gt; list
        list1 = self.node2list(node1)
        list2 = self.node2list(node2)


        # 배열 뒤집기
        list1.reverse()
        list2.reverse()

        #배열 -&gt; join -&gt; int
        num1 = int(&#39;&#39;.join(str(a) for a in list1))
        num2 = int(&#39;&#39;.join(str(a) for a in list2))
        result = list(str(num1+num2))
        result.reverse()

        return self.list2node(result) #list -&gt; linked list</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[aboutme]]></title>
            <link>https://velog.io/@minjung-s/aboutme</link>
            <guid>https://velog.io/@minjung-s/aboutme</guid>
            <pubDate>Thu, 17 Sep 2020 13:48:16 GMT</pubDate>
            <description><![CDATA[<h2 id="minjung-shin">Minjung Shin</h2>
<h3 id="🎓-education">🎓 Education</h3>
<ul>
<li>MS in Artificial Intelligence, Yonsei University <code>2021.03~</code></li>
<li>Undergraduate Student in department of Electronics&amp;Communications, Kwangwoon University <code>2016.03 ~ 2021.02 (Expected)</code></li>
</ul>
<h3 id="🔭-internship">🔭 Internship</h3>
<ul>
<li>Research Intern at the Artifical Intelligence Reasearch Lab of ETRI <code>2019.01 ~ 2019.02</code></li>
</ul>
<h3 id="✨-publication">✨ Publication</h3>
<ul>
<li>Detectable Object-Size Range Estimation Based Multi-Task Cascaded Convolutional Neural Networks in the Vehicle Environment (2019-Fall IEEE VTC)</li>
</ul>
<h3 id="⚡-interests">⚡ Interests</h3>
<ul>
<li>Generative Model</li>
<li>Image&amp;Video Generation</li>
<li>Transformer in Vision</li>
<li>Computer Vision</li>
</ul>
<h3 id="📫-contact">📫 Contact</h3>
<ul>
<li><a href="mailto:&#x73;&#109;&#106;&#x31;&#x33;&#57;&#x30;&#x35;&#x32;&#x40;&#x79;&#111;&#110;&#x73;&#x65;&#x69;&#x2e;&#97;&#99;&#46;&#x6b;&#x72;">&#x73;&#109;&#106;&#x31;&#x33;&#57;&#x30;&#x35;&#x32;&#x40;&#x79;&#111;&#110;&#x73;&#x65;&#x69;&#x2e;&#97;&#99;&#46;&#x6b;&#x72;</a></li>
</ul>
<h4 id="you-can-check-my-portfolio-💬here💬">You can check my Portfolio <a href="https://www.notion.so/78fec89202a84503a00a3f15573d5ebb">💬here💬</a></h4>
]]></description>
        </item>
    </channel>
</rss>