AI人工智慧-CNN, RNN
===
>[name=張皓凱、陳睿倬][time=Fed 25,2022]
###### tags: `AI` `tcirc` `社課` `臺中一中電研社`
---
第八節社課
===
[TOC]
---
## 電研社
講義都會公告在社網上
[社網:tcirc.tw](https://tcirc.tw/)
[IG:tcirc_39th](https://www.instagram.com/tcirc_39th/)
![ig QRcode](https://i.imgur.com/4hyS6GM.png)
[online judge:judge.tcirc.tw](https://judge.tcirc.tw/)
---
## CNN 卷積類神經網路
https://www.cs.ryerson.ca/~aharley/vis/conv/
若今天我們有一筆二維資料,我們就無法使用一般的神經網路模型。如: 辨識圖片。圖片資料有一組座標,座標裡有三個參數(rgb)。我們最多只能將座標攤平,但rgb資料無法處裡。
CNN就能處裡這個問題,其原理是藉由卷積層擷取圖像特徵,同時又保持資料關聯性。
----
### 卷積層 kernel
會對圖像中特徵部分做擷取、過濾,並生成特徵圖。當輸入一份新的資料時,會透過學習的特徵圖來辨認新的資料。為了能夠快速且準確地捕捉到關鍵特徵,cnn需要非常大的資料量。
----
#### 原理
可把卷積層想像成一個滑動視窗,他會將圖像中的每個部份乘上參數後轉換成一個數值代替,如下圖所示
![](https://i.imgur.com/IPXuh9E.png)
[圖源](https://cinnamonaitaiwan.medium.com/%E6%B7%B1%E5%BA%A6%E5%AD%B8%E7%BF%92-cnn%E5%8E%9F%E7%90%86-keras%E5%AF%A6%E7%8F%BE-432fd9ea4935)
----
所以,卷積層的優點就是能大幅縮小參數的數量,減少運算資源。
而卷積層的大小由圖像決定,若圖像很大,卷積層也會變大,才能有效減少參數量;相對的,圖像小時,卷積層會較小,避免對特徵擷取不夠仔細。
----
### 池化層
將圖像降維,減少資料量,將不必要的資料捨去。做到改變資料形狀,同時也保留關鍵特徵。通常使用最大池化法
![](https://i.imgur.com/ox29ZHf.png)
[圖源](https://zh.wikipedia.org/wiki/%E5%8D%B7%E7%A7%AF%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C)
----
### 全連接層
讀取卷積層和池化層處理後的特徵,並篩選特徵,淘汰不必要的數據,保留真正的特徵。
----
CNN透過反覆地處理上述所講述的隱藏層,來捕捉複雜圖像的特徵。
![](https://i.imgur.com/QFNA7j1.png)
[圖源](https://chih-sheng-huang821.medium.com/%E5%8D%B7%E7%A9%8D%E7%A5%9E%E7%B6%93%E7%B6%B2%E8%B7%AF-convolutional-neural-network-cnn-cnn%E9%81%8B%E7%AE%97%E6%B5%81%E7%A8%8B-ecaec240a631)
----
### 設定卷積層、池化層
```python=
from keras.layers import Dense, Flatten, Conv2D, MaxPool2D
```
conv2d是卷積層、maxpool2d是池化層,而flatten是把卷積層和池化層所擷取的數據攤平,以便導入隱藏層做深度學習。
```python=
model.add(Conv2D(filters = 輸出多少特徵量,kernel_size = (x,y)卷積層大小,input_shape = (32,32,3),activation = 'relu',padding = 'same'(填充物)))
```
```python=
model.add(tf.keras.layers.MaxPooling2D(pool_size = (x,y)))
設定池化大小x*y
```
```python=
model.add(Flatten()) # 資料攤平
```
---
### Dropout
簡單來說,當模型在訓練時,會關掉一些神經元,使模型不會由少數幾個神經元控制,大幅減少資料過擬合
![](https://i.imgur.com/IbiLXaq.png)
[圖源](https://medium.com/@a5560648/dropout-5fb2105dbf7c)
---
### early stop
如果模型訓練過程中,為了確保模型的準確性,所以會加入驗證資料來查看模型實際應用的損失函數。
然而,訓練資料的損失函數可能會和驗證資料的損失函數相差很多,也就是我們一直常提到的過擬合。也就是模型只對學習資料有很高的準確率,但是碰到未知資料時就變得非常差。
early stop目的就是希望模型訓練到一個程度時就停止學習,防止因學習的越多,導致模型偏差愈大。
----
![](https://i.imgur.com/tcONlSg.png)
[圖源](https://clay-atlas.com/blog/2020/09/29/pytorch-cn-early-stopping-code/)
---
## RNN
----
## RNN是什麼
- recurrent neural network,循環神經網路
- 是一種類神經網路
- 監督式、DL
----
## RNN用途
最常見用於NLP(Natural Language Processing,自然語言處理),亦可運用於任何與時間序列有關的資料。(~~無關的有時也能有奇效~~)
---
### NLP
Natural Language Processing,自然語言處理。
所謂自然語言指的是一種自然隨文化演化所產生的語言,e.g.英文、中文、俄文、烏克蘭語
非自然語言為程式語言、標記語言。
常見功能有:
----
1. 文本朗讀(Text to speech)/ 語音合成(Speech synthesis)
1. 語音識別(Speech recognition)
1. 自動分詞(word segmentation)
1. 詞性標註(Part-of-speech tagging)
1. 句法分析(Parsing)
1. 自然語言生成(Natural language generation)
1. 文本分類(Text categorization)
----
8. 信息檢索(Information retrieval)
1. 信息抽取(Information extraction)
1. 文字校對(Text-proofing)
6. 問答系統(Question answering)
7. 機器翻譯(Machine translation)
8. 自動摘要(Automatic summarization)
9. 文字蘊涵(Textual entailment)
> 資料取自[維基百科](https://zh.wikipedia.org/wiki/%E8%87%AA%E7%84%B6%E8%AF%AD%E8%A8%80%E5%A4%84%E7%90%86)
----
NLP難以用程式完成原因主要為單詞的邊界界定、詞義的消歧及句法的模糊性。所以就產生了RNN。
---
## RNN model基本概念
![](https://i.imgur.com/Hry5uXP.jpg)
(圖源:[medium](https://medium.com/@fredericklee_73485/attention-in-text-%E6%B3%A8%E6%84%8F%E5%8A%9B%E6%A9%9F%E5%88%B6-bc12e88f6c26))
----
![](https://i.imgur.com/ZqYroXb.jpg)
(圖源:[李教授講義](https://ai.ntu.edu.tw/resource/handouts/ML21-1.html))
<span style="color:#ff0000">A皆為同一網路且可以多層</span>
---
## input
因為輸入層只能接收數字(向量),所以必須先將原本的文字編碼之後再輸入
----
### 1-of-N encoding
假設我們有一堆文字
```
lexicon={apple, boy, cat, dog}
```
利用 1-of-N 編碼過後的向量
```
apple = [1, 0, 0, 0]
boy = [0, 1, 0, 0]
cat = [0, 0, 1, 0]
dog = [0, 0, 0, 1]
```
----
### "Other"
假設現在出現了`egg`這個單字,1-of-N 會無法給它一個向量,所以就出現了`other`來補足。將沒看過的詞彙都放到`other`這個分類。
```
lexicon={apple, boy, cat, dog}
apple = [1, 0, 0, 0, 0]
boy = [0, 1, 0, 0, 0]
cat = [0, 0, 1, 0, 0]
dog = [0, 0, 0, 1, 0]
egg = [0, 0, 0, 0, 1]
fish = [0, 0, 0, 0, 1]
```
----
### word hashing
另外一種方法是用雜湊的方式來產生向量,但這裡不多做解釋,有興趣的點[這裡](http://www.cse.yorku.ca/~oz/hash.html)看,總之就是一種把文字變向量的方法。
---
## RNN
在開始講之前,先假設一個問題。我們有兩個句子:
`Go to TCGS from TCFSH`
`Go from TCGS to TCFSH`
我們想要得知兩個句子的起點與終點分別為何?
----
### ANN?
先來看能不能用學過的ANN解決
----
![](https://i.imgur.com/IAOXSr1.png)
----
假設這是一個已經訓練好的ANN模型,現在將第一句的每一字逐一放入,假設得到以下結果
```
Go -> other
to -> other
TCGS -> destination
from -> other
TCFSH -> starting point
```
接著逐一放入第二句:
```
Go -> other
from -> other
TCGS -> destination #ANN相同輸入必有相同輸出
to -> other
TCFSH -> starting #ANN相同輸入必有相同輸出
```
可以明顯看出第二句的結果是錯的,因為自然語言在判斷時不能把每一個字都獨立判斷,必須考慮前後語意。
----
### CNN?
ANN不行,那剛剛學的CNN呢?
~~第一步、把資料卷積~~
要怎麼卷積?我也不知道,所以別想用CNN了
---
### 記憶
從剛剛的範例可以發現似乎可以透過前一個字`from`跟`to`來推測結果,RNN就是在網路中加入一個不會受到訓練改變的記憶體。
---
### 執行
在每一次執行皆有兩個輸入,第i個輸入及前一次的記憶,執行完模型後,再將數值存入記憶體中供下次使用。所以輸入的順序會影響結果,輸入AB與輸入BA的結果會不同。
----
![](https://i.imgur.com/tTAHi3X.jpg)
(圖源:[李教授講義](https://ai.ntu.edu.tw/resource/handouts/ML21-1.html))
---
## 各種RNN模型
----
### Elman Network & Jordan Network
----
![](https://i.imgur.com/9sakCDe.png)
(圖源:[李教授講義](https://ai.ntu.edu.tw/resource/handouts/ML21-1.html))
----
### 多層網路
每一層都會有各自的記憶體
----
![](https://i.imgur.com/8cMaSUV.png)
[圖源](https://zh.wikipedia.org/wiki/%E5%BE%AA%E7%8E%AF%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C)
----
### Bidirectional RNN
剛剛有講到自然語言需靠***前後***文判斷,但從剛剛的RNN只有從前文判斷,所以Bidirectionalr就同時訓練一個由後往前讀的模型,輸出解果有兩個模型共同決定
----
![](https://i.imgur.com/OQypqh4.jpg)
(圖源:[李教授講義](https://ai.ntu.edu.tw/resource/handouts/ML21-1.html))
---
## LSTM
Long Short-Term Memory,長短期記憶
----
### why LSTM
在NLP裡,通常我們不能只看前一個字,有時會需要用很前面的字來判斷,或者是會需要把記憶體清空重新存放記憶,又或者並非每一個字都要有輸出。
----
![](https://i.imgur.com/Gfeclzj.png)
(圖源:[codebasics](https://www.youtube.com/watch?v=LfnrRPFhkuY))
----
### input gate
決定是否需要透過輸入改變記憶體儲存的東西,符號$z_i$,值會經過一個函數(通常是sigmoid或tanh)後介於0(不行寫入)~1(可以寫入)之間,值會由模型自己訓練得出。
----
### output gate
決定是否需要輸出,符號$z_o$,值會經過一個函數(通常是sigmoid或tanh)後值介於0(不須輸出)~1(要輸出)之間,值會由模型自己訓練得出。
----
### forget gate
決定記憶體需要格式化,符號$z_f$,值會經過一個函數(通常是sigmoid或tanh)後值介於0(**須格式化**)~1(**不須格式化**)之間,值會由模型自己訓練得出。
----
### LSTM cell
一個基本的LSTM cell可以想成是一個需要四個輸入($z, z_i, z_o, z_f$)且只有一個輸出的**特殊神經元**。新的記憶體為:
$$
c' = g(z)f(z_i) + cf(z_f)
$$
----
![](https://i.imgur.com/WuxVaxc.jpg)
(圖源:[李教授講義](https://ai.ntu.edu.tw/resource/handouts/ML21-1.html))
----
### whole LSTM model
剛剛說到LSTM cell是一個神經元,那我們把所有的一般神經元全部換成LSTM cell就會完成一個完整的LSTM模型。那我們就會得到:
----
![](https://i.imgur.com/PSsYa5U.png)
----
這樣可能沒有RNN的時間序列感,所以我們把LSTM cell 換個方式畫:
----
![](https://i.imgur.com/xeA0Erc.jpg)
(圖源:[李教授講義](https://ai.ntu.edu.tw/resource/handouts/ML21-1.html))
----
時間序列:
----
![](https://i.imgur.com/OY7Ask5.jpg)
(圖源:[李教授講義](https://ai.ntu.edu.tw/resource/handouts/ML21-1.html))
----
多層網路:
----
![](https://i.imgur.com/11Gm2jH.jpg)
(圖源:[李教授講義](https://ai.ntu.edu.tw/resource/handouts/ML21-1.html))
----
### 改變
LSTM在現在已經變成主流的RNN模型,取代了一開始所說的simple RNN模型,因為LSTM可以解決simple RNN反向傳播效果不佳,無法穩定降低loss的問題。
---
## type
RNN模型根據輸入及輸出的量分為以下幾種:
![](https://i.imgur.com/7qfcU4S.jpg)
圖源:[karpathy](http://karpathy.github.io/2015/05/21/rnn-effectiveness/)
----
* one to many:輸入主題,產出一堆文字
* many to one:輸入評語輸出星數
* many to many:整句翻譯
---
## RNN encoder & decoder
常用於整句式翻譯,因為需要先將整句話讀過一次,才能翻譯出完整語意。這種模型會有兩個網路encoder跟decoder,encoder會先將所有的字都進行加密,接著再透過decoder進行解密並輸出。encoder與decoder是兩個不同同網路,但必須同時訓練。與GAN不同處在於,GAN是讓兩個模型互相對抗,而encoder & decoder則偏向合作。
----
![](https://i.imgur.com/0m95mRG.png)
(圖源:[codebasics](https://www.youtube.com/watch?v=LfnrRPFhkuY))
---
### 設定循環連接層RNN
```python=
from keras.layers.recurrent import SimpleRNN
model.add(SimpleRNN(units=16))
```
由於RNN有很多種,所以我們要在keras.layers.recurrent中選擇一個來用。
接著就像一般的Dense一樣,設定神經元數,但不需要設定激活函數。
---
## 參考資料
* https://cinnamonaitaiwan.medium.com/%E6%B7%B1%E5%BA%A6%E5%AD%B8%E7%BF%92-cnn%E5%8E%9F%E7%90%86-keras%E5%AF%A6%E7%8F%BE-432fd9ea4935
* https://chih-sheng-huang821.medium.com/%E5%8D%B7%E7%A9%8D%E7%A5%9E%E7%B6%93%E7%B6%B2%E8%B7%AF-convolutional-neural-network-cnn-cnn%E9%81%8B%E7%AE%97%E6%B5%81%E7%A8%8B-ecaec240a631
* https://www.youtube.com/watch?v=xCGidAeyS4M
---
## 課程程式碼
CNN: https://colab.research.google.com/drive/1bN-P9INsXTksVSfyP7t6B3tZH50emyCa?usp=sharing
RNN: https://colab.research.google.com/drive/1lPEtxlm8PmMfhzgc76oEEM9AqeZYk-Zd?usp=sharing
{"metaMigratedAt":"2023-06-16T20:21:51.443Z","metaMigratedFrom":"YAML","title":"AI人工智慧-CNN, RNN","breaks":true,"slideOptions":"{\"theme\":\"blood\",\"transistion\":\"slide\"}","contributors":"[{\"id\":\"39148de1-346d-4e2e-81c6-55b8161c633e\",\"add\":3755,\"del\":667},{\"id\":\"6a5475c5-bfd3-428c-9219-c760b9000deb\",\"add\":5978,\"del\":543}]"}