<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>수리수리연수리 코드얍</title>
    <link>https://ydduri.tistory.com/</link>
    <description>코딩하는 연뚜리</description>
    <language>ko</language>
    <pubDate>Sun, 23 Aug 2026 05:13:23 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>ydduri</managingEditor>
    <image>
      <title>수리수리연수리 코드얍</title>
      <url>https://tistory1.daumcdn.net/tistory/5930058/attach/ecac1d09921d40ce918231a0d59df262</url>
      <link>https://ydduri.tistory.com</link>
    </image>
    <item>
      <title>[CS224W] 2-3. Traditional Feature-based Methods: Graph</title>
      <link>https://ydduri.tistory.com/43</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Graph-Level Features&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Goal: We want features that characterize the structure of an entire graph&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Background: Kernel Methods&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kernel methods란 graph-level prediction을 위한 전통적인 ML에서 보편적으로 쓰이는 방법론이다. 이 방법론의 아이디어는 이름처럼, feature vector 대신 'kernel'을 디자인하자는 것이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Kernel K(G, G') $\in$ $\mathbb{R}$은 두 그래프(G) 사이의 유사도를 측정한다.&lt;/li&gt;
&lt;li&gt;Kernel matrix K는 항상 positive semi-definite이며(이는 해당 matrix가 항상 양의 eigenvalue를 가짐을 의미), 대칭행렬 이어야 한다.&lt;/li&gt;
&lt;li&gt;feature representation(vector representation) $\phi(.)$가 존재한다. kernel은 이 vector representation의 dot product로 나타낼 수 있다.&lt;/li&gt;
&lt;li&gt;kernel을 SVM(support vector machine) 등에 붙여서 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로 Graphlet kernel, Weisfeiler-Lehman kernel을 비롯한 실제 kernel에 대해 구체적으로 살펴볼 예정이다. 방금 언급한 것들 외에도 Random-walk kernel, Shortest-path graph kernel 등 여러 방법론이 존재하지만 이 강의의 범위를 벗어나는 것이라 구체적으로 다루지는 않는다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Graph Kernel&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Goal: Design graph feature vector $\phi(G)$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Key idea: Bag-of-Words(BoW) for a graph&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) Naive extension&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때, BoW란 NLP에서 모든 단어가 몇 번 나타나는지 세는 방법을 말하는데, 이를 graph에 적용할 수 있는 가장 naive한 방법은, node를 단어라고 생각하고 BoW를 적용하는 것이다. 다만 이렇게 했을 때 문제점은, 그래프의 구조가 매우 다르더라도 같은 수의 node를 가지고 있다면 같은 feature vector를 얻을 수 있다는 점이다. 일례로, 아래 두 가지 그래프는 다른 구조를 가지고 있지만 node의 개수가 4로 같기 때문에 이와 같은 naive한 접근법에서는 서로 같은 결과가 나올 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;497&quot; data-origin-height=&quot;142&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dr8TQF/btssZfPJmIO/kYwqXiOs4uQXM9C5C66EX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dr8TQF/btssZfPJmIO/kYwqXiOs4uQXM9C5C66EX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dr8TQF/btssZfPJmIO/kYwqXiOs4uQXM9C5C66EX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdr8TQF%2FbtssZfPJmIO%2FkYwqXiOs4uQXM9C5C66EX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;312&quot; height=&quot;89&quot; data-origin-width=&quot;497&quot; data-origin-height=&quot;142&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) Node Degrees&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 naive extension에서의 문제점을 보완하고자 등장한 것이 바로 node degrees를 word로 취급하자는 아이디어이다. 아래 그림에서, 위쪽 그래프는 degree 1인 node가 1개, 2인 node가 3개, 3인 node가 0개인 반면, 아래쪽 그래프는 degree 1인 node가 0개, 2, 3인 node가 각각 2개로, node의 개수는 같지만 이처럼 node degrees를 기반으로 나타내었더니 서로 다른 그래프라는 것이 잘 구분됨을 알 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;851&quot; data-origin-height=&quot;256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vWbdv/btssT7ZibO8/vSyLJj0fxvshqYXQEOj4f0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vWbdv/btssT7ZibO8/vSyLJj0fxvshqYXQEOj4f0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vWbdv/btssT7ZibO8/vSyLJj0fxvshqYXQEOj4f0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvWbdv%2FbtssT7ZibO8%2FvSyLJj0fxvshqYXQEOj4f0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;472&quot; height=&quot;142&quot; data-origin-width=&quot;851&quot; data-origin-height=&quot;256&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로 살펴볼 Graphlet kernel과 Weisfeiler-Lehman kernel에도 이러한 Bag-of-something representation이 활용되는데, 이때 something에는 node degree보다 더욱 정교한 지표가 사용된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Graphlet Features&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Key idea: Count the number of &lt;b&gt;different graphlets&lt;/b&gt; in a graph&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Graphlet이 무엇인지에 대해서는 이미 &lt;a href=&quot;https://ydduri.tistory.com/41&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2-1. Traditional Feature-based Methods: Node&lt;/a&gt;에서 살펴본 바 있다. 그런데 이 강의에서 이야기하는 graphlet의 정의는 node-level features에서의 graphlet의 정의와 살짝 다르다. 그 차이점은 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Isolated node 또한 graphlet의 일부로 허용한다.&lt;/li&gt;
&lt;li&gt;Root Node가 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;393&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCWaGz/btssUaBBEWb/i6JrHcMSOTrClSPMNwFlX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCWaGz/btssUaBBEWb/i6JrHcMSOTrClSPMNwFlX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCWaGz/btssUaBBEWb/i6JrHcMSOTrClSPMNwFlX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCWaGz%2FbtssUaBBEWb%2Fi6JrHcMSOTrClSPMNwFlX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;496&quot; height=&quot;240&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;393&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;graph G가 주어지고, graphlet list $G_k$가 주어졌을 때, Graphlet count vector $f_G$는 graph에서 나타나는 각 graphlet의 instance의 수로 정해진다. 자세한 사항은 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;777&quot; data-origin-height=&quot;262&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dIEEV5/btssT5f5J4V/kLH4cVzXHVFB5OuVKJQrpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dIEEV5/btssT5f5J4V/kLH4cVzXHVFB5OuVKJQrpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dIEEV5/btssT5f5J4V/kLH4cVzXHVFB5OuVKJQrpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdIEEV5%2FbtssT5f5J4V%2FkLH4cVzXHVFB5OuVKJQrpK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;407&quot; height=&quot;137&quot; data-origin-width=&quot;777&quot; data-origin-height=&quot;262&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dCEzNR/btssT9iqKd1/kn3LvKqMkaBKMTsStWySK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dCEzNR/btssT9iqKd1/kn3LvKqMkaBKMTsStWySK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dCEzNR/btssT9iqKd1/kn3LvKqMkaBKMTsStWySK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdCEzNR%2FbtssT9iqKd1%2Fkn3LvKqMkaBKMTsStWySK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;418&quot; height=&quot;271&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;528&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. Graphlet Kernel&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) Graphlet Kernel&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2개의 그래프 G, G'이 주어지면, graphlet kernel은 다음과 같이 각각의 graph count vector의 내적으로 표현될 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;337&quot; data-origin-height=&quot;63&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qSEL9/btssYTTq5HQ/PIeyCNp9VAsNA2cy6KYjh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qSEL9/btssYTTq5HQ/PIeyCNp9VAsNA2cy6KYjh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qSEL9/btssYTTq5HQ/PIeyCNp9VAsNA2cy6KYjh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqSEL9%2FbtssYTTq5HQ%2FPIeyCNp9VAsNA2cy6KYjh1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;198&quot; height=&quot;37&quot; data-origin-width=&quot;337&quot; data-origin-height=&quot;63&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Problem: G와 G'의 size가 다르면, 값이 크게 왜곡(skew)될 수 있다.&lt;/li&gt;
&lt;li&gt;Solution: $f_G$ 대신 전체 sum으로 나눠서 normalize한 $h_G$를 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;617&quot; data-origin-height=&quot;120&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFdzYl/btssUOymrw3/2jUG1pdHUvBCH6zS2mlKQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFdzYl/btssUOymrw3/2jUG1pdHUvBCH6zS2mlKQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFdzYl/btssUOymrw3/2jUG1pdHUvBCH6zS2mlKQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFdzYl%2FbtssUOymrw3%2F2jUG1pdHUvBCH6zS2mlKQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;391&quot; height=&quot;76&quot; data-origin-width=&quot;617&quot; data-origin-height=&quot;120&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 graphlet kernel에는 한계점이 존재하는데, graphlet을 계산하는 것이 매우 비싸다는 점이다. k-size의 graphlet을 n개의 node를 가진 graph에 대해서 계산하려면, $n^k$만큼의 연산이 필요하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;This is unavoidable in the worst-case since &lt;b&gt;subgraph isomorphism test&lt;/b&gt;(judging whether a graph is a subgraph of another graph) is &lt;b&gt;NP-hard&lt;/b&gt;(다항 시간에 맞았는지 확인할 수 있는 문제를 NP 문제라 하는데, 그보다 어려운 문제다... 라고 간단하게 이해하고 넘어가면 될 것 같다. 이때 '어렵다'는 난이도의 개념은 다항 시간 변환을 통해 비교가 가능한데, 이를 통해 어떤 문제가 이미 잘 알려진 NP-hard 문제보다 어렵다는 등의 증명이 가능하다).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;If a graph's node degree is bounded by d&lt;/b&gt;, an $O(nd^{k-1})$ algorithm exists to count all the graphlets of size k.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에서 대두되는 문제는, 보다 효율적인 graph kernel을 디자인할 수는 없는 것인가? 인데, 이에 대한 대답으로 등장하는 것이 다음에서 살펴볼 Weisfeiler-Lehman Kernel이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) Weisfeiler-Lehman Kernel&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Goal: Design an efficient graph feature descriptor $\phi(G)$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Idea: neighborhood structure를 이용하여 반복적으로 node vocabulary를 풍부하게 만드는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 one-hop neighborhood인 node degree 방식을 일반화한 버전이라고 보면 된다. 해당 kernel은 'color refinement'라는 알고리즘에 의해 이루어질 수 있는데, 이것이 무엇인지는 아래에서 자세히 보도록 하자.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3) Color Refinement&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;graph G와 set of nodes V가 주어졌다고 해보자.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Initial color $c^{(0)}(v)$를 각각의 node v에 할당한다.&lt;/li&gt;
&lt;li&gt;아래와 같은 연산을 통해 반복적으로 node의 color를 정제해 나간다(이때 HASH는 서로 다른 input이 들어왔을 때 서로 다른 색으로 매핑하는 연산이다).&lt;/li&gt;
&lt;li&gt;K step의 color refinement가 끝나고 나면, $c^{(k)}(v)$는 K-hop neighborhood 구조의 summary가 된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;706&quot; data-origin-height=&quot;72&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uUIxL/btss3L1PFC0/yVsQnDELK8rJyAkdgjdtbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uUIxL/btss3L1PFC0/yVsQnDELK8rJyAkdgjdtbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uUIxL/btss3L1PFC0/yVsQnDELK8rJyAkdgjdtbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuUIxL%2Fbtss3L1PFC0%2FyVsQnDELK8rJyAkdgjdtbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;490&quot; height=&quot;50&quot; data-origin-width=&quot;706&quot; data-origin-height=&quot;72&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구체적인 예시는 아래에서 확인할 수 있다. 비슷하지만 조금 다른 형태의 그래프 G, G'이 들어왔을 때 color refinement 연산을 적용하는 예이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1단계. Assign initial colors(동일한 initial color를 모든 nodes에 할당)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;687&quot; data-origin-height=&quot;167&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctuCdn/btssZdR2zsa/fnclwZDHKYebndfZJ8eagk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctuCdn/btssZdR2zsa/fnclwZDHKYebndfZJ8eagk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctuCdn/btssZdR2zsa/fnclwZDHKYebndfZJ8eagk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctuCdn%2FbtssZdR2zsa%2FfnclwZDHKYebndfZJ8eagk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;412&quot; height=&quot;100&quot; data-origin-width=&quot;687&quot; data-origin-height=&quot;167&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2단계. Aggregate neighboring colors(직접 이웃하고 있는 node의 개수만큼 aggreagting이 잘 된 것을 볼 수 있다)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;747&quot; data-origin-height=&quot;191&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMtO4k/btssVJXO5Ve/fndaetz7v4SPScJII5ngM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMtO4k/btssVJXO5Ve/fndaetz7v4SPScJII5ngM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMtO4k/btssVJXO5Ve/fndaetz7v4SPScJII5ngM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMtO4k%2FbtssVJXO5Ve%2Ffndaetz7v4SPScJII5ngM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;477&quot; height=&quot;122&quot; data-origin-width=&quot;747&quot; data-origin-height=&quot;191&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3단계. Hash aggregated colors(Hash table을 통해 새로운 color로 변환)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;776&quot; data-origin-height=&quot;173&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZgT65/btssZeci5hN/h3zBxUkcOBAKrLHLYc4rK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZgT65/btssZeci5hN/h3zBxUkcOBAKrLHLYc4rK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZgT65/btssZeci5hN/h3zBxUkcOBAKrLHLYc4rK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZgT65%2FbtssZeci5hN%2Fh3zBxUkcOBAKrLHLYc4rK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;498&quot; height=&quot;111&quot; data-origin-width=&quot;776&quot; data-origin-height=&quot;173&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4단계. 다시금 이웃하는 색상에 대해서 aggreagte&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;187&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0vQnS/btssTrDF2WA/BDAznXsSwG6D0pZSSd3c7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0vQnS/btssTrDF2WA/BDAznXsSwG6D0pZSSd3c7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0vQnS/btssTrDF2WA/BDAznXsSwG6D0pZSSd3c7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0vQnS%2FbtssTrDF2WA%2FBDAznXsSwG6D0pZSSd3c7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;471&quot; height=&quot;115&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;187&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5단계. 다시금 aggregate된 결과에 대하여 Hash 연산 적용&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;255&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAcUfZ/btssYQWHlie/5Dwsp2JZKg2x1ykG6NcQPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAcUfZ/btssYQWHlie/5Dwsp2JZKg2x1ykG6NcQPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAcUfZ/btssYQWHlie/5Dwsp2JZKg2x1ykG6NcQPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAcUfZ%2FbtssYQWHlie%2F5Dwsp2JZKg2x1ykG6NcQPK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;505&quot; height=&quot;158&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;255&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6단계. k번의 iteration을 거쳐 color refinement가 끝나면, WL kernel이 각 color가 등장한 횟수를 세서 summary(우리의 예시에서는 총 13개의 color가 등장하여, 첫 번째 그래프의 경우 1번 color는 6번, 2번 color는 2번... 이런 식으로 feature descriptor를 구성한다)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;816&quot; data-origin-height=&quot;372&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dOU4n4/btssUMN3uK4/2C80dxHGxheJycjBxWHJaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dOU4n4/btssUMN3uK4/2C80dxHGxheJycjBxWHJaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dOU4n4/btssUMN3uK4/2C80dxHGxheJycjBxWHJaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdOU4n4%2FbtssUMN3uK4%2F2C80dxHGxheJycjBxWHJaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;388&quot; height=&quot;177&quot; data-origin-width=&quot;816&quot; data-origin-height=&quot;372&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7단계. 이전 단계에서 구한 feature descriptor(color count vector) 사이의 내적으로 WL kernel의 결과값을 구한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;663&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbQE4x/btss9YMQLRX/ToZgQQoNY1bgk7sQE1IV4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbQE4x/btss9YMQLRX/ToZgQQoNY1bgk7sQE1IV4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbQE4x/btss9YMQLRX/ToZgQQoNY1bgk7sQE1IV4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbQE4x%2Fbtss9YMQLRX%2FToZgQQoNY1bgk7sQE1IV4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;329&quot; height=&quot;143&quot; data-origin-width=&quot;663&quot; data-origin-height=&quot;288&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WL kernel은 매우 popular할 뿐 아니라 매우 strong하며, computationally efficient하기까지 하다. color refinement의 각 step에서의 시간 복잡도는 &lt;b&gt;number of edges(size of the graph)에 linear&lt;/b&gt;하기 때문이다. 모든 node가 해야할 일은 이웃한 node들로부터 color를 수집하고, 간단한 hash function을 적용하기만 하면 되기에, 많은 시간 복잡도가 요구되지 않는다. 또한 color의 개수는 node의 전체 개수를 넘어가지 않기 때문에, 시간 복잡도가 지나치게 상승하는 것을 막을 수 있다.&lt;/p&gt;</description>
      <category>놀라운 Deep Learning/Machine Learning with Graphs</category>
      <category>cs224w</category>
      <category>GNN</category>
      <category>Graph Neural Networks</category>
      <author>ydduri</author>
      <guid isPermaLink="true">https://ydduri.tistory.com/43</guid>
      <comments>https://ydduri.tistory.com/43#entry43comment</comments>
      <pubDate>Mon, 4 Sep 2023 19:39:05 +0900</pubDate>
    </item>
    <item>
      <title>[CS224W] 2-2. Traditional Feature-based Methods: Link</title>
      <link>https://ydduri.tistory.com/42</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Link Prediction as a Task&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Link prediction task에는 크게 두 가지 종류가 있다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;랜덤하게 사라진 link 찾기(ex. protein-protein interaction network와 같은 static network에 적합)&lt;/li&gt;
