# 課程名稱: 深度學習之應用 ADL - **課程全名**: Applied Deep Learning - **學期**: 113-1 - **教授**: 陳縕儂教授 --- ## Lecture 0 : Introduction ### 什麼是AL和ML? - **Artificial Intelligence(AI)** : 用機器來模擬人類行為。 - **Machine Learning(ML)** : 讓機器從**資料**裡面學,屬於一種實踐人工智慧(AI)的方法。 - Learning ~= look for a function 可以理解為機器學習的目的根據給定的資料,尋找一個函數或模型,這個函數能夠有效地對資料進行描述、預測或分類。 ### 什麼是DL? - **Deep Learning(DL)** : Deep Learning可以理解為類神經網路(Neural network)-將模型堆疊很多層,而得到很好的performance。 <figure> <img src="https://hackmd.io/_uploads/BkANYyDnA.png" alt="DL Model"> <figcaption>上圖為Neural Network模型示意圖,只要hidden layers數量大於等於1即可稱為Neural Network。</figcaption> </figure> ### ML和DL的差異 <div style="text-align: center;"> <img src="https://hackmd.io/_uploads/HysYskvh0.png" alt="Machine Learning" width="300"> <p>ML的訓練資料由專家標註哪些特徵features是重要的。</p> </div> <div style="text-align: center;"> <img src="https://hackmd.io/_uploads/H1hqsJvn0.png" alt="Deep Learning" width="300"> <p>DL由機器自行去學習尋找哪些特徵對於這個任務是重要的。</p> </div> ### 常用的數學工具 #### Sigmoid function 一個常被作為activate function的non-linear function,定義如下 $$ \sigma(z) = \frac{1}{1 + e^{-z}} $$ <div style="text-align: center;"> <img src="https://hackmd.io/_uploads/ryJMRZP3A.png" alt="Sigmoid Function" width="350"/> </div> Sigmoid 函數可以將實數範圍的輸入對應至[0,1]範圍內,並有著特點: - **平滑性**:函數是連續的,且導數也連續。 - **非線性**:能夠引入非線性因素,使模型能夠學習複雜的數據模式。 #### Softmax 將一組k維向量σ對應至另一組k維向量σ(z),並且σ(z)中的每個元素範圍都在(0,1)之間,所有元素總和為1。 ![截圖 2024-09-18 晚上9.33.01](https://hackmd.io/_uploads/rkiiII_60.png) ### A Single Neuron * 單一Neuron的功能為將“別人傳過來的很多資訊(x~1~,x~2~....,x~N~這個N維向量 )做一些運算後,再傳y這個數值)給其他人”。 * 我們將Neuron輸出的數值y與threshold(通常為0.5)做比較,**bias用來調整要讓 input向量X 多容易使得輸出 數值y 超過threshold**。 ![Single Neuron](https://hackmd.io/_uploads/BylcxeDhC.png) ### Fat + Shallow vs. Thin + Deep ? <figure> <img src="https://hackmd.io/_uploads/rJYwXev2R.png" alt="Fat + Shallow vs. Thin + Deep"> <figcaption>越深的模型能用較少的參數量來達到和淺模型一樣好的效果。</figcaption> </figure> --- ## Lecture 1 : Neural Network Basics ### Classification Task #### 依照輸出的可能數量分為 * **Binary Classification** : 輸出只有yes或no 例子: Sentiment Analysis - 判斷一個句子的語意為正面(yes),負面(no) * **Multi-class Classification** : 輸出種類大於2種 例子: Speech Phoneme Recognition, Handwritten Recognition #### Vector Representation ![function](https://hackmd.io/_uploads/SkTJqlP20.png) ![Handwriting Classification Example](https://hackmd.io/_uploads/H1eEqew30.png) vector X 內的數值為從 input image 中取得的特徵(以圖片辨識為例-當該像素有顏色,則對應的數值為1,反之為0)。將X輸入函數f後,輸出vector Y,Y為**One-Hot Vector**,即向量內只有一個元素為1,代表屬於那個分類;其餘均為0。 ### Perceptron - A Layer of Neurons ![A Layer of Neurons](https://hackmd.io/_uploads/r1th0ev2C.png) 只有一層Neurons的model我們稱之為Perceptron,Perceptron只能做線性的分類(如:AND,OR,NOT),但沒辦法做非線性(如:XOR)。 ### Neural Networks – Multi-Layer Perceptron 為了能表示更複雜的函數(如:XOR),因此將Neurons層層堆疊。 ![Multi-Layer Perceptron](https://hackmd.io/_uploads/Hk8ckZvnC.png) ### 符號定義 $$ x為一個向量,代表整個模型初始的輸入 $$ $$ a_i^l為第l層的第i個Neural的輸出; $$ $$ a^l為一個長度N_l的向量,代表著第l層的N_l個Neural的輸出;$$ $$ W^l為一個大小為N_l*N_{l-1}的二維陣列,代表第l-1層的N_{l-1}個Neurals傳遞至第l層的N_l個Neurals的權重關係;$$ $$ \mathbf{z}^l = \mathbf{W}^l \mathbf{a}^{l-1} + \mathbf{b}^l $$ $$ \mathbf{a}^l = \sigma(\mathbf{z}^l) $$ ![截圖 2024-09-05 晚上7.01.32](https://hackmd.io/_uploads/S1S0yzPnA.png) ![截圖 2024-09-05 晚上7.01.50](https://hackmd.io/_uploads/ryJZlGD2A.png) ![截圖 2024-09-05 晚上7.02.10](https://hackmd.io/_uploads/S1B-lGwhR.png) ![截圖 2024-09-05 晚上7.03.41](https://hackmd.io/_uploads/rJjQgGw3C.png) ### Neural Network Formulation $$ y = f(x) = \sigma(W^l...\sigma(W^2\sigma(W^1x+b^1)+b^2)+...+b^l) $$ $$ 代表這個model的參數\ \theta = \{W^1,b^1,W^2,b^2...,W^l,b^l\} $$ ![Neural Network Formulation](https://hackmd.io/_uploads/HkNn-fw2R.png) ### 如何評估模型的好壞? 定義一個函數來評估模型的好壞,評估模型有多好(O)或多差(C) ![cost function & reward function](https://hackmd.io/_uploads/r11enzvhC.png) $$ 以\ supervise\ learning\ 為例 $$ $$ 目標: 預測的和真實的資料越接近越好 $$ $$ => 預測值\ f(x;\theta)\ 很接近真實值\ y $$ $$ => |y-f(x;\theta)|\ 很接近\ 0 $$ $$ 因此定義\ C(\theta)\ = \ \Sigma\ |y-f(x;\theta)|$$ 一些常見的loss functions ![some loss functions](https://hackmd.io/_uploads/Hy12hzPn0.png) ### Optimization $$ 目標: 尋找合適的參數\ \theta\ 使得C(\theta)\ 的值最小 $$ $$ \text{方法:} $$ $$ \text{1. Brute force:遍歷所有可能的 } \theta $$ $$ \text{2. Calculus:將 } C(\theta) \text{ 對 } \theta \text{ 做偏微分} $$ 以下介紹一系列基於Calculus的優化方法。 #### Gradient Descent **一次用全部訓練集**的數據去計算損失函數的梯度就更新一次參數。 ![Gradient Descent with 1 variable](https://hackmd.io/_uploads/HJFlKW_h0.png) 以上是單一參數的Gradient Descent示意圖,將loss function C對θ做偏微,並將參數θ減去偏微後的數值乘上learning rate η。 η(讀作/ita/)代表的意義為學習的過程中**調整的步伐要多大**。 ![Gradient Descent with 2 variables](https://hackmd.io/_uploads/SyTJoWu3C.png) 以上為雙參數的例子 ![Gradient Descent for Neural Network63](https://hackmd.io/_uploads/H1-4pzdnR.png) ![截圖 2024-09-06 下午2.14.17](https://hackmd.io/_uploads/SkNEAzO20.png) Example - Square error loss ![截圖 2024-09-06 下午2.16.49](https://hackmd.io/_uploads/SkddAfOh0.png) #### Stochastic Gradient Descent(SGD) 隨機梯度下降法 每次隨機抽取**一個樣本**,計算梯度並更新。 * 優點: 頻繁地更新,更容易跳出局部最佳解(local optimal) * 缺點: 不穩定 ![截圖 2024-09-06 下午2.38.01](https://hackmd.io/_uploads/B1cDQQO30.png) #### Mini-Batch SGD **一次跑一個小批次(mini-batch)樣本**然後算出一次梯度或是小批次梯度的平均後就更新一次。每次抽取的mini-batch是隨機的。 ![截圖 2024-09-06 下午2.43.50](https://hackmd.io/_uploads/Sy5aNmdnC.png) #### training time Modern computers run **matrix-matrix multiplication**(mini-Batch) faster than matrix-vector multiplication(SGD) ![截圖 2024-09-06 下午2.46.33](https://hackmd.io/_uploads/S1LKrQO3C.png) ### Backpropagation 反向傳播 類神經網路有個缺點是有著大量的重複計算,Backpropagation(反向傳播) 的精髓就在於利用鏈鎖率(Chain rule),有效地從輸出層(末端)開始逐層向前計算各層權重對於損失的影響,**減少計算量**。 ![Chain rule](https://hackmd.io/_uploads/SJgq0Pd3A.png) $$ Backpropagation的計算分為兩個部分,\frac{\partial z_i^l}{\partial w_{ij}^l}的計算為forward\ pass, \frac{\partial C(\theta)}{\partial z_i^l}的計算為backward\ pass $$ Forward: ![截圖 2024-09-06 晚上8.00.58](https://hackmd.io/_uploads/SkBf1ud3C.png) Backward: 定義δ為 loss function C 對於某一層某個Neural輸入z的偏微分 ![Neural Network with δ](https://hackmd.io/_uploads/HypIkOd2C.png) ![Initialization: compute δ^l](https://hackmd.io/_uploads/r1pJb_u3R.png) ![Relationship: compute δ^l based on δ^(l+1)](https://hackmd.io/_uploads/SJ_Q-u_2R.png) ![截圖 2024-09-06 晚上8.23.33](https://hackmd.io/_uploads/rkdDNuuhA.png) ![Remarks](https://hackmd.io/_uploads/HkdtDdu2R.png) --- ## Lecture 2 : Sequence Modeling, Attention, Transformer ### Word Representations 用機器看得懂的方式表示詞彙 有兩種表示方式: * **Knowledge-Based Representation**: 透過語文學家定義詞彙間的關係,建立**WordNet**。 ![WordNet Sample](https://hackmd.io/_uploads/SJguKBc9nA.png) 缺點: 1. 由於新詞彙會不斷出現,沒辦法涵蓋所有詞彙。 2. 主觀 3. 不容易根據距離定義兩個字間的相似性,如:(motorcar, go-kart)和 (compact, motor vehicle)距離都是2,但一組的關係為sibling,另一組為grand parent。 * **Corpus-Based Representation**: 起初想將每個字作 one-hot representation,但是有相似關係的兩個相異字為正交(orthogonal),不容易計算similarity(AND起來都變成0)。於是後來出現**考慮哪些字常一起出現**的**Neighbor-based** representation。 * Window-Based Co-occurence Matrix 直接計算每對 words pair 相鄰的次數。 ![Window-Based Co-occurence Matrix Example](https://hackmd.io/_uploads/BkTWo95nR.png) 缺點 - sparsity : Matirx內大部分元素都是0,浪費空間,效率低。 * Low-Dimentional Dense Word Vector 方法: 1. 用SVD分解降維 - 計算困難... 2. Directly learn low-dimentional word vector 一些著名方法: word2vec, Glove ### Word Embeddings 詞嵌入 把一個維數為所有詞的數量的**高維空間嵌入到一個維數低得多的連續向量空間**中。 #### Word2Vec [Visualization tool](https://ronxin.github.io/wevi/) ![截圖 2024-09-08 中午12.09.50](https://hackmd.io/_uploads/rkS_4s5h0.png) ![Word2Vec Variants](https://hackmd.io/_uploads/HJ9JHj530.png) #### Glove ![Comparison](https://hackmd.io/_uploads/SJ_fd2qh0.png) ![Glove Explanation](https://hackmd.io/_uploads/BJw2IjchA.png) #### Word Vector Evaluation * Intrinsic: 直接用單詞的類比問題評估 Word Analogies: Wa:Wb = Wc:Wx => 用Word a,b,c推測x Word Correlation: 比較人類標註詞彙間的similarity score與機器標注的score * Extrinsic: 用下游任務表現的好壞來評估 ### Language Modeling 目標: 評估一段文字出現的機率 #### N-gram language model **只考慮前n-1個字**來決定第n個字出現什麼的機率。(太久以前出現的字對現在的影響小到可以忽略) ![N-gram language model formula](https://hackmd.io/_uploads/Hkvg02c2R.png) 缺點: 並不是所有可能的sequences都出現在訓練資料集內。 #### Neural Language Modeling ![Neural Language Modeling idea & sample](https://hackmd.io/_uploads/S1zsJpchC.png) #### Recurrent Neural Network Language Modeling (RNNLM) 有**記憶力**的神經網路,過去出現的資訊透過hidden stage(藍色箭頭)傳播到後面。 ![RNN sample](https://hackmd.io/_uploads/Bk-HZaqhA.png) ### RNN (Recurrent Neural Network) 架構圖: ![Recurrent Neural Network Definition](https://hackmd.io/_uploads/Byo1mT9nA.png) 訓練方式(類似一般NN): ![RNN model training](https://hackmd.io/_uploads/SJel2j63R.png) #### Backpropagation through Time (BPTT) ![截圖 2024-09-10 晚上7.44.26](https://hackmd.io/_uploads/r15dWnahA.png) ![截圖 2024-09-10 晚上7.44.48](https://hackmd.io/_uploads/ByZt-n630.png) RNN的training issue: * 對於RNN的error signal δ每往前傳一次要乘上一次W,最後乘了很多次W,所以會導致gradient最後乘起來不是變很大(exploding gradient)就是變很小(vanishing gradient)。 ![RNN training issue](https://hackmd.io/_uploads/BkZcaiTnC.png) 對應到error surface就是有些位置很緩,有些位置很陡,不利於學習。 ![Error Surface](https://hackmd.io/_uploads/ry2I4npnA.png) * Exploding gradient解法:Clipping 當gradient大於某個值時,將其下降某個比例。 ![Clipping](https://hackmd.io/_uploads/S14grhpnR.png) * Vanishing Gradient解法:Gating 做一些小門,讓某些通道直接通過去到後面,不用乘上中間的一些matrices。 解決了傳統的 RNN 在長時間的記憶表現並不好的問題(少乘幾次 -> 權重下降的沒那麼快 -> 忘得沒麼快,記憶力提升) ![截圖 2024-09-10 晚上8.06.13](https://hackmd.io/_uploads/B1MUI36hR.png) 著名例子: Long Short-Term Memory (LSTM), Gated Recurrent Unit (GRU) --- ## Lecture 3 : Attention Mechanism * 概念:**不同時間注意在encoding的不同地方**。 * 想解決的問題:當任務的類型為**seq2seq**(輸入為一串資料,輸出也為一串資料)時,用RNN一個字一個字逐一計算(encoding),當輸入很長時,經過多次神經元的運算,**開頭的資訊可能會遺失**。 * 解決方式:讓輸入的資料不會因為遠近而有所不同,而且可以比較注意當前需要用到的資訊片段。 -> 每個步驟都計算一個向量Z,用Z表示要**注意輸入資料的哪個部分**。 ### Machine Translation with Attention ![截圖 2024-09-18 上午11.58.34](https://hackmd.io/_uploads/BJwblAw6R.png) ![截圖 2024-09-18 上午11.59.44](https://hackmd.io/_uploads/SJRHlCP6A.png) ![截圖 2024-09-18 中午12.03.09](https://hackmd.io/_uploads/rJ5zbADaA.png) ![截圖 2024-09-18 中午12.00.57](https://hackmd.io/_uploads/H1wceCPa0.png) ![截圖 2024-09-18 中午12.03.51](https://hackmd.io/_uploads/rJMrbCP6R.png) ![截圖 2024-09-18 中午12.04.28](https://hackmd.io/_uploads/HydDbCDp0.png) ### Dot-Product Attention ![Dot-Product Attention formula](https://hackmd.io/_uploads/S1b3lU_6C.png) ### Attention的應用 最早用於電腦視覺,現在則應用在NLP,語音辨識(聲音轉文字),圖像辨識(圖片轉文字),影像辨識。 ## Lecture 4 : Transformer ### Self-Attention [論文-Attention Is All You Need](https://arxiv.org/pdf/1706.03762) * 任兩個輸入之間位置的距離相同 -> 不易受距離順序影響 * 易於**平行運算** -> 將向量合併成矩陣再運算 * 缺點: **缺乏**序列中文字**位置的資訊**,所以只要句子中包含一樣的字,就會獲得同樣的資訊,如“我愛你”和“你愛我”文字相同,但意思不同。 encoding向量a^1^,a^2^,...各自乘上矩陣 W^q^, W^k^, W^v^而獲得向量**query vecter q^1^, q^2^**,...和**key vecter k^1^, k^2^**,...和**value vecter v^1^, v^2^**,...。 將其中一個query q與其他key k做內積,獲得各個位置的attention score a,代表這個位置的資訊此時的重要程度(權重)。 我們在訓練模型就是在**調整矩陣 W^q^, W^k^, W^v^的值**。(通常會直接將a的值當成query,所以取W^q^為identity matrix) ![截圖 2024-09-18 晚上9.59.07](https://hackmd.io/_uploads/Bk262UdT0.png) $$ q^1 = W^qa^1 \qquad q^2 = W^qa^2 \qquad ... $$ $$ k^1 = W^ka^1 \qquad k^2 = W^ka^2 \qquad ... $$ $$ v^1 = W^va^1 \qquad v^2 = W^va^2 \qquad ... $$ 將 向量query q 乘上 向量key k **合併為矩陣相乘**的形式,易於之後加速做平行運算。 矩陣A經過softmax處理成為矩陣A'。 ![截圖 2024-09-18 晚上10.00.26](https://hackmd.io/_uploads/Sy4Ep8da0.png) ![截圖 2024-09-18 晚上10.00.51](https://hackmd.io/_uploads/S1TVp8daC.png) ### Multi-Head Attention * 概念:把不同的資訊分開來,每組 query q 專注於不同的面向上。 待補充... ### Transformer * 想解決的問題:Self-Attention**缺乏對於空間,順序上的資訊**。 * 解法:**positional encoding** allows word at different locations to have different embeddings with fixed dimensions. (把位置的資訊一起encode進去) #### Positional Encoding ![截圖 2024-09-19 上午10.42.52](https://hackmd.io/_uploads/rJOpkfFT0.png) 將原本的Multi-Head Attention加上Positional Encoding: ![截圖 2024-09-19 上午10.51.52](https://hackmd.io/_uploads/BkFkGGFaR.png) 小結: ![Transformer Remark](https://hackmd.io/_uploads/HyAvfGY6C.png) ## Lecture 5 : Tokenization, BERT ### Tokenization 可以理解為把一段長資料切割成數個短資料單位,用這個短資料單位來理解文字的意思。 #### Byte-Pair Encoding (BPE) 將出現次數最多的pair以資料中沒有出現的新位元組替換,重複直到覺得VOCAB的位元組數量夠多為止。 以下為BPE Tokenization的示意流程: ![BPE DEMO 1](https://hackmd.io/_uploads/HytqdGYaA.png) ![BPE DEMO 2](https://hackmd.io/_uploads/SkR5ufYaC.png) pair(e,s)和pair(t,</w>)出現最多次,任選一組合併。(例子選pair(e,s))於是,VOCAB中新增位元組"es"。 ![BPE DEMO 3](https://hackmd.io/_uploads/SkrjOGYp0.png) ![BPE DEMO 4](https://hackmd.io/_uploads/BkONqMKp0.png) ![BPE DEMO 5](https://hackmd.io/_uploads/ryF4cfKaC.png) ![BPE DEMO 6](https://hackmd.io/_uploads/S1ONqfYpA.png) ![BPE DEMO 7](https://hackmd.io/_uploads/BJOE5ft60.png) ![BPE DEMO 8](https://hackmd.io/_uploads/rJOV9MY6C.png) ![BPE DEMO 9](https://hackmd.io/_uploads/r1u4cfF6R.png) ![BPE DEMO 10](https://hackmd.io/_uploads/B156cMt6A.png) ![BPE DEMO 11](https://hackmd.io/_uploads/B1569ftpR.png) ![BPE DEMO 12](https://hackmd.io/_uploads/r1pftmYT0.png) ### BERT [論文 - BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding](https://arxiv.org/abs/1810.04805) ![BERT idea #1 - MASK](https://hackmd.io/_uploads/SJv3H7_yJe.png) ![BERT idea #2 - Next Sentence Prediction](https://hackmd.io/_uploads/B1yU8NO11x.png) ![BERT fine-tuning](https://hackmd.io/_uploads/B17zON_kJl.png) 上圖說明:原始的 BERT model 過於general,原本當我們要做特定任務時就要重新訓練模型來配合新任務。後來提出一個新概念為 **Fine-tuning** 是指在一個預訓練 (**pre-trained**) 好的模型(如BERT)的基礎上,通過**少量的訓練資料對模型進行調整**,以適應特定任務。 ## Lecture 6 : NLG (Natural Language Generation) 很多事情與自然語言生成有關,如:翻譯, 摘要, 對話等。 ### Decoding Algorithm 概念:當我們有一個訓練好的模型,生成出一個機率分佈後,decoding algorithm 的功能為**決定要生成什麼字**。 #### 1. Greedy 根據之前生成的字生成**機率最高的下一個字**。 ![Greedy](https://hackmd.io/_uploads/BkotQBdyJe.png) 缺點 - 只關注local optimal,會重複產生一樣的句子。 #### 2. Beam Search 每一步只追蹤**機率最高的前k個sequence**。 ![Beam Search](https://hackmd.io/_uploads/S1wvNH_Jke.png) ![Beam size effect](https://hackmd.io/_uploads/HJXhzcd1kl.png) beam size 大小的 trade off: * 小 beam size : 比較focus在topic上,但可能會較為**不通順** * 大 beam size : 很safe,**general**,但**不符合當下的使用情境** #### 3. Top-k Sampling 限制**只從出現機率前 k 高**的字裡來sample出要輸出的下一個字。 ![Top-k Sampling](https://hackmd.io/_uploads/r1U--4t11g.png) Top-k sampling issue: * **Narrow Distribution**: 當機率都在少數幾個(x個)字上面,而 x << k,則可能會sample到出現機率較低,不適合的字。 ![narrow distribution example](https://hackmd.io/_uploads/H1JwfNKykl.png) * **Broad Distribution**: 若每個字出現的機率都差不多接近時,使用 top-k sampling 反而會限制其輸出的多樣性。 ![broad distribution example](https://hackmd.io/_uploads/rJfaGVFkJg.png) #### 4. Nucleus(Top-p) Sampling * 想解決的問題: Top-k Sampling 沒辦法根據詞彙的機率分佈來調整 sampling 的詞彙數。 * 概念: 根據distribution來改動top-k的k值,只**sample機率累加超過p的set**。 當distribution越 narrow,只需要從越少的詞彙數中sample;當distribution越 Broad,需要從越多的詞彙數中sample。 ![Nucleus(Top-p) Sampling](https://hackmd.io/_uploads/H1zClEFyyg.png) ### Generation Control #### Temperature τ * 功能: 一個調控模型輸出**多樣性**, **穩定性**的手段。 * 效果: **τ 越大**,會使每個詞的機率分佈變更**uniform**,增加模型sample不一樣詞彙的機率(**多樣性**);**τ 越小**,會使每個詞的機率分佈變更**narrow**,使模型更趨向於sample少數詞彙(**穩定性**)。 ![Temperature](https://hackmd.io/_uploads/B1gAkuK1yg.png) #### Repetition Penalty * 想解決的問題: 當模型沒有訓練好的話,**容易產生重複的句子**( 寫過HW2就知道:) ),因為模型是根據輸入的內容來生成句子。當輸入屬於某個topic時,生成出與該topic相關的詞彙的機率會上升,進而容易重複sample出那些詞彙。 * 解法: 當某個詞彙被sample出來後,**下降**該詞彙被sample出來的**機率**。 ![Repetition Penalty](https://hackmd.io/_uploads/rJB9edK1Je.png) ### Evaluation Automatic evaluation 又可分為 **Word overlap** metrics 和 **Embedding** metrics。 **Word overlap** metrics 考慮模型生成的句子與ground truth之間**用詞的相似性**,如:BLEU, ROUGE, METEOR。 **Embedding** metrics 評估兩個句子在hidden layer是否相近(意思是否相近,而不是單純比較用詞)。 #### BLEU [論文 - BLEU: a Method for Automatic Evaluation of Machine Translation](https://aclanthology.org/P02-1040.pdf) 基於 N-gram overlap,考慮 **precision** - 模型產生的句子的n-gram是否是正確的(有出現在正確答案句子的n-gram裡面)。 ![BLEU](https://hackmd.io/_uploads/B1wxCpYk1e.png) #### ROUGE (Recall-Oriented Understudy for Gisting Evaluation) [論文 - ROUGE: A Package for Automatic Evaluation of Summaries](https://aclanthology.org/W04-1013/) 基於 N-gram overlap,考慮 **recall** - 正確答案句子的n-gram是否被包含在模型產生的句子的n-gram裡面。 ![ROUGE](https://hackmd.io/_uploads/BylddRTKJ1l.png) ## Lecture 7 : Prompt Based Learning ![Three Types of Model Pre-Training](https://hackmd.io/_uploads/HJCA7qq1yg.png) ### Prompt Tuning x-Shot 的意思是先給模型x個例子,才問模型問題。 ![GPT-3 “In-Context” Learning](https://hackmd.io/_uploads/H1ZfOqq1Je.png) Question: 現在的LLM參數量太大了,當我們沒有足夠的運算資源去訓練,改變其內部參數,還能做什麼呢? Ans: 適當地下prompt能夠去影響模型的output。 ![Prompt Tuning](https://hackmd.io/_uploads/BJptt9ckJx.png) ![P-Tuning](https://hackmd.io/_uploads/Symlhc9kJx.png) ![Prefix-Tuning](https://hackmd.io/_uploads/rJguwhc9Jyx.png) ## Lecture 8 : Adaptation ### PEFT (Parameter-Efficient Fine-Tuning) #### Adapter ![Adapter](https://hackmd.io/_uploads/ryd_fsRkyl.png) #### [LoRA](https://arxiv.org/abs/2106.09685) ![LoRA](https://hackmd.io/_uploads/SyerMiRyyx.png) --- ## Homework 1: Chinese Extractive Question Answering (QA) 作業一要參加一個舉辦在Kaggle平台上的機器學習比賽-[連結](https://www.kaggle.com/competitions/ntu-adl-2024-hw-1-chinese-extractive-qa/data)。這次的任務要訓練模型**根據給定的四個文章段落來回答一個問題**,助教保證問題可以根據四個文章中的其中一個來回答,並且檢查答案的機制為Exact Match (EM)。 ### 任務流程圖 ![hw1 任務流程圖](https://hackmd.io/_uploads/rJXocWk0A.png) 上圖說明: 整個流程又可以分為兩個子任務。第一個任務為**從四個文章中找出問題的答案藏在哪個文章內**(4選1的單選題);第二個任務為**從一個給定的文章內找出某個問題的答案所在的位置**(輸出的形式會像是從第x個字元到第y個字元)。 ### [資料](https://www.kaggle.com/competitions/ntu-adl-2024-hw-1-chinese-extractive-qa/data) & 環境說明 | **檔名** | **說明** | |--------------------|------------------------------------------------------------------------------------------| | context.json | 一個包含所有文章的list。 | | train.json | 含21714筆用於訓練模型的標記訓練集。(標記:有正確答案的意思) | | valid.json | 含3009筆用於訓練模型或驗證的標記驗證集。 | | test.json | 含2213筆未標記的測試集。(比賽方在檢查的就是你的模型在test.json的作答情形) | | sample_submission.csv | 一個樣本提交文件。您應該以相同的格式提交您的提交。 | | **欄位** | **說明** | |--------------------|------------------------------------------------------------------------------------------| | id | 問題 ID。 | | question | 問題。 | | paragraphs | 一個包含 4 個段落 ID 的列表(0-base)。 | | relevant | 相關段落的 ID(0-base)(test.json 沒有這部分)。 | | answer | 問題的答案(test.json 沒有這部分)。 | | text | 答案文本。 | | start | 答案範圍在相關段落中的起始位置。 | 執行於 **Python3.10** 環境 建議用 [Miniconda](https://docs.anaconda.com/miniconda/) 開 conda 虛擬環境。 ```bash= # 下載並啟用miniconda mkdir -p miniconda3 wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda3/miniconda.sh bash miniconda3/miniconda.sh -b -u -p miniconda3 rm miniconda3/miniconda.sh source miniconda3/bin/activate # 創建並啟用 python3.10 虛擬環境 conda create -n ADL_HW1_env python=3.10 conda activate ADL_HW1_env ``` ### 任務一方法 第一個任務要我們讓模型**從4個文章中選擇出有給定的問題的答案的文章(4選1單選題)**,所以我們可以套用[**MC sample code**](https://github.com/huggingface/transformers/blob/main/examples/pytorch/multiple-choice/run_swag_no_trainer.py)來fine tune模型,模型可以從[這裡](https://huggingface.co/models)選(我的作法是選[chinese-bert-wwm](https://huggingface.co/hfl/chinese-bert-wwm),也有人用[chinese-roberta-wwm-ext](https://huggingface.co/hfl/chinese-roberta-wwm-ext))。Sampel code名稱中的[SWAG](https://huggingface.co/datasets/allenai/swag/blob/main/README.md#data-instances)為一種定義好的資料格式,有 sent1, sent2, ending0, ending1, ending2, ending3, label...等欄位。 #### 任務一第一件難事 把 train.json 和 valid.json 中的欄位 question, paragraphs, relevant 轉換為 SWAG格式 中的 sent1, sent2 ...。 其對應可以參考[ADL-2024-HW1-SWAG資料](https://huggingface.co/datasets/Binga288/ADL-2024-HW1-SWAG)。 其中,sent2 的部分我直接以 “*請問上述問題的答案出現在以下哪個文章內?*” 取代。 ``` 文章為sent1;問題為sent2;四個選項分別為ending0~3;label為問題根據文章內容從四個選項選出的正確答案的index ``` 接好後就可以開始train(fine tune)了。 #### 任務一第二件難事 fine tune 完後可以在 \-\-output_dir 資料夾內獲得模型的資料,但由於 sample code 沒辦法直接 inference test data,所以我們要稍微改動一下 sample code 讓它的功能從 fine tune 變為 inference。 觀察一下程式碼會發現最後幾行有一段程式碼似乎可以利用,這段程式碼原本的功能為預測 validation data 的 tag。 ```python= predictions = outputs.logits.argmax(dim=-1) ``` 我們可以將 test.json 丟到原本 valid.json 的位置,如此一來上面這段程式碼就會變成去預測 test data 的 tag,將 predictions 記錄下來,即可知道 test.json 內每個題目的答案所可能在的文章是哪個。(這部分概念簡單,但實際要改的東西很多) [註] 在 inference 時,參數 *model_name_or_path* 放跟之前 fine tune 時的參數 *output_dir* 一樣即可,裡頭有模型的種類,權重(model.safetensors)等參數資訊。 **[注意] 在inference時,記得刪除 metric = evaluate.load(...),這個步驟需要連接到 hugging face 的網站。** ### 任務二方法 第二個任務要**拿第一個任務輸出的文章當輸入,並從文章內截取出問題的答案**(QA)。我們可以套用[**QA sample code**](https://github.com/huggingface/transformers/blob/main/examples/pytorch/question-answering/run_qa_no_trainer.py)來fine tune模型,模型可以選擇[chinese-lert-large](https://huggingface.co/hfl/chinese-lert-large)或 [bert-base-chinese](https://huggingface.co/google-bert/bert-base-chinese)。sample code所讀取的資料格式為[squad](https://huggingface.co/datasets/rajpurkar/squad),有 id, title, context, question, answers 欄位。 ``` 任務一輸出的文章為context;問題為question;標準答案的內容與起始位置為answers ``` 接好後就可以開始train(fine tune)了。 任務二的 sample code 比任務一的 sample code 好的一點在於有寫 inference 的邏輯,但若你和我一樣 fine tune 和 inference 是分兩步執行的話,要記得把程式碼內 training 和 validation 的部分刪除。 **[注意] 在inference時,記得刪除 metric = evaluate.load(...),這個步驟需要連接到 hugging face 的網站。** inference 完的輸出放在 output_dir 內的 eval_predictions.json,儲存方式類似 `"7f4f68726faed6b987e348340a9e6a61": "\u77f3\u6cb9"`,key 是 id,value 是 answer,要將 answer 的 unicode 編碼轉換為中文。 [註] 當初第一次 fine tune QA model 時,seed 設很大,結果 valid_Acc 超低;第二次 seed 設為 1,valid_Acc 很好,但是 test_Acc 為 0;最後我又試了另一個 seed 後,valid_Acc 和 test_Acc 的效果都接近80%。 如果 inference 效果不好時,可以考慮換個 seed 再試看看。 ### Bonus 任務 Bonus 部分要求我們訓練一個 end-to-end model ,目標是單一 model 能夠直接運用給定的 test.json 及 context.json 得到所要求的結果,而不需如先前一般使用兩個模型分開 inference。助教給出的建議是使用能夠接受較長 input 的 bert 變體來做 fine-tuning ,這固然是可行的方法之一,但目前 huggingface 上能接受此類 Question Answering 接口的 long-form bert variants 模型並不多。事實上,我們可以仿造先前任務二中運用 window_size 與 doc_stride 的演算法來做處理。該演算法將一段長度大於 512 的 paragraph 進行切割處理,每隔 doc_stride 的距離切一刀,並自動取一段適當的文章範圍與問題本身合併,進行 padding 後作為 bert 的 input 輸入。文章會因此被分為多段,我們可將 test.json 中給出的四段可能文章合併成一長串,並紀錄在每個 window 中所採集的 max(prob_start + prob_end) 位置作為該切片中最有可能的答案(此處可進行 top_k 過濾以得到更準確的結果),接著考慮所有文章切片,取其中機率總和最高者即可。 [註] 此方法甚至不需要重新訓練模型,只需要取先前任務二中訓練的便能完成,且理論上準確度並不會和基礎任務相差太多,甚至可能更好 ### 相關連結 [Kaggle比賽連結](https://www.kaggle.com/competitions/ntu-adl-2024-hw-1-chinese-extractive-qa) [助教說明投影片](https://docs.google.com/presentation/d/1V5KE-AOTiVXWZjMVnr3GXyy_EjEMHeRKfeyudyeevl8/edit#slide=id.p) [NLP Course - Question answering](https://huggingface.co/learn/nlp-course/en/chapter7/7?fw=pt) --- ## Homework 2: Chinese News Summarization (Title Generation) 作業二要我們 fine tune 一個 model,讓 model **做中文新聞文章摘要**,並用 [**ROUGE** score](#ROUGE-Recall-Oriented-Understudy-for-Gisting-Evaluation) 來評估我們訓練的 model 的輸出與標準答案的相似程度,分數越高代表越相似。我們的目標是讓訓練完的模型在 public 和 private test case 上的 rouge score 大於 baseline。 ### 任務示意圖 ![Chinese News Summarization Example](https://hackmd.io/_uploads/HkhDZ9BJJx.png) 上圖說明:模型讀入一個文章,生成出其摘要 ![Rouge score Example](https://hackmd.io/_uploads/SJd9wxUJyx.png) 上圖說明:這是bench mark,比較模型生成的摘要與參考答案的相似程度 ### [資料](https://drive.google.com/drive/folders/1PMa25MwIVWTRhUtkWTfBFgqbqmGAxG2-) & 環境說明 | **檔名** | **說明** | |--------------------|------------------------------------------------------------------------------------------| | train.jsonl | 含**21710**筆資料,每筆資料的結構為{"date_publish", "**title**", "source_domain", "maintext", "split", "id"},"split"鍵的值固定為"train"。 請自行切割成 train 和 validation set 來訓練模型。 | | public.jsonl | 含**5494**筆資料,結構同上, "spilt"鍵的值固定為"dev"。 這個檔案為 public testcase 的內容,**請勿用它來 train 模型**!! | | sample_test.jsonl | 結構為每列有{"date_publish", "source_domain", "maintext", "split", "id"}。**沒有"title"**,因為"title"是這個模型要預測的東西。| | sample_submission.jsonl | 結構為每列有{"title", "id"} | | 欄位 | 說明 | | -------- | -------- | | "title" | 關於報導內容的重點摘要(這是模型要預測的東西) | | "maintext" | 完整文章報導內容 | 執行於 **Python3.8.10** 環境 ### 任務方法 從cool討論區看起來可以使用 [**Sum sample code**](https://github.com/huggingface/transformers/blob/main/examples/pytorch/summarization/run_summarization_no_trainer.py) 來 fine tune [**mt5-small**](https://huggingface.co/google/mt5-small) 。 打開data資料夾會發現裡頭只有提供 train data,可以先自行將其分割成 train 和 validation data(我的比例是19:1,但 validation data 不會影響模型更新權重的過程,因此以作業分數為導向的話可以試著降低 validation data 的比例)。接著就可以開始訓練模型了,以下是一些可以調整的參數 - 1. train時 (python指令傳入的): **batch_size**, **learning_rate**, **epochs**。 2. inference時 (使用 Transformers 庫中的 generate 方法進行文本生成時的參數,在 sample code 裡於變數 gen_kwargs 內設定): **num_beams**, **top_k**, **top_p**, **temperature**, repetition_penalty, length_penalty。若使用除了 beam search, Greedy 之外的具有**隨機性**的策略,要在 generate 函數中傳入 **do_sample=True**,代表隨機取樣(不傳的話預設 do_sample=False,會導致無論怎麼改 top_k, top_p, temperature 的值 inference 結果都一樣)。 此外,助教在執行 inference 的環境是斷網的,若用到 [nltk](https://www.nltk.org/) 的 tokenizer 請預先下載好,並把它加入環境變數內。 **[注意] 在inference時,記得刪除 metric = evaluate.load(...),這個步驟需要連接到 hugging face 的網站。** Report 部分需要我們在訓練模型的過程畫出 ROUGE Score v.s. training steps 的圖,我每訓練 1 epoch 做一次 inference valid dataset 並用eval.py檢驗輸出的ROUGE score。當 epoch==0 時,模型還沒學到任何東西,因此可能在摘要內輸出包含"(雙引號)的字串。當執行 [eval.py](https://github.com/deankuo/ADL24-HW2/blob/master/eval.py) 解析輸出的 jsonl 檔時會出現錯誤,需要對 inference 輸出的字串做預處理-把每個\"(雙引號)前加上\\(跳脫字元)。 ```python= pred_ = pred.replace('\"', '\\\"') # 將 " 替換為 \" ``` 想要簡單一點就從 epoch == 1 才開始做 inference,就不會在摘要內出現"(雙引號)了。 ### Bonus 任務 Bonus 部分要求我們試著將 GPT-2 應用在摘要生成上。這項任務其實對 GPT-2 挺困難的,因為 GPT-2 擅長的是僅根據上文選擇機率最高的字作為下一個輸出,因此無論是否經過微調,改善的幅度都非常有限。要完成 Bonus ,會需要在 Report 中解釋 GPT-2 的 architecture 和你使用的超參數,並且使用任何和 GPT-2 相關的模型(有無微調皆可)輸出摘要,計算 ROUGE score 再和 T5 的結果進行比較即可,沒有意外的話效果應不如 T5 。順帶一題,我選擇使用的 prompt engineering 方法似乎能夠使模型的輸出「稍微」自然一些(但效果依然很差)。 ### Baseline 用 [**ROUGE** score](#ROUGE-Recall-Oriented-Understudy-for-Gisting-Evaluation) 來評估模型**輸出和參考答案間的相似程度**,數值越高代表越相似。表格內的值為 f1-score * 100 。 #### public test case | rouge-1 | rouge-2 | rouge-L | | -------- | -------- | -------- | | 22.0 | 8.5 | 20.5 | #### private test case 作業截止後才會公布。 | rouge-1 | rouge-2 | rouge-L | | -------- | -------- | -------- | | 23.6 | 9.3 | 21.3 | ### 相關連結 [助教說明投影片](https://docs.google.com/presentation/d/1C9dhFQvz--9sDtjGukSL6Lmfp8CPQgmG/edit#slide=id.p1) [Hugging Face從零到一 — 從初始化到fine tune教學](https://shengyanlin0503.medium.com/hugging-face%E5%BE%9E%E9%9B%B6%E5%88%B0%E4%B8%80-%E5%BE%9E%E5%88%9D%E5%A7%8B%E5%8C%96%E5%88%B0fine-tune%E6%95%99%E5%AD%B8-da0f19c74acc) [Fine-tuning the multilingual T5 model from Huggingface with Keras](https://medium.com/@radicho/fine-tuning-the-multilingual-t5-model-from-huggingface-with-keras-f7f619ec5cfe) [NLP Course - Summarization](https://huggingface.co/learn/nlp-course/en/chapter7/5) --- ## Homework 3 訓練模型將**文言文翻譯成白話文**或將**白話文翻譯成文言文**。 ### 任務說明 ![範例](https://hackmd.io/_uploads/B1IB5beekl.png) ### [資料](https://drive.google.com/drive/folders/1HCG8EPoY7JE4XQQpxz41cEk0tfR05IUG) & 環境說明 | **檔名** | **說明** | |--------------------|------------------------------------------------------------------------------------------| | train.json | 含**10000**筆資料,每筆資料含有{id, instruction, output}。instruction內會包含請翻譯成文言文的指示(如果沒有指示,預設是翻譯成白話文)和文章。 | | public_test.json | 含**250**筆資料,每筆資料含有{id, instruction, output}。請勿拿 public_test 來訓練模型!! | | private_test.json | 含**250**筆資料,每筆資料含有{id, instruction}。 | 執行於 **Python3.10** 環境 ### 任務方法 可參考的 source 包括 [Fine-Tuning Gemma Models in Hugging Face 教學](https://huggingface.co/blog/gemma-peft) or [qlora](https://github.com/artidoro/qlora)。 在本次作業中需要 fine tune [zake7749/gemma-2-2b-it-chinese-kyara-dpo](https://huggingface.co/zake7749/gemma-2-2b-it-chinese-kyara-dpo) ,若想親自刻 training 的 code 的話,可以使用 trl 套件中的 SFTTrainer 來進行高效的 qlora finetuning。資料處理方面,通常會想將助教提供的 train.json 分割為 train set 及 valid set,但實作時發現,本作業通常只需訓練 1 epoch 即可,也許我們可以嘗試將全部資料用來訓練。 助教另外提供了 utils.py ,主要方便我們進行訓練和推理時能夠直接載入 bnb_config 和 prompt 做使用,前者能夠用於 model quantization ,幫助我們減少訓練時所使用的 VRAM ,後者對於我們達到作業要求的 baseline 可說是至關重要。 以下是助教提供的預設 prompt : ```python= def get_prompt(instruction: str) -> str: '''Format the instruction as a prompt for LLM.''' return f"你是人工智慧助理,以下是用戶和人工智能助理之間的對話。你要對用戶的問題提供有用、安全、詳細和禮貌的回答。USER: {instruction} ASSISTANT:" ``` 請試著修改以上 prompt,盡可能降低 model 的 perplexity 吧! 修改 prompt 後,我們還需要設定 lora 的 configuration,以下提供了一個範例: ```python= lora_config = LoraConfig( r=64, lora_alpha=32, lora_dropout=0.1, target_modules=["q_proj", "o_proj", "k_proj", "v_proj", "gate_proj", "up_proj", "down_proj"], bias="none", task_type="CAUSAL_LM" ) model = get_peft_model(model, lora_config) ``` 上例的重點在於我們僅選擇所有的 projection layer ,屬於進行普通 lora 微調時的慣用做法, task_type 也建議設為 CAUSAL_LM 即可。設定完 config 後只需要使用 get_peft_model 進行 apply 就能開始微調了。 最後,使用 SFTTrainer 對 model 進行 finetuning,這裡使用 peft_config 參數讀入以上設定的 lora config。 完成訓練後,我們可以使用助教提供的 ppl.py 檢驗 adapter 是否有達到 baseline 。 ### Bonus 任務 同樣是 fine-tune LLM,只是對象從 gemma2 改成了彥廷學長的 [yentinglin/Llama-3-Taiwan-8B-Instruct](https://huggingface.co/yentinglin/Llama-3-Taiwan-8B-Instruct),整體大同小異,不過這顆 model 有專注在台灣本土的中文資料上 fine-tune 過,理論上會有更好的表現。 ### baseline * Public baseline: ppl = 17.500↓ * Private baseline: ppl = 24.000↓ * prediction.json: Human evaluation ### 相關連結 [助教說明投影片](https://docs.google.com/presentation/d/1gbutje764HPndSCmS-I6TZuaGvJqPZwNQj-DR4x2H3o/edit?usp=sharing) --- ## Final Project 今年有兩個選擇,完成助教提供的 kaggle 競賽 - [Medical Diagnosis](https://www.kaggle.com/competitions/adl-2024-final-project-medical-diagnosis) & [Text-to-SQL Generation](https://www.kaggle.com/competitions/adl-2024-final-project-text-to-sql-generation),或自行發想題目進行,3~5人一組。今年很榮幸請到 Appier 的 researcher ,為我們講解 kaggle 的部分。(沒可能讓你抄,自己想吧!) [助教說明投影片](https://docs.google.com/presentation/d/1sG7cwG52AIDTf736F6IjFEDEQ59vzbt_JJlNMMFRUVA)