# Recurrent Neural Networks ## 1. Time Series Features Consider a sentence as follows : *He is a teacher. She is a student.* How do we extract the features from this sentence ? ### 1.1 Sentence-level Features - Extract features from each sentence : - Bag-of-words 1. Build a list contain all words of the sentence: [ "he", "she", "is", "a", "teacher", "student" ] 2. Generate a vector which length is the same as length of the list: [ 0, 0, 0, 0, 0, 0] 3. Replace zero with word frequency : [ 1, 1, 2, 2, 1, 1 ] - Advantage : - It can fit the most of machine learning model. - Disadvantage : - Loss the information of relation between words. - *He is a teacher. She is a student.* - *He is a student. She is a teacher.* ### 1.2 Word-level Features - Extract features from each word - One-hot - Word embedding - embedding layer - word2vec - Word-level features will contain 2 domains: - Time domain and word domain. - For example, we can get the features as follows by one-hot encoding : [[1, 0, 0, 0, 0, 0], => He [0, 0, 1, 0, 0, 0], => is [0, 0, 0, 1, 0, 0], => a [0, 0, 0, 0, 1, 0], => teacher [0, 1, 0, 0, 0, 0], => She [0, 0, 1, 0, 0, 0], => is [0, 0, 0, 1, 0, 0], => a [0, 0, 0, 0, 0, 1]] => student - We can flatten the features to a vector and feed it to maching learning model. - But the model still **cannot** learn the relation between words. ## 2. Recurrent Neural Networks ### 2.1 Basic Architecture Idea: feed a word and a previous state to machine learning model each time. The model has two output: one for prediction and another for **hidden state**. ![](https://i.imgur.com/9BWm6wW.png) ![](https://i.imgur.com/TrM1H8h.png) If we want to classify a sentence, we can treat the last output as prediction. - Ignore intermediate output. ### 2.2 Backpropagation Through Time In this architecture, backpropagation is not enough. - Because we cannot optimize intermediate output. Solution: recurrent neural network is a cyclic graph. Maybe we can simplify the architecture of recurrent neural network. ![](https://i.imgur.com/eEAcpJW.png) Here, Model 1, Model 2, ..., Model $n$ share the same weights and bias. We can treat those models as a large, sequential model. - $h_n$ is the output of this model. - Ignore $h_1, h_2, ..., h_{n-1}$ Now, we can use backpropagation calculate the gradients easily. Work flow of backpropagation through time: 1. Unroll the recurrent neural network. 2. Calculate the gradients of all trainable variables. 3. Roll-up the recurrent neural network. 4. Update trainable variables. ## 3. Long Short-Term Memory (LSTM) ### 3.1 Introduction Reference: [Understanding LSTM Networks](http://colah.github.io/posts/2015-08-Understanding-LSTMs/) #### Disadvantages of recurrent neural networks : 1. Gradient vanish 2. Gradient explode 3. Performance will be bad if time series is too long #### Solution: 1. An additional new state: **cell state** 2. Three gates: **input gate**, **forget gate**, **output gate** #### Simple work flow : ![](https://i.imgur.com/UTnk3Gn.png) ||time step 1|time step 2|time step 3|time step 4|time step 5| |:------:|:--:|:--:|:--:|:--:|:--:| |$x_t$ |2 |-1 |1 |2 |-1 | |$x_{ti}$|999 |999 |-999|999 |999 | |$x_{tf}$|999 |999 |999 |-999|-999| |$x_{to}$|999 |-999|999 |999 |-999| |C |2 |1 |1 |2 |-1 | |h |2 |0 |1 |2 |0 | Let (1) $x_t$ is a word at time stamp $t$, (2) $h_t$ is the hidden state at time stamp $t$, (3) $C_t$ is the cell state at time stamp $t$. Consider the current word and two previous states : $x_t, h_{t-1}, C_{t-1}$. A LSTM cell calculates three values : $i_t, f_t, o_t$ Use those three values to generate next two states : $h_t, C_t$ #### Calculate $i_t$ (output of input gate) : $$ i_t = Sigmoid(W_i \cdot [h_{t-1}, x_t] + b_i) $$ #### Calculate $f_t$ (output of forget gate) : $$ f_t = Sigmoid(W_f \cdot [h_{t-1}, x_t] + b_f) $$ #### Calculate $o_t$ (output of output gate) : $$ o_t = Sigmoid(W_o \cdot [h_{t-1}, x_t] + b_o) $$ #### Calculate $C_t$ (cell state) : $$ \bar C_t = tanh(W_C \cdot [h_{t-1}, x_t] + b_C) \\ C_t = f_t * C_{t-1} + i_t * \bar C_t $$ #### Calculate $h_t$ (hidden state) : $$ h_t = o_t * tanh(C_t) $$ ### 3.2 Model Architecture ![](https://i.imgur.com/7TPMPnR.png) Here, we show a simple stacked LSTM model. - $h_{11}, h_{12}, ..., h_{1n}$ , $h_{21}, h_{22}, ..., h_{2n}$, $h_{3n}$ are 1D vectors. They are hidden states of each time stamp. - The first two LSTM layers **return all hidden states**. And the last LSTM layer **only return the final hidden state**. - We will feed the final hidden state $h_{3n}$ to a neural network. We can unroll this architecture as follows : ![](https://i.imgur.com/PcIiZEo.png) example: ```python= model = Sequential() model.add(LSTM(64, return_sequences=True)) model.add(LSTM(64, return_sequences=True)) model.add(LSTM(64)) model.add(Dense(32, activation='relu')) model.add(Dense(1, activation='sigmoid')) ``` ### 3.3 Bidirectional LSTM A basic problem for all recurrent architectures: - They will **forget** the features input at the beginning. - This will be a problem if we pad all sequences to the same size. For example, consider raw data as follows: 1. I am darby. I am handsome. 2. How are you? 3. To be or not to be, this is a question. In practice, we will pad those sequences: 1. [pad] [pad] [pad] [pad] i am darby i am handsome 2. [pad] [pad] [pad] [pad] [pad] [pad] [pad] how are you 3. to be or not to be this is a question #### Solution : 1. Reverse sequence order 2. Bidirectional LSTM ![](https://cdn-images-1.medium.com/max/1200/1*6QnPUSv_t9BY9Fv8_aLb-Q.png) ## 4. Sequence to Sequence Learning Paper: [Sequence to Sequence Learning with Neural Networks](https://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf) Definition: feed a sequence to model and the model will response with a sequence, such as chatbot and machine translation. - It is not a simple classification or regression model. Instead, it's a **generative model**. ### 4.1 Limitation of generative problem on a RNN model Is it possible that we let each hidden states become an output sequence ? ![](https://i.imgur.com/19GryC6.png) - No, because we might need the whole input sequence to generate a response. ![](http://karpathy.github.io/assets/rnn/diags.jpeg) ### 4.2 Encoder-Decoder Architecture Idea: use a RNN model to encode the whole input sequence, and decode to a response by another RNN model. - Sequence-to-sequence model (seq2seq) ![](https://i.imgur.com/V8rxbS5.png) 1. For the encoder part, feed a whole input sequence to encoder model, and we will get a final cell state and hidden state. 2. For the decoder part, we **initialize** the decoder cell state and hidden state by the encoder cell state and hidden state. 3. Finally, we feed a **start token** to the decoder, and we can output a word. - We feed this word to the decoder to get next word. Repeat this process until we get an **end token**. ### 4.3 Input and Output Encoding Input: feel free to use any kind of word-level encoding method - One-hot - Word embedding (memory-friendly) Output: only consider **one-hot** encoding. - Seq2seq model will predict the class of each word. - If the vocabulary size is 80000, the output layer of the decoder will have 80000 neurons. Think: larger vocabulary size, more memory usage. ### 4.4 More Issues - Optimize encoder: reverse sequence order. - Optimize decoding process: beam search algorithm. ## 5. Attention Mechanism Let's review seq2seq model : ![](https://i.imgur.com/KCmJPN6.png) For the first generated word "I", we can know that it is generated by token "[start]" with hidden state $h_0$ and cell state $C_0$. - Also, $h_1$ and $C_1$ will be generated. The second word "am" is generated by "I", $h_1$ and $C_1$. - $h_2$ and $C_2$ will be generated, too. Summary: $Word_t$ will be generated by $h_{t-1}$, $C_{t-1}$ and $Word_{t-1}$. - $Word_t$ may depend on state $t-n$ or state $t+n$. - Differnet words has different dependencies. - For example, consider the following machine translation : - I woke up at 8:00 a.m today. => 我今天早上8點起床 - The order of action and time is reverse. The second Chinese vocaulary "今天" depends on the final English word "today". ### 5.1 Architecture Overview ![](https://i.imgur.com/trY1JmW.png) A new conception: **context vector** ### 5.2 Context Vector Hidden states of encoder could be important. - Generate a context vector which is a **weighted sum** of all hidden state of encoder. Where are the weights of the weighted sum from? - Based on **current hidden state of the decoder**. Consider all hidden states of encoder $he_1, he_2, ... he_n$ and current hidden state of decoder $hd_t$. We can calculate their weights by the following equation: $$ u^t_i = score(he_i, hd_t) \\ U^t = [u^t_1, u^t_2, u^t_3, ... u^t_n] \\ a^t = softmax(U^t) \\ c_t = \sum a^t_i \times he_i $$ $score(.)$ is a function to calcuate the relation between $he_i$ and $hd_t$. For example: $$ score(he_i, hd_t) = v^T tanh(W_e \cdot he_i + W_d \cdot hd_t) $$ - $v^T$: a weight matrices - $W_e, W_d$: trainable variables ### 5.3 Prediction Prediction will be calculated by the **context vector** and **current hidden state of decoder**. $$ \bar{hd}_t = tanh(W_c \cdot [c_t; hd_t]) \\ y_t = softmax(W_s \cdot \bar {hd}_t) $$ ## 6. More - [Attention Is All You Need](https://arxiv.org/pdf/1706.03762.pdf) ![](https://i.imgur.com/TGzq1v6.png) - [BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding](https://arxiv.org/pdf/1810.04805.pdf) (and many other BERT-variants like ALBERT, RoBERTa, XLNet, ELECTRA ...) - [Visualizing memorization in RNNs](https://distill.pub/2019/memorization-in-rnns/#appendix-autocomplete) - Bistable Reccurent Cell (BRC, 2020) >> [A bio-inspired bistable recurrent cell allows for long-lasting memory](https://arxiv.org/pdf/2006.05252.pdf) ## Reference - [A Gentle Introduction to Backpropagation Through Time](https://machinelearningmastery.com/gentle-introduction-backpropagation-time/) - [Understanding LSTM Networks](http://colah.github.io/posts/2015-08-Understanding-LSTMs/) - [Attention Mechanism(Seq2Seq)](https://www.slideshare.net/healess/attention-mechanismseq2seq) - [Hierarchical Attention Networks for Document Classification](https://www.cs.cmu.edu/~diyiy/docs/naacl16.pdf) - [Neural Machine Translation by Jointly Learning to Align and Translate](https://arxiv.org/pdf/1409.0473.pdf) - [Understanding Bidirectional RNN in PyTorch](https://towardsdatascience.com/understanding-bidirectional-rnn-in-pytorch-5bd25a5dd66) - [李宏毅 Transformer](http://speech.ee.ntu.edu.tw/~tlkagk/courses/ML_2019/Lecture/Transformer%20(v5).pdf) - [李宏毅 Structured Learning: Recurrent Neural Network](http://speech.ee.ntu.edu.tw/~tlkagk/courses/ML_2016/Lecture/RNN%20(v2).pdf)