&lt;li&gt;시간에 따라 생겨나는 link 찾기(ex. citation network, social network, collaboration network...)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제부터는 어떻게 주어진 pair of nodes에 대해 feature descriptor를 생성할 수 있는지를 알아보도록 하자. pair of nodes x, y에 대해서 몇 가지 score를 비교하는 것이 기본 아이디어가 된다(score의 예시로는 node x, y 간의 common neighbor의 개수 등이 있을 수 있다).&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;각 node 쌍 (x, y)에 대하여 score c(x, y)를 계산한다.&lt;/li&gt;
&lt;li&gt;c(x, y) 내림차순으로 node 쌍을 정렬한다.&lt;/li&gt;
&lt;li&gt;top N개의 pair들을 새로운 link로 예측한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Link-Level Features&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) Overview&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;link-level features를 잡아 내는 방법에는 크게 아래와 같은 종류가 있다. 앞으로 각각의 접근법에 대해서 자세히 살펴볼 예정이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Distance-based feature&lt;/li&gt;
&lt;li&gt;Local neighborhood overlap&lt;/li&gt;
&lt;li&gt;Global neighborhood overlap&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) Distance-Based Features&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 두 node 사이의 가장 짧은 path의 거리를 기반으로 characterize하는 방법이다. 다만 이 방법은 두 node간 최단 경로의 거리를 사용할 뿐, 이웃의 수나 강도에 대한 어떠한 정보도 capture하지 않는다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;213&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yyarb/btssSDqh7fR/nHW3hdwflkIruKTD2Va99k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yyarb/btssSDqh7fR/nHW3hdwflkIruKTD2Va99k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yyarb/btssSDqh7fR/nHW3hdwflkIruKTD2Va99k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fyyarb%2FbtssSDqh7fR%2FnHW3hdwflkIruKTD2Va99k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;491&quot; height=&quot;128&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;213&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3) Local Neighborhood Overlap&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 node간 connection의 강도를 capture하기 위해 도입된 방법이 바로 local neighborhood overlap이다. 얼마나 많은 이웃을 공통으로 가지고 있는지를 본다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Common neighbors&lt;/b&gt;: 단순히 두 node간 이웃의 개수(교집합)를 구한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Jaccard's coefficient&lt;/b&gt;: 교집합의 크기를 합집합으로 나눠 normalize한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Adamic-Adar index&lt;/b&gt;: 두 node가 공유하는 이웃을 u라고 할 때, u의 degree에 log를 취한 값으로 나눠서 구할 수 있으며, social network에서 잘 동작한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;395&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eakimn/btssTpd3vEn/TtRmFiGK8j4V4Z4KlMA2l1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eakimn/btssTpd3vEn/TtRmFiGK8j4V4Z4KlMA2l1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eakimn/btssTpd3vEn/TtRmFiGK8j4V4Z4KlMA2l1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Feakimn%2FbtssTpd3vEn%2FTtRmFiGK8j4V4Z4KlMA2l1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;571&quot; height=&quot;247&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;395&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;local neighborhood overlap의 단점은 직접적인 공통 이웃이 없으면 무조건 0이 나온다는 점이다. 아래의 예시를 보면, node A와 node E는 직접적인 공통 이웃이 없기 때문에 교집합을 구했을 때 0이 나올 수밖에 없다. 그러나 실제 세계에서 두 node A, E는 미래에 연결될 수도 있는 잠재력을 가지고 있다. 단순히 local neighborhood overlap을 사용하는 것만으로는이러한 미래의 잠재력까지 고려하기는 어렵다는 한계가 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8o9R7/btss3GFzXBl/QHoDOzJFXkj3XDB9NoMdR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8o9R7/btss3GFzXBl/QHoDOzJFXkj3XDB9NoMdR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8o9R7/btss3GFzXBl/QHoDOzJFXkj3XDB9NoMdR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8o9R7%2Fbtss3GFzXBl%2FQHoDOzJFXkj3XDB9NoMdR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;440&quot; height=&quot;142&quot; data-origin-width=&quot;682&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4) Global Neighborhood Overlap&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 언급한 local neighborhood overlap의 단점을 해결하기 위해 등장한 것이 바로 global neighborhood overlap이다. 이는 이름처럼, 직접적인 공통 이웃만을 고려하는 'local' 방식과는 달리, 'global'하게 entire graph를 고려하고자 하는 방식이다. 대표적으로 쓰이는 것이 Katz index이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Katz index&lt;/b&gt;: 주어진 node 쌍을 잇는 모든 길이의 경로의 개수를 센다. &lt;a href=&quot;https://ydduri.tistory.com/40&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;1-3. Choice of Graph Representation&lt;/a&gt;에서 배운 adjacency matrix를 이용하면 이를 쉽게 계산할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;adjacency matrix $A_{uv}$는 직접 이웃일 때 1, 아니면 0이다.&lt;/li&gt;
&lt;li&gt;$P_{uv}^{(K)}$는 K길이의 u, v를 잇는 경로이다.&lt;/li&gt;
&lt;li&gt;$P_^{(K)}$ = $A^k$이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$P_{uv}^{(2)}$를 계산하는 예시를 보자. 이는 두 단계로 나눠서 접근할 수 있다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Step 1: Compute number of walks of length 1 between each of u's neighbor and v&lt;/li&gt;
&lt;li&gt;Step 2: Sum up these number of walks across u's neighbors&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 수식적으로 접근한 결과는 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;75&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cT7U9x/btss8kPK7VC/FYGIxIoKEXlyK8oo3Pa4Ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cT7U9x/btss8kPK7VC/FYGIxIoKEXlyK8oo3Pa4Ck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cT7U9x/btss8kPK7VC/FYGIxIoKEXlyK8oo3Pa4Ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcT7U9x%2Fbtss8kPK7VC%2FFYGIxIoKEXlyK8oo3Pa4Ck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;475&quot; height=&quot;52&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;75&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;adjacency matrix를 이용해서 행렬 연산으로 시각화해보면 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clUvOJ/btssUK9SWqv/iy824PVGgKrvt5hCrr6WRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clUvOJ/btssUK9SWqv/iy824PVGgKrvt5hCrr6WRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clUvOJ/btssUK9SWqv/iy824PVGgKrvt5hCrr6WRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclUvOJ%2FbtssUK9SWqv%2Fiy824PVGgKrvt5hCrr6WRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;601&quot; height=&quot;176&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;260&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 adjacency matrix를 이용하면 계산이 쉬워진다고 했는데, 도대체 어디가 쉬워진 걸까? 바로 두 node 사이의 number of walks 계산을 adjacency matrix의 거듭제곱으로 나타낼 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$A_{uv}$ specifies #walks(number of walks) of length 1(direct neighborhood) between u and v&lt;/li&gt;
&lt;li&gt;$A_{uv}^{2}$ specifies #walks of length 2(neighbor of neighbor) between u and v&lt;/li&gt;
&lt;li&gt;$A_{uv}^{l}$ specifies #walks of length l&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 이용해서 Katz index 식을 정리해보면 아래와 같다. 이는 또한 geometric series of matrices 수식을 활용해 closed-form으로도 나타낼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;816&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d4V8Om/btss3D29Mzo/t5Jx3US9g8VoLORcfb8BKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d4V8Om/btss3D29Mzo/t5Jx3US9g8VoLORcfb8BKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d4V8Om/btss3D29Mzo/t5Jx3US9g8VoLORcfb8BKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd4V8Om%2Fbtss3D29Mzo%2Ft5Jx3US9g8VoLORcfb8BKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;517&quot; height=&quot;304&quot; data-origin-width=&quot;816&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 참고: Geometric series of matrices&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;327&quot; data-origin-height=&quot;136&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eJRaLt/btssTnADYlk/24UttBOMItmpz5VeX2HD3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eJRaLt/btssTnADYlk/24UttBOMItmpz5VeX2HD3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eJRaLt/btssTnADYlk/24UttBOMItmpz5VeX2HD3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeJRaLt%2FbtssTnADYlk%2F24UttBOMItmpz5VeX2HD3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;171&quot; height=&quot;136&quot; data-origin-width=&quot;327&quot; data-origin-height=&quot;136&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때, $S_n = I + T + ... + T^{n-1}$에서 $S_0 = I$이기 때문에, 위의 Katz index in closed form의 경우 i=0이 아닌 1부터 시작하고 있어서 I를 빼 준 것.&lt;/p&gt;</description>
      <category>놀라운 Deep Learning/Machine Learning with Graphs</category>
      <category>cs224w</category>
      <category>GNN</category>
      <category>Graph Neural Networks</category>
      <author>ydduri</author>
      <guid isPermaLink="true">https://ydduri.tistory.com/42</guid>
      <comments>https://ydduri.tistory.com/42#entry42comment</comments>
      <pubDate>Mon, 4 Sep 2023 12:23:33 +0900</pubDate>
    </item>
    <item>
      <title>[CS224W] 2-1. Traditional Feature-based Methods: Node</title>
      <link>https://ydduri.tistory.com/41</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Traditional ML Pipeline&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Traditional ML(Machine Learning) Pipeline이란 적절한 feature를 디자인하는 것에 대한 모든 것이라 할 수 있다. feature는 크게 &lt;b&gt;structural feature&lt;/b&gt;, &lt;b&gt;attribute feature&lt;/b&gt;로 나눌 수 있는데, 이 강의에서는 각각의 node과 자신과 연관 있는 attribute를 가지고 있다고 가정하고, &lt;b&gt;structural feature&lt;/b&gt;에만 집중한다. structural feature는 더 넓은 surrounding of the network에 대해 link structure를 표현할 수 있도록 해주고, 관심 있는 node 근처의 이웃 관계를 볼 수 있게 해주며, 전체 그래프의 구조를 파악할 수 있도록 해준다. 우리는 이러한 feature를 ML model에 feed함으로써 예측을 생성해낼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전통적인 ML Pipeline에는 두 가지 단계가 있다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;우리의 data points, nodes, links, entire graph를 &lt;b&gt;feature vector로 변환&lt;/b&gt;해 랜덤 포레스트, SVM, feed-forward neural network 등 classical ML &lt;b&gt;모델을 학습&lt;/b&gt;시킴&lt;/li&gt;
&lt;li&gt;위에서 학습시킨 모델을 새로운 node, link, graph에 적용하여 예측을 생성함&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;graph에 대한 effective features를 사용하는 것은 좋은 테스트 성능을 발휘하는 key라고 할 수 있다. Traditional ML pipeline에서는 위에서 살펴본 바와 같이 hand-designed feature를 사용했다. 이번 강의에서는, 이러한 traditional feature를 node-level, link-level, graph-level 등 다양한 level에서의 prediction에 대해서 살펴볼 것이다. simplicity를 위해, undirected graph에 초점을 두어 살펴볼 예정이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Machine Learning in Graphs&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Goal: Make predictions for a set of objects&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Design choices:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Features: d-dimensional vectors&lt;/li&gt;
&lt;li&gt;Objects: Nodes, edges, sets of nodes, entire graphs&lt;/li&gt;
&lt;li&gt;Objective function: What task are we aiming to solve?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;568&quot; data-origin-height=&quot;172&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzPNSz/btssN2DUeCn/Ar3ifXp9OqK0AMaQRHWwyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzPNSz/btssN2DUeCn/Ar3ifXp9OqK0AMaQRHWwyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzPNSz/btssN2DUeCn/Ar3ifXp9OqK0AMaQRHWwyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzPNSz%2FbtssN2DUeCn%2FAr3ifXp9OqK0AMaQRHWwyk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;347&quot; height=&quot;105&quot; data-origin-width=&quot;568&quot; data-origin-height=&quot;172&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리의 목표는 function을 학습시키는 것이다. 예를 들면, 각각의 node에 대해 real valued prediction을 생성하는 위와 같은 함수 f가 있을 수 있겠다. 적절한 prediction을 생성하기 위한 함수 f를 어떻게 찾을 것인가? 이것이 우리가 풀어야 할 질문이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Node-level Tasks&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) Node-Level Features: Overview&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Goal: Characterize the structure and position of a node in the network&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해 사용할 수 있는 접근법은 아래와 같다. 앞으로 각각의 접근법에 대해서 자세히 살펴볼 예정이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Node degree&lt;/li&gt;
&lt;li&gt;Node centrality&lt;/li&gt;
&lt;li&gt;Clustering coefficient&lt;/li&gt;
&lt;li&gt;Graphlets&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) Node Features: &lt;b&gt;Node Degree&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node degree에 대해서는 지난 강의 &lt;a href=&quot;https://ydduri.tistory.com/40&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;1-3. Choice of Graph Representation&lt;/a&gt;에서 이미 살펴본 바 있기에, 개념적인 설명은 건너뛰도록 하겠다. 다만 ML model을 구축하는 데 있어서 node degree가 가지는 단점이 있는데, node degree가 같은 node가 있을 때, ML model이 그들끼리 잘 구분하지 못한다는 것이다. 일례로, 아래 그래프 예시에서 node C와 E는 모두 node degree가 3으로 같다. node A, F, G, H도 node degree가 1로 같다. 우리가 눈으로 볼 때는 이들 각각이 다른 node라는 것을 알지만, ML model 입장에서는 같은 node degree를 가지기 때문에 이들 사이를 구분하기가 어렵고, 같은 feature value를 부여하게 된다. 이는 같은 node degree를 가지는 node에 대해서 같은 예측을 생성할 수 있다는 문제로 이어진다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;687&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cigcUM/btssS4AXSNR/uvqkPpZfuXe2klGsnfGl3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cigcUM/btssS4AXSNR/uvqkPpZfuXe2klGsnfGl3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cigcUM/btssS4AXSNR/uvqkPpZfuXe2klGsnfGl3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcigcUM%2FbtssS4AXSNR%2FuvqkPpZfuXe2klGsnfGl3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;459&quot; height=&quot;254&quot; data-origin-width=&quot;687&quot; data-origin-height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3) Node Features: &lt;b&gt;Node Centrality&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 살펴본 바와 같이, node degree가 각 node의 이웃의 개수만 count하고, 각각의 node가 정녕 무엇인지는 포착하지 못한다는 문제점을 해결하기 위해 등장한 것이 node centrality이다. node centrality는 '해당 node가 이 그래프에서 얼마나 중요한가?'에 대한 notion을 포함한다. node의 중요도를 model하는 방법은 아래와 같이 여러가지가 있을 수 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(1) Eigenvector Centrality&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 node와 더 많이 이웃해 있는 node가 중요한 node다! 라는 아이디어를 기반으로 한다. 이를 수식으로 나타내면 아래의 왼쪽 식과 같다. 이는 어떤 node의 중요도는 이것과 연결되어 있는 node들의 중요도의 normalized sum과 같다는 의미이다. 이 식은 오른쪽의 eigenvalue-eigenvector problem처럼 변형이 가능하다. 이 equation을 풀면, Perron-Frobenius Theorem에 의해 largest eigenvalue $\lambda_{max}$는 항상 positive하고 unique하게 된다. 그리고 leading eigenvector인 $C_{max}$가 centrality를 나타내는 지표로서 쓰이게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;231&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D7dqz/btssSBy5LDv/otAC1xPBkK3ZAffPoYq3Yk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D7dqz/btssSBy5LDv/otAC1xPBkK3ZAffPoYq3Yk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D7dqz/btssSBy5LDv/otAC1xPBkK3ZAffPoYq3Yk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD7dqz%2FbtssSBy5LDv%2FotAC1xPBkK3ZAffPoYq3Yk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;436&quot; height=&quot;128&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;231&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(2) Betweenness Centrality&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 node가 교통의 중심지라면 중요한 node라는 아이디어다. 즉, 다른 node와의 최단 경로가 많은 node가 중요한 node라고 보는 아이디어이다. 이를 식으로 나타내면, 어떤 node v의 centrality는 해당 node v를 포함하는 다른 node s, t 사이의 shortest path의 개수를, s와 t 사이의 total number of shortest paths로 normalize함으로써 구할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;117&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUOoTd/btssUJv5oyj/FB9dOi9d09DRRTvp8mJZz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUOoTd/btssUJv5oyj/FB9dOi9d09DRRTvp8mJZz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUOoTd/btssUJv5oyj/FB9dOi9d09DRRTvp8mJZz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUOoTd%2FbtssUJv5oyj%2FFB9dOi9d09DRRTvp8mJZz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;530&quot; height=&quot;69&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;117&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;글로만 설명하면 잘 안 와닿으니 예시를 보도록 하겠다. Betweenness Centrality 관점에서 봤을 때, node A, B, E의 centrality는 0으로 같다. 반면 node C의 centrality는 3인데, A에서 B로 가는 최단 경로가 C를 거쳐야 하고, A에서 D로 가는 최단 경로도 C를 거쳐야 하며, A에서 E로 가는 최단 경로도 C를 거쳐야 하기 때문에 3이라는 숫자가 나온 것이다. 마찬가지로 D의 centrality 또한 3이다. B에서 E로 가는 최단 경로가 D를 거치며, C에서 E로 가는 최단 경로도 D를 거치고, A에서 E로 가는 최단 경로도 D를 거치기 때문이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;336&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/U1seG/btssVOYeggQ/4TzP3SWx1HYhc5sX7bxPEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/U1seG/btssVOYeggQ/4TzP3SWx1HYhc5sX7bxPEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/U1seG/btssVOYeggQ/4TzP3SWx1HYhc5sX7bxPEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FU1seG%2FbtssVOYeggQ%2F4TzP3SWx1HYhc5sX7bxPEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;620&quot; height=&quot;178&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;336&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(3) Closeness Centrality&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 모든 node와의 최단 경로 길이의 합이 작을수록 중심에 위치한 node일 확률이 크고, 따라서 더 중요하다는 아이디어이다. 식은 1 나누기 다른 모든 node와의 최단 경로 길이의 합으로 매우 간단하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;111&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lbViy/btssYSTAsku/BqEBcqnAKQHdYFBnYqqCs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lbViy/btssYSTAsku/BqEBcqnAKQHdYFBnYqqCs1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lbViy/btssYSTAsku/BqEBcqnAKQHdYFBnYqqCs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlbViy%2FbtssYSTAsku%2FBqEBcqnAKQHdYFBnYqqCs1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;472&quot; height=&quot;67&quot; data-origin-width=&quot;781&quot; data-origin-height=&quot;111&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 또한 예시를 보도록 하겠다. node A의 경우 B로 가기 위해서는 2개의 edge, C로 가기 위해서는 1개의 edge, D로 가기 위해서는 2개의 edge, E로 가기 위해서는 3개의 edge를 거쳐야 한다(각 edge의 길이는 1이라고 가정하는 듯하다). 이들의 합이 분모에 들어가고, node A의 closeness centrality는 1/8이 된다. node D의 경우 A로 가기 위해서는 2개의 edge, 나머지 B, C, E와는 직접 연결되어 있기에 하나의 edge만 거치면 되기 때문에, 1/5의 closeness centrality를 가지게 된다. closeness centrality 관점에서는 node A보다 D가 더 중요한 node인 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;948&quot; data-origin-height=&quot;258&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9UGyJ/btssQaaFNvL/wXi1b7u9fg6s9nT8fzgOd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9UGyJ/btssQaaFNvL/wXi1b7u9fg6s9nT8fzgOd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9UGyJ/btssQaaFNvL/wXi1b7u9fg6s9nT8fzgOd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9UGyJ%2FbtssQaaFNvL%2FwXi1b7u9fg6s9nT8fzgOd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;605&quot; height=&quot;165&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;948&quot; data-origin-height=&quot;258&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4) Node Features:&lt;span&gt; &lt;/span&gt;&lt;b&gt;Clustering Coefficient&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Clustering Coefficient는 어떤 node의 이웃들끼리 얼마나 연결되어 있는가를 측정한다. 식은 어떤 node v의 이웃 간 연결된 경우의 수를 이웃 node끼리 서로 짝을 지어 연결될 수 있는 전체 경우의 수로 나누어준다는 뜻이다. 이웃 노드끼리 모두 연결되어 있으면 clustering coefficient가 1, 모두 연결되어 있지 않다면 0이 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;940&quot; data-origin-height=&quot;477&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rLTED/btss3KVfyt8/IoQ511a2QGHmay86PLakL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rLTED/btss3KVfyt8/IoQ511a2QGHmay86PLakL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rLTED/btss3KVfyt8/IoQ511a2QGHmay86PLakL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrLTED%2Fbtss3KVfyt8%2FIoQ511a2QGHmay86PLakL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;523&quot; height=&quot;265&quot; data-origin-width=&quot;940&quot; data-origin-height=&quot;477&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재미있는 점은, clustering coefficient를 ego-network(clustering coefficient를 따지고자 하는, 관심 있는 node v를 포함하는 네트워크)에서의 삼각형의 개수를 셈으로써 구할 수도 있다는 것이다. 우리는 이를 pre-specified subgraph의 개수를 세는 것으로 일반화할 수 있는데, 이것이 바로 다음에서 살펴볼 Graphlets의 개념이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;957&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/57lXY/btssS06pgCS/NY0VTEqI7PAWd0UaWFazgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/57lXY/btssS06pgCS/NY0VTEqI7PAWd0UaWFazgk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/57lXY/btssS06pgCS/NY0VTEqI7PAWd0UaWFazgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F57lXY%2FbtssS06pgCS%2FNY0VTEqI7PAWd0UaWFazgk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;513&quot; height=&quot;167&quot; data-origin-width=&quot;957&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5) Node Features: &lt;b&gt;Graphlets&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Graphlets란 rooted connected non-isomorphic(같은 모양이 아닌) subgraphs라 할 수 있다. 아래 그림은 node 개수에 따라 가능한 graphlets의 모양을 나열한 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;842&quot; data-origin-height=&quot;475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qDMrA/btssN33UVSi/Tmk8pz1y5amAtBLlLmYWU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qDMrA/btssN33UVSi/Tmk8pz1y5amAtBLlLmYWU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qDMrA/btssN33UVSi/Tmk8pz1y5amAtBLlLmYWU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqDMrA%2FbtssN33UVSi%2FTmk8pz1y5amAtBLlLmYWU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;528&quot; height=&quot;298&quot; data-origin-width=&quot;842&quot; data-origin-height=&quot;475&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;graphlets에 대해 이야기할 때 빠질 수 없는 중요한 개념이 'Graphlet Degree Vector(GDV)'이다. 이는 우리가 관심 있는 node에 대하여, 해당 node를 포함하는 graphlets이 몇 번이나 나타나는지를 벡터로 표현한 것이다. 아래의 예시를 보면 쉽게 이해할 수 있다. 우리가 관심 있는 node u가 각각 graphlet의 a, b, c, d node라고 할 때 각각의 graphlets에 대해서 케이스가 몇 개씩 나타나고 있는가를 벡터로 나타내면 [2, 1, 0, 2]가 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1176&quot; data-origin-height=&quot;642&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVLke8/btssTewRglS/waCKXV931FY95hgIX5Jsg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVLke8/btssTewRglS/waCKXV931FY95hgIX5Jsg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVLke8/btssTewRglS/waCKXV931FY95hgIX5Jsg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVLke8%2FbtssTewRglS%2FwaCKXV931FY95hgIX5Jsg1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;565&quot; height=&quot;308&quot; data-origin-width=&quot;1176&quot; data-origin-height=&quot;642&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #37352f; text-align: start;&quot;&gt;정리하자면, 2~5개의 Node가 참여하는 Graphlet의 갯수는 73개이다. 이를 73차원의 벡터로 표시할 수 있다. 이는 node의 이웃들에 대한 topology를 표현하는 signature라 할 수 있다. Graphlet degree vector는 node의 local network topology에 대한 measure를 제공한다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>놀라운 Deep Learning/Machine Learning with Graphs</category>
      <category>cs224w</category>
      <category>GNN</category>
      <category>Graph Neural Networks</category>
      <author>ydduri</author>
      <guid isPermaLink="true">https://ydduri.tistory.com/41</guid>
      <comments>https://ydduri.tistory.com/41#entry41comment</comments>
      <pubDate>Sun, 3 Sep 2023 14:31:45 +0900</pubDate>
    </item>
    <item>
      <title>[CS224W] 1-3. Choice of Graph Representation</title>
      <link>https://ydduri.tistory.com/40</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Components of a Network&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Objects: nodes, vertices&amp;nbsp; &amp;nbsp;&amp;rarr; N&lt;/li&gt;
