-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
377 lines (240 loc) · 154 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>JimintheBox</title>
<link href="/atom.xml" rel="self"/>
<link href="https://jimheo.github.io/"/>
<updated>2023-09-21T12:34:47.487Z</updated>
<id>https://jimheo.github.io/</id>
<author>
<name>Jim</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>딥러닝, 처음 접하는 사람들을 위한 기초</title>
<link href="https://jimheo.github.io/2021/07/27/deep-learning-from-scratch/"/>
<id>https://jimheo.github.io/2021/07/27/deep-learning-from-scratch/</id>
<published>2021-07-27T07:33:59.000Z</published>
<updated>2023-09-21T12:34:47.487Z</updated>
<content type="html"><![CDATA[<h2 id="들어가며"><a href="#들어가며" class="headerlink" title="들어가며"></a>들어가며</h2><p>올해 상반기, 나의 최대 관심사는 무엇보다도 <strong><code>졸업(!!!)</code></strong>이었다. 많은 대학원생들이 으레 그렇듯 예상치 못한 사정으로 졸업이 예정보다 반년 늦어졌고 그마저도 더 늦어지겠다 싶어 모든 우선 순위를 제쳐두고 학위 논문을 준비하게 되었다.</p><p>그렇게 1월 말부터 논문을 구상하고 작성하며 시간이 흘렀고, 실험 과정에서 굉장히 많은 시행 착오도 겪었다. 두 번의 발표와 도장을 받기위해 교수님들께 메일을 보내고 돌아다니며 모든 서류 제출을 끝내고 나니 6월이 되어있었다. 그렇게 학위 논문을 모두 제출하고 대학원과 관련된 모든 것을 털어내고서야 드디어 <strong>석사(진)</strong>이 되었다.</p><p>그래도 8월까지는 학생이니만큼 학생 신분의 마지막이 지나기 전에 자축의 의미로 본 포스팅을 작성하기로 하였다. 사실, 2년 반 동안의 지난했던 기간의 회고를 할까도 생각했지만 너무 할 말<del>(못 할 말)</del>이 많아지기 때문에 다소 식상하지만 학위 논문을 작성하면서 정리했던 인공지능의 발전사와 개략적인 개념을 최대한 많은 사람들이 이해할 수 있도록 포스팅에 설명해보기로 했다.</p><a id="more"></a><br><center><img src="/images/deep-learning-from-scratch/simpson_graduate_student.jpeg" width="50%"><font size="2" color="gray"> 아..아앗...아니야...!!<font></font></font></center><br><p>사실, 이 블로그는 루비콘 사람들과 머신러닝 스터디를 진행하며 내용을 정리하기 위한 목적으로 처음 개설했었다. 그래서 이 블로그의 초반에는 지금 할 얘기와 꽤 겹치는 얘기가 많다.<em>(스터디가 오래 이어지지는 않았어서 내용이 많지는 않다.)</em> 아직 많은 포스팅을 하지 않았지만, 당시 글을 썼을 때보다 몇 년의 시간이 지났기 때문에 일종의 리워크로써 본 포스팅을 작성한다.</p><p>지금도 부족하지만 이때의 포스팅은 다시 보기 민망하다. <span class="github-emoji" alias="sweat" style fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f613.png?v8">😓</span></p><ul><li><a href="https://jimheo.github.io/2018/10/10/ml-study-week1/">Machine Learning study 1주차</a></li><li><a href="https://jimheo.github.io/2018/10/10/extra-consideration-of-chain-rule/">Chain Rule에 대한 추가적인 고찰</a></li><li><a href="https://jimheo.github.io/2018/10/10/concept-of-cnn/">Convolutional Neural Network의 개념</a></li></ul><h2 id="인공지능-머신러닝-딥러닝-다-같은-말-아녜요-🤔"><a href="#인공지능-머신러닝-딥러닝-다-같은-말-아녜요-🤔" class="headerlink" title="인공지능? 머신러닝?? 딥러닝??? 다 같은 말 아녜요? 🤔"></a>인공지능? 머신러닝?? 딥러닝??? 다 같은 말 아녜요? 🤔</h2><p><code>인공지능</code>, <code>머신러닝</code>, <code>딥러닝</code>은 IT 및 인공지능 관련 지식이 없는 사람들이 가장 혼동하는 용어다. 대부분 이 세 가지에 대해 동일하게 생각하거나 머신러닝이나 딥러닝이라는 용어를 아직 잘 모르는 사람들이 많다.</p><p>간혹 딥러닝을 스스로 학습한다고 말하는 경우가 있는데, 그런 설명이 이해가 안되는 것은 아니지만 오히려 사람들에게 혼동을 줄 수 있기도 하고 모든 딥러닝을 정의하기에 적절한 워딩은 아니라고 생각한다.(Self-Supervised Learning이나 NAS 같은 AutoML이라면 모를까..)</p><p>아마도 높은 퍼포먼스를 보이는 방법론들이 딥러닝으로 귀결되고 있으니 용어의 혼동이 온다고 생각한다. 이들을 설명하기 위해 가장 흔하게 사용하는 다이어그램을 나도 한 번 그려보았다.</p><br><center><img src="/images/deep-learning-from-scratch/AI_ML_DL.jpg" width="50%"><font size="2" color="gray"> 인공지능, 머신러닝 그리고 딥러닝 <font></font></font></center><br><p>아무튼 먼저 인공지능은 머신러닝의, 머신러닝은 딥러닝의 슈퍼셋으로 용어들 간에는 포함 개념을 갖고 있으며 동일한 용어가 아님을 짚고 간다. 각각의 개념을 다시 아래와 같이 설명할 수 있을 듯 하다.<em>(학부 시절, 많은 것을 가르쳐주신 <span class="exturl" data-url="aHR0cHM6Ly93d3cueW91dHViZS5jb20vYy9OZW9XaXphcmQ=">박성호 교수님<i class="fa fa-external-link-alt"></i></span>의 워딩을 레퍼런스한다.)</em></p><blockquote><p><strong>인공지능(AI, Artificial Intelligence)</strong><br>인간의 학습능력, 추론능력, 지각능력 등을 <code>컴퓨터를 통해 구현</code>하는 포괄적인 개념</p><p><strong>머신러닝(ML, Machine Learning)</strong><br>주어진 <code>데이터의 특성과 패턴을 학습</code>하고 이를 바탕으로 <code>새로운 데이터</code>에 대한 결과를 <code>예측</code>, 데이터 마이닝(Data Mining)이 데이터간의 상관관계나 속성을 찾는 것이 주 목적인 반면, 머신러닝은 상관관계를 통해 새로운 데이터의 결과를 예측하는 것에 목적을 두고 있음</p><p><strong>딥러닝(DL, Deep Learning)</strong><br>머신러닝의 한 분야이며, 인공신경망(ANN, Artificial Neural Network)의 층을 깊게 하여 설계한 <code>딥 뉴럴 네트워크(Deep Neural Network)</code>로 학습하는 알고리즘의 집합</p></blockquote><h3 id="인공지능-🙄"><a href="#인공지능-🙄" class="headerlink" title="인공지능..? 🙄"></a>인공지능..? 🙄</h3><p><code>인공지능</code>이라고 하면 대부분은 <span class="exturl" data-url="aHR0cHM6Ly9tYmxvZ3RodW1iLXBoaW5mLnBzdGF0aWMubmV0L01qQXlNREF6TVRoZk5qQWcvTURBeE5UZzBORFkwT0RjeU5UUTEuZy0wLS1IMHlHMTIyN1RNUEFOdTVDWGJOTjBKcTlTaWJPQTM4MTFkMGxmTWcuaEhNVlhqOE44Y3lSSDgzdDNsdmQ4UXptZWl6M1lqX09Cc3FueGtjeWNSRWcuSlBFRy5teWhlYXJ0czE2LyVFQyU5NSU4NCVFQyU5RCVCNCVFQiVBMSU5QyVFQiVCNCU4N18lRUElQjIlQjAlRUIlQTclOTAuanBnP3R5cGU9dzgwMA==">아이, 로봇<i class="fa fa-external-link-alt"></i></span>이나 <span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmtha2FvY2RuLm5ldC9kbi9IOHdKeC9idHF6SFRuc3lZMS9Nb3k4REExaTl1ck85cHFSUTJacEtLL2ltZy5qcGc=">터미네이터<i class="fa fa-external-link-alt"></i></span> 등에 나오는 기계와 같이 사람과 유사하거나 혹은 사람을 뛰어넘은 것들을 생각하지만, 인공지능이라는 용어 자체는 굉장히 포괄적이다.</p><p>사실, 사람이 하는 일을 일부라도 기계로 대체할 수 있으면 그러한 모든 것은 <strong>인공지능</strong>이다. 그러니까, 학습하는 알고리즘이 아니라 단순히 <code>if-then-else</code>를 늘어놓은 알고리즘으로도 인공지능을 만들 수 있다는 말이다.<sup><a href="#IF-ELSE">1</a></sup></p><p>이러한 방법은 <code>퍼지이론(Fuzzy Theory)</code>에 근거한 <code>Symbolic AI(Expert System)</code><sup><a href="#Expert-System">2</a></sup>이다. 지금과 같은 대 인공지능 시대가 오기 전에 버튼만 몇 개 눌러주면 손빨래를 하지 않아도 알아서 빨래를 해주는 <strong>세탁기</strong>와 같은 인공지능 기계<span class="exturl" data-url="aHR0cHM6Ly9pbWcxLmRhdW1jZG4ubmV0L3RodW1iL1IxMjgweDAuZmpwZy8/Zm5hbWU9aHR0cDovL3QxLmRhdW1jZG4ubmV0L2JydW5jaC9zZXJ2aWNlL3VzZXIvRzJOL2ltYWdlL2xET3pLd0t4bV9aVXcycTA4bTRYcG5ub0JTSS5qcGc=">(요즘에 말하는 인공지능 세탁기가 아니라)<i class="fa fa-external-link-alt"></i></span>가 실생활에 이미 들어왔었다는 뜻이다.</p><br><center><img src="https://mblogthumb-phinf.pstatic.net/20120217_51/ktw108_1329408439677gTcez_JPEG/%B7%CE%C0%FA.jpg?type=w2" width="40%"><font size="2" color="gray"> 대-인공지능 시대를 맞는다. <font></font></font></center><br><h3 id="머신러닝-🤯"><a href="#머신러닝-🤯" class="headerlink" title="머신러닝..?? 🤯"></a>머신러닝..?? 🤯</h3><p>Symbolic AI은 전문가들의 Knowledge base로 규칙을 만들어 행동 패턴을 모델링(Rule-based Modeling)하는 방법이다. 그러나 전통적인 Symbolic AI는 학습 단계가 없다는 한계점이 있다. 이러한 한계점으로 인해 Task가 복잡해질수록 Symbolic AI으로 높은 성능을 내기는 어려웠고, 이를 대체하기 위해 나온 방법이 <code>머신러닝</code>이다.</p><p>대부분의 머신러닝 기법은 Symbolic AI에서 파생된 인공지능 방법론으로 일종의 통계학이다. 다만 Symbolic AI가 전문가의 지식을 하드 코딩으로 규칙을 만들고 이 규칙에 따라 데이터를 입력하면 정답을 출력하는 반면, 머신러닝은 데이터와 통계적 방법을 활용하여 규칙을 도출하는 방식으로 되어있다.</p><br><center><img src="https://i.pinimg.com/736x/e1/63/48/e1634867bf7a35ead5dc0d40b912f471.jpg" width="50%"><font size="2" color="gray"> 머신러닝은 블랙박스 <font></font></font></center><br><p>이러한 통계적 모델링(Statictical Modeling) 방법은 데이터를 활용하며, 보통 <strong>학습 단계</strong>와 <strong>추론 단계</strong>로 나누어져 있다. Symbolic AI와 통계학을 가장 직관적으로 접목시킨 머신러닝 알고리즘이 <strong>Decision Tree</strong>가 아닐까 싶다.</p><p><strong>러닝</strong>이란 워딩이 들어간만큼 방법론에 따라 혹은 Task에 따라 학습의 종류도 나뉘는데, 크게 <code>지도학습(Supervised Learning)</code>과 <code>비지도학습(Unsupervised Learning)</code><sup><a href="#Unsupervised-Learning">3</a></sup>으로 구분된다. 후에, 딥러닝이 발전하면서 추가적으로 <code>강화학습(Reinforcement Learning)</code>이라는 카테고리도 생겼으며, <code>준지도학습(Semi-Supervised Learning)</code> 등도 존재하지만 일반적으로 지도학습, 비지도학습과 강화학습을 가장 큰 카테고리로 보고있다.</p><blockquote><p><strong>지도학습(Supervised Learning)</strong><br><code>입력 값과 정답(값 혹은 분포)을 포함하는 학습 데이터(Training Data)</code>를 이용하여 학습하고, 그 학습된 결과를 바탕으로 새로운 데이터(Test Data)에 대해 결과 값을 예측(Prediction, Inference), 지도학습은 학습 결과를 바탕으로 Task에 따라 다시 크게 <code>회귀(Regression)</code>, <code>분류(Classification)</code><sup><a href="#Regression-Classificaion">4</a></sup> 등으로 구분</p><p><strong>비지도학습(Unsupervised Learning)</strong><br><code>정답이 없는 입력 값으로만 구축된 학습 데이터</code>를 이용하여 학습하고, 입력에 대한 정답을 찾는 것이 아닌 입력 값의 유사도(Similarity), 패턴(Pattern), 특성(Feature) 등을 학습을 통해 발견하는 방법을 말함, Task에 따라 다시 <code>군집화(Clustering)</code>나 <code>차원 축소(Dimensionality Reduction)</code> 등으로 구분</p><p><strong>강화학습(Reinforcement Learning)</strong><br>소프트웨어 에이전트(Agent)가 환경(Environment) 내에서 <code>보상(Reward)이 최대화</code>되는 방향으로 행동(Action)을 수행하도록 학습 하는 기법</p></blockquote><br><center><img src="https://i.redd.it/8lfied3ohyp11.jpg" width="50%"><font size="2" color="gray"> 학습 중... origin by <span class="exturl" data-url="aHR0cHM6Ly93d3cuaW5zdGFncmFtLmNvbS9vdXJza3kuaGsv">@oursky.hk<i class="fa fa-external-link-alt"></i></span><font></font></font></center><br><p>지도학습, 비지도학습과 강화학습의 정의는 위의 설명과 같으며, 지도학습을 위한 알고리즘은 위에서 말한 <strong>Decision Tree</strong>나 <strong>SVM</strong>, <strong>Logistic Regression</strong> 등이 있고, 비지도학습은 <strong>K-Means</strong>, <strong>KNN</strong>, <strong>DBSCAN</strong>, <strong>PCA</strong> 등이 있으며, 강화학습은 기본적으로 뉴럴 네트워크(Neural Network)를 기반으로하며 <strong>DQN(Deep Q-Networks)</strong> 등이 있다.</p><p>특히 뉴럴 네트워크, 그러니까 우리가 딥러닝이라 부르는 방법론은 지도학습과 비지도학습, 강화학습까지 모든 Task에서 활용할 수 있으며, 가장 메인스트림을 이루고 있는 지도학습 분야에서도 회귀나 분류를 가리지 않기 때문에, 사실상 현재의 새로운 머신러닝 알고리즘은 딥러닝으로부터 나오기 때문에 머신러닝과 딥러닝이라는 단어를 동일시보는 사람들도 많다.</p><br><center><img src="https://miro.medium.com/max/1000/1*x7P7gqjo8k2_bj2rTQWAfg.jpeg" width="50%"><font size="2" color="gray"> 사실은 이런걸지도..? origin by <span class="exturl" data-url="aHR0cHM6Ly93d3cuaW5zdGFncmFtLmNvbS9zYW5kc2VyaWZjb21pY3Mv">@sandserifcomics<i class="fa fa-external-link-alt"></i></span><font></font></font></center><br><h3 id="딥러닝-🤮"><a href="#딥러닝-🤮" class="headerlink" title="딥러닝..??? 🤮"></a>딥러닝..??? 🤮</h3><p>많은 사람들이 알다시피, 딥러닝은 인간(혹은 인지동물)의 뇌 구조를 본떠 만든 인공신경망(Artificical Neural Network)으로 뇌과학과도 긴밀한 관계<sup><a href="#Neuroscience">5</a></sup>를 갖고 있으며, 딥러닝이라는 용어는 딥 뉴럴 네트워크(Deep Neural Network)에서 리브랜딩한 것일 뿐이다.</p><p>사실, <code>딥러닝</code>은 인공지능 역사의 근-본에 가장 가깝다. 딥러닝의 전신인 <code>퍼셉트론(Perceptron)</code>으로부터 실질적인 인공지능의 연구가 시작되었으며, 퍼셉트론은 XOR 문제를 해결하기 위해 <code>다층 퍼셉트론(Multi-Layer Perceptron)</code>으로 발전했고, 긴 기간동안 AI Winter라고 불리는 두 번의 암흑기를 거쳐 현재의 딥러닝이 되었다.</p><p>XOR 문제로 처음 퍼셉트론의 허점이 드러나게 되면서 Symbolic AI를 지지하는 사람들이 생겨났고, 인공지능의 학파는 Symbolic AI를 지지하는 쪽과 Non-Symbolic AI, 즉 <code>연결주의(Connectionism)</code>라는 신경망을 지지하는 쪽으로 나뉘게 되었다.</p><br><center><img src="https://i.redd.it/5193db0avbey.jpg" width="50%"><font size="2" color="gray"> 아 모르겠고 레이어나 더 쌓아 <font></font></font></center><br><p>최근에서야 컴퓨팅 파워나 빅데이터의 발전으로 딥러닝이 어깨를 피면서 연결주의 학파가 승리했다고 생각하지만, 예전만 해도 신경망 기반으로 AI를 연구한다고 하면 블랙박스를 설명하기도 어려울 뿐더러 지원금도 뚝 끊기기도 해서 설명하기 쉬운 Symbolic AI 쪽이 주를 이루었다고 한다.<strong><em>(존버는 승리한다..?)</em></strong></p><h2 id="그래서-지금은"><a href="#그래서-지금은" class="headerlink" title="그래서, 지금은"></a>그래서, 지금은</h2><br><center><img src="https://miro.medium.com/max/1400/1*MkPk6IVlNyCjSmCIE000pg.png" width="70%"><font size="2" color="gray"> 한 눈에 보는 인공지능의 역사 origin by <span class="exturl" data-url="aHR0cHM6Ly90b3dhcmRzZGF0YXNjaWVuY2UuY29tL3RyYWRpdGlvbmFsLWFpLXZzLW1vZGVybi1haS01MTE3YjQ2OWEwYzk=">Awais Bajwa<i class="fa fa-external-link-alt"></i></span><font></font></font></center><br><p>지금은 당연히 딥러닝의 시대다. 인공지능 Task에 대해서 나오는 알고리즘은 모두 딥러닝이고 우승 모델도 다 딥러닝이다. 인공지능 시스템을 위한 생태계(Ecosystem)도 거의 대부분 딥러닝에 최적화 되어 있다. 그럴 수 밖에 없다. 너무 성능의 차이가 압도적이니까. 다른 머신러닝 방법론은 더 이상 메인스트림에 오르지 못한다. 오늘의 모든 방법론은 딥러닝으로부터 비롯된다.</p><p>그렇지만 간혹, 다시금 세번째 겨울이 오네마네 하는 소리가 들리곤 한다. 점차 현재의 신경망으로 닿을 수 있는 성능의 한계치에 수렴하는 느낌이 강하고, AGI 같은 범용인공지능을 만들려면 지금의 신경망으로는 턱없이 부족하기 때문이다. 또한, 딥러닝이 블랙박스로 지속되는 한 대중들에게 기술의 신뢰성을 얻어내기는 어려울 것이다.</p><p>이러한 상황을 극복하고자 블랙박스를 화이트박스로 만들기 위한 <code>설명 가능한 인공지능(XAI, eXplainable AI)</code>에 대한 연구나 딥러닝에 Symbolic AI를 결합하려는 <code>Neuro-Symbolic AI</code>과 같은 시도가 계속해서 나오고 있다.<em>(물론, 둘다 한참 멀었다고 생각한다.)</em> 그래서 우리는 딥러닝이 발전을 해도 다른 머신러닝 기법이나 선형 대수(Linear Algebra) 컨벡스 최적화(Convex Optimization), 통계적 학습(Statistical Learning)과 같은 기반 지식을 계속해서 공부해야 하나보다..<span class="github-emoji" alias="pensive" style fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f614.png?v8">😔</span></p><hr><p><a name="IF-ELSE">[1]</a> 학습의 방법을 몰랐을 때, 내가 처음 생각한 인공지능의 방법론이다.<br><a name="Expert-System">[2]</a> 1997년 세계 체스 챔피언을 이긴 IBM Watson 연구소의 Deep Blue도 이러한 방식으로 만들어졌다.<br><a name="Unsupervised-Learning">[3]</a> 개인적으로 비지도학습은 궁극적으로 지도학습을 하기 위한 수단이라고 생각한다.<br><a name="Regression-Classificaion">[4]</a> 회귀와 분류는 결과 값이 수치형(Numerical)이냐 범주형(Categorical)이냐의 차이에 따라 구분된다.<br><a name="Neuroscience">[5]</a> 현재까지도 심리학이나 뇌과학 분야에서 딥러닝을 많이 연구하고 있는 것으로 알고 있다.</p>]]></content>
<summary type="html">
<h2 id="들어가며"><a href="#들어가며" class="headerlink" title="들어가며"></a>들어가며</h2><p>올해 상반기, 나의 최대 관심사는 무엇보다도 <strong><code>졸업(!!!)</code></strong>이었다. 많은 대학원생들이 으레 그렇듯 예상치 못한 사정으로 졸업이 예정보다 반년 늦어졌고 그마저도 더 늦어지겠다 싶어 모든 우선 순위를 제쳐두고 학위 논문을 준비하게 되었다.</p>
<p>그렇게 1월 말부터 논문을 구상하고 작성하며 시간이 흘렀고, 실험 과정에서 굉장히 많은 시행 착오도 겪었다. 두 번의 발표와 도장을 받기위해 교수님들께 메일을 보내고 돌아다니며 모든 서류 제출을 끝내고 나니 6월이 되어있었다. 그렇게 학위 논문을 모두 제출하고 대학원과 관련된 모든 것을 털어내고서야 드디어 <strong>석사(진)</strong>이 되었다.</p>
<p>그래도 8월까지는 학생이니만큼 학생 신분의 마지막이 지나기 전에 자축의 의미로 본 포스팅을 작성하기로 하였다. 사실, 2년 반 동안의 지난했던 기간의 회고를 할까도 생각했지만 너무 할 말<del>(못 할 말)</del>이 많아지기 때문에 다소 식상하지만 학위 논문을 작성하면서 정리했던 인공지능의 발전사와 개략적인 개념을 최대한 많은 사람들이 이해할 수 있도록 포스팅에 설명해보기로 했다.</p>
</summary>
<category term="머신러닝" scheme="https://jimheo.github.io/categories/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D/"/>
<category term="딥러닝" scheme="https://jimheo.github.io/categories/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D/%EB%94%A5%EB%9F%AC%EB%8B%9D/"/>
<category term="Convolutional Neural Network" scheme="https://jimheo.github.io/tags/Convolutional-Neural-Network/"/>
<category term="Deep Learning" scheme="https://jimheo.github.io/tags/Deep-Learning/"/>
</entry>
<entry>
<title>Python GIL(Global Interpreter Lock)이 뭐에요?</title>
<link href="https://jimheo.github.io/2021/07/06/global-interpreter-lock/"/>
<id>https://jimheo.github.io/2021/07/06/global-interpreter-lock/</id>
<published>2021-07-06T04:57:09.000Z</published>
<updated>2023-09-21T12:34:47.491Z</updated>
<content type="html"><![CDATA[<h2 id="들어가며"><a href="#들어가며" class="headerlink" title="들어가며"></a>들어가며</h2><p>딥러닝을 입문하며 자연스럽게 파이썬을 함께 공부하게 되었고, 지금은 주 언어로 사용하고 있다. 하지만 나는 파이썬에 대해 얼마나 알고 있을까?</p><p>C/C++ 같은 컴파일 언어만 사용했던 나에게 파이썬은 꽤 난해하게 다가왔다. 사실, 파이썬을 사용하면서 느낀 생각은 “파이썬의 철학(The Zen of Python)과 많이 다른데..?” 였다.</p><p>파이썬 철학의 핵심 내용은 <code>명확한 그리고 가급적이면 유일한 하나의 방법이 존재한다(There should be one-- and preferably only one --obvious way to do it)</code>이며, 이에 따르면 규칙이 굉장히 엄격한 언어라고 한다. 그렇지만 나에게 파이썬의 처음에는 굉장히 자유로운 언어로 보였다.</p><a id="more"></a><br><h3 id="Life-is-too-short-You-need-Python"><a href="#Life-is-too-short-You-need-Python" class="headerlink" title="Life is too short, You need Python!"></a>Life is too short, You need Python!</h3><p>애초에 멀티 패러다임 언어이기도 하면서, <code>명시적인 것이 암시적인 것보다 낫다(Explicit is better than implicit)</code>고 하지만 동적 타입이기 때문에 타입 선언부터 암시적이며 굉장히 유연하다. 마찬가지로, 들여쓰기도 자유도를 제한한다고 하지만 나는 “어차피 들여쓰기는 맞춰서 하는건데 무려 괄호를 안써도 된다고?” 라고 생각했다..</p><p>이렇게 자유도를 주었으면서, 하나의 답으로 수렴하게 되는 언어라니.. 이해가 어려웠다. 그렇지만 그 정도로 자유도가 높은 언어기 때문에 컨벤션을 중시하는 거지 싶기도 했다. 어찌되었든 언어의 자유도가 높을수록 오류가 높아질 확률도 높아질테니 말이다.</p><p>파이썬은 실행가능한 의사코드(Executable Pseudocode)라고 불릴 정도로 자연어와 유사한 high-level 언어이며, <code>파이썬스럽다(Pythonic)</code>는 말까지 나올정도로 독자적이다. 사람이 쓰기 쉽도록 만든 언어이므로 사람이 읽기 편하게 하는데 가장 중점을 두며, 유연한만큼 문서적으로 제약이 많이 두고 있다고 생각한다.</p><p>생산성이 가장 좋다고 불리는 언어로써 - <code>Life is too short, You need Python.</code> - 여러 사람이 동일한 컨벤션으로 사용해야 생산성을 극대화할 수 있을 것이다.</p><p>역시 파이썬은 아직 어렵다. <span class="github-emoji" alias="joy" style fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f602.png?v8">😂</span></p><br><center><img src="https://imgs.xkcd.com/comics/python.png" width="50%"><font size="2" color="gray"> xkcd - Python!<font></font></font></center><br><p>나는 기본적으로 어떤 언어든 본질은 같기 때문에 머리에 로직만 담고 있으면, 금방 사용할 수 있다는 생각을 하고 있었다. 이 생각이 바뀐 것은 아니지만 최근에는 여기에 +$\alpha$로 언어의 철학을 이해하려는 노력이 필요하다는 생각을 하게 되었다.</p><p>클린 코드를 지향한다고 항상 말하지만 클린 코드가 정확히 무엇인지 깊게 고민한 적은 없었던 듯 싶다. 클린 코드를 위한 방법은 여러가지가 있겠으나, 언어의 철학은 언어를 만든 원리와도 같으며, 이를 이해하는 것이 그 첫걸음이라 생각하며 포스트를 작성한다.</p><p>파이썬이 왜 Garbage Collection의 방법 중 하나로 Reference Counting을 사용하는지, 왜 GIL 정책을 사용하는지도 파이썬의 기본 원리를 통해 이해할 수 있으리라 믿는다.<em>(다만, 이번 포스팅에서는 Garbage Collection과 Reference Count에 대해서 깊게 다루지는 않을 듯 하다.)</em></p><br><h2 id="파이썬에서-멀티-쓰레딩이-사실-싱글-쓰레딩이라구요"><a href="#파이썬에서-멀티-쓰레딩이-사실-싱글-쓰레딩이라구요" class="headerlink" title="파이썬에서 멀티 쓰레딩이 사실 싱글 쓰레딩이라구요?"></a>파이썬에서 멀티 쓰레딩이 사실 싱글 쓰레딩이라구요?</h2><p>최근 이런 질문을 받았다. (사실상 이 포스트를 쓰게 된 이유. 많은 도움이 되었습니다..<span class="github-emoji" alias="bow" style fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f647.png?v8">🙇</span>)</p><blockquote><p>C: 딥러닝 쪽을 주로 공부하셨으니 파이썬 많이 쓰시죠?<br>나: 음.. 네.<br>C: 그럼 파이썬에서 멀티 쓰레드를 쓸 때, 내부적으로 싱글 쓰레드로 동작하는 것 알고 계신가요?<br>나: 아.. 들어본 것도 같긴 한데.. 그런..가요..?</p></blockquote><p>많이 부끄러웠다. 당황해서 머리가 새하얘져 이후 멀티 쓰레드와 멀티 프로세스에 대한 대화에서 반대로 말하거나 Numpy의 Vectorization에 대해서도 엉뚱한 말을 했던 것 같다.</p><p>이후 이에 대해 찾아보면서 파이썬에서 <code>GIL(Global Interpreter Lock)</code>을 사용한다는 것을 알게되었다.</p><p>그럼 차근히 프로그램부터 프로세스와 쓰레드의 개념부터 내가 이해하는 언어로 다시 정리해보자.</p><blockquote><p><strong>프로그램(Program)</strong><br><code>실행 가능한 파일(Executable File in File System)</code>, 메모리에 할당되지 않은 정적 상태</p><p><strong>프로세스(Process)</strong><br><code>실행 중인 프로그램(Executing Program)</code>, 프로그램의 인스턴스(Instance of Program), 프로세스가 생성되면서 운영체제로부터 자원을 할당받음, 할당된 범위를 벗어날 수 없음</p><p><strong>쓰레드(Thread)</strong><br>프로세스 안에서 실질적으로 <code>작업을 수행하는 여러 흐름</code>, 독립적으로 스케쥴링 할 수 있는 <code>최소 단위(The Smallest Sequence)</code>, 1개의 프로세스에는 1개 이상의 쓰레드가 존재, 프로세스 내의 쓰레드는 서로 메모리를 공유(Shared Memory)</p></blockquote><p>각 개념은 기본적으로 위와 같으며, 결국 쓰레드는 할당받은 메모리의 범위를 벗어날 수 없는 프로세스의 한계를 보완하기 위해 사용되는 개념이다. 일반적으로 각 프로세스에는 <strong>Code, Data, Heap, Stack</strong>의 형식의 메모리 영역이 할당되며, 쓰레드는 별도의 <strong>Stack</strong>을 다시 할당받게 되고, <strong>Code, Data, Heap</strong>을 <strong>Shared Memory</strong>로 사용하게 된다.</p><p>이렇게 쓰레드를 하나의 프로세스 안에서 두 개 이상 사용하면 <code>동시성(Concurrency)</code> 프로그래밍을 할 수 있어 더 빠른 속도로 작업을 처리할 수 있게 된다.<em>(Concurrency와 Parallelism의 차이도 나중에 포스팅을 해보자.)</em></p><p>그러나, 메모리를 공유한다는 것(프로세스든 쓰레드든)은 양날의 검이다. 정말 개쩌는 코드를 정확하게 작성해서 사용하면 되겠지 싶지만, 혼자 사용할 코드가 아니라면 아무리 날고 기어도 항상 문제가 발생하기 마련이다.</p><p>여기서 학부시절 운영체제 강의를 들으며 교수님께서 그렇게 강조하셨던 공유 자원에 접근하는 코드(임계 영역, Critical Section)에 여러 쓰레드가 동시에 진입하게 되는 경쟁 상태(Race Condition)라는 문제가 나온다.</p><p>Race Condition이 발생하면 데이터가 불일치되는 문제로 이어지기 때문에 <strong>동기화(Synchronization)</strong> 과정을 통해 Race Condition을 방지해야만 한다.</p><p>동기화하기 위한 대표적인 조건이 Critical Section에 하나의 쓰레드만 진입할 수 있도록 하는 <code>상호 배제(Mutual Exclusion, Mutex)</code>이며, 이에 대한 방법 중 하나가 <code>Lock</code>이다.</p><br><center><img src="https://i.pinimg.com/564x/cf/3d/9a/cf3d9a67a7cb5781a15693e24bf92227.jpg" width="50%"><font size="2" color="gray"> 가망이 없어..<font></font></font></center><br><p>파이썬에서도 동일하게 이 논리가 적용된다. 파이썬으로 공유 메모리에 접근할 때도 동기화 과정이 필요하므로 Mutex를 활용하게 된다. 다만, 파이썬에서는 그 활용 방식이 조금 독특할 뿐이다.</p><p>모든 객체에 대한 Mutex를 두어 Thread-safe하게 만들려면 너무 복잡하고 쓰레드 간 자원을 요구하는 상태가 엉켜 <strong>교착 상태(Deadlock)</strong>가 발생할 수도 있다. <code>그래서 파이썬에서는 그냥 다 잠궜단다..</code> </p><br><center><img src="https://preview.redd.it/r2zt0z71yfu31.png?width=640&crop=smart&auto=webp&s=446a79718041098ad4031d8981f0e7e093e5b595" width="50%"><font size="2" color="gray"> 어.....<font></font></font></center><br><p>아무튼 그렇게 등장한 것이 바로 GIL이고, 이것이 파이썬 인터프리터에서 한 번에 한 쓰레드에서만 파이썬 Bytecode를 실행하도록 하는 장본인이다. 이로 인해, 아무리 멀티 쓰레딩을 사용한들 실질적으로는 하나의 쓰레드만 모든 자원을 점유하고 다른 쓰레드는 자원이 없으므로 실행할 수 없게 된다.</p><p>흔히 “파이썬은 사용은 쉬운데 성능이 좀..”이라고 하는데는 <span class="exturl" data-url="aHR0cDovL2pha2V2ZHAuZ2l0aHViLmlvL2Jsb2cvMjAxNC8wNS8wOS93aHktcHl0aG9uLWlzLXNsb3cv">다양한 이유<i class="fa fa-external-link-alt"></i></span>가 있겠으나 GIL은 아마 그 지분 중 한 축을 당당하게 차지한다고 생각한다. 그렇지만, GIL을 사용한데도 다 이유가 있을터.. 다시 파이썬이 GIL을 사용하게 된 경위를 들여다보자. <del>(<span class="exturl" data-url="aHR0cHM6Ly93d3cuYXJ0aW1hLmNvbS93ZWJsb2dzL3ZpZXdwb3N0LmpzcD90aHJlYWQ9MjE0MjM1">???: 그럼 느그들이 함 해봐.<i class="fa fa-external-link-alt"></i></span>)</del><sup><a href="#Removing-GIL">1</a></sup></p><br><h2 id="파이썬은-왜-사서-성능을-낮추었는가"><a href="#파이썬은-왜-사서-성능을-낮추었는가" class="headerlink" title="파이썬은 왜 사서 성능을 낮추었는가"></a>파이썬은 왜 사서 성능을 낮추었는가</h2><p>내부적인 동작을 까봤을 때, 사실 파이썬은 단순히 인터프리터 언어로 보기는 어렵다.</p><p>파이썬은 <code>CPython</code>이라고 하는 C로 되어있는 구현체를 - PyPy나 Jython 등 다른 구현체도 있지만 - 표준 인터프리터로 사용하며 CPython은 인터프리팅 하기 전에 파이썬 코드를 컴파일하는 작업을 거친다. 다만 파이썬의 컴파일 과정에서는 Assembly가 아니라, Assembly와 유사하지만 VM 위에서 실행하도록 하는 <code>Bytecode</code>로 번역하게 된다.(이 때 .pyc 파일이 생성된다.)</p><p>이 과정은 자바가 Javac와 JVM을 거치는 것과도 비슷하며, Python 자체의 VM위에서 실행되므로 CPU에 독립적인 인터프리터의 특성을 지니게 된다. 파이썬에서 문자열부터 정수나 실수 등 모든 것은 객체로 구성되어있다. 그리고 하나의 객체는 CPython에서 하나의 구조체와 대응된다.</p><p>수많은 객체를 통제하는 방법으로 파이썬에서는 객체(CPython의 구조체)에 자신을 참조하는 변수의 수를 저장하는 <code>Reference Counting</code>을 두고있다. 또한, 파이썬은 사람이 쉽게 사용할 수 있는 언어로 설계되었기 때문에, <code>Garbage Collection</code><sup><a href="#GC-RC">2</a></sup>을 사용해 메모리 영역의 할당과 해제에 대해 사람이 고민할 필요성을 없애주었다.</p><p>파이썬의 Garbage Collection은 Reference Counting을 통해 관리되며, 보통 Reference Counting의 값이 0이 되면 해당 객체의 메모리 할당을 해제하게 된다.</p><p>파이썬의 함수 호출 방식이 가뜩이나 <code>Call by Object-Reference</code>라고 하는 조금 독특한 방식인데 메모리 할당과 해제를 사람이 직접해야 한다면, 그리고 Reference Counting을 사람이 직접 세어야 한다면, 개판난 코드로 인해 메모리가 줄줄 흐르는 일이 많지 않을까 싶다.<em>(적어도 나의 경우에는 그럴 것 같다..)</em></p><p>그런데, 멀티 쓰레딩에서 Reference Counting은 Critical Section으로 여러 쓰레드가 이 영역에 진입하게 되면 Race Condition으로 인해 동기화에 문제가 발생하게 된다.</p><p>동기화를 위해 파이썬 코드의 수 많은 객체와 객체들 간 연산에서 일일히 Lock을 걸어주는 일은 GIL을 사용하는 방법보다 훨씬 큰 비용을 초래한다.</p><p>또한, 각각 Lock을 갖고 있는다면 개발자의 역량이 얼마나 뛰어난가와 관계없이 Deadlock을 초래할 확률이 높다.</p><p>GIL은 <strong>단 하나의 Lock</strong>만을 사용하기 때문에 간단하게 만들 수 있었고, Deadlock의 위험이 없으며, Overhead의 부담이 적었을 것이다. 그래서, 귀도 반 로섬과 다른 파이썬 개발자들은 GIL을 채택하게 되었고 이 방식이 현재까지 이어져 오고 있다.</p><br><center><img src="https://i.pinimg.com/originals/70/10/5f/70105ffd8406c9766503d3f15b6c82b1.jpg" width="35%"><font size="2" color="gray"> 아하! 고마워요 GIL!<font></font></font></center><br><br><h3 id="그럼-그냥-싱글-쓰레드로-써야하나요"><a href="#그럼-그냥-싱글-쓰레드로-써야하나요" class="headerlink" title="그럼 그냥 싱글 쓰레드로 써야하나요..?"></a>그럼 그냥 싱글 쓰레드로 써야하나요..?</h3><p>우선, Real Python에 포스팅된 <span class="exturl" data-url="aHR0cHM6Ly9yZWFscHl0aG9uLmNvbS9weXRob24tZ2lsLw==">What Is the Python Global Interpreter Lock (GIL)?<i class="fa fa-external-link-alt"></i></span>에서 싱글 쓰레드와 멀티 쓰레드의 성능을 비교하기 위한 코드 일부를 발췌해서 실행해보았다.</p><blockquote><p>Single-threading 성능</p></blockquote><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line">COUNT = <span class="number">50000000</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">countdown</span><span class="params">(n)</span>:</span></span><br><span class="line"> <span class="keyword">while</span> n > <span class="number">0</span>:</span><br><span class="line"> n -= <span class="number">1</span></span><br><span class="line"></span><br><span class="line">start = time.time()</span><br><span class="line">countdown(COUNT)</span><br><span class="line">end = time.time()</span><br><span class="line"></span><br><span class="line">print(<span class="string">'Time taken in seconds -'</span>, end - start)</span><br><span class="line"></span><br><span class="line"><span class="comment"># Single Threading</span></span><br><span class="line"><span class="comment"># Time taken in seconds - 2.1882541179656982</span></span><br></pre></td></tr></table></figure><br><blockquote><p>Multi-threading 성능</p></blockquote><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">from</span> threading <span class="keyword">import</span> Thread</span><br><span class="line"></span><br><span class="line">COUNT = <span class="number">50000000</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">countdown</span><span class="params">(n)</span>:</span></span><br><span class="line"> <span class="keyword">while</span> n > <span class="number">0</span>:</span><br><span class="line"> n -= <span class="number">1</span></span><br><span class="line"></span><br><span class="line">t1 = Thread(target=countdown, args=(COUNT // <span class="number">2</span>, ))</span><br><span class="line">t2 = Thread(target=countdown, args=(COUNT // <span class="number">2</span>, ))</span><br><span class="line"></span><br><span class="line">start = time.time()</span><br><span class="line">t1.start()</span><br><span class="line">t2.start()</span><br><span class="line">t1.join()</span><br><span class="line">t2.join()</span><br><span class="line">end = time.time()</span><br><span class="line"></span><br><span class="line">print(<span class="string">'Time taken in seconds -'</span>, end - start)</span><br><span class="line"></span><br><span class="line"><span class="comment"># Multi Threading</span></span><br><span class="line"><span class="comment"># Time taken in seconds - 2.1965391635894775</span></span><br></pre></td></tr></table></figure><br><p>결과에서 볼 수 있듯이 GIL로 인해 대부분의 멀티 쓰레딩은 싱글 쓰레딩과 성능의 차이가 없으며, 오히려 쓰레드의 <code>Context-Switching</code>으로 인해 Overhead가 더 커져 느리게 동작하는 경우도 발생한다.</p><p>그렇기 때문에 파이썬에서 멀티 쓰레딩은 잘 사용하지 않으며 동시성 프로그래밍을 해야 할 경우에는 가급적 멀티 프로세싱으로 대체해서 사용한다.</p><p><strong>그러니까 사실은 가급적이면 그냥 싱글 쓰레드로 사용하라는 말이다.</strong></p><p>그렇다면, 왜 파이썬 개발자들은 싱글 쓰레드만도 못한 성능의 이런 병목(Bottleneck)을 굳이 만들었을까? 그냥 멀티 쓰레드 구현 자체를 안해도 되지 않았을까?</p><p>그나마 다행히도 CPU-bound가 아닌 Sleep이나 I/O-bound(입출력에 대한 작업, File, Database, Network)에서는 위 내용이 적용되지 않는다.</p><p>GIL을 채택한 이유로 위에서 말한 것 이외에도 시기적인 측면에서, Python 자체가 개발될 당시에는 싱글코어의 사용이 일반적이었기 때문에 멀티코어 성능을 향상시키기 위한 목적보다는 다중 I/O 이벤트를 처리하기 위해 GIL을 채택한 것으로 보인다.</p><p>그러나 I/O-bound에서는 보통 I/O 이벤트에 대해 처리하는 비용보다 이벤트가 발생하기까지 기다리는 비용이 더 크기 때문에 멀티 쓰레딩을 사용하기보다는 비동기 프로그래밍을 사용하는게 훨씬 이득이다.</p><p><strong>그러니까 다시 말하지만 가급적이면 그냥 싱글 쓰레드로 사용하라는 말이다.</strong></p><br><h3 id="Java에서는-GIL-안-쓰던데"><a href="#Java에서는-GIL-안-쓰던데" class="headerlink" title="Java에서는 GIL 안 쓰던데..?"></a>Java에서는 GIL 안 쓰던데..?</h3><p>한 가지 궁금한 점이 생겼다.</p><p>겉으로 보기에는 자바도 파이썬과 비슷하게 Garbage Collection을 사용하며, 컴파일로 자바 Bytecode로 번역하고(자바는 .class 파일을 생성한다.) JVM 위에서 인터프리터로 Bytecode를 실행한다.</p><p>그런데 자바에서는 GIL을 사용하지 않는다. 자바(1995년)가 파이썬(1991년)에 비해 늦게 릴리즈되긴 했지만 그래도 4년밖에 차이가 나지 않는다. 그렇기 때문에 시기적으로 접근하기에는 무리가 있다. 자바가 GIL이 없는 이유에 대한 레퍼런스가 많지는 않으나 감사하게도 먼저 이러한 고민을 하신 분의 글을 찾게 되어 해당 <span class="exturl" data-url="aHR0cHM6Ly92ZWxvZy5pby9AbGl0aWVuL0dJTC1KYXZhJUVDJTk3JTkwJUVCJThBJTk0LSVFQyU5NyU4NiVFQiU4RCU5OCVFQiU4RCVCMA==">포스트<i class="fa fa-external-link-alt"></i></span>를 인용하고자 한다. <span class="github-emoji" alias="pray" style fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f64f.png?v8">🙏</span></p><p>파이썬에서 <code>Reference Counting</code>을 사용하는 것과 달리 자바에서는 기본적으로 Garbage Collection을 <code>Mark and Sweep</code>이라는 방식으로 관리한다.(현재는 개선된 방식을 사용한다.)</p><p>해당 방식은 메모리가 일정 이상 찼을 때 실행되며, 객체를 구성할 때 Flag로 1bit를 추가로 두어 Root 객체(Stack이나 Data에 저장된 현재 Scope의 지역 변수와 전역 변수)부터 접근 가능한 객체들의 Flag 모두 마킹하는 <code>Mark</code> 단계와 메모리 공간을 순회하며 마킹되지 않은 객체의 메모리를 해제하는 <code>Sweep</code> 단계가 각각 진행된다.</p><p>즉, Reference Counting 방식이 객체의 참조가 변경될 때마다 Critical Section에 진입을 막기 위해 Atomic한 연산을 수행해야 하는 것과 달리 Mark and Sweep에서는 이를 고려할 필요가 없다. 그렇기 때문에 자연스럽게 자바에서는 GIL을 사용할 필요가 없어진다.</p><p>대신, Mark 단계에서 Flag에 마킹을 하기 위해 모든 쓰레드를 일시정지시키는 <code>Stop-the-world</code>(여기서 발생하는 비용을 줄이는 것도 하나의 챌린지이다.)를 통해 Garbage Collection의 Atomic을 보장한다.</p><p>Mark and Sweep 방식은 인터프리터에 Lock을 두고 있지 않아 여러 쓰레드가 인터프리터에 접근할 수 있다.</p><p>다만, Reference Counting 방식이 바로 메모리를 회수하는 반면 Mark and Sweep은 메모리를 쌓고 있기 때문에 공간적인 측면의 비용을 감수해야한다. 또한, 객체 소멸 시점을 예측하기 어렵다는 단점도 존재한다.</p><p>앞서 말했듯 파이썬은 CPython를 디폴트로 하고 있으며, 이는 곧 <code>malloc()</code>과 <code>free()</code>에 대한 연산을 기본적으로 사용한다는 뜻이기도 하다. <code>malloc()</code>과 <code>free()</code>은 자바의 방식처럼 메모리를 적재해놓고 있으면 메모리 누수의 위험이 발생한다. 그렇기에 파이썬은 Reference Counting을 두어 바로바로 메모리를 해제해주는 방식을 사용하게 된 것으로 유추할 수 있다.</p><br><h2 id="마치며"><a href="#마치며" class="headerlink" title="마치며"></a>마치며</h2><p>쓰다보니 말이 길어졌다.</p><p>그래도 포스팅을 하며 스스로 내용을 정리할 수 있었으니 되었다.</p><p>파이썬을 애초에 싱글 쓰레드 이상으로 사용한 적이 거의 없었거니와 Tensorflow와 같은 프레임워크에서 코어 연산은 모두 C++로 동작하다보니 이런 고민을 잘 해본적이 없던 것 같다. (Tensorflow에서는 자체적으로 GIL을 해제해준다고도 한다.)</p><p>언어가 만들어진 여러 배경과 언어의 철학을 이해하는 노력을 더 기르면 자연스럽게 GIL과 같은 정책이 나온 이유를 생각해 볼 수 있고 이러한 것들을 이해하는 과정이 가독성과 안정성을 모두 잡은 클린 코드를 만드는 발판이 되지 않을까한다.</p><p>추가적으로 GIL이 완벽하게 <span class="exturl" data-url="aHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTcxNzM5My9pcy10aGUtb3BlcmF0b3ItdGhyZWFkLXNhZmUtaW4tcHl0aG9u">Thread-safe를 보장하지는 않다고 한다.<i class="fa fa-external-link-alt"></i></span> 그렇기 때문에, 개발이 편리하다는 파이썬의 장점을 뒤로하더라도 개발자로서 파이썬의 철학에 <code>명시적인 것이 암시적인 것보다 낫다(Explicit is better than implicit)</code> 써있듯이 명시적으로 Lock을 걸어주어 프로그램을 보호하는 습관이 필요하다.</p><hr><p><a name="Removing-GIL">[1]</a> 많은 사람들이 GIL을 제거하기 위해 많은 연구를 했지만, 아직 GIL을 제거할 수 있는 방법은 없는 듯 하다. GIL을 제거하기 위해서는 싱글 쓰레드의 성능을 떨어뜨리지 않아야한다는 전제가 있는데 이것이 쉽지 않다고 한다.<br><a name="GC-RC">[2]</a> Reference Counting에 대해 순환 참조(Reference Cycle)가 발생할 경우에는 Cyclic Garbage Collector를 별도로 사용한다고 한다.</p>]]></content>
<summary type="html">
<h2 id="들어가며"><a href="#들어가며" class="headerlink" title="들어가며"></a>들어가며</h2><p>딥러닝을 입문하며 자연스럽게 파이썬을 함께 공부하게 되었고, 지금은 주 언어로 사용하고 있다. 하지만 나는 파이썬에 대해 얼마나 알고 있을까?</p>
<p>C/C++ 같은 컴파일 언어만 사용했던 나에게 파이썬은 꽤 난해하게 다가왔다. 사실, 파이썬을 사용하면서 느낀 생각은 “파이썬의 철학(The Zen of Python)과 많이 다른데..?” 였다.</p>
<p>파이썬 철학의 핵심 내용은 <code>명확한 그리고 가급적이면 유일한 하나의 방법이 존재한다(There should be one-- and preferably only one --obvious way to do it)</code>이며, 이에 따르면 규칙이 굉장히 엄격한 언어라고 한다. 그렇지만 나에게 파이썬의 처음에는 굉장히 자유로운 언어로 보였다.</p>
</summary>
<category term="프로그래밍" scheme="https://jimheo.github.io/categories/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/"/>
<category term="코어" scheme="https://jimheo.github.io/categories/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EC%BD%94%EC%96%B4/"/>
<category term="Python" scheme="https://jimheo.github.io/tags/Python/"/>
<category term="GIL" scheme="https://jimheo.github.io/tags/GIL/"/>
<category term="Threading" scheme="https://jimheo.github.io/tags/Threading/"/>
<category term="Mutex" scheme="https://jimheo.github.io/tags/Mutex/"/>
</entry>
<entry>
<title>번아웃 극복을 위한 복기</title>
<link href="https://jimheo.github.io/2020/07/14/retrospective-to-overcome-the-burnout/"/>
<id>https://jimheo.github.io/2020/07/14/retrospective-to-overcome-the-burnout/</id>
<published>2020-07-14T07:18:39.000Z</published>
<updated>2023-09-21T12:34:47.491Z</updated>
<content type="html"><![CDATA[<p>바둑에 대해서 잘은 모르지만 그로부터 유래된 단어는 간혹 일상에서 사용하곤 한다.<br>바둑 용어 중에 <code>복기</code>라는 말이 있다.<br>대국이 끝나고 승패가 결정되었음에도 내용을 검토하기 위해 상호 간 처음부터 두었던 순서대로 다시 두어 재연함 뜻하는 단어다.<br>복기로부터 바둑 기사들은 대국에서 잘한 수와 잘못했던 수, 상대방의 전략 등을 살펴본다.<br>프로 9단 바둑기사 이창호는 다음과 같이 말할 정도로 복기를 중요시 했다고 한다.</p><blockquote><p><strong><em>승리한 대국의 복기는 이기는 습관을 만들어주고, 패배한 대국의 복기는 이기는 준비를 만들어준다</em></strong></p></blockquote><p>조훈현 9단 또한 복기가 가지않았던 길을 갈 수 있게 한다 하였으며, 패배로 인해 아플수록 더 예민하게 들여다보고 복기해야한다는 말을 했더랬다.<br>이 바둑기사들이 많은 수를 순서대로 기억하여 복기를 할 수 있는 이유는 한 수 한 수에 집중하고 의미를 부여하여 두었기 때문이라고 한다.</p><a id="more"></a><p>IT분야에서도 복기와 유사한 의미로 쓰이는 <code>회고(Retrospective)</code>라는 용어가 있다.<br>스프린트라는 일정 주기 후에 회고를 통해 달성 지표가 얼마나 되는지, 잘한 점과 잘하지 못한 점은 무엇인지, 이를 통해 개선해야 할 점은 무엇인지를 되짚는다.<br>이렇듯, 복기와 회고는 앞으로 더 나은 방향으로 가기 위해, 그리고 그에 있어 최선을 다하기 위해 필요한 과정이다.</p><br><center><img src="https://images.unsplash.com/photo-1500099817043-86d46000d58f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80" width="35%"><font size="2" color="gray"> Burn out</font></center><br><p>최근에 심각하게 <code>번아웃</code>이 왔다.<br>그것은 꽤 오랜 시간 지속되었고, 지금이야 번아웃에서부터 수면 위로 많이 올라온 상태지만, 아직까지도 완전히 회복된 것은 아니다.<br>이전에는 아예 가라앉아 있던 상태에서 이렇게 글까지 쓸 수 있을 정도니 장족의 발전이다.<br>지금 이 글을 쓰는 이유도 번아웃에서 완전히 벗어났기에 쓰는 것이 아니라, 이로부터 극복하고자 함이다.<br>번아웃으로부터 벗어나고 이전보다 더 나은 길을 가기 위해 번아웃에 대한 복기를 하고자 한다.</p><p>사실 번아웃이 온 것을 깨닫기 전부터 이에 대한 징조는 계속해서 있었다.<br>다만, 스스로를 괜찮다고 억지로 다독여오며 무리를 해왔다.<br>번아웃을 이겨내지 못한 결정적 계기는 다름아닌 건강의 악화였다.<br>몸에 심각하게 반응이 오자, 결국 내시경 검사를 받기로 했다.<br>검사 후 수면마취로 비몽사몽한 상태에서 간호사가 나에게 다행이라고 말했다.<br>다행히 별일은 없었나보다라고 생각한 순간, 간호사가 말을 이어갔다.</p><blockquote><p><strong><em>그러니까 다행이라는 말은 지금이라도 검사를 받으셔서 다행이라는 말이에요.</em></strong><br><strong><em>더 늦으셨으면 정말 심각해졌을 수도 있어요. 조직검사를 기다려봐야겠지만, 최악은 면한 것 같아요.</em></strong></p></blockquote><p>순간 정신이 아득했다.<br>검사를 받기는 했지만, 설마 이상이야 있겠어 하는 생각이었는데 설마가 사람잡는다.<br>며칠 후, 나에게 역류성 식도염, 미란성 위염<sup><a href="#Erosive-gastritis">1</a></sup>, 십이지장궤양, 장상피화생<sup><a href="#Intestinal-epithelium">2</a></sup> 등이 있다는 판정을 받았다.<br>허탈감이 몰려왔다.<br>열심히 달렸던 것의 결과가 건강 악화라니.<br>어찌할 바를 몰랐다.<br><code>어떤 것을 해야할지 감이 오지 않았다.</code><sup><a href="#Burnout-step1">3</a></sup><br>정신도 이미 피폐해질대로 피폐해진 상태였고, 모든 것이 만신창이였다.<br>그나마 다행인 점은 여지껏 열심히 해온 덕에 대학원 연구실에는 일을 하지 않고 휴식을 하는 것으로 잘 이야기가 되었다는 것이다.</p><p>휴식을 하면서 처음에는 정말 아무것도 하지 않았다.<br>그 어떤 의욕도 나지 않았고, 할 생각도 없었다.<br>조금 생각을 해보았다.<br>식습관과 생활패턴의 문제도 있었겠으나, 역시 몸과 정신을 상하게한 주 원인은 <code>스트레스</code>였다.<br>나는 나름대로의 확고한 규칙과 기준을 가지고 있으며, 누군가가 이를 흔들 때 정신적으로 많이 흔들리는 편이다.<br>일과 공부를 과중하게 한 탓도 있지만, 이는 부가적인 문제였다.<br>또한, 나는 나의 감정이나 정신 상태를 잘 깨닫지 못하는 편이다.<br>상태의 변화가 타인의 눈에도 잘 띄지 않고, 아무도 모르는 사이에 서서히 상해가다 다 곪아서야 알아차리게 된다.</p><p><code>번아웃은 시간이 지나도 나아질 기미가 보이질 않았고, 아무리 무언가 하려고 시도해봐도 이입이 되지 않고 하기가 싫어졌다.</code><sup><a href="#Burnout-step2">4</a></sup><br>거의 유일했던 취미인 여행도 갈 수 있는 상황이 아니었기에 마땅한 취미생활도 없었다.<br>글을 써보려 했지만, 그럴수록 글을 쓰는 행위조차 싫어지게 되었다.<br>꼭 일을 해야만 하는 어쩔 수 없는 경우에는 꾸역꾸역 해내긴 했지만, 이에 다시 스트레스를 받고 그 반동으로 번아웃이 가중되었다.</p><br><center><img src="/images/retrospective-to-overcome-the-burnout/machu.jpg" width="70%" height="70%"><font size="2" color="gray"> 여행을 하며 돌아다니는 것을 좋아한다. <br> 2018년 1월 1일 마추픽추.</font></center><br><p>모든 생활 패턴을 뒤엎고 처음부터 재구성해야한다고 느꼈다.<br>우선, 원체 만성적으로 앓고 있던 잔병이 많았기에 이것들을 먼저 치료하기로 했다.<br>만성 질병들이 시너지로 나를 더 방해한다고 생각했다.<br>또한, 위장에 대한 건강도 회복해야했기에 온갖 병원이란 병원은 다 찾아다녔다.<br>비염 수술을 하고, 한약을 먹고, 도수 치료를 받았다.<br>정신과에도 다니며 약을 복용하기 시작했다.<br>아침형 인간이 되기 위해 일찍 일어나 조깅을 했고, 건강한 음식을 챙겨먹으며, 술과 담배, 커피를 모두 끊었다.<sup><a href="#Alcohol">5</a></sup><br>위 노력으로 인해 건강이 많이 호전되고 조금은 의욕이 생기기도 했다.<br>그러나, 이는 내가 당장 관리하고 있는 상태이기 때문에 그렇게 느끼는 것이며, 조금이라도 소홀해지면 아직도 몸이 상하고 있는 것이 와닿는다.</p><p>스스로를 많이 끌어올릴 수 있게 된 계기는 나에게 동기부여를 하기 위함이 아니라 예상 외로 여자친구에게 조언을 해주면서였다.<br>한참, 입사한지 얼마 되지 않은 여자친구는 궂은 회사 일로 많이 힘들어하고 있었다.<br>이와 관련해서 여자친구와 많은 대화를 했고 특히, 나는 여자친구에게 <code>자존감</code>에 대한 이야기를 많이 해주었다.<br>여러 말이 있었지만, 최종적인 요점은 <code>자신의 한계를 인정하더라도 스스로를 깎아내리지 말고 보듬어주어야 한다, 나마저 나를 탓하면 아무도 나를 치유할 수 없다</code>였다.<br>이 말을 하던 도중 나에게 놀라운 일이 일어났다.<br>살면서 거의 느껴보지 못한 어떤 행복한 감정이 분비되었던 것이다.<br>내가 여자친구에게 해준 말은 나에게도 해당되는 말이었다.<br>혼자 고민할 때에는 이를 찾지 못하다가, 오히려 타인에게 조언을 함으로 나 자신에 대한 정립을 하게 되었다.<br>또한 이후에, 운이 좋게도 즐겨보던 유튜브 채널인 <span class="exturl" data-url="aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1ES0UwWVl4RjRMUQ==">알간지Alganzi<i class="fa fa-external-link-alt"></i></span>와 <span class="exturl" data-url="aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj0yUDZwYmdYckF0UQ==">1분과학<i class="fa fa-external-link-alt"></i></span>에서 위와 비슷한 말을 하였고, 정립을 더 굳힐 수 있게 되었다.</p><p>그렇게 나름대로는 해야할 일을 정립해서 하나씩 해나갈 수 있는 수준이 되고 있다.<br>이전에 비해 지금의 달라진 점은 공부를 하다가 집중력이 많이 떨어지면 그냥 하지 않기로 한 것과, 나의 몸을 더 신경쓰게 되었다는 것이다.<br>예전에는 어떤 확고한 목표가 있었고 이에 대한 무조건적으로 목표지향적인 삶을 추구했다면, 지금은 목표보다는 나의 삶을 우선 순위로 두고 행복을 느낄 수 있는 방법을 찾고 있다.</p><p>여전히 <code>목표지향적인 삶</code>은 나에게 있어 중요하며 잃고 싶지 않다.<br>하지만, 그렇다고 더 이상 무리하고 스스로를 혹사시키고 싶지도 않다.<br>이 둘을 조절하며 절충하는 것은 아직까지 나의 숙제로 남아있다.<br>지금 이 글을 쓰며 나의 번아웃 과정을 복기하는 것도 이 둘을 맞춰나가기 위한 방법 중 하나이다.<br>내가 벼랑 끝에 내몰렸을 때, 항상 이겨내고 성장을 해왔다.<br>좋다고 해야할지 나쁘다고 해야할지 잘 모르겠지만, 고통을 이겨냈을 때 더 성숙하고 견고해진다.<br><code>나는 결국에 또 나아갈 것이다.</code></p><hr><p><a name="Erosive-gastritis">[1]</a> 피부, 점막의 표피가 박리되어 진피나 점막하조직이 벗겨져 노출되는 정도의 위염이다.<br><a name="Intestinal-epithelium">[2]</a> 위의 점막을 이루는 세포가 장에 있는 세포로 바뀌어 위의 점막이 마치 장의 점막과 유사하게 변하여 제 기능을 하지 못하는 것으로, 장상피화생은 위에 염증이 생기고 다시 회복되는 일을 반복하며 생기게 되며, 위암 발생의 위험요소이다.<br><a name="Burnout-step1">[3]</a> 내가 겪은 번아웃의 1단계<br><a name="Burnout-step2">[4]</a> 내가 겪은 번아웃의 2단계<br><a name="Alcohol">[5]</a> 위 세가지를 모두 끊은지 반년이 조금 넘은 지금은 가끔 맥주 한 잔 정도는 하고 있다.</p>]]></content>
<summary type="html">
<p>바둑에 대해서 잘은 모르지만 그로부터 유래된 단어는 간혹 일상에서 사용하곤 한다.<br>바둑 용어 중에 <code>복기</code>라는 말이 있다.<br>대국이 끝나고 승패가 결정되었음에도 내용을 검토하기 위해 상호 간 처음부터 두었던 순서대로 다시 두어 재연함 뜻하는 단어다.<br>복기로부터 바둑 기사들은 대국에서 잘한 수와 잘못했던 수, 상대방의 전략 등을 살펴본다.<br>프로 9단 바둑기사 이창호는 다음과 같이 말할 정도로 복기를 중요시 했다고 한다.</p>
<blockquote>
<p><strong><em>승리한 대국의 복기는 이기는 습관을 만들어주고, 패배한 대국의 복기는 이기는 준비를 만들어준다</em></strong></p>
</blockquote>
<p>조훈현 9단 또한 복기가 가지않았던 길을 갈 수 있게 한다 하였으며, 패배로 인해 아플수록 더 예민하게 들여다보고 복기해야한다는 말을 했더랬다.<br>이 바둑기사들이 많은 수를 순서대로 기억하여 복기를 할 수 있는 이유는 한 수 한 수에 집중하고 의미를 부여하여 두었기 때문이라고 한다.</p>
</summary>
<category term="에세이" scheme="https://jimheo.github.io/categories/%EC%97%90%EC%84%B8%EC%9D%B4/"/>
<category term="Essay" scheme="https://jimheo.github.io/tags/Essay/"/>
<category term="Retrospective" scheme="https://jimheo.github.io/tags/Retrospective/"/>
<category term="Burnout" scheme="https://jimheo.github.io/tags/Burnout/"/>
<category term="Overcome" scheme="https://jimheo.github.io/tags/Overcome/"/>
</entry>
<entry>
<title>Segmentation Neural Network List Up</title>
<link href="https://jimheo.github.io/2019/03/12/segmentation-neuralnet-listup/"/>
<id>https://jimheo.github.io/2019/03/12/segmentation-neuralnet-listup/</id>
<published>2019-03-12T11:52:45.000Z</published>
<updated>2023-09-21T12:34:47.491Z</updated>
<content type="html"><![CDATA[<blockquote><p><strong><em>Migration to <span class="exturl" data-url="aHR0cHM6Ly9qaW1pbnRoZWJveC5ub3Rpb24uc2l0ZS9NZXRhLVNoZWV0LTA0ODJlM2U1MGExNDQ3MTBiMjUzMzE2ODlkMTg3ZTE2Lw==">Meta Sheet<i class="fa fa-external-link-alt"></i></span></em></strong></p></blockquote><hr><h2 id="U-Net-Convolutional-Networks-for-Biomedical-Image-Segmentation"><a href="#U-Net-Convolutional-Networks-for-Biomedical-Image-Segmentation" class="headerlink" title="U-Net: Convolutional Networks for Biomedical Image Segmentation"></a>U-Net: Convolutional Networks for Biomedical Image Segmentation</h2><p>MICCAI 2015</p><hr><h3 id="Paper"><a href="#Paper" class="headerlink" title="Paper"></a>Paper</h3><ul><li><span class="exturl" data-url="aHR0cHM6Ly9hcnhpdi5vcmcvcGRmLzE1MDUuMDQ1OTcucGRm">https://arxiv.org/pdf/1505.04597.pdf<i class="fa fa-external-link-alt"></i></span></li></ul><h3 id="Source-Code-Repository"><a href="#Source-Code-Repository" class="headerlink" title="Source Code Repository"></a>Source Code Repository</h3><ul><li>Official Model: <span class="exturl" data-url="aHR0cHM6Ly9sbWIuaW5mb3JtYXRpay51bmktZnJlaWJ1cmcuZGUvcmVzb3VyY2VzL29wZW5zb3VyY2UvdW5ldC8=">https://lmb.informatik.uni-freiburg.de/resources/opensource/unet/<i class="fa fa-external-link-alt"></i></span><ul><li>Framework: Caffe</li></ul></li><li>Reproduce Model: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2pha2VyZXQvdGZfdW5ldA==">https://github.com/jakeret/tf_unet<i class="fa fa-external-link-alt"></i></span><ul><li>Framework: Tensorflow</li><li>Paper: <span class="exturl" data-url="aHR0cHM6Ly9hcnhpdi5vcmcvcGRmLzE2MDkuMDkwNzcucGRm">https://arxiv.org/pdf/1609.09077.pdf<i class="fa fa-external-link-alt"></i></span> in Astronomy and Computing 2017</li><li>Documentation: <span class="exturl" data-url="aHR0cHM6Ly90Zi11bmV0LnJlYWR0aGVkb2NzLmlvL2VuL2xhdGVzdC9pbnN0YWxsYXRpb24uaHRtbA==">https://tf-unet.readthedocs.io/en/latest/installation.html<i class="fa fa-external-link-alt"></i></span></li></ul></li><li>Reproduce Model: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3poaXh1aGFvL3VuZXQ=">https://github.com/zhixuhao/unet<i class="fa fa-external-link-alt"></i></span><ul><li>Framework: Keras</li></ul></li><li>Reproduce Model: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL21pbGVzaWFsL1B5dG9yY2gtVU5ldA==">https://github.com/milesial/Pytorch-UNet<i class="fa fa-external-link-alt"></i></span><ul><li>Framework: PyTorch</li></ul></li></ul><a id="more"></a><h3 id="Train-Model-Code-Test-Model-Code"><a href="#Train-Model-Code-Test-Model-Code" class="headerlink" title="Train Model Code, Test Model Code"></a>Train Model Code, Test Model Code</h3><ul><li>Train Model Code<ul><li>Reproduce Model(Tensorflow) Supports API<ul><li><span class="exturl" data-url="aHR0cHM6Ly90Zi11bmV0LnJlYWR0aGVkb2NzLmlvL2VuL2xhdGVzdC91c2FnZS5odG1s">https://tf-unet.readthedocs.io/en/latest/usage.html<i class="fa fa-external-link-alt"></i></span></li></ul></li><li>Reproduce Model(Keras)<ul><li><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3poaXh1aGFvL3VuZXQvYmxvYi9tYXN0ZXIvdHJhaW5VbmV0LmlweW5i">https://github.com/zhixuhao/unet/blob/master/trainUnet.ipynb<i class="fa fa-external-link-alt"></i></span></li></ul></li></ul></li><li>Test Model Code:<ul><li>Reproduce Model(Tensorflow) Supports API<ul><li><span class="exturl" data-url="aHR0cHM6Ly90Zi11bmV0LnJlYWR0aGVkb2NzLmlvL2VuL2xhdGVzdC91c2FnZS5odG1s">https://tf-unet.readthedocs.io/en/latest/usage.html<i class="fa fa-external-link-alt"></i></span></li></ul></li><li>Reproduce Model(Keras)<ul><li><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3poaXh1aGFvL3VuZXQvYmxvYi9tYXN0ZXIvdHJhaW5VbmV0LmlweW5i">https://github.com/zhixuhao/unet/blob/master/trainUnet.ipynb<i class="fa fa-external-link-alt"></i></span></li></ul></li></ul></li></ul><p><strong>REMARK</strong> Reproduce Model(Keras) supports data augmentation docs</p><ul><li><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3poaXh1aGFvL3VuZXQvYmxvYi9tYXN0ZXIvZGF0YVByZXBhcmUuaXB5bmI=">https://github.com/zhixuhao/unet/blob/master/dataPrepare.ipynb<i class="fa fa-external-link-alt"></i></span></li></ul><h3 id="Pre-Trained-Model"><a href="#Pre-Trained-Model" class="headerlink" title="Pre-Trained Model"></a>Pre-Trained Model</h3><ul><li>Unsupported</li></ul><h3 id="Prediction-Examples"><a href="#Prediction-Examples" class="headerlink" title="Prediction Examples"></a>Prediction Examples</h3><p><img src="/images/segmentation-neuralnet-listup/unet_ex.png" alt="UNET"></p><p>Ref: <span class="exturl" data-url="aHR0cHM6Ly9hcnhpdi5vcmcvcGRmLzE1MDUuMDQ1OTcucGRm">https://arxiv.org/pdf/1505.04597.pdf<i class="fa fa-external-link-alt"></i></span></p><h3 id="Citation"><a href="#Citation" class="headerlink" title="Citation"></a>Citation</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">@article{akeret2017radio,</span><br><span class="line"> title={Radio frequency interference mitigation using deep convolutional neural networks},</span><br><span class="line"> author={Akeret, Joel and Chang, Chihway and Lucchi, Aurelien and Refregier, Alexandre},</span><br><span class="line"> journal={Astronomy and Computing},</span><br><span class="line"> volume={18},</span><br><span class="line"> pages={35--39},</span><br><span class="line"> year={2017},</span><br><span class="line"> publisher={Elsevier}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr><br><hr><h2 id="RefineNet-Multi-Path-Refinement-Networks-for-High-Resolution-Semantic-Segmentation"><a href="#RefineNet-Multi-Path-Refinement-Networks-for-High-Resolution-Semantic-Segmentation" class="headerlink" title="RefineNet: Multi-Path Refinement Networks for High-Resolution Semantic Segmentation"></a>RefineNet: Multi-Path Refinement Networks for High-Resolution Semantic Segmentation</h2><p>CVPR 2017</p><hr><h3 id="Paper-1"><a href="#Paper-1" class="headerlink" title="Paper"></a>Paper</h3><ul><li><span class="exturl" data-url="aHR0cHM6Ly9hcnhpdi5vcmcvcGRmLzE2MTEuMDY2MTIucGRm">https://arxiv.org/pdf/1611.06612.pdf<i class="fa fa-external-link-alt"></i></span></li></ul><h3 id="Source-Code-Repository-1"><a href="#Source-Code-Repository-1" class="headerlink" title="Source Code Repository"></a>Source Code Repository</h3><ul><li>Official Model: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2d1b3NoZW5nL3JlZmluZW5ldA==">https://github.com/guosheng/refinenet<i class="fa fa-external-link-alt"></i></span><ul><li>Framework: MATLAB</li></ul></li><li>Reproduce Model: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL0RyU2xlZXAvcmVmaW5lbmV0LXB5dG9yY2g=">https://github.com/DrSleep/refinenet-pytorch<i class="fa fa-external-link-alt"></i></span><ul><li>Framework: PyTorch</li></ul></li><li>Reproduce Model: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL0RyU2xlZXAvbGlnaHQtd2VpZ2h0LXJlZmluZW5ldA==">https://github.com/DrSleep/light-weight-refinenet<i class="fa fa-external-link-alt"></i></span><ul><li>Light Weight RefineNet</li><li>Framework: PyTorch</li></ul></li><li>Reproduce Model: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2VyYWdvbnJ1YW4vcmVmaW5lbmV0LWltYWdlLXNlZ21lbnRhdGlvbg==">https://github.com/eragonruan/refinenet-image-segmentation<i class="fa fa-external-link-alt"></i></span><ul><li>Framework: Tensorflow</li></ul></li></ul><h3 id="Train-Model-Code-Test-Model-Code-1"><a href="#Train-Model-Code-Test-Model-Code-1" class="headerlink" title="Train Model Code, Test Model Code"></a>Train Model Code, Test Model Code</h3><ul><li>Train Model Code: Supported</li><li>Test Model Code: Supported</li></ul><h3 id="Pre-Trained-Model-1"><a href="#Pre-Trained-Model-1" class="headerlink" title="Pre-Trained Model"></a>Pre-Trained Model</h3><ul><li>Supported<ul><li><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2d1b3NoZW5nL3JlZmluZW5ldC9ibG9iL21hc3Rlci9saWJzL21hdGNvbnZuZXQvZG9jL3NpdGUvZG9jcy9wcmV0cmFpbmVkLm1k">https://github.com/guosheng/refinenet/blob/master/libs/matconvnet/doc/site/docs/pretrained.md<i class="fa fa-external-link-alt"></i></span></li></ul></li></ul><h3 id="Prediction-Examples-1"><a href="#Prediction-Examples-1" class="headerlink" title="Prediction Examples"></a>Prediction Examples</h3><p><img src="/images/segmentation-neuralnet-listup/refinenet_ex.png" alt="REFINENET"></p><p>Ref: <span class="exturl" data-url="aHR0cHM6Ly9hcnhpdi5vcmcvcGRmLzE2MTEuMDY2MTIucGRm">https://arxiv.org/pdf/1611.06612.pdf<i class="fa fa-external-link-alt"></i></span></p><center><img src="https://camo.githubusercontent.com/8acf71017ce0d3cb059f01b8bfedcd6792db3f9e/687474703a2f2f696d672e796f75747562652e636f6d2f76692f4c3056367a6d47505f6f512f302e6a7067"></center><p>Ref: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2d1b3NoZW5nL3JlZmluZW5ldA==">https://github.com/guosheng/refinenet<i class="fa fa-external-link-alt"></i></span></p><h3 id="Citation-1"><a href="#Citation-1" class="headerlink" title="Citation"></a>Citation</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">@inproceedings{Lin:2017:RefineNet,</span><br><span class="line"> title = {Refine{N}et: {M}ulti-Path Refinement Networks for High-Resolution Semantic Segmentation},</span><br><span class="line"> shorttitle = {RefineNet: Multi-Path Refinement Networks},</span><br><span class="line"> booktitle = {CVPR},</span><br><span class="line"> author = {Lin, G. and Milan, A. and Shen, C. and Reid, I.},</span><br><span class="line"> month = jul,</span><br><span class="line"> year = {2017}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr><br><hr><h2 id="PSPNet-Pyramid-Scene-Parsing-Network"><a href="#PSPNet-Pyramid-Scene-Parsing-Network" class="headerlink" title="PSPNet: Pyramid Scene Parsing Network"></a>PSPNet: Pyramid Scene Parsing Network</h2><p>CVPR 2017, The Winner in 2016 ILSVRC Scene Parsing Challenge</p><hr><h3 id="Paper-2"><a href="#Paper-2" class="headerlink" title="Paper"></a>Paper</h3><ul><li><span class="exturl" data-url="aHR0cHM6Ly9hcnhpdi5vcmcvcGRmLzE2MTIuMDExMDUucGRm">https://arxiv.org/pdf/1612.01105.pdf<i class="fa fa-external-link-alt"></i></span></li></ul><h3 id="Source-Code-Repository-2"><a href="#Source-Code-Repository-2" class="headerlink" title="Source Code Repository"></a>Source Code Repository</h3><ul><li>Official Model: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2hzemhhby9QU1BOZXQ=">https://github.com/hszhao/PSPNet<i class="fa fa-external-link-alt"></i></span><ul><li>Framework: Caffe</li></ul></li><li>Reproduce Model: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL1ZsYWRrcnl2b3J1Y2hrby9QU1BOZXQtS2VyYXMtdGVuc29yZmxvdw==">https://github.com/Vladkryvoruchko/PSPNet-Keras-tensorflow<i class="fa fa-external-link-alt"></i></span><ul><li>Framework: Keras</li></ul></li><li>Reproduce Model: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2hlbGxvY2hpY2svUFNQTmV0LXRlbnNvcmZsb3c=">https://github.com/hellochick/PSPNet-tensorflow<i class="fa fa-external-link-alt"></i></span><ul><li>Framework: Tensorflow</li></ul></li></ul><h3 id="Train-Model-Code-Test-Model-Code-2"><a href="#Train-Model-Code-Test-Model-Code-2" class="headerlink" title="Train Model Code, Test Model Code"></a>Train Model Code, Test Model Code</h3><ul><li>Train Model Code: Supported in Reproduce Model<ul><li><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL1ZsYWRrcnl2b3J1Y2hrby9QU1BOZXQtS2VyYXMtdGVuc29yZmxvdw==">https://github.com/Vladkryvoruchko/PSPNet-Keras-tensorflow<i class="fa fa-external-link-alt"></i></span></li></ul></li><li>Test Model Code: Supported in Reproduce Model<ul><li><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL1ZsYWRrcnl2b3J1Y2hrby9QU1BOZXQtS2VyYXMtdGVuc29yZmxvdw==">https://github.com/Vladkryvoruchko/PSPNet-Keras-tensorflow<i class="fa fa-external-link-alt"></i></span></li></ul></li></ul><h3 id="Pre-Trained-Model-2"><a href="#Pre-Trained-Model-2" class="headerlink" title="Pre-Trained Model"></a>Pre-Trained Model</h3><ul><li>Supported<ul><li>Offical Model<ul><li><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2hzemhhby9QU1BOZXQ=">https://github.com/hszhao/PSPNet<i class="fa fa-external-link-alt"></i></span></li></ul></li></ul></li><li>Supported<ul><li>Reproduce Model<ul><li><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL1ZsYWRrcnl2b3J1Y2hrby9QU1BOZXQtS2VyYXMtdGVuc29yZmxvdw==">https://github.com/Vladkryvoruchko/PSPNet-Keras-tensorflow<i class="fa fa-external-link-alt"></i></span></li></ul></li></ul></li></ul><h3 id="Prediction-Examples-2"><a href="#Prediction-Examples-2" class="headerlink" title="Prediction Examples"></a>Prediction Examples</h3><center><img src="https://hszhao.github.io/projects/pspnet/figures/voc2012_visual.png"></center><p>Ref: <span class="exturl" data-url="aHR0cHM6Ly9oc3poYW8uZ2l0aHViLmlvL3Byb2plY3RzL3BzcG5ldC8=">https://hszhao.github.io/projects/pspnet/<i class="fa fa-external-link-alt"></i></span></p><h3 id="Citation-2"><a href="#Citation-2" class="headerlink" title="Citation"></a>Citation</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">@inproceedings{zhao2017pspnet,</span><br><span class="line"> author = {Hengshuang Zhao and</span><br><span class="line"> Jianping Shi and</span><br><span class="line"> Xiaojuan Qi and</span><br><span class="line"> Xiaogang Wang and</span><br><span class="line"> Jiaya Jia},</span><br><span class="line"> title = {Pyramid Scene Parsing Network},</span><br><span class="line"> booktitle = {Proceedings of IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},</span><br><span class="line"> year = {2017}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr><br><hr><h2 id="Large-Kernel-Matters-Improve-Semantic-Segmentation-by-Global-Convolutional-Network"><a href="#Large-Kernel-Matters-Improve-Semantic-Segmentation-by-Global-Convolutional-Network" class="headerlink" title="Large Kernel Matters: Improve Semantic Segmentation by Global Convolutional Network"></a>Large Kernel Matters: Improve Semantic Segmentation by Global Convolutional Network</h2><p>CVPR 2017</p><hr><h3 id="Paper-3"><a href="#Paper-3" class="headerlink" title="Paper"></a>Paper</h3><ul><li><span class="exturl" data-url="aHR0cHM6Ly9hcnhpdi5vcmcvcGRmLzE2MTIuMDExMDUucGRm">https://arxiv.org/pdf/1612.01105.pdf<i class="fa fa-external-link-alt"></i></span></li></ul><h3 id="Source-Code-Repository-3"><a href="#Source-Code-Repository-3" class="headerlink" title="Source Code Repository"></a>Source Code Repository</h3><ul><li>Official Model: None</li></ul><p><strong>REMARK</strong> Large Kernel Matters를 Tensorflow로 구현한 코드 및 설명이 기술된 한국 블로그</p><ul><li><span class="exturl" data-url="aHR0cDovL3Jlc2VhcmNoLnN1YWxhYi5jb20vcHJhY3RpY2UvMjAxOC8xMS8yMy9pbWFnZS1zZWdtZW50YXRpb24tZGVlcC1sZWFybmluZy5odG1s">http://research.sualab.com/practice/2018/11/23/image-segmentation-deep-learning.html<i class="fa fa-external-link-alt"></i></span></li></ul><h3 id="Train-Model-Code-Test-Model-Code-3"><a href="#Train-Model-Code-Test-Model-Code-3" class="headerlink" title="Train Model Code, Test Model Code"></a>Train Model Code, Test Model Code</h3><ul><li>Train Model Code: Unsupported</li><li>Test Model Code: Unsupported</li></ul><h3 id="Pre-Trained-Model-3"><a href="#Pre-Trained-Model-3" class="headerlink" title="Pre-Trained Model"></a>Pre-Trained Model</h3><ul><li>Unsupported</li></ul><h3 id="Prediction-Examples-3"><a href="#Prediction-Examples-3" class="headerlink" title="Prediction Examples"></a>Prediction Examples</h3><p><img src="/images/segmentation-neuralnet-listup/GCN_ex.png" alt="GCN"></p><p>Ref: <span class="exturl" data-url="aHR0cHM6Ly9hcnhpdi5vcmcvcGRmLzE3MDMuMDI3MTkucGRm">https://arxiv.org/pdf/1703.02719.pdf<i class="fa fa-external-link-alt"></i></span></p><hr><br><hr><h2 id="DeepLab-v3-Atrous-SeparableConvolution-for-Semantic-Image-Segmentation"><a href="#DeepLab-v3-Atrous-SeparableConvolution-for-Semantic-Image-Segmentation" class="headerlink" title="DeepLab v3(+): Atrous SeparableConvolution for Semantic Image Segmentation"></a>DeepLab v3(+): Atrous SeparableConvolution for Semantic Image Segmentation</h2><p>ECCV 2018</p><hr><h3 id="Paper-4"><a href="#Paper-4" class="headerlink" title="Paper"></a>Paper</h3><ul><li>DeepLab v3: <span class="exturl" data-url="aHR0cHM6Ly9hcnhpdi5vcmcvcGRmLzE3MDYuMDU1ODcucGRm">https://arxiv.org/pdf/1706.05587.pdf<i class="fa fa-external-link-alt"></i></span></li><li>DeepLab v3+: <span class="exturl" data-url="aHR0cHM6Ly9hcnhpdi5vcmcvcGRmLzE4MDIuMDI2MTEucGRm">https://arxiv.org/pdf/1802.02611.pdf<i class="fa fa-external-link-alt"></i></span></li></ul><h3 id="Source-Code-Repository-4"><a href="#Source-Code-Repository-4" class="headerlink" title="Source Code Repository"></a>Source Code Repository</h3><ul><li>Official Model: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3RlbnNvcmZsb3cvbW9kZWxzL3RyZWUvbWFzdGVyL3Jlc2VhcmNoL2RlZXBsYWI=">https://github.com/tensorflow/models/tree/master/research/deeplab<i class="fa fa-external-link-alt"></i></span><ul><li>Framework: Tensorflow</li></ul></li></ul><h3 id="Train-Model-Code-Test-Model-Code-4"><a href="#Train-Model-Code-Test-Model-Code-4" class="headerlink" title="Train Model Code, Test Model Code"></a>Train Model Code, Test Model Code</h3><ul><li>Train Model Code: Supported</li><li>Test Model Code: Supported</li></ul><h3 id="Pre-Trained-Model-4"><a href="#Pre-Trained-Model-4" class="headerlink" title="Pre-Trained Model"></a>Pre-Trained Model</h3><ul><li>Supported</li></ul><h3 id="Prediction-Examples-4"><a href="#Prediction-Examples-4" class="headerlink" title="Prediction Examples"></a>Prediction Examples</h3><center><img src="https://raw.githubusercontent.com/tensorflow/models/master/research/deeplab/g3doc/img/vis1.png"></center><p>Ref: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3RlbnNvcmZsb3cvbW9kZWxzL3RyZWUvbWFzdGVyL3Jlc2VhcmNoL2RlZXBsYWI=">https://github.com/tensorflow/models/tree/master/research/deeplab<i class="fa fa-external-link-alt"></i></span></p><h3 id="Citation-3"><a href="#Citation-3" class="headerlink" title="Citation"></a>Citation</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">@inproceedings{deeplabv3plus2018,</span><br><span class="line"> title={Encoder-Decoder with Atrous Separable Convolution for Semantic Image Segmentation},</span><br><span class="line"> author={Liang-Chieh Chen and Yukun Zhu and George Papandreou and Florian Schroff and Hartwig Adam},</span><br><span class="line"> booktitle={ECCV},</span><br><span class="line"> year={2018}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr><br><hr><h2 id="Inplace-ABN-In-Place-Activated-BatchNorm-for-Memory-Optimized-Training-of-DNNs"><a href="#Inplace-ABN-In-Place-Activated-BatchNorm-for-Memory-Optimized-Training-of-DNNs" class="headerlink" title="Inplace ABN: In-Place Activated BatchNorm for Memory-Optimized Training of DNNs"></a>Inplace ABN: In-Place Activated BatchNorm for Memory-Optimized Training of DNNs</h2><p>CVPR 2018</p><hr><h3 id="Paper-5"><a href="#Paper-5" class="headerlink" title="Paper"></a>Paper</h3><ul><li><span class="exturl" data-url="aHR0cHM6Ly9hcnhpdi5vcmcvcGRmLzE3MTIuMDI2MTZ2My5wZGY=">https://arxiv.org/pdf/1712.02616v3.pdf<i class="fa fa-external-link-alt"></i></span></li></ul><h3 id="Source-Code-Repository-5"><a href="#Source-Code-Repository-5" class="headerlink" title="Source Code Repository"></a>Source Code Repository</h3><ul><li>Official Model: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL21hcGlsbGFyeS9pbnBsYWNlX2Fibg==">https://github.com/mapillary/inplace_abn<i class="fa fa-external-link-alt"></i></span><ul><li>Framework: PyTorch</li></ul></li></ul><h3 id="Train-Model-Code-Test-Model-Code-5"><a href="#Train-Model-Code-Test-Model-Code-5" class="headerlink" title="Train Model Code, Test Model Code"></a>Train Model Code, Test Model Code</h3><ul><li>Train Model Code: Supported</li><li>Test Model Code: Supported</li></ul><h3 id="Pre-Trained-Model-5"><a href="#Pre-Trained-Model-5" class="headerlink" title="Pre-Trained Model"></a>Pre-Trained Model</h3><ul><li>Supported</li></ul><h3 id="Citation-4"><a href="#Citation-4" class="headerlink" title="Citation"></a>Citation</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">@inproceedings{rotabulo2017place,</span><br><span class="line"> title={In-Place Activated BatchNorm for Memory-Optimized Training of DNNs},</span><br><span class="line"> author={Rota Bul\`o, Samuel and Porzi, Lorenzo and Kontschieder, Peter},</span><br><span class="line"> booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition},</span><br><span class="line"> year={2018}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr><br><hr><h2 id="TernausNetV2-Fully-Convolutional-Network-for-Instance-Segmentation"><a href="#TernausNetV2-Fully-Convolutional-Network-for-Instance-Segmentation" class="headerlink" title="TernausNetV2: Fully Convolutional Network for Instance Segmentation"></a>TernausNetV2: Fully Convolutional Network for Instance Segmentation</h2><p>2nd place in CVPR 2018 DeepGlobe Building Extraction Challenge</p><hr><h3 id="Paper-6"><a href="#Paper-6" class="headerlink" title="Paper"></a>Paper</h3><ul><li><span class="exturl" data-url="aHR0cDovL29wZW5hY2Nlc3MudGhlY3ZmLmNvbS9jb250ZW50X2N2cHJfMjAxOF93b3Jrc2hvcHMvcGFwZXJzL3c0L0lnbG92aWtvdl9UZXJuYXVzTmV0VjJfRnVsbHlfQ29udm9sdXRpb25hbF9DVlBSXzIwMThfcGFwZXIucGRm">http://openaccess.thecvf.com/content_cvpr_2018_workshops/papers/w4/Iglovikov_TernausNetV2_Fully_Convolutional_CVPR_2018_paper.pdf<i class="fa fa-external-link-alt"></i></span></li></ul><h3 id="Source-Code-Repository-6"><a href="#Source-Code-Repository-6" class="headerlink" title="Source Code Repository"></a>Source Code Repository</h3><ul><li>Official Model: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3Rlcm5hdXMvVGVybmF1c05ldFYy">https://github.com/ternaus/TernausNetV2<i class="fa fa-external-link-alt"></i></span><ul><li>Framework: PyTorch</li></ul></li></ul><h3 id="Train-Model-Code-Test-Model-Code-6"><a href="#Train-Model-Code-Test-Model-Code-6" class="headerlink" title="Train Model Code, Test Model Code"></a>Train Model Code, Test Model Code</h3><ul><li>Train Model Code: Unsupported</li><li>Test Model Code: Unsupported</li></ul><h3 id="Pre-Trained-Model-6"><a href="#Pre-Trained-Model-6" class="headerlink" title="Pre-Trained Model"></a>Pre-Trained Model</h3><ul><li>Unsupported</li></ul><h3 id="Prediction-Example"><a href="#Prediction-Example" class="headerlink" title="Prediction Example"></a>Prediction Example</h3><center><img src="https://camo.githubusercontent.com/c3c8b42313d139c6d562880cb4725f2b453e4ec7/68747470733a2f2f686162726173746f726167652e6f72672f776562742f6b6f2f62322f74772f6b6f62327477686a7a6a666e61756978376c6a74656430376761382e706e67"></center><p>Ref: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3Rlcm5hdXMvVGVybmF1c05ldFYy">https://github.com/ternaus/TernausNetV2<i class="fa fa-external-link-alt"></i></span></p><h3 id="Citation-5"><a href="#Citation-5" class="headerlink" title="Citation"></a>Citation</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">@InProceedings{Iglovikov_2018_CVPR_Workshops,</span><br><span class="line"> author = {Iglovikov, Vladimir and Seferbekov, Selim and Buslaev, Alexander and Shvets, Alexey},</span><br><span class="line"> title = {TernausNetV2: Fully Convolutional Network for Instance Segmentation},</span><br><span class="line"> booktitle = {The IEEE Conference on Computer Vision and Pattern Recognition (CVPR) Workshops},</span><br><span class="line"> month = {June},</span><br><span class="line"> year = {2018}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr><br><hr><h2 id="Automatic-Instrument-Segmentation-in-Robot-Assisted-Surgery-Using-Deep-Learning"><a href="#Automatic-Instrument-Segmentation-in-Robot-Assisted-Surgery-Using-Deep-Learning" class="headerlink" title="Automatic Instrument Segmentation in Robot-Assisted Surgery Using Deep Learning"></a>Automatic Instrument Segmentation in Robot-Assisted Surgery Using Deep Learning</h2><p>ICMLA 2018, Wining solution and its improvement for MICCAI 2017 Robotic Instrument Segmentation Sub-Challenge</p><hr><h3 id="Paper-7"><a href="#Paper-7" class="headerlink" title="Paper"></a>Paper</h3><ul><li><span class="exturl" data-url="aHR0cHM6Ly9hcnhpdi5vcmcvcGRmLzE4MDMuMDEyMDcucGRm">https://arxiv.org/pdf/1803.01207.pdf<i class="fa fa-external-link-alt"></i></span></li></ul><h3 id="Source-Code-Repository-7"><a href="#Source-Code-Repository-7" class="headerlink" title="Source Code Repository"></a>Source Code Repository</h3><ul><li>Official Model: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3Rlcm5hdXMvVGVybmF1c05ldFYy">https://github.com/ternaus/TernausNetV2<i class="fa fa-external-link-alt"></i></span><ul><li>Framework: PyTorch</li></ul></li></ul><h3 id="Train-Model-Code-Test-Model-Code-7"><a href="#Train-Model-Code-Test-Model-Code-7" class="headerlink" title="Train Model Code, Test Model Code"></a>Train Model Code, Test Model Code</h3><ul><li>Train Model Code: Supported</li><li>Test Model Code: Supported</li></ul><h3 id="Pre-Trained-Model-7"><a href="#Pre-Trained-Model-7" class="headerlink" title="Pre-Trained Model"></a>Pre-Trained Model</h3><ul><li>Supported in <span class="exturl" data-url="aHR0cHM6Ly9kcml2ZS5nb29nbGUuY29tL2RyaXZlL2ZvbGRlcnMvMTNlMEM0ZkF0SmVtamV3WXF4UHRRSE82WGdnazdsc0tl">https://drive.google.com/drive/folders/13e0C4fAtJemjewYqxPtQHO6Xggk7lsKe<i class="fa fa-external-link-alt"></i></span></li></ul><h3 id="Prediction-Example-1"><a href="#Prediction-Example-1" class="headerlink" title="Prediction Example"></a>Prediction Example</h3><center><img src="https://raw.githubusercontent.com/ternaus/robot-surgery-segmentation/master/images/grid-1-41.png"></center><p>Ref: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3Rlcm5hdXMvcm9ib3Qtc3VyZ2VyeS1zZWdtZW50YXRpb24=">https://github.com/ternaus/robot-surgery-segmentation<i class="fa fa-external-link-alt"></i></span></p><h3 id="Citation-6"><a href="#Citation-6" class="headerlink" title="Citation"></a>Citation</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">@article{shvets2018automatic,</span><br><span class="line">title={Automatic Instrument Segmentation in Robot-Assisted Surgery Using Deep Learning},</span><br><span class="line">author={Shvets, Alexey and Rakhlin, Alexander and Kalinin, Alexandr A and Iglovikov, Vladimir},</span><br><span class="line">journal={arXiv preprint arXiv:1803.01207},</span><br><span class="line">year={2018}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr>]]></content>
<summary type="html">
<blockquote>
<p><strong><em>Migration to <span class="exturl" data-url="aHR0cHM6Ly9qaW1pbnRoZWJveC5ub3Rpb24uc2l0ZS9NZXRhLVNoZWV0LTA0ODJlM2U1MGExNDQ3MTBiMjUzMzE2ODlkMTg3ZTE2Lw==">Meta Sheet<i class="fa fa-external-link-alt"></i></span></em></strong></p>
</blockquote>
<hr>
<h2 id="U-Net-Convolutional-Networks-for-Biomedical-Image-Segmentation"><a href="#U-Net-Convolutional-Networks-for-Biomedical-Image-Segmentation" class="headerlink" title="U-Net: Convolutional Networks for Biomedical Image Segmentation"></a>U-Net: Convolutional Networks for Biomedical Image Segmentation</h2><p>MICCAI 2015</p>
<hr>
<h3 id="Paper"><a href="#Paper" class="headerlink" title="Paper"></a>Paper</h3><ul>
<li><span class="exturl" data-url="aHR0cHM6Ly9hcnhpdi5vcmcvcGRmLzE1MDUuMDQ1OTcucGRm">https://arxiv.org/pdf/1505.04597.pdf<i class="fa fa-external-link-alt"></i></span></li>
</ul>
<h3 id="Source-Code-Repository"><a href="#Source-Code-Repository" class="headerlink" title="Source Code Repository"></a>Source Code Repository</h3><ul>
<li>Official Model: <span class="exturl" data-url="aHR0cHM6Ly9sbWIuaW5mb3JtYXRpay51bmktZnJlaWJ1cmcuZGUvcmVzb3VyY2VzL29wZW5zb3VyY2UvdW5ldC8=">https://lmb.informatik.uni-freiburg.de/resources/opensource/unet/<i class="fa fa-external-link-alt"></i></span><ul>
<li>Framework: Caffe</li>
</ul>
</li>
<li>Reproduce Model: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2pha2VyZXQvdGZfdW5ldA==">https://github.com/jakeret/tf_unet<i class="fa fa-external-link-alt"></i></span><ul>
<li>Framework: Tensorflow</li>
<li>Paper: <span class="exturl" data-url="aHR0cHM6Ly9hcnhpdi5vcmcvcGRmLzE2MDkuMDkwNzcucGRm">https://arxiv.org/pdf/1609.09077.pdf<i class="fa fa-external-link-alt"></i></span> in Astronomy and Computing 2017</li>
<li>Documentation: <span class="exturl" data-url="aHR0cHM6Ly90Zi11bmV0LnJlYWR0aGVkb2NzLmlvL2VuL2xhdGVzdC9pbnN0YWxsYXRpb24uaHRtbA==">https://tf-unet.readthedocs.io/en/latest/installation.html<i class="fa fa-external-link-alt"></i></span></li>
</ul>
</li>
<li>Reproduce Model: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3poaXh1aGFvL3VuZXQ=">https://github.com/zhixuhao/unet<i class="fa fa-external-link-alt"></i></span><ul>
<li>Framework: Keras</li>
</ul>
</li>
<li>Reproduce Model: <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL21pbGVzaWFsL1B5dG9yY2gtVU5ldA==">https://github.com/milesial/Pytorch-UNet<i class="fa fa-external-link-alt"></i></span><ul>
<li>Framework: PyTorch</li>
</ul>
</li>
</ul>
</summary>
<category term="머신러닝" scheme="https://jimheo.github.io/categories/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D/"/>
<category term="딥러닝" scheme="https://jimheo.github.io/categories/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D/%EB%94%A5%EB%9F%AC%EB%8B%9D/"/>
<category term="Image Processing" scheme="https://jimheo.github.io/tags/Image-Processing/"/>
<category term="Computer Vision" scheme="https://jimheo.github.io/tags/Computer-Vision/"/>
<category term="Deep Learning" scheme="https://jimheo.github.io/tags/Deep-Learning/"/>
<category term="CVPR" scheme="https://jimheo.github.io/tags/CVPR/"/>
<category term="MICCAI" scheme="https://jimheo.github.io/tags/MICCAI/"/>
<category term="ICCV" scheme="https://jimheo.github.io/tags/ICCV/"/>
<category term="ECCV" scheme="https://jimheo.github.io/tags/ECCV/"/>
<category term="Semantic Segmentation" scheme="https://jimheo.github.io/tags/Semantic-Segmentation/"/>
</entry>
<entry>
<title>자료구조, 힙(Heap)</title>
<link href="https://jimheo.github.io/2018/10/12/about-heap/"/>
<id>https://jimheo.github.io/2018/10/12/about-heap/</id>
<published>2018-10-12T08:10:13.000Z</published>
<updated>2023-09-21T12:34:47.487Z</updated>
<content type="html"><![CDATA[<h2 id="Complete-Binary-Tree"><a href="#Complete-Binary-Tree" class="headerlink" title="Complete Binary Tree"></a>Complete Binary Tree</h2><p>Tree에 대한 기본적인 설명은 루비콘 팀 Martin Kim의 포스트를 참조한다. <span class="github-emoji" alias="bow" style fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f647.png?v8">🙇</span></p><p><strong>Ref: <span class="exturl" data-url="aHR0cHM6Ly9ibG9nLm1hcnRpbndvcmsuY28ua3IvdGhlb3J5LzIwMTgvMDkvMjIvd2hhdC1pcy10cmVlLmh0bWw=">https://blog.martinwork.co.kr/theory/2018/09/22/what-is-tree.html<i class="fa fa-external-link-alt"></i></span></strong></p><p>추가적으로 Tree에 대해 부가설명을 덧붙인다.<br>Tree의 정의는 다음 2가지를 따른다.</p><br><blockquote><p><strong>1. A root node</strong><br><strong>2. The remaining nodes are partitioned into $n(n \geq 0)$ disjoint sets $T_1, T_2, … , T_n$ ($T_i$ : subtrees of the root)</strong></p></blockquote><br><p>즉, 루트 노드가 존재하며, 0개 이상의 서브트리로 분리된 노드가 존재해야 한다.<br>이 중 Full Binary Tree는 Depth가 $k$일 때, 총 노드의 개수는 $2^k - 1$개인 트리이며,<br>Complete Binary Tree는 Depth가 $k$인 Full Binary Tree를 왼쪽에서부터 순차적으로 읽었을 때, $k-level$에서 Complete Binary Tree의 총 노드 수 $n$의 인덱스를 가진 노드가 존재하는 것을 말한다.</p><p>이 때, $k =\lceil\log_{2}(n + 1)\rceil$이 성립한다.<br>Complete Binary Tree는 마지막 레벨을 제외하고 모든 레벨이 채워져 있으며, 마지막 레벨의 모든 노드는 가능한 한 가장 왼쪽에 있기 때문에 공간의 낭비가 없어 배열로 구현하는 것이 효율적이다.</p><a id="more"></a><p><img src="/images/about-heap/treearray.png" alt="TREEARRAY"></p><p>배열로 구현 시, $i$번째 노드의 자식 노드는 각각 $2i,\ 2i + 1$이 되며, 부모 노드는 존재 시 $\lfloor i / 2\rfloor$가 된다. (부모 노드의 인덱스가 $0$부터 시작할 경우에는 자식은 $2i + 1,\ 2i + 2$, 부모는 $\lfloor(i - 1) / 2\rfloor$가 된다.)</p><h2 id="Heap의-정의와-연산"><a href="#Heap의-정의와-연산" class="headerlink" title="Heap의 정의와 연산"></a>Heap의 정의와 연산</h2><p>사전적 의미에서 Heap은 <code>무엇인가를 차곡차곡 쌓아올린 더미</code>를 뜻한다.<br>Heap은 메모리에서 동적할당을 받을 때, 정렬을 할 때, 그리고 우선순위 큐(Priority Queue)나 무손실 압축 알고리즘인 허프만 코드 등에 다양하게 사용된다.</p><p>위에서 Tree를 설명한 이유는 Heap은 Tree 구조 중 Complete Binary Tree에서 몇가지 Constraint를 더하여 파생된 자료구조기 때문이다.<br>Heap은 Max Heap과 Min Heap 두가지가 있는데, Max Heap은 Complete Binary Tree이면서 노드의 값이 자식 노드의 값보다 작지 않은 경우, Min Heap은 그 반대의 경우다.</p><p>Heap이 Complete Binary Tree를 이용하여 구현된 이유는 삽입과 삭제의 속도 때문인데, 앞서 설명 한 Complete Binary Tree에서 부모와 자식 노드의 인덱스를 빠르게 찾을 수 있는 특성 때문이다.</p><p>이 글에서는 Max Heap을 기준으로 설명한다.<br>Heap을 C++의 Class를 사용하여 정의하면 다음과 같다.</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MaxHeap</span>{</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> MaxHeap();</span><br><span class="line"> ~MaxHeap();</span><br><span class="line"> <span class="function"><span class="keyword">void</span> <span class="title">Insert</span><span class="params">(<span class="keyword">int</span> x)</span></span>; <span class="comment">//Push the element</span></span><br><span class="line"> <span class="function"><span class="keyword">void</span> <span class="title">Delete</span><span class="params">()</span></span>; <span class="comment">//Pop the root</span></span><br><span class="line"> <span class="function"><span class="keyword">int</span> <span class="title">Top</span><span class="params">()</span></span>; <span class="comment">//Return the root</span></span><br><span class="line"> <span class="function"><span class="keyword">int</span> <span class="title">Top</span><span class="params">(<span class="keyword">int</span> n)</span></span>; <span class="comment">//return the n-th rank node</span></span><br><span class="line"> <span class="function"><span class="keyword">bool</span> <span class="title">isEmpty</span><span class="params">()</span></span>; <span class="comment">//Determine the heap is empty or not</span></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> heap; <span class="comment">//Index 0 is not used</span></span><br><span class="line">};</span><br></pre></td></tr></table></figure><p>Heap의 삽입 연산의 경우 Complete Binary Tree의 특성에 따라 처음에는 Leaf 노드의 빈 곳 중 가장 왼쪽에 새로운 노드를 추가한다.<br>그 후, 삽입된 노드와 그 노드의 부모와 비교 연산을 수행하고 삽입된 노드의 값이 가장 크면 부모 노드와 자리를 바꾼다.</p><p>그리고 옮겨진 상태에서 다시 부모와 비교, Swap을 수행하며, 부모보다 값이 크지 않다면 삽입연산이 종료된다.<br>그렇지 않을 경우 계속된 과정 끝에 삽입된 노드가 루트가 되며 삽입연산이 종료된다.<br>이 과정을 <code>Bubble up</code>(거품이 올라가는 모양과 유사하여)이라 칭한다.</p><p>삽입 연산을 도식화 한 경우는 다음과 같다.</p><p><img src="/images/about-heap/insert1.jpg" alt="INSERT1"><br><img src="/images/about-heap/insert2.jpg" alt="INSERT2"><br><img src="/images/about-heap/insert3.jpg" alt="INSERT3"><br><img src="/images/about-heap/insert4.jpg" alt="INSERT4"></p><p>삽입 연산을 구현한 코드는 다음과 같다.</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">MaxHeap::Insert</span><span class="params">(<span class="keyword">int</span> x)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span>(isEmpty())</span><br><span class="line"> heap.push_back(x);</span><br><span class="line"> <span class="keyword">else</span>{</span><br><span class="line"> heap.push_back(x);</span><br><span class="line"> <span class="keyword">int</span> i = heap.<span class="built_in">size</span>() - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">while</span>(i != <span class="number">1</span>){</span><br><span class="line"> <span class="keyword">if</span>(heap.at(i) > heap.at(i / <span class="number">2</span>))</span><br><span class="line"> swap(heap.at(i), heap.at(i / <span class="number">2</span>));</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> i /= <span class="number">2</span>;</span><br><span class="line"> } <span class="comment">//bubble up</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>삭제 연산의 경우는 별도의 인덱스를 지정하는 것이 아니라, 루트 노드에 대한 연산이다.<br>루트 노드를 Pop한 후에, 가장 마지막 노드를 루트로 올린다.</p><p>그리고 자신과 두 자식(혹은 한 자식)과 비교연산을 수행한 후 가장 큰 노드를 해당 노드와 Swap한다.<br>그 후, 삽입 연산과 마찬가지로 모두 적절한 자리에 놓일 때까지 반복작업을 수행한다.</p><p>이 과정을 <code>Trickle Down</code>(물방울이 떨어지는 모양과 유사하여)이라 칭한다.<br>삭제 연산을 도식화 한 경우는 다음과 같다.</p><p><img src="/images/about-heap/insert4.jpg" alt="INSERT4"><br><img src="/images/about-heap/delete1.jpg" alt="DELETE1"><br><img src="/images/about-heap/delete2.jpg" alt="DELETE2"><br><img src="/images/about-heap/delete3.jpg" alt="DELETE3"><br><img src="/images/about-heap/delete4.jpg" alt="DELETE4"></p><p>삭제 연산을 구현한 코드는 다음과 같다.</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">MaxHeap::Delete</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">if</span>(isEmpty())</span><br><span class="line"> <span class="keyword">throw</span> <span class="string">"error"</span>;</span><br><span class="line"></span><br><span class="line"> heap.at(<span class="number">1</span>) = heap.at(heap.<span class="built_in">size</span>() - <span class="number">1</span>);</span><br><span class="line"> heap.pop_back();</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">int</span> last_idx = heap.<span class="built_in">size</span>() - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">int</span> max_child_idx;</span><br><span class="line"> <span class="keyword">while</span>(i * <span class="number">2</span> <= last_idx){</span><br><span class="line"> <span class="keyword">if</span>(i * <span class="number">2</span> + <span class="number">1</span> > last_idx) <span class="comment">//if child of i is only left side</span></span><br><span class="line"> max_child_idx = i * <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">else</span>{</span><br><span class="line"> <span class="keyword">if</span>(heap.at(i * <span class="number">2</span>) > heap.at(i * <span class="number">2</span> + <span class="number">1</span>)) <span class="comment">//compare left-child to right-child before child to parent</span></span><br><span class="line"> max_child_idx = i * <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> max_child_idx = i * <span class="number">2</span> + <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span>(heap.at(i) < heap.at(max_child_idx)) <span class="comment">//compare child to parent</span></span><br><span class="line"> swap(heap.at(i), heap.at(max_child_idx));</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> i = max_child_idx;</span><br><span class="line"> } <span class="comment">//trickle down</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>삽입과 삭제는 트리의 높이만큼의 시간의 소요되므로 이는 $O(\log_{2}n) $이다.<br>Heap에 가장 중요한 연산은 삽입과 삭제 두가지이나, 추가적으로 n번째로 큰 수를 리턴해주는 Ranking Search가 가능하며, 이 경우 Heap을 이용한 정렬인 Heap Sort가 사용된다.</p><p>Heap Sort는 힙이 비게 될 때까지, Top 연산(트리의 루트노드를 리턴)과 삭제 연산을 계속해서 수행하면서 Top 연산에서 리턴받은 값들을 차례로 새로운 배열에 저장하면 정렬이 되는 방식이다.<br>Heap Sort를 수행한 후 완성된 배열의 n번째 인덱스가 곧 힙에서 n번째로 큰 수를 의미한다.</p><p>Ranking Search에 대한 코드는 다음과 같다.</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//using heapsort</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">MaxHeap::Top</span><span class="params">(<span class="keyword">int</span> n)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span>(heap.<span class="built_in">size</span>() - <span class="number">1</span> < n)</span><br><span class="line"> <span class="keyword">throw</span> <span class="string">"error"</span>;</span><br><span class="line"></span><br><span class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> backup = heap;</span><br><span class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> sorted_heap;</span><br><span class="line"> sorted_heap.push_back(<span class="number">0</span>);</span><br><span class="line"> <span class="keyword">int</span> top;</span><br><span class="line"> <span class="keyword">while</span>(!isEmpty()){</span><br><span class="line"> top = Top();</span><br><span class="line"> Delete();</span><br><span class="line"> sorted_heap.push_back(top);</span><br><span class="line"> }</span><br><span class="line"> heap.swap(backup);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> sorted_heap.at(n);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>사실 위에 while문을 n번만큼만 돌아도 Ranking Search가 가능하지만, Heap Sort의 설명을 곁들이기 위해서 모든 노드를 비웠다. Heap Sort의 경우에는 $O(n\log_{2}n)$의 수행시간을 보인다.</p>]]></content>
<summary type="html">
<h2 id="Complete-Binary-Tree"><a href="#Complete-Binary-Tree" class="headerlink" title="Complete Binary Tree"></a>Complete Binary Tree</h2><p>Tree에 대한 기본적인 설명은 루비콘 팀 Martin Kim의 포스트를 참조한다. <span class="github-emoji" alias="bow" style fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f647.png?v8">&#x1f647;</span></p>
<p><strong>Ref: <span class="exturl" data-url="aHR0cHM6Ly9ibG9nLm1hcnRpbndvcmsuY28ua3IvdGhlb3J5LzIwMTgvMDkvMjIvd2hhdC1pcy10cmVlLmh0bWw=">https://blog.martinwork.co.kr/theory/2018/09/22/what-is-tree.html<i class="fa fa-external-link-alt"></i></span></strong></p>
<p>추가적으로 Tree에 대해 부가설명을 덧붙인다.<br>Tree의 정의는 다음 2가지를 따른다.</p>
<br>
<blockquote>
<p><strong>1. A root node</strong><br><strong>2. The remaining nodes are partitioned into $n(n \geq 0)$ disjoint sets $T_1, T_2, … , T_n$ ($T_i$ : subtrees of the root)</strong></p>
</blockquote>
<br>
<p>즉, 루트 노드가 존재하며, 0개 이상의 서브트리로 분리된 노드가 존재해야 한다.<br>이 중 Full Binary Tree는 Depth가 $k$일 때, 총 노드의 개수는 $2^k - 1$개인 트리이며,<br>Complete Binary Tree는 Depth가 $k$인 Full Binary Tree를 왼쪽에서부터 순차적으로 읽었을 때, $k-level$에서 Complete Binary Tree의 총 노드 수 $n$의 인덱스를 가진 노드가 존재하는 것을 말한다.</p>
<p>이 때, $k =\lceil\log_{2}(n + 1)\rceil$이 성립한다.<br>Complete Binary Tree는 마지막 레벨을 제외하고 모든 레벨이 채워져 있으며, 마지막 레벨의 모든 노드는 가능한 한 가장 왼쪽에 있기 때문에 공간의 낭비가 없어 배열로 구현하는 것이 효율적이다.</p>
</summary>
<category term="프로그래밍" scheme="https://jimheo.github.io/categories/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/"/>
<category term="자료구조" scheme="https://jimheo.github.io/categories/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0/"/>
<category term="C++" scheme="https://jimheo.github.io/tags/C/"/>
<category term="Data Structure" scheme="https://jimheo.github.io/tags/Data-Structure/"/>
<category term="Heap" scheme="https://jimheo.github.io/tags/Heap/"/>
<category term="Tree" scheme="https://jimheo.github.io/tags/Tree/"/>
</entry>
<entry>
<title>Concept of Data Structure</title>
<link href="https://jimheo.github.io/2018/10/12/concept-of-data-structure/"/>
<id>https://jimheo.github.io/2018/10/12/concept-of-data-structure/</id>
<published>2018-10-12T03:52:35.000Z</published>
<updated>2023-09-21T12:34:47.487Z</updated>
<content type="html"><![CDATA[<h2 id="자료구조란"><a href="#자료구조란" class="headerlink" title="자료구조란?"></a>자료구조란?</h2><p>자료구조를 공부하는 것은 알고리즘을 해결하는데 뿐만 아니라, 라이브러리나 프레임워크를 사용할 때 단순히 가져다 쓰지 않고, 내부적으로 어떻게 구현되있는지에 대한 이해도가 향상되므로 라이브러리에 있는 적절한 자료형을 사용할 수 있다.</p><h3 id="OOP와-자료구조"><a href="#OOP와-자료구조" class="headerlink" title="OOP와 자료구조"></a>OOP와 자료구조</h3><p>자료구조란 위키백과의 정의에 따르면 <code>자료를 효율적으로 이용할 수 있도록 컴퓨터에 저장하는 방법</code>이다.<br>즉, 어떠한 알고리즘을 구현하는데 있어 그에 맞는 자료구조를 설계하여 사용해야 시간적으로 혹은 공간적으로 자원을 최소화 할 수 있다.</p><p>사실, 위의 말은 이제 프로그래밍을 시작하고 자료구조라는 단어를 처음 듣는 사람들에게는 잘 와닿지 않는다.<br>조금 더 구체적으로 말하자면, 모든 프로그래밍 언어들에는 <code>int, char, boolean</code> 등의 가장 기본적인(primitive) 자료형이 존재한다.</p><p>그러나 primitive 자료형으로만 코딩을 했을 때, 재사용성이 떨어지고 제한적이다.<br>그렇기 때문에 주로 사용자 자료형, 다시 말해 추상 자료형(Abstract Data Type, ADT)를 정의하여 사용하는 것이 바람직하며, ADT가 곧 자료구조라고 할 수 있다.</p><a id="more"></a><p>물론, 배열이나 리스트 등 대표적인 자료구조는 (특히, 상위 레벨 언어에서는) 이미 예약어로 존재하지만, int와 같이 직접적으로 메모리에 할당되는 것이 아니라 언어의 버전이 올라갈수록 사용자의 편의를 위해서 구현한 것이므로 primitive로 분류하지 않는다.<br>ADT는 Object Oriented Design에서 Class와 사실상 거의 동일하므로, 클래스를 이용하여 구현하는 것이 효율적이다.</p><p>클래스처럼, ADT는 attribute와 operation을 가지고 있으며, OOD의 Encapsulation을 따라서, attribute는 private로 제한하고 모든 수행은 operation을 통해서 한다.</p><p>UML의 창시자인 Grady Booch에 따르면 OOP의 다음 3가지를 충족해야 한다.</p><ol><li>객체는 기본적인 블록 단위로 구성되어 있다.</li><li>각 객체는 클래스의 인스턴스이다.</li><li>클래스는 상속을 지원한다.</li></ol><p>C++이나 Java 등 대표적인 객체지향언어는 위 정의에 따라서 프로그래밍이 가능하다.<br>따라서, 객체지향언어는 primitive 자료형도 클래스로 구현되어 있다.<br>그렇기 때문에 아래의 두 문장은 동일하다.</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> a = <span class="number">10</span>;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">a</span><span class="params">(<span class="number">10</span>)</span></span>;</span><br></pre></td></tr></table></figure><h3 id="대표적인-자료구조형"><a href="#대표적인-자료구조형" class="headerlink" title="대표적인 자료구조형"></a>대표적인 자료구조형</h3><p><img src="/images/concept-of-data-structure/hierarchydatastr.png" alt="HIERARCHY"></p><p>위 그림에 있는 자료형이 자료구조의 가장 대표적인 자료형이다.<br>자료구조의 operation은 내부적으로 primitive 자료형에 의해서 수행되며, 결국 operation도 일련의 알고리즘이므로, 자료구조와 알고리즘은 밀접한 관계를 가진다.</p><p>C++에서는 C++11부터 Standard Template Library(STL)에는 동적 배열인 Vector부터 List, Stack, Queue 등의 대표적인 자료구조가 구현되어 있다. 이 라이브러리의 내부 연산을 직접 보는 것도 자료구조를 공부하는데 효과적인 방법이다.</p>]]></content>
<summary type="html">
<h2 id="자료구조란"><a href="#자료구조란" class="headerlink" title="자료구조란?"></a>자료구조란?</h2><p>자료구조를 공부하는 것은 알고리즘을 해결하는데 뿐만 아니라, 라이브러리나 프레임워크를 사용할 때 단순히 가져다 쓰지 않고, 내부적으로 어떻게 구현되있는지에 대한 이해도가 향상되므로 라이브러리에 있는 적절한 자료형을 사용할 수 있다.</p>
<h3 id="OOP와-자료구조"><a href="#OOP와-자료구조" class="headerlink" title="OOP와 자료구조"></a>OOP와 자료구조</h3><p>자료구조란 위키백과의 정의에 따르면 <code>자료를 효율적으로 이용할 수 있도록 컴퓨터에 저장하는 방법</code>이다.<br>즉, 어떠한 알고리즘을 구현하는데 있어 그에 맞는 자료구조를 설계하여 사용해야 시간적으로 혹은 공간적으로 자원을 최소화 할 수 있다.</p>
<p>사실, 위의 말은 이제 프로그래밍을 시작하고 자료구조라는 단어를 처음 듣는 사람들에게는 잘 와닿지 않는다.<br>조금 더 구체적으로 말하자면, 모든 프로그래밍 언어들에는 <code>int, char, boolean</code> 등의 가장 기본적인(primitive) 자료형이 존재한다.</p>
<p>그러나 primitive 자료형으로만 코딩을 했을 때, 재사용성이 떨어지고 제한적이다.<br>그렇기 때문에 주로 사용자 자료형, 다시 말해 추상 자료형(Abstract Data Type, ADT)를 정의하여 사용하는 것이 바람직하며, ADT가 곧 자료구조라고 할 수 있다.</p>
</summary>
<category term="프로그래밍" scheme="https://jimheo.github.io/categories/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/"/>
<category term="자료구조" scheme="https://jimheo.github.io/categories/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0/"/>
<category term="Data Structure" scheme="https://jimheo.github.io/tags/Data-Structure/"/>
<category term="OOP Programming" scheme="https://jimheo.github.io/tags/OOP-Programming/"/>
</entry>
<entry>
<title>Convolutional Neural Network의 개념</title>
<link href="https://jimheo.github.io/2018/10/10/concept-of-cnn/"/>
<id>https://jimheo.github.io/2018/10/10/concept-of-cnn/</id>
<published>2018-10-10T08:55:40.000Z</published>
<updated>2023-09-21T12:34:47.487Z</updated>
<content type="html"><![CDATA[<h2 id="Multi-Layer-Perceptron의-문제점"><a href="#Multi-Layer-Perceptron의-문제점" class="headerlink" title="Multi Layer Perceptron의 문제점"></a>Multi Layer Perceptron의 문제점</h2><p>해를 거듭할 수록, 정형의 데이터보다는 비정형 데이터가 늘어나는 추세다. 비정형의 데이터를 기존의 MLP로 처리하는 것은 몇가지 단점이 존재한다.</p><p>이미지를 예로 들어보자. 이미지는 픽셀단위로 이루어진 행렬이며, 일반적인 이미지의 해상도는 최소 64x64부터 시작하는 경우가 많다.</p><p>Grayscale이 아닌 경우에는 채널값을 추가적으로 고려해야 한다. 그렇기 때문에, MLP로 64x64의 컬러 이미지를 처리할 경우에 12,288개의 인풋이 들어가게 된다. 이에 따라, 기존의 MLP에서 Neural Net의 크기는 더 커지게 되며, 학습시간이 굉장히 늘어난다는 단점이 있다. 또한, 이미지의 회전이나 크기 확장 및 축소, 이동과 같은 변환이 일어날 때, 이에 대한 새로운 학습이 필요하다.</p><p>그렇기 때문에, 비정형 데이터는 각각의 특성을 고려한 발전된 Neural Net이 필요하다. 비정형 데이터를 효과적으로 학습하기 위해 등장한 것이 CNN, RNN이다. CNN은 이미지에 특화된 Neural Net이며, RNN은 음성이나 자연어와 같은 Sequential한 모델에 특화된 Neural Net이다.</p><h2 id="Convolutional-Neural-Network의-등장"><a href="#Convolutional-Neural-Network의-등장" class="headerlink" title="Convolutional Neural Network의 등장"></a>Convolutional Neural Network의 등장</h2><center><img src="https://t1.daumcdn.net/cfile/tistory/276FC94357AB43B00D"></center><p>CNN의 위의 연구에서 부터 시작한다.</p><p>실험 결과, 고양이가 특정 사물을 볼 때, 고양이는 사물의 전체를 한번에 보지 않고 부분적으로 나뉘어 관찰하며, 이 때 고양이의 뇌의 뉴런은 전체가 활성화 되지 않고 부분의 특징마다 서로 다른 시냅스를 통해 일부만 활성화 된다고 한다. 이와 동일하게 CNN은 이미지의 부분별로 Filter를 사용하여 인식을 한다.</p><a id="more"></a><center><img src="https://t1.daumcdn.net/cfile/tistory/2517944D57AB45F018"></center><p>위 그림은 CNN의 일반적인 구조를 시각화한 것이다. CNN은 여러층의 Convolutional Layer, Activation Fuction (ReLU 혹은 그와 유사한)이 먼저 구성되며, Pooling Layer를 통해 이미지를 Sampling하게 된다. 이 층들이 몇 번 반복된 후에는 Fully-Connected Layer로 이동 하는데 Fully-Connected Layer는 우리가 앞서 보았던 MLP와 동일하다. Fully-Connected에서는 최종적으로 확률이 결과물로 나와야 하므로 Softmax를 사용한다.</p><p>Convolutional Layer는 영상처리분야에서 필수 요소로 작용하는 Convolution을 기반으로 한 Layer이다. Convolution은 신호처리에서 먼저 등장한 개념이지만, 영상처리에서 이산적인 Convolution 연산을 통해 우리가 카메라 어플 등에서 흔히 보는 Filtering 부터 Edge Detection 등의 작업을 수행할 수 있다.</p><h2 id="이미지의-Convolution"><a href="#이미지의-Convolution" class="headerlink" title="이미지의 Convolution"></a>이미지의 Convolution</h2><p><strong><code>Convolution</code></strong>, 한글로 번역하면 합성곱이라는 뜻이다. Convolution 연산은 연산을 하고자 하는 픽셀의 주변 픽셀들이 출력에 영향을 미치는 것이다. 다시 말하면, 픽셀 자신과 주변 픽셀들의 Weighted Sum이다.</p><center><img src="http://i.stack.imgur.com/GvsBA.jpg"></center><p>위 그림은 Convolution의 가장 적절한 시각화 예시 중 하나이다. 그림을 보면, Source Pixel과 주변의 픽셀들을 특정한 행렬과 Element-Wise 곱을 한 후 모두 더해 출력을 낸다.</p><p>Source와 곱을 하는 특정 행렬을 Filter(혹은 Convolutional Matrix, Kernel, Window)라 부른다. 이 Filter를 Source의 Pixel들에 순차적으로 Sweeping 하면서 계산하여 하나의 Output Matrix를 만드는 것이다. Filter의 크기는 사용자가 지정하며, 일반적으로 3x3 혹은 5x5 Filter를 사용한다.</p><p>위를 수식으로 일반화하면 다음과 같다.</p><p>$$h[i, j] = f[i, j] * g[i, j] = \sum_{k=1}^n \sum_{l=1}^m f[k, l] g[i - k, j - l]$$</p><p>영상처리에서 Filter 내부의 값은 사용자가 직접 설계하며, 이때 값의 총 합은 주로 1이 되도록 하며, Edge Detection의 경우 0이 되도록 한다. 그러나, 딥러닝에서는 컴퓨터가 학습을 통하여 Filter의 값들을 획득한다. 즉, Filter는 MLP에서의 가중치와 동일한 개념이다.</p><p>다시 위 그림을 보자. 위 그림은 한번의 Convolution 연산이 끝난 상태이다. 그렇다면, 그 다음의 Convolution 연산을 위해 Filter의 이동이 필요하다. 여기서 Filter를 몇 칸 이동할 것인가를 Stride라고 한다. Stride를 몇으로 설정하는가에 따라 출력데이터의 크기가 달라지는데 출력크기는 입력크기가 NxN이고 필터크기가 FxF 일 때, (N - F) / Stride + 1이 된다.</p><p>또한, 그림에서 Source는 7x7의 Matrix이나 출력물은 5x5가 나올 것으로 보인다. 이는 Border 부분의 Pixel은 계산이 안되기 때문이다. 이렇게 되면, Convolutional Layer를 한번 거칠 때마다 이미지가 Down Sampling 되어 Layer가 깊어질 수록 데이터가 소실되는 문제가 발생한다.</p><p>그래서 Border에 Padding을 생성하여 Down Sampling을 방지한다. Padding의 값은 주로 0으로 설정한다.</p><p>이렇게 Convolution을 거쳐 나온 결과물을 Channel이라 한다. 즉, 1개의 필터 당 1개의 채널이 생성되며, 최종 결과물은 각각 다른 가중치의 여러개의 필터로 여러 채널을 생성하여 결과물을 두껍게 만든다. 이렇게 최종적으로 생성된 것을 Activation Map이라 부른다.</p><p>이 과정까지가 Convolutional Layer 층에서 하는 역할이며, 그 후 ReLU 등의 Activation Fuction을 거친다. 여러개의 Convolutional Layer를 구성하여 이 과정들을 반복한다.</p><h2 id="Pooling-Layer"><a href="#Pooling-Layer" class="headerlink" title="Pooling Layer"></a>Pooling Layer</h2><p>여러 번의 Convoltion Layer를 거치는 중간중간에 Pooling Layer를 한번 씩 넣어 주는데 Pooling은 Down Sampling, Resizing과도 비슷하다. Pooling을 통해 Resolution을 작게 만들면서 선명했던 이미지의 형체를 점점 뭉뚱그리면 이미지의 Object 들을 더 쉽게 그룹지을 수 있다.</p><p>Pooling 기법은 여러가지가 존재하며, 대표적인 기법은 Max Pooling이다. 여러개의 값 중에서 가장 큰 값들로 구성하는 기법이다.</p><p>예를 들어, 9x9 행렬은 9개의 3x3 행렬로 쪼갤 수 있다. 3x3 행렬 각각의 element들 중 가장 큰 값을 대푯값으로 내놓는 것이다. 그렇게되면 Pooling을 거친 9x9 행렬은 하나의 3x3 행렬이 된다.</p><p>9x9 행렬이 Pooling을 거치면 항상 3x3이 되는 것은 아니고 여기서도 Stride를 설정하여 출력행렬의 크기를 정할 수 있다. Pooling은 그 외에도 최솟값이나 표준편차 등을 사용하는 기법이 존재한다. 핵심은 어떤 한 값을 대푯값으로 정하는 것이다.</p><p>CNN의 가장 대표적인 예시로는 LeNet부터 AlexNet, GoogLeNet 혹은 최근에는 YOLO등이 있으며, 성킴 교수님의 블로그를 참조한다.<br>Ref: <span class="exturl" data-url="aHR0cDovL3B5dGhvbmtpbS50aXN0b3J5LmNvbS81ND9jYXRlZ29yeT01NzMzMTk=">http://pythonkim.tistory.com/54?category=573319<i class="fa fa-external-link-alt"></i></span></p>]]></content>
<summary type="html">
<h2 id="Multi-Layer-Perceptron의-문제점"><a href="#Multi-Layer-Perceptron의-문제점" class="headerlink" title="Multi Layer Perceptron의 문제점"></a>Multi Layer Perceptron의 문제점</h2><p>해를 거듭할 수록, 정형의 데이터보다는 비정형 데이터가 늘어나는 추세다. 비정형의 데이터를 기존의 MLP로 처리하는 것은 몇가지 단점이 존재한다.</p>
<p>이미지를 예로 들어보자. 이미지는 픽셀단위로 이루어진 행렬이며, 일반적인 이미지의 해상도는 최소 64x64부터 시작하는 경우가 많다.</p>
<p>Grayscale이 아닌 경우에는 채널값을 추가적으로 고려해야 한다. 그렇기 때문에, MLP로 64x64의 컬러 이미지를 처리할 경우에 12,288개의 인풋이 들어가게 된다. 이에 따라, 기존의 MLP에서 Neural Net의 크기는 더 커지게 되며, 학습시간이 굉장히 늘어난다는 단점이 있다. 또한, 이미지의 회전이나 크기 확장 및 축소, 이동과 같은 변환이 일어날 때, 이에 대한 새로운 학습이 필요하다.</p>
<p>그렇기 때문에, 비정형 데이터는 각각의 특성을 고려한 발전된 Neural Net이 필요하다. 비정형 데이터를 효과적으로 학습하기 위해 등장한 것이 CNN, RNN이다. CNN은 이미지에 특화된 Neural Net이며, RNN은 음성이나 자연어와 같은 Sequential한 모델에 특화된 Neural Net이다.</p>
<h2 id="Convolutional-Neural-Network의-등장"><a href="#Convolutional-Neural-Network의-등장" class="headerlink" title="Convolutional Neural Network의 등장"></a>Convolutional Neural Network의 등장</h2><center>
<img src="https://t1.daumcdn.net/cfile/tistory/276FC94357AB43B00D">
</center>
<p>CNN의 위의 연구에서 부터 시작한다.</p>
<p>실험 결과, 고양이가 특정 사물을 볼 때, 고양이는 사물의 전체를 한번에 보지 않고 부분적으로 나뉘어 관찰하며, 이 때 고양이의 뇌의 뉴런은 전체가 활성화 되지 않고 부분의 특징마다 서로 다른 시냅스를 통해 일부만 활성화 된다고 한다. 이와 동일하게 CNN은 이미지의 부분별로 Filter를 사용하여 인식을 한다.</p>
</summary>
<category term="머신러닝" scheme="https://jimheo.github.io/categories/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D/"/>
<category term="딥러닝" scheme="https://jimheo.github.io/categories/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D/%EB%94%A5%EB%9F%AC%EB%8B%9D/"/>
<category term="Convolutional Neural Network" scheme="https://jimheo.github.io/tags/Convolutional-Neural-Network/"/>
<category term="Image Processing" scheme="https://jimheo.github.io/tags/Image-Processing/"/>
<category term="Computer Vision" scheme="https://jimheo.github.io/tags/Computer-Vision/"/>
<category term="Deep Learning" scheme="https://jimheo.github.io/tags/Deep-Learning/"/>
</entry>
<entry>
<title>Chain Rule에 대한 추가적인 고찰</title>
<link href="https://jimheo.github.io/2018/10/10/extra-consideration-of-chain-rule/"/>
<id>https://jimheo.github.io/2018/10/10/extra-consideration-of-chain-rule/</id>
<published>2018-10-10T08:54:42.000Z</published>
<updated>2023-09-21T12:34:47.491Z</updated>
<content type="html"><![CDATA[<h2 id="Chain-Rule"><a href="#Chain-Rule" class="headerlink" title="Chain Rule"></a>Chain Rule</h2><p><code>Deep Neural Network</code>에서는 Feed Forward를 하여 나온 값과 기존의 정답 레이블 사이의 에러율을 줄이기 위한 가장 기본적인 방법으로 Gradient Descent 알고리즘을 사용한다.</p><p><code>Gradient Descent</code> 알고리즘은 이를 위해서 Back Propagation을 하면서 최적의 가중치를 구하도록 한다. 최적의 가중치는 기존의 가중치가 에러율에 미치는 영향을 구한 후 이 영향을 점차 감소시켜서 구할 수 있다.</p><p>즉, 이 과정에서 <code>편미분</code>이 사용되는 것이다. 편미분은 여러개의 파라미터가 있을 때, 하나의 파라미터가 약간 변화하면 Output이 얼마나 크게 변화하는지 확인할 수 있는 도구이다.</p><p>그러나, 딥러닝은 Multi-Layer로 구성되어 있다. 수많은 다중 함수들의 집합이라고 봐도 무방하다. 다시 말해, 가장 처음의 입력에 대한 가중치를 업데이트 해야 하는데 이 가중치의 편미분값을 구하기가 어렵다는 것이다.</p><p>이때 도입되는 개념이 <code>Chain Rule</code>이다. 정확히는 도입이 되었다기 보다는 수학적인 측면에서 보았을 때, 편미분에 당연하게 사용되는 것이다.</p><h3 id="초심자의-입장"><a href="#초심자의-입장" class="headerlink" title="초심자의 입장"></a>초심자의 입장</h3><p>딥러닝을 처음 접하는 혹은 수학에 대하여 큰 지식이 있지 않은 사람의 입장에서 Chain Rule은 그리 간단하지는 않다. 개념에 대해 이해를 하고 난 후라도 Multi-Layer에 대해 직접 Chain Rule을 적용한다면 굉장히 헷갈리기 시작한다.</p><p>그래서 가장 단순하게 이해를 하기 위해서 Sigmoid 함수 하나만을 가지고 Chain Rule을 적용해보기로 한다.</p><p>$$\sigma(z) = \frac{1}{1 + e^{-z}}$$</p><p>위 수식이 Sigmoid 함수다. 미분 공식을 어느정도 안다고 하더라도 위 식을 미분한 결과를 내는 것은 쉽지 않을 것이다. 그렇다면 위의 식을 잘게 쪼개보자.</p><a id="more"></a><p>$$<br>\begin{cases}<br>f(z) = -z \cr<br>g(f) = e^f \cr<br>h(g) = 1 + g \cr<br>i(h) = \frac{1}{h}<br>\end{cases}<br>$$</p><p>위 4개의 수식으로 잘게 나눈다면,</p><p>$$\sigma(z) = i(h(g(f(z))))$$</p><p>가 성립된다.</p><p>여기서 $\sigma(z)$을 미분한다는 것은 $z$의 변화량을 확인하는 것이다.</p><p>우변의 측면에서 이를 다시보면 다음과 같이 표현이 가능하다.</p><p>$$<br>\frac{\partial \sigma}{\partial z} = \frac{\partial i}{\partial z} = \frac{\partial i}{\bcancel{\partial h}} * \frac{\bcancel{\partial h}}{\bcancel{\partial g}} * \frac{\bcancel{\partial g}}{\bcancel{\partial f}} * \frac{\bcancel{\partial f}}{\partial z}<br>$$</p><p>즉, $\frac{\partial i}{\partial h} * \frac{\partial h}{\partial g} * \frac{\partial g}{\partial f} * \frac{\partial f}{\partial z} = f^\prime(z) * g^\prime(f) * h^\prime(g) * i^\prime(h)$ 이므로, 4개의 함수에 대한 미분을 각각 한 후에 서로 곱해주기만 하면, Sigmoid 함수의 미분함수가 나온다.</p><p>4개의 함수를 미분하면 아래와 같다.</p><p>$$<br>\begin{cases}<br>f^\prime(z)=-1 \cr<br>g^\prime(f)=e^f \cr<br>h^\prime(g)=1 \cr<br>i^\prime(h)=-\frac{1}{h^2}<br>\end{cases}<br>$$</p><p>이제 이들을 곱해준다.</p><p>$$<br>\begin{matrix}<br>f^\prime(z)g^\prime(f)h^\prime(g)i^\prime(h) &=& (-1) * e^f * 1 * (-\frac{1}{h^2}) \cr<br>&=& \frac{e^f}{h^2} \cr<br>&=& \frac{e^{-z}}{(1+e^{-z})^2} \cr<br>&=& \sigma(z) * (1-\sigma(z))<br>\end{matrix}<br>$$</p><p>최종적으로 Sigmoid 함수를 Chain Rule을 이용한 값은 위와 같은 결과가 나오는데 이는 일반적으로 알려진 Sigmoid 함수의 미분 값과 동일하다.</p><p>이처럼 복잡한 다중함수의 미분은 Chain Rule을 이용하면 가장 단순하게 풀이가 가능하다. Back Propagation의 과정 또한 Chain Rule을 적용할 수 있다.</p>]]></content>
<summary type="html">
<h2 id="Chain-Rule"><a href="#Chain-Rule" class="headerlink" title="Chain Rule"></a>Chain Rule</h2><p><code>Deep Neural Network</code>에서는 Feed Forward를 하여 나온 값과 기존의 정답 레이블 사이의 에러율을 줄이기 위한 가장 기본적인 방법으로 Gradient Descent 알고리즘을 사용한다.</p>
<p><code>Gradient Descent</code> 알고리즘은 이를 위해서 Back Propagation을 하면서 최적의 가중치를 구하도록 한다. 최적의 가중치는 기존의 가중치가 에러율에 미치는 영향을 구한 후 이 영향을 점차 감소시켜서 구할 수 있다.</p>
<p>즉, 이 과정에서 <code>편미분</code>이 사용되는 것이다. 편미분은 여러개의 파라미터가 있을 때, 하나의 파라미터가 약간 변화하면 Output이 얼마나 크게 변화하는지 확인할 수 있는 도구이다.</p>
<p>그러나, 딥러닝은 Multi-Layer로 구성되어 있다. 수많은 다중 함수들의 집합이라고 봐도 무방하다. 다시 말해, 가장 처음의 입력에 대한 가중치를 업데이트 해야 하는데 이 가중치의 편미분값을 구하기가 어렵다는 것이다.</p>
<p>이때 도입되는 개념이 <code>Chain Rule</code>이다. 정확히는 도입이 되었다기 보다는 수학적인 측면에서 보았을 때, 편미분에 당연하게 사용되는 것이다.</p>
<h3 id="초심자의-입장"><a href="#초심자의-입장" class="headerlink" title="초심자의 입장"></a>초심자의 입장</h3><p>딥러닝을 처음 접하는 혹은 수학에 대하여 큰 지식이 있지 않은 사람의 입장에서 Chain Rule은 그리 간단하지는 않다. 개념에 대해 이해를 하고 난 후라도 Multi-Layer에 대해 직접 Chain Rule을 적용한다면 굉장히 헷갈리기 시작한다.</p>
<p>그래서 가장 단순하게 이해를 하기 위해서 Sigmoid 함수 하나만을 가지고 Chain Rule을 적용해보기로 한다.</p>
<p>$$\sigma(z) = \frac{1}{1 + e^{-z}}$$</p>
<p>위 수식이 Sigmoid 함수다. 미분 공식을 어느정도 안다고 하더라도 위 식을 미분한 결과를 내는 것은 쉽지 않을 것이다. 그렇다면 위의 식을 잘게 쪼개보자.</p>
</summary>
<category term="머신러닝" scheme="https://jimheo.github.io/categories/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D/"/>
<category term="딥러닝" scheme="https://jimheo.github.io/categories/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D/%EB%94%A5%EB%9F%AC%EB%8B%9D/"/>
<category term="Deep Learning" scheme="https://jimheo.github.io/tags/Deep-Learning/"/>
<category term="Computational Graph" scheme="https://jimheo.github.io/tags/Computational-Graph/"/>
<category term="Chain Rule" scheme="https://jimheo.github.io/tags/Chain-Rule/"/>
<category term="Derivative" scheme="https://jimheo.github.io/tags/Derivative/"/>
<category term="Backpropagation" scheme="https://jimheo.github.io/tags/Backpropagation/"/>
</entry>
<entry>
<title>Machine Learning study 1주차</title>
<link href="https://jimheo.github.io/2018/10/10/ml-study-week1/"/>
<id>https://jimheo.github.io/2018/10/10/ml-study-week1/</id>
<published>2018-10-10T05:46:13.000Z</published>
<updated>2023-09-21T12:34:47.491Z</updated>
<content type="html"><![CDATA[<blockquote><p>해당 내용은 Andrew Ng의 Deeplearning ai 강의 C1W2까지에 기반을 두고 있습니다.</p></blockquote><h2 id="Introduction"><a href="#Introduction" class="headerlink" title="Introduction"></a>Introduction</h2><h3 id="머신러닝이란-무엇인가"><a href="#머신러닝이란-무엇인가" class="headerlink" title="머신러닝이란 무엇인가?"></a>머신러닝이란 무엇인가?</h3><p>어떤 알고리즘을 혹은 시스템을 구축할 때 가장 추상적으로 생각할 수 있는 그림은 다음과 같다.</p><center><img src="https://arbs.nzcer.org.nz/sites/default/files/media/images/input-output-machine.png"></center><p>Ref: <span class="exturl" data-url="aHR0cHM6Ly9hcmJzLm56Y2VyLm9yZy5uei9hbGdlYnJhaWMtcGF0dGVybnMtYW5kLXJlbGF0aW9uc2hpcHMtZGlmZmVyZW50LXR5cGVzLW51bWJlcnM=">https://arbs.nzcer.org.nz/algebraic-patterns-and-relationships-different-types-numbers<i class="fa fa-external-link-alt"></i></span></p><p>일반적인 구현에서는 위 그림의 Rule 부분을 개발자들이 직접 코드를 작성한다. 그러나 머신러닝은 Input과 Output 혹은 Input만 가지고 여러 방법론에 의하여 컴퓨터에게 학습을 시킨다. 그렇게 되면, 컴퓨터는 학습을 통해 Rule을 작성하게 된다. 그 후 다음의 Input이 들어왔을 경우 작성한 Rule을 통해 Output을 예측한다.</p><p>이는 기존에 사용하던 방법론과는 약간 상반되는 느낌이 있다. 또한, 개발자들이 작성한 Rule은 코드를 볼 수 있기 때문에 틀린 부분을 직접 수정하거나 삭제할 수 있다.</p><p>그러나 컴퓨터가 작성한 Rule은 사람이 볼 수 없는 코드이므로 그에 대한 직접적인 수정이 불가하다.</p><p>이것이 머신러닝을 흔히 블랙박스라 칭하는 이유다.</p><a id="more"></a><br><h3 id="House-Price-Prediction"><a href="#House-Price-Prediction" class="headerlink" title="House Price Prediction"></a>House Price Prediction</h3><p>Data Mining은 주어진 Dataset으로 현재 데이터들의 상관관계를 분석하는 것이다. 여기서 더 나아간 것이 Machine Learning이며, 머신러닝은 분석된 상관관계를 토대로 앞으로 입력될 데이터에 대한 출력을 예측하는 것이다.</p><p><img src="/images/ml-study-week1/housepriceprediction.png" alt="HOUSINGPREDICTION"></p><p>Ref: <span class="exturl" data-url="aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1uMWwtOWxJTVc3RSZpbmRleD0yJmxpc3Q9UExrRGFFNnNDWm42RWMtWFRiY1gxdVJnMl91NHhPRWt5MA==">deeplearning.ai Andrew Ng<i class="fa fa-external-link-alt"></i></span></p><p>집의 크기로 집값을 예측한다고 가정해보자.</p><p>집의 크기라는 파라미터에 대한 집값이라는 리턴값은 하나의 점으로 매칭이 가능하다. 수많은 데이터들이 있을 경우 이 점들은 결국 하나의 직선 혹은 곡선으로 수렴할 수 있다.</p><p>집의 크기라는 입력과 집값이라는 출력사이에는 하나의 Rule이 있을 것이다.</p><p>머신러닝에서는, 특히 Neural Network는 사람의 신경망을 모티브로 만든 방법론이므로 이를 neuron 혹은 perceptron이라 부른다. 그러나 위의 경우, 혹은 대다수의 상황에서, 하나의 변수만으로 집값을 예측한다는 것은 사실 불가능하다. 집의 위치, 방의 개수, 땅값 등등 집값을 예측하는 데에는 많은 변수가 필요하다.</p><p>즉, 뉴럴 네트워크는 수많은 뉴런들을 나누어 계산하고 그 결과를 다시 새로운 층에 두어 (한 층을 계산해서 나온 출력들은 다시 하나의 변수가 되므로) 마지막 출력이 나올 때까지 계산하는 방식이 되어야 한다.</p><p>이처럼 층이 여러개인 뉴럴 네트워크를 DNN (Deep Neural Network)이라 말하며 이것이 사람들에게 흔히 알려진 Deep Learning이다.</p><br><h2 id="Types-of-Machine-Learning"><a href="#Types-of-Machine-Learning" class="headerlink" title="Types of Machine Learning"></a>Types of Machine Learning</h2><p>머신러닝은 구조적으로 크게 3가지 방식이 있다.</p><center><img src="https://i.imgur.com/mZdJLdg.png"></center><p>Ref: <span class="exturl" data-url="aHR0cHM6Ly93d3cuZGF0YXNjaWVuY2VjZW50cmFsLmNvbS9wcm9maWxlcy9ibG9ncy90eXBlcy1vZi1tYWNoaW5lLWxlYXJuaW5nLWFsZ29yaXRobXMtaW4tb25lLXBpY3R1cmU=">https://www.datasciencecentral.com/profiles/blogs/types-of-machine-learning-algorithms-in-one-picture<i class="fa fa-external-link-alt"></i></span></p><h3 id="Supervised-Learning-지도-학습"><a href="#Supervised-Learning-지도-학습" class="headerlink" title="Supervised Learning (지도 학습)"></a>Supervised Learning (지도 학습)</h3><p>지도 학습은 입력과 정답인 출력 레이블 한 쌍을 가지고 학습시키는 방법이다.</p><p>지도 학습은 다시 Classification과 Regression으로 분류된다.</p><h3 id="Unsupervised-Learning-비지도-학습"><a href="#Unsupervised-Learning-비지도-학습" class="headerlink" title="Unsupervised Learning (비지도 학습)"></a>Unsupervised Learning (비지도 학습)</h3><p>비지도 학습은 입력 레이블만을 가지고 학습시키는 방법이다.</p><p>지도 학습의 경우에는 정답이 존재하기 때문에 학습 결과와 정답과의 오차를 계산할 수 있으나 비지도 학습은 그렇지 않다. 그렇기 때문에 비지도 학습은 입력 데이터들의 Cluster를 찾아 학습한다.</p><h3 id="Reinforcement-Learning-강화-학습"><a href="#Reinforcement-Learning-강화-학습" class="headerlink" title="Reinforcement Learning (강화 학습)"></a>Reinforcement Learning (강화 학습)</h3><p>강화 학습은 학습 데이터가 주어지지 않는다. 대신에 학습에 대한 보상(Reward)가 주어지며, 미래에 얻을 보상값들의 평균을 마르코프 의사 결정 과정을 통해 최대로 하는 함수를 찾는 것을 강화 학습이라 한다.</p><br><h2 id="Binary-Classification"><a href="#Binary-Classification" class="headerlink" title="Binary Classification"></a>Binary Classification</h2><p>Classification과 Regression의 가장 큰 차이점은 Classification은 좌표상에서 Discrete하게 표현된다는 것이며, Regression은 Continuous하게 표현된다는 것이다.</p><p>즉, Classification은 Cluster를 나누는 기준 선을 찾는 방법이며, Regression은 데이터들이 수렴하게 되는 선을 찾는 것이다.</p><p>Classification 중에서 Binary Classification은 정답이 0 혹은 1 두가지로만 구분하는 방법이다. 예를 들어, 64x64의 고양이 사진이 있을 때, 이것이 고양이인지 아닌지만 판별하게 된다.</p><p>이를 판별하기 위해서는 64x64인 행렬이 RGB 3채널로 이루어진 사진을 하나의 열벡터로 재배열해야 한다. 이때, 열벡터의 행의 개수는 $64\times64\times3=12288$개가 된다. (이를 $n_x$라 표현) 이 열벡터는 정답레이블에 맞게 변환하는 과정이 필요하다.</p><p>선형대수에 따르면 일반적으로 벡터의 변환은 Linear Combination ($v=\alpha_1v_1+\alpha_2v_2+…+\alpha_nv_n$)이며, 벡터에 가중치를 곱한 것들의 합이다. 벡터의 곱은 행렬의 곱으로 표현이 가능하며, 수식은 아래와 같다.</p><p>$$z = w^Tx + b$$</p><p>그러나 계산되어 나온 $z$는 $0$이나 $1$이 아니다. 그렇기 때문에 Logistic Regression (여기서는 Sigmoid Function)을 사용하여 $0$과 $1$에 근접하게 맵핑하여야 한다. 시그모이드 함수의 범위는 $0<\sigma(z)<1$의 연속된 실수이며, 이것은 확률을 의미한다.</p><center><img src="https://cdn-images-1.medium.com/max/800/1*Xu7B5y9gp0iL5ooBj7LtWw.png"></center><p>Ref: <span class="exturl" data-url="aHR0cHM6Ly90b3dhcmRzZGF0YXNjaWVuY2UuY29tL2FjdGl2YXRpb24tZnVuY3Rpb25zLW5ldXJhbC1uZXR3b3Jrcy0xY2JkOWY4ZDkxZDY=">https://towardsdatascience.com/activation-functions-neural-networks-1cbd9f8d91d6<i class="fa fa-external-link-alt"></i></span></p><p>$\hat{y}=\sigma(z)$이라 하면 $\hat{y}$는 $y$가 $1$인 경우에 대한 확률이며 ($\hat{y}=P(y=1 \mid x)$), 결론적으로 기계는 $\hat{y}$가 $1$에 근접할 수록 고양이라고 판단하는 것이다.</p><h2 id="Back-Propagation"><a href="#Back-Propagation" class="headerlink" title="Back Propagation"></a>Back Propagation</h2><p>앞의 과정까지가 Forward Propagation으로 진행되는 방식이다. 그러나 기계가 도출한 답과 실제 정답레이블과의 오차가 클 경우가 많다. 그렇기 때문에 우리는 Forward하게 도출한 답을 토대로 다시 가중치를 수정하면서 오차율을 줄여야 할 필요가 있다.</p><p>이를 역전파(Back Propagation)라 한다.</p><h3 id="Logistic-Regression-Cost-Function"><a href="#Logistic-Regression-Cost-Function" class="headerlink" title="Logistic Regression Cost Function"></a>Logistic Regression Cost Function</h3><p>역전파를 하기 위해 도출된 답과 실제의 답에 대한 오차율을 구해야 한다. 하나에 학습에 대한 오차율 계산 함수를 Loss Function이라 한다. Loss function을 구하는 과정은 다음과 같다.<br><br></p><p>$$<br>\begin{aligned}<br>&if \cr<br>&&&y = 1: P(y \mid x)=\hat{y} \cr<br>&else \cr<br>&&&y = 0: P(y \mid x)=1 - \hat{y}<br>\end{aligned}<br>$$</p><br><p>즉, $P(y \mid x)=\hat{y}^y(1 - \hat{y})^{(1 - y)}$가 성립하며, 이에 $\log$를 씌우면,</p><br><p>$$<br>\log P(y \mid x) = \log\hat{y}^y(1 - \hat{y})^{(1 - y)}<br>$$<br>$$<br>-\mathcal{L}(\hat{y}, y) = y\log\hat{y} + (1 - y)\log(1 - \hat{y})<br>$$</p><p>이 성립한다.</p><p>Cost Function은 각 학습 셋에 대한 Loss Function들의 평균이다. 우리는 Cost Function을 구한 후 역전파 과정을 거쳐야 한다.</p><p>$$ J(w, b) = -\frac{1}{m}\sum_{i = 1}^m (y_{(i)} \log\hat{y_{(i)}} + (1 - y_{(i)}) \log(1 - \hat{y_{(i)}}))$$</p><h3 id="Gradient-Descent-Algorithm"><a href="#Gradient-Descent-Algorithm" class="headerlink" title="Gradient Descent Algorithm"></a>Gradient Descent Algorithm</h3><p>Gradient Descent는 Cost Function을 최소화하기 위한 가중치를 찾는 알고리즘이다. 이 공식에는 편미분을 이용한다.</p><p>미분은 입력에 약간의 변화가 있을 때, 출력이 얼마만큼 변화하는지 확인하기 위함이다.<br>즉, $f(x)=2x$에 대해서 $x_1=1$일 때, $f(x_1)=2$이며, $x_2=1.001$일 때, $f(x_2)=2.002$이다.</p><p>이 경우 $f(x)$의 도함수 $f^\prime(x)$는 $\frac{0.002}{0.001}$이므로 $2$가된다.<br>편미분은 미분의 일종으로 입력 파라미터가 하나가 아닌 여러개일 때, 한 파라미터가 약간 변했을 때 출력이 얼마만큼 변화하는 지를 나타내는 것이다.</p><p>위에서는 $J(w,b)$를 $w$에서 편미분하는 것을 $\frac{\partial J(w,b)}{\partial w}$로 표현하며, 마찬가지로 $b$에 대해 편미분하면 $\frac{\partial J(w,b)}{\partial b}$로 표현한다.</p><p>Gradient Descent는 볼록한(convex) 함수가 있을 때 이 함수의 가장 아래 부분으로 점차 결과물을 내리는 방식이다. 오차율 함수 $J(w,b)$는 하단으로 갈수록 오차율이 적어지는 것을 의미한다.</p><p>$$<br>\begin{aligned}<br>w:=w-\alpha\frac{\partial J(w,b)}{\partial w} \<br>b:=b-\alpha\frac{\partial J(w,b)}{\partial b} \<br>\end{aligned}<br>$$</p><p>위 Gradient Decsent를 각 $w,b$에 적용하여 가장 낮은 오차율이 나오도록 $w$와 $b$를 수정하는 작업이다. ($\alpha$는 learning rate을 의미)</p><p>추가적으로 Linear Regression에서의 Cost Function은 Euclidean Distance를 응용한 Mean Squared Error</p><p>$$J(w,b)=\frac{1}{m}\sum_{i=1}^m\frac{1}{2}(\hat{y}-y)^2$$</p><p>를 사용하지만, Logisitc Regression에서 MSE를 사용하면 Convex하지 않은 함수가 나온다. 그렇기 때문에 위와 같은 방법을 사용하는데 이를 Cross Entropy Error라고 한다.</p><p>Back Propagation 수행 시에는 Gradient Descent를 위한 편미분을 계산하게 되는데 위의 Binary Classification 예제는 단층 레이어 구조의 뉴럴 네트워크를 사용하기 때문에 편미분 유도가 용이하다.</p><p>그러나 Deep Learning은 Multi Layer 구조이므로 편미분을 구할 때 다소 복잡하다. 그렇기 때문에 각 층의 출력에 대해 한 단계씩 뒤로 가면서 각각의 편미분을 구하는 일을 반복하게 된다. 이를 Chain Rule이라 한다.</p>]]></content>
<summary type="html">
<blockquote>
<p>해당 내용은 Andrew Ng의 Deeplearning ai 강의 C1W2까지에 기반을 두고 있습니다.</p>
</blockquote>
<h2 id="Introduction"><a href="#Introduction" class="headerlink" title="Introduction"></a>Introduction</h2><h3 id="머신러닝이란-무엇인가"><a href="#머신러닝이란-무엇인가" class="headerlink" title="머신러닝이란 무엇인가?"></a>머신러닝이란 무엇인가?</h3><p>어떤 알고리즘을 혹은 시스템을 구축할 때 가장 추상적으로 생각할 수 있는 그림은 다음과 같다.</p>
<center>
<img src="https://arbs.nzcer.org.nz/sites/default/files/media/images/input-output-machine.png">
</center>
<p>Ref: <span class="exturl" data-url="aHR0cHM6Ly9hcmJzLm56Y2VyLm9yZy5uei9hbGdlYnJhaWMtcGF0dGVybnMtYW5kLXJlbGF0aW9uc2hpcHMtZGlmZmVyZW50LXR5cGVzLW51bWJlcnM=">https://arbs.nzcer.org.nz/algebraic-patterns-and-relationships-different-types-numbers<i class="fa fa-external-link-alt"></i></span></p>
<p>일반적인 구현에서는 위 그림의 Rule 부분을 개발자들이 직접 코드를 작성한다. 그러나 머신러닝은 Input과 Output 혹은 Input만 가지고 여러 방법론에 의하여 컴퓨터에게 학습을 시킨다. 그렇게 되면, 컴퓨터는 학습을 통해 Rule을 작성하게 된다. 그 후 다음의 Input이 들어왔을 경우 작성한 Rule을 통해 Output을 예측한다.</p>
<p>이는 기존에 사용하던 방법론과는 약간 상반되는 느낌이 있다. 또한, 개발자들이 작성한 Rule은 코드를 볼 수 있기 때문에 틀린 부분을 직접 수정하거나 삭제할 수 있다.</p>
<p>그러나 컴퓨터가 작성한 Rule은 사람이 볼 수 없는 코드이므로 그에 대한 직접적인 수정이 불가하다.</p>
<p>이것이 머신러닝을 흔히 블랙박스라 칭하는 이유다.</p>
</summary>
<category term="머신러닝" scheme="https://jimheo.github.io/categories/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D/"/>
<category term="딥러닝" scheme="https://jimheo.github.io/categories/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D/%EB%94%A5%EB%9F%AC%EB%8B%9D/"/>
<category term="Deep Learning" scheme="https://jimheo.github.io/tags/Deep-Learning/"/>
<category term="Logistic Regression" scheme="https://jimheo.github.io/tags/Logistic-Regression/"/>
<category term="Gradient Descent" scheme="https://jimheo.github.io/tags/Gradient-Descent/"/>
<category term="Classification" scheme="https://jimheo.github.io/tags/Classification/"/>
</entry>
</feed>