<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>Maybe</title>
<link>https://operatingsystems.tistory.com/</link>
<description></description>
<language>ko</language>
<pubDate>Sat, 13 Jun 2020 23:30:30 +0900</pubDate>
<generator>TISTORY</generator>
<ttl>100</ttl>
<managingEditor>빛나유</managingEditor>
<image>
<title>Maybe</title>
<url>http://cfile8.uf.tistory.com/image/265E143950CC906E084FF7</url>
<link>https://operatingsystems.tistory.com</link>
<description></description>
</image>
<item>
<title>[Deep Learning] 논문 리뷰: Universal Language Fine-Tuning</title>
<link>https://operatingsystems.tistory.com/entry/Deep-Learning-%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Universal-Language-Fine-Tuning</link>
<description>&lt;p&gt;최근에&amp;nbsp;읽은&amp;nbsp;논문&amp;nbsp;하나&amp;nbsp;요약해보려고&amp;nbsp;한다.&amp;nbsp;바로&amp;nbsp;Universial&amp;nbsp;Language&amp;nbsp;Model&amp;nbsp;Fine-Tuning,&amp;nbsp;ULMFiT이다.&amp;nbsp;우선,&amp;nbsp;논문을&amp;nbsp;단&amp;nbsp;한&amp;nbsp;줄로&amp;nbsp;요약하자면, &lt;br /&gt;&lt;br /&gt;&quot;어떤&amp;nbsp;NLP&amp;nbsp;테스크&amp;nbsp;A를&amp;nbsp;수행할&amp;nbsp;때,&amp;nbsp;그것을&amp;nbsp;처음부터&amp;nbsp;학습하지&amp;nbsp;말고,&amp;nbsp;언어의&amp;nbsp;속성을&amp;nbsp;학습해둔&amp;nbsp;language&amp;nbsp;model&amp;nbsp;L을&amp;nbsp;먼저&amp;nbsp;학습&amp;nbsp;후,&amp;nbsp;그것을&amp;nbsp;가지고&amp;nbsp;A&amp;nbsp;테스크를&amp;nbsp;진행하면&amp;nbsp;훨씬&amp;nbsp;더&amp;nbsp;적은&amp;nbsp;데이터로&amp;nbsp;state-of-art&amp;nbsp;수준&amp;nbsp;이상의&amp;nbsp;결과를&amp;nbsp;빠르게&amp;nbsp;얻을&amp;nbsp;수&amp;nbsp;있다.&quot; &lt;br /&gt;&lt;br /&gt;아이고,&amp;nbsp;어렵다.&amp;nbsp;본격적으로&amp;nbsp;설명을&amp;nbsp;하기&amp;nbsp;전에&amp;nbsp;조금&amp;nbsp;만&amp;nbsp;더&amp;nbsp;풀어서&amp;nbsp;설명해보자. &lt;br /&gt;&lt;br /&gt;예를&amp;nbsp;들어,&amp;nbsp;어떤&amp;nbsp;영화의&amp;nbsp;리뷰가&amp;nbsp;긍정적인&amp;nbsp;리뷰인지&amp;nbsp;부정적인&amp;nbsp;리뷰인지를&amp;nbsp;1&amp;nbsp;또는&amp;nbsp;0으로&amp;nbsp;구분하는&amp;nbsp;모델을&amp;nbsp;만든다고&amp;nbsp;하자.&amp;nbsp;일반적으로&amp;nbsp;이것을&amp;nbsp;하기&amp;nbsp;위해&amp;nbsp;영화&amp;nbsp;리뷰&amp;nbsp;데이터&amp;nbsp;모아서&amp;nbsp;전처리하고&amp;nbsp;전처리된&amp;nbsp;것을&amp;nbsp;모델에&amp;nbsp;입력하는데,&amp;nbsp;이&amp;nbsp;모델은&amp;nbsp;조금도&amp;nbsp;학습되어&amp;nbsp;있지&amp;nbsp;않은&amp;nbsp;Scratch에서부터&amp;nbsp;시작한다.&amp;nbsp;즉,&amp;nbsp;각&amp;nbsp;레이어에서&amp;nbsp;사용되는&amp;nbsp;weight들이&amp;nbsp;랜덤으로&amp;nbsp;초기화된&amp;nbsp;상태에서&amp;nbsp;시작하게&amp;nbsp;된다.&amp;nbsp;이렇게&amp;nbsp;하는&amp;nbsp;것보다&amp;nbsp;더&amp;nbsp;좋은&amp;nbsp;방법이&amp;nbsp;있다는&amp;nbsp;것을&amp;nbsp;알려주기&amp;nbsp;위한&amp;nbsp;논문이&amp;nbsp;바로&amp;nbsp;ULMFit이다. &lt;br /&gt;그래서&amp;nbsp;어떻게&amp;nbsp;하느냐?&amp;nbsp;우선&amp;nbsp;무턱대고&amp;nbsp;영화&amp;nbsp;리뷰&amp;nbsp;데이터를&amp;nbsp;가져오지&amp;nbsp;말고,&amp;nbsp;여러가지&amp;nbsp;텍스트&amp;nbsp;데이터를&amp;nbsp;끓어와라!!&amp;nbsp;자연어라면&amp;nbsp;끓어와라!!&amp;nbsp;자연어&amp;nbsp;데이터라고&amp;nbsp;하면,&amp;nbsp;이메일&amp;nbsp;데이터일&amp;nbsp;수도&amp;nbsp;있을&amp;nbsp;것이고,&amp;nbsp;뉴스&amp;nbsp;데이터일&amp;nbsp;수도&amp;nbsp;있을&amp;nbsp;것이고,&amp;nbsp;소설&amp;nbsp;데이터일&amp;nbsp;수도&amp;nbsp;있을&amp;nbsp;것이다.&amp;nbsp;아무튼&amp;nbsp;자연어&amp;nbsp;데이터를&amp;nbsp;가져와라.&amp;nbsp;이&amp;nbsp;데이터는&amp;nbsp;레이블링도&amp;nbsp;필요&amp;nbsp;없다.&amp;nbsp;Language&amp;nbsp;Model은&amp;nbsp;주어진&amp;nbsp;단어들&amp;nbsp;이후에&amp;nbsp;그&amp;nbsp;다음&amp;nbsp;단어가&amp;nbsp;어떤&amp;nbsp;단어가&amp;nbsp;나오는지를&amp;nbsp;학습하는&amp;nbsp;유형의&amp;nbsp;모델이기&amp;nbsp;때문에&amp;nbsp;0,&amp;nbsp;1의&amp;nbsp;레이블링은&amp;nbsp;필요&amp;nbsp;없다.&amp;nbsp;아직&amp;nbsp;어떻게&amp;nbsp;만드는지는&amp;nbsp;설명하지&amp;nbsp;않지만,&amp;nbsp;어쨌든&amp;nbsp;이렇게&amp;nbsp;가지고&amp;nbsp;온&amp;nbsp;자연어&amp;nbsp;데이터를&amp;nbsp;이용해서&amp;nbsp;Language&amp;nbsp;Model을&amp;nbsp;우선&amp;nbsp;만들어&amp;nbsp;놔라(pre-train해라) &lt;br /&gt;Language&amp;nbsp;Model을&amp;nbsp;만든&amp;nbsp;후,&amp;nbsp;그&amp;nbsp;학습된&amp;nbsp;모델을&amp;nbsp;그대로&amp;nbsp;로딩해서,&amp;nbsp;그&amp;nbsp;다음부터&amp;nbsp;영화&amp;nbsp;리뷰&amp;nbsp;데이터를&amp;nbsp;이용해서&amp;nbsp;Language&amp;nbsp;Model을&amp;nbsp;Tuning하고&amp;nbsp;classifier를&amp;nbsp;학습하라는&amp;nbsp;것이다.&amp;nbsp;즉&amp;nbsp;학습을&amp;nbsp;&quot;from&amp;nbsp;scratch&quot;부터&amp;nbsp;하지&amp;nbsp;말고,&amp;nbsp;&quot;from&amp;nbsp;pre-trained&quot;부터&amp;nbsp;시작하라는&amp;nbsp;것이다.&amp;nbsp;이렇게&amp;nbsp;하면,&amp;nbsp;기본적인&amp;nbsp;언어의&amp;nbsp;속성은&amp;nbsp;이미&amp;nbsp;가지고&amp;nbsp;있는&amp;nbsp;상태에서&amp;nbsp;시작하기&amp;nbsp;때문에&amp;nbsp;만들고자&amp;nbsp;하는&amp;nbsp;'영화&amp;nbsp;리뷰&amp;nbsp;분류'&amp;nbsp;관련된&amp;nbsp;데이터가&amp;nbsp;적더라도&amp;nbsp;학습이&amp;nbsp;오버피팅되지&amp;nbsp;않고&amp;nbsp;잘&amp;nbsp;된다는&amp;nbsp;것이다.&amp;nbsp;그림으로&amp;nbsp;한번&amp;nbsp;보고&amp;nbsp;본격적으로&amp;nbsp;이&amp;nbsp;논문을&amp;nbsp;파보도록&amp;nbsp;하자.&lt;/p&gt;
&lt;p&gt;&lt;figure class='imageblock alignCenter' data-filename=&quot;ULMFiT.png&quot;&gt;&lt;span data-url='https://k.kakaocdn.net/dn/Ga0zE/btqwgBCT8ga/FyXchxNDHMKoOWupjtdllK/img.png' data-lightbox='lightbox' data-alt='ULMFiT overview'&gt;&lt;img src='https://k.kakaocdn.net/dn/Ga0zE/btqwgBCT8ga/FyXchxNDHMKoOWupjtdllK/img.png' srcset='https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fk.kakaocdn.net%2Fdn%2FGa0zE%2FbtqwgBCT8ga%2FFyXchxNDHMKoOWupjtdllK%2Fimg.png' data-filename=&quot;ULMFiT.png&quot;&gt;&lt;/span&gt;&lt;figcaption&gt;ULMFiT overview&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;1.&amp;nbsp;Train&amp;nbsp;Language&amp;nbsp;Model(LM) &lt;br /&gt;LM&amp;nbsp;학습하는&amp;nbsp;것에&amp;nbsp;대해서&amp;nbsp;이야기해보자.&amp;nbsp;사실&amp;nbsp;이&amp;nbsp;논문에서&amp;nbsp;LM의&amp;nbsp;구조를&amp;nbsp;자세히&amp;nbsp;다루지&amp;nbsp;않았다.&amp;nbsp;이들도&amp;nbsp;다른&amp;nbsp;논문에서&amp;nbsp;소개된&amp;nbsp;LM을&amp;nbsp;사용했다고&amp;nbsp;한다. &lt;br /&gt;&lt;br /&gt;&quot;In&amp;nbsp;our&amp;nbsp;experiments,&amp;nbsp;we&amp;nbsp;use&amp;nbsp;the&amp;nbsp;state-of-theart&amp;nbsp;language&amp;nbsp;model&amp;nbsp;AWD-LSTM&amp;nbsp;(Merity&amp;nbsp;et&amp;nbsp;al.,&amp;nbsp;2017a),&amp;nbsp;a&amp;nbsp;regular&amp;nbsp;LSTM&amp;nbsp;(with&amp;nbsp;no&amp;nbsp;attention,&amp;nbsp;short-cut&amp;nbsp;connections,&amp;nbsp;or&amp;nbsp;other&amp;nbsp;sophisticated&amp;nbsp;additions)&amp;nbsp;with&amp;nbsp;various&amp;nbsp;tuned&amp;nbsp;dropout&amp;nbsp;hyperparameters&quot; &lt;br /&gt;&lt;br /&gt;AWD-LSTM이라는&amp;nbsp;state-of-art&amp;nbsp;LM을&amp;nbsp;사용했다고&amp;nbsp;한다.&amp;nbsp;논문에서는&amp;nbsp;이&amp;nbsp;부분을&amp;nbsp;&quot;General-domain&amp;nbsp;LM&amp;nbsp;pretraining&quot;이라는&amp;nbsp;소제목으로&amp;nbsp;설명했는데,&amp;nbsp;여기서&amp;nbsp;기학습된&amp;nbsp;LM을&amp;nbsp;사용하는&amp;nbsp;것에&amp;nbsp;대한&amp;nbsp;실질적인&amp;nbsp;장점을&amp;nbsp;설명하고&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;&quot;Pretraining&amp;nbsp;is&amp;nbsp;most&amp;nbsp;beneﬁcial&amp;nbsp;for&amp;nbsp;tasks&amp;nbsp;with&amp;nbsp;small&amp;nbsp;datasets&amp;nbsp;and&amp;nbsp;enables&amp;nbsp;generalization&amp;nbsp;even&amp;nbsp;with&amp;nbsp;100&amp;nbsp;labeled&amp;nbsp;examples&quot; &lt;br /&gt;&lt;br /&gt;기학습된&amp;nbsp;LM을&amp;nbsp;사용하면&amp;nbsp;레이블링된&amp;nbsp;데이터가&amp;nbsp;100개만&amp;nbsp;있어도&amp;nbsp;generalization&amp;nbsp;즉&amp;nbsp;일반화된&amp;nbsp;모델을&amp;nbsp;만들어낼&amp;nbsp;수&amp;nbsp;있다는&amp;nbsp;것이다.&amp;nbsp;&quot;오버피팅을&amp;nbsp;피할&amp;nbsp;수&amp;nbsp;있다&quot;와&amp;nbsp;같은&amp;nbsp;말이다.&amp;nbsp;이건&amp;nbsp;정말&amp;nbsp;대단하다고&amp;nbsp;생각한다.&amp;nbsp;실무에서&amp;nbsp;겪는&amp;nbsp;가장&amp;nbsp;큰&amp;nbsp;문제점이&amp;nbsp;무엇일까?&amp;nbsp;데이터는&amp;nbsp;많은데&amp;nbsp;실제로&amp;nbsp;레이블링된&amp;nbsp;것이&amp;nbsp;없어서&amp;nbsp;분석가가&amp;nbsp;데이터를&amp;nbsp;한개씩&amp;nbsp;레이블링&amp;nbsp;하거나&amp;nbsp;모델&amp;nbsp;만들기를&amp;nbsp;포기하거나&amp;nbsp;등등&amp;nbsp;좋지&amp;nbsp;않은&amp;nbsp;일이&amp;nbsp;벌어진다.&amp;nbsp;그러지&amp;nbsp;않아도&amp;nbsp;된다는&amp;nbsp;것이다.&amp;nbsp;100개는&amp;nbsp;너무&amp;nbsp;실험치&amp;nbsp;숫자라고&amp;nbsp;쳐도,&amp;nbsp;500~1000개정도는&amp;nbsp;레이블링&amp;nbsp;하는&amp;nbsp;것이&amp;nbsp;크게&amp;nbsp;소모적인&amp;nbsp;일이&amp;nbsp;아니라고&amp;nbsp;생각한다. &lt;br /&gt;&lt;br /&gt;자,&amp;nbsp;그럼&amp;nbsp;LM을&amp;nbsp;학습하는&amp;nbsp;방법은&amp;nbsp;무엇이냐?&amp;nbsp;일반적으로&amp;nbsp;LM을&amp;nbsp;학습시킨다고&amp;nbsp;함은,&amp;nbsp;주어진&amp;nbsp;단어의&amp;nbsp;다음&amp;nbsp;단어를&amp;nbsp;예측하는&amp;nbsp;모델을&amp;nbsp;만든다는&amp;nbsp;것이다.&amp;nbsp;즉,&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&quot;학교&amp;nbsp;종이&amp;nbsp;땡땡땡&amp;nbsp;어서&quot;&amp;nbsp;??? &lt;br /&gt;&lt;br /&gt;???는&amp;nbsp;무엇일까?&amp;nbsp;&quot;모이자&quot;이다.&amp;nbsp;&quot;학교&amp;nbsp;종이&amp;nbsp;땡땡땡&amp;nbsp;어서&quot;라는&amp;nbsp;데이터로부터&amp;nbsp;&quot;모이자&quot;라는&amp;nbsp;타겟을&amp;nbsp;예측하는&amp;nbsp;모델을&amp;nbsp;만드는&amp;nbsp;것이&amp;nbsp;기본적인&amp;nbsp;LM의&amp;nbsp;학습&amp;nbsp;방법이다.&amp;nbsp;Word2Vec등도&amp;nbsp;LM의&amp;nbsp;일부인데,&amp;nbsp;이러한&amp;nbsp;모델도&amp;nbsp;CBOW형태나&amp;nbsp;Skipgram형태&amp;nbsp;모두&amp;nbsp;하나의&amp;nbsp;단어로부터&amp;nbsp;주변&amp;nbsp;단어를&amp;nbsp;예측하는&amp;nbsp;방식의&amp;nbsp;모델이다.&amp;nbsp;복습&amp;nbsp;차원에서&amp;nbsp;살짝&amp;nbsp;정리해보자면, &lt;br /&gt;-&amp;nbsp;CBOW:&amp;nbsp;주변&amp;nbsp;단어로부터&amp;nbsp;하나의&amp;nbsp;단어를&amp;nbsp;예측하는&amp;nbsp;모델 &lt;br /&gt;-&amp;nbsp;Skipgram:&amp;nbsp;하나의&amp;nbsp;단어를&amp;nbsp;통해서&amp;nbsp;주변&amp;nbsp;단어를&amp;nbsp;예측하는&amp;nbsp;모델 &lt;br /&gt;그러하다.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;아무튼&amp;nbsp;LM을&amp;nbsp;학습한다라는&amp;nbsp;뜻은&amp;nbsp;주어진&amp;nbsp;단어들을&amp;nbsp;이용해서&amp;nbsp;다른&amp;nbsp;단어를&amp;nbsp;예측하는&amp;nbsp;것을&amp;nbsp;학습하겠다는&amp;nbsp;의미이다.&amp;nbsp;그것을&amp;nbsp;위한&amp;nbsp;알고리즘으로&amp;nbsp;AWD-LSTM이라는&amp;nbsp;모델을&amp;nbsp;사용해서&amp;nbsp;LM을&amp;nbsp;학습했다는&amp;nbsp;것이다. AWD-LSTM은 다음 논문 리뷰에서 자세하게 다루려고 한다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;2.&amp;nbsp;Target&amp;nbsp;task&amp;nbsp;LM&amp;nbsp;fine-tuning &lt;br /&gt;논문에서는&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;말을&amp;nbsp;시작하고&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;&quot;No&amp;nbsp;matter&amp;nbsp;how&amp;nbsp;diverse&amp;nbsp;the&amp;nbsp;general-domain&amp;nbsp;data&amp;nbsp;used&amp;nbsp;for&amp;nbsp;pretraining&amp;nbsp;is,&amp;nbsp;the&amp;nbsp;data&amp;nbsp;of&amp;nbsp;the&amp;nbsp;target&amp;nbsp;task&amp;nbsp;will&amp;nbsp;likely&amp;nbsp;come&amp;nbsp;from&amp;nbsp;a&amp;nbsp;different&amp;nbsp;distribution&quot; &lt;br /&gt;&lt;br /&gt;아무리&amp;nbsp;기학습에&amp;nbsp;사용된&amp;nbsp;모델이&amp;nbsp;다양하다고&amp;nbsp;한들,&amp;nbsp;우리가&amp;nbsp;최종적으로&amp;nbsp;학습할&amp;nbsp;테스크&amp;nbsp;데이터는&amp;nbsp;완전히&amp;nbsp;다른&amp;nbsp;분포로부터&amp;nbsp;왔다는&amp;nbsp;것이다.&amp;nbsp;그래서&amp;nbsp;어느&amp;nbsp;정도의&amp;nbsp;튜닝이&amp;nbsp;필요하다는&amp;nbsp;것이다.&amp;nbsp;쉽게&amp;nbsp;말해서,&amp;nbsp;아무리&amp;nbsp;벤츠가&amp;nbsp;자동차를&amp;nbsp;잘&amp;nbsp;만든다고&amp;nbsp;한들&amp;nbsp;F1에&amp;nbsp;나가려면&amp;nbsp;약간의&amp;nbsp;튜닝은&amp;nbsp;해야된다.&amp;nbsp;대신&amp;nbsp;시골&amp;nbsp;경운기&amp;nbsp;모터로&amp;nbsp;우여곡절&amp;nbsp;끝에&amp;nbsp;만든&amp;nbsp;자동차를&amp;nbsp;F1용으로&amp;nbsp;튜닝하는&amp;nbsp;것보다는&amp;nbsp;벤츠를&amp;nbsp;가지고&amp;nbsp;F1용으로&amp;nbsp;튜닝하는&amp;nbsp;것이&amp;nbsp;훨씬&amp;nbsp;더&amp;nbsp;빠르고&amp;nbsp;성능도&amp;nbsp;좋지&amp;nbsp;않을까?&amp;nbsp;그런&amp;nbsp;개념이다.&amp;nbsp;그래서&amp;nbsp;target&amp;nbsp;task에&amp;nbsp;대한&amp;nbsp;fine-tuning은&amp;nbsp;어떤&amp;nbsp;방법으로&amp;nbsp;할까?&amp;nbsp;두가지&amp;nbsp;타입이&amp;nbsp;있다.&amp;nbsp;discrimitive&amp;nbsp;fine-tuning과&amp;nbsp;slanted&amp;nbsp;triangular&amp;nbsp;learning&amp;nbsp;rate이다.&amp;nbsp;어려운&amp;nbsp;개념은&amp;nbsp;아니므로&amp;nbsp;아래에&amp;nbsp;살짝&amp;nbsp;정리만&amp;nbsp;해두려고&amp;nbsp;한다. &lt;br /&gt;-&amp;nbsp;discrimitive&amp;nbsp;fine-tuning:&amp;nbsp;AWD-LSTM&amp;nbsp;모델의&amp;nbsp;각&amp;nbsp;LSTM&amp;nbsp;계층마다(layer)&amp;nbsp;서로&amp;nbsp;다른&amp;nbsp;learning&amp;nbsp;rate을&amp;nbsp;적용하는&amp;nbsp;기법이다. &lt;/p&gt;
&lt;p&gt;&lt;figure class='imageblock alignCenter' data-filename=&quot;3.png&quot;&gt;&lt;span data-url='https://k.kakaocdn.net/dn/nqrTB/btqwfj374v6/XwqiRVK6TTCxzNGxEIqg31/img.png' data-lightbox='lightbox' data-alt=''&gt;&lt;img src='https://k.kakaocdn.net/dn/nqrTB/btqwfj374v6/XwqiRVK6TTCxzNGxEIqg31/img.png' srcset='https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fk.kakaocdn.net%2Fdn%2FnqrTB%2Fbtqwfj374v6%2FXwqiRVK6TTCxzNGxEIqg31%2Fimg.png' data-filename=&quot;3.png&quot;&gt;&lt;/span&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;위의 식에서 l은 각각의 레이어이다. 즉, 현재 t의 파라미터 중에서 l번째 파라미터는 t-1에서의 l번째 파라미터에 어떤 숫자를 빼주면 되는데, 그 숫자는 l번째 레이어에 대한 learning rate x 파라미터의 변화량이다.&lt;/p&gt;
&lt;p&gt;-&amp;nbsp;slanted&amp;nbsp;triangular&amp;nbsp;learning&amp;nbsp;rate:&amp;nbsp;모델의&amp;nbsp;learning&amp;nbsp;rate을&amp;nbsp;삼각형&amp;nbsp;모형으로&amp;nbsp;올렸다가&amp;nbsp;내리는&amp;nbsp;것이다.&amp;nbsp;그&amp;nbsp;공식은&amp;nbsp;아래와&amp;nbsp;같다. &lt;/p&gt;
&lt;p&gt;&lt;figure class='imageblock alignCenter' data-filename=&quot;4.png&quot;&gt;&lt;span data-url='https://k.kakaocdn.net/dn/dhnzpV/btqwhhcXQhG/qbY84HXVDRYVCnXxk8IrgK/img.png' data-lightbox='lightbox' data-alt=''&gt;&lt;img src='https://k.kakaocdn.net/dn/dhnzpV/btqwhhcXQhG/qbY84HXVDRYVCnXxk8IrgK/img.png' srcset='https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fk.kakaocdn.net%2Fdn%2FdhnzpV%2FbtqwhhcXQhG%2FqbY84HXVDRYVCnXxk8IrgK%2Fimg.png' data-filename=&quot;4.png&quot;&gt;&lt;/span&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;위의 식에서 사용된 변수는 각각 아래와 같은 의미를 갖는다.&lt;/p&gt;
&lt;p&gt;T: 학습시 iteration 횟수&lt;/p&gt;
&lt;p&gt;cut_frac: (learning rate을 줄이기 시작하는 iteration)/(전체 iteration(T))&lt;/p&gt;
&lt;p&gt;p: learning rate을 증가 혹은 감소시키는 비율&lt;/p&gt;
&lt;p&gt;ratio: 가장 적은 learning rate과 maximum learning rate의(&lt;span style=&quot;color: #333333;&quot;&gt;&amp;eta;max)&lt;/span&gt; 비율&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;eta;t: t번째 iteration에서의 learning rate&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 값들을 아래와 같이 설정해서 사용했다고 한다.&lt;/p&gt;
&lt;p&gt;frac = 0.1&lt;/p&gt;
&lt;p&gt;ratio = 32&lt;/p&gt;
&lt;p&gt;&amp;eta;max = 0.01.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;3.&amp;nbsp;Target&amp;nbsp;task&amp;nbsp;classifier&amp;nbsp;fine-tuning &lt;br /&gt;classifier를&amp;nbsp;fine-tuning하는&amp;nbsp;부분이다.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&quot;Finally,&amp;nbsp;for&amp;nbsp;ﬁne-tuning&amp;nbsp;the&amp;nbsp;classiﬁer,&amp;nbsp;we&amp;nbsp;augment&amp;nbsp;the&amp;nbsp;pretrained&amp;nbsp;language&amp;nbsp;model&amp;nbsp;with&amp;nbsp;two&amp;nbsp;additional&amp;nbsp;linear&amp;nbsp;blocks.&amp;nbsp;Following&amp;nbsp;standard&amp;nbsp;practice&amp;nbsp;for&amp;nbsp;CV&amp;nbsp;classiﬁers,&amp;nbsp;each&amp;nbsp;block&amp;nbsp;uses&amp;nbsp;batch&amp;nbsp;normalization&amp;nbsp;(Ioffe&amp;nbsp;and&amp;nbsp;Szegedy,&amp;nbsp;2015)&amp;nbsp;and&amp;nbsp;dropout,&amp;nbsp;with&amp;nbsp;ReLU&amp;nbsp;activations&amp;nbsp;for&amp;nbsp;the&amp;nbsp;intermediate&amp;nbsp;layer&amp;nbsp;and&amp;nbsp;a&amp;nbsp;softmax&amp;nbsp;activation&amp;nbsp;that&amp;nbsp;outputs&amp;nbsp;a&amp;nbsp;probability&amp;nbsp;distribution&amp;nbsp;over&amp;nbsp;target&amp;nbsp;classes&amp;nbsp;at&amp;nbsp;the&amp;nbsp;last&amp;nbsp;layer.&quot; &lt;br /&gt;&lt;br /&gt;classifier를&amp;nbsp;fine-tuning하기&amp;nbsp;위해서&amp;nbsp;두&amp;nbsp;개의&amp;nbsp;리니어&amp;nbsp;블락을&amp;nbsp;변형?하겠다는(augment)&amp;nbsp;것이다.&amp;nbsp;그&amp;nbsp;구조는&amp;nbsp;다음과&amp;nbsp;같다. &lt;br /&gt;-&amp;nbsp;두번째&amp;nbsp;마지막&amp;nbsp;블록:&amp;nbsp;batch&amp;nbsp;normalization&amp;nbsp;+&amp;nbsp;ReLU&amp;nbsp;activation &lt;br /&gt;-&amp;nbsp;확률&amp;nbsp;값을&amp;nbsp;생성하는&amp;nbsp;마지막&amp;nbsp;블록:&amp;nbsp;dropout&amp;nbsp;+&amp;nbsp;softmax&amp;nbsp;activation &lt;br /&gt;&lt;br /&gt;그리고&amp;nbsp;논문에&amp;nbsp;이렇게&amp;nbsp;나온다. &lt;br /&gt;&lt;br /&gt;&quot;As&amp;nbsp;input&amp;nbsp;documents&amp;nbsp;can&amp;nbsp;consist&amp;nbsp;of&amp;nbsp;hundreds&amp;nbsp;of&amp;nbsp;words,&amp;nbsp;information&amp;nbsp;may&amp;nbsp;get&amp;nbsp;lost&amp;nbsp;if&amp;nbsp;we&amp;nbsp;only&amp;nbsp;consider&amp;nbsp;the&amp;nbsp;last&amp;nbsp;hidden&amp;nbsp;state&amp;nbsp;of&amp;nbsp;the&amp;nbsp;model.&quot;(이부분&amp;nbsp;영어...) &lt;br /&gt;&lt;br /&gt;입력으로&amp;nbsp;들어오는&amp;nbsp;텍스트&amp;nbsp;데이터의&amp;nbsp;단어가&amp;nbsp;매우&amp;nbsp;많기&amp;nbsp;때문에&amp;nbsp;모델의&amp;nbsp;마지막&amp;nbsp;hidden&amp;nbsp;state만&amp;nbsp;고려한다면&amp;nbsp;정보&amp;nbsp;손실이&amp;nbsp;일어날&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;이&amp;nbsp;문제를&amp;nbsp;해결하기&amp;nbsp;위해서&amp;nbsp;이&amp;nbsp;논문에서는&amp;nbsp;h1&amp;nbsp;~&amp;nbsp;hm을&amp;nbsp;meanpool,&amp;nbsp;maxpool한&amp;nbsp;후&amp;nbsp;concatenate했다고&amp;nbsp;한다. &lt;br /&gt;&quot;For&amp;nbsp;this&amp;nbsp;reason,&amp;nbsp;we&amp;nbsp;concatenate&amp;nbsp;the&amp;nbsp;hidden&amp;nbsp;state&amp;nbsp;at&amp;nbsp;the&amp;nbsp;last&amp;nbsp;time&amp;nbsp;step&amp;nbsp;hT&amp;nbsp;ofthedocumentwithboththemax-pooledandthe&amp;nbsp;mean-pooled&amp;nbsp;representation&amp;nbsp;of&amp;nbsp;the&amp;nbsp;hidden&amp;nbsp;states&amp;nbsp;over&amp;nbsp;as&amp;nbsp;many&amp;nbsp;time&amp;nbsp;steps&amp;nbsp;as&amp;nbsp;ﬁt&amp;nbsp;in&amp;nbsp;GPU&amp;nbsp;memory&amp;nbsp;H&amp;nbsp;=&amp;nbsp;{h1,...,hT}:&amp;nbsp;&quot; &lt;br /&gt;[공식] &lt;br /&gt;&lt;br /&gt;이&amp;nbsp;부분이&amp;nbsp;처음부터&amp;nbsp;학습을&amp;nbsp;시작하는(from&amp;nbsp;scratch)&amp;nbsp;유일한&amp;nbsp;layer이다.&amp;nbsp;이&amp;nbsp;부분에서&amp;nbsp;너무&amp;nbsp;공격적으로&amp;nbsp;학습하면&amp;nbsp;모델이&amp;nbsp;전에&amp;nbsp;학습해둔&amp;nbsp;정보를&amp;nbsp;잃게&amp;nbsp;되고(catestrophic&amp;nbsp;forgetting),&amp;nbsp;너무&amp;nbsp;조심스럽게&amp;nbsp;학습하면&amp;nbsp;수렴하는&amp;nbsp;것이&amp;nbsp;늦어진다. &lt;br /&gt;&lt;br /&gt;ULMFiT에&amp;nbsp;대한&amp;nbsp;기술적인&amp;nbsp;내용은&amp;nbsp;여기까지이다.&amp;nbsp;여기까지&amp;nbsp;개념&amp;nbsp;설명을&amp;nbsp;끝내고&amp;nbsp;ULMFiT의&amp;nbsp;효과를&amp;nbsp;검증하는&amp;nbsp;분석을&amp;nbsp;해보자.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;4.&amp;nbsp;Analysis &lt;br /&gt;분석&amp;nbsp;단계에서&amp;nbsp;몇몇&amp;nbsp;유명한&amp;nbsp;NLP&amp;nbsp;데이터를&amp;nbsp;사용했다고&amp;nbsp;한다.&amp;nbsp;IMDb,&amp;nbsp;TREC-6,&amp;nbsp;AG&amp;nbsp;등이다. &lt;br /&gt;&lt;br /&gt;4.1&amp;nbsp;pre-training의&amp;nbsp;효과&amp;nbsp;검증 &lt;br /&gt;우선&amp;nbsp;pre-training&amp;nbsp;VS&amp;nbsp;without&amp;nbsp;pre-training&amp;nbsp;training&amp;nbsp;결과를&amp;nbsp;보자.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&lt;figure class='imageblock alignCenter' data-filename=&quot;5.png&quot;&gt;&lt;span data-url='https://k.kakaocdn.net/dn/dwnWf2/btqwgAYo9MK/C0YZDLWxLk9TBkMX9UiBOk/img.png' data-lightbox='lightbox' data-alt=''&gt;&lt;img src='https://k.kakaocdn.net/dn/dwnWf2/btqwgAYo9MK/C0YZDLWxLk9TBkMX9UiBOk/img.png' srcset='https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fk.kakaocdn.net%2Fdn%2FdwnWf2%2FbtqwgAYo9MK%2FC0YZDLWxLk9TBkMX9UiBOk%2Fimg.png' data-filename=&quot;5.png&quot;&gt;&lt;/span&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;(validation&amp;nbsp;error&amp;nbsp;rate&amp;nbsp;기준) &lt;br /&gt;pretraining하는&amp;nbsp;것이&amp;nbsp;결과가&amp;nbsp;훨씬&amp;nbsp;좋다.&amp;nbsp;좋은&amp;nbsp;것도&amp;nbsp;좋은&amp;nbsp;것이지만&amp;nbsp;결과가&amp;nbsp;꽤나&amp;nbsp;일정하다.&amp;nbsp;(개인적으로&amp;nbsp;pretraining보다&amp;nbsp;일정한&amp;nbsp;결과를&amp;nbsp;낸다는&amp;nbsp;분석&amp;nbsp;결과에&amp;nbsp;더&amp;nbsp;관심이&amp;nbsp;간다.) &lt;br /&gt;&lt;br /&gt;4.2&amp;nbsp;language&amp;nbsp;model의&amp;nbsp;효과&amp;nbsp;검증 &lt;br /&gt;ULMFiT을&amp;nbsp;한&amp;nbsp;것과&amp;nbsp;일반적인&amp;nbsp;LM을&amp;nbsp;만든&amp;nbsp;것을&amp;nbsp;비교한&amp;nbsp;부분이다.&amp;nbsp;즉&amp;nbsp;pretraining&amp;nbsp;알고리즘&amp;nbsp;자체에&amp;nbsp;대한&amp;nbsp;효과성&amp;nbsp;검증이다.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&lt;figure class='imageblock alignCenter' data-filename=&quot;6.png&quot;&gt;&lt;span data-url='https://k.kakaocdn.net/dn/73Dnv/btqwhzqWa0f/fRvVzloB7uBlAIptLfTY20/img.png' data-lightbox='lightbox' data-alt=''&gt;&lt;img src='https://k.kakaocdn.net/dn/73Dnv/btqwhzqWa0f/fRvVzloB7uBlAIptLfTY20/img.png' srcset='https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fk.kakaocdn.net%2Fdn%2F73Dnv%2FbtqwhzqWa0f%2FfRvVzloB7uBlAIptLfTY20%2Fimg.png' data-filename=&quot;6.png&quot;&gt;&lt;/span&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;일반적인&amp;nbsp;LM을&amp;nbsp;뭘로&amp;nbsp;했는지는&amp;nbsp;모르겠다.&amp;nbsp;결과를&amp;nbsp;보면&amp;nbsp;테이블4에서의&amp;nbsp;pretraining&amp;nbsp;안&amp;nbsp;한것보다는&amp;nbsp;일반적인&amp;nbsp;LM이&amp;nbsp;더&amp;nbsp;좋기는&amp;nbsp;한데&amp;nbsp;ULMFiT보다는&amp;nbsp;별로다. &lt;br /&gt;&lt;br /&gt;4.3&amp;nbsp;fine-tuning의&amp;nbsp;효과&amp;nbsp;검증 &lt;/p&gt;
&lt;p&gt;&lt;figure class='imageblock alignCenter' data-filename=&quot;8.png&quot;&gt;&lt;span data-url='https://k.kakaocdn.net/dn/yGQvx/btqwhMDzOSd/FdKVFhrcJ3V99f9oH7yqy0/img.png' data-lightbox='lightbox' data-alt=''&gt;&lt;img src='https://k.kakaocdn.net/dn/yGQvx/btqwhMDzOSd/FdKVFhrcJ3V99f9oH7yqy0/img.png' srcset='https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fk.kakaocdn.net%2Fdn%2FyGQvx%2FbtqwhMDzOSd%2FFdKVFhrcJ3V99f9oH7yqy0%2Fimg.png' data-filename=&quot;8.png&quot;&gt;&lt;/span&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Full:&amp;nbsp;fine-tuning을&amp;nbsp;전체&amp;nbsp;레이어에&amp;nbsp;대해서&amp;nbsp;적용 &lt;br /&gt;Last:&amp;nbsp;fine-tuning을&amp;nbsp;마지막&amp;nbsp;레이어에&amp;nbsp;대해서만&amp;nbsp;적용 &lt;br /&gt;Freez:&amp;nbsp;gradual&amp;nbsp;unfreezing,&amp;nbsp;마지막&amp;nbsp;classification&amp;nbsp;레이어부터&amp;nbsp;시작해서&amp;nbsp;점점&amp;nbsp;위&amp;nbsp;레이어로&amp;nbsp;올라가면서&amp;nbsp;레이어의&amp;nbsp;파라미터를&amp;nbsp;unfreezing하는&amp;nbsp;것.&amp;nbsp;unfreezing한다는&amp;nbsp;것은&amp;nbsp;학습돼&amp;nbsp;있는&amp;nbsp;파라미터가&amp;nbsp;변할&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;fine-tuning한다는&amp;nbsp;것이다. &lt;br /&gt;Disc:&amp;nbsp;discriminative&amp;nbsp;fine-tuning &lt;br /&gt;Stlr:&amp;nbsp;slanted&amp;nbsp;triangular&amp;nbsp;learning&amp;nbsp;rate &lt;br /&gt;Cos:&amp;nbsp;aggressive&amp;nbsp;cosine&amp;nbsp;anealing&amp;nbsp;schedule,&amp;nbsp;Freez에&amp;nbsp;대해서만&amp;nbsp;수행함 &lt;br /&gt;가장&amp;nbsp;좋은&amp;nbsp;결과를&amp;nbsp;내는&amp;nbsp;것은&amp;nbsp;Freez&amp;nbsp;+&amp;nbsp;disc&amp;nbsp;+&amp;nbsp;stlr이다.&amp;nbsp;3개의&amp;nbsp;데이터&amp;nbsp;중&amp;nbsp;2개의&amp;nbsp;데이터에서&amp;nbsp;최고&amp;nbsp;성능을&amp;nbsp;보이고,&amp;nbsp;나머지&amp;nbsp;하나에서도&amp;nbsp;두번째로&amp;nbsp;놓은&amp;nbsp;결과를&amp;nbsp;보여주고&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;4.4&amp;nbsp;fine-tuning&amp;nbsp;진행과정 &lt;br /&gt;fine-tuning이&amp;nbsp;진행되면서&amp;nbsp;error&amp;nbsp;rate이&amp;nbsp;어떻게&amp;nbsp;변화하는지&amp;nbsp;알아보기&amp;nbsp;위한&amp;nbsp;분석이다.&amp;nbsp;아래의&amp;nbsp;그림과&amp;nbsp;같다. &lt;/p&gt;
&lt;p&gt;&lt;figure class='imageblock alignCenter' data-filename=&quot;9.png&quot;&gt;&lt;span data-url='https://k.kakaocdn.net/dn/Pzvfb/btqwil6zeEO/tefjE8uajTSVvqRw7KEDh1/img.png' data-lightbox='lightbox' data-alt=''&gt;&lt;img src='https://k.kakaocdn.net/dn/Pzvfb/btqwil6zeEO/tefjE8uajTSVvqRw7KEDh1/img.png' srcset='https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fk.kakaocdn.net%2Fdn%2FPzvfb%2Fbtqwil6zeEO%2FtefjE8uajTSVvqRw7KEDh1%2Fimg.png' data-filename=&quot;9.png&quot;&gt;&lt;/span&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;위에서부터&amp;nbsp;차례대로&amp;nbsp;IMDb,&amp;nbsp;TREC-6,&amp;nbsp;AG인데&amp;nbsp;ULMFiT에&amp;nbsp;해당하는&amp;nbsp;노란색&amp;nbsp;선들은&amp;nbsp;비교적&amp;nbsp;안정적이고&amp;nbsp;시간이&amp;nbsp;지나면&amp;nbsp;지날수록&amp;nbsp;error&amp;nbsp;rate도&amp;nbsp;작아지는&amp;nbsp;방향으로&amp;nbsp;간다.&amp;nbsp;(흠,&amp;nbsp;마지막&amp;nbsp;AG에&amp;nbsp;대해서는&amp;nbsp;조금&amp;nbsp;애매하긴하다..) &lt;br /&gt;&lt;br /&gt;ULMFiT의&amp;nbsp;논문&amp;nbsp;리뷰는&amp;nbsp;여기서&amp;nbsp;마치려고&amp;nbsp;한다.&amp;nbsp;다음&amp;nbsp;논문&amp;nbsp;리뷰는&amp;nbsp;AWD-LSTM로&amp;nbsp;하려고&amp;nbsp;한다.&lt;/p&gt;</description>
<author>빛나유</author>
<guid isPermaLink="true">https://operatingsystems.tistory.com/168</guid>
<comments>https://operatingsystems.tistory.com/entry/Deep-Learning-%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-Universal-Language-Fine-Tuning#entry168comment</comments>
<pubDate>Sat, 22 Jun 2019 07:58:22 +0900</pubDate>
</item>
<item>
<title>[Deep Learning] Activation Function</title>
<link>https://operatingsystems.tistory.com/entry/Deep-Learning-Activation-Function</link>
<description>&lt;p&gt;Activation function에 대해서 공부해보자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;공부를 하기 전에...&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://operatingsystems.tistory.com/entry/Data-Mining-Artificial-Neural-Network?category=797473&quot;&gt;https://operatingsystems.tistory.com/entry/Data-Mining-Artificial-Neural-Network?category=797473&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;위의 포스팅에서 잘못 써둔 것이 사실 하나 있다.(지금은 고침)&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&quot;...&lt;span&gt;가장 일반적으로 sigmoid function을 택한다....&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;안된다. 그러면 안된다. 이번 포스팅에서 그 오류를 설명하고 그 대안까지, 전반적으로 Activation Function에 대해서 알아야 할 많은 것들을 다뤄보려고 한다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;위의 포스팅에서 Activation Function이 뭐하는 함수인지 그냥 언급만 했다. 그것이 왜 필요한지 등은 설명하지 않았다. 이번 포스팅에서는 그것을 해보려고 한다. 정답을 우선 말해보자면, Non linear한 데이터의 분포에 대해서도 분류를 해낼 수 있도록 피처를 만들어주기 위해서이다. 무슨 말이냐.. 조금 더 쉽게 설명해보자.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;이것을 설명하는데 가장 직관적인 예제는 그 유명한 XOR 문제이다. XOR의 결과 연산을 딥러닝으로 예측하는 문제를 만들어보자. 전체 소스코드는 제일 아래에 github repository에 있으니 읽으시면서 참고하시길 바란다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1558012711550&quot; class=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;'''
XOR Model
'''

import tensorflow as tf

# placeholders for x and y
input_x = tf.placeholder(tf.float32, [None, 2])
input_y = tf.placeholder(tf.int64, [None, 2])

# weight1 and bias1
w1 = tf.Variable(tf.truncated_normal([2, 300], stddev=0.1))
b1 = tf.Variable(tf.constant(0.1, shape=[300]))
z1 = tf.nn.xw_plus_b(input_x, w1, b1)
active1 = tf.sigmoid(z1)

# weight2 and bias2
w2 = tf.Variable(tf.truncated_normal([300, 2], stddev=0.1))
b2 = tf.Variable(tf.constant(0.1, shape=[2]))
z2 = tf.nn.xw_plus_b(active1, w2, b2)

# for test purpose
no_active = tf.nn.xw_plus_b(z1, w2, b2)
sigmoid_active = tf.nn.xw_plus_b(tf.sigmoid(z1), w2, b2)
relu_active = tf.nn.xw_plus_b(tf.nn.relu(z1), w2, b2)

# prediction and training
predictions = tf.argmax(z2, axis=1)
loss = tf.nn.softmax_cross_entropy_with_logits_v2(labels=input_y, logits=z2)
mse = tf.reduce_mean(loss)
train = tf.train.GradientDescentOptimizer(0.1).minimize(mse)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위의 모델은 가장 일반적인 형태의 fully-connected network이다. 주목할 부분은 active1이다. active1을 sigmoid(z1)으로 할 때와 그냥 z1으로 할 때를 비교해보자. 결론부터 말하면 active1 = tf.sigmoid(z1)은 xor 모델 학습이 되고, active1 = z1은 학습 자체가 안된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그럼 왜 안되는지를 설명해보자. 우선 어려운 말보다는 쉽게 그림으로 설명해보려고 한다. sigmoid(z1)을 통해서 z2 값이 어떤 분포로 나타나게 되는지를 봐보자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;# 학습하는 부분 코드&lt;/p&gt;
&lt;pre id=&quot;code_1558012955480&quot; class=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import numpy as np
import tensorflow as tf

steps = 10000
bchsize = 256

def generator(train_x, train_y, bchsize=bchsize):
    start = 0
    while True:
        if start &amp;gt; len(train_x):
            start %= bchsize
        batch_x = train_x[start:start+bchsize]
        batch_y = train_y[start:start+bchsize]
        start += bchsize
        yield batch_x, batch_y
        
# shuffle dataset
random_idx = np.random.choice(len(x), (len(x)), replace=False)
x, y = x[random_idx], y[random_idx]

# split train/test dataset
n_train = int(len(x)*0.8)
train_x, train_y = x[:n_train], y[:n_train]
valid_x, valid_y = x[n_train:], y[n_train:]
valid_y = np.argmax(valid_y, axis=1)

# make generator
gen = generator(train_x, train_y)

# global variable initialization
init = tf.global_variables_initializer()

train_ops = [loss, mse, train]
transform_ops = [no_active, sigmoid_active, relu_active, predictions]
with tf.Session() as sess:
    # initialization
    sess.run(init)
    
    # do training
    for i in range(steps):
        bx, by = next(gen)
        feed_dict = {
            input_x: bx,
            input_y: by
        }
        train_loss, train_mse, _ = sess.run(train_ops, feed_dict=feed_dict)
        if i % 1000 == 0:
            pred = sess.run(predictions, feed_dict={input_x: valid_x})
            acc = (valid_y == pred).astype(int).mean()
            print('%sth iteration finished: %.4f, validation_accracy: %.4f' % (i, train_mse, acc))
            
    # transform data
    feed_dict = {input_x: x}
    no_active_x, sigmoid_active_x, relu_active_x, pred_x = sess.run(transform_ops, feed_dict=feed_dict)
    
    print(no_active_x.shape, sigmoid_active_x.shape, relu_active_x.shape, pred_x.shape)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;학습이 끝난 후에 전체 데이터 x에 대해서 z2값을 구하고, 그것을 plot해보니 아래와 같은 결과가 나왔다. 원래의 데이터 분포, active1 = tf.sigmoid(z1)과 active1 = z1 둘의 결과를 비교해보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class='imageblock alignLeft' data-filename=&quot;active_plot.png&quot;&gt;&lt;span data-url='https://k.kakaocdn.net/dn/m9cZT/btqvlhlwcFS/TPReqsXtjPkZdbT2QfhcjK/img.png' data-lightbox='lightbox' data-alt=''&gt;&lt;img src='https://k.kakaocdn.net/dn/m9cZT/btqvlhlwcFS/TPReqsXtjPkZdbT2QfhcjK/img.png' srcset='https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fk.kakaocdn.net%2Fdn%2Fm9cZT%2FbtqvlhlwcFS%2FTPReqsXtjPkZdbT2QfhcjK%2Fimg.png' data-filename=&quot;active_plot.png&quot;&gt;&lt;/span&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Original Data, No Activation은 선 하나로 나눌 수 없게 돼 있고, Sigmoid Activation과 ReLu Activation은 나눌 수 있게 돼 있다. 왜 그럴까? 일단 가장 큰 차이는 activation function의 유무이다. 기본적으로 2차원 데이터를 평면 상에 나타냈을 때(Original Data)는 선 하나로 나눌 수 없는 형태이다. 그래서 모델 학습을 진행하는데, activation 함수를 적용하지 않았더니(No Activation) 학습을 하나 마나였다는 것이다. 그런데 activation 함수를 적용을 하니(Sigmoid Activation, ReLu Activation) 선 하나를 이용해서 둘로 나눌 수 있는 형태가 됐다는 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;종합하면, 다음과 같은 결론이 나온다. xor 데이터의 0과 1을 선 하나로 구분하는 것은 불가능하다. 그래서 우리는 sigmoid, relu와 같은 함수를 중간에 적용해준다. 그러면 선 하나로 구분할 수 있는 형태로 변형이 가능하다. 여기서 &quot;선 하나로&quot;라고 계속 이야기하는 것을 조금 유식하게 말하면 linear하게(=선형적으로)이다. 즉 xor 데이터는 선형적으로는 구분을 할 수 없으니, 비선형 함수인 sigmoid, relu함수 등을 사용해서 학습해주면 된다는 것이다. 이 비선형 함수를 적용한 결과가 위의 가운데 그림인 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;자 이제, activation 함수를 왜 사용하는지 알아봤다. 이걸 사용해야 선형으로 나눌 수 없는 모델을 나눌 수 있게 되기 때문이다. 그럼 이제 어떤 activation 함수들이 있는지와 그것들의 특징에 대해서 알아보자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 부분을 이야기하기 전에 2000년 이전에 딥러닝이 발전하지 않았을 때 사용했던 Activation 함수들에 대해서 이야기를 먼저 해보려고 한다. sigmoid, tahn 함수들이 바로 그것들이다. 이 함수들은 각각 아래와 같은 모양으로 그래프를 그릴 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class='imageblock alignLeft' data-filename=&quot;sigtan.png&quot;&gt;&lt;span data-url='https://k.kakaocdn.net/dn/bnLas3/btqvmtlk2JH/Cxpc5HLWQ4hcaHLFLOm0eK/img.png' data-lightbox='lightbox' data-alt=''&gt;&lt;img src='https://k.kakaocdn.net/dn/bnLas3/btqvmtlk2JH/Cxpc5HLWQ4hcaHLFLOm0eK/img.png' srcset='https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fk.kakaocdn.net%2Fdn%2FbnLas3%2Fbtqvmtlk2JH%2FCxpc5HLWQ4hcaHLFLOm0eK%2Fimg.png' data-filename=&quot;sigtan.png&quot;&gt;&lt;/span&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;두 함수의 공통점은 뭘까? 음/양 무한대로 가면 값이 거의 똑같다는 것이다. 이는 두 함수를 미분했을 경우, 음/양 무한대의 미분값은 거의 0이라는 뜻이다. 이것이 딥러닝의 학습 과정에서 영향을 주는 것이 그 유명한 Gradient vanishing problem이다. Gradient vanishing problem에 대해서는 다음에 자세하게 포스팅하려고 하는데, 여기서는 간단하게 이렇게만 설명하고 넘어가보자. 딥러닝 학습 과정은 기본적으로 cost function을 최소화하는데 있다. 어떤 함수의 최소값을 구할 때 우리는 고등학교 때 미분을 하곤 했다. 즉, 딥러닝 학습 과정을 거치기 위해서는 미분 과정을 거쳐야 하는데, sigmoid와 tahn 함수를 미분할 경우에는 x 값이 음/양 무한대로 가면 갈수록 미분 값이 0이 되고, 그 결과 학습되는 양이 거의 0에 수렴하게 된다. gradient가 기울기, 즉 미분 값을 의미하는데&amp;nbsp; 그 값이 사라지는 문제. 그것이 gradient vanishing problem이다. (여기에서는 이렇게 간단하게만 이야기하고 이것에 대해서는 자세하게 다음에 포스팅하려고 한다.)&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;여기서 재미있는 인터뷰 영상을 하나 보자.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=pnTLZQhFpaE&quot;&gt;https://www.youtube.com/watch?v=pnTLZQhFpaE&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignLeft&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=pnTLZQhFpaE&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/fAVbN/hyBcm6nVYn/Te6YvYdPoTgWdDl8Ebt7wK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=592_256_944_640&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/pnTLZQhFpaE&quot; width=&quot;860&quot; height=&quot;418&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;3:00 정도에 Andrew님께서(동양분) Yoshua께(서양분) 이렇게 질문한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Andrew: .... 예전에 했었던 가장 큰 실수가 있다면 어떤 것이 있을까요??&lt;/p&gt;
&lt;p&gt;Yoshua: ... 예전에는 당연히 선형적이지 않은 부분을 smooth하게 해야 된다고 생각했다. 그런데 2010년도에 와서 보니까 ReLU와 같은 non-linear한 형태의 activation 함수가 잘 동작한다는 것을 알게 됐다. ...&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이런 대화를 한다. 이 대화를 여러 각도에서 생각해볼 필요가 있다. 우선, 저렇게 똑똑한 분들이 지난 몇 십년동안 당연하다고 생각했던 것도 틀릴 수 있다는 것이다. 그러니까 Yoshua님도 big surprise로 이것을 든 것이다. (과연 우리가 지금 당연하게 알고 있는 것들도 그런 것들이 있을 수 있을까? maybe?)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 분들의 인터뷰 영상을 연결고리로 해서 ReLU에 대해서 이야기해보려고 한다. ReLU는 Rectified Linear Unit의 약자이다. Rectified는 교정된이라는 뜻이다. 그렇다면, &quot;수정된 선형 유닛&quot;정도로 억지 번역될 수 있겠다. 우선 ReLU 함수를 그려보자.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class='imageblock alignLeft' data-filename=&quot;relu.png&quot;&gt;&lt;span data-url='https://k.kakaocdn.net/dn/xpInc/btqvmsUfa8u/M1RzvST1NwnFVaYztlsJa0/img.png' data-lightbox='lightbox' data-alt=''&gt;&lt;img src='https://k.kakaocdn.net/dn/xpInc/btqvmsUfa8u/M1RzvST1NwnFVaYztlsJa0/img.png' srcset='https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fk.kakaocdn.net%2Fdn%2FxpInc%2FbtqvmsUfa8u%2FM1RzvST1NwnFVaYztlsJa0%2Fimg.png' data-filename=&quot;relu.png&quot;&gt;&lt;/span&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&quot;이렇게 하면 안 될것이다&quot;라고 Yoshua님께서 젊었을 때 생각하셨단다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Yoshua: 이렇게 하면 너무 많은 부분에서 0이 나오게 되기 때문에 학습에 방해된다. 따라서 이렇게 하면 아니되오!! 라고 생각했다. 그런데 2010년 이후에 확인해보니, 실제로 이렇게 학습하는 것이 훨씬 잘 학습을 한다는 것을 발견했다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;ReLU 함수는 computation 역시 빠르게 가능하다. max(x, 0)가 전부이다. 즉, 0보다 크면 x, 그렇지 않으면 0이므로, 단순 if-else 문으로 구현할 수 있는 함수이다. 그렇다면 ReLU의 단점은 뭘까? dying problem이 있다. Yoshua님께서 걱정했듯이, 학습 시에 많은 부분이 0이 되버리는(die) 문제이다. 이런 문제점을 해결하기 위해 나온 ReLU 변형은 아래에 가볍게 리스팅만 해두려고 한다.&lt;/p&gt;
&lt;p&gt;- leaky ReLU&lt;/p&gt;
&lt;p&gt;- maxout (ReLU와 leaky ReLU를 같이 고려해서 만듬)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;자, 그래서 어떤 activation 함수를 골라야 할까? 사실 답은 없다. Yoshua님께서 깨닳으신데로 우리가 당연히 그것이 맞다라고 생각한 것도 틀릴 수 있는 것이다. 그렇지만 보통 여러 사람들이 일반적으로 하는 말은, &quot;모르면 ReLU를 써라&quot;이다. 일반적으로 sigmoid나 tanh 보다는 좋다고 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;# Reference&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://towardsdatascience.com/activation-functions-and-its-types-which-is-better-a9a5310cc8f&quot;&gt;https://towardsdatascience.com/activation-functions-and-its-types-which-is-better-a9a5310cc8f&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://medium.com/the-theory-of-everything/understanding-activation-functions-in-neural-networks-9491262884e0&quot;&gt;https://medium.com/the-theory-of-everything/understanding-activation-functions-in-neural-networks-9491262884e0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;# github repository&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/jinkilee/operatingsystems.tistory.com/tree/master/source/blog_1&quot;&gt;https://github.com/jinkilee/operatingsystems.tistory.com/tree/master/source/blog_1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
<category>Deep Learning</category>
<author>빛나유</author>
<guid isPermaLink="true">https://operatingsystems.tistory.com/167</guid>
<comments>https://operatingsystems.tistory.com/entry/Deep-Learning-Activation-Function#entry167comment</comments>
<pubDate>Wed, 08 May 2019 13:55:45 +0900</pubDate>
</item>
<item>
<title>시작하며</title>
<link>https://operatingsystems.tistory.com/entry/%EC%8B%9C%EC%9E%91%ED%95%98%EB%A9%B0-8</link>
<description>&lt;p&gt;내가 딥러닝 하는 사람 맞아?&lt;/p&gt;
&lt;p&gt;요즘 가장 많이 하는 생각이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;분명 이 분야의 전문가.. 정확히 말하면 머신러닝의 전문가가 되고 싶다.&lt;/p&gt;
&lt;p&gt;그리고 그 분야에서 일을 하고 있다. 그런데 내가 아는게 얼마나 많은가? 생각해보면 별로 아는게 없는 것 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그렇게 1~2년이 훌쩍 지났고, 뭔가 액팅을 해야겠다는 생각이 들었다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그래서 제일 처음에 생각이 나는게 공부. 공부하면 블로그 쓰기.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그래서 다시 하나의 카테고리를 만들었다. 딥러닝.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이전에 Data Mining 쪽에도 딥러닝 관련된 포스팅들이 몇 개 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그런데 또 만든 것은, 더 제대로 해보고자 하기 위함이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그래서!! 나답게 시작해보자.&lt;/p&gt;</description>
<category>Deep Learning</category>
<author>빛나유</author>
<guid isPermaLink="true">https://operatingsystems.tistory.com/166</guid>
<comments>https://operatingsystems.tistory.com/entry/%EC%8B%9C%EC%9E%91%ED%95%98%EB%A9%B0-8#entry166comment</comments>
<pubDate>Wed, 08 May 2019 11:52:37 +0900</pubDate>
</item>
<item>
<title>[High Performance Computing] MPI</title>
<link>https://operatingsystems.tistory.com/entry/High-Performance-Computing-MPI</link>
<description>&lt;p&gt;우와 이게 진짜 얼마만의 블로깅이냐... 작년 6월을 마지막으로 한 개도 못 올렸다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 255, 255);&quot;&gt;이유는... 나에게도 평생을 함께할 사람이 생겨서 그 준비를 좀 하느라...&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아무튼 오랜만에 포스팅을 해보려고 한다. 오늘 포스팅할 내용은 HPC!! High Performance Computing이다. 고성능 컴퓨팅!! 번역하면 이렇게 되겠다. 영국 유학 중에 배웠던 데이터 마이닝 이외의 내용 중에서 가장 유용하고 잘 배웠다고 생각하는 과목이기도 했다. 그런데 이유는 모르겠지만 유학 생활 중에 이 내용을 포스팅해두지 않았었다. 그래서 지금이라도 한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;System Programming 탭에도 성능 관련된 포스팅들이 몇 개가 있다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://operatingsystems.tistory.com/entry/SP-Optimizing-a-program?category=495589&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://operatingsystems.tistory.com/entry/SP-Optimizing-a-program?category=495589&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://operatingsystems.tistory.com/entry/SP-Optimizing-a-Program-with-a-hardware-dependent-perspective?category=495589&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://operatingsystems.tistory.com/entry/SP-Optimizing-a-Program-with-a-hardware-dependent-perspective?category=495589&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 포스팅들은 코딩을 효율적으로 해서 프로그램의 성능을 높이는데 초점을 맞추고 있다. 즉, 어떻게 하면 레지스터로부터 바로 값을 가져오고, 캐시를 바로 사용할 수 있고, 메모리 접근을 최대한 지양하고 등등. 그런데 오늘 포스팅할 내용들은 관점을 조금 달리한다. HPC에서 성능은 어떻게 하면 한 작업을 여럿이서 수행할 수 있게 할 수 있을까? 이다. 즉 Parallel Computing(병렬 컴퓨팅)이다. Parallel Computing을 하기 위해서 보통 아래의 세가지 접근 방법을 택할 수 있다.&lt;/p&gt;&lt;p&gt;1. multi-thread&lt;/p&gt;&lt;p&gt;2. multi-process&lt;/p&gt;&lt;p&gt;3. GPU&lt;/p&gt;&lt;p&gt;&lt;br /&gt;multi-thread는 thread를 여러 개 생성해서 각자가 동작하는 것이고, multi-process는 프로세스를 여러 개 생성해서 각자가 동작하도록 하는 것이다. GPU는 말할 것도 없다. 여기서는 multi-process에 대해서 이야기 해보려고 한다. 그것을 할 수 있게 하는 것이 이 포스팅의 제목!! MPI(&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;Message Passing Interface)이다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;우선, multi-thread와 multi-process의 차이를 설명하면서 왜 &lt;b&gt;MESSAGE PASSING&lt;/b&gt; Interface인지 설명해보려고 한다. thread는 하나의 프로세스에서 생성된다. 그리고 그 프로세스에서 생성된 여러 개의 thread 끼리는 자원을 서로 공유한다. 여기서 말하는 자원은 하나의 프로세스에게 할당된 virtual memory address이다. 즉, 하나의 virtual memory address를 공유한다. 반면 multi-process는 프로세스를 여러 개 띄운다. 즉 서로 다른 프로세스가 같은 일을 하게 한다는 것이다. 쉽게 말하면, p1.c 하나, p2.c 하나, p3.c 하나, p4.c 하나를 각각 컴파일해서 p1,exe, p2.exe, p3.exe, p4.exe가 하나의 연산을 수행하도록 하는 것과 같은 개념이라는 말이다. (물론 MPI에서 서로 다른 소스코드를 작성해서 하나로 합치고 그러지는 않는다.) 여러 개의 프로세스는 완전히 서로 독립돼 있다. 마치 메모장이라는 프로그램과 크롬 브라우저가 서로 어떤 것도 공유하고 있지 않는 것처럼, 여러 개의 프로세스는 완전히 서로 독립된 프로세스이다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;'아 그럼 서로 독립된 프로세스가 같은 작업을 할 수 있게 하면 되는구나?!'&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;그렇다. 그런데 여기서 문제가 있다. 하나의 작업을 수행하려면 중간 연산 결과를 서로 서로 공유해야 할 때가 있다. 예를 들어, 1부터 100까지 더하는 연산을 생각해보자. 이것을 하나의 프로세스로 하면 아래와 같이 하면 된다.&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:436px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/999C6F355A8A4B560C&quot; filemime=&quot;image/jpeg&quot; filename=&quot;1.png&quot; height=&quot;337&quot; width=&quot;436&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;그런데 여러 개의 프로세스로 하면 아래와 같이 할 수 있다.&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99DF4E335A8A4B6219&quot; filemime=&quot;image/jpeg&quot; filename=&quot;2.png&quot; height=&quot;360&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;위의 그림에서 보면 각각의 프로세스가 25개씩 부분적으로 SUM을 하고, 그 결과를 한 프로세스에 몰아준다. 즉, 프로세스끼리 연산 결과를 보내고 받는 등의 작업이 필요하다는 것이다. 이것이 MESSAGE PASSING이다. 그래서 MPI라는 것은 작업한 결과물을 다른 프로세스에게 전달할 수 있게 하는 인터페이스라는 의미이다.&amp;nbsp;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;이 포스팅에서 MPI에서 사용되는 함수들의 개념과 MPI를 사용한 예제 프로그램, 그리고 그것을 이용해서 어느 정도의 성능 향상을 이뤘는지를 알아보도록 하자.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;b&gt;1. MPI에서 사용되는 함수들의 개념&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;MPI에서 사용되는 함수들이 있다. 보통 Python이든, C++이든 무슨 언어든 간에 MPI에서 지원해주는 공통적인 함수를 의미한다. 여기서는 C++을 기반으로 이야기하려고 한다. 아래의 함수는 모두 C++에서 지원하는 정확한 함수명이다.&amp;nbsp;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;보통 요즘 CPU들은 4코어까지 사용할 수 있게 하므로, 4개의 프로세스를 가정하고 설명을 해보려고 한다. 그리고 각각의 프로세스를 0, 1, 2, 3 이렇게&amp;nbsp;&lt;/font&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;번호로&lt;/span&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;&amp;nbsp;나타내보자.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;b&gt;MPI_Send&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;int MPI_Send(&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; const void *buf,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; # 보내려는 데이터의 시작 주소&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; int count,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # 보내려는 데이터의 개수&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;&amp;nbsp; &amp;nbsp; MPI_Datatype datatype,&amp;nbsp; &amp;nbsp;# 보내려는 데이터의 타입&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;&amp;nbsp; &amp;nbsp; int dest,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; # 보내려는 프로세스의 번호(etc, 0, 1, 2, 3)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;&amp;nbsp; &amp;nbsp; int tag,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; # 태그&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;&amp;nbsp; &amp;nbsp; MPI_Comm comm&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; # MPI handler&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;조금 더 상세하게 설명해보자. A라는 프로세스가 B라는 프로세스에 Integer 타입의 Array 10개를 보내려고 한다면, A라는 프로세스에서 그 Integer Array의 시작 주소를 우선 파라미터로 넣어야 한다. 그것이 buf이다. 그러면 그 메모리 주소에서 어떤 데이터 타입을 기준으로 몇 개를 보낼 것인지 결정해야 하는데, 그것이 각각 datatype과 count이다. dest는 보내려는 프로세스의 번호로, 0이라고 넣으면 0번 프로세스에게 보내겠다는 뜻이다. tag는 아무런 값이나 넣어도 된다. optional한 파라미터이고, 가령 Double Type에 대해서는 1, Integer Type에 대해서는 2와 같이 구분해주기 위한 태그일 뿐이고, 프로그램 동작 상에는 전혀 영향을 주지 않는다. 마지막으로 comm은 MPI Handler이고 나중에 실제 사용 예제를 통해서 더 확실하게 알아볼 수 있을 것 같다.&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;b&gt;MPI_Recv&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;int MPI_Recv(&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;&amp;nbsp; &amp;nbsp; void *buf,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # 데이터를 받을 곳의 시작 주소&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;&amp;nbsp; &amp;nbsp; int count,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; # 받을 데이터의 개수&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;&amp;nbsp; &amp;nbsp; MPI_Datatype datatype, # 받을 데이터의 타입&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;&amp;nbsp; &amp;nbsp; int source,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; # 데이터를 받을 프로세스의 번호&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;&amp;nbsp; &amp;nbsp; int tag,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; # 태그&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;&amp;nbsp; &amp;nbsp; MPI_Comm comm,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; # MPI handler&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;&amp;nbsp; &amp;nbsp; MPI_Status *status&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# 상태&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;다른 내용은 MPI_Send를 통해 모두 설명했고, status만 더 설명하면 될 것 같다. status는 말 그대로 상태이다. 데이터를 받아들이는데 상태를 나타낸다. 이는 MPI_Status 라는 구조체를 통해 정의되어 있는데 그 구조체는 아래와 같다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;typedef struct _MPI_Status {&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; int count;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; int cancelled;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; int MPI_SOURCE;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; int MPI_TAG;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&amp;nbsp; &amp;nbsp; int MPI_ERROR;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;} MPI_Status, *PMPI_Status;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;이것에 대한 해석은 그냥 독자에게 맞기려고 한다.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;b&gt;MPI_Bcast&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;여기서부터는 함수의 파라미터를 자세하게 설명하지 않고 동작 방식을 위주로 설명하려고 한다. 파라미터는 어짜피 MPI_Recv나 MPI_Send에서 했었던 것과 크게 다르지 않다. 여기서부터는 동작 방식이 더 중요하므로 그것에 더 초점을 맞춰보자. MPI_Bcast는 Broadcast이다. 즉, 한 프로세스가 모든 프로세스에게 값을 전달해주겠다는 뜻이다. 하나의 프로세스의 데이터를 모든 프로세스가 공유해야 할 경우 이 함수를 사용하면 된다.&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:306px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/998CB53E5A8A4ABC07&quot; filemime=&quot;image/jpeg&quot; filename=&quot;3.png&quot; height=&quot;174&quot; width=&quot;306&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;b&gt;MPI_Gather&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;Gather는 반대로 모든 프로세스로부터의 데이터를 한 프로세스가 필요로 할 때 사용한다.&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:290px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99640C3A5A8A4AD40B&quot; filemime=&quot;image/jpeg&quot; filename=&quot;5.png&quot; height=&quot;163&quot; width=&quot;290&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;b&gt;MPI_Scatter&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;Scatter는 하나의 프로세스에서의 데이터를 다른 프로세스에 &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;골고루&lt;/span&gt; 나눠줄 때 필요하다. 즉 데이터를 쪼개서 보내준다는 뜻이다. 예를 들어, 1부터 100까지 더하는 프로그램에서, 제일 처음 할 일은, 특정 프로세스가 1부터 100까지의 데이터를 만들어서 그것을 4개 단위로 쪼개서 나머지 프로세스에게 보내주는 과정이다. 이 과정을 Scatter 함수를 통해야 한다.&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:308px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99C7C7385A8A4AE536&quot; filemime=&quot;image/jpeg&quot; filename=&quot;4.png&quot; height=&quot;177&quot; width=&quot;308&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;b&gt;MPI_Allgather&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;각각의 프로세스의 결과를 모든 프로세스가 공유해야 할 때 사용한다. 즉, 모든 프로세스가 각각 Bcast 함수를 수행하는 것과 같다.&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:223px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99887E375A8A4AFC06&quot; filemime=&quot;image/jpeg&quot; filename=&quot;6.png&quot; height=&quot;177&quot; width=&quot;223&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;b&gt;MPI를 이용한 예제 프로그램&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;아래와 같은 프로그램이 있다.&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9943103B5A8A4B0C12&quot; filemime=&quot;image/jpeg&quot; filename=&quot;7.png&quot; height=&quot;287&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;이 프로그램을 아래와 같이 바꿨다.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;# MPI handler 추가&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9991C63C5A8A4B1916&quot; filemime=&quot;image/jpeg&quot; filename=&quot;9.png&quot; height=&quot;86&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;# 처리할 데이터 Scatter&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/990BCA3F5A8A4B2811&quot; filemime=&quot;image/jpeg&quot; filename=&quot;10.png&quot; height=&quot;59&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;# move() 함수에 대한 병렬 처리 구현&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/997E3F335A8A4BAF12&quot; filemime=&quot;image/jpeg&quot; filename=&quot;8.png&quot; height=&quot;297&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;참고로 이 프로그램은 Force Directed Graph라는 알고리즘을 어떤 사람이 Python으로 구현해둔 것을 내가 C++과 MPI를 이용한 C++으로 구현해둔 것이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;MPI를 이용한 C++ 프로그램은 아래와 같이 컴파일하고 실행하면 된다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;# mpic++ -std=c++11 -o test spring_mpi.cpp&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;# mpirun -n 4 ./test&lt;/font&gt;&lt;/p&gt;&lt;div&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;&lt;b&gt;성능 향상&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(84, 84, 84); font-family: &amp;quot;Apple SD Gothic Neo&amp;quot;, arial, sans-serif; font-size: small;&quot;&gt;위 두 프로그램의 연산 결과는 정확하게 일치하는데 성능 차이는 약 3.96배(13.34초/3.3651초) 차이 난다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;Reference:&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color=&quot;#545454&quot; face=&quot;Apple SD Gothic Neo, arial, sans-serif&quot; size=&quot;2&quot;&gt;&lt;a href=&quot;http://mpitutorial.com/tutorials/mpi-scatter-gather-and-allgather/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://mpitutorial.com/tutorials/mpi-scatter-gather-and-allgather/&lt;/a&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.mpich.org/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://www.mpich.org/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
<category>etc...</category>
<author>빛나유</author>
<guid isPermaLink="true">https://operatingsystems.tistory.com/165</guid>
<comments>https://operatingsystems.tistory.com/entry/High-Performance-Computing-MPI#entry165comment</comments>
<pubDate>Mon, 19 Feb 2018 09:44:18 +0900</pubDate>
</item>
<item>
<title>[Deep Learning] Convolutional Neural Network</title>
<link>https://operatingsystems.tistory.com/entry/Data-Mining-Convolutional-Neural-Network</link>
<description>&lt;p&gt;오랜만에 포스팅한다. 포스팅을 하다보니까 Data Mining 폴더에 Machine learning 관련된 포스팅을 하게 되고 그러다보니 Deep Learning까지 하게 됐다. 뭔가 분류가 잘 안 맞는 것 같지만 그렇다고 몇 개 있지도 않은 Deep learning 포스팅만 따로 분류하기도 좀 그렇고. 그냥 이렇게 하련다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;오늘은 Convolutional Neural Network에 대해서 이야기해보려고 한다. Convolutional Neural Network은 줄여서 CNN이라고 하고 앞으로 CNN으로 용어 통일하려고 한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;CNN은 Neural Network의 한 종류이다. 기본적으로 Neural Network가 들어가면 데이터가 이쪽 계층에서 저쪽 계층으로 그리고 그 다음 계층으로 흘러가는 형태의 Network가 있다. 그 Network가 다양한 구조를 하고 있을 수 있는데 CNN도 CNN 나름의 독특한? 구조를 하고 있다. 보통 숲을 보고 나무를 보는 것이 좋은 경우도 있지만 무언가 디테일한 것을 공부할 때는 나무를 보고 숲을 보는 것이 더 좋을 때가 있다. CNN을 이전에 계속 보다가 이해를 못 했었는데 나무를 보고 숲을 보는 전략을 선택하니까 이해가 편하더라.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 포스팅에서도 CNN의 나무를 먼저 보고 숲을 보려고 한다. 어짜피 알고리즘은 숫자로 연산하는 과정이다. 그 과정이 무슨 역할인지를 이해하는 것이 중요하긴 하지만 일단 숫자로 연산을 어떻게 하는지(나무 보기) 알아보고 그 연산이 전체 CNN에서 어떤 역할인지를(숲 보기) 알아보자.&lt;/p&gt;&lt;p&gt;CNN의 나무를 보기 위해서 우리는 하나의 데이터를 예시로 보여주려고 한다. 그 데이터는 사진 이미지이다. 사진 이미지는 0부터 256 사이의 숫자로 되어있다. 픽셀 수에 따라서 굉장히 여러 숫자로 이루어진 데이터가 될 수도 있지만 여기에서는 아주 적은 개수의 픽셀로 예를 들어보자. 10x10개의 픽셀 데이터로 해보자.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 데이터를 가지고 CNN이 어떻게 동작하는지를 알아보려고 한다. 재밌는 숫자놀이를 해보자. 우선 5x5 크기의 랜덤 메트리스 하나를 준비하자. 이 메트리스를 필터1이라고 해보자. 그러면 우리는 필터1을 이용해서 10x10데이터 전체를 스캔해보자. 아래와 같이 스캔해보자.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/242E914C59589F981D&quot; filemime=&quot;image/jpeg&quot; filename=&quot;pic3.png&quot; height=&quot;392&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;스캔할 때 연산은 그냥 단순 곱셈과 덧셈이다. 각 숫자를 곱하고 그 곱한 값을 더하여 하나의 숫자로 만들어낸다. 즉 스캔을 한 결과는 하나의 숫자가 된다.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;text-align: center;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/253D594C59589F992F&quot; filemime=&quot;image/jpeg&quot; filename=&quot;pic4.png&quot; height=&quot;237&quot; style=&quot;text-align: center;&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;자 고정된 값을 가지고 있는 5x5 메트리스인 필터1을 10x10 메트리스 데이터에 전체적으로 스캔을 돌리면 스캔한 결과가 몇 개가 나올까? 10x10개가 나온다. 스캔을 한 번 하면 그 결과는 숫자 하나이기 때문에 10x10번의 스캔을 하면 10x10 메트리스가 생성된다. 이 메트리스를 스캔1 메트리스라고 하자.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;text-align: center;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/223F944C59589F9A0C&quot; filemime=&quot;image/jpeg&quot; filename=&quot;pic5.png&quot; height=&quot;471&quot; style=&quot;text-align: center;&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이렇게 나온 스캔1 메트리스에 &amp;nbsp;ReLu 함수를 적용한다. ReLu 함수의 정의는 아래와 같다.&lt;/p&gt;&lt;p&gt;ReLu(x) = max(0, x)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;간단한 함수다. x값을 0과 비교해서 둘 중에 큰 값을 리턴해주는 함수이다. ReLu 함수도 숫자 하나에 대해서 숫자 하나를 리턴해주기 때문에 10x10 메트리스에 대해서는 10x10 ReLu 함수 결과가 나온다.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;text-align: center;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/223F944C59589F9A0C&quot; filemime=&quot;image/jpeg&quot; filename=&quot;pic5.png&quot; height=&quot;471&quot; style=&quot;text-align: center;&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;(애초에 데이터가 모두 0보다 큰 데이터들이라 결과는 입력과 똑같다)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 메트리스를 2x2 메트리스 단위로 요약해보자. 요약이라는 말은 단순히 2x2 메트리스에서 가장 큰 값으로 바꿔보자는 이야기이다. 아래의 그림과 같이 하면 된다.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:364px;text-align: center;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/22207D4C59589F9A16&quot; filemime=&quot;image/jpeg&quot; filename=&quot;pic6.png&quot; height=&quot;247&quot; style=&quot;text-align: center;&quot; width=&quot;364&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;CNN에서 위와 같은 요약을 풀링이라고(pooling) 한다. 위의 결과는 가장 큰 값으로 요약을 하는, 즉 가장 큰 값으로 풀링을 하는 것이므로, max pooling이라고 한다. 즉 풀링하는 방법에 따라서 min pooling, mean pooling도 있을 수 있다는 것이다.(안 쓰지만)자, 이제 메트리스를 풀링했으니까 이제 5x5로 크기가 줄어들었다. 이 메트리스를 풀링1 메트리스라고 하자.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;지금까지 한 과정을 CNN에서 사용하는 용어로 설명해보자. 이미지에 대해서 하나의 필터로 스캔한 것을 Convolve 한다고 한다. 그것에 대해서 ReLu 함수를 적용한 과정은 Activate 한다고 하고, max pooling을 적용하는 부분은 풀링한다고 한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이제 위에서 설명한 단순한 숫자놀이가 각각 무엇을 의미했는지 알아보자. 제일 처음에 10x10 데이터는 그저 데이터에 불과하다. (실제 tensorflow 등으로 구현을 할 때는 100 크기의 input을 받아서 10x10으로 reshape해주는 과정을 거친다.) 이 10x10 데이터를 필터1로 쭉 스캔을 해서 10x10 스캔1 메트리스를 얻는다. 이 스캔 결과 메트리스에 ReLu 함수를 적용하여 또 다른 10x10 메트리스를 얻는다. 이 메트리스를 2x2 크기로 풀링을 해서 5x5 크기의 풀링1 메트리스를 얻는다. 이 과정을 그림으로 간략하게 설명해보면 아래와 같다.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;text-align: center;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2374C84C59589F9B2A&quot; filemime=&quot;image/jpeg&quot; filename=&quot;pic7.png&quot; height=&quot;153&quot; style=&quot;text-align: center;&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;일반적으로 CNN에서 필터를 여러 개를 갖는다. 필터1 때문에 스캔1, 풀링1 메트리스가 나왔으니까 필터가 N개 있으면 스캔1부터 스캔 N까지 있을 것이고, 풀링1부터 풀링N까지 있을 것이다.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;text-align: center;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2677F24C59589F9B10&quot; filemime=&quot;image/jpeg&quot; filename=&quot;pic8.png&quot; height=&quot;198&quot; style=&quot;text-align: center;&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;CNN의 전체적인 그림은 위와 같다. 지금까지 계속 설명을 하면서 필터라는 용어를 사용했는데, 필터라는게 무엇일까? 우리가 지금까지 사용한 5x5 필터는 그 모양이 있는지 확인하는 모양틀 같은 거라고 생각하면 된다. 예를 들어 아래와 같은 필터는 십자가 모양을 확인하는 필터이다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:279px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/233BD0445958A0A033&quot; filemime=&quot;image/jpeg&quot; filename=&quot;pic13.png&quot; height=&quot;242&quot; width=&quot;279&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위의 필터를 이용하여 주어진 그림을 쭉 스캔하면 십자가 모양에 가까운 부분이 있을 수록 스캔 결과가 큰 값이 나올 것이다. (물론 그냥 일반적으로 말한 것 뿐이다) 물론 실제 CNN에서 위와 같이 완벽한 필터를 처음부터 랜덤으로 만들어서 한다는 것은 아니다. 처음에는 필터가 랜덤하게 초기화되지만 트레이닝이 진행되면서 랜덤하게 초기화된 필터가 점점 제 모양을 찾아간다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;지금까지 CNN이 CNN이라고 불릴 수 있는 핵심 부분을 설명했다. 그런데 아직 절반 밖에 설명하지 않았다. Convolution layer 다음에 있는 부분은 아직 설명하지 않았다. 그 다음 부분을 지금부터 설명하려고 한다. 그런데 이 부분 부터는 이미 예전에 자세하게 설명한 부분이다. Fully Connected Layer라고 불리는데 일반적인 input layer, hidden layer, output layer를 가지는 부분이다. 이 부분이 왜 있을까? 실제로 분류를 해주기 위해서이다. CNN은 보통 이미지 분류와 같은 영역에서 큰 성과를 나타낸다. 이미지 분류!! 예를 들어서 어떤 주어진 이미지에 대하여 책이 있다? 없다? 혹은 주어진 그림이 0이다? 1이다? 2다? 3이다? (MNIST 데이터셋) 등등을 분류해야 하기 때문에 Fully Connected Layer를 통해서 실제 분류를 해내는 것이다. 그러면 Fully Connected Layer 이전에 있었던 Convolution Layer는 무슨 역할인가? 주어진 이미지 데이터에 대하여 올바른 피처를 뽑아내는 역할을 하는 것이다. 여기서 말하는 올바른 피처가 N개의 필터를 통해서 검출되는 것이다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;text-align: center;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/231A0E4C59589F9D1F&quot; filemime=&quot;image/jpeg&quot; filename=&quot;pic9.png&quot; height=&quot;219&quot; style=&quot;text-align: center;&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이것이 CNN의 전부이다. 그런데 여기서 하나 더 알아야 하는 것이 있다. 바로 체널이다. 체널이 무엇이냐? 하나의 데이터를 이루는 층이다. 예를 들어 컬러 사진을 놓고 생각해보자. 보통 R(Red), G(Green), B(Blue) 값으로 하나의 이미지가 세 개의 층을 갖는다. 세 개의 층에 대해서 Convolution Layer, ReLu Layer, MaxPooling Layer를 거치면 어떻게 되는지 숫자로 알아보자.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아래의 예제는 5x5 RGB 이미지에(5x5x3) 대하여 체널 3개를 가지고 있는 3x3 필터 하나를(3x3x3) 적용하여 그 결과로 5x5x1 메트리스를 갖는 과정을 설명한 그림이다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;# 과정&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;text-align: center;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2113304F59589F9D0F&quot; filemime=&quot;image/jpeg&quot; filename=&quot;pic10.png&quot; height=&quot;267&quot; style=&quot;text-align: center;&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;# 결과&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;text-align: center;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/260C1A4F59589F9E28&quot; filemime=&quot;image/jpeg&quot; filename=&quot;pic11.png&quot; height=&quot;241&quot; style=&quot;text-align: center;&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위의 그림이 더 명확하다고 생각하지만, 그래도 과정을 설명해보자. 입력 데이터에 대한 R, G, B를 각각 R필터 G필터 B필터와 Convolve한다. 그 결과를 합쳐서 5x5개 중 하나의 결과가 나오는 것이다. 즉 그 과정을 25번 반복해야 최종 결과를 가질 수 있다는 것이다. 위의 결과에 대한 코드는 아래와 같다.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;text-align: center;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2345164F59589F9F1C&quot; filemime=&quot;image/jpeg&quot; filename=&quot;pic12.png&quot; height=&quot;323&quot; style=&quot;text-align: center;&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;포스팅하는데 진짜 오래 걸렸다. 이것만 하는 것이 아니라 개인적으로 벌려놓은 일이 참 많은데.. 같이 하느라 포스팅이 참 늦어졌다. 게다가 포스팅하다가 갑자기 내용이 헷깔려서 다시 공부하고 하느라.. 그래도 결국은 끝냈다. 다음 포스팅은 RNN과 LSTM 정도가 되지 않을까?&lt;/p&gt;&lt;p&gt;&lt;/p&gt;</description>
<category>Deep Learning</category>
<author>빛나유</author>
<guid isPermaLink="true">https://operatingsystems.tistory.com/162</guid>
<comments>https://operatingsystems.tistory.com/entry/Data-Mining-Convolutional-Neural-Network#entry162comment</comments>
<pubDate>Sat, 10 Jun 2017 10:09:50 +0900</pubDate>
</item>
<item>
<title>포스팅 내용에 대하여</title>
<link>https://operatingsystems.tistory.com/entry/%ED%8F%AC%EC%8A%A4%ED%8C%85-%EB%82%B4%EC%9A%A9%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC</link>
<description>&lt;p&gt;한 4년간 꾸준히 블로그를 해오면서 하루 하루 방문하는 사람들 수도 많이 늘었고 뎃글들도 종종 올라온다. 나는 포스팅할 때 나름 공을 들여서 한다. 여기에 이렇게 공을 들일 필요가 있나?라는 생각이 들 정도로 공을 들인다. (참고로 그 답은 '있다'이다) 내 포스팅에 대해서 대부분의 사람들이 좋은 피드백을 주지만, 가끔 보면 매너가 영 꽝인 사람들이 있다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;나도 아직 배울 것들이 너무 많은 한 사람에 불과하다. 포스팅을 쓰다보면 고의가 아니게 잘못된 내용들이 있을 수 있다. 인터넷에 올리는 A-Z까지의 모든 정보가 틀리지 않으면 좋겠지만, 사실 그러기는 힘들다. 그리고 개인의 발전을 위해 애쓰는 중에 아직 제대로 이해를 못 해서 내용에 오류가 있을 수도 있다. 대부분의 사람들이 좋은 뎃글을 남겨주셔서 기분이 좋지만, 가끔은 내용 틀렸다는 식으로 거친 말투를 사용하는 사람도 가끔 있다.(심지어 내용이 틀리지도 않았음) 난 요즘 포스팅할 때 내가 공부했던 참고 자료 링크도 전부 같이 포스팅한다. 내가 몇 일씩 하나만을 위해서 공부를 하는 것처럼 독자분들도 이 글을 읽으면 모든 것을 다 알게 될 것이라는 기대를 버리시고 스스로 학습할 각오를 하셨으면 한다. 이 포스팅은 그저 여러분의 공부길을 조금 아주 조금 편하게 해줄 수 있는 참고자료에 불과하다는 것을 잊지 말아줬으면 한다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아 물론 틀린 내용에 대한 지적은 좋다&lt;/p&gt;&lt;p&gt;A라는 부분이 잘못된 것 같아요 (O)&lt;/p&gt;&lt;p&gt;A는&amp;nbsp;틀린거 아니에요? 왜 내용 제대로 확인도 안하고 이따위로 적어두셨지? (X)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;성격 상 이런 걸로 스트레스 받는 스타일은 아니다. 매너 없는 뎃글이 올라오면 그냥 읽고 잊어버리거나 지워버리면 그만이다. 그런데 한 마디 정도는 해도 되지 않을까 싶어서 이렇게 글을 올린다.&lt;/p&gt;</description>
<author>빛나유</author>
<guid isPermaLink="true">https://operatingsystems.tistory.com/161</guid>
<comments>https://operatingsystems.tistory.com/entry/%ED%8F%AC%EC%8A%A4%ED%8C%85-%EB%82%B4%EC%9A%A9%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC#entry161comment</comments>
<pubDate>Sat, 10 Jun 2017 08:47:56 +0900</pubDate>
</item>
<item>
<title>[Data Mining] Markov Process, Markov Reward Process</title>
<link>https://operatingsystems.tistory.com/entry/Data-Mining-Markov-Process-Markov-Reward-Process</link>
<description>&lt;p&gt;이전 포스팅에서 Reinforcement learning을 공부해봤다. Reinforcement learning의 일부로 Markov Decision Process라는 것이 있는데, 이것을 공부해보려고 한다.&amp;nbsp;그런데 이것을 공부하려면 먼저 Markov Process와 Markov Reward Process를 먼저 공부해야한다. 그래서 이번 포스팅에는 이 두 개를 먼저 설명하고 다음 포스팅에서 Markov Decision Process를 설명하도록 하겠다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;우선 Markov Process이다. 아래와 같은 그래프가 있다고 해보자.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/21549D4458BA31A643&quot; filemime=&quot;image/jpeg&quot; filename=&quot;dm284.png&quot; height=&quot;182&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 그래프를 간략하게 설명하자면... class1에서 class2로 갈 확률이 0.5 페북을 할 확률이 0.5!! 한번 패북을 하면 0.9확률로 계속 페북을 하고.. 뭐 이런 쉬운 그래프이다. 이 그래프에서 여러가지 흐름이 있을 수 있다. 예를 들어서&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;흐름1 : Class1 - Class2 - Class3 - Pub - Class2 - Class3 - Pass - Sleep&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이런 흐름이 있을 수 있다. Markov Process는 다음 State는&amp;nbsp;지금의 State에 의해서 결정된다는 이론이다. 무슨 말이냐면... 위의 흐름에서 Pub에서 Class2로 가는 것은 이전에 어떤 흐름을 거쳤든 오로지 Pub→Class2의 확률에 의해 결정된다는 것이다. 이전에 Class1에 있었든 pub에 있었든 페북을 했든 상관이 없고 오로지 현재 Pub에 있다는 사실에 의해 결정된다는 것이다. No History At All!! 이것이 Markov Process이다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위의 그래프에서 각각의 State에서 다음 State로 넘어가는 확률을 조건부 확률로 표현할 수 있다. 예를 들어 Class1에서 Class2로 넘어가는 확률은 P(Class2|Class1)으로 나타내고 그 값은 0.5가 된다. 이런 조건부 확률을 아래와 같이 표로 나타낼 수 있다.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2252F94458BA31A716&quot; filemime=&quot;image/jpeg&quot; filename=&quot;dm285.png&quot; height=&quot;206&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://www0.cs.ucl.ac.uk/staff/d.silver/web/Teaching_files/MDP.pdf&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;http://www0.cs.ucl.ac.uk/staff/d.silver/web/Teaching_files/MDP.pdf&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Markov Reward Process는 Markov Process에 Reward 개념을 추가한 것이다. 위의 그래프에서 아래와 같이 Reward를 추가해보자.&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/276BD54458BA31A80E&quot; filemime=&quot;image/jpeg&quot; filename=&quot;dm286.png&quot; height=&quot;181&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Markov Reward Process에서는 Value라는 개념이 나온다. 각 State는 각각의 Value를 갖는데, 이 Value는 '값'이 아닌 '가치'의 Value이다. Value와 Reward가 둘다 '좋은 것'이기 때문에 헷깔릴 수 있다. 헷깔리지 말자. &lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;Value와 Reward는 다른 것이다.&lt;/span&gt;&amp;nbsp;Value는 그 State에 있을 때 최종 목적을 이룰 수 있는 잠재력을 의미한다. 그 State에 있을 때의 당장의 이득(Reward)가 아닌 최종적으로 목적을 이룰 수 있는 잠재력을 의미한다. 예를 들어 아침에 일찍 일어나서 공부를 하는 것은 매우 힘든 일이다. 당장은 몸도 힘들고 그날 하루가 조금 힘들어질 수도 있다. 하지만 장기적으로 봤을 때 아침 일찍 일어나서 공부를 하면 그만큼 성실해지고 그만큼 성공적인 삶을 살 확률도 높아진다. 따라서 '아침공부'라는 State가 있다면 그것은 Reward는 작아도 Value는 클 수 있다는 것이다. 다시 한번 말한다. Value와 Reward는 다르다. 그러면 우리가 Value는 어떻게 구하는지 한번 알아보자.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;Value Function으로 Value를 구하는데 Value Function에는 gamma라는 파라미터가 들어간다. 이 gamma는 항상 0과 1 사이의 값인데, 0에 가까울 때는 당장의 이득만 쫒아가면서 value를 계산하고, 1에 가까울 때는 멀리보고 value를 계산하게 된다. 식을 보면 이 말이 이해가 된다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;지금(t)에서의 Value는 아래와 같이 계산될 수 있다.&lt;/p&gt;&lt;p&gt;V(t) = Reward(t) + gamma*E( Reward(t+1) * p(state(t+1)|state(t)) )&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;gamma가 극단적으로 0이면 gamma^1*Reward(t+1)와 이후 부분이 모두 0이 되므로 현재의 Reward인 Reward(t)가 V(t)가 되버린다. 즉 미래에 얻을 Reward는 하나도 생각 안 하겠다는 것이다. 한번 예를 들어서 Value 하나를 계산해보자.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Value(Class3) = Reward(Class3)&amp;nbsp;+ gamma*(p(Pub|Class3)*Reward(Pub)&amp;nbsp;+ p(PASS|Class3)*Reward(PASS))&lt;/p&gt;&lt;p&gt;Value(Class3) = -2 + gamma*(0.4*1 + 0.6*10)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;gamma = 0.9로 놓으면,&lt;/p&gt;&lt;p&gt;Value(Class3) = -2 + 0.9*(0.4*1 + 0.6*10)&amp;nbsp;&lt;/p&gt;&lt;p&gt;Value(Class3) = -2 + 0.9*(6.4)&lt;/p&gt;&lt;p&gt;Value(Class3) = -2 + 5.76&lt;/p&gt;&lt;p&gt;Value(Class3) = 3.76&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이것을 각 state 마다 계속 반복하면 거의 변하지 않는 어떤 상태로 Converge되는데 그 결과는 아래와 같다. 코딩한 것도 같이 업로드했으니 같이 참고해보기 바란다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;# 코드 : state.py&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/223B074458BA31AA07&quot; filemime=&quot;image/jpeg&quot; filename=&quot;dm289.png&quot; height=&quot;170&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;※ value는 최초에는 reward 값으로 초기화된다. 이 값은 Markov Reward Process를 거치면서 업데이트된다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;# 코드 : markov_reward_process.py&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2164984458BA31A910&quot; filemime=&quot;image/jpeg&quot; filename=&quot;dm288.png&quot; height=&quot;466&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;# 결과&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:231px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/215E704458BA31A812&quot; filemime=&quot;image/jpeg&quot; filename=&quot;dm287.png&quot; height=&quot;144&quot; width=&quot;231&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;이게 Markov Reward Process이다. 여기에 Action 개념을 추가한 것이 Markov Decision Process이다. 반대로 말하면 Markov Decision Process에서 Action이 완전히 정해진 것이 Markov Reward Process인데 아무튼 우리는 Markov Decision Process에 대해서는 다음 포스팅에서 더 자세히 공부해보도록 하자.&lt;/p&gt;</description>
<category>Data Mining</category>
<author>빛나유</author>
<guid isPermaLink="true">https://operatingsystems.tistory.com/160</guid>
<comments>https://operatingsystems.tistory.com/entry/Data-Mining-Markov-Process-Markov-Reward-Process#entry160comment</comments>
<pubDate>Sat, 04 Mar 2017 12:23:14 +0900</pubDate>
</item>
<item>
<title>[Data Mining] Reinforcement Learning</title>
<link>https://operatingsystems.tistory.com/entry/Data-Mining-Reinforcement-Learning</link>
<description>&lt;p&gt;오랜만에 포스팅이다. Reinforcement learning을 공부해보자. 한글로는 강화학습이라고 하는데 사실은 이 분야는 Data Mining이라기보다는 Machine Learning 부분이다. 그런데 Data Mining 폴더에 집어넣는 이유는... 모르겠다. 아무튼 Reinforcement learning을 공부해보자.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이번 포스팅에서는 Reinforcement learning의 개념을 알아보려고 한다. 우선 Supervised learning을 먼저 생각해보자. 이 개념은 아주 간단하다. 주어진 데이터를 기반으로 학습을 진행하여 학습되지 않은 데이터에 대해서 예측을 하는 것이다. 단, 그 학습을 할 때 사용되는 데이터는 반드시 레이블을 가지고 있어야 한다. 이것이 Supervised learning이다. Supervised learning은 기본적으로 데이터를 가지고 학습이 진행된다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그런데 Reinforcement learning은 조금 개념이 다르다. 일단 데이터 뭐 이런거 잊어보자. 내가 알파고(Agent)를 만든다고 해보자. 이 알파고의 최종&amp;nbsp;목적은 바둑을 둬서 이기는 것이다. 알파고는 이기면 항상 보상을(Reward)&amp;nbsp;받게 된다. 그런데 알파고는 이길 수도 있고 질 수도 있다. 뭐에 따라서? 상대방이 어떻게 두느냐에 따라서(환경). 상대방이 어떻게 두더라도(여러 환경) 알파고는 최대한 이길 수 있는 수를(Reward를 쫒아서)&amp;nbsp;두도록 학습해간다.&amp;nbsp; 바둑이라는 예로 Reinforcement learning을 설명해봤다. 한 가지 예를 더 들어보자. 탁구를 치는 로봇을(Agent) 만든다고 해보자. 그 로봇은 오는 공을 받아칠 때마다 잘했다고 칭찬을 받는다(Reward). 상대방은 여러 방향에서 다각도로 공을 준다(여러 환경). 로봇은 상대방이 주는 공을 항상 받아칠 수 있도록 계속적으로 Reward를 쫓아서 학습되어간다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;조금 더 이론적으로 설명해볼까?&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Agent가 (알파고, 탁구로봇)&lt;/p&gt;&lt;p&gt;주어진 환경에 대하여 (상대방이 두는 바둑 수, 상대방이 치는 탁구)&lt;/p&gt;&lt;p&gt;Reward를 얻을 수 있는 (바둑을 이기기, 상대방의 공을 잘 쳐내기)&lt;/p&gt;&lt;p&gt;방향으로 계속 학습해나가는 것 (상황에 따른 최고의 바둑 수를 두기, 상황에 따른 최적의 각도와 힘으로 공을 쳐내기)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;바둑을 예로 한번 더 설명해보자. Reinforcement learning을 하는 과정을 보면 알파고가 여러가지의 기보 데이터를 가지고 학습을 진행한다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;기보1 : A, B, C, D, E, ..., Z → 승리&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;알파고가 A를 두고 상대방이 뭐를 뒀을 것이고 그 상태에서 B를 두고 상대방이 또 뭐를 뒀을 것이고 그 상태에서 C를 또 두고 이런 식이다.&amp;nbsp;이 기보의 결과가 승리라고 해보자. 그럼 알파고는 A, B, C...Z까지의 결정을 올바른 결정이라고 학습한다. 그런데 이게 상식적으로 맞나? 아니다. 예를 들어 B가 실수여도 나머지를 잘 둬서 결론적으로 승리를 할 수 있다. 반대로 특정 수를 매우 잘 뒀어도 나머지를 잘못둬서 결론적으로 패배했을 수도 있다. 그런데 강화학습에서는 이것들이 계속적으로 반복되어 수많은 기보로부터 학습을 하면 그&amp;nbsp;영향이 사라진다고 말하고 있다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 과정을 다시 한번 예제로 들어보자.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;DeepMind에서 스타크래프트를 하는 인공지능도 개발 중이라고 하는데, 스타크래프트를 예로 들어서 설명해보자. 수 많은 스타크래프트 개임 데이터가 있다고 하자. 그 중에 한 경기가 아래와 같이 흘러갔다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;스타1 : 벙커링 실패, 저글링러쉬로 본진이 거의 초토화, 드랍십공격 성공, 베틀크루져생산, 저크폭탄드랍방어 → 승리&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;자 대충 이런 경기가 있었다고 해보자. 이 태란 유저는 승리를 했다. 그런데 벙커링 실패하고 저글링러쉬로 본진이 거의 초토화됐는데 역전승을 한 경우이다. 강화학습에서는 이런 경우에도 벙커링 실패한 것과 저글링러쉬로 본진이 거의 초토화된 상태에 대해서도 올바른 결정으로 판단을 한다는 것이다. 단, 이런 경우는 거의 없기 때문에 스타크래프트 데이터를 계속적으로 학습하다보면 그 영향은 사라진다는 것이다.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이제 다시 이론적으로 말해보자. 강화학습은 어떤 agent가 최종적으로 reward를 얻기 위하여 그 과정의 행동 결정 하나하나를 최고의 행동으로 결정하는 것을 반복하여, 최종적으로 optimal한 decision process를 갖춘 agent를 만드는 과정인 것이다. 아래의 그림을 봐보자.&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2646923E58BA0CA416&quot; filemime=&quot;image/jpeg&quot; filename=&quot;dm280.png&quot; height=&quot;285&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;/p&gt;&lt;p&gt;이 그림에서 START state에서 로봇이 움직인다. +Reward로 가면 성공, -Reward로 가면 실패이다. 그렇게 가기 위해서 로봇은 이리저리 움직인다. 벽면에 부딧히기도 할 것이고 실패도 하고 성공도 할 것이다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/235C254258BA0D2B23&quot; filemime=&quot;image/jpeg&quot; filename=&quot;dm282.png&quot; height=&quot;289&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그런데 계속적으로 로봇을 훈련을 시키면 가장 Optimal하게 아래와 같이 간다&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;text-align: center;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2479A03E58BA0CA51C&quot; filemime=&quot;image/jpeg&quot; filename=&quot;dm281.png&quot; height=&quot;285&quot; style=&quot;text-align: center;&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이렇게 움직이는 거를 아래와 같이 구현해봤다.&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/256E083758BA13C51A&quot; filemime=&quot;image/jpeg&quot; filename=&quot;dm283.png&quot; height=&quot;213&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;위의 그림이 강화학습을 한 최종 결과인데, EAST, NORTH, WEST, SOUTH는 각각 그 방향으로 움직일 확률을 의미한다. 즉, 7에서 0.84의 확률로 EAST로 움직이고, 6에서 0.88의 확률로 NORTH, 5에서 0.92의 확률로 NORTH, 4에서 0.96의 확률로 다시 EAST로 가면 결국 +REWARD(PEND)로 가게 된다는 것이다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;※ 여기서 이해하기 쉽게 설명하기 위해서 저 숫자를 확률이라고 했는데, 사실은 확률이 아니라 그 State에 있는 value 값이다. 이것에 대해서는 다음 포스팅에 설명하려고 하니 여기서는 그냥 확률 정도로 이해하는 것이 편할 것 같다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;다음 포스팅에서는 Reinforcement learning에 대한 개요는 끝내고 조금 더 디테일하게 Reinforcement learning의 Markov Reward Process에 대하여 이야기 해보려고 한다.&lt;/p&gt;</description>
<category>Data Mining</category>
<author>빛나유</author>
<guid isPermaLink="true">https://operatingsystems.tistory.com/159</guid>
<comments>https://operatingsystems.tistory.com/entry/Data-Mining-Reinforcement-Learning#entry159comment</comments>
<pubDate>Sat, 04 Mar 2017 00:41:26 +0900</pubDate>
</item>
<item>
<title>[Semantic Web] OWL (Web Ontology Language)</title>
<link>https://operatingsystems.tistory.com/entry/OWL-Web-Ontology-Language</link>
<description>&lt;p cxspfirst&quot;=&quot;&quot;&gt;&lt;span&gt;OWL&lt;/span&gt;을 설명해보자&lt;span&gt;.
OWL&lt;/span&gt;은&lt;span&gt; Web Ontology Language&lt;/span&gt;의 약자로 &lt;span&gt;WOL&lt;/span&gt;이라고 하면 뭔가 읽기도 이상해서 &lt;span&gt;OWL&lt;/span&gt;이라고 살짝 순서를 바꿔서
약자를 지었다고 한다&lt;span&gt;. &lt;/span&gt;지금까지 이전 포스팅에서 설명한 &lt;span&gt;RDFS&lt;/span&gt;까지의
내용을 보면 확실히 뭔가 세상의 물체의 개념은 설명이 가능할 것 같다&lt;span&gt;. &lt;/span&gt;그렇지만 아직 관계는 그렇게
확실하게 설명하지 못한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p cxsplast&quot;=&quot;&quot;&gt;예를 들어&lt;span&gt;, &lt;/span&gt;지금까지 &lt;span&gt;RDFS&lt;/span&gt;를 통해서 &lt;span&gt;person Class&lt;/span&gt;는 &lt;span&gt;animal Class&lt;/span&gt;의 &lt;span&gt;subclass&lt;/span&gt;라는 것을 명시할 수 있다고
했다&lt;span&gt;. &lt;/span&gt;그런데 이 정도 수준이 전부이다&lt;span&gt;. RDFS&lt;/span&gt;로 &lt;span&gt;DateOfBirth Class&lt;/span&gt;와 &lt;span&gt;BirthDay Class&lt;/span&gt;가 같은
&lt;span&gt;Class&lt;/span&gt;라는 것을 알 수 있나&lt;span&gt;? &lt;/span&gt;모른다&lt;span&gt;. RDFS&lt;/span&gt;에서는 이 두 &lt;span&gt;Class&lt;/span&gt;는 그저 서로 다른 &lt;span&gt;Class&lt;/span&gt;일 뿐이다&lt;span&gt;. &lt;/span&gt;즉&lt;span&gt;, RDFS&lt;/span&gt;로는
컴퓨터가 &lt;span&gt;DateOfBirth&lt;/span&gt;와 &lt;span&gt;BirthDay&lt;/span&gt;가 같은 것을
의미한다는 것을 모른다&lt;span&gt;. &lt;/span&gt;또 다른 예를 들어보자&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxsplast&quot;=&quot;&quot; style=&quot;text-indent: 0px; &quot;&gt;&lt;span style=&quot;text-indent: -20pt;&quot;&gt;- John is a Father of Michael.&lt;/span&gt;&lt;/p&gt;&lt;p cxsplast&quot;=&quot;&quot; style=&quot;text-indent: 0px; &quot;&gt;&lt;span style=&quot;text-indent: -20pt;&quot;&gt;- Marry is a John’s sister.&lt;/span&gt;&lt;/p&gt;&lt;p cxsplast&quot;=&quot;&quot; style=&quot;text-indent: 0px; &quot;&gt;&lt;span style=&quot;text-indent: -20pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;이 두 문장으로 예를 들어보자&lt;span&gt;. John&lt;/span&gt;이 &lt;span&gt;Michael&lt;/span&gt;의 아버지고 &lt;span&gt;Marry&lt;/span&gt;가 &lt;span&gt;John&lt;/span&gt;의 여동생이니까&lt;span&gt;, &lt;/span&gt;우리는 굳이 말하지 않아도 &lt;span&gt;Michael&lt;/span&gt;의 이모는 &lt;span&gt;Marry&lt;/span&gt;라는 것을 안다&lt;span&gt;. &lt;/span&gt;그런데 컴퓨터는&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;text-indent: -20pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;text-indent: -20pt;&quot;&gt;Marry is an aunt of Michael&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;text-indent: -20pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p cxspfirst&quot;=&quot;&quot;&gt;이라고 명시해주지 않는 이상 모른다&lt;span&gt;. &lt;/span&gt;이것을 어떻게
컴퓨터도 알 수 있게 할까&lt;span&gt;? &lt;/span&gt;컴퓨터가 &lt;span&gt;Class&lt;/span&gt;간의 관계를
이해하고 추론할 수 있게 하기 위해서 우리는 &lt;span&gt;Ontology&lt;/span&gt;를 이용하는 것이다&lt;span&gt;. &lt;/span&gt;이제 본격적으로&lt;span&gt; Ontology&lt;/span&gt;를 이용해서 구체적으로 어떤 방법으로
&lt;span&gt;Class&lt;/span&gt;간의 관계를 명시하는지를 설명해보자&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p cxsplast&quot;=&quot;&quot;&gt;대학교를 설명하는 &lt;span&gt;Ontology&lt;/span&gt;를 만든다고 할 때&lt;span&gt;, &lt;/span&gt;기본적으로 몇몇 &lt;span&gt;Class&lt;/span&gt;가 있을 것이다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxsplast&quot;=&quot;&quot; style=&quot;text-indent: 0px; &quot;&gt;&lt;span style=&quot;text-indent: -20pt;&quot;&gt;- Student&lt;/span&gt;&lt;/p&gt;&lt;p cxsplast&quot;=&quot;&quot; style=&quot;text-indent: 0px; &quot;&gt;&lt;span style=&quot;text-indent: -20pt;&quot;&gt;- Professor&lt;/span&gt;&lt;/p&gt;&lt;p cxsplast&quot;=&quot;&quot; style=&quot;text-indent: 0px; &quot;&gt;&lt;span style=&quot;text-indent: -20pt;&quot;&gt;- Course&lt;/span&gt;&lt;/p&gt;&lt;p cxsplast&quot;=&quot;&quot; style=&quot;text-indent: 0px; &quot;&gt;&lt;span style=&quot;text-indent: -20pt;&quot;&gt;- Lab&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;이 &lt;span&gt;Class&lt;/span&gt;들 사이에는 당연히 아래와 같은 관계들이 존재한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-indent: 0px; &quot;&gt;&lt;span style=&quot;text-indent: -20pt;&quot;&gt;- Professor Teach Student&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-indent: 0px; &quot;&gt;&lt;span style=&quot;text-indent: -20pt;&quot;&gt;- Student BelongsTo Lab&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-indent: 0px; &quot;&gt;&lt;span style=&quot;text-indent: -26.6667px;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;text-indent: -26.6667px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-indent: -20pt;&quot;&gt;Lab IsOwnedBy Professor&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-indent: 0px; &quot;&gt;&lt;span style=&quot;text-indent: -26.6667px;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;text-indent: -26.6667px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-indent: -20pt;&quot;&gt;Student Take several Course&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-indent: 0px; &quot;&gt;&lt;span style=&quot;text-indent: -20pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p cxspfirst&quot;=&quot;&quot;&gt;더 많이 만들 수 있지만 예제로 간단하게 만드는 것이니 이 정도만 하기로 하자&lt;span&gt;. &lt;/span&gt;살짝 부연 설명을 하면&lt;span&gt;, “&lt;/span&gt;모든 교수들은 학생들을 가르친다&lt;span&gt;”&lt;/span&gt;는 당연한 이야기이다&lt;span&gt;. “&lt;/span&gt;마찬가지로 학생들이 &lt;span&gt;Lab&lt;/span&gt;에 속한다&lt;span&gt;” &lt;/span&gt;역시 당연한 것이다&lt;span&gt;.
(&lt;/span&gt;그렇다고 하자&lt;span&gt;) &lt;/span&gt;위의 네 문장을&lt;span&gt; OWL&lt;/span&gt;로 표현을
하면 이와 같이 표현할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspfirst&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:450px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2724FC4D5897AE4420&quot; filemime=&quot;image/jpeg&quot; filename=&quot;sw14.png&quot; height=&quot;328&quot; width=&quot;450&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p cxspfirst&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;위와 같이 정의를 해두면 가령 누군가가&lt;span&gt; Student&lt;/span&gt;가
&lt;span&gt;Professor&lt;/span&gt;를 &lt;span&gt;Teach&lt;/span&gt;한다라고 썼을 경우 오류가 나게
된다&lt;span&gt;. &lt;/span&gt;즉 &lt;span&gt;“Student Teach Professor”&lt;/span&gt;가
잘못된 문장이라는 것을 컴퓨터가 이해할 수 있게 된다&lt;span&gt;. Ontology&lt;/span&gt;에서 이와 같은 것을 &lt;span&gt;Object Property&lt;/span&gt;라고 한다&lt;span&gt;. &lt;/span&gt;객체들이 가져야 되는 속성이라는
것이다&lt;span&gt;. Teach&lt;/span&gt;라는 것은 반드시 주어 부분에 &lt;span&gt;Professor&lt;/span&gt;가
와야 하고 목적어 부분에는 &lt;span&gt;Student&lt;/span&gt;가 와야 된다는 속성이라는 말이다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;DataType Property&lt;/span&gt;라는 것도 있다&lt;span&gt;. &lt;/span&gt;이것도 어려운 내용은 아니다&lt;span&gt;. &lt;/span&gt;예를 들어 모든 학생은 나이가 있다&lt;span&gt;. &lt;/span&gt;그래서 아래와 같이 정수&lt;span&gt;(Integer)&lt;/span&gt;형으로 &lt;span&gt;age&lt;/span&gt;의 &lt;span&gt;DataType&lt;/span&gt;을 &lt;span&gt;Student&lt;/span&gt;에
대하여 정의해준다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspfirst&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2502CE4D5897AE4522&quot; filemime=&quot;image/jpeg&quot; filename=&quot;sw15.png&quot; height=&quot;52&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p cxspfirst&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;age&lt;/span&gt;라는 것은 반드시 그 범위가 음수가 아닌 정수여야
한다는 것을 명시적으로 정의해준 것이다&lt;span&gt;. &lt;/span&gt;이렇게 해두면 누군가가 &lt;span&gt;“&lt;/span&gt;학생
&lt;span&gt;John&lt;/span&gt;의 나이는 &lt;span&gt;-10&lt;/span&gt;살이다&lt;span&gt;”&lt;/span&gt;라고 했을 때 컴퓨터가 그것이 틀렸다는 것을 알 수 있게 된다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;이제 &lt;span&gt;OWL&lt;/span&gt;이 어떤 면에서 &lt;span&gt;Class&lt;/span&gt;들간의 관계를 설명한다는 것인지 어느 정도 감이 올 것이다&lt;span&gt;. &lt;/span&gt;추가적으로
몇 개를 더 해보자&lt;span&gt;. &lt;/span&gt;가령 이런 것도 가능하다&lt;span&gt;. “&lt;/span&gt;생일&lt;span&gt;”&lt;/span&gt;과 &lt;span&gt;“&lt;/span&gt;태어난 날&lt;span&gt;”&lt;/span&gt;이라는
&lt;span&gt;Class&lt;/span&gt;가 같다는 것은 아래와 같이 정의할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspfirst&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:451px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2524794D5897AE4620&quot; filemime=&quot;image/jpeg&quot; filename=&quot;sw16.png&quot; height=&quot;53&quot; width=&quot;451&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p cxspfirst&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p cxspfirst&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span&gt;equivalentClass &lt;/span&gt;구문을 이용해서&lt;span&gt; BirthDay&lt;/span&gt;와 &lt;span&gt;DateOfBirth&lt;/span&gt;가 같은 &lt;span&gt;Class&lt;/span&gt;라는 것을 명시해줬다&lt;span&gt;. &lt;/span&gt;반대 관계도 표현할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot; align=&quot;left&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:446px;text-align: center;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2314C84D5897AE4622&quot; filemime=&quot;image/jpeg&quot; filename=&quot;sw17.png&quot; height=&quot;87&quot; style=&quot;text-align: center;&quot; width=&quot;446&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;Teach&lt;/span&gt;와 &lt;span&gt;IsToughtBy&lt;/span&gt;는
반대말이라는 것을 추가적으로 명시해줬다&lt;span&gt;. &lt;/span&gt;따라서 &lt;span&gt;Teach&lt;/span&gt;는
주어 부분에 &lt;span&gt;Professor&lt;/span&gt;를 두고 목적어 부분에는 &lt;span&gt;Student&lt;/span&gt;를
두며 &lt;span&gt;IsToughtBy&lt;/span&gt;와는 반대관계라는 것을 정의할 수 있다&lt;span&gt;. &lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;지금까지 설명한 내용들은 &lt;span&gt;OWL&lt;/span&gt;을 이해하기 위함이지
그것의 전부가 아니다&lt;span&gt;. OWL&lt;/span&gt;에서 관계를 표현할 수 있는 방법은 무수히 많고 지금까지 설명한 것은 빙산의
일각에 불과하다&lt;span&gt;. &lt;/span&gt;실제로 구현된 &lt;span&gt;Ontology&lt;/span&gt;로 &lt;span&gt;Google&lt;/span&gt;의 &lt;span&gt;Knowledge Graph&lt;/span&gt;와 &lt;span&gt;Facebook&lt;/span&gt;의&lt;span&gt; Graph Search&lt;/span&gt;를 보자&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;# Google’s Knowledge Graph&lt;/span&gt;&lt;/p&gt;&lt;p cxspfirst&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/27674E4D5897AE4620&quot; filemime=&quot;image/jpeg&quot; filename=&quot;sw18.jpg&quot; height=&quot;281&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p cxspfirst&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;a href=&quot;http://searchengineland.com/laymans-visual-guide-googles-knowledge-graph-search-api-241935&quot;&gt;http://searchengineland.com/laymans-visual-guide-googles-knowledge-graph-search-api-241935&lt;/a&gt;&lt;/p&gt;&lt;p cxspfirst&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;# Facebook’s Graph Search&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot; align=&quot;left&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:482px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/21192C4D5897AE471F&quot; filemime=&quot;image/jpeg&quot; filename=&quot;sw19.png&quot; height=&quot;300&quot; width=&quot;482&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;&lt;a href=&quot;https://neo4j.com/blog/why-the-most-important-part-of-facebook-graph-search-is-graph/&quot;&gt;https://neo4j.com/blog/why-the-most-important-part-of-facebook-graph-search-is-graph/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;























































































&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;이것으로 &lt;span&gt;Ontology&lt;/span&gt;에 대한 설명은 마치려고
한다&lt;span&gt;. &lt;/span&gt;다음 포스팅은 뭐가 될지 모르겠지만 뭔가 비슷한 분야가 되지 않을까 싶다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;</description>
<category>etc...</category>
<author>빛나유</author>
<guid isPermaLink="true">https://operatingsystems.tistory.com/158</guid>
<comments>https://operatingsystems.tistory.com/entry/OWL-Web-Ontology-Language#entry158comment</comments>
<pubDate>Mon, 06 Feb 2017 08:01:24 +0900</pubDate>
</item>
<item>
<title>[Semantic Web] RDFS</title>
<link>https://operatingsystems.tistory.com/entry/RDFS</link>
<description>&lt;p cxspfirst&quot;=&quot;&quot;&gt;&lt;span&gt;RDFS &lt;/span&gt;개념은&lt;span&gt;
Object-Oriented Programming &lt;/span&gt;개념과 거의 같다고 보면 된다&lt;span&gt;. OOP&lt;/span&gt;에
대해서는 아래의 &lt;span&gt;Link&lt;/span&gt;에 포스팅을 해두었으니 &lt;span&gt;OOP&lt;/span&gt;에 대해서
전혀 모르는 분들은 참고하길 바란다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;Link : &lt;a href=&quot;http://operatingsystems.tistory.com/entry/Programming-OOP&quot;&gt;http://operatingsystems.tistory.com/entry/Programming-OOP&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;RDFS&lt;/span&gt;는 이전 포스팅에서 이야기했듯이&lt;span&gt;, &lt;/span&gt;세상의 모든 사물과 개념들을 표현하기 위한 기본 틀이 필요하다&lt;span&gt;. &lt;/span&gt;예를
들어&lt;span&gt;, &lt;/span&gt;사람을 표현할 때는 나이&lt;span&gt;, &lt;/span&gt;키&lt;span&gt;, &lt;/span&gt;몸무게&lt;span&gt;, &lt;/span&gt;시력 등등의 개념들이 필요하다&lt;span&gt;. &lt;/span&gt;따라서 사람을 표현하기 위한 기본 틀은 위와 같은 요소들을 가지고 있어야 한다&lt;span&gt;. &lt;/span&gt;우리가 앞으로 이 기본 틀을 &lt;span&gt;Class&lt;/span&gt;라고 부를 것이다&lt;span&gt;. OOP&lt;/span&gt;에서도&lt;span&gt; Class&lt;/span&gt;라고 부른다&lt;span&gt;.
Java&lt;/span&gt;로는 아래와 같이 표현할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:280px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/24450B505897AD5E16&quot; filemime=&quot;image/jpeg&quot; filename=&quot;sw8.png&quot; height=&quot;98&quot; width=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;위 &lt;span&gt;Class&lt;/span&gt;를 이용해서 우리는 각각의 객체들을
생성해낼 수 있다&lt;span&gt;. &lt;/span&gt;위의 &lt;span&gt;Person Class&lt;/span&gt;를 가지고
우리는 무수히 많은 사람들을&lt;span&gt;(&lt;/span&gt;객체들을&lt;span&gt;) &lt;/span&gt;생성해낼 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:291px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2745ED505897AD5F1D&quot; filemime=&quot;image/jpeg&quot; filename=&quot;sw9.png&quot; height=&quot;39&quot; width=&quot;291&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;이와 같은 원리를 똑같이 &lt;span&gt;RDF&lt;/span&gt;를 통해 살펴보자&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/233446505897AD5F17&quot; filemime=&quot;image/jpeg&quot; filename=&quot;sw10.png&quot; height=&quot;153&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;왼쪽의 코드가 오른쪽의 그래프로 표현이 가능하다는 말이다&lt;span&gt;.
(&lt;/span&gt;엄밀히 말하면 뭔가 하나가 추가되어야 하는데 개념을 이해하는데는 위의 그래프로도 무방하다&lt;span&gt;. &lt;/span&gt;무시해도
좋다&lt;span&gt;.) &lt;/span&gt;위의 그래프는 &lt;span&gt;Class&lt;/span&gt;만 표현이 되어있는데 한번
&lt;span&gt;person &lt;/span&gt;객체 &lt;span&gt;john&lt;/span&gt;을 추가해보자&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/254F61505897AD6017&quot; filemime=&quot;image/jpeg&quot; filename=&quot;sw11.png&quot; height=&quot;181&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot; style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;animal, person, horse&lt;/span&gt;는 &lt;span&gt;class&lt;/span&gt;이고 &lt;span&gt;john&lt;/span&gt;은 객체이기 때문에 모양을 다르게 그려놨다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;RDF&lt;/span&gt;에서 데이터를 문장처럼 하나하나씩 설명을 하고
있다면&lt;span&gt;, RDFS&lt;/span&gt;에서는 &lt;span&gt;Class&lt;/span&gt;라는 개념을 통해서 데이터가
실제 세계와 비슷하게 그려질 수 있도록 관계를 나타내주고 있다&lt;span&gt;. &lt;/span&gt;이와 같이 &lt;span&gt;Class&lt;/span&gt;의 구조를 설명하는 것 이외에 &lt;span&gt;RDFS&lt;/span&gt;가 할 수 있는 것은
각&lt;span&gt; Class&lt;/span&gt;의 특징들을 명시해줄 수 있다는 것이다&lt;span&gt;. &lt;/span&gt;예를
들어 &lt;span&gt;RDFS&lt;/span&gt;에서&lt;span&gt; subClassOf&lt;/span&gt;을 통해 어떤 &lt;span&gt;Class&lt;/span&gt;가 어떤 &lt;span&gt;Class &lt;/span&gt;밑에 있는 것인지 명시해줄 수 있다&lt;span&gt;. &lt;/span&gt;사실 위에서 이미 적어뒀는데&lt;span&gt;, person Class&lt;/span&gt;는 &lt;span&gt;animal Class&lt;/span&gt;의 &lt;span&gt;subClass&lt;/span&gt;가 되기 때문에 &lt;span&gt;RDFS&lt;/span&gt;를 작성할 때 반드시 아래와&lt;span&gt; rdfs:subClassOf&lt;/span&gt;로 명시를
해줘야 한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:500px;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/234171505897AD601B&quot; filemime=&quot;image/jpeg&quot; filename=&quot;sw12.png&quot; height=&quot;162&quot; width=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot; align=&quot;left&quot;&gt;이와 같이 특정 &lt;span&gt;Class&lt;/span&gt;의 특징들을 명시해주는 것이 아래와 같이 여러 개 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot; align=&quot;left&quot; style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display:inline-block;width:204px;text-align: center;;height:auto;max-width:100%&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/244FF5505897AD6017&quot; filemime=&quot;image/jpeg&quot; filename=&quot;sw13.png&quot; height=&quot;169&quot; style=&quot;text-align: center;&quot; width=&quot;204&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;위의 것들은 지금 설명하지 않고 다음 포스팅에서 설명할 &lt;span&gt;OWL&lt;/span&gt;을
설명하면서 이야기하려고 한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;지금 이 시점에서 &lt;span&gt;Linked Data&lt;/span&gt;의 개념을
다시 생각해보자&lt;span&gt;. Linked Data&lt;/span&gt;는 결국 데이터가 어떻게 이어져 있는지를 설명해주는 것이다&lt;span&gt;. &lt;/span&gt;그것이 결국 &lt;span&gt;RDFS&lt;/span&gt;와 같이 구조적으로&lt;span&gt; Class&lt;/span&gt;들이 서로 이어져 있는 형태로 존재한다는 것이다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;















































&lt;/p&gt;&lt;p cxspmiddle&quot;=&quot;&quot;&gt;다음 포스팅에서는 조금 더 &lt;span&gt;OWL&lt;/span&gt;을 설명하려고 한다&lt;span&gt;. OWL&lt;/span&gt;은 &lt;span&gt;Web Ontology Language&lt;/span&gt;의 약자이고&lt;span&gt;, &lt;/span&gt;이것을 통해 진정 &lt;span&gt;Ontology &lt;/span&gt;개념을 설명할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;</description>
<category>etc...</category>
<author>빛나유</author>
<guid isPermaLink="true">https://operatingsystems.tistory.com/157</guid>
<comments>https://operatingsystems.tistory.com/entry/RDFS#entry157comment</comments>
<pubDate>Mon, 06 Feb 2017 07:57:00 +0900</pubDate>
</item>
</channel>
</rss>