&lt;li&gt;Interactions: links, edges&amp;nbsp; &amp;rarr; E&lt;/li&gt;
&lt;li&gt;System: network, graph&amp;nbsp; &amp;nbsp; &amp;rarr; G(N, E)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Graph는 일반적인 언어이다. 배우와 배우 사이의 관계, 사람과 사람 사이의 관계, 단백질과 단백질 사이의 관계를 나타내는 세 개의 모식도는 모두 우측 아래 검은색 그래프와 같은 공통된 수학적인 표현으로 나타낼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;910&quot; data-origin-height=&quot;526&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dIuf6B/btssgmWmbNz/C4K03yJ7lRd1XKV54Tjft0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dIuf6B/btssgmWmbNz/C4K03yJ7lRd1XKV54Tjft0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dIuf6B/btssgmWmbNz/C4K03yJ7lRd1XKV54Tjft0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdIuf6B%2FbtssgmWmbNz%2FC4K03yJ7lRd1XKV54Tjft0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;478&quot; height=&quot;276&quot; data-origin-width=&quot;910&quot; data-origin-height=&quot;526&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Choosing a Proper Representation&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연한 이야기지만, 적절한 graph representation을 선택하는 일은 매우 중요하다. 일례로 같은 개인을 연결하더라도 professional한 관계를 따지느냐, sexual한 관계를 따지느냐에 따라 네트워크의 종류는 달라지게 된다. 그렇기에 node가 무엇인지, link가 무엇인지를 결정하는 게 중요한 것이다. 데이터셋이 주어졌을 때, 우리는 우선 underlying graph를 어떻게 디자인할 것인지를 결정해야 한다. interest nodes에 대응하는 객체는 무엇이 될 것인지, 그들 사이의 관계는 어떻게 되며 그렇다면 edge는 무엇이 될 것인지를 정해야 한다. 적절한 graph representation을 결정하는 일이, 네트워크를 얼마나 성공적으로 활용할 수 있을지를 좌우한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) Directed vs. Undirected Graphs&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Undirected&lt;/b&gt;: symmetric(대칭적인), reciprocal(상호간의) 관계를 모델링하기에 적합
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;ex) collaboration, friendship on Facebook, interaction between proteins...&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Directed&lt;/b&gt;: 모든 link가 방향을 가지고 있거나 source 혹은 destination이 있을 때, 화살표로 나타내기에 적합
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;ex) phone calls, financial transactions, following on Twitter&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;358&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csxILG/btssfwZwlKL/oPhf36SEtshA1bSfekNo70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csxILG/btssfwZwlKL/oPhf36SEtshA1bSfekNo70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csxILG/btssfwZwlKL/oPhf36SEtshA1bSfekNo70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsxILG%2FbtssfwZwlKL%2FoPhf36SEtshA1bSfekNo70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;402&quot; height=&quot;176&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;358&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;Undirected&lt;/span&gt;, &lt;span style=&quot;color: #006dd7;&quot;&gt;Directed&lt;/span&gt; graph에서 서로 다르게 정의되는 용어들을 살펴보자. &lt;span style=&quot;color: #ef5369;&quot;&gt;Node degree&lt;/span&gt;와 &lt;span style=&quot;color: #ef5369;&quot;&gt;Average node degree&lt;/span&gt;는 &lt;span style=&quot;color: #ef5369;&quot;&gt;Undirected graph&lt;/span&gt;에서, &lt;span style=&quot;color: #006dd7;&quot;&gt;in-degree&lt;/span&gt;와 &lt;span style=&quot;color: #006dd7;&quot;&gt;out-degree&lt;/span&gt;는 &lt;span style=&quot;color: #006dd7;&quot;&gt;Directed graph&lt;/span&gt;에서 정의되는 용어이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;Node degree&lt;/span&gt;&lt;/b&gt;: 어떤 노드 i와 인접한 edge의 개수. 아래의 그림에서 노드 A의 node degree는, 인접한 노드가 4개이므로 4가 된다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;Average Node degree&lt;/b&gt;&lt;/span&gt;: 해당 네트워크의 모든 노드에 대한 degree를 평균한 것, 계산식은 아래와 같다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;아래 계산식을 정리하면 결과적으로 edge의 개수의 두 배를 node의 개수로 나눈 값이 된다. 분자가 edge 개수의 두 배가 되는 이유는, 우리가 node degree를 계산할 때, edge는 서로 다른 node를 연결해주기 때문에 모든 node에 대해서 degree를 구하면 edge는 두 번씩 카운트되기 때문이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;247&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8zhDl/btssf2KBs23/DWxkU9b2IA2OTTlhmSbm41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8zhDl/btssf2KBs23/DWxkU9b2IA2OTTlhmSbm41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8zhDl/btssf2KBs23/DWxkU9b2IA2OTTlhmSbm41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8zhDl%2Fbtssf2KBs23%2FDWxkU9b2IA2OTTlhmSbm41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;463&quot; height=&quot;125&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;247&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;in-degree&lt;/b&gt;&lt;/span&gt;: 어떤 노드를 향하고 있는 edge의 개수&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;out-degree&lt;/b&gt;&lt;/span&gt;: 어떤 노드로부터 시작된, 밖을 향하고 있는 edge의 개수&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일례로, 아래 그림의 예시에서 node C를 기준으로 봤을 때, in-degree는 node C를 향하고 있는 화살표의 개수를 세면 되므로 2, out-degree는 반대 방향으로 뻗어나가는 화살표의 개수를 세면 되므로 1이 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;337&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8VyHF/btssfHNwWoX/8NSc4wZHmlakpOtgZU6wY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8VyHF/btssfHNwWoX/8NSc4wZHmlakpOtgZU6wY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8VyHF/btssfHNwWoX/8NSc4wZHmlakpOtgZU6wY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8VyHF%2FbtssfHNwWoX%2F8NSc4wZHmlakpOtgZU6wY0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;444&quot; height=&quot;173&quot; data-origin-width=&quot;865&quot; data-origin-height=&quot;337&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) Bipartite Graph&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;270&quot; data-origin-height=&quot;338&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUmlAb/btssk3aqSJt/YZ9evViTNAHahVGdLF6IG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUmlAb/btssk3aqSJt/YZ9evViTNAHahVGdLF6IG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUmlAb/btssk3aqSJt/YZ9evViTNAHahVGdLF6IG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUmlAb%2Fbtssk3aqSJt%2FYZ9evViTNAHahVGdLF6IG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;153&quot; height=&quot;192&quot; data-origin-width=&quot;270&quot; data-origin-height=&quot;338&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 도메인을 자연스럽게 표현할 수 있어서 많이 사용되는 구조인 'Bipartite Graph'에 대해서 보자. 이는 두 개의 다른 타입의 node로 구성되며, node는 오직 다른 타입의 node하고만 상호작용한다. 따라서 edge는 서로 다른 두 partition을 연결하는 역할을 하지, 한 partition 내에서 연결하지는 않는다. bipartite graph의 예시는 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Authors-to-Papers(they authored)&lt;/li&gt;
&lt;li&gt;Actors-to-Movies(they appeared in)&lt;/li&gt;
&lt;li&gt;Users-to-Movies(they rated)&lt;/li&gt;
&lt;li&gt;Recipes-to-Ingredients(they contain)&lt;/li&gt;
&lt;li&gt;Customers-to-Products(they purchased)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 또한 'folded' 혹은 'projected' network라는 용어에 대해 정의할 수 있다. folded/projected bipartite graph는 그 이름처럼, bipartite graph를 오른쪽 또는 왼쪽 중 한쪽으로 project 시켜서 만들 수 있다. 예를 들어, 아래의 그래프에서 U가 저자, V가 논문이라고 한다면, 그중에서도 논문 A에 연결된 저자 1, 2, 3은 해당 논문의 공저자라 할 수 있다. 만일 저자 쪽으로 projection을 시켜서 projection 저자 그래프를 만든다고 한다면, 공통된 논문의 공저자인 1, 2, 3은 서로 관계가 있다고 볼 수 있을 것이다. 반면, 저자 3, 4는 함께 작업한 논문이 아무것도 없으므로 관계가 없다고 할 수 있고, 실제로 projection 저자 그래프에서 edge로 연결되어 있지 않다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1036&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXPBgq/btssfDYJCks/jg2kPQSpYppprtkkoAeSX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXPBgq/btssfDYJCks/jg2kPQSpYppprtkkoAeSX1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXPBgq/btssfDYJCks/jg2kPQSpYppprtkkoAeSX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXPBgq%2FbtssfDYJCks%2Fjg2kPQSpYppprtkkoAeSX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;477&quot; height=&quot;285&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1036&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Representing Graphs&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;1) Adjacency Matrix&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래프를 표현하는 방법 중 하나는 adjacency matrix(인접 행렬: 각 노드 간의 연결 상태를 행렬과 같은 형태로 표현)를 이용하는 것이다. node의 개수가 n일 때, n*n 행렬 A를 만든다. 이 행렬은 binary로, 0 또는 1의 entity를 가지게 된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Undirected graph&lt;/b&gt;: i번째 node와 j번째 node가 서로 연결되어 있다면 행렬 A의 (i, j) 위치에 1을, 연결되어 있지 않다면 0을 넣는다. 그래서 Undirected graph의 adjacency matrix는 symmetric할 수밖에 없다(대칭적이라는 의미).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Directed graph&lt;/b&gt;: i번째 node에서 j번째 node로 edge가 뻗어나가고 있다면 행렬 A의 (i, j) 위치에 1을, 그렇지 않다면 0을 넣는다. 아래 그래프의 예시에서, node 2에서 1로 화살표가 향하고 있으므로 행렬 A의 (2, 1) 위치에 1이 채워졌다. 그러나 그 역으로는 화살표가 향하지 않으므로 그와 대칭되는 위치에 있는 (1, 2)에는 0이 들어간다. Directed graph는 symmetric하지 않을 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rFXy0/btsslbzAWtE/8ykiJ4KLz6T2HW3BDROj90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rFXy0/btsslbzAWtE/8ykiJ4KLz6T2HW3BDROj90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rFXy0/btsslbzAWtE/8ykiJ4KLz6T2HW3BDROj90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrFXy0%2FbtsslbzAWtE%2F8ykiJ4KLz6T2HW3BDROj90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;446&quot; height=&quot;332&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;adjacency matrix를 이용하면, node degree를 구할 때 어떤 node와 인접한 edge가 몇 개나 있는지 직접 셀 필요 없이, 행과 열의 합으로서 그 값을 구할 수 있다는 장점도 있다. 이처럼 adjacency matrix는 연산을 편하게 만들어준다는 장점이 있지만, 단점도 존재한다. 바로 극도로 sparse하다는 점이다. 전 세계 사람들 사이의 social network를 그린다고 생각해보자. 80억 개가 넘는 node가 존재할테지만, 80억 명의 친구를 가진 사람은 그 누구도 없을 것이다. 따라서 실제로 연결된 node는 극히 일부일 것이고, 그렇기 때문에 adjacency matrix는 극도로 sparse해질 수밖에 없다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1214&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIZD1D/btssgtuuFL1/Pgs58klPIhvKLUPtA8klKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIZD1D/btssgtuuFL1/Pgs58klPIhvKLUPtA8klKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIZD1D/btssgtuuFL1/Pgs58klPIhvKLUPtA8klKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIZD1D%2FbtssgtuuFL1%2FPgs58klPIhvKLUPtA8klKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;611&quot; height=&quot;371&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1214&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) Edge list&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래프를 표현하는 또 다른 방법 중 하나는 바로 그래프를 edges의 목록으로 나타내는 것이다. 이러한 representation은 딥러닝 프레임워크에서 꽤나 자주 쓰이는 방법인데, 그래프를 2D matrix로 간단하게 나타낼 수 있도록 해주기 때문이다. 다만 이 방식은 graph manipulation이나 분석을 하기 어렵다는 단점도 있다. node degree를 계산하는 것이 non-trivial(자명하지 않다고 해석해야 할 듯)하기 때문이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;497&quot; data-origin-height=&quot;340&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bESMWe/btssk0x38KF/vEHdYskKsUSMiAqRJXvdWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bESMWe/btssk0x38KF/vEHdYskKsUSMiAqRJXvdWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bESMWe/btssk0x38KF/vEHdYskKsUSMiAqRJXvdWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbESMWe%2Fbtssk0x38KF%2FvEHdYskKsUSMiAqRJXvdWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;335&quot; height=&quot;229&quot; data-origin-width=&quot;497&quot; data-origin-height=&quot;340&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3) Adjacency list&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;graph analysis, manipulation 측면에서는 위의 edge list 방식보다 더 나은 방법이라 할 수 있다. 각 node의 이웃을 목록 형식으로 표현하는 방식으로서, 크고 sparse한 네트워크에 적용하기 좋다. 또한 이 방식은 주어진 node의 모든 이웃들을 빠르게 retrieve할 수 있도록 해준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;363&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dbYFiN/btssfTfTkvZ/qkAHuUmweiro9gIzQLL8a1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dbYFiN/btssfTfTkvZ/qkAHuUmweiro9gIzQLL8a1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dbYFiN/btssfTfTkvZ/qkAHuUmweiro9gIzQLL8a1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdbYFiN%2FbtssfTfTkvZ%2FqkAHuUmweiro9gIzQLL8a1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;335&quot; height=&quot;211&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;363&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. Node and Edge Attributes&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 그래프에 추가적인 특성을 attach할 수도 있다. 아래는 가능한 option의 종류이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Weight(edgd에 가중치 부여): ex. frequency of communication&lt;/li&gt;
&lt;li&gt;Ranking: ex. best friend, second best friend...&lt;/li&gt;
&lt;li&gt;Type: ex. friend, relative, co-worker&lt;/li&gt;
&lt;li&gt;Sign: Friend vs. Foe, Trust vs.Distrust&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래프를 구성하는 각 개체는 속성을 가질 수 있다. 사람 사이의 관계를 예로 들자면, node(즉, 사람)는 성별, 관심사, 위치 등의 속성을 가질 수 있고, edge(그들 사이의 link)는 호의적인지, 친한지 등의 속성을 가질 수 있다. 그래프를 이용해서 화학 분자를 나타낸다면, node 하나하나는 각각의 화학적인 특성을 가지게 될 것이다. 뿐만 아니라 전체 그래프 그 자체도 속성을 가질 수 있는데, 이는 해당 그래프를 구성하는 객체들의 속성에 기반한다. 따라서, Graph Neural Network를 모델링할 때 우리는 단순히 그래프의 topology뿐만 아니라, 그것을 구성하는 객체 각각이 가지는 속성까지 고려하여야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. More Types of Graphs&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래프의 속성을 representation 자체에 녹여낼 수도 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) Unweighted vs. Weighted&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, edge에 가중치가 가해지는 경우, adjacency matrix를 0과 1의 entity로 구성된 binary matrix로 만드는 대신, 연결 강도에 따라 entity의 크기를 달리함으로써 표현할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;662&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XNPRC/btssk8waSBs/0g6iTPpiWKk8S9wkaYnbU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XNPRC/btssk8waSBs/0g6iTPpiWKk8S9wkaYnbU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XNPRC/btssk8waSBs/0g6iTPpiWKk8S9wkaYnbU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXNPRC%2Fbtssk8waSBs%2F0g6iTPpiWKk8S9wkaYnbU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;330&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;662&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) Self-edges(Self-loops), Multigraph&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;self-edges(self-loops)를 가지는 경우에는, adjacency matrix의 diagonal 부분이 채워지므로 이를 통해 표현할 수 있다. 같은 두 개의 node 사이에 여러 개의 edge가 있는 경우, 그만큼 연결이 강하다는 의미이므로 가중치를 부여했듯이 edge의 개수에 따라 entity를 증가시키며 표현할 수 있다. 그러나 만일 Multigraph의 같은 두 개의 node를 이어주는 edge 사이의 속성이 다르다면, adjacency matrix를 이용해 퉁쳐서 표현하기보다는 각각의 edge를 살려서 표현해주어야 할 수도 있다. 그렇기는 하지만, 일상 생활 중에 Multigraph를 사용해야 할 상황이 꽤 되기 때문에(ex. phone calls: 같은 사람들끼리 여러 번 전화할 수 있음), Multigraph는 그런 상황을 표현하는 데 매우 유용하게 사용될 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1075&quot; data-origin-height=&quot;657&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHWhMB/btssfEJ6JmR/9mb5xfeNAMmtE12ge52BPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHWhMB/btssfEJ6JmR/9mb5xfeNAMmtE12ge52BPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHWhMB/btssfEJ6JmR/9mb5xfeNAMmtE12ge52BPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHWhMB%2FbtssfEJ6JmR%2F9mb5xfeNAMmtE12ge52BPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;525&quot; height=&quot;321&quot; data-origin-width=&quot;1075&quot; data-origin-height=&quot;657&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Weighted graph&lt;/b&gt;: 가중치에 따라 matrix entity의 크기 변화시킴&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Self-edges graph&lt;/b&gt;: diagonal이 채워짐&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Multigraph&lt;/b&gt;: node 사이의 edge 개수에 따라 matrix entity의 크기 변화시킴&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3) Connectivity of Undirected Graphs&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;715&quot; data-origin-height=&quot;217&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcdjZj/btssfwee9ux/FbmEdz9c8CkIs4rZge1XP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcdjZj/btssfwee9ux/FbmEdz9c8CkIs4rZge1XP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcdjZj/btssfwee9ux/FbmEdz9c8CkIs4rZge1XP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdcdjZj%2Fbtssfwee9ux%2FFbmEdz9c8CkIs4rZge1XP0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;481&quot; height=&quot;146&quot; data-origin-width=&quot;715&quot; data-origin-height=&quot;217&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Undirected Graph에서 그래프가 connected되어 있다는 말은, 어떤 두 개의 node도 적어도 하나의 edge로 서로 연결되어 있다는 것을 의미한다. 흥미로운 점은, undirected disconnected graph를 adjacency matrix로 나타내면 block diagonal structure를 갖게 된다는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;722&quot; data-origin-height=&quot;381&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bskcNR/btssfFCjXCz/gHfROsbyDcokqnOnKt8n80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bskcNR/btssfFCjXCz/gHfROsbyDcokqnOnKt8n80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bskcNR/btssfFCjXCz/gHfROsbyDcokqnOnKt8n80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbskcNR%2FbtssfFCjXCz%2FgHfROsbyDcokqnOnKt8n80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;447&quot; height=&quot;236&quot; data-origin-width=&quot;722&quot; data-origin-height=&quot;381&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4) Connectivity of Directed Graphs&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;823&quot; data-origin-height=&quot;270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UeIGA/btsswVpwINa/HnclrczmjxbKvA3WIeJiUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UeIGA/btsswVpwINa/HnclrczmjxbKvA3WIeJiUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UeIGA/btsswVpwINa/HnclrczmjxbKvA3WIeJiUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUeIGA%2FbtsswVpwINa%2FHnclrczmjxbKvA3WIeJiUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;168&quot; data-origin-width=&quot;823&quot; data-origin-height=&quot;270&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Strongly connected directed graph&lt;/b&gt;: 어떤 노드에서 출발하든 edge 방향을 따라서 다른 모든 노드에 도달할 수 있는 그래프&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Weakly connected directed graph&lt;/b&gt;: edge 방향을 무시한다면 다른 모든 노드와 연결된 그래프&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Strongly connected components&lt;/b&gt;: edge 방향을 따라서 연결될 수 있는 노드들의 집합, 일종의 cycle을 형성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;395&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUqqlD/btssvuy9h7D/UmiUfKV8C6ynetICCR7ar0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUqqlD/btssvuy9h7D/UmiUfKV8C6ynetICCR7ar0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUqqlD/btssvuy9h7D/UmiUfKV8C6ynetICCR7ar0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUqqlD%2Fbtssvuy9h7D%2FUmiUfKV8C6ynetICCR7ar0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;514&quot; height=&quot;265&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;395&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>놀라운 Deep Learning/Machine Learning with Graphs</category>
      <category>cs224w</category>
      <category>GNN</category>
      <category>Graph Neural Networks</category>
      <author>ydduri</author>
      <guid isPermaLink="true">https://ydduri.tistory.com/40</guid>
      <comments>https://ydduri.tistory.com/40#entry40comment</comments>
      <pubDate>Sun, 27 Aug 2023 20:12:19 +0900</pubDate>
    </item>
    <item>
      <title>[CS224W] 1-2. Applications of Graph ML</title>
      <link>https://ydduri.tistory.com/39</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Different Types of Tasks&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지난 글, &lt;a href=&quot;https://ydduri.tistory.com/38&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;1-1. Why Graphs&lt;/a&gt;에서도 잠깐 언급한 바 있지만, 그래프에 대한 딥러닝 모델링에서 output인 prediction은 여러 수준에서 이루어질 수 있다. 개별 node level일 수도 있고, edge(pairs of nodes) level일 수도 있고, community(subgraph) level일 수도, graph 혹은 graph generation level일 수도 있다. 아래에서 각각 level에서의 task가 무엇이 있는지, 그 응용 사례에는 어떤 것이 있는지 소개하겠다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;652&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ecRmRf/btssblc5xQt/ZMbylTPiznwJhxg1MvfFg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ecRmRf/btssblc5xQt/ZMbylTPiznwJhxg1MvfFg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ecRmRf/btssblc5xQt/ZMbylTPiznwJhxg1MvfFg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FecRmRf%2Fbtssblc5xQt%2FZMbylTPiznwJhxg1MvfFg1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;359&quot; height=&quot;228&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;652&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Node Classification&lt;/b&gt;: predict a property of a node(ex. categorize online users/items)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Link Prediction&lt;/b&gt;: predict whether there are missing links between two nodes(ex. knowledge graph completion)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Graph Classification&lt;/b&gt;: categorize different graphs(ex. molecule property prediction, drug design에 응용 가능)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Clustering&lt;/b&gt;: detect if nodes form a community(social circle detection)&lt;/li&gt;
