張皓凱、陳睿倬Fed 25,2022
AI
tcirc
社課
臺中一中電研社
講義都會公告在社網上
社網:tcirc.tw
IG:tcirc_39th
online judge:judge.tcirc.tw
https://www.cs.ryerson.ca/~aharley/vis/conv/
若今天我們有一筆二維資料,我們就無法使用一般的神經網路模型。如: 辨識圖片。圖片資料有一組座標,座標裡有三個參數(rgb)。我們最多只能將座標攤平,但rgb資料無法處裡。
CNN就能處裡這個問題,其原理是藉由卷積層擷取圖像特徵,同時又保持資料關聯性。
會對圖像中特徵部分做擷取、過濾,並生成特徵圖。當輸入一份新的資料時,會透過學習的特徵圖來辨認新的資料。為了能夠快速且準確地捕捉到關鍵特徵,cnn需要非常大的資料量。
可把卷積層想像成一個滑動視窗,他會將圖像中的每個部份乘上參數後轉換成一個數值代替,如下圖所示
圖源
所以,卷積層的優點就是能大幅縮小參數的數量,減少運算資源。
而卷積層的大小由圖像決定,若圖像很大,卷積層也會變大,才能有效減少參數量;相對的,圖像小時,卷積層會較小,避免對特徵擷取不夠仔細。
將圖像降維,減少資料量,將不必要的資料捨去。做到改變資料形狀,同時也保留關鍵特徵。通常使用最大池化法
圖源
讀取卷積層和池化層處理後的特徵,並篩選特徵,淘汰不必要的數據,保留真正的特徵。
CNN透過反覆地處理上述所講述的隱藏層,來捕捉複雜圖像的特徵。
圖源
from keras.layers import Dense, Flatten, Conv2D, MaxPool2D
conv2d是卷積層、maxpool2d是池化層,而flatten是把卷積層和池化層所擷取的數據攤平,以便導入隱藏層做深度學習。
model.add(Conv2D(filters = 輸出多少特徵量,kernel_size = (x,y)卷積層大小,input_shape = (32,32,3),activation = 'relu',padding = 'same'(填充物)))
model.add(tf.keras.layers.MaxPooling2D(pool_size = (x,y))) 設定池化大小x*y
model.add(Flatten()) # 資料攤平
簡單來說,當模型在訓練時,會關掉一些神經元,使模型不會由少數幾個神經元控制,大幅減少資料過擬合
圖源
如果模型訓練過程中,為了確保模型的準確性,所以會加入驗證資料來查看模型實際應用的損失函數。
然而,訓練資料的損失函數可能會和驗證資料的損失函數相差很多,也就是我們一直常提到的過擬合。也就是模型只對學習資料有很高的準確率,但是碰到未知資料時就變得非常差。
early stop目的就是希望模型訓練到一個程度時就停止學習,防止因學習的越多,導致模型偏差愈大。
最常見用於NLP(Natural Language Processing,自然語言處理),亦可運用於任何與時間序列有關的資料。(無關的有時也能有奇效)
Natural Language Processing,自然語言處理。
所謂自然語言指的是一種自然隨文化演化所產生的語言,e.g.英文、中文、俄文、烏克蘭語
非自然語言為程式語言、標記語言。
常見功能有:
資料取自維基百科
NLP難以用程式完成原因主要為單詞的邊界界定、詞義的消歧及句法的模糊性。所以就產生了RNN。
(圖源:medium)
(圖源:李教授講義)
A皆為同一網路且可以多層
因為輸入層只能接收數字(向量),所以必須先將原本的文字編碼之後再輸入
假設我們有一堆文字
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]
假設現在出現了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]
另外一種方法是用雜湊的方式來產生向量,但這裡不多做解釋,有興趣的點這裡看,總之就是一種把文字變向量的方法。
在開始講之前,先假設一個問題。我們有兩個句子:
Go to TCGS from TCFSH
Go from TCGS to TCFSH
我們想要得知兩個句子的起點與終點分別為何?
先來看能不能用學過的ANN解決
假設這是一個已經訓練好的ANN模型,現在將第一句的每一字逐一放入,假設得到以下結果
Go -> other
to -> other
TCGS -> destination
from -> other
TCFSH -> starting point
接著逐一放入第二句:
Go -> other
from -> other
TCGS -> destination #ANN相同輸入必有相同輸出
to -> other
TCFSH -> starting #ANN相同輸入必有相同輸出
可以明顯看出第二句的結果是錯的,因為自然語言在判斷時不能把每一個字都獨立判斷,必須考慮前後語意。
ANN不行,那剛剛學的CNN呢?
第一步、把資料卷積
要怎麼卷積?我也不知道,所以別想用CNN了
從剛剛的範例可以發現似乎可以透過前一個字from
跟to
來推測結果,RNN就是在網路中加入一個不會受到訓練改變的記憶體。
在每一次執行皆有兩個輸入,第i個輸入及前一次的記憶,執行完模型後,再將數值存入記憶體中供下次使用。所以輸入的順序會影響結果,輸入AB與輸入BA的結果會不同。
(圖源:李教授講義)
(圖源:李教授講義)
每一層都會有各自的記憶體
剛剛有講到自然語言需靠前後文判斷,但從剛剛的RNN只有從前文判斷,所以Bidirectionalr就同時訓練一個由後往前讀的模型,輸出解果有兩個模型共同決定
(圖源:李教授講義)
Long Short-Term Memory,長短期記憶
在NLP裡,通常我們不能只看前一個字,有時會需要用很前面的字來判斷,或者是會需要把記憶體清空重新存放記憶,又或者並非每一個字都要有輸出。
(圖源:codebasics)
決定是否需要透過輸入改變記憶體儲存的東西,符號\(z_i\),值會經過一個函數(通常是sigmoid或tanh)後介於0(不行寫入)~1(可以寫入)之間,值會由模型自己訓練得出。
決定是否需要輸出,符號\(z_o\),值會經過一個函數(通常是sigmoid或tanh)後值介於0(不須輸出)~1(要輸出)之間,值會由模型自己訓練得出。
決定記憶體需要格式化,符號\(z_f\),值會經過一個函數(通常是sigmoid或tanh)後值介於0(須格式化)~1(不須格式化)之間,值會由模型自己訓練得出。
一個基本的LSTM cell可以想成是一個需要四個輸入(\(z, z_i, z_o, z_f\))且只有一個輸出的特殊神經元。新的記憶體為:
\[ c' = g(z)f(z_i) + cf(z_f) \]
(圖源:李教授講義)
剛剛說到LSTM cell是一個神經元,那我們把所有的一般神經元全部換成LSTM cell就會完成一個完整的LSTM模型。那我們就會得到:
這樣可能沒有RNN的時間序列感,所以我們把LSTM cell 換個方式畫:
(圖源:李教授講義)
時間序列:
(圖源:李教授講義)
多層網路:
(圖源:李教授講義)
LSTM在現在已經變成主流的RNN模型,取代了一開始所說的simple RNN模型,因為LSTM可以解決simple RNN反向傳播效果不佳,無法穩定降低loss的問題。
RNN模型根據輸入及輸出的量分為以下幾種:
圖源:karpathy
常用於整句式翻譯,因為需要先將整句話讀過一次,才能翻譯出完整語意。這種模型會有兩個網路encoder跟decoder,encoder會先將所有的字都進行加密,接著再透過decoder進行解密並輸出。encoder與decoder是兩個不同同網路,但必須同時訓練。與GAN不同處在於,GAN是讓兩個模型互相對抗,而encoder & decoder則偏向合作。
(圖源:codebasics)
from keras.layers.recurrent import SimpleRNN model.add(SimpleRNN(units=16))
由於RNN有很多種,所以我們要在keras.layers.recurrent中選擇一個來用。
接著就像一般的Dense一樣,設定神經元數,但不需要設定激活函數。