<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>reniew's blog</title>
 <link href="https://reniew.github.io/atom.xml" rel="self"/>
 <link href="https://reniew.github.io/"/>
 <updated>2020-06-20T18:25:14+00:00</updated>
 <id>https://reniew.github.io</id>
 <author>
   <name>reniew</name>
   <email></email>
 </author>

 
 <entry>
   <title>ALBERT: A Lite BERT For Self-Supervised Learning of Language Representations</title>
   <link href="https://reniew.github.io/49/"/>
   <updated>2020-03-10T07:41:15+00:00</updated>
   <id>https://reniew.github.io/49</id>
   <content type="html">&lt;p&gt;오늘은 2019년 google research에서 나온 논문인 &lt;a href=&quot;https://arxiv.org/pdf/1909.11942.pdf&quot;&gt;ALBERT: A Lite BERT For Self-Supervised Learning of Language Representations&lt;/a&gt;에 대해서 알아보도록 한다. 기존의 다양한 BERT의 후속 논문들이 모델 사이즈를 늘리며 성능을 올리던 것을 지적하며, ALBERT는 GPU memory를 효율적으로 사용하면서 모델 성능을 향상시킨 모델이다. 2020년 2월 현재 &lt;a href=&quot;https://rajpurkar.github.io/SQuAD-explorer/&quot;&gt;SQuAD 2.0 Leaderboard&lt;/a&gt;를 보면    1등부터 8등까지 랭크하고 있는 모델들이 모두 ALBERT를 활용한 모델이다.&lt;/p&gt;

&lt;p&gt;이렇게 BERT의 GPU-utilize를 효율적으로 개선했음에도 불구하고 향상된 성능을 보이는 ALBERT에 대해서 알아보도록 하자.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;introduction&quot;&gt;Introduction&lt;/h3&gt;

&lt;p&gt;Fully network pre-training(BERT, GPT, ULMFiT) 방법들은 계속해서 language representation learning 분야에서 breakthrough를 가져왔다.
데이터가 부족한 많은 NLP task에서 이러한 방법들은 pre-trained을 효과적으로 적용되어왔다.&lt;/p&gt;

&lt;p&gt;다양한 pre-training 방법론들에서 Large size의 network를 사용하는 것이 성능을 향상시키는데 중요한 역할을 했다. 또한, pre-trained large network를 smaller한 network로  distilling시키는 방법들도 많이 제시되었다.
이러한 흐름을 바탕으로 우리는 “더 큰 모델을 가지는 것이 더 좋은 NLP 모델을 만드는 방법인가?” 라는 질문을 한다.&lt;/p&gt;

&lt;p&gt;하지만 이러한 질문에 대한 대답에서 문제가 되는 부분은 더 큰 모델을 사용한다는 것은 GPU memory에 제약을 받는다는 점이다. 최근의 다양한 높은 성능을 보이는 모델들을 매우 많은 파라미터들을 가지고 있고, 실제로 이를 이용해보려 하면 memory 제약을 쉽게 경험 할 수 있다.&lt;/p&gt;

&lt;p&gt;이러한 memory limitation을 다룬 여러 방법들(model parallelization, clever memory management)이 있었지만 이는 결국 communication overhead는 다루지 못헀다.&lt;/p&gt;

&lt;p&gt;따라서 이 논문에서 앞서 언급한 문제점들을 해결하는 더 작은 파라미터를 가진 A Lite BERT(ALBERT) architecture를 소개한다.&lt;/p&gt;

&lt;p&gt;ALBERT는 두 가지 parameter reduction 기법을 사용한다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Factorized embedding parameterization&lt;/li&gt;
  &lt;li&gt;Cross-layer parameter sharing&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;첫 번째 Factorized embedding parameterization 방법은 기존의 큰 embedding matrix를 두개의 matrix로 나눠 파라미터 수를 줄였고. 두 번째 Croos-layer parameter sharing은 모델의 깊이가 깊어질 수록 파라미터 개수가 선형적으로 늘어나는 것을 방지한다.&lt;/p&gt;

&lt;p&gt;이러한 방법들을 통해 ALBERT는 BERT-large모델에 비해 18배 적은 파라미터를 가지고 1.7배 빠르게 학습된다.&lt;/p&gt;

&lt;p&gt;추가적인 성능향상을 위해 ALBERT는 self-supervised loss인 SOP(Sentence order prediction) loss를 사용한다. 이 loss는 기존의 NSP loss의 비효율성을 개선하기 위해 사용한다.&lt;/p&gt;

&lt;h3 id=&quot;the-elements-of-albert&quot;&gt;The Elements of ALBERT&lt;/h3&gt;

&lt;h4 id=&quot;model-architecture-choices&quot;&gt;Model Architecture choices&lt;/h4&gt;

&lt;p&gt;ALBERT의 기본 architecture는 BERT와 유사하다. Transformer의 Encoder 구조와 함께 GELU activation function을 사용했다. 여기서 notation은 기존의 BERT에서와 동일하게 사용한다. embedding size는 $E$, encoder layer의 수를 $L$, hidden size를 $H$로 표기한다.
기존 BERT와 동일하게 feed-forward의 size를 $4H$로 attention head 수를 $H/64$로 사용했다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Factorized embedding parameterization&lt;/strong&gt;
BERT에서 WordPiece embedding size $E$와 모델의 hidden layer size $H$는 동일하게 설정되어 있다. 이러한 설정은 모델링 측면과, 실용적인 부분에 최적의 방법이 아니다.&lt;/p&gt;

&lt;p&gt;그 이유에 대해서 얘기하자면 우선 모델링 관점에서 보면, WordPiece embedding 은 context-independent한 representation인 반면 hidden-layer embedding의 경우 context-dependent한 representation이다.
&lt;a href=&quot;https://arxiv.org/pdf/1907.11692.pdf&quot;&gt;RoBERTa: A robustly optimized BERT pretraining approach.&lt;/a&gt; 에서의 context length에 관한 실험에서 볼 수 있듯이 BERT-like representation의 효과는 context-dependent한 representation을 학습하는데 있다.
따라서 WordPiece embedding size인 $E$와 hidden layer size인 $H$를 다르게 설정하는 것이 더 효과적인 모델 파라미터들의 활용일 수 있다.&lt;/p&gt;

&lt;p&gt;실용적인 관점에서 보면, NLP 모델들은 vocabulary size $V$를 가지는데, 대부분 매우 큰 값을 가진다. 이 떄 앞서 말했던 $E$와 $H$를 동일하게 설정한다면 자연스럽게 embedding matrix의 파라미터 수인  $V \times E$가 커지게 된다. 이 값은 보통 $E=H$ 로 설정한다면 쉽게 10억개 이상의 파라미터를 가지고 학습 속도를 매우 느리게 한다.&lt;/p&gt;

&lt;p&gt;따라서 ALBERT에서는 factorization of embedding parameters를 사용한다. 이는 큰 embedding matrix를 작은 두개의 matrix로 나누는 방법으로 먼저 기존에 $E$ dimension으로 바로 mapping 했던 것을 보다 작은 dimension인 $E$로 mapping한 후 $E$ dimension의 vector를 다시 $H$ dimension으로 보낸다.
이렇게 되면 기존에  $V \times H$ 였던 파라미터 수는 $V \times E + E \times H$으로 줄어들게 된다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cross-layer parameter sharing&lt;/strong&gt;
ALBERT에서는 cross-layer paraeter sharing 기법을 사용한다. 이는 파라미터를 효율성을 향상시킨다. Parameter를 sharing하는 다양한 방법들이 존재한다. 예를들면 Transformer network에서 FFN(Feed-Forward Network)의 파라미터만 공유하거나, attention parameter만 공유한다던지. ALBERT에서는 모든 parameter들을 공유한다.&lt;/p&gt;

&lt;p&gt;Universail Transformer(Dehghani et al., 2018)와 Deep Equilibrium Models, DQE(Bai et al., 2019)에서 이와 유사한 방법이 사용되었다. ALBERT와 다른점은 UT에서는 기존의 vanilla Transformer 보다 높은 성능을 보이고, DQE에서는 특정 layer에서의 embedding의 input과 output이 동일해지는 equilibrium point에 도달한다는 것을 확인 할 수 있다.
우리의 실험에서는 embedding의 L2 distance 및 cosine similarity가 converge 하지 않고 oscillating한 것을 확인 할 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/TZaHMcT.png&quot; alt=&quot;figure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위의 그림을 통해 layer를 통한 transition이 ALBERT에서가 BERT에 비해 더 smoother한 것을 확인 할 수 있다. 즉, 이러한 결과는 weight-sharing이 network parameter들을 stabilizing하는데 효과가 있다는 것을 보여준다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inter-sentence coherence loss&lt;/strong&gt;
Masked Language Modeling(MLM) loss와 더불어 BERT 는 Next-Sentence Prediction loss를 사용했다. NSP는 입력값으로 들어간 두 문장이 이어진 문장인지, 아니면 관계없는 문장인지를 예측하는 binary classification task이다. NSP는 기본적으로 sentence pair의 관계를 capture하는 downstream task의 성능 향상을 위해 설계되었다. 하지만 최근 RoBERTa(Liu et al., 2019), XLNet(Yang et al., 2019)등 다양한 연구에서 NSP의 효과에 대해서 의문을 제기하고, NSP loss를 제거하고 pre-train을 진행하고 있다. 그리고 이러한 결과는 여러 downstream task에서 성능의 향상을 가져 왔다.&lt;/p&gt;

&lt;p&gt;우리는 이러한 NSP의 비효율성의 이유를 task가 MLM에 대비해서 매우 쉬운데에 있을거라 추측한다. NSP는 하나의 task로 &lt;em&gt;topic prediction&lt;/em&gt; 과 &lt;em&gt;coherence prediction&lt;/em&gt; 두 개의 예측을 진행한다. 이 때 topic prediction 은 상대적으로 coherence prediction에 비해 매우 쉽고, MLM과 겹치는 부분이 상당수이다.&lt;/p&gt;

&lt;p&gt;우리는 sentence간의 관계를 보는 modeling이 natural language understanding에 매우 중요한 부분이라 생각하고, 이를 위해 &lt;em&gt;coherence&lt;/em&gt;에 기반을 둔 loss를 제안한다.
즉 ALBERT에서는 sentence-order prediction(SOP) loss를 사용한다. 이는 해당 loss가 topic을 예측하지 않고 sentence간의 coherence를 예측하도록 한다.&lt;/p&gt;

&lt;p&gt;SOP는 동일한 document에서 가져온 연속된 두개의 segment를 입력값으로 넣는다. 이 때 각각 50%의 확률로 순서를 그대로 넣거나, 순서를 반대로 섞어서 넣는다. 그리고 모델을 통해 순서가 제대로 된 순서인지, 반대로 되어있는지를 예측하도록 한다. SOP에 대한 실험을 보면 SOP를 사용함으로써 NSP를 사용한 성능보다 향상된 것을 확인 할 수 있다.&lt;/p&gt;

&lt;h4 id=&quot;model-setup&quot;&gt;Model setup&lt;/h4&gt;

&lt;p&gt;ALBERT에서 BERT와 다르게 설정한 hyperparameter들은 아래와 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/FQkHoGZ.png&quot; alt=&quot;table2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;앞서 언급한 model design을 통해 ALBERT는 BERT 모델과 비교해서 상대적으로 매우 작은 파라미터 개수를 가진다. 예를들면, ALBERT-large 모델의 경우 BERT-large에 비해 18배 적은 파라미터를 자긴다.&lt;/p&gt;

&lt;h3 id=&quot;experiments&quot;&gt;Experiments&lt;/h3&gt;

&lt;h4 id=&quot;overall-comparison-between-bert-and-albert&quot;&gt;Overall Comparison between BERT and ALBERT&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/ij7k6Yv.png&quot; alt=&quot;table3&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;factorized-embedding-parameterization&quot;&gt;Factorized Embedding Parameterization&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/NWKom53.png&quot; alt=&quot;table4&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;cross-layer-parameter-sharing&quot;&gt;Cross-Layer Parameter Sharing&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/PhCbhHq.png&quot; alt=&quot;table5&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;sentence-order-predictionsop&quot;&gt;Sentence Order Prediction(SOP)&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/Alss6qn.png&quot; alt=&quot;table6&quot; /&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>A Structured Self-Attentive Sentence Embedding</title>
   <link href="https://reniew.github.io/48/"/>
   <updated>2019-03-01T04:47:35+00:00</updated>
   <id>https://reniew.github.io/48</id>
   <content type="html">&lt;p&gt;2017 ICLR Conference에서 소개된 논문 중 IBM Watson의 Attention mechanism을 사용해 Sentence embedding을 하는 &lt;a href=&quot;https://arxiv.org/abs/1703.03130&quot;&gt;A Structured Self-Attentive Sentence Embedding&lt;/a&gt; 논문에 대해서 알아보도록 한다. 해당 모델은 sentence embedding을 위한 self-attention mechanism과 정규화를 위해 새로운 regularization term을 소개한다. 뿐만 아니라 추가적으로 visualizing을 쉽게 할 수 있도록 설계되어있어 간단하게 visualizing을 할 수 있도록 한다. 해당 모델의 성능을 측정하기 위해서 3개의 task(author profiling, sentiment classification, textual entailment)에서 실험했다.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;1-introduction&quot;&gt;1 Introduction&lt;/h3&gt;

&lt;p&gt;Word embedding 기법, 즉 개별 단어들에 대해 유의미한 distributed representation을 학습하는 기법들을 계속해서 많은 발전을 이뤄왔다. 반면 아직 phrase나 sentence의 representation을 만드는 데는 word에 비해 아직은 부족한 상황이다. 보통 이와 같이 phrase나 sentence를 representation하는 방법은 두가지로 나뉜다. 첫 번째는 unsupervised 학습을 사용해 universal sentence representation을 만드는 방법이다.(&lt;em&gt;SkipThought vector, ParagraphVector, recursive auto-encoders, Sequential Denoising Autoencoder, FastSent&lt;/em&gt;, etc)&lt;/p&gt;

&lt;p&gt;또 다른 방법은 특정 task를 위해 특별하게 학습하는 방법이다. 이러한 방법은 보통 supervised 학습하고, downstream application과 합쳐져서 사용된다. 그리고 몇몇 모델의 경우에는 일반적인 단어 임베딩을 사용하고 중간에 &lt;em&gt;recurrent networks, recursive networks, convolutional networks&lt;/em&gt; 등을 사용함으로써 sentence representation을 얻어 다양한 task에 적용되었다.&lt;/p&gt;

&lt;p&gt;Attention mechanism을 CNN 혹은 LSTM 네트워크 상단에 적용함으로써 추가적인 정보를 통해 sentence embedding을 추출하는 모델이 몇가지 task에서 제안되었다. 하지만 sentiment analysis 같은 단일 문장이 입력으로 들어가는 경우에 추가적인 정보로 활용할 문장이 없기 떄문에 attention mechanism을 적용할 수 없다.&lt;/p&gt;

&lt;p&gt;따라서 대부분의 경우에는 max or average pooling 기법을 적용하거나 RNN의 마지막 hidden vector를 선택해서 사용하는데, 해당 모델에서는 &lt;strong&gt;self-attention&lt;/strong&gt; 기법을 통해서 기존의 방법들을 대체한다. self-attention의 경우에는 추가적인 입력값이 없는 하나의 문장에 대해서도 적용할 수 있고, 긴 문장에 대해서도 좋은 성능을 낸다. 이후 section 2.1 에서 self-attentive sentence embedding 모델을 소개하고 2.2에서 모델에서 사용한 정규화 방법에 대해서 소개한다. 마지막으로 2.3 에서는 효과적으로 해당 기법을 시각화 할 수 있는 방법에 대해서 소개할 것이다.&lt;/p&gt;

&lt;h3 id=&quot;2-approach&quot;&gt;2 Approach&lt;/h3&gt;

&lt;h4 id=&quot;21-model&quot;&gt;2.1 Model&lt;/h4&gt;

&lt;p&gt;Sentence embedding 모델은 크게 두개의 part로 구성되어 있다. 첫 번째 part는 bidirectional LSTM 을 사용하는 부분이고 다음은 self-attention을 적용하는 방법이다. 두 번째 part에서 나오는 값들을 사용해 LSTM의 hidden state값을 weighted sum 하게 되고 이 값이 입력 문장에 대한 embedding vector 로 사용된다. 그리고 이 값을 활용해서 각각의 task에 맞게 추가적인 networks를 모델 상단에 적용시킬 수 있다. 예를 들면 sentence embedding vector에 multi-layer perceptron을 적용시켜서 sentiment analysis task에 적용할 수 있다. 아래의 그림은 해당 예시를 도식화한 그림이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/Ao2kIqr.png&quot; alt=&quot;스크린샷 2019-03-02 오전 11.54.20&quot; /&gt;&lt;/p&gt;

&lt;p&gt;모델의 세부 과정에 대해서 자세히 알아보도록 하자. 우선 아래와 같이 $n$개의 token을 가지는 입력 문장이 있다고 하자. 입력 문장은 아래와 같이 각 단어들의 vector들이 모여서 matrix가 된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;S = (\mathbf{w_1}, \mathbf{w_2}, ... ,\mathbf{w_n})&lt;/script&gt;

&lt;p&gt;여기서 $\mathbf{w_i}$ 는 $i$번째 단어의 $d$-dimensional vector이다. 입력 문장 $S$ 는 $(n,d)$ 형태가 된다. 해당 입력 문장에 bidirectional LSTM을 적용시켜 두 개의 $u$-dimensional hidden vector 값을 구한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\begin{matrix}
\overset{\rightarrow}{h} = \overset{\longrightarrow}{\text{LSTM}}(w_t, \overset{\longrightarrow}{h_{t-1}})\\
\overset{\leftarrow}{h} = \overset{\longleftarrow}{\text{LSTM}}(w_t, \overset{\longleftarrow}{h_{t+1}})
\end{matrix}&lt;/script&gt;

&lt;p&gt;Bidirectional LSTM hidden state인 $\overset{\rightarrow}{h_t}$와 $\overset{\leftarrow}{h_t}$를 concatenate한 결과인 $h_t$를 사용한다. 전체 길이 $n$에 대해 다음과 같이 n개의 hidden state값이 나오게 된다. 이 값들을 모아서 하나의 matrix로 만들면$(n,2u)$의 size를 가지게 된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;H=(\mathbf{h_1},\mathbf{h_2},...,\mathbf{h_n})&lt;/script&gt;

&lt;p&gt;가변 길이의 입력값에 대해서 동일한 크기의 embedding 값을 얻는 것을 목표로 하기 떄문에, $n$개의 LSTM state를 적당한 linear combination을 통해 일정한 크기로 만들어 줘야 한다. 여기서는 self-attention mechanism을 linear combination으로 사용한다. Attention mechanism의 입력으로는 $H$를 사용하고, weight로 사용되는 output $\mathbf{a}$가 나오게 된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{a} =softmax(\mathbf{w_{s2}}\tanh(W_{s1}H^T))&lt;/script&gt;

&lt;p&gt;여기서 $W_{s1}$은 $(d_a, 2u)$ 크기의 가중치 행렬이고, $\mathbf{w_{s2}}$는 $(d_a)$ dimension의 가중치 벡터이다. 최종 output인 $\mathbf{a}$는 $n$ dimension의 벡터가 나오게 된다. 해당 값은 각 token에 대해 얼마나 반영할지를 확률값으로 표현되어있다. 이 값을 사용해 $H$의 가중 합을 구하게 된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{m} = \text{sum}(\mathbf{a}\odot H)&lt;/script&gt;

&lt;p&gt;이 값은 한 문장에 대해서 하나의 semantic 정보를 담고있다. 하지만 일반적으로 문장의 경우 여러개의 의미를 담는경우가 많이 있다. 예를 들면 ‘and’로 연결되어 있는 문장의 경우 한문장이더라도 여러개의 의미를 담고 있다. 따라서 이러한 전체적인 의미를 담은 represent하기 위해서 multiple $\mathbf{m}$을 필요로 한다. 따라서 multiple hops of attention을 사용한다. 문장에서 $r$개의 각각 다른 부분의 의미를 추출하기 위해서 기존의 $\mathbf{w_{s2}}$를 $(r,d_a)$크기의 가중치 행렬로 확장시켜서 다음과 같이 attention matrix를 구하게 된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;A = softmax(W_{s2}\tanh(W_{s1}H^T))&lt;/script&gt;

&lt;p&gt;이후 최종 output은 위의 attention matrix $A$와 $H$를 행렬곱해서 얻게된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;M = AH&lt;/script&gt;

&lt;h4 id=&quot;22-penalization-term&quot;&gt;2.2 Penalization Term&lt;/h4&gt;

&lt;p&gt;앞서 구한 $M$은 $r$개의 정보를 담아야 하는데 만약 비슷한 값들만을 갖게 된다면 정확한 정보를 전달하기 어려워지는데 이러한 문제를 해결하기 위해 penalization term을 통해 다양한 정보를 각각의 attention hop이 가질 수 있도록 만들어 준다.&lt;/p&gt;

&lt;p&gt;다양성을 평가하는 가장 좋은 방법은 Kullback Leibler divergence를 측정하는 것이다. 하지만 해당 모델에서 KL-divergence를 사용한 경우에 unstable하기 때문에 해당 모델에서는 다른 regularization term을 사용해서 Regularization을 한다. 뿐만 아니라 여기서 제시하는 penalization term의 경우 KL-divergence와 비교해서 연산량이 1/3로 cost 측면에서도 효율적이다.&lt;/p&gt;

&lt;p&gt;해당 term은 아래와 같이 계산한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;P = \Vert (AA^T-I)\Vert_F^2&lt;/script&gt;

&lt;p&gt;여기서 사용한 $\Vert\cdot\Vert_F$은 Frobenius norm이다. L2 regularization term과 비슷하게 해당 term은 coefficient를 곱한 후 loss와 함께 최소화하게 된다.&lt;/p&gt;

&lt;h4 id=&quot;23-visualization-term&quot;&gt;2.3 Visualization term&lt;/h4&gt;

&lt;p&gt;해당 모델에서 sentence embedding을 interpretation하는 것은 매우 간단하게 annotation matrix $A$를 사용함으로써 매우 간단히 해결할 수 있다. embedding matrix $M$의 각 row에 대해 각각 상응하는 annotation vector $\mathbf{a}$를 가진다. 각 element는 각 position의 token이 얼마나 contribution을 한지 확인 할 수 있다. 이 값을 사용해 Visualization을 쉽게 할 수 있다. Visualization결과는 다음과 같이 나타난다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/DSLl0cs.jpg&quot; alt=&quot;스크린샷 2019-03-02 오후 2.16.26&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;conclusion--discussion&quot;&gt;Conclusion &amp;amp; Discussion&lt;/h4&gt;

&lt;p&gt;해당 논문에서는 self-attention을 사용해서 고정된 크기의 matrix sentence embedding을 만들었다. 해당 모델을 3개의 task에 실험한 결과는 해당 모델의 다른 sentence embedding 모델에 비해 더 좋은 성능을 보인다는 것을 확인할 수 있다.&lt;/p&gt;

&lt;p&gt;LSTM의 결과에 attention mechanism을 적용함으로써 LSTM은 마지막 hidden state에 모든 token의 정보를 담을 필요가 없고 단지 각 token의 정보들만을 담으면 된다. 따라서 해당 모델은 sentence의 길이가 길어지더라도 좋은 성능을 보인다.&lt;/p&gt;

&lt;p&gt;그리고 해당 모델은 가변 길이의 문장을 하나의 고정된 길이의 representation으로 나타낼 수 있고, long-term의 경우에도 동일하게 정보를 잠 담는다. 이러한 장점은 모델이 scalability 하다는 것을 나타낸다. 따라서 단순 문장이 아니라 paragraph, articles등 더욱 긴 content에도 적용할 수 있다는 것을 볼 수 있다.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>BERT: Bidirectional Transformers for Language Understanding</title>
   <link href="https://reniew.github.io/47/"/>
   <updated>2018-12-06T04:47:35+00:00</updated>
   <id>https://reniew.github.io/47</id>
   <content type="html">&lt;p&gt;이번에는 많은 Task 에서 SotA(State of the Art)의 성능을 보이고 있는 BERT(&lt;strong&gt;B&lt;/strong&gt;ert &lt;strong&gt;E&lt;/strong&gt;ncoder &lt;strong&gt;R&lt;/strong&gt;epresentations form &lt;strong&gt;T&lt;/strong&gt;ransformers)에 대해서 알아보도록 하자. 이전에 소개된 ELMo, GPT에 이어 Pre-trained을 함으로써 성능을 올릴 수 있도록 만든 모델이다. 해당 모델은 Google에서 제시한 모델로 &lt;a href=&quot;https://arxiv.org/pdf/1810.04805.pdf&quot;&gt;BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding&lt;/a&gt; 논문에서 소개되었다. 이제 논문을 살펴보자.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;1-introduction&quot;&gt;1 Introduction&lt;/h3&gt;

&lt;p&gt;많은 Task 에서 Language model pre-training은 효과적이라는 것을 계속해서 입증해오고 있다. &lt;a href=&quot;https://arxiv.org/pdf/1802.05365.pdf&quot;&gt;&lt;strong&gt;ELMo&lt;/strong&gt;&lt;/a&gt;, OpenAI의 &lt;a href=&quot;https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf&quot;&gt;&lt;strong&gt;Generative Pre-trained Transformer(GPT)&lt;/strong&gt;&lt;/a&gt; 등 다양한 모델에서 pre-train을 함으로써 대부분의 NLP의 task의 성능이 향상됨을 보여왔다.&lt;/p&gt;

&lt;p&gt;우선 여기에는 pre-train 된 언어 표현을 실제 task에 적용시키는 방법은 두 가지로 나뉜다. 하나는 &lt;em&gt;feature-base&lt;/em&gt; 방법이고, 하나는 &lt;em&gt;fine-tuning&lt;/em&gt; 방법이다.&lt;/p&gt;

&lt;p&gt;우선 feature-based 방법의 경우 예시는 ELMo이며, 이 경우에는 ELMo를 통해 사전 학습한 feature를 사용하지만, task에 적합한 새로운 architecture를 추가로 사용해서 task를 해결한다. 즉 사전 학습을 통해 언어 표현 feature만 사용하고, 모델의 경우 별개의 개념인 것이다.&lt;/p&gt;

&lt;p&gt;그와 다르게 fine-tuning 방법의 경우 예시는 OpenAI의 GPT이다. 이 방법의 경우 task에 맞게 새로운 task-specific한 parameter를 사용한다. 이 parameter를 각 task에 학습하는데, 이 때 사전 학습한 parameter를 사용해 fine-tuning 하는 방법이다.&lt;/p&gt;

&lt;p&gt;이러한 두 방법 모두 같은 목적 함수를 사용해 사전 학습하지만, 두 방법 모두 단방향의 language model을 사용해서 언어 표현을 학습한다.&lt;/p&gt;

&lt;p&gt;해당 논문에서는 기존의 이러한 기법들(ELMo, GPT)이 pre-train된 표현의 제대로된 성능을 저해하는 요소가 있다고 주장한다. 이러한 요소에 대해서 설명하면, 먼저 이러한 langugage model 이 단방향으로 학습한다는 점이다. 그리고 이러한 이유로 pre-train 과정에서 사용될 architecture를 선택할 수 있는 폭을 줄어든다는 점이다.&lt;/p&gt;

&lt;p&gt;예를 들어 OpenAI의 GPT의 경우 텍스트에서 왼쪽에서 오른쪽으로만 참고할 수 있는 구조를 취하고 있다.&lt;/p&gt;

&lt;p&gt;따라서 해당 논문에서는 fine-tuning based 방법으로 &lt;em&gt;BERT: Bidirectional Encoder Representations from Transformers&lt;/em&gt; 를 사용함으로써 성능을 향상시킬 것이다. 해당 방법의 경우 기존의 방법이 단방향이였다면, “&lt;strong&gt;masked language model(MLM)&lt;/strong&gt;“를 통해 사전학습을 함으로써 이러한 제약을 해결할 것이다.&lt;/p&gt;

&lt;p&gt;Masked language model은 임의로 input token의 몇가지를 masking 처리하고, 다른 token들을 사용해서 masking된 token들을 예측하는 방향으로 학습한다. 기존의 왼쪽에서 오른쪽으로 단방향으로만 사전 학습하는 모델과는 다르게 MLM의 목적은 좌,우의 모든 문맥이 융화되도록 하는 것이다.&lt;/p&gt;

&lt;p&gt;그리고 Masked language model과 더불어 “&lt;strong&gt;next sentence prediction&lt;/strong&gt;” 라는 task를 사전 학습 과정에서 같이 사용할 것이다.&lt;/p&gt;

&lt;p&gt;마지막으로 해당 논문이 기여하려고 하는 바는 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;해당 논문에서는 언어 표현을 위해 양방향으로 사전 학습하는 것의 중요성을 증명할 것이다. OpenAI의 GPT 처럼 단방향으로 사전 학습을 하지 않고 BERT는 masked langugage model을 사용해 언어 표현을 위한 양방향으로 사전 학습을 진행한다. 그리고 ELMo의 경우 좌에서 우, 우에서 좌 둘다 사용해서 양방향이라 표현할 수 있지만, 해당 논문에서는 좌에서 우, 우에서 좌로 각각 학습한 후 이를 concatenate 해서 사용했다는 점이 BERT와의 차이점이다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;또한 많은 engineering이 필요한 task-spesific한 architecture를 사용할 필요성을 사전 학습을 통해 줄여준다. BERT는 문장 단위와 단어 단위 모두에서 SotA의 성능을 보이는 최초의 fine-tuning 기반의 표현(representation) 모델이다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;BERT를 사용함으로써 11개의 NLP task들에서 SotA의 성능을 향상시켰다. 그리고 BERT를 통해 양방향 특성이 가장 중요한 점이라는 것을 보여준다. 그리고 code와 pre-trained 모델의 경우 &lt;a href=&quot;https://github.com/google-research/bert&quot;&gt;goo.gl/language/bert&lt;/a&gt;에서 사용할 수 있다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;2-related-work&quot;&gt;2 Related Work&lt;/h3&gt;

&lt;p&gt;먼저 사전 학습 모델의 역사에 대해서 간략하게 알아보도록 하자.&lt;/p&gt;

&lt;h5 id=&quot;21-feature-based-approaches&quot;&gt;2.1 Feature-based Approaches&lt;/h5&gt;

&lt;p&gt;우선 Feature based 한 Pre-trained 기법들을 Neural이 아닌 모델들도 많이 있었다. 그리고 Pre-trained 시 단순히 단어에 대한 임베딩만을 진행하는 것이 아니라, 문장 및 구절에 대해서도 임베딩 하기도 한다.&lt;/p&gt;

&lt;p&gt;그 중에서도 ELMo는 이러한 전형적인 단어 임베딩 연구를 다른 차원으로 일반화 시켰다. ELMo 모델에서는 context-sensitive 특징을 모델을 통해 추출했다.&lt;/p&gt;

&lt;h5 id=&quot;22-fine-tuning-approaches&quot;&gt;2.2 Fine-tuning Approaches&lt;/h5&gt;

&lt;p&gt;최근의 Langugage model에서 tansfer learning의 트렌드는 실제 task에 맞는 지도 학습 모델을 적용하기 전에 동일한 모델을 사전 학습한 후 학습한 결과를 사용해서 fine-tuning하는 방법이다. 이러한 방법의 장점은 학습해야 하는 parameter의 수가 적다는 점이다. 더 적은 수의 parameter를 학습하면 된다.&lt;/p&gt;

&lt;h5 id=&quot;23-transfer-learning-from-supervised-data&quot;&gt;2.3 Transfer Learning from Supervised Data&lt;/h5&gt;

&lt;p&gt;비지도 학습의 사전 학습 방법은 무한정의 데이터를 사용할 수 있다는 장점이 있지만, 큰 데이터에 대해서 지도 학습 방법의 transfer가 더욱 효과적이라는 것이 입증되었다.&lt;/p&gt;

&lt;h3 id=&quot;3-bert&quot;&gt;3 BERT&lt;/h3&gt;

&lt;p&gt;이제 본격적인 BERT의 세부적인 구현 내용에 대해서 알아보도록 하자. 순서는 우선 전체 모델의 architecture에 대해서 알아보고 input의 형태를 먼저 알아본다. 그리고 다음으로 pre-training task에 대해서 알아본 뒤 pre-training, fine-tuning의 세부적인 절차에 대해서 알아본다. 마지막으로 BERT와 OpenAI GPT의 차이점에 대해서 다뤄보도록 한다.&lt;/p&gt;

&lt;h5 id=&quot;31-model-architecture&quot;&gt;3.1 Model Architecture&lt;/h5&gt;

&lt;p&gt;BERT의 모델 구조는 multi layer의 양방향 Transformer 인코더를 기반으로한 구조이다. Transformer에 대한 자세한 설명은 생략하도록 한다.(&lt;a href=&quot;https://reniew.github.io/43&quot;&gt;블로그 글 참고&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;해당 모델의 트랜스 포머의 layer의 수(Transformer 블록의 수)는 $L$로 지칭하고, hidden size는 $H$로 지칭한다. 그리고 self-attention의 head 수는 $A$로 지칭한다. 마지막으로 Transformer의 feed-forward layer의 첫번째 layer의 unit 수는 $4H$로 지정한다.&lt;/p&gt;

&lt;p&gt;해당 모델에서는 2개의 각각 다른 하이퍼 파라미터를 가지는 모델을 정의했다. 각 모델의 하이퍼 파라미터 값은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;$\text{BERT}_\text{BASE}$: $L=12, H=768, A=12, \text{Total Parameters} = 110M$&lt;/li&gt;
  &lt;li&gt;$\text{BERT}_\text{LARGE}$: $L=24, H=1024, A=16, \text{Total Parameters} = 340M$&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;$\text{BERT}_\text{BASE}$는 비교를 위해 OpenAI의 GPT 모델과 같은 크기로 설정했다. BERT와 OpenAI의 GPT와 ELMo의 모델의 차이점은 아래의 그림을 참고하자.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/Rs2cg2I.jpg&quot; alt=&quot;BERT&quot; /&gt;&lt;/p&gt;

&lt;h5 id=&quot;32-input-representation&quot;&gt;3.2 Input Representation&lt;/h5&gt;

&lt;p&gt;이제 입력값의 형태에 대해서 알아보도록 하자. 여기서 입력값의 형태는 약간 모호할 수 있다. 하나의 문장이 입력값이 될 수도 있고 두개의 문장 쌍(e.g. [Question, Answer])이 입력값이 될 수도 있다. 주어진 token에 대해서 다음의 세가지 값을 더함으로써 입력값으로 사용한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Token의 Embedding&lt;/li&gt;
  &lt;li&gt;Segment의 Embedding&lt;/li&gt;
  &lt;li&gt;Position의 Embedding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위의 세가지 값을 더하면 입력값이 된다. 입력값에 대한 부분은 아래의 그림을 참고하자.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/5Uvo5tl.jpg&quot; alt=&quot;INpu&quot; /&gt;&lt;/p&gt;

&lt;p&gt;입력값에 대한 구체적인 특징들은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;30,000개의 token vcabulary를 가지는 WordPiece 임베딩 값(&lt;a href=&quot;https://arxiv.org/pdf/1609.08144.pdf&quot;&gt;Wu et al., 2016&lt;/a&gt;)을 사용했다. 그리고 split word의 경우 ##으로 사용했다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;그리고 Positional 임베딩 값으로는 512 토큰 길이에 맞게 학습된 임베딩 값을 사용했다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;모든 문장의 첫 토큰은 special classification embedding값([CLS])을 넣어준다. 해당 토근에 대응하는 마지막 hidden state(Transformer의 출력값)는 분류 task에서 사용된다. 만약 분류 task가 아니라면 해당 벡터는 무시한다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;문장 쌍은 하나로 묶여서 하나의 문장으로 만들어지는데, 실제로 다른 이 문장 쌍을 두가지 방법으로 구별한다. 첫 번쨰는 두 문장 사이에 special token([SEP])를 넣어주고, 두 번째 방법은 학습된 문장 A 임베딩 값을 앞쪽 문장 모든 token에 더해주고 문장 B 임베딩 값을 뒤쪽 문장 모든 token에 더해준다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;단일 문장 입력값의 경우 문장 A 임베딩 값만을 사용한다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;33-pre-training-tasks&quot;&gt;3.3 Pre-training Tasks&lt;/h5&gt;

&lt;p&gt;해당 모델에서는 전형적인 좌에서 우 혹은 우에서 좌로 가는 language model을 사용해서 BERT를 pre-train하지 않았다. 대신 BERT는 두개의 비지도 예측 task들을 통해 pre-train 했다. 이 Section에서 두개의 비지도 학습 task에 대해서 알아보도록 하자.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.3.1 Task #1: Masked LM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;직관적으로 양방향 모델이 기존의 좌-&amp;gt;우 / 우-&amp;gt;좌 모델보다 훨씬 더 좋다는 것은 합당하다. 하지만 불행이도 양방향 조건은 간접적으로 각 단어를 본인 스스로를 보도록 하기 때문에, 일반적인 조건부 language model은 오직 좌에서 우, 우에서 좌로만 학습할 수 있다.
따라서 양방향 학습을 위해서 여기서는 특정 확률만큼에 해당하는 입력 토큰들을 임의로 마스킹 처리한다. 그리고 마스킹 된 단어들을 예측하도록 한다. 이러한 기법을 “masked LM”이라 부른다.(MLM) denoising auto-encoders와는 대조적으로 여기서는 오직 masking 한 값만 비교를 해서 학습을 진행한다.&lt;/p&gt;

&lt;p&gt;이러한 MLM 기법을 통해서 양방향 학습이 가능하도록 했지만, 이러한 기법의 큰 두가지 문제점이 남아있다. 첫 번째는 pre-train 과정에서는 “[MASK]” 토큰을 사용하지만, fine-tuning 한 후에는 사용하지 않아서 pre-train과 fine-tuning 사이의 간극이 생긴다는 점이다. 이러한 문제점을 해결하기 위해 학습 과정에서 모든 masking된 값을 [MASK] 토큰으로 대체하지 않았다. 자세하게 이러한 문제점을 해결하는 방법에 대해서 알아보도록 하자. 예를 들어 &lt;em&gt;“내 개는 크다”&lt;/em&gt; 라는 문장이 있다고 하자. 이 때 &lt;em&gt;“크다”&lt;/em&gt; 라는 단어를 masking 하려고 한다면 다음과 같이 진행된다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;항상 &lt;em&gt;“크다”&lt;/em&gt; 라는 단어를 [MASK] 토큰으로 대체하는 것이 아니라 다음과 같이 진행한다.&lt;/li&gt;
  &lt;li&gt;전체 시간의 80%: &lt;em&gt;“크다”&lt;/em&gt; 라는 단어를 “[MASK]” 토큰으로 대체한다. 즉 &lt;em&gt;“내 개는 크다”&lt;/em&gt; $\rightarrow$ &lt;em&gt;“내 개는 [MASK]”&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;전체 시간의 10%: &lt;em&gt;“크다”&lt;/em&gt; 라는 단어를 임의의 다른 단어로 대체한다. 즉 &lt;em&gt;“내 개는 크다”&lt;/em&gt; $\rightarrow$ &lt;em&gt;“내 개는 사과”&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;전체 시간의 10%: Masking 된 단어, &lt;em&gt;“크다”&lt;/em&gt; 를 그대로 둔다. 즉 &lt;em&gt;“내 개는 크다”&lt;/em&gt; $\rightarrow$ &lt;em&gt;“내 개는 크다”&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위와 같이 masking 함으로써 pre-train과 fine-tuning 과의 간극을 줄여서 첫 번째 문제점을 해결한다. 두 번째 MLM의 문제점은 오직 15%의 token 만 각 batch 에서 예측된다는 점인데, 따라서 pre-train 값이 수렴하기 위해서는 더 많은 step을 학습해야 한다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/4k6wu1i.jpg&quot; alt=&quot;step&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위 그림을 보면 MLM 기법을 사용한 BERT 모델이 단방향의 BERT 모델 보다 더 많은 step이 지나야 수렴한다는 것을 확인할 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.3.2 Task #2: Next Sentence Prediction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Question Answering, Natural Language Inference 등의 Task들은 두 문장 사이의 관계를 이해하는 것이 매우 중요하다. 문장 사이의 관계를 모델이 학습할 수 있도록 단일 Corpus로 구성된 두 개의 문장에 대해 문장이 관계있는지 없는지 이진 분류하는 next sentence prediction task를 통해 pre-train 한다. 구체적으로 두개의 A, B 문장을 선택하는데, 학습 과정에서 절반은 B 를 실제 A의 다음 문장으로 선택하고, 나머지는 임의의 다른 문장을 선택한다. 아래의 예를 보자.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
\text{Input} = &amp;\text{[CLS] the man went to [MASK] store [SEP]}\\
&amp;\text{he bought a gallon [MASK] milk [SEP]}\\
\text{Label} =&amp;\text{IsNext}
\end{align*} %]]&gt;&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
\text{Input} = &amp;\text{[CLS] the man [MASK] to the store [SEP]}\\
&amp;\text{penguin [MASK] are flight ##less birds [SEP]}\\
\text{Label} =&amp;\text{NotNext}
\end{align*} %]]&gt;&lt;/script&gt;

&lt;p&gt;NotNext 문장의 경우 완전히 임의로 선택했다. 해당 테스크에 대해서 최종적으로 pre-train된 모델의 경우 97~98%의 정확도를 보여준다. 이러한 task는 QA 와 NLI task에 대해서 아래와 같은 성능 향상을 보여줬다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/ukCeaMm.jpg&quot; alt=&quot;nli&quot; /&gt;&lt;/p&gt;

&lt;h5 id=&quot;34-pre-training-procedure&quot;&gt;3.4 Pre-training Procedure&lt;/h5&gt;

&lt;p&gt;pre-traning Corpus를 위해 두개의 Corpus를 합쳐서 사용했다. BooksCorpus(800M words)와 Engish Wikipedia(2,500M words)를 합쳐 하나의 Corpus로 만들었다. Wikipedia corpus의 경우 list, tables, header를 모두 무시하고 text만을 추출했다.&lt;/p&gt;

&lt;p&gt;각 학습 입력값을 만들어주기 위해서 두개의 문장을 뽑아서 하나의 문장으로 만들어 준다. 첫 번쨰 문장의 경우 A 임베딩 값을 가지고 두 번째 문장의 경우 B 임베딩 값을 가진다. B의 50%는 실제 A의 다음 문장을 사용하고 나머지는 임의의 문장을 사용한다. 이렇게 뽑아 “next sentence prediction” task에 사용한다. 그리고 두 문장을 합친 문장의 최대 길이는 512 토큰으로 제한한다.&lt;/p&gt;

&lt;p&gt;학습 시 batch size의 경우 256 문장으로 한다. 따라서 한 batch에 총 256 sequence $\times$ 512 tokens 인 128,000개의 토큰이 학습된다. 또한 전체 step은 1,000,000번 으로 33억개의 단어 corpus에 대해서 대략 40 에폭정도 학습한다.&lt;/p&gt;

&lt;p&gt;또한 학습은 Adam 을 사용하였으며 하이퍼 파라미터 값은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Learning rate: $10^{-4}$&lt;/li&gt;
  &lt;li&gt;$\beta_1 = 0.9$&lt;/li&gt;
  &lt;li&gt;$\beta_1 = 0.999$&lt;/li&gt;
  &lt;li&gt;0.01 값으로 L2 가중치 감소 사용&lt;/li&gt;
  &lt;li&gt;Learning rate의 경우 10,000 스탭마다 선형으로 감소하도록 함&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;그리고 드랍아웃의 경우 0.1 확률로 모든 레이어에 적용했다. 활성화 함수로는 gelu를 사용했다. 학습 loss의 경우 mean masked LM likelihood and mean next sentence prediction likelihood를 더한 값을 사용했다.&lt;/p&gt;

&lt;h5 id=&quot;35-fine-tuning-procedure&quot;&gt;3.5 Fine-tuning Procedure&lt;/h5&gt;

&lt;p&gt;문장의 classification task는 BERT의 fine-tuning이 직관적이고 간단한다. 입력값에 대해서 고정된 길이의 벡터를 추출해야 하는데, 해당 모델에서 첫 번째 입력값인 [CLS] 토큰에 의해 출력되는 마지막 hidden state값을 사용한다. 이 벡터를 $C\in\mathbb{R}^H$라 부른다. fine-tuning 과정에서 전체 파라미터는 그대로 유지되지만 마지막 classification을 위해 classification layer $W\in\mathbb{R}^{K\times H}$를 추가한다. 여기서 $K$는 classification 해야 되는 라벨의 개수를 의미한다. 해당 layer를 거친 벡터에 대해서 소프트맥스 함수를 적용시켜 확률 벡터인 $P\in\mathbb{R}^K$를 계산한다. 즉 아래의 수식과 같이 최종 확률 벡터가 계산된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;P = \text{softmax}(CW^T)&lt;/script&gt;

&lt;p&gt;BERT의 모든 parameter와 $W$는 실제 라벨과 비교한 log-probability 를 최대화 하며 학습된다. 사실 이러한 최종적인 fine-tuning과정과 학습 방법은 task에 따라 조금은 달라지는데 아래의 그림을 참고하자.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/g7361fl.jpg&quot; alt=&quot;bert_cl&quot; /&gt;&lt;/p&gt;

&lt;p&gt;fine-tuning 과정에서 대부분의 모델의 hyper parameters는 pre-train 과정과 동일하게 진행하지만, batch size, learning rate, epoch 값은 변경한다.&lt;/p&gt;

&lt;p&gt;그리고 대부분의 최적의 hyper parameters는 task마다 매우 다르다.&lt;/p&gt;

&lt;h3 id=&quot;4-conclusion&quot;&gt;4 Conclusion&lt;/h3&gt;

&lt;p&gt;최근의 language model 에서의 transfer leaning의 효과가 입증되었다. 그리고 비지도 학습의 pre-training 이 대부분의 language understanding의 한 부분으로 통합되었다.&lt;/p&gt;

&lt;p&gt;해당 논문을 통한 가장 큰 기여는 양방향의 구조를 통해 pre-train 모델이 대부분의 NLP 모델에 성공적으로 적용된다는 점이다. 대부분의 결과가 매우 성공적이지만, 일부 사람의 성능보다 떨어지기도 하기 때문에 더 많은 연구를 통해 BERT에 의해 잡지 못하는 언어적 현상을 잡도록 해야 한다.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>End to End Memory Network</title>
   <link href="https://reniew.github.io/46/"/>
   <updated>2018-10-07T09:47:35+00:00</updated>
   <id>https://reniew.github.io/46</id>
   <content type="html">&lt;p&gt;지난 포스트인 &lt;a href=&quot;https://arxiv.org/pdf/1410.3916.pdf&quot;&gt;Memory Network&lt;/a&gt;에 이어 다음 논문으로 볼 수 있는 &lt;a href=&quot;https://arxiv.org/pdf/1503.08895.pdf&quot;&gt;End to End Memory Network&lt;/a&gt; 논문을 소개한다. 기존의 Memory Network의 경우 모델의 전 과정이 supervised 하기 떄문에 일반적으로 사용하기 어렵고 제약된 사항이 많았으나, 해당 논문의 경우 이름을 보면 알 수 있듯 End to End 한 모델을 제시해서 사용하기 쉽도록 구성되어있다. 이전 논문을 읽지 않았다면 읽은 후에 이 글을 읽도록 하자.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/45&quot;&gt;Memory Network&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/46&quot;&gt;End-to-End Memory Network&lt;/a&gt;[현재글]&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;introduction&quot;&gt;Introduction&lt;/h4&gt;

&lt;p&gt;최근 모델에서 attention의 개념과 부가적인 storage를 도입함으로써 모델의 성능을 향상시켰다. “Memory Network”, “Neural machine translation by jointly learning to align and translate”, “Neural turing machines” 에서 소개된 모델을을 보면 continuous한 representation을 저장하는 저장소를 따로 사용하고 있다. 그리고 이 값들을 읽고 모델의 일부분으로 사용을 한다.&lt;/p&gt;

&lt;p&gt;해당 논문에서는 continuous한 형태의 Memory Network 모델을 소개한다. 기존의 memory network의 경우 backpropagation을 통해 학습이 어려웠고, 각 component, 즉 각 layer에서 supervised 하기 때문에 제약이 있었다는 단점이 있다. 이러한 문제를 해결하기 위해 end to end로 학습할 수 있는 모델을 제시한다. 따라서 이 모델은 기존의 모델보다 unsupervised한 성격의 모델로 제약없이 많은 task에 적용할 수 있을 것이다.&lt;/p&gt;

&lt;h4 id=&quot;approach&quot;&gt;Approach&lt;/h4&gt;

&lt;p&gt;모델에서 input 값으로 discrete 한 값인 $x_1, x_2,…,x_n$를 받는다. 이 값들은 하나를 제외한 전부는 memory로 저장될 것이고 하나는 질문(query) $q$이다. 그리고 output은 이 질문에 대한 대답인 $a$가 나온다. memory $x_i$, query $q$, answer $a$ 는 모두 $V$개의 단어들의 dictionary들의 값들로 구성된다. input 값들은 multiple hop 구조를 통해 continuous한 output인 $a$ 값을 만든다. 이러한 구조는 backpropagation을 통해 학습이 쉽도록 만든다. 모델의 전체적인 구조는 아래의 그림과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/Ff2G9Qm.jpg&quot; alt=&quot;end2end&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위의 그림의 (a)인 왼쪽 그림은 전체 구조에서 하나의 layer를 나타내고 오른쪽 그림인 (b)는 이 layer들이 쌓여 전체 구조를 나타낸다. (a), (b)를 각각 나눠 따로 설명한다.&lt;/p&gt;

&lt;h5 id=&quot;single-layer&quot;&gt;Single Layer&lt;/h5&gt;

&lt;p&gt;앞서 말했듯이 모델은 multiple hop 구조를 가진다고 했다. 전체 모델을 소개 전에 우선 하나의 layer에 대해서 먼저 설명한다. multiple hop 구조는 이 single layer가 여러개 쌓인 형태이므로 간단하다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Input memory representation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;우선 input값 중 $x_1,x_2,…,x_i$는 memory에 저장된다. 저장될 떄는 d-차원의 embedding vector로 변환된 후 저장된다. 따라서 ${x_i}$는 ${m_i}$로 storage에 저장된다. 이 때 embeddng vector를 만들기 위해 embedding matrix $A\in\mathbb{R}^{d\times V}$를 곱한다. 그리고 질문(query)도 embedding 된다. 이 때는 $A$와 같은 형태를 가지는 embedding matrix $B$를 곱한다. embedding 된 질문은 internal state $u$ 라 부른다. 다음으로는 질문과 문장들의 연관도를 구하기위해 각각의 $m_i$과 $u$를 각각 곱한 후 softmax를 취해서 계산한다. 이 값은 각 sentence와 query와의 연관성을 계산한 후 확률 벡터로 만들어준다고 생각하면된다. 즉 어떤 문장이 질문에 대해 연관성이 높은지를 계산한 값이다. 이 값을 확률 벡터 $p$라 부른다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p_i=\text{Softmax}(u^Tm_i)&lt;/script&gt;

&lt;p&gt;&lt;strong&gt;Ouput memory representation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;위에서 각 ${x_i}$를 ${m_i}$로 만든 것처럼 똑같이 embedding한 output vector인 $c_i$들을 계산한다. 계산은 embedding matrix $C\in\mathbb{R}^{d\times V}$ 이 값을 output 값을 만들기 위해 사용된다. 그리고 최종 response를 만들기 위해 위에서 계산한 확률 벡터와 output vector를 가중평균한다. 이렇게 최종 response인 $o$를 만든다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;o=\sum_ip_ic_i&lt;/script&gt;

&lt;p&gt;여기서 사용된 함수들은 smooth한 함수들이기 때문에 gardient를 계산하기 쉽다. 따라서 backpropagation을 통해 학습이 쉬워진다. 그리고 여기서 가중평균한 개념은 self attention과 유사한 개념이다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generating the final prediction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;이제 최종 response를 통해 마지막 prediction값을 계산해야 한다. 이 떄 response와 계산하기 위해 질문 벡터(query vector)를 embedding 한 vector인 $u$를 사용한다. 두 벡터를 더한 후 가중치 행렬인 $W$를 곱한 후 Softmax 함수를 취해서 최종 prediction을 계산한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\hat{a}=\text{Softmax}(W(o+u))&lt;/script&gt;

&lt;p&gt;여기까지하면 Single layer의 모델이 끝이난다. 총 4개의 parameter matrix $A,B,C,W$가 있고 학습의 경우 prediction 값인 $\hat{a}$와 실제 label $a$를 비교한 cross-entropy loss 함수를 사용하고 update는 SGD를 사용한다.&lt;/p&gt;

&lt;h5 id=&quot;multiple-layers&quot;&gt;Multiple Layers&lt;/h5&gt;

&lt;p&gt;이제 위의 single layer를 확장해 전체 모델을 만들어 보자.위의 layer를 K개 쌓아서 만들면 된다. 이 때 몇 가지 특징이 있는데 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;첫 번째 layer를 제외한 layer의 질문(query) 벡터는 이전 layer의 output vector인 $o^k$와 query vector 인 $u^k$를 더한 값을 사용한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;u^{k+1} = u^k+o^k&lt;/script&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;각 layer는 모두 다른 embedding matrix $A^k, C^k$를 사용한다. 하지만 parameter를 줄이기 위해 가중치를 공유할 수 있다 이는 밑에서 설명한다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;마지막 layer에서 계산하는 prediction은 다음과 같이 계산된다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\hat{a}=\text{Softmax}(Wu^{K+1})=\text{Softmax}(W(u^{K}+o^K))&lt;/script&gt;

&lt;p&gt;그리고 앞서 말했던 parameter를 줄이기 위한 방법으로 두 가지 방법이 사용될 수 있다.&lt;/p&gt;

&lt;p&gt;1. &lt;strong&gt;Adjacent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;인접한 embedding matrix를 같은 weight를 사용하게 함으로써 paramter 수를 줄이는 방법이다. 즉 모든 $k$에 대해 아래의 식들을 만족한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;$A^{k+1}=C^k$ : 이전 layer의 $C$ matrix 와 해당 layer의 $A$ matrix는 같다.&lt;/li&gt;
  &lt;li&gt;$W^T=C^K$ : prediction을 위한 matrix은 $W$는 마지막 layer의 $C$ matrix를 transpose한 것과 같다.&lt;/li&gt;
  &lt;li&gt;$B=A^1$ : query를 embedding 하는 matrix인 $B$와 첫 layer의 $A$ matrix는 같다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2. &lt;strong&gt;Layer-wise(RNN-like)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;여기서는 여러 matrix가 생기는 $A$와 $C$들이 각각 모두 같은 matrix를 사용하도록 한다. 즉 아래의 식을 만족한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;A^1=A^2=...=A^K&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;C^1=C^2=...=C^K&lt;/script&gt;

&lt;p&gt;그리고 이 경우에는 추가적인 linear mapping 함수인 $H$를 사용한다. 이 함수는 $u$ vector를 다음 값으로 넘길 때 사용된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;u^{k+1}=Hu^k+o^k&lt;/script&gt;

&lt;p&gt;여기까지가 전체 모델에 대한 설명이다. 전체적으로 기존 memory network의 모델인 menNN과 비슷한 형태를 취하고 있다. 가장 큰 차이점으로는 QA task에서 질문에 답하기 위해 모든 sentence를 필요로하지 않고 몇 개의 sentence만 필요로한다. 기존 모델인 menNN의 경우에는 이렇게 몇 개의 질문만을 사용하기 위해 supporting subset을 명시적으로 지정하고 학습 시 계속해서 따로 분리시키는데, 해당 모델에서는 이러한 과정없이 한번의 계산으로 질문과 유사한 문장들을 계산하기 때문에 End to End 한 모델이 될 수 있는 것이다.&lt;/p&gt;

&lt;p&gt;그리고 학습에 사용된 몇 가지 세부적인 특징은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Training data의 10%를 Validation data로 사용&lt;/li&gt;
  &lt;li&gt;update 시 learning rate 는 0.01 사용, 매 25 에폭마다 절반으로 줄였고 총 100에폭동안 학습&lt;/li&gt;
  &lt;li&gt;가중치의 경우 평균 0, 표준편차 1인 정규 분포를 따르도록 했다. $\sim N(0,1)$&lt;/li&gt;
  &lt;li&gt;Batch size 32&lt;/li&gt;
  &lt;li&gt;학습시 gradient 값의 $l_2 norm$이 40보다 커질 경우 더 커지지 못하고 40을 가지도록 함.&lt;/li&gt;
  &lt;li&gt;K=3 으로 지정&lt;/li&gt;
  &lt;li&gt;파라미터를 줄이는 방법으로는 앞서 설명한 adjacent weight sharing 방법 사용&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;그리고 모델에 추가적으로 사용된 기법들에 대해서 알아보자.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sentence Representation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;문장의 경우 두 가지 representation 방식을 사용했다. 처음으로는 bag-of-words(BoW)를 사용했는데, 이 방식을 사용할 경우 단어들의 위치 정보를 반영하지 못하는 단점이 있다. 따라서 위치 값을 encoding해서 representation을 하였다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;m_i = \sum_j l_j\otimes Ax_{ij}&lt;/script&gt;

&lt;p&gt;위 식에서 $l_j$가 위치 정보를 담은 값이다. 그리고 이 값은 아래의 수식 값을 가진다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;l_{kj}=(1-j/J) - (k/d)(1-2j/J)&lt;/script&gt;

&lt;p&gt;이렇게 위치 정보를 embedding 하는 방법을 position encoding(PE)라 부른다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Temporal Encoding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;하나의 정보에 대해 두 가지 선택지가 나오는 경우가 있다. 예를 들어 특정 사람이 두 위치에 다녀왔고, 현재 위치를 물어보는 경우를 대비해서 temporal context의 개념을 사용했다. 이 방식은 memory vector인 $m_i$ 와 output vector인 $c_i$ 계산시 사용된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;m_i = \sum_j Ax_{ij}+T_A(i)&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;c_i=\sum_jCx_{ij}+T_C(i)&lt;/script&gt;

&lt;p&gt;여기서 사용된 $T_A$ 와 $T_C$는 temporal 정보를 가지는 matrix이고, 학습 시 같이 학습되는 가중치이다.&lt;/p&gt;

&lt;h4 id=&quot;result--conclusion&quot;&gt;Result &amp;amp; Conclusion&lt;/h4&gt;

&lt;p&gt;이 모델도 결과는 따로 설명하지 않는다. 우선 이전의 모델과 비교하면 성능 자체는 약간 떨어지지만 End to End 로 학습한다는 것에 의미가 있고, 다른 task에 적용하기 쉽다는것이 해당 모델의 큰 장점이다. 이후 Dynamic Memory Network(DMN) 모델도 추가적으로 나왔으므로 이후에 같이 학습하면 도움이 될 것이다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;오역 및 잘못된 내용이 있을 수 있습니다. 잘못된 부분 혹은 이해가 잘 안되는 부분은 댓글 혹은 메일로 말씀해주시면 감사하겠습니다!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Memory Network</title>
   <link href="https://reniew.github.io/45/"/>
   <updated>2018-10-05T06:47:35+00:00</updated>
   <id>https://reniew.github.io/45</id>
   <content type="html">&lt;p&gt;이번에 리뷰할 논문은 &lt;a href=&quot;https://arxiv.org/pdf/1410.3916.pdf&quot;&gt;Memory Network&lt;/a&gt;입니다. Memory network 중 첫 논문으로 이 모델에서 중점적으로 보는 부분은 memory를 사용해서 긴 text에서 필요한 부분만 저장해서 사용할 수 있도록 하는 것입니다. 주로 Question Answering Task에 실험했으며, QA task를 여러 경우로 나눠서 모델을 구성했습니다. 이 모델의 경우 QA 분야가 아니라 Text generation 등 다른 분야에서 사용할 수 있으며 넓은 범위로 의미있는 논문이므로 자세히 리뷰를 통해 자세히 알아보겠습니다. 해당 Post 이후 향후 이 논문 이후에 나온 “End-to-End Memory Network” 까지 알아봄으로써 Memory Network에 대해 자세히 다룰 예정입니다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/45&quot;&gt;Memory Network&lt;/a&gt;[현재글]&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/46&quot;&gt;End-to-End Memory Network&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;introduction&quot;&gt;Introduction&lt;/h4&gt;

&lt;p&gt;대부분의 머신러닝 모델은 long-term component를 잘 읽고 사용하지 못한다. 예를 들면 전체 소설을 읽고 주제를 말하는 것과 같은 질문을 답하기는 어렵다. RNN 모델을 사용하면서 이런 long-term을 잘 읽을 수 있게 되긴 했지만, 결국 이 memory가 hidden state vector &amp;amp; weights 로 저장되는데, 크기 자체가 크지않고 제한적이다.&lt;/p&gt;

&lt;p&gt;따라서 여기서는 momory network라 불리는 모델을 통해 이러한 문제를 해결하고자 한다. 핵심 idea는 머신러닝에서 효과적인 학습 전략과 memory component를 결합해서 사용하는 것이다. 이제 모델에 대해서 알아보자.&lt;/p&gt;

&lt;h4 id=&quot;memory-network&quot;&gt;Memory Network&lt;/h4&gt;

&lt;p&gt;Memory Network는 메모리 $\mathbf{m}$(객체 $\mathbf{m}_i$ 들의 배열, 여기서 말하는 객체는 vector 혹은 string을 뜻한다)와 4개의 component인 $I,G,O,R$로 구성된다. 여기서 말하는 4개의 component의 역할은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;$I$: (input feature map) input을 내부적인 feature 표현으로 바꿔준다.&lt;/li&gt;
  &lt;li&gt;$G$: (generalization) 새로운 인풋을 통해 기존의 memory를 update한다. 이러한 과정을 genralization이라 부른다.&lt;/li&gt;
  &lt;li&gt;$O$: (output feature map) 새로운 input과 현재 memory의 값들을 사용해 output을 만든다.&lt;/li&gt;
  &lt;li&gt;$R$: (response) output을 원하는 포맷의 response로 만들어 준다. 예를 들면 터를 text 혹은 action 으로 바꿔준다.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;위의 4가지 component에 대한 설명은 범용적인 개념으로 설명되어 있다. 따라서 해당 모델이 사용한 것에 맞게 component들을 설명하면 다음과 같다.&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;$I$: input 값을 bag-of-word를 사용해서 embedding 해준다.&lt;/li&gt;
    &lt;li&gt;$G$: embedding 한 vector를 남아있는 memory slot $m_n$ 에 저장한다. 이 경우에 기존것이 삭제 될 수 있다.&lt;/li&gt;
    &lt;li&gt;$O$: 모든 memory 값에 대해서 k번 loop를 돌며 match되는 값을 찾고 최종적으로 output $o$를 만들어낸다. (아래 loop은 k=2 인 경우)
      &lt;ul&gt;
        &lt;li&gt;1st - input 값과 가장 match score가 높은 memory slot $m_i$를 찾는다.&lt;/li&gt;
        &lt;li&gt;2nd - input 과 이전 loop에서 찾은 memory slot $m_i$를 같이 사용해 다음으로 match score가 높은 memory slot인 $m_j$를 찾는다.&lt;/li&gt;
        &lt;li&gt;input과 $m_i,~m_j$ 모두 사용해 output 값을 만든다.&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;$R$: (reponse) output을 사용해 dictionary의 모든 word들의 score를 계산해 하나의 word를 찾는다.&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;즉 전체 모델은 memory와 4개의 component들을 사용하는 구조이다. 모델의 전체적인 그림은 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://adriancolyer.files.wordpress.com/2016/03/memory-network.png?w=566&amp;amp;zoom=2&quot; alt=&quot;memory&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이제 모델에 대해 자세히 알아보자. 모델은 input $x$가 다음의 순서로 모델에 흘러간다. 여기서 input 값은 charcter, word, sentence등이 될 수 있다.(image or audio signal이 될 수도 있다)&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;input $x$를 feature 표현으로 바꾼다. 즉 embedding한다: $I(x)$.&lt;/li&gt;
  &lt;li&gt;새로운 input으로 memory를 update한다: $\mathbf{m}_i=G(\mathbf{m}_i,I(x),\mathbf{m}), \forall i$.&lt;/li&gt;
  &lt;li&gt;input과 memory를 이용해 output $o$를 계산한다: $o=O(I(x),\mathbf{m})$&lt;/li&gt;
  &lt;li&gt;마지막으로 output을 decode해서 최종 response를 만든다: $r=R(o)$&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;위의 process는 학습과 테스트 모두에 적용된다. 학습과 테스트의 다른점은 학습시에는 memory와 4개의 component인 $I,G,O,R$모두 update되는데 테스트 때는 memory만 update된다.&lt;/p&gt;

&lt;p&gt;그리고 memory netword의 해당 모델은 범용적으로 제안된 모델로 각각의 component들은 기존의 machine model 어느 것을 사용해서 구현할 수 있다.(e.g SVMs, decision tress, etc.)&lt;/p&gt;

&lt;p&gt;이제 각 component들 각각에 대해서 자세히 살펴보자.&lt;/p&gt;

&lt;p&gt;$I$ &lt;strong&gt;- component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;$I$ component는 전처리의 표준으로 사용할 수 있다. 예를 들면 text input을 parsing, coreference, entity resolution 등을 하는 과정을 넣을 수 있다. 이러한 과정을 통해 raw한 input값을 feature 표현(representation)으로 만든다. 즉 text 를 feature vector로 만들어 준다.&lt;/p&gt;

&lt;p&gt;$G$ &lt;strong&gt;- component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;component $G$의 가장 간단한 형태는 $I(x)$를 memory의 “slot”에 저장하는 것이다. 즉 아래의 식을 수행하는 것이 component $G$가 된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{m}_{H(x)}=I(x)&lt;/script&gt;

&lt;p&gt;여기서 $H(.)$는 저장될 slot을 선택하는 함수이다. 즉 $G$는 memory의 배열 중 index $H(x)$의 메모리인 $\mathbf{m}_{H(x)}$를 update한다. $G$는 구현 방법에 따라 기존에 slot에 저장된 memory를 모두 제거하거나 부분적으로 제거한 후 update한다.&lt;/p&gt;

&lt;p&gt;그리고 만약 memory가 커질 경우에는 memory를 조직화할 필요가 있다. 이 때 Hash 함수를 사용해 choosing 함수인 $H(x)$를 구현한다. 그리고 이 함수는 경우에 따라 주제나 개체에 따라 저장되는 곳이 함수를 통해 지정될 수 있다. 즉 choosing 을 모든 slot에 대해서 적용하는 것이 아니라, 조직화한 후 적용되는 부분 slot에 대해서만 choosing한다.&lt;/p&gt;

&lt;p&gt;그리고 만약 메모리가 가득 찼다면 “foregetting”이라는 $H$를 통해 구현해야 한다. 즉 $H$는 각 메모리의 사용에 대한 점수를 측정하고 점수가 낮은 memory를 제거한 후 update한다. 이런 forgetting에 대한 부분은 이 논문에서 구현하고 실험하지 않았다.&lt;/p&gt;

&lt;p&gt;$O$ &lt;strong&gt;and&lt;/strong&gt; $R$ &lt;strong&gt;components&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;$O$ component는 memory를 읽고 inference 과정을 수행한다. 예를 들어 연관성이 높은 memory와 계산하고 output을 만들어낸다. 그리고 $R$ component는 output으로 부터 최종 결과물을 만들어 낸다. Question answering 분야로 생각해보면, $O$를 통해 연관성 높은 memory 와 계산을 해서 output을 만들고 $R$을 통해 해당 output을 다시 실제 답변 text로 만들어 낸다.&lt;/p&gt;

&lt;h4 id=&quot;a-mennn-implementation-for-text&quot;&gt;A MenNN Implementation for Text&lt;/h4&gt;

&lt;p&gt;Memory Network 구현의 하나의 예시로 각 components를 Nerual network로 구현했다. 따라서 이러한 모델을 memory neural networks(MenNNs)라 부르고, 이번 section에서 이러한 방법으로 구현한 모델에 대해서 설명한다. 그리고 이 모델의 input과 output은 text인 경우를 다룰 것이다.&lt;/p&gt;

&lt;h5 id=&quot;basic-model&quot;&gt;Basic model&lt;/h5&gt;

&lt;p&gt;우선 기본적인 모델의 Architecture에 대해서 알아보자, $I$ 모듈은 text를 input으로 받는다. 여기서는 우선 text가 문장(sentence)라고 생각하자. 그리고 이 문장은 질문이 될수도 있고 사실들이 적혀있는 글일 수 있다. 그리고 text는 가능한 memory slot에 저장된다. 즉 $S(x)$를 통해서 비어있는 memory slot $N$을 찾고 해당 메모리에 input을 저장한다: $\mathbf{m}_N=x,~N=N+1$. $G$ 모듈은 새로운 메모리 저장에만 사용되고 이미 저장된 메모리는 건들지 않는다.&lt;/p&gt;

&lt;p&gt;추론(inference)의 핵심은 $O$와 $R$ 모듈이다. $O$ 모듈은 input $x$에 대해 $k$개의 supporting memory를 찾는다. $k=2$로 예를 들어보자. 총 2번의 loop을 돌게되는데 첫 번째 loop에서는 input과 가장 match score가 높은 memory를 찾는다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;o_1 = O_1(x,\mathbf{m})=\underset{i=1,...,N}{\arg\max}~s_O(x,\mathbf{m}_i)&lt;/script&gt;

&lt;p&gt;여기서 함수 $s_O$는 input 문장과 하나의 memory $\mathbf{m}_i$와의 match score를 측정한다. 그리고 이제 두 번째 loop에서는 input과 이전에 찾은 memory 를 같이 사용해 다음 match score가 높은 memory를 찾는다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;o_2 = O_2(x,\mathbf{m})=\underset{i=1,...,N}{\arg\max}~s_O([x, \mathbf{m}_{o_1}],\mathbf{m}_i)&lt;/script&gt;

&lt;p&gt;최종 output $o$는 &lt;script type=&quot;math/tex&quot;&gt;[x,\mathbf{m}_{o_1},\mathbf{m}_{o_2}]&lt;/script&gt;가 된다. 그리고 이 값은 module $R$의 input으로 사용된다.&lt;/p&gt;

&lt;p&gt;마지막으로 $R$ 모듈은 위의 input값을 사용해 text response인 $r$을 만든다. 가장 간단한 형태로 response를 만드는 방법은 $k$ loop을 돌며 나온 결과 중 마지막 memory인 $\mathbf{m}_{o_k}$를 text로 만드는 방법이다. 만약 sentence generation을 해야 된다면 하나의 예로 RNN모델을 사용해 generation 할 수 있다. 해당 논문에서의 실험에서는 text response를 단일 단어로 제한해서 모델을 만들었다. 이 경우에는 $O$의 output으로 나온 값들과 vocabulary $W$의 모든 단어들과의 score를 측정해서 가장 높은 score를 가지는 단어를 response로 출력한다. 즉 다음의 수식을 통해 $r$을 만든다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;r = \underset{w\in W}{\arg\max}~s_R([x,\mathbf{m}_{o_1},\mathbf{m}_{o_2}],w)&lt;/script&gt;

&lt;p&gt;예를 통해 모델을 이해해보자. 우선 아래의 문장을 input으로 사용한다고 하자.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Joe went to the kitchen. Fred went to the kitchen. Joe picked up the milk.
Joe travelled to the office. Joe left the milk. Joe went to the bath room
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 문장에 대해서 다음의 질문들이 주어진다고 하자.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Where is the milk now?
Where is Joe?
Where was Joe before the office?
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;우선 첫 번째 질문에 답한다고 하자. 그러면 input은 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;x=\text{&quot;Where is the milk now?&quot;}&lt;/script&gt;

&lt;p&gt;그리고 $O$ 모듈은 모든 메모리에 대해서 첫 번째 loop을 돌 것이다. 즉 전체 문장에 대해서 주어진 질문과 가장 유사한 문장을 찾아낸다. 그리고 이 경우에 결과를 통해 나온 memory는 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{m}_{o_1}=\text{&quot;Joe left the milk&quot;}&lt;/script&gt;

&lt;p&gt;그리고 그 다음 loop을 돌 것이다. 주어진 input 그리고 memory slot  $\mathbf{m}_{o_1}$을 사용해서 다음으로 match score가 높은 두 번째 문장을 찾는다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{m}_{o_2}=\text{&quot;Joe travelled to the office&quot;}&lt;/script&gt;

&lt;p&gt;마지막으로 $R$ 모듈에서 $[x,\mathbf{m}&lt;em&gt;{o_1},\mathbf{m}&lt;/em&gt;{o_2}]$를 사용해 최종 output을 만든다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;r=\text{&quot;office&quot;}&lt;/script&gt;

&lt;p&gt;그리고 실험에서 score fucntion인 $s_O$와 $s_R$은 같은 형태의 함수를 사용했다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;s(x,y)=\Phi_x(x)^TU^TU\Phi_y(y)&lt;/script&gt;

&lt;p&gt;여기서 $U$는 $n\times D$ matrix이다. $D$는 feature의 수를 뜻하고 $n$는 embedding 차원의 크기를 뜻한다. 그리고 $\Phi_x$ 와 $\Phi_y$ 는 raw한 형태의 text를 D 차원의 vector로 만들어주는 함수이다. $\Phi$ 함수의 가장 간단한 예는 bag of words 표현 방식을 사용하는 것이다. 이 실험에서 $D=3\vert W\vert$로 사용했다. 즉 각 문장을 3개의 표현방식을 사용해 vector로 만들었다. 하나는 $\Phi_x(.)$를 위한 representation이고, 하나는 $Phi_y$를 위한 representation이다. 그리고 마지막 하나는 이후의 장에서 설명한다. 이렇게 만든 이유는 input이 실제 처음 input text를 통해서 온 것인지, memory에서 온 것인지 구별하기 위해 각각 따로 representation을 했다. 마지막으로 $U$의 경우에도 $R$ 모듈과 $O$ 모듈 각각 다른 matrix를 사용했다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Training&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;학습은 fully supervised setting을 통해 진행되었다. 즉 input과 response이 모두 주어지고 supporting sentence도 모두 labeling 되어있다. 따라서 score의 함수의 best choice를 알 수 있다. 그리고 학습 시 loss는 margin ranking loss함수를 사용하고 update는 stochastic gradient descent(SGD)를 사용했다. 우선 loss함수를 보면 다음과 같이 구성된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\sum_{\bar{f}\ne \mathbf{m}_{o_1}}\max(0,\gamma-s_O(x,\mathbf{m}_{o_1})+s_O(x,\bar{f}))+&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\sum_{\bar{f}'\ne \mathbf{m}_{o_2}}\max(0,\gamma-s_O([x,\mathbf{m}_{o_1}],\mathbf{m}_{o_2})+s_O([x,\mathbf{m}_{o_1}],\bar{f}))+&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\sum_{\tilde{r}\ne r}\max(0,\gamma-s_R([x,\mathbf{m}_{o_1},\mathbf{m}_{o_2}],r)+s_R([x,\mathbf{m}_{o_1},\mathbf{m}_{o_2}],\tilde{r})&lt;/script&gt;

&lt;p&gt;Loss 함수를 자세히 알아보자. 우선 3개의 부분으로 나눠지는데 이는 k를 설정함에 따라 달라진다. 이 경우에는 위와 같이 $k=2$의 경우이고, $k$ 값이 커질수록 loss의 term의 개수가 많아질 것이다. 우선 하나씩 알아보자. 첫 번째 term의 경우 첫 번째 memory 선정에 따른 loss이고, 두 번째는 두 번째 memory 선정에 따른 loss함수이다. 마지막은 최종 결과인 response의 loss함수가 된다. 각 loss함수는 동일하게 margin ranking loss함수 형태인데, 이 loss함수의 의미는 학습시 선택한 memory(혹은 response)인 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{m}_{o_1},\mathbf{m}_{o_2},r&lt;/script&gt; 과 선택하지 않은 것 중에서 score가 높은 memory(혹은 response)인 &lt;script type=&quot;math/tex&quot;&gt;\bar{f}, \bar{f}', \tilde{r}&lt;/script&gt; 과의  차이가 margin(위 식에서는 $\gamma$)보다 크도록 학습시키는 과정이다. 예를 들어 생각해보자. 위 식에서 우리가 선택한 memory와의 score와 다른 선택지 중 가장 높은 score와의 차이가 margin인 $\gamma$보다 작다면 loss는 양수값이 나올 것이다. 만약 margin보다 큰 경우에는 max를 통해 loss값이 0이 된다.&lt;/p&gt;

&lt;p&gt;그리고 MemNN 구현 시 R은 RNN을 사용해서 구현했다. 따라서 이 경우에는 loss 함수의 마지막 term을 일반적인 language modeling에서 사용되는 일반적인 log likelihood를 사용했다.&lt;/p&gt;

&lt;h5 id=&quot;word-sequences-as-input&quot;&gt;Word Sequences as Input&lt;/h5&gt;

&lt;p&gt;위에서는 input을 문장으로 가정한 모델을 설명했다. 만약에 input이 단어라면 어떻게 해야 할까? 우선 word로 들어올 경우 가장 큰 문제점은 statement와 question이 구분되지 않는다는 점이다. 따라서 위의 경우와는 다른 접근법이 필요하다. 따라서 “segementation” 함수, 즉 단어들을 구분지어서 statement와 question들을 구분시켜주는 학습시킬 함수를 사용한다. 이 함수를 segementer라 한다. 이 segementer을 사용하면 sequence를 memory에 쓸 수 있고 그 이후는 위에 나온 모델과 동일하게 사용하면된다. 그리고 이 segementer는 다른 component들과 같이 embedding model 형태이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;seg(c)=W_{seg}^TU_S\Phi_{seg}(c)&lt;/script&gt;

&lt;p&gt;여기서 $W_{seg}$는 vector이다. 이 vector의 역할은 embedding 된 값을 linear clasification 해주는 역할이다. 그리고 $c$는 input seqeunce로 vector 형태이다. 즉 각 단어들이 bag of words 형태로 들어온다. 따라서 이 함수의 결과값이 특정 margin $\gamma$보다 큰지 안큰지에 따라서 sequence가 하나의 segment인지 아닌지를 판단한다. 즉 아래와 같이 구분된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
c =
\begin{cases}
\text{segment}&amp;\text{, if }seg(c)&gt;\gamma\\
\text{not segment} &amp;\text{, otherwise}&amp;
\end{cases} %]]&gt;&lt;/script&gt;

&lt;h4 id=&quot;result--conclusion&quot;&gt;Result &amp;amp; Conclusion&lt;/h4&gt;

&lt;p&gt;실험결과에 대해서는 소개하지 않는다. 논문을 참고하길 바란다. 그리고 해당 모델은 하나의 Attention으로 볼 수 있는데, Hard attention으로 분류된다. 이후 다음 모델은 해당 모델보다 좀더 unsupervised한 성격의 모델로 Soft attention 성격의 모델이다. Memory를 사용하는 모델로 기존 RNN 혹은 LSTM 보다 성능이 좋다는 것을 확인할 수 있다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;오역 및 잘못된 내용이 있을 수 있습니다. 잘못된 부분 혹은 이해가 잘 안되는 부분은 댓글 혹은 메일로 말씀해주시면 감사하겠습니다!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>ConvS2S: Convolutional Sequence to Sequence Learning</title>
   <link href="https://reniew.github.io/44/"/>
   <updated>2018-09-11T06:47:35+00:00</updated>
   <id>https://reniew.github.io/44</id>
   <content type="html">&lt;p&gt;이번에 소개할 논문은 Facebook에서 발표한 ConvS2S라 불리는 &lt;a href=&quot;https://arxiv.org/pdf/1705.03122.pdf&quot;&gt;Convolutional Sequence to Sequence Learning&lt;/a&gt;이다. 이름부터 알 수 있듯이 sequence to sequence 모델을 convolutional neural network를 사용해서 만든 모델이다. 기존의 sequence to sequence 모델들은 대부분 RNN을 기반으로 나왔는데, CNN을 사용해서 sequence를 다루면서 높은 성능을 보여준 모델이라 많은 의미가 있다. RNN 대신 CNN으로 어떻게 모델을 구성하는지, 또 RNN대신 CNN을 사용하면 어떤 장점이 있는지 알아보자.&lt;/p&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;introduction&quot;&gt;Introduction&lt;/h4&gt;

&lt;p&gt;Sequence to sequence learning은 기계번역, 음성인식, text 요약 등 많은 분야에서 성공적인 결과를 보여줬다. 이러한 모델 구성중 대부분이 encoder에서 bi-directional RNN을 사용하고 decoder에서도 RNN을 사용했다.&lt;/p&gt;

&lt;p&gt;그에 반해 Convolutional neural network는 sequence를 다루는 모델에서는 별로 사용하지 않았다. sequence 모델에 CNN을 적용할 때를 RNN을 적용할 때와 비교해 보자. CNN을 적용하면 고정된 크기의 문맥만을 얻을 수 있다. 즉 우리가 정의한 kernel size로만 문맥을 파악하게 할 수 있는데, 다행이도 CNN은 몇개의 layer를 추가함으로써 context size를 늘리는 것이 쉽다. 따라서 모델의 maximum length of dependencies를 제어하기가 쉽다. 또한 RNN은 이전 step의 값이 있어야 계산을 할 수 있는데 반해 CNN은 그럴 필요가 없기 때문에 병렬화가 쉽다는 장점이 있다.&lt;/p&gt;

&lt;p&gt;Multi-layer CNN을 생각해보자. 층층이 쌓여서 hierarchical한 구조를 만드는데 이는 lower layer에서는 단어 주변의 문맥을 파악하고 higher layer로 가면 먼 거리의 단어도 파악할 수 있게 된다.&lt;/p&gt;

&lt;p&gt;그렇다면 시간을 고려해보자. CNN의 경우 n개의 단어를 문맥으로 파악하려면 드는 시간은 $O(\frac{n}{k})$이다. RNN의 경우를 생각해보면 linear하기 때문에 시간은 $O(n)$이 된다.&lt;/p&gt;

&lt;p&gt;해당 논문에서는 sequence를 다루는 모델로 전체가 convolutional neural network로 구성된 모델을 소개한다. 다음의 세가지를 사용해서 모델을 구성할 것이다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Gated linear units (Dauphin et al., 2016)&lt;/li&gt;
  &lt;li&gt;residual connections (He et al., 2015)&lt;/li&gt;
  &lt;li&gt;attention&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;소개한 모델의 평가는 두가지 task로 진행한다. Machine translation과 Text summerization으로 진행한다.&lt;/p&gt;

&lt;h4 id=&quot;recurrent-sequence-to-sequence-learning&quot;&gt;Recurrent Sequence to Sequence Learning&lt;/h4&gt;

&lt;p&gt;기존의 recurrent한 sequence to sequence 모델을 생각해보자. input에 대해서 RNN을 통해 representation을 계산한다. 여기까지가 encoder이고, decoder에서는 구한 representation을 가지고 다시 RNN 모델을 사용해 output을 만든다. 그리고 decoder에서는 conditional input을 사용하기도 한다. attention을 도입한 모델에서는 conditional input으로 representation을 가중 평균한 값으로 사용한다.&lt;/p&gt;

&lt;p&gt;그리고 가장 흔히 쓰이는 RNN 모델은 LSTM과 GRU이다. 둘다 Elman RNN을 응용해서 나온 모델로 long-term dependency를 잡기 위해 만들어 졌다. 그리고 최근에 가장 많이 쓰이는 모델은 bi-directional encoder 이다. RNN을 input에 대해 양방향으로 두개의 RNN을 만들어서 사용하는 것이다. 그리고 추가적인 기법으로는 shortcut과 residual connection을 많이 사용한다.&lt;/p&gt;

&lt;h4 id=&quot;a-convolutional-architecture&quot;&gt;A Convolutional Architecture&lt;/h4&gt;

&lt;p&gt;sequence to seqeunce modeling을 fully convolutional architecture를 살펴보자.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Position Embeddings&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;우선 가장 먼저 input $\mathbf{x}$을 embedding vector $\mathbf{w}$로 만든다. 그리고 embedding한 dimension과 똑같이 각 token의 절대적인 위치에 대한 embedding vector $\mathbf{p}$를 만들어서 두 vector를 더해서 representation vector $\mathbf{e}$를 만든다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
&amp;\mathbf{x} = (x_1,...,x_m)\\
&amp;\mathbf{w} = (w_1,...,w_m)\\
&amp;\mathbf{p} = (p_1,...,p_m)\\
&amp;\mathbf{e} = (w_1+p_1, ...,w_m+p_m)
\end{align*} %]]&gt;&lt;/script&gt;

&lt;p&gt;그리고 이러한 position embedding 기법은 decoder에 의해 만들어진 ouput 값에서도 사용된다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Convolutional Block Structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;encoder와 docoder 모두 simple block 구조를 비슷하게 사용한다. 이 block은 고정된 개수의 input을 연산한다. 여기서 $l$-th block을 decoder에서는 $\mathbf{h}^l=(h_1^l,…,h_m^l)$이라 표현하고 encoder에서는 $\mathbf{z}^l=(z_1^l,…,z_m^l)$라 표현한다. 그리고 해당 논문에서 block과 layer는 같은 의미로 사용된다.&lt;/p&gt;

&lt;p&gt;각각의 block의 구성은 1d convolution + non-linearity로 구성된다. 하나의 예를 보자. decoder에서 하나의 block이 있다고 하자. 그리고 이 block의 kernel size가 5라고 하면 convolution 하나의 단일 결과인 $h_i^1$는 k개의 단어에 대한 정보를 포함하고 있다. 몇개의 block들을 위에 쌓음으로써 정보를 포함하는 단어의 개수를 늘릴 수 있다.&lt;/p&gt;

&lt;p&gt;예를 들어 kernel size가 5인 6개의 blcok을 쌓았다고 생각하면 총 25개의 단어의 정보를 포함하고 있다.&lt;/p&gt;

&lt;p&gt;그리고 각 convolution의 kernel의 파라미터는 $\mathbf{W}\in\mathbb{R}^{2d\times kd}$와 $\mathbf{b}_w\in\mathbb{R}^{2d}$이다. 위 파라미터는 단어 하나당 $d$-dimension vector인 단어 k개를 포함하는 matrix인 $\mathbf{X}\in \mathbb{R}^{k\times d}$를 input으로 계산된다.&lt;/p&gt;

&lt;p&gt;kernel에 적용시킨 결과 output을 $\mathbf{Y}\in\mathbb{R}^{2d}$라 부른다. 이 vecotr의 dimension은 input의 dimension의 2배가 되었는데 이는 gated linear unit을 적용시키기 위함이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{Y}=\text{conv}(\mathbf{X}\mathbf{W})+\mathbf{b}&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\text{where}~ \mathbf{X} = [\mathbf{e}_i,...,\mathbf{e}_{i+k-1}]\text{,  with  }\mathbf{e}_i = \mathbf{w}_i + \mathbf{p}_i&lt;/script&gt;

&lt;p&gt;그리고 이 모델에서는 convolution 결과에 non-linearity로 gated linear unit(GLU: &lt;a href=&quot;https://arxiv.org/pdf/1612.08083&quot;&gt;Dauphin et al., 2016&lt;/a&gt;)를 사용했다. convolution을 output의 dimension을 생각해보면 input과는달리 2d였다. 이는 GLU를 사용하기위해 dimension을 2배로 만들어 준것인데, dimension이 2배가된 output vector를 2개로 나눠서(A,B) GLU에 적용시킨다. GLU의 식은 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;v([A,B]) = A\otimes\sigma(B)&lt;/script&gt;

&lt;p&gt;여기서 $A, B$는 d차원의 vector가 된다. 그리고 $\otimes$는 element-wise multiplication이다. GLU를 통해 다시 output은 resize되어서 dimension이 input과 같아진다.&lt;/p&gt;

&lt;p&gt;GLU에 대해서 좀 더 생각해보자. input으로 A,B 두 벡터가 들어가게 되는데, 하나는 값 그대로 들어가고 또 다른 하나는 sigmoid를 적용시켜서 들어간다. sigmoid를 적용시킨 값은 A를 문맥에 적용시키기 위해서 사용한 것이다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;개인적인 생각&lt;/strong&gt;
GLU에서 하나의 vector를 반으로 나눠서 적용시키는데 이는 거의 유사한 값이라고 생각하자. 이때 하나는 그 값 그대로 넣고 나머지 하나는 sigmoid를 적용시킨다. 따라서 한 벡터는 값을 의미하고 한 벡터는 그에 대한 확률 값이라 생각할 수 있다. 즉 input을 적용시키지 않고 비율을 각각 곱해준뒤 적용시킨다고 생각할 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;해당 논문에서는 GLU에서 sigmoid를 사용했는데, tanh를 사용하는 경우도 있다. 하지만 Dauphin의 말을 인용하면 language modeling에서는 tanh 보다 sigmoid를 적용하는 것이 성능이 좋다고 한다.&lt;/p&gt;

&lt;p&gt;다음으로는 deep한 convolutional network를 만들기 위해서 residual connection을 사용했다.  residual connection을 사용한 수식은 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;h_i^l = v(\mathbf{W}^l[h_{i-k/2}^{l-1},...,h_{i+k/2}^{l-1}]+b_w^l)+h_i^{l-1}&lt;/script&gt;

&lt;p&gt;수식에서 마지막 더해진 항이 residual connection 값이다.&lt;/p&gt;

&lt;p&gt;encoder network에서 output값이 input값과 동일하게 하기 위해서 sequence의 양끝에 padding을 추가한다. 즉, 양 끝에 k-1 개의 0값을 추가한다. 그리고 output에서 마지막 k개의 원소를 제거해서 사용한다.&lt;/p&gt;

&lt;p&gt;마지막으로 decoder의 output인 $h_i^L$에 weight를 곱한 후 bias를 더한 값에 softmax를 취해서 다음 token 값인 $y_{i+1}$을 얻어낸다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(y_{i+1}\vert y_1,...,y_i,\mathbf{x})=\text{softmax}(W_oh_i^L+b_o)\in \mathbb{R}^T&lt;/script&gt;

&lt;p&gt;&lt;strong&gt;Multi-step Attention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;해당 논문에서 decoder layer에 separate attention mechanism을 적용시켰다. attention 계산을 위해서 현재 decoder state vector에 이전 target element의 embedding값($g_i$)을 더해준다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;d_i^l=W_d^lh_i^l+b_d^l+g_i&lt;/script&gt;

&lt;p&gt;decoder layer $l$의 attention 값인 $a_{ij}^l$은 현재 state $i$에 대한 source 원소인 $j$의 attention 값을 나타낸다. 계산은 decoder의 state summary 값인 $d_i^l$과 encoder의 output값인 $z_j^u$를 dot-product한 값을 softmax 취해주면 된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;a^l_{ij}=\frac{\exp(d_i^l\cdot z_j^u)}{\sum^m_{t=1}\exp(d_i^l\cdot z_t^u)}&lt;/script&gt;

&lt;p&gt;그리고 이 attention 값을 사용해서 decoder에 사용될 conditional input $c_i^j$를 계산한다. 이 때 attention 값을 encoder의 output 값에 가중평균하는데 encoder의 output만 사용하는 것이 아니라 input값이 embedding 값도 더해줘서 가중평균한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;c_i^l=\sum^m_{j=1}a_{ij}^l(z_j^u+e_j)&lt;/script&gt;

&lt;p&gt;이 attention 구조는 기존의 RNN에서 사용한 attention 과는 $z$뿐만아니라 embedding 값인 $e$를 사용했다는 점이 다르다. 여기서 사용한 attention을 생각해보면 encoder를 통해서 나온 값인 $z$를 key로 해석할 수 있고, 각 input의 embedding 값인 $e$를 value로 해석할 수 있다.&lt;/p&gt;

&lt;p&gt;또 다른 해석은 $z$는 context에 대한 정보도 포함을 하고 있고, $e$는 하나의 token에 대한 정보를 담고 있으므로 두 정보를 모두 사용하는 것이다.&lt;/p&gt;

&lt;p&gt;계산된 conditional input $c$는 간단하게 decoder layer의 output $h_i^l$에 더해서 사용한다.&lt;/p&gt;

&lt;p&gt;attention은 multi hop구조로 적용된다. 즉 attention을 통해 나온 결과를 바로 결과로 만든는 것이 아니라 결과를 다시 또 attention을 거치게 하는 구조이다. 이러한 구조는 첫 attention을 통해 유용한 정보를 결정하고 이제 유용한 정보만을 사용해서 다시 attention을 적용하는 구조로 생각할 수 있다.&lt;/p&gt;

&lt;p&gt;이때까지 나온 구조를 그림을 통해서 이해해보자. 우선 전체 그림은 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/cqA9lCO.jpg&quot; alt=&quot;convs2s_archi1&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;그림의 윗 부분이 encoder이고 아랫 부분이 decoder이다. 중간의 matrix는 attention 값들을 의미한다. encoder의 값들과 decoder의 값들을 사용해서 attention 값을 을 계산한다. encoder의 우측부분은 embedding vector 와 encoder output을 더하는 것을 의미한다. 이 값을 attention값과 가중 평균 해준다.&lt;/p&gt;

&lt;p&gt;이제 encoder와 decoder를 나눠서 살펴보자. 이제부터의 그림은 stanford의 &lt;a href=&quot;https://nlp.stanford.edu/seminar/details/mauli.pdf&quot;&gt;seminar slide&lt;/a&gt;에서 나온 그림이다.&lt;/p&gt;

&lt;p&gt;먼저 encoder 먼저 살펴보자.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/818EToJ.jpg&quot; alt=&quot;encoder&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;convolution을 계산한 후 2개의 벡터로 나눠서 gated linear unit이 계산된다. 그리고 residual connection으로 연결된 모습을 볼 수 있다. 위 그림의 가장 상단의 결과가 $z$가 될 것이다.&lt;/p&gt;

&lt;p&gt;이제 decoder의 그림을 보자.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/jVHBnSL.jpg&quot; alt=&quot;decoder&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;우선 encoder와 마찬가지로 convolution이 계산되고 gated linear unit까지 계산되는 부분은 동일하다. 이제 그 결과를 encoder값과 같이 attention 값을 사용한다. 그리고 그 결과를 이전의 결과 값과 더해주고 마지막으로 residual connection까지 계산을 해주면 최종 출력이 나오는 모습이다.&lt;/p&gt;

&lt;p&gt;하지만 해당 논문에서는 이런 single attention이 아닌 multi hop 구조를 사용했다고 했는데 이를 그림으로 표현하면 다음과 같을 것이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/D9BlwsO.jpg&quot; alt=&quot;multi_hop&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;attention 까지 계산한 결과가 다시 input으로 들어가서 다시한번 attention을 계산하는 형태이다. 전체적인 multi hop 구조는 아래의 그림을 보면 좀 더 이해가 쉬울 것이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/1VgwtYQ.gif&quot; alt=&quot;fairseq&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;전체적인 구조에 대한 설명은 여기까지이다. 이제 Normalization 방법과 initialize한 방법에 대해서 알아보자.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Normalization Strategy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;해당 논문에서는 Batch Normalization은 사용하지 않고 weight nomalization을 사용했다. 논문의 말에 따르면 network의 전체적인 varience가 크게 변하지 않도록 initialize와 normalize에 신경을 썻다고 한다.&lt;/p&gt;

&lt;p&gt;특히 residual block의 output과 attention을 scaling 해서 전체적인 variance를 크게 변하지 않도록 했다. residual block에는 $\sqrt{0.5}$를 곱해서 varience를 절반으로 줄였다.&lt;/p&gt;

&lt;p&gt;그리고 attention 값인 conditional input $c_i^l$에는 전체 attention score가 균등 분포를 따른다고 가정하고 원래 크기에 맞춰주기 위해 $m\sqrt{1/m}$을 곱해서 scale up 했다.&lt;/p&gt;

&lt;p&gt;그리고 multiple attention을 사용한 convolutional decoder에는 gradient 값도 사용한 attention 수만큼 scaling 했다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initialization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Residual connection과 같이 다른 layer의 값을 어떤 layer에 더하는 모델에는 초기값 설정이 매우 중요하다. 사용한 초기값 설정은 대부분 정규 분포를 따르도록 했으며, 평균 0 에 표준편차를 weight에 맞게끔 설정해줬다.&lt;/p&gt;

&lt;h4 id=&quot;experiment&quot;&gt;Experiment&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Datasets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;데이터셋은 간단하게 소개만 한다. 다음의 데이터셋들을 사용해서 실험을 했다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;WMT’16 English-Romanian&lt;/li&gt;
  &lt;li&gt;WMT’14 English-German&lt;/li&gt;
  &lt;li&gt;WMT’14 English-French&lt;/li&gt;
  &lt;li&gt;그 외 몇가지 corpus&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Model Parameters and Optimization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Parameter와 사용한 optimization에 대한 정보는 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Encoder 와 decoder에 512개의 hidden unit 사용.&lt;/li&gt;
  &lt;li&gt;모든 embedding은 512 dimension&lt;/li&gt;
  &lt;li&gt;Nesterov’s accelerated gradient 방법을 사용해서 학습
    &lt;ul&gt;
      &lt;li&gt;하이퍼 파라미터인 모멘텀 값은 0.99로 하고 norm이 0.1을 넘지 않도록 만들었다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;학습률은 0.25로 설정했다.
    &lt;ul&gt;
      &lt;li&gt;학습률은 학습이 경과하면서 계속 감소하도록 설정하고 그 값이 $10^{-4}$보다 작아지는 Epoch에서 학습을 멈추도록 설정&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;64 크기의 mini-batch 사용&lt;/li&gt;
  &lt;li&gt;가장 긴 sentnece의 길이는 GPU memory에 맞게 설정(64 mini batch에서 메모리가 허용하는 가장 긴 길이 사용)&lt;/li&gt;
  &lt;li&gt;gradient는 mini-batch의 padding 값이 아닌 값들의 개수로 normalize함&lt;/li&gt;
  &lt;li&gt;convolutional block의 input과 embedding에 dropout사용&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;result&quot;&gt;Result&lt;/h4&gt;

&lt;p&gt;결과도 간단히 보고 넘어가자.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://norman3.github.io/papers/images/fairseq/f04.png&quot; alt=&quot;13&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://norman3.github.io/papers/images/fairseq/f05.png&quot; alt=&quot;123&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;다른 모델들에 비해 상대적으로 최근에 나온 모델이고, 모델을 발표한 facebook에서 소스코드 또한 공개를 해서 성능 높은 모델을 접근성 높게 사용할 수 있다는 장점이 있다. 그리고 기존의 RNN이 대부분이였던 Sequence to sequence 모델에서 CNN만을 사용해서도 다른 모델보다 높은 성과를 보여줬다는 것은 새로운 모델도 계속해서 나올 것이라는 것을 예상해 볼 수 있다.&lt;/p&gt;

&lt;p&gt;그리고 무었보다 이 모델의 sequence에 적용했을 때의 장점은 다른 RNN계열의 모델들 보다 병렬화가 쉽기 때문에 속도가 매우 빠르다는 것이 큰 장점이다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;오역 및 잘못된 내용이 있을 수 있습니다. 잘못된 부분 혹은 이해가 잘 안되는 부분은 댓글 혹은 메일로 말씀해주시면 감사하겠습니다!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Transformer: Attention is all you need</title>
   <link href="https://reniew.github.io/43/"/>
   <updated>2018-09-08T06:47:35+00:00</updated>
   <id>https://reniew.github.io/43</id>
   <content type="html">&lt;p&gt;이번에 리뷰할 논문은 Google에서 발표한 &lt;a href=&quot;https://arxiv.org/pdf/1706.03762&quot;&gt;Attention is all you need&lt;/a&gt;이다. 논문 이름부터 어떤 내용을 다룰지 짐작가게 하는데, 기존의 attention에 대해서 생각해보면 sequence to sequence 모델에서 혹은 convolutional neural network 모델에서 부가적으로 attention mechanism을 적용시켰다고 볼 수 있는데, 이 논문에서는 attention만으로 모든 모델을 만들었다는 점이 흥미롭다.&lt;/p&gt;

&lt;p&gt;자세한 설명 이전에 간단히 설명하자면 기존의 모델들 처럼 RNN 혹은 CNN을 사용하지 않고 attention만 사용해서 연산량이 매우 줄었다. 그럼에도 불구하고 성능도 매우 높게 나오는 모델이다. Transfomer라고도 불리는데 논문을 보면서 어떻게 구성되어 있는지 자세히 알아보도록 하자.&lt;/p&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;introduction&quot;&gt;Introduction&lt;/h4&gt;

&lt;p&gt;RNN 모델들이 주로 기계 번역 혹은 language modeling 등 sequence를 다루기 위한 모델로 많이 사용되고 있다. 하지만 이런 RNN을 활용한 모델을 문장이 길어질수록 성능이 떨어지고 memory의 제약으로 batch에도 제한이 생길 수 있다는 단점이있다. 또한 단순한 sequence to sequence 모델은 sequnece의 alignment를 해결하지 못한 문제가 아직 남아있다.&lt;/p&gt;

&lt;p&gt;attention mechanism을 통해 위에서 언급했던 RNN 모델의 문제점을 어느정도 해결했지만 결국 대부분의 모델은 attention이 RNN과 함께 사용되는 용도로만 사용되었다.&lt;/p&gt;

&lt;p&gt;해당 논문에서는 &lt;strong&gt;Transformer&lt;/strong&gt; 라 불리는 모델을 소개한다. 다른 CNN 혹은 RNN 모델 없이 단순히 attention mechanism만으로 모델을 구성했으며 학습시간이 매우 빠르다는 장점이 있다.&lt;/p&gt;

&lt;h4 id=&quot;model-architecture&quot;&gt;Model Architecture&lt;/h4&gt;

&lt;p&gt;대부분의 sequence를 다루는 모델들은 encoder-decoder 구조로 되어있다. 여기서 encoder는 input sequence를 continuous한 representations로 바꾸고 decoder는 이 representation을 통해 output을 만들어낸다.&lt;/p&gt;

&lt;p&gt;Transformer의 전체적인 architecture는 stacked self-attention(intra-attention)과 point-wise fc layer들을 사용해서 구성되어 있다. 아래 그림이 전체 architecture를 나타낸다. 그림에서 왼쪽이 encoder이고 오른쪽이 decoder이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1200/1*HunNdlTmoPj8EKpl-jqvBA.png&quot; alt=&quot;archi&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이제 모델 하나하나 자세히 알아보도록 하자.&lt;/p&gt;

&lt;h5 id=&quot;encoder--decoder&quot;&gt;Encoder &amp;amp; Decoder&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;Encoder&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Encoder는 동일한 layer가 N개 반복되는 형태이다. 이 논문에서는 6번 반복했다. 그리고 각 layer는 두개의 sub-layer로 구성된다. 첫 sub-layer는 multi-head self-attention mechanism이고 두번쨰는 간단한 point-wise fc-layer이다. 그리고 모델 전체적으로 각 sub-layer에 residual connection을 사용했다. 그리고 residual 값을 더한 뒤에 layer 값을 Nomalize한다. 즉 각 sub-layer는 결과에 대해 residual 값을 더하고 그 값을 nomalize한 값이 output으로 나오게 된다. 그리고 모델 전체적으로 residual 계산을 쉽게하기 위해서 output의 dimension은 모두 512로 맞췄다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decoder&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Decoder도 encoder와 마찬가지로 동일한 layer가 N개 반복되는 형태이다. 그리고 이 논문에서는 decoder도 6번 반복했다. 그러나 반복되는 layer가 encoder와는 다른 구조이다. 총 3개의 sub-layer로 구성되어 있는데, 2개는 기존의 encoder의 sub-layer와 동일하고 나머지 하나는 encoder의 ouput에 대해 multi-head attention을 계산하는 sub-layer가 추가되었다. 그림으로 보면 오른쪽의 가운데 sub-layer이다.&lt;/p&gt;

&lt;p&gt;Decoder에서도 residual connection을 사용했다. residual 값을 더한 후 동일하게 layer nomalize를 해준다. 그리고 self-attetion을 encoder와는 약간 다르게 수정을 했는데, masking을 추가했다. self-attention시 현재 위치보다 뒤에 있는 단어는 attend 못하도록 masking을 추가해준 것이다.&lt;/p&gt;

&lt;h5 id=&quot;attention&quot;&gt;Attention&lt;/h5&gt;

&lt;p&gt;이 모델에서 사용한 attention은 총 2가지 종류이다. 하나는 Scaled dot-product attention이고 나머지 하나는 Multi-head attention이다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scaled dot-product attention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/Auqdy3w.jpg&quot; alt=&quot;123&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;해당 attention의 input은 3가지다. $d_k$ dimension을 가지는 queries와 keys, 그리고 $d_v$ dimension을 가지는 values로 구성된다. 우선 하나의 query에 대해 모든 key들과 dot product를 한 뒤 각 값을 &lt;script type=&quot;math/tex&quot;&gt;\sqrt{d_k}&lt;/script&gt;로 나눠준다. 그리고 softmax함수를 씌운 후 마지막으로 value를 곱하면 attention 연산이 끝난다.&lt;/p&gt;

&lt;p&gt;실제로 계산할때는 query, key, value를 vector하나하나 계산하는 것이 아니라 여러개를 matrix로 만들어 계산한다. 수식은 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\text{Attention}(Q, K, V) =\text{softmax}(\frac{QK^T}{\sqrt{d_k}})V&lt;/script&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;추가적인 설명&lt;/strong&gt;
우선 query와 key, value에 대해서 설명하면 query가 어떤 단어와 관련되어 있는지 찾기 위해서 모든 key들과 연산한다. 여기서 실제 연산을 보면 query와 key를 dot-product한뒤 softmax를 취하는데, 의미하는 것은 하나의 query가 모든 key들과 연관성을 계산한뒤 그 값들을 확률 값으로 만들어 주는 것이다. 따라서 query가 어떤 key와 높은 확률로 연관성을 가지는지 알게 되는 것이다. 이제 구한 확률값을 value에 곱해서 value에 대해 scaling한다고 생각하면된다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;추가적인 설명&lt;/strong&gt;
key와 value는 사실상 같은 단어를 의미한다. 하지만 두개로 나눈 이유는 key값을 위한 vector와 value를 위한 vector를 따로 만들어서 사용한다. key를 통해서는 각 단어와 연관성의 확률을 계산하고 value는 그 확률을 사용해서 attention 값을 계산하는 용도이다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;보통 흔히 사용되는 attention 함수는 additive attention과 dot-product(multiplicative) attention 두가지다. 후자의 경우가 현재 사용하고 있는 attention과 거의 유사하다. 다른점은 $\frac{1}{\sqrt{d_k}}$로 scailing을 하지 않았다는 점이다. 그리고 dot-product attention과 additive attention을 비교하면 dot-product attention이 속도측면에서 앞선다. 복잡도는 비슷한데 속도가 앞서는 이유는 matrix multiplication에 대한 최적화된 구현이 많이 있기 때문이다.&lt;/p&gt;

&lt;p&gt;그리고 앞서 설명하지 않았던 것이 하나 있다. rescaling을 하는 부분인데, 만약 dimension의 루트값으로 나눠주지 않는다면 어떤 일이 생기는지 생각해보자. vector의 길이가 길어질수록, 즉 dimension이 커질수록 자연스럽게 dot-product값은 점점 더 커질 것이다. 그러나 이후에 softmax함수가 있기 때문에 back-propagation 과정에서도 미분값이 조금만 넘어오게 되서 상대적으로 학습이 느려지거나 학습이 잘안되는 상황이 발생할 수 있다. 따라서 dimension이 큰 경우를 대비해 dimension의 루트값으로 나눠준다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-head attention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/HIHgT9y.jpg&quot; alt=&quot;mul&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;기존의 attention은 전체 dimension에 대해서 하나의 attention만 적용시켰다. 여기서 사용한 Multi-head attention이란 전체 dimension에 대해서 한번 attention을 적용하는 것이 아니라 전체 dimension을 h로 나눠서 attention을 $h$번 적용시키는 방법이다.&lt;/p&gt;

&lt;p&gt;각 query, key, value의 vector는 linearly하게 $h$개로 project 된다. 이후 각각 나눠서 attention을 시킨 후 만들어진 $h$개의 vector를 concat하면 된다. 마지막으로 vector의 dimension을 &lt;script type=&quot;math/tex&quot;&gt;d_{\text{model}}&lt;/script&gt;로 다시 맞춰주도록 matrix를 곱하면 끝난다. Multi-head attention을 수식으로 표현하면 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\begin{matrix}
\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1,...,\text{head}_h)W^O\\
\text{where}~\text{head}_i = \text{Attention}(QW_i^Q, KW_i^K,VW_i^V)
\end{matrix}&lt;/script&gt;

&lt;p&gt;각 파라미터의 shape은 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;W_i^Q,~W_i^K\in\mathbb{R}^{d_{\text{model}}\times d_k}, W_i^V \in\mathbb{R}^{d_{\text{model}}\times d_k}, W^O \in \mathbb{R}^{hd_v\times d_{\text{model}}}&lt;/script&gt;

&lt;p&gt;해당 논문에서는 $h=8$ 즉 8개의 head를 사용했다. 따라서 각 vector들의 dimension은 다음과 같이 8로 나눠진다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;d_k=d_v=d_{\text{model}}/h = 64&lt;/script&gt;

&lt;p&gt;$h$번 계산했지만 각 head들이 dimension이 줄었기 때문에 전체 연산량은 비슷하다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Applications of Attention in our Model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Transformer에서 multi-head attention을 다음과 같은 방법으로 사용했다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;“encoder-decoder attention” layer에서 query들은 이전 decoder layer에서 온다. 그리고 encoder에서 온 key와 value를 사용한다. 따라서 decoder의 모든 위치의 token은 input sequence의 어느 곳이든 attend할 수 있게 된다.&lt;/li&gt;
  &lt;li&gt;encoder는 self-attention layer를 가진다. 모든 key, value, query는 같은 sequence에서 온다. 정확히는 이전 layer의 output에서 온다. 따라서 encoder는 이전 layer의 전체 위치를 attend할 수 있다.&lt;/li&gt;
  &lt;li&gt;decoder의 self-attention layer도 이전 layer의 모든 position을 attend 할 수 있는데, 정확히는 자신의 position이전의 position까지만 attend 할 수 있다. 직관적으로 이해하면 sequence에서 앞의 정보만을 참고할 수 있게 한 것이다. 이러한 목적을 scaled dot-product를 masking 함으로써 구현했다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;position-wise-feed-forward-networks&quot;&gt;Position-wise Feed-Forward Networks&lt;/h5&gt;

&lt;p&gt;attention sub-layer에 이어서 fully connected feed-forward network 거치게 되는데 이 network는 두개의 linear transformation으로 구성되어 있고 두 transformation 사이에 ReLU 함수를 사용한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\text{FFN}(x)=\max(0, xW_1+b_1)W_2+b_2&lt;/script&gt;

&lt;h5 id=&quot;embeddings-and-softmax&quot;&gt;Embeddings and Softmax&lt;/h5&gt;

&lt;p&gt;다른 sequence 모델과 유사하게 embedding vector를 사용한다. 입력 token을 linear transformation 해서 &lt;script type=&quot;math/tex&quot;&gt;d_{\text{model}}&lt;/script&gt; dimension vector로 바꿔주고 softmax로 나온 decoder의 결과 값을 predicted next-token으로 다시 linear transformation해서 바꿔준다. 모델 전체를 보면 3번 embedding 과정(역 embedding 포함)이 있는데, 이 때 linear transofrmation에 사용되는 weight matrix는 다 같은 matrix를 사용한다. 즉 2개의 embedding layer에서의 linear transformation과 softmax 다음의 linear transormation에서 같은 matrix를 사용하는 것이다.&lt;/p&gt;

&lt;h5 id=&quot;positional-encoding&quot;&gt;Positional Encoding&lt;/h5&gt;

&lt;p&gt;해당 모델에서는 recurrence나 convolution을 전혀 사용하지 않았기 떄문에, 추가적으로 위치 정보를 넣어줘야 한다. 따라서 “positional encoding”을 사용해서 input embedding에 위치 정보를 넣어준다. 각 위치에 대해서 embedding과 동일한 dimension을 가지도록 encoding을 해준 뒤 그 값을 embedding값과 더해서 사용한다.&lt;/p&gt;

&lt;p&gt;positional encoding에는 여러 방법이 있지만 여기서는 sin, cos 함수를 사용해서 구현한다. 각 위치 $pos$와 dimension $i$에 대한 positional encoding값은 다음과 같이 구한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\begin{matrix}
PE_{(pos,2i)}=\sin(pos/10000^{2i/d_{\text{model}}})\\
PE_{(pos,2i+1)}=\cos(pos/10000^{2i/d_{\text{model}}})
\end{matrix}&lt;/script&gt;

&lt;h4 id=&quot;why-self-attention&quot;&gt;Why self-attention&lt;/h4&gt;

&lt;p&gt;이 모델에서 recurrent 나 convolution을 사용하지 않고 self-attention만을 사용한 이유에 대해서 알아보자. 3가지 이유로 self-attention을 선택했다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;레이어당 전체 연산량이 줄어든다.&lt;/li&gt;
  &lt;li&gt;병렬화가 가능한 연산이 늘어난다.&lt;/li&gt;
  &lt;li&gt;long-range의 term들의 dependency도 잘 학습할 수 있게 된다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;그리고 위의 3가지 외에 또 다른 이유는 attention을 사용하면 모델 자체의 동작을 해석하기 쉬워진다는(interpretable) 장점 때문이다. attention 하나의 동작 뿐만 아니라 multi-head의 동작 또한 어떻게 동작하는지 이해하기 쉽다는 장점이 있다. 아래의 그림을 보면 어떻게 attention mechanism이 적용되는지 쉽게 이해할 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/b5ZiWkh.jpg&quot; alt=&quot;att&quot; /&gt;
&lt;img src=&quot;https://i.imgur.com/ZpAw6ml.jpg&quot; alt=&quot;att2&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;training&quot;&gt;Training&lt;/h4&gt;

&lt;p&gt;학습에 사용된 것들을 하나씩 알아보자.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Training data and batching&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;학습에 사용된 데이터는 WMT 2014 English-German 데이터 셋이다. 총 450만개의 영어-독일어 문장 쌍이 있다. 그리고 WMT 2014 English-French 데이터 셋도 사용했다. 총 360만개의 문장 쌍이 있다. 학습시 대략 25000개의 token을 포함하는 문장 쌍을 하나의 배치로 사용했다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optimizer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;학습에 사용된 optimizer는 Adam을 사용했다. 하이퍼 파라미터로는 $\beta_1=0.9$, $\beta_2=0.98$, $\epsilon=10^{-9}$를 사용했다. 학습률(learning rate)의 경우 학습 경과에 따라서 변화하도록 만들었다. 아래의 공식으로 학습률을 계산해서 적용했다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;lrate=d_{\text{model}}^{-0.5}\cdot\min(\text{step_num}^{-0.5},\text{step_num}\cdot \text{warmup_steps}^{-1.5})&lt;/script&gt;

&lt;p&gt;여기서 warmup_step의 값으로는 4000을 사용했다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Regularization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;학습 시 정규화를 위해서는 세가지 방법을 사용했다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Residual dropout&lt;/li&gt;
  &lt;li&gt;Attention dropout&lt;/li&gt;
  &lt;li&gt;label smoothing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;여기서 dropout 값은 0.1로 했고, label smoothing 값도 0.1로 설정했다.&lt;/p&gt;

&lt;h4 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;번역에서 Tansformer는 다른 모델들 보다 훨씬 빠르게 학습했다. 그리고 빠른 속도에도 성능에서도 이전의 모델들보다 좋은 성능을 보여줬다.&lt;/p&gt;

&lt;p&gt;Recurrent, convolution을 전혀 사용하지 않고 attention만 사용해서 만든 모델임에도 좋은 성능을 보여줬다. 우선 이 모델이 크게 의미하는 바는 빠른 학습속도를 보여준 것이다. 따라서 앞으로도 번역 뿐만 아니라 이미지 등 큰 input을 가지는 문제에도 적용할 수 있을 것이다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;오역 및 잘못된 내용이 있을 수 있습니다. 잘못된 부분 혹은 이해가 잘 안되는 부분은 댓글 혹은 메일로 말씀해주시면 감사하겠습니다!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>CS20(TensorFlow) Lecture Note (12): Machine Translation, Seqeunce-to-sequence and Attention</title>
   <link href="https://reniew.github.io/42/"/>
   <updated>2018-09-07T04:47:35+00:00</updated>
   <id>https://reniew.github.io/42</id>
   <content type="html">&lt;p&gt;스탠포드의 TensorFlow 강의인 cs20 강의의 lecture note를 정리한 글입니다. 강의는 오픈되지 않아서 Lecture note, slide 위주로 정리된 글임을 참고 해주시길 바랍니다. 강의의 자세한 Syllabus 및 자료들을 아래 링크를 참고해 주세요.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://web.stanford.edu/class/cs20si/&quot;&gt;CS20: TensorFlow for Deep Learning Research&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h5 id=&quot;post-list&quot;&gt;Post list&lt;/h5&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/32&quot;&gt;Lecture 1, 2: Overview &amp;amp; TensorFlow Operation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/33&quot;&gt;Lecture 3: Linear and Logistic Regression&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/34&quot;&gt;Lecture 4: Eager execution and interface&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/36&quot;&gt;Lecture 5: word2vec + manage experiments&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/38&quot;&gt;Lecture 6, 7: Intro to ConvNet &amp;amp; ConvNet in TensorFlow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/39&quot;&gt;Lecture 8: CNN(Style transfer), TFRecord &lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/40&quot;&gt;Lecture 10: Variational Auto Encoders(VAE)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/41&quot;&gt;Lecture 11: RNNs in the TensorFlow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/42&quot;&gt;Lecture 12: Machine Translation, Seqeunce-to-sequence and Attention&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;12-machine-translation-seqeunce-to-sequence-and-attention&quot;&gt;12. Machine Translation, Seqeunce-to-sequence and Attention&lt;/h3&gt;

&lt;p&gt;이번 강의에서 알아볼 내용은 크게 다음과같이 세가지로 나눌 수 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;새로운 task: Machine Translation&lt;/li&gt;
  &lt;li&gt;새로운 neural netwrok architecture: Sequence to sequence&lt;/li&gt;
  &lt;li&gt;새로운 neural technique: Attention&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위의 세가지는 각각 별개의 내용이 아니고 깊게 연관되어있다. Machine Translation을 위한 주로 사용하는 architecture가 seuqeunce to sequence이고, seqeunce to sequence를 사용할 때 같이 주로 사용하는 것이 attention 기술이다. 이제 하나씩 알아보도록 하자.&lt;/p&gt;

&lt;h4 id=&quot;machine-translation&quot;&gt;Machine Translation&lt;/h4&gt;

&lt;p&gt;Machine translation이란 말 그대로 기계를 통해 번역을 하는 문제다. 정확히 말하면 어떤 언어의 input sentence를 다른 언어의 output sentence로 만드는 task이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\begin{matrix}
\text{x:	L'homme est né libre, et partout il est dans les fers}\\
\downarrow\\
\text{y: 	Man is born free, but everywhere he is in chains
}
\end{matrix}&lt;/script&gt;

&lt;p&gt;기계번역은 시대에 따라서 번역을 하는 방법이 계속해서 바껴왔는데, 어떤 방식으로 진행해 왔는지 알아보자.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1950년대&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Machine Translation이 처음 나온것이 1950년이다. 시대적으로 기계번역이 나온 역사적 이유가있다. 이 시기는 냉전 시기로 소련과 미국은 항상 서로의 통신이나 기밀 문서들을 자동으로 번역해서 해석하기를 원했는데, 이를 위해 Machine Translation이 처음 도입된 것이다. 따라서 이당시의 machine translation은 주로 영어, 러시아어 번역이 대부분이였다.&lt;/p&gt;

&lt;p&gt;그리고 이 당시의 번역은 주로 rule-based 방식이였다. 즉 두 개의 언어의 사전을 통해 각 단어가 대응되는 것을 찾아서 번역하는 가장 단순한 방식이다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1990 ~ 2000년대 초반&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;기존의 rule-based 방식이 아닌 data를 통해서 번역하는 방식이 처음으로 사용되었다. 이때의 방식을 Statistical Machine Translation이라 부르는데, 데이터를 통해 확률 분포를 학습하는 방법이다.&lt;/p&gt;

&lt;p&gt;데이터를 통해 확률을 가장 높이는 방법으로 번역한다. 즉 특정 언어 input sentnece $x$에 대해서 또 다른 언어 output sentence인  $y$로 번역할 때 다음의 확률이 가장 높은 sentence를 선택하게 된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\arg\max_y P(x\vert y)P(y)&lt;/script&gt;

&lt;p&gt;그리고 실제로 사용할 때는 위의 수식을 bayes theorem을 사용해 다음과 같이 번형해서 두개의 부분을 계산하는 방식으로 수행한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\propto\arg\max_yP(x\vert y)P(y)&lt;/script&gt;

&lt;p&gt;위 식을 보면 $P(x\vert y)$와 $P(y)$로 두개의 두분으로 나뉘는데, 앞부분은 Translation Model이라 부르고 parallel 데이터를 통해서 확률을 계산하고 뒷부분은 Language Model으로 monolingual 데이터를 통해서 계산한다.&lt;/p&gt;

&lt;p&gt;여기서 parallel 데이터란, 문장들이 두개의 언어 모두로 표현되어 있는 데이터이다. 따라서 한 문장에 대해 두가지 언어표현을 통해 한 언어에 대한 다른 언어로 바꿧을 때의 확률을 계산할 수 있게 한다. 그리고 monolingual 데이터란 하나의 언어만 있는 데이터로 이 데이터를 통해 언어의 특성을 확률값으로 계산한다.&lt;/p&gt;

&lt;p&gt;Statistical machine translation(SMT)를 통해 기존의 rule-based 방식에 비해 정확도를 매우 높였지만 그럼에도 불구하고 alignment 문제가 아직 남아있다. alignment 문제란 번역에서 두개의 언어는 각각 특성이 달라서 단어들의 순서나 품사의 순서가 다른데 이러한 부분을 SMT로는 이런 부분까지 파악하기 어렵다는 점이다. 아래는 alignment가 제대로 이뤄지지 않은 번역을 나타낸다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\begin{matrix}
\text{x: i go to school}\\
\downarrow\\
\text{y: 나는 간다 학교에}
\end{matrix}&lt;/script&gt;

&lt;p&gt;위와 같은 alignment 문제가 있음에도 불구하고 SMT는 불과 몇 년전까지만 하더라도 대부분 사용하는 방법이였고, 많은 연구가 이뤄졌다. SMT의 특징을 정리하면 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;좋은 성능을 내는 SMT system은 매우 복잡한 구조이다.&lt;/li&gt;
  &lt;li&gt;각 system은 각 부분부분으로 나눠서 sub-system들이 모여있는 형태다.&lt;/li&gt;
  &lt;li&gt;많은 feature engineering이 필요하다.&lt;/li&gt;
  &lt;li&gt;추가적인 많은 자료를 필요로 한다.&lt;/li&gt;
  &lt;li&gt;사람의 손이 빠지고는 좋은 성능을 기대하기 어렵다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2014년 ~&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;2014년 Sequence to sequence라는 모델을 통해 Nerual Machine Translation이 도입되었다. 기존의 SMT모델에 비해 매우 간단함에도 불구하고 매우 높은 성능을 보여줬다. 그리고 현재의 대부분의 Machine translation은 NMT를 사용한다.&lt;/p&gt;

&lt;p&gt;세계에서 가장 많이 사용하는 번역기인 google 번역기도 2014년 sequence to sequence가 나온 2년뒤인 2016년 기존의 Statistical machine translation에서 Neural machine translation으로 바꾸었다. 기존의 SMT가 오랜 기간에 거쳐서 실제 사용할 수 있게된것에 비해 NMT의 경우에는 2년만에 바로 사용하는 것을 보면 성능이 좋다는 것을 의미한다고 볼 수 있다.&lt;/p&gt;

&lt;p&gt;그렇다면 NMT의 장점을 정리해서 보자. SMT에 비해 NMT는 다음의 장점이 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;높은 성능
    &lt;ul&gt;
      &lt;li&gt;더욱 사람이 한 것 같은 번역&lt;/li&gt;
      &lt;li&gt;문맥 이해를 잘한다&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;하나의 neural network만으로도 사용할 수 있다.&lt;/li&gt;
  &lt;li&gt;사람이 직접 engineering을 많이 하지 않아도 된다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;많은 장점이 있지만, 무조건 좋은 것은 아니다 NMT에도 다음과 같은 단점이 존재한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;해석하기 어렵다. 즉, 정확하게 어떻게 번역되는지 확인이 어려워 debug또한 어렵다.&lt;/li&gt;
  &lt;li&gt;위와 비슷한 이유로 제어하기 어렵다는 단점이 있다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;따라서 무조건 NMT만 사용하는 것이 아니라 SMT도 결합해 사용하거나 SMT를 아직 사용하기도 한다. 그리고 NMT를 사용할 때 어려운 점은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Out-of-vocabulary 문제&lt;/li&gt;
  &lt;li&gt;학습, 테스트 데이터의 domain이 다른 경우 성능이 떨어지는 문제&lt;/li&gt;
  &lt;li&gt;문장이 길어질 때 문맥을 이해하기 어려운 문제&lt;/li&gt;
  &lt;li&gt;language-pair 데이터가 많지 않은 문제&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;그리고 뿐만 아니라 NMT를 사용할 경우 아래와 같이 편향된 결과가 나올 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/BO401r4.jpg&quot; alt=&quot;kk&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Machine translation이 어떻게 발전해 왔는지 알아봤다. 최초의 방식부터 최근의 NMT 방식까지 다양한 모델들이 존재하는데, 그렇다면 machine translation 모델을 평가하는 것을 생각해보자. 사람이 직접하더라도 번역은 정답이 없는 문제이다. 하지만 우리는 모델을 평가해야 하는데 어떤 방식으로 평가할지를 정해야 한다. 따라서 평가 방식에 대해서 알아보자.&lt;/p&gt;

&lt;h4 id=&quot;how-to-evaluate-machine-translation&quot;&gt;How to evaluate Machine translation&lt;/h4&gt;

&lt;p&gt;machine translation이 제대로 이뤄졌는지 확인하는 대표적인 지표는 ‘BLUE’ 점수이다. 이 방법 외에도 다양한 방법이 있지만 아직까지는 대부분 BLUE 점수를 통해서 모델을 평가한다. 그렇다면 BLUE는 어떤 방식으로 모델을 평가하는지 알아보도록 하자.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BLUE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;BLUE(Bilingual Evaluation Understudy)란 기계에 의해 번역된 문장과 사람이 작성한 문장을 비교해서 유사도를 측정해서 성능을 측정하는 지표이다. 다음의 3가지 측면으로 평가를 한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;n-gram precision: 1 ~ 4 gram으로 나눠 얼마나 맞는지 확인&lt;/li&gt;
  &lt;li&gt;문장 길이가에 대한 패널티를 곱한다.(짧은 문장에 패널티)&lt;/li&gt;
  &lt;li&gt;같은 단어에 대한 보정&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위와 같은 계산 방식을 사용하며, 아직까지는 가장 많이 사용하는 지표이며, BLUE 점수가 절대적인것은 아니므로 다양한 지표로 평가를 해야한다.&lt;/p&gt;

&lt;h4 id=&quot;seqeunce-to-sequence&quot;&gt;Seqeunce to sequence&lt;/h4&gt;

&lt;p&gt;Sequence to sequence란 RNN을 사용해서 sequence를 다루는 모델이다. &lt;a href=&quot;https://arxiv.org/abs/1406.1078&quot;&gt;Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation&lt;/a&gt; 논문을 통해 처음 나왔으며 전체 내용에 대한 자세한 내용은 블로그 &lt;a href=&quot;https://reniew.github.io/31&quot;&gt;post&lt;/a&gt;를 참고하자.&lt;/p&gt;

&lt;p&gt;전체적인 모델을 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/z0tAytE.jpg&quot; alt=&quot;en-de&quot; /&gt;&lt;/p&gt;

&lt;p&gt;input sequence를 받아서 하나의 벡터로 encoding하는 앞부분과 encoding된 vector를 활용해서 output sequence를 만드는 decoder로 구성되어 있다.&lt;/p&gt;

&lt;p&gt;Machine translation에 적용해보면 input은 번역할 문장이 되고 outout은 번역이 완료된 다른 언어의 문장이 될 것이다.&lt;/p&gt;

&lt;p&gt;이 모델을 통해 처음으로 NMT가 시작되었지만 문제가 하나 있다. 모델을 보면 input을 단 하나의 벡터로 만드는데 이 과정에서 bottleneck 현상이 발생한다. 그리고 번역의 경우 alignment가 중요한데 위와 같은 구조로는 input의 alignment정보를 decoder로 전달하기 어렵다는 문제가 생긴다. 따라서 이러한 문제를 해결하기 위해서 사용된 기술이 Attention 기법이다.&lt;/p&gt;

&lt;h4 id=&quot;attention&quot;&gt;Attention&lt;/h4&gt;

&lt;p&gt;attention은 Sequence to sequence with attention이라 불리는 논문인 &lt;a href=&quot;https://arxiv.org/pdf/1409.0473.pdf&quot;&gt;Neural Machine Translation by Jointly Learning to Align and Translate&lt;/a&gt;에서 처음 제안된 기법이다. 이 논문에 대한 자세한 내용은 블로그 &lt;a href=&quot;https://reniew.github.io/37&quot;&gt;post&lt;/a&gt;를 참고하자.&lt;/p&gt;

&lt;p&gt;Attention 기법은 input 문장의 alignment정보를 decoder에 전달하기 위해 사용된다. 기존의 모델을 생각하면 input에 대한 정보를 하나의 vector로 만들어 output sequence를 만들 때 사용했었다. attention이란 위의 encoding된 vector와 함께 alignment 정보를 같이 사용해서 계산한뒤 sequence의 각 값들을 계산한다. 아래의 그림을 참고하면 attention이 어떤 구조로 계산되는지 어느정도 이해할 수 있을 것이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/HddESNP.gif&quot; alt=&quot;attention&quot; /&gt;&lt;/p&gt;

&lt;p&gt;output은 앞의 정보들을 계산해 가장 확률이 가장 높은 단어들이 나오는 구조인데, 이때 단순히 가장 높은 token을 선택하는 greedy한 방법을 사용하는 것이 아니라 Beam search라는 기법을 이용해서 output token을 선택한다. 마지막으로 beam search를 알아보자.&lt;/p&gt;

&lt;h4 id=&quot;beam-search&quot;&gt;Beam Search&lt;/h4&gt;

&lt;p&gt;beam search란 정해둔 크기(beam size)의 개수만큼 높은 확률의 token을 계속해서 후보로 두고 전체 output sequence를 선택하는 방식이다. 아래의 그림을 보면 beam search를 직관적으로 이해할 수 있을 것이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/TnXJIDl.gif&quot; alt=&quot;beam&quot; /&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>CS20(TensorFlow) Lecture Note (11): RNNs in the TensorFlow</title>
   <link href="https://reniew.github.io/41/"/>
   <updated>2018-09-06T04:47:35+00:00</updated>
   <id>https://reniew.github.io/41</id>
   <content type="html">&lt;p&gt;스탠포드의 TensorFlow 강의인 cs20 강의의 lecture note를 정리한 글입니다. 강의는 오픈되지 않아서 Lecture note, slide 위주로 정리된 글임을 참고 해주시길 바랍니다. 강의의 자세한 Syllabus 및 자료들을 아래 링크를 참고해 주세요.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://web.stanford.edu/class/cs20si/&quot;&gt;CS20: TensorFlow for Deep Learning Research&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h5 id=&quot;post-list&quot;&gt;Post list&lt;/h5&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/32&quot;&gt;Lecture 1, 2: Overview &amp;amp; TensorFlow Operation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/33&quot;&gt;Lecture 3: Linear and Logistic Regression&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/34&quot;&gt;Lecture 4: Eager execution and interface&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/36&quot;&gt;Lecture 5: word2vec + manage experiments&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/38&quot;&gt;Lecture 6, 7: Intro to ConvNet &amp;amp; ConvNet in TensorFlow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/39&quot;&gt;Lecture 8: CNN(Style transfer), TFRecord &lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/40&quot;&gt;Lecture 10: Variational Auto Encoders(VAE)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/41&quot;&gt;Lecture 11: RNNs in the TensorFlow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/42&quot;&gt;Lecture 12: Machine Translation, Seqeunce-to-sequence and Attention&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;11-rnns-in-the-tensorflow&quot;&gt;11. RNNs in the TensorFlow&lt;/h3&gt;

&lt;p&gt;이번 lecture에서 배울 내용은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;From feed-forward to recurrent&lt;/li&gt;
  &lt;li&gt;Tricks &amp;amp; treats&lt;/li&gt;
  &lt;li&gt;Presidential tweets&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;from-feed-forward-to-recurrent-neural-networksrnns&quot;&gt;From feed-forward to Recurrent Neural Networks(RNNs)&lt;/h4&gt;

&lt;p&gt;지난 몇년간 feed-forward network 부터 convolutional neural network는 좋은 결과를 보여줬고 많은 문제에 적용시켜서 엄청난 성과를 보여줬다.&lt;/p&gt;

&lt;p&gt;그럼에도 불구하고 아직도 이러한 feed-forward network와 convolutional neural network 모델로는 적용시키기 어려운 문제들이 아직 많이 있었다. 이러한 한계의 가장 큰 이유는 모델에 적용시킬 수 있는 data가 singular한 형태만 가능하기 때문이다. 따라서 언어나 음악과 같은 sequence데이터를 적용시키기에는 많은 어려움이 있었다. 따라서 위의 문제에 이어서 이런 sequencial한 데이터를 다루는 모델에 대해 연구가 많이 이뤄졌다.&lt;/p&gt;

&lt;p&gt;이러한 연구의 결과로 나온것이 RNN이다. RNN은 sequential한 정보를 잡아내기 위해 만들어 졌고 가장 기본적인 형태의 RNN인 Simple Recurrent Network(SRN)은 Jeff Elman에 의해 만들어졌다.&lt;/p&gt;

&lt;p&gt;RNN은 feed-forward의 unit과 똑같은 연산을 하는 unit이 적용되었다. 하지만 이러한 unit들이 계속해서 연결되어 있다는 점이다. Feed-forward의 경우 input에 의한 신호는 계속해서 한방향으로 이어지고, loop은 만들어 지지 않는다. 그에 반해 RNN은 loop이 생기고 neuron들이 각자 스스로 연결된다. 즉 이전의 neuron이 또 옆의 neuron에 영향을 준다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/TZZgorB.jpg&quot; alt=&quot;9999&quot; /&gt;&lt;/p&gt;

&lt;p&gt;가장 기본적인 형태의 RNN인 simple recurrent networks(SRN)은 Elman network와 Jordan network를 뜻한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Elman Network, Jordan Network&lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
h_t &amp;= \sigma_h(W_h x_t + U_h h_{t-1}+b_h)\\
y_t &amp;=\sigma_y(W_y h_t+b_y)
\end{align*} %]]&gt;&lt;/script&gt;

&lt;ul&gt;
  &lt;li&gt;$x_t$ : input vector&lt;/li&gt;
  &lt;li&gt;$h_t$ : hidden layer vector&lt;/li&gt;
  &lt;li&gt;$y_t$ : output vector&lt;/li&gt;
  &lt;li&gt;$W,~U$ : and $b$ : parameter matrices and vector&lt;/li&gt;
  &lt;li&gt;$\sigma_h$ and $\sigma_y$ : Activation functions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/SnG0uQ0.jpg&quot; alt=&quot;992&quot; /&gt;&lt;/p&gt;

&lt;p&gt;대부분의 사람들은 RNN을 NLP의 한 분야라 생각한다. 그도 당연할 것이 언어가 매우 대표적인 sequential한 데이터이기 때문이다. 그러나 NLP분야 외에도 audio, image, video등 많은 분야에서도 RNN은 사용된다. 가령 MNIST의 경우에도 적용할 수 있다. 이 때는 각 image를 pixel들의 sequence로 적용시킨다.&lt;/p&gt;

&lt;h4 id=&quot;back-propagation-through-timebptt&quot;&gt;Back-propagation through Time(BPTT)&lt;/h4&gt;

&lt;p&gt;Feed-forward와 Convolutional Network에서는 error를 back-propagation을 통해 loss 값이 모든 layer에 전달 되었다. 이런 방법을 통해 parameter들을 update시켰다.&lt;/p&gt;

&lt;p&gt;RNN에서는 erros는 loss값이 모든 timestep에 전달된다. 앞선 내용과 두가지 큰 차이점이 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;feed-forward의 각 layer는 각자 자신의 parameter를 가지는 반면 RNN에서는 모든 timestep들이 parameter들을 공유한다. 따라서 모든 timestep의 gradient 값들을 모두 합쳐서 parameter를 update하는데 적용시켰다.&lt;/li&gt;
  &lt;li&gt;feed-forward의 경우 고정된 숫자의 layer를 가지는 반면 RNN은 임의의 timestep 수를 가진다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;아래의 차이점을 보자. 만약에 sequence가 매우 길어진다면, back-propagation은 모든 time-step에서 계산되는데 이 계산량이 매우 많아질 것이다. 또다른 본질적인 문제는 gradient 자체가 매우 커지거나 매우 작아져서 학습이 불가능한 경우가 생긴다.(vanishing/exploding gradients)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/K53Co1t.jpg&quot; alt=&quot;9282&quot; /&gt;&lt;/p&gt;

&lt;p&gt;모든 timestep에서 모든 parameter를 update해서 계산량이 매우 많아지는 상황을 피하기 위해 보통 update시키는 timestep의 수를 제한시키는 방법을 사용한다.(truncated BPTT)&lt;/p&gt;

&lt;p&gt;TensorFlow에서 RNN은 unrolled된 버전의 network를 사용한다. 즉 정확히 몇 개의 timestep을 사용할지를 정해줘야 한다는 뜻이다. RNN의 특성을 생각해보면 이러한 구현 방법은 큰 제약이 된다. input의 경우 길이가 일정할 수도 있지만 정해지지 않을 수도 있기 떄문이다. 예를 들면 여러 text를 다루는데 하나의 text는 20개의 단어로 구성되지만 또 어떤 text는 200개의 단어로 구성될 수 있기 때문이다. 이러한 문제를 해결하기 위한 하나의 방법은 data를 나눠서 각각 다른 bucket으로 넣는 것이다. 이 bucket에는 비슷한 크기의 sequence가 들어간다. 만약 becket보다 길이가 짧다면 padding을 이용하면 된다.&lt;/p&gt;

&lt;h4 id=&quot;gated-recurrent-unitlstm-and-gru&quot;&gt;Gated Recurrent unit(LSTM and GRU)&lt;/h4&gt;

&lt;p&gt;실제로 RNN을 사용해보니 기대와는 달리 Long-term에 대한 정보를 잘 못잡아내는 것이 밝혀졌다. 이런 결함을 해결하기 위해 나온 것이 LSTM이다. 이러한 LSTM의 개발은 사실 오래전에 vanishing gradient 문제를 해결하기 위해 만들어 졌던 것이다.&lt;/p&gt;

&lt;p&gt;LSTM의 unit은 gating mechanism이라 불리는 것을 위해 사용된다. 총 4개의 gate가 사용되고 일반적으로 $i,o,f,\tilde{c}$로 작성하고 각각 input, output, forget, candidate/new memory gate라 부른다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
&amp;i^{(t)}=\sigma(W^{(i)}x^{(t)}+U^{(i)}h^{(t-1)})\\
&amp;f^{(t)}=\sigma(W^{(f)}x^{(t)}+U^{(f)}h^{(t-1)})\\
&amp;o^{(t)}=\sigma(W^{(o)}x^{(t)}+U^{(o)}h^{(t-1)})\\
&amp;\tilde{c}^{(t)}=\tanh(W^{(c)}x^{(t)}+U^{(c)}h^{(t-1)})\\
&amp;c^{(t)}=f^{(t)}\circ\tilde(c)^{(t-1)}+i^{(t)}\circ\tilde{c}^{(t)}\\
&amp;h^{(t)}=o^{(o)}\circ\tanh(c^{(t)})
\end{algin*} %]]&gt;&lt;/script&gt;

&lt;p&gt;직관적인 각 gate에 대한 이해는 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;input gate: 현재 input이 얼마나 사용할지 결정한다.&lt;/li&gt;
  &lt;li&gt;forget gate: 이전 state의 정보를 얼마나 사용할지 결정한다.&lt;/li&gt;
  &lt;li&gt;output gate: hidden state 값이 다음 timestep에 얼마나 전달할지 결정한다.&lt;/li&gt;
  &lt;li&gt;candidate gate: 일반적인 RNN와 유사한 부분이다. 이전 hidden state 값과 현재 input값을 기반으로 candidate를 계산한다.&lt;/li&gt;
  &lt;li&gt;final memory cell: candidate hidden state들을 합쳐서 내부의 memory 값을 만든다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Long Term에 대한 정보를 잡아내기 위한 모델에 LSTM 뿐만 아니라 GRU도 많이 사용된다. 조금 다른 구조이지만 거의 유사한 방식으로 동작한다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/YpHfETv.jpg&quot; alt=&quot;119&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;application&quot;&gt;Application&lt;/h4&gt;

&lt;p&gt;RNN모델을 활용한 application은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Language modeling&lt;/li&gt;
  &lt;li&gt;Machine Translation&lt;/li&gt;
  &lt;li&gt;Text Summarization&lt;/li&gt;
  &lt;li&gt;Image Captioning&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;rnn-in-tensorflow&quot;&gt;RNN in TensorFlow&lt;/h4&gt;

&lt;p&gt;RNN은 기본적으로 하나하나의 cell들이 결합된 구조이다. TensorFlow에서는 여러가지 RNN 모델을 만들기 위해 다음과 같은 cell들을 지원한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;BasicRNNCell: 가장 기본적인 RNN cell&lt;/li&gt;
  &lt;li&gt;RNNCell: RNN Cell을 위한 Abstract Object&lt;/li&gt;
  &lt;li&gt;BasicLSTMCell: 기본적인 LSTM recurrent network cell&lt;/li&gt;
  &lt;li&gt;LSTMCell: LSTM recurrent network cell&lt;/li&gt;
  &lt;li&gt;GRUCell: GRU cell&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위의 cell들은 다음과 같이 구현한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rnn_cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GRUCell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hidden_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그리고 RNN의 모델을 생각해보자. cell들이 stacked된 구조이다. 따라서 여러개의 cell들을 쌓아야하는데 다음과 같이 구현하면 된다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rnn_cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GRUCell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hidden_sizes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cells&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rnn_cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MultiRNNCell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그리고 동적으로 graph를 만들기 위해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.nn.dynamic_rnn&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.nn.bidirectional_dynamic_rnn&lt;/code&gt;를 사용한다. 설명은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.nn.dynamic_rnn&lt;/code&gt;: tf.While loop을 사용해서 동적으로 graph를 만든다. graph의 생성이 빠르고 batch를 가변 크기로 사용할 수 있다.(batch의 가변길이가 sequence의 가변길이를 뜻하진 않음)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.nn.bidirectional_dynamic_rnn&lt;/code&gt;: 위와 같은 방식이지만 양방향의 RNN을 만들 수 있다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dynamic_rnn&lt;/code&gt;을 사용해서 다음과 같이 RNN들을 stack 할 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rnn_cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GRUCell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hidden_sizes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cells&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rnn_cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MultiRNNCell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dynamic_rnn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;하지만 앞서 소개한 RNN의 제약을 생각해보자. sequence는 어느정도 비슷한 크기를 가져야 했었다. 따라서 일정 크기(max_length)를 정하고 그 크기보다 큰 경우 자르고 크기보다 작은 경우에는 zero-padding을 사용한다.&lt;/p&gt;

&lt;p&gt;하지만 padding을 사용하는 것에도 새로운 문제가 생긴다. input 뿐만 아니라 label에도 padding을 해야하는데 이렇게 label에 padding을 하게되면 loss에 영향을 줘서 학습에 문제가 생길 수 있다. 이를 해결하기 위한 두 가지 접근법이 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Approach 1
    &lt;ul&gt;
      &lt;li&gt;mask를 사용한다. 실제 label에는 True값을 주고 padding된 label에는 False를 준다.&lt;/li&gt;
      &lt;li&gt;model을 real/padded token 모두를 가지고 돌린다.&lt;/li&gt;
      &lt;li&gt;real 값들만을 가지고 loss를 계산한다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이 방법을 사용하기 위한 구현은 다음과 같다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;full_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;softmax_cross_entropy_with_logits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;preds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce_mean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;boolean_mask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;full_loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Approach 2
    &lt;ul&gt;
      &lt;li&gt;model에게 실제 sequence 길이를 알려줘서 예측도 실제 길이만큼만 하도록 해서 label과 비교한다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이 방법을 사용한 구현은 다음과 같다. (line 3)&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rnn_cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GRUCell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hidden_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rnn_cells&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rnn_cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MultiRNNCell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce_max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dynamic_rnn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;tips-and-tricks-for-implementation&quot;&gt;Tips and Tricks for implementation&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Vanishing Gradient&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;RNN의 중요한 문제점 중 하나인 Vanishing gradient를 막기위해서는 다음과 같은 방법을 사용할 수 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;다른 종류의 Activation 함수 사용하기(ReLU계열)
    &lt;ul&gt;
      &lt;li&gt;tf.nn.relu&lt;/li&gt;
      &lt;li&gt;tf.nn.relu6&lt;/li&gt;
      &lt;li&gt;tf.nn.crelu&lt;/li&gt;
      &lt;li&gt;tf.nn.elu&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;다른 종류의 Activation 함수 사용하기(기타)
    &lt;ul&gt;
      &lt;li&gt;tf.nn.softplus&lt;/li&gt;
      &lt;li&gt;tf.nn.softsign&lt;/li&gt;
      &lt;li&gt;tf.nn.bias_add&lt;/li&gt;
      &lt;li&gt;tf.sigmoid&lt;/li&gt;
      &lt;li&gt;tf.tanh&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Exploding Gradient&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;그리고 또 하나의 문제점인 Exploding gradient를 방지하기 위해서 gradient 값을 일정 크기 이상 못올라가도록 제한시킨다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# 모든 학습가능한 변수들에 대한 cost의 gradient를 구한다.
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gradients&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gradients&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;trainable_variables&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# gradient를 일정 크기 이상 못올라가도록 할 clip을 정의한다.
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clipped_gradients&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clip_by_global_norm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gradients&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;max_grad_norm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AdamOptimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;learning_rate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;train_op&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apply_gradients&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gradients&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trainables&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Anneal learning rate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;학습률(learning rate)를 학습 과정에서 점차 감소키는 방법은 다음과 같다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;learning_rate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exponential_decay&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init_lr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
										   &lt;span class=&quot;n&quot;&gt;global_step&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
										   &lt;span class=&quot;n&quot;&gt;decay_steps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
										   &lt;span class=&quot;n&quot;&gt;decay_rate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
										   &lt;span class=&quot;n&quot;&gt;staircase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AdamOptimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;learning_rate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Overfitting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dropout을 사용해서 overfitting을 방지하는데 dropout을 사용하는 방법은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.nn.dropout&lt;/code&gt;을 사용하는 방법과, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DropoutWrapper&lt;/code&gt;를 사용하는 두 가지 방법이 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.nn.dropout&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;hidden_layer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dropout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hidden_layer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keep_prob&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;DropoutWrapper&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rnn_cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GRUCell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hidden_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rnn_cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DropoutWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;     
                                    &lt;span class=&quot;n&quot;&gt;output_keep_prob&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keep_prob&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;language-modeling-in-tensorflow&quot;&gt;Language Modeling in TensorFLow&lt;/h4&gt;

&lt;p&gt;이번에는 TensorFlow를 통해 Language modeling을 구현해보도록 한다. 우선 어떤 language modeling을 할지 부터 정해야 하는데, 보통 흔히 사용되는 Neural Language Modeling은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Word-level: n-gram
    &lt;ul&gt;
      &lt;li&gt;매우 전통적인 모델이다.&lt;/li&gt;
      &lt;li&gt;특정 단어 이전의 n개의 단어를 통해 특정 단어를 예측하는 모델.&lt;/li&gt;
      &lt;li&gt;단어를 미리 저장하는 vocabulary가 필요한데 이 크기가 매우 크다.&lt;/li&gt;
      &lt;li&gt;Out-of-vocabulary에 대한 대처가 필요하다.&lt;/li&gt;
      &lt;li&gt;많은 메모리를 요구한다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Character-level
    &lt;ul&gt;
      &lt;li&gt;input과 output모두 문자 하나하나로 구성된다.&lt;/li&gt;
      &lt;li&gt;vocabulary 크기가 매우 작다(영어의 경우 소문자 26개)&lt;/li&gt;
      &lt;li&gt;단어 embedding 과정이 필요없다.&lt;/li&gt;
      &lt;li&gt;학습이 빠르다.&lt;/li&gt;
      &lt;li&gt;유연하지 않은 단점이 있다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Subword-level:
    &lt;ul&gt;
      &lt;li&gt;input과 output이 subword이다.&lt;/li&gt;
      &lt;li&gt;W개의 가장 자주나오는 단어와, S개의 자주나오는 음절을 정한 후 기존 text를 변형 시킨다. (e.g new company dreamworks interactive -&amp;gt; new company dre+ am+ wo+ rks: in+ te+ ra+ cti+ ve:)&lt;/li&gt;
      &lt;li&gt;word-level과 char-level보다 좋은 성능을 보인다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이번 구현에서는 Character-level의 모델을 만들어 보도록 한다. 데이터는 ‘Donald Trump’s tweets’데이터로 2018년 2월 15일까지의 donald trump의 트윗으로 구성되어 있다. 총 19,469개의 트윗이 있으며 각각 최대 140자이다. 그리고 트윗의 모든 링크들 즉, URL은 __HTTP__로 작성되어 있다. 데이터를 학습시킨 후 나온 결과는 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/M8tr031.jpg&quot; alt=&quot;wwwwwww&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이제 구현을 해보자. 먼저 우리가 사용할 라이브러리들을 import먼저 한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;environ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'TF_CPP_MIN_LOG_LEVEL'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'2'&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;random&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'..'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;time&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;tensorflow&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;utils&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;우선은 char를 각각의 input으로 넣는다고 했었다. 그렇다고 input으로 바로 ‘c’를 넣는 것이 아니라 전체 character들을 vocabulary에 넣고 각 character를 index화 시켜서 input으로 넣는다. 즉 각 input의 character에 해당하는것을 vocabulary에서 찾고 index를 반환하는 encode함수와 출력시 다시 숫자를 character로 바꿔주는 decode함수부터 구현한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# encode 후 index를 0이 아닌 1부터 갖도록 만든다.
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;vocab_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;vocab_decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제 데이터를 불러오는 함수를 만들어야 한다. 데이터는 txt 파일로 되어있다. 각 데이터를 한 줄씩 읽어와서 위에 정의한 encode함수를 사용해서 vector화 시켜준다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;read_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;overlap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'r'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readlines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shuffle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vocab_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;overlap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;window&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그리고 불러온 데이터를 배치화 시켜주는 함수를 만든다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;read_batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제 전체 모델을 Class 형태로 만들어 준다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CharRNN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'data/'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'.txt'&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;$%'()+,-./0123456789:;=?ABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;&lt;/span&gt;
                    &lt;span class=&quot;s&quot;&gt;&quot; '&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;_abcdefghijklmnopqrstuvwxyz{|}@#➡📈&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;placeholder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hidden_sizes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0003&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;skip_step&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_steps&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# for RNN unrolled
&lt;/span&gt;        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len_generated&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gstep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trainable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'global_step'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create_rnn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rnn_cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GRUCell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hidden_sizes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cells&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rnn_cell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MultiRNNCell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;zero_states&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cells&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zero_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;float32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;placeholder_with_default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]])&lt;/span&gt;
                                &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zero_states&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# this line to calculate the real length of seq
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# all seq are padded to be of the same length, which is num_steps
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce_max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dynamic_rnn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cells&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;one_hot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_rnn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dense&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;softmax_cross_entropy_with_logits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                                                        &lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:])&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# sample the next character from Maxwell-Boltzmann Distribution
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# with temperature temp. It works equally well without tf.exp
&lt;/span&gt;        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sample&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;multinomial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[:,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;opt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AdamOptimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;minimize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;global_step&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gstep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;saver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Saver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;min_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FileWriter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'graphs/gist'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;global_variables_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;ckpt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_checkpoint_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'checkpoints/'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'/checkpoint'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ckpt&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ckpt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model_checkpoint_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;saver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;restore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ckpt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model_checkpoint_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;iteration&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gstep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_steps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;overlap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_steps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

            &lt;span class=&quot;c1&quot;&gt;# for batch in read_batch(read_data(DATA_PATH, vocab)):
&lt;/span&gt;                &lt;span class=&quot;n&quot;&gt;batch_loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;opt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iteration&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;skip_step&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Iter {}. &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;    Loss {}. Time {}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iteration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch_loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                    &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;online_infer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;checkpoint_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'checkpoints/'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'/char-rnn'&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;min_loss&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;saver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;checkpoint_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iteration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;min_loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;saver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;checkpoint_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iteration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;min_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch_loss&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;iteration&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;online_infer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot; Generate sequence one character at a time, based on the previous character
        &quot;&quot;&quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Hillary'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'I'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'R'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'T'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'@'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'N'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'M'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'.'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'G'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'A'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'W'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;sentence&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len_generated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vocab_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sentence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;feed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# for the first decoder step, the state is None
&lt;/span&gt;                    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;feed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]})&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sample&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;feed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;sentence&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vocab_decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sentence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;마지막으로 구현한 모델들을 실행시키는 main함수를 넣으면 끝난다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'trump_tweets'&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;utils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;safe_mkdir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'checkpoints'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;utils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;safe_mkdir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'checkpoints/'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;lm&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CharRNN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;lm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;lm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'__main__'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;RNN을 통해 character단위 뿐만 아니라 word level등 다양한 모델을 만들 수 있으므로 이번 기회에 자세히 알아보도록 하자.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>CS20(TensorFlow) Lecture Note (8): CNN(Style transfer), TFRecord</title>
   <link href="https://reniew.github.io/39/"/>
   <updated>2018-08-16T04:47:35+00:00</updated>
   <id>https://reniew.github.io/39</id>
   <content type="html">&lt;p&gt;스탠포드의 TensorFlow 강의인 cs20 강의의 lecture note를 정리한 글입니다. 강의는 오픈되지 않아서 Lecture note, slide 위주로 정리된 글임을 참고 해주시길 바랍니다. 강의의 자세한 Syllabus 및 자료들을 아래 링크를 참고해 주세요.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://web.stanford.edu/class/cs20si/&quot;&gt;CS20: TensorFlow for Deep Learning Research&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h5 id=&quot;post-list&quot;&gt;Post list&lt;/h5&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/32&quot;&gt;Lecture 1, 2: Overview &amp;amp; TensorFlow Operation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/33&quot;&gt;Lecture 3: Linear and Logistic Regression&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/34&quot;&gt;Lecture 4: Eager execution and interface&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/36&quot;&gt;Lecture 5: word2vec + manage experiments&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/38&quot;&gt;Lecture 6, 7: Intro to ConvNet &amp;amp; ConvNet in TensorFlow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/39&quot;&gt;Lecture 8: CNN(Style transfer), TFRecord &lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/40&quot;&gt;Lecture 10: Variational Auto Encoders(VAE)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/41&quot;&gt;Lecture 11: RNNs in the TensorFlow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/42&quot;&gt;Lecture 12: Machine Translation, Seqeunce-to-sequence and Attention&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;8-cnnstyle-transfer-tfrecord&quot;&gt;8. CNN(Style transfer), TFRecord&lt;/h3&gt;

&lt;p&gt;이번 lecture에서는 TFRecord와 Style transfer에 대해서 알아보도록 한다. TFRecord란 텐서플로우 데이터 포맷이다. tensorflow에서 추천하는 포맷인 만큼 이번 장에서 알아보자.&lt;/p&gt;

&lt;h4 id=&quot;tfrecord&quot;&gt;TFRecord&lt;/h4&gt;

&lt;p&gt;TFRecord는 TensorFlow 데이터 포맷으로, 바이너리 형식으로 저장된다. 따라서 dick cache를 효율적으로 사용하고, 사용 시 속도가 빠르다. 그리고 바이너리 형식이라 다른 형식의 데이터들도 같이 다룰 수 있다.(image 와 label을 같이 넣을 수 있다)&lt;/p&gt;

&lt;p&gt;image와 label을 TFRecord 파일로 저장하는 방법에 대해서 알아보자.&lt;/p&gt;

&lt;p&gt;먼저 TFRecord 파일을 작성할 writer를 만든다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Python&quot;&gt;writer = tf.python_io.TFRecrodWriter(out_file)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;그리고 image의 shape과 value(binary)를 가져온다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;binary_image&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_image_binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;다음으로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.train.Features&lt;/code&gt; 객체를 만든다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;features&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;feature&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'label'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_int64_feature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                                        &lt;span class=&quot;s&quot;&gt;'shape'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_bytes_feature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                                        &lt;span class=&quot;s&quot;&gt;'image'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_bytes_feature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;binary_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위에서 정의한 feature들을 포함하는 sample을 만든다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;sample&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Example&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;features&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;마지막으로 sample을 TFRecord파일로 작성한후 writer를 close한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sample&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SerializeToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;TFRecord파일로 저장하는 방법이 끝났다. 위의 저장하는 과정을 보면 각각 int와 byte값으로 형식이 다르더라도 같이 저장할 수 있다는 장점이 있다.&lt;/p&gt;

&lt;p&gt;위에서 사용한 각 다른 데이터 형식을 하나의 byte string으로 만드는 함수인 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_int64_feature&lt;/code&gt;와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_bytes_feature&lt;/code&gt;는 다음과 같이 정의된다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_int64_feature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Feature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int64_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Int64List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_bytes_feature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Feature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Bytes64List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제 저장한 TFRecord 파일을 사용하는 방법에 대해서 알아보자. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.data&lt;/code&gt;를 이용해서 불러올 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TFRecordDataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tfrecord_files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 불러올 수 있다. 하지만 저장할 때를 생각해보자. 각각 다른 데이터 형식을 하나의 데이터로 저장했었다. 따라서 불러온 후 다시 다른 데이터 형식은 나눠줘야 한다. 따라서 파싱하는 함수인 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_parse_function_&lt;/code&gt;을 정의한후 이용하면 된다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_parse_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tfrecord_serialized&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;features&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'label'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FixedLenFeature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;'shape'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FixedLenFeature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;'image'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FixedLenFeature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그리고 정의한 함수를 데이터의 mapping 함수로 적용하면 된다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_parse_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;TFRecord를 이용해서 데이터를 저장하고 불러오는 방법에 대해서 알아봤다. 전체 코드는 &lt;a href=&quot;https://github.com/chiphuyen/stanford-tensorflow-tutorials&quot;&gt;github&lt;/a&gt;를 참고하자.&lt;/p&gt;

&lt;h4 id=&quot;style-transfer&quot;&gt;Style transfer&lt;/h4&gt;

&lt;p&gt;Style transfer란 두개의 이미지를 사용해서 하나의 이미지에 다른 하나의 이미지의 style을 적용시키는 모델이다. 아래 그림은 Deadpool 그림이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/g3YRW5H.jpg&quot; alt=&quot;dea&quot; /&gt;&lt;/p&gt;

&lt;p&gt;그리고 아래는 Picasso의 Guernica라는 그림이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/oiCnufE.jpg&quot; alt=&quot;guer&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이 두 이미지를 가지고 style transfer 모델에 적용시키면, Picasso의 Guernica그림의 style을 Deadpool 그림에 적용시킬 수 있다. 즉 아래의 그림처럼 된다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/ApStIEK.jpg&quot; alt=&quot;e,c&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이 모델에서는 중요한 두가지 loss가 정의된다. 여기서 내용 이미지는 위의 예시로 보면 Deadpool 이미지가 되고 스타일 이미지는 피카소의 이미지가 된다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Content loss&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;내용 이미지의 내용과 생성된 이미지의 내용간의 content loss를 측정&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathcal{L}_{content}(\vec{p}, \vec{x}, l) = \frac{1}{2}\sum_{i,j}(F^l_{ij}-P^l_{ij})^2&lt;/script&gt;

&lt;ul&gt;
  &lt;li&gt;Style loss&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;스타일 이미지의 스타일과 생성된 이미지의 스타일간의 style loss를 측정&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\begin{matrix}
E_l=\frac{1}{4N^2_lM^2_l}\sum_{ij}(G^l_{ij}-A^l_{ij})^2\\
\mathcal{L}(\vec{a}, \vec{x})=\sum^L_{l=0}w_lE_l
\end{matrix}&lt;/script&gt;

&lt;p&gt;그리고 이 모델의 Optimizer는 두개의 loss를 같이 최소화 하도록 한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathcal{L}_{total}(\vec{p},\vec{a},\vec{x})=\alpha\mathcal{L}_{content}(\vec{p},\vec{x})+\beta\mathcal{L}_{style}(\vec{a},\vec{x})&lt;/script&gt;

&lt;p&gt;그리고 구현 과정에 대해서 설명하면 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;가중치 대신 input값을 학습한다.&lt;/li&gt;
  &lt;li&gt;같은 변수를 공유해서 사용한다.&lt;/li&gt;
  &lt;li&gt;Pre-trained 된 가중치를 사용했다.(VGG-19)&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>CS20(TensorFlow) Lecture Note (6), (7): Intro to ConvNet & ConvNet in TensorFlow</title>
   <link href="https://reniew.github.io/38/"/>
   <updated>2018-08-16T04:47:35+00:00</updated>
   <id>https://reniew.github.io/38</id>
   <content type="html">&lt;p&gt;스탠포드의 TensorFlow 강의인 cs20 강의의 lecture note를 정리한 글입니다. 강의는 오픈되지 않아서 Lecture note, slide 위주로 정리된 글임을 참고 해주시길 바랍니다. 강의의 자세한 Syllabus 및 자료들을 아래 링크를 참고해 주세요.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://web.stanford.edu/class/cs20si/&quot;&gt;CS20: TensorFlow for Deep Learning Research&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h5 id=&quot;post-list&quot;&gt;Post list&lt;/h5&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/32&quot;&gt;Lecture 1, 2: Overview &amp;amp; TensorFlow Operation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/33&quot;&gt;Lecture 3: Linear and Logistic Regression&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/34&quot;&gt;Lecture 4: Eager execution and interface&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/36&quot;&gt;Lecture 5: word2vec + manage experiments&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/38&quot;&gt;Lecture 6, 7: Intro to ConvNet &amp;amp; ConvNet in TensorFlow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/39&quot;&gt;Lecture 8: CNN(Style transfer), TFRecord &lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/40&quot;&gt;Lecture 10: Variational Auto Encoders(VAE)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/41&quot;&gt;Lecture 11: RNNs in the TensorFlow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/42&quot;&gt;Lecture 12: Machine Translation, Seqeunce-to-sequence and Attention&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;6-intro-to-convnet&quot;&gt;6. Intro to ConvNet&lt;/h3&gt;

&lt;p&gt;5장에서는 Convolution에 대한 소개를 하고 있고, 6장에서는 Convolutional Neural Network를 TensorFlow에서 구현하는 방법에 대해서 설명하고 있다. 5장의 내용인 CNN에 대한 소개는 블로그 포스팅으로 대체 한다. 아래의 글들을 참고하자.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/06&quot;&gt;About CNN&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/08&quot;&gt;Modern CNN&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/10&quot;&gt;Image Detection&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/11&quot;&gt;Image Detection 2&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/17&quot;&gt;Semantic Segmentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;7-convnet-in-tensorflow&quot;&gt;7. ConvNet in TensorFlow&lt;/h3&gt;

&lt;p&gt;Convolutional Neural Network에 대해서는 위 글들을 통해 확인 했다면 이제 CNN을 TensorFLow에서 구현하는 방법에 대해서 알아보자. 우선은 Convolution을 구현하기 위한 핵심 모듈인 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.nn.conv2d&lt;/code&gt;에 대해서 알아보자. 함수는 아래와 같이 구성된다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conv2d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;strides&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;use_cudnn_on_gpu&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;data_format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'NHWC'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;dilations&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;input과 filter, 그리고 Stride의 형태는 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Input: Batch Size (N) x Height (H) x Width (W) x Channels (C)&lt;/li&gt;
  &lt;li&gt;Filter: Height x Width x Input Channels(channel) x Output Channel(# of filters)&lt;/li&gt;
  &lt;li&gt;Stride: 1 x stride x stride x 1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;conv2d는 우리가 흔히 사용하는 일반적인 Convolution이라고 생각하면 된다. 그렇다면 또 다른 convolution 모듈인 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.nn.conv1d&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.nn.conv3d&lt;/code&gt;와는 어떤 차이가 있을까?&lt;/p&gt;

&lt;p&gt;큰 차이는 Output의 형태, convolution이 수행되는 방향(direction) 이 두 가지로 분류할 수 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Output의 shape&lt;/li&gt;
&lt;/ul&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Conv&lt;/th&gt;
      &lt;th&gt;특징&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conv1d&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;output이 1D array(vector)가 된다.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conv2d&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;output이 2D array(matrix)가 된다.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conv3d&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;output이 3D array(tensor)가 된다.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;ul&gt;
  &lt;li&gt;Convolution이 수행되는 방향&lt;/li&gt;
&lt;/ul&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Conv&lt;/th&gt;
      &lt;th&gt;특징&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conv1d&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;한 방향으로만 수행된다. (1-direction)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conv2d&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;두 방향으로 수행된다. (2-direction)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conv3d&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;세 방향으로 수행된다. (3-direction)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;위의 두 가지 차이점 외에 또 다른 차이점은 filter의 크기와 관련되어있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Filter의 크기&lt;/li&gt;
&lt;/ul&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Conv&lt;/th&gt;
      &lt;th&gt;특징&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conv1d&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;input과 filter의 Height(dimension), channel값이 같다.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conv2d&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;input과 filter의 channel만 같다.(Height은 filter가 더 작다)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conv3d&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;filter의 height과 channel이 모두 input보다 작다.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;사실상 위의 세가지 차이점 모두 일맥 상통하는 얘기이다. 마지막 차이점이 있기 떄문에 direction이 차이가 생기고 이 차이 때문에 output값의 차이가 생기는 것이다.&lt;/p&gt;

&lt;p&gt;아래의 그림을 보면 좀더 명확히 이해가 될 것이다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conv1d&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://i.stack.imgur.com/woaXM.jpg&quot; alt=&quot;conv1dd&quot; /&gt;
&lt;img src=&quot;https://i.stack.imgur.com/9VBtu.jpg&quot; alt=&quot;conv1d&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conv2d&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://i.stack.imgur.com/49cdt.png&quot; alt=&quot;conv2d&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conv3d&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://i.stack.imgur.com/IvDQP.png&quot; alt=&quot;conv3d&quot; /&gt;&lt;/p&gt;

&lt;p&gt;(출처:  https://stackoverflow.com/questions/42883547/what-do-you-mean-by-1d-2d-and-3d-convolutions-in-cnn)&lt;/p&gt;

&lt;p&gt;이제 MNIST 데이터를 Classification하는 Convolutional Neural Network를 TensorFlow로 구현하는 방법에 대해서 알아보자.&lt;/p&gt;

&lt;h4 id=&quot;convnet-on-mnist&quot;&gt;ConvNet on MNIST&lt;/h4&gt;

&lt;p&gt;이전 3강에서 MNIST 손글씨 이미지를 Logistic Regression을 통해 분류하는 모델을 이미 만들었다. 이번에는 CNN 모델을 통해 MNIST 분류기를 만들어 보도록 한다.&lt;/p&gt;

&lt;p&gt;먼저 우리가 만들 모델에 대해서 간략히 소개하면, 두개의 conv layer를 사용하고 각각 ReLU함수와 max-pooling layer를 적용하고, 두개의 fully connected layer를 사용한다. stride = 1 으로 적용한다. 만들 모델을 도식화하면 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/s44aTqq.jpg&quot; alt=&quot;convmnis&quot; /&gt;&lt;/p&gt;

&lt;p&gt;모델을 보면 (Conv + ReLU), (Max-Pooling), (fc layer)를 각각 두번씩 적용하기 때문에 재사용가능 하도록 함수로 정의한 후 모델을 만든다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Convolutional layer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;앞서 설명한 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.nn.cocnv2d&lt;/code&gt;를 사용해서 convolutional layer를 구현할 것이다. 여기에 우리는 활성화 함수 ReLU를 추가하면 된다. 아래와 같이 함수를 정의하자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;conv_relu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stride&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;variable_scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scope_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AUTO_REUSE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;in_channels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;kernel&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'kernel'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in_channels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                                &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;truncated_normal_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;biases&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'biases'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_normal_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;conv&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conv2d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kernel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strides&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stride&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stride&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;relu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conv&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;biases&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;중간의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;in_channels&lt;/code&gt; 값은 Image의 channel 값이 된다. RGB이미지는 채널이 3이 될 것이고 MNIST는 흑백 이미지 이므로 1이 된다.&lt;/p&gt;

&lt;p&gt;다음 함수를 정의하기 전에 output의 size를 구하는 공식을 확인하고 넘어가자.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Input 크기 ($W$)&lt;/li&gt;
  &lt;li&gt;Filter 크기 ($F$)&lt;/li&gt;
  &lt;li&gt;Stride 값 ($S$)&lt;/li&gt;
  &lt;li&gt;padding 값 ($P$)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위와 같이 입력값을 가질때 output의 size는 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\frac{W-F+2P}{S}+1&lt;/script&gt;

&lt;p&gt;우리가 만드는 MNIST 모델에서 적용해보면, input은 28x28 size이고, filter는 5x5크기를 사용한다. 그리고 stride는 1, padding은 2를 사용한다. 따라서 output의 크기는 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\frac{28-5+2\times2}{1}+1 = 28&lt;/script&gt;

&lt;p&gt;&lt;strong&gt;Pooling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pooling은 feature map의 차원 수를 감소시켜서 특징을 추출하고, 수행 시간을 감소시키는 역할을 한다. 보통 max-pooling 혹은 average-pooling을 사용한다. 이 모델에서는 max-pooling을 사용하므로 아래와 같이 max-pooling 함수를 정의하자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;maxpool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ksize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stride&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'VALID'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'pool'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;variable_scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scope_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AUTO_REUSE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;pool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;ksize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ksize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ksize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;strides&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stride&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stride&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pool&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;pooling을 적용시켰을 떄의 output 크기의 공식은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;input 크기 ($W$)&lt;/li&gt;
  &lt;li&gt;pooling 크기 ($K$)&lt;/li&gt;
  &lt;li&gt;pooling 시 stride 값 ($S$)&lt;/li&gt;
  &lt;li&gt;padding 값 ($P$)&lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\frac{W-K+2P}{S}+1&lt;/script&gt;

&lt;p&gt;우리의 모델에서는 input은 28x28이고, pooling 크기는 2x2이고, stride는 2이고, padding은 하지 않으므로 다음과 같이 output 크기를 가질 것이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\frac{28-2+2\times0}{2}+1=14&lt;/script&gt;

&lt;p&gt;&lt;strong&gt;Fully Connected&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;fc layer를 정의해야 한다. 아래와 같이 정의하자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fully_connected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out_dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'fc'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;variable_scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scope_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AUTO_REUSE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;in_dim&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'weights'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out_dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;truncated_normal_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'biases'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out_dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constant_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matmul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Putting it together&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;이제 만든 함수들을 하나로 모아서 전체 모델을 만들자. 순서대로 우리가 만든 함수를 사용하면 된다. 하나 유의할 점은 마지막 pooling 후 fc-layer로 갈 때 3차원 배열이였던 것을 1차원으로 reshape해줘야 하는데, 이 때 1차원 vector의 크기는 원래 배열의 각 차원의 길이를 곱해줘서 구하면 된다. 그리고 마지막으로 fc-layer에 dropout을 한번 적용한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;inference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;conv1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;conv_relu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;filters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;k_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;stride&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'SAME'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;scope_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'conv1'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;pool1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxpool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conv1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'VALID'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'pool1'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;conv2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;conv_relu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pool1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;filters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;k_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;stride&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'SAME'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;scope_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'conv2'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;pool2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxpool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'VALID'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'pool2'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;feature_dim&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pool2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pool2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pool2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;pool2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reshape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pool2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;feature_dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;fc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;relu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fully_connected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pool2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'fc'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dropout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dropout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keep_prob&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;training&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;training&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'dropout'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fully_connected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dropout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_classes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'logits'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그리고 만든 모델을 통해 예측값을 뽑는 함수를 정의한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'''
        Count the number of right predictions in a batch
        '''&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'predict'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;preds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;softmax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;correct_preds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argmax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;preds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argmax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accuracy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cast&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;correct_preds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;float32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;전체 코드는 &lt;a href=&quot;https://github.com/chiphuyen/stanford-tensorflow-tutorials&quot;&gt;github&lt;/a&gt;를 참고하자.&lt;/p&gt;

&lt;p&gt;이제 실행한 뒤 TensorBoard로 loss값과 accuracy 값을 확인 해보면 다음과 같이 나올 것이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/AtKL5pf.jpg&quot; alt=&quot;112222&quot; /&gt;&lt;/p&gt;

&lt;p&gt;그리고 총 25 epoch을 학습 시키면 Accuracy가 98%가 나온다. 간단한 모델임에도 불구하고 매우 높은 수치의 정확도를 보여준다!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>CS20(TensorFlow) Lecture Note (5): word2vec + manage experiments</title>
   <link href="https://reniew.github.io/36/"/>
   <updated>2018-08-16T04:47:35+00:00</updated>
   <id>https://reniew.github.io/36</id>
   <content type="html">&lt;p&gt;스탠포드의 TensorFlow 강의인 cs20 강의의 lecture note를 정리한 글입니다. 강의는 오픈되지 않아서 Lecture note, slide 위주로 정리된 글임을 참고 해주시길 바랍니다. 강의의 자세한 Syllabus 및 자료들을 아래 링크를 참고해 주세요.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://web.stanford.edu/class/cs20si/&quot;&gt;CS20: TensorFlow for Deep Learning Research&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h5 id=&quot;post-list&quot;&gt;Post list&lt;/h5&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/32&quot;&gt;Lecture 1, 2: Overview &amp;amp; TensorFlow Operation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/33&quot;&gt;Lecture 3: Linear and Logistic Regression&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/34&quot;&gt;Lecture 4: Eager execution and interface&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/36&quot;&gt;Lecture 5: word2vec + manage experiments&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/38&quot;&gt;Lecture 6, 7: Intro to ConvNet &amp;amp; ConvNet in TensorFlow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/39&quot;&gt;Lecture 8: CNN(Style transfer), TFRecord &lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/40&quot;&gt;Lecture 10: Variational Auto Encoders(VAE)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/41&quot;&gt;Lecture 11: RNNs in the TensorFlow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/42&quot;&gt;Lecture 12: Machine Translation, Seqeunce-to-sequence and Attention&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;5-word2vec--manage-experiments&quot;&gt;5. word2vec + manage experiments&lt;/h3&gt;

&lt;p&gt;이때까지는 간단한 모델을 만드는 방법에 대해서 알아보았다. 이번 강의에서는 이전 보다는 좀 더 복잡한 모델인인 word2vec을 예제로 모델을 만들어 보도록 한다. 이번 모델을 만들면서 variable sharing, model sharing 그리고 manage our experiments에 대해서 알아보도록 할 것이다.&lt;/p&gt;

&lt;h4 id=&quot;word2vec&quot;&gt;Word2vec&lt;/h4&gt;

&lt;p&gt;단어 임베딩을 하는 방법 중에서 가장 널리 알려지고 많이 사용되는 기술은 word2vec일 것이다. 내용에 대해서는 아마 대부분이 알고 있을 것이라 생각하고 자세한 내용은 설명하지 않는다. 만약 잘 모른다면 다음의 글들을 참고하자 : &lt;a href=&quot;https://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf&quot;&gt;paper1&lt;/a&gt;, &lt;a href=&quot;https://arxiv.org/pdf/1301.3781.pdf&quot;&gt;paper2&lt;/a&gt;, &lt;a href=&quot;https://reniew.github.io/21/&quot;&gt;blog1&lt;/a&gt;, &lt;a href=&quot;https://reniew.github.io/22/&quot;&gt;blog2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;word2vec의 두 가지 모델(skip-gram, CBOW)중에서 이번 강의에서는 skip-gram 모델을 구현해보도록 한다.&lt;/p&gt;

&lt;h4 id=&quot;implementing-word2vec&quot;&gt;Implementing word2vec&lt;/h4&gt;

&lt;p&gt;여기서는 Session을 사용할 것이다. eager를 사용하는 모델은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;examples/04_word2vec_eager.py&lt;/code&gt; 파일을 참고하자.&lt;/p&gt;

&lt;p&gt;우선은 우리가 사용할 라이브러리들을 임포트한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;environ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'TF_CPP_MIN_LOG_LEVEL'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'2'&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;numpy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;tensorflow.contrib.tensorboard.plugins&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;projector&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;tensorflow&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;utils&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;word2vec_utils&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;word2vec_utils은 중간에 사용되는 몇 가지 기능들을 미리 만들어 놓은 파이썬 파일이다. 그리고 다음으로는 모델의 하이퍼 파라미터를 정의하자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;VOCAB_SIZE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50000&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;BATCH_SIZE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;EMBED_SIZE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;# dimension of the word embedding vectors
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SKIP_WINDOW&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;             &lt;span class=&quot;c1&quot;&gt;# the context window
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NUM_SAMPLED&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;# number of negative examples to sample
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LEARNING_RATE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;NUM_TRAIN_STEPS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100000&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;VISUAL_FLD&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'visualization'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SKIP_STEP&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5000&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;DOWNLOAD_URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'http://mattmahoney.net/dc/text8.zip'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;EXPECTED_BYTES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;31344016&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;NUM_VISUALIZE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3000&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# number of tokens to visualize
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;우선은 이제 데이터를 다운받고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.data&lt;/code&gt;를 정의해야 한다. 데이터의 구조에 대해서 먼저 설명하면, skip-gram에서는 input값은 중간의 단어가 되고 output은 단어 주변의 context 단어가 된다. 하지만 여기서 구현할 때는 단어 자체를 input으로 넣지 않고 흔한 단어들에 대해서 dictionary를 만들고 input은 중간 단어에 대한 vocabulary에서의 index값을 줄 것이다. 예를 들어 만약 vocabulary에서 1000번째 단어인 경우에는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;input = 3&lt;/code&gt; 이 된다.&lt;/p&gt;

&lt;p&gt;데이터를 다운로드하고, 각 데이터를 정해진 hyperparameter에 맞게 input 값인 인덱스들을 배치사이즈로 만들어 주는 함수를 미리 정의했다. 이 함수는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;word2vec_utils.py&lt;/code&gt;에 정의되어 있으며 이 과정의 세부적인 내용은 해당 파이썬 파일을 참고하자.&lt;/p&gt;

&lt;p&gt;여기서는 해당 함수를 사용해서 데이터를 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.data&lt;/code&gt;로 불러온 후 iterator를 정의하자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_generator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                              &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TensorShape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BATCH_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TensorShape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BATCH_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;make_initializable_iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;center_words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_words&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;skip-gram모델에서의 파라미터는 매트릭스 형태인데, 이 매트릭스의 row vector가 단어 임베딩 벡터가 된다. 따라서 매트릭스의 크기는 [VOCAB_SIZE, EMBED_SIZE]가 된다. 해당 파라미터 매트릭스는 보통 random distribution을 따르도록 초기화하는데, 여기서는 uniform distribution을 따르도록 초기화 하자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;embed_matrix&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'embed_matrix'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                &lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VOCAB_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EMBED_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                                &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_uniform_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;skip-gram모델에서 단어는 원래 one-hot 인코딩 되어 있고 파라미터와 곱해질 떄 아래 그림 처럼 결국 특정 행만 계산된다. 결국 나머지는 모두 0이 됨에도 불구하고 모두 계산된다. TensorFlow에서는 이와 같은 문제를 해결하기 위한 함수인 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.nn.embedding_lookup&lt;/code&gt;함수를 제공한다. 따라서 이 함수를 통해 batch의 단어들에 해당하는 row의 vector 값들만 사용 할 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://mccormickml.com/assets/word2vec/matrix_mult_w_one_hot.png&quot; alt=&quot;12&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.nn.embedding_lookup&lt;/code&gt;함수의 구조는 아래와 같다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;embedding_lookup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;partition_strategy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'mod'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;validate_indices&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;max_norm&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;따라서 위의 함수를 다음과 같이 사용한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;embed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;embedding_lookup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;embed_matrix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;center_words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'embedding'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제 loss함수를 정의해야 한다. loss함수로 NCE함수를 사용할 것이다. 이미 tf에서 이 함수를 제공하고 있으므로 사용하도록 하자. NCE함수는 아래와 같이 구성되어 있다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nce_loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;weights&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;biases&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;num_sampled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;num_classes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;num_true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sampled_values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;remove_accidental_hits&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;partition_strategy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'mod'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'nce_loss'&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;(위 함수의 인자 중에서 3번 째가 실제로는 input이고, 4번째가 label이다)&lt;/p&gt;

&lt;p&gt;NCE loss를 사용하기 위해 nce_weight과 nce_bias를 따로 만들어 준 후 loss 함수를 정의하자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;nce_weight&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'nce_weight'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VOCAB_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EMBED_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;truncated_normal_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stddev&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EMBED_SIZE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;nce_bias&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'nce_bias'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VOCAB_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce_mean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nce_loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;weights&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nce_weight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                        &lt;span class=&quot;n&quot;&gt;biases&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nce_bias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                        &lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target_words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                        &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;embed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                        &lt;span class=&quot;n&quot;&gt;num_sampled&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NUM_SAMPLED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                        &lt;span class=&quot;n&quot;&gt;num_classes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VOCAB_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'loss'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제 optimizer만 정의하면된다. gradient descent optimizer를 사용한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GradientDescentOptimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LEARNING_RATE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;minimize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제 정의한 graph를 실행하면 된다. Session을 통해 실행하자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;global_variables_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# we use this to calculate late average loss in the last SKIP_STEP steps
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FileWriter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'graphs/word2vec_simple'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NUM_TRAIN_STEPS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;loss_batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss_batch&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SKIP_STEP&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Average loss at step {}: {:5.1f}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SKIP_STEP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OutOfRangeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;여기까지 하면 tensorflow로 만든 word2vec 모델이 다 끝났다. 매우 짧은 코드만으로도 복잡한 모델인 word2vec의 skip-gram을 구현했다. 코드를 다시 보면 매우 간단하지만 다시 사용하기는 어려울 것이다. 그렇다면 어떻게 해야 다시 사용하기 쉽도록 코드를 구성할 것인가?&lt;/p&gt;

&lt;p&gt;정답은 Class 구조로 만드는 것이다. 위의 코드들을 Class구조로 만들면 다음과 같이 구성된다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;environ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'TF_CPP_MIN_LOG_LEVEL'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'2'&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;numpy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;tensorflow.contrib.tensorboard.plugins&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;projector&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;tensorflow&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;utils&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;word2vec_utils&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;VOCAB_SIZE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50000&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;BATCH_SIZE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;EMBED_SIZE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;# dimension of the word embedding vectors
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SKIP_WINDOW&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;             &lt;span class=&quot;c1&quot;&gt;# the context window
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NUM_SAMPLED&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;# number of negative examples to sample
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LEARNING_RATE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;NUM_TRAIN_STEPS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100000&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;VISUAL_FLD&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'visualization'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SKIP_STEP&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5000&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;DOWNLOAD_URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'http://mattmahoney.net/dc/text8.zip'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;EXPECTED_BYTES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;31344016&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;NUM_VISUALIZE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3000&lt;/span&gt;       


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;word2vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'data'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;make_initializable_iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;center_words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_words&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'embed'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;embed_matrix&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'embed_matrix'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                        &lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VOCAB_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EMBED_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                                        &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_uniform_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;embed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;embedding_lookup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;embed_matrix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;center_words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'embedding'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'loss'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;nce_weight&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'nce_weight'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VOCAB_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EMBED_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;truncated_normal_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stddev&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EMBED_SIZE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;nce_bias&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'nce_bias'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VOCAB_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce_mean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nce_loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;weights&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nce_weight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                            &lt;span class=&quot;n&quot;&gt;biases&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nce_bias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                            &lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target_words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                            &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;embed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                            &lt;span class=&quot;n&quot;&gt;num_sampled&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NUM_SAMPLED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                            &lt;span class=&quot;n&quot;&gt;num_classes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VOCAB_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'loss'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'optimizer'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GradientDescentOptimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LEARNING_RATE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;minimize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;utils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;safe_mkdir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'checkpoints'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;global_variables_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FileWriter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'graphs/word2vec_simple'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NUM_TRAIN_STEPS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;loss_batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss_batch&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SKIP_STEP&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Average loss at step {}: {:5.1f}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SKIP_STEP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OutOfRangeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;gen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word2vec_utils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch_gen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DOWNLOAD_URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EXPECTED_BYTES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VOCAB_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                        &lt;span class=&quot;n&quot;&gt;BATCH_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SKIP_WINDOW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VISUAL_FLD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_generator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TensorShape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BATCH_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TensorShape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BATCH_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;word2vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'__main__'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;코드가 조금더 길어졌지만, 이렇게 만듬으로써 이 모델을 재사용하기 쉬워졌다.&lt;/p&gt;

&lt;h4 id=&quot;how-to-structure-yout-tensorflow-model&quot;&gt;How to structure yout TensorFlow model&lt;/h4&gt;

&lt;p&gt;TensorFlow로 모델을 만드는 흐름에 대해서 다시 얘기해보자. 대부분의 코드들은 다음의 구조를 가질 것이다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase1: assemble your graph&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;데이터 불러오기(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.data&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;placeholder&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;파라미터 정의&lt;/li&gt;
  &lt;li&gt;inference 모델 정의&lt;/li&gt;
  &lt;li&gt;loss 함수 정의&lt;/li&gt;
  &lt;li&gt;optimizer 정의&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Phase2: execute the computation&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;모든 변수 초기화&lt;/li&gt;
  &lt;li&gt;데이터 iterator, feed 초기화&lt;/li&gt;
  &lt;li&gt;inference 모델 실행(각 input에 대해 학습한 결과 계산)&lt;/li&gt;
  &lt;li&gt;cost계산&lt;/li&gt;
  &lt;li&gt;파라미터 갱신&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;대부분 위의 흐름을 크게 벗어나지 않을 것이다.&lt;/p&gt;

&lt;h4 id=&quot;variable-sharing&quot;&gt;Variable Sharing&lt;/h4&gt;

&lt;p&gt;word2vec 모델을 TensorBoard로 그래프를 보면 다음과 같이 나온다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/NVtTd7p.jpg&quot; alt=&quot;gra&quot; /&gt;&lt;/p&gt;

&lt;p&gt;그래프를 보면 노드들이 다 흩어져 있는 것을 볼 수 있다. 만약 word2vec보다 조금 더 복잡한 모델이라면 그래프를 보기가 매우 어려울 것이다. 그렇다면 이런 그래프를 좀더 보기좋게 비슷한 것들끼리 그룹화를 할 수 있다면 어떨까? &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.name_scope&lt;/code&gt;를 사용하면 쉽게 grouping을 할 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.name_scope&lt;/code&gt;는 다음과 같이 사용할 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_of_that_scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;# declare op_1
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;# declare op_2
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;# ...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이전의 전체 python 코드를 보면 name_scope로 묶여있는 것을 볼 수 있다. 이렇게 묶은 후 TensorBoard로 그래프를 보면 아래와 같이 좀 더 명확하게 보기 쉽다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/KnRzvBQ.jpg&quot; alt=&quot;graph&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Variable Scpoe&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;TensorFlow를 사용하다보면 name_scope와 variable_scope를 언제 구분해서 사용하는지 의문이 들 때가 있다. 이번에는 variable_scope에 대해서 알아보자.&lt;/p&gt;

&lt;p&gt;두 개의 input을 받고, 2 hidden layer를 가지는 신경망을 생각해보자. 그러면 아래와 같이 Neural Network를 정의하고 사용할 것이다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;two_hidden_layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;as_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;w1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;h1_weights&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;b1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;h1_biases&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;h1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matmul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;as_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  
    &lt;span class=&quot;n&quot;&gt;w2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;h2_weights&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;b2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;h2_biases&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matmul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b2&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;logits1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;two_hidden_layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logits2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;two_hidden_layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;TensorFlow는 함수를 실행할 때 마다 다른 variable집합을 만든다. 따라서 위의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;two_hidden_layers()&lt;/code&gt;를 호출할 때마다 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get_variable&lt;/code&gt;이 실행되서 새로운 variable을 만들 것이다. 따라서 중복으로 생성하기 때문에 아래와 같은 error message가 나온다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;ValueError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h1_weights&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;already&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;disallowed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Did&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;you&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mean&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AUTO_REUSE&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VarScope&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이런 Variable의 중복을 방지하기 위해 VarScope를 사용한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fully_connected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output_dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;variable_scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;weights&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output_dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_normal_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;biases&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output_dim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constant_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matmul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;two_hidden_layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;h1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fully_connected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'h1'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;h2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fully_connected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'h2'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;variable_scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'two_layers'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;logits1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;two_hidden_layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reuse_variables&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;logits2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;two_hidden_layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같이 작성하면 중복 error가 발생하지 않는다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Graph collections&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;모델을 만들 때 variable을 graph의 서로 다른 부분에 같이 넣는 상황이 있을 수 있다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.get_collection&lt;/code&gt;을 사용하면 특정 variable 모음에 접근할 수 있게 한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_collection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Default로 모든 variabls은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.GraphKeys.GLOBAL_VARIABLES&lt;/code&gt;에 들어가 있다. ‘my_scope’의 모든 variable들을 사용하려면 다음과 같이 사용할 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_collection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GraphKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GLOBAL_VARIABLES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'my_scope'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;만약에 Variable중에서 옵션 중 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;trainable=True&lt;/code&gt;로 설정한 변수들 사용하고 싶으면, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.GraphKeys.TRAINABLE_VARIABLES&lt;/code&gt; collection을 사용하면 된다.&lt;/p&gt;

&lt;h4 id=&quot;manage-experiments&quot;&gt;Manage experiments&lt;/h4&gt;

&lt;p&gt;우리는 앞서 word2vec을 적은 데이터셋으로 만들어보고 결과도 나름 잘나오는 것을 확인했다. 하지만 실제로는 더 많은 데이터셋이 필요하고, 따라서 시간도 훨씬 많이 걸릴 것이다. 복잡한 모델일 수록 학습에 필요한 시간은 급격히 늘어날 것이다. 예를 들어 기계번역 분야는 하루정도는 최소 학습시켜야 하고 경우에 따라 더 많이 학습을 해야 한다.&lt;/p&gt;

&lt;p&gt;이렇게 몇일씩 걸리는 모델을 학습하면 모델이 학습이 끝나기 전까지는 우리는 전혀 결과를 알 수 없다. 심지어 중간에 컴퓨터에 문제라도 발생하게 되면 결과를 확인조차 할 수 없다.&lt;/p&gt;

&lt;p&gt;그리고 또 하나의 문제점은 모델에 대해서 실험할 때 여러 요인들을 바꿔가며 실험하는데 이러한 요소들에 따른 비교를 하기가 어렵다.&lt;/p&gt;

&lt;p&gt;따라서 이번에는 우리가 모델을 실험할 때 사용할 수 있는 몇가지 기능들에 대해서 알아보도록 한다. 알아볼 것들은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.train.Saver()&lt;/code&gt;, TensorFlow’s random state, visualization에 대해서 알아보도록 할 것이다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.train.Saver()&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.train.Saver()&lt;/code&gt;를 사용하면 주기적으로 우리의 모델의 파라미터값들을 저장할 수 있다. graph의 변수들을 binary파일로 저장한다. 이 Class의 save함수는 다음과 같이 구성된다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Saver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;save_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;global_step&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;latest_filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;meta_graph_suffix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'meta'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;write_meta_graph&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;write_state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;예를 들어서 만약에 1000 step마다 변수들을 저장하고 싶다면 아래와 같이 작성하면 된다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;saver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Saver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;step&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;training_steps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;step&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	   &lt;span class=&quot;n&quot;&gt;saver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'checkpoint_directory/model_name'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;global_step&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;global_step&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;보통 흔히 쓰는 말로 graph의 변수를 저장하는 step을 ‘checkpoint’라 표현한다. 코드를 보면 ‘global_step’이라는 변수가 새로 나와있는데, 이 값을 설정해주면 학습과정을 좀 더 명확히 이해할 수 있어 좋다. 선언시에는 학습이 되지 않도록 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;trainable=False&lt;/code&gt;로 지정하고 0으로 초기화한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;global_step&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trainable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'global_step'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그리고 global_step은 학습이 진행될 때마다 점점 증가해야 되는데 따로 연산을 만들 필요없이 optimizer에 옵션으로 넣어주면 자동으로 증가한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GradientDescentOptimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;minimize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;global_step&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;global_step&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;저장해둔 checkpoint를 복구하기 위해서는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;saver.restore()&lt;/code&gt;함수를 사용한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;saver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;restore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'checkpoints/skip-gram-10000'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;checkpoint들이 저장되어 있는 directory에서 가장 최근의 checkpoint를 사용하고 싶으면 아래와 같이 작성하면 자동으로 가장 최신의 checkpoint를 찾을 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ckpt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_checkpoint_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'checkpoints/checkpoint'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ckpt&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ckpt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model_checkpoint_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;saver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;restore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ckpt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model_checkpoint_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;따라서 모델을 만들 때 우선 checkpoint가 있는지 확인을 하고 있다면 그 checkpoint부터 다시 학습을 시작하면 된다. 따라서 기존의 word2vec 코드에서 checkpoint를 확인하고 사용하는 부분을 추가하면 다음과 같다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;saver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Saver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;initial_step&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;utils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;safe_mkdir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'checkpoints'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;global_variables_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# if a checkpoint exists, restore from the latest checkpoint
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;ckpt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_checkpoint_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'checkpoints/checkpoint'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ckpt&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ckpt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model_checkpoint_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;saver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;restore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ckpt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model_checkpoint_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FileWriter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'graphs/word2vec'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_train_steps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;# save the model every 1000 steps
&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;saver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'checkpoints/skip-gram'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OutOfRangeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;기본적으로는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.Saver.save&lt;/code&gt;를 사용하면 모든 변수가 자동으로 저장된다. 보통은 이 방법을 사용하기를 추천하지만, 경우에 따라 몇개의 변수만 따로 저장하고 싶은 경우에도 사용할 수 있다. 특정 변수를 list 혹은 dictionary 형태로 Saver 객체의 인자로 설정하면 그 변수들만 저장된다. 아래의 예시를 참고하자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'v1'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'v2'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;saver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Saver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'v1'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'v2'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;saver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Saver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;saver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Saver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;op&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.summary&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;보통 우리는 matplotlib을 사용해서 우리의 losses, accuracy를 시각화했는데, TensorFlow를 사용하면 그럴 필요가 없다. TensorBoard를 활용하면 우리의 요약된 자료들을 쉽게 시각화 해준다.&lt;/p&gt;

&lt;p&gt;보통 시각화를 많이하는 값인 loss, average loss, accuracy를 시각화를 해보자. 시각화는 scalar plot, histogram, image 형태 모두 가능하다. 우선은 우리가 사용할 값들을 summary operation을 사용한뒤 하나의 namescope로 정의한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_create_summaries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;summaries&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scalar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;loss&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scalar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;accuracy&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accuracy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;            
            &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;histogram&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;histogram loss&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;# because you have several summaries, we should merge them all
&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;# into one op to make it easier to manage
&lt;/span&gt;            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary_op&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;merge_all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;summary는 하나의 연산(operation)이므로 session으로 실행해줘야 한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;loss_batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary_op&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                                  &lt;span class=&quot;n&quot;&gt;feed_dict&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;feed_dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Filewriter를 통해 summary를 write하면 TensorBoard를 통해 확인할 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_summary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;global_step&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제 TensorBoard를 명령 프롬프트로 실행시킨 후 http://localhost:6006 을 들어가보면 다음과 같이 확인 할 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/dVOwFjJ.jpg&quot; alt=&quot;loss&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/tZSAAqr.jpg&quot; alt=&quot;histo&quot; /&gt;&lt;/p&gt;

&lt;p&gt;graph 폴더에서 두개의 sub-폴더를 만들어서 summary들을 저장하면 여러 모델 혹은 여러 하이퍼파라미터들에 따른 비교를 할 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/WkUpbio.jpg&quot; alt=&quot;loss-&quot; /&gt;&lt;/p&gt;

&lt;p&gt;마지막으로 image로 표현하는 방법은 다음의 함수를 사용한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;max_outputs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;collections&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Control randomization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;텐서플로우를 사용하다 보면, Random한 값을 사용해야 할 때가 많이 있을 것이다. random 값을 가질 수 있는 방법은 여러가지 있는데, 이런 random 값을 어느정도 제어할 수 있는 방법이 있다. seed를 사용하는 것인데 크게 두 가지 정도로 구분되어 사용된다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;random seed in operation level&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;operation 단계에서 random seed 를 할당하는 방법이다. 아래의 여러 예들을 보며 사용 방법을 익혀보자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_uniform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([],&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &amp;gt;&amp;gt; 3.57493
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &amp;gt;&amp;gt; -5.97319
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_uniform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([],&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &amp;gt;&amp;gt; 3.57493
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &amp;gt;&amp;gt; 3.57493
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_uniform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([],&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_uniform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([],&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &amp;gt;&amp;gt; 3.57493
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &amp;gt;&amp;gt; 3.57493
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;random seed at graph level with tf.Graph.seed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;만약 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a.py&lt;/code&gt;와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b.py&lt;/code&gt; 두 파일이 똑같이 아래와 같은 코드로 구성되었을 때 실행시키면 어떻게 되는지 알아보자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;tensorflow&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_random_seed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_uniform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([],&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_uniform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([],&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;python&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;py&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;4.00752&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.98339&lt;/span&gt;

&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;python&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;py&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;4.00752&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.98339&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이와 같이 seed를 graph 단계에서 주면 다른 파일이더라도 같은 값을 가진다.&lt;/p&gt;

&lt;h4 id=&quot;autodiff-how-tensorflow-takes-gradients&quot;&gt;Autodiff (how TensorFlow takes gradients)&lt;/h4&gt;

&lt;p&gt;텐서플로우는 자동 미분기능을 제공하는데, 우리가 명시적으로 사용하기 위한 함수도 존재한다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.gradients()&lt;/code&gt;를 사용하면 우리가 원하는 함수를 우리가 정한 변수로 미분할 수 있다. 함수는 아래와 같이 구성된다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gradients&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grad_ys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'gradients'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;colocate_gradients_with_ops&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gate_gradients&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregation_method&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ys&lt;/code&gt;는 미분할 함수이고, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xs&lt;/code&gt;로 미분을 하겠다는 것이다. 그리고 여러 변수로 미분을 하거나 chain rule을 통해 미분도 가능하다. 아래의 예제를 보자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;grad_y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gradients&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grad_y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &amp;gt;&amp;gt; 24.0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;grad_z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gradients&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grad_z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &amp;gt;&amp;gt; [768.0, 32.0]
# 768 is the gradient of z with respect to x, 32 with respect to y
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>CS20(TensorFlow) Lecture Note (4): Eager execution and interface</title>
   <link href="https://reniew.github.io/34/"/>
   <updated>2018-08-16T04:47:35+00:00</updated>
   <id>https://reniew.github.io/34</id>
   <content type="html">&lt;p&gt;스탠포드의 TensorFlow 강의인 cs20 강의의 lecture note를 정리한 글입니다. 강의는 오픈되지 않아서 Lecture note, slide 위주로 정리된 글임을 참고 해주시길 바랍니다. 강의의 자세한 Syllabus 및 자료들을 아래 링크를 참고해 주세요.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://web.stanford.edu/class/cs20si/&quot;&gt;CS20: TensorFlow for Deep Learning Research&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h5 id=&quot;post-list&quot;&gt;Post list&lt;/h5&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/32&quot;&gt;Lecture 1, 2: Overview &amp;amp; TensorFlow Operation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/33&quot;&gt;Lecture 3: Linear and Logistic Regression&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/34&quot;&gt;Lecture 4: Eager execution and interface&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/36&quot;&gt;Lecture 5: word2vec + manage experiments&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/38&quot;&gt;Lecture 6, 7: Intro to ConvNet &amp;amp; ConvNet in TensorFlow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/39&quot;&gt;Lecture 8: CNN(Style transfer), TFRecord &lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/40&quot;&gt;Lecture 10: Variational Auto Encoders(VAE)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/41&quot;&gt;Lecture 11: RNNs in the TensorFlow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/42&quot;&gt;Lecture 12: Machine Translation, Seqeunce-to-sequence and Attention&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;4-eager-execution-and-interface&quot;&gt;4. Eager execution and interface&lt;/h3&gt;

&lt;p&gt;이때까지의 강의를 통해 TensorFlow는 크게 두개의 흐름으로 구성된다는 것을 배웠다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;assembling the computation graph&lt;/li&gt;
  &lt;li&gt;executing that graph&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위와 같이 그래프를 구성하고, 실행하는 것이 구분되어 있었다. 하지만 파이썬의 구동과 같이 TensorFlow도 imperatively하게 실행될 수 있다면 어떨까? 가능하다면 TensorFlow 모델을 만드는데 있어서 직관적이고 디버깅도 쉬워질 것이다.&lt;/p&gt;

&lt;p&gt;TensorFLow의 &lt;strong&gt;eager&lt;/strong&gt; 모드를 통해 TensorFlow도 imperatively하게 작성할 수 있다.&lt;/p&gt;

&lt;h4 id=&quot;eager-execution&quot;&gt;Eager execution&lt;/h4&gt;

&lt;p&gt;Eager execution에 대한 소개는 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;GPU가속과 자동 미분계산을 지원하는 수치 계산을위한 넘파이를 기본으로 하는 라이브러리이다.&lt;/li&gt;
  &lt;li&gt;머신러닝 연구와 실험을 위한 유연한 플랫폼이다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eager모드의 핵심 장점은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Eager 모드는 파이썬 디버깅 툴에 적합하다.(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pdb.set_trace()&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;즉각적인 에러 report&lt;/li&gt;
  &lt;li&gt;파이썬 데이터 구조를 사용할 수 있다.&lt;/li&gt;
  &lt;li&gt;사용이 쉽고, Pythonic하다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;그렇다면 eager모드를 사용하는 기본적인 방법을 보자, 단 몇줄로 쉽게 사용 가능하다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;tensorflow&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;tensorflow.contrib.eager&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tfe&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tfe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;enable_eager_execution&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위의 문장만 사용하면 eager모드로 코딩이 가능하다. 따라서 파이썬 자료형으로도 아래와 같이 작성할 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matmul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Session이 필요없다.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;예제만 보더라도 기존의 Operator, Variable, Session을 사용할 때보다 훨씬 직관적이고 쉽다. 아직은 eager모드에서 기존의 모드처럼 많은 기능들을 제공하지는 않지만 점점 추가될 예정이다.&lt;/p&gt;

&lt;p&gt;eager모드로 미분을 하는 방법도 매우 간단하다. 정의된 연산을 미분 함수에 넣으면 자동으로 미분을 계산해준다. 아래의 예시를 보자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;square&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;grad&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tfe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gradients_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;square&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;square&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;3.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# tf.Tensor(9., shape=(), dtype=float32)
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;3.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;     &lt;span class=&quot;c1&quot;&gt;# [tf.Tensor(6., shape=(), dtype=float32))]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그렇다면 이제 lecture 4에서 만들었던 Linear regression 모델을 eager모드로 만들어 보자.&lt;/p&gt;

&lt;p&gt;우선은 eager를 포함해 필요한 라이브러리를 임포트한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;time&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;tensorflow&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;tensorflow.contrib.eager&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tfe&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;utils&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;2장에서 했던 방법 그대로 데이터를 불러오자. 그리고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tfe.enable_eager_execution()&lt;/code&gt;를 통해 eager를 실행한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;DATA_FILE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'data/birth_life_2010.txt'&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;tfe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;enable_eager_execution&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Read the data into a dataset.
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n_samples&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_birth_life_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DATA_FILE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_tensor_slices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이후 우리가 사용할 parameter를 정의한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tfe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tfe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제 우리가 사용할 linear모델을 만들고, 사용할 loss함수를 정의한다. loss는 square와 huber 두 가지 모두 정의한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;prediction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;squared_loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_predicted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_predicted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;  

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;huber_loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_predicted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# 기본 m 값은 1.0으로 준다.
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_predicted&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;abs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;abs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제 optimizer를 포함해서 하나씩 뽑아서 loss를 구하는 함수와 학습과정들을 모두포함해서 하나의 함수로 만든다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss_fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Training; loss function: '&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss_fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GradientDescentOptimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;learning_rate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;loss_for_example&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss_fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prediction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;grad_fn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tfe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;implicit_value_and_gradients&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss_for_example&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;epoch&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x_i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tfe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gradients&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grad_fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x_i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apply_gradients&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gradients&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;epoch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Epoch {0}: {1}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;epoch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n_samples&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Took: %f seconds'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;마지막으로 학습함수를 실행시키고 시각화를 위해 matplotlib을 사용한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;huber_loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'bo'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'r'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;huber regression&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;legend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;show&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;코드를 보면 기존의 방법과는 달리 좀 더 파이썬스럽고 직관적으로 보인다. 이전 lecture에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;placeholder&lt;/code&gt;와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; 둘다 알아보고 익힌것 처럼 session을 통한 TensorFlow 코드와 eager를 통한 TensorFlow 코드 모두 익히도록 하자.&lt;/p&gt;

&lt;p&gt;그렇다면 Eager는 어떤 경우에 사용하는 것이 좋을까? 다음의 경우에 사용하는 것이 이점이 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;연구자들이 사용하기에 적합하다.&lt;/li&gt;
  &lt;li&gt;유연한 Framework을 원하는 사람&lt;/li&gt;
  &lt;li&gt;새로운 모델을 만드는 사람들&lt;/li&gt;
  &lt;li&gt;TensorFlow를 새롭게 접하는 사람들&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eager모드의 장점인 디버깅이 쉽다는 점 때문에 위와 같은 경우에는 eager모드를 사용하는 것이 더욱 적합할 것이다.&lt;/p&gt;

&lt;p&gt;하지만 모든 경우에 eager모드를 사용할 수 있는 것이 아니고, 1.5 버전 이상의 TensorFlow에서만 사용할 수 있다.&lt;/p&gt;

&lt;p&gt;eager모드에 대해서 더 자세한 내용은 &lt;a href=&quot;https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/eager/python/g3doc/guide.md&quot;&gt;user guide&lt;/a&gt;를 참고하자.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>CS20(TensorFlow) Lecture Note (3): Linear and Logistic Regression</title>
   <link href="https://reniew.github.io/33/"/>
   <updated>2018-08-15T04:47:35+00:00</updated>
   <id>https://reniew.github.io/33</id>
   <content type="html">&lt;p&gt;스탠포드의 TensorFlow 강의인 cs20 강의의 lecture note를 정리한 글입니다. 강의는 오픈되지 않아서 Lecture note, slide 위주로 정리된 글임을 참고 해주시길 바랍니다. 강의의 자세한 Syllabus 및 자료들을 아래 링크를 참고해 주세요.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://web.stanford.edu/class/cs20si/&quot;&gt;CS20: TensorFlow for Deep Learning Research&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h5 id=&quot;post-list&quot;&gt;Post list&lt;/h5&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/32&quot;&gt;Lecture 1, 2: Overview &amp;amp; TensorFlow Operation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/33&quot;&gt;Lecture 3: Linear and Logistic Regression&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/34&quot;&gt;Lecture 4: Eager execution and interface&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/36&quot;&gt;Lecture 5: word2vec + manage experiments&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/38&quot;&gt;Lecture 6, 7: Intro to ConvNet &amp;amp; ConvNet in TensorFlow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/39&quot;&gt;Lecture 8: CNN(Style transfer), TFRecord &lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/40&quot;&gt;Lecture 10: Variational Auto Encoders(VAE)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/41&quot;&gt;Lecture 11: RNNs in the TensorFlow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/42&quot;&gt;Lecture 12: Machine Translation, Seqeunce-to-sequence and Attention&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;3-linear-and-logistic-regression&quot;&gt;3. Linear and Logistic Regression&lt;/h3&gt;

&lt;p&gt;이번 Lecture는 프로젝트로 진행된다. 앞서 배웠던 operation, sessiom, variable, constant 등을 이용해서 두개의 프로젝트를 진행한다.&lt;/p&gt;

&lt;p&gt;첫 번째는 birth rate를 통해 life expectancy를 예측하는 linear regression 모델을 만드는 것이다.&lt;/p&gt;

&lt;p&gt;두 번째는 MNIST 손글씨 데이터를 logistic regression을 통해 예측하는 모델을 만든다.&lt;/p&gt;

&lt;p&gt;두 모델의 다른 점은 linear와 logistic의 차이뿐만 아니라 구현과정에서 데이터를 읽는 방식을 다르게 진행했다. 첫 번쨰 모델에서는 일반적이고 이전에 배웠던 방법인 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.placeholder&lt;/code&gt;를 이용해서 데이터를 받을 것이고, 두 번째에서는 최근의 방법인 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.data&lt;/code&gt;를 통해서 데이터를 다룰 것이다. 두 방법모두 익히는 것이 좋으므로 모델을 만들면서 차이와 구현방법에 대해서 알아보도록 하자.&lt;/p&gt;

&lt;h4 id=&quot;linear-regression-predict-life-expectancy-from-birth-rate&quot;&gt;Linear regression: Predict life expectancy from birth rate&lt;/h4&gt;

&lt;p&gt;제목에서 나와 있듯이 birth rate를 통해서 life expectancy를 예측하는 모델을 만들 것이다. 다르게는 두 수치간의 관계를 찾는다고 생각하도 된다. 우선은 우리가 알아볼 데이터에 대해서 알아보자.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;X = brith rate, (Type:float)&lt;/li&gt;
  &lt;li&gt;Y = life expectancy, (Type:float)&lt;/li&gt;
  &lt;li&gt;총 190개의 데이터&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위 데이터를 가지고 모델을 만들 것이다. 우리는 두 수치간의 관계가 linear하다고 생각하고, linear한 모델을 만들 것이다. 즉 아래의 식으로 모델링을 한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;Y=wX+b&lt;/script&gt;

&lt;p&gt;이제 우리는 데이터를 통해 w,b를 학습시킬것이다. 이제 코드를 살펴보자. 전체 코드는 &lt;a href=&quot;https://github.io/reniew&quot;&gt;github&lt;/a&gt;을 참고하자.&lt;/p&gt;

&lt;p&gt;우선은 우리가 필요한 라이브러리들을 import한다. utils은 데이터 다운로드, 데이터 읽기등을 위해 미리 만들어 놓은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;utils.py&lt;/code&gt; 파일이다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;environ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'TF_CPP_MIN_LOG_LEVEL'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'2'&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# 로그 레벨, warning이상만 logging
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;time&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;numpy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;tensorflow&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;utils&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;데이터를 읽어오자. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;utils&lt;/code&gt;의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read_birth_life_data&lt;/code&gt; 함수를 사용하면된다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;DATA_FILE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'data/birth_life_2010.txt'&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n_samples&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_birth_life_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DATA_FILE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제는 데이터를 받을 X, Y를 정의해야 한다. 여기서는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;placeholder&lt;/code&gt;를 사용한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;X&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;placeholder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;float32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;placeholder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;float32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그리고 linear regression 모델의 파라미터인 w와 b를 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get_variable&lt;/code&gt;함수로 생성한다. 처음에는 모두 0으로 초기화 하자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'weight'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'bias'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;참고로 여기서 w,b,X,Y 모두 scalar값이다. 따라서 shape는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shape = ()&lt;/code&gt;으로 설정하거나 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shape = []&lt;/code&gt;으로 설정하면 된다.&lt;/p&gt;

&lt;p&gt;이제 우리의 모델을 정의한다. linear 모델이므로 아래와 같이 작성한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Y_predicted&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;X&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그리고 loss 와 optimizer를 정해줘야 한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;square&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Y_predicted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'loss'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GradientDescentOptimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;learning_rate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.001&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;minimize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;마지막으로 학습시간 측정을 위해 시작 시간을 측정한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제 필요한 것을 다 선언했으므로 Session을 통해 실행하자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# 모든 변수 일괄 초기화
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;global_variables_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FileWriter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'./graphs/linear_reg'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# 총 100에폭
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;# Execute train_op and get the value of loss.
&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;# Don't forget to feed in data for placeholders
&lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;feed_dict&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss_&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Epoch {0}: {1}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_samples&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# close the writer when you're done using it
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Step 9: output the values of w and b
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;w_out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b_out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;각 에폭마다 average loss 값을 출력하고 모든 학습이 끝나면 w와 b값을 저장한다. 그리고 학습에 소요된 시간과 마지막 loss, w, b 값을 모두 출력한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Took: %f seconds'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'last value of loss, w, b: {0}, {1}, {2}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_samples&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w_out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b_out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;control-flow-huber-loss&quot;&gt;Control flow: Huber loss&lt;/h4&gt;

&lt;p&gt;간단한 모델인 만큼 구현도 간단하게 끝났다. 다음 모델로 넘어가기 전에 Loss함수에 대해서 얘기해보자. 여기 모델에서는 일반적인 Square loss 함수를 사용했다. 다른 loss를 사용하려 하는데, tensorflow에서 제공하는 함수가 없어 직접 정의해서 사용해야 한다고 하자. 우리가 사용할 loss함수는 Huber loss로 수식은 다음과 같이 구성된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
L_\delta(y,f(x))=
\begin{cases}
\begin{align*}
&amp;\frac{1}{2}(y-f(x))^2&amp;\text{for}~\vert y-f(x)\vert\le\delta,\\
&amp;\delta\vert y-f(x)\vert-\frac{1}{2}\delta^2&amp;\text{otherwise}
\end{align*}
\end{cases} %]]&gt;&lt;/script&gt;

&lt;p&gt;조건에 따라 함수가 달라지는 경우이다. 이럴 경우에는 어떻게 해야 할까, 만약 파이썬 코드로 짠다면, 즉 Pythonic하게 짠다면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if&lt;/code&gt;문을 사용해야 할것이다. TensorFlow도 다음과 같은 경우에 사용할 수 있는 함수가 있다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.cond&lt;/code&gt;함수이다. 함수의 구성은 다음과 같다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cond&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pred&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;true_fn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;false_fn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;즉 pred 조건식에 따라 true이면 ture_fn함수를 사용, false이면 false_fn함수를 사용한다. 따라서 huber loss는 다음과 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.cond&lt;/code&gt;를 사용해서 정의할 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;huber_loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prediction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delta&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;14.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;residual&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;abs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prediction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;square&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;residual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delta&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;residual&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;square&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cond&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;residual&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;cond함수는 true, false의 경우로 구분하는데 많은 case로 나누는 경우는 tf.case함수를 사용하면 된다.&lt;/p&gt;

&lt;h4 id=&quot;tfdata&quot;&gt;tf.data&lt;/h4&gt;

&lt;p&gt;위의 코드에서는 데이터를 사용할 때 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;placeholder&lt;/code&gt;를 사용했다. 하지만 placeholder는 오래된 방식이고, 이 방식에 대해서는 다양한 의견이 있다. 찬성의 의견은 data 처리를 TF 밖에서 쉽게 할 수 있다는 점이고, 단점은 데이터 처리를 single쓰레드로 처리해야 하고 데이터 병목현상으로 느려진다는 점이다. 따라서 이러한 문제를 해결하기 위한 것이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.data&lt;/code&gt;이다.&lt;/p&gt;

&lt;p&gt;tf.data를 사용하는 방법에 대해서 알아보자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_tensor_slices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;feature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;여기서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;feature&lt;/code&gt;와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;labels&lt;/code&gt;은 Tensor 자료형이여야 한다. 하지만 tensor 자료형은 numpy 자료형과 같으므로 numpy 자료형을 넣어도 된다. 즉 위의 모델에서 데이터를 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.data&lt;/code&gt;로 읽는다면 다음과 같이 작성하면 된다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n_samples&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_birth_life_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DATA_FILE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_tensor_slices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그리고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.data.Dataset&lt;/code&gt;에는 데이터 파일을 Tensorflow file format parser로 바로 읽을 수 있는 여러 방법이 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.data.TextLineDataset(filenames)&lt;/code&gt;
파일의 각 줄을 하나의 데이터로 읽는다. 주로 csv파일 읽을 때나 기계번역 분야의 데이터에서 많이 사용된다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.data.FixedLengthRecordData(filenames)&lt;/code&gt;
고정된 길이의 데이터에서 주로 사용된다. 정해진 길이 만큼 하나의 데이터로 받는다. 자주 사용되는 곳 또한 고정된 길이로 구성된 데이터에서 많이 사용된다. 예를 들면 CIFAR 데이터 혹은 ImageNet 데이터와 같은 것들을 읽을 때 사용한다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.data.TFRecordDataset(filenames)&lt;/code&gt;
tfrecord 형식의 데이터에 사용한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;데이터를 읽는 방법을 알아봤다. 이제는 데이터를 사용할 때를 살펴보자. 기존의 코드에서는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt;문을 통해서 데이터의 값을 하나씩 뽑아서 사용했다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.data&lt;/code&gt;에서는 iterator를 사용하면 더욱 쉽게 데이터를 하나씩 사용할 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;make_one_shot_interator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_netx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이러한 방식으로 사용하면 된다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dataset.make_one_shot_interator()&lt;/code&gt;는 데이터를 하나씩 사용할 떄 사용하는 방식이고 batch방식등 여러 기능을 제공한다. 위와 같이 정의한 data를 session에서 다음과 같이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;while&lt;/code&gt;문으로 사용하면 된다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# initialize the iterator
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OutOfRangeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;tf.data를 사용하는 것은 placeholder를 사용하는 것보다 32.4% 정도 빠르다고 알려져 있다. 따라서 tf.data를 사용하는 것을 추천한다.&lt;/p&gt;

&lt;h4 id=&quot;optimizer&quot;&gt;Optimizer&lt;/h4&gt;

&lt;p&gt;Optimizer를 사용하는 방법은 매우 간단하다. 단 몇줄의 코드만으로도 복잡한 구성의(미분, update) optimizer를 쉽게 사용할 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GradientDescentOptimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;learning_rate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.001&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;minimize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;optimizer를 사용하면 미분값 계산, update 등을 자동으로 수행한다. 따라서 관련된 모든 variable에 적용이되는데, 경우에 따라서 update를 안해야하는 variable이 있을 수 있다. 그러한 variable의 경우에는 option으로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;trainable=False&lt;/code&gt;만 지정해주면 train 되지 않도록 쉽게 설정 가능하다&lt;/p&gt;

&lt;p&gt;그리고 위에서 사용한 GD opmizer뿐만 아니라 다른 다양한 optimizer또한 tensorflow 함수로 제공한다. 아래는 optimizer의 리스트이다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;tf.train.Optimizer&lt;/li&gt;
  &lt;li&gt;tf.train.GradientDescentOptimizer&lt;/li&gt;
  &lt;li&gt;tf.train.AdadeltaOptimizer&lt;/li&gt;
  &lt;li&gt;tf.train.AdagradOptimizer&lt;/li&gt;
  &lt;li&gt;tf.train.AdagradDAOptimizer&lt;/li&gt;
  &lt;li&gt;tf.train.MomentumOptimizer&lt;/li&gt;
  &lt;li&gt;tf.train.AdamOptimizer&lt;/li&gt;
  &lt;li&gt;tf.train.FtrlOptimizer&lt;/li&gt;
  &lt;li&gt;tf.train.ProximalGradientDescentOptimizer&lt;/li&gt;
  &lt;li&gt;tf.train.ProximalAdagradOptimizer&lt;/li&gt;
  &lt;li&gt;tf.train.RMSPropOptimizer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;다양한 optimizer에 대해서 Sebastain Ruder의 &lt;a href=&quot;http://sebastianruder.com/optimizing-gradient-descent/&quot;&gt;블로그&lt;/a&gt;에 정리한 글이 있는데 내용의 일부만 인용하면 다음과 같다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“RMSprop is an extension of Adagrad that deals with its radically diminishing learning rates. It is identical to Adadelta, except that Adadelta uses the RMS of parameter updates in the numerator update rule. Adam, finally, adds bias-correction and momentum to RMSprop. Insofar, RMSprop, Adadelta, and Adam are very similar algorithms that do well in similar circumstances. Kingma et al. [15] show that its bias-correction helps Adam slightly outperform RMSprop towards the end of optimization as gradients become sparser. Insofar, Adam might be the best overall choice.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;내용이 길지만 요약하면 결국 다음과 같다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Adam을 사용하자”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4 id=&quot;logistic-regression-with-mnist&quot;&gt;logistic Regression with MNIST&lt;/h4&gt;

&lt;p&gt;이번에는 MNIST 손글씨 데이터를 통해 손글씨 이미지를 보고 숫자를 예측하는 모델을 만들어 보도록 한다. MNIST데이터는 0~9까지의 숫자의 손글씨로 이루어져 있고, 각 이미지는 28x28 pixel로 이루어져 있다. 여기서는 28x28 이미지를 평평하게 1-d tensor(vector)로 만들어서 사용할 것이다. 데이터는 아래와 같은 형태이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/wgkNuhs.jpg&quot; alt=&quot;mnist&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이제 모델을 만들어 보자. 우선은 임포트부터 진행한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;environ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'TF_CPP_MIN_LOG_LEVEL'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'2'&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;numpy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;tensorflow&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;time&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;utils&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;다음으로는 우리가 사용할 값들을 정의한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;learning_rate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.01&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;n_epochs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;n_train&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60000&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;n_test&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그리고 데이터를 불러온 뒤 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.data&lt;/code&gt;활용해 data를 불러오고, batch사이즈로 나눠주자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;mnist_folder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'data/mnist'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;utils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;download_mnist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mnist_folder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# 404 Not Found 에러 발생 시 unit의 download_mnist함수의 url 마지막에 '/' 추가
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utils&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_mnist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mnist_folder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flatten&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;train_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_tensor_slices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;train_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shuffle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# 선택
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;test_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_tensor_slices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;test_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그리고 iterator를 만들고 초기화 방법을 정한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_structure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output_types&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                           &lt;span class=&quot;n&quot;&gt;train_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output_shapes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;train_init&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;make_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;# initializer for train_data
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_init&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;make_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;# initializer for train_data
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;모델의 파라미터인 w,b 를 생성한다. img 크기에 맞게 shape을 정해준다. 그리고 w는 평균 0, 표준편차 분산 0.01의 정규분포로 초기화하고, b는 0으로 초기화한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'weight'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;784&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_normal_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'bias'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;logit과 softmax 함수를 정의하고 loss함수를 정의한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matmul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;entropy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;softmax_cross_entropy_with_logits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'entropy'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce_mean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entropy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'loss'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Optimizer는 Adam optimizer를 사용한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AdamOptimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;learning_rate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;minimize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;예측하는 연산과, 예측이 맞았는지 확인하는 것과 정확도 계산 연산을 정의한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;preds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;softmax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;correct_preds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argmax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;preds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argmax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;accuracy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce_sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cast&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;correct_preds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;float32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제 Session을 통해 정의한 것들을 실행하자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FileWriter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'./graphs/logreg'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_default_graph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;start_time&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;global_variables_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# train the model n_epochs times
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_epochs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;# drawing samples from train_data
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;n_batches&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;n_batches&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OutOfRangeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Average loss epoch {0}: {1}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total_loss&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_batches&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Total time: {0} seconds'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start_time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# test the model
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;			&lt;span class=&quot;c1&quot;&gt;# drawing samples from test_data
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;total_correct_preds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;accuracy_batch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accuracy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;total_correct_preds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;accuracy_batch&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OutOfRangeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Accuracy {0}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;total_correct_preds&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;참고로 위의 코드중에서 데이터를 suffle하는 것을 선택하도록 했는데, suffle을 안하고 실행시 정확도가 91.34%로 일정했는데, suffle을 하면 88~93%사이의 값으로 정확도가 변했다. 즉 suffle은 경우에따라 좋을 수도 있고 안좋을 수도 있다.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Seq2seq with attention: Neural Machine Translation by Jointly Learning to Align and Translate</title>
   <link href="https://reniew.github.io/37/"/>
   <updated>2018-08-13T04:47:35+00:00</updated>
   <id>https://reniew.github.io/37</id>
   <content type="html">&lt;p&gt;최근 NLP에서 많은 모델에서 사용되는 기술인 attention기법을 처음으로 도입한 논문인 &lt;a href=&quot;https://arxiv.org/pdf/1409.0473.pdf&quot;&gt;Neural Machine Translation by Jointly Learning to Align and Translate&lt;/a&gt;에 대해 알아보도록 한다. 최초로 attention을 도입한 이 논문은 Seqeunce to seqeunce with attetion으로도 유명하다.&lt;/p&gt;

&lt;p&gt;정확히는 이 논문은 Seqeunce to sequence를 처음으로 도입한 조경현 교수님의 Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation(참고: &lt;a href=&quot;https://reniew.github.io/31/&quot;&gt;블로그 글&lt;/a&gt;)에서의 문제점을 해결하기 위해 이어서 나온 논문이라 볼 수 있다.&lt;/p&gt;

&lt;p&gt;이전 논문을 기억해보면 Encoder-Decoder구조는 RNN Encoder를 통해 가변길이의 sequence를 하나의 고정된 길이의 vector로 만든 후 다시 그 vector를 통해 가변길이의 output sequence로 만드는 구조였다. 하지만 여기서의 문제점은 중간의 하나의 vector로는 앞선 모든 sequence의 정보를 담기 어렵다는 것이였고, 따라서 이 논문에서의 attention 메커니즘을 통해 해결하려 한다.&lt;/p&gt;

&lt;p&gt;이제 논문리뷰를 해보자.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;learning-phrase-representations-using-rnn-encoderdecoder-for-statistical-machine-translation&quot;&gt;Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation&lt;/h3&gt;

&lt;p&gt;논문의 저자는 KyunHyun Cho, Yoshua Bengio, Dzmitry Bahdanau로 원 논문은 &lt;a href=&quot;https://arxiv.org/pdf/1409.0473.pdf&quot;&gt;링크&lt;/a&gt;를 참고하자.&lt;/p&gt;

&lt;h4 id=&quot;introduction&quot;&gt;Introduction&lt;/h4&gt;

&lt;p&gt;Neural machine translation(NMT)은 최근 기계번역 분야에서 부상된 분야이다. 기존의 통계적 기계 번역(SMT)와는 달리 NMT는 번역 성능을 올리기 위한 단일 신경망을 만드는 것을 목표로 한다. 최근 제안된 NMT 모델은 encoder-decoder 구조의 모델이다.&lt;/p&gt;

&lt;p&gt;이 논문에서는 encoder-decoder 구조에서 중간의 fixed-size vector를 사용하는 것에 의해 병목현상이 일어날 것이라 추측했다. 실제로도 input sentence가 길어질수록 성능이 급격하게 떨어졌다. 따라서 이러한 문제를 해결하기 위해 이 구조를 확장시켜서 자동으로 문장에서 target 단어와 중요한 관계를 가지는 부분을 찾도록 할 것이다.&lt;/p&gt;

&lt;p&gt;즉 align and translate를 같이 학습하는 encoder-decoder 모델을 만들 것이다. 매 time-step 마다 번역된 단어를 만들면서 source 문장에서의 관련된 정보를 가지는 것들의 위치를 찾는다.&lt;/p&gt;

&lt;p&gt;이러한 접근법을 통해서 번역 성능을 매우 향상시킬 것이며, 긴 문장에도 높은 성능을 보여줄 것이다.&lt;/p&gt;

&lt;h4 id=&quot;background-neural-machine-translation&quot;&gt;Background: Neural Machine translation&lt;/h4&gt;

&lt;p&gt;확률적인 관점에서 보면 번역은 아래의 수식의 &lt;script type=&quot;math/tex&quot;&gt;y&lt;/script&gt;를 찾는 과정이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\arg\max_{\mathbf{y}}p(\mathbf{y}\vert\mathbf{x})&lt;/script&gt;

&lt;p&gt;Nueral machine translation에서는 위 식의 확률을 최대화 하기 위해서 번역 데이터 쌍을 통해 파라미터를 학습한다. 최근에 많은 논문들이 이러한 Neural machine translation 모델들을 제안했는데, 이 모델들은 보통 두개의 부분으로 나뉜다. 첫 번째는 source 문장 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{x}&lt;/script&gt;를 encode하는 과정이고, 두 번째는 다시 target 문장 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{y}&lt;/script&gt;로 decode하는 과정이다.&lt;/p&gt;

&lt;p&gt;이러한 구조를 가지는 모델들은 RNN을 base로 하고 있다. 따라서 RNN Encoder-Decoder라고도 불리는데, 이 구조를 조금 더 설명하자면, 우선 Encoder 과정에서는 input sequence에 대해서 encoding된 vector인 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{c}&lt;/script&gt;로 만든다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;h_t=f(x_t,h_{t-1})&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{c}=q(\{h_1,...,h_{T_x}\})&lt;/script&gt;

&lt;p&gt;Decoder 과정은 주어진 context vector인 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{c}&lt;/script&gt;를 사용해서 다음 단어인 &lt;script type=&quot;math/tex&quot;&gt;y_{t'}&lt;/script&gt;을 예측한다. 이러한 과정을 반복해서 전체 단어들인 &lt;script type=&quot;math/tex&quot;&gt;{y_1,...,y_{t'-1}}&lt;/script&gt;을 예측한다. 즉 decoder는 다음의 확률로 해석될 수 있다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(\mathbf{y}) = \prod^T_{t=1}p(y_t\vert \{y_1,...,y_{t-1}\},c)&lt;/script&gt;

&lt;p&gt;여기서 확률은 non-linear함수인 $g$에 대해 다음과 같이 정의된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(y_t\vert\{y_1,...,y_{t-1},c)=g(y_{t-1},s_t,c)&lt;/script&gt;

&lt;h4 id=&quot;learning-to-align-and-translate&quot;&gt;Learning to align and translate&lt;/h4&gt;

&lt;p&gt;앞서 말한 것처럼 align 과 translation을 같이 학습하는 모델을 만들 것이다. 따라서 이러한 새로운 모델에는 두가지의 새로운 구조가 있다. 하나는 Bidirection RNN encoder이고, 또 하나는 디코딩 과정에서 source sentence를 검색하는 decoder이다. 아래의 그림은 전체적인 구조를 그림으로 나타낸 것이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/wOx53vt.jpg&quot; alt=&quot;s2swa&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decoder: Genenral description&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;이전 section에서 정의한 조건부 확률을 다시 새롭게 정의한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(y_i\vert y_1,...,y_{i-1},\mathbf{x})=g(y_{y-1},s_i,c_i)&lt;/script&gt;

&lt;p&gt;여기서 새롭게 나온 &lt;script type=&quot;math/tex&quot;&gt;s_i&lt;/script&gt;는 RNN의 hidden state이다. 다음과 같이 계산된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;s_i=f(s_{i-1}, y_{i-1}, c_i)&lt;/script&gt;

&lt;p&gt;우선은 이 방법은 기존의 encoder-decoder 방식과는 다르다. 여기서 &lt;script type=&quot;math/tex&quot;&gt;c_i&lt;/script&gt;는 encoder의 &lt;script type=&quot;math/tex&quot;&gt;(h_1,...,h_{T_x})&lt;/script&gt;에 의해 계산된다. 여기서 각각의 &lt;script type=&quot;math/tex&quot;&gt;h_i&lt;/script&gt;는 i번째 단어 주변을 좀 더 focus한 정보를 가지고 있다.(이 부분에 대한 설명은 다음 section에서 자세히 설명한다)&lt;/p&gt;

&lt;p&gt;따라서 context vector &lt;script type=&quot;math/tex&quot;&gt;c_i&lt;/script&gt;는 각 &lt;script type=&quot;math/tex&quot;&gt;h_i&lt;/script&gt;들에 weight들을 각각 곱해서 계산된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;c_i=\sum^{T_x}_{j=1}\alpha_{ij}h_j&lt;/script&gt;

&lt;p&gt;여기서 각 &lt;script type=&quot;math/tex&quot;&gt;h_j&lt;/script&gt;에 대한 가중치인 &lt;script type=&quot;math/tex&quot;&gt;\alpha_{ij}&lt;/script&gt;는 다음과 softmax의 형태로 계산된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\alpha_{ij}=\frac{\exp(e_{ij})}{\sum^{T_x}_{k=1}\exp(e_{ik})}&lt;/script&gt;

&lt;p&gt;그리고 또 여기의 &lt;script type=&quot;math/tex&quot;&gt;e_{ij}&lt;/script&gt;는 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;e_{ij}=a(s_{i-1}, h_j)&lt;/script&gt;

&lt;p&gt;&lt;script type=&quot;math/tex&quot;&gt;e_{ij}&lt;/script&gt;은 alignment model이라 부른다. 이 값은 j번째 input 주변의 정보들이 얼마나 i번째 output과 적합한지에 대한 점수를 나타낸다. 이 점수는 RNN의 hidden state인 &lt;script type=&quot;math/tex&quot;&gt;s_{i-1}&lt;/script&gt;과 j번 째 annotation인 &lt;script type=&quot;math/tex&quot;&gt;h_j&lt;/script&gt;에 의해 계산된다.&lt;/p&gt;

&lt;p&gt;alignment model인 a는 하나의 feedforward neural network로 만들었으며, 다른 네트워크와 같이 학습되도록 만들었다. 기존의 machine translation에서는 alignment를 latent variable로 봤었는데, 여기서는 하나의 network의 variable이 된다.&lt;/p&gt;

&lt;p&gt;따라서 두개의 network가 같이 학습되는 것인데, 학습과정에서 cost의 gradient는 backpropagation을 통해 두 network에 같이 사용된다.&lt;/p&gt;

&lt;p&gt;그리고 그 전의 annotation(&lt;script type=&quot;math/tex&quot;&gt;h&lt;/script&gt;)들을 weighted sum 하는 것은 annotation의 기대값을 구하는 것이라 생각하면 된다. 즉 &lt;script type=&quot;math/tex&quot;&gt;\alpha_{ij}&lt;/script&gt;를 target word &lt;script type=&quot;math/tex&quot;&gt;y_i&lt;/script&gt;와 source word &lt;script type=&quot;math/tex&quot;&gt;x_j&lt;/script&gt;에 대한 확률이라 생각하면, i번째 context vector &lt;script type=&quot;math/tex&quot;&gt;c_i&lt;/script&gt;는 annotation의 기대값이 된다.&lt;/p&gt;

&lt;p&gt;확률 값인 &lt;script type=&quot;math/tex&quot;&gt;\alpha_{ij}&lt;/script&gt;와 거기에 사용된 energy인 &lt;script type=&quot;math/tex&quot;&gt;e_{ij}&lt;/script&gt;는 annotation &lt;script type=&quot;math/tex&quot;&gt;h_j&lt;/script&gt;의 &lt;script type=&quot;math/tex&quot;&gt;s_{j-1}&lt;/script&gt;에 대한 중요도를 나타낸다.&lt;/p&gt;

&lt;p&gt;이러한 구조를 통해 decoder는 attention 메커니즘을 가진다. 즉 decoder가 source sentence에서 집중해야 할 부분을 결정할 수 있게 한다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Encoder: Bidirectional RNN for annotating sequences&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;일반적인 RNN 구조에서는 input sequence에 대해 순방향으로 차례대로 계산을 하게 된다. 그러자 여기에서는 annotation이 앞선 단어에 대한 정보 뿐만 아니라 이후에 오는 정보도 포함할 수 있도록 양방향의 RNN(bidirection RNN, BiRNN)을 사용했다. 그리고 이 BiRNN은 이미 음성 인식분야에서 성공적인 성과를 보여줬다.&lt;/p&gt;

&lt;p&gt;BiRNN은 순방향(forward)와 역방향(backward) RNN, 두개의 RNN으로 구성된다. 먼저 순방향 RNN &lt;script type=&quot;math/tex&quot;&gt;\overset{\rightarrow}{f}&lt;/script&gt;은 sequence를 처음부터 순서대로 읽고 forward hidden state&lt;script type=&quot;math/tex&quot;&gt;({\overset{\rightarrow}{f}}_1,...,{\overset{\rightarrow}{f}}_{T_x})&lt;/script&gt;를 계산한다. 역방향 RNN &lt;script type=&quot;math/tex&quot;&gt;\overset{\leftarrow}{f}&lt;/script&gt;는 sequence를 역방향으로 마지막부터 처음까지 읽고 backward hidden state&lt;script type=&quot;math/tex&quot;&gt;({\overset{\leftarrow}{f}}_1,...,{\overset{\leftarrow}{f}}_{T_x})&lt;/script&gt;를 계산한다.&lt;/p&gt;

&lt;p&gt;이제 각 단어 &lt;script type=&quot;math/tex&quot;&gt;x_j&lt;/script&gt;에 대해서 foward hidden state와 backward hidden state를 concatenate해서 annotation &lt;script type=&quot;math/tex&quot;&gt;h_j&lt;/script&gt;를 구한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;h_j=\big[{\overset{\rightarrow}{f}}^T_j;{\overset{\leftarrow}{f}}_j^T\big]&lt;/script&gt;

&lt;p&gt;이 방법을 통해 annotation &lt;script type=&quot;math/tex&quot;&gt;h_j&lt;/script&gt;는 j번쨰 단어 앞뒤의 정보를 모두 포함할 수 있게 된다.&lt;/p&gt;

&lt;h4 id=&quot;experiment-settings&quot;&gt;Experiment Settings&lt;/h4&gt;

&lt;p&gt;실험을 위한 데이터셋은 WMT’14 English-French corpora를 사용했다. 데이터에 대한 설명은 조경현 교수님의 paper review 글을 참고하자(&lt;a href=&quot;https://reniew.github.io/31/&quot;&gt;blog&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;그리고 data selection 방법을 통해 데이터의 size를 줄였고, 앞선 데이터의 monolingual data는 사용하지 않았다.&lt;/p&gt;

&lt;p&gt;실험을 위해 두가지 모델을 학습 시켰다. 하나는 기존은 RNN Encoder-Decoder모델(RNNencdec)이고 나머지 하나는 이 글에서 소개한 모델(RNNsearch)이다. 두 모델을 각각 두번 학습 시켰는데, 한번은 문장 길이를 30으로 제한한 것이고(RNNencdec-30, RNNsearch-30), 두 번째는 문장 길이를 50(RNNencdec-50, RNNsearch-50)으로 제한시켰다.&lt;/p&gt;

&lt;p&gt;RNNencdec와 RNNsearch 모두 encoder,decoder는 각각 1000개의 hidden unit을 가진다.&lt;/p&gt;

&lt;p&gt;학습과정에서 minibatch SGD 알고리즘을 사용했으며, Adadelta를 사용해 파라미터 update를 했다. 각 SGD update는 80 크기의 mini-batch로 업데이트 되었다.&lt;/p&gt;

&lt;p&gt;모델을 학습 한 이후에는 beam search를 이용해 번역을 진행했다. 이 과정 또한 앞선 모델의 설명에서 확인 할 수 있다.&lt;/p&gt;

&lt;h4 id=&quot;quantitative-results&quot;&gt;Quantitative Results&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/AMZVlsm.jpg&quot; alt=&quot;qresult&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/jeHbIcU.jpg&quot; alt=&quot;qresult2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;우선은 위의 그래프를 보면 RNNencdec 모델의 경우 문장 길이가 길어 질 수록 BLUE 스코어가 확연히 떨어지는 것을 볼 수 있는데 RNNsearch-50 의 경우 문장의 길이가 길어 지더라도 지속적으로 높은 BLUE 스코어를 가진다.&lt;/p&gt;

&lt;h4 id=&quot;qualitative-analysis&quot;&gt;Qualitative Analysis&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/cNPVifz.jpg&quot; alt=&quot;qual&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위 그림은 각각의 단어에 대해 annotation &lt;script type=&quot;math/tex&quot;&gt;\alpha_{ij}&lt;/script&gt; 값을 grayscale로 나타낸 그림이다. 그림을 보면 각각 단어가 매칭되는 부분에서 annotation이 높은 값을 가지는 것을 알 수 있고, 정확히 대칭되는 위치가 아니라 앞 뒤의 위치에서도 매칭될 수 있는 모습을 볼 수 있다.&lt;/p&gt;

&lt;p&gt;그리고 논문에는 긴 문장의 영어를 번역했을 때 나온 불어가 굉장히 잘 번역되었다고 하는데, 이 부분은 불어를 잘 모르기 때문에 생략한다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;긴글 읽어주셔서 감사합니다. 오역 및 잘못된 내용이 있을 수 있습니다. 잘못된 부분 혹은 이해가 잘 안되는 부분은 댓글 혹은 메일로 말씀해주시면 감사하겠습니다!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Seq2seq (2): Sequence to Sequence Learning with Neural Networks</title>
   <link href="https://reniew.github.io/35/"/>
   <updated>2018-08-13T04:47:35+00:00</updated>
   <id>https://reniew.github.io/35</id>
   <content type="html">&lt;p&gt;최초의 Seq2Seq 개념을 도입한 논문에 대해서 알아보았다. 이번에는 Sequence to sequence 개념을 사용해 일반적으로 최초의 Neural Machine Translation 모델로 알려져 있는 Google의 &lt;a href=&quot;https://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf&quot;&gt;Sequence to Sequence Learning with Neural Networks&lt;/a&gt;에 대해서 알아보자.&lt;/p&gt;

&lt;hr /&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/31&quot;&gt;Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/35&quot;&gt;Sequence to Sequence with Neural Network&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;sequence-to-sequence-learning-with-neural-networks&quot;&gt;Sequence to Sequence Learning with Neural Networks&lt;/h3&gt;

&lt;h4 id=&quot;introduction&quot;&gt;Introduction&lt;/h4&gt;

&lt;p&gt;Deep Neural Network는 여러 분야에서 많은 성과를 보여줬다. 많은 분야에서 이미 증면된 DNN은 유연하고 강력함에도 불구하고, input과 target이 고정된 dimension의 vector인 경우의 문제에만 사용할 수 있었다. 이러한 점이 DNN의 심각한 한계였다. 많은 중요한 문제는 input과 target이 길이에 대한 정보가 미리 주어지지 않은 sequence이기 때문이다. 예를 들어 QA(Question Answering)문제도 주어진 가변길이의 sequence를 answer에 대한 가변길이 seqeunce로 바꾸는 문제이다.&lt;/p&gt;

&lt;p&gt;따라서 이 논문에서는 LSTM을 활용해서 sequence에서 sequence로 가는 구조를 소개한다. 아래의 그림은 모델의 구조를 보여준다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/KK3SZzU.jpg&quot; alt=&quot;s2s&quot; /&gt;&lt;/p&gt;

&lt;p&gt;모델에 대해서 자세히 알아보자.&lt;/p&gt;

&lt;h4 id=&quot;the-model&quot;&gt;The Model&lt;/h4&gt;

&lt;p&gt;Recurrent Neural Network는 sequence의 일반적인 feedforward neural network이다. 주어진 input sequence &lt;script type=&quot;math/tex&quot;&gt;(x_1,...,x_n)&lt;/script&gt;에 대해, RNN은 아래의 수식을 반복하면서 output sequence &lt;script type=&quot;math/tex&quot;&gt;(y_1,...,y_T)&lt;/script&gt;를 계산한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
h_t&amp;=\sigma(\mathbf{W}^{hx}x_t+\mathbf{W}^{hh}h_{t-1})\\
y_t&amp;=\mathbf{w}^{yh}h_t
\end{align*} %]]&gt;&lt;/script&gt;

&lt;p&gt;RNN을 통해 input sequence를 앞선 시간 정보를 포함한 output seqeunce으로 쉽게 mapping 할 수 있다. 하지만 input의 길이와 output길이가 다르고 두 길이가 간단한 관계로 이루어 지지 않은 경우에는 RNN을 적용하기 어렵다.&lt;/p&gt;

&lt;p&gt;이를 해결할 간단한 전략은 input sequence를 RNN을 통해 고정된 길이의 vector로 만든 후에 다시 그 vector를 RNN을 통해 우리가 원하는 target sequence를 구하는 방법이다.(&lt;a href=&quot;https://arxiv.org/abs/1406.1078&quot;&gt;Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation&lt;/a&gt;와 유사한 방식이다) 단순한 RNN을 통해서도 이러한 전략을 구현할 수 있지만, 중요한 문제점은 RNN은 Long-term에 대한 정보를 포함하지 않는다는 것이다. 따라서 Long Short-Term Memory(LSTM)을 사용해서 이러한 long-term에 대한 정보를 잡아 낼 것이다.&lt;/p&gt;

&lt;p&gt;여기서 LSTM의 최종적인 목표는 input sequence에 대한 output sequence의 조건부 확률 &lt;script type=&quot;math/tex&quot;&gt;p(y_1,...,y_{T'}\vert x_1,...,x_T)&lt;/script&gt;를 구하는 것이다. 따라서 위의 전략대로 우선 주어진 input sequence를 통해 고정된 길이의 vector representation &lt;script type=&quot;math/tex&quot;&gt;v&lt;/script&gt;를 먼저 구한다. 여기서 벡터 &lt;script type=&quot;math/tex&quot;&gt;v&lt;/script&gt;는 첫 RNN의 마지막 hidden state의 값이 된다. 그리고 다시 LSTM을 통해 &lt;script type=&quot;math/tex&quot;&gt;y_1,...,y_{T'}&lt;/script&gt;에 대한 확률을 게산한다. 즉 아래의 식과 같이 계산한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(y_1,...,y_{T'}\vert x_1,...,x_T)=\prod^{T'}_{t=1}p(y_t\vert v,y_1,...,y_{t-1})&lt;/script&gt;

&lt;p&gt;위 식에서 우항의 &lt;script type=&quot;math/tex&quot;&gt;p(y_t\vert v,y_1,...,y_{t-1})&lt;/script&gt;은 전체 vocabulary의 단어를 통해 softmax값을 계산해서 구한다. 문장이 끝난 지점에는 “&lt;EOS&gt;&quot;라는 토큰을 사용해 문장이 끝났다는 정보를 주고 그 지점부터 다시 output의 계산을 시작한다. 즉 위의 그림을 보면 먼저 LSTM은 &quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;&lt;EOS&gt;&quot;를 먼저 계산한다 그리고 마지막의 hidden state값을 통해 &quot;W&quot;, &quot;X&quot;, &quot;Y&quot;, &quot;Z&quot;, &quot;&lt;EOS&gt;&quot; 에 대한 확률을 계산한다.&lt;/EOS&gt;&lt;/EOS&gt;&lt;/EOS&gt;&lt;/p&gt;

&lt;p&gt;실제 모델은 위의 설명과 세가지 방법이 다르다. 첫 번째로는 input sequence와 output sequence에 대해 두개의 다른 LSTMs를 사용했다. 두 번째로는 deep한 LSTM의 성능이 더 뛰어난 것을 확인한 후 4개의 layer를 사용하는 LSTM을 사용했다. 세 번쨰로는 input sequence의 순서를 뒤집어서 사용했다. 예를 들면 문장 a, b, c를 d, e, f로 번역하는 대신 순서를 바꿔 c, b, a 를 LSTM을 통해 d, e, f 값이 나오도록 학습시켰다.(a-&amp;gt;d, b-&amp;gt;e, c-&amp;gt;f 가 정확한 번역) 이러한 간단한 data transformation이 LSTM의 성능을 획기적으로 올려준다는 것을 확인 했다.&lt;/p&gt;

&lt;h4 id=&quot;experiments&quot;&gt;Experiments&lt;/h4&gt;

&lt;p&gt;WMT’14 English to French 기계번역 테스크에 이 모델을 적용시켰다. 그리고 다른 SMT 시스템을 참고하지 않고 직접 이 모델을 통해 번역했다.&lt;/p&gt;

&lt;p&gt;데이터에 대해서 자세한 사항은 총 12M개의 sentence 중 일부를 학습시켰는데 여기에는 348M개의 프랑스어 단어와 304M개의 영어 단어가 포함되어있다. 그리고 두 언어에 대해서 각각 일정한 vocabulary를 사용했는데, 여기에는 160,000개의 가장 많이 사용되는 단어가 포함되어 있다. 그리고 vocabulary에 포함되지 않은 단어는 “UNK”라는 토큰으로 대체했다.&lt;/p&gt;

&lt;p&gt;실험의 핵심은 크고 깊은 LSTM 모델을 많은 문장 쌍으로 학습시키는 것이다. 학습은 주어진 문장 &lt;script type=&quot;math/tex&quot;&gt;S&lt;/script&gt;에 대한 정확히 번역된 문장 &lt;script type=&quot;math/tex&quot;&gt;T&lt;/script&gt;의 log-확률값을 최대화 하는 것이다. 따라서 objective 함수는 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;1/\vert S\vert\sum_{(T,S)\in S}\log p(T\vert S)&lt;/script&gt;

&lt;p&gt;여기서 &lt;script type=&quot;math/tex&quot;&gt;S&lt;/script&gt;가 training set이 된다. 학습이 끝난 후에는 주어진 문장에 대해서 가장 높은 확률을 같은 문장 &lt;script type=&quot;math/tex&quot;&gt;T&lt;/script&gt;를 찾는다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\hat{T}=\arg\max_T p(T\vert S)&lt;/script&gt;

&lt;p&gt;실제 예측 과정에서는 간단한 left-to-right beam search decoder를 사용했다. 즉 어떤 특정 $B$개의 문장을 정하고 각 timestep마다 다른 문장들을 추가한 후 위의 log-확률이 높은 B개를 제외하고 나머지는 모두 버린다. 그리고 “&lt;EOS&gt;&quot; 토큰이 나오면  문장에 이 토큰을 더해 완성된 문장을 만든다. Decoder의 경우 근사시키는 방법인 반면 이 방법은 구현하기 매우 간단하다. beam size를 1로 했을 때도 매우 잘 동작했다.&lt;/EOS&gt;&lt;/p&gt;

&lt;h4 id=&quot;reversing-the-source-sentence&quot;&gt;Reversing the Source Sentence&lt;/h4&gt;

&lt;p&gt;앞서 말했듯이 LSTM에서 source sentence를 거꾸로 사용했을 때 더욱 좋은 결과를 만들어 냈다. 이러한 방법을 통해 perplexity는 5.8에서 4.7까지 떨어졌고, BLEU score는 25.9에서 30.6까지 올랐다.&lt;/p&gt;

&lt;p&gt;이러한 현상에 대해서 정확한 이유는 아직 모르지만, input sentence를 뒤집음으로써 각 대응되는 단어끼리의 평균 길이는 변하지 않고 처음의 단어에 대해 대응되는 단어와 거리가 가까워지기 때문에 조금 더 효율이 올라갔을거라는 추측을한다.&lt;/p&gt;

&lt;h4 id=&quot;training-detalis&quot;&gt;Training detalis&lt;/h4&gt;

&lt;p&gt;학습과정에서 사용한 방법들의 자세한 설명은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;4개의 layer&lt;/li&gt;
  &lt;li&gt;1000개의 cell&lt;/li&gt;
  &lt;li&gt;단어의 경우 1000 dimension으로 embedding&lt;/li&gt;
  &lt;li&gt;160,000개의 input vocabulary&lt;/li&gt;
  &lt;li&gt;80,000개의 output vocabulary&lt;/li&gt;
  &lt;li&gt;모든 파라미터는 (-0.08, 0.08)사이의 uniform distribution이루도록 초기화&lt;/li&gt;
  &lt;li&gt;SGD 사용, learning rate = 0.7, 5에폭 후에는 0.5에폭마다 learning rate를 절반으로 줄임. 총 7.5에폭으로 학습&lt;/li&gt;
  &lt;li&gt;128 sequence 크기의 배치 사용&lt;/li&gt;
  &lt;li&gt;Vanishing gradient는 발생하지 않았지만, exploding gradient의 발생 떄문에 gradient의 norm 값에 대해 constraint를 줌. 즉 매 배치에 대해서 평균 gradient의 L2 norm값이 5를 넘어가면 5값을 줌.&lt;/li&gt;
  &lt;li&gt;대부분의 문장은 20~30정도의 길이로 짧았지만 몇몇의 경우 100이상의 길이인 경우도 있었다. 따라서 128의 mini batch에는 주로 짧은 문장이 대부분이였고 긴문장 몇개가 포함되었다. 따라서 미니배치로 학습시 길이가 너무 달라 학습이 잘되지 않는 문제를 위해 미니배치안에서 길이를 고정시켰다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;result&quot;&gt;Result&lt;/h4&gt;

&lt;p&gt;결과는 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/FrZJLbd.jpg&quot; alt=&quot;result_s2s&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/RhjACoH.jpg&quot; alt=&quot;result_s2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;그리고 이 모델에서 중간의 input에서 output으로 가는 hidden state의 값인 고정된 벡터를 PCA를 통해 2차원 좌표상에 나타낸 결과는 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/7S4U55z.jpg&quot; alt=&quot;pca&quot; /&gt;&lt;/p&gt;

&lt;p&gt;결과를 보면, 문장 순서에 따라 값이 매우 달라지는 것을 볼 수 있고, 능/수동 은 크게 상관없는 것을 확인 할 수 있다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;긴글 읽어주셔서 감사합니다. 오역 및 잘못된 내용이 있을 수 있습니다. 잘못된 부분 혹은 이해가 잘 안되는 부분은 댓글 혹은 메일로 말씀해주시면 감사하겠습니다!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>CS20(TensorFlow) Lecture Note (1),(2): Overview & TensorFlow Operation</title>
   <link href="https://reniew.github.io/32/"/>
   <updated>2018-08-13T04:47:35+00:00</updated>
   <id>https://reniew.github.io/32</id>
   <content type="html">&lt;p&gt;스탠포드의 TensorFlow 강의인 cs20 강의의 lecture note를 정리한 글입니다. 강의는 오픈되지 않아서 Lecture note, slide 위주로 정리된 글임을 참고 해주시길 바랍니다. 강의의 자세한 Syllabus 및 자료들을 아래 링크를 참고해 주세요.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://web.stanford.edu/class/cs20si/&quot;&gt;CS20: TensorFlow for Deep Learning Research&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h5 id=&quot;post-list&quot;&gt;Post list&lt;/h5&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/32&quot;&gt;Lecture 1, 2: Overview &amp;amp; TensorFlow Operation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/33&quot;&gt;Lecture 3: Linear and Logistic Regression&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/34&quot;&gt;Lecture 4: Eager execution and interface&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/36&quot;&gt;Lecture 5: word2vec + manage experiments&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/38&quot;&gt;Lecture 6, 7: Intro to ConvNet &amp;amp; ConvNet in TensorFlow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/39&quot;&gt;Lecture 8: CNN(Style transfer), TFRecord &lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/40&quot;&gt;Lecture 10: Variational Auto Encoders(VAE)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/41&quot;&gt;Lecture 11: RNNs in the TensorFlow&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/42&quot;&gt;Lecture 12: Machine Translation, Seqeunce-to-sequence and Attention&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;1-introduction-to-tensofflow&quot;&gt;1. Introduction to TensofFlow&lt;/h3&gt;

&lt;p&gt;텐서플로우에 대한 소개는 텐서플로우 웹사이트에서 소개한 말을 인용한다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;TensorFlow is an open source software library for numerical computation using data flow graphs&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;소개에 대한 부분은 자세히 쓰지 않는다. 텐서플로우의 장점 및 자세한 내용은 &lt;a href=&quot;https://www.tensorflow.org/&quot;&gt;텐서플로우 홈페이지&lt;/a&gt;를 참고하자.&lt;/p&gt;

&lt;h3 id=&quot;2-tensorflow-ops&quot;&gt;2. TensorFlow Ops&lt;/h3&gt;

&lt;h4 id=&quot;tensorboard&quot;&gt;TensorBoard&lt;/h4&gt;

&lt;p&gt;텐서플로우의 사용 방법 이전에 우선 텐서플로우를 사용하면서 좀 더 직관적인 이해와 시각화를 위한 소프트웨어인 텐서보드를 먼저 소개한다.&lt;/p&gt;

&lt;p&gt;텐서보드는 텐서플로 설치시 포함되어있는 Graph visualization 소프트웨어로 Google의 TensorBoard에 대한 설명을 인용한다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“The computations you’ll use TensorFlow for - like training a massive deep neural network - can be complex and confusing. To make it easier to understand, debug, and optimize TensorFlow programs, we’ve included a suite of visualization tools called TensorBoard”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;텐서플로우로 실행시킨 내역에 대해서 텐서보드로 확인 할 수 있다. 예를 들어 아래의 텐서플로우 코드에 대해서 텐서보드로 확인한다고 하자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;tensorflow&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;텐서보드로 실행시키기 위해서는 계산되는 값에 대해 log file을 만들어 줭야 한다. 따라서 아래의 명령어를 입력해야 한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FileWriter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logdir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;logdir&lt;/code&gt;은 log file이 저장될 경로를 뜻하고, graph는 우리가 동작시키는 프로그램의 하나의 graph를 뜻한다.&lt;/p&gt;

&lt;p&gt;로그파일을 저장했다면 명령 프롬프트에서 다음과 같이 입력하면 된다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ python [my_program.py]
$ tensorboard --logdir=&quot;logdir&quot; --port 6006
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이후 웹 브라우저에서 &lt;a href=&quot;http://localhost:6006&quot;&gt;http://localhost:6006&lt;/a&gt;으로 들어가면 TensorBoard를 사용할 수 있다.&lt;/p&gt;

&lt;p&gt;그리고 텐서보드를 사용할 때 로그파일을 저장하는데, log파일이 쌓여서 겹칠 경우에는 가장 최신의 파일을 인식한다. 그리고 경고가 뜨는데 이 경고를 없에기 위해서는 쌓여있는 log파일을 정리해줘야 한다.&lt;/p&gt;

&lt;h4 id=&quot;constant&quot;&gt;Constant&lt;/h4&gt;

&lt;p&gt;constant를 만드는 가장 기본적인 방법은 다음과 같다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Const'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;verify_shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Flase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그 외에 다양한 종류의 constant를 만드는 방법은 다음과 같다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;float32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros_like&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ones&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;float32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ones_like&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dims&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lin_space&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delta&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'range'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;여기서 주의해야 할 점은 아래의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.lin_space()&lt;/code&gt;와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.range()&lt;/code&gt;함수는 iterable하지 않기 때문에 for문에서 사용할 수 없다.&lt;/p&gt;

&lt;p&gt;각 함수를 사용해서 직접 만드는 예시는 다음과 같다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros_like&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ones&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ones_like&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lin_space&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;10.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;13.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;linspace&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;10.0&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;11.0&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;12.0&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;13.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 'start' is 3, 'limit' is 18, 'delta' is 3
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 'limit' is 5
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위의 방법외에도 random한 값을 가지는 constant를 지정해줄 수 있는데 아래와 같은 다양한 함수를 통해 만들 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;tf.random_normal
tf.truncated_normal
tf.random_uniform
tf.random_shuffle
tf.random_crop
tf.multinomial
tf.random_gamma
tf.set_random_seed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이 함수들의 자세한 내용은 &lt;a href=&quot;https://www.tensorflow.org/api_guides/python/constant_op&quot;&gt;링크&lt;/a&gt;를 참고하자&lt;/p&gt;

&lt;h4 id=&quot;math-operation&quot;&gt;Math Operation&lt;/h4&gt;

&lt;p&gt;텐서플로우는 많은 수학 연산을 제공하는데 전체 리스트는 &lt;a href=&quot;https://www.tensorflow.org/api_guides/python/math_ops&quot;&gt;링크&lt;/a&gt;를 참고하자.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Division operation&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;텐서플로우에는 다양한 나눗셈 연산들이 있다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.division&lt;/code&gt;은 일반적인 파이썬의 연산을 생각하면 된다. 그리고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.div&lt;/code&gt;는 텐서플로우 스타일의 나눗셈 연산으로 사용된다. 전체 나눗셈에 대한 자세한 내용은 &lt;a href=&quot;https://www.tensorflow.org/api_docs/python/tf/divide&quot;&gt;documentation&lt;/a&gt;을 참고하자. 아래는 나눗셈을 사용하는 예시이다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'a'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'b'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;             &lt;span class=&quot;err&quot;&gt;⇒&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;divide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;          &lt;span class=&quot;err&quot;&gt;⇒&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;truediv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;         &lt;span class=&quot;err&quot;&gt;⇒&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;floordiv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;        &lt;span class=&quot;err&quot;&gt;⇒&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;realdiv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;         &lt;span class=&quot;err&quot;&gt;⇒&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Error: only works for real values
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;truncatediv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;     &lt;span class=&quot;err&quot;&gt;⇒&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;floor_div&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;       &lt;span class=&quot;err&quot;&gt;⇒&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;tf.add_n&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;덧셈 연산을 한다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.add_n([a,b,b])&lt;/code&gt;는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a+b+b&lt;/code&gt;와 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Dot product &amp;amp; matmul&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.matmul&lt;/code&gt;과 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.tensordot&lt;/code&gt;을 구분해서 사용해야 한다. 전자는 rank가 2이상인 matrix에서 사용하는 것이다. 아래의 예시를 보자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'a'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'b'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;multiply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;           &lt;span class=&quot;err&quot;&gt;⇒&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# element-wise multiplication
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensordot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;       &lt;span class=&quot;err&quot;&gt;⇒&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;data-type&quot;&gt;Data Type&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Python Native Type&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;파이썬의 기본 데이터 타입의 경우에는 텐서플로우에서 다음과 같이 취급 된다.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Data&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;example&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;in Tensor&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Single value&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;Bool,String,Numeric&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;0-d tensor(scalar)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;List of value&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;[‘a’,’b’,’c’], [2,3],[True,False]&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;1-d tensor(vector)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;List of list&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;[[1,2,], [2,3]]&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;2-d tensor(matrix)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;파이썬 데이터 타입을 사용하면 예를들어 아래와 같이 적용된다.&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;t_0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Treated as a 0-d tensor, or &quot;scalar&quot;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros_like&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t_0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;                   &lt;span class=&quot;c1&quot;&gt;# ==&amp;gt; 0
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;t_1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;b&quot;apple&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;b&quot;peach&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;b&quot;grape&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# treated as a 1-d tensor, or &quot;vector&quot;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros_like&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;             

&lt;span class=&quot;n&quot;&gt;t_2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
       &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
       &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;         &lt;span class=&quot;c1&quot;&gt;# treated as a 2-d tensor, or &quot;matrix&quot;
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros_like&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t_2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;                   &lt;span class=&quot;c1&quot;&gt;# ==&amp;gt; 3x3 tensor, all elements are False
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;TensorFlow Native Data&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;텐서플로우는 많은 데이터 타입을 가지고 있다. 전체 리스트는 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;tf.float16: 16-bit half-precision floating-point.&lt;/li&gt;
  &lt;li&gt;tf.float32: 32-bit single-precision floating-point.&lt;/li&gt;
  &lt;li&gt;tf.float64: 64-bit double-precision floating-point.&lt;/li&gt;
  &lt;li&gt;tf.bfloat16: 16-bit truncated floating-point.&lt;/li&gt;
  &lt;li&gt;tf.complex64: 64-bit single-precision complex.&lt;/li&gt;
  &lt;li&gt;tf.complex128: 128-bit double-precision complex.&lt;/li&gt;
  &lt;li&gt;tf.int8: 8-bit signed integer.&lt;/li&gt;
  &lt;li&gt;tf.uint8: 8-bit unsigned integer.&lt;/li&gt;
  &lt;li&gt;tf.uint16: 16-bit unsigned integer.&lt;/li&gt;
  &lt;li&gt;tf.uint32: 32-bit unsigned integer.&lt;/li&gt;
  &lt;li&gt;tf.uint64: 64-bit unsigned integer.&lt;/li&gt;
  &lt;li&gt;tf.int16: 16-bit signed integer.&lt;/li&gt;
  &lt;li&gt;tf.int32: 32-bit signed integer.&lt;/li&gt;
  &lt;li&gt;tf.int64: 64-bit signed integer.&lt;/li&gt;
  &lt;li&gt;tf.bool: Boolean.&lt;/li&gt;
  &lt;li&gt;tf.string: String.&lt;/li&gt;
  &lt;li&gt;tf.qint8: Quantized 8-bit signed integer.&lt;/li&gt;
  &lt;li&gt;tf.quint8: Quantized 8-bit unsigned integer.&lt;/li&gt;
  &lt;li&gt;tf.qint16: Quantized 16-bit signed integer.&lt;/li&gt;
  &lt;li&gt;tf.quint16: Quantized 16-bit unsigned integer.&lt;/li&gt;
  &lt;li&gt;tf.qint32: Quantized 32-bit signed integer.&lt;/li&gt;
  &lt;li&gt;tf.resource: Handle to a mutable resource.&lt;/li&gt;
  &lt;li&gt;tf.variant: Values of arbitrary types.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;텐서플로우의 데이터 타입을 보면 Numpy의 데이터 타입과 비슷하게 생겼다는 것을 알 수 있다. 실제로도 두 데이터 타입은 같은 데이터 타입이다. 텐서플로우의 것이 넘파이의 데이터 타입을 기반으로 만들어졌기 때문이다. 따라서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.int32 == np.int32&lt;/code&gt; 와 같이 사용하면 True의 반환한다.&lt;/p&gt;

&lt;p&gt;그리고 넘파이 데이터로 텐서플로우 데이터 생성시 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run&lt;/code&gt;하기 전까지는 텐서플로우 데이터로 나오나 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run&lt;/code&gt;이후에는 넘파이 데이터로 나온다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;  			&lt;span class=&quot;c1&quot;&gt;# ⇒ &amp;lt;class 'tensorflow.python.framework.ops.Tensor'&amp;gt;
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;  			&lt;span class=&quot;c1&quot;&gt;# ⇒ &amp;lt;class 'numpy.ndarray'&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;variables&quot;&gt;Variables&lt;/h4&gt;

&lt;p&gt;Constant와 variable의 차이에 대해서 먼저 얘기해보자.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;constant는 constant이다. 즉 불변하다는 것이다. 학습과정에서 우리는 weight와 bias를 update해줘야 한다.&lt;/li&gt;
  &lt;li&gt;constant 값은 graph에 저장된다. 그리고 graph가 로드될 때 마다 계속해서 복제된다. 그러나 variable은 각각 저장되어서 복제되지 않고 parameter서버에서 동시에 사용된다.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;2번의 내용이 매우 중요하다. constant는 graph definition에 저장되는데 constant 자체가 매우 크면 계속해서 graph를 호출할 때 마다 복제되어서 시스템이 느려진다. 여기서 말하는 graph의 정의를 호출하는 방법은 다음과 같다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;tensorflow&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;my_const&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;my_const&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_default_graph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;as_graph_def&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;결과는 다음과 같다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;my_const&quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;op&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Const&quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;dtype&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DT_FLOAT&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;attr&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;value&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DT_FLOAT&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;tensor_shape&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;tensor_content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\000\000\200&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\000\000\000&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;versions&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;producer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Creating variables&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;변수를 선언하기 위해서는 우선 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.Variable&lt;/code&gt;객체의 인스턴스를 만들어야한다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;tf.constant의 c는 소문자이고 tf.Variable의 V는 대문자이다. 그 이유는 constant는 연산이고 Variable은 연산을 포함하는 객체이기 때문이다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;변수를 만드는 고전적인 방법은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.Variable(&amp;lt;initial-value&amp;gt;, name=&amp;lt;optional-name&amp;gt;)
&lt;/code&gt;를 사용하는 것이다. 예시를 보자.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Python&quot;&gt;s = tf.Variable(2, name=&quot;scalar&quot;)
m = tf.Variable([[0, 1], [2, 3]], name=&quot;matrix&quot;)
W = tf.Variable(tf.zeros([784,10]))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;하지만 이러한 고전적인 방법보다는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.get_variable&lt;/code&gt;을 사용하는 것을 추천한다. 이 방법을 통하면 변수들을 공유하는 것이 매우 쉬워진다. 사용하는 방법은 다음과 같다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;regularizer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;trainable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;collections&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;caching_device&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;partitioner&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;validate_shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;use_resource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;custom_getter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;constraint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;직접 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.get_variable&lt;/code&gt; 사용해서 변수를 생성해보자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;scalar&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;matrix&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;W&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;big_matrix&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;784&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Initialize variables&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;변수를 선언만하고 값을 할당하지 않으면 FailedPreconditionError가 발생하면서 사용할 수 없다. 따라서 우리는 변수를 초기화 해야 하는데, 초기화에는 다양한 방법들이 있다. 우선은 방법들을 알아보기 전에 초기화되지 않은 변수들의 리스트를 확인하는 방법에 대해서 먼저 알아보자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;report_uninitialized_variables&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그리고 모든 변수를 한번에 초기화하는 방법은 다음과 같다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Python&quot;&gt;with tf.Session() as sess:
	sess.run(tf.global_variables_initializer())
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;부분적으로 초기화 하거나 하나씩 초기화하는 방법은 다음과 같다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#initialize subset of variables
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;variables_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#initialize each variables
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  	&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;W&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Assign values to variables&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;변수에 값을 할당하는 방법은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.Varibale.assign()&lt;/code&gt;를 사용하는 것이다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;W&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;W&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;W&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;W&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &amp;gt;&amp;gt; 10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;하지만 위와 같이 실행을 하면 W에 100이 할당되지 않은 것을 확인할 수 있다. 왜 그럴까?
이유는 assign을 선언만 해놓고 실제 실행을 하지 않았기 떄문이다.(assign도 하나의 연산이기 떄문에 run해줘야 적용된다.)&lt;/p&gt;

&lt;p&gt;즉 아래와 같이 assign을 run을 해야 한다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;W&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;assign_op&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;W&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assign_op&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;W&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# &amp;gt;&amp;gt; 100
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그리고 변수를 초기화할 떄 assign을 사용해서 초기화 할 수도 있다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# in the source code
&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_initializer_op&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state_ops&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_initial_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;validate_shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;validate_shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;op&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assign_add&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assign_sub&lt;/code&gt;등 여러 할당 함수들이 있다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Python&quot;&gt;W = tf.Variable(10)

with tf.Session() as sess:
	sess.run(W.initializer)
	print(sess.run(W.assign_add(10))) # &amp;gt;&amp;gt; 20
	print(sess.run(W.assign_sub(2)))  # &amp;gt;&amp;gt; 18
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Interactive Session&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Interacitve session을 사용하면 별다른 session을 호출할 필요없이 바로 run, eval을 할 수 있다. 간단한 방법이지만 만약 여러 session을 다루기에는 어려움이 있다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InteractiveSession&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;5.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;6.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# we can use 'c.eval()' without explicitly stating a session
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Importing Data&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이제 텐서플로우 사용에서 가장 중요한 방법인 data를 불러오는 방법이다. 먼저 기존의 방식에 대해서 설명한다.&lt;/p&gt;

&lt;p&gt;기존의 방식은 placeholders 와 feed_dict를 사용하는 방식이다.&lt;/p&gt;

&lt;p&gt;paceholders란 데이터를 담아둘 곳이라고 생각하면 된다. 그리고 feed_dict를 통해 값을 할당하면 된다. 우선 placeholder를 정의하는 방법은 다음과 같다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;placeholder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;옵션을 보면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dtype&lt;/code&gt;은 데이터 타입을 뜻하고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt;은 사용자가 지정할 이름을 뜻한다. 그리고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shape&lt;/code&gt;는 담을 데이터의 형태를 뜻하는데 만약 지정하지 않으면 어떤 데이터이든지 넣을 수 있다는 장점이 있지만 디버그과정에서는 문제가 되는 부분을 찾기가 매우 힘들어 진다. 따라서 웬만하면 shape를 지정하도록 하자.&lt;/p&gt;

&lt;p&gt;이제 placeholder를 정의하고 feed_dict를 통해 값을 할당하는 방법에 대해 알아보자.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Python&quot;&gt;a = tf.placeholder(tf.float32, shape=[3]) # a is placeholder for a vector of 3 elements
b = tf.constant([5, 5, 5], tf.float32)
c = a + b # use the placeholder as you would any tensor

with tf.Session() as sess:
	# compute the value of c given the value of a is [1, 2, 3]
	print(sess.run(c, {a: [1, 2, 3]})) 		# [6. 7. 8.]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위와 같이 사용하면 된다. feed_dict는 iterative하게 사용가능하다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a_value&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list_of_a_values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그리고 feed_dict는 placeholder에만 사용되는 것이 아니고 일반 연산에서도 사용 가능하다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;multiply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; 						&lt;span class=&quot;c1&quot;&gt;# &amp;gt;&amp;gt; 21
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;# compute the value of b given the value of a is 15
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;feed_dict&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}))&lt;/span&gt; 			&lt;span class=&quot;c1&quot;&gt;# &amp;gt;&amp;gt; 45
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위의 place_holder와 feed_dict는 데이터를 다루는 고전적인 방법이라고 배웠다. 그렇다면 최신의 방법은 무었일까 바로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.data&lt;/code&gt;를 사용하는 것이다. 이 방법에 대해서는 다음 강의에서 알아보도록 한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Lazy Loading&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;마지막으로 텐서플로우를 사용하면서 발생할 수 있는 문제에 대해서 소개한다. 우선 아래의 두 예시를 보자.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'x'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'y'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;global_variables_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FileWriter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'graphs/normal_loading'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'x'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Variable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'y'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;global_variables_initializer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FileWriter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'graphs/lazy_loading'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;sess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_default_graph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;as_graph_def&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;예시를 보면 두 코드다 같이 반복적으로 add연산을 수행하고 있다. 하지만 실행해보면 아래의 코드가 속도가 더 느리다. 만약 반복횟수가 더 커지면 커질수록 느려질 것이다. 왜그럴까?&lt;/p&gt;

&lt;p&gt;아래의 코드는 ‘add’ 노드를 연산 수행할 때마다 계속해서 정의하고 수행한다. 그에 반해 첫번째 코드는 연산을 먼저 정의한 후 정의한 연산을 반복 사용만하는 것이다. 따라서 아래의 코드에 비해 속도가 빠른것이다.&lt;/p&gt;

&lt;p&gt;위와 같이 정의자체를 반복하도록하면 ‘add’ 노드 자체가 여러개 생겨서 속도가 느려질 것이다. 따라서 코딩을 할 때 연산의 경우 정의와 실행을 구분해서 사용하도록 하자.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Seq2seq (1): Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation</title>
   <link href="https://reniew.github.io/31/"/>
   <updated>2018-08-13T04:47:35+00:00</updated>
   <id>https://reniew.github.io/31</id>
   <content type="html">&lt;p&gt;최근의 기계 번역(Machine) 분야에서 주를 이루고 있는 Neural Machine Translation의 시초를 뽑으라고 하면 Sequence to Sequence 모델을 뽑을 것이다. Google이 발표한 논문인 ‘Sequence to Sequence with Neural Network’를 통해 본격적인 NML분야가 활발해졌다고 볼 수 있다.&lt;/p&gt;

&lt;p&gt;따라서 이번 포스트에서는 sequence to sequence 모델에 대해서 알아 보도록 할 것이다. 앞서 말한 구글의 논문 이전에 최초로 sequence to sequence모델을 도입한 논문인 ‘Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation’(&lt;a href=&quot;https://arxiv.org/abs/1406.1078&quot;&gt;paper&lt;/a&gt;)에 대해 먼저 알아 본 후 다음 포스트를 통해 google의 ‘Sequence to Sequence with Neural Network’(&lt;a href=&quot;https://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf&quot;&gt;paper&lt;/a&gt;)에 대해 알아보도록 한다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/31&quot;&gt;Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/35&quot;&gt;Sequence to Sequence with Neural Network&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;p&gt;Sequence to sequence는 가장 많이 사용되는 기계번역 분야 뿐만 아니라 다양한 분야에서 사용된다. sequence를 사용하는 분야라면 어느 테스크에서든 사용할 수 있다. RNN을 기본으로한 모델인 이 모델은 뉴욕대의 조경현교수님께서 만드신 모델이다. 이 논문을 통해 seqeunce to sequence가 세상에 소개된 것 뿐만 아니라 새로운 RNN 구조인 GRU 또한 소개되어서 세상의 많은 관심을 받은 논문이다.&lt;/p&gt;

&lt;p&gt;처음 sequence to sequence의 개념이 도입된 이 논문에서는 sequence to sequence라는 이름을 쓰지 않고 encoder-decoder로 표현되었다. 이제 논문을 보며 자세히 알아보도록 하자.&lt;/p&gt;

&lt;h3 id=&quot;learning-phrase-representations-using-rnn-encoderdecoder-for-statistical-machine-translation&quot;&gt;Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation&lt;/h3&gt;

&lt;h4 id=&quot;introduction&quot;&gt;Introduction&lt;/h4&gt;

&lt;p&gt;Neural network를 활용해서 Object detection분야와 speech recognition분야에서 많은 성과를 보여줬다. 뿐만 아니라 최근에는 NLP분야에서도 nerual network를 통해 많은 발전을 이뤄왔다. 그리고 기계 번역 분야에서 기존에 활용되던 Statical Machine Translation(SMT)분야에서의 Neural network의 접목을 통해 더 좋은 성능을 보여줬는데 이 논문에서도 SMT의 한 부분으로 Neural network를 사용하는 것을 보여줄 것이다.&lt;/p&gt;

&lt;p&gt;앞으로 보여줄 모델을 RNN Encoder-Decoder라 부른다. 이 모델의 구성은 각각 encoder, decoder 역활을 하는 두개의 RNN으로 구성되어 있는데 encoder는 가변 길이의 sequence를 고정길이의 벡터로 만들고 decoder는 이렇게 seuquence를 vector로 표현한 것을 다시 가변 길이의 sequence로 바꿔준다. 이 두개의 네트워크는 주어진 sequence에 대해서 target sequence의 조건부 확률을 최대화 시키면서 학습된다. 그리고 부가적으로 메모리 사용량과 학습을 쉽게해줄 몇가지 정교한 hidden unit에 대해서도 소개할 것이다.&lt;/p&gt;

&lt;p&gt;모델의 평가는 English-French 번역 결과에 대한 점수를 통해 평가한다. 이제 모델에 대해서 자세히 알아보자.&lt;/p&gt;

&lt;h4 id=&quot;rnn-encoder-decoder&quot;&gt;RNN Encoder-Decoder&lt;/h4&gt;

&lt;p&gt;앞서 말했듯이 &lt;em&gt;encode&lt;/em&gt; 는 가변길이의 sequence를 고정길이의 벡터 representation으로 만드는 것이고 &lt;em&gt;decode&lt;/em&gt; 는 고정길이의 벡터 representation을 다시 가변길이의 sequence로 만드는 것을 뜻한다. 확률적인 관점에서 이 모델은 input 값인 가변길이의 sequence에 대한 decoder에 의해 만들어진 가변길이의 sequence의 조건부 분포를 학습하는 것이다. 즉 아래의 확률 분포를 학습한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(y_1,..,y_{T'}~\vert~x_1,...,x_T)&lt;/script&gt;

&lt;p&gt;여기서 길이를 뜻하는 &lt;script type=&quot;math/tex&quot;&gt;T&lt;/script&gt;와 &lt;script type=&quot;math/tex&quot;&gt;T'&lt;/script&gt;은 다른 길이이다.&lt;/p&gt;

&lt;p&gt;Encoder-Decoder의 그림은 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/Lq8GkLL.jpg&quot; alt=&quot;en-de&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Encoder는 하나의 RNN이며, input sentence &lt;script type=&quot;math/tex&quot;&gt;\mathbf{x}&lt;/script&gt;의 각 symbol을 순서대로 읽는다. 각 symbol을 읽을 때, 이 RNN 구조의 각 hidden state는 각 symbol값은 아래의 수식으로 계산된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\mathbf{h}_{&lt;t&gt;}=f(\mathbf{h}_{&lt;t-1&gt;},x_t) %]]&gt;&lt;/script&gt;

&lt;p&gt;전체 sequence에 대해 모든 symbol을 마지막 까지 다 읽은 후에는, 마지막 hidden state에서 전체 input sequence를 하나의 벡터 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{c}&lt;/script&gt;로 요약한다. 여기까지가 encoder에 대한 설명이다.&lt;/p&gt;

&lt;p&gt;Decoder는 또 하나의 다른 RNN이다. 여기서는 RNN은 주어진 hidden state 값인 &lt;script type=&quot;math/tex&quot;&gt;% &lt;![CDATA[
\mathbf{h}_{&lt;t&gt;} %]]&gt;&lt;/script&gt;를 활용해서 다음 symbol인 &lt;script type=&quot;math/tex&quot;&gt;y_t&lt;/script&gt;를 예측하면서 전체 output sequence를 만들어 내면서 학습된다. 여기서는 위의 encoder에서 사용된 일반적인 RNN수식으로 hidden state값을 계산하는 것이 아니라 이전의 output symbol인 &lt;script type=&quot;math/tex&quot;&gt;y_{t-1}&lt;/script&gt;값도 사용한다. 즉 아래의 수식으로 계산된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\mathbf{h}_{&lt;t&gt;}=f(\mathbf{h}_{&lt;t-1&gt;}, y_{t-1}, \mathbf{c}) %]]&gt;&lt;/script&gt;

&lt;p&gt;따라서 이 수식은 다음 symbol에 대한 조건부 분포로 나타내면 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
p(y_t\vert y_{t-1}, y_{t-2},...,y_1,\mathbf{c})=g(\mathbf{h}_{&lt;t&gt;},y_{t-1},\mathbf{c}) %]]&gt;&lt;/script&gt;

&lt;p&gt;여기서 $f,g$는 활성화 함수이다.(e.g. softmax)&lt;/p&gt;

&lt;p&gt;두 개의 부분으로 구성된 이 &lt;em&gt;RNN Encoder-Decoder&lt;/em&gt; 는 다음의 조건부 log-확률을 최대화하면서 학습된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\max_\theta\frac{1}{N}\sum^N_{n=1}\log p_\theta(\mathbf{y}_n\vert\mathbf{x}_n)&lt;/script&gt;

&lt;p&gt;&lt;script type=&quot;math/tex&quot;&gt;\theta&lt;/script&gt;는 모델의 파라미터를 뜻하고 &lt;script type=&quot;math/tex&quot;&gt;(\mathbf{x}_k, \mathbf{y}_k)&lt;/script&gt;는 학습 데이터의 input sequence, output sequence 쌍이다.&lt;/p&gt;

&lt;p&gt;학습의 경우는 gradient-based 알고리즘을 사용해서 모델의 파라미터를 학습시켰다.&lt;/p&gt;

&lt;p&gt;일단, RNN Encoder-Decoder가 학습되면 모델은 두개의 용도로 사용된다. 하나는 주어진 input sequence에 대해서 target sequence를 만드는 용도로 사용되었고, 또 다른 하나의 용도는 주어진 두개의 sequence 쌍(input sequence, output sequence)에 대해서 위에 주어진 확률 값을 사용해서 점수를 매기는 용도로 사용되었다.&lt;/p&gt;

&lt;h4 id=&quot;hidden-unit-that-adaptively-remembers-and-forgets&quot;&gt;Hidden Unit that Adaptively Remembers and Forgets&lt;/h4&gt;

&lt;p&gt;위의 모델 architecture 뿐만 아니라 이 구조를 위해 새로운 형태의 hidden unit을 사용했다. 먼저 general한 RNN 수식을 보자.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\mathbf{h}_{&lt;t&gt;}=f(\mathbf{h}_{&lt;t-1&gt;},x_t) %]]&gt;&lt;/script&gt;

&lt;p&gt;여기서 함수 $f$는 단순히 일반적인 activation 함수를 뜻할 수도 있고 LSTM의 수식으로 activate되는 것을 뜻할 수도 있다. 새로운 형태의 hidden unit이란 새롭게 정의한 이 함수를 뜻하는데 LSTM을 motive로 해서 만들어 졌으나, 훨신 계산이 쉽고 구현이 쉬운형태이다.&lt;/p&gt;

&lt;p&gt;새롭게 정의한 hidden unit을 그림으로 표현하면 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/X7RnoXc.jpg&quot; alt=&quot;hidden_unit&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이제 이 hidden unit에서 어떻게 activate되는지 알아보자. 먼저 reset gate인 &lt;script type=&quot;math/tex&quot;&gt;r_j&lt;/script&gt;는 다음과 같이 계산된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
r_j=\sigma\big([\mathbf{W}_r\mathbf{x}]_j+[\mathbf{U}_r\mathbf{h}_{&lt;t-1&gt;}]_j \big), %]]&gt;&lt;/script&gt;

&lt;p&gt;여기서 &lt;script type=&quot;math/tex&quot;&gt;\sigma&lt;/script&gt;는 logistic sigmoid 함수이고 &lt;script type=&quot;math/tex&quot;&gt;[.]_j&lt;/script&gt;는 벡터의 &lt;script type=&quot;math/tex&quot;&gt;j&lt;/script&gt;번째 원소를 뜻한다. 그리고 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{x}&lt;/script&gt; 와 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{h}_{t-1}&lt;/script&gt;은 각각 input과 이전 hidden state를 뜻한다. 마지막으로 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{W}_r&lt;/script&gt;과 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{U}_r&lt;/script&gt;은 학습해야 할 weight matrix이다.&lt;/p&gt;

&lt;p&gt;그리고 또 하나의 gate인 update gate &lt;script type=&quot;math/tex&quot;&gt;z_j&lt;/script&gt;는 다음과 같이 계산된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
z_j=\sigma\big([\mathbf{W}_z\mathbf{x}]_j+[\mathbf{U}_z\mathbf{h}_{&lt;t-1&gt;}]_j \big), %]]&gt;&lt;/script&gt;

&lt;p&gt;이제 두 gate의 값을 사용해서 hidden unit 값을 계산한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{matrix}
h_j^{&lt;t&gt;}=z_jh_j^{&lt;t-1&gt;}+(1-z_j)\tilde{h}_j^{&lt;t&gt;}\\ \\
\tilde{h}_j^{&lt;t&gt;}=\phi\big([\mathbf{W}\mathbf{x}]_j+[\mathbf{U}(\mathbf{r}\odot\mathbf{h}_{&lt;t-1&gt;})]_ j \big)
\end{matrix} %]]&gt;&lt;/script&gt;

&lt;p&gt;이 공식에 따르면 reset gate가 0에 가까워지면 hidden state는 이전 hidden state값을 무시하게 된다. 그리고 현재 input값으로만 reset되게 된다. 따라서 효과적으로 hidden state의 다음 앞으로의 state와 관계가 없는 정보는 제거(drop)할 수 있게 되기 때문에 더욱 압축적인 정보를 갖게 된다.&lt;/p&gt;

&lt;p&gt;반면에 update gate는 얼마나 많은 정보를 이전 hidden state로 부터 가지고 올것인지를 결정하는데, 이것은 실제로 LSTM의 memory cell과 유사하게 동작한다. 따라서 오래된 정보를 RNN에게 전달할 수 있게 된다. 또한 adaptive variant of leaky-integration unit을 고려한다.&lt;/p&gt;

&lt;p&gt;각 hidden unit은 개별의 reset과 update gate를 가지는데, 각 hidden unit은 다른 시간 scale에 대한 의존성을 통해 학습한다.(특성에 따라 long-term의 값을 사용하거나, short-term의 값을 사용한다)&lt;/p&gt;

&lt;h4 id=&quot;statistical-machine-translation&quot;&gt;Statistical Machine Translation&lt;/h4&gt;

&lt;p&gt;기존의 흔히 사용되던 statistical machine translation 시스템의 목표는 주어진 문장 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{e}&lt;/script&gt;에 대해translation function인 &lt;script type=&quot;math/tex&quot;&gt;f&lt;/script&gt;를 찾는 것이다. 즉 아래의 식을 최대화 하기 위한 것이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(\mathbf{f}\vert\mathbf{e})\propto p(\mathbf{e}\vert\mathbf{f})p(\mathbf{f})&lt;/script&gt;

&lt;p&gt;하지만 실제로는 대부분의 SMT 시스템은 아래의 log식을 모델링한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\log p(\mathbf{f}\vert\mathbf{e})=\sum^N_{n=1}w_n f_n(\mathbf{f},\mathbf{e})+\log Z(\mathbf{e})&lt;/script&gt;

&lt;p&gt;여기서 &lt;script type=&quot;math/tex&quot;&gt;f_n&lt;/script&gt;과 &lt;script type=&quot;math/tex&quot;&gt;w_n&lt;/script&gt;은 각각 n번째 feature와 weight이다. 그리고 &lt;script type=&quot;math/tex&quot;&gt;Z(\mathbf{e})&lt;/script&gt;는 일반화 상수이다. 경우에 따라 여기서의 weight는 BLEU(bilingual evalutation understudy)값을 최대화 하기 위해 학습된다.&lt;/p&gt;

&lt;p&gt;phrase 기반의 SMT는 어절 단위의 통계적 기계 번역으로 각 어절에 대해서 그에 대응하는 문장에 대한 확률로 나눠서 계산한다.&lt;/p&gt;

&lt;h4 id=&quot;experiments&quot;&gt;Experiments&lt;/h4&gt;

&lt;p&gt;실험은 WMT’14의 English/French 번역 task를 통해 진행되었다. 이 bilingual한 말뭉치는 Europarl(61M words), news commentary(5.5M words), UN(421M words)과 90M, 780M개의 crawled한 copora를 포함한다.&lt;/p&gt;

&lt;p&gt;그리고 French language model을 학습하기 위대 대략 712M 개의 단어를 학습했다.&lt;/p&gt;

&lt;p&gt;일반적으로 statistical한 모델을 학습시킬 때 여러 데이터들을 concat하는 것이 항상 최적의 성능을 보장하지 않을 뿐더러 큰 모델일수록 다루기 어렵기 떄문에 여기서는 data selection 방법(Moore and Lewis,2010)을 적용했다. 이러한 방법을 사용해서 Language modeling을 위해  418M개의 단어를 뽑았으며, 학습을 위해 348M개의 단어를 뽑았다.&lt;/p&gt;

&lt;p&gt;데이터 셀렉션과 weight tuning을 위해 nestest2012 와 2013 사용했고 테스트를 위해서 nestest 22014를 사용했다. 각각의 set은 7만개 이상의 단어로 구성되어있다.&lt;/p&gt;

&lt;p&gt;RNN Encoder-Decoder를 포함하는 이 네트워크를 학습하기 위해 source, target vocabulary의 크기를 각각 가장 많이 나오는 English, French 둘다 15,000개의 단어만 포함하도록 제한했다. 이 15,000개의 단어는 전체 단어의 93%에 달한다. 그리고 모든 out-of-vocabulary 단어는 ([UNK]) 토큰으로 바꾸었다.&lt;/p&gt;

&lt;p&gt;실험 결과에 대해 baseline phrase-based SMT 시스템은 기본값의 Moses를 사용해서 만들었다. 이 시스템의 BLEU 스코어느 30.64, 33.3이다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RNN Encoder-Decoder in experiment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;실험에 사용된 RNN Encoder-Decoder의 구조는 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;1000 hidden unit(GRU 사용)&lt;/li&gt;
  &lt;li&gt;input symbol에서 hidden unit으로 갈 떄 사용되는 input matrix는 2 lower-rank approxiamtion한 matrix 사용, output matrix로 같은 방식 사용&lt;/li&gt;
  &lt;li&gt;rank 100 Matrix 사용&lt;/li&gt;
  &lt;li&gt;hidden unit 계산 시 &lt;script type=&quot;math/tex&quot;&gt;\tilde{h}&lt;/script&gt; 계산할 때 활성화 함수로 tanh사용&lt;/li&gt;
  &lt;li&gt;Decoder에서 hidden state 값으로 output 계산과정에서는 deep neural network 구조 사용(single intermediate layer, 500 maxout units,pooling 2 input)&lt;/li&gt;
  &lt;li&gt;모든 파라미터는 (0, 0.01)의 가우시안 분포로 초기화&lt;/li&gt;
  &lt;li&gt;파라미터 업데이트에는 SGD, Adadelta 사용(hyperparameter는 &lt;script type=&quot;math/tex&quot;&gt;\epsilon=10^{-6}, \rho=0.95&lt;/script&gt;사용)&lt;/li&gt;
  &lt;li&gt;매 업데이트 마다 64개의 임의 추출된 phrase pair사용&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;실험에서는 target language를 학습하기 위한 전통적인 neural network 인 CSLM도 추가해서 실험했다. 그리고 추가적으로 word penalty 방식도 추가했다. 따라서 실험을 위한 모든 조합은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Baseline&lt;/li&gt;
  &lt;li&gt;Baseline + RNN&lt;/li&gt;
  &lt;li&gt;Baseline + CSLM + RNN&lt;/li&gt;
  &lt;li&gt;Baseline + CSLM + RNN + Word Penalty&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;실험에 대한 결과는 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/N4rOQuB.jpg&quot; alt=&quot;table&quot; /&gt;&lt;/p&gt;

&lt;p&gt;결과를 보면 우선 encoder-decoder방식을 사용하면서 성능이 올라갔으며, CSLM과 같이 사용할 때 더 성능이 올라갔다. 하지만 Word penalty를 적용시켰을 때 test에서 성능이 약간 떨어졌다.&lt;/p&gt;

&lt;p&gt;그리고 BLEU 스코어 뿐만 아니라 Qulitative한 분석을 통해서 이 모델이 의미적, 그리고 문법적으로도 잘 분석한다는 것을 확인 할 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/i60LpP7.jpg&quot; alt=&quot;quali&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;긴글 읽어주셔서 감사합니다. 오역 및 잘못된 내용이 있을 수 있습니다. 잘못된 부분 혹은 이해가 잘 안되는 부분은 댓글 혹은 메일로 말씀해주시면 감사하겠습니다!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Chapter 2: Function Approximation as Supervised Learning</title>
   <link href="https://reniew.github.io/30/"/>
   <updated>2018-08-10T04:47:35+00:00</updated>
   <id>https://reniew.github.io/30</id>
   <content type="html">&lt;h3 id=&quot;chapter-2&quot;&gt;Chapter 2&lt;/h3&gt;

&lt;h3 id=&quot;function-approximation-as-supervised-learning&quot;&gt;Function Approximation as Supervised Learning&lt;/h3&gt;

&lt;p&gt;이 내용은 Newyork University의 조경현교수님의 DS-GA 3001강의 lecture note중 Neural Laguage Models단원을 정리한 내용입니다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;이번 챕터에서는 인공 신경망을 통해 Natural Language를 함수로 근사시킬 것이다. 이러한 과정은 기본적인 신경망을 공부하는데 도움이 될 것이며, 다음 챕터부터의 공부에 용이하게 할 것이다.&lt;/p&gt;

&lt;h3 id=&quot;21-function-approximation-parametrix-approache&quot;&gt;2.1 Function Approximation: Parametrix Approache&lt;/h3&gt;

&lt;h4 id=&quot;211-expected-cost-function&quot;&gt;2.1.1 Expected Cost Function&lt;/h4&gt;

&lt;p&gt;가장 먼저 데이터 분포를 &lt;script type=&quot;math/tex&quot;&gt;p_{\text{data}}&lt;/script&gt;로 정의한다. 각 데이터는 input 벡터인 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{x}\in\mathbb{I}^d&lt;/script&gt;와 output 벡터인 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{y}\in\mathbb{O}^d&lt;/script&gt;로 정의한다. &lt;script type=&quot;math/tex&quot;&gt;\mathbb{I,O}&lt;/script&gt;는 input과 output으로 가능한 실수 값의 집합이다.&lt;/p&gt;

&lt;p&gt;이제 우리의 목표는 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{x}&lt;/script&gt; 와 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{y}&lt;/script&gt; 사이의 관계를 찾는 것이다. 정확히는 두 집합사이의 함수 &lt;script type=&quot;math/tex&quot;&gt;f:\mathbb{R}^d\rightarrow\mathbb{O}^k&lt;/script&gt;를 찾는 것이다. 최대한 정확한 &lt;script type=&quot;math/tex&quot;&gt;f&lt;/script&gt;를 찾기 위해 함수를 parametric function을 고려한다. 여기서 파라미터는 &lt;script type=&quot;math/tex&quot;&gt;\theta&lt;/script&gt;라 칭한다.&lt;/p&gt;

&lt;p&gt;이제 우리가 근사한 함수가 얼마나 정확히 input에서 output으로 가기위해 확인하기 위해 우리가 예측한 값에 대해 정의한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\hat{\mathbf{y}}=f_{\theta}(\mathbf{x})&lt;/script&gt;

&lt;p&gt;이제 우리가 정의한 함수의 정확도는 위의 값과 output과의 차이(&lt;script type=&quot;math/tex&quot;&gt;D(\hat{\mathbf{y}},\mathbf{y})&lt;/script&gt;)를 비교하면 될것이다. 그리고 최종적으로 해야 할 것은 이 차이를 최소화하는 파라미터 &lt;script type=&quot;math/tex&quot;&gt;\theta&lt;/script&gt;를 찾으면 된다. 하지만 input과 output은 여러 쌍이 존재하는데 정확히 이 모든 쌍에 대해서 이 차이를 최소화하는 파라미터는 존재하기 어렵다. 따라서 전체 쌍에 대해서 차이의 총합을 최소화 하는 방향으로 가야한다. 이를 수식으로 표현하면 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\arg\min_{\theta}\int_{\mathbf{x}}\int_{\mathbf{y}}p_{\text{data}}(\mathbf{x},\mathbf{y})D(\hat{\mathbf{y}},\mathbf{y})d\mathbf{x}d\mathbf{y}&lt;/script&gt;

&lt;p&gt;만약 각 데이터들이 discrete하다면 적분 대신 &lt;script type=&quot;math/tex&quot;&gt;\sum&lt;/script&gt;을 이용하면 된다. 이제 우리는 최소화 해야 하는 이 값을 Cost Function이라 부를 것이다. 그리고 이 값을 계산하는 것은 distance의 평균(기대값)을 계산하는 것과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
C(\theta)&amp;=\int_{\mathbf{x}}\int_{\mathbf{y}}p_{\text{data}}(\mathbf{x},\mathbf{y})D(\hat{\mathbf{y}},\mathbf{y})d\mathbf{x}d\mathbf{y}
&amp;=\mathbb{E}_{\mathbf{x},\mathbf{y}\~p_{\text{data}}}[D(\hat{\mathbf{y}},\mathbf{y})]
\end{align*} %]]&gt;&lt;/script&gt;

&lt;p&gt;이 값을 cost 말고 또 loss 혹은 risk 라고도 부른다.&lt;/p&gt;

&lt;p&gt;아쉽게도 이 값을 정확하게 계산하는 것은 불가능하다. 애초에 data의 정확한 distribution을 알지 못하고 안다고 해도 정확히 cost를 계산하는 것은 과한 가정을 필요로한다.&lt;/p&gt;

&lt;h4 id=&quot;212-empirical-cost-function&quot;&gt;2.1.2 Empirical Cost Function&lt;/h4&gt;

&lt;p&gt;우리가 정확한 data의 분포를 모른다고 하더라도 일정 크기의 data는 우리에게 주어진다. 따라서 sampleling의 가정을 통해 정확한 cost를 근사하는 값을 구할 수 있다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;C(\theta)\approx\tilde{C}(\theta)=\frac{1}{N}\sum^N_{n=1}D(\hat{\mathbf{y}^n},\mathbf{y}^n)&lt;/script&gt;

&lt;p&gt;이 값을 empirical cost function이라 부른다. 이 값은 계산이 쉽기 때문에 이 값을 사용할 것이다. 하지만 후에 우리의 최종 목표는 정확한 expected Cost를 계산하는 것이다.&lt;/p&gt;

&lt;h3 id=&quot;22-learning-as-optimization&quot;&gt;2.2 Learning as Optimization&lt;/h3&gt;

&lt;p&gt;앞서 설명한 Cost값을 가장 최소로하는 파라미터들을 찾아가는 과정을 &lt;em&gt;학습한다&lt;/em&gt; 라고 표현한다. 기계에서 학습 데이터를 통해 최적의 함수를 찾도록 하는 것이다. 그리고 이 학습하는 과정을 최적화(optimization)이라고도 한다.&lt;/p&gt;

&lt;h4 id=&quot;221-gradient-based-local-iterative-optimization&quot;&gt;2.2.1 Gradient-based Local Iterative Optimization&lt;/h4&gt;

&lt;p&gt;최적화 알고리즘은 다양하다. 때로는 closed한 형태의 최적화 파라미터를 찾을 수 있지만 보통의 경우에는 반복적으로 최적화 알고리즘을 수행하면서 최적의 파라미터 값을 찾아가야 한다.&lt;/p&gt;

&lt;p&gt;여기서 말하는 반복적 최적화 알고리즘이란 조금씩 파라미터들을 수정하면서 최적의 Cost function, 즉 cost function의 최소값으로 수렴하는 것을 의미한다. 대부분의 파라미터 공간은 지역적이라 전체 공간을 측정할 필요가 없다.&lt;/p&gt;

&lt;p&gt;가장 간단한 지역적 반복 최적화 알고리즘 중 하나는 경사하강법(Gradient Discent, GD) 알고리즘이다. 이름에서 나와있듯이 이 알고리즘은 Cost 함수의 미분값(gradient)에 의해 수행된다.&lt;/p&gt;

&lt;p&gt;Cost 함수의 미분값인 &lt;script type=&quot;math/tex&quot;&gt;\nabla\tilde{C}&lt;/script&gt; 는 현재 파라미터 값에 대해서 값을 올리는 방향에 대한 벡터값을 갖는다. 따라서 이 벡터값의 반대방향으로 파라미터를 이동시키면 Cost함수가 적어지는 방향으로 이동한다. 아래 그림은 이러한 과정을 나타낸다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/lOFnCBF.jpg&quot; alt=&quot;GD&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이 알고리즘에서 중요한 점은 우리가 찾은 방향에 대해서 얼마나 움직일 것인가 이다. 만약 너무 많이 움직인 다면 우리가 가야하는 최적의 값을 지나칠 수 있고 너무 조금 움직인다면 최적의 값으로 가기까지가 너무 오래걸린다. 여기서 말한 얼마나 움직일것인가를 나타내는 값은 &lt;script type=&quot;math/tex&quot;&gt;\eta&lt;/script&gt;로 쓰고 학습률(learning rate)라 표현한다. 이 값은 우리가 정해줘야하는 파라미터 값이므로 GD 알고리즘의 hyperparameter이다.&lt;/p&gt;

&lt;p&gt;학습률을 고려한 정확한 경사하강법 알고리즘에서 파라미터를 재정의(update)하는 방법을 정의하면 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\theta \leftarrow \theta-\eta\nabla\tilde{C}(\theta)&lt;/script&gt;

&lt;p&gt;위의 update는 우리가 정의한 횟수만큼 반복된 후에 그만한다.&lt;/p&gt;

&lt;h4 id=&quot;222-stochastic-gradient-descent&quot;&gt;2.2.2 Stochastic Gradient Descent&lt;/h4&gt;

&lt;p&gt;GD알고리즘은 간단하지만 매우 잘 동작한다. 그리고 이 알고리즘은 앞으로 나올 좀 더 향상된 알고리즘들의 기본 개념이 된다. 좀더 향상된 방법들을 배우기 이전에 GD알고리즘에 대해서 좀더 논의해본다. GD알고리즘에는 약간의 문제점이 있다. 바로 &lt;script type=&quot;math/tex&quot;&gt;\tilde{C}&lt;/script&gt;을 계산하는 것이 매우 많은 연산을 필요로 한다는 것이다. 데티어가 많아질 수록 연산은 더욱 많아지는데, 그 이유는 앞서 본것처럼 Cost를 계산할 때 우리는 모든 data에 대해서 Cost를 계산한 뒤 모든 값들을 평균한 값을 최종 Cost로 사용한다. 따라서 모든 많은 데이터에 대해서 Cost를 모두 계산해야 하는데 이러한 과정을 반복하기에는 연산량이 매우 많다.&lt;/p&gt;

&lt;p&gt;이러한 연산량이 많다는 문제점을 해결하기 위한 알고리즘이 Stochastic gradient descent(SGD)이다.&lt;/p&gt;

&lt;p&gt;알고리즘을 설명하기에 앞서 설명한 Cost 함수를 정의를 다시 살펴보자.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;C(\theta)\approx\tilde{C}(\theta)=\frac{1}{N}\sum^N_{n=1}D(\hat{\mathbf{y}^n},\mathbf{y}^n)&lt;/script&gt;

&lt;p&gt;위 식을 보면 Cost 함수의 sum이 모든 데이터인 $N$에 대해서 계산된다. SGD 알고리즘에서는 이 값을 모두 계산하는 것이 아니라 $\mu&amp;lt;N$인 $\mu$개의 데이터에 대해서만 Cost를 계산해 평균한다. 따라서 아래의 식으로 다시 정의된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;C(\theta)\approx\tilde{C}_{\mu}(\theta)=\frac{1}{\mu}\sum^\mu_{n=1}D(\hat{\mathbf{y}^n},\mathbf{y}^n)&lt;/script&gt;

&lt;p&gt;따라서 전체 데이터에 대해서 계산하는 일반적인 Cost와는 달리 적은 수에 대해서 Cost를 계산하므로 계산량이 매우 줄어들 것이다. 그리고 계산한 cost에 대해서 앞서 말한 파라미터 업데이트 방법으로 업데이트 하면된다.&lt;/p&gt;

&lt;p&gt;여기서 $\mu$는 사용자가 직접 지정하면 되고, 극단적으로 1로 지정해도 된다. 놀랍게도 이미 1951년에 이 방법이 최적값에 수렴한다는 것이 증명 되었다.&lt;/p&gt;

&lt;h3 id=&quot;23-when-do-we-stop-learning&quot;&gt;2.3 When do we stop learning?&lt;/h3&gt;

&lt;p&gt;이제부터는 우리는 SGD방법을 통해 최적의 함수 &lt;script type=&quot;math/tex&quot;&gt;f&lt;/script&gt;를 찾아간다고 하자. 즉 데이터를 조금씩 적용시키면서 학습한다. 이때까지 학습하는 과정에서의 몇 가지 문제점들에 대해서 살펴봤다. 또 하나의 중요한 문제점이 있는데, 우리는 expectec cost function 함수를 사용할 수 없다는 점이다. 그 대신 우리는 empirical cost 함수를 사용한다고 해서 expected cost 함수에 근사시킨다고 했었다. 그런데 왜 이러한 점이 문제점일까? 왜냐하면 우리는 우리가 찾은 empirical cost함수의 minimum값이 expected cost function의 minimum값인지 알 수 없다. 아래의 그림을 보면 두 함수의 최소값이 다른 예를 볼 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/V7fywvZ.jpg&quot; alt=&quot;mini&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;231-early-stopping&quot;&gt;2.3.1 Early Stopping&lt;/h4&gt;

&lt;p&gt;그렇다면 우리는 어떻게 해야 하는가? 이러한 문제는 여러가지 방법이 있다. 그 중 하나인 반복적 최적화 방법에서 사용되는 early stopping에 대해서 소개한다.&lt;/p&gt;

&lt;p&gt;early stopping을 사용하기위해 우선 데이터를 &lt;script type=&quot;math/tex&quot;&gt;D_{\text{train}}&lt;/script&gt;과 &lt;script type=&quot;math/tex&quot;&gt;D_{\text{validate}}&lt;/script&gt; 두 부분으로 나눈다. 이 두개의 부분 데이터셋을 학습 데이터(training set), 검증 데이터(validation set)이라 부른다. 이제 학습 cost를 다음과 같이 정의한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\tilde{C}(\theta)=C_{\text{train}}(\theta)=\frac{1}{\vert D_{\text{train}}\vert}\sum_{(x,y)\in D_{\text{train}}}D(\hat{y},y)&lt;/script&gt;

&lt;p&gt;그리고 검증 cost는 다음과 같이 정의한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\tilde{C}(\theta)=C_{\text{val}}(\theta)=\frac{1}{\vert D_{\text{val}}\vert}\sum_{(x,y)\in D_{\text{val}}}D(\hat{y},y)&lt;/script&gt;

&lt;p&gt;이렇게 두개의 cost 함수를 정의하면 early stopping을 사용할 준비가 끝났다.&lt;/p&gt;

&lt;p&gt;학습 Cost로 SGD를 사용해서 parameter를 업데이트 할 때마다 검증 Cost를 계산한다. 이러한 과정을 계속 반복하다가 검증 Cost가 줄어들지 않을 때 그 때 반복을 멈춘다.&lt;/p&gt;

&lt;p&gt;매우 간단한 방법임에도 불구하고 early stopping 은 매우 효율적이다. 이 방법은 사실상 deep learning과 machine learning 분야에서 표준이 되었다.&lt;/p&gt;

&lt;p&gt;이러한 방법, 즉 학습과 검증을 구분한 것의 의미는 학습 데이터에 섞인 노이즈에 의한 학습이 제대로 되지 않는 것을 줄이는 것이다.&lt;/p&gt;

&lt;h4 id=&quot;232-model-selection&quot;&gt;2.3.2 Model Selection&lt;/h4&gt;

&lt;p&gt;검증 데이터를 early stopping에서 활용하는 것에 대해서 알아봤다. ealry stopping 뿐만 아니라 Model Selection 에서도 검증 데이터를 활용한다. 그렇다면 Model selection이 무었인지 알아보도록하자.&lt;/p&gt;

&lt;p&gt;전체 최적화, 학습 과정은 전체 hypothesis(가정) space에서 최적의 hypothesis을 찾아가는 과정으로 표현할 수 있다. 여기서 말하는 hypothesis가 의미하는 것은 특정한 파라미터와 특정한 형태를 가지는 함수이다. 회귀(regression)의 경우에 hypothesis space에는 n차 다항식 함수가 포함될 것이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;f(x)=\sum_{\sum^d_{k=1}i_k=n,i_k\ge0}a_{i_1,i_2,...,i_k}\prod^d_{k'=1}x_{k'}^{i_k}&lt;/script&gt;

&lt;p&gt;신경망의 경우에는 이러한 hypothesis space는 모든 가능한 모델을 포함할 것이다. 그리고 각각의 hypothesis는 레이어의 수, 비선형성의 종류, hidden unit의 개수에서 특정 값을 가질 것이다.&lt;/p&gt;

&lt;p&gt;우리가 특정 hypothesis(&lt;script type=&quot;math/tex&quot;&gt;M\in H&lt;/script&gt;)를 사용한다고 하자. 우리는 각각의 hypothesis에 대해서 각각의 Cost를 점수로 줄 수 있다. 그러면 이제 우리의 최종 목표는 전체적으로 최저의 cost값을 갖는 hypothesis를 선택하는 것이다.&lt;/p&gt;

&lt;p&gt;이때까지의 최적화 방법은 반복적으로 empirical cost를 계산하는 것이다. 그러나 이러한 방법은 모델이 overfitting 될 수 있다는 문제점이 있다. 따라서 앞서서 early stopping이라는 기법을 소개했었다.&lt;/p&gt;

&lt;p&gt;하지만 이러한 방법으로도 최적의 hypothesis를 찾는 것에는 충분하지는 않다. 우리가 최적이라고 생각하는 hypothesis가 최적이 아닐 수도 있다는 문제점이 항상 존재한다.&lt;/p&gt;

&lt;p&gt;이러한 문제의 해결책은 간단하다. 하나 이상의 hypothesis를 고려하는 것이다. 예를들어 회귀문제에 대해서 우리는 linear 함수, quadratic 함수, sinusoidal 함수 모두를 hypothesis로 고려할 수 있다. 이제 마지막 남은 질문은 어떻게 이 hypothesis들을 비교하고 선택해야 하는가 이다.&lt;/p&gt;

&lt;p&gt;early sotpping에서 했던 것과 비슷하게 우리는 검증 cost를 이용해 hypothesis들을 비교한다. 우리가 고려한 hypothesis들 중에서 가장 적은 검증 cost 값을 가지는 hypothesis를 선택하면 된다.&lt;/p&gt;

&lt;h3 id=&quot;24-evaluation&quot;&gt;2.4 Evaluation&lt;/h3&gt;

&lt;p&gt;우리는 검증 cost를 통해서 최적화를 early stop했다. 이렇게 찾은 값이 최적화를 위한 값임에는 틀림없지만 실제 세계의 데이터 분포에도 완벽히 최적화된 값이라고 하기에는 어려움이 있다. 일단 최적화가 완료되어도 아직 우리는 더많은 검증을 위한 자료들이 필요하다.&lt;/p&gt;

&lt;p&gt;따라서 우리는 데이터를 앞전처럼 두 개로 나누는 것이 아니라 이번에는 세 개로 나눈다. 학습 데이터인 &lt;script type=&quot;math/tex&quot;&gt;D_{\text{train}}&lt;/script&gt;, 검증 데이터 &lt;script type=&quot;math/tex&quot;&gt;D_{\text{validation}}&lt;/script&gt;, 그리고 시험(test) 데이터
&lt;script type=&quot;math/tex&quot;&gt;D_{\text{test}}&lt;/script&gt;. 결과적으로 우리는 학습, 검증, 시험의 총 3개의 cost를 가진다. 여기서 추가로 나눈 시험(test) 데이터는 학습, 검증 데이터를 모두 사용해 최적이라고 선택한 모델에 대해서 시험한다. 테스트 데이터에 대해서 가장 중요한 말이 하나있다. “must never look at a test set”, 즉 test 데이터는 최종적으로 test하기 이전에는 절대 건들면 안된다는 뜻이다.&lt;/p&gt;

&lt;h3 id=&quot;25-linear-regression-for-non-linear-functions&quot;&gt;2.5 Linear Regression for Non-Linear Functions&lt;/h3&gt;

&lt;p&gt;간단한 linear 함수를 생각해보자.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\hat{\mathbf{y}}=f(\mathbf{x})=\mathbf{W}^T\mathbf{x}&lt;/script&gt;

&lt;p&gt;여기서 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{W}\in\mathbf{R}^{d\times l}&lt;/script&gt;는 weight matrix로 이 함수의 파라미터가 된다.&lt;/p&gt;

&lt;p&gt;이 때 empirical cost 함수는 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\tilde{C}(\theta)=\frac{1}{N}\sum^N_{n=1}\frac{1}{2}\Vert\mathbf{y}^n-\mathbf{W}^T\mathbf{x}^n\Vert^2_2&lt;/script&gt;

&lt;p&gt;그리고 이 empirical cost함수의 gradient는 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\nabla\tilde{C}(\theta)=-\frac{1}{N}\sum^N_{n=1}(\mathbf{y}^n-\mathbf{W}^T\mathbf{x}^n)^T\mathbf{x}^n&lt;/script&gt;

&lt;p&gt;위 함수들을 통해 우리는 SGD, GD와 반복적 최적화 알고리즘을 적용시킬 수 있다. 이 알고리즘을 통해 최적의 파라미터 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{W}&lt;/script&gt;를 찾을 수 있고 또 검증 데이터를 사용해서 early stopping을 사용한다면 더 최적화된 파리미터를 찾을 수 있다.
하지만 이런 linear 함수는 우리가 만족기에는 부족하다.&lt;/p&gt;

&lt;h4 id=&quot;251-feature-extraction&quot;&gt;2.5.1 Feature Extraction&lt;/h4&gt;

&lt;p&gt;왜 우리는 만족하지 못할까?&lt;/p&gt;

&lt;p&gt;첫 째로, 일단 모든 데이터에 맞는 함수가 linear라고 확신 할 수 없다. 만약 맞다고 하더라도 정확하게 linaer regression을 하는 것도 쉽지 않다.&lt;/p&gt;

&lt;p&gt;두 번째 이유는 주어진 데이터 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{x}&lt;/script&gt;에 대해서 어떻게 이 값을 input으로 표현하는지에 대해서 확실한 방법이 없다는 것이다. 예를 들어 5년 전에 판매를 시작한 에어컨의 예상 판매 대수를 예측하는 문제를 생각해보자. 이 때 input을 판매를 시작한 때부터의 기간이라고 가정하고 output을 하루당 판매 대수라고 생각하자.&lt;/p&gt;

&lt;p&gt;명백하게 우선 input과 output은 선형관계가 아닐 것이다. 계절에 따라 판매량을 등락을 반복할 것이고 따라서 단순히 직선으로는 표현할 수 없다. 그러나 만약에 input을 위와 같이 판매를 시작한 때부터의 기간이 아니라 6월을 기준으로 몇월 차이가 나는지로 한다고 하자. 예를 들면 8월이면 input은 2가 되고 3월이면 input은 3이 된다. 이러한 경우에는 직관적으로도 input과 output은 선형을 만족할 것이라는 것을 알 수 있다.&lt;/p&gt;

&lt;p&gt;즉 여기서 말하는 바는 input 값을 어떻게 표현하냐가 매우 중요하게 작용할 수 있다는 것이다. 이러한 input을 표현하는 과정을 Feature Extraction(특징 추출)이라고 표현한다.&lt;/p&gt;

&lt;p&gt;이러한 특징 추출은 우리가 해결할 문제의 영역에 대한 깊은 이해를 필요로한다.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>NLP를 위한 CNN (5): Character-level Convolutional Network for Text Classification</title>
   <link href="https://reniew.github.io/29/"/>
   <updated>2018-08-09T04:47:35+00:00</updated>
   <id>https://reniew.github.io/29</id>
   <content type="html">&lt;p&gt;NLP에서 활용되는 Convolutional Network에 대해서 논문 하나씩 알아보도록 한다. 전체 List는 다음과 같다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/25/&quot;&gt;Understanding CNN for NLP&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/26/&quot;&gt;Convolutional Neural Network for Sentence Classification, 2014&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/27/&quot;&gt;A Convolutional Neural Network for Modelling Sentences, 2014&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/28/&quot;&gt;A Sensitivity Analysis of Convolutional Neural Networks for Sentence Classification&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/29/&quot;&gt;Character-level Convolutional Networks for Text Classification&lt;/a&gt; [현재글]&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;character-level-convolutional-network-for-text-classification&quot;&gt;Character-level Convolutional Network for Text Classification&lt;/h3&gt;

&lt;p&gt;다섯 번째로 소개할 NLP를 위해 CNN을 활용한 모델은 Xiang Zhang, Junbo Zhao, Yann LeCun의 &lt;a href=&quot;https://arxiv.org/pdf/1509.01626.pdf&quot;&gt;Character-level Convolutional Network for Text Classification&lt;/a&gt;이다.&lt;/p&gt;

&lt;p&gt;이때까지의 Convolutional neural network를 활용한 모델들은 input값의 최소단위를 단어(embedded word vector)였다. 하지만 이번 논문에서는 character(글자)단위의 convolutional neural network를 사용해서 문서 분류 문제를 해결하려 한다. 문서 분류문제에서 주류를 이뤘던 모델들은 보통 word2vec으로 임베딩된 단어 벡터들 그리고 TFIDF 정보 혹은 n-gram 정보들을 취합한 Bag of Word 모델들이 주를 이뤘다. 해당 논문에서는 단어보다 좀더 raw한 정보인 글자에 주목한다. 좀 더 근본적인 언어 구조의 특징을 뽑아내려는 시도이다. Charater단위를 ConvNet에 적용시킨 최초의 논문인 만큼 어떤 내용을 담고 있는지 살펴보도록 하자.&lt;/p&gt;

&lt;h4 id=&quot;introduction&quot;&gt;Introduction&lt;/h4&gt;

&lt;p&gt;만약 매우 큰 데이터셋으로 학습한다면 ConvNet은 단어에 대한 정보를(통사론, 의미론적이 정보를 포함한) 필요로 하지 않는다. 그리고 이렇게 character 단위로 만들어진 모델은 조금의 수정으로도 여러 언어에 적용 될 수 있고, 오타 혹은 이모티콘 또한 일반적인 단어와 마찬가지로 잘 학습될 수 있다는 장점이 있다.&lt;/p&gt;

&lt;h4 id=&quot;character-level-conovolutional-networks&quot;&gt;Character-level Conovolutional Networks&lt;/h4&gt;

&lt;p&gt;해당 단원에서는 character-level ConvNet의 design에 대해서 소개한다. 해당 모델은 모듈식으로 구성되어 있다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key-Module&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;가장 핵심적인 부분은 temporal convolutional 모듈이다. 이 모듈은 1-D Convolutional 을 계산한다. discrete한 input 함수를 &lt;script type=&quot;math/tex&quot;&gt;g(x)\in[1,l]\rightarrow\mathbb{R}&lt;/script&gt;라 하고 discrete한 kenel 함수를 &lt;script type=&quot;math/tex&quot;&gt;f(x)\in[1,k]\rightarrow\mathbb{R}&lt;/script&gt;라 하자. 그러면 Convolution은 &lt;script type=&quot;math/tex&quot;&gt;h(y)\in[1,\lfloor(l-k)/d\rfloor+1]&lt;/script&gt;라는 함수로 표현될 수 있고, Conovlution은 모든 input에 대해 kenel이 모두 계산되는 것이므로 함수는 아래와 같이 정의 된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;h(y)=\sum^k_{x=1}f(x)\cdot g(y\cdot d-x+c)&lt;/script&gt;

&lt;p&gt;위에서 사용된 상수 &lt;script type=&quot;math/tex&quot;&gt;c&lt;/script&gt;는 &lt;script type=&quot;math/tex&quot;&gt;c=k-d+1&lt;/script&gt;로 offset 상수 이다. Vision에서 흔히 사용되는 Convolutional network처럼 이 모듈은 kernel 함수들의 집합을 파라미터로 가진다. input &lt;script type=&quot;math/tex&quot;&gt;g_i(x)&lt;/script&gt;에 대해서 output &lt;script type=&quot;math/tex&quot;&gt;h_j(y)&lt;/script&gt;로 갈 때 계산되는 파라미터를 다음과 같이 정의한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
f_{ij}(x) ,i=1,2,...,m~\&amp;j=1,2,...,n %]]&gt;&lt;/script&gt;

&lt;p&gt;위의 파라미터를 &lt;em&gt;weight&lt;/em&gt; 라 부른다. 그리고 위의 input, output값인 &lt;script type=&quot;math/tex&quot;&gt;g_i,h_j&lt;/script&gt;는 &lt;em&gt;feature&lt;/em&gt; 라고도 불리며, 전체 길이에 해당하는 $m, n$을 feature 라 한다. 즉 다시말해 output &lt;script type=&quot;math/tex&quot;&gt;h_j(y)&lt;/script&gt;는 모든 $i$에 대해서 &lt;script type=&quot;math/tex&quot;&gt;g_i(x)&lt;/script&gt;와 &lt;script type=&quot;math/tex&quot;&gt;f_{ij}(x)&lt;/script&gt;를 convolution 연산한 것을 더하면서 얻어진다.&lt;/p&gt;

&lt;p&gt;그리고 이 깊은 모델을 학습하는데 또 중요한 모듈은 max-pooling 모듈이다. input 함수를 &lt;script type=&quot;math/tex&quot;&gt;g(x)\in[1,l]\rightarrow\mathbb{R}&lt;/script&gt;라 하고 max-pooling 함수를 &lt;script type=&quot;math/tex&quot;&gt;h(y)\in[1,\lfloor(l-k)/d\rfloor+1]\rightarrow\mathbb{R}&lt;/script&gt;이라 하면 이 함수는 다음과 같이 정의 된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;h(y)=\max^k_{x=1}g(y\cdot d-x+c)&lt;/script&gt;

&lt;p&gt;여기서도 $c$는 offset 상수인 &lt;script type=&quot;math/tex&quot;&gt;c=k-d+1&lt;/script&gt;이 된다. 이러한 max-pooling 모듈 덕분에 전체 모델은 총 6 layer만큼 깊어 질 수 있다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;(수식으로 설명되서 어렵게 느껴질 수 있는데 우리가 흔히 아는 convolution과 padding을 생각하면 된다,)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;그리고 non-linearity를 위한 함수로는 ReLU 함수를 사용했다. 그리고 학습과정에서는 128 크기의 minibatch로 Stochastic gradient descent(SGD)를 사용했으며 모멘텀을 사용해 update했다. 모멘텀 사용 시 모멘텀 상수는 0.9로 하였고 학습률은 0.01 시작해서 3에폭마다 절반으로 줄이는 방식을 사용했다. 그리고 각 에폭은 각 class에 대해 동일하게 추출된 특정 크기의 데이터를 뜻하고 이 값에 대해서는 각 dataset에 따라서 다르므로 뒤에서 설명한다.&lt;/p&gt;

&lt;h4 id=&quot;character-quantization&quot;&gt;Character quantization&lt;/h4&gt;

&lt;p&gt;모델에서 인코딩된 글자(character)들의 sequence를 input값으로 받았다. 여기서 인코딩은 m개의 알파벳에 대해 one-hot 인코딩 방식을 사용했다. 따라서 각 input은 m-dimension의 벡터가 된다. 만약 알파벳에 들어가지 않는 문자에 대해서는 0벡터로 만든다. 그리고 특정 길이까지만 input으로 입력받는데, 길이를 넘어가는 값에 대해서는 무시한다. 이 모델에서는 알파벳을 총 70개의 문자로 정의한다. 알파벳에 속하는 문자는 26개의 영어 문자, 10개의 숫자, 그리고 33개의 특수문자이다. 전체 알파벳은 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/eA7X9Hs.jpg&quot; alt=&quot;alpha&quot; /&gt;&lt;/p&gt;

&lt;p&gt;여기서는 영어 문자에 대해서는 소문자만 받도록 했는데 나중에 소문자와 대문자를 구별하는 것과도 비교할 것이다.&lt;/p&gt;

&lt;h4 id=&quot;model-design&quot;&gt;Model Design&lt;/h4&gt;

&lt;p&gt;2개의 ConvNet을 design했다. 하나는 많은 feature를 가지는 ConvNet이고 하나는 적은 feature를 가지는 ConvNet이다. feature의 개수를 제외하고는 다른 부분은 모두 동일하다. 전체 모델은 총 9개의 layer이고 그 중 6개는 convolutional layer이고 3개는 fully-connected layer이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/IXY0weI.jpg&quot; alt=&quot;conv&quot; /&gt;&lt;/p&gt;

&lt;p&gt;세부적인 사항에 대해서 살펴보면 input의 feature의 수는 70이다. 앞서 설명한 encoding 방식을 사용하면 한 문자당 70 dimension의 vector가 되기 떄문이다. 그리고 앞서 말한 것 처럼 특정 길이까지의 문자만 입력으로 받는데 여기서는 1,014개의 문자까지만 입력으로 받는다. 논문에 따르면 이 정도 길이면 글의 주된 내용은 모두 잡아낼 수 있다고 한다. 그리고 앞서 말한 것처럼 feature의 수가 다른 2개의 ConvNet을 design 했다고 했는데, Large feature는 Convolution을 통해 총 1024의 feature를 가지는 Convolution을 수행하고 small feature는 256의 feature를 갖도록 convolution을 수행했다. 즉 다른 필터의 사이즈를 사용했다고 이해하면 된다. 아래의 표는 각 Convolutional layer의 값들을 설명했다. (참고로 stride는 1이고 pooling과정에서 overlap되는 부분이 없도록 한다)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/INO7psM.jpg&quot; alt=&quot;feat&quot; /&gt;
&lt;img src=&quot;https://i.imgur.com/uKq3tc4.jpg&quot; alt=&quot;feat2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;그리고 fully-connected layer 사이에 dropout을 2번 사용했다. dropout 확률은 0.5로 설정했다. 그리고 가중치 초기화는 가우시안 분포를 따르도록 하고 분포의 평균과 분산은 큰 모델에 대해서는 (0, 0.02)로 작은 모델은 (0, 0.05)로 설정했다.&lt;/p&gt;

&lt;h4 id=&quot;data-augmentation-using-thesaurus&quot;&gt;Data Augmentation using Thesaurus&lt;/h4&gt;

&lt;p&gt;데이터 증가는 일반적으로 데이터가 많이 필요한 deep learning 에서는 매우 중요한 부분이지만, image나 speech 분야와는 달리 text에서의 데이터 증가는 문자의 순서가 매우 중요할 수 있는데, 이런 언어의 규칙을 데이터를 증가시키면서 손상시킬 수 있기 때문에 조심스럽다. 따라서 여기서 사용한 데이터 증가 방식은 단어나 특정 문자들을 유사어로 대체시키는 방법을 사용했다.(English thesaurus를 사용했다.)&lt;/p&gt;

&lt;h4 id=&quot;comparison-models&quot;&gt;Comparison Models&lt;/h4&gt;

&lt;p&gt;비교를 위한 모델로는 전통적인 NLP 방식과 Deep Learning 방식 두가지 모두 사용해서 비교했다. 각 모델은 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional Methods&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Bag of words and its TFIDF&lt;/li&gt;
  &lt;li&gt;Bag of ngrams and its TFIDF&lt;/li&gt;
  &lt;li&gt;Bag of means on word embedding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Deep Learning Methods&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Word based ConvNets&lt;/li&gt;
  &lt;li&gt;Long short term memory&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;dataset-and-result&quot;&gt;Dataset and Result&lt;/h4&gt;

&lt;p&gt;비교를 위해 사용한 데이터셋은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;AG’s news corpus&lt;/li&gt;
  &lt;li&gt;Sogou news corpus&lt;/li&gt;
  &lt;li&gt;DBPedia ontology dataset&lt;/li&gt;
  &lt;li&gt;Yelp reviews&lt;/li&gt;
  &lt;li&gt;Yahoo! AAnswers dataset&lt;/li&gt;
  &lt;li&gt;Amazon reviews&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;데이터셋에 대한 세부적인 설명은 생략한다. 6개의 데이터셋 중에서 앞의 3개는 비교적 작은 크기의 데이터셋이고 뒤의 3개는 큰 데이터셋이다.&lt;/p&gt;

&lt;p&gt;그리고 결과는 다음과 같다. 각 모델에 명명에 대해서 설명하면 Lg 와 Sm은 Large와 small을 의미하고, Lk는 Look-up table을 사용한 것이다. 그리고 Th는 앞서 말한 Thesaurus를 의미한다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/hc6ZN78.jpg&quot; alt=&quot;result&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이제 결과에 대해서 몇 가지만 요약하면 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;글자 단위의 Convolutional Network도 문서 분류에서 높은 성능을 보인다.&lt;/li&gt;
  &lt;li&gt;작은 데이터셋에서는 전통적인 NLP방식이 DL방식보다 더 높은 성능을 보인다.&lt;/li&gt;
  &lt;li&gt;ConvNet은 사용자가 만든 데이터에서 좋다.(오타를 잘 잡는다)&lt;/li&gt;
  &lt;li&gt;Alphabet의 선택에 따라 성능이 많이 달라진다.&lt;/li&gt;
  &lt;li&gt;Bag-of-means 모델은 안좋다.&lt;/li&gt;
  &lt;li&gt;모든 데이터셋에 있어 최적의 모델은 없다.( 많은 실험을 통해 데이터셋에 가장 적합한 모델을 찾아야 한다)&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;긴글 읽어주셔서 감사합니다. 오역 및 잘못된 내용이 있을 수 있습니다. 잘못된 부분 혹은 이해가 잘 안되는 부분은 댓글 혹은 메일로 말씀해주시면 감사하겠습니다!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>NLP를 위한 CNN (4): A Sensitivity Analysis of Convolutional Neural Networks for Sentence Classification</title>
   <link href="https://reniew.github.io/28/"/>
   <updated>2018-08-06T04:47:35+00:00</updated>
   <id>https://reniew.github.io/28</id>
   <content type="html">&lt;p&gt;NLP에서 활용되는 Convolutional Network에 대해서 논문 하나씩 알아보도록 한다. 전체 List는 다음과 같다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/25/&quot;&gt;Understanding CNN for NLP&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/26/&quot;&gt;Convolutional Neural Network for Sentence Classification, 2014&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/27/&quot;&gt;A Convolutional Neural Network for Modelling Sentences, 2014&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/28/&quot;&gt;A Sensitivity Analysis of Convolutional Neural Networks for Sentence Classification&lt;/a&gt; [현재글]&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/29/&quot;&gt;Character-level Convolutional Networks for Text Classification&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;a-sensitivity-analysis-of-convolutional-neural-networks-for-sentence-classification&quot;&gt;A Sensitivity Analysis of Convolutional Neural Networks for Sentence Classification&lt;/h3&gt;

&lt;p&gt;이 논문은 CNN을 활용한 새로운 구조의 모델을 소개하는 논문이 아니라, CNN을 활용해서 Sentence Classification을 위한 모델을 만들 때 선택해야할 여러 Hyperparameter들의 선택을 돕기 위해 여러 가지를 비교하며 보여주는 논문에 가깝다.&lt;/p&gt;

&lt;p&gt;CNN의 경우 학습과정이 빠르지 않기 때문에 다향한 Hyperparameter들의 실험하는 것이 어렵다. 따라서 이 논문에서 소개하는 내용을 참고하는 것이 속도 및 효율측면에서 도움이 된다. 여기에서 실험해본 요소로는 다음의 것들이 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;input word 표현(embedding)&lt;/li&gt;
  &lt;li&gt;filter의 region size&lt;/li&gt;
  &lt;li&gt;feature map의 수&lt;/li&gt;
  &lt;li&gt;activation function&lt;/li&gt;
  &lt;li&gt;pooling 전략&lt;/li&gt;
  &lt;li&gt;정규화 방법&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;cnn-architecture&quot;&gt;CNN Architecture&lt;/h4&gt;

&lt;p&gt;여기에서는 Architecture의 경우 세부적인 내용은 계속해서 바뀌므로 일반적인 부분에 대해서 소개한다. 우선은 1-layer CNN을 사용했으며, input값에 대해서 먼저 알아보자.&lt;/p&gt;

&lt;p&gt;input값은 각 문장을 tokenize한 뒤 각 단어를 embedding 한 벡터로 만들어서 단어 벡터들을 합친 matrix가 된다. embedding 방법으로는 &lt;a href=&quot;https://reniew.github.io/21/&quot;&gt;word2vec&lt;/a&gt;과 &lt;a href=&quot;https://reniew.github.io/23/&quot;&gt;glove&lt;/a&gt;를 사용했다. 그리고 벡터의 dimension은 $d$라 한다.&lt;/p&gt;

&lt;p&gt;그 다음으로는 convolution의 filter에 대해서 설명하면, filter의 넓이(width)는 건들지 않고 $d$로 고정시켰다. 단어 임베딩의 dimension이 $d$이기 때문에 이 부분은 수정하지 않고 높이(height)만 수정했다. 즉 filter가 몇개의 단어를 보는지를 바꾸면서 실험했다. 이 부분이 의미하는 것이 필터의 region size이다.&lt;/p&gt;

&lt;p&gt;필터를 적용시킨 후 bias(&lt;script type=&quot;math/tex&quot;&gt;\mathbf{b}&lt;/script&gt;)를 더하고 activation fucntion(&lt;script type=&quot;math/tex&quot;&gt;f&lt;/script&gt;)를 각 요소에 사용했다.&lt;/p&gt;

&lt;p&gt;다음으로는 풀링을 적용시킨다. 일반적인 방법은 1-max pooling으로 각 feature map에 대해서 하나의 scalar값을 뽑는 방법이다. 풀링의 결과인 filter map으로 부터 만들어진 output을 고정된 길이로 concatenate한다. 이후 classification을 위해 softmax함수를 사용한다. 여거서 정규화를 위해 dropout을 사용할 수 있다. 또 l2 norm 정규화도 사용 될 수 있다. 아래의 그림이 위의 여러 경우의 Architecture를 하나로 설명한 그림이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/2zeqaFH.jpg&quot; alt=&quot;anlysis&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이제 학습과정이 남았다. 우선은 Objective funciton으로는 cross-entropy loss함수를 사용한다. 그리고 optimization으로는 SGD와 back-propagation을 사용한다.&lt;/p&gt;

&lt;h4 id=&quot;datasets&quot;&gt;DataSets&lt;/h4&gt;

&lt;p&gt;하나의 데이터셋으로 비교할 경우 정확한 결과를 얻기 힘드므로 여러 데이터셋을 사용해서 비교한다. 사용한 데이터셋은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;MR&lt;/li&gt;
  &lt;li&gt;SST-1&lt;/li&gt;
  &lt;li&gt;SST-2&lt;/li&gt;
  &lt;li&gt;Subj&lt;/li&gt;
  &lt;li&gt;TREC&lt;/li&gt;
  &lt;li&gt;CR&lt;/li&gt;
  &lt;li&gt;MPQA&lt;/li&gt;
  &lt;li&gt;Opi&lt;/li&gt;
  &lt;li&gt;Irony&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;effect-of-each-factor&quot;&gt;Effect of each factor&lt;/h4&gt;

&lt;p&gt;각각의 요소에 의한 영향들을 비교 분석하면서 확인해보자.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Effect of input word vector&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;가장 먼저 word vector represent 방법에 따른 영향을 분석해보자. 앞서 말했듯이 방법은 word2vec과 glove로 학습된 벡터를 사용한 뒤 비교하는 것이다. word2vec의 경우 1000억개의 google news의 단어를 학습한 벡터이고 glove는 web의 8400억개의 token을 학습시켰다. 두 방법 모두 300dimension의 벡터로 만들었으며 학습 중간에 update하지는 않았다. 그리고 word2vec과 glove를 concatenate한 벡터도 input으로 사용해서 실험을 했다. 즉 600 dimension의 vector로 사용한 것이다. 결과는 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/Q6nVxgg.jpg&quot; alt=&quot;wordrepre&quot; /&gt;&lt;/p&gt;

&lt;p&gt;결과를 보면 word2vec과 glove의 경우 dataset에 따라 성능이 좋은 것이 다르고 보통은 크게 차이가 나지 않았다. 하지만 word2vec과 glove를 concatenate한 것은 생각보다 성능이 좋게 나오지는 않았다.&lt;/p&gt;

&lt;p&gt;그리고 위의 결과에는 나와있지 않지만 one-hot encoding방식으로도 실험을 진행했지만 embedding방법에 비해 성능이 나오지 않았다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Effect of filter region size&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;filter가 적용되는 크기인 region size를 1, 3, 5, 7, 10, 15, 20, 25, 30의 크기를 두고 비교했다. 결과를 보면 각 데이터셋에 맞는 최적의 region size가 있다는 것을 알 수 있다. 데이터의 sentence길이가 길수록 이 최적의 region size의 길이는 길어지는 경향이 있다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/eub1lhJ.jpg&quot; alt=&quot;filter1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;그리고 region size를 단일값으로만 사용하지 않고 여러 size를 사용해서 실험 한 결과는 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/4jcFQC8.jpg&quot; alt=&quot;filter2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;결과를 보면 region size를 여러개 사용한다고 크게 성능에서 차이가 나지 않음을 보인다. 가장 높은 효율을 보일 때는 모든 region size를 동일하게 7로 했을 때이다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Effect of number of feature maps for each filter region size&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;여기서는 region 크기는 3,4,5로 고정을 하고 feature map의 수를 10, 50, 100, 200, 400, 600, 1000, 2000으로 둬서 비교했다. 여기서도 마찬가지로 각 데이터셋에 맞는 최적의 feature map수가 있다는 것을 볼 수 있는데 그래도 하나의 경향성은 보통 feature map 수가 600까지는 성능이 증가한다는 것을 볼 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Effect of activation function&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;활성화 함수로는 ReLU, tanh, sigmoid, softplus, cube, tanh cube, 그리고 ‘iden’으로 identitiy function도 사용했다. 결과는 다음과 같이 나온다.&lt;/p&gt;

&lt;p&gt;9개의 데이터셋 중 8개의 데이터셋에서 Iden, ReLU, tanh중 하나가 가장 최적의 활성화 함수였다. 그리고 MPQA데이터셋에서는 SoftPlus가 다른 데이터에 비해 성능이 월등히 좋게 나왔다. 나머지 활성화 함수의 경우 다른 앞서 말한 활성화 함수들에 비해 성능이 나오지 않아서 표에서 확인할 수 없다. 결과에 대해서 분석을 해보자면 tanh의 경우 함수가 zero-centered한 성질이 있기 떄문에 좋은 성능을 보인 것 같다. 그리고 ReLU의 경우 sigmoid에 비해 non-saturating 한 성질이 도움이 된다. 그리고 SGD와 사용시 수렴하는 속도가 매우 빠르다. 한 가지 흥미로운 결과는 항등함수(identity)가 경우에 따라 좋은 결과를 만들기도 한다는 점이다. 그러나 만약 multiple hidden layer를 가진 network이라면 항등함수의 경우에는 non-linear이기 떄문에 적합하지 않다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Effect of pooling strategy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pooling의 경우에는 pooling region size와 strategy를 변경하며 실험했다. region size는 3, 10, 20, 30, 1-max pooling을 사용했고, 5, 10, 15, 20의 값에 대해 $k$-max pooling도 사용했다. 그리고 3, 10, 20 ,30의 region size로 average 풀링도 적용했다.&lt;/p&gt;

&lt;p&gt;실험 결과는 average pooling이 일반적으로 max pooling보다 성능이 좋지 않았고 분석 결과 1-max pooling이 sentence classification에서는 좋은 성능을 보인다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Effect of regularization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;여기서는 dropout과 $l2$ regularization을 분석했다. 일반적으로 $l_2$ norm constraint는 성능을 향상시키지 못했다. 그리고 dropout의 비율을 다르게 하는 것 또한 성능변화가 크게 일어나지 않았다. 다음으로는 dropout을 penultimate layer가 아닌 convolutional layer에 적용시켰을 때는 성능이 조금은 좋아졌다. 결과적으로 이 논문에서는 dropout rate를 0~0.5정도로 적은 값으로 설정하고 상대적으로 max norm의 경우에는 크게 설정하라고 추천한다.&lt;/p&gt;

&lt;h4 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;이 논문을 통해 본 결과 모든 요소들이 데이터셋과 다른 요소들에 의해서 좋고 나쁨이 명확하지는 않다. 하지만 성능에 크게 영향을 미치는 요소는 실험을 통해 tuning할 필요가 있다는 것을 의미한다. 튜닝이 필요한 hyperparameter는 우선 filter의 regionsize이다. 그리고 feature map의 수 또한 성능에 많은 영향을 미치므로 tuning이 필요하다. 나머지의 경우 얘기를하면 word representation은 word2vec 과 glove가 다른 방법들에 비해 classifcation에서는 월등한 성능을 보이므로 두 가지 중에서 사용하는 것이 좋다. 그리고 풀링은 1-max pooling이 적합하다. 마지막으로 regularization은 상대적으로 다른 요소들에 비해 영향이 적으니 크게 고려하지 않아도 된다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;긴글 읽어주셔서 감사합니다. 오역 및 잘못된 내용이 있을 수 있습니다. 잘못된 부분 혹은 이해가 잘 안되는 부분은 댓글 혹은 메일로 말씀해주시면 감사하겠습니다!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>NLP를 위한 CNN (3): A Convolutional Neural Network for Modelling Sentences</title>
   <link href="https://reniew.github.io/27/"/>
   <updated>2018-08-06T04:47:35+00:00</updated>
   <id>https://reniew.github.io/27</id>
   <content type="html">&lt;p&gt;NLP에서 활용되는 Convolutional Network에 대해서 논문 하나씩 알아보도록 한다. 전체 List는 다음과 같다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/25/&quot;&gt;Understanding CNN for NLP&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/26/&quot;&gt;Convolutional Neural Network for Sentence Classification, 2014&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/27/&quot;&gt;A Convolutional Neural Network for Modelling Sentences, 2014&lt;/a&gt; [현재글]&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/28/&quot;&gt;A Sensitivity Analysis of Convolutional Neural Networks for Sentence Classification&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/29/&quot;&gt;Character-level Convolutional Networks for Text Classification&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;a-convolutional-neural-netwrok-for-modelling-sentences&quot;&gt;A Convolutional Neural Netwrok for Modelling Sentences&lt;/h3&gt;

&lt;p&gt;Oxford의 Kalchbrenner에 의해 발표된 이 논문에서 소개하는 CNN은 Dynamic Convolutional Neural Netwrok(DCNN)으로 Dynamic k-Max Pooling을 사용한다. 그리고 가변 길이의 sentence를 input으로 받으며, feature graph를 만들어서 short term과 long term의 특징을 모두 사용한다. 아래의 그림을 보자.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/9T5tSru.jpg&quot; alt=&quot;klo&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이 네트워크를 가지고 4가지 실험을 했다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;binary classification&lt;/li&gt;
  &lt;li&gt;multi-class sentiment classification&lt;/li&gt;
  &lt;li&gt;six-way question classification&lt;/li&gt;
  &lt;li&gt;twitter sentiment prediction&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;결과를 먼저 말하자면 논문의 네트워크를 사용함으로써 위의 모든 tasks에서 높은 성능을 보여줬고 1,2,3번의 경우에는 기존의 baseline보다 25%나 상승된 성능을 보여줬다.&lt;/p&gt;

&lt;p&gt;논문에서 사용된 sentence model은 classification과 generation을 위해 만들어 졌으며, 문장 내용의 의미를 표현하거나 분석한다. 다양한 task에 해당 모델을 활용할 수 있다.&lt;/p&gt;

&lt;p&gt;이제 model의 특징에 대해서 알아보도록 하자.&lt;/p&gt;

&lt;h4 id=&quot;convolutional-neural-networks-with-dynamic-k-max-pooling&quot;&gt;Convolutional Neural Networks with Dynamic $k$-Max Pooling&lt;/h4&gt;

&lt;p&gt;해당 논문에서는 wide-convolution을 &lt;em&gt;k-max pooling&lt;/em&gt; 을 사용하는dynamic pooling layer로 대체한다. 이 모델의 input이 가변 길이의 sentence를 받기 때문에 중간 layer에서의 feature map의 넓이는 각각 다르다. 하지만 CNN의 경우 고정 크기의 map에 대해서 연산할 수 있다. 이러한 문제를 해결하기 위한 것이 Dynamic Convolutional Neural Netwrok이다. DCNN을 그림으로 나타내면 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/hDtaWjl.jpg&quot; alt=&quot;dcnn&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wide Convolution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;주어진 input 문장에 대해서 각 단어의 임베딩값을 구한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{w}_i\in\mathbb{R}^d&lt;/script&gt;

&lt;p&gt;만들어진 임베딩 벡터를 concatenate해서 문장 matrix를 만든다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{s}\in\mathbb{R}^{d\times s}&lt;/script&gt;

&lt;p&gt;여기서 각 단어 벡터&lt;script type=&quot;math/tex&quot;&gt;\mathbf{w}_i&lt;/script&gt;는 학습 과정에서 최적화 될 것이다. convolutional layer는 weight matrix인 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{m}\in\mathbb{R}^{d\times m}&lt;/script&gt;를 convolution한다. 여기서 dimension $d$와 필터의 넓이인 $m$은 hyper parameter이다. 이 과정을 wide one-dimensional convolution이라 한다. 그리고 이 결과 나오는 matrix를 $\mathbf{c}$라 하고 dimension은 $d\times(s+m-1)$이 된다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;k-Max Pooling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;여기서 사용할 Pooling연산은 &lt;a href=&quot;https://ronan.collobert.com/pub/matos/2008_nlp_icml.pdf&quot;&gt;Max-TDNN&lt;/a&gt; 문장 모델에서 사용된 max pooling over the time dimension을 사용한다. 이 연산은 일반적인 일부 지역은 모아 pooling하는 것과는 다른 연산이다. 과정에 대해 설명하면 우선 어떤 &lt;script type=&quot;math/tex&quot;&gt;k&lt;/script&gt;값이 주어진다. 그리고 &lt;script type=&quot;math/tex&quot;&gt;p\ge k&lt;/script&gt;인 dimension을 가지는 sequence(vector) &lt;script type=&quot;math/tex&quot;&gt;\mathbf{p}&lt;/script&gt;에 대해서 &lt;script type=&quot;math/tex&quot;&gt;k&lt;/script&gt;-max pooling은 sequence &lt;script type=&quot;math/tex&quot;&gt;\mathbf{p}&lt;/script&gt;에서 &lt;script type=&quot;math/tex&quot;&gt;k&lt;/script&gt;개의 최대 값을 선택해 subseqeunce &lt;script type=&quot;math/tex&quot;&gt;\mathbf{p}^k_{max}&lt;/script&gt;를 만든다.&lt;/p&gt;

&lt;p&gt;$k$-max pooling은 위치가 가까운것에 신경쓰지 않고 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{p}&lt;/script&gt;에서 k개의 active한 값을 뽑아낸다. 그리고 연산을 한 후에는 각 feature의 정확한 위치 정보는 소실되지만 각 feature들간의 순서 정보는 보존된다. 이 $k$-max pooling 연산은 해당 네트워크에서 가장 위에있는 convolutional layer이후에 적용된다. 이 연산을 통해 jully connected layer로 가기 위한 input값의 크기 제한이 없어진다. 다음으로 우리가 알아볼 pooling은 convolutional layer 중간에서 적용되며 $k$값이 고정되어 있지 않고 더 넓은 범위의 순서를 보존하며 뽑기위해 동적으로 선택된다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dyanmic &lt;script type=&quot;math/tex&quot;&gt;k&lt;/script&gt;-Max Pooling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;dynamic k-max pooling 연산은 k-max pooling과 같은 과정으로 수행되지만 k값이 정해지는 함수가 존재한다. 이 함수는 문장의 길이와 네트워크의 총 깊이(전체 레이어의 수)에 의해 결정된다. 문장 길이를 $s$라 하고 네트워크의 깊이는 $L$이라 한다. 이 떄 함수는 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;k_l=\max(k_{top}, \lceil \frac{L-l}{L}s\rceil)&lt;/script&gt;

&lt;p&gt;여기서 $l$은 현재 convolutional layer의 층이다. 그리고 $k_{top}$은 가장 높은층의 convolutional layer를 위한 고정된 parameter이다. 예를 들어보자. 전체 3개의 convolutional layer가 있고, &lt;script type=&quot;math/tex&quot;&gt;k_{top}=3&lt;/script&gt;이고 input 문장의 길이는 &lt;script type=&quot;math/tex&quot;&gt;s=18&lt;/script&gt;이라 하자. $k$값들은 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
&amp;k_1= \max(3 , \lceil \frac{3-1}{3}\cdot18\rceil)=12\\
&amp;k_2= \max(3 , \lceil \frac{3-2}{3}\cdot18\rceil)=6\\
&amp;k_3= k_{\max}=3
\end{align*} %]]&gt;&lt;/script&gt;

&lt;p&gt;이 Pooling에 대해서 조금 직관적으로 이해를 해보자. k값은 층이 올라갈 수록 수가 적어지는 구조이다. 이 구조가 의미하는 것은 층이 낮은 곳에서는 더 많은 중요한 feature를 뽑고 층이 올라갈 수록 더욱 중요한 feature를 고르는 과정으로 이해할 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Non-linear Feature Funciton&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;위의 $k$-max pooling 연산은 conovlution 연산의 결과에 적용된다는 것을 알 수 있다. 이렇게 pooling을 한 이후에 바로 값을 다음으로 보내는 것이 아니라 bias &lt;script type=&quot;math/tex&quot;&gt;\mathbf{b}\in\mathbb{R}^d&lt;/script&gt;를 더하고 non-linear 함수인 &lt;script type=&quot;math/tex&quot;&gt;g&lt;/script&gt;를 요소별로 적용 시킨 후 적용시킨 후 다음 층으로 전달 된다. 각 pooling matrix에서는 각각의 단일 값의 bias가 존재한다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multiple Feature Maps&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;이때까지는 우리는 각 layer에서 convolution과 pooling이 하나씩만 적용되는 경우로 생각했다. 하지만 처음에 봤던 전체 network에 대한 그림을 보면 알 수 있듯이 각 layer에서 2개씩 적용된다. 즉 여러개의 feature map을 만든 뒤 만든 feature map을 새로운 parameter를 곱한 뒤 합쳐주는 형태이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{F}^i_j=\sum^n_{k=1}\mathbf{m}^i_{j,k}* \mathbf{F}^{i-1}_k&lt;/script&gt;

&lt;p&gt;여기서 *가 의미하는 것은 wide convolution이다. 실제 netwrok에서 병렬로 진행하는 모델의 수는 그림처럼 꼭 2개는 아니고 사용자가 정하는 것이다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Folding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;이때까지의 모델을 살펴보면, feature map을 뽑을 때 convolution과 pooling이 모두 각 row에 대해서 연산되는 것을 볼 수 있다. 이렇게 진행을 한다면 각 row는 독립적으로 진행되어서 서로 연관관계에 대한 정보는 전혀 포함 할 수 없다. 따라서 이러한 row-independent한 문제를 해결하기 위해 연산을 마친 각 row들을 합치는 folding과정을 마지막 pooling 전에 수행한다. 2개의 row를 각각 합하는 형태로 진행되기 때문에 새로운 parameter도 필요하지 않다. 이 과정을 수행하면 matrix의 높이가 절반으로 줄어드게 된다.&lt;/p&gt;

&lt;h4 id=&quot;properties-of-sentence-model&quot;&gt;Properties of Sentence Model&lt;/h4&gt;

&lt;p&gt;해당 네트워크의 sentence modeling의 몇 가지 특성에 대해서 소개한다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Word and n-Gram Order&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;stence modeling에서 중요한 것은 특정 n-gram이 input에서 발생하는 것을 구별하는 것과 구별한 n-gram에 대해서 상대적인 순서 정보 또한 가지고 있는 것이 중요하다. 해당 netwrok는 두 중요점을 위해 설계했다. &lt;script type=&quot;math/tex&quot;&gt;\mathbf{m}&lt;/script&gt;필터로 wide convolution을 하면 특정 n-gram에 대한 정보를 뽑고, pooling과정에서 각 순서 정보를 포함하게 된다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Induced Feature Graph&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;해당 모델을 좀 더 큰 그림으로 보자. 우선 각 matrix의 하나의 row의 관점에서만 보게 된다면 각 값들 중 몇 가지만 선택되서 다음 layer로 전달 된다. 나머지 값들은 탈락된 것이며 선택된 값들 중 그 다음으로 또 전달 되는 것은 그 일부이다. 이러한 내용을 전체적으로 보면 각 값(feature)에 대한 graph 구조로 생각할 수 있다. 이 글의 시작에서 소개한 그림의 형태로 진행되고 있는 것이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/9T5tSru.jpg&quot; alt=&quot;klo&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;train&quot;&gt;Train&lt;/h4&gt;

&lt;p&gt;학습에 사용된 방법들에 대해 소개하면 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;top-layer는 softmax를 통해 예측한 class에 대한 확률 분포를 가진다. 학습과정에서 이 분포에 대해 실제 분포와 비교해서 cross-entropy를 최소화하는 방향으로 학습한다.&lt;/li&gt;
  &lt;li&gt;학습 시 &lt;script type=&quot;math/tex&quot;&gt;L_2&lt;/script&gt; 정규화를 사용했다.&lt;/li&gt;
  &lt;li&gt;mini-batch 방식으로 학습시켰다.&lt;/li&gt;
  &lt;li&gt;update policy는 Adagrad를 통해 update했다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;expreriments&quot;&gt;Expreriments&lt;/h4&gt;

&lt;p&gt;실험은 다음의 4가지 문제에 대해서 진행했다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Sentiment Prediction in Movie Review&lt;/li&gt;
  &lt;li&gt;Question Type Classification&lt;/li&gt;
  &lt;li&gt;Twitter Sentiment Prediction with Distant Supervision&lt;/li&gt;
  &lt;li&gt;Visualising Feature Detectors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;각 task들에 대한 결과는 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sentiment Prediction in the movie reviews dataset&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/Q9H5yyX.jpg&quot; alt=&quot;movie&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Six-Way Question Classification on TREC&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/Ad2afqv.jpg&quot; alt=&quot;question classi&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Twitter Sentiment Prediction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/bks4yOx.jpg&quot; alt=&quot;twitter&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Feature Detectors&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/pWr24cl.jpg&quot; alt=&quot;featuredetec&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;긴글 읽어주셔서 감사합니다. 오역 및 잘못된 내용이 있을 수 있습니다. 잘못된 부분 혹은 이해가 잘 안되는 부분은 댓글 혹은 메일로 말씀해주시면 감사하겠습니다!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>NLP를 위한 CNN (2): Convolutional Neural Network for Sentence Classification</title>
   <link href="https://reniew.github.io/26/"/>
   <updated>2018-08-05T04:47:35+00:00</updated>
   <id>https://reniew.github.io/26</id>
   <content type="html">&lt;p&gt;NLP에서 활용되는 Convolutional Network에 대해서 논문 하나씩 알아보도록 한다. 전체 List는 다음과 같다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/25/&quot;&gt;Understanding CNN for NLP&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/26/&quot;&gt;Convolutional Neural Network for Sentence Classification, 2014&lt;/a&gt; [현재글]&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/27/&quot;&gt;A Convolutional Neural Network for Modelling Sentences, 2014&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/28/&quot;&gt;A Sensitivity Analysis of Convolutional Neural Networks for Sentence Classification&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/29/&quot;&gt;Character-level Convolutional Networks for Text Classification&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;convolutional-neural-network-for-sentence-classification&quot;&gt;Convolutional Neural Network for Sentence Classification&lt;/h3&gt;

&lt;p&gt;가장 먼저 소개할 논문은 Newyork 대학의 Yoon kim님의 논문인 &lt;a href=&quot;http://www.aclweb.org/anthology/D14-1181&quot;&gt;Convolutional Neural Network for Sentence Classification&lt;/a&gt;입니다. 매우 간단한 구조의 CNN을 활용해서 문장 분류에서 상당한 효율을 보이며 많은 주목을 받았던 논문입니다.&lt;/p&gt;

&lt;p&gt;자연어 처리 분야에서 딥러닝 기법을 활용한 중요한 기술은 단어 표현을 학습하는 것이다. 즉 one-hot 벡터로만 사용하던 단어표현이 &lt;a href=&quot;https://reniew.github.io/21/&quot;&gt;word2vec&lt;/a&gt;, &lt;a href=&quot;https://reniew.github.io/23/&quot;&gt;Glove&lt;/a&gt;등 많은 기술들을 통해 dense한 low-dimension vector로 표현함으로써 비슷한 의미의 단어는 가까운 거리(유클리디언 거리 혹은 코사인 유사도)에 있도록 만들었다.&lt;/p&gt;

&lt;p&gt;그리고 CNN은 원래는 Computer vision분야의 문제를 해결하기 위해 나왔지만 많은 NLP 문제에서도 효과적이라고 알려졌다. 이 논문에서는 한개의 layer를 사용하는 CNN에 대해서 소개한다. 그리고 CNN에 사용할 단어 벡터는 1,000억개의 단어를 사전학습한 벡터를 사용한다. 여기서는 이 벡터를 수정하거나 하지 않고 Network의 parameter만 학습한다. 우선 사용할 architecture에 대해서 보자.&lt;/p&gt;

&lt;h4 id=&quot;model&quot;&gt;Model&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/TNjCKHf.jpg&quot; alt=&quot;yoon.k&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위의 architecture는 Collobert(2011)의 architecture를 약간 수정한 것이다. 세부적으로 하나씩 알아보자.&lt;/p&gt;

&lt;p&gt;우선 input은 $k$-dimension의 단어 벡터이다. 문장의 $i$번 째 단어는 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;x_i\in\mathbb{R}^k&lt;/script&gt;

&lt;p&gt;그리고 문장은 $n$개의 단어를 concat하여 사용하는데, 필요하다면 padding을 추가한다. 따라서 다음과 같이 표현된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{x}_{i:i+j}=\mathbf{x}_i\oplus \mathbf{x}_{i+1}\oplus ... \oplus \mathbf{x}_{i+j}.&lt;/script&gt;

&lt;p&gt;위의 $\oplus$는 concatenation 연산자이다. 위의 sentence에 convolution을 한다. 필터는 $hk$크기의 벡터의 모양이다. $h$개의 단어에 적용되서 새로운 feature를 뽑아낸다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{w}\in\mathbb{R}^{h\times k}&lt;/script&gt;

&lt;p&gt;convolution 연산을 하면 feature $c_i$가 만들어진다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;c_i=f(\mathbf{w}\cdot \mathbf{x}_{i:i+h-1}+b)&lt;/script&gt;

&lt;p&gt;여기서 $b\in \mathbb{R}$는 bias이고 $f$는 tanh와 같은 non-linear 함수이다. 이 필터는 sliding하면서 sentence &lt;script type=&quot;math/tex&quot;&gt;[\mathbf{x}_{1:h},\mathbf{x}_{2:h+1},...,\mathbf{x}_{n-h+1:n}]&lt;/script&gt;에 대해서 각각 적용되서 feature map &lt;script type=&quot;math/tex&quot;&gt;\mathbf{c}&lt;/script&gt;를 만든다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{c}=[c_1,c_2,...,c_{n-h+1}] \in \mathbb{R}^{n-h+1}&lt;/script&gt;

&lt;p&gt;만들어진 feature map에 max-over-time pooling(Collobert et al., 2011)을 하고 최대 값을 뽑아낸다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\hat{c}=\max\{\mathbf{c}\}&lt;/script&gt;

&lt;p&gt;위 값은 특정 필터에 상응하는 feature가 된다. feature map에서 가장 중요한 값(높은 값)을 뽑아내는 방법이다. 이러한 방법을 사용하면 하나의 필터에 대해서 하나의 feature를 뽑아 낸다. 이러한 피쳐들은 penultimate layer를 구성하고 fully connected sofmax layer로 통과시켜서 라벨에 대한 확률 분포를 만들어 낸다.&lt;/p&gt;

&lt;p&gt;그리고 마지막으로 그림을 보면 input에서 2개의 channel이 존재한다. 하나는 위에서 설명한 static한 word vector들을 모아둔 것이고, 나머지는 backpropagation을 통해 fine tuning 한 것이다. 즉 두 개의 channel에 대해서 filter를 적용시킨 후 더해서 사용한다. 1개의 channel만 사용한다면 더하는 과정 없이 바로 사용하면 된다.&lt;/p&gt;

&lt;h4 id=&quot;regularization&quot;&gt;Regularization&lt;/h4&gt;

&lt;p&gt;여기서는 정규화를 위해 dropout과 l2-norm 정규화를 사용했다. dropout의 경우에는 penultimate layer에서 마지막 layer로 가는 파라미터에서 사용했는데 이를 사용함으로써 hidden unit들이 같이 더해지는 것을 방지한다. forward와 back propagation에서 모두 사용했다. 즉 일반화해서 나타내면, penultimate layer를 $\mathbf{z}=[\hat{c}_1,…,\hat{c}_m]$이라 하자. 그러면,&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;y=\mathbf{w}\cdot\mathbf{z}+b&lt;/script&gt;

&lt;p&gt;를 사용하는 대신에, 아래의 식을 사용했다.(in forward)&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;y=\mathbf{w}\cdot(\mathbf{z}\odot\mathbf{r})+b&lt;/script&gt;

&lt;p&gt;여기서 $\odot$은 원소별 곱샘을 뜻하고 $\mathbf{r}$은 ‘masking’ 벡터로 각 값이 확률 $p$의 Bernoulli분포를 따르기 때문에 0 혹은 1의 값을 가진다. test과정에서는 dropout을 하지 않고 $\mathbf{w}$ 대신에 dropout 확률 $p$를 곱해서 사용한다. $\hat{\mathbf{w}}=p\mathbf{w}$&lt;/p&gt;

&lt;p&gt;그리고 $l_2$ 정규화의 경우 가중치 벡터의 $l_2$ norm이 $s$보다 클 경우 $s$값을 가지도록 조정한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\mathbf{w}=
\begin{cases}
w, ~\text{if }{\|\mathbf{w}||}_2&lt;s\\
s, ~\text{other wise}
\end{cases} %]]&gt;&lt;/script&gt;

&lt;h4 id=&quot;dataset&quot;&gt;DataSet&lt;/h4&gt;

&lt;p&gt;이 논문에서 사용 된 데이터셋은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;MR : 리뷰당 하나의 문장으로 된 영화 리뷰&lt;/li&gt;
  &lt;li&gt;SST-1 : Stanford Sentiment Treebank (label이 세분화)&lt;/li&gt;
  &lt;li&gt;SST-2 : Stanford Sentiment Treebank (label이 binary)&lt;/li&gt;
  &lt;li&gt;Subj : 주관성 데이터셋&lt;/li&gt;
  &lt;li&gt;TREC : TREC 질문 데이터셋&lt;/li&gt;
  &lt;li&gt;CR : 소비자 리뷰 데이터셋&lt;/li&gt;
  &lt;li&gt;MPQA&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;학습과-그-외-기타-사항들&quot;&gt;학습과 그 외 기타 사항들&lt;/h4&gt;

&lt;p&gt;이 모델에서 사용한 hyperparameter 및 함수는 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ReLU 함수&lt;/li&gt;
  &lt;li&gt;100 feature map으로 filter의 크기는 3,4,5로 지정&lt;/li&gt;
  &lt;li&gt;Dropout 확률 : 0.5&lt;/li&gt;
  &lt;li&gt;$l_2$ 값 : 3&lt;/li&gt;
  &lt;li&gt;미니 배치 크기 : 50&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;그리고 early stopping이 추가적으로 사용된 것 외에는 다른 특별한 사항은 없다. 그리고 학습 과정에서는 무작위의 mini batch에 대해서 SGD를 사용했고(엄밀히 말하면 MGD를 사용한 것이다), 파라미터 업데이트는 Adadelta를 사용했다.&lt;/p&gt;

&lt;p&gt;단어 벡터의 경우는 앞에서 나왔듯이 google news를 활용해 word2vec으로 사전 학습된 임베딩 벡터를 사용했으며 만약 vocabulary에 들어가 있지 않은 단어의 경우에는 임의의 값으로 초기화해서 사용했다. 그리고 실험단계에서 여러가지 상황을 바꿔가며 성능을 비교했는데 아래의 종류로 구분지어서 실험했다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;CNN-rand&lt;/strong&gt; : baseline값으로 사용하기 위해 사용. 모든 단어 벡터를 임의의 값으로 초기화해서 사용했다.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;CNN-static&lt;/strong&gt; : 앞서 말한 사전 학습된 word2vec 단어 벡터를 사용한 모델이다.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;CNN-non-static&lt;/strong&gt; : 위의 모델과 같이 학습된 벡터를 사용했지만 각 task에서 벡터값은 update된다.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;CNN-multichannel&lt;/strong&gt; : architecture 소개 부분에서 나왔듯이 input값을 1-channel로 한 것이 아니라, 2-channel인 모델. 둘 다 word2vec으로 학습한 단어 벡터인데 하나는 static하게 값이 그대로이고 나머지 하나는 학습 중간 계속 update된다. 즉 위의 static과 non-static을 섞어서 사용한 것과 같다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이렇게 4개의 경우로 나눠서 실험 했으며 결과는 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/46YUAdQ.jpg&quot; alt=&quot;yoon.k2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;표의 상위 4개가 비교하는 모델이고 아래의 값들은 다른 모델의 값을 비교한 것이다. 결과를 보면 절대적으로 좋은 모델은 없고 데이터셋에 따라 좋은 결과를 보이는 모델이 다르다. 하지만 명확한 것은 CNN을 활용해 만든 매우 간단한 모델임에도 불구하고 다른 모델들과 비교해서도 결코 적지 않은 성능을 보이거나 아니면 오히려 뛰어난 성능을 보여준다.&lt;/p&gt;

&lt;p&gt;이번 논문의 내용만 보더라도 CNN은 Image에서만이 아니라 자연어 처리 분야에서도 쉽고 간단하게 높은 성능을 기대할 수 있다. 그리고 이 논문을 통해 알게 된 또 하나의 사실은 word2vec등 단어를 임베딩하는 것이 NLP분야에서는 필수적이고 그 자체만으로도 성능이 엄청 오른다는 것을 알 수 있다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;긴글 읽어주셔서 감사합니다. 오역 및 잘못된 내용이 있을 수 있습니다. 잘못된 부분 혹은 이해가 잘 안되는 부분은 댓글 혹은 메일로 말씀해주시면 감사하겠습니다!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>NLP를 위한 CNN (1): Understanding CNN for NLP</title>
   <link href="https://reniew.github.io/25/"/>
   <updated>2018-08-03T04:47:35+00:00</updated>
   <id>https://reniew.github.io/25</id>
   <content type="html">&lt;p&gt;NLP에서 활용되는 Convolutional Network에 대해서 논문 하나씩 알아보도록 한다. 전체 List는 다음과 같다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/25/&quot;&gt;Understanding CNN for NLP&lt;/a&gt; [현재글]&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/26/&quot;&gt;Convolutional Neural Network for Sentence Classification, 2014&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/27&quot;&gt;A Convolutional Neural Network for Modelling Sentences, 2014&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/28/&quot;&gt;A Sensitivity Analysis of Convolutional Neural Networks for Sentence Classification&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://reniew.github.io/29/&quot;&gt;Character-level Convolutional Networks for Text Classification&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;p&gt;첫 번째로는 논문이 아닌 NLP에서 사용되는 CNN에 대한 대략적인 이해를 위해 CNN의 NLP에서의 활용에 대한 설명을 할 것이다. 해당 내용은 제가 직접 구성한 내용이 아니라 &lt;a href=&quot;http://www.wildml.com/2015/11/understanding-convolutional-neural-networks-for-nlp/&quot;&gt;블로그 글&lt;/a&gt;를 번역하고 나름 정리해서 쓴 글입니다. 의역이 포함되고 혹여나 오역이 있을 수 있어 원문과 비교하면서 읽으시는 것을 추천합니다!&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;understanding-convolutional-neural-network-for-nlp&quot;&gt;Understanding Convolutional Neural Network for NLP&lt;/h3&gt;

&lt;p&gt;일반적으로 우리가 CNN를 생각하면 Computer Vision 분야를 대부분 떠올릴 것이다. 실제로 CNN은 Computer Vision 분야에서 많은 발전을 이뤘다. Image Classification, Image Detection, Semantic Segmentation 등 많은 분야에서도 CNN을 활용해서 성능 발전을 보여준 사례가 많다. 해당 분야에 대해서 좀 더 알고 싶다면 블로그 글을 참고하자.(&lt;a href=&quot;https://reniew.github.io/08/&quot;&gt;Image Classification&lt;/a&gt;, &lt;a href=&quot;https://reniew.github.io/10/&quot;&gt;Image Detection(1)&lt;/a&gt;, &lt;a href=&quot;https://reniew.github.io/11/&quot;&gt;(2)&lt;/a&gt; , &lt;a href=&quot;https://reniew.github.io/18/&quot;&gt;Semantic Segmentation(1)&lt;/a&gt;, &lt;a href=&quot;https://reniew.github.io/19/&quot;&gt;(2)&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;좀 더 최근에는 CNN을 NLP문제에 활용하기 위한 많은 시도들을 했다. 사용한 NLP문제에서도 좋은 결과를 만들었다. 이 포스트에서는 CNN에 대한 내용을 간략히 소개하고 NLP에 CNN에 적용하는 방법에 대해 소개한다. CNN에 대한 직관적인 이해는 Computer Vision의 예를 들어 이해하는 것이 훨씬 쉬우므로 처음에는 Image를 예로들어 CNN에 대해서 알아보도록 한다.&lt;/p&gt;

&lt;h4 id=&quot;convolutional-neural-network-합성곱-신경망&quot;&gt;Convolutional Neural Network (합성곱 신경망)&lt;/h4&gt;

&lt;p&gt;CNN은 window가 sliding 하며 Convolution 연산이 수행되는 과정이 포함된 네트워크이다. 아래의 그림은 Convolution하는 과정을 잘 보여준다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://deeplearning.stanford.edu/wiki/images/6/6c/Convolution_schematic.gif&quot; alt=&quot;conv&quot; /&gt;&lt;/p&gt;

&lt;p&gt;CNN을 활용하는 예시를 생각해보자. 먼저 Image는 흑백이미지로 구성되며 각 pixel의 값은 0(black) 과 1(white) 값을 가진다고 하자. (일반적인 흑백 이미지는 0~255값을 가지는 grayscale이다.)&lt;/p&gt;

&lt;p&gt;이제 이 Iamge는 Kernel, Filter, Feature detector라 불리는 window에 의해 합성곱이 이뤄질 것이다. 여기서는 3x3 크기의 필터를 사용했다고 생각하자. 이러한 Convolution 과정이 실제로 의미하는 바는 무었일까? 직관적인 이해를 위해서 다음의 두가지 의미로 해석할 수 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;픽셀값을 주변의 값들로 묶어 평균해서 Image를 흐리게 만든다.
&lt;img src=&quot;http://docs.gimp.org/en/images/filters/examples/generic-taj-convmatrix-blur.jpg&quot; alt=&quot;blur&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;주변의 pixel의 차이를 계산함으로써 edge를 찾는다.
&lt;img src=&quot;http://docs.gimp.org/en/images/filters/examples/generic-taj-convmatrix-edge-detect.jpg&quot; alt=&quot;edge&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;좀 더 많은 예시는 &lt;a href=&quot;http://docs.gimp.org/en/plug-in-convmatrix.html&quot;&gt;GIMP manual&lt;/a&gt;에서 참고할 수 있다. 일반적인 CNN과정에 대해 더 알고 싶다면 &lt;a href=&quot;https://reniew.github.io/06/&quot;&gt;포스트&lt;/a&gt;를 참고하자.&lt;/p&gt;

&lt;h4 id=&quot;nlp문제에서의-cnn의-활용&quot;&gt;NLP문제에서의 CNN의 활용&lt;/h4&gt;

&lt;p&gt;Image Pixel대신 NLP문제를 해결할 때는 문장이나 전체 글을 matrix형태가 Input값이 된다. 이 matrix의 각 행은 하나의 token이 된다. token은 주로 단어가 된지만 경우에 따라 개별 문자가 하나의 token으로 활용하기도 한다. 즉 각 행은 단어 vector를 뜻한다. 대부분의 경우 이 단어 vector는 임베딩한 vector가 되는데 임베딩의 경우 &lt;a href=&quot;https://reniew.github.io/21/&quot;&gt;word2vec&lt;/a&gt; 혹은 &lt;a href=&quot;https://reniew.github.io/23/&quot;&gt;glove&lt;/a&gt; 기술을 통해 임베딩시킨 벡터이다. 경우에 따라 임베딩 시키지 않고 one-hot vector가 단어 vector가 될 수도 있다. 임베딩이든 one-hot이든 일단 벡터의 차원이 100차원이라 하고 token의 수, 즉 단어의 수를 10개라고 하면 이 matrix는 10x100 크기가 된다. 이 matrix가 우리의 “image”가 된다.&lt;/p&gt;

&lt;p&gt;Vision 문제에서 필터는 image를 지역적으로 sliding한다. 그러나 NLP에서는 필터는 matrix의 모든 단어의 전체 행에 사용된다. 따라서 필터의 넓이는 보통 matrix의 넓이와 같다. 즉 단어벡터의 dimension과 같게 된다. 높이(or region size)는 달라지지만 보통의 경우 2~5개의 단어를 sliding한다. 위의 과정에 대해 아래 그림을 보며 좀더 정확히 이해해보자.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.wildml.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-06-at-12.05.40-PM-1024x937.png&quot; alt=&quot;convinnlp&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Computer Vision에서의 중요한 직관은 위치의 불변성과 지역적 결합이다. 그러나 NLP에 이러한 직관은 해당되지 않는다. pixel의 경우는 비슷한 위치에 있으면 거의 의미적으로도 비슷한 pixel이지만 단어의 경우에는 항상 이러한 경우가 성립하지는 않는다. 단어들은 몇 가지 방법으로 구성된다. 예를 들면 명사를 변형시킨 형용사와 같이 단어들이 어떤 규칙이 있다. 그러나 정확히 이러한 단어가 높은 단계에서 어떤 의미를 가지는지는 알기 어렵다.&lt;/p&gt;

&lt;p&gt;이러한 모든 것들을 고려해볼때 CNN은 자연어 처리 분야에 적합하지 않아 보인다. Recurrent Neural Network가 훨씬 더 직관적으로 좋아보인다. RNN은 우리가 실제 언어를 사용하는 방법과 많이 비슷하다. 우리가 언어를 읽을 때도 왼쪽부터 오른쪽으로 순서대로 읽는 과정이 RNN과 비슷하다. 그러나 다행이도 이러한 내용이 CNN이 부적합하다는 것을 의미하지는 않는다. 다는 아니지만 몇몇의 모델은 유용하게 사용된다. Bag-of-Words 모델도 가정 자체가 지나치게 단순화해서 잘못된 가정이긴 하지만 그럼에도 불구하고 몇년동안 나름 좋은 결과를 만들어냈다.&lt;/p&gt;

&lt;p&gt;CNN의 가장 큰 장점은 매우 빠르다는 것이다. 합성곱 자체가 컴퓨터 그래픽의 핵심적인 부분이고 GPU단계에서 잘 동작한다. n-gram모델같은 것들과 비교해서 CNN은 단어 표현에 효율적이다. 단어사전이 굉장히 큰 경우 3-gram만 해도 비용이 급격하게 증가한다. 심지어 구글조차 5-gram이상의 것들은 제공하지 않는다. Convolutional Filter는 전체 단어 사전 없이도 자동으로 좋은 단어표현을 학습시킨다. 그리고 이 필터의 크기가 5보다 크더라도 문제가 되지 않는다. 첫 번째 레이어에서 학습된 많은 필터가 n-gram과 유사하다고 생각한다. 그러나 조금 간결한 방법으로 표현한다.&lt;/p&gt;

&lt;h4 id=&quot;cnn-hyperparameters&quot;&gt;CNN Hyperparameters&lt;/h4&gt;

&lt;p&gt;CNN이 어떻게 NLP 문제에 적용되는지 설명하기 전에 우선 Convolutional Neural Network를 만들 때 필요한 몇 가지 선택안에 대해서 살펴보자. 몇 가지 방안에 대해서 본다면 관련 분야에서 이해가 더 쉬워질 것이다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Narrow vs Wide Convolution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;위에서 Convolution을 설명할 때 자세한 내용은 생략했었다. 3x3 필터를 input의 중간에는 적용하는 것이 직관적이지만 가장 자리에는 3의 크기가 안나올 수 있다. 이런 경우는 어떻게 할까? 다들 알다시피 zero padding을 사용한다. 가장 자리에 추가로 모든 원소가 0을 갖도록 만들어 주는 것이다. 패딩을 함으로써 모든 matrix의 모든 요소에 대해 convolution을 수행할 수 있게 된다. 그리고 그 뿐만 아니라 input에 비해 좀 더 크거나 동일한 크기의 output을 갖게 된다. 즉 zero padding을 더한 것을 &lt;em&gt;wide convolution&lt;/em&gt; 이라 부르고, 사용하지 않은 것을 &lt;em&gt;narrow convolution&lt;/em&gt; 이라 부른다. 두 가지 방법을 1-dimension에 적용시킨 것을 그림으로 나타내면 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.wildml.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-05-at-9.47.41-AM-1024x261.png&quot; alt=&quot;navswi&quot; /&gt;&lt;/p&gt;

&lt;p&gt;필터의 크기가 input 크기에 비해 상대적으로 큰 경우에 wide convolution을 필요로 한다. 위의 그림에서 narrow convolution(왼쪽)은 output size가 $(7-5)+1=3$이 되고, wide convolution(오른쪽)은 output size가 $(7+2*4-5)+1=11$이 된다. 더 일반적으로 공식으로 본다면 output 크기는 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;n_{\text{out}}=(n_{\text{in}}+2\times n_{\text{padding}}-n_{\text{filter}})+1&lt;/script&gt;

&lt;p&gt;&lt;strong&gt;Stride Size&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;padding이외에 또 다른 hyperparameter는 stride size이다. 각 단게에서 필터가 얼만큼 움직여서 convolution을 수행할 지 결정하는 것이다. 위의 모든 그림은 stride가 1로 설정했을 때이고 이 경우에 convolution되는 부분이 겹쳐진다. 만약 stride를 크게 잡는다면 필터가 더 적게 사용될 것이고 output size도 작아질 것이다. 다음의 그림은 &lt;a href=&quot;http://cs231n.github.io/convolutional-networks/&quot;&gt;cs231&lt;/a&gt;의 stride 크기가 1과 2인 예제이다.&lt;/p&gt;

&lt;p&gt;보통의 경우 stride는 1로 설정하지만 더 큰 stride사용한다면 Recursive Neural Network와 비슷한 효과를 만든다. 즉 tree구조가 되는 것이다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pooling Layers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CNN의 핵심은 pooling layer이다. 주로 convolution layer 다음에 적용된다. pooling layer는 input 값을 subsample하는 것과 같다. 보통 일반적으로는 max pooling을 사용한다. Pooling은 전체 matrix에 대해서 적용할 필요없이 window 크기를 정하고 해당 window에 대해서 pooling을 진행하면 된다. 아래 그림은 2x2 window로 max pooling을 하는 것을 보여준다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.wildml.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-05-at-2.18.38-PM.png&quot; alt=&quot;max-pool&quot; /&gt;&lt;/p&gt;

&lt;p&gt;그렇다면 풀링은 왜하는 것일까? 두가지 정도의 이유가 있다. 첫 번째 이유는 보통 분류 문제에서 고정된 크기의 output을 만들기 위해서 사용한다. 예를 들면 1000개의 filter를 사용해서 풀링을 하면 input 값에 관계없이 1000-dimension의 output을 만들 수 있다. 이러한 특성은 NLP에서 매우 중요하자 우리가 input으로 길이가 각각 다른 문장을 넣을 수 있게 된 것이다. 언어의 특성상 문장의 길이는 대부분 항상 다른데 풀링을 사용함으로써 고정된 output dimension을 가질 수 있는 것이다.&lt;/p&gt;

&lt;p&gt;그리고 두 번째로는 풀링은 크기(dimension)을 줄이지만, 중요한 정보는 모두 보존하기 때문이다. 각 필터에서 특정 특징들을 잘 추출한다. 예를들면 부정적인 내용인 “not amazing” 같은 것들이다. 만약 이 문구가 문장 어딘가에 등장했다면 필터를 적용하면 이 문구에 대한 수치가 높기 때문에 풀링 결과 그 수치가 나올 것이다. 따라서 풀링을 진행하면 각 필터에서 핵심적인 정보는모두 보존하는 것이다.&lt;/p&gt;

&lt;p&gt;이미지 인식에서 풀링은 기본적인 움직임이나 회전에 대해 불변성을 제공한다. 한 부분에서 풀리을 할 때 output은 이미지를 적은 pixel로 회전하거나 이동시키더라도 거의 동일하다. 비슷한 지역에서 max값은 크게 변하지 않기 떄문이다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Channels&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;마지막으로 필요한 것은 Channel에 대한 개념이다. Channel은 input이 어떤 것이냐에 따라 개념이 매우 달라진다. 예를들어 컬러 이미지를 input으로 한다면 Channel은 RGB 3개의 값을 각각 하나의 channel로 가질 것이다. NLP에서도 다양한 Channel을 생각할 수 있다. 예를 들면 word2vec으로 임베딩한 벡터들이 모인 matrix를 하나의 채널로 glove로 임베딩한 벡터들이 모인 matrix를 또 하나의 채널로 사용할 수도 있다. 또 다른 방법으로는 같은 문장에 대해 각 channel은 서로 다른 언어를 나타내는 방법도 있다.&lt;/p&gt;

&lt;h4 id=&quot;nlp-적용하는-convolutional-neural-network&quot;&gt;NLP 적용하는 Convolutional Neural Network&lt;/h4&gt;

&lt;p&gt;이제 CNN의 자연어 처리 분야에서의 활용을 알아보자. 여러 연구 결과들에 대해서 요약해서 알아보도록 한다. 모든 흥미로운 연구들을 볼 수는 없지만, 최대한 유명한 연구들을 살펴 볼 것이다.&lt;/p&gt;

&lt;p&gt;CNN이 가장 적합한 분야는 당연히 분류 문제일 것이다. 예를들면 감정 분석, 스팸 탐지, 주제 분류 등이 있을 것이다. Convolution 과 Pooling은 단어들의 순서에 관한 정보를 보존하지 않을 것이고, 따라서 순서가 중요한 PoS Tagging이나 Entitiy Extraction은 CNN을 통해 해결하기 어려울 것이다.(불가능은 아니다. 지역 특징을 input에 추가하면 가능하다.)&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://arxiv.org/abs/1408.5882&quot;&gt;Convolutional Neural Networks for Sentence Classification(Kim Y,2014)&lt;/a&gt;은 CNN을 다양한 분류 dataset에 적용했다. 주로 감정 분석과 주제 분류문제이다. CNN architecture는 dataset마다 매우 좋은 성능을 보여줬다. 놀랍게도 논문에 사용된 network는 매우 간단하고 효과가 좋다. input값은 word2vec으로 임베딩된 단어들을 concat시킨 문장이다. 이후에 여러개의 filter로 convolution layer를 통과시킨 후 max-pooling layer를 통과시킨다. 마지막으로는 softmax함수를 사용해 분류를 했다. 그리고 이 논문을 보면 두개의 다른 채널을 사용해 실험했다. 하나의 채널은 정적인 단어 임베딩을 사용했고 나머지 하나는 동적인 단어 임베딩을 사용헀다. 이 네트워크는 기존의 CNN 네트워크 (&lt;a href=&quot;http://arxiv.org/abs/1404.2188&quot;&gt;Kalchbrenner&lt;/a&gt;, &lt;a href=&quot;http://www.aclweb.org/anthology/P15-2058&quot;&gt;Wang&lt;/a&gt;)과 비슷한 구조를 사용했지만 몇가지 layer를 좀 더 추가했다. 추가한 layer는 “semantic clustering”을 하기 위한 layer이다. 아래는 이 논문의 architecture를 보여준다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.wildml.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-06-at-8.03.47-AM-1024x413.png&quot; alt=&quot;yoon.k&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://arxiv.org/abs/1504.01255&quot;&gt;Effective use of Word Order for Text Categorization with Convolutional Neural Network(Johnson R &amp;amp; Zhang T, 2015)&lt;/a&gt;에서는 word2vec이나 Glove와 같은 걸로 임베딩시키지 않고 학습을 시킨다. one-hot vector를 바로 convolution하는 것이다. 저자는 space efficient bag of words like representation을 제안했다. 이는 학습해야 할 파라미터 수를 줄여준다.&lt;/p&gt;

&lt;p&gt;그리고 &lt;a href=&quot;https://papers.nips.cc/paper/5849-semi-supervised-convolutional-neural-networks-for-text-categorization-via-region-embedding&quot;&gt;Semi-supervised Convolutional Neural Networks for Text Categorization via Region Embedding(Johnson R &amp;amp; Zhang T, 2015)&lt;/a&gt;에서는 모델을 더욱 확장시켜서 text region의 context를 예측하는 CNN을 학습시키위해 unsupervised “region embedding”을 추가했다. 이러한 접근은 긴 글에서(ex.영화 리뷰) 더욱 잘 동작한다. 그러나 짧은 문장에서는(ex. tweets)에서는 좋은 성능을 보장하지는 않는다. 직관적으로 짧은 문장에서 미리 학습된 단어 임베딩을 사용하는 것이 긴 문장에서 사용하는 것 보다 더 많은 효율을 얻을 수 있다.&lt;/p&gt;

&lt;p&gt;CNN 구조를 만드는 것은 위에서 소개된 것들처럼 많은 hyperparameter를 선택해야 한다. 선택해야 하는 것들은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Input representation (word2vec, Glove, one-hot)&lt;/li&gt;
  &lt;li&gt;필터의 크기&lt;/li&gt;
  &lt;li&gt;풀링 전략(max, average)&lt;/li&gt;
  &lt;li&gt;활성화 함수(ReLU, tanh)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;http://www.aclweb.org/anthology/P15-2058&quot;&gt;A Sensitivity Analysis of Convolutional Neural Netwroks for Sentence Classification(Zhang Y &amp;amp; Wallace B, 2015)&lt;/a&gt;에서는 CNN architecture에 사용되는 위와 같은 hyperparameter들 각각의 영향에 대해 실증적인 평가를 했다. text classification을 위한 CNN architecture를 직접 만들 계획을 하고 있다면 이 논문을 참고하면서 만드는 것을 추천한다. 몇 가지 나온 결과로는 max-pooling이 항상 average-pooling보다 좋은 성능을 보였고, 필터 크기는 중요하지만 어떤 작업이냐에 따라 다르다는 점이다. 그리고 정규화(regularization)는 NLP 문제에서는 크게 중요하지 않다는 것을 알 수 있다. 하지만 이런 논문 결과를 참고할 때 데이터의 구성이나 크기에 따라 많은 차이가 있을 수 있으므로 데이터가 어떤 구조인지 잘 살펴보고 참고해야 한다.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.cs.nyu.edu/~thien/pubs/vector15.pdf&quot;&gt;Relation Extraction: Perspective from Convolutional Neural Networks. Workshop on Vector Modeling for NLP(Nguyen T.H &amp;amp; Grishman R, 2015)&lt;/a&gt;에서는 관계 추출과 관계 분류 문제에 대해 연구했다. 저자는 우리가 관심있는 개체에 대한 상대적인 단어의 위치를 convolutional layer의 input값으로 사용했다. 이러한 모델은 각 개체의 위치가 주어졌다고 가정하고 각각의 input은 하나의 관계를 포함한다고 가정한다. &lt;a href=&quot;http://ijcai.org/papers15/Papers/IJCAI15-192.pdf&quot;&gt;Sun Y et al&lt;/a&gt;과 &lt;a href=&quot;http://www.aclweb.org/anthology/C14-1220&quot;&gt;Zeng D&lt;/a&gt;도 비슷한 모델을 연구했다.&lt;/p&gt;

&lt;p&gt;또 다른 NLP에서의 CNN활용한 것들 중 흥미로운 것은 Microsoft Research의 &lt;a href=&quot;http://research.microsoft.com/pubs/226584/604_Paper.pdf&quot;&gt;Modeling Interestingness with Deep Neural Network(Gao J et al, 2014)&lt;/a&gt;와 &lt;a href=&quot;http://research.microsoft.com/pubs/226585/cikm2014_cdssm_final.pdf&quot;&gt;A Latent Semantic Model with COnvolutional-Pooling Structure for Information Retrieval(Sehn Y et al, 2014)&lt;/a&gt;이다. 이 논문들에서는 어떻게 정보 추출에서 사용될 수 있게 문장의 의미를 잘 표현할 수 있는 지를 소개한다. 주어진 예제는 사용자가 읽고있는 문서를 기반으로 잠재적으로 의미있는 문서를 추천하는 것이다. 문장 표현은 검색엔진의 log 데이터를 기반으로 학습되었다.&lt;/p&gt;

&lt;p&gt;대부분의 CNN architecture들은 단어와 문장을 임베딩한다. 하지만 모든 논문이 이러한 부분의 학습에 집중하는 것은 아니다. &lt;a href=&quot;http://emnlp2014.org/papers/pdf/EMNLP2014194.pdf&quot;&gt;Semantic Embeddings from Hashtags(Weston J &amp;amp; Adams K, 2014)&lt;/a&gt; 에서는 단어와 문장의 의미있는 임베딩을 만들어 내면서 Facebook의 해시태그를 예측하는 CNN architecture를 소개한다. 그들은 성공적으로 임베딩을 했으며 이 값으로 사용자 클릭 데이터를 기반으로한 문서 추천에 적용했다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Character-Level CNNs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;이때까지는 각 단어를 단위로 했다. 이제는 단어를 단위로 하는 것이 아니라 각 문자들을 바로 CNN에 사용하는 모델들을 알아보자.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://jmlr.org/proceedings/papers/v32/santos14.pdf&quot;&gt;Learning Character-level Representations for Part-of-Speech Tagging(Santos C &amp;amp; Zadrozny B, 2014)&lt;/a&gt;에서는 문자 단위의 임베딩을 학습했다. 그리고 학습한 문자 단위의 임베딩값을 미리 학습된 단어 임베딩을 결합해서 Speech tagging문제를 위한 CNN 구조에 사용했다.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://arxiv.org/abs/1509.01626&quot;&gt;Character-level Convolutional Networks for Text Classification(Zhang X &amp;amp; Zhao J, 2015)&lt;/a&gt;와 &lt;a href=&quot;http://arxiv.org/abs/1502.01710&quot;&gt;Text Understanding from Scratch(Zhang X &amp;amp; LeCun Y, 2015)&lt;/a&gt;에서는 어떠한 사전 학습된 임베딩값도 사용하지 않고 문자 단위로 바로 CNN에 학습시켰다. 여기서 주목할만한 점은 논문의 저자가 상대적으로 깊은 network를 사용했다는 점이다. 총 9층의 network를 사용해서 감정 분석과 Text Categorization 문제에 활용했다. 문자 단위를 바로 학습시킨 결과는 매우 큰 데이터셋(수 백만~)에서 잘 동작했다. 그러나 상대적으로 적은 데이터셋(수백~수천)에서는 좋은 결과를 보이지 못했다.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://arxiv.org/abs/1508.06615&quot;&gt;Character-Aware Neural Language Models(Kim Y et al, 2015)&lt;/a&gt;에서는 문자 단위의 CNN의 output값을 LSTM의 각 time step의 input으로 활용한 모델을 연구했다. 이 모델은 다양한 언어에 적용되었다.&lt;/p&gt;

&lt;p&gt;여기까지가 CNN의 NLP문제에서의 활용에 대한 간략한 소개였다. 놀라운점은 위에 소개된 논문들이 불과 지난 2~3년밖에 안된 논문들이라는 점이다. 분명히 이전에서 NLP에서의 CNN의 활용이 있었지만 새로운 결과와 발표되는 최고수준의 시스템들은 계속해서 과속화되고 있다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;긴글 읽어주셔서 감사합니다. 오역 및 잘못된 내용이 있을 수 있습니다. 잘못된 부분 혹은 이해가 잘 안되는 부분은 댓글 혹은 메일로 말씀해주시면 감사하겠습니다!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>TF-IDF : Term Frequency-Inverse Document Frequency</title>
   <link href="https://reniew.github.io/24/"/>
   <updated>2018-08-01T04:47:35+00:00</updated>
   <id>https://reniew.github.io/24</id>
   <content type="html">&lt;p&gt;정보 검색분야에서 자주 사용되는 TF-IDF에 대해서 소개하려 한다. 뉴스 기사에서 키워드 추천을 위한 수치로도 많이 사용되는 이 값은 NLP분야에서도 다른 기법과 함께 사용되며 score를 올려주는 부가적인 기법으로 자주 사용된다.&lt;/p&gt;

&lt;p&gt;TF-IDF는 Term frequency - Inverse document frequency의 약자로 특정 단어에 대해서 단어가 얼마나 자주 등장하는지, 그리고 다른 문서에 대비해서 이 문서에 많이 등장하는 단어인지를 측정하는 수치로 이해할 수 있다.&lt;/p&gt;

&lt;p&gt;용어를 보면 알 수 있듯이 TF-IDF는 TF라는 수치와 IDF라는 수치 두가지를 사용했다. 우선 TF, Term Frequency에 대해서 알아본다.&lt;/p&gt;

&lt;h4 id=&quot;term-frequency&quot;&gt;Term Frequency&lt;/h4&gt;

&lt;p&gt;Term Frequency는 문장 docunment($d$)안에서 특정 term($t$)이 몇 번 등장했는지를 나타낸다. 예를 들어 뉴스 기사에서 ‘인공지능’이라는 단어가 총 4번 등장 했다면 이 documnet의 TF값은 4가 되는 것이다. 위 수치는 다음과 같이 표기된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;tf(t,d) = f_{t,d}&lt;/script&gt;

&lt;p&gt;여기서 $f_{f,d}$값은 위에서 말한 문서안에서 term이 나온 횟수자체이다. 하지만 경우에 따라서 tf값을 나온 수치 그대로 사용하는 것이 아니라 변형해서 사용하기도 한다. tf 값을 정의하는 여러 방법들은 아래와 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;binary 값(Boolean), 문서 안에 나왔다면 1, 아니면 0&lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;tf(t,d) =
\begin{cases}
1, \text{ if t occur in d}\\
0, \text{ otherwise}
\end{cases}&lt;/script&gt;

&lt;ul&gt;
  &lt;li&gt;나온 횟수&lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;tf(t,d) = f_{t,d}&lt;/script&gt;

&lt;ul&gt;
  &lt;li&gt;문서안의 전체 term들의 $f$ 값들의 합으로 나눈 값, 전체 문장 길이를 반영한다. 단순히 나온 횟수만 보게 된다면 매우 긴 문장에서 4번 나온 수치와 짧은 문장에서 4번 나온 수치를 같은 값으로 보게 된다.&lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;tf(t,d) = \frac{f_{t,d}}{\sum_{t'\in d}f_{t',d}}&lt;/script&gt;

&lt;ul&gt;
  &lt;li&gt;나온 횟수를 log scale로 바꾼 값, 많이 등장한 것에 대해서 가중치를 줄이는 방법.&lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;log(1+f_{t,d})&lt;/script&gt;

&lt;ul&gt;
  &lt;li&gt;증가된 수치, 긴 문서에서 편향되는 것을 막는 방법&lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;tf(d,f) = 0.5+0.5\frac{f_{t,d}}{max\{f_{t',d},t'\in d\}}&lt;/script&gt;

&lt;p&gt;TF에 대해서 알아보았다. 이제는 IDF를 소개한다. IDF는 Inverse Document Frequency의 약자로 Document Frequency값을 역수로 만든 값을 의미한다. 그렇다면 DF에 대해서 먼저 알아보도록하자.&lt;/p&gt;

&lt;h4 id=&quot;document-frequency&quot;&gt;Document Frequency&lt;/h4&gt;

&lt;p&gt;DF는 한 문서만 고려하는 값이 아니다. 여러개의 문서가 있을 때 어떤 특정한 단어(term)이 얼마나 많은 문서에 등장하는지 확인 할 수 있는 값이 된다. 계산은 다음과 같이 한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;df(t,D) = \frac{|\{d\in D:t\in d\}|}{|D|}&lt;/script&gt;

&lt;p&gt;수식에 대해 설명하면, 우선 $D$와 $d$의 차이는 $d$는 개별 문서를 뜻하며 $D$는 전체 문서 집합을 의미한다. 따라서 $df$값은 특정 단어 $t$가 들어가 있는 문서 수를 전체 문서 수로 나눠준 값을 의미한다. $idf(t,D)$ 값은 단순히 이 값을 역수로 만든 값이다. 대체 왜 역수를 취한 값을 사용하는 것일까? 이 $idf$값의 의미는 어떤 문서에 등장한 특정 단어가 다른 문서들에서는 잘 나오지 않은 단어인지 측정하는 척도이다.&lt;/p&gt;

&lt;p&gt;만약 어떤 단어가 다른 문서에는 많이 들어가 있지 않는데 현재 문서에 들어가 있다면 $idf$값은 높게 나올 것이다.&lt;/p&gt;

&lt;h4 id=&quot;tf-idf&quot;&gt;TF-IDF&lt;/h4&gt;

&lt;p&gt;그렇다면 tf-idf의 의미는 다음과 같을 것이다. 현재 해당 문서에서 특정 단어가 나온 횟수값과 그리고 이 단어가 다른 문서에는 잘 나오지 않는 그런 단어인지를 같이 고려하는 것이다. 이 값의 계산은 다음과 같이 두 값을 곱해주기만 하면 된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;tfidf(t,d,D) = tf(t,d)\times idf(t,D)&lt;/script&gt;

&lt;p&gt;마지막으로 이 값을 보는 이유에 대해서 설명을 하자면 각 단어에 대해 중요도를 보는 것이다. 얼마나 자주 등장한 단어인지, 그리고 그 단어가 다른 문서들에는 자주 나오지 않고 해당 문서에서 중요도가 높은 단어인지를 알 수 있다.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Glove : Global Vectors for Word Representation</title>
   <link href="https://reniew.github.io/23/"/>
   <updated>2018-07-27T04:47:35+00:00</updated>
   <id>https://reniew.github.io/23</id>
   <content type="html">&lt;p&gt;지난 포스트에서는 단어 임베딩 기술인 Word2Vec에 대해서 알아보았다. 이번에는 또 다른 단어 임베딩 기술 중 하나인 Glove에 대해서 알아 보도록한다. 이번 포스트는 요약이 아닌 논문의 흐름을 따라 설명한다. (&lt;a href=&quot;https://nlp.stanford.edu/pubs/glove.pdf&quot;&gt;Paper&lt;/a&gt;)&lt;/p&gt;

&lt;h4 id=&quot;glove&quot;&gt;Glove&lt;/h4&gt;

&lt;p&gt;GLove란 Global Vectors for Word Represnetation의 약자로 미국의 Stanford대학에서 2014년 개발한 기술로 Word2Vec과 마찬가지로 단어 임베딩 과정에서 많이 쓰이는 기법이다.&lt;/p&gt;

&lt;p&gt;Glove에 대한 설명을 하기 전 기존의 단어 임베딩 기술에 대해서 먼저 보자. 기존의 단어 임베딩의 경우 크게 두 가지 범주로 나눌 수 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Matrix Factorization Method&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Shallow Window-Based Method&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;두가지 분류에 대해서 하나씩 알아보자. 먼저 Matrix Factorization Method는 LSA, HAL와 같은 것들이 있다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;LSA&lt;/strong&gt; 에 대해서 간단히 설명을 하자면 전체 문장에서 단어들의 동시 등장정보(공기정보, Co-occurrence)를 이용한다. 전체 문장에 있는 모든 단어에 대해 동시등장정보들을 matrix로 만들어 준다. 하지만 여기에 큰 문제점이 있다. matrix의 크기가 매우 크고 sparse하다는 문제점인데 이를 해결하기 위한 기법이 SVD(Singular Value Decomposition)이다. 이 기법을 이용해 matrix의 차원을 줄이고 dense하게 만들어준다. 이러한 내용이 LSA의 전체적인 내용이다. 자세한 내용을 설명하기엔 전체적인 맥락에 벗어나므로 다음 기회에 설명하도록 한다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;이러한 Matrix Factorization Method는 global한 statical information을 잘 잡아내고 학습이 빠르다는 큰 장점은 있지만 단어 유사도 외의 문제에는 적용하기 어렵고 새로운 단어에 추가시키려면 처음부터 다시 해야한다는 단점이 있다.&lt;/p&gt;

&lt;p&gt;그리고Shallow Window-Based Method의 경우는 이전 포스트에서 알아봤던 Word2Vec의 CBOW모델과 Skip-Gram 모델, 그리고 NNLM, HLBL등의 모델들은 뜻한다. Word2Vec에 대한 자세한 설명은 이전 포스트를 참고하자(&lt;a href=&quot;https://reniew.github.io/21/&quot;&gt;Word2Vec(1)&lt;/a&gt;, &lt;a href=&quot;https://reniew.github.io/22/&quot;&gt;Word2Vec(2)&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Shallow Window-Based Method은 우선 성능이 매우 좋다는 것이 가장 큰 장점이다. 그리고 복잡한 패턴을 dense한 vector로 만들면서 잘잡아낸다는 장점이 있지만, 통계적인 자료를 활용하는데 비효율적이다라는 단점이 있다. 위 내용들을 요약하면 다음과 같다.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Counte based&lt;/th&gt;
      &lt;th&gt;Shallow Window-Based Method&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;LSA, HAL&lt;/td&gt;
      &lt;td&gt;NNLM, SkipGram, CBOW&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;학습이 빠르다, 전체의 통계정보를 활용한다.&lt;/td&gt;
      &lt;td&gt;성능이 좋다, 패턴을 잘 잡아낸다.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;단어 유사도 외의 문제에 적용이 어렵다.&lt;/td&gt;
      &lt;td&gt;전체적인 통계정보를 활용하기 어렵다.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Glove는 자신의 모델을 설명할 때 위와 같은 기존의 단어 임베딩 기술들에 대한 문제점들을 해결하려 했다고 합니다. 대표적으로 Word2Vec과 LSA에 대한 단점들에 대해 얘기합니다. 해당 글을 소개하면 다음과 같습니다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;While methods like LSA efficiently leverage statistical information, they do relatively poorly on the word analogy task, indicating a sub-optimal vector space structure. Methods like skip-gram may do better on the analogy ask, but they poorly utilize the statistics of the corpus since they train on separate local context windows instead of on global co-occurrence counts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;즉 이전에 설명한 것과 같은 내용입니다. LSA의 경우 단어 분석 문제에는 적합하지 않고, Skip-gram과 같은 방법의 경우는 분석에는 적합하지만 global한 co-occurrence(동시등장) 정보와 같은 통계치를 활용하기에는 적합하지 않다는 것입니다.&lt;/p&gt;

&lt;p&gt;따라서 Glove는 이러한 문제점들을 해결하는데 초점을 맞췄습니다. 먼저 동시 등장 정보를 활용하기 위해 Co-occurrence Matrix를 정의합니다.&lt;/p&gt;

&lt;h4 id=&quot;co-occurrence-matrix&quot;&gt;Co-occurrence Matrix&lt;/h4&gt;

&lt;p&gt;Co-occurrence Matrix는 $X$라 부르고 행렬의 원소 $X_{ij}$는 단어 $i$의 context안에서 단어$j$가 등장한 횟수로 정의한다.&lt;/p&gt;

&lt;p&gt;그리고 $X_i$는 단어 $i$의 context안에 등장한 단어들의 총 수라 하자. 수식은 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;X_i=\sum_k X_{ik}&lt;/script&gt;

&lt;p&gt;이러한 행렬의 계산은 말뭉치가 커질 수록 계산량이 급증한다. 예를들어 10,000개의 말뭉치가 있다면 행렬은 총 1억개의 원소를 가지게 된다. 하지만 이 Matrix의 경우 여러번 계산하는 것이 아니라 모델 초반에 한번만 계산하면 된다는 점이 있다.&lt;/p&gt;

&lt;h4 id=&quot;objective-function&quot;&gt;Objective function&lt;/h4&gt;

&lt;p&gt;확률 $P_{ij}$은 단어 $i$의 context안에서 단어 $j$가 등장할 확률이라 하고 다음과 같이 정의한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;P_{ij}=P(j|i)=\frac{X_{ij}}{X_j}&lt;/script&gt;

&lt;p&gt;정의한 확률에 대한 직관적인 이해를 위해 간단한 예를 들어 보자. 두 개의 별개의 단어를 정의하자. 단어 i를 ‘ice’ 라고하고 단어 j를 ‘steam’ 이라고 하자.&lt;/p&gt;

&lt;p&gt;이제 두 단어 사이의 관계에 대해서 알아보려고 한다. 이 경우 우리는 다른 여러가지 단어 $k$ 들에 대한 동시 등장 확률(Co-occurrence Plobability, 위에서 정의한 $P$)의 비율을 확인하면 될 것이다.&lt;/p&gt;

&lt;p&gt;먼저 ice에서는 관련되었지만 steam에는 관련없는 단어를 단어 $k$에 지정하자. 단어 $k$를 ‘solid’라고 한다. 이 경우 확률들의 비율인 $\frac{P_{ik}}{P_{jk}}$는 커질 것이다. 그리고 이번에는 ice에 관련 없고 steam에 관련있는 단어인 ‘gas’를 단어 $k$로 정하자. 이 경우 확률의 비율은 작아질 것이다. 만약 두 단어 모두에 연관있는 ‘water’의 경우나 두 단어 모두에 연관이 없는 ‘fashion’의 경우에는 비율이 1에 가깝게 결정될 것이다.
&lt;img src=&quot;https://i.imgur.com/LKjp70Z.jpg&quot; alt=&quot;glove&quot; /&gt;
이 결과를 통해 우리는 연관없는 단어를 구분하는 것이 쉽다는 것을 알 수 있다.
따라서 우리는 두 단어에 대한 직접적인 확률이 아니라, 다른 단어에 대한 각각의 확률에 대한 수식을 새우는 것을 목표로한다. 먼저 일반화된 모델을 제시한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;F(w_i,w_j,\tilde{w}_k)=\frac{P_{ik}}{P_{jk}}&lt;/script&gt;

&lt;p&gt;여기서 $w\in\mathbb{R}^d$는 단어 벡터이고 $\tilde{w}\in\mathbb{R}^d$는 separate context 단어 벡터이다.&lt;/p&gt;

&lt;p&gt;위 수식 중 $F$는 확률에 대한 비율을 정보를 포함해야할 것이다. 그리고 그 정보는 단어 벡터 공간안의 정보여야할 것이므로 두 비율은 벡터들의 차이로 해석할 수 있을 것이다. 따라서 수식을 다음과 같이 수정한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;F(w_i-w_j,\tilde{w}_k)=\frac{P_{ik}}{P_{jk}}&lt;/script&gt;

&lt;p&gt;아직까지 정의한 식에서 애매한 부분이 있다. 함수의 인자가 되는 값들은 vector인데 수식의 우변에 있는 값들은 scalar값이다. 따라서 좌변의 인자값을 내적하는 것으로 수정한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;F((w_i-w_j)^T\tilde{w}_k)=\frac{P_{ik}}{P_{jk}}&lt;/script&gt;

&lt;p&gt;이제 동시 등장 행렬에 대해 중요한 것은 단어 $j$와 context 단어인 단어 $i$는 무작위로 선택되는 것이기 때문에 이 둘의 역활을 자유롭게 바꿀 수 있어야 한다. 따라서 아래의 조건을 만족해야 한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;w\leftrightarrow\tilde{w}&lt;/script&gt;

&lt;p&gt;이렇게 되면 행렬 $X$는 symetric 해야한다. 즉,&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;X\leftrightarrow X^T&lt;/script&gt;

&lt;p&gt;최종적으로 마지막 모델은 각 단어에 라벨링하는 것에 따라 변하지 않아야 한다. 그러나 아직 위의 $F$함수는 그렇지 않기 떄문에 두 가지 조건을 만족하도록 해야한다. 첫 째로는 Homomorphism 조건이다. 즉, $F$가 Homomorphism해야 한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\text{Homomorphism} ~F : (\mathbb{R},+)\rightarrow(\mathbb{R_{&gt;0}},\times)&lt;/script&gt;

&lt;p&gt;위 조건을 만족시킨다면 함수 $F$는 다음의 수식을 만족시킨다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;F((w_i-w_j)^T\tilde{w}_k)=\frac{F(w_i^T\tilde{w}_k)}{F(w_j^T\tilde{w}_k)}&lt;/script&gt;

&lt;p&gt;우변의 각 $F$는 원래 식과 같으므로 다음을 만족한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;F(w_i^T\tilde{w}_k)=P_{ik}=\frac{X_{ik}}{X_i}&lt;/script&gt;

&lt;p&gt;이제 함수 $F$를 정해야 한다. 위의 Homomorphism 조건을 만족시키는 함수들 중 exponential함수를 이용하면 된다. 따라서 $F=exp$로 정의한다. 이 경우 아래 수식을 만족할 것이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
&amp;F(w_i^T\tilde{w}_k)=P_{ik}\\
&amp;\Leftrightarrow exp(w_i^T\tilde{w}_k)=P_{ik}\\
&amp;\Leftrightarrow w_i^T\tilde{w}_k=\log(P_{ik})=\log(X_{ik})-\log(X_i)
\end{align*} %]]&gt;&lt;/script&gt;

&lt;p&gt;하지만 위의 마지막 수식을 보자 아직 $\log(X_i)$ 때문에 수식이 symmetric하지 않다. 하지만 위 식은 $k$에 대해 independent하기 떄문에 bias를 각각 더함으로써 이 문제를 해결할 수 있다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;w_i^T\tilde{w}_k+b_i+\tilde{b}_k=\log(X_{ik})&lt;/script&gt;

&lt;p&gt;따라서 우리는 위의 식을 만족하도록 모델을 만들 것이다. 따라서 목적함수는 Least sqares regression 함수로한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;J=\sum_{i,j=1}^V(w_i^T\tilde{w}_j+b_i+\tilde{b}_j-\log{X_{ij}})^2&lt;/script&gt;

&lt;p&gt;아직 이 수식에는 큰 문제점이 있다. $X$ 행렬은 sparse한 매트릭스인데 log함수를 넣으면 행렬값이 0 이될경우 발산하기 때문에 계산이 불가능해진다. 따라서 행렬 $X$에 대해서 모든 원소에 1을 더해주면 이 문제는 해결할 수 있다.
하지만 이러한 해결방법은 또 다른 문제를 야기한다. 행렬 $X$의 경우 매우 sparse해서 보통 원래 원소값이 0인 경우가 75~95%정도 되는데 우리가 모든 원소에 1을 더함으로써 거의 안나오는 경우와 한번도 안나오는 경우를 같은 동시 등장 값을 가진다. 따라서 우리는 Weighting 함수를 추가한 목적함수를 만든다 Weighting 함수 $f$는 다음의 특징을 가지며, 수식은 아래와 같이 정의한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;$f(0)=0$ 이다. 행렬 $X_{ij}$값이 0이더라도 발산하지 않게끔 하기 위함이다.&lt;/li&gt;
  &lt;li&gt;$f(x)$는 non-decreasing 해야한다. 드물게 등장하는 경우에 overweighted 되지 않게 하기 위함이다.&lt;/li&gt;
  &lt;li&gt;$f(x)$는 $x$값이 클 경우 상대적으로 작은 값을 가져야 한다. 자주 등장하는 단어가 overweighted 되지 않도록 한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
f(x) =
\begin{cases}
(x/x_{\text{max}})^\alpha~~,\text{if}~x&lt;x_{\text{max}}\\
1,~~otherwise
\end{cases} %]]&gt;&lt;/script&gt;

&lt;p&gt;$x_{\text{max}}$와 \alpha값은 직접 지정해줘야 하는 hyperparameter이다. 논문에 따르면 $\alpha=3/4$와 $x_{\text{max}}=100$이 가장 좋은 결과를 만들었다고 한다.&lt;/p&gt;

&lt;p&gt;이제 마지막으로 weighted least squares 함수를 정의하자.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;J=\sum_{i,j=1}^Vf(X_{ij})(w_i^T\tilde{w}_j+b_i+\tilde{b}_j-\log{X_{ij}})^2&lt;/script&gt;

&lt;p&gt;위의 목적함수를 학습시킨 후 나온 $w$벡터를 임베딩 벡터로 사용한다.&lt;/p&gt;

&lt;p&gt;마지막으로 논문에서 여러 임베딩 기법들을 비교한 자료를 보며 포스트를 마치도록 한다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/fkpbxsn.jpg&quot; alt=&quot;glove2&quot; /&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Word2Vec (2) : Skip Gram 모델 & 튜닝 기법</title>
   <link href="https://reniew.github.io/22/"/>
   <updated>2018-07-24T04:47:35+00:00</updated>
   <id>https://reniew.github.io/22</id>
   <content type="html">&lt;ol&gt;
  &lt;li&gt;Word Embedding &amp;amp; Word2Vec(CBOW model) (&lt;a href=&quot;https://reniew.github.io/21/&quot;&gt;이전 포스트&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Word2Vec(Skip-Gram) &amp;amp; 튜닝 기법&lt;/li&gt;
&lt;/ol&gt;

&lt;h4 id=&quot;skip-gram&quot;&gt;Skip-Gram&lt;/h4&gt;

&lt;p&gt;이제는 Word2Vec의 두 번째 모델인 Skip-Gram 모델에 대해서 알아보도록 한다. CBOW와 비슷한 아이디어지만 반대의 개념이다. CBOW는 주변 단어들을 통해서 중간의 단어를 예측하는 모델이였다면 Skip-Gram은 중심 단어를 통해 주변단어를 예측하는 모델이다. 아래 예시를 보자.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;__ __ __ 배가 __ __ __ __&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;위의 예시와 같이 중간의 단어를 통해 주변단어를 예측하는 모델이다. 아키텍쳐 또한 CBOW와 반대라고 생각하면 된다. 아래 그림을 보자.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/c4sUimp.png&quot; alt=&quot;skip&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Skip-Gram 모델이 진행되는 과정에 대해서 알아보자.&lt;/p&gt;

&lt;p&gt;가운데 단어를 one-hot vector로 만들어 준다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;x\in\mathbb{R}^{|V|}&lt;/script&gt;

&lt;p&gt;다음으로 파라미터 매트릭스인 $\mathbf{W}_{V\times N}$를 중간 단어 one-hot vector에 곱해줘서 embedded vector를 구한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;v_c=\mathbf{W}x\in\mathbb{R}^n&lt;/script&gt;

&lt;p&gt;embedded vector를 두 번째 파라미터 매트릭스인 $\mathbf{W^{\prime}}$를 곱해서 score vector를 계산한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;z=\mathbf{W}^{\prime}v_c&lt;/script&gt;

&lt;p&gt;이제 위에서 구한 각 score vector에 대해서 확률값으로 만들어 준다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\hat{y}=\text{softmax}(z)&lt;/script&gt;

&lt;p&gt;Skip-Gram의 모델의 경우 context의 주변 단어 모두를 예측하기 때문에 확률 값이 다음과 같이 $2m$개 나올것이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\hat{y}_{c-m}, ..., \hat{y}_{c-1},\hat{y}_{c+1},...,\hat{y}_{c+m}&lt;/script&gt;

&lt;p&gt;이제 구한 확률값에 대해서 각 위치의 정답과 비교한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;y^{(c-m)},...,y^{(c-1)},y^{(c+1)},...,y^{(c+m)}&lt;/script&gt;

&lt;p&gt;이제 학습을 위해 Objective function은 다음과 같이 정의하고 최소화 할 것이다.
여기서 중요한 CBOW와의 차이점은 우리가 각 단어에 대해 독립이라고 가정을 한다는 것이다. 즉 중심 단어에 대해 주변 단어들을 완벽하게 독립적이라고 가정하는 것이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
\text{minimize}~J&amp;=-\log P(w_{c-m},...,w_{c-1},w_{c+1},...,w_{c+m}|w_c)\\
&amp;=-\log \prod^{2m}_{j=0,j\ne m} P(w_{c-m+j}|w_c)\\
&amp;=-\log \prod^{2m}_{j=0,j\ne m}\frac{\exp(u^{\intercal}_{c-m+j}v_c)}{\sum_{k=1}^{|V|}\exp(u_k^{\intercal}v_c)}\\
&amp;=-\sum^{2m}_{j=0, j\ne m}u^{\intercal}_{c-m+j}v_c+2m\log\sum^{|V|}_{k=1}\exp(u_k^{\intercal}v_c)
\end{align*} %]]&gt;&lt;/script&gt;

&lt;p&gt;CBOW 모델과 같이 확률값을 cross-entropy함수로 정의된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
J&amp;=-\sum^{2m}_{j=0,j\ne m}\log P(u_{c-m+j}|v_c)\\
&amp;=\sum^{2m}_{j=0,j\ne m}H(\hat{y},y_{c-m+j})
\end{align*} %]]&gt;&lt;/script&gt;

&lt;p&gt;여기서 $H()$가 cross entropy가 된다.
여기까지가 Skip-Gram에 대한 소개다. 하지만 이번 포스트에서는 skip-gram을 좀 더 빠르고 효율적으로 만드는 세가지 기법에 대해서 소개한다.&lt;/p&gt;

&lt;h4 id=&quot;subsampling-frequent-words&quot;&gt;Subsampling Frequent words&lt;/h4&gt;

&lt;p&gt;Skip-Gram모델은 중심 단어에 대해서 주변 단어를 예측하며 Update하기 때문에 CBOW모델보다 각 단어에 대해서 update 기회가 더 많다(&lt;em&gt;SkipGram모델을 CBOW보다 많이 쓰는 이유이기도 하다.&lt;/em&gt;). 아래 그림을 보면 Skip-Gram이 학습을 진행하는 과정에 대해서 볼 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://mccormickml.com/assets/word2vec/training_data.png&quot; alt=&quot;skgm&quot; /&gt;&lt;/p&gt;

&lt;p&gt;학습 과정을 보면 단어 “the”와 다른 단어들이 같이 trainning되는 경우가 많다는 것을 볼 수 있다. 이 그림은 하나의 Sentence에 대해서 본 것이지만 실제 학습은 전체 Data에 대해서 진행 할 것이다. Data안에서 “the” 라는 단어와 함께 update 되는 것들이 얼마나 많을지 생각해보자. 단어의 특성상 Data안에서 매우 자주 등장할 것이고 그 만큼 update되는 횟수도 많은 것이다. 하지만 update되는 횟수에 비해 “the”라는 단어가 의미적으로 중요하지도 않다. 이러한 경우 학습시간만 증가시킬뿐 학습 정확도에는 크게 기여하지 않는다. 이런 문제를 해결하는 방법이 Subsampling Frequent words이다.&lt;/p&gt;

&lt;p&gt;Subsampling하는 방법은 학습시에 단어들을 무작위로 제외시키는 것이다. 만약 자주 등장하는 단어라면 더 자주 제외시켜야한다. 단어별로 제외되는 확률은 다음과 같이 정의된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;P(w_i) = 1- \sqrt{\frac{t}{f(w_i)}}&lt;/script&gt;

&lt;p&gt;위 식에서 $f()$는 각 단어의 전체 Data에서 출현하는 횟수이다. 즉 자주등장하는 단어일수록 확률값을 줄어들게 된다. 그리고 $t$는 HyperParameter값으로 논문의 연구진들은 $t$값으로 $0.00001(10^{-5})$ 값을 추천한다.&lt;/p&gt;

&lt;h4 id=&quot;negative-sampling&quot;&gt;Negative Sampling&lt;/h4&gt;

&lt;p&gt;그리고 Skip-Gram모델의 Objective function을 다시 한번 보자. Summation이 $|V|$번 돌고 있다는 것을 볼 수 있다. $|V|$은 vocabulary의 크기로 단어의 개수는 수만에서 수백만 까지도 될 수 있다는 점을 기억하자. 직관적으로 봐도 이 식을 계산하는 것은 매우 오래걸릴 것 같다. 실제로도 오래걸린다.&lt;/p&gt;

&lt;p&gt;그렇다면 학습 과정에서 속도를 올려줄 수 있는 방법은 무었일까?
방법은 정확한 계산을 하지 않고 계산량을 줄인 다음 근사시키는 방법이다. 이러한 방법 중 하나인 Negative Samgpling 방법에 대해서 소개한다.&lt;/p&gt;

&lt;p&gt;Negative Sampling의 방법은 다음과 같다. 기존의 확률계산(Softmax 계산)에서는 모든단어에 대해서 전체 경우를 구했지만, 여기서는 현재 Window내에서 등장하지 않는단어를 특정개수만 뽑아서 확률을 계산하는 것이다. 예를들면 Window size가 5라면 window내에 등장하지 않는 Data내의 다른 단어 5~25개 정도의 단어를뽑아서 확률을 계산하는 것이다.&lt;/p&gt;

&lt;p&gt;Negative Sampling을 사용하기위해 Objective function을 다시 정의한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;J_t(\theta)=\log\sigma(u_o^\intercal v_c)+\sum_{j\sim P(w)}[\log\sigma(-u_j^\intercal v_c)]&lt;/script&gt;

&lt;p&gt;여기서 확률 $P()$는 ‘Unigram Distribution’이며 다음과 같이 정의한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;P(w_i)=\frac{f(w_i)^{3/4}}{\sum_{j=0}^n(f(w_j)^{3/4})}&lt;/script&gt;

&lt;p&gt;3/4같은 수는 고정값으로 논문에 따르면 다른 값들에 비해 성능을 가장 잘 내는 값이라고 한다.&lt;/p&gt;

&lt;h4 id=&quot;hierarchical-softmax&quot;&gt;Hierarchical Softmax&lt;/h4&gt;

&lt;p&gt;Hierarchical Softmax는 기존의 계산량이 많은 Softmax함수 대신 사용해서 계산량을 줄이는 방법 중 하나이다. 이름 그대로 Softmax를 전체로 계산하기 보다는 Tree구조로 Hierarchical하게 Softmax를 계산한다. 먼저 그림을 보자.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://shuuki4.files.wordpress.com/2016/01/hsexample.png&quot; alt=&quot;hi soft&quot; /&gt;&lt;/p&gt;

&lt;p&gt;각 단어에 대해 Softmax를 계산하려면 우선 node값부터 해당 word까지 내려가면서 각 값을 곱하는 방법이다. Hierarchical의 계산과정에 대한 자세한 설명을 생략한다. 자세히 알고 싶다면 이 &lt;a href=&quot;http://building-babylon.net/2017/08/01/hierarchical-softmax/&quot;&gt;링크&lt;/a&gt;를 통해 확인하자.&lt;/p&gt;

&lt;p&gt;Hierarchical Softmax와 Negative Sampling은 확률 값 계산의 계산량을 줄이기 위한 방법으로 목적이 같다. 따라서 택일하여 사용해야한다.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Word2Vec (1) : 단어 임베딩 & CBOW 모델</title>
   <link href="https://reniew.github.io/21/"/>
   <updated>2018-07-21T04:47:35+00:00</updated>
   <id>https://reniew.github.io/21</id>
   <content type="html">&lt;h4 id=&quot;word2vec&quot;&gt;Word2Vec&lt;/h4&gt;

&lt;p&gt;NLP에 처음 공부하고 부터 계속해서 듣고 사용하는 기술 중 하나는 무엇보다도 Word2Vec이다. 기존의 one-hot vector 방식의 단어 표현은 단어간 유사도를 전혀 표현할 수 없다는 치명적인 단점을 해결하기 위해 Google에서 나온 기술로 단어들의 특정 dimension의 vector로 만들어 주는 word embedding의 대표적인 방법이다.&lt;/p&gt;

&lt;p&gt;매번 라이브러리를 사용해 Word2Vec을 사용만해와서 학습과정이나 모델의 세부적인 내용에 대해서는 잘 알지 못했는데 cs224n 강의를 들으면서 이번 기회에 정리를 해보려한다.&lt;/p&gt;

&lt;p&gt;다음의 순서로 Word2Vec을 소개하려한다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Word Embedding &amp;amp; Word2Vec(CBOW model)&lt;/li&gt;
  &lt;li&gt;Word2Vec(Skip-Gram) &amp;amp; 튜닝 기법(&lt;a href=&quot;https://reniew.github.io/22/&quot;&gt;다음 포스트&lt;/a&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;wordembedding&quot;&gt;WordEmbedding&lt;/h4&gt;

&lt;p&gt;컴퓨가 문장을 어떻게 이해할까? 컴퓨터의 경우 문자를 유니코드의 집합으로 읽을 것이다. 따라서 컴퓨터가 문장의 뜻이나 문장간의 유사도등을 이해하기는 불가능에 가까울 것이다. 그래서 컴퓨터에게 문장을 학습시키위해 단어를 수치화시키는 것이 첫 목표였다.
가장 기존의 방식은 다음과 같다. 다음과 같은 단어가 있다고 하자.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\text{I watch the movie yesterday}&lt;/script&gt;

&lt;p&gt;그리고 우리는 여러 단어를 포함하는 다음과 같은 사전을 가지고 있다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
&amp;\text{0 : watch}\\
&amp;\text{1 : I}\\
&amp;\text{2 : the}\\
&amp;\text{4 : yesterday}\\
&amp;\text{5 : movie}
\end{align*} %]]&gt;&lt;/script&gt;

&lt;p&gt;그렇다면 위의 문장은 다음의 벡터들의 집합으로 표현할 수 있다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
&amp;[0,1,0,0,0] \text{ = I}\\
&amp;[1,0,0,0,0] \text{ = watch}\\
&amp;[0,0,1,0,0] \text{ = the}\\
&amp;[0,0,0,0,1] \text{ = yesterday}\\
&amp;[0,0,0,1,0] \text{ = movie}\\
\end{align*} %]]&gt;&lt;/script&gt;

&lt;p&gt;이런 방법을 one-hot encoding 방법이라 부른다. 벡터의 하나의 원소만 ‘1’이고 나머지는 모두 ‘0’인 벡터로 encoding한다는 것이다. 하지만 이러한 방법들은 단어를 수치화하는데는 성공했지만 치명적인 단점이 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;단어간 유사도를 나타낼 수 없다.(어느 두벡터를 내적해서 0이나온다)&lt;/li&gt;
  &lt;li&gt;문장 데이터가 많아질수록 사전벡터의 크기가 너무 커져 모델이 느려지고 비효율적이다.&lt;/li&gt;
  &lt;li&gt;벡터가 너무 크고 sparse하다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이러한 문제를 해결하기 위해 단어를 유의미한 수치를 가지는 벡터로 만들기 위한 방법을 연구했다. 이러한 방법을 Word Embedding이라 부른다. 따라서 단어는 각 벡터로 표현되고 이 벡터는 단어들간 유사도 또한 나타내는 것이다.&lt;/p&gt;

&lt;p&gt;이러한 방법은 2003년부터 제기된 방법부터 여러가지가 있지만 최근 가장많이 사용하고 가장 효율이 좋은 Miklov에 의해 만들어진 word2vec에 대해 알아보도록 한다.&lt;/p&gt;

&lt;h5 id=&quot;word2vec-1&quot;&gt;Word2Vec&lt;/h5&gt;

&lt;p&gt;Word2Vec은 2013년 &lt;a href=&quot;https://arxiv.org/pdf/1301.3781.pdf&quot;&gt;Efficient Estimation of Word Representations in
Vector Space&lt;/a&gt;에서 처음 나왔으며, 이후 같은 모델이지만 몇 가지 튜닝기법 추가와 약간 수정된 &lt;a href=&quot;http://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf&quot;&gt;Distributed Representations of Words and Phrases
and their Compositionality
&lt;/a&gt;이 나왔다.&lt;/p&gt;

&lt;p&gt;Word2Vec의 가장 중요한 아이디어는 언어학의 Distributional Hypothesis이다. 즉 ‘비슷한 분포를 가진 단어들은 비슷한 의미를 가진다’라는 의미로 좀 더 쉽게 표현하면 &lt;strong&gt;같이 등장하는 횟수가 많을 수록 두 단어는 비슷한 의미를 가진다&lt;/strong&gt; 라는 내용이 핵심 아이디어이다.
모델은 Continuous Bag Of Word(CBOW)와 Skip-Gram모델 두 가지다. 최근에는 CBOW보다는 Skip-Gram을 주로 사용하지만, 여기서는 두 모델 모두 하나씩 알아보도록 하자.&lt;/p&gt;

&lt;h5 id=&quot;continuous-bag-of-words-model-cbow&quot;&gt;Continuous Bag of Words Model (CBOW)&lt;/h5&gt;

&lt;p&gt;CBOW의 기본적인 아이디어는 다음과 같다.
주변단어를 통해서 주어진 단어가 무었인지 찾는 것이다. 정확히는 앞뒤로 $\frac c2$개의 단어를 (총c개) 통해 주어진 단어를 예측한다는 것이 CBOW의 아이디어이다.
다음의 문장을 보자&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“아침을 안먹었더니 __가 너무 고프다”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;위와같은 문장이 있다고 하자. 우리는 주변 단어들을 통해 빈칸에 들어갈 단어를 예측할 수 있다.&lt;/p&gt;

&lt;p&gt;CBOW의 아키텍처는 다음의 그림과 같다.
&lt;img src=&quot;https://shuuki4.files.wordpress.com/2016/01/cbow.png?w=520&amp;amp;h=600&quot; alt=&quot;cbow&quot; /&gt;
CBOW의 학습과정에 대해 알아보자.&lt;/p&gt;

&lt;p&gt;우선 학습시킬 문장의 모든 단어들을 one-hot encoding 방식으로 벡터화 한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;x_k=[0,...,0,1,0,...,0]&lt;/script&gt;

&lt;p&gt;그리고 하나의 중심단어에 대해 $2m$개의 단어 벡터를 input값으로 갖는다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;(x^{c-m},x^{c-m+1},...,x^{c-1},x^{c+1},...x^{c+m-1},x^{c+m})\in\mathbb{R}^{|V|}&lt;/script&gt;

&lt;p&gt;파라미터는 Input Layer에서 Hidden Layer로 가는 파라미터 매트릭스와 output layer로 가는 파라미터 매트릭스 이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{W}\in\mathbb{R}^{V\times N},~\mathbf{W}^{\prime}\in\mathbb{R}^{N\times V}&lt;/script&gt;

&lt;p&gt;&lt;em&gt;(작성상 편의와 햇갈림을 방지하기 위해 $\mathbf{W}^{\prime}$는 아래의 설명에서는 $\mathbf{U}$작성했다.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;이 모델의 목적은 주변단어들이 주어졌을 떄의 중심 단어의 조건부 확률을 최대화 하는 것이다. 즉 다음의 확률을 최대화 하는 것이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;P(x_c|x_{c-m},...x_{c-1},x_{c+1},...,x_{c+m})&lt;/script&gt;

&lt;p&gt;그렇다면 네트워크의 진행 과정에 대해서 알아보자.
각 단어는 one-hot encoding 방식이므로 파라미터 $W$와 곱하면 각 단어를 나타내는 행과 곱해지고 나머지는 0으로 곱해지지 않을 것이다. 아래의 그림을 보면 명확하게 이해될 것이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://mccormickml.com/assets/word2vec/matrix_mult_w_one_hot.png&quot; alt=&quot;ckarh&quot; /&gt;&lt;/p&gt;

&lt;p&gt;즉 one-hot encoding 방식의 단어벡터들은 파라미터와 곱해져서 embedded word vector가 될 것이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;(v_{c-m}=\mathbf{W}x^{c-m},...,v_{c+m}=\mathbf{W}x^{c+m})\in\mathbb{R}^n&lt;/script&gt;

&lt;p&gt;이후 $2m$개의 embedded vector들의 평균을 구한다. 이때 평균해서 구한 벡터가 Hidden Layer값이 된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\hat{v}=\frac{v_{c-m}+v_{c-m+1}+\dotsm+v_{c+m}}{2m}\in\mathbb{R}^n&lt;/script&gt;

&lt;p&gt;이제 output layer로 전달할 값인 score값을 계산해야 한다. 파라미터 $\mathbf{U}$를 곱해서 각 단어에 대한 score를 만든다. 가까운 위치의 단어들은 높은 값을 갖도록 해야 한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;z=\mathbf{U}\hat{v}\in\mathbb{R}^{|V|}&lt;/script&gt;

&lt;p&gt;마지막으로 각 score값들을 확률 값으로 계산한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\hat{y}=softmax(z)\in\mathbb{R}^{|V|}&lt;/script&gt;

&lt;p&gt;확률은 softmax를 사용한다. 각 단어에 파라미터 $\mathbf{W}$를 곱하면 단어는 one-hot vector이기 때문에 각 단어에 해당하는 행만 계산될 것이다. 이때 각 단어에 해당하는 행은 단어의 embedding vector($v_k$)가 된다.&lt;/p&gt;

&lt;p&gt;네트워크의 진행과정에 대해서 소개했다. 이제 필요한 것은 이 파라미터들을 학습하는 것이다. 학습을 위해 Objective function을 정의해야한다. Objective function은 아래와 같으며 우리는 그 값을 minimize하는 방향으로 학습할 것이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;H(\hat{y},y)=-\sum^{|V|}_{j=1}y_j\log(\hat{y_j})&lt;/script&gt;

&lt;p&gt;Objective function은 위와 같다. 모든 원소에 대한 sum을 계산하는 것이지만 $y_j$벡터가 one-hot vector라는 것을 기억하자. 결국 하나의 원소에 대해서만 계산될 것이다. 결국 Objective function은 다음과 같이 간단하게 표현할 수 있다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;H(\hat{y},y)=-y_i\log(\hat{y}_i)&lt;/script&gt;

&lt;p&gt;여기서 $i$는 우리가 예측하는 단어가 될 것이다.
단어를 정확하게 예측했다면  $H$값은 0이 될 것이다.그리고 우리는 위 식을 다음과 같이 확률 분포에 대한 식으로 볼 수 있다. 따라서 Objective funciton을 다음과 같이 표현한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
minimize J &amp;=-\log P(w_c|w_{c-m},...,w_{c+m})\\
&amp;=-\log P(u_c|v^)\\
&amp;=-\log \frac{exp(u_c^{\intercal}\hat{v})}{\sum^{|V|}_{j=1}exp(u_j^{\intercal}\hat{v})}\\
&amp;=-u_c^{intercal}\hat{v}+\log\sum^{|V|}_{j=1}exp(u_j^{\intercal}\hat{v})
\end{align*} %]]&gt;&lt;/script&gt;

&lt;p&gt;optimize 방법으로는 SGD를 사용한다.
마지막으로 CBOW모델의 계산량은 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;$C$개의 단어를 Hidden Layer로 보내는 $C\times N$&lt;/li&gt;
  &lt;li&gt;Hidden Layer에서 Output Layer로 가는 $N\times V$&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;즉 전체 계산량은 $C\times N + N\times V$이다.&lt;/p&gt;

&lt;p&gt;모든 문장에 대해 학습을 마친후 우리는 $W$ 행렬의 각 행을 각 단어의 embedding vector로 사용하게 된다.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Chapter 4: Recurrent Neural Networks and Gated Recurrent Units</title>
   <link href="https://reniew.github.io/20/"/>
   <updated>2018-07-18T04:47:35+00:00</updated>
   <id>https://reniew.github.io/20</id>
   <content type="html">&lt;h3 id=&quot;chapter-4&quot;&gt;Chapter 4&lt;/h3&gt;
&lt;h3 id=&quot;recurrent-neural-networks-and-gated-recurrent-units&quot;&gt;Recurrent Neural Networks and Gated Recurrent Units&lt;/h3&gt;

&lt;p&gt;이 내용은 Newyork University의 조경현교수님의 NLP_DL강의 lecture note중 Recurrent Neural Networks and Gated Recurrent Units단원을 정리한 내용이다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;이번 단원에는 몇 개의 단원에서 생략된 부분이 있습니다. 전체적인 흐름에 있어선는 문제가 없다고 판단되는 선에서 생략했으나, 혹시나 생략된 부분에 알고 싶으신 분들은 &lt;a href=&quot;https://github.com/nyu-dl/NLP_DL_Lecture_Note/blob/master/lecture_note.pdf&quot;&gt;lecture note&lt;/a&gt;를 참고해 주시기 바랍니다.&lt;/em&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;41-recurrent-neural-network&quot;&gt;4.1 Recurrent Neural Network&lt;/h4&gt;

&lt;p&gt;기존의 우리가 배운 Neural Network에서는 input $x$가 고정 size의 scalar 혹은 vector였다. 그러나 여기서는 input $x$가 고정 size라는 가정을 없에고 가변 길이의 input, 즉 sequence를 다루는 법을 알아 볼 것이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;x^k=(x_1^k, ..., x^k_{l^k})&lt;/script&gt;

&lt;p&gt;우선 가장 간단한 형태인 binary값을 가지는 sequence에 대해서 살펴보자. 1 혹은 0 만을 가지는 sequence에 대해서 1의 개수를 알고 싶다면 어떻게 해야 할까?
이 때 사용해야 하는 함수는 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/aebn6mC.jpg&quot; alt=&quot;캡처&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위 알고리즘을 사용한다면 sequence에서의 1값이 몇번인지 확인 할 수 있을 것 이다.
&lt;em&gt;ADD1&lt;/em&gt; 알고리즘의 중요한 특징은 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;‘1’의 개수를 새는 memory &lt;strong&gt;$s$&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;sequence의 각 symbol에 ‘하나씩’ 적용된다.(차례대로)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이 두가지 특성 때문에 가변길이의 sequence에 사용될 수 있다. 이 &lt;em&gt;ADD1&lt;/em&gt; 알고리즘의 idea(‘memory’&amp;amp;’recursive function’)를 일반화 하자.
가장 일반적인 예는 컴퓨터이다. 특히 컴퓨터에서 CPU가 명령어를 처리하는 과정에 위의 idea가 사용되었다. (CPU : sequence of instruction($x_i$))
그러나 우리가 필요한 것은 학습을 위한 Network이므로 parametric recursive function (NLP를 하기 위한 언어적 symbol을 읽을 수 있는)가 필요하다.&lt;/p&gt;

&lt;p&gt;Parametric recursive function을 만들기 위해 필요한 것에 대해 먼저 생각해보자. 우선 memory역할을 할 vector가 필요하다 이를 $h\in\mathbb{R}^{d_h}$라 하자. 그리고 recursive한 fucntion은 input symbol과 memory $h$ 둘 다 input으로 받는다. 이후 function을 통과시켜 memory를 업데이트 시킨 후 return한다. 각각의 memory $h$를 구분하기 위해 time index을 사용한다. ($h_t,h_{t-1},…$) 이러한 recursive한 fucntion은 다음과 같이 작성될 것이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;h_t=f(x_t,h_{t-1})&lt;/script&gt;

&lt;p&gt;그리고 함수 $f()$는 다음과 같이 정의한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;f(x_t, h_{t-1})=g(W)\phi(x_t)+Uh_{t-1}&lt;/script&gt;

&lt;ul&gt;
  &lt;li&gt;$\phi(~~)$함수는 input symbol을 d dimension으로 바꿔주는 함수.&lt;/li&gt;
  &lt;li&gt;$W\in\mathbb{R}^{d_h\times d}$&lt;/li&gt;
  &lt;li&gt;$U\in\mathbb{R}^{d_h\times d_h}$&lt;/li&gt;
  &lt;li&gt;$g$는 element-wise nonlinear한 activation function뭐든 사용가능 하다.(e.g $tanh, sigmoid$)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위의 함수를 통과하게 되면 $d_h$ dimension을 가지는 vector가 된다. 이 값은 다음 값의 memory로 사용되거나 output으로 사용된다.&lt;/p&gt;

&lt;p&gt;함수에 대해서 정의했으므로 이제는 두 가지 분류로 문제를 구분할 것이다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;fixed-size의 output $y$&lt;/li&gt;
  &lt;li&gt;variable length sequence의 output $y$&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;411-fixed-size-output&quot;&gt;4.1.1 Fixed size output&lt;/h4&gt;

&lt;p&gt;기본적인 binary classification의 경우에 대해서 살펴보자. 가장 대표적인 binary classification의 예는 글에 대해 positive(1), negative(0) 감정을 평가하는 문제다. 이러한 문제는 결과가 0 혹은 1이므로 bernoulli distribution이라 생각할 수 있다. 따라서 우리는 distribution의 유일한 parameter인 $\mu$만 구하면 된다. 따라서 $\mu$를 다음과 같이 정의한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mu = \sigma(\mathbf{v}^\intercal h_l)&lt;/script&gt;

&lt;ul&gt;
  &lt;li&gt;마지막 memory인 $h_l$사용&lt;/li&gt;
  &lt;li&gt;활성화 함수로 sigmoid 함수 사용한다.(0~1값을 출력해야 하므로)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;따라서 전체적인 계산은 다음과 같이 한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mu = \sigma(\mathbf{v}^\intercal~g(\mathbf{W}\phi(x_l)+\mathbf{U}g(\mathbf{W}\phi(x_{l-1})+\mathbf{U}g(\mathbf{W}\phi(x_{l-2}))+\dotsm)))&lt;/script&gt;

&lt;p&gt;여기서 가장 최초의 memory인 $h_0$는 보통 all zero vector를 사용한다. 그리고 $\mathbf{W, U}$는 shared parameter다.&lt;/p&gt;

&lt;p&gt;또 다른 예를 들어 보자. 이번에도 감정 분석 문제이지만, 이번에는 분석해야 할 class가 3개, 즉 positive(1), neutral(2), neagtive(3)으로 분석해야 하는 문제에 대해 살펴보자. 이번에는 출력값이 $\mu$값 1개가 아닌, 3개의 $\mu$를 가지는 $\mathbf{\mu}= [\mu_1, \mu_2, \mu_3]$벡터를 출력으로 구해야 한다.
구하는 방식은 이전과 거의 비슷하지만 마지막 output을 뽑아낼 때 sigmoid가 아닌 softmax를 사용해야 한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mu = [\mu_1, \mu_2, \mu_3]^\intercal=softmax(\mathbf{v}h_l)&lt;/script&gt;

&lt;h4 id=&quot;414-variable-length-output&quot;&gt;4.1.4 Variable length output&lt;/h4&gt;

&lt;p&gt;가변길이의 output은 sequence형태가 된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;y=(y_1,y_2,...,y_l),~~\text{such that}. ~|x_k|=|y_k|&lt;/script&gt;

&lt;p&gt;이러한 문제의 대표적인 예는 POS tagging 문제다. 각 input $x$에 대해 noun, verb, adjective, others에 대한 각각의 확률값을 출력하는 문제다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\begin{matrix}
x = (\text{children, eat, sweet, candy})\\
y = (\text{noun, verb, adjective, noun})
\end{matrix}&lt;/script&gt;

&lt;p&gt;이러한 경우에는 각각의 step에서 memory를 각 step의 출력층, 다음 step 두 곳 모두로 보낸다. 각각의 layer에서의 출력은 다음과 같이 계산한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{matrix}
\mu_t &amp;=&amp; [\mu_{t,1}, \mu_{t,2}, \mu_{t,3},\mu_{t,4}]\\
&amp;=&amp;softmax(\mathbf{V}h_t)~~~~~
\end{matrix} %]]&gt;&lt;/script&gt;

&lt;p&gt;학습을 위해 각 step의 Cost는 다음과 같이 정의한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;C_{x,t}(\theta)=-\log \sum^k_{k=1}\mathbb{I}_{k=y}\mu_{t,k}&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\mathbb{I}_{k=y}=
\begin{cases}
1, &amp;  \text{if}~~k=y \\
0, &amp; \text{elsewise}
\end{cases} %]]&gt;&lt;/script&gt;

&lt;blockquote&gt;
  &lt;p&gt;Cost함수에 대해서 간단히 설명을 하자면 I함수 때문에 정답 label을 가지는 단어에 대해서만 log값을 계산한다. 이 때 -log함수이기 떄문에 1에 가까울수록 적은 Cost를 가지고, 0에 가까울 수록 매우 큰 Cost를 가지게 된다. 따라서 전체적으로 우리는 Cost를 minimize하는 방향으로 가야 한다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cost 계산을 실제로 할때는 총합을 계산해서 학습을 시킨다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;C_{x}(\theta)=-\sum_{t=1}^l\log \sum^k_{k=1}\mathbb{I}_{k=y}\mu_{t,k}&lt;/script&gt;

&lt;p&gt;위의 전체 cost를 minimize하는 방향으로 Network를 학습시켜야 한다.&lt;/p&gt;

&lt;p&gt;결국 이 식이 목표하는 것은&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;P(y|x) = \sum^l_{t=1}\log P(y_t|x_1, ...,x_t)&lt;/script&gt;

&lt;p&gt;이 조건부 확률을 최대화 하는 것이다. 그러나 위의 식을 단순히 cost함수로 표현을 하기에는 각각의 $x$ value들이 independent하다는 가정이 필요하다. 그러나 대부분의 경우에 그러한 가정을 사용하기에는 무리가 있다. 예를 들어 POS tagging 의 경우에만 봐도 명사 뒤에는 동사가 나올 확률이 높아진다. 이런 경우만 봐도 $x$ value들은 independent라고 하기는 어렵다.
따라서 우리는 condition으로 $y$의 값도 사용함으로써 독립 가정에 의한 격차를 줄인다.
즉, 아래와 같은 식으로 계산한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;h_t=f(x_t,y_{t-1},h_{t-1})=g(\mathbf{W}_x\phi_x(x_t)+\mathbf{W}_y\phi_y(y_{t-1}+\mathbf{W}_hh_{t-1}))&lt;/script&gt;

&lt;h3 id=&quot;42-gated-recurrent-unit&quot;&gt;4.2 Gated Recurrent Unit&lt;/h3&gt;

&lt;p&gt;이때까지의 살펴본 RNN은 CPU가 작동하는 과정과 매우 유사하다고 볼 수 있다. 그러나 유사하다는 것은 concept적인 부분이고 실제 practical한 부분에서는 차이가 있다. 우리가 살펴본 RNN구조에서는 각 step에서 모든 memory가 refresh(update)된다는 점인데, CPU에서는 memory중 사용되는 값과 사용되지 않는 값이 다르게 refresh된다.
이런 CPU의 계산 과정을 mathmatical하게 표현하면 아래와 같이 표현할 수 있다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\tilde{h}_t=g(\mathbf{W}\phi(x_t)+\mathbf{U}(\mathbf{r}\odot h_{t-1}))&lt;/script&gt;

&lt;p&gt;여기서 $\odot$은 element-wise multiply를 의미한다.
위 식은 실제 사용되는 메모리가 아니라 candidate memory로 memory값으로 사용 될 수 있는 memory를 의미한다. 실제 메모리의 수식은 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;h_t=(1-\mathbf{u})\odot h_{t-1}+\mathbf{u}\odot\tilde{h}_t&lt;/script&gt;

&lt;p&gt;수식을 보면 아직 소개하지 않은 값들이 있는데 $\mathbf{r, u}$이다.
이 두값은 다음과 같이 표현될 수 있다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\mathbf{u}=
\begin{cases}
1, &amp;  \text{will not be used} \\
0, &amp; \text{will be used}
\end{cases} %]]&gt;&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\mathbf{r}=
\begin{cases}
1, &amp;  \text{will change} \\
0, &amp; \text{does not changed}
\end{cases} %]]&gt;&lt;/script&gt;

&lt;p&gt;이 식들 중 $\tilde{h}_t$를 구하는 식을 reset gate라 부르고, $h_t$를 구하는 식을 update gate라 부른다.&lt;/p&gt;

&lt;p&gt;이제 우리가 알아볼 GRU에 대해서 살펴보자. GRU의 경우에는 위의 CPU가 working하는 과정과 매우 유사하다. 하지만 차이점에 대해서 먼저 생각해보면 우선 GRU의 경우 CPU처럼 instruction들에 대한 정보가 없어서 $\mathbf{u,r}$를 미리 setting 할 수 없다.
그리고 또 큰 차이점이자 문제점이라 할 수 있는 부분은 $\mathbf{u,r}$를 binary하게 0,1 값으로만 준다면 학습 시 미분값이 거의 대부분 0이 되서 학습을 할 수 없다.
따라서 두 벡터를 binary한 값이 아닌, [0,1]의 값을 가지는 real valued vector로 만든다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{u}\in[0,1]^{n_h},~~\mathbf{r}\in[0,1]^{n_h}&lt;/script&gt;

&lt;p&gt;그리고 다음과 같은 식이 최종적으로 완성된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\begin{matrix}
\mathbf{r}_t=\sigma(\mathbf{W}_r\phi(x_t)+\mathbf{U}_rh_{t-1})\\
\mathbf{u}_t=\sigma(\mathbf{W}_u\phi(x_t)+\mathbf{U}_u(\mathbf{r}\odot h_{t-1}))\\
\end{matrix}&lt;/script&gt;

&lt;p&gt;그리고 각 step 에서 update는 다음과 같이 진행됩니다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\begin{matrix}
\tilde{h}=\tanh(\mathbf{W}x_t+r_t\odot\mathbf{U}h_{t-1})\\
h_t=\mathbf{u}_t\odot h_{t-1}+(1-\mathbf{u}_t)\odot\tilde{h}_t
\end{matrix}&lt;/script&gt;

&lt;p&gt;전체적인 구조와 각 계산들에 대해 하나씩 그림으로 보겠습니다. 그림의 출처는 &lt;a href=&quot;https://towardsdatascience.com/understanding-gru-networks-2ef37df6c9be&quot;&gt;이곳&lt;/a&gt;이며 소개한 수식에서 $\mathbf{u}$가 $\mathbf{v}$로 표현됬다는 차이가 있습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;전체 구조&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1600/1*6eNTqLzQ08AABo-STFNiBw.png&quot; alt=&quot;1&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Update Gate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1600/1*gSlR_JLNeuZBSCAKyjmAdA.png&quot; alt=&quot;2&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Reset Gate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1600/1*5M6LYj544UKKHkFkDmDQ8A.png&quot; alt=&quot;3&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;cadidate memory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1600/1*AZObvZ2GXSDYkJ2iv28MaQ.png&quot; alt=&quot;4&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Final memory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1600/1*UxZ0pTQW8kofL9bzPVYV1w.png&quot; alt=&quot;5&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;423-long-short-term-memorylstm&quot;&gt;4.2.3 Long Short-Term Memory(LSTM)&lt;/h4&gt;

&lt;p&gt;위의 GRU는 LSTM을 motive로 만들어진 network이다.
LSTM과 GRU의 차이는 LSTM은 memory state $c_t$와 output $h_t$를 분리했다는 점이다. 이 책에는 LSTM에 대한 설명이 많지 않아서 다음 포스트에서 LSTM에 대해 따로 소개하도록 한다.&lt;/p&gt;

&lt;h3 id=&quot;43-why-not-rectifiers&quot;&gt;4.3 Why not Rectifiers?&lt;/h3&gt;

&lt;p&gt;GRU의 구조를 보면 활성화 함수로 sigmoid와 tanh를 사용했다는 점을 알 수 있다.
sigmoid의 경우에는 0~1값을 출력을 위해 사용했다고 이해 할 수 있지만, tanh같은 경우에는 CNN에서 좋은 성능을 보이는 Rectify계열의 활성화 함수(e.g. maxout,ReLU)를 사용하지 않은 이유에 대해 알아보도록 한다.&lt;/p&gt;

&lt;p&gt;아래의 식을 보자. 이전에 소개된 식이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;f(x_t,\mathbf{h}_{t-1}=g(\mathbf{w}\phi(x_t)+\mathbf{U}\mathbf{h}_{t-1}))&lt;/script&gt;

&lt;p&gt;이 식에서 함수 $g()$는 활성화 함수이다. 이 함수를 다음과 같은 Recifier함수를 사용해 보자.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;g(a)=a&lt;/script&gt;

&lt;p&gt;그리고 마지막 output을 계산하기 위한 값이자 memory인 $h_l$을 계산해보고 그 값의 norm을 계산해보자.
이 계산과정에 대한 다른 설명은 따로 하지 않고 lecture note에 나온 계산 과정만 확인한다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;img src=&quot;https://i.imgur.com/aHWYc6x.jpg&quot; alt=&quot;1&quot; /&gt;
&lt;img src=&quot;https://i.imgur.com/COyGwFL.jpg&quot; alt=&quot;2&quot; /&gt;
&lt;img src=&quot;https://i.imgur.com/1jdGekL.jpg&quot; alt=&quot;3&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;다음의 식에서 알 수 있는 것은 Rectify계열의 함수는 unbounded 하다는 특성이 있다. 따라서 RNN의 특성상 연쇄적으로 곱해진다면 norm은 기하급수적으로 증가하게 된다. 따라서 마지막 메모리인 $h_l$값이 무한대로 발산하게 된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;||h_l||\to\infty&lt;/script&gt;

&lt;p&gt;이러한 문제점들 때문에 unbounded한 함수를 사용하지 않고 bounded된 sigmoid 혹은 unbounded한 함수를 활성화 함수로 사용한다.&lt;/p&gt;

&lt;h4 id=&quot;432-is-tanh-a-blessing&quot;&gt;4.3.2 Is tanh a Blessing?&lt;/h4&gt;

&lt;p&gt;이전 section에서 rectify계열의 활성화 함수를 사용하는 것 보다 sigmoid 또는 tanh를 사용해야 한다는 것을 확인했다. 그렇다면 tanh(혹은 sigmoid)의 경우는 항상 좋은 점만 있는지 살펴보자.&lt;/p&gt;

&lt;p&gt;일반적으로 RNN을 계산해 output을 계산할 때 까지는 큰 문제점 없이 계산된다. 하지만 학습과정에서 backpropagation을 하면 문제점이 발생한다.&lt;/p&gt;

&lt;p&gt;여기서도 note에 소개된 계산 과정에 대해서는 설명하지 않겠다. 어떠한 과정인지만 설명을 하자면 Backpropagation에서 마지막 memory인 $h_l$에 대한 처음 memory인 $h_{l_0}+1$로 미분한 값의 norm을 구하는 과정이다. 아래를 보도록 하자.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;img src=&quot;https://i.imgur.com/fXELCT7.jpg&quot; alt=&quot;44&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;이 식에서 의미하는 것은 $\mathbf{U}$의 eigenvalue의 최대값이 $\frac1\lambda$보다 크다면 미분값이 무한대로 갈 것이고, 반대의 경우에는 0으로 수렴한다는 내용이다.&lt;/p&gt;

&lt;p&gt;즉 tanh를 사용한 경우 feedforward계산에는 크게 문제가 없지만 backpropagation과정에서 &lt;strong&gt;gradient exploding&lt;/strong&gt; 과 &lt;strong&gt;gradient vanishing&lt;/strong&gt; 이 발생한다는 문제점이 있다.&lt;/p&gt;

&lt;h4 id=&quot;433-are-we-doomed&quot;&gt;4.3.3 Are We Doomed?&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;Exploding Gradient&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이전 section에서 gradient가 exploding하는 문제에 대해 확인했다. 그렇다면 이러한 문제를 해결하는 방법은 무었일까?
다행이도 이러한 문제를 해결하는 것은 어렵지 않다. Cost에 대한 gradient 값을 계속해서 확인해서 일정한 임계값($\tau$)을 넘어 갈 경우 이 값을 줄여주면 된다. 여기서는 다음과 같은 식이 사용된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\tilde{\nabla}=
\begin{cases}
\tau \frac{\nabla}{||\nabla||},~~~~&amp;\text{if}||\nabla||&gt;\tau\\
\nabla,&amp;\text{otherwise}
\end{cases} %]]&gt;&lt;/script&gt;

&lt;p&gt;이러한 방법은 gradient clippikng이라고도 불린다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Vanishing Gradient&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vanishing gradient는 exploding과 다르게 큰 문제점으로 받아들여진다.
gradient가 vanishing하는 과정에 대한 수식적인 소개가 note에는 나와있지만 여기서는 생략한다. vanishing gradient의 가장 큰 문제점은 이러한 문제를 해결할 방법이 거의 없다는 것이다. 그리고 우리는 vanishing gradient가 어떤 원인으로 발생하는지 구별하는 것이 어렵다. 예를 들면, lack of dependency에 의한 것인지, 혹은 underlying function때문인지 아니면 parameter setting이 잘못된 것인지 구분하기가 어렵다.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>CNN을 활용한 주요 Model - (4) : Semantic Segmentation</title>
   <link href="https://reniew.github.io/18/"/>
   <updated>2018-07-14T04:47:35+00:00</updated>
   <id>https://reniew.github.io/18</id>
   <content type="html">&lt;h4 id=&quot;cnn을-활용한-주요-model---4--semantic-segmentation&quot;&gt;CNN을 활용한 주요 Model - (4) : Semantic Segmentation&lt;/h4&gt;

&lt;p&gt;CNN을 활용한 최초의 기본적인 Model들 부터 계속해서 다양한 구조를 가지는 많은 모델들이 계속해서 나오고 있다. 이번 포스트에서는 아래의 분류를 기준으로 CNN의 주요 모델들에 대해서 하나씩 알아 보도록 하겠다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Modern CNN
    &lt;ul&gt;
      &lt;li&gt;LeNet&lt;/li&gt;
      &lt;li&gt;AlexNet&lt;/li&gt;
      &lt;li&gt;VGG Nets&lt;/li&gt;
      &lt;li&gt;GoogLeNet&lt;/li&gt;
      &lt;li&gt;ResNet&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Image Detection
    &lt;ul&gt;
      &lt;li&gt;RCNN&lt;/li&gt;
      &lt;li&gt;Fast RCNN&lt;/li&gt;
      &lt;li&gt;Faster RCNN&lt;/li&gt;
      &lt;li&gt;SPP Net&lt;/li&gt;
      &lt;li&gt;Yolo&lt;/li&gt;
      &lt;li&gt;SDD&lt;/li&gt;
      &lt;li&gt;Attention Net&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Semantic Segmentation&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;FCN&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;DeepLab v1, v2&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;U-Net&lt;/li&gt;
      &lt;li&gt;ReSeg&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Image Captioning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;이번 포스트에서는 Sematic Segmentation을 위해 만들어진 모델들에 대해서 소개한다. Semantic Segmentation 문제에 대해 먼저 소개를 하자. 우선 Segmentation을 먼저 설명하면, Detection이 물체가 있는 위치를 찾아서 물체에 대해 Boxing을 하는 문제였다면, Segmentation이란, Image를 Pixel단위로 구분해 각 pixel이 어떤 물체 class인지 구분하는 문제다.&lt;/p&gt;

&lt;p&gt;아래 그림이 Image문제에 대한 분류를 잘 설명했다.
&lt;img src=&quot;http://ataspinar.com/wp-content/uploads/2017/11/deeplearing_types.png&quot; alt=&quot;image task&quot; /&gt;
&lt;em&gt;출처 : http://ataspinar.com/2017/12/04/using-convolutional-neural-networks-to-detect-features-in-sattelite-images/&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;그리고 Segmentation은 두가지로 나뉜다. Semantic Segmentation과 Instance Segmentation로 구분되는데 이번에 소개할 Semantic Segmentation은 pixel단위로 물체를 구분한뒤 각각의 물체가 어떤 class인지만 구분 하는 문제고, Instance Segmentation이란 같은 class이더라도 다른 것이라면 구분하는 문제라 할 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://research.sualab.com/assets/images/image-recognition-overview-2/segmentation-types.svg&quot; alt=&quot;seg&quot; /&gt;
(&lt;em&gt;출처 : http://research.sualab.com/computer-vision/2017/11/29/image-recognition-overview-2.html&lt;/em&gt;)
&lt;em&gt;Instance Segmentation에서는 각각의 사람들을 다른 사람으로 구분한 것을 볼 수 있다.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Segmentation은 자율주행 자동차에서 매우 중요한 기술로 많은 모델들이 소개 되었다. 많은 모델 중 몇가지만 알아보도록 한다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;FCN&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;FCN이란 Fully Convolutinal Network의 약자로, 2015년 &lt;a href=&quot;https://arxiv.org/abs/1411.4038&quot;&gt;Fully Convolutional Network for Semantic Semgentation&lt;/a&gt;에서 소개됬다.
 FCN은 최초의 pixelwise end to end 예측 모델로 많은 의미를 가진다.&lt;/p&gt;

&lt;p&gt;FCN에서 가장 중요한 부분은 이름에서 나와있듯 Convolution layer만을 사용했다는 것이다. 기본적으로 CNN 모델에서는 모델 뒤쪽에서 Fully Connected layer가 나오는데, FCN에서는 FC Layer 대신 1x1 Convolution layer를 사용했다는 점이다.
 이렇게 사용한 이유에 대해 추측을 해보자면, 우선 Fully Connected layer를 사용하기 위해서는 고정된 input size를 가질 수 밖에 없다. 그리고 FC layer를 지나는 순간 각 pixel에 대한 위치정보는 소실된다. 따라서 FCN은 모든 Network를 Convolution layer만 사용함으로써 input size의 제한을 받지 않고, 위치정보를 보존할 수 있게 되었다.&lt;/p&gt;

&lt;p&gt;FCN의 Architecture는 크게 3단계정도로 나뉜다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/uCL3VC5.jpg&quot; alt=&quot;FCN&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Feature를 추출하는 Convolution 단계&lt;/li&gt;
  &lt;li&gt;뽑아낸 future에 대해 pixelwise prediction 단계&lt;/li&gt;
  &lt;li&gt;classification을 한뒤 각 원래의 크기로 만들기 위한 Upsampling 단계&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이러한 단계를 거친 후 각 pixel에 class따라 색칠을 한뒤 Segmentation 결과를 보여준다.
세부적인 Architecture에 대한 소개를 하기보단 여기서 사용된 주요한 개념들에 대해서 소개를 한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Convolutionalization&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/Vm5oHz0.jpg&quot; alt=&quot;fcn2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;FCN은 Fully Connected Layer를 사용하지 않고 1x1 Convolution Layer를 사용했다고 했는데, 논문에서 이러한 1x1 Convolution을 Convolutionalization이라 표현했다.
그림 중간의 256크기의 matrix가 4096의 크기로 reshape된 것을 볼 수 있다. 이렇게 reshape을 한 후 여기에 1x1 Convolution을 진행한다.
하지만 이렇게 크기를 줄인다면 output dimension이 줄어들어 원래 크기의 image에 대해 segmentation을 할 수 없게 된다. 따라서 다시 크기를 원래 size로 만들어 줘야 한다. 즉 Upsampling 단계가 필요하다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Upsampling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;FCN에서 feature extraction을 크기가 줄어 하나의 pixel이 원래 image의 32x32크기를 나타낸다. 여기서 다시 크기를 키우기 위해 32x32의 크기로 바로 만든다면 많은 정보들이 소실되고 정확도 또한 떨이지게 된다. 따라서 여기서는 1/32 크기만을 이용하는 것이 아니라 이전 Layer에서의 1/16크기와 1/8에서의 값도 같이 사용한다.
이전의 layer들의 값을 다른 연산을 거치지 않고 Skip하여 마지막에서 같이 합쳐서 사용하게 된다. 따라서 이러한 과정을 ‘Skip Layer’ 혹은 ‘Skip Connection’이라 부른다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/A1mCLJO.jpg&quot; alt=&quot;fcn3&quot; /&gt;&lt;/p&gt;

&lt;p&gt;그림을 보면 이전의 Pooling Layer의 값을 가져와 더하는 것을 볼 수 있다.
이렇게 여러 크기의 값들을 Upsampling 한 것들을 합치는 것의 효과는 다음의 그림을 통해 확인하자.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/lAFLKkw.jpg&quot; alt=&quot;fcn4&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;DeebLab v1, v2, v3&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;최근 Segmentation 분야에서 State-of-art한 성능을 보여주는 DeepLab의 3번 째 versio이 오픈소스로 공개가 되어 많은 사람들의 주목을 받았다.(&lt;a href=&quot;https://github.com/tensorflow/models/tree/master/research/deeplab&quot;&gt;DeepLab. v3 Github&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;DeepLab은 2015년 처음으로 나온 DeepLab. v1 인 Semantic Image Segmentation With Deep Convolutional Nets And Fully Connected CRFs(&lt;a href=&quot;http://arxiv.org/pdf/1412.7062.pdf&quot;&gt;PaPer&lt;/a&gt;)을 시작으로 2016년 DeepLab v2(&lt;a href=&quot;http://arxiv.org/pdf/1606.00915.pdf&quot;&gt;Paper&lt;/a&gt;), 그리고 올해 오픈소스로 나온 DeepLab v3까지 Semantic Segmentaion분야에서 높은 성능을 보여줬다.&lt;/p&gt;

&lt;p&gt;DeepLab v2는 v1과 Atrous Convolution과 Fully Connected CRF(Conditional Random Field)를 사용한다는 점에서 비슷하지만 v2에서는 Atrous spatial pyramid pooling을 사용해서 Multiple sclae에 대응하는 방법이 개선되었다.&lt;/p&gt;

&lt;p&gt;여기서는 DeepLab v2만 다룰 예정이다. v1과 v3에 대해서는 위의 링크를 참고하길 바란다.&lt;/p&gt;

&lt;p&gt;DeepLab. v2에서 주목했던 문제들은 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Reduced feature resolution&lt;/li&gt;
  &lt;li&gt;Reduced Local accuracy&lt;/li&gt;
  &lt;li&gt;Existence of objects at multiple scale&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deep Lab. v2에서는 위의 세 가지 문제를 다음을 사용해서 해결하려 한다&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Reduced feature resolution
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;Atrous Convolution&lt;/strong&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Reduced Local accuracy
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;CRF(Conditional Random Field)&lt;/strong&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Existence of objects at multiple scale
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;Atrous Spatial pyramid pooling&lt;/strong&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위 3가지 기술들에 대해 하나씩 살펴보자.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Atrous Convolution
Classification 문제와는 달리 Image를 Pixel별로 구분해야 하는 Segmentaion에서는 CNN의 Layer가 깊어질수록 Feature의 크기가 작아지는 특징이 단점으로 작용했다. 따라서 이러한 Reduced Feature Resolution 문제를 Atrous Convolution을 사용해 해결했다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Atrous Convolution이란 의미적으로 구멍 뚫린 Convolution이라 해석하면 될 것이다. 아래 논문의 그림을 보자.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99107B33598343D524&quot; alt=&quot;atrous&quot; /&gt;&lt;/p&gt;

&lt;p&gt;그림의 위쪽은 일반적인 Convolution과정이고 아래는 Atrous Convolution을 의미한다. 중간중간 Hole(중간중간을 0으로 만듬)을 만들어서 좀 더 먼 쪽과 Convolution을 진행한다. 이런 과정을 통해 모델은 좀더 Dense한 Feature를 학습한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99B70033598344A324&quot; alt=&quot;atours2&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위의 그림을 보면 Atrous Convolution의 효과가 직관적으로 보인다. 아래의 빨간 화살표가 rate=2로 Atrous Conv를 실행한 것인데 위의 일반적인 Conv에 비해 Receptive Field 가 넓어 실제 그림과 비슷한 region을 얻는 것을 볼 수 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Conditional random field&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이제 큰 그림을 줄이면서 각 pixel에 대한 feature를 얻었으니 다시 Segmentation을 위해 다시 image를 늘리는 과정을 해야 한다. 아래 그림과 같이 Bilinear Interpolation만을 수행하면 원래 Image의 Segment를 정확히 얻지 못하는 것을 볼 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/msrY2vf.jpg&quot; alt=&quot;aspp&quot; /&gt;&lt;/p&gt;

&lt;p&gt;따라서 Conditinal Ramdom Field를 사용해서 더욱 정확한 Segment를 얻는다.
아래의 그림은 CRF를 반복할 수록 더욱 정확한 Segment를 얻는 과정을 보여준다.
&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/999FF63359834AE52D&quot; alt=&quot;at3&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Atrous spatial pyramid pooling(ASPP)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DeepLab v1에서는 크기가 다른 물체들이 있을 떄 이를 잘 Segmentation하지 못하는 문제가 있었는데 v2에서는 ASPP를 사용해서 이를 해결했다.&lt;/p&gt;

&lt;p&gt;ASPP란 특정 레이어 대해서 Atrous Convolution을 여러 rate를 이용해서 진행한 후 결과들을 합치는 방법이다. 아래의 그림을 보자.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99DCFD33598348311E&quot; alt=&quot;at4&quot; /&gt;&lt;/p&gt;

&lt;p&gt;rate 6, 12, 18, 24로 각각 convolution을 한 후 이들을 합치는 과정을 Atrous Spatial Pyramid Pooling 이라 한다.&lt;/p&gt;

&lt;p&gt;위의 3가지 방법들을 합친 DeepLab v2의 전반적인 진행과정은 다음 그림과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99ABA333598349D501&quot; alt=&quot;at_final&quot; /&gt;&lt;/p&gt;

&lt;p&gt;여기까지가 DeepLab에 대한 설명이였다.&lt;/p&gt;

&lt;p&gt;출처&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://modulabs-biomedical.github.io/FCN&quot;&gt;모두의 연구소 논문 리뷰 블로그&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://laonple.blog.me/220991967450&quot;&gt;라온피플 블로그&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://dogfoottech.tistory.com/169&quot;&gt;SweetzLab의 기술블로그&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>정보이론 : 엔트로피, KL-Divergence</title>
   <link href="https://reniew.github.io/17/"/>
   <updated>2018-07-12T06:47:35+00:00</updated>
   <id>https://reniew.github.io/17</id>
   <content type="html">&lt;h3 id=&quot;정보이론--엔트로피-kl-divergence&quot;&gt;정보이론 : 엔트로피, KL-Divergence&lt;/h3&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;지난 포스트에서 소개했던 것 처럼 정보이론이란 정보의 양을 측정하는 분야이다. 그리고 그 정보의 양을 표현하는 개념이 엔트로피(Entropy)이다. 그리고 정보를 전달할 때는 비트의 단위로 전달을 하게 된다.&lt;/p&gt;

&lt;p&gt;셰넌은 그의 논문에서 정보를 ‘불확정성’ 또는 ‘불확실성’으로 표현했다. 즉 어떤 사건에 대해 불확실성이 커질수록 정보량이 많아진다는 것이다.&lt;/p&gt;

&lt;p&gt;직관적인 이해를 위해 설명을 하면, 어떠한 사건을 누군가에게 통신을 통해 전달해야 한다고 가정을 하자. 확률이 높은 사건이 설명하기 쉽겠는가, 확률이 희박한 사건을 설명하기 쉽겠는지에 대해 생각해보면 된다. 예를 들어 동전던지기를 설명하려면 앞면, 뒷면 두가지 경우중에 한가지가 나왔다는 것을 전달하면 되지만 주사위 던지기의 경우에는 1부터 6까지의 경우 중에서 하나가 나왔다는 것을 전달해야 한다. 이 두가지 경우중 전달해야 할 정보량이 많은 것은 당연이 후자일 것이다.
&lt;br /&gt;&lt;/p&gt;
&lt;h4 id=&quot;self-information&quot;&gt;Self-Information&lt;/h4&gt;
&lt;p&gt;&lt;br /&gt;
확률 $p$를 가지는 사건(메시지) $A$ 의 정보를 정의하는 것을 Self-Information(or surpisal)이라고 한다.
어떤 메시지 $m$에 대한 self-information은 다음과 같이 정의된다.
(여기서 log는 밑이 2인 log를 뜻 한다.)&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;I(m)=log\bigg(\frac{1}{p(m)}\bigg)=-\log(p(m))&lt;/script&gt;

&lt;p&gt;정보량은 확률에대해 $log_2$를 씌운 값인데, 확률은 $0$~$1$값을 가지므로 음수값이 나오게된다. 그러나 정보량은 양수의 값을 가져야 하므로 -를 씌워줘서 양수로 만들어준다. 그리고 항상 로그의 밑이 2가 되는 것은 아니다. 경우에 따라 맞는 수를 사용하면 된다. 예를 들어 Discrete한 사건이 아니라 Continuous한 random variable에 대해서 정보량을 측정할 떄에는 보통 e를 밑으로 하는 log를 사용한기도 한다.
그리고 이 정보량인 $I(m)$의 단위는 비트(bit)이다.(&lt;em&gt;여기서 밑을 2로한 이유이기도 하다.&lt;/em&gt;) 예를 들어서 확률 1/8을 가지는 사건에 대한 정보량은 $-log(\frac18)$로 3이된다. 즉 이 메시지를 전달하기 위해서는 3bit가 필요하다는 뜻이 된다.
&lt;br /&gt;&lt;/p&gt;
&lt;h4 id=&quot;entropy&quot;&gt;Entropy&lt;/h4&gt;
&lt;p&gt;&lt;br /&gt;
Self-Information은 하나의 메시지에 대한 자기 자신의 정보량을 나타냈다. 엔트로피란 어떤 다수의 메시지들(메시지 집합$M$)에 대해서 각각의 정보량을 평균한 값을 의미한다.
평균값을 계산하는 방법이 메시지 공간($M$)의 사건들이 Discrete한 경우와 Continuous한 경우 계산하는 방법이 다르므로 두 가지 수식을 나눠서 설명한다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;메시지 집합 $M$에 대한 엔트로피(Discrete)&lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;H(M)=E[I(M)]=\sum_{m\in M} p(m)I(m)=-\sum_{m\in M}p(m)\log p(m)&lt;/script&gt;

&lt;p&gt;여기서 $E[]$는 평균값(기대값)이다. 즉 평균을 계산하는 것이므로 각 변수와 그 변수에 대한 확률들을 더한 값이 엔트로피가 된다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;메시지 집합 $M$에 대한 엔트로피(Continuous)&lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;H(X)=E[I(X)]=\int p(x)I(x) dx = -\int p(x)\log(p(x))dx&lt;/script&gt;

&lt;p&gt;모든 변수 $x$에 대한 적분값으로 의미적으로는 기대값을 계산하는 것이므로 위의 식과 같다고 할 수 있다.
(여기서는 보통 $\log_2$대신 $\ln$을 사용한다.)&lt;/p&gt;

&lt;p&gt;그리고 어떤 메시지 공간에 대해 엔트로피가 최대가 되는 경우 또한 중요하다. 공간 $M$에 대해서 각 사건들이 uniform distribution이 되는 경우 엔트로피가 최대가 된다. 즉 각 사건의 확률이 $p(m)=\frac1M$으로 동일하다면 엔트로피가 최대가 된다.
($E[M]=\log|M|$)
&lt;br /&gt;&lt;/p&gt;
&lt;h4 id=&quot;joint-entropy&quot;&gt;Joint Entropy&lt;/h4&gt;
&lt;p&gt;&lt;br /&gt;
Discrte한 두 변수 $X,~Y$에 대한 entropy인 Joint Entropy는 다음과 같이 정의된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;H(X,Y)=E_{X,Y}=[-\log p(x,y)]=-\sum_{x,y}p(x,y)\log p(x,y)&lt;/script&gt;

&lt;p&gt;만약 $X,~Y$가 independent하면, Joint Entropy는 각각의 Entropy의 합이 된다.
Continuous한 경우의 Entropy도 Sigma 대신 Integral을 사용해서 계산하면 된다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h4 id=&quot;cross-entropy&quot;&gt;Cross Entropy&lt;/h4&gt;
&lt;p&gt;&lt;br /&gt;
Cross Entropy는 Joint Entropy와 수식적으로 비슷해 혼동되는 경우가 있는데, 다른 개념이다.
두 확률 분포 $p$와 $q$에 대해서 분포$p$ 대신 $q$를 사용해 분포 $p$를 설명할때 필요한 정보량을 Cross Entropy라 한다.&lt;/p&gt;

&lt;p&gt;수식을 보자.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;H(p,q) = E_p[-\log(q)] = -\sum_xp(x)\log q(x)&lt;/script&gt;

&lt;p&gt;정보를 나타내는 $log$값에 $p(x)$대신 $q(x)$를 사용한 것을 볼 수 있다. 즉 분포 $q(x)$를 활용해서 $p$를 설명하기 위해 $p$의 기대값을 구한 식이다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h4 id=&quot;conditional-entropy&quot;&gt;Conditional Entropy&lt;/h4&gt;
&lt;p&gt;&lt;br /&gt;
어떤 특정한 값을 같는 random variable $Y=y$에 대해 $X$의 conditional entropy는 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;H(X|Y=y)=E_{X|Y=y}[-\log p(x,y)]=-\sum_{x\in X}p(x|y)\log p(x|y)&lt;/script&gt;

&lt;p&gt;conditional entropy는 다음의 식이 성립한다&lt;/p&gt;

&lt;p&gt;&lt;script type=&quot;math/tex&quot;&gt;H(X|Y) = H(X,Y) - H(Y)&lt;/script&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;h4 id=&quot;kullback-leibler-divergencekl-divergence&quot;&gt;Kullback-Leibler divergence(KL-Divergence)&lt;/h4&gt;
&lt;p&gt;&lt;br /&gt;
KL-Divergence에 대한 수식을 설명하기 전에 개념의 Idea부터 얘기를 해보자.&lt;/p&gt;

&lt;p&gt;우리가 어떤 확률 분포 $p(x)$를 가지고 있다. 이 확률 분포를 전송을 해서 정보를 전달을 해야하는데 각각의 변수$x$에 대해 $p(x)$를 모두 전달하기에는 정보량도 많고 전달할 수단이 부족하다고 가정하자. 이때 우리는 분포 $p(x)$를 전달하기보다 이미 정의된 다른 확률 변수$q(x)$를 대신 전달하려는 생각을 했다. 이렇게 되면 어떤 분포인지, 그리고 분포의 특정 몇가지 값들만 전달하면 되므로 정보량 자체가 엄청나게 줄고 그래서 전송 또한 가능해진다.&lt;/p&gt;

&lt;p&gt;그러면 이제 새로운 문제에 봉착한다. 과연 어떤 분포 $q(x)$를 선택해서 보내야 하는가이다.
최대한 분포$p(x)$와 유사한 분포를 선택해야할 것이다. 이때 분포 $p$와 $q$의 유사한 정도를 계산하는 방법이 KL-Divergence이다.&lt;/p&gt;

&lt;p&gt;KL-Divergence는 그 값이 작을 수록 두 분포가 유사하다는 것을 의미하고 값이 0이 되면 두 분포가 같은 분포라는 뜻이 된다.&lt;/p&gt;

&lt;p&gt;KL-Divergence 수식을 위해서는 Cross Entropy를 사용한다. $p$를 $q$로 설명하는 정보량을 뜻하는 Cross Entropy에서 $p$가 자기자신을 설명하는 정보량인 $p$의 엔트로피의 차이가 KL-Divergence가 된다.
수식을 보자&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
D_{KL}(p||q) &amp;= H(p,q)-H(q)\\\\
&amp;=-\sum_{x\in X} p(x)\log q(x)-(-\sum_{x\in X}p(x))\\\\
&amp;=\sum_{x\in X}p(x)\log\frac{p(x)}{q(x)}
\end{align*} %]]&gt;&lt;/script&gt;

&lt;p&gt;두 엔트로피의 차이를 계산함으로써 $p$대신 $q$를 사용했을 때의 정보량의 차이를 계산하는 식이다. 그리고 KL-Divergence를 거리함수로 생각하는 경우도 있는데 엄밀하게 말하면 거리함수가 아니다. 왜냐하면 p,q를 바꿨을 때 두 값이 같아야 하지만 계산해보면 다르기 때문에 엄밀하게 거리함수라 할 수는 없다.&lt;/p&gt;

&lt;p&gt;이번 포스트에서 정보이론의 내용 중 정보량을 다루는 개념들에 대해서 알아보았다. 다음 포스트에서는 정보를 압축하는 방법들에 대해 다뤄보도록 한다.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>정보이론</title>
   <link href="https://reniew.github.io/16/"/>
   <updated>2018-07-12T05:47:35+00:00</updated>
   <id>https://reniew.github.io/16</id>
   <content type="html">&lt;h4 id=&quot;정보이론&quot;&gt;정보이론&lt;/h4&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;정보이론이란 최대한 많은 데이터를 매체에 저장하거나 채널을 통해 통신하기 위해 데이터를 정량화하는 응용수학의 한 분야이다.
&lt;br /&gt;
&lt;em&gt;출처 : 위키피디아&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;정보이론은 1948년 Claude E. Shannon에 의해 처음 소개되었으며 정보의 통신, 저장, 부량(Quantificaiton)에 대해 연구하는 분야이다. 정보이론을 활용한 분야로는 대표적으로 무손실 데이터 압축(e.g. ZIP files), 손실 데이터 압축(e.g. MP3, JPEG), 채널 코딩(e.g digital subscriber line(DSL))등이 있다. 보이저계획의 성공, compact disk, 휴대전화 개발등 많은 분야에서 중요한 역할을 했다.&lt;/p&gt;

&lt;p&gt;정보이론의 가장 핵심인 내용은 &lt;strong&gt;앤트로피(Entropy)&lt;/strong&gt; 이다. 엔트로피란 무작위 사건에 대한 결과 또는 random variable에 대한 불확실성을 포함하는 정보의 양이다.
예를 들어, 앞면 혹은 뒷면만 나오는 동전던지기의 결과에 대한 엔트로피와 6면체 주사위를 던졌을때 나오는 결과에 대한 엔트로피를 비교하면 후자가 더 크다.&lt;/p&gt;

&lt;p&gt;정보량 뿐만 아니라 정보이론에서 주요하게 다뤄지는 다른 내용들은 상호 의존정보(mutual information), 채널용량(channel capacity), error exponet, 상대 엔트로피(relative entropy)등이 있다.&lt;/p&gt;

&lt;p&gt;정보이론에 대해 모든 것을 다루기에는 어렵기도 어려우며, 양이 너무많아 정보량에 관한 내용과 압축에 관한 내용만 다음 포스트를 통해 소개하겠다. 다른 부분에 대해서는 아래 작성된 위키피디아의 목차에 대해 소개와 link를 통해 알아볼 수 있다.&lt;/p&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Information_theory#Quantities_of_information&quot;&gt;정보량&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Information_theory#Entropy_of_an_information_source&quot;&gt;정보의 엔트로피&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Information_theory#Joint_entropy&quot;&gt;결합 엔트로피&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Information_theory#Conditional_entropy_(equivocation)&quot;&gt;조건부 엔트로피&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Information_theory#Mutual_information_(transinformation)&quot;&gt;상호 의존 정보&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Information_theory#Kullback%E2%80%93Leibler_divergence_(information_gain)&quot;&gt;KL Divergence&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Information_theory#Coding_theory&quot;&gt;코딩이론&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Information_theory#Source_theory&quot;&gt;소스 이론&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Information_theory#Channel_capacity&quot;&gt;채널 용량&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;출처 : 위키피디아&lt;/p&gt;

&lt;hr /&gt;
</content>
 </entry>
 
 <entry>
   <title>Chater 5: Neural Laguage Models</title>
   <link href="https://reniew.github.io/15/"/>
   <updated>2018-07-11T04:47:35+00:00</updated>
   <id>https://reniew.github.io/15</id>
   <content type="html">&lt;h3 id=&quot;chapter-5&quot;&gt;Chapter 5&lt;/h3&gt;

&lt;h3 id=&quot;neural-language-models&quot;&gt;Neural Language Models&lt;/h3&gt;

&lt;p&gt;이 내용은 Newyork University의 조경현교수님의 DS-GA 3001강의 lecture note중 Neural Laguage Models단원을 정리한 내용입니다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 id=&quot;51-language-modeling&quot;&gt;5.1 Language Modeling&lt;/h3&gt;

&lt;p&gt;Machine이 우리의 언어를 이해하는 방법은 어떻게 될까?
가장 basic한 방법으로는 문장들이 얼마나 유사(Likeliness)한지에 대해 이해하는 것이다. 아래의 두 문장을 보자.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Colorless green ideas sleep furiously”&lt;br /&gt;
“Jane and me went to see a movie yesterday”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;첫 번째 문장은 문법적으로 완벽한 문장이다. 하지만 문장을 사람이 이해하려해도 어떤 의미인지 쉽게 받아 들여지지 않는다. 단어들끼리의 유사도가 매우 안맞는 문장이다. 그에 반해 두 번째 문장은 문법적으로는 잘못된 문장이다. me 대신 i가 들어가야 하지만, 저 문장을 이해하는데는 어려움이 없이 쉽게 이해 된다.&lt;/p&gt;

&lt;p&gt;따라서 우리는 기계에게 문장을 이해시키는 방법으로 유사도를 통한 의미적인 부분을 학습시킬 것이다. 물론, 문법적인 부분도 해야 하겠지만 이는 어려운 문제이다.&lt;/p&gt;

&lt;h4 id=&quot;52-what-if-those-linguistic-structures-do-exist&quot;&gt;5.2 What if those linguistic structures do exist&lt;/h4&gt;

&lt;p&gt;Language Modeling에 대해 통계학적 접근법은 문법적으로 완벽한 문장을 유사하지 않다고 결론 지을 수 있다. 이러한 문제는 문장들간의 유사도에 대해서 다루는 문제를 확률 모델로 만들 수 있을 것이다. 주어진 문장 $S$가 있다고 하자, 이때 확률 $P(S)$는 어떻게 구할 것인가?
(여기서 $P(S)$는 간략하게 유사도와 문법적 정확도를 같게 보는 것으로 해석할 것이다.)
 우선 $S$에 의해 만들어지는 잠재적 언어학 구조를 $G$라 가정하자. 아래와 같은 식을 얻을 수 있다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(S,G) = p(S|G)p(G)&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(S)=\sum_G p(S, G)&lt;/script&gt;

&lt;p&gt;하지만 여기서 $G$는 정해진 것이 아니므로, 무한할 수 있다. 따라서 실제 계산을 위해서는 Lower bound를 사용해 아래와 같은 식을 사용해 $p(S)$를 근사한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(S)=\sum_G p(S, G) \ge p(S,\hat G)&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;where\;\hat G = argmax_G p(S,G) = argmax_G p(G|S)&lt;/script&gt;

&lt;p&gt;하지만 이러한 모델링에도 문제점이 있다. 첫 째로, $G$를 사용하는 것에 대해 명백하지 않다. 둘 째로는 이러한 형식들이 의미적으로 불확실하다.&lt;/p&gt;

&lt;p&gt;이제부터는 model-free한 접근법에 대해서 알아볼것이다.&lt;/p&gt;

&lt;h4 id=&quot;512-quick-note-on-linguistic-units&quot;&gt;5.1.2 Quick Note on Linguistic Units&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;“언어학적 최소 단위가 무었일까?”&lt;/em&gt;
위 질문에 대한 대답은 음소(phoneme)가 될 것이다. 하지만 “음소가 언어를 이해할 수 있는 단계인가?” 에 대해서는 아니라고 할 것이다.
이러한 low-level의 unit들 (음소, 글자)는 의미를 수반하지 않기 떄문에 이해할 수 있는 단계가 아니다. 따라서 우리는 한 단어를 최소 단위로 의미를 이해할 수 있다. 그러나 여기에도 문제가 있다. ‘어떤것을 단어로 볼 것인가?’ 보통은 띄어쓰기(sequence of non-blank characters)를 기준으로 단어를 구분한다. 그러나 구두점과 같은 것들이 나오면 단어에 대한 정의가 애매해진다.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;“hello,” , “hello.”, “hello!”, “hello?”, ““hello””, “‘hello’”
위의 hello들은 모두 같은 단어이지만 구두점 때문에 다른 의미로 해석될 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;뿐만 아니라 중국어 같은 언어에서는 띄어쓰기가 사용되지 않아서 위와 같은 정의를 적용시킬 수 없다.
따라서 우리는 이 최소단위에 대한 정의에 대한 고민을 해야 할 것이다. 이 분야는 물론 지금도 계속 연구되고 있고 답이 없는 분야이다. 즉, character와 word 사이의 적절한 liguistic unit이 있는지를 찾아야 한다.&lt;/p&gt;

&lt;h3 id=&quot;52-statical-laguage-model&quot;&gt;5.2 Statical Laguage Model&lt;/h3&gt;

&lt;p&gt;Liguistic unit에 상관없이, 어떤 문장$S$는 $T$개의 각각의 symbol들로 구분될 수 있다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;S=(w_1, w_2, ... ,w_T)&lt;/script&gt;

&lt;p&gt;각 symbol들은 vocabulary라는 가능한 모든 symbol이 모여있는 집합의 원소이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;V= \{v_1, v_2, ... , v_{|V|}\}&lt;/script&gt;

&lt;p&gt;Laguage Modeling 문제는 Sentence에 대해 확률 $P(S)$를 할당하는 model을 찾는 문제이다.
그러나 우리는 확률 분포에 대한 정보가 없을 것이고, Data로 부터 학습을 해야 할 것이다.
$D$를 $N$개의 Sentence를 가지고 있는 Data라 하자.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;D=\{S^1, S^2, ... S^N\}&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;S^n = (w_1^n, w_2^n, ... w_{T^n}^n)&lt;/script&gt;

&lt;p&gt;$T^n$이라는 표현은 각 sentence들의 길이가 다르다는 것을 의미한다.&lt;/p&gt;

&lt;p&gt;이제 주어진 Data $D$에 대해 Sentence $S$의 확률을 다음과 같이 정의하자.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(S) = \frac{\sum_n^NI_{S=S^n}}{N}&lt;/script&gt;

&lt;p&gt;여기서 $I$는 indicator function으로 동일한 Sentence면 1, 아니면 0을 주는 함수이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
I_{S=S^n}=\bigg\lbrace\begin{matrix} 1, &amp; \text{if}\ \ S=S^n \\ 0, &amp; \text{otherwise} \end{matrix} %]]&gt;&lt;/script&gt;

&lt;p&gt;위의 확률은 sentence $S$가 Data 내에서 몇번 나왔는지와 같다.&lt;/p&gt;

&lt;h4 id=&quot;521-data-sparsityscarcity&quot;&gt;5.2.1 Data Sparsity/Scarcity&lt;/h4&gt;

&lt;p&gt;Laguage model에서 가장 중요한 issue는 corpus의 크기가 얼마나 큰가이다. 즉 dataset의 크기가 중요한데, 실제 세계의 사용가능한 모든 문장을 data로 가지고 있을 수는 없다.
$|V|$개의 symbol을 가지는 vocabulary가 있다고 하자. 각 sentence의 최소한 $T$개의 symbol가진다. 이러한 vocabulary는 충분히 큰 크기가 될 것이다(100k ~ 1M). 그럼에도 불구하고, 많은 실제로 사용할만한 문장임에도 불구하고 corpus에 포함되지 않을 수 있다.
그 예를 한번 찾아보자. Google Books Ngram Viewer라는 서비스는 Google Books의 문장들이 모두 모여있는 거대한 corpus를 나타낸다. 여기서 “I like llama”라는 문장을 검색해보자, 이 문장은 충분히 사용할만한 문장임에도 불구하고 결과가 나오지 않는다.
&lt;img src=&quot;https://i.imgur.com/keV0Uh7.jpg&quot; alt=&quot;3123123&quot; /&gt;
이전 part에서 정의한 sentence에 대한 확률을 생각해보자, “i like llama”라는 문장은 corpus에 존재하지만, 많이 등장하지는 않을 것이다. 따라서 데이터셋이 매우 크므로 확률은 거의 0에 수렴할 것이다. 이러한 문제를 &lt;em&gt;data sparsity&lt;/em&gt; 라 부른다.
즉 trainning set이 전체 input space를 cover하지 못하는 경우를 뜻한다.&lt;/p&gt;

&lt;h3 id=&quot;53-n-gram-language-model&quot;&gt;5.3 n-Gram Language Model&lt;/h3&gt;

&lt;p&gt;Data Sparsity 문제는 sentence의 최대 길이가 커질수록 악화된다. 우리는 이 사실에 착안해서 straightforward한 접근법을 사용한다. (&lt;em&gt;limit the maximum length of phrases/sentences we estimate a probability on&lt;/em&gt;)
이러한 idea는 n-Gram language model의 base가 되었다.
n-Gram 모델에서는 위에서 정의한 sentence에 대한 확률을 재정의한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
p(S)=p(w_1,w_2,...w_T)=p(w_1)p(w_2|w_1)\dotsm p(w_k|w_{&lt;k})\dotsm p(w_T|w_{&lt;T}) %]]&gt;&lt;/script&gt;

&lt;p&gt;여기에서 $w_{&amp;lt;k}$는 k 번째 symbol 이전의 모든 symbol들을 뜻한다. 아래의 식과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
p(w_k|w_{&lt;k})\approx p(w_k|w_{k-n},w_{k-n+1},...,w_{k-1}) %]]&gt;&lt;/script&gt;

&lt;p&gt;따라서 Sentence의 확률이 다음과 같이 정의된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(S)\approx \prod_{t=1}^Tp(w_t|w_{t-n},...w_{t-1})&lt;/script&gt;

&lt;p&gt;위 식이 의미하는 것은 sentence내의 symbol은 이전의 $n-1$개의 symbol들에 의해 predictable하다는 것이다.
예를 들어 “In Korea, more than half of all the residents speak Korean” 문장을 보면 마지막의 ‘Korean’이라는 단어는 사람과 언어 두가지 의미를 가지는데, 그 이전의 speak과 Korea라는 단어에 대해 상대적인 확률로 생각을 해보면 언어를 뜻하는 것이 더 타당하다는 것을 알 수 있다. 즉 n-Gram 모델을 사용하면 이전의 symbol에 대한 정보를 가지고 현재 symbol의 의미를 파악하기 때문에 유용하다는 것을 알 수 있다.
위의 예를 통해 보면, 확률 추정의 정확도와 $n$의 크기에 따른 통계적인 효율은 trade-off 관계에 있다는 것을 알 수 있다. 즉, $n$의 값이 커질수록, conditional distribution은 더 나은 결과를 만들 것이지만 data sparsity는 커져 정확도가 떨어질 수 있다.M&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;n-gram Probablity Estimate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;n-gram conditional probabilty는 trainning corpus를 통해 계산할 수 있다. 아래의 식을 보자.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(w_k|w_{k-n},w_{k-n+1},...,w_{k-1})=\frac{p(w_{k-n},...w_{k-1},w_k)}{p(w_{k-n},...,w_{k-1})}&lt;/script&gt;

&lt;p&gt;여기서 분모는 다음과 같이 계산할 수 있다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(w_{k-n},...,w_{k-1})=\sum_{w^\prime\in V}p(w_{k-n},...,w_{k-1},w^\prime)&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(w_{k-n},...,w_{k-1},w^\prime)\approx \frac{c(w_{k-n},...w_{k-1},w^\prime)}{N_n}&lt;/script&gt;

&lt;p&gt;여기서 $c(\cdot)$가 의미하는 것은 trainning corpus에서 주어진 n-gram의 등장 횟수이다. 그리고 $N_n$은 trainning corpus에서의 모든 n-gram의 수 이다.
마지막으로 다음과 같이 식을 정리한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(w_k|w_{k-n},...,w_{k-1})=\frac{\cancel{\frac{1}{N_n}}c(w_{k-n},...,w_{k-1},w^\prime)} {\cancel{\frac{1}{N_n}}\sum_{w^\prime\in V}c(w_{k-n},...w_{k-1},w^\prime)}&lt;/script&gt;

&lt;h4 id=&quot;531-smoothing-and-back-off&quot;&gt;5.3.1 Smoothing and Back-Off&lt;/h4&gt;

&lt;p&gt;n-gram model의 가장 큰 issue는 어떤 n-gram을 포함하는 sentence에 대해 얼마다 다른 n-gram들과 유사한지와 상관없이 0의 확률을 갖는 것이다.
예시를 통해 이러한 경우에 대해 살펴보자.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;“I like llama which is a domesticated South American camelid”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위의 문장에 대한 확률은 다음과 같이 계산될 것이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
&amp;p(\text{&quot;I&quot;,&quot;like&quot;,&quot;llama&quot;,&quot;which&quot;,&quot;is&quot;,&quot;a&quot;,&quot;domesticated&quot;,&quot;South&quot;,&quot;American&quot;,&quot;camelid&quot;}\\
&amp;=p(&quot;\text{I}&quot;)p(&quot;\text{like}&quot;|&quot;\text{I}&quot;)\underbrace{p(&quot;\text{llama}&quot;|&quot;\text{I}&quot;,&quot;\text{like}&quot;)}_{=0}\dotsm p(&quot;\text{camelid}&quot;|&quot;\text{South}&quot;,&quot;\text{American}&quot;)\\
&amp;=0
\end{align*} %]]&gt;&lt;/script&gt;

&lt;p&gt;위 식과 같이 특정 n-gram 확률 때문에 전체가 0이되는 문제를 해결하기 위해 corpus의 크기를 키우면 되지 않을까 라고 생각한다. 하지만 이러한 “data sparsity” 문제는 corpus의 크기와 상관없이 statistical modeling에서 항상 발생하는 문제이다. 그렇다면 어떻게 해결해야 할 것인가?
방법은 기존에 존재하지 않는 n-gram에 대해 작은 특정 값을 갖도록 하는 것이다. 그러면 기존에 나오지않은 n-gram이더라도 특정 값을 가지므로 0이 되는 문제는 발생하지 않을 것이다. 식을 아래와 같이 구현함으로써 이 방법을 사용할 수 있다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
p(w_k|w_{k-n},...,w_{k-1})&amp;=\frac{\alpha+c(w_{k-n},...,w_{k})}{\sum_{w^{\prime}\in V}(\alpha+c(w_{k-n},...,w^\prime))}\\
&amp;=\frac{\alpha+c(w_{k-n},...,w_{k})}{\alpha|V|+\sum_{w^{\prime}\in V}c(w_{k-n},...,w^\prime)}
\end{align*} %]]&gt;&lt;/script&gt;

&lt;p&gt;$\alpha$는 scalar 값으로 보통 다음의 범위로 정한다. $0&amp;lt;\alpha\le1$&lt;/p&gt;

&lt;p&gt;&lt;em&gt;unseen n-gram&lt;/em&gt; 을 위와 같이 해결하는 방법을 smoothing 기법(부족한 데이터를 해결하는 방법)이라 표현하고 위와 같이 특정 scalar값을 더해주는 방법을 Additive Smoothing 혹은 Lidstone Smoothing이라고 표현한다. 그 중 $\alpha$값으로 1을 지정하는 방법은 Laplace Smoothing이라고 한다.(Laplace는 한번도 안나온 데이터에 대해 최소 한번은 나왔다고 지정하는 방법)
 하지만 직관적으로 봐도 위 방법은 효율일 잘 안나올 것 같다. unseen n-gram들에 대해 모두 다 똑같은 빈도수를 준다는 점에서 문제가 발생한다.&lt;/p&gt;

&lt;p&gt;이에 대한 해결책은 n-gram 확률을 interpolation 방법을 통해 smoothing하는 것이다. 수식은 다음과 같이 정의한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\begin{align*}
p^S(w_k|w_{k-n},...,w_{k-1})=&amp;\lambda(w_{k-n},...,w_{k-1})p(w_k|w_{k-n},...,w_{k-1})\\
&amp;+(1-\lambda(w_{k-n},...,w_{k-1}))p^S(w_k|w_{k-n+1},...,w_{k-1})
\end{align*} %]]&gt;&lt;/script&gt;

&lt;p&gt;위 식에 따르면 n-gram 확률은 이전 n-gram확률에 의해 재귀적으로 계산되는 것을 볼 수 있다. 이제 중요한 것은 $\lambda$값을 어떻게 지정해야할까 이다. 간단한 방법은 데이터에 맞추는 방법이다. 즉 데이터에서 출현빈도에 초점을 맞추는 방법이다. $\lambda$값까지 정한뒤 일반화하면 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p^S(w_k|w_{k-n},...,w_{k-1})=
\begin{cases}
\alpha(w_k|w_{k-n},...,w_{k-1}),~~\text{if}~~c(w_{k-n},...,w_{k-1},w_k)&gt;0\\
\gamma(w_{k-n+1},...,w_k)p^S(w_k|w_{k-n+1},...,w_{k-1}),~otherwise
\end{cases}&lt;/script&gt;

&lt;p&gt;여기서 $\alpha$값과 $\gamma$값의 선택에 따라 여러 techniques으로 나뉜다.&lt;/p&gt;

&lt;p&gt;대표적인 smoothing 방법은 KN smoothing과 GT smoothing 방법이다. 이에 대한 설명은 생략한다.&lt;/p&gt;

&lt;h4 id=&quot;532-lack-of-generalization&quot;&gt;5.3.2 Lack of Generalization&lt;/h4&gt;

&lt;p&gt;n-gram 모델이 대부분의 상황에서 잘 동작하지만, 몇몇 특수한 상황에서 아쉬운 상황을 생긴다. 그 이유 중 하나는 Lack of Generalization인데, 여기서 말하는 Generalization은 아래의 예를 보며 이해를 하자.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Chases a rabbit&lt;/li&gt;
  &lt;li&gt;Chases a cat&lt;/li&gt;
  &lt;li&gt;Chases a dog&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;세 문장을 보면 우리는 Chases라는 단어 뒤에 오는 단어에 대한 패턴을 인식할 수 있다. 즉 사람은 일정한 단어들을 보고 그것들의 상위개념들을 이해할 수 있다. 하지만 n-gram 모델에서는 이런 상위개념들로 일반화시키는 것을 할 수 없다.&lt;/p&gt;

&lt;p&gt;만약 n-gram 모델에게 이런 일반화 과정들을 이해시키려면 각 단어의 정의에 대한 사전을 이해시키거나 각 단어의 정확한 뜻을 알려주는 방법인데 이 방법을 해결한다는 것은 정의를 text로 알려주는 한 결국 Language를 이해시키는 것과 똑같기 때문에 불가능 하다.&lt;/p&gt;

&lt;p&gt;다음 장에서는 이런 Lack of Generalization문제를 어느정도 해결하는 방법에 대해서 살펴보도록 하자.&lt;/p&gt;

&lt;h3 id=&quot;54-neural-language-model&quot;&gt;5.4 Neural Language Model&lt;/h3&gt;

&lt;p&gt;n-gram 모델은 현재 단어 이전의 n개의 단어에 대해 현재 단어에 대한 조건부 확률을 계산하는 것이였다. 즉 n개의 단어에 대해 확률을 구하는 함수를 찾는 것이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(w_k|w_{k-n},...,w_{k-1})=f^{w_k}_\theta (w_{k-n},...,w_{k-1})&lt;/script&gt;

&lt;p&gt;위 함수를 정의하기 위해 가장 먼저 해야 할 것은 input값을 정의하는 것이다. 사전의 단어에 대한 정보를 최소화 해야하기 때문에 우리는 one-hot encoding 방식을 사용할 것이다. input은 다음과 같이 정의된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;w_i=[0, 0,...,1,...0]^\intercal\in{0,1}^{|V|}&lt;/script&gt;

&lt;p&gt;이제 일반적인 Neural Net과 비슷한 방식으로 계산한다. 우선 간 단어 벡터에 가중치 행렬( $E\in\mathbb{R}^{|V| \times d}$ )을 곱해서 연속된 vector들을 구하자.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p^j=E^\intercal w^j&lt;/script&gt;

&lt;p&gt;input값이 one-hot vector였던 것을 생각하자. 가중치 행렬과 곱해질 때 $w_k$는 1이 1개만 있으므로 가중치 행렬의 k번째 행과만 계산될 것이다. 따라서 가중치 행렬은 다음과 같이 각 벡터들의 모음으로 작성할 수 있다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;E=
\begin{bmatrix}
e_1\\
e_2\\
\vdots\\
e_{|V|}
\end{bmatrix}&lt;/script&gt;

&lt;p&gt;따라서 input과 가중치 행렬의 곱은 다음과 같이 정의된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;E^\intercal w_i = e_i&lt;/script&gt;

&lt;p&gt;이 식이 의미하는 바는 가중치 행렬의 i행 vecter인 $e_i$는 단어들중 i번째 단어를 포현하는 벡터로 해석될 수 있다는 점이다. 따라서 $e_i$벡터를 input값으로 사용할 것이다. 이제 input값이 n개의 vector를 concat한 뒤 non-linear하게 만들어 주면 모델링 과정이 끝난다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{p}=[p^1;p^2;...;p^n]^\intercal&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{h}=\tanh(\mathbf{Wp+b})&lt;/script&gt;

&lt;p&gt;최종적으로 모델링을 사용한 조건부 확률은 다음과 같이 정의된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(w_n=k|w_1,...w_{n-1}) =\mu_k=\frac{\exp(u_k^\intercal h+c_k)}{\sum^{|K|}_{k'=1}\exp(u_{k'}^\intercal h+c_{k'})}&lt;/script&gt;

&lt;h4 id=&quot;541-how-does-neural-language-model-generalize-to-unseen-n-grams---distributional-hypothesis&quot;&gt;5.4.1 How does Neural Language Model Generalize to Unseen n-Grams? - Distributional Hypothesis&lt;/h4&gt;

&lt;p&gt;이때까지 Neural language model에 대해서 소개했다. 이번에는 주로 unseen n-gram을 generalize하는 방법에 대해서 알아보도록 한다.&lt;/p&gt;

&lt;p&gt;이전의 neural language model을 두개의 합수의 합성으로 만들어보자. ($f\circ g$) 먼저 $f$는 context word의 순열 또는 n-1개의 앞선 단어를 벡터로 만들어 주는 함수라고 한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;f:\{0,1\}^{|V|\times n-1}\rightarrow \mathbb{R}^d&lt;/script&gt;

&lt;p&gt;각 단어에 대해 $f$함수를 통과시킨 결과로 나온 $d$ 차원의 벡터를 $\mathbf{h}$라 하고 context vector라 부른다. 두 번째 단계인 $g$는 continuous vector인 $\mathbf{h}$를 단어 확률로 만들어 주는 함수이다. 이 단계에서 affine 변환과 softmax함수를 통한 일반화 과정이 포함된다. 이전에 사용된 확률 함수인 $g$를 다시 한번 살펴보자.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\frac{\exp(u_k^\intercal h+c_k)}{\sum^{|K|}_{k'=1}\exp(u_{k'}^\intercal h+c_{k'})}&lt;/script&gt;

&lt;p&gt;간단한 형태로 보기위해 bias인 $c$를 빼고 확인해보자.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\frac{\exp(u_k^\intercal h)}{\sum^{|K|}_{k'=1}\exp(u_{k'}^\intercal h)}&lt;/script&gt;

&lt;p&gt;$k$ 번째 확률은 output vector인 $u_k$(output matrix $\mathbf{U}$의 $k$ 번째 행)가 context vector인 $\mathbf{h}$와 잘 맞을 경우 커질 것이다. 즉 다음 단어로 k 번째 단어가 등장할 확률은 context vector인 $\mathbf{h}$와 해당 word vector인 $u_k$와 내적한 값에 비례할 것이다.&lt;/p&gt;

&lt;p&gt;두 개의 context vector $\mathbf{h}_j$와 $\mathbf{h}_k$가 있다고 하자. 각 문맥은 단어들 간의 유사도(다음 단어의 조건부 분포가 서로 얼마나 유사한지)에 따라 결정된다.&lt;/p&gt;

&lt;p&gt;context vector 를 고려한 특정 target 단어 $w_l$에 대한 확률을 보자.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\begin{matrix}
p^l_j=p(w_l|h_j)=\frac{1}{Z_j}\exp(\mathbf{w}_l^T \mathbf{h}_j)\\
p^l_k=p(w_l|h_k)=\frac{1}{Z_k}\exp(\mathbf{w}_k^T \mathbf{h}_j)
\end{matrix}&lt;/script&gt;

&lt;p&gt;두 context(문맥)에 대한 확률의 비율은 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\frac{p^l_j}{p^l_k}=\frac{Z_K}{Z_j}\exp(\mathbf{w}_l^T(\mathbf{h}_j-\mathbf{h}_k))&lt;/script&gt;

&lt;p&gt;위 식을 보면, 두 context에 대한 확률이 같아질려면($\frac{p^l_j}{p^l_k}$) 아래의 식을 만족시켜야 한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mathbf{w}_l^T(\mathbf{h}_j-\mathbf{h}_k)=0&lt;/script&gt;

&lt;p&gt;위 식을 만족시키는 경우에 대해서 알아보자. 우선 단어 벡터인 $\mathbf{w}$는 0이 아니라 가정한다. 위 식이 0이 되려면 두 context 벡터의 값이 같아져야 한다. 즉 다시 말해, 두 context 벡터값이 서로 유사해져야 한다는 뜻이다.(이를 테면 유클리디언 거리가 가깝다) 이러한 상황이 의미하는 것이 무엇일까? 이것은 neural language model은 다른 주변의 n-gram은 먼 지점으로 투영하면서 동일한 단어에 따라 나오는 (n-1)-gram을 context 벡터 공간에서 비슷한 지점으로 투영해야 한다. 즉 이는 같은 단어에 대해 비슷한 확률을 주기 위해 필요하다. 만약 이와 같이 동일한 단어에 대해 context vector 공간의 다른 지점으로 투영한다면 우리가 예측해야할 다음 단어에 대한 확률이 다르게 나올 것이고 이는 좋지 않은 language model이다.&lt;/p&gt;

&lt;p&gt;위의 설명에 대해 직관적인 이해를 위해 극단적인 예를 한번 들어보자. 아래의 세 문장을 보자&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;There are &lt;strong&gt;three teams&lt;/strong&gt; left for the qualification&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;four teams&lt;/strong&gt; have passed the first round&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;four groups&lt;/strong&gt; are playing in the field&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;굵은 글씨들을 보자. 이 bigram의 각 첫 번째 단어가 context word이다. 그리고 neural language model은 이 context 단어 뒤에 나오는 단어의 확률을 예측해야 한다.&lt;/p&gt;

&lt;p&gt;여기서 neural laguage model은 “three”와 “four”를 context space의 비슷한 지점으로 투영해야 할 것이다. 즉 이 두 단어의 context vector는 “teams”에 대한 비슷한 확률을 만들어야 한다. 그리고 각 target 단어인 “teams”와 “groups”은 각 vector가 유사해야 할 것이다.&lt;/p&gt;

&lt;p&gt;이제 위의 세 문장을 학습시킨 neural language 모델에서 unseen n-gram인 “three group”에 대한 확률을 할당하는 것을 생각해보자. 위 문장으로 학습시킨 모델은 “three”의 context vector 와 “four”의 context vector는 context 공간에서 비슷한 지점으로 투영시킬 것이다. 따라서 “three”의 context vector에 의해 다음 단어가 “group”일 확률을 높게 계산할 것이다.&lt;/p&gt;

&lt;p&gt;이러한 과정을 통해 neural language 모델은 unseen n-gram 에 적당한 확률값을 줄 수 있다. 위의 예를 통해 확인할 수 있는 점은 neural laguage 모델은 자동으로 다른 context vector들 사이의 유사도를 측정할 수 있다는 점이다.(target word가 다르더라도, 동시 등장확률에 의해)&lt;/p&gt;

&lt;p&gt;실제 세계에서 우리의 언어는 “Distributional Hypothesis”를 만족하는 것은 자명하다. 즉 유사한 의미를 갖는 단어는 비슷한 위치에 등장한다. 따라서 단어들이 같이 등장하는 단어들을 관찰하면 단어의 잠재 의미를 뽑아낼 수 있을 것이다.&lt;/p&gt;

&lt;h4 id=&quot;542-continuous-bag-of-words-language-model-maximum-pseudo-likelihood-approach&quot;&gt;5.4.2 Continuous Bag-of-Words Language Model: Maximum Pseudo-Likelihood Approach&lt;/h4&gt;

&lt;p&gt;“&lt;em&gt;왜 우리는 language modeling을 할 때 앞선 단어만 고려하는 것일까?&lt;/em&gt;” “&lt;em&gt;앞선 단어만 의존한 단어 분포가 적합한 가정일까?&lt;/em&gt;”&lt;/p&gt;

&lt;p&gt;위 두개의 질문에 대한 대답은 “&lt;em&gt;꼭 그럴 필요는 없다&lt;/em&gt;” 가 될것이다. 우리는 특정 단어에 대해 앞선 단어가 아닌 해당 단어 앞 뒤로 $n$개의 단어를 고려하는 모델을 만들 수 있다. 이러한 모델이 &lt;em&gt;Markov random field language model&lt;/em&gt; 이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/BYTtwE8.jpg&quot; alt=&quot;markov&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Markov random field language 모델 (MRF-LM)에서 주어진 문장에서 각 단어는 랜덤 변수 $w_i$로 말할 수 있다. 그리고 둘러싼 $2n$개의 각 단어를 비방향 선(undirected edges)으로 각 단어를 연결할 수 있다. 여기서 연결된 선은 조건부 의존성(conditional dependency) 구조를 의미한다. 위의 그림이 n=1 일때의 MRF-LM을 그림으로 나타낸 것이다. 이 경우에 Markov random field의 확률은 각 그래프의 꼭지점(clique)의 potential 값들의 곱으로 표현된다. 여기서 potential이란 각 꼭지점에서 각 input 값이 random 변수인 positive 함수를 의미한다.&lt;/p&gt;

&lt;p&gt;MRF-LM에서 두개의 랜덤 변수의 꼭지점을 제외한 모든 꼭지점에는 1의 potential을 할당한다.(즉, pairwise potential만을 사용한다) $i$ 와 $j$ 단어의 pairwise potential은 다음과 같이 정의된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\phi(\mathbf{w}^i,\mathbf{w}^j)=\exp\big((\mathbf{E}^T\mathbf{w}^i)^T(\mathbf{E}^T\mathbf{w}^j)\big)&lt;/script&gt;

&lt;p&gt;여기서 $E$는 위에서 나왔던 가중치 행렬을 의미한다. 그리고 $\mathbf{w}^i$는 $i$번 째 단어의 one-hot vector이다. 위 식은 많은 pairwise potential 중 하나이고 다른 많은 경우도 있다.(가령 dot product로 정의 할 수도 있다)&lt;/p&gt;

&lt;p&gt;위의 식과 함께 전체 Sentence의 확률은 다음과 같이 정의된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(w_1,w_2,...,w_T)=\frac1Z \prod_{t=1}^{T-n}\prod_{j=t}^{t+n}\phi(\mathbf{w}^t,\mathbf{w}^j)=\frac1Z \exp(\sum^{T-n}_{t=1}e^T_{w^t}e_{w^j})&lt;/script&gt;

&lt;p&gt;여기서 $Z$는 일반화 상수이다. 이 값은 potential의 곱을 확률로 만들어준다. 이 값을 전체 문장에 대해 계산하는건 불가능하기 떄문에 주어진 condition의 단어들에 대해 각 단어에 대해 조건부 확률을 계산한다.&lt;/p&gt;

&lt;p&gt;조건부 확률을 계산할 떄는 각 단어에 대해 Markov blanket이라 불리는 부분에 포함된 단어의 값에 의해 계산된다. 여기서 Markov blanket이란 각 단어를 둘러싼 $n$개의 단어를 뜻한다. 즉 각 단어의 앞의 $n$개 뒤의 $n$개의 단어를 본다. 따라서 조건부 확률은 다음과 같이 정의 될 것이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(w^i|w^{i-n},...,w^{i-1},w^{i+1},...,w^{i+n})=\frac{1}{Z'}\exp\bigg(\mathbf{e}^T_{w^i}\bigg(\sum^n_{k=1}\mathbf{e}^T_{w^{i-k}}+\sum^n_{k=1}\mathbf{e}^T_{w^{i+k}}\bigg)\bigg)&lt;/script&gt;

&lt;p&gt;여기서 일반화 상수인 $Z’$은 다음과 같이 계산된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;Z'=\sum_{v\in V}\exp\bigg(\mathbf{e}^T_v\bigg(\sum^n_{k=1}\mathbf{e}^T_{w^{i-k}}+\sum^n_{k=1}\mathbf{e}^T_{w^{i+k}}\bigg)\bigg)&lt;/script&gt;

&lt;p&gt;앞서봤던 neural language 모델과 굉장히 비슷하다는 것을 볼 수 있다. 이러한 조건부 확률은 얕은(shallow) neral network와 같다. input이 context 단어들인 한개의 linear한 은닉층을 가지고, output이 중심 단어에 대한 조건부 확률이 되는 것이다. 이 network를 그림으로 표현하면 다음과 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/KBcqdfp.jpg&quot; alt=&quot;cbo&quot; /&gt;&lt;/p&gt;

&lt;p&gt;우리는 이미 전체 문장에 대한 확률 $p(w^1,…,w^T)$을 직접 계산하는 것은 $Z$ 게산량이 많아 어렵다는 것을 알고 있다. 다행이 상대적으로 계산이 쉬운 조건부 확률을 계산하는 것을 확인했다. 전자의 경우는 log-likelihood를 최대화하는 것과 같고, 후자의 경우에는 pseudo-likelihood를 최대화 하는 것과 같다.&lt;/p&gt;

&lt;p&gt;따라서 MRF-LM의 Pseudo-likelihood는 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\log \text{PL}=\sum^T_{i=1}\log p(w^i|w^{i-n},...,w^{i-1},w^{i+1},...,w^{i+n})&lt;/script&gt;

&lt;p&gt;위의 Pseudo-likelihood를 최대화 하는 것은 위의 그림의 network를 학습하는 것과 동일하다. 즉 주변 단어에 대한 중심 단어의 확률을 높이는 것이다.&lt;/p&gt;

&lt;p&gt;위의 식을 잘 계산한다해도 아직 전체 문장에 대한 확률을 계산하는 좋은 방법은 없다. 어떤 특정한 상황에서는 pseudo-likelihood 값이 maximum likelihood 값에 수렴하기도 하지만 그렇다고 조건부 확률들의 곱이 전체 문장의 확률을 대체할 수 있는 것은 아니다. 그렇지만 다행이도 MRF-LM 모델을 사용한다면 pseudo-probability도 다른 문장의 점수를 줄 수 있다. 앞서서 우리가 처음 neural language 모델에 대해 처음 봤을 떄는 각 단어의 조건부 확률을 첫 단어부터 마지막까지 곱하면 주어진 문장의 확률을 구할 수 있다는 내용과는 대조적이다. 이러한 결과가 MRF-LM을 laguage 모델로 잘 사용하지 않는 이유 중 하나일 것이다. 하지만 이 단원에서 처음으로 이 복잡한 모델을 설명한 이유가 있다.&lt;/p&gt;

&lt;p&gt;Continuous bag-of-words(CBOW)에서 처음 소개된 이러한 접근법은 흥미로운 특징을 발견했다. CBOW 모델의 한 부분인 학습된 단어 임베딩 행렬 $\mathbf{E}$가 단어의 잠재 구조를 매우 잘 반영한다는 것이다. 결국 이 모델은 최근 자연어 처리 분야에서 가장 각광받는 기술이 되었다. 다음 장에서 이 부분에 대해 더욱 다뤄볼 것이다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skip-Gram and Implicit Matrix Factorization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Markov에 의해 CBOW모델 뿐 아니라 skip-gram이라 불리는 모델 또한 소개되었다. skip-gram모델은 CBOW의 반대되는 모델이라 생각하면 된다. 주변 $2n$개의 단어에 의해 중심단어를 예측한는 CBOW와는 반대로 skip-gram의 경우는 중심 단어를 통해 주변 $2n$개의 단어를 예측하는 모델이다. 그리고 실제로 두 모델에 의해 생성된 단어 vector 중 skip-gram에 의해 만들어진 vector가 좀 더 효과가 좋다는 것이 결론이다. 물론 좋은 단어 vector를 판단하는 것은 논란의 여지가 있는 부분이지만 많은 “intrinsic”한 평가에서 skip-gram 모델이 더 좋은 것으로 보여진다.
위 기술들을 만든 Markov는 negative sampling으로 skip-gram모델을 학습시키는 것은 positive point-wise mutual information matrix(PPMI) 을 2 lower-dimensional matrix로 만드는 것과 동일하다고 한다.&lt;/p&gt;

&lt;h4 id=&quot;543-semi-supervised-learning-with-pretrained-word-embeddings&quot;&gt;5.4.3 Semi-Supervised Learning with Pretrained Word Embeddings&lt;/h4&gt;

&lt;p&gt;위에 나온 n-gram language model, neural language modellanguage model, continuous bag-of-words 모델들에서 중요한 점은 모든 모델이 unsupervised 하다는 점이다. unsupervised가 중요한 이유는 각 데이터에 대해 label을 필요로 하지 않는다. 이러한 점이 다른 modeling에 비해 statical한 modeling이 language modeling에 더욱 적합한 이유이다. 그리고 label이 필요없기 때문에 학습 시킬 수 있는 데이터는 무한히 많이 존재한다는 장점이 있다. 그리고 소개된 modeling중에 embedding된 word vector는 자연어 처리 분야에서 최근에 대부분이 사용하게 됬다.&lt;/p&gt;

&lt;p&gt;하나의 예를 들어보자. 영어 단어를 긍정과 부정으로 나누는 문제이다. 예를 들어 “happy”는 긍정이고, “sad”는 부정으로 분류하는 문제이다. 긍정 부정 각각 1개씩 총 2개의 데이터만 존재한다고 하자. 어떻게 classifier를 만들 것인가?&lt;/p&gt;

&lt;p&gt;우선 두 가지 이슈가 있다. 먼저 input을 어떻게 표현할지를 선택해야한다. 기본적으로는 one-hot vector로 input을 넣고 output을 위해 softmax layer를 사용할 것이다. 그러나 여기에도 문제가 아직 남아있다. 학습을 위한 데이터가 오직 2개 뿐이라는 것이다.&lt;/p&gt;

&lt;p&gt;이러한 문제를 해결하기 위해 한가지 가정을 한다. 비슷한 input값은 비슷한 감정을 가진다는 가정을 한다. 이러한 가정은 semi-supervised 학습의 핵심이다. 이것을 높은 차원의 데이터를 효과적으로 저차원으로 옮기는 것이다. 이러한 과정을 통해 저차원의 데이터를 가지고 좋은 모델을 만들 수 있다.&lt;/p&gt;

&lt;p&gt;이제 사전 학습된 단어 벡터를 사용한다고 하자. 그러면 다음과 같은 nearest neighbour(NN) 분류기를 만들 수 있다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;NN(w)=
\begin{cases}
\text{positive,~~~~if~}\cos(\mathbf{e}_w,\mathbf{e}_{\text{happy}})&gt;\cos(\mathbf{e}_w,\mathbf{e}_{\text{bad}})\\
\text{negative,~~~otherwise}
\end{cases}&lt;/script&gt;

&lt;p&gt;여기서 &lt;script type=&quot;math/tex&quot;&gt;\cos(\cdot ,\cdot )&lt;/script&gt;은 아래의 식인 cosine similarity를 의미한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\cos(\mathbf{e}_i,\mathbf{e}_j)=\frac{\mathbf{e}_i^T\mathbf{e}_j}{\|\mathbf{e}_i\|\|\mathbf{e}_j\|}&lt;/script&gt;

&lt;p&gt;이 연산을 통해 우리는 ‘유사도’라는 성질을 이용한다. 이 방법을 통해 사전 학습된 단어 벡터는 대부분의 문제를 해결할 수 있지만, 경우에 따라 사용하는데 주의해야 한다. 이러한 단어 벡터는 어떤 objective function을 최대화 하면서 만들어진다. 실제로 유사도에는 다양한 측면에서 적용되지만 이렇게 학습된 단어 벡터는 몇 개의 특정한 측면의 유사도만 적용된다. 몇 가지 측면은 학습할 때의 데이터에 따라 달라진다.&lt;/p&gt;

&lt;p&gt;예를 들어 “happy”, “sad”, “angry”와 같은 감정을 표현하는 단어를 continuous bag-of-words의 문맥에서 생각해보자. 이러한 감정을 표현하는 단어들은 “feel”이라는 단어와 같이 등장하는 경우가 많다. 따라서 위와 같은 단어들은 “feel”이후에 등장할 확률이 높도록 학습될 것이다. 즉 각각의 감정을 표현하는 단어가 비슷한 벡터 공간에 존재할 수 있다. 그러나 감정 분석적인 측면에서는 이러한 표현은 좋지 않다.&lt;/p&gt;

&lt;p&gt;만약 적은 데이터로 언어와 관련된 문제를 해결하려 한다면, 사전 학습된 벡터를 사용하는 것을 고려해보도록 한다. 그러나 해결해야 하는 문제를 고려해서 학습된 벡터를 사용해야 한다.&lt;/p&gt;

&lt;h3 id=&quot;55-recurrent-laguage-model&quot;&gt;5.5 Recurrent Laguage Model&lt;/h3&gt;

&lt;p&gt;Neural Language modeling은 일반적인 n-gram모델의 일반화 부족(lack of generalization)문제를 해결한다. 하지만 여전히 n번째 단어는 이전 n-1 개의 단어를 보는 Markov 속성을 가정한다. 즉 이전에 들었던 예시인 “In Korea, more than half of all the residents speak Korea”이라는 문장에서 처럼 마지막 단어에 대한 조건부 확률 분포는 문장의 2번째단어, 즉 10개 전인 단어에 대해 추정하는 것이 효율적이다.&lt;/p&gt;

&lt;p&gt;4.1.4 단원에서 배웠던 것을 다시 생각해보자. 우리는 가변 길이의 문장을 읽고 가변 길이의 output을 만드는 recurrent neural network에 대해 배웠다. POS-tagging 을 하는 이전에 봤던 예시를 다시 보자. input은 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;x=(\text{Children},~\text{eat},~\text{sweet},~\text{candy})&lt;/script&gt;

&lt;p&gt;그리고 target output 은 품사의 sequence이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;y=(\text{noun},~\text{verb},~\text{adjective},~\text{noun})&lt;/script&gt;

&lt;p&gt;각각의 예측되는 tag들이 서로 독립이라는 가정을 제거하기 위해 각 step의 예측 값인 &lt;script type=&quot;math/tex&quot;&gt;Y_t&lt;/script&gt;의 값이 다음 step의 input 값인 &lt;script type=&quot;math/tex&quot;&gt;X_{t+1}&lt;/script&gt;과 함께 다음 step에서 계산된다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/cDsUgXm.jpg&quot; alt=&quot;recurrent&quot; /&gt;&lt;/p&gt;

&lt;p&gt;전체 문장 확률을 계산하는 과정에서의 단일 단어에 대한 확률계산하는 것을 생각해보자.($a$)&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;p(w^1,w^2,...w^T)=\prod^T_{t=1}\underbrace{p(w^t|w^1,...,w^{t-1})}_{(a)}&lt;/script&gt;

&lt;p&gt;이때까지 배웠던 내용을 토대로 우리는 input &lt;script type=&quot;math/tex&quot;&gt;(w^1,...,w^{t-1})&lt;/script&gt; 에 대해 위의 조건부 확률($a$)을 neural network를 통해 구할 수 있다.(앞서 배운 것과 input이 가변길이라는 점만 다르고 나머지는 모두 같다)&lt;/p&gt;

&lt;p&gt;하지만 여기서는 가변 길이의 input 문장을 summarizing/memorizing 할 수 있는 recurrent neural network를 사용해 본다. recurrent neural network는 input 문장 (w^1,…,w^{t-1})를 메모리 상태인 &lt;script type=&quot;math/tex&quot;&gt;\mathbf{h}^{t-1}&lt;/script&gt;로 summarizing한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\mathbf{h}^{t'}=
\begin{cases}
\begin{matrix}
0,&amp;\text{if~}t'=0\\
f(\mathbf{e}_{w^{t'}},\mathbf{h}^{t'-1}),&amp;\text{otherwise}
\end{matrix}
\end{cases} %]]&gt;&lt;/script&gt;

&lt;p&gt;여기서 &lt;script type=&quot;math/tex&quot;&gt;t'&lt;/script&gt;은 &lt;script type=&quot;math/tex&quot;&gt;0&lt;/script&gt;부터 &lt;script type=&quot;math/tex&quot;&gt;t-1&lt;/script&gt;까지 계산된다. &lt;script type=&quot;math/tex&quot;&gt;f&lt;/script&gt;는 이전에 배웠던 recurrent 함수 중 선택해서 사용하면 된다.(GRU, LSTM) 그리고 $\mathbf{e}_{w’}$은 단어 $w’$의 벡터 이다.&lt;/p&gt;

&lt;p&gt;마지막 과정은 어떻게 해야 하는 지 기억 할 것이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\mu = \text{softmax}(\mathbf{V}\mathbf{h}^{t-1})&lt;/script&gt;

&lt;p&gt;이 계산결과로 나온 $\mu$는 모든 단어에 대한 확률 벡터가 된다. 이 과정에서 input 문장을 단 한번만 읽어서 계산한다. 즉 각 setp에서 단어 하나만 읽어서 update한다.&lt;/p&gt;

&lt;p&gt;이러한 lagugage model을 recurrent neural netwrok language model(RNN-LM)(b)이라 부른다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/HBTm3bC.jpg&quot; alt=&quot;rnn1&quot; /&gt;&lt;em&gt;(a) A Recurrent neural network, (b) Recurrent neural network language model&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;56-how-do-n-gram-language-model-neural-language-model-and-rnn-lm-compare&quot;&gt;5.6 How do &lt;em&gt;n&lt;/em&gt;-gram language model, neural language model and RNN-LM compare?&lt;/h3&gt;

&lt;p&gt;마지막으로 이제 하나의 질문이 남았다. 이 때까지 배운 language model 중 어떤 model을 실전에서 선택해서 사용해야 하는 가? 이다. 우선 이 질문에 대답하기 위해 먼저 일반적으로 language model들을 평가하는 방법에 대해 얘기해 보자.&lt;/p&gt;

&lt;p&gt;가장 일반적으로 많이 사용하는 측정법은 &lt;em&gt;perplexity&lt;/em&gt; 이다. model $\mu$에 대해 perplexity PPL은 다음과 같이 계산한다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\text{PPL} = b^{-\frac{1}{N}\sum^N_{n=1}\log_b p_\mu(w_n|w_{&lt;n}) } %]]&gt;&lt;/script&gt;

&lt;p&gt;$N$은 validation/test 말뭉치의 모든 단어의 수 이고, $b$는 상수로 보통 2 또는 10의 값을 사용한다.&lt;/p&gt;

&lt;p&gt;이 값이 의미하는 것은 무었일까? 이 값에 대해 정보이론을 바탕으로 자세히 설명된 내용이 있지만 이 값을 전부 우리가 이해할 필요는 없다.&lt;/p&gt;

&lt;p&gt;exponential 함수는 단조 증가 함수이므로 위 함수에서 $log_b$ 대신 자연 로그를 사용하더라도 괜찮다.(b&amp;gt;1 이라 가정한다)&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
-\frac{1}{N}\sum^N_{n=1}\log p_\mu(w_n|w_{&lt;n}) %]]&gt;&lt;/script&gt;

&lt;p&gt;이 함수는 cost 함수 혹은 negative log-likelihood와 매우 유사하다. summation 안의 항에 대해서만 보자.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;% &lt;![CDATA[
\log p_\mu(w_n|w_{&lt;n}) %]]&gt;&lt;/script&gt;

&lt;p&gt;이 값은 language model $\mu$이 주어진 이전 단어에 대해 정확한 현재 단어를 예측하면 높은 값을 가진다. (log는 단조 증가이기 떄문)&lt;/p&gt;

&lt;p&gt;요약하면 perplexity를 측정하는 것은 language model이 test/validate 말뭉치에 대해 정확히 예측한 평균치 값을 의미한다. 따라서 더 나은 language model은 적은 perplexity 값은 갖는 model이다.&lt;/p&gt;

&lt;p&gt;이제 우리는 language model을 비교할 준비가 되었다. 다음의 3가지의 model을 생각해보자.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;count-based &lt;em&gt;n&lt;/em&gt;-gram language model&lt;/li&gt;
  &lt;li&gt;neural &lt;em&gt;n&lt;/em&gt;-gram language model&lt;/li&gt;
  &lt;li&gt;recurrent neural netowrk language model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이렇게 여러 모델을 비교할 때 가장 큰 어려움은 제어하기 어려운 요소들이다. 예를들면 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Language&lt;/li&gt;
  &lt;li&gt;Genre/Topic of training, validation and test corpora&lt;/li&gt;
  &lt;li&gt;Size of a training corpus&lt;/li&gt;
  &lt;li&gt;Size of a language model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이러한 어려움 때문에 모델들의 비교는 종종 특정한 downstream application에서 진행한다. 이런 downstream application은 가능한 크기, 말뭉치 target language, language model의 size등 많은 제약을 가진다. 예를 들어 &lt;a href=&quot;https://arxiv.org/abs/1412.7119&quot;&gt;Pragmatic neural language modelling in machine translation&lt;/a&gt; 에서는 n-gram과 neural language model을 다양한 근사 기술들을 통해 기계 번역 분야에서 비교했다. 그리고 &lt;a href=&quot;https://www.lsv.uni-saarland.de/fileadmin/teaching/seminars/ASR-2015/DL-Seminar/From_Feedforward_to_Recurrent_LSTM_Neural_Networks_for_Language_Modeling.pdf&quot;&gt;From feedforward to recurrent lstm neural networks for language
modeling&lt;/a&gt;에서는 저자는 세개의 language model을 자동 음성 인식분야에서 비교했다.&lt;/p&gt;

&lt;p&gt;먼저 &lt;a href=&quot;https://www.lsv.uni-saarland.de/fileadmin/teaching/seminars/ASR-2015/DL-Seminar/From_Feedforward_to_Recurrent_LSTM_Neural_Networks_for_Language_Modeling.pdf&quot;&gt;From feedforward to recurrent lstm neural networks for language
modeling&lt;/a&gt;의 결과를 살펴보자.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/lJ1tbue.jpg&quot; alt=&quot;comp&quot; /&gt;&lt;/p&gt;

&lt;p&gt;결과를 보면 RNN-LM이 일반적인 neural language model을 사용하는 것과 비교해서 효과적이다. 특지 LSTM을 사용할 때는 다른 모델에 비해 성능 향상이 눈에 띈다. 그리고 같은 모델 안에서도 model의 크기를 키우면 성능이 좋아진느 것도 볼 수 있다. 그리고 perplexity도 더 큰 language 모델이 적은 값을 가졌고 여러 모델 중에서는 RNN-LM이 적은 값을 가졌다.&lt;/p&gt;

&lt;p&gt;이러한 결과를 통해 보면, neural model 또는 recurrent model이 language modeling 할 때 좋은 후보가 될 수 있다. 그리고 많은 논문에서의 관찰을 통해 보면 count-based n-gram과 neural, recurrent 모델들을 같이 사용할 때 좋은 결과를 보여줬다. 즉 hybird한 model에서 각 model이 잠재적인 언어 구조를 잘 잡아 냈다는 것이다. 그러나 아직 어떻게 다른 구조를 잡아내는 지에 대해 밝혀지진 않았다.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>파라미터 최적화</title>
   <link href="https://reniew.github.io/14/"/>
   <updated>2018-07-02T04:47:35+00:00</updated>
   <id>https://reniew.github.io/14</id>
   <content type="html">&lt;h4 id=&quot;파라미터-최적화-parameter-optimization&quot;&gt;파라미터 최적화 (Parameter Optimization)&lt;/h4&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;딥러닝 학습의 기본은 파라미터들을 최적의 값으로 빠르고 정확하게 수렴하는 것을 목적으로 한다.
파라미터를 최적화 하는 방법에는 여러 방법들이 있다. Gradient Descent를 기반으로한 방법들, 모멘텀 방식을 도입한 학습 방법 그 외에도 AdaGrad, RMSProp, Adam까지 여러 방법들이 존재한다.
최적화 방법 선택에 따라 최적화까지의 시간에 차이는 매우 크게 난다. 따라서 최적화 방법을 잘 선택하는 것이 매우 중요한데, 그럼 방법들에 대해서 하나씩 알아보도록 한다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Gradient Descent기반 방식들&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;파라미터 최적화 방법으로 가장 널리 알려진 방법은 그라디언트 디센트(Gradient Descent)방식이다. 이 방법은 현재의 미분값을 기반으로해서 파라미터가 업데이트 해야할 방향과 크기를 설정합니다. 업데이트 수식을 아래와 같습니다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\theta \leftarrow \theta -\eta\frac{\partial L}{\partial \theta}&lt;/script&gt;

&lt;p&gt;여기서 $\theta$는 학습할 파라미터를 뜻하고, $\eta$는 미분값을 기준으로 update할 시 어느정도의 크기로 학습할 것인가를 나타내는 학습률(Learning rate)을 뜻한다. $L$은 모델의 손실함수(Cost Function)을 뜻한다.
따라서 위식에 따르면, 파라미터를 파라미터로 손실함수를 미분한 값 반대방향으로 $\eta\frac{\partial L}{\partial \theta}$크기만큼 이동하라는 것을 뜻한다.&lt;/p&gt;

&lt;p&gt;여기까지가 Gradient Descent의 기본에 대해 설명한 것이고, 이 방법을 기반으로 한 방법들에 대해서 하나씩 살펴보도록 하자.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1-1)Batch Gradient Descent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Batch Gradient Descent 방식이란, 모든 데이터셋을 하나의 batch로 보고 전체의 미분값을 평균하여 1에폭동안 update를 딱 한번 수행하는 방식이다. 속도가 느리다는 단점이 있지만, 최적값을 찾을 수 있다는 장점이 있다.&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nb_epochs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;params_grad&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evaluate_gradient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;learning_rate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params_grad&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;1-2)Stochastic Gradient Descent(SGD)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;확률적 경사하강법인 Stocchastic Gradient Descent(SGD)는 각 iteration에서 하나의 example만을 뽑아서 학습시키는 방법이다. 엄밀하게 SGD는 하나의 data만을 뽑아서 학습시키는 방법이지만, 랜덤하게 n개의 데이터를 뽑아 update시키는 방법인 MGD(Mini-Batch Gradient Descent)방식 대신 SGD로 표현해서 사용하기도 합니다. SGD사용은 속도를 훨씬 빠르게 한다는 장점이있고, 아래와 같은 특징들이 있다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;for-loop을 돌기전 데이터 셋을 랜덤하게 Suffle할 필요가 있다.&lt;/li&gt;
  &lt;li&gt;SGD방식은 BGD방식에 비해 최적화로 가는 과정에서 Noise가 많이 발생할 수 있다.
    &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nb_epochs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shuffle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;iter&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start_iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  	&lt;span class=&quot;n&quot;&gt;params_grad&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evaluate_gradient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  	&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;learning_rate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params_grad&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1-3)Mini-Batch Gradient Descent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;미니배치 방식의 Gradient Descent 방식은 일정크기 n만큼의 데이터에 대해서 미분값을 평균하여 update하는 방식이다. SGD에 비해 안정적이며, 속도도 BGD에 비해 빨라 대부분 많이 사용하는 방식이다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nb_epochs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shuffle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_batches&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    	&lt;span class=&quot;n&quot;&gt;params_grad&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evaluate_gradient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    	&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;learning_rate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params_grad&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;2. Momentum&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2-1) Momentum&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;모멘텀이란 물리학 용어로 물체의 속도와 질량에 관련된 운동량을 뜻한다. 아래 그림을 보자
&lt;img src=&quot;https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSev7u058BSjclHjekadU10geQdMMG_DHTDYoJTS4XbGj38AlfG&quot; alt=&quot;momentum&quot; /&gt;
왼쪽 그림의 경우 위 아래 방향으로는 계속해서 반복되는 운동을 하는 것을 볼 수 있는데, 오른쪽으로는 한방향으로만 움직인다. 이러한 경우 오른쪽 방향으로의 운동량이 계속해서 누적된다는 것을 확인 할 수 있다. 따라서 Momentum 방식을 따르면 오른쪽 그림과 같이 위 아래 반복적인 움직임은 여전히 보여주지만 오른쪽으로 지속적인 움직임이 누적되서 더욱 빠르게 최적화가 되는 것을 확인할 수 있다.&lt;/p&gt;

&lt;p&gt;모멘텀의 수식은 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;v\leftarrow \mu v-\eta \frac { \partial L }{ \partial \theta  }&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\theta \leftarrow \theta +v&lt;/script&gt;

&lt;p&gt;GD방식과는 달리 새로운 하이퍼 파라미터 $\mu$와 변수인 $v$가 새롭게 추가되었다.
위 수식을 보면 위의 모멘텀을 적용한 학습 경과가 이해될 것이다. 오른쪽 방향으로의 미분값은 계속해서 $v$에 더해져서 더욱 큰 값을 갖게 되어 빠르게 이동할 수 있는 것이다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;param_grad&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evaluate_gradient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mu&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;learning_rate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;param_grad&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;param&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;param&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;2-2) Nesterov 모멘텀 (Nesterov Momentum)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nesterov Momentum 방식은 최근 많은 주목을 받은 방식으로, Momentum과는 약간 다르다. Convex function에서는 이 함수가 이론적으로 최적화에 유리하며, 일반적으로도 Momentum 방식보다는 좋다는 의견이 있다.&lt;/p&gt;

&lt;p&gt;Nestrov 모멘텀의 방식은 모멘텀방식에서 현재위치인 $\theta$에서 미분값을 구하는 것이 아니라, 우리가 이동할 위치인 $\theta+\mu v$의 위치에서의 미분값을 계산하는 것이 모멘텀 방식과의 다른점이다.
그림을 통해 살펴보자.
&lt;img src=&quot;http://aikorea.org/cs231n/assets/nn3/nesterov.jpeg&quot; alt=&quot;nestrov&quot; /&gt;
momentum방식에서는 빨간점에서의 미분값을 계산해 update를 시켰으나, Nestrov 방식에서는 초록색 벡터의 끝점에서 미분값을 계산해 update를 시킨다는 것을 의미한다.
아래 식을 보면 조금 더 명확하게 이해될 것이다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;v_{t+1}=\mu v_{t}-\eta g(\theta_{t}+\mu v_{t})&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\theta_{t+1}=\theta_{t}+v_{t+1}&lt;/script&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;params_ahead&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mu&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;params_grad_ahead&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evaluate_gradient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params_ahead&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mu&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;learning_rate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params_grad_ahead&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;3. Per-parameter adaptive learning rate 방법들&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;이때까지의 파라미터 최적화 방법들에서는 모든 파라미터에 대해 똑같은 학습 속도를 적용 하였다. 그러나 Per-parameter adaptive learning rate 방법들에서는 각 파라미터에 대해 adaptive한 학습 속도를 적용한다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3-1) AdaGrad&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AdaGra는 Adaptive gradient based 방식으로 &lt;a href=&quot;http://jmlr.org/papers/v12/duchi11a.html&quot;&gt;Duchi et al.&lt;/a&gt;에서 처음으로 소개했다.
AdaGrad에서는 이전 update에서 update가 많이 된 파라미터들에 대해서는 학습량을 줄이는 방법을 사용한다. 수식은 아래와 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;h\leftarrow h+\frac { \partial L }{ \partial \theta  } \odot \frac { \partial L }{ \partial \theta  }&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\theta \leftarrow \theta -\frac { \eta  }{ \sqrt { h }  } \frac { \partial L }{ \partial \theta  }&lt;/script&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;params_grad&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evaluate_gradient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params_grad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;learning_rate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sqrt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params_grad&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;코드를 확인해보면, 수식과는 약간 다른점을 확인 할 수 있다. 아래 식의 $\sqrt{h}$ 값에 eps라는 변수가 더해져 있다. 이 값은 $h$가 0이 되거나 0에 너무 가깝게 되서 전체값이 너무 커져버리는 상황을 방지하기위한 변수로 주로 1e-4에서 1e-8정도의 값을 준다.&lt;/p&gt;

&lt;p&gt;하지만 이 방법은 지나치게 learning rate을 낮추는 경향이 있어 deep learning model에 적용 시 잘 학습이 되지 않는 경향이 있어 자주 사용하지 않는다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3-2) RMSProp&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AdaGrad에서는 $L$을 parameter로 미분한 값을 제곱한 값을 계속 더한 것을 update시 미분값에 나눠준다. 이러한 과정을 계속해서 반복하면, 최종적으로 upadate 값이 0에 수렴해 학습이 불가능해진다.
RMSProp은 이러한 문제를 개선한 방법으로 지수 이동 평균(Exponential moving average)을 사용하였다.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;지수 이동 평균이란 과거의 모든 기간을 계산 대상으로 하며, 최근의 데이터에 더 높은 가중치를 부여한는 일종의 가중 이동 평균 방법이다.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;params_grad&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evaluate_gradient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;decay_rate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;decay_rate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params_grad&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;learning_rate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sqrt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params_grad&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;위 코드에서 decay_rate는 hyper-parameter로 사용자가 직접 정해야 하며, 주로 0.9, 0.99, 0.999중 하나를 선택해 사용한다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3-3) Adam&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;모멘텀 기법은 운동량에 착안해서 만든 방법이고, RMSProp은 파라미터 개별마다 Adaptive한 학습방식이다. Adam 은 이 두방법을 합친 방법이라 할 수 있다.
실전에서 Adam은 가장 기본적으로 사용되는 방법이고, 성능이 좋아 많이 사용하는 방법이다.&lt;/p&gt;

&lt;p&gt;수식은 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;m_t = \beta_1 m_{t-1} + (1-\beta_1)\nabla_\theta J(\theta)&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;v_t = \beta_2 v_{t-1} + (1-\beta_2)(\nabla_\theta J(\theta))^2&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\hat{m_t} = \frac{m_t}{1-\beta_1^t}&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\hat{v_t} = \frac{v_t}{1-\beta_2^t}&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\theta = \theta - \frac{\eta}{\sqrt{\hat{v_t}+\epsilon}}\hat{m_t}&lt;/script&gt;

&lt;p&gt;사용자가 직접 설정해야 할 Hyper parameter는 $\beta_{1}$과 $\beta_{2}$, 그리고 $\epsilon$으로 3가지다.
보통 $\beta_{1}=0.9$, $\beta_{2}=0.999$, $\epsilon$ 값으로는 $1e-8$ 로 설정한다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;파라미터 최적화 방법 비교&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://aikorea.org/cs231n/assets/nn3/opt2.gif&quot; alt=&quot;para&quot; /&gt;
&lt;img src=&quot;http://aikorea.org/cs231n/assets/nn3/opt1.gif&quot; alt=&quot;para2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;출처&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://cs231n.github.io/neural-networks-3/#hyper&quot;&gt;cs231 Lecture Note&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ratsgo.github.io/deep%20learning/2017/04/22/NNtricks/&quot;&gt;ratsgo’s blog&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://shuuki4.github.io/deep%20learning/2016/05/20/Gradient-Descent-Algorithm-Overview.html&quot;&gt;shuuki4’s blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>가중치 초기화 (Weight Initialization)</title>
   <link href="https://reniew.github.io/13/"/>
   <updated>2018-07-01T04:47:35+00:00</updated>
   <id>https://reniew.github.io/13</id>
   <content type="html">&lt;h4 id=&quot;초기-가중치-설정-weight-initialization&quot;&gt;초기 가중치 설정 (weight initialization)&lt;/h4&gt;

&lt;p&gt;딥러닝 학습에 있어 초기 가중치 설정은 매우 중요한 역활을 한다. 가중치를 잘못 설정할 경우 기울기 소실 문제나 표현력의 한계를 갖는 등 여러 문제를 야기하게 된다. 또한 딥러닝의 학습의 문제가 non-convex 이기 때문에 초기값을 잘못 설정할 경우 local minimum에 수렴할 가능성이 커지게 된다.&lt;/p&gt;

&lt;p&gt;초기값 설정을 잘못해 문제가 발생하는 경우들을 살펴보자.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1) 초기값을 모두 0으로 설정한 경우&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;만약 데이터를 평균 0정도로 정규화시킨다면, 가중치를 0으로 초기화 시킨다는 생각은 꽤 합리적으로 보일 수 있다. 그러나 실제로 0으로 가중치를 초기화 한다면 모든 뉴런들이 같은 값을 나타낼 것이고, 역전파 과정에서 각 가중치의 update가 동일하게 이뤄질 것이다. 이러한 update는 학습을 진행 해도 계속해서 발생할 것이며, 결국 제대로 학습하기 어려울 것이다. 또한 이러한 동일한 update는 여러 층으로 나누는 의미를 상쇄시킨다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2) 활성화 함수로 sigmoid 사용시 정규 분포 사용&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;지난 포스트에서 확인했듯이 sigmoid함수는 input의 절대값이 조금이라도 커지게 되면 미분값이 소실되는 문제가 발생한다는 것을 확인했다.(&lt;a href=&quot;reniew.github.io/12&quot;&gt;Post&lt;/a&gt; 참고) 이 경우에 평균 0이고 표준편차가 1인 정규분포를 따르도록 가중치를 랜덤하게 초기화 한다고 가정하자.
&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/994C2F3C5AB623C526&quot; alt=&quot;gradien vanishing&quot; /&gt;
이 경우에는 표준편차가 크기 때문에 학습을 반복할 수록 가중치 값들이 0,1 로 치우치는 문제 발생한다.(Gradient Vanishing) 이 경우 물론 Activation Function을 바꿈으로써 해결 할 수도 있겠지만, 가중치 초기화를 잘 설정함으로써도 어느정도 해결할 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3) 2의 case에서 표준편차를 줄였을 경우&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;2의 문제를 확인하고 표준편차가 커 $|x|$값이 커지면서 기울기가 소실되는 문제를 확인했기 때문에, 표준편차를 줄여서 $|x|$값을 줄이려는 생각을 가지고 표준편차를 0.01로 설정한다고 가정하자.
이 경우에는 또다른 문제가 발생한다.
&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/993C01365AB6262903&quot; alt=&quot;representation&quot; /&gt;&lt;br /&gt;
이렇게 표준편차를 적게 하면 층이 깊어질 수록 가중치 값들이 중간 값인 0.5 부근에 몰리는 문제를 확인할 수 있을 것이다.&lt;/p&gt;

&lt;p&gt;따라서 이렇게 가중치를 설정하는 것만으로도 학습의 큰영향을 끼친다는 것을 확인할 수 있었다. 그렇다면 더 나은 학습을 위해 가중치를 초기화하는 여러 방법들에 대해서 알아보도록 한다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. LeCun Initialization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;LeCun은 지난번 소개한 LeNet의 창시자이며, CNN을 세상에 도입한 사람이라 할 수 있다. 1998년 LeCun은 효과적인 역전파를 위한 논문에서 초기화 방법에 대해서 소개했는데 정규분포를 따르는 방법과 균등분포를 따르는 두가지 방법에 대해서 소개하였다.(&lt;a href=&quot;http://yann.lecun.com/exdb/publis/pdf/lecun-98b.pdf&quot;&gt;LeCun 98, Efficient Backprop&lt;/a&gt;)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;LeCun Normal Initialization&lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;W\sim N({ 0 }, Var(W))&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;Var(W)=\sqrt{\frac { 1 }{ n_{ in }}  }&lt;/script&gt;

&lt;p&gt;($n_{in}$ : 이전 layer(input)의 노드 수)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;LeCun Uniform Initialization&lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;W\sim U(- \sqrt{\frac { 1 }{ { n }_{ in } } } , \space\space + \sqrt{\frac { 1 }{ { n }_{ in } } } )&lt;/script&gt;

&lt;p&gt;($n_{in}$ : 이전 layer(input)의 노드 수)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Xavier Initialization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Xavier Initialization 혹은 Glorot Initialization라고도 불리는 초기화 방법은 이전 노드와 다음 노드의 개수에 의존하는 방법이다. Uniform 분포를 따르는 방법과 Normal분포를 따르는 두가지 방법이 사용된다.(&lt;a href=&quot;http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf&quot;&gt;Glorot &amp;amp; Bengio, AISTATS 2010&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;구조는 LeCun의 초기화 방법과 유사하지만 다음 층의 노드 수도 사용하고, 많은 연구를 통해 가장 최적화된 상수값 또한 찾아냈다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Xavier Normal Initialization&lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;W\sim N({ 0 }, Var(W))&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;Var(W)=\sqrt{\frac { 2 }{ { n }_{ in }+{ n }_{ out } } }&lt;/script&gt;

&lt;p&gt;($n_{in}$ : 이전 layer(input)의 노드 수, $n_{out}$ : 다음 layer의 노드 수)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Xavier Uniform Initialization&lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;W\sim U(- \sqrt{\frac { 6 }{ { n }_{ in }+{ n }_{ out } } } , \space\space + \sqrt{\frac { 6 }{ { n }_{ in }+{ n }_{ out } } } )&lt;/script&gt;

&lt;p&gt;($n_{in}$ : 이전 layer(input)의 노드 수, $n_{out}$ : 다음 layer의 노드 수)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Xaiver함수는 비선형함수(ex. sigmoid, tanh)에서 효과적인 결과를 보여준다. 하지만 ReLU함수에서 사용 시 출력 값이 0으로 수렴하게 되는 현상을 확인 할 수 있다.
따라서 ReLU함수에는 또 다른 초기화 방법을 사용해야 한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3.He Initialization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ReLU를 활성화 함수로 사용 시 Xavier 초기값 설정이 비효율적인 결과를 보이는 것을 확인했는데, 이런 경우 사용하는 초기화 방법을 He initialization이라고 한다. 이 방법 또한 정규분포와 균등분포 두가지 방법이 사용된다.(&lt;a href=&quot;http://arxiv.org/abs/1502.01852&quot;&gt;He et al. ,2015&lt;/a&gt;)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;He Normal Initialization&lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;W\sim N({ 0 }, Var(W))&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;Var(W)=\sqrt{\frac { 2 }{ { n }_{ in } } }&lt;/script&gt;

&lt;p&gt;($n_{in}$ : 이전 layer(input)의 노드 수)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;He Uniform Initialization&lt;/li&gt;
&lt;/ul&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;W\sim U(- \sqrt{\frac { 6 }{ { n }_{ in } } } , \space\space + \sqrt{\frac { 6 }{ { n }_{ in } } } )&lt;/script&gt;

&lt;p&gt;($n_{in}$ : 이전 layer(input)의 노드 수)&lt;/p&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;bias-초기화&quot;&gt;Bias 초기화&lt;/h4&gt;

&lt;p&gt;가중치 초기화 뿐만 아니라 편향(bias) 초기값 또한 초기값 설정 또한 중요하다.&lt;br /&gt;
보통의 경우에는 Bias는 0으로 초기화 하는 것이 일반적이다. ReLU의 경우 0.01과 같은 작은 값으로 $b$를 초기화 하는 것이 좋다는 보고도 있지만 모든 경우는 아니라 일반적으로는 0으로 초기화 하는 것이 효율적이다.&lt;/p&gt;

&lt;h5 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h5&gt;

&lt;p&gt;다양한 종류의 초기화 방법에 대해서 알아 보았다. 초기값 설정이 학습과정에 매우 큰 영향을 끼칠 수 있기 때문에 초기화 방법 또한 신중히 선택해야 한다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Sigmoid, tanh 경우 Xavier 초기화 방법이 효율적이다.&lt;/li&gt;
  &lt;li&gt;ReLU계의 활성화 함수 사용 시 He 초기화 방법이 효율적이다.&lt;/li&gt;
  &lt;li&gt;최근의 대부분의 모델에서는 He초기화를 주로 선택한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;마지막으로, 대부분의 초기화 방법이 Normal Distribution과 Uniform Distribution을 따르는 두가지 방법이 있는데 이에대한 선택 기준에 대해서는 명확한 것이 없다. 하지만 He의 논문의 말을 인용하면,&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;최근의 Deep CNN 모델들은 주로 Gaussian Distribution을 따르는 가중치 초기화 방법을 사용한다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;따라서 Deep CNN의 경우 보통의 Gaussian 초기화 방법을 사용해 볼 수 있다.하지만 여러 초기화 방법들을 테스트하며 사용하는 것이 가장 좋은 방법일 것이다.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>딥러닝에서 사용하는 활성화함수</title>
   <link href="https://reniew.github.io/12/"/>
   <updated>2018-07-01T04:47:35+00:00</updated>
   <id>https://reniew.github.io/12</id>
   <content type="html">&lt;h4 id=&quot;딥러닝에서-사용하는-활성화-함수&quot;&gt;딥러닝에서 사용하는 활성화 함수&lt;/h4&gt;

&lt;p&gt;딥러닝 네트워크에서는 노드에 들어오는 값들에 대해 곧바로 다음 레이어로 전달하지 않고 주로 비선형 함수를 통과시킨 후 전달한다. 이때 사용하는 함수를 &lt;strong&gt;활성화 함수(Activation Function)&lt;/strong&gt; 이라 부른다.&lt;/p&gt;

&lt;p&gt;여기서 주로 비선형 함수를 사용하는 이유는 선형함수를 사용할 시 층을 깊게 하는 의미가 줄어들기 때문이다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;선형함수인 h(x)=cx를 활성화함수로 사용한 3층 네트워크를 떠올려 보세요. 이를 식으로 나타내면 y(x)=h(h(h(x)))가 됩니다. 이는 실은 y(x)=ax와 똑같은 식입니다. a=c3이라고만 하면 끝이죠. 즉, 은닉층이 없는 네트워크로 표현할 수 있습니다. 뉴럴네트워크에서 층을 쌓는 혜택을 얻고 싶다면 활성화함수로는 반드시 비선형 함수를 사용해야 합니다.
- 밑바닥부터 시작하는 딥러닝 -&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;이번 포스트에서는 딥러닝에서 사용되는 활성화 함수들에 대해서 하나씩 알아보도록한다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. 시그모이드 함수 (Sigmoid)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;시그모이드 함수는 Logistic 함수라 불리기도한다. 선형인 멀티퍼셉트론에서 비선형 값을 얻기 위해 사용하기 시작했다. 함수는 아래와 같이 구성된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\sigma(x)=\frac{1}{ 1+e^{-x} }&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;\sigma'(x)=\sigma(x)(1-\sigma(x))&lt;/script&gt;

&lt;p&gt;시그모이드 함수와 시그모이드 함수의 미분함수를 그래프로 나타내면
&lt;img src=&quot;https://mlnotebook.github.io/img/transferFunctions/sigmoid.png&quot; alt=&quot;sig&quot; /&gt;&lt;img src=&quot;https://mlnotebook.github.io/img/transferFunctions/dsigmoid.png&quot; alt=&quot;dsig&quot; /&gt;&lt;/p&gt;

&lt;p&gt;sigmoid에 대해 특징을 살펴보자.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;우선 함수값이 (0, 1)로 제한된다.&lt;/li&gt;
  &lt;li&gt;중간 값은 $\frac{1}{2}$이다.&lt;/li&gt;
  &lt;li&gt;매우 큰 값을 가지면 함수값은 거의 1이며, 매우 작은 값을 가지면 거의 0이다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이러한 특징을 가지는 sigmoid는 신경망 초기에는 많이 사용되었지만, 최근에는 아래의 단점들 때문에 사용하지 않는다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Gradient Vanishing&lt;/strong&gt; 현상이 발생한다.
미분함수에 대해 $x=0$에서 최대값 $\frac{1}{4}$ 을 가지고, input값이 일정이상 올라가면 미분값이 거의 0에 수렴하게된다. 이는 $|x|$값이 커질 수록 Gradient Backpropagation시 미분값이 소실될 가능성이 크다.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;함수값 중심이 0이 아니다.&lt;/strong&gt;
함수값 중심이 0이 아니라 학습이 느려질 수 있다. 그 이유를 알아보면.
만약 모든 $x$값들이 같은 부호(ex. for all $x$ is positive) 라고 가정하고 아래의 파라미터 $w$에 대한 미분함수식을 살펴보자.
$\frac{\partial{L}}{\partial{w}}=\frac{\partial{L}}{\partial{a}}\frac{\partial{a}}{\partial{w}}$
그리고 $\frac{\partial{a}}{\partial{w}}=x$이기 때문에,
$\frac{\partial{L}}{\partial{w}}=\frac{\partial{L}}{\partial{a}}x$ 이다.
위 식에서 모든 $x$가 양수라면 결국 $\frac{\partial{L}}{\partial{w}}$는 $\frac{\partial{L}}{\partial{a}}$ 부호에 의해 결정된다. 따라서 한 노드에 대해 모든 파라미터$w$의 미분값은 모두 같은 부호를 같게된다. 따라서 같은 방향으로 update되는데 이러한 과정은 학습을 zigzag 형태로 만들어 느리게 만드는 원인이 된다.&lt;/li&gt;
  &lt;li&gt;exp 함수 사용시 비용이 크다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이러한 단점들 때문에 초기에는 자주 사용하는 활성화 함수였지만, 최근에는 자주 사용하지 않게 되었다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. $tanh$ 함수, (Hyperbolic tangent function)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;하이퍼볼릭탄젠트란 쌍곡선 함수중 하나이다.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;쌍곡선 함수 : 쌍곡선 함수란 삼각함수와 유사한 성질을 가지고, 표준 쌍곡선을 매개변수로 표시할 때 나오는 함수이다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;하이퍼볼릭탄젠트 함수는 시그모이드 함수를 transformation해서 얻을 수 있다.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;-1 vertical shift &amp;amp; 1/2 horizontal squeeze &amp;amp; 2 vertical stretch&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;함수는 다음과 같이 정의된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;tanh(x)= 2\sigma(2x)-1&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;tanh(x) =\frac { { e }^{ x }-{ e }^{ -x } }{ { e }^{ x }+{ e }^{ -x } }&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;tanh'(x)=1-tanh^2(x)&lt;/script&gt;

&lt;p&gt;&lt;img src=&quot;https://mlnotebook.github.io/img/transferFunctions/tanh.png&quot; alt=&quot;tanh&quot; /&gt;
&lt;img src=&quot;https://mlnotebook.github.io/img/transferFunctions/dtanh.png&quot; alt=&quot;tanh'&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;tanh 함수는 함수의 중심값을 0으로 옮겨 sigmoid의 최적화 과정이 느려지는 문제를 해결했다.&lt;/li&gt;
  &lt;li&gt;하지만 미분함수에 대해 일정값 이상 커질시 미분값이 소실되는 &lt;strong&gt;gradient vanishing&lt;/strong&gt; 문제는 여전히 남아있다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. ReLU 함수 (Rectified Linear Unit)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ReLu함수는 최근 가장 많이 사용되는 활성화 함수이다. 함수는 아래와 같이 정의된다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;f(x)=max(0, x)&lt;/script&gt;

&lt;p&gt;&lt;img src=&quot;https://mlnotebook.github.io/img/transferFunctions/relu.png&quot; alt=&quot;relu&quot; /&gt;&lt;/p&gt;

&lt;p&gt;ReLU함수의 특징을 살펴보자.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;$x&amp;gt;0$ 이면 기울기가 1인 직선이고, $x&amp;lt;0$이면 함수값이 0이된다.&lt;/li&gt;
  &lt;li&gt;sigmoid, tanh 함수와 비교시 학습이 훨씬 빨라진다.&lt;/li&gt;
  &lt;li&gt;연산 비용이 크지않고, 구현이 매우 간단하다.&lt;/li&gt;
  &lt;li&gt;$x&amp;lt;0$인 값들에 대해서는 기울기가 0이기 때문에 뉴런이 죽을 수 있는 단점이 존재한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Leakly ReLU&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;leakly ReLU는 ReLU의 뉴런이 죽는(“Dying ReLu”)현상을 해결하기위해 나온 함수이다. 함수도 매우 간단한 형태로 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;f(x)=max(0.01x,x)&lt;/script&gt;

&lt;p&gt;위의 식에서 0.01대신 다른 매우 작은 값 사용 가능하다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Leakly ReLU는 음수의 $x$값에 대해 미분값이 0되지 않는다는 점을 제외하면 ReLU와 같은 특성을 가진다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. PReLU&lt;/strong&gt;&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;f(x)=max(\alpha x,x)&lt;/script&gt;

&lt;p&gt;Leakly ReLU와 거의 유사하지만 새로운 파라미터 $\alpha$ 를 추가하여 $x&amp;lt;0$에서 기울기를 학습할 수 있게 하였다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Exponential Linear Unit(ELU)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ELU는 비교적 가장 최근에 나온 함수이다. &lt;a href=&quot;http://arxiv.org/abs/1511.07289&quot;&gt;Clevert et al. ,2015&lt;/a&gt;&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;f(x)=x\quad if\quad x&gt;0&lt;/script&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;f(x)=\alpha ({ e }^{ x }-1)\quad if\quad x\le 0&lt;/script&gt;

&lt;p&gt;ELU 의 특징은 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;ReLU의 모든 장점을 포함한다.&lt;/li&gt;
  &lt;li&gt;“Dying ReLU” 문제를 해결했다.&lt;/li&gt;
  &lt;li&gt;출력값이 거의 zero-centered에 가깝다&lt;/li&gt;
  &lt;li&gt;일반적인 ReLU와 달리 exp함수를 계산하는 비용이 발생한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;7. Maxout 함수&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Maxout 함수는 다음과 같다.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;f(x)=max({ w }_{ 1 }^{ T }x+{ b }_{ 1 },{ w }_{ 2 }^{ T }x+{ b }_{ 2 })&lt;/script&gt;

&lt;p&gt;이 함수는 ReLU가 가지는 모든 장점을 가졌으며, dying ReLU문제 또한 해결한다. 하지만 계산량이 복잡하다는 단점이 있다.&lt;/p&gt;

&lt;h5 id=&quot;결론&quot;&gt;결론&lt;/h5&gt;

&lt;p&gt;위와 같이 여러 활성화 함수가 있는데, 어떤 함수를 사용해야 할지에 대한 결론은 다음고 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;우선 가장 많이 사용되는 함수는 ReLU이다. 간단하고 사용이 쉽기 때문에 우선적으로 ReLU를 사용한다.&lt;/li&gt;
  &lt;li&gt;ReLU를 사용한 이후 Leakly ReLU등 ReLU계열의 다른 함수도 사용 해본다.&lt;/li&gt;
  &lt;li&gt;sigmoid의 경우에는 사용하지 않도록 한다.&lt;/li&gt;
  &lt;li&gt;tanh의 경우도 큰 성능은 나오지 않는다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;참고&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://mlnotebook.github.io/img/transferFunctions/dtanh.pn&quot;&gt;MLNoteBook&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://mlnotebook.github.io/img/transferFunctions/dtanh.pn&quot;&gt;ratsgo’s blog&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://jleewebblog.wordpress.com/2016/10/26/%EB%94%A5%EB%9F%AC%EB%8B%9D%EC%97%90%EC%84%9C-%ED%99%9C%EC%84%B1-%ED%95%A8%EC%88%98-%EA%B0%80%EC%9D%B4%EB%93%9C-activation-function-guide-in-deep-learning/&quot;&gt;jleewebblog&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://nmhkahn.github.io/NN&quot;&gt;nmhkahn blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>CNN을 활용한 주요 Model - (3) : Image Detection-2</title>
   <link href="https://reniew.github.io/11/"/>
   <updated>2018-06-27T04:47:35+00:00</updated>
   <id>https://reniew.github.io/11</id>
   <content type="html">&lt;h4 id=&quot;cnn을-활용한-주요-model---3--image-detection-2&quot;&gt;CNN을 활용한 주요 Model - (3) : Image Detection-2&lt;/h4&gt;

&lt;p&gt;CNN을 활용한 최초의 기본적인 Model들 부터 계속해서 다양한 구조를 가지는 많은 모델들이 계속해서 나오고 있다. 이번 포스트에서는 아래의 분류를 기준으로 CNN의 주요 모델들에 대해서 하나씩 알아 보도록 하겠다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Modern CNN
    &lt;ul&gt;
      &lt;li&gt;LeNet&lt;/li&gt;
      &lt;li&gt;AlexNet&lt;/li&gt;
      &lt;li&gt;VGG Nets&lt;/li&gt;
      &lt;li&gt;GoogLeNet&lt;/li&gt;
      &lt;li&gt;ResNet&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Image Detection&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;RCNN&lt;/li&gt;
      &lt;li&gt;Fast RCNN&lt;/li&gt;
      &lt;li&gt;Faster RCNN&lt;/li&gt;
      &lt;li&gt;SPP Net&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Yolo&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;SDD&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Attention Net&lt;/strong&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Semantic Segmentation
    &lt;ul&gt;
      &lt;li&gt;FCN&lt;/li&gt;
      &lt;li&gt;DeepLab v1, v2&lt;/li&gt;
      &lt;li&gt;U-Net&lt;/li&gt;
      &lt;li&gt;ReSeg&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Image Captioning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;지난 포스트에 이어서 Image Detection에 사용된 Model들에 대해서 알아보도록 하겠다.
이번에 소개될 모델들은 지난 모델에 대해 좀 더 최신의 모델들로 성능 및 속도가 향상되었다는 것을 알 수 있다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;YOLO&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;딥러닝에서의 YOLO란 우리가 흔히 알고 있는 You Only Live Once의 약자가 아닌 You Only Look Once의 약자로 기존의 Object detection 알고리즘들의 속도가 real-time으로 사용하기에는 느리다는 문제점을 해결하기 위해 나온 알고리즘이다.
YOLO의 가장 큰 특징은 이름에서 나오듯이 Image를 bounding box를 찾을때와 classification을 따로하는 것이 아니라 두가지를 한번에 한다는 것이다.&lt;/p&gt;

&lt;p&gt;YOLO의 실행 과정에 대해 소개하면,
&lt;img src=&quot;https://cdn-images-1.medium.com/max/1200/1*m8p5lhWdFDdapEFa2zUtIA.jpeg&quot; alt=&quot;YOLO&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;우선 Image를 S x S grid로 나눈다.&lt;/li&gt;
  &lt;li&gt;각각의 grid cell은 B개의 Bounding box에 대해 5개의 예측값을 갖는다.
($x,y$ : offset,$w,h$ : Bounding Box size, $conf$ : confidence score)
confidence score은 bounding box가 해당 cell에 포함되지 않으면 0이 된다.&lt;/li&gt;
  &lt;li&gt;각각의 grid cell은 C개의 class에 대해 conditional class probability를 갖는다.
(하나의 cell은 하나의 class에 대해 예측값 갖는다)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;YOLO의 Architecture는 다음과 같다.
&lt;img src=&quot;https://curt-park.github.io/images/yolo/Figure3.JPG&quot; alt=&quot;yoloarchi&quot; /&gt;
Input size가 기존의 모델에 비해 448x448로 더욱 크다는 것을 알 수 있다. 그리고 중간의 Convolution layer들이 1x1, 3x3등 여러 size를 같이 사용하는 것이 Inception module과 비슷하다.&lt;/p&gt;

&lt;p&gt;그러나 속도가 빠르고 backgorund에 대해 예측도 잘하는데도 불구하고 YOLO가 가지는 한계점은&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;각 cell은 2개의 bounding box와 하나의 class probability만을 예측한다.
따라서 작은 물체들에 대해서는 예측률이 낮다.&lt;/li&gt;
  &lt;li&gt;Loss fuction이 작은 bounding box와 큰 bounding box에 대해 error를 동일 하게 다루기 때문에, Scoring에 부적합 하다.&lt;/li&gt;
  &lt;li&gt;몇 단계를 거친 feature map에 대해서 예측하기 때문에, Localization이 부정확해 질 수 있다.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;SSD&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;기존의 detection 모델들은 Bounding box를 만들고 각 box에 있는 feature를 extract한 후 classifier를 적용합니다. 하지만 이러한 과정은 real-time으로 적용하기에 느리고, 임베디드화 시키기에도 연산량이 너무 많다는 단점이 있다. 그에 반해 YOLO는 빠르다는 장점이 있지만 정확도가 떨어진다는 단점이 있다. SSD는 이러한 단점까지 보안한 Model이다. 각 모델들의 연산량과 정확도를 확인해보면,&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Faster R-CNN : 7FPS, mAP 73.2% on VOC 2007&lt;/li&gt;
  &lt;li&gt;YOLO : 45FPS, mAP 63.4%&lt;/li&gt;
  &lt;li&gt;SSD : 59FPS, mAP 74.3%
(FPS : Frame Per Second, mAP : mean AP)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SSD의 구조는 특별한 것이 아니라 기존의 Feed-Forward Convolutional Network에서 feature map까지를 하나로 보고 보조적 도구 몇 가지를 더하였다.
이 기본 구조는 VGG-16 network 에서 conv5_3까지를 잘라서 사용하였다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://openresearch.ai/uploads/default/optimized/1X/0b0340f7bd3686237a5d6b4c0141e8a6a2ab854b_1_690x482.png&quot; alt=&quot;SSD&quot; /&gt;&lt;/p&gt;

&lt;p&gt;SSD의 핵심은 다수의 conv feature map의 각 cell으로부터 category score와 box offset값을 예측하는 것이다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Attention Net&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Attention Net은 기존의 multiple detection이 아닌 single object에 대해 detection을 하는 model이다. 하나의 Object만 detect함에도 불구하고 이 모델이 의미있는 이유는 다음과 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;정확한 Bounding Box를 얻을 수 있다.&lt;/li&gt;
  &lt;li&gt;높은 성능&lt;/li&gt;
  &lt;li&gt;간단한 구조&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://ai2-s2-public.s3.amazonaws.com/figures/2017-08-08/6f7de9849be93eff1c5f133defd9d70e5ff437ac/1-Figure1-1.png&quot; alt=&quot;attention&quot; /&gt;&lt;/p&gt;

&lt;p&gt;기존의 모델에서 detection은 Object에 대해 알맞는 Bounding box를 찾는 문제 였지만, Attention Net에서는 Bounding box 크기를 조정하며 Object에 딱 맞는 Bounding box를 찾는 과정이라 할 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://dgyoo.github.io/images/iccv15.PNG&quot; alt=&quot;attnetion2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Attention Net의 과정은 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Input Image를 고정된 사이즈로 Reshape한다.&lt;/li&gt;
  &lt;li&gt;reshape된 image를 Convolution layer들을 통과시켜 크기 5의 2개의 벡터를 얻는다.
각각의 벡터는 Bounding box의 좌측 상단(TL), 좌측 하단(BR)에 대한 예측값이다.&lt;/li&gt;
  &lt;li&gt;이후 예측 값을 알맞게 예측됬는지를 확인하는 두개의 층을 통과시킨다.
(예측이 제대로 되지 않았다면 다시 bounding box를 조정해 반복한다)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;출처&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://ratsgo.github.io/deep%20learning/2017/10/09/CNNs/&quot;&gt;ratsgo’s blog&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://adeshpande3.github.io/adeshpande3.github.io/The-9-Deep-Learning-Papers-You-Need-To-Know-About.html&quot;&gt;adeshpande github&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://laonple.blog.me/220654387455&quot;&gt;라온피플 블로그&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://arclab.tistory.com/150&quot;&gt;arclab’s blog&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/sjchoi86/dl_tutorials_10weeks&quot;&gt;sjchoi’s blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>CNN을 활용한 주요 Model - (2) : Image Detection</title>
   <link href="https://reniew.github.io/10/"/>
   <updated>2018-06-27T04:47:35+00:00</updated>
   <id>https://reniew.github.io/10</id>
   <content type="html">&lt;h4 id=&quot;cnn을-활용한-주요-model---2--image-detection&quot;&gt;CNN을 활용한 주요 Model - (2) : Image Detection&lt;/h4&gt;

&lt;p&gt;CNN을 활용한 최초의 기본적인 Model들 부터 계속해서 다양한 구조를 가지는 많은 모델들이 계속해서 나오고 있다. 이번 포스트에서는 아래의 분류를 기준으로 CNN의 주요 모델들에 대해서 하나씩 알아 보도록 하겠다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Modern CNN
    &lt;ul&gt;
      &lt;li&gt;LeNet&lt;/li&gt;
      &lt;li&gt;AlexNet&lt;/li&gt;
      &lt;li&gt;VGG Nets&lt;/li&gt;
      &lt;li&gt;GoogLeNet&lt;/li&gt;
      &lt;li&gt;ResNet&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Image Detection&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;RCNN&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Fast RCNN&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Faster RCNN&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;SPP Net&lt;/li&gt;
      &lt;li&gt;Yolo&lt;/li&gt;
      &lt;li&gt;SDD&lt;/li&gt;
      &lt;li&gt;Attention Net&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Semantic Segmentation
    &lt;ul&gt;
      &lt;li&gt;FCN&lt;/li&gt;
      &lt;li&gt;DeepLab v1, v2&lt;/li&gt;
      &lt;li&gt;U-Net&lt;/li&gt;
      &lt;li&gt;ReSeg&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Image Captioning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Computer vision분야에는 다양한 문제들이 있다. 우선 Computer Vision의 Task들에 대해서 먼저 알아보자.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/qhsh15m.jpg&quot; alt=&quot;1_Hz6t-tokG1niaUfmcysusw&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Classification&lt;/strong&gt;이란, Object가 하나있는 image에 대해서 Object의 class를 분류하는 문제이다.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Classification&lt;/strong&gt;과 Localization을 합친 문제는 Object의 class 분류와 object의 위치는 bounding box로 위치를 찾는 문제다.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Object Detection&lt;/strong&gt;은 우선 Image에 있어 single object가 아닌 multiple object를 다루는 문제다. 각각의 Object에 대해 class를찾고 위치를 찾는 문제다.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Image Segmentation&lt;/strong&gt;이란 Object Detection과 유사하지만, 다른점은 Object의 위치를 bounding box를 통해 나타내는것이 아닌 Object의 실제 edge를 찾아 정확한 형체까지 찾아 내는 문제이다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이번 포스트에서는 Image Detection에서 사용된 CNN 모델들에 대해서 보도록한다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;RCNN, Fast RCNN, Faster RCNN&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;2013년의 RCNN의 등장이후 Fast RCNN, Faster RCNN 까지 RCNN모델들은 많은 사람들에게 영향을 주었으며, Computer Vision분야에서 가장 Impactful한 network라 할 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://adeshpande3.github.io/assets/rcnn.png&quot; alt=&quot;RCNN&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RCNN&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;RCNN의 목적은 Object Detection 문제를 풀기 위함이다. 어떠한 이미지가 주어지면, 그 이미지에 있는 모든 Object들에 대해 Bounding box를 그리는 것이 최종 목적이다. 따라서 문제는 두가지 과정으로 나뉜다. 첫 번째, Resion Proposal과정과 Classification과정으로 나뉜다.&lt;/p&gt;

&lt;p&gt;RCNN은 &lt;a href=&quot;https://ivi.fnwi.uva.nl/isis/publications/2013/UijlingsIJCV2013/UijlingsIJCV2013.pdf&quot;&gt;Selective Search&lt;/a&gt;를 사용한다. &lt;em&gt;Selective Search&lt;/em&gt;란 Image에 대해서 2000개 정도의 각각 다른 region을 생성해낸 후 물체가 들어가 있을 확률이 가장 높은 것을 뽑는 과정이다.
이렇게 Region을 뽑아내는 &lt;em&gt;Region proposal&lt;/em&gt; 과정을 거친 후 bounding된 Image들에 대해 AlexNet을 통과시켜 &lt;em&gt;Feature extraction&lt;/em&gt; 과정을 거친다.(Image들은 AlexNet에 넣기 위해 227x227크기로 reshape한다) 이때 AlexNet을 통과시켜 나오는 최종 Output값을 뽑는 것이 아니라, 최종 출력층 이전 두 번째 FC Layer의 output 값인 4,096크기의 vector를 뽑는 것이다. 4,096크기의 vector에 대해 linear SVM(각 class들에 대해 사전 학습 된)을 통해 각 Region을 Scoring한다. 마지막으로 각 region들에 대해 Non-Maximum Suppression(NMS)를 사용해 bounding box를 구한다.&lt;/p&gt;

&lt;p&gt;다시한번 과정을 정리하면&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Selective Search Algorithms을 통해 2000개정도의 region을 생성한다.&lt;/li&gt;
  &lt;li&gt;각각의 region들을 228x228 크기로 Reshape한다.&lt;/li&gt;
  &lt;li&gt;reshape한 image들을 AlexNet을 통과시켜 마지막 output이전의 FC Layer의 output인 4,096크기의 vector를 뽑아낸다.&lt;/li&gt;
  &lt;li&gt;뽑아낸 vector를 SVM을 통해 classification을 한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;RCNN의 Process를 보다보면 생각보다 복잡하며, 과도한 연산 및 손실되는 정보가 많은 것 같다는 생각이 든다.
실제로 2000개 정도의 region에 대해 연산을 실행하면서 연산량이 늘어나며 image를 reshape하며 손실되는 정보들 또한 많다는 단점이 있다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fast-RCNN&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://adeshpande3.github.io/assets/FastRCNN.png&quot; alt=&quot;Fast RCNN&quot; /&gt;
Fast-RCNN은 기존의 RCNN모델의 주요한 문제들을 해결하기 위해 나왔다.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;ul&gt;
    &lt;li&gt;RCNN은 학습을 위해 최소한 3가지 과정을 거쳐야한다.(CNN, SVM, region regression) 따라서 연산량이 매우 높아져서 속도가 매우느려 실제로 사용하기에 어렵다.&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fast RCNN의 과정을 설명하면&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Image를 ConvNet을 통과시켜 ConvNet의 마지막 Feature map을 region proposal의 feature로 얻는다.&lt;/li&gt;
  &lt;li&gt;RoI Pooling layer를 통해 각각의 Bounding box에 대해 fixed-size의 feature vector를 얻는다.&lt;/li&gt;
  &lt;li&gt;마지막으로 feature vector에 대해 FC layer를 통해 class label과 bounding box location을 output으로 받는다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;여기서 처음에 통과시키는 ConvNet에서 Bounding box를 얻는 과정은 SPP Net의 방법과 유사하다. SPP Net에 대해서는 아래에서 보도록 하겠다.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Faster-RCNN&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://adeshpande3.github.io/assets/FasterRCNN.png&quot; alt=&quot;faster-rcnn&quot; /&gt;
Faster RCNN은 RCNN과 Faster RCNN의 복잡한 학습과정 때문에 나오게 되었다. 여기서는 Region proposal network가 Convolution layer로 feature map을 뽑은 이후 나온다. Region Proposal Network외의 나머지 pipeline은 Fast-RCNN의 것과 똑같다.(ROI, FC, Classification, Regression)&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;SPP Net&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;SPP Net이란, Spatial Pyramid Pooling Network의 준말이다.
SPPNet은 RCNN이 나온 후 등장한 Network이다. RCNN에서는 region을 여러개 뽑은 후 CNN에 넣게 되는데, CNN에 Input값으로 넣기 위해서는 fixed-size의 image가 되어야한다. 이 과정에서 많은 정보들이 손실되는 문제점이 발생한다. 따라서 region을 만든후 Convlution layer를 통과시키는 것이 아니라, 먼저 Convolution layer를 통과시킨다. 이때 각각의 filter들은 다양한 size의 feature map들을 만든다. 이렇게 만들어진 다양한 size의 map에 대해서 feature extraction을 수행한다.
&lt;img src=&quot;https://i.imgur.com/rAAIQqf.jpg&quot; alt=&quot;spp1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;그다음 SPP Net에서 사용한 중요한 구조는 이름에서도 알 수 있듯이 Spatial Pyramid Pooling Layer이다. 이전의 다양한 size에서 Extracted feature들을 SPP Layer를 통과시킨 후 FC-layer를 통해 최종 Output값을 얻는다.&lt;/p&gt;

&lt;p&gt;가장 중요한 SPP Layer에 대해서 살펴보자.
&lt;img src=&quot;https://i.imgur.com/A8NpefQ.jpg&quot; alt=&quot;spp2&quot; /&gt;
SPP Layer에서는 Conv Layer에서 나온 feature map들에 대해서 다양한 사이즈로 pooling을 진행한다.(1x1, 2x2, 3x3 등) 다양한 크기로 Pooling을 한 뒤 이 값들을 하나의 vector로 만들어준다.&lt;/p&gt;

&lt;p&gt;이러한 과정을 통해 SPP Net은 RCNN에 비해 월등히 빠른 속도를 가지고 있다. 그럼에도 불구하고 학습이 어렵다는 단점과 여전히 Pipeline이 복잡하다는 단점이 존재한다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;YOLO&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;YOLO란 우리가 흔히 You Only Look Once의 약자로 기존의 Object detection 알고리즘들의 속도가 real-time으로 사용하기에는 느리다는 문제점을 해결하기 위해 나온 알고리즘이다.
YOLO의 가장 큰 특징은 이름에서 나오듯이 Image를 bounding box를 찾을때와 classification을 따로하는 것이 아니라 두가지를 한번에 한다는 것이다.&lt;/p&gt;

&lt;p&gt;YOLO의 실행 과정에 대해 소개하면,
&lt;img src=&quot;https://cdn-images-1.medium.com/max/1200/1*m8p5lhWdFDdapEFa2zUtIA.jpeg&quot; alt=&quot;YOLO&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;우선 Image를 S x S grid로 나눈다.&lt;/li&gt;
  &lt;li&gt;각각의 grid cell은 B개의 Bounding box에 대해 5개의 예측값을 갖는다.
($x,y$ : offset,$w,h$ : Bounding Box size, $conf$ : confidence score)
confidence score은 bounding box가 해당 cell에 포함되지 않으면 0이 된다.&lt;/li&gt;
  &lt;li&gt;각각의 grid cell은 C개의 class에 대해 conditional class probability를 갖는다.
(하나의 cell은 하나의 class에 대해 예측값 갖는다)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;YOLO의 Architecture는 다음과 같다.
&lt;img src=&quot;https://curt-park.github.io/images/yolo/Figure3.JPG&quot; alt=&quot;yoloarchi&quot; /&gt;
Input size가 기존의 모델에 비해 448x448로 더욱 크다는 것을 알 수 있다. 그리고 중간의 Convolution layer들이 1x1, 3x3등 여러 size를 같이 사용하는 것이 Inception module과 비슷하다.&lt;/p&gt;

&lt;p&gt;그러나 속도가 빠르고 backgorund에 대해 예측도 잘하는데도 불구하고 YOLO가 가지는 한계점은&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;각 cell은 2개의 bounding box와 하나의 class probability만을 예측한다.
따라서 작은 물체들에 대해서는 예측률이 낮다.&lt;/li&gt;
  &lt;li&gt;Loss fuction이 작은 bounding box와 큰 bounding box에 대해 error를 동일 하게 다루기 때문에, Scoring에 부적합 하다.&lt;/li&gt;
  &lt;li&gt;몇 단계를 거친 feature map에 대해서 예측하기 때문에, Localization이 부정확해 질 수 있다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;출처&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://ratsgo.github.io/deep%20learning/2017/10/09/CNNs/&quot;&gt;ratsgo’s blog&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://adeshpande3.github.io/adeshpande3.github.io/The-9-Deep-Learning-Papers-You-Need-To-Know-About.html&quot;&gt;adeshpande github&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://laonple.blog.me/220654387455&quot;&gt;라온피플 블로그&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://arclab.tistory.com/150&quot;&gt;arclab’s blog&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/sjchoi86/dl_tutorials_10weeks&quot;&gt;sjchoi’s blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Bag of words meets bag of popcorn</title>
   <link href="https://reniew.github.io/09/"/>
   <updated>2018-06-27T04:47:35+00:00</updated>
   <id>https://reniew.github.io/09</id>
   <content type="html">&lt;h4 id=&quot;bag-of-words-meets-bag-of-popcorn&quot;&gt;Bag of words meets bag of popcorn&lt;/h4&gt;
&lt;h5 id=&quot;part-2--word-vector&quot;&gt;Part 2 / Word Vector&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;word2vec 모델&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;논문&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Efficient Estimation of Word Representations in Vector Space (2013, Mikolov)
    &lt;ul&gt;
      &lt;li&gt;초기버전&lt;/li&gt;
      &lt;li&gt;CBOW ,Skip-gram&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Distributed Representations of Words and Phrases and their Compositionality (2013,Mikolov)
    &lt;ul&gt;
      &lt;li&gt;튜닝기법이 추가&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;word2vec 관련 참고 자료&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://arxiv.org/pdf/1301.3781v3.pdf&quot;&gt;Efficient Estimation of Word Representations in Vector Space&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf&quot;&gt;Distributed Representations of Words and Phrases and their Compositionality&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://tensorflowkorea.gitbooks.io/tensorflow-kr/g3doc/tutorials/word2vec/&quot;&gt;Word2Vec tensorflow 한글 번역본&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ratsgo.github.io/natural%20language%20processing/2017/03/08/word2vec/&quot;&gt;Word2Vec 블로그 정리글 - Word2Vec으로 문장 정리하기&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://nohhj.blogspot.kr/2015/08/word-embedding.html&quot;&gt;Word2Vec 블로그 정리글 - Word embedding관련 정리&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ratsgo.github.io/from%20frequency%20to%20semantics/2017/03/30/word2vec/&quot;&gt;Word2Vec 블로그 정리글 - Word2Vec 학습방법&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;각 단어들을 원 핫인코딩 방식 혹은 Bag of words 방식으로 나타낼 경우 size가 매우 크고 벡터가 너무 sparse해서 neural net 성능이 잘 나오지 않는다.&lt;/li&gt;
  &lt;li&gt;단어 주변이 비슷하면 그 단어들은 의미가 유사하다는 아이디어&lt;/li&gt;
  &lt;li&gt;단어를 벡터로 바꿔주는 엠베딩(Embedding)과정&lt;/li&gt;
  &lt;li&gt;Word2Vec은 분산 된 텍스트 표현을 사용하여 개념 간 유사성을 본다. 예를 들어, 파리와 프랑스가 베를린과 독일이 (수도와 나라) 같은 방식으로 관련되어 있음을 이해한다.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;https://camo.githubusercontent.com/97ec511f00892d0560dab2419288e434ded52255/68747470733a2f2f312e62702e626c6f6773706f742e636f6d2f2d51374638756c44366643302f5567766e564353476d58492f41414141414141414162672f4d43574c545942756668732f73313630302f696d61676530302e676966&quot; alt=&quot;image.png&quot; /&gt;
&lt;img src=&quot;http://i.imgur.com/agTBWiT.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;5 CBOW와 Skip-gram 기법 사용&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;CBOW
    &lt;ul&gt;
      &lt;li&gt;CBOW(continuous bag-of-words)&lt;/li&gt;
      &lt;li&gt;전체 텍스트로 하나의 단어를 예측한다.&lt;/li&gt;
      &lt;li&gt;작은 데이터셋일수록 유리&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Skip-Gram
    &lt;ul&gt;
      &lt;li&gt;타겟 단어들로 부터 원본 단어들을 역으로 유추하는 과정&lt;/li&gt;
      &lt;li&gt;큰 규모의 데이터셋일수록 유리
&lt;img src=&quot;https://camo.githubusercontent.com/1a8235d525ad46485e764e5008cbc29c8c17a5be/68747470733a2f2f692e696d6775722e636f6d2f795859314c78562e706e67&quot; alt=&quot;image.png&quot; /&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;c1&quot;&gt;# 참고 : https://gist.github.com/yong27/7869662
# http://www.racketracer.com/2016/07/06/pandas-in-parallel/
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;multiprocessing&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Pool&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;numpy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_apply_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply_by_multiprocessing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 키워드 항목 중 workers 파라메터를 꺼냄
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;workers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'workers'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 위에서 가져온 workers 수로 프로세스 풀을 정의
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;pool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;processes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;workers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 실행할 함수와 데이터프레임을 워커의 수 만큼 나눠 작업
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_apply_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array_split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)])&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 작업 결과를 합쳐서 반환
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;kaggleBagofWord&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kaggleBagofWord&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;##전처리과정에 사용하는 것들을 class화~
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'data/labeledTrainData.tsv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delimiter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;quoting&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'data/testData.tsv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                   &lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delimiter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;quoting&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;unlabeled_train&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'data/unlabeledTrainData.tsv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delimiter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;quoting&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unlabeled_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'review'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'review'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unlabeled_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'review'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(25000, 3)
(25000, 2)
(50000, 2)
25000
25000
50000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;kaggleBagofWord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;review_to_wordlist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'review'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;['with', 'all', 'this', 'stuff', 'go', 'down', 'at', 'the', 'moment', 'with']
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;sentences&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;review&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;review&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sentences&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kaggleBagofWord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;review_to_sentences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;review&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remove_stopwords&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;C:\ProgramData\Anaconda3\lib\site-packages\bs4\__init__.py:219: UserWarning: &quot;b'.'&quot; looks like a filename, not markup. You should probably open this file and pass the filehandle into Beautiful Soup.
  ' Beautiful Soup.' % markup)
C:\ProgramData\Anaconda3\lib\site-packages\bs4\__init__.py:219: UserWarning: &quot;b'...'&quot; looks like a filename, not markup. You should probably open this file and pass the filehandle into Beautiful Soup.
  ' Beautiful Soup.' % markup)
C:\ProgramData\Anaconda3\lib\site-packages\bs4\__init__.py:282: UserWarning: &quot;http://www.happierabroad.com&quot;&quot; looks like a URL. Beautiful Soup is not an HTTP client. You should probably use an HTTP client like requests to get the document behind the URL, and feed that document to Beautiful Soup.
  ' that document to Beautiful Soup.' % decoded_markup
C:\ProgramData\Anaconda3\lib\site-packages\bs4\__init__.py:219: UserWarning: &quot;b'12.'&quot; looks like a filename, not markup. You should probably open this file and pass the filehandle into Beautiful Soup.
  ' Beautiful Soup.' % markup)
C:\ProgramData\Anaconda3\lib\site-packages\bs4\__init__.py:219: UserWarning: &quot;b'music.'&quot; looks like a filename, not markup. You should probably open this file and pass the filehandle into Beautiful Soup.
  ' Beautiful Soup.' % markup)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;review&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unlabeled_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;review&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sentences&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kaggleBagofWord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;review_to_sentences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;review&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remove_stopwords&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;C:\ProgramData\Anaconda3\lib\site-packages\bs4\__init__.py:219: UserWarning: &quot;b'.'&quot; looks like a filename, not markup. You should probably open this file and pass the filehandle into Beautiful Soup.
  ' Beautiful Soup.' % markup)
C:\ProgramData\Anaconda3\lib\site-packages\bs4\__init__.py:282: UserWarning: &quot;http://www.archive.org/details/LovefromaStranger&quot;&quot; looks like a URL. Beautiful Soup is not an HTTP client. You should probably use an HTTP client like requests to get the document behind the URL, and feed that document to Beautiful Soup.
  ' that document to Beautiful Soup.' % decoded_markup
C:\ProgramData\Anaconda3\lib\site-packages\bs4\__init__.py:282: UserWarning: &quot;http://www.loosechangeguide.com/LooseChangeGuide.html&quot;&quot; looks like a URL. Beautiful Soup is not an HTTP client. You should probably use an HTTP client like requests to get the document behind the URL, and feed that document to Beautiful Soup.
  ' that document to Beautiful Soup.' % decoded_markup
C:\ProgramData\Anaconda3\lib\site-packages\bs4\__init__.py:219: UserWarning: &quot;b'... ...'&quot; looks like a filename, not markup. You should probably open this file and pass the filehandle into Beautiful Soup.
  ' Beautiful Soup.' % markup)
C:\ProgramData\Anaconda3\lib\site-packages\bs4\__init__.py:219: UserWarning: &quot;b'...'&quot; looks like a filename, not markup. You should probably open this file and pass the filehandle into Beautiful Soup.
  ' Beautiful Soup.' % markup)
C:\ProgramData\Anaconda3\lib\site-packages\bs4\__init__.py:219: UserWarning: &quot;b'....'&quot; looks like a filename, not markup. You should probably open this file and pass the filehandle into Beautiful Soup.
  ' Beautiful Soup.' % markup)
C:\ProgramData\Anaconda3\lib\site-packages\bs4\__init__.py:282: UserWarning: &quot;http://www.msnbc.msn.com/id/4972055/site/newsweek/&quot;&quot; looks like a URL. Beautiful Soup is not an HTTP client. You should probably use an HTTP client like requests to get the document behind the URL, and feed that document to Beautiful Soup.
  ' that document to Beautiful Soup.' % decoded_markup
C:\ProgramData\Anaconda3\lib\site-packages\bs4\__init__.py:219: UserWarning: &quot;b'12.'&quot; looks like a filename, not markup. You should probably open this file and pass the filehandle into Beautiful Soup.
  ' Beautiful Soup.' % markup)
C:\ProgramData\Anaconda3\lib\site-packages\bs4\__init__.py:219: UserWarning: &quot;b'..'&quot; looks like a filename, not markup. You should probably open this file and pass the filehandle into Beautiful Soup.
  ' Beautiful Soup.' % markup)
C:\ProgramData\Anaconda3\lib\site-packages\bs4\__init__.py:282: UserWarning: &quot;http://www.youtube.com/watch?v=a0KSqelmgN8&quot;&quot; looks like a URL. Beautiful Soup is not an HTTP client. You should probably use an HTTP client like requests to get the document behind the URL, and feed that document to Beautiful Soup.
  ' that document to Beautiful Soup.' % decoded_markup
C:\ProgramData\Anaconda3\lib\site-packages\bs4\__init__.py:219: UserWarning: &quot;b'.. .'&quot; looks like a filename, not markup. You should probably open this file and pass the filehandle into Beautiful Soup.
  ' Beautiful Soup.' % markup)
C:\ProgramData\Anaconda3\lib\site-packages\bs4\__init__.py:282: UserWarning: &quot;http://jake-weird.blogspot.com/2007/08/beneath.html&quot;&quot; looks like a URL. Beautiful Soup is not an HTTP client. You should probably use an HTTP client like requests to get the document behind the URL, and feed that document to Beautiful Soup.
  ' that document to Beautiful Soup.' % decoded_markup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sentences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;795538
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;sentences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;['with', 'all', 'this', 'stuff', 'go', 'down', 'at', 'the', 'moment', 'with']
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;sentences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;['mayb', 'i', 'just', 'want', 'to', 'get', 'a', 'certain', 'insight', 'into']
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Word2Vec 모델의 파라메터&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;아키텍처 : 아키텍처 옵션은 skip-gram (default) 또는 CBOW 모델이다. skip-gram (default)은 느리지 만 더 나은 결과를 낸다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;학습 알고리즘 : Hierarchical softmax (default) 또는 negative 샘플링. 여기에서는 기본값이 잘 동작한다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;빈번하게 등장하는 단어에 대한 다운 샘플링 : Google 문서는 .00001에서 .001 사이의 값을 권장한다. 여기에서는 0.001에 가까운 값이 최종 모델의 정확도를 높이는 것으로 보여진다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;단어 벡터 차원 : 많은 feature를 사용한다고 항상 좋은 것은 아니지만 대체적으로 좀 더 나은 모델이 된다. 합리적인 값은 수십에서 수백 개가 될 수 있고 여기에서는 300으로 지정했다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;컨텍스트 / 창 크기 : 학습 알고리즘이 고려해야하는 컨텍스트의 단어 수는 얼마나 될까? hierarchical softmax 를 위해 좀 더 큰 수가 좋지만 10 정도가 적당하다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Worker threads : 실행할 병렬 프로세스의 수로 컴퓨터마다 다르지만 대부분의 시스템에서 4에서 6 사이의 값을 사용하다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;최소 단어 수 : 어휘의 크기를 의미있는 단어로 제한하는 데 도움이 된다. 모든 문서에서이 여러 번 발생하지 않는 단어는 무시된다. 10에서 100 사이가 적당하며, 이 경진대회의 데이터는 각 영화가 30개씩의 리뷰가 있기 때문에 개별 영화 제목에 너무 많은 중요성이 붙는 것을 피하기 위해 최소 단어 수를 40으로 설정한다. 그 결과 전체 어휘 크기는 약 15,000 단어가 된다. 높은 값은 제한 된 실행시간에 도움이 된다.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;logging&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;basicConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'%(asctime)s : %(levelname)s : %(message)s'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;INFO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# 파라메터값 지정
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_features&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# 문자 벡터 차원 수
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min_word_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# 최소 단어 수
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_workers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# 병렬 처리 스레드 수
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# 문자열 창 크기
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;downsampling&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1e-3&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# 문자 빈도 수 Downsample
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 초기화 및 모델 학습
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;gensim.models&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word2vec&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 모델 학습
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word2vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Word2Vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sentences&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                          &lt;span class=&quot;n&quot;&gt;workers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_workers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                          &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                          &lt;span class=&quot;n&quot;&gt;min_count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min_word_count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                          &lt;span class=&quot;n&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                          &lt;span class=&quot;n&quot;&gt;sample&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;downsampling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;C:\ProgramData\Anaconda3\lib\site-packages\gensim-3.4.0-py3.6-win-amd64.egg\gensim\utils.py:1197: UserWarning: detected Windows; aliasing chunkize to chunkize_serial
  warnings.warn(&quot;detected Windows; aliasing chunkize to chunkize_serial&quot;)
2018-04-30 12:06:49,740 : INFO : 'pattern' package not found; tag filters are not available for English
2018-04-30 12:06:49,755 : INFO : collecting all words and their counts
2018-04-30 12:06:49,756 : INFO : PROGRESS: at sentence #0, processed 0 words, keeping 0 word types
2018-04-30 12:06:49,831 : INFO : PROGRESS: at sentence #10000, processed 225803 words, keeping 12465 word types
2018-04-30 12:06:49,912 : INFO : PROGRESS: at sentence #20000, processed 451892 words, keeping 17070 word types
2018-04-30 12:06:49,990 : INFO : PROGRESS: at sentence #30000, processed 671315 words, keeping 20370 word types
2018-04-30 12:06:50,077 : INFO : PROGRESS: at sentence #40000, processed 897815 words, keeping 23125 word types
2018-04-30 12:06:50,154 : INFO : PROGRESS: at sentence #50000, processed 1116963 words, keeping 25365 word types
2018-04-30 12:06:50,253 : INFO : PROGRESS: at sentence #60000, processed 1338404 words, keeping 27283 word types
2018-04-30 12:06:50,342 : INFO : PROGRESS: at sentence #70000, processed 1561580 words, keeping 29024 word types
2018-04-30 12:06:50,435 : INFO : PROGRESS: at sentence #80000, processed 1780887 words, keeping 30603 word types
2018-04-30 12:06:50,537 : INFO : PROGRESS: at sentence #90000, processed 2004996 words, keeping 32223 word types
2018-04-30 12:06:50,628 : INFO : PROGRESS: at sentence #100000, processed 2226967 words, keeping 33579 word types
2018-04-30 12:06:50,717 : INFO : PROGRESS: at sentence #110000, processed 2446581 words, keeping 34827 word types
2018-04-30 12:06:50,790 : INFO : PROGRESS: at sentence #120000, processed 2668776 words, keeping 36183 word types
2018-04-30 12:06:50,886 : INFO : PROGRESS: at sentence #130000, processed 2894304 words, keeping 37353 word types
2018-04-30 12:06:50,999 : INFO : PROGRESS: at sentence #140000, processed 3107006 words, keeping 38376 word types
2018-04-30 12:06:51,128 : INFO : PROGRESS: at sentence #150000, processed 3332628 words, keeping 39556 word types
2018-04-30 12:06:51,248 : INFO : PROGRESS: at sentence #160000, processed 3555316 words, keeping 40629 word types
2018-04-30 12:06:51,364 : INFO : PROGRESS: at sentence #170000, processed 3778656 words, keeping 41628 word types
2018-04-30 12:06:51,477 : INFO : PROGRESS: at sentence #180000, processed 3999237 words, keeping 42599 word types
2018-04-30 12:06:51,589 : INFO : PROGRESS: at sentence #190000, processed 4224450 words, keeping 43461 word types
2018-04-30 12:06:51,685 : INFO : PROGRESS: at sentence #200000, processed 4448604 words, keeping 44301 word types
2018-04-30 12:06:51,771 : INFO : PROGRESS: at sentence #210000, processed 4669968 words, keeping 45212 word types
2018-04-30 12:06:51,863 : INFO : PROGRESS: at sentence #220000, processed 4894969 words, keeping 46134 word types
2018-04-30 12:06:52,013 : INFO : PROGRESS: at sentence #230000, processed 5117546 words, keeping 46986 word types
2018-04-30 12:06:52,126 : INFO : PROGRESS: at sentence #240000, processed 5345051 words, keeping 47854 word types
2018-04-30 12:06:52,229 : INFO : PROGRESS: at sentence #250000, processed 5559166 words, keeping 48699 word types
2018-04-30 12:06:52,345 : INFO : PROGRESS: at sentence #260000, processed 5779147 words, keeping 49469 word types
2018-04-30 12:06:52,438 : INFO : PROGRESS: at sentence #270000, processed 6000436 words, keeping 50416 word types
2018-04-30 12:06:52,525 : INFO : PROGRESS: at sentence #280000, processed 6226315 words, keeping 51640 word types
2018-04-30 12:06:52,612 : INFO : PROGRESS: at sentence #290000, processed 6449475 words, keeping 52754 word types
2018-04-30 12:06:52,694 : INFO : PROGRESS: at sentence #300000, processed 6674078 words, keeping 53755 word types
2018-04-30 12:06:52,782 : INFO : PROGRESS: at sentence #310000, processed 6899392 words, keeping 54734 word types
2018-04-30 12:06:52,871 : INFO : PROGRESS: at sentence #320000, processed 7124279 words, keeping 55770 word types
2018-04-30 12:06:52,953 : INFO : PROGRESS: at sentence #330000, processed 7346022 words, keeping 56687 word types
2018-04-30 12:06:53,036 : INFO : PROGRESS: at sentence #340000, processed 7575534 words, keeping 57629 word types
2018-04-30 12:06:53,133 : INFO : PROGRESS: at sentence #350000, processed 7798804 words, keeping 58485 word types
2018-04-30 12:06:53,208 : INFO : PROGRESS: at sentence #360000, processed 8019467 words, keeping 59345 word types
2018-04-30 12:06:53,296 : INFO : PROGRESS: at sentence #370000, processed 8246659 words, keeping 60161 word types
2018-04-30 12:06:53,379 : INFO : PROGRESS: at sentence #380000, processed 8471806 words, keeping 61069 word types
2018-04-30 12:06:53,467 : INFO : PROGRESS: at sentence #390000, processed 8701556 words, keeping 61810 word types
2018-04-30 12:06:53,546 : INFO : PROGRESS: at sentence #400000, processed 8924505 words, keeping 62546 word types
2018-04-30 12:06:53,634 : INFO : PROGRESS: at sentence #410000, processed 9145855 words, keeping 63263 word types
2018-04-30 12:06:53,716 : INFO : PROGRESS: at sentence #420000, processed 9366935 words, keeping 64024 word types
2018-04-30 12:06:53,797 : INFO : PROGRESS: at sentence #430000, processed 9594472 words, keeping 64795 word types
2018-04-30 12:06:53,882 : INFO : PROGRESS: at sentence #440000, processed 9821225 words, keeping 65539 word types
2018-04-30 12:06:53,966 : INFO : PROGRESS: at sentence #450000, processed 10044987 words, keeping 66378 word types
2018-04-30 12:06:54,047 : INFO : PROGRESS: at sentence #460000, processed 10277747 words, keeping 67158 word types
2018-04-30 12:06:54,141 : INFO : PROGRESS: at sentence #470000, processed 10505672 words, keeping 67775 word types
2018-04-30 12:06:54,220 : INFO : PROGRESS: at sentence #480000, processed 10726056 words, keeping 68500 word types
2018-04-30 12:06:54,308 : INFO : PROGRESS: at sentence #490000, processed 10952800 words, keeping 69256 word types
2018-04-30 12:06:54,409 : INFO : PROGRESS: at sentence #500000, processed 11174456 words, keeping 69892 word types
2018-04-30 12:06:54,485 : INFO : PROGRESS: at sentence #510000, processed 11399731 words, keeping 70593 word types
2018-04-30 12:06:54,554 : INFO : PROGRESS: at sentence #520000, processed 11623082 words, keeping 71267 word types
2018-04-30 12:06:54,630 : INFO : PROGRESS: at sentence #530000, processed 11847480 words, keeping 71877 word types
2018-04-30 12:06:54,703 : INFO : PROGRESS: at sentence #540000, processed 12072095 words, keeping 72537 word types
2018-04-30 12:06:54,789 : INFO : PROGRESS: at sentence #550000, processed 12297646 words, keeping 73212 word types
2018-04-30 12:06:54,873 : INFO : PROGRESS: at sentence #560000, processed 12518936 words, keeping 73861 word types
2018-04-30 12:06:54,961 : INFO : PROGRESS: at sentence #570000, processed 12748083 words, keeping 74431 word types
2018-04-30 12:06:55,074 : INFO : PROGRESS: at sentence #580000, processed 12969579 words, keeping 75087 word types
2018-04-30 12:06:55,232 : INFO : PROGRESS: at sentence #590000, processed 13195104 words, keeping 75733 word types
2018-04-30 12:06:55,349 : INFO : PROGRESS: at sentence #600000, processed 13417302 words, keeping 76294 word types
2018-04-30 12:06:55,458 : INFO : PROGRESS: at sentence #610000, processed 13638325 words, keeping 76952 word types
2018-04-30 12:06:55,556 : INFO : PROGRESS: at sentence #620000, processed 13864650 words, keeping 77503 word types
2018-04-30 12:06:55,644 : INFO : PROGRESS: at sentence #630000, processed 14088936 words, keeping 78066 word types
2018-04-30 12:06:55,726 : INFO : PROGRESS: at sentence #640000, processed 14309719 words, keeping 78692 word types
2018-04-30 12:06:55,805 : INFO : PROGRESS: at sentence #650000, processed 14535475 words, keeping 79295 word types
2018-04-30 12:06:55,888 : INFO : PROGRESS: at sentence #660000, processed 14758265 words, keeping 79864 word types
2018-04-30 12:06:55,973 : INFO : PROGRESS: at sentence #670000, processed 14981658 words, keeping 80381 word types
2018-04-30 12:06:56,060 : INFO : PROGRESS: at sentence #680000, processed 15206490 words, keeping 80912 word types
2018-04-30 12:06:56,141 : INFO : PROGRESS: at sentence #690000, processed 15428683 words, keeping 81482 word types
2018-04-30 12:06:56,227 : INFO : PROGRESS: at sentence #700000, processed 15657389 words, keeping 82074 word types
2018-04-30 12:06:56,316 : INFO : PROGRESS: at sentence #710000, processed 15880378 words, keeping 82560 word types
2018-04-30 12:06:56,411 : INFO : PROGRESS: at sentence #720000, processed 16105665 words, keeping 83036 word types
2018-04-30 12:06:56,492 : INFO : PROGRESS: at sentence #730000, processed 16332046 words, keeping 83571 word types
2018-04-30 12:06:56,578 : INFO : PROGRESS: at sentence #740000, processed 16553079 words, keeping 84127 word types
2018-04-30 12:06:56,657 : INFO : PROGRESS: at sentence #750000, processed 16771406 words, keeping 84599 word types
2018-04-30 12:06:56,735 : INFO : PROGRESS: at sentence #760000, processed 16990810 words, keeping 85068 word types
2018-04-30 12:06:56,818 : INFO : PROGRESS: at sentence #770000, processed 17217947 words, keeping 85644 word types
2018-04-30 12:06:56,906 : INFO : PROGRESS: at sentence #780000, processed 17448093 words, keeping 86160 word types
2018-04-30 12:06:56,996 : INFO : PROGRESS: at sentence #790000, processed 17675169 words, keeping 86665 word types
2018-04-30 12:06:57,045 : INFO : collected 86996 word types from a corpus of 17798270 raw words and 795538 sentences
2018-04-30 12:06:57,045 : INFO : Loading a fresh vocabulary
2018-04-30 12:06:57,131 : INFO : min_count=40 retains 11986 unique words (13% of original 86996, drops 75010)
2018-04-30 12:06:57,133 : INFO : min_count=40 leaves 17434033 word corpus (97% of original 17798270, drops 364237)
2018-04-30 12:06:57,209 : INFO : deleting the raw counts dictionary of 86996 items
2018-04-30 12:06:57,216 : INFO : sample=0.001 downsamples 50 most-common words
2018-04-30 12:06:57,217 : INFO : downsampling leaves estimated 12872363 word corpus (73.8% of prior 17434033)
2018-04-30 12:06:57,281 : INFO : estimated required memory for 11986 words and 300 dimensions: 34759400 bytes
2018-04-30 12:06:57,282 : INFO : resetting layer weights
2018-04-30 12:06:57,559 : INFO : training model with 4 workers on 11986 vocabulary and 300 features, using sg=0 hs=0 sample=0.001 negative=5 window=10
2018-04-30 12:06:58,622 : INFO : EPOCH 1 - PROGRESS: at 3.42% examples, 427165 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:06:59,625 : INFO : EPOCH 1 - PROGRESS: at 6.68% examples, 422080 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:00,629 : INFO : EPOCH 1 - PROGRESS: at 9.81% examples, 413311 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:01,661 : INFO : EPOCH 1 - PROGRESS: at 13.08% examples, 411567 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:02,692 : INFO : EPOCH 1 - PROGRESS: at 16.72% examples, 418921 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:03,708 : INFO : EPOCH 1 - PROGRESS: at 19.38% examples, 404802 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:04,719 : INFO : EPOCH 1 - PROGRESS: at 21.80% examples, 391006 words/s, in_qsize 8, out_qsize 1
2018-04-30 12:07:05,725 : INFO : EPOCH 1 - PROGRESS: at 24.56% examples, 386193 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:06,724 : INFO : EPOCH 1 - PROGRESS: at 26.97% examples, 377823 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:07,738 : INFO : EPOCH 1 - PROGRESS: at 29.47% examples, 372069 words/s, in_qsize 6, out_qsize 1
2018-04-30 12:07:08,756 : INFO : EPOCH 1 - PROGRESS: at 32.18% examples, 368533 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:09,779 : INFO : EPOCH 1 - PROGRESS: at 34.27% examples, 359451 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:10,806 : INFO : EPOCH 1 - PROGRESS: at 36.11% examples, 349544 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:11,835 : INFO : EPOCH 1 - PROGRESS: at 37.73% examples, 339030 words/s, in_qsize 8, out_qsize 2
2018-04-30 12:07:12,914 : INFO : EPOCH 1 - PROGRESS: at 40.80% examples, 341046 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:13,915 : INFO : EPOCH 1 - PROGRESS: at 42.41% examples, 332956 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:14,935 : INFO : EPOCH 1 - PROGRESS: at 44.89% examples, 331693 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:15,974 : INFO : EPOCH 1 - PROGRESS: at 47.28% examples, 329834 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:16,983 : INFO : EPOCH 1 - PROGRESS: at 49.65% examples, 328681 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:17,999 : INFO : EPOCH 1 - PROGRESS: at 52.43% examples, 329647 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:19,009 : INFO : EPOCH 1 - PROGRESS: at 54.99% examples, 329598 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:20,031 : INFO : EPOCH 1 - PROGRESS: at 57.42% examples, 328726 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:21,038 : INFO : EPOCH 1 - PROGRESS: at 59.85% examples, 328154 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:22,049 : INFO : EPOCH 1 - PROGRESS: at 62.82% examples, 330233 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:23,065 : INFO : EPOCH 1 - PROGRESS: at 65.18% examples, 328977 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:24,103 : INFO : EPOCH 1 - PROGRESS: at 67.12% examples, 325612 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:25,119 : INFO : EPOCH 1 - PROGRESS: at 68.38% examples, 319379 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:26,120 : INFO : EPOCH 1 - PROGRESS: at 70.39% examples, 317302 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:27,124 : INFO : EPOCH 1 - PROGRESS: at 72.49% examples, 315815 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:28,130 : INFO : EPOCH 1 - PROGRESS: at 75.48% examples, 317963 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:29,141 : INFO : EPOCH 1 - PROGRESS: at 77.66% examples, 316696 words/s, in_qsize 7, out_qsize 1
2018-04-30 12:07:30,164 : INFO : EPOCH 1 - PROGRESS: at 79.92% examples, 315602 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:31,172 : INFO : EPOCH 1 - PROGRESS: at 81.98% examples, 314064 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:32,200 : INFO : EPOCH 1 - PROGRESS: at 83.84% examples, 311640 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:33,222 : INFO : EPOCH 1 - PROGRESS: at 85.63% examples, 309199 words/s, in_qsize 6, out_qsize 1
2018-04-30 12:07:34,268 : INFO : EPOCH 1 - PROGRESS: at 87.69% examples, 307650 words/s, in_qsize 7, out_qsize 1
2018-04-30 12:07:35,278 : INFO : EPOCH 1 - PROGRESS: at 90.07% examples, 307646 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:36,278 : INFO : EPOCH 1 - PROGRESS: at 91.92% examples, 305841 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:37,297 : INFO : EPOCH 1 - PROGRESS: at 94.15% examples, 305076 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:38,300 : INFO : EPOCH 1 - PROGRESS: at 96.53% examples, 305000 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:39,314 : INFO : EPOCH 1 - PROGRESS: at 98.72% examples, 304525 words/s, in_qsize 7, out_qsize 1
2018-04-30 12:07:39,910 : INFO : worker thread finished; awaiting finish of 3 more threads
2018-04-30 12:07:39,949 : INFO : worker thread finished; awaiting finish of 2 more threads
2018-04-30 12:07:39,970 : INFO : worker thread finished; awaiting finish of 1 more threads
2018-04-30 12:07:39,998 : INFO : worker thread finished; awaiting finish of 0 more threads
2018-04-30 12:07:40,000 : INFO : EPOCH - 1 : training on 17798270 raw words (12871193 effective words) took 42.4s, 303498 effective words/s
2018-04-30 12:07:41,052 : INFO : EPOCH 2 - PROGRESS: at 2.45% examples, 308316 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:42,073 : INFO : EPOCH 2 - PROGRESS: at 4.59% examples, 288681 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:43,118 : INFO : EPOCH 2 - PROGRESS: at 7.30% examples, 303057 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:44,125 : INFO : EPOCH 2 - PROGRESS: at 9.29% examples, 290343 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:45,150 : INFO : EPOCH 2 - PROGRESS: at 11.20% examples, 280107 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:46,152 : INFO : EPOCH 2 - PROGRESS: at 13.03% examples, 272151 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:47,162 : INFO : EPOCH 2 - PROGRESS: at 14.72% examples, 264022 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:48,234 : INFO : EPOCH 2 - PROGRESS: at 16.29% examples, 254190 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:49,266 : INFO : EPOCH 2 - PROGRESS: at 18.42% examples, 254662 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:50,266 : INFO : EPOCH 2 - PROGRESS: at 20.73% examples, 258713 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:51,269 : INFO : EPOCH 2 - PROGRESS: at 23.04% examples, 261984 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:52,282 : INFO : EPOCH 2 - PROGRESS: at 25.22% examples, 263287 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:53,303 : INFO : EPOCH 2 - PROGRESS: at 26.91% examples, 259337 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:54,304 : INFO : EPOCH 2 - PROGRESS: at 29.98% examples, 268955 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:55,304 : INFO : EPOCH 2 - PROGRESS: at 33.03% examples, 276327 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:56,321 : INFO : EPOCH 2 - PROGRESS: at 35.33% examples, 277230 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:57,359 : INFO : EPOCH 2 - PROGRESS: at 38.01% examples, 280612 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:07:58,371 : INFO : EPOCH 2 - PROGRESS: at 40.46% examples, 282449 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:07:59,381 : INFO : EPOCH 2 - PROGRESS: at 43.36% examples, 287092 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:00,390 : INFO : EPOCH 2 - PROGRESS: at 45.89% examples, 288824 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:01,406 : INFO : EPOCH 2 - PROGRESS: at 48.16% examples, 288917 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:02,451 : INFO : EPOCH 2 - PROGRESS: at 50.68% examples, 289948 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:03,521 : INFO : EPOCH 2 - PROGRESS: at 53.10% examples, 289944 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:04,538 : INFO : EPOCH 2 - PROGRESS: at 54.81% examples, 287055 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:05,539 : INFO : EPOCH 2 - PROGRESS: at 56.72% examples, 285394 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:06,541 : INFO : EPOCH 2 - PROGRESS: at 58.63% examples, 284133 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:07,542 : INFO : EPOCH 2 - PROGRESS: at 60.64% examples, 283253 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:08,562 : INFO : EPOCH 2 - PROGRESS: at 63.10% examples, 284282 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:09,583 : INFO : EPOCH 2 - PROGRESS: at 65.57% examples, 285213 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:10,602 : INFO : EPOCH 2 - PROGRESS: at 67.97% examples, 285854 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:11,661 : INFO : EPOCH 2 - PROGRESS: at 70.60% examples, 287023 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:12,662 : INFO : EPOCH 2 - PROGRESS: at 72.72% examples, 286639 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:13,682 : INFO : EPOCH 2 - PROGRESS: at 74.80% examples, 285883 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:14,713 : INFO : EPOCH 2 - PROGRESS: at 77.10% examples, 285918 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:15,742 : INFO : EPOCH 2 - PROGRESS: at 79.57% examples, 286573 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:16,743 : INFO : EPOCH 2 - PROGRESS: at 82.09% examples, 287607 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:17,759 : INFO : EPOCH 2 - PROGRESS: at 84.67% examples, 288667 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:18,763 : INFO : EPOCH 2 - PROGRESS: at 87.64% examples, 291075 words/s, in_qsize 7, out_qsize 1
2018-04-30 12:08:19,765 : INFO : EPOCH 2 - PROGRESS: at 90.31% examples, 292449 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:20,779 : INFO : EPOCH 2 - PROGRESS: at 93.80% examples, 296159 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:21,802 : INFO : EPOCH 2 - PROGRESS: at 97.35% examples, 299801 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:22,540 : INFO : worker thread finished; awaiting finish of 3 more threads
2018-04-30 12:08:22,558 : INFO : worker thread finished; awaiting finish of 2 more threads
2018-04-30 12:08:22,574 : INFO : worker thread finished; awaiting finish of 1 more threads
2018-04-30 12:08:22,578 : INFO : worker thread finished; awaiting finish of 0 more threads
2018-04-30 12:08:22,579 : INFO : EPOCH - 2 : training on 17798270 raw words (12872113 effective words) took 42.6s, 302461 effective words/s
2018-04-30 12:08:23,608 : INFO : EPOCH 3 - PROGRESS: at 3.36% examples, 426875 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:24,615 : INFO : EPOCH 3 - PROGRESS: at 6.90% examples, 438685 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:25,630 : INFO : EPOCH 3 - PROGRESS: at 10.37% examples, 437207 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:26,642 : INFO : EPOCH 3 - PROGRESS: at 13.43% examples, 424408 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:27,645 : INFO : EPOCH 3 - PROGRESS: at 16.50% examples, 417336 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:28,659 : INFO : EPOCH 3 - PROGRESS: at 19.94% examples, 420156 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:29,661 : INFO : EPOCH 3 - PROGRESS: at 23.38% examples, 422990 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:30,667 : INFO : EPOCH 3 - PROGRESS: at 26.18% examples, 414959 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:31,669 : INFO : EPOCH 3 - PROGRESS: at 28.99% examples, 408924 words/s, in_qsize 8, out_qsize 1
2018-04-30 12:08:32,673 : INFO : EPOCH 3 - PROGRESS: at 31.67% examples, 401902 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:33,696 : INFO : EPOCH 3 - PROGRESS: at 34.76% examples, 400514 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:34,707 : INFO : EPOCH 3 - PROGRESS: at 37.62% examples, 397562 words/s, in_qsize 8, out_qsize 1
2018-04-30 12:08:35,734 : INFO : EPOCH 3 - PROGRESS: at 40.80% examples, 397784 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:36,737 : INFO : EPOCH 3 - PROGRESS: at 43.69% examples, 396176 words/s, in_qsize 8, out_qsize 1
2018-04-30 12:08:37,745 : INFO : EPOCH 3 - PROGRESS: at 46.72% examples, 395548 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:38,764 : INFO : EPOCH 3 - PROGRESS: at 49.94% examples, 396492 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:39,810 : INFO : EPOCH 3 - PROGRESS: at 53.10% examples, 395892 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:40,816 : INFO : EPOCH 3 - PROGRESS: at 56.49% examples, 398171 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:41,831 : INFO : EPOCH 3 - PROGRESS: at 59.84% examples, 400068 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:42,834 : INFO : EPOCH 3 - PROGRESS: at 62.99% examples, 400243 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:43,846 : INFO : EPOCH 3 - PROGRESS: at 66.28% examples, 401222 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:44,884 : INFO : EPOCH 3 - PROGRESS: at 68.72% examples, 396460 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:45,894 : INFO : EPOCH 3 - PROGRESS: at 70.27% examples, 387967 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:46,898 : INFO : EPOCH 3 - PROGRESS: at 72.72% examples, 385020 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:47,916 : INFO : EPOCH 3 - PROGRESS: at 75.82% examples, 385212 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:48,924 : INFO : EPOCH 3 - PROGRESS: at 79.06% examples, 386378 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:49,946 : INFO : EPOCH 3 - PROGRESS: at 82.09% examples, 386199 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:50,950 : INFO : EPOCH 3 - PROGRESS: at 84.17% examples, 381952 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:51,969 : INFO : EPOCH 3 - PROGRESS: at 86.53% examples, 379028 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:52,997 : INFO : EPOCH 3 - PROGRESS: at 88.81% examples, 375949 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:08:54,001 : INFO : EPOCH 3 - PROGRESS: at 90.82% examples, 372184 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:55,048 : INFO : EPOCH 3 - PROGRESS: at 93.01% examples, 368873 words/s, in_qsize 8, out_qsize 1
2018-04-30 12:08:56,057 : INFO : EPOCH 3 - PROGRESS: at 95.59% examples, 367458 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:57,073 : INFO : EPOCH 3 - PROGRESS: at 98.11% examples, 366274 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:08:57,760 : INFO : worker thread finished; awaiting finish of 3 more threads
2018-04-30 12:08:57,811 : INFO : worker thread finished; awaiting finish of 2 more threads
2018-04-30 12:08:57,816 : INFO : worker thread finished; awaiting finish of 1 more threads
2018-04-30 12:08:57,822 : INFO : worker thread finished; awaiting finish of 0 more threads
2018-04-30 12:08:57,825 : INFO : EPOCH - 3 : training on 17798270 raw words (12874360 effective words) took 35.2s, 365412 effective words/s
2018-04-30 12:08:58,843 : INFO : EPOCH 4 - PROGRESS: at 2.29% examples, 294724 words/s, in_qsize 7, out_qsize 1
2018-04-30 12:08:59,845 : INFO : EPOCH 4 - PROGRESS: at 5.03% examples, 323737 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:00,850 : INFO : EPOCH 4 - PROGRESS: at 7.54% examples, 321039 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:01,855 : INFO : EPOCH 4 - PROGRESS: at 9.00% examples, 287446 words/s, in_qsize 6, out_qsize 1
2018-04-30 12:09:02,921 : INFO : EPOCH 4 - PROGRESS: at 10.76% examples, 271258 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:03,924 : INFO : EPOCH 4 - PROGRESS: at 12.68% examples, 266864 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:04,931 : INFO : EPOCH 4 - PROGRESS: at 14.45% examples, 260620 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:05,954 : INFO : EPOCH 4 - PROGRESS: at 15.95% examples, 251781 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:06,980 : INFO : EPOCH 4 - PROGRESS: at 17.52% examples, 244878 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:07,999 : INFO : EPOCH 4 - PROGRESS: at 19.21% examples, 241613 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:09,020 : INFO : EPOCH 4 - PROGRESS: at 21.24% examples, 242812 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:10,037 : INFO : EPOCH 4 - PROGRESS: at 22.98% examples, 240963 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:11,067 : INFO : EPOCH 4 - PROGRESS: at 25.00% examples, 241868 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:12,066 : INFO : EPOCH 4 - PROGRESS: at 26.91% examples, 242089 words/s, in_qsize 6, out_qsize 1
2018-04-30 12:09:13,144 : INFO : EPOCH 4 - PROGRESS: at 29.04% examples, 242988 words/s, in_qsize 8, out_qsize 2
2018-04-30 12:09:14,288 : INFO : EPOCH 4 - PROGRESS: at 31.20% examples, 242746 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:15,319 : INFO : EPOCH 4 - PROGRESS: at 32.97% examples, 241197 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:16,359 : INFO : EPOCH 4 - PROGRESS: at 34.65% examples, 239327 words/s, in_qsize 6, out_qsize 0
2018-04-30 12:09:17,377 : INFO : EPOCH 4 - PROGRESS: at 36.34% examples, 237946 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:18,407 : INFO : EPOCH 4 - PROGRESS: at 38.40% examples, 239011 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:19,442 : INFO : EPOCH 4 - PROGRESS: at 40.13% examples, 237942 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:20,494 : INFO : EPOCH 4 - PROGRESS: at 42.14% examples, 238351 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:21,521 : INFO : EPOCH 4 - PROGRESS: at 43.92% examples, 237784 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:22,538 : INFO : EPOCH 4 - PROGRESS: at 45.71% examples, 237327 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:23,553 : INFO : EPOCH 4 - PROGRESS: at 47.62% examples, 237505 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:24,612 : INFO : EPOCH 4 - PROGRESS: at 49.66% examples, 238085 words/s, in_qsize 6, out_qsize 2
2018-04-30 12:09:25,636 : INFO : EPOCH 4 - PROGRESS: at 51.31% examples, 236856 words/s, in_qsize 8, out_qsize 2
2018-04-30 12:09:26,653 : INFO : EPOCH 4 - PROGRESS: at 53.43% examples, 238013 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:27,726 : INFO : EPOCH 4 - PROGRESS: at 54.81% examples, 235514 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:28,731 : INFO : EPOCH 4 - PROGRESS: at 55.94% examples, 232529 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:29,882 : INFO : EPOCH 4 - PROGRESS: at 57.73% examples, 231598 words/s, in_qsize 6, out_qsize 1
2018-04-30 12:09:30,929 : INFO : EPOCH 4 - PROGRESS: at 59.39% examples, 230825 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:31,968 : INFO : EPOCH 4 - PROGRESS: at 61.02% examples, 229926 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:32,976 : INFO : EPOCH 4 - PROGRESS: at 63.16% examples, 231149 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:33,992 : INFO : EPOCH 4 - PROGRESS: at 64.73% examples, 230245 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:35,003 : INFO : EPOCH 4 - PROGRESS: at 67.29% examples, 232907 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:36,040 : INFO : EPOCH 4 - PROGRESS: at 69.03% examples, 232444 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:37,047 : INFO : EPOCH 4 - PROGRESS: at 71.54% examples, 234763 words/s, in_qsize 6, out_qsize 1
2018-04-30 12:09:38,075 : INFO : EPOCH 4 - PROGRESS: at 74.12% examples, 237022 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:39,090 : INFO : EPOCH 4 - PROGRESS: at 77.21% examples, 240818 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:40,091 : INFO : EPOCH 4 - PROGRESS: at 79.34% examples, 241612 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:41,121 : INFO : EPOCH 4 - PROGRESS: at 82.56% examples, 245368 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:42,124 : INFO : EPOCH 4 - PROGRESS: at 85.34% examples, 247963 words/s, in_qsize 6, out_qsize 1
2018-04-30 12:09:43,142 : INFO : EPOCH 4 - PROGRESS: at 88.52% examples, 251479 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:44,149 : INFO : EPOCH 4 - PROGRESS: at 91.32% examples, 253803 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:45,173 : INFO : EPOCH 4 - PROGRESS: at 94.60% examples, 257163 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:46,197 : INFO : EPOCH 4 - PROGRESS: at 97.62% examples, 259774 words/s, in_qsize 7, out_qsize 2
2018-04-30 12:09:46,892 : INFO : worker thread finished; awaiting finish of 3 more threads
2018-04-30 12:09:46,915 : INFO : worker thread finished; awaiting finish of 2 more threads
2018-04-30 12:09:46,920 : INFO : worker thread finished; awaiting finish of 1 more threads
2018-04-30 12:09:46,929 : INFO : worker thread finished; awaiting finish of 0 more threads
2018-04-30 12:09:46,930 : INFO : EPOCH - 4 : training on 17798270 raw words (12873324 effective words) took 49.1s, 262219 effective words/s
2018-04-30 12:09:47,958 : INFO : EPOCH 5 - PROGRESS: at 3.13% examples, 399629 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:48,990 : INFO : EPOCH 5 - PROGRESS: at 6.40% examples, 402616 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:50,001 : INFO : EPOCH 5 - PROGRESS: at 9.75% examples, 408700 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:51,010 : INFO : EPOCH 5 - PROGRESS: at 12.57% examples, 396184 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:52,024 : INFO : EPOCH 5 - PROGRESS: at 15.84% examples, 399643 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:53,087 : INFO : EPOCH 5 - PROGRESS: at 19.04% examples, 396274 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:54,098 : INFO : EPOCH 5 - PROGRESS: at 22.20% examples, 396805 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:55,102 : INFO : EPOCH 5 - PROGRESS: at 25.40% examples, 398372 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:56,121 : INFO : EPOCH 5 - PROGRESS: at 28.70% examples, 400506 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:57,133 : INFO : EPOCH 5 - PROGRESS: at 32.02% examples, 401787 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:09:58,149 : INFO : EPOCH 5 - PROGRESS: at 35.21% examples, 402060 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:09:59,155 : INFO : EPOCH 5 - PROGRESS: at 38.63% examples, 405073 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:10:00,174 : INFO : EPOCH 5 - PROGRESS: at 41.86% examples, 405512 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:10:01,211 : INFO : EPOCH 5 - PROGRESS: at 44.84% examples, 402875 words/s, in_qsize 6, out_qsize 1
2018-04-30 12:10:02,215 : INFO : EPOCH 5 - PROGRESS: at 47.56% examples, 399532 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:10:03,254 : INFO : EPOCH 5 - PROGRESS: at 50.10% examples, 394475 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:10:04,259 : INFO : EPOCH 5 - PROGRESS: at 52.83% examples, 391585 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:10:05,269 : INFO : EPOCH 5 - PROGRESS: at 56.16% examples, 393617 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:10:06,270 : INFO : EPOCH 5 - PROGRESS: at 59.39% examples, 395269 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:10:07,284 : INFO : EPOCH 5 - PROGRESS: at 62.43% examples, 394699 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:10:08,298 : INFO : EPOCH 5 - PROGRESS: at 65.68% examples, 395585 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:10:09,304 : INFO : EPOCH 5 - PROGRESS: at 69.03% examples, 397157 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:10:10,319 : INFO : EPOCH 5 - PROGRESS: at 71.76% examples, 395053 words/s, in_qsize 6, out_qsize 1
2018-04-30 12:10:11,325 : INFO : EPOCH 5 - PROGRESS: at 74.68% examples, 394162 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:10:12,345 : INFO : EPOCH 5 - PROGRESS: at 77.94% examples, 394830 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:10:13,375 : INFO : EPOCH 5 - PROGRESS: at 81.37% examples, 396089 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:10:14,393 : INFO : EPOCH 5 - PROGRESS: at 84.51% examples, 396105 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:10:15,406 : INFO : EPOCH 5 - PROGRESS: at 87.64% examples, 396246 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:10:16,418 : INFO : EPOCH 5 - PROGRESS: at 90.71% examples, 396094 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:10:17,418 : INFO : EPOCH 5 - PROGRESS: at 93.74% examples, 395884 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:10:18,419 : INFO : EPOCH 5 - PROGRESS: at 96.69% examples, 395222 words/s, in_qsize 7, out_qsize 0
2018-04-30 12:10:19,426 : INFO : EPOCH 5 - PROGRESS: at 99.44% examples, 394099 words/s, in_qsize 8, out_qsize 0
2018-04-30 12:10:19,516 : INFO : worker thread finished; awaiting finish of 3 more threads
2018-04-30 12:10:19,536 : INFO : worker thread finished; awaiting finish of 2 more threads
2018-04-30 12:10:19,547 : INFO : worker thread finished; awaiting finish of 1 more threads
2018-04-30 12:10:19,552 : INFO : worker thread finished; awaiting finish of 0 more threads
2018-04-30 12:10:19,553 : INFO : EPOCH - 5 : training on 17798270 raw words (12871972 effective words) took 32.6s, 394752 effective words/s
2018-04-30 12:10:19,555 : INFO : training on a 88991350 raw words (64362962 effective words) took 202.0s, 318637 effective words/s





&amp;lt;gensim.models.word2vec.Word2Vec at 0x23f36bbac18&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# 학습이 완료 되면 필요없는 메모리를 unload 시킨다.
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init_sims&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;model_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'300features_40minwords_10text'&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# model_name = '300features_50minwords_20text'
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;2018-04-30 12:10:19,865 : INFO : precomputing L2-norms of word weight vectors
2018-04-30 12:10:20,082 : INFO : saving Word2Vec object under 300features_40minwords_10text, separately None
2018-04-30 12:10:20,099 : INFO : not storing attribute vectors_norm
2018-04-30 12:10:20,118 : INFO : not storing attribute cum_table
2018-04-30 12:10:21,103 : INFO : saved 300features_40minwords_10text
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# 유사도가 없는 단어 추출
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doesnt_match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'man woman child kitchen'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;'kitchen'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;doesnt_match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;france england germany berlin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;2018-04-30 12:10:21,386 : WARNING : vectors for words {'germany', 'france'} are not present in the model, ignoring these words





'england'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# 가장 유사한 단어를 추출
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;most_similar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;man&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[('woman', 0.6355543732643127),
 ('businessman', 0.5106414556503296),
 ('lad', 0.49627137184143066),
 ('millionair', 0.4852792024612427),
 ('ladi', 0.48219048976898193),
 ('policeman', 0.47352561354637146),
 ('widow', 0.4686756134033203),
 ('farmer', 0.4667765200138092),
 ('men', 0.4604969620704651),
 ('boxer', 0.4499785602092743)]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;most_similar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;queen&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[('princess', 0.6181148886680603),
 ('madam', 0.5621399283409119),
 ('latifah', 0.5599690675735474),
 ('countess', 0.557962954044342),
 ('dame', 0.5570350885391235),
 ('stepmoth', 0.554591178894043),
 ('victoria', 0.5522404909133911),
 ('maid', 0.5426138639450073),
 ('maria', 0.533758282661438),
 ('eva', 0.5325278639793396)]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# model.wv.most_similar(&quot;happy&quot;)
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;most_similar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;happi&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# stemming 처리 시
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[('unhappi', 0.45206087827682495),
 ('sad', 0.43361160159111023),
 ('bitter', 0.40061312913894653),
 ('satisfi', 0.3947785198688507),
 ('lucki', 0.3823172450065613),
 ('joy', 0.37378984689712524),
 ('happier', 0.36996692419052124),
 ('glad', 0.3682306408882141),
 ('sappi', 0.36718422174453735),
 ('afraid', 0.3600339889526367)]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# 참고 https://stackoverflow.com/questions/43776572/visualise-word2vec-generated-from-gensim
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sklearn.manifold&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TSNE&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;matplotlib&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mpl&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;gensim&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;gensim.models&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 그래프에서 마이너스 폰트 깨지는 문제에 대한 대처
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mpl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rcParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'axes.unicode_minus'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;model_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'300features_40minwords_10text'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Doc2Vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;X&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tsne&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TSNE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_components&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 100개의 단어에 대해서만 시각화
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X_tsne&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tsne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fit_transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,:])&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# X_tsne = tsne.fit_transform(X)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;2018-04-30 12:10:26,511 : INFO : loading Doc2Vec object from 300features_40minwords_10text
2018-04-30 12:10:26,982 : INFO : loading wv recursively from 300features_40minwords_10text.wv.* with mmap=None
2018-04-30 12:10:26,983 : INFO : setting ignored attribute vectors_norm to None
2018-04-30 12:10:26,984 : INFO : loading vocabulary recursively from 300features_40minwords_10text.vocabulary.* with mmap=None
2018-04-30 12:10:26,985 : INFO : loading trainables recursively from 300features_40minwords_10text.trainables.* with mmap=None
2018-04-30 12:10:26,986 : INFO : setting ignored attribute cum_table to None
2018-04-30 12:10:26,987 : INFO : loaded 300features_40minwords_10text
C:\ProgramData\Anaconda3\lib\site-packages\ipykernel_launcher.py:15: DeprecationWarning: Call to deprecated `__getitem__` (Method will be removed in 4.0.0, use self.wv.__getitem__() instead).
  from ipykernel import kernelapp as app


11986
[-0.04888876  0.02344336 -0.11825124 -0.0108145  -0.02040573  0.09992806
 -0.01389777 -0.02648932 -0.07141103 -0.03799058]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataFrame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X_tsne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vocab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'x'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'y'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(100, 2)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div&gt;
&lt;style scoped=&quot;&quot;&gt;
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
&lt;/style&gt;
&lt;table border=&quot;1&quot; class=&quot;dataframe&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;text-align: right;&quot;&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;x&lt;/th&gt;
      &lt;th&gt;y&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;with&lt;/th&gt;
      &lt;td&gt;-12.056787&lt;/td&gt;
      &lt;td&gt;4.115122&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;all&lt;/th&gt;
      &lt;td&gt;-2.497947&lt;/td&gt;
      &lt;td&gt;5.160569&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;this&lt;/th&gt;
      &lt;td&gt;-3.791062&lt;/td&gt;
      &lt;td&gt;4.612969&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;stuff&lt;/th&gt;
      &lt;td&gt;-2.408651&lt;/td&gt;
      &lt;td&gt;-1.128544&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;go&lt;/th&gt;
      &lt;td&gt;-9.874672&lt;/td&gt;
      &lt;td&gt;0.933419&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;down&lt;/th&gt;
      &lt;td&gt;-11.559048&lt;/td&gt;
      &lt;td&gt;7.447039&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;at&lt;/th&gt;
      &lt;td&gt;-10.873740&lt;/td&gt;
      &lt;td&gt;5.436837&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;the&lt;/th&gt;
      &lt;td&gt;-2.758157&lt;/td&gt;
      &lt;td&gt;6.790027&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;moment&lt;/th&gt;
      &lt;td&gt;0.124072&lt;/td&gt;
      &lt;td&gt;2.817021&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;mj&lt;/th&gt;
      &lt;td&gt;3.170858&lt;/td&gt;
      &lt;td&gt;-2.268975&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;fig&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;figure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;fig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_size_inches&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_subplot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'x'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'y'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pos&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterrows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;annotate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fontsize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;show&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/oI3BCf8.png&quot; alt=&quot;output_22_0&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;numpy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;makeFeatureVec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
    주어진 문장에서 단어 벡터의 평균을 구하는 함수
    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 속도를 위해 0으로 채운 배열로 초기화 한다.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;featureVec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,),&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;float32&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;nwords&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Index2word는 모델의 사전에 있는 단어명을 담은 리스트이다.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# 속도를 위해 set 형태로 초기화 한다.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;index2word_set&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index2word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 루프를 돌며 모델 사전에 포함이 되는 단어라면 피처에 추가한다.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index2word_set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;nwords&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nwords&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;featureVec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;featureVec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 결과를 단어수로 나누어 평균을 구한다.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;featureVec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;divide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;featureVec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nwords&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;featureVec&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getAvgFeatureVecs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reviews&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 리뷰 단어 목록의 각각에 대한 평균 feature 벡터를 계산하고
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# 2D numpy 배열을 반환한다.
&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 카운터를 초기화 한다.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 속도를 위해 2D 넘파이 배열을 미리 할당한다.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;reviewFeatureVecs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reviews&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;float32&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;review&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reviews&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
       &lt;span class=&quot;c1&quot;&gt;# 매 1000개 리뷰마다 상태를 출력
&lt;/span&gt;       &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1000.&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
           &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Review %d of %d&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reviews&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
       &lt;span class=&quot;c1&quot;&gt;# 평균 피처 벡터를 만들기 위해 위에서 정의한 함수를 호출한다.
&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;reviewFeatureVecs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;makeFeatureVec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;review&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; \
           &lt;span class=&quot;n&quot;&gt;num_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
       &lt;span class=&quot;c1&quot;&gt;# 카운터를 증가시킨다.
&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reviewFeatureVecs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# 멀티스레드로 4개의 워커를 사용해 처리한다.
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getCleanReviews&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reviews&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;clean_reviews&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;clean_reviews&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kaggleBagofWord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apply_by_multiprocessing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;\
        &lt;span class=&quot;n&quot;&gt;reviews&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;review&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kaggleBagofWord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;review_to_wordlist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;\
        &lt;span class=&quot;n&quot;&gt;workers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clean_reviews&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trainDataVecs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getAvgFeatureVecs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;\
    &lt;span class=&quot;n&quot;&gt;getCleanReviews&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_features&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Review 0 of 25000


C:\ProgramData\Anaconda3\lib\site-packages\ipykernel_launcher.py:18: DeprecationWarning: Call to deprecated `__getitem__` (Method will be removed in 4.0.0, use self.wv.__getitem__() instead).


Review 1000 of 25000
Review 2000 of 25000
Review 3000 of 25000
Review 4000 of 25000
Review 5000 of 25000
Review 6000 of 25000
Review 7000 of 25000
Review 8000 of 25000
Review 9000 of 25000
Review 10000 of 25000
Review 11000 of 25000
Review 12000 of 25000
Review 13000 of 25000
Review 14000 of 25000
Review 15000 of 25000
Review 16000 of 25000
Review 17000 of 25000
Review 18000 of 25000
Review 19000 of 25000
Review 20000 of 25000
Review 21000 of 25000
Review 22000 of 25000
Review 23000 of 25000
Review 24000 of 25000
Wall time: 2min 43s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;testDataVecs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getAvgFeatureVecs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;\
        &lt;span class=&quot;n&quot;&gt;getCleanReviews&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_features&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Review 0 of 25000


C:\ProgramData\Anaconda3\lib\site-packages\ipykernel_launcher.py:18: DeprecationWarning: Call to deprecated `__getitem__` (Method will be removed in 4.0.0, use self.wv.__getitem__() instead).


Review 1000 of 25000
Review 2000 of 25000
Review 3000 of 25000
Review 4000 of 25000
Review 5000 of 25000
Review 6000 of 25000
Review 7000 of 25000
Review 8000 of 25000
Review 9000 of 25000
Review 10000 of 25000
Review 11000 of 25000
Review 12000 of 25000
Review 13000 of 25000
Review 14000 of 25000
Review 15000 of 25000
Review 16000 of 25000
Review 17000 of 25000
Review 18000 of 25000
Review 19000 of 25000
Review 20000 of 25000
Review 21000 of 25000
Review 22000 of 25000
Review 23000 of 25000
Review 24000 of 25000
Wall time: 2min 28s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sklearn.ensemble&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RandomForestClassifier&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;forest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RandomForestClassifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;n_estimators&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n_jobs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random_state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2018&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;forest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;forest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trainDataVecs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;sentiment&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Wall time: 21.1 s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sklearn.model_selection&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cross_val_score&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cross_val_score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;\
    &lt;span class=&quot;n&quot;&gt;forest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trainDataVecs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; \
    &lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'sentiment'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scoring&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'roc_auc'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Wall time: 3min 18s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;score&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;0.904642208
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;forest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;testDataVecs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataFrame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;sentiment&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'data/Word2Vec_AverageVectors_{0:.5f}.csv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;quoting&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;output_sentiment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'sentiment'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value_counts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output_sentiment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output_sentiment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;output_sentiment&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;66





0    12533
1    12467
Name: sentiment, dtype: int64
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;seaborn&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sns&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matplotlib&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inline&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;fig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;axes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subplots&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ncols&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;fig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_size_inches&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;countplot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'sentiment'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;axes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;countplot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'sentiment'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;axes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;matplotlib.axes._subplots.AxesSubplot at 0x1681f5faa90&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/907lNNZ.png&quot; alt=&quot;output_35_1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Score 81.34%&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>CNN을 활용한 주요 Model - (1) : Modern CNN</title>
   <link href="https://reniew.github.io/08/"/>
   <updated>2018-06-27T04:47:35+00:00</updated>
   <id>https://reniew.github.io/08</id>
   <content type="html">&lt;h4 id=&quot;cnn을-활용한-주요-model---1--modern-cnn&quot;&gt;CNN을 활용한 주요 Model - (1) : Modern CNN&lt;/h4&gt;

&lt;p&gt;CNN을 활용한 최초의 기본적인 Model들 부터 계속해서 다양한 구조를 가지는 많은 모델들이 계속해서 나오고 있다. 이번 포스트에서는 아래의 분류를 기준으로 CNN의 주요 모델들에 대해서 하나씩 알아 보도록 하겠다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Modern CNN&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;LeNet&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;AlexNet&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;VGG Nets&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;GoogLeNet&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;ResNet&lt;/strong&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Image Detection
    &lt;ul&gt;
      &lt;li&gt;RCNN&lt;/li&gt;
      &lt;li&gt;Fast RCNN&lt;/li&gt;
      &lt;li&gt;Faster RCNN&lt;/li&gt;
      &lt;li&gt;SPP Net&lt;/li&gt;
      &lt;li&gt;Yolo&lt;/li&gt;
      &lt;li&gt;SDD&lt;/li&gt;
      &lt;li&gt;Attention Net&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Semantic Segmentation
    &lt;ul&gt;
      &lt;li&gt;FCN&lt;/li&gt;
      &lt;li&gt;DeepLab v1, v2&lt;/li&gt;
      &lt;li&gt;U-Net&lt;/li&gt;
      &lt;li&gt;ReSeg&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Image Captioning&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;LeNet&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;지난 포스트에서 얘기한 것 처럼 CNN 모델을 최초로 개발한 사람은 프랑스 출신의 Yann LeCun이며, 1989년 &lt;em&gt;“Backpropagation applied to handwritten zip code recognition”&lt;/em&gt; 논문을 통해 최초로 CNN을 사용하였고, 이후 1998년 LeNet이라는 Network를 소개하였다.&lt;/p&gt;

&lt;p&gt;LeNet은 우편번호와 수표의 필기체를 인식하기 위해 개발되었다. LeNet의 최종 모델인 LeNet5의 Architecture를 보면 아래와 같이 이루어져
&lt;img src=&quot;http://nocotan.github.io/images/20170804/lenet.png&quot; alt=&quot;LeNet5&quot; /&gt;&lt;/p&gt;

&lt;p&gt;LeNet 5는 총 7개의 Layer로 구성되어 있다. 두개의 Convolution Layer, 2개의 Sub-Sampling Layer, 2개의 Fully-Connected Layer 그리고 최종 출력 Layer로 이루어져 있다.&lt;/p&gt;

&lt;p&gt;LeNet에 대한 자세한 내용은 LeNet Post를 참고하면 된다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;AlexNet&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;보통 CNN을 얘기할 때 가장 먼저 얘기되는 AlexNet은 2012년 저명한 Computer Vision 대회인 ILSVRC(ImageNet Large-Scale Visual Recognition Challenge)에서 2등(26.2%)보다 월등히 앞서 1등(15.4%)을 하며 소개되었다.
이렇게 월등히 높은 top-5 error로 세상은 CNN에 대해 주목을 하게 된 계기가 되었다.&lt;/p&gt;

&lt;p&gt;AlexNet의 Architecture는 아래와 같다.
&lt;img src=&quot;https://i.imgur.com/CwIvlUW.png&quot; alt=&quot;alexNet&quot; /&gt;
구성은&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;5 Conv layer&lt;/li&gt;
  &lt;li&gt;max polling layer&lt;/li&gt;
  &lt;li&gt;drop out layer&lt;/li&gt;
  &lt;li&gt;3 FC layer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;으로 이루어졌으며 병렬 구조를 이루고 있다.&lt;/p&gt;

&lt;p&gt;AlexNet의 주요 포인트는 아래와 같다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;22000이상의 Categories를 가지는 1500만개 이상의 ImageNet data를 사용하였다.&lt;/li&gt;
  &lt;li&gt;비선형 함수인 ReLU를 사용하였다.(기존의 tanh함수를 사용할때 보다 ReLu를 사용하면서 학습시간이 줄었다)&lt;/li&gt;
  &lt;li&gt;Data Augmentation 기술을 사용하였다(Image translation/Horizontal reflections/Patch extraction)&lt;/li&gt;
  &lt;li&gt;모델 최적화시 SGD를 사용하였고 가중지 감소와 모멘텀 기술을 사용했다.&lt;/li&gt;
  &lt;li&gt;GTX 580을 사용해 5~6일 동안 학습하였다.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;VGG Net&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AlexNet이후의 모델들에게 있어 가장 중요한 쟁점은 얼마나 더 Deep하게 모델을 만드는가 였다. 그런 Deep한 대표적인 모델이 VGG Net과 GoogLeNet이다.
VGG의 특징은 간단한 구조로 사용하기 쉽다는 점이다. 모든 Conv layer는 3x3filter를 동일하게 사용하고 1stride, 1pad를 사용한다. Sub-Sampling은 2x2 Max Polling을 2stride로 이뤄진다. 구조를 그림으로 보자.
&lt;img src=&quot;https://kakalabblog.files.wordpress.com/2017/04/slide034-e1491546326293.jpg&quot; alt=&quot;vggnet&quot; /&gt;&lt;/p&gt;

&lt;p&gt;VGG Net의 주요포인트는 다음과 같다&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;AlexNet의 11x11 filter와 ZFNet의 7x7 filter를 사용한 것과는 달리 VGG Net은 3x3 filter를 사용하였다. 뿐만 아니라 3x3 filter를 Convolution하는 layer를 두개씩 연이어 사용했다. 3x3 filter를 두번 사용함으로써 5x5 filter receptive field를 얻는것과 같은 효과를 얻는다.&lt;/li&gt;
  &lt;li&gt;3개의 연이은 conv layer를 통해 7x7 receptive field를 갖는 효과를 얻는다.&lt;/li&gt;
  &lt;li&gt;max-pooling layer에서 input volume을 줄임으로써 network를 깊게 만든다.&lt;/li&gt;
  &lt;li&gt;VGG Net을 통해 Image Classification과 Localization Task 둘다에 사용하였다.(Localization은 마지막 단에서 Regression을 사용하였다. &lt;a href=&quot;http://arxiv.org/pdf/1409.1556v6.pdf&quot;&gt;Paper&lt;/a&gt;참고)&lt;/li&gt;
  &lt;li&gt;Data Augmentation을 위해 scale jittering를 사용하였다.&lt;/li&gt;
  &lt;li&gt;각 conv layer이후 ReLU함수를 사용하였고, batch gradient descent를 사용했다.&lt;/li&gt;
  &lt;li&gt;NVidia Titan Black GPU 4개를 사용해 2~3주간 학습했다.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;GoogLeNet&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;2014년 ILSVRC에서 Google은 GoogLeNet으로 VGG를 재치고 근소한 차이로 1등을 차지하게 된다.
이때부터의 모델들이 주목하던 부분은 얼마나 깊게(Deep) 모델을 만드는 것이다. 기존의 filter를 여러개 사용하던 LeNet, AlexNet과는 달리 하나의 Conv Layer에서 1개의 filter만 사용되었다.
우선 기본 architecture부터 살펴보면 이전의 model들 보다는 훨씬 더 깊다는 것을 한눈에 알 수 있다.
&lt;img src=&quot;https://adeshpande3.github.io/assets/GoogleNet.gif&quot; alt=&quot;GoogLeNet&quot; /&gt;
&lt;img src=&quot;https://adeshpande3.github.io/assets/GoogLeNet.png&quot; alt=&quot;GoogLeNet&quot; /&gt;
총 22개의&lt;/p&gt;

&lt;p&gt;GoogLeNet에서 사용된 가장 중요한 기술은 &lt;strong&gt;Inception-module&lt;/strong&gt; 을 사용했다는 점이다.
&lt;img src=&quot;https://adeshpande3.github.io/assets/GoogLeNet3.png&quot; alt=&quot;Inception-module&quot; /&gt;
Inception module을 사용함으로써 Parameter 수를 획기적으로 줄였으며, 다양한 receptive field를 가지는 convolution들을 concatenate함으로써 이미지 인식률을 높였다.&lt;/p&gt;

&lt;p&gt;GoogLeNet의 주요 포인트은 아래와 같다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;9개의 Inception modules을 사용하면서 총 100개가 넘는 깊은 network를 가진다.&lt;/li&gt;
  &lt;li&gt;FC layer를 사용하지않고 average pooling을 사용해 7x7x1024를 1x1x1024로 만들었다. 이과정을 통해 파라미터 수를 획기적으로 줄였다.&lt;/li&gt;
  &lt;li&gt;R-CNN concept를 사용하였다(for detection model)&lt;/li&gt;
  &lt;li&gt;Inception model은 계속해서 Update되었다(~7)&lt;/li&gt;
  &lt;li&gt;학습은 GPU를 활용해 한주동안 하였다.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;ResNet&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;이전까지의 AlexNet이후의 Model들은 모델들을 깊게 쌓음으로써 높은 인식률을 보여줬다. 하지만 깊게 쌓으면서 몇 가지 문제가 발생했다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Vanishing/Exploding Gradient : Parameter학습 시 gradient값이 너무 크거나 작아서 학습이 제대로 이뤄지지 않는 문제이다. 보통 Batch Normalization, parameter 초기값 설정 등으로 해결 하지만 layer가 깊어질 수록 해결이 어렵다.&lt;/li&gt;
  &lt;li&gt;Degeneration : depth를 깊게 쌓으면서 일정 깊이 이상 넘어갈 시 성능이 더 좋아지지 않는 문제.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ResNet은 이러한 문제를 &lt;strong&gt;Residual Block&lt;/strong&gt;을 통해 해결 하고 ILSVRC 2015에서 3.6%의 error 라는 놀라울 결과를 보여주었다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Residual Block&lt;/strong&gt;
&lt;img src=&quot;https://adeshpande3.github.io/assets/ResNet.png&quot; alt=&quot;res&quot; /&gt;
Residual Block은 input에 대해 layer를 통과시킨 값($F(x)$)을 바로 다음 단으로 통과시키는 것이 아니라 Input값을 더해서 다음 단으로 통과시킨다.($F(x)+x$)
이러한 구조를 통해 저자는 학습이 훨씬 쉬워졌다고 말한다. 또한 Back propagation과정에서 gradient값이 $x$를 더함으로써 더욱 이전 단으로 잘 전달된다.&lt;/p&gt;

&lt;p&gt;나머지 Model들에 대해서는 다음 포스트에서 계속해서 알아보도록 하겠다.&lt;/p&gt;

&lt;p&gt;출처&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://ratsgo.github.io/deep%20learning/2017/10/09/CNNs/&quot;&gt;ratsgo’s blog&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://adeshpande3.github.io/adeshpande3.github.io/The-9-Deep-Learning-Papers-You-Need-To-Know-About.html&quot;&gt;adeshpande github&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://laonple.blog.me/220654387455&quot;&gt;라온피플 블로그&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://arclab.tistory.com/150&quot;&gt;arclab’s blog&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/sjchoi86/dl_tutorials_10weeks&quot;&gt;sjchoi’s blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>LeNet</title>
   <link href="https://reniew.github.io/07/"/>
   <updated>2018-06-27T04:47:35+00:00</updated>
   <id>https://reniew.github.io/07</id>
   <content type="html">&lt;h4 id=&quot;lenet&quot;&gt;LeNet&lt;/h4&gt;

&lt;p&gt;CNN 모델을 최초로 개발한 사람은 프랑스 출신의 Yann LeCun이며, 1989년 &lt;em&gt;“Backpropagation applied to handwritten zip code recognition”&lt;/em&gt; 논문을 통해 최초로 CNN을 사용하였고, 이후 1998년 LeNet이라는 Network를 소개하였다.&lt;/p&gt;

&lt;p&gt;LeNet은 우편번호와 수표의 필기체를 인식하기 위해 개발되었다. LeNet의 최종 모델인 LeNet5의 Architecture를 보면 아래와 같이 이루어져
&lt;img src=&quot;http://nocotan.github.io/images/20170804/lenet.png&quot; alt=&quot;LeNet5&quot; /&gt;&lt;/p&gt;

&lt;p&gt;LeNet 5는 총 7개의 Layer로 구성되어 있다. 두개의 Convolution Layer, 2개의 Sub-Sampling Layer, 2개의 Fully-Connected Layer 그리고 최종 출력 Layer로 이루어져 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;1-layer : Convolution Layer
Input Data(32x32, 1개의 Channel)를 5x5 Filter 6개를 사용해 Convolution한다. 그결과로는 28x28 사이즈의 Feature map을 6개 만들어 낸다. Parameter의 수는 아래와 같다.
5x5 filter 6개, bias 6개 =&amp;gt; $5&lt;em&gt;5&lt;/em&gt;6+1*6=156$&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;2-layer : SubSampling Layer
28x28의 feature map에 대해 2x2size의 receptive field로 Average Pooling을 시행한다. 따라서 14x14 size를 6개 만든다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;3-layer : Convolution layer2
Conv layer1과 동일하게 5x5 Filter 16개를 사용해 총 10x10 feature map 16개를 만들어 낸다. 일반적으로 수행한다면 6x16 인 96개의 feature map이 만들어져야 하지만 여기서는 모든 map을 연결 하는 것이 아니라 아래의 Table과 같이 선택적으로 연결시켜 network의 symmetry한 성질을 없애려는 것으로 볼 수 있다. 최종적으로 Global feature를 얻기 위함이다.&lt;br /&gt;
파라미터 수는 $5&lt;em&gt;5&lt;/em&gt;60+1*16=1,516$개다.
&lt;img src=&quot;http://img1.daumcdn.net/thumb/R1920x0/?fname=http%3A%2F%2Fcfile23.uf.tistory.com%2Fimage%2F99BE20385AA60C52242B82&quot; alt=&quot;3-layer&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;4-layer : SubSampling layer2
subsmapling1 layer와 마찬가지로 2x2 receptive field에 대해서 average polling을 시행한다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;5-layer : FC layer
5x5 filter 120개를 사용해 1x1 feature map 120개를 만든다
파라미터의 수는 $5&lt;em&gt;5&lt;/em&gt;1920+1*120$개가 된다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;6-layer : FC layer2
1x1x120 date를 1x1x84개의 data로 만든다.
파라미터 수는 $120x84+1*84$개 이다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;7-layer :&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>About CNN</title>
   <link href="https://reniew.github.io/06/"/>
   <updated>2018-06-27T04:47:35+00:00</updated>
   <id>https://reniew.github.io/06</id>
   <content type="html">&lt;h4 id=&quot;about-cnn&quot;&gt;About CNN&lt;/h4&gt;

&lt;h5 id=&quot;cnn의-역사&quot;&gt;CNN의 역사&lt;/h5&gt;

&lt;p&gt;CNN이 최초로 등장한 것은 1989년 LeCun의 &lt;em&gt;“Backpropagation applied to handwritten zip code recognition”&lt;/em&gt; 에서 처음으로 등장하였다. CNN을 활용해 필기체 인식에서 성과를 확인하였지만, 이를 범용화 하기에는 아직까지는 어려움이 많이있었다. LeCun은 이후 LeNet이라는 Network를 1998년 처음으로 소개하게 되었다.&lt;/p&gt;

&lt;p&gt;이후 2003년 Behnke의 논문 “&lt;em&gt;Hierarchical Neural Networks for Image Interpretation&lt;/em&gt;” 과 simard의 논문 “&lt;em&gt;Best Practices for Convolutional Neural Networks Applied to Visual Document Analysis&lt;/em&gt;” 을 통해 일반화과 되었다고 볼 수 있다.&lt;/p&gt;

&lt;p&gt;Image에서 CNN을 도입한데에는 기존의 Fully-Connected Neural Network들이 Image에 적용할 경우 똑같은 Object를 나타내더라도 조금만 변형(ex. 기울어짐, 비틀림 등)이 일어나도 다른 Object로 인식을 할 수 있다는 단점이 존재했기 떄문이다.(&lt;em&gt;Image의 Topology 변화에 대응이 어렵다&lt;/em&gt;)&lt;/p&gt;

&lt;h5 id=&quot;about-cnn-1&quot;&gt;About CNN&lt;/h5&gt;

&lt;p&gt;CNN은 기본적으로 Image에 대해 Convolution 연산을 사용하는 layer들이 사용된 Neural Network를 뜻한다.&lt;/p&gt;

&lt;p&gt;CNN의 기본적인 구조는 아래와 같다.
&lt;img src=&quot;https://taewanmerepo.github.io/2018/01/cnn/cnnexam.png&quot; alt=&quot;CNN Architecture&quot; /&gt;&lt;em&gt;CNN의 기본적인 Architecture (출처 : https://taewanmerepo.github.io/2018/01/cnn/cnnexam.png)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Convolution Layer와 Sub-Sampling Layer들이 일정 수 만큼 나온 후 마지막에 Fully-Connected Layer가 나오는 구조이다.&lt;/p&gt;

&lt;h5 id=&quot;cnn의-주요-용어&quot;&gt;CNN의 주요 용어&lt;/h5&gt;

&lt;p&gt;CNN에서 주로 사용되는 사용되는 용어는 아래와 같다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Convolution&lt;/li&gt;
  &lt;li&gt;Channel&lt;/li&gt;
  &lt;li&gt;Filter&lt;/li&gt;
  &lt;li&gt;Kernel&lt;/li&gt;
  &lt;li&gt;Stride&lt;/li&gt;
  &lt;li&gt;Padding&lt;/li&gt;
  &lt;li&gt;Fiture Map&lt;/li&gt;
  &lt;li&gt;Activation Map&lt;/li&gt;
  &lt;li&gt;Polling&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Convolution&lt;/strong&gt;
CNN에서의 합성곱이란 각각의 Pixel에 대해 일정한 값들을 곱한 후 합치는 과정을 의미한다. 아래의 그림과 같이 Convolution 연산이 이뤄진다.
&lt;img src=&quot;http://deeplearning.stanford.edu/wiki/images/6/6c/Convolution_schematic.gif&quot; alt=&quot;Convolution&quot; /&gt;
&lt;em&gt;합성곱 연산 (출처: http://deeplearning.stanford.edu/wiki/index.php/Feature_extraction_using_convolution)&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Channel&lt;/strong&gt;
Image의 층으로 이해할 수 있다. 기본적으로 흑백이 아닌 컬러사진은 각 픽셀에 대해 RGB값이 3개의 Value를 갖는다. 따라서 컬러 사진은 3개의 채널을 가지게 된다.
&lt;img src=&quot;https://taewanmerepo.github.io/2018/01/cnn/channel.jpg&quot; alt=&quot;Channel&quot; /&gt;&lt;em&gt;Channel (출처:https://en.wikipedia.org/wiki/Channel_(digital_image))&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Filter&lt;/strong&gt;
Filter는 Convolution 연산이 이뤄지는 window를 의미한다.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Kernel&lt;/strong&gt;
CNN에서 Kernel은 Filter와 같은 의미로 사용된다.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Stride&lt;/strong&gt;
Convolution Layer에서 기본적으로는 filter가 한칸씩 이동하면 Convolution 연산이 이뤄지지만, Stride 값에 따라 Convolution연산을 한 뒤 n칸만큼 이동한 후 Convolution 연산이 이뤄진다. 그림을 통해 이해하면 쉽다.
&lt;img src=&quot;https://taewanmerepo.github.io/2018/01/cnn/filter.jpg&quot; alt=&quot;Stride&quot; /&gt;&lt;em&gt;(출처:https://taewanmerepo.github.io/2018/01/cnn/filter.jpg)&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Padding&lt;/strong&gt;
Padding이란 Convolution Layer에서 이미지의 가장자리에 일정한 값을 추가로 넣는 것을 의미한다 주로 Zero Padding이 사용된다.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Fiture Map&lt;/strong&gt;
Convolution 결과로 만들어진 Map을 의미한다.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Activation Map&lt;/strong&gt;
Filter Map에 Activation Fuction을 적용한 Map을 의미한다.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Polling&lt;/strong&gt;
Polling 이란 Fiture Map의 크기를 줄이기 위해 주로 사용한다. 일정한 크기의 영역의 값들을 어떠한 특징으로 값을 뽑아 하나의 값으로 줄이는 과정이다
&lt;img src=&quot;https://taewanmerepo.github.io/2018/02/cnn/maxpulling.png&quot; alt=&quot;Polling&quot; /&gt;&lt;em&gt;(출처 : https://taewanmerepo.github.io/2018/02/cnn/maxpulling.png)&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h5 id=&quot;cnn을-활용한-computer-vision-문제들&quot;&gt;CNN을 활용한 Computer Vision 문제들&lt;/h5&gt;

&lt;p&gt;초기에는 필기체 숫자들을 분류하기 위해 CNN을 사용하였지만, 시간이 흐르면서 점점 많은 분야에 CNN이 활용되고 있다.&lt;/p&gt;

&lt;p&gt;CNN이 사용되는 대표적인 Task들을 다음과 같다&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Image Classification&lt;/li&gt;
  &lt;li&gt;Semantic Segmentation&lt;/li&gt;
  &lt;li&gt;Object Detection&lt;/li&gt;
  &lt;li&gt;Object Localization&lt;/li&gt;
  &lt;li&gt;Visual QnA&lt;/li&gt;
  &lt;li&gt;Image Captioning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이러한 Task들을 풀어가는 CNN 모델들에 대해서 다음 포스트에서 하나씩 알아보도록 하겠다.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Tensorflow Tutorial - Image Recognition</title>
   <link href="https://reniew.github.io/05/"/>
   <updated>2018-06-18T04:47:35+00:00</updated>
   <id>https://reniew.github.io/05</id>
   <content type="html">&lt;h3 id=&quot;image-recognition&quot;&gt;Image Recognition&lt;/h3&gt;

&lt;h4 id=&quot;image-recognition-1&quot;&gt;Image Recognition&lt;/h4&gt;
&lt;p&gt;(이 문서는 Tensorflow의 공식 tutorial 가이드를 따라한 것입니다. (&lt;a href=&quot;https://www.tensorflow.org/tutorials/image_recognition&quot;&gt;Tensorflow tutorial&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;사람의 뇌는 어떠한 사진을 보고 사자인지, 표범인지 구별하거나, 사람의 얼굴의 인식하는 것을 매우 쉽게 한다. 그러나 이러한 일들은 컴퓨터에게는 쉽지 않은 일이다.
지난 몇년동안 이러한 분야에서 machine learning 은 많은 성과를 이뤘다. &lt;a href=&quot;https://colah.github.io/posts/2014-07-Conv-Nets-Modular/&quot;&gt;CNN&lt;/a&gt; 모델을 통해 우리는 visual recognition 분야에서 reasonable한 perfomance를 보여줬다.&lt;/p&gt;

&lt;p&gt;많은 연구들은 computer vision분야에서 학문적인 기준점이 되는 &lt;a href=&quot;http://www.image-net.org/&quot;&gt;ImageNet&lt;/a&gt;에 대해 계속해서 발전해나가는 연구들을 선보였다.
이후 많은 연구들이 계속해서 state-of-art한 성과를 보여줬다. : &lt;a href=&quot;https://static.googleusercontent.com/media/research.google.com/en//archive/unsupervised_icml2012.pdf&quot;&gt;QuocNet&lt;/a&gt;, &lt;a href=&quot;https://www.cs.toronto.edu/~fritz/absps/imagenet.pdf&quot;&gt;AlexNet&lt;/a&gt;, &lt;a href=&quot;https://arxiv.org/abs/1409.4842&quot;&gt;Inception (GoogLeNet)&lt;/a&gt;, &lt;a href=&quot;https://arxiv.org/abs/1502.03167&quot;&gt;BN-Inception-v2&lt;/a&gt;
이후에도 계속해서 Google은 많은 논문들을 작성하고 기존의 모델들을 수정해 새롭게 공개했다. 그 중 우리는 가장 최근 모델인 &lt;a href=&quot;https://arxiv.org/abs/1512.00567&quot;&gt;Inception-v3&lt;/a&gt;에 대해서 알아보겠다.&lt;/p&gt;

&lt;p&gt;Inception-v3 모델은 &lt;a href=&quot;http://www.image-net.org/&quot;&gt;ImageNet&lt;/a&gt;(2012년 부터 진행된 같은 데이터를 사용하는 Visual Recognition Challenge), Computer vision분야에서 가장 기본적인 task는 전체 이미지를 &lt;a href=&quot;http://image-net.org/challenges/LSVRC/2014/browse-synsets&quot;&gt;1000개의 class&lt;/a&gt;로 구분하는 문제이다.(ex. “Zebra”, “Dalmation”, “Dishwasher”),
예를 들면 아래의 결과는 AlexNet이 Classify한 결과이다.
&lt;img src=&quot;https://i.imgur.com/GYPYNQQ.png&quot; alt=&quot;IR1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;모델들을 비교하기 위해 각 모델들이 top 5 guesses에 대해 얼마나 예측을 실패 한지를 비교하였다.(top-5 error rate)&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.cs.toronto.edu/~fritz/absps/imagenet.pdf&quot;&gt;AlexNet&lt;/a&gt; : 15.3%&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1409.4842&quot;&gt;Inception (GoogLeNet)&lt;/a&gt; : 6.67%&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1502.03167&quot;&gt;BN-Inception-v2&lt;/a&gt; : 4.9%&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1512.00567&quot;&gt;Inception-v3&lt;/a&gt; : 3.46%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이번 Tutorial에서는 &lt;a href=&quot;https://arxiv.org/abs/1512.00567&quot;&gt;Inception-v3&lt;/a&gt; model을 사용하는 방법에 대해서 배울 것이다. Python 또는 C++ 에서 &lt;a href=&quot;http://image-net.org/challenges/LSVRC/2014/browse-synsets&quot;&gt;1000개의 클래스들&lt;/a&gt;로 분류하는 방법에 대해서 배워 볼 것이다.&lt;/p&gt;

&lt;h5 id=&quot;usage-with-python-api&quot;&gt;Usage with Python API&lt;/h5&gt;

&lt;p&gt;classify_image.py 파일을 &lt;a href=&quot;https://github.com/reniew/tensorflow_tutorials&quot;&gt;이곳&lt;/a&gt;에서 다운받는다.
코드 전문을 보면,&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-Python&quot;&gt;from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import os.path
import re
import sys
import tarfile

import numpy as np
from six.moves import urllib
import tensorflow as tf

FLAGS = None

# pylint: disable=line-too-long
DATA_URL = 'http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz'
# pylint: enable=line-too-long


class NodeLookup(object):
  &quot;&quot;&quot;Converts integer node ID's to human readable labels.&quot;&quot;&quot;

  def __init__(self,
               label_lookup_path=None,
               uid_lookup_path=None):
    if not label_lookup_path:
      label_lookup_path = os.path.join(
          FLAGS.model_dir, 'imagenet_2012_challenge_label_map_proto.pbtxt')
    if not uid_lookup_path:
      uid_lookup_path = os.path.join(
          FLAGS.model_dir, 'imagenet_synset_to_human_label_map.txt')
    self.node_lookup = self.load(label_lookup_path, uid_lookup_path)

  def load(self, label_lookup_path, uid_lookup_path):
    &quot;&quot;&quot;Loads a human readable English name for each softmax node.
    Args:
      label_lookup_path: string UID to integer node ID.
      uid_lookup_path: string UID to human-readable string.
    Returns:
      dict from integer node ID to human-readable string.
    &quot;&quot;&quot;
    if not tf.gfile.Exists(uid_lookup_path):
      tf.logging.fatal('File does not exist %s', uid_lookup_path)
    if not tf.gfile.Exists(label_lookup_path):
      tf.logging.fatal('File does not exist %s', label_lookup_path)

    # Loads mapping from string UID to human-readable string
    proto_as_ascii_lines = tf.gfile.GFile(uid_lookup_path).readlines()
    uid_to_human = {}
    p = re.compile(r'[n\d]*[ \S,]*')
    for line in proto_as_ascii_lines:
      parsed_items = p.findall(line)
      uid = parsed_items[0]
      human_string = parsed_items[2]
      uid_to_human[uid] = human_string

    # Loads mapping from string UID to integer node ID.
    node_id_to_uid = {}
    proto_as_ascii = tf.gfile.GFile(label_lookup_path).readlines()
    for line in proto_as_ascii:
      if line.startswith('  target_class:'):
        target_class = int(line.split(': ')[1])
      if line.startswith('  target_class_string:'):
        target_class_string = line.split(': ')[1]
        node_id_to_uid[target_class] = target_class_string[1:-2]

    # Loads the final mapping of integer node ID to human-readable string
    node_id_to_name = {}
    for key, val in node_id_to_uid.items():
      if val not in uid_to_human:
        tf.logging.fatal('Failed to locate: %s', val)
      name = uid_to_human[val]
      node_id_to_name[key] = name

    return node_id_to_name

  def id_to_string(self, node_id):
    if node_id not in self.node_lookup:
      return ''
    return self.node_lookup[node_id]


def create_graph():
  &quot;&quot;&quot;Creates a graph from saved GraphDef file and returns a saver.&quot;&quot;&quot;
  # Creates graph from saved graph_def.pb.
  with tf.gfile.FastGFile(os.path.join(
      FLAGS.model_dir, 'classify_image_graph_def.pb'), 'rb') as f:
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(f.read())
    _ = tf.import_graph_def(graph_def, name='')


def run_inference_on_image(image):
  &quot;&quot;&quot;Runs inference on an image.
  Args:
    image: Image file name.
  Returns:
    Nothing
  &quot;&quot;&quot;
  if not tf.gfile.Exists(image):
    tf.logging.fatal('File does not exist %s', image)
  image_data = tf.gfile.FastGFile(image, 'rb').read()

  # Creates graph from saved GraphDef.
  create_graph()

  with tf.Session() as sess:
    # Some useful tensors:
    # 'softmax:0': A tensor containing the normalized prediction across
    #   1000 labels.
    # 'pool_3:0': A tensor containing the next-to-last layer containing 2048
    #   float description of the image.
    # 'DecodeJpeg/contents:0': A tensor containing a string providing JPEG
    #   encoding of the image.
    # Runs the softmax tensor by feeding the image_data as input to the graph.
    softmax_tensor = sess.graph.get_tensor_by_name('softmax:0')
    predictions = sess.run(softmax_tensor,
                           {'DecodeJpeg/contents:0': image_data})
    predictions = np.squeeze(predictions)

    # Creates node ID --&amp;gt; English string lookup.
    node_lookup = NodeLookup()

    top_k = predictions.argsort()[-FLAGS.num_top_predictions:][::-1]
    for node_id in top_k:
      human_string = node_lookup.id_to_string(node_id)
      score = predictions[node_id]
      print('%s (score = %.5f)' % (human_string, score))


def maybe_download_and_extract():
  &quot;&quot;&quot;Download and extract model tar file.&quot;&quot;&quot;
  dest_directory = FLAGS.model_dir
  if not os.path.exists(dest_directory):
    os.makedirs(dest_directory)
  filename = DATA_URL.split('/')[-1]
  filepath = os.path.join(dest_directory, filename)
  if not os.path.exists(filepath):
    def _progress(count, block_size, total_size):
      sys.stdout.write('\r&amp;gt;&amp;gt; Downloading %s %.1f%%' % (
          filename, float(count * block_size) / float(total_size) * 100.0))
      sys.stdout.flush()
    filepath, _ = urllib.request.urlretrieve(DATA_URL, filepath, _progress)
    print()
    statinfo = os.stat(filepath)
    print('Successfully downloaded', filename, statinfo.st_size, 'bytes.')
  tarfile.open(filepath, 'r:gz').extractall(dest_directory)


def main(_):
  maybe_download_and_extract()
  image = (FLAGS.image_file if FLAGS.image_file else
           os.path.join(FLAGS.model_dir, 'cropped_panda.jpg'))
  run_inference_on_image(image)


if __name__ == '__main__':
  parser = argparse.ArgumentParser()
  # classify_image_graph_def.pb:
  #   Binary representation of the GraphDef protocol buffer.
  # imagenet_synset_to_human_label_map.txt:
  #   Map from synset ID to a human readable string.
  # imagenet_2012_challenge_label_map_proto.pbtxt:
  #   Text representation of a protocol buffer mapping a label to synset ID.
  parser.add_argument(
      '--model_dir',
      type=str,
      default='/tmp/imagenet',
      help=&quot;&quot;&quot;\
      Path to classify_image_graph_def.pb,
      imagenet_synset_to_human_label_map.txt, and
      imagenet_2012_challenge_label_map_proto.pbtxt.\
      &quot;&quot;&quot;
  )
  parser.add_argument(
      '--image_file',
      type=str,
      default='',
      help='Absolute path to image file.'
  )
  parser.add_argument(
      '--num_top_predictions',
      type=int,
      default=5,
      help='Display this many predictions.'
  )
  FLAGS, unparsed = parser.parse_known_args()
  tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 
 <entry>
   <title>Tensorflow Tutorial - Image Retraining</title>
   <link href="https://reniew.github.io/04/"/>
   <updated>2018-06-18T04:45:35+00:00</updated>
   <id>https://reniew.github.io/04</id>
   <content type="html">&lt;h3 id=&quot;image-retraining&quot;&gt;Image Retraining&lt;/h3&gt;

&lt;h4 id=&quot;how-to-retrain-an-image-classifier-for-new-categories&quot;&gt;How to Retrain an Image Classifier for New Categories&lt;/h4&gt;
&lt;p&gt;(이 문서는 Tensorflow의 공식 tutorial 가이드를 따라한 것입니다. (&lt;a href=&quot;https://www.tensorflow.org/tutorials/image_retraining&quot;&gt;Tensorflow tutorial&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;현대의 image recognition model들은 수백만개의 파라미터들을 가지고 있다. 막대한 양의 파라미터들을 처음부터 그냥 학습시키는것은 엄청난 양의 computer power를 필요로 한다. &lt;em&gt;Transer Learning&lt;/em&gt; 은 우리의 task와 연관된 pre-trained 모델들을 사용함으로써 계산량을 줄이는 손쉬운 방법이다.
이번 튜토리얼에서는 ImageNet으로 학습된 강력한 Image Classifier를 통해 feature extraction을 재사용한 후 상단의 classification layer를 학습해보도록 할 것이다. 더 많은 정보는 &lt;a href=&quot;https://arxiv.org/abs/1310.1531&quot;&gt;DeCAF : A Deep Convolutional Activation Feature for Generic Visual Recognition&lt;/a&gt;을 통해 보면 된다.&lt;/p&gt;

&lt;p&gt;전체 모델을 새롭게 학습하는 것보다는 좋지는 않지만, 이러한 방법은 놀랍게도 많은 Applications, Works(적당한 양의, 수천개의 Trainning data)에서 효과적이고, 이것은 GPU없이 노트북에서도 삼십분정도면 실행시킬 수 있다.
이번 tutorial에서 각자 자신의 image를 가지고 예제를 실행하는 방법에 대해서 알아볼 것이며, 학습과정을 제어할 수 있는 몇 가지 옵션에 대해서 알아볼 것이다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;NOTE 이번 튜토리얼은 &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/tensorflow-for-poets/#0&quot;&gt;Codelab&lt;/a&gt;에서도 실행 가능하다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;이번 tutorial에서 흔히 &lt;em&gt;Module&lt;/em&gt; 이라 불리는 사전 학습된 모델들을 사용할 것이다. 처음으로 우리는 &lt;a href=&quot;https://www.tensorflow.org/modules/google/imagenet/inception_v3/feature_vector/1&quot;&gt;Image feature extraction module&lt;/a&gt; 모델을 사용한다. 이 모델을 inception V3 아키텍쳐를 가지며, ImageNet을 사전 학습했다. 그 후에는 더 많은 옵션(&lt;a href=&quot;https://research.googleblog.com/2017/11/automl-for-large-scale-image.html&quot;&gt;NASNet&lt;/a&gt;/PNASNet, &lt;a href=&quot;https://research.googleblog.com/2017/06/mobilenets-open-source-models-for.html&quot;&gt;Mobile NET V1&lt;/a&gt;, V2)들을 학습할 것이다.&lt;/p&gt;

&lt;p&gt;시작하기 전에, &lt;em&gt;tensorflow-hub&lt;/em&gt; PIP package를 설치해야 한다. 설치에 대한 자세한 사항은 &lt;a href=&quot;https://www.tensorflow.org/hub/installation&quot;&gt;Installation instructions&lt;/a&gt;참고&lt;/p&gt;

&lt;h5 id=&quot;trainning-on-flowers&quot;&gt;Trainning On Flowers&lt;/h5&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/SFFNC0k.jpg&quot; alt=&quot;daisies&quot; /&gt;&lt;a href=&quot;https://www.flickr.com/photos/95072945@N05/9922116524/&quot;&gt;&lt;em&gt;Image by Kelly Sikkema&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;학습을 시작하기 전 우리는 우리가 인식하고 싶어하는 새로운 클래스의 사진들이 필요할 것이다. 이후에 각자 자신들의 사진으로 학습하는 방법을 배워보고, 그전에 먼저 CC LICENSE인 Flower 사진들을 가지고 학습을 해보도록 하겠다. 사진을 가져오기 위해 아래 명령어를 실행하자.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd ~
curl -LO http://download.tensorflow.org/example_images/flower_photos.tgz
tar xzf flower_photos.tgz
// 윈도우의 경우에는 직접 압축을 풀자
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;사진을 받았다면, 우리가 필요한 code를 github에서 clone 하자.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir ~/example_code
cd ~/example_code
curl -LO https://github.com/tensorflow/hub/raw/r0.1/examples/image_retraining/retrain.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이후 retrainner 파일을 실행하자, 컴퓨터마다 다르겟지만 30분정도 소요된다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;python retrain.py --image_dir ~/flower_photos
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;뿐만 아니라 수많은 옵션들을 확인해보자,&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;python retrain.py -h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위의 retrain.py 파일은 방금 다운받은 Flower사진들로 network을 재학습시킬 것이다. 참고로 위의 Flower 사진들은 pre-trained시킨 data인 ImageNet에는 전혀 들어가 있지 않은 사진들이다.&lt;/p&gt;

&lt;h5 id=&quot;bottlenecks&quot;&gt;Bottlenecks&lt;/h5&gt;

&lt;p&gt;위의 프로그램을 실행하면, 가장 먼저 사진들에 대해 분석하고, 계산해서 저장하는 값들은 bottleneck값이 된다. ‘Bottleneck’이란 실제 분류가 진행되는 마지막 층(Final output layer) 이전의 layer를 지칭하는 비공식적인 용어이다.(&lt;em&gt;Tensorflow Hub은 이를 “image feature vector”라 부른다&lt;/em&gt;) 위의 뒤에서 두번째 레이어는 인식하려하는 클래스들을 충분히 잘 구별할 수 있게 output값을 내놓도록 학습된다. 즉, 매운 작은 값들을 선택해 잘 분류 하기 위한 충분한 정보들을 가지기 때문에, 이 layer들은 이미지의 의미있는 압축된 요약본이라 할 수 있다. 마지막 레이어를 재학습시키는 것이 잘 작동하는 이유는 1000개의 클래스가 있는 ImageNet을 학습시킨 것이 다른 새로운 종류의 개체를 구별하는데도 유용하기 때문이다.&lt;/p&gt;

&lt;p&gt;모든 이미지들은 각각의 Bottleneck을 학습하고 계산하는데 많은 양의 시간을 소모하기 떄문에, 이 속도는 이러한 bottleneck값을 cache화 시켜서 다시 계산될 필요가 없도록 하는 것에 달려있다. &lt;em&gt;/tmp/bottleneck&lt;/em&gt; 에 저장된 default값에 의해 만약 다시 프로그램을 돌린다면, 그들은 저장된 값을 사용함으로써 Bottleneck Part를 기다릴 필요가 없다.&lt;/p&gt;

&lt;h5 id=&quot;training&quot;&gt;Training&lt;/h5&gt;

&lt;p&gt;일단 Bottleneck이 완료되면, 네트워크 상단 layer의 실제 학습은 진행된다. 여러 스탭의 결과들을 볼 수 있는데, 각각 ‘training accuracy’, ‘validation accuracy’, ‘cross entropy’를 출력한다. 각각의 값을 살펴보면.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Training accuracy : 현재 trainning batch 중 제대로 예측한 data의 비율이다.&lt;/li&gt;
  &lt;li&gt;validation accuracy : 각각 다른 set으로 부터 무작위로 선택된 이미지의 그룹들의 정확도이다.
    &lt;ul&gt;
      &lt;li&gt;training accuracy를 핵심 지표로 활용할 경우 noise까지도 학습하게 되서 Overfit될 가능성이 있다. 따라서 실제 성능의 척도는 training data에 포함되지 않은 data들에 대한 성능을 확인해야 한다(= validation accuracy).&lt;/li&gt;
      &lt;li&gt;Traindata에 대한 accuracy는 높은 반면, Validation accuracy는 낮게 나온다면, Overfitting 됬다는 뜻이며, 이는 좋지 않는 결과이다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Cross Entropy : loss function으로 학습의 진척도를 보여준다.&lt;/li&gt;
  &lt;li&gt;우리 학습의 목표는 cross entropy를 가능한 가장 작게 만드는 것이다.
여기에서 우리는 4,000Step(Default)을 학습한다. 각각의 스텝에서 trainning set에서 10개의 무작위 image가 선택한 후 Cache로 부터 각각의 bottleneck을 찾은 후 예측을 위해 마지막 레이어에 통과시킨다. 이러한 예측과 실제 label을 비교해 마지막 레이어의 weight들을 back-propagation 과정을 통해 update시킨다. process가 진행될 수록 우리는 accuracy가 올라가는 것을 확인할 수 있다. 모든 학습이 끝난 후 test를 위해 따로 구분해놓은 set을 예측함으로써 final test accuracy가 나온다. 이 수치는 모델이 얼마나 잘 학습했는지를 알려주는 가장 좋은 지표이다. 우리는 90~95%정도의 수치를 보는데 각각 다른이유는 각각 스탭마다 무작위로 사진을 뽑기 떄문이다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;visualizing-the-retraining-with-tensorboard&quot;&gt;Visualizing the retraining with TensorBoard&lt;/h5&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;retrain.py&lt;/code&gt; 파일은 tensorboard를 포함한다. tensorboard란 weights, accuracy등의 통계수치, 그래프들을 시각적으로 보여줘서 이해, debug, 최적화에 용이하게 한다.&lt;/p&gt;

&lt;p&gt;tensorboard를 실행하기 위해 아래의 명령어를 입력하자&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;tensorboard --logdir /tmp/retrain_logs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Tensorboard가 실행되면,web browser에서 &lt;a href=&quot;http://localhost:6006&quot;&gt;localhost:6006&lt;/a&gt;에 접속하면 된다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;retrain.py&lt;/code&gt;은 기본적으로 log를 /tmp/retrain_logs에 저장한다. 저장경로는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--summaries_dir&lt;/code&gt; flag로 바꿀 수 있다.
&lt;a href=&quot;https://github.com/tensorflow/tensorboard&quot;&gt;TensorBoard’s Github Repository&lt;/a&gt;에서 TensorBoard에 대한 더욱 많은 설명과 tip들을 확인할 수 있다.&lt;/p&gt;

&lt;h5 id=&quot;using-retrained-model&quot;&gt;Using Retrained Model&lt;/h5&gt;
</content>
 </entry>
 
 <entry>
   <title>Tensorflow Tutorial - MNIST</title>
   <link href="https://reniew.github.io/03/"/>
   <updated>2018-05-26T04:45:35+00:00</updated>
   <id>https://reniew.github.io/03</id>
   <content type="html">&lt;h3 id=&quot;mnist&quot;&gt;MNIST&lt;/h3&gt;

&lt;h4 id=&quot;tensorflow-layers-가이드--convoltional-neural-network-만들기&quot;&gt;TensorFlow Layers 가이드 : Convoltional Neural Network 만들기&lt;/h4&gt;
&lt;p&gt;(이 문서는 Tensorflow의 공식 tutorial 가이드를 따라한 것입니다. (&lt;a href=&quot;https://www.tensorflow.org/tutorials/layers#training_and_evaluating_the_cnn_mnist_classifier&quot;&gt;Tensorflow tutorial&lt;/a&gt;))&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;목차&lt;/strong&gt;&lt;/p&gt;

&lt;!-- @import &quot;[TOC]&quot; {cmd=&quot;toc&quot; depthFrom=1 depthTo=6 orderedList=false} --&gt;
&lt;!-- code_chunk_output --&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#mnist&quot;&gt;MNIST&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#tensorflow-layers-가이드-convoltional-neural-network-만들기&quot;&gt;TensorFlow Layers 가이드 : Convoltional Neural Network 만들기&lt;/a&gt;
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;#시작하기&quot;&gt;시작하기&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#cnn-소개&quot;&gt;CNN 소개&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#cnn-mnist-분류기-만들기&quot;&gt;CNN MNIST 분류기 만들기&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;!-- /code_chunk_output --&gt;

&lt;p&gt;[toc]&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;TF는 쉽게 Neural network을 블록쌓듯 만들 수 있게 high-level의 API로써 Tensorflow LayerModule을 제공한다.(&lt;a href=&quot;https://www.tensorflow.org/api_docs/python/tf/layers&quot;&gt;Module 참고&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;이번 Tutorial에서는 손글씨 MNIST데이터를 학습하기 위한 CNN모델을 만들기 위해 Layer를 만들 것이다.&lt;/li&gt;
  &lt;li&gt;&lt;img src=&quot;https://i.imgur.com/klzPlWu.png&quot; alt=&quot;mnist&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;MNIST 데이터는 위와 같은 28x28-pixel의 0~9까지의 숫자 데이터로 이루어져있으며, trainning data 는 6만개, test data는 만개로 이루어져 있다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;시작하기&quot;&gt;시작하기&lt;/h5&gt;

&lt;p&gt;아래와 같은 code로 이루어진 cnn_mnist.py파일을 만든다.&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;__future__&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;absolute_import&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;__future__&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;division&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;__future__&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;print_function&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Imports
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;numpy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;tensorflow&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;## Tensorflow는 5가지 ligging type을 제공한다.( DEBUG, INFO, WARN, ERROR, FATAL )
## default값은 WARN
## 우리는 이를 INFO로 바꿔준다.
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_verbosity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;INFO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Logic들은 이곳에 추가된다.
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;최종 코드는 다음에서 확인 가능하다. (&lt;a href=&quot;https://github.com/tensorflow/tensorflow/blob/r1.8/tensorflow/examples/tutorials/layers/cnn_mnist.py&quot;&gt;Final Code&lt;/a&gt;)&lt;/p&gt;

&lt;h5 id=&quot;cnn-소개&quot;&gt;CNN 소개&lt;/h5&gt;
&lt;p&gt;CNN은 연속된 필터를 raw pixel 이미지 데이터에 적용한다. 이를 통해 high-level의 특징을 뽑아내고 학습한다. CNN은 세가지 구성요소로 이루어진다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Convolution Layers&lt;/strong&gt; 는 특정한 수의 필터를 이미지에 적용시킨다. 각각의 subregion에 합성곱(Convolution)됨으로써 single value를 만든다. 그 이후 일반적으로 ReLU 활성화 함수를 통과시켜 비선형(non-linear)한 output을 만든다.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Pooling Layers&lt;/strong&gt; 는 &lt;a href=&quot;https://en.wikipedia.org/wiki/Convolutional_neural_network#Pooling_layer&quot;&gt;Image data를 downsampling&lt;/a&gt;하는 과정이다. Feature map의 차원을 감소시킴으로써 수행시간을 감소시킨다. 일반적으로 Max-pooling을 사용한다.(최고값만을 남기고 나머지는 버린다.)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Dense (fully connected) layers&lt;/strong&gt; 는 분류를 수행하는 Layer이다. 여기서는 모든 layer들이 이전 모든 노드들과 연결되어있다.
일반적으로 CNN은 위의 요소들을 블록처럼 쌓으면서 만들어지는 model이다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;cnn-mnist-분류기-만들기&quot;&gt;CNN MNIST 분류기 만들기&lt;/h5&gt;
&lt;p&gt;다음과 같은 arichitecture를 가지는 모델을 만들어 MNIST 데이터를 분류할 것이다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Convolutional Layer #1&lt;/strong&gt; :32개의 5x5 filter로 구성, ReLU 함수 사용&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Pooling Layer #1&lt;/strong&gt; : 2x2 Filter로 2stride를 적용해  max pooling사용&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Convolutional Layer #2&lt;/strong&gt;: 64개의 5x5 filter로 구성, ReLU 함수 사용&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Pooling Layer #2&lt;/strong&gt;: 2와 같은 구조&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Dense Layer #1&lt;/strong&gt;: 1,024개의 뉴련, 0.4의 dropout 사용&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href=&quot;https://www.tensorflow.org/api_docs/python/tf/layers&quot;&gt;Tf.layer&lt;/a&gt; 모듈은 아래의 3가지 type의 layer를 만들 수 있다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;conv2d()&lt;/strong&gt;. Constructs a two-dimensional convolutional layer. Takes number of filters, filter kernel size, padding, and activation function as arguments.&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;max_pooling2d()&lt;/strong&gt; . Constructs a two-dimensional pooling layer using the * max-pooling algorithm. Takes pooling filter size and stride as arguments.&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;dense()&lt;/strong&gt;. Constructs a dense layer. Takes number of neurons and activation function as arguments.&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;이전의 cnn_mnist.py를 열어 다음과 같이 cnn_model_fn 함수를 만든다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;cnn_model_fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;Model function for CNN.&quot;&quot;&quot;&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Input Layer 28x28 input size
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;input_layer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reshape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Convolutional Layer #1 (32개의 5x5 필터, padding = &quot;same&quot;은 입력과 출력 크기가 같도록 유지시킨다. 활성화함수는 ReLU)
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;conv1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conv2d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_layer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;filters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;kernel_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;same&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;activation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;relu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Pooling Layer #1 (2x2, stride2로 Max-pooling사용)
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;pool1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_pooling2d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conv1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pool_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strides&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Convolutional Layer #2 and Pooling Layer #2(64개의 5x5필터)
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;conv2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conv2d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pool1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;filters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;kernel_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;same&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;activation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;relu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;pool2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_pooling2d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pool_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strides&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Dense Layer (3136x1로 reshape 한뒤 1024x1로 만든후 dropout실행 )
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;pool2_flat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reshape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pool2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;dense&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dense&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pool2_flat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;units&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;activation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;relu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;dropout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dropout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dense&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;training&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;estimator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ModeKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TRAIN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Logits Layer
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dense&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dropout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;units&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;predictions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# Generate predictions (for PREDICT and EVAL mode)
&lt;/span&gt;      &lt;span class=&quot;s&quot;&gt;&quot;classes&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argmax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;axis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# Add `softmax_tensor` to the graph. It is used for PREDICT and by the
&lt;/span&gt;      &lt;span class=&quot;c1&quot;&gt;# `logging_hook`.
&lt;/span&gt;      &lt;span class=&quot;s&quot;&gt;&quot;probabilities&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;softmax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;softmax_tensor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;estimator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ModeKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PREDICT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;estimator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EstimatorSpec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;predictions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predictions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Calculate Loss (for both TRAIN and EVAL modes)
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;losses&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sparse_softmax_cross_entropy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Configure the Training Op (for TRAIN mode)
&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;estimator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ModeKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TRAIN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GradientDescentOptimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;learning_rate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.001&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;train_op&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;optimizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;minimize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;global_step&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_global_step&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;estimator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EstimatorSpec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_op&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_op&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Add evaluation metrics (for EVAL mode)
&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;eval_metric_ops&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;&quot;accuracy&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;metrics&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accuracy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;predictions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predictions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;classes&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;estimator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EstimatorSpec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eval_metric_ops&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eval_metric_ops&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제부터 함수 하나씩 살펴보자&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;tf.layer.conv2d&lt;/strong&gt;
    &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;conv1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conv2d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_layer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;filters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;kernel_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;same&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;activation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;relu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;em&gt;Convolutional Layer #1&lt;/em&gt; &amp;amp; &lt;em&gt;Convolutional Layer #2&lt;/em&gt;&lt;/li&gt;
      &lt;li&gt;모든예시는 첫번째 conv인 Convolutional Layer #1을 예로 한다.&lt;/li&gt;
      &lt;li&gt;&lt;em&gt;input&lt;/em&gt;은 다음과 같은 shape을 가져야 한다.
        &lt;ul&gt;
          &lt;li&gt;&lt;em&gt;[batch_size, image_height, image_width, channels]&lt;/em&gt;&lt;/li&gt;
          &lt;li&gt;여기서는 [batch_size, 28, 28, 1]이 된다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;filter는 필터의 수를 뜻한다.&lt;/li&gt;
      &lt;li&gt;&lt;em&gt;kernel_size&lt;/em&gt; 는 filter의 크기를 뜻한다.
        &lt;ul&gt;
          &lt;li&gt;&lt;em&gt;[height, width]&lt;/em&gt; (여기서는, [5, 5]).&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;em&gt;padding&lt;/em&gt; 은 &lt;em&gt;valid&lt;/em&gt; 값(default) 혹은 &lt;em&gt;same&lt;/em&gt; 값으로 설정한다.
        &lt;ul&gt;
          &lt;li&gt;&lt;em&gt;valid&lt;/em&gt; 는 패딩 없음&lt;/li&gt;
          &lt;li&gt;&lt;em&gt;same&lt;/em&gt; 은 0패딩을 포함시켜, 출력 크기가 입력 크기 와 동일 하게 한다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;em&gt;activation&lt;/em&gt; 은 활성화 함수를 선택한다. 여기서는 ReLU함수를 사용하므로 &lt;em&gt;tf.nn.relu&lt;/em&gt; 로 하였다.&lt;/li&gt;
      &lt;li&gt;따라서 conv2d의 아웃풋인 conv1의 shape은 &lt;em&gt;[batch_size, 28, 28, 32]&lt;/em&gt; 을 가진다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;tf.layer.max_pooling2d&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;em&gt;Pooling Layer #1&lt;/em&gt; &amp;amp; &lt;em&gt;Pooling Layer #2&lt;/em&gt;&lt;/li&gt;
      &lt;li&gt;모든 예시는 첫번째 pool인 Pooling Layer #1으로 한다.&lt;/li&gt;
      &lt;li&gt;Pooling 필터를 2x2 로 하고 stride를 2로하여서 겹치는 부분없이 최대값을 뽑아내는 max pooling을 사용하였다.&lt;/li&gt;
      &lt;li&gt;풀링을 함으로써 height과 width의 size가 절반으로 줄었다.( &lt;em&gt;[batch_size, 14, 14, 32]&lt;/em&gt; )&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Dense Layer&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;Fully Connected Layer를 만들기 위한 과정이다.&lt;/li&gt;
      &lt;li&gt;먼저 우리는 feature map(pool2)을 tf.reshape 함수로 평평하게 만들어 준다.
        &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;pool2_flat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reshape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pool2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;reshpae()함수에서 -1은 batch_size에 맞게 설정되도록 한다. 따라서 reshape을 하고 나면 shape가 &lt;em&gt;[batch_size, 3136]&lt;/em&gt; 가 된다.
        &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;dropout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dropout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dense&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;training&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;estimator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ModeKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TRAIN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;평평하게 만든 뒤 tf.layers.dense 함수를 사용해 dense layer와 연결한다.
        &lt;ul&gt;
          &lt;li&gt;input값은 평평하게 만든 feature map 값(pool2_flat)이다&lt;/li&gt;
          &lt;li&gt;units 값은 dense layer의 뉴런의 수이다. (1024)&lt;/li&gt;
          &lt;li&gt;활성화 함수는 ReLU 사용&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;dense layer와 연결한 뒤 Dropout 사용 (0.4)
        &lt;ul&gt;
          &lt;li&gt;tf.layers.dropout함수 에서 training 인자는 현재 학습 상태인지 예측하는 상태인지를 Bool 값으로 받는다. 학습상태에서만 dropout 실행&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Output 값은 &lt;em&gt;[batch_size, 1024]&lt;/em&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Logits Layer&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;마지막으로 1024개의 뉴런을 10개의 뉴런(0~9 예측 위해) 으로 만드는 Logit layer 만든다.
        &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;layers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dense&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dropout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;units&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;Linear activation 사용(default)&lt;/li&gt;
      &lt;li&gt;최종 output은 &lt;em&gt;[batch_size, 10]&lt;/em&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Generate Predictions&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;“Class” 와 “probabilities”값 리턴
        &lt;ul&gt;
          &lt;li&gt;Class 는 argmax값 통해 가장 값이 큰 것의 index 리턴&lt;/li&gt;
          &lt;li&gt;Probabilities는 softmax값 리턴(tf.nn.softmax 함수 사용)&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;mode 가 예측일 때만 리턴&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;predictions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;classes&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argmax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;axis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;probabilities&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;softmax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;softmax_tensor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;estimator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ModeKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PREDICT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;estimator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EstimatorSpec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;predictions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predictions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Calculate Loss&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;MNIST 분류 문제는 multi-classication 문제이므로 일반적으로 cross entropy 사용&lt;/li&gt;
      &lt;li&gt;아래의 코드는 trainning과 evaluation 모두에서 사용된다.
        &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;onehot_labels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;one_hot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;indices&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cast&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;depth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;losses&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;softmax_cross_entropy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;onehot_labels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;onehot_labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;em&gt;label&lt;/em&gt; one-hot 인코딩 방식이므로 tf.one_hot 함수 사용
        &lt;ul&gt;
          &lt;li&gt;one-hot 함수의 &lt;em&gt;indices&lt;/em&gt; 인자는 1로 표시할 index&lt;/li&gt;
          &lt;li&gt;depth는 벡터의 크기로 class수가 된다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Configure trainning Op&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;학습하는 동안 Loss를 갱신시킬 방법을 선택한다.&lt;/li&gt;
      &lt;li&gt;이번 예제에서는 SGD(Stochastic Gradient Descent)를 사용한다.(learning_rate = 0.001)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code class=&quot;language-Python&quot;&gt;if mode == tf.estimator.ModeKeys.TRAIN:
  optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
  train_op = optimizer.minimize(
      loss=loss,
      global_step=tf.train.get_global_step())
  return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)
&lt;/code&gt;&lt;/pre&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Add Evaluation Matrics&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;accuracy를 추가한 Estimator를 만든다.
        &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;eval_metric_ops&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;s&quot;&gt;&quot;accuracy&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;metrics&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accuracy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;predictions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predictions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;classes&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;estimator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EstimatorSpec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eval_metric_ops&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eval_metric_ops&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h5 id=&quot;실제로-mnist-분류기를-학습시키고-평가하기&quot;&gt;실제로 MNIST 분류기를 학습시키고 평가하기&lt;/h5&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Trainning data와 Test data를 불러온다.&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;main()함수를 만들어서 data를 불러온다.
        &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unused_argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Load training and eval data
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mnist&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contrib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;learn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datasets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load_dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;mnist&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;train_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mnist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;images&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Returns np.array
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;asarray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mnist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;eval_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mnist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;images&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Returns np.array
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eval_labels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;asarray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mnist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;data들은 numpy배열로 이루어져 있다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Create Estimator&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;main()함수에 estimator를 추가한다.
        &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;mnist_classifier&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;estimator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Estimator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;model_fn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cnn_model_fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model_dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/tmp/mnist_convnet_model&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;model_fn 인자로는 우리가 위에서 만들었던 함수를 넣는다.&lt;/li&gt;
      &lt;li&gt;model_dir은 model이 저장될 위치를 지정한다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Set up Logging Hook&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
  &lt;li&gt;logging할 방법을 정한다.
    &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;tensors_to_log&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;probabilities&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;softmax_tensor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logging_hook&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LoggingTensorHook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tensors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensors_to_log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;every_n_iter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;여기서 &lt;a href=&quot;https://www.tensorflow.org/api_docs/python/tf/train/SessionRunHook&quot;&gt;tf.train.SessionRunHook&lt;/a&gt;을 사용해 &lt;a href=&quot;https://www.tensorflow.org/api_docs/python/tf/train/SessionRunHook&quot;&gt;tf.train.LoggingTensorHook&lt;/a&gt;만들 수 있다. 이를 통해 softmax값인 확률값을 logging할 수 있다.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;모델 학습하기&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
  &lt;li&gt;main()함수에 다음의 train함수를 추가한다.
    &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Train the model
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_input_fn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;estimator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numpy_input_fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;num_epochs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;shuffle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;mnist_classifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;input_fn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_input_fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;hooks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logging_hook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;모델 평가하기&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
  &lt;li&gt;다음의 함수를 main()에 추가해서 Estimator를 추가한다.
    &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;eval_input_fn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;estimator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numpy_input_fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;x&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eval_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eval_labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;num_epochs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;shuffle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;eval_results&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mnist_classifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_fn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eval_input_fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eval_results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이제 완성된 cnn_mnist.py파일을 실행시킨다.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Run cnn_mnist.py.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;정확도 : 97.3%&lt;/em&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Tensorflow 설치하기</title>
   <link href="https://reniew.github.io/02/"/>
   <updated>2018-05-26T04:45:35+00:00</updated>
   <id>https://reniew.github.io/02</id>
   <content type="html">&lt;h3 id=&quot;tensroflow-설치하기&quot;&gt;Tensroflow 설치하기&lt;/h3&gt;

&lt;p&gt;이때까지 공부할때는 tensorflow를 사용하지 않고 아나콘다 배포판의 라이브러리들로만 했었는데, 미리미리 tensorflow를 손에 익혀 두는 것이 좋을 것같아 tensorflow tutorial를 따라가며 손에 익혀 보기러 한다.&lt;/p&gt;

&lt;!-- @import &quot;[TOC]&quot; {cmd=&quot;toc&quot; depthFrom=1 depthTo=6 orderedList=false} --&gt;
&lt;!-- code_chunk_output --&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#tensroflow-설치하기&quot;&gt;Tensroflow 설치하기&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#1-tensorflow&quot;&gt;1. Tensorflow&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#2-설치하기&quot;&gt;2. 설치하기&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#3-설치-확인하기&quot;&gt;3. 설치 확인하기&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;!-- /code_chunk_output --&gt;

&lt;h4 id=&quot;1-tensorflow&quot;&gt;1. Tensorflow&lt;/h4&gt;

&lt;p&gt;tensorflow의 설치방법에는 여러가지가 있지만(참고:&lt;a href=&quot;https://www.tensorflow.org/install/&quot;&gt;Tensorflow Site&lt;/a&gt;), 여러 방법 중 나는 Ananconda를 통해 다운 받는 방법을 선택했다.&lt;/p&gt;

&lt;p&gt;설치하기 전에 tensorflow는 CPU-only 와 GPU도 사용하는 방법 두가지로 나눠져있다.
Tensorflow site의 설명을 확인하면,&lt;/p&gt;

&lt;blockquote&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;TensorFlow with CPU support only&lt;/strong&gt;. If your system does not have a NVIDIA® GPU, you must install this version. Note that this version of TensorFlow is typically much easier to install (typically, in 5 or 10 minutes), so even if you have an NVIDIA GPU, we recommend installing this version first. Prebuilt binaries will use AVX instructions.&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;TensorFlow with GPU support&lt;/strong&gt;. TensorFlow programs typically run significantly faster on a GPU than on a CPU. Therefore, if your system has a NVIDIA® GPU meeting the prerequisites shown below and you need to run performance-critical applications, you should ultimately install this version.&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;그리고 GPU-version을 사용하기 위해서는 요구사항들이 있다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;CUDA® Toolkit 9.0&lt;/li&gt;
  &lt;li&gt;The NVIDIA drivers associated with CUDA Toolkit 9.0&lt;/li&gt;
  &lt;li&gt;cuDNN v7.0&lt;/li&gt;
  &lt;li&gt;GPU card with CUDA Compute Capability 3.0 or higher for building from source and 3.5 or higher for our binaries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;요구사항에 대한 자세한 내용들을 사이트를 참고하자(&lt;a href=&quot;https://www.tensorflow.org/install/install_windows&quot;&gt;Tensorflow&lt;/a&gt;, &lt;a href=&quot;https://developer.nvidia.com/&quot;&gt;NVIDIA&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;현재 나는 따로 GPU가 없기 떄문에 일반 버전으로 설치하기로 했다.&lt;/p&gt;

&lt;h4 id=&quot;2-설치하기&quot;&gt;2. 설치하기&lt;/h4&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;우선 관리자 권한으로 Anaconda Prompt를 실행시켜 준다.
(Anaconda를 설치하지 않은 사람은 Anaconda를 먼저 설치한다.(&lt;a href=&quot;https://www.anaconda.com/download/&quot;&gt;아나콘다 설치&lt;/a&gt;))&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;이후 pip 버전을 최신버전으로 맞춰준다.
    &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;python&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pip&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upgrade&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pip&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;tensorflow이름으로 conda환경만들기
    &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;conda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensorflow&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pip&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;python&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;3.5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;conda 환경 활성화
    &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;activate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensorflow&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;p&gt;활성화를 하게 되면 prompt가 (tensorflow) 로 바뀌게 된다.&lt;/p&gt;
    &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensorflow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;CPU-only 또는 GPU 두 가지 버전 중 하나를 골라서 설치한다.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
  &lt;li&gt;CPU-only
    &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensorflow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pip&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ignore&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;installed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upgrade&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensorflow&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;GPU version
    &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensorflow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pip&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ignore&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;installed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upgrade&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tensorflow&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gpu&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;여기까지 별 다른 error가 뜨지 않았다면 잘 설치 된 것이다.
그러면 이제 제대로 설치가 되었는지 확인 해 보자.&lt;/p&gt;

&lt;h4 id=&quot;3-설치-확인하기&quot;&gt;3. 설치 확인하기&lt;/h4&gt;

&lt;p&gt;Anaconda를 통해 설치했기 떄문에 anaconda prompt를 통해 실행 해본다&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Anaconda 실행 후 Python 실행
    &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensorflow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;python&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;tensorflow import 후 사용
    &lt;pre&gt;&lt;code class=&quot;language-Python&quot;&gt;&amp;gt;&amp;gt;&amp;gt; import tensorflow as tf
&amp;gt;&amp;gt;&amp;gt; hello = tf.constant('Hello, TensorFlow!')
&amp;gt;&amp;gt;&amp;gt; sess = tf.Session()
&amp;gt;&amp;gt;&amp;gt; print(sess.run(hello))
&lt;/code&gt;&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;만약 잘 설치되었다면, 다음과 같은 문장이 출력 될 것이다.
    &lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TensorFlow&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;다음 부터는 이제 TensorFlow의 공식 Tutorial(&lt;a href=&quot;https://www.tensorflow.org/tutorials/&quot;&gt;TensorFlow Tutorial&lt;/a&gt;) 문서를 보며 하나씩 따라 해보도록 하겠다.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Recent trend in NLP</title>
   <link href="https://reniew.github.io/01/"/>
   <updated>2018-05-09T00:00:00+00:00</updated>
   <id>https://reniew.github.io/01</id>
   <content type="html">&lt;p&gt;Recent Trends in Deep Learning Based Natural Laguage Process (2017)&lt;br /&gt;
- 최신의 딥러닝 기반 자연어처리기법 최근 연구 동향&lt;/p&gt;

&lt;hr /&gt;

&lt;!-- @import &quot;[TOC]&quot; {cmd=&quot;toc&quot; depthFrom=1 depthTo=6 orderedList=false} --&gt;
&lt;!-- code_chunk_output --&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#0-서론&quot;&gt;0. 서론&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#1-distributed-representation분산표상&quot;&gt;1. Distributed representation(분산표상)&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#b-word2vec&quot;&gt;B. Word2Vec&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#c-character-embeddings문자-임베딩&quot;&gt;C. Character Embeddings(문자 임베딩)&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#2-cnn&quot;&gt;2. CNN&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#a-cnn-기본구조&quot;&gt;A. CNN 기본구조&lt;/a&gt;
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;#1-문장-모델링&quot;&gt;1) 문장 모델링&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#2-window-approach&quot;&gt;2) window approach&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#b-cnn-application&quot;&gt;B. CNN Application&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;!-- /code_chunk_output --&gt;

&lt;hr /&gt;

&lt;h4 id=&quot;0-서론&quot;&gt;0. 서론&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;기존의 NLP풀기위한 머신러닝 기법들은 sparse한 feature를 shallow한 model(ex&amp;gt;SVM)이였다.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;최근에는 워드 임베딩과 딥러닝 모델 기법의 성공에 힘입어 dense한 vector representation에 기반한 NN가 trend이다.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;Recurrent neural network based language model&lt;/p&gt;

        &lt;ul&gt;
          &lt;li&gt;http://www.fit.vutbr.cz/research/groups/speech/publi/2010/mikolov_interspeech2010_IS100722.pdf&lt;/li&gt;
          &lt;li&gt;&lt;img src=&quot;https://i.imgur.com/MsjH5yb.png&quot; alt=&quot;figure0&quot; /&gt;&lt;/li&gt;
          &lt;li&gt;Sequential data모델 위해 Recurrent Neural Network 사용(Simple RNN or Elman network 아키텍쳐 사용)&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Distributed Representations of Words and Phrases and their Compositionality
        &lt;ul&gt;
          &lt;li&gt;https://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf&lt;/li&gt;
          &lt;li&gt;Word2Vec&lt;/li&gt;
          &lt;li&gt;2가지 모델 CBOW(Continuous bag of words)와 Skip-gram 제시&lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;CBOW&lt;/p&gt;

            &lt;ul&gt;
              &lt;li&gt;&lt;img src=&quot;https://i.imgur.com/kbjoDe9.png&quot; alt=&quot;figure1&quot; /&gt;&lt;/li&gt;
              &lt;li&gt;CBOW 모델도 마찬가지의 방법을 사용한다. 주어진 단어에 대해 앞 뒤로 C/2개 씩 총 C개의 단어를 Input으로 사용하여, 주어진 단어를 맞추기 위한 네트워크를 만든다.&lt;/li&gt;
              &lt;li&gt;CBOW 모델은 크게 Input Layer, Projection Layer, Output Layer로 이루어져 있다. 그림에는 중간 레이어가 Hidden Layer라고 표시되어 있기는 하지만, Input에서 중간 레이어로 가는 과정이 weight를 곱해주는 것이라기 보다는 단순히 Projection하는 과정에 가까우므로 Projection Layer라는 이름이 더 적절할 것 같다.&lt;/li&gt;
              &lt;li&gt;Input에서는 NNLM 모델과 똑같이 단어를 one-hot encoding으로 넣어주고, 여러 개의 단어를 각각 projection 시킨 후 그 벡터들의 평균을 구해서 Projection Layer에 보낸다.&lt;/li&gt;
              &lt;li&gt;뒤는 여기에 Weight Matrix를 곱해서 Output Layer로 보내고 softmax 계산을 한 후, 이 결과를 진짜 단어의 one-hot encoding과 비교하여 에러를 계산한다.&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;p&gt;Skip-Gram&lt;/p&gt;

            &lt;ul&gt;
              &lt;li&gt;&lt;img src=&quot;https://i.imgur.com/c4sUimp.png&quot; alt=&quot;figure2&quot; /&gt;&lt;/li&gt;
              &lt;li&gt;CBOW와는 반대 방향의 모델이라고 생각할 수 있을 것 같다.&lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Recursive Deep Models for Semantic Compositionality Over a Sentiment Treebank&lt;/p&gt;

        &lt;ul&gt;
          &lt;li&gt;https://nlp.stanford.edu/~socherr/EMNLP2013_RNTN.pdf&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Collobert el al(2011, http://www.jmlr.org/papers/volume12/collobert11a/collobert11a.pdf)은 간단한 딥러닝 프레임워크들에 대해 제시하였다.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Named Entity Recognition, NER(개체명 인식)&lt;/li&gt;
      &lt;li&gt;Semantic Role Labelling, SRL(의미역결정)&lt;/li&gt;
      &lt;li&gt;POS tagging(품사태깅)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;이후 많은 복잡한 딥러닝 기반의 프레임워크들이 제시되었다.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;CNN&lt;/li&gt;
      &lt;li&gt;RNN&lt;/li&gt;
      &lt;li&gt;Recursive NN&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;위의 주요적인 프레임워크들 뿐만 아니라 최근의 여러 모델 또한 제시 되었다.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Attention 메커니즘&lt;/li&gt;
      &lt;li&gt;RL&lt;/li&gt;
      &lt;li&gt;Deep Generative Model&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;이 논문 이전 NLP연구의 딥런닝 기법들의 소개는 Goldberg(2016)을 제외하고 전무했다.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Goldberg 또한 다양한 딥러닝 아키텍쳐에 대해 논의한것은 아니고 튜토리얼 방식으로 NLP를 소개하고 Word2Vec과 CNN같은 distributional semantics에 주로 초점을 맞춘다.&lt;/li&gt;
      &lt;li&gt;http://u.cs.biu.ac.il/~yogo/nnlp.pdf&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;이후 이 논문의 구성은 섹션2에서 Distributed representation(분산표상)에 대해서 소개하고 섹션 3,4,5에서는 CNN,RNN,Recursive NN을 소개한 후 섹션 6에서 NLP에서 사용된 강화학습 응용사례와 비지도학습기법의 발전에 대해서 알아볼 것이며, 섹션 7에서는 딥러닝 모델과 메모리 모듈 결합의 최근 트렌드를 소개한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;1-distributed-representation분산표상&quot;&gt;1. Distributed representation(분산표상)&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Distributed representation연구의 동기&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;통계기반의 자연어 처리 기법은 복잡한 자연어를 모델링하는데 이 기법은 초기에 ‘차원의 저주(curse of dimentionality)’에 어려움을 겪는다&lt;/li&gt;
      &lt;li&gt;Language model은 결합함수를 학습해야 하기 때문이다.&lt;/li&gt;
      &lt;li&gt;따라서 저차원 벡터공간에 존재하는 단어의 분산표상을 연구의 동기가 되었다.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h5 id=&quot;a-word-embedding단어-임베딩&quot;&gt;A. Word Embedding(단어 임베딩)&lt;/h5&gt;
  &lt;/li&gt;
  &lt;li&gt;Distributed vectors와 Word Embedding은 근본적으로 distributional hypothesis를 전제로 한다.&lt;/li&gt;
  &lt;li&gt;Distributional hypothesis라는 이 가정은 비슷한 의미를 지닌 단어는 비슷한 문맥에 등장하는 경향이 있을 것이라는 내용이 핵심이다.&lt;/li&gt;
  &lt;li&gt;따라서 이 벡터들은 이웃한 단어의 특징을 잡아내고자 한다. 따라서 벡터들은 단어간 유사성을 내포한다.&lt;/li&gt;
  &lt;li&gt;유사도는 Cosine 유사도같은 지표를 사용한다.&lt;/li&gt;
  &lt;li&gt;&lt;img src=&quot;https://i.imgur.com/k12GMnL.png&quot; alt=&quot;figure3&quot; /&gt;&lt;em&gt;(Figure 1. D차원 벡터로 표현된 단어 벡터. V를 전체 단어 수라고 할 때, D는 V보다 훨씬 작다.)&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Word Embedding은 Deep learning model의 첫 번째 데이터 처리 계층에서 주로 사용된다.&lt;/li&gt;
  &lt;li&gt;Word Embedding은 단어들의 의미와 구문론적인 의미들을 학습하기위해 보조적인 목적으로 최적화하는 형태로 사전 학습된다. (Mikolov et al., 2013b, a).&lt;/li&gt;
  &lt;li&gt;또한 Embedding Vector의 Dimension이 작은 덕분에 계산이 빠르고 효율적이다.&lt;/li&gt;
  &lt;li&gt;이러한 방법은 전통적인 방법인 Word count 기반의 모델과 딥러닝 기반의 모델과의 가장 큰 차이점이다.&lt;/li&gt;
  &lt;li&gt;Word Embedding은 NLP문제의 광범위한 범위에서 state-of-art한 결과를 이끌어 냈다(&lt;a href=&quot;http://www.thespermwhale.com/jaseweston/papers/wsabie-ijcai.pdf&quot;&gt;Weston et al.2011&lt;/a&gt;, ; &lt;a href=&quot;http://ai.stanford.edu/~ang/papers/icml11-ParsingWithRecursiveNeuralNetworks.pdf&quot;&gt;Socher et al., 2011a&lt;/a&gt;; &lt;a href=&quot;https://www.microsoft.com/en-us/research/wp-content/uploads/2017/07/jair10.pdf&quot;&gt;Turney and Pantel, 2010&lt;/a&gt;).&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.icml-2011.org/papers/342_icmlpaper.pdf&quot;&gt;Glorot et al.(2011)&lt;/a&gt;는 도메인 특성에 맞는 감성 분류를 위한 stacked denoising autoencoder 모델에 word embedding을 사용했다.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.icml-2011.org/papers/342_icmlpaper.pdf&quot;&gt;Hermann and Blunsom(2013)&lt;/a&gt;는 embedding을 활용해 문장 합성을 학습하기 위한 combinatory categorical autoencoders를 제안했다.&lt;/li&gt;
  &lt;li&gt;Embedding은 주로 Context를 통해 학습된다.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;초기의 embedding에 대한 연구&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;1990년대의  Dumais, 2004; &lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.95.866&amp;amp;rep=rep1&amp;amp;type=pdf&quot;&gt;Elman, 1991&lt;/a&gt;; &lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.134.9807&amp;amp;rep=rep1&amp;amp;type=pdf&quot;&gt;Glenberg and Robertson, 2000&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;Latent Dirichlet Allocation, &lt;a href=&quot;https://endymecy.gitbooks.io/spark-ml-source-analysis/content/%E8%81%9A%E7%B1%BB/LDA/docs/Latent%20Dirichlet%20Allocation.pdf&quot;&gt;Blei et al., 2003&lt;/a&gt;, &lt;a href=&quot;https://ratsgo.github.io/from%20frequency%20to%20semantics/2017/06/01/LDA/&quot;&gt;블로그&lt;/a&gt;와 같은 토픽 모델과 언어모델(Language models, &lt;a href=&quot;http://www.jmlr.org/papers/volume3/bengio03a/bengio03a.pdf&quot;&gt;Bengio et al., 2003&lt;/a&gt;)&lt;/li&gt;
      &lt;li&gt;표현학습(representation learning, &lt;a href=&quot;https://ratsgo.github.io/deep%20learning/2017/04/25/representationlearning/&quot;&gt;블로그&lt;/a&gt;)&lt;/li&gt;
      &lt;li&gt;분산표상을 학습하는 신경 언어 모델(&lt;a href=&quot;http://www.jmlr.org/papers/volume3/bengio03a/bengio03a.pdf&quot;&gt;Bengio et al.(2003)&lt;/a&gt;)&lt;/li&gt;
      &lt;li&gt;사전 학습된 단어 임베딩의 유용성(&lt;a href=&quot;https://ronan.collobert.com/pub/matos/2008_nlp_icml.pdf&quot;&gt;Collbert and Weston(2008)&lt;/a&gt;)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;위의 많은 word embedding에 대한 연구가 있었지만, 가장 많은 인기를 끌고 있는 임베딩 기법은 &lt;a href=&quot;https://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf&quot;&gt;Milokov et al.(2013a)&lt;/a&gt;의 CBOW와 skip-gram모델이다.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality.pdf&quot;&gt;Pennington et al.(2014)&lt;/a&gt;은 word2vec과 달리 빈도수 기반의 단어 임베딩 기법이다(참고: &lt;a href=&quot;https://ratsgo.github.io/from%20frequency%20to%20semantics/2017/04/09/glove/&quot;&gt;블로그&lt;/a&gt;)&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;위의 기법은 우선 word co-occurence count matrix를 생성한 뒤 빈도 수를 정규화 하고 log smooting을 한다.&lt;/li&gt;
      &lt;li&gt;저차원 벡터를 얻기 위해 Reconstruction loss를 최소화하는 방식으로 이 행렬을 factorize한다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;b-word2vec&quot;&gt;B. Word2Vec&lt;/h5&gt;

&lt;ul&gt;
  &lt;li&gt;Mikolov et al이 제시한 모델, 첫 논문(Efficient Estimation of Word Representations in Vector Space)과 여러 튜닝 기법이 포함 된 두번 째 논문으로 구성(Distributed Representations of Words and Phrased and their Compositionality)&lt;/li&gt;
  &lt;li&gt;CBOW와 Skip-gram으로 구성&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;CBOW&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;k개만큼 주변 단어가 주어 졌을 때 중심 단어의 조건부 확률을 계산한다.&lt;/li&gt;
      &lt;li&gt;&lt;img src=&quot;https://i.imgur.com/QHGG2y4.png&quot; alt=&quot;figure4&quot; /&gt;
&lt;em&gt;(Figure 2. Word2Vec의 CBOW 모델) -&amp;gt; 1개의 hidden layer 가진 simple fully connected neural network이다.&lt;/em&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Skip-Gram&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;CBOW와 정반대로 중심단어가 주어졌을 때 주변 단어를 예측한다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;개별 단어 임베딩의 한계는 두개 이상의 단어의 조합(ex. hot potato -&amp;gt; hot + potato의 의미와 전혀 다른 의미)이 ㄱ개별 단어 벡터의 조합으로 표현될 수 없다.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;위의 문제의 해결책은 동시등장단어(word coocurrence)에 기반한 구문 식별, 이들 별도로 학습&lt;/li&gt;
      &lt;li&gt;최근의 기법은 레이블이 없는 데이터로 부터 n-gram 임베딩을 직접적으로 학습시키는 방법(&lt;a href=&quot;https://arxiv.org/pdf/1504.01255.pdf&quot;&gt;Johnson and Zhang, 2015&lt;/a&gt;).&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;또다른 한계는 주변 단어의 작은 window 내에만 기반한 임베딩을 학습하는데서 비롯된다. -&amp;gt; Good과 Bad가 같은 임베딩을 공유할 수 있다. -&amp;gt; 감정분석에서 문제될 수 있다.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;이러한 임베딩은 위와 같이 상반된 극성 갖는 단어가 의미상 유사한 단어로 Clustrering된다.&lt;/li&gt;
      &lt;li&gt;이러한 문제 해결을 위해  &lt;a href=&quot;http://ir.hit.edu.cn/~dytang/paper/sswe/14ACL.pdf&quot;&gt;Tang et al. (2014)&lt;/a&gt;는 Sentiment specific word embedding(SSWE)을 제안 -&amp;gt; 임베딩을 학습하는 동안 손실함수에 감정에 대한 양,음 값을 포함시켰다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;단어 임베딩의 주의사항은 임베딩이 사용된 application(space)에 의존한다.&lt;/li&gt;
  &lt;li&gt;따라서  Labutov and Lipson (2013)은 단어 벡터를 재학습해서 현재 task space에 맞추기 위해 task specific embedding을 제안했다.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arxiv.org/pdf/1301.3781.pdf&quot;&gt;Mikolov et al. (2013b)&lt;/a&gt;는 negatice sampling 기법 제안&lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;c-character-embeddings문자-임베딩&quot;&gt;C. Character Embeddings(문자 임베딩)&lt;/h5&gt;

&lt;ul&gt;
  &lt;li&gt;단어 임베딩은 문법적, 의미적 정보를 잡아낼 수 있다. 그러나 품사태깅(POS-tagging)이나 개체명인식(NER) 같은 task 에서는 단어 내부의 형태,정보(문자) 또한 중요하다.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;문자 수준의 NLP시스템 구축도 관심을 끌고 있다. (&lt;a href=&quot;https://arxiv.org/pdf/1508.06615.pdf&quot;&gt;Kim et al. ,2016&lt;/a&gt; ; &lt;a href=&quot;http://anthology.aclweb.org/C/C14/C14-1008.pdf&quot;&gt;Dos Santos and Gatti, 2014&lt;/a&gt;; ‘Santos and Guimaraes, 2015](http://www.anthology.aclweb.org/W/W15/W15-3904.pdf); &lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.646.4491&amp;amp;rep=rep1&amp;amp;type=pdf&quot;&gt;Santos and Zadrozny, 2014&lt;/a&gt;).&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;http://www.anthology.aclweb.org/W/W15/W15-3904.pdf&quot;&gt;Santos and Guimaraes (2015)&lt;/a&gt;는 단어 임베딩과 함께 문자 수준 임베딩을 개체명 인식 문제에 적용해 스페인어에서 state-of-art한 성과 이뤘다.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://arxiv.org/pdf/1508.06615.pdf&quot;&gt;Kim et al. (2016)&lt;/a&gt;은 문자 임베딩만 사용한 enural laguage model을 구축해 긍적적인 결과를 보였다.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://www.cs.cmu.edu/~dyogatam/papers/yogatama+etal.acl2015short.pdf&quot;&gt;Ma et al. (2016)&lt;/a&gt;은 개체명인식에서 pre-trained된 레이블 임베딩을 학습위해 문자 trigram을 포함 몇몇 임베딩 기법 활용했다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;문자 임베딩은 미등재단어(the unknown word) 이슈 대처 가능하다.&lt;/li&gt;
  &lt;li&gt;중국어와 같은 단어의 의미가 문자들의 합성에 대응되는 언어에서는 문자수준의 시스템 구축은 단어분할(word segmentation)을 피하기 위해 자연스러운 선택이다.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://sentic.net/radical-embeddings-for-chinese-sentiment-analysis.pdf&quot;&gt;Peng et al. (2017)&lt;/a&gt;은 radical 기반의 처리가 감성 분류 성능 개선시킴을 입증했다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;2-cnn&quot;&gt;2. CNN&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;문장모델링에서 CNN을 활용하는 것은  &lt;a href=&quot;https://ronan.collobert.com/pub/matos/2008_nlp_icml.pdf&quot;&gt;Colobert and Weston(2008)&lt;/a&gt;에서 시작되었다.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;이 연구는 다범주 예측결과를 출력 위해 multi-task learning을 사용했다.&lt;/li&gt;
      &lt;li&gt;품사태깅, 청킹, 개체명인식, 의미역결정, 의미적으로 유사한 단어 찾기, 랭귀지 모델 같은 NLP 과제 수행 위해 사용&lt;/li&gt;
      &lt;li&gt;Look up table(참조테이블)은 각 단어를 사용자가 정의한 차원 벡터로 변형해 사용&lt;/li&gt;
      &lt;li&gt;따라서 Input  {s1,s2,..,sn}은 참조테이블 활용해 벡터들의 나열로 변형  {ws1,ws2,…,wsn}&lt;/li&gt;
      &lt;li&gt;&lt;img src=&quot;https://i.imgur.com/uAZFnfh.png&quot; alt=&quot;figure5&quot; /&gt;&lt;em&gt;(Figure 3. Colbert and Weston(2008)이 제시한 CNN 프레임 워크. 그들은 단어 범주 예측에 이 모델 사용&lt;/em&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.jmlr.org/papers/volume12/collobert11a/collobert11a.pdf&quot;&gt;Collobert et al. (2011)&lt;/a&gt;은 NLP문제들을 해결 위해 일반적인 CNN기반 프레임워크를 제안했다.&lt;/li&gt;
  &lt;li&gt;위의 논문들은 NLP 연구자들 사이에 CNN이 큰 인기를 끌도록 촉발 시켰다.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;CNN은 문장의 잠재적인 semantic represention을 만들기 위해 입력 문장으로부터 핵심적인 n-gram feature를 추출하는 능력 가진다.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;이 분야의 업적은  &lt;a href=&quot;http://www.jmlr.org/papers/volume12/collobert11a/collobert11a.pdf&quot;&gt;Collobert et al. (2011)&lt;/a&gt;, &lt;a href=&quot;http://www.aclweb.org/anthology/P14-1062&quot;&gt;Kalchbrenner et al. (2014)&lt;/a&gt;, &lt;a href=&quot;http://www.aclweb.org/anthology/D14-1181&quot;&gt;Kim(2014)&lt;/a&gt;이다(&lt;a href=&quot;https://ratsgo.github.io/natural%20language%20processing/2017/03/19/CNN/&quot;&gt;블로그&lt;/a&gt;.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;a-cnn-기본구조&quot;&gt;A. CNN 기본구조&lt;/h5&gt;

&lt;h6 id=&quot;1-문장-모델링&quot;&gt;1) 문장 모델링&lt;/h6&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;문장의 $i$번째 단어에 해당하는 임베딩 벡터를 $w_i\in R^d$, 임베딩 벡터의 차원수를 $d$라 두면, $n$개 단어로 이루어진 문장 주어졌을 떄, 문장은 $n$ x $d$(W$\in$$R^{n*d}$) 크기의 Embedding matrix로 표현할 수 있다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;img src=&quot;https://i.imgur.com/sZXqAtG.png&quot; alt=&quot;figure6&quot; /&gt;&lt;em&gt;텍스트 처리를 위한 CNN  &lt;a href=&quot;https://arxiv.org/pdf/1510.03820.pdf&quot;&gt;Zhang and Wallace(2015)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;$w_i,  w_{i+1}, …, w_j$ 의 결합(concatenation)(=$d$x$(j-i)$ dimension의 matrix가 된다)을 $w_{i:i+j}$ 라 두자.&lt;/li&gt;
  &lt;li&gt;콘볼루션은 위의 값(Input embedding layer)에 의해 수행 된다.&lt;/li&gt;
  &lt;li&gt;Convolution Filter $k$는 dimension이 $hd$인 filter이다. 이 Filter는 h개의 단어에 window로 작용해 새로운 feature를 만든다.&lt;/li&gt;
  &lt;li&gt;예를 들어 feature $c_i$는 $w_{i:i+j}$에 window를 씌움으로써 만들어 진다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;script type=&quot;math/tex&quot;&gt;c_i = f(w_{i:i+h-1}\cdot k^T+b)&lt;/script&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;여기서 b는 bias이고 f 는 activation ftn이다.&lt;/li&gt;
  &lt;li&gt;Filter k 는 모든 window에 같은 weight로 적용되서 feature map 을 만든다.
&lt;script type=&quot;math/tex&quot;&gt;c = [c_1, c_2, ..., c_{n+h-1}]&lt;/script&gt;&lt;/li&gt;
  &lt;li&gt;CNN에서 각각 다른 width의 많은filter(called kernel) 전체 word embedding matrix에 slide 된다.&lt;/li&gt;
  &lt;li&gt;각각의 kernel은 n-gram의 각각의 특징을 추출한다.&lt;/li&gt;
  &lt;li&gt;convolution layer는 주로 max-pooling을 사용함
    &lt;ul&gt;
      &lt;li&gt;최대값을 취함으로써 subsampling을 한다.&lt;/li&gt;
      &lt;li&gt;max-pooling을 사용하는데는 두가지 이유가 있다,
        &lt;ul&gt;
          &lt;li&gt;첫번째, max-pooling은 classification에 필요한 fixed-length output을  제공한다. 따라서 filter의 size에 상관없이 고정된 크기의 output을 제공한다.&lt;/li&gt;
          &lt;li&gt;두번째, max-pooling은 전체 문장에서 중요한 n-gram feature들을 보존한채 output의 dimension을 감소시킨다. 이러한 방법은 개별 filter에서 특정한 feature(ex.부정)을 잘 추출할 수 있다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Convolution layer와 max-pooling을 겹겹이 쌓는 sequential convolution은 풍부한 정보를 포함한 고도로 추상화된 표현을 잡아내 문장분석을 개선 할 수 있다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h6 id=&quot;2-window-approach&quot;&gt;2) window approach&lt;/h6&gt;

&lt;ul&gt;
  &lt;li&gt;위의 CNN 아키텍쳐는 자연어 문장을 벡터로 표현한다.&lt;/li&gt;
  &lt;li&gt;그러나 개체명 인식, 품사태킹, SRL과 같은 task에서는 단어 단위의 예측이 필요하다.&lt;/li&gt;
  &lt;li&gt;따라서 이러한 task들에 적용하기 위해 window 접근법이 사용된다.&lt;/li&gt;
  &lt;li&gt;window approach는 단어의 범주(tag)가 이웃한 단어에 의존할 것이라 가정한다.&lt;/li&gt;
  &lt;li&gt;따라서 각 단어에 대해 고정된 크기의 window가 적용되고 그 윈도의 내의 하위 문장들(sub-sentence)이 고려된다.&lt;/li&gt;
  &lt;li&gt;Standalone CNN은 이러한 하위 문장들(sub-sentence)에 적용되고 윈도우 중앙의 단어에 의해 예측된다.&lt;/li&gt;
  &lt;li&gt;이러한 접근에 따라 &lt;a href=&quot;http://sentic.net/aspect-extraction-for-opinion-mining.pdf&quot;&gt;Poria et al. (2016a)&lt;/a&gt;는 문장 각 단어에 aspect(주제) 혹은 non-aspect태그를 붙이기 위해 multi-level Deep CNN을 제안했다.
    &lt;ul&gt;
      &lt;li&gt;언어적 패턴 집합과 함께 사용한 앙상블 classifier는 aspect detection에 있어 좋은 성능을 냈다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;단어 수준 분류의 주요 목표는 전체 문장에 레이블 시퀀스(sequence)를 할당하는 것이다.&lt;/li&gt;
  &lt;li&gt;Conditional Random Field(CRF) 같은 구조화된 예측 기법(structed prediction)은 때때로 인접한 클래스 레이블 간의 의존성을 더 잘 포착한다.&lt;/li&gt;
  &lt;li&gt;이 기법은 결국 전체 문장에 최대 스코어를 내는 결합된 레이블 시퀀스(cohesive label sequence)를 생성한다&lt;a href=&quot;https://arxiv.org/pdf/1511.05067.pdf&quot;&gt;(Kirillov et al., 2015)&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;더 넓은 문맥적 범위를 위해 전통적인 윈도우 접근법은 종종 time-dealy neural network(TDNN)와 결합된다.&lt;a href=&quot;http://www.cs.toronto.edu/~fritz/absps/waibelTDNN.pdf&quot;&gt;(Waibel et al., 1989).&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;위의 방법에서 Convolution은 모든 window에서 적용된다.&lt;/li&gt;
  &lt;li&gt;하지만 filter들의 폭이 고정되었기 때문데 convolution은 제약을 가진다. 이러한 문제를 해결하기 위해 전통적인 방법은 레이블이 달린 단어 주변의 윈도우에 있는 단어들만 고려하지만, TDNN은 윈도의 내의 모든단어를 고려한다.&lt;/li&gt;
  &lt;li&gt;때떄로 TDNN는 CNN처럼  stack처럼 쌓여 하위 계층에서는 local feature 상위계층에서는 global feature를 뽑아낸다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5 id=&quot;b-cnn-application&quot;&gt;B. CNN Application&lt;/h5&gt;

&lt;ul&gt;
  &lt;li&gt;CNN을 사용한 다양한 응용들을 소개한다.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.aclweb.org/anthology/D14-1181&quot;&gt;Kim(2014.)&lt;/a&gt;은 감성, 주관(Subjectivity), 질문유형 분류 포함해서 다양한 sentence 분류 문제에 CNN Architecture를 사용했다.
    &lt;ul&gt;
      &lt;li&gt;Kim의 연구는 간단하지만 효율적이라 많이 사용되었다.&lt;a href=&quot;https://ratsgo.github.io/natural%20language%20processing/2017/03/19/CNN/&quot;&gt;블로그참고&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;특정 task에 대한 trainning후, random initialized convolution kernel은 특정 목적에 융요한 n-gram feature 탐지기가 되었다.&lt;/li&gt;
      &lt;li&gt;그러나, Long-term의 dependency를 모델링 할 수 없다는 등 여러 단점이 있다.&lt;/li&gt;
      &lt;li&gt;&lt;img src=&quot;https://i.imgur.com/owRQiEX.png&quot; alt=&quot;figure7&quot; /&gt; &lt;em&gt;(Figure4. Top 7-gram by four learned 7-gram kernel ; 각각의 필터는 특정 종류의 7-gram에 민감하다.)&lt;/em&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;이러한 이슈(long-term dependency)를 해결하기 위해, 	&lt;a href=&quot;http://www.aclweb.org/anthology/P14-1062&quot;&gt;Kalchbrenner et al.(2014)&lt;/a&gt;은 DCNN(Dynamic CNN)을 제안했다.
    &lt;ul&gt;
      &lt;li&gt;DCNN은 dynamic k-max pooling을 사용한다.
        &lt;ul&gt;
          &lt;li&gt;dynamic k-max pooling이란 시퀀스$p$가 주어졌을 때 가장 active한 k개의 feature를 뽑는 것이다.&lt;/li&gt;
          &lt;li&gt;이러한 선택들은 순서를 보존하지만 위치에는 민감하지 않다.&lt;/li&gt;
          &lt;li&gt;&lt;img src=&quot;https://i.imgur.com/9DP4wpR.png&quot; alt=&quot;figure8&quot; /&gt; &lt;em&gt;(Figure5.DCNN의 sub-graph.)&lt;/em&gt;&lt;/li&gt;
          &lt;li&gt;DCNN = TDNN(base) + dynamic k-max pooling&lt;/li&gt;
          &lt;li&gt;이러한 전략은 filter의 좁은 너비가 넓은 범위의 sentence를 cover할 수 있게 되었다.&lt;/li&gt;
          &lt;li&gt;Figure5 에서 상위의 Feature는 가변적인 너비를 가진다.&lt;/li&gt;
          &lt;li&gt;즉 이 연구는 문맥적 의미를 모델링하는 데 있어 개별 필터의 범위(range)에 대해 언급했고, 필터의 도달 범위를 확장하는 방법론을 제안했다.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;감정분석에 필요한 task는 효과적인 aspect추출과 감정 극성(polarity)이다.&lt;a href=&quot;https://www.cs.uic.edu/~liub/publications/ACL-2012-aspect-extraction.pdf&quot;&gt;(Mukerjee and Liu, 2012)&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.aclweb.org/anthology/S/S16/S16-1053.pdf&quot;&gt;Ruder et al. (2016)&lt;/a&gt;은 좋은 결과를 위해 word embedding 과 aspect vector를 결합한 값을 input으로 하는 CNN적용했다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;CNN은 Text의 길이에 따라 성능이 달라진다.
    &lt;ul&gt;
      &lt;li&gt;장문에서는 CNN 성과가 좋았으나, 단문에서는 성과가 좋지 않았다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.aclweb.org/anthology/P15-2058&quot;&gt;Wang et al.(2015b)&lt;/a&gt;은 짧은 Text 표현에 CNN을 사용하기 위해 외부의 지식이 사용된 multi-scale semantic units를 도입한 의미적 clustering(semantic clustering)을 제안했다.
    &lt;ul&gt;
      &lt;li&gt;CNN은 이러한 Unit들을 결합해 represention을 만들어 낸다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;CNN에서 고도의 문맥정보를 요구하는 것은 어렵다.
    &lt;ul&gt;
      &lt;li&gt;CNN사용한 단문 분석을 종종 부가정인 정보와 외부 지식을 필요로 한다.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://arxiv.org/pdf/1610.08815.pdf&quot;&gt;Poria et al.(2016)&lt;/a&gt;은 CNN을 활용하여 twitter text에서 빈정대는 부분을 찾아내는 task(sarcasm detection)를 만들었다.&lt;/li&gt;
      &lt;li&gt;여기에서 감정,감성,개별 데이터셋이 사전학습된 보조적인 자료로서 사용되어서 state-of-the-art한 성능을	이끌어 냈다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 

</feed>