&lt;li&gt;Others: &lt;b&gt;Graph Generation&lt;/b&gt;(ex. drug discovery), &lt;b&gt;Graph Evolution&lt;/b&gt;(ex. physical simulation)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 Graph ML task들은 high-impact applications로 이어질 수 있다! 아래에서 보다 구체적인 예시를 소개하겠다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1) Example of Node-level ML Tasks&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(1) Protein Folding&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1210&quot; data-origin-height=&quot;447&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blW3eY/btssfZmMmQr/fnY4U42gMYTdDV7K8QspJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blW3eY/btssfZmMmQr/fnY4U42gMYTdDV7K8QspJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blW3eY/btssfZmMmQr/fnY4U42gMYTdDV7K8QspJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblW3eY%2FbtssfZmMmQr%2FfnY4U42gMYTdDV7K8QspJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;628&quot; height=&quot;232&quot; data-origin-width=&quot;1210&quot; data-origin-height=&quot;447&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 약들이 우리 인체의 protein(단백질)과 결합하거나 그들의 특성을 변화시킴으로써, 결과적으로 인체 내 biological processes를 변화시키는 방식으로 작동한다. 단백질은 아미노산으로 구성되어 있다. 달리 말해, 단백질은 아미노산의 sequence인 것이다. 그런데, magnetic 혹은 다른 종류의 힘에 의해서 단백질은 쫙 펴진 아미노산 chain 형태로 존재하는 것이 아니라, 매우 복잡한 형태로 접혀 있게 된다. 이러한 단백질의 3D 구조를 예측하는 것은 생물학계의 오랜 난제였다. &quot;아미노산 sequence가 주어졌을 때, 3D 구조를 예측할 수 있을 것인가?&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DeepMind사가 개발한 인공지능 AlphaFold는 이 문제에 대해 큰 성능 향상을 이루었다. AlphaFold의 핵심 아이디어는 바로 &quot;spatial graph&quot;였다. 이때 node는 protein sequence의 아미노산이 되고, edge는 아미노산 사이의 proximity(근접성)가 된다. 이는 모든 아미노산의 위치와 그 사이의 proximities가 주어진다면, 아미노산의 새로운 위치를 예측할 수 있는 Graph Neural Networks를 구축할 수 있음을 의미한다. 이를 이용하면 protein folding을 시뮬레이션할 수 있을 뿐 아니라, 분자들의 최종적인 위치를 예측할 수 있다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2) Example of Edge-level ML Tasks&lt;/b&gt;&lt;/h3&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;(2) Recommender Systems&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유저는 아이템과 상호작용한다. 이때 아이템은 상품이 될 수도 있고, 영화나 음악이 될 수도 있다. 유저와 아이템 각각을 node로 표현하고, 유저-아이템 상호작용을 edge로 표현하면 이를 그래프로 구축할 수 있다(유저-아이템 상호작용은 유저가 어떤 상품을 사고, 리뷰를 남기거나, 영화를 보거나, 음악을 듣는 등의 행위를 가리킨다). 이렇게 그래프를 구축함으로써, 우리는 어떤 유저가 관심 있어할 만한 다른 아이템을 추천하거나 예측할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1222&quot; data-origin-height=&quot;650&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OOrhC/btssbhIvJpx/6fpuyjiPtcPbp8KmNICOZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OOrhC/btssbhIvJpx/6fpuyjiPtcPbp8KmNICOZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OOrhC/btssbhIvJpx/6fpuyjiPtcPbp8KmNICOZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOOrhC%2FbtssbhIvJpx%2F6fpuyjiPtcPbp8KmNICOZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;570&quot; height=&quot;303&quot; data-origin-width=&quot;1222&quot; data-origin-height=&quot;650&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Graph Neural Network를 이용한 Recommender system에서의 key insight는, nodes를 어떻게 embed 혹은 represent하냐는 것이다. 서로 연관이 있는 노드는, 관계가 없는 노드에 비해 더 가까이 embedding 되어야 한다. 핀터레스트의 예시를 들면, query pin으로 케이크 이미지가 주어졌을 때, 비슷한 케이크 이미지는 가까이 embedding, 관련이 없는 스웨터 이미지는 멀리 embedding 되도록 함으로써 성공적인 recommendation이 이루어질 수 있도록 만든다. 이는 이미지 그 자체보다는, 이미지와 그래프 구조를 함께 고려하는 것이 보다 나은 추천을 가능케 할 수 있음을 시사한다.&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;(3) Drug Side Effects&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 환자들이 complex하거나 함께 발병한 질병들을 치료할 목적으로 동시에 여러 종류의 약물을 사용하곤 한다. 그런데, 이처럼 둘 이상의 약물을 동시에 사용하는 행위는 예상치 못한 부작용을 불러일으킬 수 있다. 그렇다고 그 많은 종류의 약물 조합을 하나하나 실제로 테스트해볼 수도 없는 노릇. 해당 task에서의 과제는 임의의 약물 조합이 어떻게 상호작용하며, 어떠한 부정적인 부작용을 불러올 수 있는지를 알아내는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;738&quot; data-origin-height=&quot;493&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dlZ5e1/btsscDEyPo7/SzliiQrkXCrKb4GizkOPzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dlZ5e1/btsscDEyPo7/SzliiQrkXCrKb4GizkOPzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dlZ5e1/btsscDEyPo7/SzliiQrkXCrKb4GizkOPzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdlZ5e1%2FbtsscDEyPo7%2FSzliiQrkXCrKb4GizkOPzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;418&quot; height=&quot;279&quot; data-origin-width=&quot;738&quot; data-origin-height=&quot;493&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 또한 그래프로 접근할 수 있다. 이때 node는 약물과 단백질이 되며, edge는 그들 사이의 상호작용이 될 것이다. 우리가 알아내야할 부분은 drug와 drug 사이의 상호작용으로 인한 부작용이므로, drug-drug 사이의 missing connection을 알아내는 것이 목표라 할 수 있다. 이것이 해당 task가 edge-level ML task에 속하는 이유이다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3) Example of Subgraph-level ML Tasks&lt;/b&gt;&lt;/h3&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;(4) Traffic Prediction&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1151&quot; data-origin-height=&quot;572&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eM4zp1/btsshwYr9Ut/Dg6ES4ubVUXdtYKkyazUPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eM4zp1/btsshwYr9Ut/Dg6ES4ubVUXdtYKkyazUPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eM4zp1/btsshwYr9Ut/Dg6ES4ubVUXdtYKkyazUPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeM4zp1%2FbtsshwYr9Ut%2FDg6ES4ubVUXdtYKkyazUPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;465&quot; height=&quot;231&quot; data-origin-width=&quot;1151&quot; data-origin-height=&quot;572&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지도를 켜서 고려대학교에서 연세대학교까지 어떻게 가는지를 찍어보면, 경로와 함께 예상 소요 시간도 알려준다. 이 또한 그래프 네트워크의 결과물이다. 이때 nodes는 road segment, edge는 road segment간의 connectivity가 된다. Graph Neural Network는 각 road segment의 condition 및 traffic patterns, 출발점으로부터 도착점까지의 경에 기반하여 travel time을 예측하도록 훈련된다. 실제로 구글맵에서는 도착 시간 예상, travel time 예측에 이러한 방식을 사용하고 있다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4) Example of Graph-level ML Tasks&lt;/b&gt;&lt;/h3&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;(5) Drug Discovery&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1007&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kzQOu/btssimaeeOf/aIq0IJ7wGLQW5Y7g933F01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kzQOu/btssimaeeOf/aIq0IJ7wGLQW5Y7g933F01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kzQOu/btssimaeeOf/aIq0IJ7wGLQW5Y7g933F01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkzQOu%2FbtssimaeeOf%2FaIq0IJ7wGLQW5Y7g933F01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;492&quot; height=&quot;277&quot; data-origin-width=&quot;1007&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Antibiotics(항생제)는 atoms(원자)를 node로 하고, chemical bonds(화학 결합)을 edge로 하는 small molecular graph이다. 우리가 관심 있는 부분은 그래프로 표현되어지는 각각의 분자가 치료 효과를 가지는지다. 실제로 MIT에서 Graph Neural Network를 이용해서 엄청난 양의 candidate pool에서 치료 효과를 가지는 분자를 빠르게 선별해 내는 antibiotic discovery를 수행한 연구 사례가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 또한, 더 나아가서 graph generation에 대해서도 생각해볼 수 있다. 이는 지금껏 합성되거나 고려되지 않은 새로운 분자를 발견하는 데 활용될 수 있다. non-toxic하거나 high solubility 혹은 high drug likeness를 가지는 새로운 분자를 생성해내는 등 우리가 원하는 특성을 가지는 새로운 분자, 새로운 구조를 연구하는 데 응용 가능하다. 또한, 기존에 존재하던 분자가 desirable한 특성을 가질 수 있도록 optimization하는 데도 사용될 수 있다.&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;(6) Physics Simulation&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1230&quot; data-origin-height=&quot;537&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PU9Mu/btssqynCeLg/l0f4tuNinKCCZgHKHQK1sK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PU9Mu/btssqynCeLg/l0f4tuNinKCCZgHKHQK1sK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PU9Mu/btssqynCeLg/l0f4tuNinKCCZgHKHQK1sK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPU9Mu%2FbtssqynCeLg%2Fl0f4tuNinKCCZgHKHQK1sK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;583&quot; height=&quot;255&quot; data-origin-width=&quot;1230&quot; data-origin-height=&quot;537&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 물질을 set of particles라고 나타낼 수 있고, 이는 그래프 구조로 표현 가능하다. node는 particles 각각이 되며, edge는 그 particle들 사이의 interaction이 된다. Physics Simulation에 Graph Neural Network가 응용되는 과정은 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;proximity에 기반해 particle 간의 interaction을 표현하여 proximity graph를 만든다.&lt;/li&gt;
&lt;li&gt;현재의 특성(particle의 위치, 속도)을 반영하여 graph neural network를 구축하고, 이러한 정보에 기반했을 때 미래의 particle의 위치나 속도가 어떻게 변화할지를 예측한다.&lt;/li&gt;
&lt;li&gt;위에서의 예측에 기반하여 그래프를 업데이트하고, 1번으로 돌아가서 위 과정을 반복한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 과정은 매우 빠르고 정확한 physics simulation을 가능케 한다.&lt;/p&gt;</description>
      <category>놀라운 Deep Learning/Machine Learning with Graphs</category>
      <category>cs224w</category>
      <category>GNN</category>
      <category>Graph Neural Networks</category>
      <author>ydduri</author>
      <guid isPermaLink="true">https://ydduri.tistory.com/39</guid>
      <comments>https://ydduri.tistory.com/39#entry39comment</comments>
      <pubDate>Sun, 27 Aug 2023 16:45:35 +0900</pubDate>
    </item>
    <item>
      <title>[CS224W] 1-1. Why Graphs</title>
      <link>https://ydduri.tistory.com/38</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;※ Machine Learning with Graphs 카테고리의 글 시리즈는 Stanford University의 동명의 강의(CS224W)&lt;span&gt;&amp;nbsp;&lt;/span&gt;내용을 정리한 것입니다. 혹시 오류를 발견하신다면 언제든지 댓글로 알려주시면 감사하겠습니다!&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;강의 영상:&lt;span&gt; &lt;a href=&quot;https://www.youtube.com/playlist?list=PLoROMvodv4rPLKxIpqhjhPgdQy7imNkDn&quot;&gt;https://www.youtube.com/playlist?list=PLoROMvodv4rPLKxIpqhjhPgdQy7imNkDn&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1693097598767&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Stanford CS224W: Machine Learning with Graphs&quot; data-og-description=&quot;This course covers important research on the structure and analysis of such large social and information networks and on models and algorithms that abstract ...&quot; data-og-host=&quot;www.youtube.com&quot; data-og-source-url=&quot;https://www.youtube.com/playlist?list=PLoROMvodv4rPLKxIpqhjhPgdQy7imNkDn&quot; data-og-url=&quot;http://www.youtube.com/playlist?list=PLoROMvodv4rPLKxIpqhjhPgdQy7imNkDn&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bbNY4T/hyTMb6EobB/30ar88dSoWvk9dDqabeWB0/img.jpg?width=168&amp;amp;height=94&amp;amp;face=133_8_155_32,https://scrap.kakaocdn.net/dn/bgIn9A/hyTL2WaV1X/HYyJ4cl2fnRi1yDVKOB5U0/img.jpg?width=196&amp;amp;height=110&amp;amp;face=156_10_179_35,https://scrap.kakaocdn.net/dn/GVfRE/hyTMhTkASi/64K5b95o4pNOVrSUy1suT0/img.jpg?width=246&amp;amp;height=138&amp;amp;face=197_12_225_42,https://scrap.kakaocdn.net/dn/F96tT/hyTILaIgjx/KY2xZ4eoPXA5se0gg6h7Gk/img.jpg?width=336&amp;amp;height=188&amp;amp;face=266_15_309_62&quot;&gt;&lt;a href=&quot;https://www.youtube.com/playlist?list=PLoROMvodv4rPLKxIpqhjhPgdQy7imNkDn&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.youtube.com/playlist?list=PLoROMvodv4rPLKxIpqhjhPgdQy7imNkDn&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bbNY4T/hyTMb6EobB/30ar88dSoWvk9dDqabeWB0/img.jpg?width=168&amp;amp;height=94&amp;amp;face=133_8_155_32,https://scrap.kakaocdn.net/dn/bgIn9A/hyTL2WaV1X/HYyJ4cl2fnRi1yDVKOB5U0/img.jpg?width=196&amp;amp;height=110&amp;amp;face=156_10_179_35,https://scrap.kakaocdn.net/dn/GVfRE/hyTMhTkASi/64K5b95o4pNOVrSUy1suT0/img.jpg?width=246&amp;amp;height=138&amp;amp;face=197_12_225_42,https://scrap.kakaocdn.net/dn/F96tT/hyTILaIgjx/KY2xZ4eoPXA5se0gg6h7Gk/img.jpg?width=336&amp;amp;height=188&amp;amp;face=266_15_309_62');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Stanford CS224W: Machine Learning with Graphs&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This course covers important research on the structure and analysis of such large social and information networks and on models and algorithms that abstract ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.youtube.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. What is Graph?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Graph(그래프)는 entity(개체)간의 관계, 상호작용을 설명하고 분석하기 위해 사용되는 일반적인 언어이다. 이는 이 세상이나 주어진 도메인을 독립된 데이터 포인트들의 집합으로 보기보다는, entity 사이의 네트워크와 관계의 관점에서 보는 것이다. entity들은 그래프의 구조에 따라 서로 연결되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;태생적으로 그래프의 형태로 표현되는 데이터 종류들이 굉장히 많고, 이러한 도메인의 데이터들을 그래프 구조로 표현하는 것은 보다 믿을만하고, 정확한 방법이다. 그래프로 표현되는 도메인의 대표적인 예시는 아래와 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Event Graphs&lt;/li&gt;
