<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Databuzz&#39;s Tech Blog</title>
  
  
  <link href="/atom.xml" rel="self"/>
  
  <link href="https://databuzz-team.github.io/"/>
  <updated>2020-10-09T10:11:28.888Z</updated>
  <id>https://databuzz-team.github.io/</id>
  
  <author>
    <name>Databuzz, Databuzz.team@gmail.com</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>&lt;Deep Learning&gt; Tensorflow로 DNN 모델링하며 Good Practice에 대해서 생각해보자</title>
    <link href="https://databuzz-team.github.io/2019/01/30/Basic-dnn-using-tensorflow/"/>
    <id>https://databuzz-team.github.io/2019/01/30/Basic-dnn-using-tensorflow/</id>
    <published>2019-01-30T11:51:44.000Z</published>
    <updated>2020-10-09T10:11:28.888Z</updated>
    
    <content type="html"><![CDATA[<div style="display: none;"><img src="/images/danial/tensorflow.jpeg"></div><h3 id="About"><a href="#About" class="headerlink" title="About"></a>About</h3><p>이번 포스트에서는 Tensorflow를 이용하여 Deep Neural Networks를 구현하는 법을 간단히 알아보도록 하고, 어떻게 하면 코드 복사 붙여넣기 없이 할 수 있을까에 대해서 생각해보고 구현한 것을 공유하고자 한다.</p><p>특히 찾아보면 간단한 예제를 통해서 개념들을 설명하는 경우는 많지만 Practical한 예제를 사용한 경우는 드물어서 필자는 조금 더 Practical하게 작성하고자 노력해봤다.</p><p>다만 물론 필자도 경험이 많은 것이 아니어서, 아래의 예들이 좋은 코드 패턴은 아닐 수 있음에 양해를 구하며, 만약 더 좋은 생각이 나 궁금한 점은 댓글을 통해서 꼭 알려주시길 부탁드린다.</p><blockquote><p>만약 Neural Network에 대해서 잘 모르신다면 아래 링크들을 확인하시길<br>1.<a href="/2018/11/05/Back-Propagation/"><neural network=""> 인공신경망에 대한 이해(Part 1 - Feedforward Propagation)</neural></a><br>2.<a href="/2018/12/27/Back-Propagation-Part-2/"><neural network=""> 인공신경망에 대한 이해(Part 2 - Back Propagation)</neural></a></p></blockquote><h3 id="Tensorflow를-이용한-DNN-실습"><a href="#Tensorflow를-이용한-DNN-실습" class="headerlink" title="Tensorflow를 이용한 DNN 실습"></a>Tensorflow를 이용한 DNN 실습</h3><h4 id="연습으로-MNIST-Digit-이미지를-이용하도록-하자"><a href="#연습으로-MNIST-Digit-이미지를-이용하도록-하자" class="headerlink" title="연습으로 MNIST Digit 이미지를 이용하도록 하자."></a>연습으로 MNIST Digit 이미지를 이용하도록 하자.</h4><p>코드에서는 주석을 보며 생각흐름을 따라오면 된다.<br><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><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> tensorflow <span class="keyword">as</span> tf</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">from</span> keras.utils <span class="keyword">import</span> np_utils</span><br><span class="line"></span><br><span class="line">mnist = tf.keras.datasets.mnist</span><br><span class="line"><span class="comment"># mnist dataset을 load한다.</span></span><br><span class="line">(x_train, y_train),(x_test, y_test) = mnist.load_data()</span><br><span class="line"><span class="comment"># float로 변환하고 minmax 스케일링을 한다. 이는 이미지 전처리의 가장 보편적인 방법 중 하나이다.</span></span><br><span class="line">x_train = x_train.reshape(<span class="number">60000</span>, <span class="number">784</span>).astype(<span class="string">'float32'</span>) / <span class="number">255.0</span></span><br><span class="line">x_test = x_test.reshape(<span class="number">10000</span>, <span class="number">784</span>).astype(<span class="string">'float32'</span>) / <span class="number">255.0</span></span><br><span class="line">print(x_train.shape, x_train.dtype)</span><br><span class="line"><span class="comment"># y 값을 one-hot-encoding로 변환해준다.</span></span><br><span class="line">y_unique_num = len(np.unique(y_train))</span><br><span class="line">y_train = np_utils.to_categorical(y_train, y_unique_num)</span><br><span class="line">y_test = np_utils.to_categorical(y_test, y_unique_num)</span><br><span class="line">y_train[:<span class="number">5</span>]</span><br><span class="line"></span><br><span class="line"><span class="comment"># test로 이미지를 한번 출력해보자.</span></span><br><span class="line">r = random.randint(<span class="number">0</span>, x_train.shape[<span class="number">0</span>] - <span class="number">1</span>)</span><br><span class="line">plt.imshow(</span><br><span class="line">    x_train[r].reshape(<span class="number">28</span>, <span class="number">28</span>),</span><br><span class="line">    cmap=<span class="string">"Greys"</span>,</span><br><span class="line">    interpolation=<span class="string">"nearest"</span> <span class="comment"># 중간에 비어있는 값 처리</span></span><br><span class="line">)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure></p><h4 id="먼저-클래스를-사용하지-않고-구현해보자"><a href="#먼저-클래스를-사용하지-않고-구현해보자" class="headerlink" title="먼저 클래스를 사용하지 않고 구현해보자."></a>먼저 클래스를 사용하지 않고 구현해보자.</h4><p>아래는 Graph를 만드는 코드다.</p><p>혹시 placeholder, Variable 등 기본적인 함수에 대해서 잘 모른다면, <a href="https://databuzz-team.github.io/2018/10/24/Basic-deep-learning-tensorflow-for-beginner-2/"><deep learning=""> An introduction to deep learning with tensorflow(part-2)</deep></a> 블로그를 확인하면 된다.</p><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><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># input data를 위한 공간(placeholder)를 만든다.</span></span><br><span class="line">X = tf.placeholder(tf.float32, shape=[<span class="keyword">None</span>, <span class="number">28</span>*<span class="number">28</span>*<span class="number">1</span>])</span><br><span class="line"><span class="comment"># label data를 위한 공간도 만든다.</span></span><br><span class="line">y = tf.placeholder(tf.float32, shape=[<span class="keyword">None</span>, <span class="number">10</span>])</span><br><span class="line"></span><br><span class="line"><span class="comment"># layer 1</span></span><br><span class="line">W1 = tf.Variable(tf.random_normal([<span class="number">28</span>*<span class="number">28</span>*<span class="number">1</span>, <span class="number">10</span>]))</span><br><span class="line">b1 = tf.Variable(tf.random_normal([<span class="number">10</span>]))</span><br><span class="line"><span class="comment"># 이번 예제에서는 activation 함수로는 sigmoid를 사용하기로 하자.</span></span><br><span class="line">layer1 = tf.sigmoid(tf.matmul(X, W1) + b1)</span><br><span class="line"></span><br><span class="line"><span class="comment"># layer 2</span></span><br><span class="line">W2 = tf.Variable(tf.random_normal([<span class="number">10</span>, <span class="number">20</span>]))</span><br><span class="line">b2 = tf.Variable(tf.random_normal([<span class="number">20</span>]))</span><br><span class="line">layer2 = tf.sigmoid(tf.matmul(layer1, W2) + b2)</span><br><span class="line"></span><br><span class="line"><span class="comment"># layer 3</span></span><br><span class="line">W3 = tf.Variable(tf.random_normal([<span class="number">20</span>, <span class="number">20</span>]))</span><br><span class="line">b3 = tf.Variable(tf.random_normal([<span class="number">20</span>]))</span><br><span class="line">layer3 = tf.sigmoid(tf.matmul(layer2, W3) + b3)</span><br><span class="line"></span><br><span class="line"><span class="comment"># layer 4</span></span><br><span class="line">W4 = tf.Variable(tf.random_normal([<span class="number">20</span>, <span class="number">10</span>]))</span><br><span class="line">b4 = tf.Variable(tf.random_normal([<span class="number">10</span>]))</span><br><span class="line">hypothesis = tf.nn.softmax(tf.matmul(layer3, W4) + b4)</span><br><span class="line"></span><br><span class="line">cost = tf.reduce_mean(-tf.reduce_sum(y * tf.log(hypothesis), axis=<span class="number">1</span>))</span><br><span class="line">train = tf.train.GradientDescentOptimizer(learning_rate=<span class="number">0.01</span>).minimize(cost)</span><br><span class="line"></span><br><span class="line">prediction = tf.argmax(hypothesis, <span class="number">1</span>)</span><br><span class="line">is_correct = tf.equal(prediction, tf.argmax(y, <span class="number">1</span>))</span><br><span class="line">accuracy = tf.reduce_mean(tf.cast(is_correct, tf.float32))</span><br></pre></td></tr></table></figure><p>그리고 세션을 이용해서 학습해보자.<br><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></pre></td><td class="code"><pre><span class="line">sess = tf.Session()</span><br><span class="line">sess.run(tf.global_variables_initializer())</span><br><span class="line"></span><br><span class="line">batch_size = <span class="number">200</span></span><br><span class="line">epoch = <span class="number">100</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> step <span class="keyword">in</span> range(epoch):</span><br><span class="line">    total_batch = int(len(x_train)/batch_size)</span><br><span class="line">    c_avg = <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> range(total_batch):</span><br><span class="line">        batch_x = x_train[batch_size*i : batch_size*(i+<span class="number">1</span>)]</span><br><span class="line">        batch_y = y_train[batch_size*i : batch_size*(i+<span class="number">1</span>)]</span><br><span class="line">        c, _  = sess.run([cost, train], feed_dict=&#123;X: batch_x, y: batch_y&#125;)</span><br><span class="line">        c_avg = c_avg + (c/total_batch)</span><br><span class="line">    <span class="keyword">if</span> step % <span class="number">10</span> == <span class="number">0</span>:</span><br><span class="line">        print(step, c_avg)</span><br><span class="line">print(sess.run(accuracy, feed_dict=&#123;X: x_test, y: y_test&#125;))</span><br></pre></td></tr></table></figure></p><p>필자가 이 네트워크로 얻은 Accuracy값은 0.7291이었다. 그렇다면 이제 네트워크를 바꿔가며 하이퍼패러미터 튜닝을 시도해야할텐데, 그때마다 위의 Graph코드를 복사해서 붙여넣고 중간에 layer들은 변경한다거나 해야한다.</p><p>코드도 지저분해지고 자유도가 엄청 떨어지는 이 문제점을 해결하기 위해서 아래처럼 모델은 Class로 Train은 함수로 따로 구현해봤다.</p><p>코드가 많이 복잡해보이는데, 그 이유는 크게 4가지이다.</p><ol><li>Model은 Graph를 만드는 역할만 수행하고 Session과 결합하지 않았다.</li><li>Model을 빌드할 때 자유롭게 미리 config에서 설정한 layer, neuron의 개수, initializer, activation 등을 적용할 수 있게 하였다.</li><li>각 Layer마다 사용된 variable을 가져올 수 있게 하였다.</li><li>Tensorboard에도 기록될 수 있게 하였다.</li></ol><blockquote><p>이번 예제에서는 구현하지는 않았지만, activation이나 initializer 등을 넘어서 dropout 등도 응용해서 적용하면 된다.</p></blockquote><p>그렇게되면 장점은</p><ol><li>내부 layer 등을 달리한 모델 m1, m2를 객체화하고 학습은 같은 train() 함수를 이용해서 진행할 수 있어서 객체 내부에 중복된 train 함수를 들고있을 필요가 없다.</li><li>더 큰 네트워크를 만들기 용이하다.</li></ol><p>이제 코드로 살펴보자.</p><p>먼저 사용법을 살펴보고 나머지들을 설명하도록 하겠다.<br><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></pre></td><td class="code"><pre><span class="line"><span class="comment"># input 데이터가 가진 feature 개수</span></span><br><span class="line">n_features = x_train.shape[<span class="number">1</span>]</span><br><span class="line"><span class="comment"># label 개수</span></span><br><span class="line">n_class = len(y_train[<span class="number">0</span>])</span><br><span class="line"><span class="comment"># model build를 위한 config를 만든다.</span></span><br><span class="line">config = &#123;</span><br><span class="line">    <span class="string">"name"</span> : <span class="string">"dnn_model"</span>, <span class="comment"># 나중에 tensorboard를 확인하면 여기서 정한 이름으로 graph가 만들어진다.</span></span><br><span class="line">    <span class="string">"n_features"</span> : n_features,</span><br><span class="line">    <span class="string">"n_class"</span> : n_class,</span><br><span class="line">    <span class="string">"n_li"</span> : [n_features, <span class="number">1000</span>, <span class="number">1000</span>, <span class="number">1000</span>, n_class], <span class="comment"># input부터 output사이의 hidden layer neuron 개수들을 리스트형식으로 적어준다.</span></span><br><span class="line">    <span class="string">"initializer_li"</span> : [<span class="string">"random_normal"</span>, <span class="string">"random_normal"</span>, <span class="string">"random_normal"</span>, <span class="string">"random_normal"</span>], <span class="comment"># 각 레이어마다 Variable들이 사용할 initializer를 적어준다. 코드에서는 random_normal, xavier 두 가지 경우만을 고려하였다.</span></span><br><span class="line">    <span class="string">"activation_li"</span> : [<span class="string">"sigmoid"</span>, <span class="string">"sigmoid"</span>, <span class="string">"sigmoid"</span>, <span class="keyword">None</span>]</span><br><span class="line">    <span class="comment"># 각 레이어별로 뉴론에서 사용할 activation 함수를 적어준다. 코드에서는 sigmoid와 relu 두 가지 경우만을 고려하였다.</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment"># 객체를 만들자</span></span><br><span class="line">dnn_model = DNNModel(config)</span><br><span class="line"><span class="comment"># train함수에 만든 graph와 x_train, y_train을 넣어준다. epoch, lr, batch_size 등도 여기서 변경하며 실험해볼 수 있다.</span></span><br><span class="line">train(dnn_model, x_train, y_train, epoch=<span class="number">15</span>)</span><br><span class="line"><span class="comment"># accuracy, predict도 모델과 샘플 데이터들을 넣어주면 된다. 참고로 위에서 선언한 네트워크로 필자는 accuracy가 0.8로 나왔다.</span></span><br><span class="line">accuracy(dnn_model, x_test, y_test), predict(dnn_model, x_test)</span><br></pre></td></tr></table></figure></p><h4 id="Model-Class"><a href="#Model-Class" class="headerlink" title="Model Class"></a>Model Class</h4><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><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">DNNModel</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, config)</span>:</span></span><br><span class="line">        self.config = config <span class="comment"># 위에서 넣어준 config를 객체 내부에 저장하자.</span></span><br><span class="line">        self.endpoints = &#123;&#125; <span class="comment"># layer마다 사용한 variable을 저장할 공간을 만든다.</span></span><br><span class="line">        self.graph = tf.Graph() <span class="comment"># graph 정보를 train에서 session을 연결할 때 사용해야하므로 역시 객체에 저장해준다.</span></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">build_net</span><span class="params">(self, x_placeholder, y_placeholder)</span>:</span></span><br><span class="line">        <span class="keyword">with</span> self.graph.as_default(): <span class="comment"># 위에서 선언한 graph안에 빌드를 한다.</span></span><br><span class="line">            <span class="keyword">with</span> tf.variable_scope(self.config[<span class="string">"name"</span>]): <span class="comment"># tensorboard에서 확인하기 좋고, debugging에 유리하도록 name을 설정해준다.</span></span><br><span class="line">                self.X = x_placeholder <span class="comment"># 모델 클래스 자체가 blackbox처럼 만들기위해서 x_placeholder는 외부에서 주입받도록 하였다. input to output 매핑이 가능하도록..</span></span><br><span class="line">                self.y = y_placeholder <span class="comment"># 마찬가지로 위부(train 함수)에서 주입을 반든다.</span></span><br><span class="line"></span><br><span class="line">                layer_output_li = []</span><br><span class="line">                <span class="comment"># 항상 다음 layer에서 activation 함수를 통과할 때는 직전 layer에서 activation을 통과해서 나온 값과 현재 layer의 weight 및 bias와 연산을 진행하게된다.</span></span><br><span class="line">                <span class="comment"># 그러므로 각 layer output은 리스트로 저장해서 필요시 사용하도록 한다.</span></span><br><span class="line">                <span class="keyword">for</span> idx, n <span class="keyword">in</span> enumerate(self.config[<span class="string">"n_li"</span>][:<span class="number">-1</span>]):</span><br><span class="line">                    <span class="keyword">with</span> tf.name_scope(<span class="string">"Layer_"</span> + str(idx)) <span class="keyword">as</span> scope:</span><br><span class="line">                        previous_dim = self.config[<span class="string">"n_li"</span>][idx]</span><br><span class="line">                        next_dim = self.config[<span class="string">"n_li"</span>][idx + <span class="number">1</span>]</span><br><span class="line">                        <span class="comment"># 아래의 shape은 중간의 weights matrix와 bias의 shape를 위해 필요하다.</span></span><br><span class="line">                        shape = [previous_dim, next_dim]</span><br><span class="line">                        <span class="comment"># 이전 layer output을 가져오도록 하자.</span></span><br><span class="line">                        pre_layer_output = layer_output_li[<span class="number">-1</span>] <span class="keyword">if</span> idx &gt; <span class="number">0</span> <span class="keyword">else</span> self.X</span><br><span class="line">                        self.__set_weight_and_bias(idx, shape)</span><br><span class="line">                        layer = self.__set_layer_endpoint(idx, pre_layer_output)</span><br><span class="line">                        layer_output_li.append(layer)</span><br><span class="line"></span><br><span class="line">            <span class="keyword">with</span> tf.name_scope(<span class="string">"Cost"</span>) <span class="keyword">as</span> scope:</span><br><span class="line">                self.cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=self.logits, labels=self.y))</span><br><span class="line">                cost_sum = tf.summary.scalar(<span class="string">"Cost"</span>, self.cost)</span><br><span class="line"></span><br><span class="line">            self.predict = tf.argmax(self.logits, <span class="number">1</span>)</span><br><span class="line">            correct_prediction = tf.equal(tf.argmax(self.logits, <span class="number">1</span>), tf.argmax(self.y, <span class="number">1</span>))</span><br><span class="line">            self.accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__set_weight_and_bias</span><span class="params">(self, idx, shape)</span>:</span></span><br><span class="line">        <span class="comment"># random_normal과 xavier만 만들었지만, 필요하면 if문을 추가하면된다.</span></span><br><span class="line">        <span class="keyword">if</span> self.config[<span class="string">"initializer_li"</span>][idx] == <span class="string">"random_normal"</span>:</span><br><span class="line">            self.endpoints[<span class="string">"W_"</span> + str(idx)] = tf.Variable(tf.random_normal(shape), name = <span class="string">"W_"</span> + str(idx))</span><br><span class="line">        <span class="keyword">elif</span> self.config[<span class="string">"initializer_li"</span>][idx] == <span class="string">"xavier"</span>:</span><br><span class="line">            self.endpoints[<span class="string">"W_"</span> + str(idx)] = tf.get_variable(<span class="string">"W_"</span> + str(idx), shape=shape,</span><br><span class="line">                                initializer=tf.contrib.layers.xavier_initializer())</span><br><span class="line">        self.endpoints[<span class="string">"b_"</span> + str(idx)] = tf.Variable(tf.random_normal(shape[<span class="number">1</span>:]), name = <span class="string">"b_"</span> + str(idx))</span><br><span class="line">        W_hist = tf.summary.histogram(<span class="string">"W_hist_"</span> + str(idx), self.endpoints[<span class="string">"W_"</span> + str(idx)])</span><br><span class="line">        b_hist = tf.summary.histogram(<span class="string">"b_hist_"</span> + str(idx), self.endpoints[<span class="string">"b_"</span> + str(idx)])</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__set_layer_endpoint</span><span class="params">(self, idx, pre_layer_output)</span>:</span></span><br><span class="line">        W = self.endpoints[<span class="string">"W_"</span> + str(idx)]</span><br><span class="line">        b = self.endpoints[<span class="string">"b_"</span> + str(idx)]</span><br><span class="line">        <span class="keyword">if</span> idx + <span class="number">1</span> == len(self.config[<span class="string">"n_li"</span>][:<span class="number">-1</span>]):</span><br><span class="line">            self.logits = tf.matmul(pre_layer_output, W) + b</span><br><span class="line">            layer_hist = tf.summary.histogram(<span class="string">"Layer_hist_"</span> + str(idx), self.logits)</span><br><span class="line">            <span class="keyword">return</span> self.logits</span><br><span class="line"></span><br><span class="line">        <span class="comment"># weight &amp; bias와 마찬가지로 필요하면 sigmoid, relu 이외에도 추가하면 된다.</span></span><br><span class="line">        <span class="keyword">if</span> self.config[<span class="string">"activation_li"</span>][idx] == <span class="string">"sigmoid"</span>:</span><br><span class="line">            self.endpoints[<span class="string">"layer_"</span> + str(idx)] = tf.sigmoid(tf.matmul(pre_layer_output, W) + b)</span><br><span class="line">        <span class="keyword">elif</span> self.config[<span class="string">"activation_li"</span>][idx] == <span class="string">"relu"</span>:</span><br><span class="line">            self.endpoints[<span class="string">"layer_"</span> + str(idx)] = tf.nn.relu(tf.matmul(pre_layer_output, W) + b)</span><br><span class="line">        layer_hist = tf.summary.histogram(<span class="string">"Layer_hist_"</span> + str(idx), self.endpoints[<span class="string">"layer_"</span> + str(idx)])       </span><br><span class="line">        <span class="keyword">return</span> self.endpoints[<span class="string">"layer_"</span> + str(idx)]</span><br></pre></td></tr></table></figure><h4 id="Train-function"><a href="#Train-function" class="headerlink" title="Train function"></a>Train function</h4><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><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">train</span><span class="params">(model, X_train, y_train, lr=<span class="number">1e-4</span>, epoch=<span class="number">15</span>, batch_size=<span class="number">200</span>)</span>:</span></span><br><span class="line">    <span class="comment"># 모델의 그래프 안에 build하지 않으면 찾을 수 없다고 오류가 발생한다.</span></span><br><span class="line">    <span class="keyword">with</span> model.graph.as_default():</span><br><span class="line">        x_placeholder = tf.placeholder(tf.float32, shape=[<span class="keyword">None</span>, model.config[<span class="string">"n_features"</span>]], name=<span class="string">"X"</span>)</span><br><span class="line">        y_placeholder = tf.placeholder(tf.float32, shape=[<span class="keyword">None</span>, model.config[<span class="string">"n_class"</span>]], name=<span class="string">"y"</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># graph에 build</span></span><br><span class="line">    model.build_net(x_placeholder, y_placeholder)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># Session이 정확히 특정한 graph에 연결을 하기 때문에 각 객체간에 엇갈릴 일이 없다.</span></span><br><span class="line">    <span class="keyword">with</span> tf.Session(graph=model.graph) <span class="keyword">as</span> sess:</span><br><span class="line">        train_op = tf.train.AdamOptimizer(learning_rate=lr).minimize(model.cost)</span><br><span class="line">        init = tf.global_variables_initializer()</span><br><span class="line">        merged_summary = tf.summary.merge_all()</span><br><span class="line">        writer = tf.summary.FileWriter(<span class="string">"./logs"</span>, sess.graph)</span><br><span class="line">        sess.run(init)</span><br><span class="line">        <span class="keyword">for</span> step <span class="keyword">in</span> range(epoch):</span><br><span class="line">            total_batch = int(len(X_train)/batch_size)</span><br><span class="line">            c_avg = <span class="number">0</span></span><br><span class="line">            <span class="keyword">for</span> i <span class="keyword">in</span> range(total_batch):</span><br><span class="line">                batch_x = X_train[batch_size*i : batch_size*(i+<span class="number">1</span>)]</span><br><span class="line">                batch_y = y_train[batch_size*i : batch_size*(i+<span class="number">1</span>)]</span><br><span class="line">                summary, c, _  = sess.run([merged_summary, model.cost, train_op],</span><br><span class="line">                                              feed_dict=&#123;model.X: batch_x, model.y: batch_y&#125;)</span><br><span class="line">                c_avg = c_avg + (c/total_batch)</span><br><span class="line">                writer.add_summary(summary, i)</span><br><span class="line">            print(step, c_avg)</span><br><span class="line">        saver = tf.train.Saver()</span><br><span class="line">        <span class="comment"># predict나 accuracy도 model 밖에서 접근하므로 use uninitialized weights 오류를 피하려면 checkpoint를 저장하고 불러쓰는 방법을 써야했다.</span></span><br><span class="line">        saver.save(sess, <span class="string">'./checkpoint/'</span> + model.config[<span class="string">"name"</span>] + <span class="string">'.chkp'</span>)</span><br></pre></td></tr></table></figure><h4 id="Predict-and-accuracy-function"><a href="#Predict-and-accuracy-function" class="headerlink" title="Predict and accuracy function"></a>Predict and accuracy function</h4><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">predict</span><span class="params">(model, x_test)</span>:</span></span><br><span class="line">    <span class="keyword">with</span> tf.Session(graph=model.graph) <span class="keyword">as</span> sess:</span><br><span class="line">        saver = tf.train.Saver()</span><br><span class="line">        saver.restore(sess, <span class="string">'./checkpoint/'</span> + model.config[<span class="string">"name"</span>] + <span class="string">'.chkp'</span>)</span><br><span class="line">        <span class="keyword">return</span> sess.run([model.predict], feed_dict=&#123;model.X : x_test&#125;)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">accuracy</span><span class="params">(model, x_test, y_test)</span>:</span></span><br><span class="line">    <span class="keyword">with</span> tf.Session(graph=model.graph) <span class="keyword">as</span> sess:</span><br><span class="line">        saver = tf.train.Saver()</span><br><span class="line">        saver.restore(sess, <span class="string">'./checkpoint/'</span> + model.config[<span class="string">"name"</span>] + <span class="string">'.chkp'</span>)</span><br><span class="line">        <span class="keyword">return</span> sess.run([model.accuracy], feed_dict=&#123;model.X : x_test, model.y : y_test&#125;)</span><br></pre></td></tr></table></figure><p>마지막으로 학습한 Endpoints를 확인하고 싶다면?<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dnn_model.endpoints</span><br></pre></td></tr></table></figure></p><p><img src="/images/danial/dnn/dnn_endpoints.png"></p><p>참고로 아래처럼 config를 하면 accuracy는 0.9749까지 올라간다.(이 network가 최고라는 것은 결코 아니니 오해하지 마시길)<br><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></pre></td><td class="code"><pre><span class="line">n_features = x_train.shape[<span class="number">1</span>]</span><br><span class="line">n_class = len(y_train[<span class="number">0</span>])</span><br><span class="line">config = &#123;</span><br><span class="line">    <span class="string">"name"</span> : <span class="string">"dnn_model"</span>,</span><br><span class="line">    <span class="string">"n_features"</span> : n_features,</span><br><span class="line">    <span class="string">"n_class"</span> : n_class,</span><br><span class="line">    <span class="string">"n_li"</span> : [n_features, <span class="number">1000</span>, <span class="number">1000</span>, <span class="number">1000</span>, n_class],</span><br><span class="line">    <span class="string">"initializer_li"</span> : [<span class="string">"xavier"</span>, <span class="string">"xavier"</span>, <span class="string">"xavier"</span>, <span class="string">"xavier"</span>],</span><br><span class="line">    <span class="string">"activation_li"</span> : [<span class="string">"relu"</span>, <span class="string">"relu"</span>, <span class="string">"relu"</span>, <span class="keyword">None</span>]</span><br><span class="line">&#125;</span><br><span class="line">dnn_model = DNNModel(config)</span><br><span class="line">train(dnn_model, x_train, y_train, epoch=<span class="number">15</span>)</span><br></pre></td></tr></table></figure></p><p>전체 코드는 <a href="https://github.com/DanialDaeHyunNam/Deep-Learning-Good-Practice/tree/master/tensorflow/dnn" target="_blank" rel="noopener">github</a>에도 올려놨으니 필요하신분은 확인하시길..</p><p>위에서도 설명했지만 이 방법이 좋은 방법인지 필자도 알 수는 없다. 적어도 필자의 목적은 이룬 코드 패턴이어서 소개를 하였는데, 부디 도움이 되길 바란다.</p><div class="notebook-embedded"><iframe src="https://nbviewer.jupyter.org/github/DanialDaeHyunNam/Deep-Learning-Good-Practice/blob/master/tensorflow/dnn/Tensorflow_DNN_example.ipynb" width="100%" height="100%" frameborder="0" allowfullscreen></iframe></div><h3 id="Related-Posts"><a href="#Related-Posts" class="headerlink" title="Related Posts"></a>Related Posts</h3><p><a href="https://danthetech.netlify.com/DataScience/basic-dnn-using-tensorflow/" target="_blank" rel="noopener"><deep learning=""> Tensorflow로 DNN 모델링하며 Good Practice에 대해서 생각해보자</deep></a></p>]]></content>
    
    <!-- <summary type="html">
    
    </summary> -->
    
      <category term="Danial Nam" scheme="https://databuzz-team.github.io/categories/Danial-Nam/"/>
    
    
      <category term="Data Science" scheme="https://databuzz-team.github.io/tags/Data-Science/"/>
    
      <category term="Machine Learning" scheme="https://databuzz-team.github.io/tags/Machine-Learning/"/>
    
      <category term="Deep Learning" scheme="https://databuzz-team.github.io/tags/Deep-Learning/"/>
    
      <category term="Tensorflow" scheme="https://databuzz-team.github.io/tags/Tensorflow/"/>
    
      <category term="Deep Neural Networks" scheme="https://databuzz-team.github.io/tags/Deep-Neural-Networks/"/>
    
  </entry>
  
  <entry>
    <title>&lt;Tensorflow&gt; Tensorflow에서 Graph와 Session의 차이</title>
    <link href="https://databuzz-team.github.io/2019/01/30/difference-between-graph-and-session/"/>
    <id>https://databuzz-team.github.io/2019/01/30/difference-between-graph-and-session/</id>
    <published>2019-01-29T16:07:47.000Z</published>
    <updated>2020-10-09T10:11:34.616Z</updated>
    
    <content type="html"><![CDATA[<div style="display: none;"><img src="/images/danial/tensorflow.jpeg"></div><h3 id="About"><a href="#About" class="headerlink" title="About"></a>About</h3><p>Tensorflow로 이것저것 도전하면서<br><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></pre></td><td class="code"><pre><span class="line">ValueError: Operation name: <span class="string">"init"</span></span><br><span class="line">op: <span class="string">"NoOp"</span></span><br><span class="line">input: <span class="string">"^val/Assign"</span></span><br><span class="line"> <span class="keyword">is</span> <span class="keyword">not</span> an element of this graph.</span><br></pre></td></tr></table></figure></p><p>오류라던가<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Tensor Tensor(<span class="string">"val:0"</span>, shape=(), dtype=int32_ref) <span class="keyword">is</span> <span class="keyword">not</span> an element of this graph.</span><br></pre></td></tr></table></figure></p><p>와 같은 오류들을 마주치면서 graph에 대해서 좀 더 깊게 이해하는 것이 좋겠다는 생각이 들었다.</p><p>그래서 찾던 도중에 좋은 예제가 있어서 이번 포스팅을 통해서 소개하고자한다.</p><h3 id="Graph"><a href="#Graph" class="headerlink" title="Graph?"></a>Graph?</h3><ol><li>Graph는 operation을 정의한 것을 말한다. Tensor와 Node간의 계산 등을 포함한 설계도를 의미하며 Data와는 관계가 없다.</li><li>Graph를 Session을 통해서 실행할 때, 우리가 layer간에 설치한 dimensions나 type등을 체크하며 문제가 있을시에는 예외를 발생시킨다.</li><li>Graph를 실행하기 위해서는 Data를 feed 해야한다.</li></ol><h3 id="Session"><a href="#Session" class="headerlink" title="Session?"></a>Session?</h3><p>Graph에게 전화를 거는 것이다. 특정 Graph에게 전화를 걸고 우리가 원하는 결과를 얻기위해 일을 시키는 것이라고 생각하면 된다.<br><figure class="highlight python"><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">with</span> tf.Session(graph=graph_we_want_to_connect) <span class="keyword">as</span> sess:</span><br><span class="line">  sess.run([op], feed_dict=&#123;data:data&#125;)</span><br></pre></td></tr></table></figure></p><h3 id="실습"><a href="#실습" class="headerlink" title="실습"></a>실습</h3><p>위의 뜻을 해석해보면 다양한 모델(Graph)을 만들고 세션마다 원하는 모델에 연결해서 학습을 진행할 수 있다는 것이다.</p><p>무슨 뜻인지 아래의 예제를 통해서 확인해보자.</p><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> tensorflow <span class="keyword">as</span> tf</span><br><span class="line"></span><br><span class="line">graph_1 = tf.Graph()</span><br><span class="line"></span><br><span class="line"><span class="keyword">with</span> graph_1.as_default():</span><br><span class="line">  W_1 = tf.Variable(<span class="number">100</span>, name=<span class="string">"graph_1_W"</span>)</span><br><span class="line">  init_graph_1 = tf.global_variables_initializer()</span><br><span class="line"></span><br><span class="line">graph_2 = tf.Graph()</span><br><span class="line"></span><br><span class="line"><span class="keyword">with</span> graph_2.as_default():</span><br><span class="line">  W_2 = tf.Variable(<span class="number">200</span>, name=<span class="string">"graph_2_W"</span>)</span><br><span class="line">  init_graph_2 = tf.global_variables_initializer()</span><br><span class="line"></span><br><span class="line"><span class="keyword">with</span> tf.Session(graph=graph_1) <span class="keyword">as</span> sess:</span><br><span class="line">  sess.run(init_graph_1)</span><br><span class="line">  print(sess.run(W_1))</span><br><span class="line"></span><br><span class="line"><span class="comment"># output 100</span></span><br></pre></td></tr></table></figure><p>이 경우에 아래처럼 실행하면<br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">with</span> tf.Session(graph=graph_1) <span class="keyword">as</span> sess:</span><br><span class="line">  sess.run(init_graph_2)</span><br><span class="line">  print(sess.run(W_1))</span><br></pre></td></tr></table></figure></p><p>아래같은 오류가 난다.<br><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></pre></td><td class="code"><pre><span class="line">Operation name: <span class="string">"init"</span></span><br><span class="line">op: <span class="string">"NoOp"</span></span><br><span class="line">input: <span class="string">"^graph_2_W/Assign"</span></span><br><span class="line"> <span class="keyword">is</span> <span class="keyword">not</span> an element of this graph.</span><br></pre></td></tr></table></figure></p><p>오류 의미 그대로이다. 우리가 실행하고자 한 init_graph_2가 graph_1에 해당하는 것이 아니어서 오류가 발생한 것이다.</p><p>변수의 경우도 마찬가지로 아래처럼 실행하면 오류가 발생한다.<br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">with</span> tf.Session(graph=graph_1) <span class="keyword">as</span> sess:</span><br><span class="line">  sess.run(init_graph_1)</span><br><span class="line">  print(sess.run(W_2))</span><br></pre></td></tr></table></figure></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Tensor(<span class="string">"graph_2_W:0"</span>, shape=(), dtype=int32_ref) <span class="keyword">is</span> <span class="keyword">not</span> an element of this graph.</span><br></pre></td></tr></table></figure><h3 id="결론"><a href="#결론" class="headerlink" title="결론"></a>결론</h3><p>Graph는 모델이며, Session은 원하는 모델을 선택하여 전화를 걸고 일을 시키는 행위를 말한다.</p><h3 id="Related-Posts"><a href="#Related-Posts" class="headerlink" title="Related Posts"></a>Related Posts</h3><p><a href="https://danthetech.netlify.com/DataScience/tensorflow-difference-between-graph-and-session/" target="_blank" rel="noopener"><tensorflow> Tensorflow에서 Graph와 Session의 차이</tensorflow></a><br><a href="http://goingmyway.cn/2017/07/14/Understanding-Session-and-Graph/" target="_blank" rel="noopener">Understanding Session and Graph</a></p>]]></content>
    
    <!-- <summary type="html">
    
    </summary> -->
    
      <category term="Danial Nam" scheme="https://databuzz-team.github.io/categories/Danial-Nam/"/>
    
    
      <category term="Deep Learning" scheme="https://databuzz-team.github.io/tags/Deep-Learning/"/>
    
      <category term="Tensorflow" scheme="https://databuzz-team.github.io/tags/Tensorflow/"/>
    
      <category term="Graph" scheme="https://databuzz-team.github.io/tags/Graph/"/>
    
      <category term="Session" scheme="https://databuzz-team.github.io/tags/Session/"/>
    
  </entry>
  
  <entry>
    <title>&lt;Neural Network&gt; 인공신경망에 대한 이해(Part 2 - Back Propagation)</title>
    <link href="https://databuzz-team.github.io/2018/12/27/Back-Propagation-Part-2/"/>
    <id>https://databuzz-team.github.io/2018/12/27/Back-Propagation-Part-2/</id>
    <published>2018-12-27T06:54:51.000Z</published>
    <updated>2020-10-09T10:11:24.084Z</updated>
    
    <content type="html"><![CDATA[<div style="display: none;"><img src="/images/danial/back-prop/thumbnail_2.png"></div><p><br></p><p>이번 포스트(Part 2)에서는 인공 신경망을 가능하게 한 <strong>역전파(Back Propagation)</strong> 에 대해 알아보도록 하겠다.(모바일에는 최적화되어있지 않으니 가능하면 PC로 보시길 추천한다)</p><p>만약 인공 신경망의 기본 개념과 <strong>순방향 전파(Feedforward Propagation)</strong> 에 대해서 잘 모른다면 <a href="https://Databuzz-team.github.io/2018/11/05/Back-Propagation/">이전 포스트(Part 1)</a>를 먼저 보고 오기 바란다.</p><h3 id="목차"><a href="#목차" class="headerlink" title="목차"></a>목차</h3><ul><li><a href="#why-back-propagation">왜 Back propagation를 이해해야 할까?</a></li><li><a href="#back-propagation">Back Propagation 설명</a><ul><li><a href="#derivatives">역전파 계산에 사용될 도함수</a></li><li><a href="#layer1">Back propagating the error (output Layer -&gt; K Layer2)</a></li><li><a href="#layer2">Back propagating the error (K Layer2 - &gt; J Layer1)</a></li><li><a href="#v-g-p">그래디언트 소멸 문제(Vanishing gradient problem)</a></li><li><a href="#initial-weight">Weight 초기값 설정</a></li><li><a href="#conclusion">문제점 해결 방법 및 결론</a></li></ul></li></ul><h3 id="why-back-propagation" href="#why-back-propagation">왜 Back propagation를 이해해야 할까?</h3><p>“어차피 TensorFlow를 사용하면 다 자동으로 계산해주는 것인데 왜 우리가 공부해야 하는 것일까?”</p><p>합리적인 질문이다. 공식만 봐도 어려워보이는 이 부분을 공부하는 것이 동기부여가 쉽게 되지않는것이 사실이기 때문에..</p><p>하지만, <a href="https://medium.com/@karpathy/yes-you-should-understand-backprop-e2f06eab496b" target="_blank" rel="noopener">Yes you should understand backprop</a> 글에서 설명했듯 <strong>Back Propagation</strong> 은 <strong>Leaky Abstraction</strong> 라는 것이다.</p><blockquote><p><strong>Leaky Abstraction</strong><br><br>Joel Spolsky이 설명한 <a href="https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/" target="_blank" rel="noopener">The Law of Leaky Abstraction</a>에서 사용된 표현으로써 프로그래밍 언어를 추상화시켜서 내부 구현을 모르도록 만들어놨지만, <strong style="color:red">결국 제대로 사용하려면 내부 구현을 상당 부분 알아야 한다는 것을 의미한다.</strong></p></blockquote><p>이 포스트에서는 역전파 계산과정을 통해서 왜 인공 신경망의 문제점(그래디언트 소멸 문제와 초기값의 중요성)에 발생하는 것이며 어떻게 해결할 수 있는지에 대해서도 알아볼 것이다.</p><h3 id="back-propagation" href="#back-propagation">Back propagation 설명</h3>시작에 앞서 먼저 <a href="/2018/11/05/Back-Propagation/">이전 포스트</a>에서 정의한 네트워크를 다시 살펴보자.<br><br><img src="/images/danial/back-prop/network.png">$$Input = \left[ \begin{array}{cccc}i_{1} & i_{2} \\\end{array} \right]$$$$W_{ij} = \left[ \begin{array}{cccc}W_{i1j1} & W_{i1j2} & W_{i1j3} \\W_{i2j1} & W_{i2j2} & W_{i2j3} \\\end{array} \right]W_{jk} = \left[ \begin{array}{cccc}W_{j1k1} & W_{j1k2} & W_{j1k3} \\W_{j2k1} & W_{j2k2} & W_{j2k3} \\W_{j3k1} & W_{j3k2} & W_{j3k3} \\ \end{array} \right]W_{ko} = \left[ \begin{array}{cccc}W_{k1o1} & W_{k1o2} \\W_{k2o1} & W_{k2o2} \\W_{k3o1} & W_{k3o2} \\ \end{array} \right]$$$$Output = \left[ \begin{array}{cccc}o_{1} & o_{2} \\\end{array} \right]$$(자세한 Feedforward 계산은 <a href="/2018/11/05/Back-Propagation/">이전 포스트</a>에서 확인하길 바란다.)<br><br><blockquote>이번 포스트는 계산식이 많이 나오고 첨자가 헷갈릴 수 있으니 공책에 적으며 따라가는 것을 추천한다.</blockquote><h4 id="derivatives" href="#derivatives">역전파 계산에 사용될 도함수</h4>먼저 설명을 시작하기에 앞서 우리가 사용하게 될 도함수들을 살펴보자.<br><br><strong>Sigmoid</strong>$$Sigmoid = 1/(1+\mathrm{e}^{-x})$$$$\frac{\partial (1/(1+\mathrm{e}^{-x}))}{\partial x} = 1/(1+\mathrm{e}^{-x}) \times (1- 1/(1+\mathrm{e}^{-x}))$$$$\frac{\partial Sigmoid}{\partial x} = Sigmoid \times (1- Sigmoid)$$<strong>Softmax</strong>$$Softmax = \mathrm{e}^{x_{a}}/(\sum_{a=1}^{2}\mathrm{e}^{x_{a}})$$$$\frac{\partial (Softmax)}{\partial x_{1}} = \mathrm{e}^{x_{1}} * \mathrm{e}^{x_{2}}/ (\mathrm{e}^{x_{1}}+\mathrm{e}^{x_{2}})^2$$<strong>Cross Entropy</strong>$$cross entropy = - (1/n)(\sum_{i=1}^{3} (y_{i} \times \log(o_{outi})) + ((1-y_{i}) \times \log((1-o_{outi}))))$$$$\frac{\partial (cross entropy)}{\partial O_{out1}} =  -1 *  ((y_{1} * (1/O_{out1}) + (1-y_{1})* (1/(1-O_{out1}))$$<blockquote><strong>수학적인 기본이 너무 튼튼한 분들은 이 부분을 무시해도 좋다.</strong> 필자가 이 부분을 길게 설명하는 이유는 앞으로 계산과정이 복잡하여 그 과정 중에는 <strong>계산하는 의미</strong> 를 잊기쉽기 때문이다. 우리의 목적은 <strong>계산(이건 컴퓨터가 한다..)</strong>이 아니라 <strong>의미를 이해하는 것</strong>이므로.. 계산을 시작하기전에 한번 더 짚고 넘어가자.<br><br> 도함수의 역할?<br> 원래의 함수를 미분해서 얻어낸 도함수는 같은 입력에 대해 원래 함수의 기울기를 출력한다.<br><br> 우리가 수정하고자하는 값(<strong>변수</strong>)은?<br> Weight와 bias<br><br> 우리는 앞으로 예측값(y_pred)과 실제값(y_true)의 차이를 보여주는 <strong>오차 함수</strong>를 <strong>위의 변수들</strong>로 <strong>미분</strong>하여, 매 Step에서 그 <strong>변수</strong>들이 크고 작아짐에 따라 끼치는 영향(<strong>기울기</strong>)을 보며 <strong>값을 수정</strong>해나갈 것이다.<br><br> 이제 계산을 해보자!</blockquote><h4 id="layer1" href="#layer1">Back propagating the error (output Layer -> K Layer2)</h4><div style="float:left; width:40%; margin-right: 10px;">  <img src="/images/danial/back-prop/o_k_layer.png"></div><!-- <div style=''> -->먼저 K layer와 output layer 사이의 W<sub>ko</sub>가 E<sub>total</sub>(오차값)에 끼치는 영향을 확인하고 E<sub>total</sub>이 낮아지는 방향으로 값을 수정해보자.<br>이를 수식으로 표현해보면 아래와 같다.$${E_{total}} = {(-1 * ((y * \log(O_{out}) + (1-y) * \log((1-O_{out}))}$$$${E_{total}} =\left[ \begin{array}{cccc}E_{1} & E_{2}\\\end{array} \right]$$$$\delta W_{ko} =\frac{\partial E_{total}}{\partial W_{ko}} = \left[ \begin{array}{cccc}\frac{\partial E_{1}}{\partial W_{k1o1}} & \frac{\partial E_{2}}{\partial W_{k1o2}}\\\frac{\partial E_{1}}{\partial W_{k2o1}} & \frac{\partial E_{2}}{\partial W_{k2o2}}\\\frac{\partial E_{1}}{\partial W_{k3o1}} & \frac{\partial E_{2}}{\partial W_{k3o2}}\end{array} \right]$$행렬의 각 원소들의 계산법은 같으므로 하나만 살펴보게되면,$$\frac{\partial E_{1}}{\partial W_{k1o1}}$$이었던 식은 체인룰에 의해서$$\frac{\partial E_{1}}{\partial W_{k1o1}} = \frac{\partial E_{1}}{\partial O_{out1}} * \frac{\partial O_{out1}}{\partial O_{in1}} * \frac{\partial O_{in1}}{\partial W_{k1o1}}$$가 된다. 여기서 관찰할 점은 컴퓨터가 순방향 전파를 진행하면서 O<sub>out1</sub>, O<sub>in1</sub>들을 다 계산했었다는 점이다. 즉 이들은 역전파가 이루어지는 이 순간에 상수로 작용한다. 그렇게 보면 도함수에 해당 값들을 대입하기만 하면 되므로 계산량이 상대적으로 크지 않다는 것을 알 수 있다.<br><br>자 이제 <a href="#derivatives">역전파 계산에 사용될 도함수</a>에서 보여준 함수에 값을 대입하면 된다.$$\frac{\partial E_{1}}{\partial O_{out1}} =  -1  * ((y_{1} * (1/O_{out1}) + (1-y_{1}) * (1/(1-O_{out1}))$$<blockquote>여기서 y1은 실제 값(y_true)을 의미한다.</blockquote>$$\frac{\partial O_{out1}}{\partial O_{in1}}  =\mathrm{e}^{O_{in1}} * \mathrm{e}^{O_{in2}}/ (\mathrm{e}^{O_{in1}}+\mathrm{e}^{O_{in2}})^2$$이제 가장 마지막 함수를 살펴보자.$$\definecolor{first}{RGB}{245, 166, 35}\definecolor{second}{RGB}{74, 144, 226}\definecolor{third}{RGB}{189, 16, 224}\frac{\partial O_{in1}}{\partial W_{k1o1}} = \frac{\partial (\textcolor{first}{W_{k1o1}} \times K_{out1} +\textcolor{second}{W_{k2o1}} \times K_{out2} +\textcolor{third}{W_{k3o1}} \times K_{out3} + b_{o1})}{\partial \textcolor{first}{W_{k1o1}}}$$이 부분의 미분한 값은 K<sub>out1</sub>이 된다.즉,$$\frac{\partial O_{in1}}{\partial W_{k1o1}} = K_{out1}$$이제 종합해보면$$\delta W_{k1o1} = \frac{\partial E_{1}}{\partial O_{out1}} * \frac{\partial O_{out1}}{\partial O_{in1}} * \frac{\partial O_{in1}}{\partial W_{k1o1}}$$이 된다. 이제 전체를 보게되면$$\delta W_{ko} = \left[ \begin{array}{cccc}\frac{\partial E_{1}}{\partial O_{out1}} * \frac{\partial O_{out1}}{\partial O_{in1}} * \frac{\partial O_{in1}}{\partial W_{k1o1}} & \frac{\partial E_{2}}{\partial O_{out2}} * \frac{\partial O_{out2}}{\partial O_{in2}} * \frac{\partial O_{in2}}{\partial W_{k1o2}} \\\frac{\partial E_{1}}{\partial O_{out1}} * \frac{\partial O_{out1}}{\partial O_{in1}} * \frac{\partial O_{in1}}{\partial W_{k2o1}}& \frac{\partial E_{2}}{\partial O_{out2}} * \frac{\partial O_{out2}}{\partial O_{in2}} * \frac{\partial O_{in2}}{\partial W_{k2o2}} \\\frac{\partial E_{1}}{\partial O_{out1}} * \frac{\partial O_{out1}}{\partial O_{in1}} * \frac{\partial O_{in1}}{\partial W_{k3o1}} & \frac{\partial E_{2}}{\partial O_{out2}} * \frac{\partial O_{out2}}{\partial O_{in2}} * \frac{\partial O_{in2}}{\partial W_{k3o2}} \\ \end{array} \right]$$가 된다.이제 W<sub>ko</sub>을 앞서 계산한 값에 맞춰서 수정하자.$$\acute{W_{kl}} = \left[ \begin{array}{cccc}W_{k1o1} - (lr*\delta W_{k1o1}) & W_{k1o2} - (lr * \delta W_{k1o2}) \\W_{k2o1} - (lr* \delta W_{k2o1}) & W_{k2o2} - (lr * \delta W_{k2o2}) \\W_{k3o1} - (lr * \delta W_{k3o1}) & W_{k3o2} - (lr * \delta W_{k3o2}) \\ \end{array} \right]$$여기서 lr은 하이퍼 패러미터인 learning rate을 의미한다.<h4 id="layer2" href="#layer2">Back propagating the error (K Layer -> J Layer1)</h4><div style="float:left; width:40%; margin-right: 10px;">  <img src="/images/danial/back-prop/k_j_layer.png"></div>이제 다음 Layer를 확인해보며 조금 더 이해를 높여보자.역시 이번에도 체인룰에 의해$$\frac{\partial E_{total}}{\partial W_{j1k1}} = \frac{\partial E_{total}}{\partial K_{out1}} * \frac{\partial K_{out1}}{\partial K_{in1}} * \frac{\partial K_{in1}}{\partial W_{j1k1}}$$가 된다. 이번엔 제일 우측부터 확인해보자.$$\definecolor{first}{RGB}{10, 233, 134}\definecolor{second}{RGB}{74, 144, 226}\definecolor{third}{RGB}{245, 166, 35}\frac{\partial K_{in1}}{\partial W_{j1k1}} =\frac{\partial(\textcolor{first}{W_{j1k1}} \times J_{out1} +\textcolor{second}{W_{j2k1}} \times J_{out2} +\textcolor{third}{W_{j3k1}} \times J_{out3} + b_{k1})}{\partial \textcolor{first}{W_{j1k1}}}$$위에서와 마찬가지로 이 부분은 한단계 전 Layer의 output을 의미한다. 즉,$$\frac{\partial K_{in1}}{\partial W_{j1k1}} = J_{out1}$$이 된다.이제 그 다음이 중요하다.$$\frac{\partial K_{out1}}{\partial K_{in1}} = Sigmoid(K_{in1}) * (1 - Sigmoid(K_{in1}))$$항상 체인룰에 의해 곱해지는 이 미분 값이 바로 <strong id="v-g-p">그래디언트 소멸 문제(Vanishing gradient problem)</strong>을 발생시키는 원인이기 때문이다.그 이유는 아래 그림을 보면 명백하다.<img style="width:100%;" src="/images/danial/back-prop/sigmoid_derivative.png">위의 그림의 주황색선 미분값을 보게되면 크기가 1보다 작고, 가장 클 때 0.25인 Sigmoid 함수 미분값(기울기)이 매번 곱해지게 되면서 결국$$\delta W_{j1k1}$$를 0에 가깝게 만들게되고, 그 결과로$$\acute{W_{j1k1}} = W_{j1k1} - (lr * \delta W_{j1k1})$$식에 의해서 수정되는 Weight 값이 거의 변동이 없어지기 때문이다.<strong>이 현상은 Layer가 많아질수록 심각해진다.</strong> 그 이유를 계속해서 계산하며 확인해보자!$$\frac{\partial E_{total}}{\partial K_{out1}}$$바로 이 녀석이 문제의 녀석이다.위 식의 의미는$$\frac{\partial E_{total}}{\partial K_{out1}} = \frac{\partial E_{1}}{\partial K_{out1}} + \frac{\partial E_{2}}{\partial K_{out1}}$$체인룰로 풀게되면 아래와 같다.$$\frac{\partial E_{1}}{\partial K_{out1}} = \frac{\partial E_{1}}{\partial O_{out1}} * \frac{\partial O_{out1}}{\partial O_{in1}} * \frac{\partial O_{in1}}{\partial K_{out1}}$$$$\frac{\partial E_{2}}{\partial K_{out1}} = \frac{\partial E_{2}}{\partial O_{out2}} * \frac{\partial O_{out2}}{\partial O_{in2}} * \frac{\partial O_{in2}}{\partial K_{out1}}$$위에서 계산한 Output layer -> K layer 부분 역전파에서 우린 이미$$\frac{\partial E_{1}}{\partial O_{out1}} * \frac{\partial O_{out1}}{\partial O_{in1}}$$$$\frac{\partial E_{2}}{\partial O_{out2}} * \frac{\partial O_{out2}}{\partial O_{in2}}$$는 계산했던 것이다. 그러니 그냥 그 값들을 대입하면 끝이다.여기서! 위에서 말한 Layer 층이 많아질수록 소멸현상이 심해지는 이유는 이번 K-J레이어 간의 Weight를 업데이트 시키기 위해서 찾고있는$$\delta W_{j1k1}$$값은$$\frac{\partial K_{out1}}{\partial K_{in1}}, \frac{\partial O_{out1}}{\partial O_{in1}}$$두 개의 활성화 함수의 기울기 값이 곱해지고 있는 것이다.<br><br><strong>물론 위의 예는 output Layer를 포함하고 있어서 아까전에 말한 Sigmoid 함수의 문제를 증폭시키는 것은 아니지만, 중앙에 위치한 어떤 Layer의 Weight값을 수정하기위한 계산이라고 생각해보라. 역전파가 Input에 가까워질수록 변경하게될 Weight값을 사실상 0이나 다름없게 되는 것이다.</strong><br><br>이 부분이 이해가 되면 이번 포스트는 70%정도 역할을 해냈다고 본다.. (설명이 마음에 들었다면 부디 공유를 부탁!!)<br><br>다음도 중요한 부분이니 계속해서 살펴보자!<br><br>이제$$\frac{\partial E_{1}}{\partial K_{out1}} = \frac{\partial E_{1}}{\partial O_{out1}} * \frac{\partial O_{out1}}{\partial O_{in1}} * \frac{\partial O_{in1}}{\partial K_{out1}}$$에서 남은 것은$$\frac{\partial O_{in1}}{\partial K_{out1}}$$뿐이다.결국 이 식이 의미하는 것은 자세히 풀어서 살펴보면,$$\definecolor{first}{RGB}{245, 166, 35}\definecolor{second}{RGB}{74, 144, 226}\definecolor{third}{RGB}{189, 16, 224}\frac{\partial O_{in1}}{\partial K_{out1}} = \frac{\partial (\textcolor{first}{W_{k1o1}} \times K_{out1} +\textcolor{second}{W_{k2o1}} \times K_{out2} +\textcolor{third}{W_{k3o1}} \times K_{out3} + b_{o1})}{\partial K_{out1}}$$이므로,$$\definecolor{first}{RGB}{245, 166, 35}\textcolor{first}{W_{k1o1}}$$를 의미한다.<br>이제 통합해보면$$\left[ \begin{array}{cccc}\frac{\partial E_{total}}{\partial K_{out1}}  \\\frac{\partial E_{total}}{\partial K_{out2}}   \\\frac{\partial E_{total}}{\partial K_{out3}} \\ \end{array} \right] =  \left[ \begin{array}{cccc}(\frac{\partial E_{1}}{\partial O_{out1}} * \frac{\partial O_{out1}}{\partial O_{in1}} * W_{k1o1}) + (\frac{\partial E_{2}}{\partial O_{out2}} * \frac{\partial O_{out2}}{\partial O_{in2}} * W_{k1o2})\\(\frac{\partial E_{1}}{\partial O_{out1}} * \frac{\partial O_{out1}}{\partial O_{in1}} * W_{k2o1}) + (\frac{\partial E_{2}}{\partial O_{out2}} * \frac{\partial O_{out2}}{\partial O_{in2}} * W_{k2o2})\\(\frac{\partial E_{1}}{\partial O_{out1}} * \frac{\partial O_{out1}}{\partial O_{in1}} * W_{k3o1}) + (\frac{\partial E_{2}}{\partial O_{out2}} * \frac{\partial O_{out2}}{\partial O_{in2}} * W_{k3o2})\\\end{array} \right]$$가 되겠다!여기서 <strong>포인트</strong>는 <strong id="initial-weight">Weight 초기값 설정</strong>이 너무나도 중요하다는 것이다.<br><br><strong>역전파에서 계속해서 곱해지는 값 중 하나가 바로 이전 Layer(역전파 기준으로 이전)의 Weight값이라는 점.곱셈으로 연결되어 있는 체인룰에 의해서 초기값을 0으로 하게되면 당연히 업데이트가 일어나지 않게 되는 것이다. 인공지능분야 유명한 교수인 Hinton교수님이 하신 말씀이 We initialized the weights in a stupid way. 즉! 초기값을 어떻게 설정하는지가 매우 중요하다는 것! 이 부분을 꼭 기억하자.</strong><br><br>이제 위에서 구한 모든 식을 곱하게 되면$$\delta W_{jk} =  \left[ \begin{array}{cccc}\frac{\partial E_{total}}{\partial K_{out1}} * \frac{\partial K_{out1}}{\partial K_{in1}} * \frac{\partial K_{in1}}{\partial W_{j1k1}} & \frac{\partial E_{total}}{\partial K_{out2}} * \frac{\partial K_{out2}}{\partial K_{in2}} * \frac{\partial K_{in2}}{\partial W_{j1k2}}& \frac{\partial E_{total}}{\partial K_{out3}} * \frac{\partial K_{out3}}{\partial K_{in3}} * \frac{\partial K_{in3}}{\partial W_{j1k3}} \\\frac{\partial E_{total}}{\partial K_{out1}} * \frac{\partial K_{out1}}{\partial K_{in1}} * \frac{\partial K_{in1}}{\partial W_{j2k1}}& \frac{\partial E_{total}}{\partial K_{out2}} * \frac{\partial K_{out2}}{\partial K_{in2}} * \frac{\partial K_{in2}}{\partial W_{j2k2}} & \frac{\partial E_{total}}{\partial K_{out3}} * \frac{\partial K_{out3}}{\partial K_{in3}} * \frac{\partial K_{in3}}{\partial W_{j2k3}} \\\frac{\partial E_{total}}{\partial K_{out1}} * \frac{\partial K_{out1}}{\partial K_{in1}} * \frac{\partial K_{in1}}{\partial W_{j3k1}} & \frac{\partial E_{total}}{\partial K_{out2}} * \frac{\partial K_{out2}}{\partial K_{in2}} * \frac{\partial K_{in2}}{\partial W_{j3k2}} & \frac{\partial E_{total}}{\partial K_{out3}} * \frac{\partial K_{out3}}{\partial K_{in3}} * \frac{\partial K_{in3}}{\partial W_{j3k3}} \\ \end{array} \right]$$를 구할 수 있다.<br><br>역시 마찬가지로,$$\acute{W_{jk}} = \left[ \begin{array}{cccc}W_{j1k1} - (lr*\delta W_{j1k1}) & W_{j1k2} - (lr * \delta W_{j1k2}) &W_{j1k3} - (lr * \delta W_{j1k3}) \\W_{j2k1} - (lr* \delta W_{j2k1}) & W_{j2k2} - (lr * \delta W_{j2k2}) &W_{j2k3} - (lr * \delta W_{j2k3}) \\W_{j3k1} - (lr * \delta W_{j3k1}) & W_{j3k2} - (lr * \delta W_{j3k2}) & W_{j3k3} - (lr * \delta W_{j3k3}) \\ \end{array} \right]$$방식으로 수정해주면 되겠다.<br><br>아직 J layer에서 Input layer 역전파 부분과 bias에 대한 계산이 아직 남은 것은 알지만.. 사실상 계산법이 차이가 크게 없기 때문에 더 설명하지는 않고 계산은 여기서 끝내도록 하겠다. 여기까지 읽으신 분에게 박수를.. 보낸다. 이제 위에서 설명한 소멸 문제와 초기값에 대해서 좀 더 얘기하고 이번 포스트를 마무리하도록 하겠다.<h3 id="conclusion">문제점 해결 방법 및 결론</h3><p>첫 번째는 활성화 함수 Sigmoid가 발생시키는 <strong>그래디언트 소멸 문제(Vanishing gradient problem)</strong>는 활성화 함수 종류를 바꾸면 해결된다(물론 무조건 좋은 활성화 함수란 없다고 한다.. 수렴이 잘되는 것을 찾는 것이 우리의 역할). 그 중에 하나는 Relu인데, 특징은</p><script type="math/tex; mode=display">Relu = max(0, x)</script><p>라서 음수는 다 0으로 만들고 양수인 경우만 남기게 된다. 덕분에 기울기도 0이나 1만 나오게되서 계산이 편하다. 그 외에도 하이퍼탄젠트 활성화 함수 등이 있으니 따로 검색해보길 추천한다. 혹은 <a href="https://datascienceschool.net/view-notebook/f18248a467e94c6483783afc93d08af9/" target="_blank" rel="noopener">데이터 사이언스 스쿨 - 신경망 성능 개선</a>에서도 확인이 가능하다.</p><p>가중치 초기화 관련된 문제도 위의 링크에서 확인할 수 있는데, TensorFlow에서 Xavier가 2010년에 제시한 Xavier initializer를 사용할 수 있는데 대회에서 수상한 경우에는 주로 이 Weight 초기화법을 사용했다고 하니 기억하면 좋을 것으로 보인다.</p><p>사용법은 아래처럼 사용하면 된다.</p><figure class="highlight python"><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">import</span> tensorflow <span class="keyword">as</span> tf</span><br><span class="line">tf.contrib.layers.xavier_initializer()</span><br></pre></td></tr></table></figure><p>이쯤에서 이 내용들을 시각화해서.. 알려주는 최고의 Youtuber 3Blue1Brown의 영상(아래 링크)을 보게되면 좋은 복습이 될 것이라 생각한다. <a href="https://www.youtube.com/watch?v=Ilg3gGewQ5U&amp;index=4&amp;list=PLZHQObOWTQDNU6R1_67000Dx_ZCJB-3pi" target="_blank" rel="noopener">What is backpropagation really doing?</a></p><p>Backpropagation에 대한 설명을 드디어 마쳤다. 과정을 이해함으로써 소멸문제 및 초기화의 중요성에 대해서 제법 시원한 해답을 얻었지만, 더 많은 호기심들이 생겨난다. Gradient Descent하는 방법, 즉 어떤 Optimizer를 쓰는 것이 좋을까? 등등..</p><p>만약 도움이 많이 되었다면 꼭 공유해주길!</p><p>다음 포스팅 내용은 Tensorflow를 이용하여 CNN 모델링하는 법에 대해서 작성하겠다!</p><h3 id="Related-Posts"><a href="#Related-Posts" class="headerlink" title="Related Posts"></a>Related Posts</h3><ul><li><a href="https://github.com/Prakashvanapalli/TensorFlow/blob/master/Blogposts/Backpropogation_with_Images.ipynb" target="_blank" rel="noopener">Backprop is very simple. Who made it Complicated?</a></li></ul>]]></content>
    
    <!-- <summary type="html">
    
    </summary> -->
    
      <category term="Danial Nam" scheme="https://databuzz-team.github.io/categories/Danial-Nam/"/>
    
    
      <category term="Artificial Intelligence" scheme="https://databuzz-team.github.io/tags/Artificial-Intelligence/"/>
    
      <category term="Deep Learning" scheme="https://databuzz-team.github.io/tags/Deep-Learning/"/>
    
      <category term="Neural Network" scheme="https://databuzz-team.github.io/tags/Neural-Network/"/>
    
      <category term="Back Propagation" scheme="https://databuzz-team.github.io/tags/Back-Propagation/"/>
    
  </entry>
  
  <entry>
    <title>&lt;Medium 블로그 번역&gt;데이터 사이언티스트 취업을 위한 포트폴리오 만드는 법</title>
    <link href="https://databuzz-team.github.io/2018/12/23/how-to-build-a-data-science-portfolio/"/>
    <id>https://databuzz-team.github.io/2018/12/23/how-to-build-a-data-science-portfolio/</id>
    <published>2018-12-23T01:10:05.000Z</published>
    <updated>2020-10-09T10:11:18.484Z</updated>
    
    <content type="html"><![CDATA[<div style="display: none;"><img src="/images/danial/how-to-build-portfolio/thumbnail.jpg"></div><p>이 포스팅은 Medium 블로그를 번역한 내용입니다.  </p><blockquote><p>원문 링크 : <a href="https://towardsdatascience.com/how-to-build-a-data-science-portfolio-5f566517c79c" target="_blank" rel="noopener">How to Build a Data Science Portfolio</a></p></blockquote><p><strong>어떻게 하면 Data Scientist로 취업할 수 있을까?</strong> 통계, 머신러닝, 프로그래밍 등을 충분히 안다면 취업을 하는 것은 어려운 일이 아니다. 하지만 최근에 내가 발견한 점은 사람들이 데이터 사이언티스트로 취업에 필요한 스킬들은 갖췄음에도 포트폴리오를 준비하지 않은 경우를 많이 볼 수 있었다. 당연히 이력서나 자소서가 중요하듯! 사람들에게 자신의 능력을 증명할 수 있는 포트폴리오가 취업 때 하는 역할은 더할 나위 없이 중요하다. 해외 취업의 경우 신뢰할 수 있는 사람으로부터의 소개나 추천이 있다 하더라도, <strong>그냥 말로 자신이 무엇을 할 수 있는지 전달하는 것보다는 보여주는 것이 훨씬 중요하다는 것.</strong> 이 포스팅에서는 많은 프로페셔널 데이터 사이언티스트들이 말하는 포트폴리오에 어떤 것을 포함해야 하는지? 어떻게 돋보이게 할 수 있는지 등을 포함하고 있으니 꼭 도움이 되길 바란다!<br><br></p><h2>목차</h2><ul><li>  <a href="#importance-of-a-portfolio">포트폴리오의 중요성</a></li><li>  <a href="#portfolio-to-get-experience">포트폴리오로 경험 부분 채우기</a></li><li>  <a href="#type-of-projects">  어떤 프로젝트를 포트폴리오에 포함해야할까?  </a></li><li>  <a href="#type-of-projects-not-to-include">  포트폴리오에 넣으면 안되는 프로젝트는?  </a></li><li>  <a href="#portfolios-are-iterative">  포트폴리오는 재사용 가능하다  </a></li><li>  <a href="#incorporation-portfolio">  포트폴리오를 1장짜리 이력서에 포함시키자  </a></li><li>  <a href="#importance-of-social-media">  소셜미디어의 중요성  </a></li><li>  <a href="#conclusion">  결론  </a></li></ul><h2 id="importance-of-a-portfolio">포트폴리오의 중요성</h2>만드는 과정에서 배우는 것이 있다는 점 외에도 취업에 있어서 아주 큰 혜택을 주는 것이 포트폴리오이다. 이 포스팅에서는 포트폴리오의 정의를 <strong>대중들에게 자신이 가진 데이터 사이언스 스킬을 증명하는 것</strong>으로 하자. (이 정의는 DataCamp의 Chief 데이터 사이언티스트인 <a href="https://twitter.com/drob" target="_blank" rel="noopener"><strong>David Robinson</strong></a>이 <strong>Mode Analytics blog소속 Marissa Gemma</strong>의 인터뷰에서 표현한 것을 가져왔다). 그는 어떻게 처음에 이 분야에서 일하게 됐냐는 질문에 아래처럼 답했다.<br><br><i>"내가 사용했던 가장 효과적인 방법은 public 한 작업들을 했다는 것이었다. 블로그를 했고 박사학위 과정 중에는 많은 오픈소스 프로젝트에 참여하였는데, 이 경험은 내가 데이터 사이언스 기술들을 많이 가졌다는 것을 사람들에게 알리는 계기가 되었던 것이다. 처음으로 이 분야에 일을 구하게 된 가장 큰 계기는 Stack overflow에 남겼던 나의 답변 덕이었는데, 그 답변에 감탄한 한 회사의 직원이 내게 연락이 왔고, 몇 번의 면접 후에 취업을 했던 것이었다."</i><br><br>David은 자신의 블로그에 이와 관련해 표현하기를,<br><br><i>공개적인 작업을 많이 할 수록 이런 극적인 우연들이 일어날 확률이 높아진다.</i><br><br>사람들은 간혹 소프트웨어 엔지니어나 데이터 사이언티스트들도 그들에게 발생한 문제들을 구글링한다는 사실을 깜빡한다. 만약 이들이 당신이 공개한 작업에 의해서 도움을 받은 적이 있다면, 그들은 당신에게 연락을 하려고 할 것이다.<h2 id="portfolio-to-get-experience">포트폴리오로 경험 부분 채우기</h2><p>아래의 짤에서 보여주듯 대부분 회사들은 신입사원을 뽑는 공고에서조차 일 경험이 있길 기대하는 경우가 많다.<br><img src="/images/danial/how-to-build-portfolio/portfolio-meme.png"><br>문제는 이처럼 일 경험이 없는데 경험을 요구하면 어떻게 해야하는 것인가하는 점이다. 그 해답은 바로 <strong>프로젝트</strong>이다. <a href="https://will-stanton.com/2015/07/15/creating-a-great-data-science-resume/" target="_blank" rel="noopener">Will Stanson</a>은 프로젝트가 경험을 대체할 수 있는 최고의 방법이라고 말한다.<br><i><br>만약 당신이 데이터 사이언티스트 경험이 없다면, 반드시 개인 프로젝트를 실시해야한다.</i><br>실제로 <a href="https://medium.com/@skyetetra" target="_blank" rel="noopener">Jonathan Nolis</a>가 지원자에게 듣고싶어했던 것은 최근에 프로젝트 진행중에 어떤 문제점을 해결했는지였다.<br><i><br>“난 그들이 최근에 한 프로젝트를 듣고 싶다. 그들에게 해당 프로젝트를 시작하게 된 동기라던가 그 일에 왜 시간을 투자하기로 결정했는지, 진행과정과 결과 등을 물어봤다. 또한 그들이 프로젝트를 통해서 배운 점이 무엇인지를 물어봤고, 특히 ‘해결하고자 하는 문제가 가진 가치가 무엇이며 그것을 위해서 어떤 식으로 노력했는가?’라는 질문을 통해서 가장 얻고 싶은 대답들을 얻을 수 있었다.”</i><br>만약 당신이 데이터 사이언티스트로써의 경험이 없다면 최고의 방법은 당신이 진행한 데이터 사이언스 프로젝트를 최대한 보여주는 것이다.</p><p></p><h2 id="type-of-projects">어떤 프로젝트를 포트폴리오에 포함해야할까?</h2><br>데이터 사이언스의 범위가 너무 넓어서 채용매니저들이 어떤 프로젝트들을 보고싶어할지 알기는 어렵다. Quora의 데이터 사이언스 매니저인 <a href="https://twitter.com/wzchen" target="_blank" rel="noopener">William Chen</a>이 2018년 Kaggle 채용 박람회에서 아래처럼 설명했다.<br><i><br>난 사람들이 숙제나 과제를 넘어 데이터에 대한 관심을 보여주는 것을 좋아한다. 개인적 프로젝트를 통해서 데이터셋에 대한 자신만의 열정이나 흥미로운 결과를 보여주는 것.. 그 것에 대해서 깔끔하게 문서화한 것.. 그런 작업들을 통해서 난 자주 감탄을하고 한다.</i><br><br><br>많은 사람들이 프로젝트를 만드는 것의 가치를 알고있으나, 가장 중요한 점은 왜 그 데이터들에 당신이 관심을 가졌고, 어떤 인사이트를 얻거나 얻으려했는지에 대해서는 잘 설명해내지 못한다. Airbnb의 데이터 사이언티스트인 <a href="https://medium.com/@jasonkgoodman" target="_blank" rel="noopener">Jason Goodman</a>은 자신의 포스트인 <a href="https://medium.com/@jasonkgoodman/advice-on-building-data-portfolio-projects-c5f96d8a0627" target="_blank" rel="noopener">“데이터 포트폴리오 프로젝트에 관한 조언”</a>에서 다양한 프로젝트 아이디어와 어떤 데이터셋을 이용하면 좋은지에대해 조언을 해주고 있다. 그는 또한 William이 말한 것처럼 interesting data, 흥미로운 데이터를 가지고 작업해야한다는 점을 강조했다.<br><br><br><i><br>난 최고의 포트폴리오 프로젝트는 화려한 모델링보다는 흥미로운 데이터셋을 사용하는 것에 있다고 생각한다. 많은 사람들이 금융 데이터나 트위터데이터를 사용하는데, 이런 데이터들은 주로 흥미롭지는 않아서 고행을 겪을 확률이 높다.</i><br><br><br>그는 웹 스크래핑이 흥미로운 데이터를 얻기위한 좋은 방법이라고 이야기했다. 만약 당신이 웹스크래핑을 통해서 데이터셋을 얻고싶다면 나의 <a href="https://towardsdatascience.com/using-scrapy-to-build-your-own-dataset-64ea2d7d4673" target="_blank" rel="noopener">포스트</a>를 확인하길 바란다. 또한 만약 당신이 학위를 얻고있는 중이라면 논문에 사용한 프로젝트는 아주 좋은 프로젝트가 될 수 있다는 점도 명심하자(예로는 William Chen이 포스팅한 <a href="https://www.youtube.com/watch?v=xrhPjE7wHas&feature=youtu.be&t=31m15s" target="_blank" rel="noopener">자료</a>를 확인하자).<p></p><p></p><h2 id="type-of-projects-not-to-include">포트폴리오에 넣으면 안되는 프로젝트는?</h2><br>넣으면 오히려 안좋은 프로젝트들은 존재한다. <a href="https://towardsdatascience.com/@jeremie_sharpestminds" target="_blank" rel="noopener">Jaremie Harris</a>가 <a href="https://towardsdatascience.com/the-4-fastest-ways-not-to-get-hired-as-a-data-scientist-565b42bd011e" target="_blank" rel="noopener">데이터 사이언티스트로 채용안되는 최고의 4가지 방법</a>에서 설명하기를,<br><br><br><br><i><br>이력서나 포트폴리오에서 개인 프로젝트란에 개념 설명용 데이터셋을 사용하여 진행한 프로젝트가 포함되어 있는것보다 떨어지기 쉬운 방법은 없다.</i><br><br><br><br>그에 해당하는 프로젝트가 어떤 것이 있는지 헷갈린다면.. 몇가지 소개해주겠다.<p></p><ul><li>Titanic Dataset</li><li>MNIST Dataset</li><li>iris Dataset</li><li>...</li></ul>어떤 프로젝트를 포함하면 안되는지 충분히 감이 왔을것이라 생각한다. 자신만의 프로젝트를 포함시키도록 하자!<h2 id="portfolios-are-iterative">포트폴리오는 재사용 가능하다</h2><a href="https://towardsdatascience.com/@faviovazquez" target="_blank" rel="noopener">Favio Vazquez</a>의 멋진 <a href="https://towardsdatascience.com/how-to-get-a-job-as-a-data-scientist-f417078fe13e" target="_blank" rel="noopener">포스팅</a>에서 어떻게 자신이 데이터 사이언티스트로 취업됐는지 설명했는데 그 중 좋은 팁을 소개하자면,<br><br><i>만약 당신이 진짜 데이터를 이용하는 데이터 사이언티스트로써 높은 연봉을 받고 싶다면 포트폴리오를 만드세요. 프로젝트들을 Github에 포스팅하고, Kaggle 시합만이 아닌 당신이 문제를 직접 정의하고 데이터 셋을 만들어서 해결한 경험이 있어야 합니다.</i><br><br>여기서 중요한 점은 취업을 계속 도전하면서 포트폴리오도 개선해나가야 한다는 점입니다.<br><br><i>난 125번 정도 이력서를 제출한 경험이 있다. 이 중에서 25-30 곳에서 답장이 왔지만, 그 중 일부는 거절 답장이었으며, 15 곳 정도에서만 면접을 제안받았다.<br><br>난 매순간 무엇인가를 배우며 개선해나갔다. 많은 시간을 공부와 프로그래밍에 투자하였고 많은 articles와 posts를 읽은 것이 취업하는 것에 큰 도움이 되었다.</i><br><br>당신은 여러번의 면접을 보게될 것인데 그때마다 배운점을 반드시 업데이트해야함을 명심하자. 이와같은 조언들은 다양한 포스팅에서 발견할 수 있는데, <a href="https://medium.com/@jasonkgoodman" target="_blank" rel="noopener">Jason Goodman</a>은<br><br><i>공개후에 계속해서 수정해도되니 두려워하지말고 미완성인 프로젝트도 꼭 공개하라.</i><br><br>라고 표현했다. <strong>특히 이 조언은 꼭 적용시키도록 하자!</strong>  Airbnb의 데이터 사이언티스트인 <a href="https://towardsdatascience.com/@kellypeng17" target="_blank" rel="noopener">Kelly Peng</a>같은 경우가 계속해서 개선하여 성공한 대표적인 사례다. 그녀의 <a href="https://towardsdatascience.com/how-to-land-a-data-scientist-job-at-your-dream-company-my-journey-to-airbnb-f6a1e99892e8" target="_blank" rel="noopener">포스팅</a>에서 어떤 과정을 겪었는지 아래처럼 밝혔다.<br><br><i>지원 : 475<br>전화 면접 : 50<br>완성한 사전 과제 : 9<br>현장 면접 : 8<br>최종 제안 : 2<br>총 사용한 시간 : 6개월</i><br><br>위에서 보다시피 그녀는 정말 끈질기게 도전을하였다. 고맙게도 그녀는 포스팅에서 어떤 방식으로 계속해서 도전했는지 알려줬는데 그 방법을 아래와 같다.<br><br><i>면접 때 받은 모든 질문을 꼭 기록하자. 특히, 대답을 하는 것에 실패한 것이면 더욱 더 중요하다. 당신은 또 떨어질수는 있지만, 같은 문제때문에 떨어져서는 안된다. 항상 배우고 개선하자!</i><br><br><div><img src="https://cdn-images-1.medium.com/max/1600/1*WwMBOf3sv2p6FaU4rsaA7g.png"><a href="https://towardsdatascience.com/how-to-build-a-data-science-portfolio-5f566517c79c" style="display: block; width:100%; text-align:center;" target="_blank" rel="noopener">출처 : How to build a data science portfolio</a></div><h2 id="incorporation-portfolio">포트폴리오를 1장짜리 이력서에 포함시키자</h2>포트폴리오를 알리는 방법은 당연히 이력서에 포함시키는 것이다. <strong>이력서</strong>는 특히 어떤 기술을 할 줄 아는지 적는 것에 집중하는 것이 좋고, 간결하게 당신이 왜 해당 직무에 맞는지를 설명하는 가장 좋은 회라고 볼 수 있다. 채용 매니저들은 아주 빠른 속도로 이력서를 훑기때문에 당신이 가진 시간은 실제로 아주 짧다는 것을 명심하고, 이력서를 개선하는 것이 면접으로 가는 최고의 지름길임을 기억하자.<br><br>Quora의 데이터 사이언티스트 매니저인 <a href="https://twitter.com/wzchen" target="_blank" rel="noopener">William Chen</a>은 <a href="https://www.youtube.com/watch?v=xrhPjE7wHas&feature=youtu.be&t=2m43s" target="_blank" rel="noopener">데이터 사이언티스트 이력서 만드는 9가지 팁</a> 영상에서 밝힌 9가지를 아래에 나열해봤다.<ul><li>1. <strong>길이 : </strong> 최대한 간결하게 1장으로 끝내자.<div><img src="https://cdn-images-1.medium.com/max/1600/1*WfOBVYnlXkWo3ErwSPEKDA.png"><a href="https://towardsdatascience.com/how-to-build-a-data-science-portfolio-5f566517c79c" style="display: block; width:100%; text-align:center;" target="_blank" rel="noopener">출처 : How to build a data science portfolio</a></div></li><li>2. <strong>Objective(목적) : </strong> 포함하지말자. 다들 비슷하게 적기때문에 여기서 차별화를 하긴 어렵다.</li><li>3. <strong>경험있는 지식분야 : </strong> Job description에서 요구하는 분야를 기입하는 것이 좋다(예: Machine Learning, Neural Networks and Language, NLP ...).</li><li>4. <strong>기술(Skills) : </strong> 스스로 점수를 부여하지는 말자. 만약 적고싶으면 proficient, familiar 등으로 묘사하자.</li><li>5. <strong>기술(Skills) : </strong> 역시 Job description에서 언급한 기술들을 적는 것이 좋고, 자신이 가장 잘하는 순서대로 적자.</li><li>6. <strong>프로젝트 : </strong> 숙제와 같은 프로젝트는 기입하지말고, 좀 더 차별화 가능한 프로젝트만을 기입할 것.</li><li>7. <strong>프로젝트 : </strong> 결과와 <strong>링크</strong>를 꼭 달아주자. 만약 Kaggle 시합을 나간거라면 상위 몇 퍼센트에 해당하는지 rank를 포함하는 것이 좋다.</li><li>8. <strong>포트폴리오 : </strong> 가장 기본은 LinkedIn 프로필이다. 이는 좀 더 넓은 범위를 포함한 이력서가 되어주기 때문이며, Github과 Kaggle 프로필도 도움이 된다.꼭 링크들을 포함시키고, Github의 경우에는 repo들의 설명도 간결하게 포함하자. medium이나 quora같은 블로그 링크도 포함하는 것이 좋다. 데이터 사이언스는 특히 데이터가 어떤의미를 가졌는지를 사람들에게 표현하는 것이므로 그런 요약이 잘되어있는 몇가지가 있으면 더 좋다.</li><li>9. <strong>경험 : </strong> 경험은 역시 이력서의 코어가 되는 부분이다. 하지만 만약 아직 일 경험이 없다면 어떡해야할까? 그럴 땐 개인 프로젝트에 집중하면 대체할 수 있으니 꼭 잘 표현하도록 하자. 개인 프로젝트라고하면, 개인적인 연구나 논문 혹은 Kaggle 시합이 있을 수 있다. 혹시라도 관계없는 경험을 이력서에 적는 것은 피하도록 하자.</li></ul><p></p><h2 id="importance-of-social-media">소셜미디어의 중요성</h2><br>이 부분은 포트폴리오와는 조금 독립적인 부분이지만, Github, Kaggle profile, Stack Overflow 등은 이력서에서 아주 좋은 역할을 할 수 있으니 소개하고자 한다.<br><br><br><br><a href="http://varianceexplained.org/r/start-blog/" target="_blank" rel="noopener">David Robinson</a>은<br><br><br><br><i><br>대체적으로 난 지원자들을 평가할 때, 그들이 공개해놓은 작업들을 보는 것을 좋아한다. 설사 그 작업들이 미완성이거나 깔끔하게 정리되어있지 않더라도 언제나 공유하는 것이 공유하지않는 것보다 좋은 것을 명심하자.</i><br><br><br><br>이라고 표현했으며, <a>Will Stanson</a>은 데이터 사이언티스트가 작업을 공개하는 것이 중요한 이유를 아래처럼 표현했다.<br><br><br><br><i><br>데이터 사이언티스트는 공개하는 것을 문제를 해결하는 하나의 방법으로 사용한다. 만약 당신이 그렇게 해낼 수 있다면, 아직 데이터 사이언티스트로 글자 그대로 일한 경험이 없다고 하더라도 이미 데이터 사이언티스트가 된 것을 의미한다.</i><br><br><br><br>대부분의 데이터 사이언스는 데이터를 공개하고 그것에 대해서 대화를 나누는 것이므로 이러한 온라인 프로필을 갖는 것은 매우 중요하다. 특히 아래와 같은 소셜미디어들은 당신의 경험을 공유할 수 있을 뿐아니라, 많은 사람들로 하여금 당신의 이력서에 도달하게 만든다는 점에서 놀라운 역할을 하고 있는 것이다.<p></p><p></p><h2>Github</h2><br>Github 프로필은 가장 영향력있는 도구이다. 사람들은 이력서에서 자신의 코드가 포함된 링크를 포함하게되는데 그때 Github을 사용한다. 또한, 사람들에게 어떤 작업을 하고있는지 READEME.md를 통해서 깔금하게 알릴 수 있다. 어떤 회사들에서는 채용 매니저들이 꼭 Github을 확인한다고하니 시간을 들여서 당신의 Github 프로필을 깔끔하게 유지하도록 하자!<br><br><br><br>특히 READEME.md는 간단한 소개를 하는 최고의 방법이니 꼭 사용하도록 하자. <strong>데이터 사이언스란 결국 결과를 소통하는 것</strong>이니 README.md는 당신의 많은 것을 보여주는 창구이다!<p></p><p></p><h2>Kaggle</h2><br>Kaggle 시합에 참여하고, Kernel을 만드는 등 다양한 토론에 참여하는 것은 데이터 사이언티스트로써의 자질을 증명하는 또 하나의 좋은 방법이다. Kaggle 시합에 대해서 <a href="https://twitter.com/reshamas" target="_blank" rel="noopener">Reshama Shaikh</a>는 <a href="https://reshamas.github.io/to-kaggle-or-not/" target="_blank" rel="noopener">To Kaggle or not</a>에서 Kaggle 시합의 가치를 아래처럼 표현했다.<br><br><br><i><br>Kaggle 시합을 하는 것이 그 사람을 데이터 사이언티스트라고 증명하는 것은 아니다. 물론 수업을 하나 들었다거나, 컨퍼런스를 참여하였거나, 하나의 데이터셋을 분석한 것, 관련 책 한권 읽은 것 역시 그 것을 증명하는 것은 결코 아니다.<br><br><br>하지만 시합을 참여한 것은 당신의 경험을 더해주고 당신의 포트폴리오에 힘을 실어주는 것은 사실이다. 비록 리트머스지 테스트처럼 데이터 사이언스 스킬셋을 증명하는 것은 아니지만 당신의 다른 프로젝트들을 보충해주는 역할을 할 수도 있다.</i><br><br><br><p></p><p></p><h2>LinkedIn</h2><br>한장으로만 설명해야하는 이력서와는 달리 LinkedIn은 항상 당신의 경험들을 깊이있게 설명할 수 있다. Udacity에는 심지어 <a href="https://career-resource-center.udacity.com/linkedin-github-profiles/how-to-stand-out-on-linkedin" target="_blank" rel="noopener">LinkedIn에 좋은 프로필 만들기</a>라는 수업까지 있을 정도다. 특히 관련 Keywords를 당신의 프로필에 포함시켜서 채용 매니저들로부터 Searchable하게 만드는 것이 중요하다. (해외에서 채용매니저들은 대부분 LinkedIn을 통해서 구인을 하므로 관련 포스팅들을 참고하는 것을 추천한다)<p></p><p></p><h2>Medium이나 블로그 플랫폼들</h2><br>다시한번 설명하지만 데이터 사이언스는 결국 데이터를 소개하고 소통하는 직업이므로 블로그 활동과 같은 소통방법을 사용한다면 역시 취업할 때 유리하다.<br><br><br><br>David Robinson은 블로그를 통해서 얻을 수 있는 혜택을 아래처럼 나열했다.<p></p><ul><li><strong>Data cleaning</strong></li><li><strong>Statistics</strong></li><li><strong>Machine Learning</strong></li><li><strong>Visualization</strong></li><li><strong>Communication</strong></li></ul><p></p><h2>Twitter</h2><br>트위터에서 활성화 유저라면 이 분야에서 일하는 다양한 사람들과 소통하기에 아주 좋으며, 당신의 블로그나 포트폴리오를 홍보할 수도 있다.<p></p><p></p><h2>Tableau Public</h2><br>물론 모든 데이터 사이언티스트들이 Tableau 등의 BI 툴들을 사용하는 것은 아니지만, 만약 이러한 툴들을 사용하는 회사에 지원을 하게된다면 아주 좋은 방법이 될 수 있다. 좋은 프로필 예로 <a href="https://public.tableau.com/profile/orysya.stus#!/" target="_blank" rel="noopener">Orysya Stus</a>와 <a href="https://public.tableau.com/profile/brit4337#!/" target="_blank" rel="noopener">Brit Cava</a>를 추천한다.<p></p><p></p><h2 id="conclusion">결론</h2><p></p><p><div><img src="https://cdn-images-1.medium.com/max/1600/1*wK9vKXEm6h1YVnpXBvaF4Q.png"><a href="https://towardsdatascience.com/how-to-build-a-data-science-portfolio-5f566517c79c" style="display: block; width:100%; text-align:center;" target="_blank" rel="noopener">출처 : How to build a data science portfolio</a></div><br>강력한 이력서는 지금까지 자신의 잠재적 고용인에게 자신을 소개하는 최고의 방법이었지만, 최근에는 자신이 가진 기술들을 다양한 방법으로 보여주는 것이 취업을 하는 것에 더 큰 효과를 보여주고 있다. 포트폴리오라는 공개적인 증명방법은 이전에 평범한 방법으로 자신을 알리던 것보다 훨씬 다양한 기회를 제공하게 된다.<br><br><br>특히 포트폴리오라는 것은 재사용가능하고 계속해서 개선할 수 있는 점을 꼭 강조하고 싶다. <strong>배우고 성장하는 것을 결코 멈추지 말자.</strong></p><hr><p>번역하면서 어색한 부분이나 정확히 전달되지 않은 부분들에 대해서는 꼭 원문을 통해서 확인하길 바란다. <br><br><br>특히, 소셜미디어 파트에서는 생략한 부분도 많으니, 원문을 통해서 부족한 부분을 확인하길 바라며, 이 글은 해외 취업을 하는 사람들뿐만 아니라 국내에서 취업을 희망하는 사람들에게도 참고하면 좋은 가이드라인들이 많으니 다들 좋은 포트폴리오를 통해서 자신을 어필하여 원하는 좋은 기업에 취업되길 기원한다.</p>]]></content>
    
    <!-- <summary type="html">
    
    </summary> -->
    
      <category term="Danial Nam" scheme="https://databuzz-team.github.io/categories/Danial-Nam/"/>
    
    
      <category term="Data Science" scheme="https://databuzz-team.github.io/tags/Data-Science/"/>
    
      <category term="Portfolio" scheme="https://databuzz-team.github.io/tags/Portfolio/"/>
    
      <category term="Resume" scheme="https://databuzz-team.github.io/tags/Resume/"/>
    
  </entry>
  
  <entry>
    <title>&lt;Machine Learning&gt;하이퍼파라미터 튜닝</title>
    <link href="https://databuzz-team.github.io/2018/12/05/hyperparameter-setting/"/>
    <id>https://databuzz-team.github.io/2018/12/05/hyperparameter-setting/</id>
    <published>2018-12-05T06:29:33.000Z</published>
    <updated>2018-12-23T04:00:52.537Z</updated>
    
    <content type="html"><![CDATA[<h3 id="1-모델-세부-튜닝"><a href="#1-모델-세부-튜닝" class="headerlink" title="1. 모델 세부 튜닝"></a>1. 모델 세부 튜닝</h3><p> 프로젝트 진행 시 EDA와 데이터 전처리를 하고 자신의 목적에 적합한 모델을 선택했다고 가정을 하면 그 이후에 진행되어야할 지루한 작업중에 하나가 바로 하이퍼파라미터 값들을 튜닝하는 것일 겁니다.<br> 수동으로 하나 하나 조정하며 모델을 돌려볼 수도 있지만 작업이 한번 끝날때마다 새로운 값으로 조정하는 것은 매우 귀찮은 일이고 시간적으로도 낭비가 많습니다. 이러한 문제점을 해결하기 위해 Scikit Learn에서 제공하는 기능을 활용해보겠습니다.</p><h3 id="2-하이퍼파라미터-튜닝-방법"><a href="#2-하이퍼파라미터-튜닝-방법" class="headerlink" title="2. 하이퍼파라미터 튜닝 방법"></a>2. 하이퍼파라미터 튜닝 방법</h3><h4 id="2-1-Grid-Search"><a href="#2-1-Grid-Search" class="headerlink" title="2.1 Grid Search"></a>2.1 Grid Search</h4><p>우선 Grid Search 방식은 모델에 적용하고 싶은 하이퍼 파라미터 값들을 직접 지정해서 param_grid에 설정해두면 그 값들의 조합을 적용해서 모델의 성능을 평가할 수 있습니다.</p><div><img src="/images/HyunGeun/hyperparameter_tunning/hyperparam_tuning_01.png"><span style="font-size:12px; text-align:center; display:block; color: #999;"> Grid Search</span></div><p>위의 코드는 예시를 들기 위해서 하이퍼마라미터와 모델등을 임의로 선택하였습니다. 첫번째 dictionary는 n_estimator는 [10, 20, 30], max_features값은 [2, 4], 두번째 dictionary는 다른 하이퍼 파라미터 값은 동일하고 bootstrap값을 [False]로 선택하였습니다. 교차 검증값은 2로 설정하였기 때문에 각 파라미터 조합을 2번씩 훈련하도록 코드를 작성하였습니다.</p><div><img src="/images/HyunGeun/hyperparameter_tunning/hyperparam_tuning_02.png"><span style="font-size:12px; text-align:center; display:block; color: #999;"> Grid Search result</span></div><p>이 결과를 보면 첫번째 dictionary는 제가 선택한 n_estimators값과 max_features값을 조합하여 2 X 3 = 6개를 두번씩 평가하여 12개 두번째 dictionary는 bootstrap값을 False로 설정하여 평가하여 총 24개를 평가하였음을 볼 수 있습니다. 저는 결과를 빠르게 보기위해 파라미터의 조합의 경우를 줄이고 교차 검증도 2번만 하였지만 실제 프로젝트를 진행하는 경우에는 좀 더 많은 실험을 할 것 입니다.</p><div><img src="/images/HyunGeun/hyperparameter_tunning/hyperparam_tuning_03.png"><span style="font-size:12px; text-align:center; display:block; color: #999;"> GridSearchCV hyperparameter</span></div><p>또한 GridSearchCV의 parameter값이 어떻게 설정되어 작동하였는지를 알 수 있습니다. 여기에서 refit이 True로 설정되어 있으면 교차 검증으로 최적의 추정기를 찾은 다음 전체 훈련 세트로 다시 훈련을 시킵니다. 데이터를 여러개로 나누어 학습을 시킨것보다 데이터의 양이 많아지므로 더 좋은 성능을 기대할 수 있습니다.</p><p>최적의 조합값이 무엇인지도 저장이 되어 있으므로 이렇게 그 값을 확인이 가능합니다.</p><div><img src="/images/HyunGeun/hyperparameter_tunning/hyperparam_tuning_04.png"><span style="font-size:12px; text-align:center; display:block; color: #999;"> Best Hyperparameter</span></div><p>최적의 추정기 또한 확인이 가능합니다.</p><div><img src="/images/HyunGeun/hyperparameter_tunning/hyperparam_tuning_05.png"><span style="font-size:12px; text-align:center; display:block; color: #999;"> Best Estimator</span></div><p>또한 아래와 같이 각각의 조합값의 평가 점수도 확인이 가능하기 때문에 자신에게 필요한 조합값을 선택할 수도 있습니다.</p><div><img src="/images/HyunGeun/hyperparameter_tunning/hyperparam_tuning_06.png"><span style="font-size:12px; text-align:center; display:block; color: #999;"> Cross validation score</span></div><p>Grid Search 방법은 편리하지만 대략적으로 최적의 hyperparameter의 조합을 알고 있거나 적은 수의 조합을 실험해볼때는 적합하지만 탐색공간이 넓은 경우에는 적합한 방법이 아닙니다. 그래서 이러한 경우에는 다음에서 이야기할 Random Search를 사용하면 더욱 효과적입니다.</p><h3 id="2-2-Random-Search"><a href="#2-2-Random-Search" class="headerlink" title="2.2 Random Search"></a>2.2 Random Search</h3><p>Random Search를 사용하는 방법은 Grid Search와 거의 동일합니다. 대신 하이퍼 파라미터 값을 우리가 직접 조합 가능한 값으로 정해주는 것이 아니라 범위를 지정하면 임의의 수를 선택하여 탐색합니다.</p><div><img src="/images/HyunGeun/hyperparameter_tunning/hyperparam_tuning_07.png"><span style="font-size:12px; text-align:center; display:block; color: #999;"> Random Search</span></div><p>위의 코드를 보면 Grid Search와 비슷한 방식으로 사용할 수 있습니다. n_iter값을 50으로 지정해 두었기때문에 임의로 50번씩 다양한 수를 선택하여 모델의 성능을 평가하고 cv는 2이기 때문에 총 100번의 탐색을 반복합니다. 최적의 조합과 추정기를 확인할 수 있는 것도 Grid Search와 동일합니다.</p><h2 id="3-결론"><a href="#3-결론" class="headerlink" title="3. 결론"></a>3. 결론</h2><p>위에서 설명한 두가지 방법외에도 Bayesian Optimization 방법도 존재합니다. 이는 추후에 내용을 추가하겠습니다.<br>Grid Search와 Random Search를 이용한다는 것만으로 최적의 하이퍼파라미터 값을 찾을 수 있다고 보장해주는 것은 아닙니다. 예를 들어 우리가 지정한 조합이나 범위안에 모델의 최적 하이퍼파라미터값이 없다면 시간을 낭비하는 것일 수도 있습니다. 또한 최종적으로 결정한 값들이 과연 최적의 값인지 의문을 가질 수도 있습니다. 이는 많은 경험과 도메인 지식, 요령이 필요한 부분입니다. 실제 많은 사람들이 이러한 고민을 하고 있고 다양한 방법을 제시하고 있습니다. 예를 들어 어떤 하이퍼파라미터 값을 지정해야 할지 모를 때는 연속된 10의 거듭제곱 수로 시도를 하는 경우도 있고 필요에 따라서는 더 작은 값을 지정하기도 합니다. 그렇지만 위의 두가지 방법을 잘 활용한다면 반복된 작업을 직접 수행하면서 낭비되는 시간을 줄일 수 있고 컴퓨팅 성능이 뒷받침을 해준다면 좀 더 효율적으로 하이퍼파라미터 튜닝을 하는데 도움이 될 것입니다. </p>]]></content>
    
    <!-- <summary type="html">
    
    </summary> -->
    
      <category term="HyunGeun Yoon" scheme="https://databuzz-team.github.io/categories/HyunGeun-Yoon/"/>
    
    
      <category term="Machine Learning" scheme="https://databuzz-team.github.io/tags/Machine-Learning/"/>
    
      <category term="Hyperparameter" scheme="https://databuzz-team.github.io/tags/Hyperparameter/"/>
    
  </entry>
  
  <entry>
    <title>&lt;Scikit Learn&gt;전처리를 위한 변환기 만들기</title>
    <link href="https://databuzz-team.github.io/2018/11/11/make_pipeline/"/>
    <id>https://databuzz-team.github.io/2018/11/11/make_pipeline/</id>
    <published>2018-11-11T02:42:06.000Z</published>
    <updated>2018-11-25T02:01:37.786Z</updated>
    
    <content type="html"><![CDATA[<h3 id="1-변환기의-필요성"><a href="#1-변환기의-필요성" class="headerlink" title="1. 변환기의 필요성"></a>1. 변환기의 필요성</h3><p>프로젝트를 진행하다보면 가장 많은 시간이 걸리고 노력이 필요한 부분이 데이터 전처리 과정일 것입니다. 처음 프로젝트를 할때는 경험이 부족해 필요할 때마다 데이터를 변환하다보니 테스트를 위해 분류해둔 테스트 데이터를 변환하기위해 같은 작업을 반복하느라 시간을 낭비하는 경우가 많았습니다.<br>만약 나만의 변환기를 만들어 둔다면 이러한 문제를 해결하는데 도움이 될 것입니다. 기본적으로 Scikit-Learn에서 제공하는 변환기가 많지만 우리가 필요한 모든 변환기가 구현되어 있진 않기때문에 필요에 따라 직접 원하는 변환기를 만들어야 할때가 있습니다.</p><p>이 포스트에서는 그 방법에 대해서 알아 보도록 하겠습니다.</p><p>우선 Scikit-Learn은 덕 타이핑<sup>duck typing</sup>을 지원하므로 fit(), transform(), fit_transform() 메서드를 구현한 파이썬 클래스를 만들면 됩니다. 여기에서 덕 타이핑이란 상속이나 인터페이스 구현이 아니라 객체의 속성이나 메서드가 객체의 유형을 결정하는 방식입니다. 마지막의 fit_transform()은 <a href="https://github.com/scikit-learn/scikit-learn/blob/bac89c253b35a8f1a3827389fbee0f5bebcbc985/sklearn/base.py#L435" target="_blank" rel="noopener">TransformerMixin</a>으로 구현이 되어 있고 이를 상속하면 자동으로 생성됩니다.<br>또한 <a href="https://github.com/scikit-learn/scikit-learn/blob/bac89c253b35a8f1a3827389fbee0f5bebcbc985/sklearn/base.py#L129" target="_blank" rel="noopener">BaseEstimator</a>를 상속하면 하이퍼파라미터 튜닝에 필요한 두 메서드 get_params()와 set_params()를 얻게 됩니다. 이때 생성자에 <code>*args</code>나 <code>**kargs</code>를 사용하지 않아야 합니다. 자세한 내용은 아래의 예시를 통해서 설명하겠습니다. 참고로 Scikit-Learn에 구현되어 있는 코드는 링크를 통해 확인해 볼 수 있습니다.</p><h3 id="2-예시"><a href="#2-예시" class="headerlink" title="2. 예시"></a>2. 예시</h3><p>예시 코드는 <a href="https://www.kaggle.com/" target="_blank" rel="noopener">Kaggle</a>에서 제공하는 <a href="https://www.kaggle.com/c/titanic" target="_blank" rel="noopener">Titanic</a>데이터를 활용하겠습니다. 이 글은 변환기를 만드는 방법에 대한 설명이라 전처리 방법은 간단한 방법으로 구현하여 올바른 방법이 아닐 수 있음을 말씁드립니다.</p><div><img src="/images/HyunGeun/make_pipeline/Titanic_Data.png"><span style="font-size:12px; text-align:center; display:block; color: #999;"> Titanic Data</span></div><p>위 그림에서 데이터를 살펴보면 age에 NaN값이 존재함을 알 수 있습니다. NaN값을 처리하는 다양한 방법이 있지만 여기에서는 간단하게 모든 age값의 평균으로 채워 넣겠습니다.</p><div><img src="/images/HyunGeun/make_pipeline/Age_Transformer.png"><span style="font-size:12px; text-align:center; display:block; color: #999;"> Age Transformer</span></div><p>위 코드와 같이 용도에 따라서 fit(), transform()을 만들어 주고 TransformerMix을 상속해주기만 하면 fit_transform()이 생성됩니다. 여러가지의 변환기를 연결시켜주는 Pipeline을 만들기 위해 name값을 first name만 표시하는 변환기를 만들어 보겠습니다.</p><div><img src="/images/HyunGeun/make_pipeline/Name_Transformer.png"><span style="font-size:12px; text-align:center; display:block; color: #999;"> Name Transformer</span></div><p>이제 두 변환기를 Pipeline으로 연결하겠습니다.</p><div><img src="/images/HyunGeun/make_pipeline/Pipeline.png"><span style="font-size:12px; text-align:center; display:block; color: #999;"> Pipeline</span></div><p>Pipeline으로 합쳐진 변환기의 결과를 보면 알 수 있듯이 위의 두 변환기를 각각 적용한 것을 하나의 pipeline으로 수행이 가능합니다. 이러한 방법으로 나만의 변환기를 만들어 사용할 수 있습니다.</p><h3 id="3-결론"><a href="#3-결론" class="headerlink" title="3. 결론"></a>3. 결론</h3><p>위의 예시로 보았듯이 크게 어렵지 않게 변환기를 만들수 있었습니다. 사이킷런의 FeatureUnion을 사용하면 여러개의 pipeline을 하나의 pipeline으로 합칠 수도 있습니다. 하지만 아직 사이킷런의 pipeline에는 Pandas의 DataFrame을 직접 주입할 수 없고 결과도 array로 반환되기 때문에 이를 염두에 두고 만들어야 합니다. 필요에 따라서는 필요한 특성만을 선택하는 변환기를 따로 만들어야 하는 경우도 있습니다. 처음에는 어려울 수도 있지만 간단한 것부터 만들면서 원리를 익혀간다면 필요한 변환기를 만들 수 있을 것입니다.   </p><p>※ 이 글의 내용은 <a href="http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&amp;mallGb=KOR&amp;barcode=9791162240731&amp;orderClick=LAG&amp;Kc=" target="_blank" rel="noopener">Hands-On Machine Learning with Scikit-learn &amp; TensorFlow</a> 를 참고하여 작성하였습니다.</p>]]></content>
    
    <!-- <summary type="html">
    
    </summary> -->
    
      <category term="HyunGeun Yoon" scheme="https://databuzz-team.github.io/categories/HyunGeun-Yoon/"/>
    
    
      <category term="Scikit Learn" scheme="https://databuzz-team.github.io/tags/Scikit-Learn/"/>
    
  </entry>
  
  <entry>
    <title>Try StackEdit</title>
    <link href="https://databuzz-team.github.io/2018/11/05/howto-stackedit/"/>
    <id>https://databuzz-team.github.io/2018/11/05/howto-stackedit/</id>
    <published>2018-11-05T08:00:00.000Z</published>
    <updated>2018-12-23T04:00:52.539Z</updated>
    
    <content type="html"><![CDATA[<h1 id="StackEdit-사용하기"><a href="#StackEdit-사용하기" class="headerlink" title="StackEdit 사용하기"></a>StackEdit 사용하기</h1><p>이 글은 StackEdit으로 작성되었다.</p><p><img src="https://lh3.googleusercontent.com/PbFld4k-vlnfAeV61KRigj_0BDLKuseBt63P83AjlrAZT4akqk0OJgPFbGXti850KeYHLK2Fq6E" alt="welcome file"></p><p><strong>StackEdit</strong>(<a href="https://stackedit.io/app#" target="_blank" rel="noopener">https://stackedit.io/</a>)은 브라우저에서 마크다운을 읽고, 쓰고, 저장하고, 깃헙으로 발행할 수 있는 오픈소스 웹 어플리케이션.  작성하는 모든 내용이 실시간으로 저장, 동기화된다. 이미지, 인용, 코드, 표, 등등을 작성할 수 있고 LaTeX로 수학식을 쓰거나 다이어그램도 그릴 수 있다.<br>로컬에 저장되기 때문에 오프라인으로도 사용 가능.</p><p><a href="https://github.com/benweet/stackedit/" target="_blank" rel="noopener">개발자 깃헙</a>에 따르면 다음과 같은걸 할 수 있다.</p><h3 id="StackEdit은"><a href="#StackEdit은" class="headerlink" title="StackEdit은:"></a>StackEdit은:</h3><ul><li>여러 마크다운 파일을 온라인/오프라인으로 관리</li><li>파일을 마크다운, HTML, PDF, Word, EPUB 등으로 내보내기</li><li>클라우드에 마크다운파일을 동기화</li><li>구글 드라이브, 드롭박스, 로컬에 저장된 마크다운을 편집</li><li>마크다운을 GitHub, Gist, 구글 드라이브, 드롭박스에 발행</li><li>구글 드라이브와 CouchDB로 워크 스페이스를 공유<br><br><h3 id="주요-기능"><a href="#주요-기능" class="headerlink" title="주요 기능:"></a>주요 기능:</h3></li><li>편집창과 미리보기가 스크롤바를 묶어주는 스크롤 싱크로 실시간 HTML 프리뷰</li><li>Markdown Extra/GitHub Flavored Markdown,  Prism.js syntax highlighting 지원</li><li>KaTeX를 이용한 LaTeX 수식 구현</li><li>Mermaid를 이용한 다이어그램과 플로우차트</li><li><a href="https://www.froala.com/wysiwyg-editor/examples/toolbar-buttons" target="_blank" rel="noopener">WYSIWYG 컨트롤버튼</a> (스크린 사이즈에 맞춰 커스텀화되는 툴바 버튼</li><li>스마트 레이아웃</li><li>원클릭 동기화: Blogger, Dropbox, Gist, GitHub, Google Drive, WordPress, Zendesk</li></ul><p><br><br><br>아래 설명은 StackEdit을 시작하면 기본적으로 저장되어있는 Welcome File을 참고해 간단한 기능 소개를 하려 한다. 자세한 원리가 알고 싶다면 Welcome File에 친절한 설명과 깃헙 링크가 나와있다.</p><h2 id="동기화"><a href="#동기화" class="headerlink" title="동기화"></a>동기화</h2><p><img src="https://lh3.googleusercontent.com/Xv370o9zVCiqA3CNqCq8HBoo6siDtFpa5fQkKu4Aro_rVFYrah9iOVKycXyE-Uj-3_KoV8-kFHc" alt="" title="MENU"></p><p>로컬 브라우저에 저장되지만 <strong>구글계정</strong>으로 로그인 하면 다른 브라우저에서도 동기화가 가능하다. 파일을 별도로 관리하고 싶으면 <strong>구글 드라이브</strong> , <strong>드롭박스</strong>, <strong>깃헙</strong> 등에 워크 스페이스를 만들어 저장할 수 있고 모든 수정사항이 실시간으로 동기화된다. 오른쪽의 StackEdit아이콘을 누르면 메뉴가 나온다. 한 계정 안에서 여러개의 워크 스페이스를 만들 수 있음.</p><p><img src="https://lh3.googleusercontent.com/lDtQxjzRy6zfFRCiohVy10GOE8-WR7EmyDbWZj0Xgh7yUODkP1rNaUUOw8fa_k8Vygdn5aytSkI" alt="" title="Workspace"></p><p>사실 계정 하나로 로그인해놓고 브라우저에서 노트하는 걸로만 써와서 워크스페이스는 거의 안 써봤다. <br><br>깃에 바로 퍼블리싱 할 수 있는 기능은 굉장히 유용하다. 레포 내에서의 경로 지정도 가능.</p><h2 id="툴바"><a href="#툴바" class="headerlink" title="툴바"></a>툴바</h2><p><img src="https://lh3.googleusercontent.com/6nb7yQ5zbZeVVYHlm-4DLlkd_LgY9dd74lUnXnp_QzDv-IVN-Am0bip8j6JgJKNsac5Cgzj0t9gA" alt="enter image description here"><br><br><br>기본적인 기능은 다 툴바에 아이콘으로 표시되어있다. 순서대로 <strong>굵게</strong>, <strong>기울이기</strong>, <strong>글자 크기</strong>,<strong>취소선</strong>, <strong>인용</strong>,<strong>표</strong>,<strong>하이퍼링크</strong>,<strong>이미지</strong>. 굳이 아이콘을 이용하지 않아도 <strong>메뉴</strong>의 <strong>마크다운 치트시트</strong>에 친절하게 안내되어 있으니 참고하자.</p><h3 id="이미지-첨부하기"><a href="#이미지-첨부하기" class="headerlink" title="+ 이미지 첨부하기"></a>+ 이미지 첨부하기</h3><p><img src="https://lh3.googleusercontent.com/q--du9ULEm3AkmfX3VJDVk9OAQWMWd8zbNUFWNMhtIxU7MXuY_vx8bVu_v1FqfkU5rZDBLrAlOJ3" alt="enter image description here"><br><br> <br><br>이미지는 링크로 가져와야하는데 구글포토와 연동하면 구글포토에 업로드한 사진을 가져올 수 있다. 로컬에 있는 이미지를 올리고 싶을 때 구글포토 백업을 사용하면 편리하다. 가끔 이미지 사이즈가 멋대로 조절된다는 단점이 있다.<br> <br> <br> <br></p><h2 id="편집화면-미리보기"><a href="#편집화면-미리보기" class="headerlink" title="편집화면, 미리보기"></a>편집화면, 미리보기</h2><p><img src="https://lh3.googleusercontent.com/Fzjdt8B2-EecweJvJGZHR_cGzbGqSeM5inju_pJdMSnFqn4l9CxQfDnDt7y_q4NTtJvKb9Qjb2A-" alt="" title="control"></p><p><br>편집창 왼쪽에 보이는 아이콘 세 개다. 위에서부터 차례대로 <strong>툴바 접기/펴기</strong>, <strong>미리보기 열기 접기</strong>, <strong>미리보기</strong>.  </p><h3 id="1-미리보기"><a href="#1-미리보기" class="headerlink" title="1. 미리보기"></a>1. 미리보기</h3><p>편집한 내용을 미리보기 할 수 있다. 이 기능을 이용하면 StackEdit 내부의 기능을 사용하면서 프리젠테이션 용도로도 사용할 수 있을 듯.</p><p><img src="https://lh3.googleusercontent.com/0usMVJbbi4HpRL93oMhmq63j-IeS-Oe3rkglDLvDmBqUcff1DRX2IfcGbLUA2j8tqToCi-ur9kg" alt="" title="view only"></p><p><br></p><h3 id="2-미리보기-열기-접기"><a href="#2-미리보기-열기-접기" class="headerlink" title="2. 미리보기 열기 접기"></a>2. 미리보기 열기 접기</h3><p>미리보기를 열어서 편집과 미리보기 화면을 보면서 동시에 편집할 수 있다. 이미지를 띄우면 미리보기 창과 스크롤의 차이가 생긴다. <br><br><img src="https://lh3.googleusercontent.com/sb6GyTTWVV8kWDNt-Ni4nB9e_Co3SptQy0grevgGEXXk_bsfOIO5B1V8LWb7-0Z1M8cjbRC3JM8" alt="" title="twosides"></p><p><br><br><br><br>접으면 아래처럼 편집창만 보인다.<br></p><p><img src="https://lh3.googleusercontent.com/ORBPJTp_gxf7gA5WiXL2uzANpXLBhn3nCU5gh5P8wSBck17O9gOwjLOQFtLY24Dlqoe-038TqGQ" alt="" title="editonly"></p><h2 id="마크다운-확장기능"><a href="#마크다운-확장기능" class="headerlink" title="마크다운 확장기능"></a>마크다운 확장기능</h2><h2 id="SmartyPants"><a href="#SmartyPants" class="headerlink" title="SmartyPants"></a>SmartyPants</h2><p>표, 인용, 대쉬. 가장 유용하다.<br><br><br></p><div class="table-container"><table><thead><tr><th></th><th>ASCII</th><th>HTML</th></tr></thead><tbody><tr><td>Single backticks</td><td><code>&#39;Isn&#39;t this fun?&#39;</code></td><td>‘Isn’t this fun?’</td></tr><tr><td>Quotes</td><td><code>&quot;Isn&#39;t this fun?&quot;</code></td><td>“Isn’t this fun?”</td></tr><tr><td>Dashes</td><td><code>-- is en-dash, --- is em-dash</code></td><td>— is en-dash, —- is em-dash</td></tr></tbody></table></div><h2 id="KaTeX"><a href="#KaTeX" class="headerlink" title="KaTeX"></a>KaTeX</h2><p>KaTeX를 이용해 LaTeX의 수학식을 표시할 수 있다. 자세한건 Welcome File와 <a href="https://katex.org/" target="_blank" rel="noopener">KaTeX</a> 참조. 현재 블로그에서는 구현되지 않아서 이미지로 대체한다.</p><p>예:</p><p><img src="https://lh3.googleusercontent.com/B-hZCzfY5RXT5VpTh1S5EprLEhDARx32Lfqpgh5VUXXg3u8uuI7HCyAMq6gGbtjlorEdW7jLCggV=s10000" alt=""><br>코드:</p><p>The <em>Gamma function</em> satisfying $\Gamma(n) = (n-1)!\quad\forall n\in\mathbb N$ is via the Euler integral</p><script type="math/tex; mode=display">\Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,.</script><h2 id="UML-다이어그램"><a href="#UML-다이어그램" class="headerlink" title="UML 다이어그램"></a>UML 다이어그램</h2><p>아래처럼 모델링을 위한 다이어그램을 그릴 수 있다. <br><br><img src="https://lh3.googleusercontent.com/2XhLOPDrgFGbxBNmtQ7pEJubtEs0UAV50PrAYDyColKnvFwKb0ww8f95r7RwaSzB-CTR4xRSQSj5" alt="enter image description here"></p><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">sequenceDiagram</span><br><span class="line">Alice -&gt;&gt; Bob: Hello Bob, how are you?</span><br><span class="line">Bob--&gt;&gt;John: How about you John?</span><br><span class="line">Bob--x Alice: I am good thanks!</span><br><span class="line">Bob-x John: I am good thanks!</span><br><span class="line">Note right of John: Bob thinks a long&lt;br/&gt;long time, so long&lt;br/&gt;that the text does&lt;br/&gt;not fit on a row.</span><br><span class="line"></span><br><span class="line">Bob--&gt;Alice: Checking with John...</span><br><span class="line">Alice-&gt;John: Yes... John, how are you?</span><br></pre></td></tr></table></figure><p><br><br><br>플로우 차트는 아래처럼 그려진다.<br><img src="https://lh3.googleusercontent.com/noBNIQAm987yT5gHTSP52BUGgD1ZcaZkEMspO1mMLbLr-JkGO_ADmIDgqUOe2k9ed9T9NEsarF4S" alt="enter image description here"></p><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></pre></td><td class="code"><pre><span class="line">graph LR</span><br><span class="line">A[Square Rect] -- Link text --&gt; B((Circle))</span><br><span class="line">A --&gt; C(Round Rect)</span><br><span class="line">B --&gt; D&#123;Rhombus&#125;</span><br><span class="line">C --&gt; D</span><br></pre></td></tr></table></figure><p>[  ] 사각형<br>((  )) 원형<br>(   ) 모서리가 둥근 사각형<br>{   } 마름모</p><p>#<br>별도의 설치 없이 로컬 브라우저에서 편집할 수 있는 훌륭한 툴을 이용하는데에 도움이 되었길 바란다. 유용했다면 오픈소스에게 귀중한 5달러를 기부해도 좋을 듯. <br> <br> <br> <img src="https://lh3.googleusercontent.com/HjZDx-jC6U4n5_QOBp6fxxwt5IfjJ3NrNEgk4SwPmMXWb20YImZf1lll3MoNeALzEm2wLt9EaI3C" alt="" title="donate please"></p>]]></content>
    
    <!-- <summary type="html">
    
    </summary> -->
    
      <category term="SoHyun Bae" scheme="https://databuzz-team.github.io/categories/SoHyun-Bae/"/>
    
    
      <category term="Markdown" scheme="https://databuzz-team.github.io/tags/Markdown/"/>
    
  </entry>
  
  <entry>
    <title>&lt;Neural Network&gt; 인공신경망에 대한 이해(Part 1 - Feedforward Propagation)</title>
    <link href="https://databuzz-team.github.io/2018/11/05/Back-Propagation/"/>
    <id>https://databuzz-team.github.io/2018/11/05/Back-Propagation/</id>
    <published>2018-11-05T05:16:52.000Z</published>
    <updated>2020-10-09T10:11:10.820Z</updated>
    
    <content type="html"><![CDATA[<p><br></p><p>이번 포스트(Part 1)에서는 TensorFlow로 DNN을 구현하기 전에 먼저 기본 개념을 알아보고 다음 포스트(Part 2)에서는 인공 신경망을 가능하게 한 <strong>Back Propagation</strong> 에 대해 알아보도록 하겠다.(모바일에는 최적화되어있지 않으니 가능하면 PC로 보시길 추천한다)</p><div style="display: none;"><img src="/images/danial/back-prop/thumbnail.png"></div><h3 id="목차"><a href="#목차" class="headerlink" title="목차"></a>목차</h3><ul><li><a href="#nn-history">Neural Network 역사</a></li><li><a href="#feedforward-propagation">Feedforward Propagation 설명</a><ul><li><a href="#init-network">네트워크 초기화</a></li><li><a href="#layer1">Layer 1 (input -&gt; J)</a></li><li><a href="#layer2">Layer 2 (J -&gt; K)</a></li><li><a href="#layer3">Layer 3 (K -&gt; output)</a></li><li><a href="#conclusion">정리</a></li></ul></li><li><a href="#cost-function">오차 함수(Cost function)</a></li><li><a href="#optimization">가중치 최적화</a></li></ul><h3 id="nn-history" href="#nn-history">Neural Network 역사</h3><p> 1943년, 워런 맥컬록(Warren McCulloch)와 월터 피츠(Walter Pitts)의 수학과 임계 논리(Threshold logic)라 불리는 알고리즘을 바탕으로 <strong>Neural Network</strong> 역사가 시작되었다.</p><p> 하지만, 1969년에 마빈 민스키(Marvin Minsky)와 시모어 페퍼트(Seymour Papert)에 의해 기계학습 논문이 발표된 후 침체되었는데, 그 이유는 두 가지였다.</p><ol><li><p><strong>단층 신경망</strong> 은 선형으로 분류하기 때문에 아래의 그림처럼 문제가 배타적 논리합 회로(XOR problem)인 경우에는 해결하지 못한다.</p><div><img style="width: 50%;" src="https://cdn-images-1.medium.com/max/2000/0*qdRb80zUpJPtrbRD."><a style="display: block; text-align: center;" href="https://medium.com/@jayeshbahire/the-xor-problem-in-neural-networks-50006411840b" target="_blank" rel="noopener">출처 : [Medium] Back-Propagation is very simple. Who made it Complicated ?</a></div></li><li><p>Computing power가 부족하다.</p></li></ol><p>위의 두 가지 문제점 외에도 가중치를 업데이트하기 위한 회로 수학 계산이 너무 복잡하였기에 <strong>오차역전파법(Back Propagation)</strong> 이 세상에 나오기 전까지는 연구가 침체될 수밖에 없었다.</p><h3 id="feedforward-propagation" href="#feedforward-propagation">Feedforward Propagation 설명</h3><h4 style="color: #cb4a44;" id="init-network" href="#init-network">네트워크 초기화</h4><img src="/images/danial/back-prop/network.png">$$Input = \left[ \begin{array}{cccc}i_{1} & i_{2} \\\end{array} \right]$$$$W_{ij} = \left[ \begin{array}{cccc}W_{i1j1} & W_{i1j2} & W_{i1j3} \\W_{i2j1} & W_{i2j2} & W_{i2j3} \\\end{array} \right]W_{jk} = \left[ \begin{array}{cccc}W_{j1k1} & W_{j1k2} & W_{j1k3} \\W_{j2k1} & W_{j2k2} & W_{j2k3} \\W_{j3k1} & W_{j3k2} & W_{j3k3} \\ \end{array} \right]W_{ko} = \left[ \begin{array}{cccc}W_{k1o1} & W_{k1o2} \\W_{k2o1} & W_{k2o2} \\W_{k3o1} & W_{k3o2} \\ \end{array} \right]$$$$Output = \left[ \begin{array}{cccc}o_{1} & o_{2} \\\end{array} \right]$$<p>이 포스트에서는 간단한 계산을 위해 Hidden layer가 2층 구조인 모형으로 초기화를 하였지만, 실제로는 layer마다 Neuron 개수나 Hidden layer의 층수는 우리가 알아내야 할 하이퍼 파라미터이다.</p><p><strong>인공 신경망</strong> 알고리즘에는 여느 예측 문제와 마찬가지로 Feature에 해당하는 Input이 존재하고, 들어온 데이터들이 Hidden layer의 Neuron이 가진 <strong>하이퍼 파라미터에 의해 모양이 바뀌는 비선형 기저 함수</strong></p><blockquote><strong>기저 함수</strong> 는 위에서 설명한 배타적 논리합 회로(XOR problem)를 해결하기 위한 방법으로, Input데이터 x대신 &phi;(x)를 사용하는 것을 의미한다.여기서 "<strong>하이퍼 파라미터에 의해 모양이 바뀌는</strong>"라는 수식어가 붙은 이유는 Hidden layer로 이동할 때 계산되는 <strong>행렬(Matrix)</strong> 과 <strong>Bias</strong> 에 의해서 계속해서 모양을 바뀌는 것을 의미한다. 가장 기본적인 <strong>Activation 함수</strong> 인 Logistic Sigmoid를 예로 보자면,$$Sigmoid = 1/(1+\mathrm{e}^{-(w_{ji}x + b_{j})})$$형태의 기저함수를 가지게 되는 것.</blockquote><p>에 의해서 비선형 문제를 해결할 수 있는 형태로 정보의 차원을 변경하며 전파하는 과정을 거친다. 마지막에는 Output으로 분류인 경우에는 Class 개수만큼, 회귀분석인 경우에는 1개의 실수값을 내보내는 것으로 마무리 된다.</p><p><strong>역방향 전파(Back Propagation)</strong> 을 이해하기 위해서는 먼저 인공신경망의 계산 과정인 <strong>순방향 전파(Feedforward propagation)</strong> 를 이해해야 하므로 살펴보도록 하자.</p><hr><h4 id="layer1" href="#layer1" style="color: #cb4a44; ">Layer 1 (Input -> J)</h4><div style="float:left; width:40%; margin-right: 10px;">  <img src="/images/danial/back-prop/layer_j.png"></div><div style="">$$\definecolor{first}{RGB}{10, 199, 139}\definecolor{second}{RGB}{74, 144, 226}\left[ \begin{array}{cccc}i_{1} & i_{2} \\\end{array} \right] \times\left[ \begin{array}{cccc}\textcolor{first}{W_{i1j1}} & \textcolor{first}{W_{i1j2}} & \textcolor{first}{W_{i1j3}} \\\textcolor{second}{W_{i2j1}} &\textcolor{second}{W_{i2j2}} &\textcolor{second}{W_{i2j3}} \\\end{array} \right] +\left[ \begin{array}{cccc}b_{j1} & b_{j2} & b_{j3} \\\end{array} \right]$$$$\downarrow$$$$\definecolor{first}{RGB}{10, 199, 139}\definecolor{second}{RGB}{74, 144, 226}\left[ \begin{array}{cccc}\textcolor{first}{W_{i1j1}} \times i_{1} +\textcolor{second}{W_{i2j1}} \times i_{2} + b_{j1} \\\textcolor{first}{W_{i1j2}} \times i_{1} +\textcolor{second}{W_{i2j2}} \times i_{2} +b_{j2} \\\textcolor{first}{W_{i1j3}} \times i_{1} +\textcolor{second}{W_{i2j3}} \times i_{2} +b_{j3} \\\end{array} \right]^{T} =\left[ \begin{array}{cccc}J_{in1} \\ J_{in2} \\ J_{in3} \\\end{array} \right]^{T}$$<p style="">  계산은 어려운게 없으니 따로 설명하지 않겠다. 중요한 점은 Hidden layer는 들어온 값(<strong>J<sub>in</sub></strong>)과 나가는 값(<strong>J<sub>out</sub></strong>)이 다르다는 것이다. 그 과정은 아래에서 살펴보자.</p></div><div class="clearfix" style="clear:both"><div style="float:left; width:40%; margin-right:10px;">  <img src="/images/danial/back-prop/activation_j.png"></div><div style=""><p style=""><strong>Hidden layer</strong>의 <strong>Neuron</strong>은 앞서 설명했듯 <strong>기저함수</strong>의 역할을 해야하므로 좌측의 그림처럼 <strong>J<sub>in</sub></strong>이 Activation function에 의해 변한 <strong>J<sub>out</sub></strong>을 다음 레이어에 들어가는 Input이 되게 한다.이 포스팅의 예제에서 <strong>활성화 함수(Activation function)</strong> 은 모두 <strong>Logistic Sigmoid</strong> 함수를 사용하기로 한다.</p>$$Sigmoid = 1/(1+\mathrm{e}^{-x})$$$$Sigmoid(J_{in}) =\left[ \begin{array}{cccc}1/(1+\mathrm{e}^{-J_{in1}}) \\1/(1+\mathrm{e}^{-J_{in2}}) \\1/(1+\mathrm{e}^{-J_{in3}}) \\\end{array} \right]^{T}= \left[ \begin{array}{cccc}J_{out1} \\ J_{out2} \\ J_{out3} \\\end{array} \right]^{T}$$<p style="">이제는 위에서 설명한 <strong>하이퍼 파라미터에 의해 모양이 바뀌는</strong>이라는 표현이 이해가 더 잘 될 것이다. <strong>J<sub>in</sub></strong>은 w<sub>ij</sub>와 b<sub>j</sub>에 의해 바뀌고 그에 의해 <strong>J<sub>out</sub></strong>이 바뀔 것이므로.</p></div></div><hr><div class="clearfix"><h4 id="layer2" href="#layer2" style="color: #cb4a44; clear:both; margin-top: 10px;">Layer 2 (J -> K)</h4><div style="float:left; width:40%; margin-right: 10px;">  <img src="/images/danial/back-prop/j_k_layer.png"></div><div style="">$$\definecolor{first}{RGB}{10, 233, 134}\definecolor{second}{RGB}{74, 144, 226}\definecolor{third}{RGB}{245, 166, 35}\left[ \begin{array}{cccc}J_{out1} & J_{out2} & J_{out3}\\\end{array} \right] \times\left[ \begin{array}{cccc}\textcolor{first}{W_{j1k1}} & \textcolor{first}{W_{j1k2}} & \textcolor{first}{W_{j1k3}} \\\textcolor{second}{W_{j2k1}} & \textcolor{second}{W_{j2k2}} & \textcolor{second}{W_{j2k3}} \\\textcolor{third}{W_{j3k1}} & \textcolor{third}{W_{j3k2}} & \textcolor{third}{W_{j3k3}} \\ \end{array} \right] +\left[ \begin{array}{cccc}b_{k1} & b_{k2} & b_{k3} \\\end{array} \right]$$$$\downarrow$$$$\definecolor{first}{RGB}{10, 233, 134}\definecolor{second}{RGB}{74, 144, 226}\definecolor{third}{RGB}{245, 166, 35}\left[ \begin{array}{cccc}\textcolor{first}{W_{j1k1}} \times J_{out1} +\textcolor{second}{W_{j2k1}} \times J_{out2} +\textcolor{third}{W_{j3k1}} \times J_{out3} + b_{k1}\\\textcolor{first}{W_{j1k2}} \times J_{out1} +\textcolor{second}{W_{j2k2}} \times J_{out2} +\textcolor{third}{W_{j3k2}} \times J_{out3} + b_{k2}\\\textcolor{first}{W_{j1k3}} \times J_{out1} +\textcolor{second}{W_{j2k3}} \times J_{out2} +\textcolor{third}{W_{j3k3}} \times J_{out3} + b_{k3}\\\end{array} \right]^{T} = \left[ \begin{array}{cccc}K_{in1} \\ K_{in2} \\ K_{in3} \\\end{array} \right]^{T}$$<p style="">  <strong>K<sub>in</sub></strong>과 <strong>K<sub>out</sub></strong> 사이의 Activation function은 Layer 1에서와 마찬가지로 Logistic Sigmoid를 사용한다.</p>$$Sigmoid(K_{in}) =\left[ \begin{array}{cccc}1/(1+\mathrm{e}^{-K_{in1}}) \\1/(1+\mathrm{e}^{-K_{in2}}) \\1/(1+\mathrm{e}^{-K_{in3}}) \\\end{array} \right]^{T}= \left[ \begin{array}{cccc}K_{out1} \\ K_{out2} \\ K_{out3} \\\end{array} \right]^{T}$$<p style="">  Layer 1과 비교해서 새로운 점이 없으므로 그림상에 Notation은 자세하게 하지 않았다.</p></div></div><hr><p></p><h4 id="layer3" href="#layer3" style="color: #cb4a44; clear:both; margin-top: 10px;">Layer 3 (K -&gt; output)</h4><p></p><div style="float:left; width:40%; margin-right: 10px;">  <img src="/images/danial/back-prop/k_o_layer.png"></div><div style="">$$\definecolor{first}{RGB}{245, 166, 35}\definecolor{second}{RGB}{74, 144, 226}\definecolor{third}{RGB}{189, 16, 224}\left[ \begin{array}{cccc}K_{out1} & K_{out2} & K_{out3}\\\end{array} \right] \times\left[ \begin{array}{cccc}\textcolor{first}{W_{k1o1}} & \textcolor{first}{W_{k1o2}} \\\textcolor{second}{W_{k2o1}} & \textcolor{second}{W_{k2o2}} \\\textcolor{third}{W_{k3o1}} & \textcolor{third}{W_{k3o2}} \\ \end{array} \right] +\left[ \begin{array}{cccc}b_{o1} & b_{o2} \\\end{array} \right]$$$$\downarrow$$$$\definecolor{first}{RGB}{245, 166, 35}\definecolor{second}{RGB}{74, 144, 226}\definecolor{third}{RGB}{189, 16, 224}\left[ \begin{array}{cccc}\textcolor{first}{W_{k1o1}} \times K_{out1} +\textcolor{second}{W_{k2o1}} \times K_{out2} +\textcolor{third}{W_{k3o1}} \times K_{out3} + b_{o1}\\\textcolor{first}{W_{k1o2}} \times K_{out1} +\textcolor{second}{W_{k2o2}} \times K_{out2} +\textcolor{third}{W_{k3o2}} \times K_{out3} + b_{o2}\\\end{array} \right]^{T} =\left[ \begin{array}{cccc}o_{in1} \\ o_{in2}\\\end{array} \right]^{T}$$<p style="">  Output으로 나가는 값(o<sub>out</sub>)은 우리가 예측하고자하는 Target 값을 가장 잘 보여줄 수 있는 형태로 만들어야한다.</p><p style="">  일반적으로는 <strong>회귀분석</strong>에는 특별한 <strong>활성화 함수 없이</strong> 내보내는 경우가 있지만, 만약 Target 데이터가 0보다 크고 1보다 작은 실수값만을 가진 상황이라면 Logistic Sigmoid을 사용했을 때 더 좋은 결과가 나올수도 있다는 의미다.</p><p style="">  이 포스트에서는 분류 문제라고 가정하여 활성화 함수로는 <strong>Softmax</strong>를 이용하여 확률값처럼 변환시키는 것을 예로 들겠다.</p></div><div class="clearfix" style="clear:both"><div style="float:left; width:40%; margin-right: 10px;">  <img src="/images/danial/back-prop/softmax_o.png"></div><div style="">$$Softmax = \mathrm{e}^{o_{ina}}/(\sum_{a=1}^{2}\mathrm{e}^{o_{ina}})$$$$Softmax(o_{in}) =\left[ \begin{array}{cccc}\mathrm{e}^{o_{in1}}/(\sum_{a=1}^{2}\mathrm{e}^{o_{ina}})   \\ \mathrm{e}^{o_{in2}}/(\sum_{a=1}^{2}\mathrm{e}^{o_{ina}})   \\\end{array} \right]^{T} = \left[ \begin{array}{cccc}o_{out1} \\ o_{out2}\\\end{array} \right]^{T}$$<p style="">이렇게 Output으로 나온 o<sub>out</sub> 벡터가 우리의 예측값 y_pred이다.물론 Random하게 초기화된 W, b값에 의해 예측한 값이라고 하기엔 터무니없는 값들이 나올 것임을 명심하자.</p></div></div><hr><h3 id="conclusion" href="#conclusion" style="color: #cb4a44; clear:both; margin-top: 10px;">정리</h3><img src="/images/danial/back-prop/network_detail.png"><p>여기까지 계산 과정은 자세히 알아보았다. 현실 데이터들을 사용하게 되면 저것보다 Layer 개수나 각 Layer의 Neuron 개수는 차이가 나겠지만, 행렬 곱이란 점에서 식을 쓰는 법은 사실상 차이가 없을 것이다.<br><br>Neural network에 대해서 다시 생각해보자면 실제 인간 뇌의 <strong>"Neuron들이 input이 들어오면 <strong>어떤 임계값(Threshold)</strong>이상의 전기신호가 존재해야 전달하는 것"</strong>에서 아이디어를 얻은 것이므로, <br> 위의 그림에서 J, K layer는 그런 Threshold가 넘는지를 <strong>활성화 함수(Activation function)</strong>을 통과시키며 해당 Neuron을 활성화할지 비활성화할지를 결정하는 과정인 것이다.<br><br>이제 고민해보자. input과 output은 우리가 측정한 실재하는 값이므로 변하지 않는 상수이지만, Hidden layer 내에서는 한 층을 통과할 때마다 새로운 값을 배출하고, 그 값을 다시 다음 층에서 받아서 또 통과시키면서 최초 input이 어떤 패턴을 가졌는지를 확인하는 과정이라고 볼 수 있지 않을까?<br><br>물론 패턴이라는 것은 해당 layer에서 <strong>활성화(우린 Sigmoid를 사용했으니, 0.5 이상인 경우를 활성화된 상태라고 하자)</strong>시킨 뉴런이 어떻게 분포해있는가를 말하는 것이고, 그 패턴을 해석한 파워는 input -> layer까지 오는 길에 계산한 W, b에서 나오는 것이므로, 이 값들을 우리는 더 <strong>정확한 패턴 해석</strong>을 위해서 학습하게 되는 것이다.<br><br>W, b가 우리의 학습하려는 값이라고 설명하면 끝나는 것을 길게 얘기했는데, 사실 필자도 이것이 어떻게 도움이 될지는 정확히 모르겠다. 하지만, 어떤 수학 문제가 있을 때 가장 쉽게 푸는 법을 알아내는 사람이 더 뛰어난 것이듯이,<br><br>분류 혹은 예측 성공률이 매우 높으면서도, 가장 적은 컴퓨팅 파워, 즉 해당 문제를 풀기 위한 가장 최적의 Layer 개수와 Neuron 개수가 존재할 수 있다는 것을 위의 해석 방식에서는 나타내고 있다는 점에서 의미가 있다고 본다.<br><br><blockquote>이 분야를 공부하는 사람이라면 3Blue1Brown이라는 유튜버를 알고 있을 텐데, 그가 <a href="https://www.youtube.com/watch?v=aircAruvnKk" target="_blank" rel="noopener">신경망이란 무엇인가? | 1장.딥러닝에 관하여</a>에서 설명한 것에서 영감을 얻어 말로 풀어 설명한 것이니 영상을 보며 정리하면 더 도움이 될 것.</blockquote></p><hr><h3 id="cost-function" href="#cost-function" style="clear:both; margin-top: 10px;">오차 함수(Cost function)</h3><p>로지스틱 활성 함수를 이용한 분류 문제를 풀 때는 정답 y가 클래스 k에 속하는 데이터에 대해서 k번째 값만 1이고 나머지는 0인 one-hot-encoding 벡터를 사용한다.</p><p>Cost-function은 Cross-Entropy Error를 사용한다.</p><script type="math/tex; mode=display">cross entropy = - (1/n)(\sum_{i=1}^{3} (y_{i} \times \log(o_{outi})) + ((1-y_{i}) \times \log((1-o_{outi}))))</script><h3 id="optimization" href="#optimization" style="clear:both; margin-top: 10px;">가중치 최적화</h3><p>오차함수를 최소화하기 위해 아래처럼 미분(gradient)을 사용한 <strong>Steepest gradient descent</strong> 방법을 적용하자. 여기서 &mu;는 step size 혹은 learning rate라고 부른다.</p><script type="math/tex; mode=display">w_{k+1} = w_{k} - \mu \frac{\partial C}{\partial w}</script><script type="math/tex; mode=display">b_{k+1} = b_{k} - \mu \frac{\partial C}{\partial b}</script><p>문제점은 단순하게 수치적으로 미분을 계산하게되면 모든 가중치에 대해서 개별적으로 미분을 계산해야하는 문제가 있다. 하지만 <strong>역전파 (Back propagation)</strong> 을 사용하면 모든 가중치에 대한 미분값을 한번에 계산할 수 있다.</p><p>다음 포스트에서 자세하게 알아보도록 하자!</p><blockquote><p>이번 <strong><neural network=""> 인공신경망에 대한 이해</neural></strong> 포스팅들은 시간을 많이 들여서 가능한 쉽고 직관적으로 설명하기 위해 노력하였다. 만약 도움이 되었다면! 공유를 부탁드린다!</p></blockquote><h3 style="clear:both; margin-top: 20px;"> Related Posts</h3><p><a href="https://www.youtube.com/watch?v=tIeHLnjs5U8&amp;fbclid=IwAR2lsWOByt_MrzBkv5-Dc9P6JIdvHv1pUELE5q-0SVqQ73b6tS-RYGUI9eM" target="_blank" rel="noopener">Backpropagation calculus | Deep learning, chapter 4 by 3Blue1Brown</a><br><a href="https://datascienceschool.net/view-notebook/0178802a219c4e6bb9b820b49bf57f91/" target="_blank" rel="noopener">신경망 기초 이론</a></p>]]></content>
    
    <!-- <summary type="html">
    
    </summary> -->
    
      <category term="Danial Nam" scheme="https://databuzz-team.github.io/categories/Danial-Nam/"/>
    
    
      <category term="Artificial Intelligence" scheme="https://databuzz-team.github.io/tags/Artificial-Intelligence/"/>
    
      <category term="Deep Learning" scheme="https://databuzz-team.github.io/tags/Deep-Learning/"/>
    
      <category term="Neural Network" scheme="https://databuzz-team.github.io/tags/Neural-Network/"/>
    
  </entry>
  
  <entry>
    <title>&lt;Deep Learning&gt; An introduction to Deep Learning with Tensorflow(Part-3)</title>
    <link href="https://databuzz-team.github.io/2018/10/30/Basic-deep-learning-tensorflow-for-beginner-3/"/>
    <id>https://databuzz-team.github.io/2018/10/30/Basic-deep-learning-tensorflow-for-beginner-3/</id>
    <published>2018-10-30T05:30:36.000Z</published>
    <updated>2020-10-09T10:11:05.276Z</updated>
    
    <content type="html"><![CDATA[<h3>About</h3><p>이번 포스트에서는 간단하게 <strong>회귀분석(Linear Regression)</strong> 의 개념과 <strong>Tensorflow</strong> 를 이용하여 학습하는 법에 대해서 알아보자.</p><h4 id="목차"><a href="#목차" class="headerlink" title="목차"></a>목차</h4><ul><li><a href="#linear-regression">회귀분석(Regression Analysis)이란?</a></li><li><a href="#tensorflow-regression">Tensorflow를 이용한 회귀 분석 실습</a><ul><li><a href="#preprocessing">데이터 전처리(Data preprocessing)</a></li><li><a href="#tensorflow-regerssion-modeling">Tensorflow Modeling</a></li></ul></li><li><a href="#jupter-notebook">Jupyter Notebook</a></li></ul><h3 id="linear-regression" href="#linear-regression">회귀분석(Regression Analysis)이란?</h3><p>위키피디아의 정의에 의하면,</p><blockquote><p>통계학에서, 선형 회귀(linear regression)는 종속 변수 y와 한 개 이상의 독립 변수 (또는 설명 변수) X와의 선형 상관 관계를 모델링하는 회귀분석 기법이다.</p></blockquote><p>여기서 <strong>독립 변수</strong> 는 입력값이나 원인을 나타내며, <strong>종속 변수</strong> 는 결과물이나 효과를 나타낸다.</p><p>예) 집값을 예측하는 모델이라면 집값이 종속 변수(y)이고, 집의 위치, 방의 개수 등의 특징(Feature)들이 독립 변수(x)가 된다.</p><div><img src="https://upload.wikimedia.org/wikipedia/commons/b/be/Normdist_regression.png"><p style="width: 100%; text-align:center;"><a href="https://ko.wikipedia.org/wiki/%ED%9A%8C%EA%B7%80_%EB%B6%84%EC%84%9D" target="_blank" rel="noopener">출처 : 위키백과</a></p></div><p>위 그림은 독립 변수 1개와 종속 변수 1개를 가진 회귀 분석의 예이며, 그 중에서도 <strong>선형 회귀(Linear Regression)</strong> 를 한 예이다.</p><p>여기서 <strong>선형 회귀</strong> 에 대해서만 간단하게 소개하자면 가장 널리 사용되는 기법이며, 종속 변수와 독립 변수의 관계가 <strong>선형(Linear)</strong> 인 경우에 사용한다.</p><blockquote><p>회귀 분석 기법은 선형 회귀 외에도 다양한 종류가 있는데, 이 포스트에서 소개하지는 않을 예정이고, 나중에 <a href="https://www.analyticsvidhya.com/blog/2015/08/comprehensive-guide-regression/" target="_blank" rel="noopener">링크</a>의 내용을 번역하여 공유하도록 하겠다.(자세한 내용이 궁금한 사람은 위의 링크를 통해서 확인하자)</p></blockquote><h3 id="tensorflow-regression" href="#tensorflow-regression">Tensorflow를 이용한 회귀 분석 실습</h3><h4 id="preprocessing" href="#preprocessing">1. 데이터 전처리(Data preprocessing)</h4><blockquote><p>데이터 전처리는 이번 포스트의 주목적이 아니므로 자세한 설명을 더하진 않겠다.</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><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Import Dependencies</span></span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> pandas <span class="keyword">as</span> pd</span><br><span class="line"><span class="keyword">import</span> tensorflow <span class="keyword">as</span> tf</span><br><span class="line"><span class="keyword">from</span> sklearn.datasets <span class="keyword">import</span> load_boston</span><br><span class="line">boston = load_boston()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 독립 변수와 종속 변수를 분리한다.</span></span><br><span class="line">X_data = pd.DataFrame(boston.data, columns=boston.feature_names)</span><br><span class="line">y_data = pd.DataFrame(boston.target, columns=[<span class="string">"Target"</span>])</span><br><span class="line"></span><br><span class="line"><span class="comment"># Train Test 데이터를 분리한다</span></span><br><span class="line">X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, test_size=<span class="number">0.2</span>, random_state=<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># StandardScaler를 사용하여 스케일링한다</span></span><br><span class="line"><span class="keyword">from</span> sklearn.preprocessing <span class="keyword">import</span> StandardScaler</span><br><span class="line"></span><br><span class="line"><span class="comment"># 객체로 사용해야 나중에 Test데이터에 같은 Mean, Variance를 사용할 수 있다.</span></span><br><span class="line">scaler = StandardScaler()</span><br><span class="line">scaler.fit(X_train)</span><br><span class="line">X_train = pd.DataFrame(data=scaler.transform(X_train), columns=X_train.columns, index=X_train.index)</span><br><span class="line"><span class="comment"># 주의 : Test 데이터는 fit을하면 안된다! 객체 내부에 설정된 Mean, Variance값이 Update되기 때문에 여기서는 transform만 사용한다.</span></span><br><span class="line">X_test = pd.DataFrame(data=scaler.transform(X_test), columns=X_test.columns, index=X_test.index)</span><br><span class="line"></span><br><span class="line"><span class="comment"># Tensorflow에서 사용할 땐 Numpy 데이터 타입으로 사용할 예정이니 변환하자</span></span><br><span class="line">X_train = np.array(X_train)</span><br><span class="line">y_train = np.array(y_train)</span><br><span class="line">X_test = np.array(X_test)</span><br><span class="line">y_test = np.array(y_test)</span><br><span class="line">type(X_train), type(y_train), type(X_test), type(y_test)</span><br></pre></td></tr></table></figure><p>이 예제에서는 Scaler로 <strong>StandardScaler(평균은 0으로, 표준편차는 1로 만드는 Scaler)</strong> 를 사용하였지만, 데이터마다 적절한 Scaler는 다를 수 있음을 명심하자. 역시 이 포스트에서는 자세히 다루지 않겠으며, 관심이 있는 사람들은 아래에 링크를 통해서 간략하게 이해를 하는 것을 추천한다.</p><ul><li><a href="http://scikit-learn.org/stable/auto_examples/preprocessing/plot_all_scaling.html" target="_blank" rel="noopener">Compare the effect of different scalers on data with outliers(Scikit-learn documentation)</a></li><li><a href="https://datascienceschool.net/view-notebook/f43be7d6515b48c0beb909826993c856/" target="_blank" rel="noopener">Scikit-Learn의 전처리 기능(데이터 사이언스 스쿨)</a></li></ul><p></p><h4 id="tensorflow-regerssion-modeling" href="#tensorflow-regerssion-modeling">2. Tensorflow Modeling</h4><br><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></pre></td><td class="code"><pre><span class="line"><span class="comment"># Learning Rate</span></span><br><span class="line">lr = <span class="number">0.01</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 가중치를 몇번 업데이트 할 것인가?</span></span><br><span class="line">epochs = <span class="number">2000</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Features 독립 변수</span></span><br><span class="line">X = tf.placeholder(dtype=tf.float32, shape=[<span class="keyword">None</span>, X_train.shape[<span class="number">1</span>]])</span><br><span class="line"><span class="comment"># Labels 종속 변수</span></span><br><span class="line">y = tf.placeholder(dtype=tf.float32, shape=[<span class="keyword">None</span>, <span class="number">1</span>])</span><br><span class="line"></span><br><span class="line"><span class="comment"># Weight 가중치, 초기값은 정규분포에서 랜덤하게 뽑는다</span></span><br><span class="line">W = tf.Variable(tf.random_normal([X_train.shape[<span class="number">1</span>], <span class="number">1</span>]))</span><br><span class="line"><span class="comment"># Bias 초기값은 정규분포에서 랜덤하게 뽑는다</span></span><br><span class="line">b = tf.Variable(tf.random_normal([<span class="number">1</span>]))</span><br></pre></td></tr></table></figure><p></p><p>여기서 <strong>placeholder()</strong> , <strong>Variable()</strong> 메서드 사용법에 대해서는 <a href="https://databuzz-team.github.io/2018/10/24/Basic-deep-learning-tensorflow-for-beginner-2/">이전 포스트</a>를 참고하자.  </p><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></pre></td><td class="code"><pre><span class="line"><span class="comment"># tf.Variable을 사용했거나, 메서드 내부적으로 변수가 존재하는 경우에는 Variables</span></span><br><span class="line"><span class="comment"># 초기화해줘야 한다.</span></span><br><span class="line">init = tf.global_variables_initializer()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 우리가 예측하는 값 W*X + b</span></span><br><span class="line">hypothesis = tf.add(tf.matmul(X, W), b)</span><br><span class="line"></span><br><span class="line"><span class="comment"># cost function으로는 MSE를 사용</span></span><br><span class="line">cost = tf.reduce_mean(tf.square(y - hypothesis))</span><br><span class="line"></span><br><span class="line"><span class="comment"># Gradient Descent 방법으로 최적화</span></span><br><span class="line">optimizer = tf.train.GradientDescentOptimizer(learning_rate=lr).minimize(cost)</span><br><span class="line"></span><br><span class="line"><span class="comment"># cost_history를 기록하면 마지막에 epoch 변화에 따른 cost 변화를 확인할 때 편리하다</span></span><br><span class="line">cost_history = np.empty(shape=[<span class="number">1</span>], dtype=float)</span><br></pre></td></tr></table></figure><p>이렇게 필요한 Graph는 다 만들었으니, 이제 Session을 열어서 W, b를 update하며 Cost Function의 값을 최소화하는 작업을 실행하자.<br><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><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">with</span> tf.Session() <span class="keyword">as</span> sess:</span><br><span class="line">    sess.run(init)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> epoch <span class="keyword">in</span> range(<span class="number">0</span>, epochs):</span><br><span class="line">        <span class="comment"># optimizer에서 반환하는 값은 의미가 없으니 _로 받아주자</span></span><br><span class="line">        _, err = sess.run([optimizer, cost], feed_dict=&#123;X: X_train, y: y_train&#125;)</span><br><span class="line"></span><br><span class="line">        cost_history = np.append(cost_history, err)</span><br><span class="line"></span><br><span class="line">        <span class="comment"># 100 번에 한번씩 Error 변화를 확인하자</span></span><br><span class="line">        <span class="keyword">if</span> epoch%<span class="number">100</span> == <span class="number">0</span>:</span><br><span class="line">            print(<span class="string">'Epoch: &#123;0&#125;, Error: &#123;1&#125;'</span>.format(epoch, err))</span><br><span class="line"></span><br><span class="line">    print(<span class="string">'Epoch: &#123;0&#125;, Error: &#123;1&#125;'</span>.format(epoch + <span class="number">1</span>, err))</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 우리가 설정한 Epochs만큼의 학습이 끝난 후에 나온 값을 확인하기 위해 받아두자</span></span><br><span class="line">    updated_W = sess.run(W)</span><br><span class="line">    updated_b = sess.run(b)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># Test 데이터를 예측한 값</span></span><br><span class="line">    y_pred = sess.run(hypothesis, feed_dict=&#123;X: X_test&#125;)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># Mean Squared Error</span></span><br><span class="line">    mse = sess.run(tf.reduce_mean(tf.square(y_pred - y_test)))</span><br></pre></td></tr></table></figure></p><p>위의 코드들을 통해서 <strong>Tensorflow Session</strong> 을 이용하여 <strong>회귀 분석(Regression Analysis)</strong> 방법을 알아보았고, 아래에 <strong>Jupyter notebook</strong> 에서는 <strong>Tensorflow</strong> 이 제공하는 <strong>Estimator API</strong> 를 사용하여 <strong>Linear Regression</strong> 하는 방법도 추가되어 있으니 도움이 되길 바란다.</p><h3 id="jupter-notebook" href="#jupter-notebook">Jupyter Notebook</h3><div class="notebook-embedded"><iframe src="https://nbviewer.jupyter.org/gist/DanialDaeHyunNam/6d96c11ac99bc2f2413ca5c8c6490dbc" width="100%" height="100%" frameborder="0" allowfullscreen></iframe></div><p>이 다음 포스트에서는 <strong>Tensorflow</strong> 로 <strong>인공 신경망(Neural Network)</strong> 을 구현하는 법에 대해서 작성하겠다.</p><h3 id="Related-Posts"><a href="#Related-Posts" class="headerlink" title="Related Posts"></a>Related Posts</h3><ul><li><a href="http://scikit-learn.org/stable/auto_examples/preprocessing/plot_all_scaling.html" target="_blank" rel="noopener">Compare the effect of different scalers on data with outliers(Scikit-learn documentation)</a></li><li><a href="https://datascienceschool.net/view-notebook/f43be7d6515b48c0beb909826993c856/" target="_blank" rel="noopener">Scikit-Learn의 전처리 기능(데이터 사이언스 스쿨)</a></li></ul>]]></content>
    
    <!-- <summary type="html">
    
    </summary> -->
    
      <category term="Danial Nam" scheme="https://databuzz-team.github.io/categories/Danial-Nam/"/>
    
    
      <category term="Data Science" scheme="https://databuzz-team.github.io/tags/Data-Science/"/>
    
      <category term="Machine Learning" scheme="https://databuzz-team.github.io/tags/Machine-Learning/"/>
    
      <category term="Tensorflow" scheme="https://databuzz-team.github.io/tags/Tensorflow/"/>
    
      <category term="Regression" scheme="https://databuzz-team.github.io/tags/Regression/"/>
    
  </entry>
  
  <entry>
    <title>&lt;MACHINE LEARNING&gt;Catboost 알아보기</title>
    <link href="https://databuzz-team.github.io/2018/10/24/Catboost/"/>
    <id>https://databuzz-team.github.io/2018/10/24/Catboost/</id>
    <published>2018-10-24T06:47:02.000Z</published>
    <updated>2018-11-05T08:51:13.621Z</updated>
    
    <content type="html"><![CDATA[<p>Machine Learning을 공부하였다면 한번쯤 XGBoost와 LightGBM, H2O를 들어보았을 것이다. 최근 이 분야에서 기존의 기술들을 위협하는 새로운 기술이 나와 이를 소개하고자 한다.</p><p>이 글은 <a href="https://towardsdatascience.com/https-medium-com-talperetz24-mastering-the-new-generation-of-gradient-boosting-db04062a7ea2" target="_blank" rel="noopener">참고블로그</a> (Towards Data Science)와 <a href="https://www.analyticsvidhya.com/blog/2017/08/catboost-automated-categorical-data/" target="_blank" rel="noopener">참고기사</a>의 내용을 번역 및 요약 정리하였고 좀 더 자세한 내용은 링크를 통해 확인해볼 수 있다.</p><h3 id="Catboost란-무엇인가"><a href="#Catboost란-무엇인가" class="headerlink" title="Catboost란 무엇인가?"></a>Catboost란 무엇인가?</h3><p>Catboost란 Yandex에서 개발된 오픈 소스 Machine Learning이다. 이 기술은 다양한 데이터 형태를 활용하여 기업이 직면한 문제들을 해결하는데 도움을 준다. 특히 분류 정확성에서 높은 점수를 제공한다.</p><p>Catboost는 Category와 Boosting을 합쳐서 만들어진 이름이다.<br>여기에서 Boost는 Gradient boosting machine learnin algorithm에서 온 말인데 Gradient boosting은 추천 시스템, 예측 등 다양한 분야에서 활용되어지는 강력한 방법이고 Deep Learning과 달리 적은 데이터로도 좋은 결과를 얻을 수 있는 효율적인 방법이다.</p><h3 id="왜-Catboost를-활용하는가"><a href="#왜-Catboost를-활용하는가" class="headerlink" title="왜 Catboost를 활용하는가?"></a>왜 Catboost를 활용하는가?</h3><h4 id="더-좋은-결과"><a href="#더-좋은-결과" class="headerlink" title="더 좋은 결과"></a>더 좋은 결과</h4><p>Catboost는 Benchmark에서 더 좋은 결과를 얻었다.</p><div>    <img src="https://cdn-images-1.medium.com/max/1600/1*vsg1IUlGtzCoNuGo9XqGwg.png">    <span style="font-size:11px; text-align:center; display:block; color: #999;">        <a href="https://towardsdatascience.com/https-medium-com-talperetz24-mastering-the-new-generation-of-gradient-boosting-db04062a7ea2" target="_blank" rel="noopener">            GBDT Algorithms Benchmark          </a>    </span></div><h4 id="Category-features-사용의-편리성"><a href="#Category-features-사용의-편리성" class="headerlink" title="Category features 사용의 편리성"></a>Category features 사용의 편리성</h4><p>Category features를 사용하기 위해서는 One-Hot-Encoding등 데이터를 전처리할 필요가 있었지만 Catboost에서는 사용자가 다른 작업을 하지 않아도 자동으로 이를 변환하여 사용한다. 이 분야를 공부한 경험이 있다면 이 기능이 얼마나 편리한지를 알 수 있을 것이다. 자세한 내용은 <a href="https://tech.yandex.com/catboost/doc/dg/concepts/algorithm-main-stages_cat-to-numberic-docpage/" target="_blank" rel="noopener">document</a>를 통해 확인할 수 있다.</p><h4 id="빠른-예측"><a href="#빠른-예측" class="headerlink" title="빠른 예측"></a>빠른 예측</h4><p>학습 시간이 다른 GBDT에 보다는 더 오래 걸리는 대신에 예측 시간이 13-16배 정도 더 빠르다.</p><div>    <img src="https://cdn-images-1.medium.com/max/2000/1*BE8PZe54DMWe6gFdHlYsxg.png">    <span style="font-size:11px; text-align:center; display:block; color: #999;">        <a href="https://towardsdatascience.com/https-medium-com-talperetz24-mastering-the-new-generation-of-gradient-boosting-db04062a7ea2" target="_blank" rel="noopener">            Left : CPU, Right : GPU        </a>    </span></div><h4 id="더-나은-기능들"><a href="#더-나은-기능들" class="headerlink" title="더 나은 기능들"></a>더 나은 기능들</h4><ul><li>default parameters값으로 더 나은 성능<br>hyper-parmeter tuning을 하지 않더라도 기본적인 세팅으로도 좋은 결과를 얻을 수 있어 활용성이 뛰어나다. 자세한 내용은 <a href="https://tech.yandex.com/catboost/doc/dg/concepts/parameter-tuning-docpage/" target="_blank" rel="noopener">document</a>를 통해 확인할 수 있다.</li></ul><div>    <img src="https://cdn-images-1.medium.com/max/1600/1*znsWIb1X3Eez5LjNf4mg_g.png">    <span style="font-size:11px; text-align:center; display:block; color: #999;">        <a href="https://towardsdatascience.com/https-medium-com-talperetz24-mastering-the-new-generation-of-gradient-boosting-db04062a7ea2" target="_blank" rel="noopener">            GBDT Algorithms with default parameters Benchmark        </a>    </span></div><ul><li>feature interactions</li></ul><div>    <img src="https://cdn-images-1.medium.com/max/1600/1*VV1eH5Iwz3hJmKWAaV_Y6w.png">    <span style="font-size:11px; text-align:center; display:block; color: #999;">        <a href="https://towardsdatascience.com/https-medium-com-talperetz24-mastering-the-new-generation-of-gradient-boosting-db04062a7ea2" target="_blank" rel="noopener">    Catboost’s Feature Interactions     </a>    </span></div><ul><li>feature importances</li></ul><div>    <img src="https://cdn-images-1.medium.com/max/1600/1*6Y9gHBQLxk-PoIJLd2wr1g.png">    <span style="font-size:11px; text-align:center; display:block; color: #999;">        <a href="https://towardsdatascience.com/https-medium-com-talperetz24-mastering-the-new-generation-of-gradient-boosting-db04062a7ea2" target="_blank" rel="noopener">    Catboost’s Feature Importance     </a>    </span></div><ul><li>object(row) importances</li></ul><div>    <img src="https://cdn-images-1.medium.com/max/1600/1*ZoMzKdiIyLU9wDelELQMvg.png">    <span style="font-size:11px; text-align:center; display:block; color: #999;">        <a href="https://towardsdatascience.com/https-medium-com-talperetz24-mastering-the-new-generation-of-gradient-boosting-db04062a7ea2" target="_blank" rel="noopener">    Catboost’s Object Importance    </a>    </span></div><ul><li>the snapshot</li></ul><h3 id="결론"><a href="#결론" class="headerlink" title="결론"></a>결론</h3><p>프로젝트 등을 수행하다보면 Catgory feature를 이용하는 것이 상당히 번거롭다는 것을 알 수 있을 것이다. 뿐만 아니라 예측 시간이 오래걸린다면 실제로 시스템에 적용하는데는 큰 문제점을 가지고 있음을 알고 있다.</p><p>다른 Maching Learning algorithms의 단점을 보완해주는 Catboost를 잘 활용한다면 좀 더 나은 시스템을 개발하는데 도움이 될 것이다.</p><h3 id="유용한-자료"><a href="#유용한-자료" class="headerlink" title="유용한 자료"></a>유용한 자료</h3><ul><li><a href="https://tech.yandex.com/catboost/doc/dg/concepts/about-docpage/" target="_blank" rel="noopener">Catboost Documentation</a></li><li><a href="https://github.com/catboost/catboost" target="_blank" rel="noopener">Catboost Github</a></li><li><a href="https://catboost.ai/" target="_blank" rel="noopener">Catboost official website</a></li><li><a href="https://arxiv.org/abs/1706.09516" target="_blank" rel="noopener">CatBoost: unbiased boosting with categorical features</a></li></ul>]]></content>
    
    <!-- <summary type="html">
    
    </summary> -->
    
      <category term="HyunGeun Yoon" scheme="https://databuzz-team.github.io/categories/HyunGeun-Yoon/"/>
    
    
      <category term="Machine Learning" scheme="https://databuzz-team.github.io/tags/Machine-Learning/"/>
    
      <category term="Catboost" scheme="https://databuzz-team.github.io/tags/Catboost/"/>
    
  </entry>
  
  <entry>
    <title>&lt;Deep Learning&gt; An introduction to Deep Learning with Tensorflow(Part-2)</title>
    <link href="https://databuzz-team.github.io/2018/10/24/Basic-deep-learning-tensorflow-for-beginner-2/"/>
    <id>https://databuzz-team.github.io/2018/10/24/Basic-deep-learning-tensorflow-for-beginner-2/</id>
    <published>2018-10-24T01:03:01.000Z</published>
    <updated>2020-10-09T10:10:59.224Z</updated>
    
    <content type="html"><![CDATA[<p>이번 포스트에서는 Tensorflow에서 꼭 알아야 할 기본적인 지식들에 대해서 알아보자.(Tensorflow설치법에 대해서는 다루지 않을 것)</p><h3 id="1-Dataflow"><a href="#1-Dataflow" class="headerlink" title="1. Dataflow"></a>1. Dataflow</h3><div style="width:40%; float:left;"><img src="https://www.tensorflow.org/images/tensors_flowing.gif"><p style="text-align:center"><a href="https://www.tensorflow.org/guide/graphs" target="_blank" rel="noopener">출처 :Graphs and Sessions</a></p></div><div style="width: 60%; float:right; color: #333;"><a href="https://databuzz-team.github.io/2018/10/22/Basic-deep-learning-tensorflow-for-beginner/">이전 포스트 Part 1</a>에서 이미 다룬 내용인데다 개념 설명이라 지루할 수도 있지만, Tensorflow를 사용하기 위해선 꼭 이해해야 하는 부분을 그림과 함께 짧게 설명하고자 하니, 이 부분을 꼭 읽어주시길 바란다.옆의 그림은 <strong>Tensorflow</strong> 공식 홈페이지에 나와있는데, 정말 직관적으로 Tensorflow의 <strong>Dataflow Graph(Node And Operation)</strong> 를 표현해냈다.먼저 <strong>Tensor</strong> 는 옆에서 보이는 검은 라인이고(Edge), <strong>Operation</strong> 은 노드(Node)들, 그림에서 타원들을 의미한다. 즉, Tensor가 Operation으로 들어가서 해당 Operation에서 설정한 연산을 진행하고 다시 Tensor를 Output으로 내보내는 것이다.<br><br><blockquote>필자가 이해한 바대로라면 Tensor나 Operation이라는 낯선 단어들을 사용해서 어렵게 느껴지지만 결국은 함수의 기능을 한다고 봐주면 되겠다. 차이점은 Graph는 선언이고 Session을 통해서 Run을 한다는 것</blockquote><br>물론! 끝은 Output으로 값을 내보내는 것을 목적으로 하는 것은 아니다. 우리의 목적은 <strong>W 가중치</strong> 를 <strong>Update</strong> 하는 것이므로, 마지막에 우리가 <strong>Optimizer</strong> 의 변수로 설정한 <strong>W1, b1, W2, b2 ...</strong> 들이 <strong>Update</strong> 되는 것으로 <strong>Session.run()</strong> 이 종료된다.<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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> tensorflow <span class="keyword">as</span> tf</span><br><span class="line">sess = tf.Session()</span><br><span class="line">sess.run(task)</span><br><span class="line">sess.close()</span><br></pre></td></tr></table></figure></div><div style="width: 100%; clear:both; color: #333;"><h3>2. Operation의 name과 scope의 간략한 소개</h3>본격적으로 코드에 대해 설명하기 전에 <strong>Debugging</strong> 에 도움이 되는 정보인 Operation name에 대해서 간략하게 살펴만 보자.<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></pre></td><td class="code"><pre><span class="line">c_0 = tf.constant(<span class="number">0</span>, name=<span class="string">"c"</span>)  <span class="comment"># =&gt; operation 이름은 "c"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 이미 사용된 이름은 자동으로 유니크화 시킨다.</span></span><br><span class="line">c_1 = tf.constant(<span class="number">2</span>, name=<span class="string">"c"</span>)  <span class="comment"># =&gt; operation 이름은 "c_1"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Name scope는 접두사로 붙게되는데 나중에 설명할 Tensorboard에서 확인할 때 훨씬 편리하다.</span></span><br><span class="line"><span class="keyword">with</span> tf.name_scope(<span class="string">"outer"</span>):</span><br><span class="line">  c_2 = tf.constant(<span class="number">2</span>, name=<span class="string">"c"</span>)  <span class="comment"># =&gt; operation 이름은 "outer/c"</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># Name scope 아래로는 경로로 계층을 표현한다.</span></span><br><span class="line">  <span class="keyword">with</span> tf.name_scope(<span class="string">"inner"</span>):</span><br><span class="line">    c_3 = tf.constant(<span class="number">3</span>, name=<span class="string">"c"</span>)  <span class="comment"># =&gt; operation 이름은 "outer/inner/c"</span></span><br><span class="line"></span><br><span class="line">  c_4 = tf.constant(<span class="number">4</span>, name=<span class="string">"c"</span>)  <span class="comment"># =&gt; operation 이름은 "outer/c_1"</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">with</span> tf.name_scope(<span class="string">"inner"</span>):</span><br><span class="line">    c_5 = tf.constant(<span class="number">5</span>, name=<span class="string">"c"</span>)  <span class="comment"># =&gt; operation 이름은 "outer/inner_1/c"</span></span><br></pre></td></tr></table></figure><p style="text-align:center; margin:0"><a href="https://www.tensorflow.org/guide/graphs" target="_blank" rel="noopener">출처 :Graphs and Sessions</a></p></div><div style="width: 100%; clear:both; color: #333;"><h3>3. Tensorflow 가장 많이 사용되는 함수들을 알아보자</h3>이 포스트에서는 필자가 많이 사용된다고 생각하는 가장 기본적인 함수들만 작성했는데, 이 외에도 거의 모든 수학 연산은 다 구현되어 있으니 자세한 API는 <a href="https://www.tensorflow.org/api_docs/python/" target="_blank" rel="noopener">링크</a>를 통해서 찾아보도록 하자.<ul><li><h5>tf.placeholder()</h5><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></pre></td><td class="code"><pre><span class="line">tf.placeholder(</span><br><span class="line">    dtype,</span><br><span class="line">    shape=<span class="keyword">None</span>,</span><br><span class="line">    name=<span class="keyword">None</span></span><br><span class="line">)</span><br></pre></td></tr></table></figure><strong>tf.placeholder()</strong> 는 머신러닝에서 무조건 사용하는 함수이며, 구조는 위의 코드에서 보듯 dtype, shape, name으로 이루어져있는데 핵심은 <strong>shape</strong> 이다.<br><br><blockquote>다른 포스트에서 언급하겠지만 tensorflow에서 shape을 이해하는 것은 매우 중요하다.</blockquote><br>예를 들어 집값을 예측하는 모델을 우리가 만들고 있고, 집의 <strong>Feature(특징)</strong> 는 <strong>rooms, is_riverside</strong> 로 이루어져 있다고 하자. 그리고 만약 우리가 최종적으로 사용할 <strong>Feature</strong> 의 수는 위에서 말한 두 가지면 충분하다고 결정했다고 본다면, <strong>Input</strong> 데이터의 <strong>shape</strong> 으로 <strong>[?, 2]</strong>, 즉 컬럼은 2 개로 결정을 한 상태라는 것이다. 하지만, 집의 개수, 즉 데이터의 개수는 많을수록 좋은 것이므로 변동의 여지가 언제나 있는 값일 뿐 아니라 최종적으로 우리가 새로운 데이터를 예측하려 할 때에도 변하는 값이라는 것이다.<br><br>그런 이유에서 <strong>tensorflow</strong> 에서는 <strong>placeholder</strong> 라는 함수를 제공하는 것이며, <strong>Feature(X)</strong> 와 <strong>Label(y)</strong> 은 <strong>placeholder</strong> 를 사용해서 넣어준다. 주의할 점은 <strong>sess.run()</strong> 시에 <strong>feed_dict</strong> 에 꼭 값을 직접 <strong>넣어(feed)</strong> 주어야 한다는 것.<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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> tensorflow <span class="keyword">as</span> tf</span><br><span class="line">x_data = np.array([[<span class="number">3</span>, <span class="number">1</span>], [<span class="number">4</span>, <span class="number">0</span>], [<span class="number">5</span>, <span class="number">1</span>]])</span><br><span class="line">y_data = np.array([[<span class="number">120000</span>], [<span class="number">100000</span>], [<span class="number">200000</span>]])</span><br><span class="line"></span><br><span class="line">X = tf.placeholder(tf.float32, shape=[<span class="keyword">None</span>, <span class="number">2</span>], name=<span class="string">"X"</span>)</span><br><span class="line"><span class="comment"># 이 예제에서는 각 집마다의 가격을 예측하는 것이므로, shape은 [None, 1]이 된 것.</span></span><br><span class="line">y = tf.placeholder(tf.float32, shape=[<span class="keyword">None</span>, <span class="number">1</span>], name=<span class="string">"y"</span>)</span><br></pre></td></tr></table></figure></li><li><h5>tf.Variable()</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tf.Variable(&lt;initial-value&gt;, name=&lt;optional-name&gt;)</span><br></pre></td></tr></table></figure>머신러닝을 통해서 구하고자하는 값인 <strong>Weight</strong> 나 <strong>Bias</strong> 와 같은 값은 <strong>tensorflow</strong> 의 <strong>tf.Variable()</strong> 함수를 사용해서 선언해야한다. 구조는 위의 code에서 보듯 아주 단순하며, 보통은 Random하게 초기화하는 경우가 많으므로 행렬곱을 할 상대인 <strong>X</strong> 와 예측 값으로 내보내는 <strong>y</strong> 의 <strong>shape</strong> 을 고려해서 <strong>tf.random_normal()</strong> 을 사용하게 된다.<figure class="highlight python"><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">W = tf.Variable(tf.random_normal([<span class="number">2</span>, <span class="number">1</span>]), name=<span class="string">'wight'</span>)</span><br><span class="line">b = tf.Variable(tf.random_normal([<span class="number">1</span>]), name=<span class="string">'bias'</span>)</span><br></pre></td></tr></table></figure></li><li><h5>tf.matmul()</h5><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></pre></td><td class="code"><pre><span class="line">tf.matmul(</span><br><span class="line">    a,</span><br><span class="line">    b,</span><br><span class="line">    transpose_a=<span class="keyword">False</span>,</span><br><span class="line">    transpose_b=<span class="keyword">False</span>,</span><br><span class="line">    adjoint_a=<span class="keyword">False</span>,</span><br><span class="line">    adjoint_b=<span class="keyword">False</span>,</span><br><span class="line">    a_is_sparse=<span class="keyword">False</span>,</span><br><span class="line">    b_is_sparse=<span class="keyword">False</span>,</span><br><span class="line">    name=<span class="keyword">None</span></span><br><span class="line">)</span><br></pre></td></tr></table></figure>머신러닝에서는 <strong>원소간의 곱(Element-wise multiplication)</strong> 보다는 <strong>행렬곱(Matrix multiplication)</strong> 이 훨씬 많이 쓰이므로 <strong>tf.matmul()</strong> 은 꼭 알아야하는 함수이다.<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hypothesis = tf.matmul(X, W) + b</span><br></pre></td></tr></table></figure></li><li><h5>tf.train module</h5>오늘 소개할 마지막은 함수가 아닌 <strong>모듈(Module)</strong> 이다. 아래는 가장 보편적인 <strong>Optimizer</strong> 인 <strong>GradientDescentOptimizer</strong> 로 예를 들었지만, 훨씬 많은 모델들을 <strong>tensorflow</strong> 에서는 제공하고 있으니, 이 외에 필요한 정보는 <a href="https://www.tensorflow.org/api_docs/python/tf/train" target="_blank" rel="noopener">링크</a>에서 확인하도록 하자.<br><br><blockquote><strong>목표 함수(Cost function)</strong> 에 대해서 이 포스트에서는 특별히 다루지 않지만, 다음 포스트들에서 CNN, RNN 등의 알고리즘을 구현하며 설명을 추가하겠다.</blockquote><figure class="highlight python"><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">cost = tf.reduce_mean(tf.square(hypothesis - y))</span><br><span class="line">train = tf.train.GradientDescentOptimizer(learning_rate=lr).minimize(cost)</span><br></pre></td></tr></table></figure></li></ul><h3>4. 마무리</h3>이번 포스트는 어려운 내용이 없지만 <strong>tensorflow</strong> 를 공부하며 간단한 모델들을 구현해보며 가장 자주 사용되고 중요하다고 느꼈던 점을 정리해보았는데, 처음 시작하는 사람들에게 꼭 도움이 되길 바란다.<br><br>아래는 가장 간단하게 회귀분석 모델을 구현한 코드이며, 위에서 설명한 개념들을 정말 간단한 예제이긴 하지만, 대략적으로 어떻게 쓰이나 보여주기 위해서 작성해보았다.<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><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> tensorflow <span class="keyword">as</span> tf</span><br><span class="line">x_data = np.array([[<span class="number">3</span>, <span class="number">1</span>], [<span class="number">4</span>, <span class="number">0</span>], [<span class="number">5</span>, <span class="number">1</span>]])</span><br><span class="line">y_data = np.array([[<span class="number">120000</span>], [<span class="number">100000</span>], [<span class="number">200000</span>]])</span><br><span class="line"></span><br><span class="line"><span class="comment"># hyper parameter</span></span><br><span class="line">lr = <span class="number">0.01</span></span><br><span class="line">n_epoch = <span class="number">2000</span></span><br><span class="line"></span><br><span class="line">X = tf.placeholder(tf.float32, shape=[<span class="keyword">None</span>, <span class="number">2</span>], name=<span class="string">"X"</span>)</span><br><span class="line">y = tf.placeholder(tf.float32, shape=[<span class="keyword">None</span>, <span class="number">1</span>], name=<span class="string">"y"</span>)</span><br><span class="line"></span><br><span class="line">W = tf.Variable(tf.random_normal([<span class="number">2</span>, <span class="number">1</span>]), name=<span class="string">'wight'</span>)</span><br><span class="line">b = tf.Variable(tf.random_normal([<span class="number">1</span>]), name=<span class="string">'bias'</span>)</span><br><span class="line"></span><br><span class="line">hypothesis = tf.matmul(X, W) + b</span><br><span class="line"></span><br><span class="line">cost = tf.reduce_mean(tf.square(hypothesis - y))</span><br><span class="line">train = tf.train.GradientDescentOptimizer(learning_rate=lr).minimize(cost)</span><br><span class="line"></span><br><span class="line"><span class="keyword">with</span> tf.Session() <span class="keyword">as</span> sess:</span><br><span class="line">    <span class="comment"># 변수가 있는 경우에는 초기화를 실행해줘야 한다.</span></span><br><span class="line">    sess.run(tf.global_variables_initializer())</span><br><span class="line">    <span class="comment"># train이 반환하는 값은 우리에게 필요없다.</span></span><br><span class="line">    <span class="keyword">for</span> step <span class="keyword">in</span> range(n_epoch):</span><br><span class="line">        c, _ = sess.run([cost, train], feed_dict=&#123;X: x_data, y: y_data&#125;)</span><br><span class="line">        <span class="keyword">if</span> step % <span class="number">500</span> == <span class="number">0</span>:</span><br><span class="line">            print(<span class="string">"Step :"</span>, step, <span class="string">"Cost :"</span>, c)</span><br><span class="line">            <span class="comment"># x, y를 임의로 만든거라..</span></span><br><span class="line">            <span class="comment"># 이 부분은 train data를 학습시키는지 확인하는 목적 외에는 없다.</span></span><br><span class="line">            print(sess.run(hypothesis, feed_dict=&#123;X: x_data&#125;))</span><br></pre></td></tr></table></figure></div><h3 id="Related-Posts"><a href="#Related-Posts" class="headerlink" title="Related Posts"></a>Related Posts</h3>]]></content>
    
    <!-- <summary type="html">
    
    </summary> -->
    
      <category term="Danial Nam" scheme="https://databuzz-team.github.io/categories/Danial-Nam/"/>
    
    
      <category term="Machine Learning" scheme="https://databuzz-team.github.io/tags/Machine-Learning/"/>
    
      <category term="Artificial Intelligence" scheme="https://databuzz-team.github.io/tags/Artificial-Intelligence/"/>
    
      <category term="Deep Learning" scheme="https://databuzz-team.github.io/tags/Deep-Learning/"/>
    
      <category term="Tensorflow" scheme="https://databuzz-team.github.io/tags/Tensorflow/"/>
    
  </entry>
  
  <entry>
    <title>&lt;Deep Learning&gt; An introduction to Deep Learning with Tensorflow(Part-1)</title>
    <link href="https://databuzz-team.github.io/2018/10/22/Basic-deep-learning-tensorflow-for-beginner/"/>
    <id>https://databuzz-team.github.io/2018/10/22/Basic-deep-learning-tensorflow-for-beginner/</id>
    <published>2018-10-22T14:27:01.000Z</published>
    <updated>2020-10-09T10:10:52.540Z</updated>
    
    <content type="html"><![CDATA[<p><br></p><p>최근에 번역한 <a href="https://databuzz-team.github.io/2018/10/15/The-Most-in-Demand-Skills-for-Data-Scientists/">“DATA SCIENTISTS에게 가장 요구되는 기술(SKILLS)들”</a> 글에서 확인했듯, 급부상하는 분야인 Machine Learning에서도 Deep Learning은 우리가 앞으로 이 분야에서 일하자면 꼭 공부해야 한다.</p><p>먼저 간단하게 <strong>Machine Learning</strong> 에 대해서 알아보자.</p><h3 id="Machine-Learning"><a href="#Machine-Learning" class="headerlink" title="Machine Learning?"></a>Machine Learning?</h3><p>사실 역사는 이미 오래된 분야다. 하지만 최근들어서야 급부상하는 이유는 무엇보다도 Computing Power의 성장과 방대한 데이터가 있다는 점이다.</p><p>크게는 지도학습과 비지도학습으로 나뉘는데, 지도학습은 Input과 Output을 알려주고 그 사이에 존재하는 로직을 기계가 학습하도록 하는 것이며, 비지도학습은 Input만 알려주고 데이터가 가진 특징 속에서 스스로 학습해나가는 것을 말한다.</p><p>아래의 영상은 최근에 공개된 영상인데 Deep Learning의 현재 수준이 이미 놀라운 수준임을 알 수 있다.</p><iframe src="https://www.youtube.com/embed/PCBTZh41Ris" width="560" height="315" frameborder="0" allowfullscreen></iframe><p>만약 가장 트렌디한 머신러닝 기술들을 보고싶다면 <a href="https://arxiv.org/" target="_blank" rel="noopener">링크</a>를 확인하는 것이 가장 좋다고한다. 학회에 제출하고 논문이 Accept가 되는데 평균적으로 7개월이 걸리는데, 그 기간이면 이미 새로운 기술이 나오는 상황이라.. 만약 트렌드한 기술을 캐치하자면 꼭 <a href="https://arxiv.org/" target="_blank" rel="noopener">링크</a>에서 확인하자.</p><h3 id="왜-Tensorflow인가"><a href="#왜-Tensorflow인가" class="headerlink" title="왜 Tensorflow인가?"></a>왜 Tensorflow인가?</h3><p>Tensorflow는 Google이 개발한 Library인데, 현재는 가장 사랑을 받고 있는 Library로써, Google 자체에서도 Google Photo, Google Voice Search 등은 모두 Tensorflow를 간접적으로 사용하고 있는 App 들이다.</p><h3 id="Tensorflow-기본-개념"><a href="#Tensorflow-기본-개념" class="headerlink" title="Tensorflow 기본 개념"></a>Tensorflow 기본 개념</h3><blockquote><p>이 부분은 <a href="https://towardsdatascience.com/a-beginner-introduction-to-tensorflow-part-1-6d139e038278" target="_blank" rel="noopener">A beginner introduction to TensorFlow (Part-1)</a>을 번역 정리하였다.</p></blockquote><ul><li><strong>Tensorflow</strong> 의 Core는 그래프(computational graph)와 Tensor로 이루어져있다.</li><li><strong>Tensor와 Vector의 차이점</strong> 은 Tensor는 크기만 가진경우도 존재한다는 점이다. 즉 Vector는 Tensor의 특수상황이며, 부분집합으로 볼 수 있다.</li><li><p><strong>Tensor</strong> 는 이해했으니 <strong>Flow</strong> 를 살펴보자. <strong>Flow</strong> 는 computational graph 혹은 단순한 graph라고 볼 수 있다. cyclic한 구조는 아니며, 각 노드(아래 그림에서 동그라미)는 덧셈, 뺄셈 등의 기능을 가지고 있다. <div><img src="https://cdn-images-1.medium.com/max/1600/1*7lklTJQytHz8w7Eeqz5ZhA.png"><span style="font-size:12px; text-align:center; display:block; color: #999;"><a href="https://towardsdatascience.com/a-beginner-introduction-to-tensorflow-part-1-6d139e038278" target="_blank" rel="noopener">출처 : A beginner introduction to TensorFlow (Part-1)</a></span></div></p></li><li><p><strong>e = (a+b) * (b+1)</strong><br>기능(operation)적인 역할을 해야 하는 모든 연결되는 노드(꼭짓점)은 graph의 시작일 수는 없고, Tensor를 받거나 새로운 Tensor를 생성하는 역할을 한다. 또한, computational graph는 항상 복잡한 계층 구조로 되어있는데, 위의 그림에서도 마찬가지로 표현되어 있듯 a+b는 c로 b+1은 d로 표현될 수 있다.</p></li><li><p><strong>e = (c)*(d), c = a+b and b = b+1</strong><br>위의 그림에서 명백하게 표현되어있듯 각 노드는 전 노드에 의존적이어서 c는 a, b 없이 나올 수 없고, e는 c, d 없이 나올 수 없다. 단 c, d처럼 같은 계층에 존재하는 노드들은 상호 독립적이다. 이 점은 computational graph를 이해할 때 가장 중요한 부분으로써, <strong>같은 레벨에 있는 노드 c의 경우는 d가 먼저 계산되어야 할 이유가 없고, 평행적으로 실행될 수 있다.</strong></p></li><li><p>위에서 설명한 computational graph의 평행 관계(parallelism)가 가장 중요한 개념이니 꼭 숙지해야 한다. 이 평행 관계의 의미는 c 계산이 끝나지 않았다고, d 계산은 평행적으로 이루어진다는 점이며, tensorflow는 이 부분을 멋지게 해낸다.</p></li></ul><h3 id="Tensorflow-분할-실행"><a href="#Tensorflow-분할-실행" class="headerlink" title="Tensorflow 분할 실행"></a>Tensorflow 분할 실행</h3><div><img src="https://cdn-images-1.medium.com/max/1600/1*cok4bMhTvE93UdGmRblEyw.png"><span style="font-size:12px; text-align:center; display:block; color: #999;"><a href="https://towardsdatascience.com/a-beginner-introduction-to-tensorflow-part-1-6d139e038278" target="_blank" rel="noopener">출처 : A beginner introduction to TensorFlow (Part-1)</a></span></div><ul><li><strong>Tensorflow</strong> 는 여러 기계에 평행적으로 계산을 실행하여 훨씬 빠른 연산을 할 수가 있는데, 따로 설정할 필요 없이 내부적으로 설정이 된다.<br><br><blockquote><p>위의 그림에서 왼쪽은 single Tensorflow session을 사용한 경우라서 single worker가 존재하는 것이고, 오른쪽은 multiple workers를 사용한 경우</p></blockquote></li></ul><ul><li>Worker들은 서로 다른 기기에서 독립적으로 연산을 하고 다음 노드에 해당하는 Worker에게 Result를 넘겨준다. 이때, Delay로 인한 성능 저하가 일어날 수 있는데 이는 주로 <strong>Tensor</strong> 의 <strong>Size</strong> 에서 발생하므로 어떤 <strong>자료형</strong> 을 설정할 것인지가 <strong>중요한 문제</strong> 다.</li></ul><h3 id="결론"><a href="#결론" class="headerlink" title="결론"></a>결론</h3><p>이번 Part1 글에서는 Machine Learning과 Tensorflow에 대한 소개를 중점으로 썼고, Part2에서는 Tensorflow의 기본 문법과 MNIST Digit 이미지 분류하는 코딩에 대해서 포스팅하겠다.</p><hr><h3 id="Related-Posts"><a href="#Related-Posts" class="headerlink" title="Related Posts"></a>Related Posts</h3><p><a href="https://towardsdatascience.com/a-beginner-introduction-to-tensorflow-part-1-6d139e038278" target="_blank" rel="noopener">A beginner introduction to TensorFlow (Part-1)</a></p>]]></content>
    
    <!-- <summary type="html">
    
    </summary> -->
    
      <category term="Danial Nam" scheme="https://databuzz-team.github.io/categories/Danial-Nam/"/>
    
    
      <category term="Machine Learning" scheme="https://databuzz-team.github.io/tags/Machine-Learning/"/>
    
      <category term="Artificial Intelligence" scheme="https://databuzz-team.github.io/tags/Artificial-Intelligence/"/>
    
      <category term="Deep Learning" scheme="https://databuzz-team.github.io/tags/Deep-Learning/"/>
    
      <category term="Tensorflow" scheme="https://databuzz-team.github.io/tags/Tensorflow/"/>
    
  </entry>
  
  <entry>
    <title>&lt;Github&gt; Gist를 사용하여 Jupyter Notebook 포스팅하기</title>
    <link href="https://databuzz-team.github.io/2018/10/21/Github-Gist/"/>
    <id>https://databuzz-team.github.io/2018/10/21/Github-Gist/</id>
    <published>2018-10-21T13:01:32.000Z</published>
    <updated>2020-10-09T09:47:08.741Z</updated>
    
    <content type="html"><![CDATA[<h5 id="Gist를-사용하면-아래처럼-소스코드를-임베딩-할-수-있다"><a href="#Gist를-사용하면-아래처럼-소스코드를-임베딩-할-수-있다" class="headerlink" title="Gist를 사용하면 아래처럼 소스코드를 임베딩 할 수 있다."></a><a href="https://gist.github.com/" target="_blank" rel="noopener">Gist</a>를 사용하면 아래처럼 소스코드를 임베딩 할 수 있다.</h5><p>아래의 예는 <strong>Jupyter Notebook</strong> 을 임베딩한 것이지만, 이 외에도 .py, .md, .html 등 소스 코드는 다 할 수 있다.</p><script src="https://gist.github.com/DanialDaeHyunNam/afc48b2814cd7798ee7dbaa00e321468.js"></script><h5 style="color: red;">  만약 위의 박스 안에 Jupyter Notebook이 보이지 않는다면.. Gist 사이트에 올린 .ipynb 파일이 Rendering 실패하는 것이므로 <a href="#new-method">여기</a>를 클릭해서 불필요한 내용은 Skip 하시길..</h5><p>사용하는 방법은 아래와 같다.</p><hr><h3 id="1-먼저-Gist-사이트로-이동"><a href="#1-먼저-Gist-사이트로-이동" class="headerlink" title="1. 먼저 Gist 사이트로 이동"></a>1. 먼저 <a href="https://gist.github.com/" target="_blank" rel="noopener">Gist</a> 사이트로 이동</h3><p><img src="/images/danial/gist_1.png"><br>위의 사진처럼 코드를 적는 창이 있다. Jupyter Notebook의 경우에는 해당 파일을 <strong>Drag &amp; Drop</strong> 하면 된다.</p><h3 id="2-Indent-Mode를-Spaces에서-Tabs로-변경"><a href="#2-Indent-Mode를-Spaces에서-Tabs로-변경" class="headerlink" title="2. Indent Mode를 Spaces에서 Tabs로 변경"></a>2. Indent Mode를 Spaces에서 Tabs로 변경</h3><p><img src="/images/danial/gist_2.png"><br>이 경우는 <strong>Jupyter Notebook</strong> 을 임베딩하는 경우에만 적용될 수도 있는 사항이니 조심하자.</p><p>필자는 Jupyter Notebook을 처음부터 도전하였는데, Spaces의 경우에는 계속 Render를 실패하기에 이유를 찾아보다가 발견한 방법이다.</p><h3 id="3-Script-Copy"><a href="#3-Script-Copy" class="headerlink" title="3. Script Copy"></a>3. Script Copy</h3><p><img src="/images/danial/gist_3.png"><br>이미지처럼 Embed 옆에 아이콘을 클릭하면 아래처럼 <strong>script</strong> 태그가 복사된다. Markdown 파일이나 HTML에 붙여넣기하면 된다.<br><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://gist.github.com/&#123;UserId&#125;/&#123;script&#125;.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure></p><h3 id="Tip-1-이후에-다른-소스코드를-포스팅하고자-하면-Add-file이-아닌-New-gist로-새로운-파일들을-추가하면-된다"><a href="#Tip-1-이후에-다른-소스코드를-포스팅하고자-하면-Add-file이-아닌-New-gist로-새로운-파일들을-추가하면-된다" class="headerlink" title="Tip 1) 이후에 다른 소스코드를 포스팅하고자 하면 Add file이 아닌 New gist로 새로운 파일들을 추가하면 된다."></a>Tip 1) 이후에 다른 소스코드를 포스팅하고자 하면 Add file이 아닌 New gist로 새로운 파일들을 추가하면 된다.</h3><p><img src="/images/danial/gist_helper.png"></p><h3 id="Tip-2-이미-Gist에서-정해준-iframe의-크기를-조절하고-싶은-경우에는-아래의-css를-추가해주면-된다"><a href="#Tip-2-이미-Gist에서-정해준-iframe의-크기를-조절하고-싶은-경우에는-아래의-css를-추가해주면-된다" class="headerlink" title="Tip 2) 이미 Gist에서 정해준 iframe의 크기를 조절하고 싶은 경우에는 아래의 css를 추가해주면 된다."></a>Tip 2) 이미 Gist에서 정해준 iframe의 크기를 조절하고 싶은 경우에는 아래의 css를 추가해주면 된다.</h3><figure class="highlight css"><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="selector-class">.gist</span>&#123;</span><br><span class="line">  <span class="attribute">max-width</span>: <span class="number">80%</span>;</span><br><span class="line">  <span class="attribute">margin-top</span>: <span class="number">10px</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.gist-data</span>&#123;</span><br><span class="line">  <span class="attribute">max-height</span>: <span class="number">300px</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.gist</span> <span class="selector-tag">iframe</span><span class="selector-class">.render-viewer</span>&#123;</span><br><span class="line">  <span class="attribute">max-height</span>: <span class="number">260px</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h5 style="color: blue;">  Gist가 Rendering을 문제없이 해냈다면 여기서부터 아래 내용은 볼 필요가 없다.</h5><hr><h3 id="new-method" href="#new-method">  New) Gist에서 제공하는 방법보다는 불편하고 깔끔하지는 않지만, Jupyter Notebook을 Embed하는 다른 방법이 있어 소개하고자 한다.</h3><blockquote><p>이 방법의 경우에는 사실 github repo에 올린 jupyter notebook에도 적용되는 방법이므로, 꼭 Gist를 사용할 필요는 없지만 이 포스트에서는 Gist에 올린 경우에 대해서만 설명하겠다.</p></blockquote><h3 id="1-Gist-사이트에-업로드"><a href="#1-Gist-사이트에-업로드" class="headerlink" title="1. Gist 사이트에 업로드"></a>1. Gist 사이트에 업로드</h3><p>일단 위의 순서 중에 <a id="1-먼저-Gist-사이트로-이동" href="#1-먼저-Gist-사이트로-이동">1.Gist 사이트로 이동</a>는 필요하므로 Drag&amp;Drop 하는 부분까지는 진행을 하자.</p><h3 id="2-업로드한-Gist의-주소를-복사"><a href="#2-업로드한-Gist의-주소를-복사" class="headerlink" title="2. 업로드한 Gist의 주소를 복사"></a>2. 업로드한 Gist의 주소를 복사</h3><p>1번에서 업로드한 Gist의 URL을 복사한다.<br><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://gist.github.com/&#123;id&#125;/&#123;key-value&#125;</span><br></pre></td></tr></table></figure></p><h3 id="3-https-nbviewer-jupyter-org-로-이동"><a href="#3-https-nbviewer-jupyter-org-로-이동" class="headerlink" title="3. https://nbviewer.jupyter.org/ 로 이동"></a>3. <a href="https://nbviewer.jupyter.org/" target="_blank" rel="noopener">https://nbviewer.jupyter.org/</a> 로 이동</h3><p><a href="https://nbviewer.jupyter.org/" target="_blank" rel="noopener">nbviewer 사이트</a>로 이동을 하면,<br><strong>URL | GitHub username | GitHub username/repo | Gist ID</strong> 를 입력하는 Input 창이 있다. 거기에 2번에서 복사한 주소를 넣으면 <strong>해당 Notebook이 Rendering</strong> 된 화면으로 넘어간다.</p><h3 id="4-Hexo-Tag-Plugins를-이용해서-Embedding하면-끝"><a href="#4-Hexo-Tag-Plugins를-이용해서-Embedding하면-끝" class="headerlink" title="4. Hexo Tag Plugins를 이용해서 Embedding하면 끝!"></a>4. Hexo Tag Plugins를 이용해서 Embedding하면 끝!</h3><p>필자는 아래의 Markdown에 html을 같이 사용했다.<br><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">'notebook-embedded'</span>&gt;</span></span></span><br><span class="line">&#123;% iframe https://nbviewer.jupyter.org/gist/&#123;id&#125;/&#123;unknown-value&#125; 100% 100% %&#125;</span><br><span class="line"><span class="xml"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br></pre></td></tr></table></figure></p><p>여기서 굳이 <a href="https://hexo.io/docs/tag-plugins.html" target="_blank" rel="noopener">Hexo Tag Plugins</a>에서 제공한<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;% iframe [width] [height] %&#125;</span><br></pre></td></tr></table></figure></p><p>방식의 표현식을 사용한 것은 Markdown preview에서 iframe이 계속해서 reload되는 것이 싫어서 그랬을 뿐 html 태그를 사용해도 무방하다.</p><p>div에 class를 준 것은 원하는 디자인 틀을 만들기 위해서였고 css는 아래와 같다.<br><figure class="highlight css"><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"><span class="selector-class">.notebook-embedded</span>&#123;</span><br><span class="line">  <span class="attribute">width</span>: <span class="number">100%</span>;</span><br><span class="line">  <span class="attribute">border</span>: <span class="number">1px</span> solid <span class="number">#eee</span>;</span><br><span class="line">  <span class="attribute">border-bottom</span>: <span class="number">40px</span> solid <span class="number">#eee</span>;</span><br><span class="line">  <span class="attribute">border-radius</span>: <span class="number">4px</span>;</span><br><span class="line">  <span class="attribute">height</span>: <span class="number">400px</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><h3 id="5-적용한-결과는-아래와-같다"><a href="#5-적용한-결과는-아래와-같다" class="headerlink" title="5. 적용한 결과는 아래와 같다"></a>5. 적용한 결과는 아래와 같다</h3><div class="notebook-embedded"><iframe src="https://nbviewer.jupyter.org/gist/DanialDaeHyunNam/afc48b2814cd7798ee7dbaa00e321468" width="100%" height="100%" frameborder="0" allowfullscreen></iframe></div>]]></content>
    
    <!-- <summary type="html">
    
    </summary> -->
    
      <category term="Danial Nam" scheme="https://databuzz-team.github.io/categories/Danial-Nam/"/>
    
    
      <category term="Git" scheme="https://databuzz-team.github.io/tags/Git/"/>
    
  </entry>
  
  <entry>
    <title>&lt;Machine Learning&gt; 비대칭 데이터 문제는 어떻게 해결해야 하나?</title>
    <link href="https://databuzz-team.github.io/2018/10/21/Handle-Imbalanced-Data/"/>
    <id>https://databuzz-team.github.io/2018/10/21/Handle-Imbalanced-Data/</id>
    <published>2018-10-21T02:23:13.000Z</published>
    <updated>2020-10-09T10:11:39.114Z</updated>
    
    <content type="html"><![CDATA[<p><br></p><blockquote><p><a href="https://machinelearningmastery.com/tactics-to-combat-imbalanced-classes-in-your-machine-learning-dataset/" target="_blank" rel="noopener">참고 블로그(8 Tactics to Combat Imbalanced Classes in Your Machine Learning Dataset) 링크</a><br><a href="https://machinelearningmastery.com/" target="_blank" rel="noopener">블로거 링크</a></p></blockquote><p>아직 데이터 사이언스에 입문한지 오래되지는 않았지만, 개인 프로젝트로 인스타그램 데이터를 크롤링하여 작업하면서 <strong>비대칭 데이터 문제(Imbalanced Data)</strong> 에 부딪혔다.</p><p>생각해보면 현실세계에서 우리가 예측하고자 하는 클래스가 Uniform하게 분포되어있을 확률은 낮은 것이 당연하다.</p><h3 id="비대칭-데이터란"><a href="#비대칭-데이터란" class="headerlink" title="비대칭 데이터란?"></a>비대칭 데이터란?</h3><p>비대칭 데이터는 일반적으로 분류 문제에서 클래스들이 균일하게 분포하지 않은 문제를 의미한다.</p><p>간단한 예를 들자면, 100개의 과일 사진 중에 사과 사진이 90개, 귤 사진이 10개인 경우다.</p><p>이 경우라면 100개 중에 랜덤하게 뽑은 사진이 무슨 사진인지 맞춰야 한다면 사과라고 말하는 것이 가장 합리적일 것이다. 이것이 비대칭 데이터에서 일어나는 가장 큰 문제점이다.</p><hr><h3 id="비대칭-데이터-문제를-다루는-8가지-전략"><a href="#비대칭-데이터-문제를-다루는-8가지-전략" class="headerlink" title="비대칭 데이터 문제를 다루는 8가지 전략"></a>비대칭 데이터 문제를 다루는 8가지 전략</h3><p>이제 비대칭 문제에 대해서는 이해했을 것이다. 이제 문제를 해결하기 위해 취해야 할 전략(서두에서 링크한 블로그에서 소개한 8가지 전략)을 알아보자.</p><h3 id="1-데이터를-더-모을-수-있나"><a href="#1-데이터를-더-모을-수-있나" class="headerlink" title="1. 데이터를 더 모을 수 있나?"></a>1. 데이터를 더 모을 수 있나?</h3><p>너무 당연한 질문! 더 많은 데이터는 당연히 조금은 더 클래스 대칭적인 결과를 제공할 것이므로..</p><h3 id="2-평가-기준을-바꿔보자"><a href="#2-평가-기준을-바꿔보자" class="headerlink" title="2. 평가 기준을 바꿔보자."></a>2. 평가 기준을 바꿔보자.</h3><p><strong>Accuracy</strong> 는 비대칭 문제에서는 사용하면 안되는 평가 기준이다(<a href="https://en.wikipedia.org/wiki/Accuracy_paradox" target="_blank" rel="noopener">Accuracy Paradox</a>를 참고하자).</p><p>원문 저자는 자신의 포스트 <a href="https://machinelearningmastery.com/classification-accuracy-is-not-enough-more-performance-measures-you-can-use/" target="_blank" rel="noopener">Classification Accuracy is Not Enough: More Performance Measures You Can Use</a> 에서 소개한 평가기준들을 추천했다.</p><ul><li>Confusion Matrix:<br>예측 결과를 테이블 형태로 보여준다.</li><li>Precision:<br>Positive 클래스에 속한다고 출력한 샘플 중 실제로 Positive 클래스에 속하는 샘플 수의 비율</li><li>Recall<br>실제 Positive 클래스에 속한 샘플 중에 Positive 클래스에 속한다고 출력한 표본의 수</li><li>F1 Score<br>정밀도(Precision)과 재현율(Recall)의 가중 조화 평균</li></ul><p>이 외에도</p><ul><li>Kappa(or Cohen’s kappa)<br>Accuracy를 정규화한 값으로 보여준다.</li><li>ROC Curves<br>ROC(Receiver Operator Characteristic) 커브는 클래스 판별 기준값의 변화에 따른 위양성률(fall-out)과 재현율(recall)의 변화를 시각화한 것이다.</li></ul><h3 id="3-데이터셋을-Re-샘플링하자"><a href="#3-데이터셋을-Re-샘플링하자" class="headerlink" title="3. 데이터셋을 Re-샘플링하자."></a>3. 데이터셋을 Re-샘플링하자.</h3><p>데이터 셋을 변형시켜서 전체 클래스의 분포를 균일하게 만드는 방법으로 두 가지 방법이 있다.</p><ol><li>Over-sampling</li><li>Under-sampling</li></ol><p>둘 다 사용해보는 것을 추천한다.</p><p><a href="https://datascienceschool.net/view-notebook/c1a8dad913f74811ae8eef5d3bedc0c3/" target="_blank" rel="noopener">비대칭 데이터 문제</a> &lt;- 이 링크에서 다양한 샘플링 방법을 시각화해서 설명한 자료들이 있으니 확인하자.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 다양한 샘플링 방법을 구현한 파이썬 패키지이다.</span></span><br><span class="line"></span><br><span class="line"><span class="variable">$pip</span> install -U imbalanced-learn</span><br></pre></td></tr></table></figure><h3 id="4-가짜-데이터-샘플을-만들자"><a href="#4-가짜-데이터-샘플을-만들자" class="headerlink" title="4. 가짜 데이터 샘플을 만들자."></a>4. 가짜 데이터 샘플을 만들자.</h3><p>Over sampling의 기법은 가짜 데이터를 더 생성하는 것이니 위의 방법을 좀 더 발전시킨 전략이라고 보면 되겠다.</p><p><strong>Naive Bayes</strong> 알고리즘을 사용할 경우에는 생성도 가능하니 이를 이용하거나, 가장 인기있는 방법인 <strong>SMOTE(Synthetic Minority Over-sampling Technique)</strong> 를 사용하는 것을 추천한다.</p><p>SMOTE는 부족한 클래스의 모조 샘플을 만들어내는 것이다. 이 알고리즘은 2개 이상의 비슷한 객체들을 선택하여 거리를 재고 사이사이 새로운 데이터를 생성해나간다.</p><p>자세한 정보는 <a href="http://www.jair.org/papers/paper953.html" target="_blank" rel="noopener">링크</a>를 확인하자.</p><h3 id="5-다른-Algorithms을-사용해보자"><a href="#5-다른-Algorithms을-사용해보자" class="headerlink" title="5. 다른 Algorithms을 사용해보자."></a>5. 다른 Algorithms을 사용해보자.</h3><p>언제나 그렇듯, 자신이 가장 좋아하는 알고리즘을 모든 문제에 사용하지 않는 것을 추천한다.</p><p><strong>의사 결정 나무(Decision Tree)</strong> 는 비대칭 문제에서 성능이 좋은 경우가 많다.</p><p>C4.5, C5.0, CART and Random Forest 등 다양하게 사용해보는 것을 추천.</p><h3 id="6-모델에-제한을-준다"><a href="#6-모델에-제한을-준다" class="headerlink" title="6. 모델에 제한을 준다."></a>6. 모델에 제한을 준다.</h3><p><strong>Penalized classification(패널티가 있는 분류)</strong> 는 함수를 설정하여 부족한 클래스를 분류하는 것에 오류가 일어나게 만드는 것을 의미한다. 제한사항으로 설정한 함수(패널티 함수)는 부족한 클래스를 분류하는 것에 좀 더 집중을 할 수 있게 한다.</p><blockquote><p>penalized-SVM, penalized-LDA 등 penalized 된 버젼들이 존재한다.<br>그뿐만아니라, 패널라이즈드 모델들을 위해 Framework도 존재하는데, 예를들어 Weka의 <a href="http://weka.sourceforge.net/doc.dev/weka/classifiers/meta/CostSensitiveClassifier.html#CostSensitiveClassifier--" target="_blank" rel="noopener">CostSensitiveClassifier</a>가 있다.</p></blockquote><p>패널티 매트릭스를 만드는 것은 매우 복잡하여, 특정 알고리즘을 써야 하거나 Re-샘플링이 불가능한 경우에 사용하는 것이 좋다.</p><h3 id="7-다른-관점으로-시도하자"><a href="#7-다른-관점으로-시도하자" class="headerlink" title="7. 다른 관점으로 시도하자."></a>7. 다른 관점으로 시도하자.</h3><p>추천하는 방법으로는 <strong>Anomaly Detection</strong>, <strong>Change Detection</strong> 가 있다.</p><ul><li><a href="https://en.wikipedia.org/wiki/Anomaly_detection" target="_blank" rel="noopener">Anomaly Detection</a></li><li><a href="https://en.wikipedia.org/wiki/Change_detection" target="_blank" rel="noopener">Change Detection</a></li></ul><hr><h3 id="결론"><a href="#결론" class="headerlink" title="결론"></a>결론</h3><p>위의 방법들은 당연하게 시행되어야 하는 순서를 보여준다고 생각한다. 조금 허무할 수도 있지만, 결국은 데이터 <strong>사이언티스트(Scientist)</strong> 라는 단어가 의미하듯.. 실험적인 정신을 가지고 다양한 각도에서 도전하고 가장 좋은 결과를 내기 위해 최선을 다해야 한다는 것..</p><hr><h3 id="Related-Posts"><a href="#Related-Posts" class="headerlink" title="Related Posts"></a>Related Posts</h3><p><a href="https://datascienceschool.net/view-notebook/731e0d2ef52c41c686ba53dcaf346f32/" target="_blank" rel="noopener">분류 성능 평가(데이터 사이언스 스쿨)</a></p>]]></content>
    
    <!-- <summary type="html">
    
    </summary> -->
    
      <category term="Danial Nam" scheme="https://databuzz-team.github.io/categories/Danial-Nam/"/>
    
    
      <category term="Machine Learning" scheme="https://databuzz-team.github.io/tags/Machine-Learning/"/>
    
  </entry>
  
  <entry>
    <title>&lt;Medium 블로그 번역&gt; Data Scientists에게 가장 요구되는 기술(Skills)들</title>
    <link href="https://databuzz-team.github.io/2018/10/15/The-Most-in-Demand-Skills-for-Data-Scientists/"/>
    <id>https://databuzz-team.github.io/2018/10/15/The-Most-in-Demand-Skills-for-Data-Scientists/</id>
    <published>2018-10-15T12:28:03.000Z</published>
    <updated>2020-10-09T10:10:45.336Z</updated>
    
    <content type="html"><![CDATA[<p>요즘 글로벌 시장에서 <strong>Data Scientists</strong> 부족으로 난리라고 한다.. 가장 요구되는 기술들이 무엇인지 분석한 기사가 있어서 번역을 통해서 소개하고자 한다 (자세한 내용은 아래의 링크를 통해서 원문을 확인하자).</p><blockquote><p><a href="https://towardsdatascience.com/the-most-in-demand-skills-for-data-scientists-4a4a8db896db" target="_blank" rel="noopener">원문(The Most in Demand Skills for Data Scientists) 링크</a><br><a href="https://towardsdatascience.com/@jeffhale" target="_blank" rel="noopener">저자 Jeff Hale 블로그 링크</a></p></blockquote><p>기사에서는 조사지역은 미국, 키워드는 “Data Scientist”와 “다른 키워드”를 AND 타입으로 검색하여 데이터 사이언티스트와 연관 키워드가 완전히 매칭되는 결과들만을 모아서 조사하였다. 사용한 채용 사이트는 <strong>LinkedIn, Indeed, SimplyHired, Monster, AngelList</strong>로 5가지이다.</p><p>먼저 아래의 그래프를 통해 요구되는 일반적 스킬들에 대해서 알아보자.<br>(그래프를 만드는데 사용된 자료 및 과정은 <a href="https://www.kaggle.com/discdiver/the-most-in-demand-skills-for-data-scientists/" target="_blank" rel="noopener">Jeff Hale Kaggle Kernel</a>을 참고할 것).</p><div><img src="https://cdn-images-1.medium.com/max/800/1*-oG0j_wGSW_9cNNs4_qgFQ.png"><span style="font-size:12px; text-align:center; display:block; color: #999;"><a href="https://towardsdatascience.com/the-most-in-demand-skills-for-data-scientists-4a4a8db896db" target="_blank" rel="noopener">출처 : The Most In Demand Skills For Data Scientists</a></span></div><p>원본 데이터를 통해서 확인해보면 LinkedIn을 제외한 다른 채용사이트들에서는 Analysis의 비중이 더 높았다. 그래서 전체를 Combine한 결과를 보여주는 위의 그래프에서는 Analysis가 가장 비중이 높은 것으로 보이는 것이다.</p><p>원문 저자가 얻은 Insight를 요약하자면,</p><ul><li>Machine Learning은 예측 시스템을 만드는 가장 핵심 기술이므로 가장 요구되는 기술.</li><li>Data Science는 통계 및 Computer Science기술이 필수.</li><li>Communication이 절반에 가까운 잡 포스팅에서 요구되고 있는 점.</li><li>AI, Deep Learning의 빈도수가 높지 않았으나, 이는 Machine Learning의 부분집합이므로 생긴 현상이다.</li><li>Deep Learning의 경우는 점점 더 사용되는 경우가 늘고 있다. 예를 들어 자연어 처리의 경우에도 가장 많이 사용되고 있는 알고리즘은 Deep Learning. <strong>미래에 Deep Learning 스킬이 훨씬 많은 곳에서 요구하게 될 것이며, Machine Learning은 즉 Deep Learning을 의미하게 될 것이라 본다.</strong></li></ul><p>다음으로는 회사가 원하는 <strong>Technology Skills</strong> 에 대해서 살펴보자.</p><div><img src="https://cdn-images-1.medium.com/max/800/1*jnZT4gFAzScOJ_VnYsni0g.png"><span style="font-size:12px; text-align:center; display:block; color: #999;"><a href="https://towardsdatascience.com/the-most-in-demand-skills-for-data-scientists-4a4a8db896db" target="_blank" rel="noopener">출처 : The Most In Demand Skills For Data Scientists</a></span></div><ol><li><strong>Python</strong><br>1위는 Python. 말이 필요 없다.</li><li><strong>R</strong><br>R은 Python과 비중에서 큰 격차를 보이진 않는데, 이는 R이 Python 이전에 Data Science의 필수 언어였기 때문이다. R의 최초 목적은 통계학을 위해서 시작되었고, 아직도 많은 통계학자들에게 사랑을 받는다.</li><li><strong>SQL</strong><br>SQL은 간혹 Data Science 세계에서 무시되는 경우도 있지만, 실제로는 많은 회사에서 요구되며 해당 스킬을 가지고 있으면 채용시장에서 당연히 훨씬 유리하다.</li><li><strong>Hadoop And Spark</strong><br>둘은 모두 Apache에서 제공되는 빅데이터를 위한 Open Source Tool이다.<br>이 두 가지 스킬은 Medium에서나 Tutorial 등이 눈에 띄게 적게 다뤄지고 있다. 지원자(취준) 중에도 앞서 설명한 기술들을 사용하지만 이 두 가지는 못하는 경우가 훨씬 많으므로, Hadoop과 Spark를 할 줄 안다면 채용시장에서 확실히 유리해질 것이다.</li><li><strong>Java and SAS</strong><br>저자는 이 두 가지 스킬이 이렇게 요구되는 사실에 놀랐다. 이 둘은 보통 Data Science 커뮤니티에서 그렇게 주목받고 있지는 않다.</li><li><strong>Tableau</strong><br>Tableau는 분석 플랫폼 및 시각화 도구이며, 사용법이 간편하다. 현재 무료 버젼이 있지만, 데이터를 Private하게 보관하려면 유료이다.</li></ol><p>저자는 만약 <strong>Tableau</strong> 을 사용한 경험이 없다면, Udemy의 <a href="https://www.udemy.com/tableau10/" target="_blank" rel="noopener">Tableau 강의</a> 를 추천했다.</p><p>아래 그래프는 2017년과 2018년을 비교한 것이다.</p><div><img src="https://cdn-images-1.medium.com/max/800/1*iueZKOOBidZtr-FTYyf6QA.png"><span style="font-size:12px; text-align:center; display:block; color: #999;"><a href="https://towardsdatascience.com/the-most-in-demand-skills-for-data-scientists-4a4a8db896db" target="_blank" rel="noopener">출처 : The Most In Demand Skills For Data Scientists</a></span></div><p>전체적으로 비슷하다. 하지만, <strong>R, Hadoop, Java, SAS and Matlab</strong> 의 요구도는 내려가고 있고, <strong>Tableau</strong> 는 확실히 올라가고 있다는 점은 주목할만하다.</p><h4 id="결론-추천-사항들"><a href="#결론-추천-사항들" class="headerlink" title="결론(추천 사항들)"></a>결론(추천 사항들)</h4><ul><li>데이터 분석은 기본, Machine Learning 기술을 높이는데 집중하자.</li><li>Communication 능력에 투자할 것. 추천 책으로는 <a href="https://www.amazon.com/Made-Stick-Ideas-Survive-Others/dp/1400064287" target="_blank" rel="noopener">Made to Stick</a>이 있고, <a href="http://www.hemingwayapp.com" target="_blank" rel="noopener">Hemmingway Editor</a>을 통해서 writing 능력도 키우자.</li><li>Deep Learning 프레임워크들을 마스터하자. Deep Learning 프레임워크을 능숙하게 사용할 수 있어야한다. 저자가 쓴 다른 <a href="https://towardsdatascience.com/deep-learning-framework-power-scores-2018-23607ddf297a" target="_blank" rel="noopener">블로그 글</a>도 참고할 것.</li><li>만약 R과 Python 중에 배울 언어를 고민 중이라면, Python을 선택할 것. 먼저 Python이 능숙하다면 R을 배우는 것을 고려해볼 것(채용시장에서 더 유리할 것이다).</li></ul><p>회사에서 Python을 사용하는 Data Scientist을 구한다는 것은 당연히 Data Science Libraries(<strong>numpy, pandas, scikit-learn, matplotlib 등</strong>)를 다루길 기대하는 것이다.</p><p>만약 Deep learning을 배우고자 한다면, <strong>Keras, FastAI</strong> 를 <strong>TensorFlow or PyTorch</strong> 이전에 시작할 것을 추천한다. Keras 공부를 위한 추천 책은 <a href="https://www.amazon.com/Deep-Learning-Python-Francois-Chollet/dp/1617294438" target="_blank" rel="noopener">Deep Learning with Python</a>이다.</p><p>끝으로 채용사이트는 <strong>LinkedIn</strong>을 추천한다.</p>]]></content>
    
    <!-- <summary type="html">
    
    </summary> -->
    
      <category term="Danial Nam" scheme="https://databuzz-team.github.io/categories/Danial-Nam/"/>
    
    
      <category term="Data Science" scheme="https://databuzz-team.github.io/tags/Data-Science/"/>
    
      <category term="Tech News" scheme="https://databuzz-team.github.io/tags/Tech-News/"/>
    
  </entry>
  
  <entry>
    <title>&lt;MACHINE LEARNING&gt; CHAPTER1. 한눈에 보는 머신 러닝</title>
    <link href="https://databuzz-team.github.io/2018/10/13/hands-on-chapter1/"/>
    <id>https://databuzz-team.github.io/2018/10/13/hands-on-chapter1/</id>
    <published>2018-10-13T05:34:56.000Z</published>
    <updated>2018-10-28T09:55:53.090Z</updated>
    
    <content type="html"><![CDATA[<p>Hands-On Machine Learning with Scikit-Learn &amp; TensorFlow 책을 읽고 공부하면서 내용을 요약하고 정리한 것입니다.<br><a id="more"></a></p><h3 id="1-1-머신-러닝이란"><a href="#1-1-머신-러닝이란" class="headerlink" title="1.1 머신 러닝이란?"></a>1.1 머신 러닝이란?</h3><blockquote><p>어떤 작업 T에 대한 컴퓨터 프로그램의 성능을 P로 측정했을 때 경험E로 인해 성능이 향상됐다면, 이 컴퓨터 프로그램은 작업 T와 성능 측정 P에 대해 경험 E로 학습한 것이다.</p><pre><code>                                     - 톰 미첼(Tom Mitchell, 1997)</code></pre></blockquote><p>위키백과 문서를 모두 내려받는 것 -&gt; 많은 데이터를 갖게 되는 것 : 머신 러닝 X</p><h3 id="1-2-왜-머신-러닝을-사용하는가"><a href="#1-2-왜-머신-러닝을-사용하는가" class="headerlink" title="1.2 왜 머신 러닝을 사용하는가?"></a>1.2 왜 머신 러닝을 사용하는가?</h3><ul><li>기존 솔루션으로는 많은 수동 조정과 규칙이 필요한 문제 : 하나의 머신러닝 모델이 코드를 간단하고 더 잘 수행되도록 할 수 있습니다.</li><li>전통적인 방식으로는 전혀 해결 방법이 없는 복잡한 문제 : 가장 뛰어난 머신러닝 기법으로 해결 방법을 찾을 수 있습니다.</li><li>유동적인 환경 : 머신러닝 시스템은 새로운 데이터에 적응할 수 있습니다.</li><li>복잡한 문제와 대량의 데이터에서 통찰 얻기</li></ul><h3 id="1-3-머신러닝-시스템의-종류"><a href="#1-3-머신러닝-시스템의-종류" class="headerlink" title="1.3 머신러닝 시스템의 종류"></a>1.3 머신러닝 시스템의 종류</h3><ul><li>사람의 감독 하에 훈련하는 것인지 그렇지 않은 것인지(지도, 비지도, 준지도, 강화 학습)</li><li>실시간으로 점진적인 학습을 하는지 아닌지(온라인 학습과 배치 학습)</li><li>단순하게 알고 있는 데이터 포인트와 새 데이터 포인트를 비교하는 것인지 아니면 훈련 데이터셋에서 과학자들처럼 패턴을 발견하여 예측 모델을 만드는지(사례 기반 학습과 모델 기반 학습)</li></ul><p>-&gt; 서로 배타적이지 않으며 연결 가능</p><h4 id="1-3-1-지도-학습과-비지도-학습"><a href="#1-3-1-지도-학습과-비지도-학습" class="headerlink" title="1.3.1  지도 학습과 비지도 학습"></a>1.3.1  지도 학습과 비지도 학습</h4><p>학습하는 동안의 감독 형태나 정보량’에 따라 분류</p><h4 id="지도학습-supervised-learning"><a href="#지도학습-supervised-learning" class="headerlink" title="지도학습(supervised learning)"></a>지도학습(supervised learning)</h4><p>-&gt; 훈련데이터에 레이블 포함</p><ul><li>회귀(regression) : <strong>예측 변수</strong><sup>predictor variable</sup>라 부르는 <strong>특성</strong><sup>featrue</sup>(주행거리, 연식, 브랜드 등)을 사용해 중고차 가격 같은 <strong>타깃</strong> 수치를 예측하는 것</li><li>분류 (Classification) : 전형적 지도 학습</li></ul><p>가장 중요한 지도 학습 알고리즘</p><ul><li>k-최근접 이웃 <sup> k-Nearest Neighbors</sup></li><li>선형 회귀 <sup>Linear Regression</sup></li><li>로지스틱 회귀 <sup>Logistic Regression</sup></li><li>서포트 벡터 머신 <sup>Support Vector Machines(SVM)</sup></li><li>결정 트리 <sup>Decision Tree</sup>와 랜덤 포레스트 <sup>Random Forests</sup></li><li>신경망 <sup>Neural networks</sup></li></ul><h4 id="비지도-학습-unsupervised-learning"><a href="#비지도-학습-unsupervised-learning" class="headerlink" title="비지도 학습(unsupervised learning)"></a>비지도 학습(unsupervised learning)</h4><p>-&gt; 훈련데이터에 레이블 미포함</p><p>가장 중요한 비지도 학습 알고리즘</p><ul><li>군집 <sup>clustering</sup><ul><li>k-평균<sup>k-Means</sup></li><li>계층 군집 분석<sup>Hierarchical Cluster Analysis</sup>(HCA)</li><li>기댓값 최대화<sup>Expectation Maximization</sup></li></ul></li><li>시각화<sup>visualization</sup>와 차원 축소<sup>dimensionality reduction</sup><ul><li>주성분 분석<sup>Principal Component Analysis</sup>(PCA)</li><li>커널<sup>kernel</sup>PCA</li><li>지역적 선형 임베딩<sup>Locally-Linear Embedding</sup>(LLE)</li><li>t-SNE<sup>t-distributed Stochastic Neighbor Embedding</sup></li></ul></li><li>연관 규칙 학습<sup>Assiociation rule learning</sup><ul><li>어프라이어리<sup>Apriori</sup></li><li>이클렛<sup>Eclat</sup></li></ul></li></ul><p>시각화<sup>visualization</sup>알고리즘 : 도식화 가능한 2D나 3D 표현 , 가능한 구조 유지<br>차원 축소<sup>dimensionality reduction</sup> : 상관관계가 있는 여러 특성을 하나로 합치는 것  ex) 주행거리, 연식 -&gt; 차의 마모 (<strong>특성 추출</strong>)<br>이상치 탐지<sup>anomaly detection</sup> : 학습 알고리즘 주입 전 데이터셋에 이상한 값을 자동으로 제거<br>연관 규칙 학습<sup>association rule learning</sup> : 대량의 데이터에서 특성 간의 흥미로운 관계</p><h4 id="준지도-학습semisupervised-learning"><a href="#준지도-학습semisupervised-learning" class="headerlink" title="준지도 학습semisupervised learning"></a>준지도 학습<sup>semisupervised learning</sup></h4><p>레이블이 일부만 존재</p><h4 id="강화-학습Reinforcement-Learning"><a href="#강화-학습Reinforcement-Learning" class="headerlink" title="강화 학습Reinforcement Learning"></a>강화 학습<sup>Reinforcement Learning</sup></h4><p>학습하는 시스템을 <strong>에이전트</strong>, 환경을 관찰해서 행동을 실행하고 보상 또는 벌점을 받습니다. 가장 큰 보상을 얻기 위해 <strong>정책</strong><sup>policdy</sup>이라 부르는최상 전략을 스스로 학습합니다.</p><h4 id="1-3-2-배치-학습과-온라인-학습"><a href="#1-3-2-배치-학습과-온라인-학습" class="headerlink" title="1.3.2 배치 학습과 온라인 학습"></a>1.3.2 배치 학습과 온라인 학습</h4><p>입력 데이터의 스트림<sup>stream</sup>으로부터 점진적으로 학습할 수 있는 여부</p><p><strong>배치 학습</strong><sup>batch learning</sup></p><ul><li>가용한 데이터를 모두 사용해 훈련</li><li>제품 시스템에 적용하면 더 이상의 학습없이 실행</li><li>많은 컴퓨팅 자원 필요(CPU, 메모리 공간, 디스크 공간, 디스크 IO, 네트워크 IO 등)</li><li>자원이 제한된 시스템(예 - 스마트폰, 화성 탐사 로버)이 스스로 학습해야 할 때 많은 자원 사용하면 심각한 문제</li></ul><p><strong>온라인 학습</strong><sup>online learning</sup></p><ul><li>데이터를 순차적으로 한 개씩 또는 미니배치<sup>mini-batch</sup>라 부르는 작은 묶음 단위로 주입</li><li>빠른 변화에 스스로 적응해야하는 시스템에 적합, 컴퓨팅 자원이 제한된 경우</li><li>메인 메모리에 들어갈 수 없는 아주 큰 데이터셋을 학습하는 시스템(<strong>외부 메모리</strong><sup>out-of-core</sup> 학습)</li><li>전체 프로세스는 보통 오프라인, 따라서 <strong>점진적 학습</strong><sup>incremental learning</sup>으로 생각</li><li><strong>학습률</strong><sup>learning rate</sup> : 변화는 데이터에 얼마나 빠르게 적응할 것</li></ul><h4 id="1-3-3-사례-기반-학습과-모델-기반-학습"><a href="#1-3-3-사례-기반-학습과-모델-기반-학습" class="headerlink" title="1.3.3 사례 기반 학습과 모델 기반 학습"></a>1.3.3 사례 기반 학습과 모델 기반 학습</h4><p>어떻게 <strong>일반화</strong>되는가에 따라 분류</p><p><strong>사례 기반 학습</strong><sup>instance-based learning</sup></p><ul><li><strong>유사도</strong><sup>similarity</sup>를 측정하여 새로운 데이터를 일반화</li></ul><p><strong>모델 기반 학습</strong><sup>model-based learning</sup></p><ul><li>모델을 만들어 <strong>예측</strong>에 사용<ul><li>데이터를 분석</li><li>모델 선택</li><li>훈련 데이터로 모델 훈련(비용 함수<sup>cost function</sup> 최소화 하는 모델 파라미터 탐색)</li><li>새로운 데이터에 모델을 적용해 예측, 잘 일반화되길 기대</li></ul></li></ul><h3 id="1-4-머신러닝의-주요-도전-과제"><a href="#1-4-머신러닝의-주요-도전-과제" class="headerlink" title="1.4 머신러닝의 주요 도전 과제"></a>1.4 머신러닝의 주요 도전 과제</h3><p>문제점</p><ol><li>나쁜 알고리즘</li><li>나쁜 데이터</li></ol><h4 id="1-4-1-충분하지-않은-양의-훈련-데이터"><a href="#1-4-1-충분하지-않은-양의-훈련-데이터" class="headerlink" title="1.4.1 충분하지 않은 양의 훈련 데이터"></a>1.4.1 충분하지 않은 양의 훈련 데이터</h4><h4 id="1-4-2-대표성-없는-훈련-데이터"><a href="#1-4-2-대표성-없는-훈련-데이터" class="headerlink" title="1.4.2 대표성 없는 훈련 데이터"></a>1.4.2 대표성 없는 훈련 데이터</h4><ul><li>샘플이 작으면 <strong>샘플링 잡음</strong><sup>sampling noise</sup>(즉, 우연에 의한 대표성 없는 데이터)</li><li>샘플이 큰 경우도 추출 방법이 잘못된 경우 <strong>샘플링 편향</strong><sup>sampling bias</sup></li></ul><h4 id="1-4-3-낮은-품질의-데이터"><a href="#1-4-3-낮은-품질의-데이터" class="headerlink" title="1.4.3 낮은 품질의 데이터"></a>1.4.3 낮은 품질의 데이터</h4><ul><li>에러, 이상치<sup>outlier</sup>, 잡음</li><li>이상치가 명확하면 무시하거나 수동으로 잘못된 것을 고침</li><li>일부 특성 중 데이터가 누락된 경우 특성을 무시할지, 샘플을 무시할지, 빠진값을 채울지, 특성을 넣은 모델과 제외한 모델을 따로 훈련 시킬것인지 결정</li></ul><h4 id="1-4-4-관련-없는-특성"><a href="#1-4-4-관련-없는-특성" class="headerlink" title="1.4.4 관련 없는 특성"></a>1.4.4 관련 없는 특성</h4><ul><li><strong>특성 공학</strong><sup>feature engineering</sup> : 훈련에 사용할 좋은 특성들을 찾는 것<ul><li><strong>특성 선택</strong><sup>feature selection</sup> : 가지고 있는 특성 중에서 훈련에 가장 유용한 특성을 선택</li><li><strong>특성 추출</strong><sup>feature extraction</sup> : 특성을 결합하여 더 유용한 특성을 만듬(차원 축소 알고리즘)</li><li>새 특성을 만듬</li></ul></li></ul><h4 id="1-4-5-훈련-데이터-과대적합"><a href="#1-4-5-훈련-데이터-과대적합" class="headerlink" title="1.4.5 훈련 데이터 과대적합"></a>1.4.5 훈련 데이터 과대적합</h4><ul><li><strong>과대적합</strong><sup>overfitting</sup> : 모델이 훈련 데이터에 너무 잘 맞지만 일반성이 떨어짐<ul><li>훈련 데이터에 있는 잡음의 양에 비해 모델이 너무 복잡할 때 발생</li><li>파라미터 수가 적은 모델 선택, 훈련데이터에 특성수를 줄임, 모델에 제약을 가하여 단순화(<strong>하이퍼파라미터</strong><sup>hyperparameter</sup> : 학습하는 동안 적용할 규제의 양, 학습 알고리즘의 파라미터)</li><li>훈련 데이터를 더 많이 모음</li><li>훈련 데이터의 잡음을 줄임</li></ul></li></ul><h4 id="1-4-6-훈련-데이터-과소적합"><a href="#1-4-6-훈련-데이터-과소적합" class="headerlink" title="1.4.6 훈련 데이터 과소적합"></a>1.4.6 훈련 데이터 과소적합</h4><ul><li><strong>과소적합</strong><sup>underfitting</sup> : 모델이 너무 단순해서 데이터의 내재된 구조를 학습하지 못할 때<ul><li>파라미터가 더 많은 강력한 모델 선택</li><li>더 좋은 특성 제공(특성 엔지니어링)</li><li>모델의 제약을 줄임( 규제 하이퍼파라미터를 감소)</li></ul></li></ul><h3 id="1-5-테스트와-검증"><a href="#1-5-테스트와-검증" class="headerlink" title="1.5 테스트와 검증"></a>1.5 테스트와 검증</h3><ul><li><strong>훈련 세트</strong> 와 <strong>테스트 세트</strong> 로 나누어 훈련<ul><li><strong>일반화 오차</strong><sup>generalization error</sup>(<strong>외부 샘플 오차</strong><sup>out-of-sample erro</sup>) : 새로운 샘플에 대한 오류 비율</li><li>훈련 오차가 낮지만 일반화 오차가 높다면 과대 적합</li></ul></li><li><strong>검증 세트</strong><sup>validation set</sup><ul><li><strong>교차 검증</strong><sup>cross-validation</sup> 기법</li></ul></li></ul>]]></content>
    
    <!-- <summary type="html">
    
      &lt;p&gt;Hands-On Machine Learning with Scikit-Learn &amp;amp; TensorFlow 책을 읽고 공부하면서 내용을 요약하고 정리한 것입니다.&lt;br&gt;
    
    </summary> -->
    
      <category term="HyunGeun Yoon" scheme="https://databuzz-team.github.io/categories/HyunGeun-Yoon/"/>
    
    
      <category term="Machine Learning" scheme="https://databuzz-team.github.io/tags/Machine-Learning/"/>
    
  </entry>
  
  <entry>
    <title>&lt;Hexo&gt; 블로그에 수식 사용하기 - mathjax 설정</title>
    <link href="https://databuzz-team.github.io/2018/10/13/hexo-mathjax/"/>
    <id>https://databuzz-team.github.io/2018/10/13/hexo-mathjax/</id>
    <published>2018-10-13T05:30:55.000Z</published>
    <updated>2018-10-28T09:55:53.091Z</updated>
    
    <content type="html"><![CDATA[<p>필자의 개인 블로그에 포스팅한 내용을 가져와 소개합니다. (<a href="https://hyeshinoh.github.io/2018/10/24/hexo_mathjax_00/" target="_blank" rel="noopener">원문 블로그</a>)</p><p>Hexo 블로그에서 LaTex로 수식을 작성할 수 있도록 mathjax를 설정하는 방법을 정리해보겠습니다.</p><h2 id="1-설치"><a href="#1-설치" class="headerlink" title="1. 설치"></a>1. 설치</h2><h3 id="1-renderer-설치-및-세팅"><a href="#1-renderer-설치-및-세팅" class="headerlink" title="1) renderer 설치 및 세팅"></a>1) renderer 설치 및 세팅</h3><p>Hexo의 기본 renderer인 hexo-renderer-marked는 mathjax 문법을 지원하지 않는다고 합니다. 따라서 다음과 같이 새로운 rendering engine으로 교체해줍니다.</p><p><code>$ npm uninstall hexo-renderer-marked --save</code><br><code>$ npm install hexo-renderer-kramed --save</code></p><p>그리고 <code>&lt;your-project-dir&gt;/node_modules/hexo-reneder-kramed/lib/renderer.js</code>를 열어 다음과 같이 return 값을 text로 수정합니다.</p><figure class="highlight javascript"><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"><span class="comment">// Change inline math rule</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">formatText</span>(<span class="params">text</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// Fit kramed's rule: $$ + \1 + $$</span></span><br><span class="line">  <span class="comment">// return text.replace(/`\$(.*?)\$`/g, '$$$$$1$$$$');</span></span><br><span class="line">  <span class="keyword">return</span> text;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="2-mathjax-설치"><a href="#2-mathjax-설치" class="headerlink" title="2) mathjax 설치"></a>2) mathjax 설치</h3><p>다음으로는 mathjax plugin을 설치합니다.<br><code>npm install hexo-renderer-mathjax --save</code></p><p>그리고 <code>&lt;your-project-dir&gt;/node_modules/hexo-reneder-mathjax/mathjax.html</code>을 열고 CDN URL을 아래와 같이 수정합니다.</p><figure class="highlight html"><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="comment">&lt;!-- &lt;script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"&gt;&lt;/script&gt; --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML'</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="2-LaTex와-markdown의-문법-충돌-fix하기"><a href="#2-LaTex와-markdown의-문법-충돌-fix하기" class="headerlink" title="2. LaTex와 markdown의 문법 충돌 fix하기"></a>2. LaTex와 markdown의 문법 충돌 fix하기</h2><p>LaTex와 markdown에는 다음과 같이 문법이 충돌하는 부분이 있습니다. </p><ul><li>markdown: <code>*</code>과 <code>_</code>는 bold와 italic</li><li>LaTex: <code>_</code>는 subscript</li></ul><p>따라서 <code>_</code>는 LaTex의 문법만을 따라서 아랫첨자를 나타내도록 하기위해<code>node_modules\kramed\lib\rules\inline.js</code>를 열고 다음과 같이 수정합니다.</p><figure class="highlight plain"><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">escape: /^\\([`*\[\]()#$+\-.!_&gt;])/,</span><br><span class="line">em: /^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,</span><br></pre></td></tr></table></figure><h2 id="3-Mathjax-사용하기"><a href="#3-Mathjax-사용하기" class="headerlink" title="3. Mathjax 사용하기"></a>3. Mathjax 사용하기</h2><p>사용하고 있는 theme의 <code>_config.yml</code> 파일을 열고 다음과 같이 mathjax를 enabling 해줍니다.</p><figure class="highlight plain"><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">mathjax:</span><br><span class="line">  enable: true</span><br></pre></td></tr></table></figure><h2 id="4-markdown-post-작성하기"><a href="#4-markdown-post-작성하기" class="headerlink" title="4. markdown post 작성하기"></a>4. markdown post 작성하기</h2><p>이제 hexo 블로그에 수식을 사용하기 위한 설정은 모두 마쳤습니다.<br>마지막으로 post 작성시 header 부분에 <code>mathjax: true</code>를 넣어주면 블로그에 수식이 잘 표현되게 됩니다.</p><h4 id="참고-자료"><a href="#참고-자료" class="headerlink" title="참고 자료"></a>참고 자료</h4><ul><li>블로그 <a href="https://www.infiniteft.xyz/2018/03/21/make-hexo-support-latex/" target="_blank" rel="noopener">Make Hexo Support Latex</a></li><li>블로그 <a href="https://irongaea.github.io/2018/08/21/hexo-inline-math/" target="_blank" rel="noopener">hexo-inline-math</a></li><li>블로그 <a href="https://johngrib.github.io/wiki/mathjax-latex/#3-%EB%8F%84%EA%B5%AC" target="_blank" rel="noopener">MathJax로 LaTeX 사용하기</a></li><li><a href="https://www.mathjax.org/#gettingstarted" target="_blank" rel="noopener">www.mathjax.org</a></li></ul>]]></content>
    
    <!-- <summary type="html">
    
    </summary> -->
    
      <category term="HyeShin Oh" scheme="https://databuzz-team.github.io/categories/HyeShin-Oh/"/>
    
    
      <category term="Hexo" scheme="https://databuzz-team.github.io/tags/Hexo/"/>
    
      <category term="Mathjax" scheme="https://databuzz-team.github.io/tags/Mathjax/"/>
    
  </entry>
  
  <entry>
    <title>&lt;DataBuzz&gt; 블로그 작성법 및 주의사항</title>
    <link href="https://databuzz-team.github.io/2018/10/10/How-To-Use/"/>
    <id>https://databuzz-team.github.io/2018/10/10/How-To-Use/</id>
    <published>2018-10-10T09:04:34.000Z</published>
    <updated>2018-10-13T07:04:42.780Z</updated>
    
    <content type="html"><![CDATA[<h3 id="Hexo-Scaffolds란"><a href="#Hexo-Scaffolds란" class="headerlink" title="Hexo Scaffolds란?"></a>Hexo Scaffolds란?</h3><p>hexo new -[page/post/draft 등] 을 실행했을 때 Default로 들어갈 정보를 입력하는 공간이다.</p><h3 id="1-Scaffolds-post-md-파일-수정하기"><a href="#1-Scaffolds-post-md-파일-수정하기" class="headerlink" title="1. Scaffolds/post.md 파일 수정하기"></a>1. Scaffolds/post.md 파일 수정하기</h3><figure class="highlight bash"><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"><span class="comment"># /scaffolds/post.md</span></span><br><span class="line">---</span><br><span class="line">title: &#123;&#123; title &#125;&#125;</span><br><span class="line">date: &#123;&#123; date &#125;&#125;</span><br><span class="line">categories:</span><br><span class="line">  - <span class="string">"Danial Nam"</span> &lt;- 이 부분을 자신의 이름으로 변경한다.</span><br><span class="line">tags:</span><br><span class="line">  -</span><br><span class="line">thumbnail:</span><br><span class="line">---</span><br></pre></td></tr></table></figure><h3 id="2-New-post-추가하기"><a href="#2-New-post-추가하기" class="headerlink" title="2. New post 추가하기"></a>2. New post 추가하기</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo new post <span class="string">"제목"</span></span><br></pre></td></tr></table></figure><h3 id="3-Title"><a href="#3-Title" class="headerlink" title="3. Title"></a>3. Title</h3><figure class="highlight bash"><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">Title에는 []를 사용할 경우 오류가난다.</span><br><span class="line">필요시에는 &lt;&gt;로 대체할 것.</span><br></pre></td></tr></table></figure><h3 id="4-Tags"><a href="#4-Tags" class="headerlink" title="4. Tags"></a>4. Tags</h3><figure class="highlight bash"><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">깔끔한 블로그 관리를 위하여 Tag는 영어 Full Name으로 표기하며,</span><br><span class="line">파스칼케이스를 사용한다.</span><br><span class="line"></span><br><span class="line"><span class="comment"># Depth 및 Indent에 주의할 것!</span></span><br><span class="line">tags:</span><br><span class="line">  - Artificial Intelligence</span><br><span class="line">  - Data Science</span><br><span class="line">  -</span><br><span class="line"></span><br><span class="line">예)</span><br><span class="line">  AI -&gt; Artificial Intelligence</span><br><span class="line">  Data science -&gt; Data Science</span><br></pre></td></tr></table></figure><h3 id="5-Deploy-중요함"><a href="#5-Deploy-중요함" class="headerlink" title="5. Deploy(중요함!!)"></a>5. Deploy(중요함!!)</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sh post.sh</span><br><span class="line"><span class="comment"># 반드시 위의 명령을 실행하여 업로드한다!</span></span><br><span class="line"><span class="comment"># hexo g -d 명령을 사용해서 업로드해서는 안된다!!</span></span><br></pre></td></tr></table></figure><p>마지막에 Git pull해라는 오류가 뜨면, Pull을 실행하고 다시 sh post.sh로 재업로드해줄것!</p>]]></content>
    
    <!-- <summary type="html">
    
    </summary> -->
    
      <category term="Danial Nam" scheme="https://databuzz-team.github.io/categories/Danial-Nam/"/>
    
    
      <category term="Data Science" scheme="https://databuzz-team.github.io/tags/Data-Science/"/>
    
  </entry>
  
</feed>