&lt;li&gt;Computer Networks&lt;/li&gt;
&lt;li&gt;Disease Pathways&lt;/li&gt;
&lt;li&gt;Food Webs&lt;/li&gt;
&lt;li&gt;Particle Networks&lt;/li&gt;
&lt;li&gt;Underground Networks&lt;/li&gt;
&lt;li&gt;Social Networks&lt;/li&gt;
&lt;li&gt;Economic Networks&lt;/li&gt;
&lt;li&gt;Communication Networks&lt;/li&gt;
&lt;li&gt;Citation Networks&lt;/li&gt;
&lt;li&gt;Internet&lt;/li&gt;
&lt;li&gt;Networks of Neurons&lt;/li&gt;
&lt;li&gt;Knowledge Graphs&lt;/li&gt;
&lt;li&gt;Regulatory Networks&lt;/li&gt;
&lt;li&gt;Scene Graphs&lt;/li&gt;
&lt;li&gt;Code Graphs&lt;/li&gt;
&lt;li&gt;Molecules&lt;/li&gt;
&lt;li&gt;3D shapes&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Types of Networks and Graphs&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래프로 나타낼 수 있는 데이터는 근본적으로 크게 두 개 파트로 나눌 수 있다. 하나는 natural graphs 혹은 networks라 부르는 것으로, 기저에 있는 도메인이 태생적으로 graph로 표현되게 된다. 이에 속하는 도메인의 종류는 아래와 같다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) Networks(also known as Natural Graphs):&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Social networks&lt;/b&gt;: Society is a collection of 7+ billion individuals&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Communication and transactions&lt;/b&gt;: Electronic devices, phone calls, financial transactions&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Biomedicine&lt;/b&gt;: Interactions between genes/proteins regulate life&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Brain connections&lt;/b&gt;: Our thoughts are hidden in the connections between billions of neurons&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 하나의 파트는, 태생적으로 그래프 형태를 갖는 것은 아니지만 relational structure를 가지고 있어서 그래프로 표현될 수 있는 도메인이다. 그 예시는 아래와 같다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) Graphs(as a representation):&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Information/knowledge&lt;/b&gt;: are organized and linked&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Software&lt;/b&gt;: can be represented as a graph&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Similarity networks&lt;/b&gt;: Connect similar data points&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Relational Structures&lt;/b&gt;: Molecules, Scene graphs, 3D shapes, Particle-based physics simulations&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 강의에서 다룰 메인 주제는 &quot;relational structure(그래프)를 활용하여 어떻게 더 나은 prediction을 할 수 있는가?&quot;이다. 복잡해 보이는 도메인은, 그래프로 표현될 수 있는 풍부한 relational structure의 집합이라고 볼 수 있다. 이러한 관계를 명시적으로 모델링한다면 우리는 보다 좋은 performance를 발휘할 수 있고, 보다 정확한 모델을 구축하여 정확한 예측을 하도록 만들 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Why is Graph Deep Learning Hard?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 딥러닝의 toolbox는 단순한 시퀀스, 그리드같은 데이터에 특화되어 있다. 선형적인 구조로 표현될 수 있는 text나 speech, fixed size의 그리드로 표현될 수 있는 이미지 등이 그 예시다. 현대의 딥러닝 모델들은 이러한 유형의 데이터들을 처리하는데 매우 뛰어난 성능을 보이고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;695&quot; data-origin-height=&quot;211&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dlTTlT/btssfyiHwI7/yNVVuip6QT3hFKy5fd98u1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dlTTlT/btssfyiHwI7/yNVVuip6QT3hFKy5fd98u1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dlTTlT/btssfyiHwI7/yNVVuip6QT3hFKy5fd98u1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdlTTlT%2FbtssfyiHwI7%2FyNVVuip6QT3hFKy5fd98u1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;599&quot; height=&quot;182&quot; data-origin-width=&quot;695&quot; data-origin-height=&quot;211&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 그래프는 앞서의 text, speech, 이미지 데이터에 비해 더욱 복잡한 구조를 가지고 있기 때문에 다루기가 까다롭다. 구체적인 이유는 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;임의의 크기와 복잡한 topology(위상)를 가지고 있다.&lt;/li&gt;
&lt;li&gt;그리드나 text에서와 같은 spatial locality가 없다. 그리드의 경우 상하좌우, 텍스트의 경우 좌우의 spatial locality를 가지는데, 그래프의 경우 고정된 기준점이나 순서가 없기 때문에 이를 따질 수 없다.&lt;/li&gt;
&lt;li&gt;네트워크 자체가 dynamic하고, multi-modal한 특징까지 가진다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 강의에서는 그래프와 같은 복잡한 데이터 유형에 대해 딥러닝 모델링을 하는 방법에 대해서 다룬다. 이때 모델의 input은 그래프가 되고, output은 prediction이 된다. prediction은 개별 노드 수준에서 이루어질 수도 있고, 노드 쌍이나 노드 간의 링크 수준에서 이루어질 수도 있고, 아예 새로운 그래프를 생성해내거나 그래프로 나타나지는 주어진 molecule의 특성을 예측하는 것처럼 더욱 복잡한 수준일 수도 있다. 그래프에 대한 모델링은 실제로 아직 활발히 개척 중인 분야이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;452&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ME5WO/btssqzfI5uy/u4K07uqLYHHTnYRqAuKQLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ME5WO/btssqzfI5uy/u4K07uqLYHHTnYRqAuKQLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ME5WO/btssqzfI5uy/u4K07uqLYHHTnYRqAuKQLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FME5WO%2FbtssqzfI5uy%2Fu4K07uqLYHHTnYRqAuKQLK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;620&quot; height=&quot;367&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;452&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 강의에서 하고자 하는 것은, &quot;representation learning&quot;이다. feature engineering 과정 없이, 자동적으로 그래프에 대한 좋은 representation을 학습하게 만들고자 한다. 이를 위해 representation learning 과정에서는 우리의 그래프의 노드들을 d차원으로 임베딩하여 d차원의 벡터를 만든다(이렇게 만들어진 벡터는 'representation', 'feature representation', 'embedding' 등 여러 이름으로 불린다). 유사한 노드끼리 embedding space에서 가까이 위치하도록 만드는 것이다. 임베딩이 잘 되면 downstream task에도 쉽게 적용이 가능하므로, 결국 우리의 목표는 그래프를 잘 임베딩하는 것이라고 표현할 수도 있겠다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;232&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zQNRz/btssgsa9SC2/wolE4GgbNkv9KdBK9cu06k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zQNRz/btssgsa9SC2/wolE4GgbNkv9KdBK9cu06k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zQNRz/btssgsa9SC2/wolE4GgbNkv9KdBK9cu06k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzQNRz%2Fbtssgsa9SC2%2FwolE4GgbNkv9KdBK9cu06k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;523&quot; height=&quot;159&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;232&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>놀라운 Deep Learning/Machine Learning with Graphs</category>
      <category>cs224w</category>
      <category>GNN</category>
      <category>Graph Neural Networks</category>
      <author>ydduri</author>
      <guid isPermaLink="true">https://ydduri.tistory.com/38</guid>
      <comments>https://ydduri.tistory.com/38#entry38comment</comments>
      <pubDate>Sun, 27 Aug 2023 14:59:42 +0900</pubDate>
    </item>
    <item>
      <title>Linear Regression</title>
      <link>https://ydduri.tistory.com/37</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 지도 학습(Supervised Learning)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라벨(Y, 정답)이 존재하는 학습 방법, 모델에게 정답을 가르쳐주는 학습 방법. 지도 학습에는 크게 '회귀(regression)'와 '분류(classification)'의 두 가지 종류가 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 61px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;회귀(Regression)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;분류(Classification)&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;변수들 간의 함수적 관계를 탐색&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px; text-align: center;&quot;&gt;이미 정해진 몇 개의 클래스 라벨 중 하나를 예측&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 17px;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;연속형 수치, 연속형 자료&lt;/span&gt; 예측&lt;br /&gt;ex) 몸무게로 키 예측&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 17px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;이산형 수치, 범주형 자료&lt;/span&gt; 예측&lt;br /&gt;ex) 이메일의 스팸 여부&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 10px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 10px;&quot;&gt;단순선형회귀분석(Simple Linear Regression)&lt;br /&gt;다중선형회귀분석(Multiple Linear Regression)&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 10px;&quot;&gt;이진 분류(binary classification)&lt;br /&gt;다중 분류(multiclass classification)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지도 학습을 할 때, 데이터를 받으면 우선 우리가 해야 하는 task가 무엇인지(회귀인지 분류인지) 명확히 해야 한다. 이후에 어떤 방법론을 사용할 것인지를 결정한다. task에 따라 어떤 방법론을 사용할 것인지가 달라진다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;회귀일 경우: linear regression, ridge, lasso...&lt;/li&gt;
&lt;li&gt;분류일 경우: SVM, logistic regression&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 회귀분석(Regression)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회귀분석(Regression)이란 변수들 사이의 함수적 관계를 탐색하는 과정이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;X(독립, 설명변수): 다른 변수에 영향을 주는 변수&lt;/li&gt;
&lt;li&gt;Y(종속, 반응변수): 다른 변수로부터 영향을 받는 변수&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 Y가 supervised(지도식)이면서 연속형 자료라면 회귀분석을 이용하면 좋다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1) 선형회귀분석(Linear Regression)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선형회귀분석(Linear Regression)이란 회귀분석의 일종이다. 회귀분석은 크게 선형회귀분석과 비선형회귀분석으로 나뉘는데, 그중 선형회귀분석은 독립변수와 종속변수 간 선형 상관관계를 모델링하는 기법이다. 데이터들에 가장 가까운 선형식(hyperplane $\widehat{y} = \beta_0 + \beta_1x_1 + ... + \beta_kx_k$)을 찾는 것이 선형회귀분석의 목표이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;(1) 단순선형회귀(Simple Linear Regression)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock floatLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;770&quot; data-origin-height=&quot;494&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wtQRL/btr42SCyFdR/Titu8ntVkm25KTJvBiN0t0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wtQRL/btr42SCyFdR/Titu8ntVkm25KTJvBiN0t0/img.png&quot; data-alt=&quot;출처) https://godongyoung.github.io&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wtQRL/btr42SCyFdR/Titu8ntVkm25KTJvBiN0t0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwtQRL%2Fbtr42SCyFdR%2FTitu8ntVkm25KTJvBiN0t0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;192&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;770&quot; data-origin-height=&quot;494&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처) https://godongyoung.github.io&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;독립변수 1개로 종속변수를 예측하는 선형회귀분석의 일종. 입력 데이터($x$)가 1개인 경우, 출력 데이터($\widehat{y}$)는 y절편이 $\beta_0$, 기울기가 $\beta_1$인 1차 함수로 표현할 수 있다. 이때 출력 데이터($\widehat{y}$)에서 y 위에 모자처럼 얹어진 기호를 실제로도 'hat'이라 하는데, 이는 '추정치'라는 의미이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$\widehat{y} = \beta_0 + \beta_1x_1$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때, $\beta_0$, $\beta_1$: 회귀계수(학습 파라미터)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;(2) 다중선형회귀(Multiple Linear Regression)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock floatLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;447&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/39mcy/btr4LIaAgcO/0R0PT7v9xE89WKtZycfwl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/39mcy/btr4LIaAgcO/0R0PT7v9xE89WKtZycfwl0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/39mcy/btr4LIaAgcO/0R0PT7v9xE89WKtZycfwl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F39mcy%2Fbtr4LIaAgcO%2F0R0PT7v9xE89WKtZycfwl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;200&quot; height=&quot;204&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;447&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;독립변수 여러 개로 종속변수를 예측하는 선형회귀분석의 일종. 독립변수(입력 데이터 $x$)가 여러 개인 경우 아래와 같이 절편과 기울기로 이루어진 초평면(hyperplane)의 식을 통해 회귀 모델을 설정할 수 있다. 예를 들어 특성($x$)이 2개일 경우, 회귀 모델은 3차원 공간에 있는 데이터를 설명하는 평면이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$\widehat{y} = \beta_0 + \beta_1x_1 + ... + \beta_kx_k$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때, $\beta_0$, $\beta_1$, $\beta_2$, ..., $\beta_k$: 회귀계수(학습 파라미터)&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2) 회귀계수 $\beta$를 추정하는 방법&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회귀분석을 통한 우리의 목표는 입력 데이터 $x$가 주어졌을 때 출력 데이터 $\widehat{y}$를 추정하는 것이다. 그런데 위 식들을 통해 $\widehat{y}$를 추정하기 위해서는 $\beta$들, 즉 회귀계수들을 알아야 한다. 그렇다면 회귀계수 $\beta$는 어떻게 추정할 수 있을까? 그 방법은 크게 아래와 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;최소제곱법(Ordinary Least Squares Method, OLS)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정규방정식을 이용&lt;/li&gt;
&lt;li&gt;특잇값 분해로 유사역행렬을 구하여 정규방정식을 변형&lt;/li&gt;
&lt;li&gt;경사 하강법(Gradient Descent, GD)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;최대우도법(Maximum Likelihood Estimation, MLE)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 각각의 방법에 대해 보다 자세하게 살펴보도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;(1) 최소제곱법(OLS)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최소제곱법은 말그대로 제곱 값이 최소가 되도록 하는 회귀계수를 찾는다는 뜻으로, 여기서 제곱 값이란 잔차제곱합(Sum of Squared Errors, SSE)을 의미한다. 잔차란 실제 출력변수와 예측한 출력변수의 차이, 즉 오차이므로 최소제곱법의 의미는 결국 오차를 최소화하는 회귀계수를 찾는다는 뜻으로 귀결된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;잔차(residual): 실제 출력변수와 예측한 출력변수의 차이, $$e_i = y_i - \widehat{y}_i$$&lt;/li&gt;
&lt;li&gt;잔차제곱합(Sum of Squared Errors, SSE), $$SSE = \sum_{i=1}^{n}{e_i}^{2} = \sum_{i=1}^{n}({y_i-\widehat{y}_i})^{2}$$&lt;/li&gt;
&lt;li&gt;평균제곱오차(Mean of Squared Errors, MSE), $$MSE = \frac{1}{n-k-1}\sum_{i=1}^{n}{e_i}^{2} = \frac{1}{n-k-1}\sum_{i=1}^{n}({y_i-\widehat{y}_i})^{2}$$&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 n은 총 데이터의 수, k는 독립변수의 개수(선형회귀식이 몇 차원인지 나타내는 값으로, 독립변수가 1개라면 2차원 평면에 선형회귀식을 직선으로 나타낼 수 있고, 독립변수가 2개라면 3차원 공간에 선형회귀식을 평면으로 나타낼 수 있다)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;① 정규방정식 이용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최소제곱법을 적용하는 첫 번째 방법은 정규방정식을 이용하는 것이다. 최소제곱법을 통한 우리의 목표, 즉 '잔차제곱합(SSE)'을 최소화하는 회귀계수 $\beta$ 값을 찾자'를 식으로 표현하면 아래와 같다. $$\underset{\beta}{min}\sum_{i=1}^{n}({y_i-\widehat{y}_i})^{2}$$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 우리는 위와 같은 목표를 달성하기 위해 SSE로부터 $\beta$에 대한 정규방정식을 이끌어낼 것이다. 그 과정은 다음과 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20230203_134911757.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2566&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beEwEx/btrX1zwu1Cp/cykTCCiKxFllolwEXaVAR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beEwEx/btrX1zwu1Cp/cykTCCiKxFllolwEXaVAR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beEwEx/btrX1zwu1Cp/cykTCCiKxFllolwEXaVAR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeEwEx%2FbtrX1zwu1Cp%2FcykTCCiKxFllolwEXaVAR1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;835&quot; data-filename=&quot;KakaoTalk_20230203_134911757.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2566&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 유도 과정을 통해 우리는 최종적으로 정규방정식 $\mathbf{\widehat{\beta}} = (\mathbf{X}^{T}\mathbf{X})^{-1}\mathbf{X}^{T}\mathbf{y}$을 구해낼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;② 특잇값 분해로 유사역행렬을 구하여 정규방정식을 변형&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정규방정식은 비교적 어렵지 않은 수식적 아이디어를 이용해 회귀계수를 찾을 수 있게 해준다는 장점이 있지만, 대표적인 단점이 두 가지 존재한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;모델이 복잡해질수록 연산 시간이 크게 증가한다.&lt;/li&gt;
&lt;li&gt;$(\mathbf{X}^{T}\mathbf{X})$의 역행렬을 구할 수 없을 때 사용할 수 없다(실제로 정규방정식 유도의 마지막 부분에서 역행렬이 존재하는 경우에만 최종적으로 $\mathbf{\widehat{\beta}}$에 대한 식을 끌어낼 수 있었다).&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 우리는 이러한 단점을 해결하기 위해, 특잇값 분해를 이용해서 유사역행렬을 구하고, 기존 정규방정식을 변형해볼 것이다. 역행렬은 기본적으로 n*n 형태의 정방 행렬(sqaure matrix)에서만 정의되는데, 정방 행렬이 아닌 다른 모양의 행렬에 대해서는 '유사역행렬'을 적용할 수 있다. 다시 말해, 유사역행렬은 역행렬과 달리 항상 구할 수 있는 것이다. 유사역행렬의 또다른 장점으로는 정규방정식을 이용한 ①번 방법보다 계산 복잡도가 낮다는 점도 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;유사역행렬&lt;/b&gt;이란?&lt;br /&gt;&lt;br /&gt;$Ax = I$ 식을 만족하는 벡터 $x$를 구하기 위해 우리는 $A$의 역행렬인 $A^{-1}$을 양변에 곱하여, $$A^{-1} A x = A^{-1} I$$와 같은 방식으로 $x$를 찾곤 했다. 그런데 이처럼 $A$의 역행렬을 구하기 위해서는 $A$가 $n*n$ 꼴의 정사각 행렬이어야만 한다. 만약 $m*n$ 꼴의 비정사각 행렬인 $A$에 대해서 $x$를 구하고 싶다면 어떻게 해야 할까? 이럴 때 사용하는 것이 바로 유사역행렬이다. $$A^T A x = A^T$$우선 위와 같이 식의 양변에 A의 transpose를 곱해줌으로써 $A$를 억지로 $n*n$의 정사각 행렬로 만들어준다. $A$가 $m*n$ 꼴이라면 $A$의 tranpose인 $A^T$는 $n*m$ 꼴을 가지고 있을 텐데, 위의 식처럼 곱할 경우 결과적으로 $n*n$의 정사각 행렬이 만들어지게 된다. 그런 다음, $$(A^T A)^{-1} A^T A x = (A^T A)^{-1} A^T$$ 위와 같이 $A^T A$ 전체에 대한 역행렬을 곱해주면 마침내 우리는 식을 원하던 대로 $x$에 대해서 정리할 수 있게 된다. $$x=(A^T A)^{-1} A^T$$ 이때 우변에 위치한 $(A^T A)^{-1} A^T$ 이러한 형태가 바로 유사역행렬이다(여기서는 $A$의 유사역행렬). 유사역행렬은 + 첨자를 붙여서 나타내며, 여기서처럼 $A$의 유사역행렬을 구한 경우 $A^+$로 표시한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 구한 정규방정식 $\mathbf{\widehat{\beta}} = (\mathbf{X}^{T}\mathbf{X})^{-1}\mathbf{X}^{T}\mathbf{y}$을 보면, 우변에 $(\mathbf{X}^{T}\mathbf{X})^{-1}\mathbf{X}^{T}$ 이렇게 유사역행렬 형태가 들어 있는 것을 확인할 수 있다. 이를 유사역행렬 $\mathbf{X}^+$로 대체하면 다음과 같이 나타낼 수 있다. $$\mathbf{\widehat{\beta}} = \mathbf{X}^+ \mathbf{y}$$ 그리하여 &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;b&gt;좀 더 확장성이 증가하는 방향으로 정규방정식을 변형&lt;/b&gt;시킬 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;③ 경사하강법&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock floatLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;565&quot; data-origin-height=&quot;551&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c15xhV/btr4RzRVD1B/sqWguEKpoLC9IXuUkPMP41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c15xhV/btr4RzRVD1B/sqWguEKpoLC9IXuUkPMP41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c15xhV/btr4RzRVD1B/sqWguEKpoLC9IXuUkPMP41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc15xhV%2Fbtr4RzRVD1B%2FsqWguEKpoLC9IXuUkPMP41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;200&quot; height=&quot;551&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;565&quot; data-origin-height=&quot;551&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;딥러닝이나 머신러닝을 공부한 경험이 있으신 분들은 딥러닝에서 등장하던 용어가 여기서 나타난 것에 의아할 수도 있겠다. 경사하강법은 딥러닝에서 손실함수를 최소화하기 위해 매개변수를 반복적으로 조정하는 과정을 말하는데, 이때 &lt;b&gt;딥러닝에서의 '회귀 손실함수'가 곧 머신러닝에서의 '선형회귀 목적함수'에 대응&lt;/b&gt;된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 딥러닝에서 다루는 경사하강법은 머신러닝에서도 적용할 수 있고, &lt;b&gt;반복적인 학습을 통해 모델의 최적 파라미터를 찾는 것이 머신러닝에서의 경사하강법의 목표&lt;/b&gt;라 할 수 있다.&lt;/p&gt;</description>
      <category>재미있는 Machine Learning</category>
      <author>ydduri</author>
      <guid isPermaLink="true">https://ydduri.tistory.com/37</guid>
      <comments>https://ydduri.tistory.com/37#entry37comment</comments>
      <pubDate>Mon, 20 Mar 2023 17:09:28 +0900</pubDate>
    </item>
    <item>
      <title>4. Fortran의 산술연산과 format이 없는 입출력문(실전편)</title>
      <link>https://ydduri.tistory.com/36</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실습 코드:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/ydduri/Joyful_Fortran_Tutorial/tree/main/4.%20Fortran%EC%9D%98%20%EC%82%B0%EC%88%A0%EC%97%B0%EC%82%B0%EA%B3%BC%20format%EC%9D%B4%20%EC%97%86%EB%8A%94%20%EC%9E%85%EC%B6%9C%EB%A0%A5%EB%AC%B8/%EC%8B%A4%EC%A0%84%ED%8E%B8&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;ydduri 깃허브 - Joyful_Fortran_Tutorial&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;목차&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;#c1&quot;&gt;1. format이 없는 입출력문&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;#c2&quot;&gt;2. 산술연산 연습하기&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;#c3&quot;&gt;3. 내장함수&lt;/a&gt;&lt;/blockquote&gt;
&lt;h3 id=&quot;c1&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. format이 없는 입출력문&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1) 세 점수 입력 받아 평균 계산&lt;span style=&quot;color: #006dd7;&quot;&gt;(4_1_1.f90)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전글인 &lt;a href=&quot;https://ydduri.tistory.com/20&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;4. Fortran의 산술연산과 format이 없는 입출력문(이론편)&lt;/span&gt;&lt;/a&gt;에서 format이 없는 입출력문에 대해서 배웠다. format은 입출력의 형태를 지정하는 방식을 이야기하는 것인데, 이번에는 format을 지정하지 않고 입력문, 출력문을 어떻게 작성하는지에 초점을 맞추었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fortran에서 입력문은 read, 출력문은 print로 나타낸다. 매우 직관적이다. 그렇다면 입출력문에 format을 지정하지 않겠다는 것을 Fortran에게 어떻게 전달해야 할까? 그건 바로 *(별표)다!&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;read*, x1, x2, ... , xm&lt;/b&gt;(이때 x1, x2, ..., xm은 입력 받을 변수명)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;print*, x1, x2, ... , xm&lt;/b&gt;(이때 x1, x2, ..., xm은 출력할 변수명 혹은 상수값)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, 지금까지 배운 내용을 바탕으로 점수 세 개를 입력 받은 뒤 세 점수의 평균을 계산하여 출력하는 프로그램을 작성해 보자!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1071&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nQNSy/btr3pq9uoHO/Bj2gVG7k7KtIKdfmRG0PF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nQNSy/btr3pq9uoHO/Bj2gVG7k7KtIKdfmRG0PF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nQNSy/btr3pq9uoHO/Bj2gVG7k7KtIKdfmRG0PF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnQNSy%2Fbtr3pq9uoHO%2FBj2gVG7k7KtIKdfmRG0PF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;1071&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1071&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1677828742643&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;결과
(입력이 정해지지 않았으므로 결과는 사람마다 다를 수 있음)

 Enter three scores
100.0 85.0 60.0
 average score:   81.6666641&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;첫 번째 print* 문에서 'Enter three scores'라는 안내문 출력&lt;/li&gt;
&lt;li&gt;read* 문에서 세 개의 점수 score1, score2, score3 입력&lt;/li&gt;
&lt;li&gt;두 번째 print* 문에서 'average score: 계산한 평균' 출력&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2) max, min 내장함수를 활용한 최고점과 최저점 출력&lt;span style=&quot;color: #006dd7;&quot;&gt;(4_1_2.f90)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 위에서 짠 프로그램에 더해서, 최고점과 최저점을 함께 출력해보도록 하자! 방법은 간단하다. 최댓값을 출력하는 max, 최솟값을 출력하는 min이라는 내장함수를 이용하면 된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;max(x1, x2, ... , xm): &lt;/b&gt;x1, x2, ..., xm의 최댓값을 계산&lt;/li&gt;
&lt;li&gt;&lt;b&gt;min(x1, x2, ... , xm): &lt;/b&gt;x1, x2, ..., xm의 최솟값을 계산&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1071&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8Yd02/btr3kxnwOXx/ZnIgxDGYqY7V5TiKQMsfb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8Yd02/btr3kxnwOXx/ZnIgxDGYqY7V5TiKQMsfb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8Yd02/btr3kxnwOXx/ZnIgxDGYqY7V5TiKQMsfb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8Yd02%2Fbtr3kxnwOXx%2FZnIgxDGYqY7V5TiKQMsfb1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;1071&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1071&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1677828742644&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;결과
(입력이 정해지지 않았으므로 결과는 사람마다 다를 수 있음)

 Enter three scores
100.0 85.0 60.0
 average score:   81.6666641    
 highest score:   100.000000    
 lowest score:   60.0000000&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;c2&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 산술연산 연습하기&lt;span style=&quot;color: #006dd7;&quot;&gt;(4_2.f90)&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 산술연산과 좀 더 친해지는 시간이다! 아래 6가지 식의 값을 계산하는 프로그램을 짜되, 이번에는 read 문이 아니라 프로그램 내에서 값을 할당하여 결과를 계산하도록 작성해보자. 프로그램 내에서 값을 할당해주어야 하는 변수는 총 3개인데, 각각 x = 1.2, y = 3.4, n = 2.0을 할당하면 된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$2xy^2-2x^2y$&lt;/li&gt;
&lt;li&gt;$(4+\frac{x}{y})^{n-1}$&lt;/li&gt;
&lt;li&gt;$\sqrt{3x^2+5y^2}$&lt;/li&gt;
&lt;li&gt;$e^{xy}-|x^2-y^2|$&lt;/li&gt;
&lt;li&gt;$ln(x+y)^2$&lt;/li&gt;
&lt;li&gt;$cos(\log_{10}{(x+3y)})$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1071&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pp4hD/btr3GUokMIR/PM65K6MZKrvD84R5KoWPZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pp4hD/btr3GUokMIR/PM65K6MZKrvD84R5KoWPZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pp4hD/btr3GUokMIR/PM65K6MZKrvD84R5KoWPZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpp4hD%2Fbtr3GUokMIR%2FPM65K6MZKrvD84R5KoWPZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;1071&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1071&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1678682584984&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;결과

   17.9519997       4.35294104       7.88162422       49.0254898       3.05211282      0.491569757&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;c3&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 내장함수&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1) 헷갈리는 내장함수의 대표주자, int, nint, floor, ceiling&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;(4_3_1.f90)&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내장함수 중에는 직관적으로 사용할 수 있는 것들이 많지만, 종종 그 기능이 헷갈리는 경우들이 있다. 헷갈리는 내장함수의 대표주자라 할 수 있는 int, nint, floor, ceiling의 결과 차이를 직접 확인해보는 것이 이번 문제의 목표이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;int(x): x의 정수부&lt;/li&gt;
&lt;li&gt;nint(x): x를 반올림&lt;/li&gt;
&lt;li&gt;floor(x): x를 내림&lt;/li&gt;
&lt;li&gt;ceiling(x): x를 올림&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1071&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EOm3G/btr3lDn1oGM/sKXJxNMA6hXP3MUBdTmJok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EOm3G/btr3lDn1oGM/sKXJxNMA6hXP3MUBdTmJok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EOm3G/btr3lDn1oGM/sKXJxNMA6hXP3MUBdTmJok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEOm3G%2Fbtr3lDn1oGM%2FsKXJxNMA6hXP3MUBdTmJok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;1071&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1071&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1677828742644&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;결과

 x=   3.40000010    
 int(x)=           3
 nint(x)=           3
 floor(x)=           3
 ceiling(x)=           4&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x로 3.4를 입력했을 때,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;int(x): 3.4의 정수부인 3만 출력(소수점 아래 절삭)&lt;/li&gt;
&lt;li&gt;nint(x): 3.4를 반올림하여 3 출력&lt;/li&gt;
&lt;li&gt;floor(x): 3.4를 내림하여 3 출력&lt;/li&gt;
&lt;li&gt;ceiling(x): 3.4를 올림하여 4 출력&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만일 x로 3.6을 입력했다면, 반올림 값을 출력하는 nint(x)의 결과만 4로 달라지고 나머지 값들은 동일할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2)&lt;span&gt;&amp;nbsp;&lt;/span&gt;삼각함수&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;(4_3_2.f90)&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 좀 대기과학스러운 문제를 풀어보도록 하겠다. 삼각함수를 활용해서, 위도를 degree 단위로 입력하면 코리올리 매개변수(Coriolis parameter) 값을 계산하여 출력해주는 프로그램을 작성해보자!&lt;span style=&quot;color: #666666;&quot;&gt;(공식은 알려드리니 걱정하지 않으셔도 좋다)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코리올리 매개변수를 계산하는 식은 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$f = 2\Omega sin\phi$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 $\Omega$는 지구의 회전 각속도로, $7.292\times 10^{-5}rads^{-1}$의 값을 가지고, $\phi$는 위도이다. 아마 감이 오셨을 테지만, 프로그램을 짤 때 상수인 $\Omega$는 parameter문을 사용해서 나타내주고, 위도 $\phi$는 입력받을 수 있도록 만들 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코리올리 매개변수를 계산할 때 sin 함수를 사용해야 하는데, Fortran에도 물론 삼각함수가 내장되어 있으나, 그 인자를 radian 단위로 작성해야 한다는 특징이 있다. 그런데 우리는 위도를 degree 단위로 입력받을 것이기 때문에 degree 각도를 radian 각도로 변환하는 과정이 필요한데, 이는 degree와 radian의 관계식을 이용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$1^{\circ}&amp;nbsp;=&amp;nbsp;(\frac{\pi}{180})radian$&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 degree를 radian으로 바꾸기 위해서는 degree 각도에 $\frac{\pi}{180}$를 곱해주면 된다는 것을 보여준다. 이 과정을 보다 간편하게 수행하기 위해 $\frac{\pi}{180}$를 d2rad(degree to radian 이라는 뜻)라는 변수로 선언해주도록 하겠다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1071&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4cdJe/btr3HVt7taQ/2DujiLGzQ0dOtQTEQPC8k1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4cdJe/btr3HVt7taQ/2DujiLGzQ0dOtQTEQPC8k1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4cdJe/btr3HVt7taQ/2DujiLGzQ0dOtQTEQPC8k1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4cdJe%2Fbtr3HVt7taQ%2F2DujiLGzQ0dOtQTEQPC8k1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;1071&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;1071&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1677828742645&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;결과

 Enter the latitude
40
 latitude=   40.0000000     f=   9.37441364E-05&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;degree로 입력받은 위도 40도를 d2rad를 곱해줌으로써 radian 단위로 만들어주고, 이를 주어진 식에 대입하여 최종적으로 coriolis parameter f를 구할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글을 보시면서 과연 format은 어떻게 지정하는가에 대한 궁금증이 증폭되셨지 않을까 생각한다. Fortran 문법에서 중요한 'format'을 포함한 일반적인 입출력문에 대해서는 다음 글에서 다룰 예정이니 관심 있게 봐주시면 좋을 것 같다!&lt;/p&gt;</description>
      <category>즐거운 Fortran</category>
      <category>format이 없는 입출력문</category>
      <category>FORTRAN</category>
      <category>내장함수</category>
      <category>산술연산</category>
      <author>ydduri</author>
      <guid isPermaLink="true">https://ydduri.tistory.com/36</guid>
      <comments>https://ydduri.tistory.com/36#entry36comment</comments>
      <pubDate>Mon, 13 Mar 2023 17:11:40 +0900</pubDate>
    </item>
    <item>
      <title>[EECS 498-007/598-005] 16강. Detection and Segmentation(3)</title>
      <link>https://ydduri.tistory.com/35</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. Segmentation: Instance Segmentation&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;지금까지의 16강에서 object detection, semantic segmentation 등의 내용을 다루었는데, computer vision의 task는 아직 끝나지 않았다. 또다른 segmentation 방법을 소개하기에 앞서 things와 stuff에 대해 정의하고 가도록 하자. object는 크게 things와 stuff로 분류될 수 있는데, things란 instances로 나뉠 수 있는 object, 예를 들면 고양이, 자동차, 사람 등을 의미하고, stuff란 instances로 나뉠 수 없는 object, 일례로 하늘, 풀, 물, 나무 등이 이에 속한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드46.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnWrUH/btr1ILO0psn/4TKlUhnL3gZKp02KmKOvHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnWrUH/btr1ILO0psn/4TKlUhnL3gZKp02KmKOvHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnWrUH/btr1ILO0psn/4TKlUhnL3gZKp02KmKOvHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnWrUH%2Fbtr1ILO0psn%2F4TKlUhnL3gZKp02KmKOvHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드46.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;지금까지 본 computer vision task 중 object detection은 things에 대해서만 detection을 하는 것이고, semantic segmentation의 경우 things, stuff 모두에 대해 라벨링을 하지만, things object의 instances를 세분화할 수는 없었다.&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드47.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bymmLP/btr1vsCCTb2/mpxh7GQESM1Vw2CpofzYs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bymmLP/btr1vsCCTb2/mpxh7GQESM1Vw2CpofzYs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bymmLP/btr1vsCCTb2/mpxh7GQESM1Vw2CpofzYs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbymmLP%2Fbtr1vsCCTb2%2Fmpxh7GQESM1Vw2CpofzYs0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드47.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;지금부터 다룰 instance segmentation은 object detection과 segmentation의 콜라보라고 할 수 있다.&amp;nbsp;things에 대해서만 detection을 한 뒤에, 각 things를 instance로 세분화하여 라벨링까지 하는 작업이다. 먼저 object detection을 수행한 뒤, 각 object에 대해 segmentation을 하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드48.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/05E81/btr1EejBqHf/R9JkRzUcRgdD1EdrIToY4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/05E81/btr1EejBqHf/R9JkRzUcRgdD1EdrIToY4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/05E81/btr1EejBqHf/R9JkRzUcRgdD1EdrIToY4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F05E81%2Fbtr1EejBqHf%2FR9JkRzUcRgdD1EdrIToY4K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드48.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이를 구현하기 위해서는 mask R-CNN을 이용해야 하는데, 이는 앞서 object detection 파트에서 배운 faster R-CNN과 구조가 매우 흡사하나, 우리가 detect한 object들에 대해 segmentation을 수행하는 &amp;lsquo;mask prediction&amp;rsquo; branch가 추가됐다는 차이점이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드49.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzyAAA/btr1PNSxnaI/4nmyIzTyj8xBOg4CAoJM30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzyAAA/btr1PNSxnaI/4nmyIzTyj8xBOg4CAoJM30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzyAAA/btr1PNSxnaI/4nmyIzTyj8xBOg4CAoJM30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzyAAA%2Fbtr1PNSxnaI%2F4nmyIzTyj8xBOg4CAoJM30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드49.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;mask R-CNN은 faster R-CNN과 비슷한 구조를 가진 만큼 동작 과정도 유사하다. image level features를 얻기 위해 input image를 backbone CNN에 집어넣는다는 점, region proposal network를 통과한다는 점, 각 region proposal에 대해 feature map을 얻기 위해 RoI Align을 수행한다는 점은 object detection 과정과 동일하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이후 segmentation mask를 예측하기 위해 앞서 과정을 통해 detect한 object에 대해 semantic segmentation network를 수행하게 되는데, 이것도 이미 배웠던 내용이다.&amp;nbsp;차이점이라면 전체 input image가 아니라 object detection을 통해 추출한 object에 대해서만 semantic segmentation을 수행한다는 것이 다를 뿐, 지금까지 배운 object detection과 semantic segmentation의 조합이라고 보면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드50.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dCiTU1/btr1znnyF4q/PVCsxyvKTz87pKOfmXLs80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dCiTU1/btr1znnyF4q/PVCsxyvKTz87pKOfmXLs80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dCiTU1/btr1znnyF4q/PVCsxyvKTz87pKOfmXLs80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdCiTU1%2Fbtr1znnyF4q%2FPVCsxyvKTz87pKOfmXLs80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드50.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;아래 그림의 예시들은 segmentation mask의 training target이 bounding box에 따라 달라지는 것을 볼 수 있도록 해주는데,&amp;nbsp;bounding box가 의자 크기에 딱 맞게 생성됐을 때는 위와 같은 형태로, 조금 더 여백을 두고 생성됐을 때는 아래와 같은 형태로 segmentation이 이루어진다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드51.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RKKsM/btr1MoZMwks/7wxIIbXkKqeRGv43fcdl1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RKKsM/btr1MoZMwks/7wxIIbXkKqeRGv43fcdl1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RKKsM/btr1MoZMwks/7wxIIbXkKqeRGv43fcdl1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRKKsM%2Fbtr1MoZMwks%2F7wxIIbXkKqeRGv43fcdl1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드51.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;segmentation 결과는 object의 카테고리 라벨에 따라서도 달라지는데, segmentation을 하고자 하는 object를 소파로 잡았을 때는 위와 같은 형태로, object를 사람으로 잡았을 때는 아래와 같은 형태로 segmentation이 이루어진다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드52.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bai4GH/btr1MjqwcNg/L43SXLkYst25VqPnD9XKo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bai4GH/btr1MjqwcNg/L43SXLkYst25VqPnD9XKo1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bai4GH/btr1MjqwcNg/L43SXLkYst25VqPnD9XKo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbai4GH%2Fbtr1MjqwcNg%2FL43SXLkYst25VqPnD9XKo1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드52.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;mask R-CNN을 사용했을 때 instance segmentation 결과가 매우 좋은 것을 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드53.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b78tld/btr1Kv5PUDZ/WlMdG7IUxDnqn5O6hlGJ90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b78tld/btr1Kv5PUDZ/WlMdG7IUxDnqn5O6hlGJ90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b78tld/btr1Kv5PUDZ/WlMdG7IUxDnqn5O6hlGJ90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb78tld%2Fbtr1Kv5PUDZ%2FWlMdG7IUxDnqn5O6hlGJ90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드53.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. Beyond Instance Segmentation&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1) Panoptic Segmentation&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;여기서부터는 좀 더 발전된 형태의 segmentation task를 가볍게 소개하는 시간이니 편하게 보면 될 것 같다. semantic segmentation과 instance segmentation을 합친, things와 stuff 모두에 대해서 labeling을 해주면서 각각의 instance를 구분까지 할 수 있는 panoptic segmentation도 존재하는데,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드54.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHyqiB/btr1Utzfsnl/96ihpvrVpnmYLIaVI1mD40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHyqiB/btr1Utzfsnl/96ihpvrVpnmYLIaVI1mD40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHyqiB/btr1Utzfsnl/96ihpvrVpnmYLIaVI1mD40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHyqiB%2Fbtr1Utzfsnl%2F96ihpvrVpnmYLIaVI1mD40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드54.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이 또한 매우 좋은 성능을 내고 있다고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드55.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pVxT8/btr1PM7c6bi/48qPpe0UrGtmslEWHoWHmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pVxT8/btr1PM7c6bi/48qPpe0UrGtmslEWHoWHmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pVxT8/btr1PM7c6bi/48qPpe0UrGtmslEWHoWHmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpVxT8%2Fbtr1PM7c6bi%2F48qPpe0UrGtmslEWHoWHmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드55.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2) Human Keypoints&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;특히 사람에 대해서 segmentation을 하는 것에서 더 나아가, 그들의 포즈를 보다 디테일하게 분석하려는 시도도 존재하는데, 이를 위한 방법론 중 하나가 key point estimation이다. 눈, 귀, 코, 관절 등을 key point로 하여 각각의 위치를 예측하는 방식이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드56.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D7p21/btr1UuEWoaR/Huphve1S0RGyOdwGklrQtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D7p21/btr1UuEWoaR/Huphve1S0RGyOdwGklrQtk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D7p21/btr1UuEWoaR/Huphve1S0RGyOdwGklrQtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD7p21%2Fbtr1UuEWoaR%2FHuphve1S0RGyOdwGklrQtk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드56.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;keypoint estimation에도 mask R-CNN이 좋은 성능을 발휘한다. instance segmentation을 위해서 faster R-CNN에 mask prediction을 더해 mask R-CNN을 만들었던 것처럼, mask R-CNN을 keypoint estimation 작업에 활용하기 위해서는 keypoint prediction을 추가해야 한다. 모델의 동작 방식은 mask R-CNN과 동일하나, 딱 한 가지, semantic segmentation mask 대신 k개의 keypoints에 대한 keypoint mask를 활용한다는 차이점이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드57.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pmyxC/btr1T7bZr3C/Alp3X8WtSv9pLqNvtjOmfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pmyxC/btr1T7bZr3C/Alp3X8WtSv9pLqNvtjOmfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pmyxC/btr1T7bZr3C/Alp3X8WtSv9pLqNvtjOmfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpmyxC%2Fbtr1T7bZr3C%2FAlp3X8WtSv9pLqNvtjOmfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드57.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이 task에 대해서도 굉장히 좋은 성능을 내고 있는 것을 볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드58.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IFj21/btr1URfDnzk/pZao9DnEZ03AEpvREF4nNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IFj21/btr1URfDnzk/pZao9DnEZ03AEpvREF4nNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IFj21/btr1URfDnzk/pZao9DnEZ03AEpvREF4nNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIFj21%2Fbtr1URfDnzk%2FpZao9DnEZ03AEpvREF4nNk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드58.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3) Dense Captioning&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그밖에도, faster R-CNN의 뼈대에 caption prediction을 위한 LSTM 모델(자연어 처리-NLP- 분야의 모델_을 더해서 detect한 object에 대해 자연어로 설명을 덧붙일 수 있는 연구도 진행되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드59.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFKXTL/btr1MnmlngN/C2mjjMKpLXCoEjKghfQCk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFKXTL/btr1MnmlngN/C2mjjMKpLXCoEjKghfQCk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFKXTL/btr1MnmlngN/C2mjjMKpLXCoEjKghfQCk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFKXTL%2Fbtr1MnmlngN%2FC2mjjMKpLXCoEjKghfQCk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드59.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4) 3D Shape Prediction&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;또한, mask R-CNN에 mesh head를 결합함으로써 2D image로부터 3D shapes를 생성해내는 기술도 개발되었다고 하는데, 이에 대해서는 다음 강의에서 자세히 다룰 예정이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드60.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqDeLQ/btr1Mkpq2uG/L3rx2xrkjkGbBd8sE0plJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqDeLQ/btr1Mkpq2uG/L3rx2xrkjkGbBd8sE0plJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqDeLQ/btr1Mkpq2uG/L3rx2xrkjkGbBd8sE0plJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqDeLQ%2Fbtr1Mkpq2uG%2FL3rx2xrkjkGbBd8sE0plJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드60.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5) General Idea&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;지금까지 설명을 들으면서 감이 왔겠지만, computer vision의 많은 task들은 이처럼 faster R-CNN이나 mask R-CNN에, 새로운 종류의 output을 낼 수 있도록 특화된 추가적인 &amp;lsquo;head&amp;rsquo;를 붙임으로써 수행할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드61.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckmhWK/btr1JagBnf0/AfQMHdizuRx5K9i4iAVvxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckmhWK/btr1JagBnf0/AfQMHdizuRx5K9i4iAVvxK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckmhWK/btr1JagBnf0/AfQMHdizuRx5K9i4iAVvxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckmhWK%2Fbtr1JagBnf0%2FAfQMHdizuRx5K9i4iAVvxK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드61.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>놀라운 Deep Learning/Deep Learning for Computer Vision</category>
      <category>computer vision</category>
      <category>cv</category>
      <category>EECS 498-007/598-005</category>
      <category>human keypoints</category>
      <category>Instance Segmentation</category>
      <category>Panoptic segmentation</category>
      <author>ydduri</author>
      <guid isPermaLink="true">https://ydduri.tistory.com/35</guid>
      <comments>https://ydduri.tistory.com/35#entry35comment</comments>
      <pubDate>Fri, 3 Mar 2023 15:03:27 +0900</pubDate>
    </item>
    <item>
      <title>[EECS 498-007/598-005] 16강. Detection and Segmentation(2)</title>
      <link>https://ydduri.tistory.com/34</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Segmentation: Semantic Segmentation&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Segmentation에는 여러 종류가 있는데, 첫 번째로 semantic segmentation을 보겠다. 이는 이미지의 각각의 픽셀에 카테고리 label을 붙이는 것이다. Instance를 구분하는 것이 아니라 오직 픽셀에만 집중하기 때문에, 오른쪽 그림에서처럼 두 마리의 소가 붙어 있더라도 이를 소 1, 소 2로 구분하는 것이 아니라 &amp;lsquo;소&amp;rsquo;라는 하나의 카테고리 라벨로 통칭한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드25.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YsNlZ/btr0IuHorx6/YDy1IwKLHltzwqgLXKuuHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YsNlZ/btr0IuHorx6/YDy1IwKLHltzwqgLXKuuHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YsNlZ/btr0IuHorx6/YDy1IwKLHltzwqgLXKuuHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYsNlZ%2Fbtr0IuHorx6%2FYDy1IwKLHltzwqgLXKuuHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드25.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1) Sliding Window&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;강연자께서 semantic segmentation task를 해결하는 &amp;lsquo;멍청한&amp;rsquo; 아이디어라고 소개한 내용인데, 바로 sliding window다. 이는 이미지의 각 픽셀에 대해 그 주변부를 포함한 작은 patch를 추출하고, 그 patch들 각각을 CNN에 넣어서 라벨링을 하는 방식이다. 이걸 모든 픽셀에 대해서 계속해서 반복한다고 생각하면&amp;hellip; 생각만 해도 아찔하다.&amp;nbsp;워낙 느리고 매우 비효율적인 방법이라 잘 사용하지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드26.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AsX5a/btr02AFT7jG/WOeoJ8NbKkKIciCLFR1Zf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AsX5a/btr02AFT7jG/WOeoJ8NbKkKIciCLFR1Zf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AsX5a/btr02AFT7jG/WOeoJ8NbKkKIciCLFR1Zf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAsX5a%2Fbtr02AFT7jG%2FWOeoJ8NbKkKIciCLFR1Zf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드26.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2) Fully Convolutional Network&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;대신에 더 보편적으로 쓰이는 방법은 fully convolutional network라 불리는 CNN architecture를 활용하는 것이다. 이는 fully connected layer나 global pooling layer가 없는, &lt;b&gt;convolution layer의 &amp;lsquo;big stack&amp;rsquo;&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;해당 신경망을 통과하고 난 &lt;b&gt;output은 각각의 픽셀에 대한 class scores 정보&lt;/b&gt;를 가지게 된다. 예를 들어 사이즈 3*3, padding=1, stride=1의 convolution layer를 쌓으면, output은 input과 같은 size를 가지게 되며, 채널의 개수는 우리가 구분하고자 하는 카테고리의 개수와 같아지게 된다. &lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;output인 score layer는 말그대로 각 픽셀마다의 카테고리 label score를 가지게 되며, 우리는 softmax를 이용해 확률값을 반환함으로써 각 픽셀에 대한 label을 판단할 수 있다. 해당 모델은 픽셀 별 cross entropy loss를 구함으로써 train 시킬 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드27.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBuotK/btr0JNzZjUR/oC04T2flKpk7UWZySE198k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBuotK/btr0JNzZjUR/oC04T2flKpk7UWZySE198k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBuotK/btr0JNzZjUR/oC04T2flKpk7UWZySE198k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBuotK%2Fbtr0JNzZjUR%2FoC04T2flKpk7UWZySE198k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드27.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그런데 이 방식에는 두 가지 문제점이 있다. 첫 번째는 사이즈 3*3, padding=1, stride=1인 convolution layer를 계속해서 쌓기 때문에 receptive field의 크기가 convolution layer 개수에 따라 linearly하게 증가한다는 점이다. L개의 layer를 쌓으면 receptive field의 개수는 1+2L 만큼 증가한다고 한다. 두 번째는 고해상도 이미지에서 convolution이 비싸다는 것이다. 그래서 필요한 것이 바로 &amp;lsquo;downsampling&amp;rsquo;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드28.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AsG39/btr0JB0Cffh/PXlUQkcaLC9kpWpO61aIxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AsG39/btr0JB0Cffh/PXlUQkcaLC9kpWpO61aIxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AsG39/btr0JB0Cffh/PXlUQkcaLC9kpWpO61aIxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAsG39%2Fbtr0JB0Cffh%2FPXlUQkcaLC9kpWpO61aIxk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드28.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그런데 downsampling을 하더라도, 결과물은 input 이미지와 동일한 해상도로 나와야 할 것이기 때문에 다시 upsampling을 해주어야 한다. downsampling은 pooling이나 stride 조절을 통해 할 수 있다는 걸 알고 있는데, upsampling은 어떻게 할까? 지금부터 upsampling의 방법에 대해 다루겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드29.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eh76Wr/btr0VKa4Hkk/8QLxoM6JuBTfK5U03tic91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eh76Wr/btr0VKa4Hkk/8QLxoM6JuBTfK5U03tic91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eh76Wr/btr0VKa4Hkk/8QLxoM6JuBTfK5U03tic91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Feh76Wr%2Fbtr0VKa4Hkk%2F8QLxoM6JuBTfK5U03tic91%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드29.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;3) Upsampling&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;(1) In-Network Upsampling: &quot;Unpooling&quot;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;앞서 언급했듯이 pooling이 downsampling을 수행하게 해주는 방법이었으므로, upsampling을 수행하려면 그 반대인 &amp;lsquo;unpooling&amp;rsquo;을 하면 된다. unpooling을 하는 방법 첫 번째는 &amp;lsquo;bed of nails&amp;rsquo;라는 방식인데, 아래 그림과 같은 방식으로 왼쪽 위에 input feature들을 넣고, 사이즈를 키우면서 생긴 나머지 칸을 모두 0으로 채우는 방법이다. 딱 봐도 감이 올 테지만 그리 좋지 못한 방법이라 자주 사용하진 않는다고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;좀 더 보편적으로 사용되는 다른 unpooling 기법은 nearest neighbor로, 아래 그림과 같이 input feature 값을 복사하여 확대된 칸을 채우는 방식이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드30.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/talMS/btr0HzJchzG/YGAMd3bXtb7Erek61lu7f1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/talMS/btr0HzJchzG/YGAMd3bXtb7Erek61lu7f1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/talMS/btr0HzJchzG/YGAMd3bXtb7Erek61lu7f1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtalMS%2Fbtr0HzJchzG%2FYGAMd3bXtb7Erek61lu7f1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드30.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;(2) In-Network Upsampling: Bilinear Interpolation&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;또다른 방법은 아까 RoI Align 할 때 사용했던 쌍선형 보간법을 이용하는 것이다. 아래 그림에서 옅은 하늘색 점으로 표시된 것이 sample point이고, 보간 과정은 앞서 자세히 설명했기 때문에 생략하도록 하겠다. 그 결과로 나오는 upsampling output이 nearest neighbor에 비해 스무스하다는 특징이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드31.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLRmFS/btr1PODidso/XlD5n2Wn9kuWdlqN2ixpB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLRmFS/btr1PODidso/XlD5n2Wn9kuWdlqN2ixpB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLRmFS/btr1PODidso/XlD5n2Wn9kuWdlqN2ixpB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLRmFS%2Fbtr1PODidso%2FXlD5n2Wn9kuWdlqN2ixpB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드31.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;다른 종류의 interpolation을 이용하는 방법도 있다. 바로 bicubic interpolation인데, bilinear는 x, y 방향으로 각각 2칸씩 고려했다면, bicubic은 3칸씩 고려하는 방식이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;16. Detection and Segmentation_박서연.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bg2XE8/btr1ILt2rAY/Y8buaIPfS8gfuIK5fuUK21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bg2XE8/btr1ILt2rAY/Y8buaIPfS8gfuIK5fuUK21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bg2XE8/btr1ILt2rAY/Y8buaIPfS8gfuIK5fuUK21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbg2XE8%2Fbtr1ILt2rAY%2FY8buaIPfS8gfuIK5fuUK21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;16. Detection and Segmentation_박서연.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;강의에서는 bicubic interpolation에 대해 자세히 다루지는 않았는데, JPEG 이미지를 resizing하는 데 좋다는 것을 포함해 여러 장점이 있어 가장 보편적으로 사용되는 upsamling 방식이라고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드33.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dQdLYh/btr1yAGXkld/e5KxCc1CloG6oL29PmXQ60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dQdLYh/btr1yAGXkld/e5KxCc1CloG6oL29PmXQ60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dQdLYh/btr1yAGXkld/e5KxCc1CloG6oL29PmXQ60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdQdLYh%2Fbtr1yAGXkld%2Fe5KxCc1CloG6oL29PmXQ60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드33.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;(3) In-Network Upsampling: Max Unpooling&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;max pooling으로 downsampling이 가능할 경우에 적용할 수 있는 max unpooling이라는 기법도 있다. max unpooling의 특징은 max pooling을 수행할 때 각각의 구역별로 최댓값이 나타나는 위치를 기억한다는 것이다. 그 뒤로는 아래 그림에서 보이는 예시처럼 bed of nails 방식이나 bilinear 등 앞서 살펴봤던 방식을 적용해서 upsampling을 수행하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;network에서 먼저 수행된 max pooling과 대응되기 때문에 downsampling 전과 upsampling 후의 misalignment를 방지할 수 있다는 장점이 있다. 경험적으로 봤을 때, pooling을 할 때 max pooling을 이용했다면 이와 같은 max unpooling을 사용하는 것이 좋고, average pooling 등 다른 pooling 방법을 사용했다면 앞에서 소개했던 다른 방식을 적용해도 무방하다고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드34.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byBlQ2/btr1Uux3D9W/KZnZAWzYMg7iCdBdlSuBlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byBlQ2/btr1Uux3D9W/KZnZAWzYMg7iCdBdlSuBlK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byBlQ2/btr1Uux3D9W/KZnZAWzYMg7iCdBdlSuBlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyBlQ2%2Fbtr1Uux3D9W%2FKZnZAWzYMg7iCdBdlSuBlK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드34.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;(4) Learnable Upsampling: Transposed Convolution&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;지금까지 살펴본 upsampling 방식은 fixed function으로, 학습시켜야 할 파라미터가 없었는데,&amp;nbsp;&amp;lsquo;transposed convolution&amp;rsquo;이라 불리는 learnable upsampling 방법도 존재한다. 그림에서 볼 수 있듯이 stride의 크기가 1 이상이라면 learnable downsampling을 할 수 있다.&amp;nbsp;그렇다면 stride 크기를 1보다 작게 하면 learnable upsampling을 할 수 있지 않을까? 해서 등장한 것이 바로 transposed convolution이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드35.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dKlfd6/btr1QxoqptI/On4mkA5V8aAgYipLUx8Wrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dKlfd6/btr1QxoqptI/On4mkA5V8aAgYipLUx8Wrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dKlfd6/btr1QxoqptI/On4mkA5V8aAgYipLUx8Wrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdKlfd6%2Fbtr1QxoqptI%2FOn4mkA5V8aAgYipLUx8Wrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드35.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;transposed convolution을 시각적으로 이해해보자. transposed convolution의 목표는 input보다 output의 크기를 키우는 것이므로, input feature들을 필터에 곱해서 더 큰 output으로 확장시켜야&amp;nbsp;한다. 아래 그림과 같은 filter와 input이 있을 때, input과 filter의 해당 부분을 곱해서 이런 방식으로 output의 각 칸을 채워 나가는 과정이 transposed convolution이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드36.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1AXn1/btr1UTRZRop/GcJTI5Zzfso4D95Pewpcw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1AXn1/btr1UTRZRop/GcJTI5Zzfso4D95Pewpcw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1AXn1/btr1UTRZRop/GcJTI5Zzfso4D95Pewpcw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1AXn1%2Fbtr1UTRZRop%2FGcJTI5Zzfso4D95Pewpcw1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드36.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;한 번 더 예시를 들면 다음과 같다. 그런데 이런 식으로 연산을 계속하다 보면 필터가 서로 겹치는 칸이 생기기 마련인데 어떻게 할까?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드37.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KJOGo/btr1ILVIJca/yAKtq3PYApA8QToRhkqB1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KJOGo/btr1ILVIJca/yAKtq3PYApA8QToRhkqB1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KJOGo/btr1ILVIJca/yAKtq3PYApA8QToRhkqB1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKJOGo%2Fbtr1ILVIJca%2FyAKtq3PYApA8QToRhkqB1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드37.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그럴 경우 아래 그림에서와 같이 각각의 연산 결과를 더해서 최종 output을 구한다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드38.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9Zykf/btr1T6xjK7D/GVGW3rqhnymTWRQdbUmjy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9Zykf/btr1T6xjK7D/GVGW3rqhnymTWRQdbUmjy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9Zykf/btr1T6xjK7D/GVGW3rqhnymTWRQdbUmjy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9Zykf%2Fbtr1T6xjK7D%2FGVGW3rqhnymTWRQdbUmjy0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드38.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이런 방식으로 모든 칸에 대해서 연산을 수행한 결과는 아래 그림과 같이 표현할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드39.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXk32s/btr1USyM5tu/z0Zd24QKKgNr18elcwsxK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXk32s/btr1USyM5tu/z0Zd24QKKgNr18elcwsxK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXk32s/btr1USyM5tu/z0Zd24QKKgNr18elcwsxK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXk32s%2Fbtr1USyM5tu%2Fz0Zd24QKKgNr18elcwsxK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드39.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;1차원으로 예시를 들어 보면 아래 그림과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드40.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MMKjb/btr1PORppUC/mbsjLAPhNmxCDyQAH7kUfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MMKjb/btr1PORppUC/mbsjLAPhNmxCDyQAH7kUfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MMKjb/btr1PORppUC/mbsjLAPhNmxCDyQAH7kUfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMMKjb%2Fbtr1PORppUC%2FmbsjLAPhNmxCDyQAH7kUfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드40.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이 연산에 &amp;lsquo;transposed&amp;rsquo; convolution이라는 이름이 붙게 된 이유는 convolution 연산을 matrix multiplication으로 나타내면 쉽게 알 수 있다. 이 슬라이드는 x y z로 구성된 길이가 3인 벡터 x와 a b c d로 구성된 a 사이의 convolution을 나타낸 것이다. 이때 x는 필터, a는 input에 해당하고, 벡터 a의 위아래에 있는 0은 zero padding을 의미한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드41.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kAGT1/btr1EfvT1np/7hertFKwvKNvgwrpdKOOd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kAGT1/btr1EfvT1np/7hertFKwvKNvgwrpdKOOd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kAGT1/btr1EfvT1np/7hertFKwvKNvgwrpdKOOd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkAGT1%2Fbtr1EfvT1np%2F7hertFKwvKNvgwrpdKOOd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드41.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;우리가 살펴보고자 하는 transposed convolution은 벡터 x를 transpose한 상태로 convolution을 수행하는 것을 말한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드42.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bf7Mny/btr1T5rDXu2/yIhY3kyC7kt8feXKtcYweK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bf7Mny/btr1T5rDXu2/yIhY3kyC7kt8feXKtcYweK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bf7Mny/btr1T5rDXu2/yIhY3kyC7kt8feXKtcYweK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbf7Mny%2Fbtr1T5rDXu2%2FyIhY3kyC7kt8feXKtcYweK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드42.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(사실 이 부분은 강의를 들으면서 아리까리했는데, 우선은 내가 이해한 대로 써보겠다...)&lt;/span&gt; stride가 1인 경우 normal convolution과 transposed convolution을 비교해보면, padding 규칙이 약간 달라졌을 뿐, 둘 다 convolution 연산을 수행하고 있음을 확인할 수 있다. transposed convolution과 normal convolution은 수학적으로 동일한 연산이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드43.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sBk5U/btr1Kwp6Ge4/GKFqK7dkQKy3cBzfXuAUzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sBk5U/btr1Kwp6Ge4/GKFqK7dkQKy3cBzfXuAUzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sBk5U/btr1Kwp6Ge4/GKFqK7dkQKy3cBzfXuAUzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsBk5U%2Fbtr1Kwp6Ge4%2FGKFqK7dkQKy3cBzfXuAUzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드43.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그런데 stride가 1보다 커질 경우 상황이 좀 달라진다.&amp;nbsp;stride가 1일 때의 normal convolution과 transposed convolution은 padding이 있냐 없냐의 차이였는데, 여기서는 아예 input 행렬의 형태 자체가 다르다. 따라서 이때의 transposed convolution은 normal convolution으로 바꿔서 나타내는 것이 불가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;종종 transposed convolution을 deconvolution이라 부르는 경우가 있는데, deconvolution은 convolution의 역과정이라는 의미인데, 방금 보았듯이 stride가 2 이상이 되면 transposed convolution은 normal convolution과 완전히 다른 연산이 되므로, 역과정이라는 것이 성립하지 않는다. 그렇기 때문에 deconvolution은 틀린 용어라고 보면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드44.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/snwb3/btr1KQCebLx/cHkBSoqjUgGiBt5E5CoRG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/snwb3/btr1KQCebLx/cHkBSoqjUgGiBt5E5CoRG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/snwb3/btr1KQCebLx/cHkBSoqjUgGiBt5E5CoRG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsnwb3%2Fbtr1KQCebLx%2FcHkBSoqjUgGiBt5E5CoRG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드44.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;방금까지 본 upscaling 연산은 semantic segmentation의 과정 중에 수행되는 것으로, 앞서 다룬 interpolation, transposed convolution 등 여러 종류 중 적절한 것을 택해서 사용하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드45.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Jqs1H/btr1Jsn5hp0/gSa1igCKtsJgASwQnuewSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Jqs1H/btr1Jsn5hp0/gSa1igCKtsJgASwQnuewSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Jqs1H/btr1Jsn5hp0/gSa1igCKtsJgASwQnuewSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJqs1H%2Fbtr1Jsn5hp0%2FgSa1igCKtsJgASwQnuewSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-filename=&quot;슬라이드45.PNG&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후로는 Instance Segmentation 등 새로운 내용이 등장하기 때문에 강의의 남은 부분은 다음 글에서 마저 정리하도록 하겠다.&lt;/p&gt;</description>
      <category>놀라운 Deep Learning/Deep Learning for Computer Vision</category>
      <category>computer vision</category>
      <category>cv</category>
      <category>EECS 498-007/598-005</category>
      <category>Fully convolutional network</category>
      <category>Semantic Segmentation</category>
      <category>Transposed Convolution</category>
      <category>Upsampling</category>
      <author>ydduri</author>
      <guid isPermaLink="true">https://ydduri.tistory.com/34</guid>
      <comments>https://ydduri.tistory.com/34#entry34comment</comments>
      <pubDate>Fri, 3 Mar 2023 14:38:27 +0900</pubDate>
    </item>
  </channel>
</rss>