在最後一天的這個時間我們就不學習新東西了,而是回想一下在過去30天內每一個章節中該理解什麼、學會甚麼,因此在這理我將會幫你整理出我在這30天內想要傳達給你的文章重點,若你在這個時候有看不懂的地方你就可以馬上回到當天的內容進行複習,這樣子就能夠穩固你對於該技術的知識。
在學習自然語言處理的過程中,大部分的人對於電腦如何讀取文字並沒有太深入的理解。所以在Day 2的教學中,我們初步學習了如何進行句子斷詞,同時也介紹了兩個特殊詞彙[PAD]
和[UNK]
。[PAD]
在填補不同長度資料時特別有用,因為在執行深度學習的程式時,輸入的資料長度必須相同;而[UNK]
則能夠幫我們解決面對未知字元的困擾,使模型可以通過上下文推測出該字元的意義。
在Day 3所學習的內容中,我們探索了One-hot encoding
的概念,並討論到該編碼方式會導致生成的向量非常稀疏、記憶體消耗大,以及文字之間缺乏關聯性等問題,因此我們也介紹了詞嵌入(Word Embedding)
這種文字向量表達方式,並透過程式的實作,說明這些文字向量在實際運用上的效果。
在Day 4中,我注意到網路上有許多文章並沒有完善的告訴讀者如何正確安裝Pytroch與TorchText,但這兩個工具在自然語言處理中卻極其重要,所以我用了一整天的時間來教你你如何設置這些安裝環境。
而在Day 5,我開始教你有關深度神經網路(DNN)
前向傳播的計算公式。我也稍微講解了softmax
這種激活函數對輸出結果的影響,並解釋了模型在反向傳播過程中是如何被調整的,並且通過Day 6的內容,我使用Pytorch將模型實現出來,以此加深你對該模型的印象。
在Day 7的部分,我們主要探討了文字作為時間序列資料的特性,並且闡述了基於循環神經網路(Recurrent Neural Network, RNN)
的時間序列模型的運算機制。我們同時也介紹了tanh
和sigmoid
兩種在深度學習中常見的激勵函數的特性,最後在Day 8的內容裡,我們透過IMDB情緒分析來示範TorchText的使用方式,以及如何正確應用這些時間序列模型進行分類。同時我們也探討了過度擬和(Overfitting)
的成因與概念。
從Day 9開始,我們進入了文字生成的範疇,在此部分,我們首先需要理解基於Encoder-Decoder
架構Seq2Seq
的特性,即Encoder
負責理解Decoder
則用於生成,並且在這過程中告訴你,生成式語言模型中將會常用的Teacher Forcing(教師強制)
訓練方式,以及貪婪解碼(Greedy Decoding)
的文字生成方法。
在Day 10中,我們開始探討自然語言處理中的一個核心概念注意力機制(Attention)
。這個概念主要是通過利用兩個向量生成一個全新的向量,其實踐過程包括了透過Encoder
的各個隱狀態和Decoder
的各個隱狀態進行運算,以此得出注意力分數(Attention Scores)
,並在此基礎上,我們進一步介紹了如何應用softmax
進行實際的運算,從而計算出最後的注意力權重(Attention Weights)
,以找出最適合的上下文向量(Context Vector)
。
Day 11進一步解析了Seq2Seq+Attention
的概念,並透過程式實作該模型的架構。在這裡我們提到了<SOS>
和<EOS>
兩個特殊詞彙,前者代表Decoder
的輸入,後者則標示文字輸出的結尾,這樣模型便能自動調整生成的文字結果。最後我們將生成文的注意力機制可視化,使我們可以更清楚地了解文字在生成時對隱狀態的注意力分布狀態。
最後在Day 12的部分,我們講解了隱藏式馬可夫模型(HMM)
這種基於統計學的斷詞方式,並逐一釐清每個損失函數的實際計算公式,同時我們深度分析了每個激勵函數的優缺點與特性,並以圖形方式呈現其效果。
在Day 13中,我們主要學習了遷移學習(Transfer Learning)
的基本概念以及如何進行模型的微調(fine-tune)
的作法。接著在Day 14、Day 15和Day 16學習了基於特徵(feature base)
的預訓練模型以及相關的技術,並且在此過程中我使用了Pytorch將這些公式進行了轉換。在這些內容中主要學習了Word2Vec
的CBOW
和Skip-gram
、Glove
的共現矩陣(Co-occurrence Matrix)
以及最佳化的目標方式,還有fastText
中最重要的Subword(子詞)
概念和層次Softmax(Hierarchical Softmax)
的實踐方法。
Day 17,我們針對這三個模型進行比較,同時學習如何導入這些預訓練向量導入模型的方法,同時學習了如何進行對敏感資料去識別化(De-identification)
的動作。
最後在Day 18我們了解到每個文字的詞嵌入向量應該根據上下文進行變化,在這之前的模型並沒有完整地考慮這一點,他們的詞嵌入向量往往會偏向於某個領域的向量區間,就因為這一問題所以我在Day 19展示了ELMo的詞嵌入向量與其他模型的獨特之處。
在這兩天內我主要來與你們解析人工智慧領域中被認為最強大的模型Transformer
的理論架構,在Day 20中,我們先學習了Positional Encoding
—這種為文字賦予絕對位置的編碼方式,接著我們了解到了Muti-Head Attention
是如何計算每一個詞彙的注意力的,我們也詳細道解說它式如何以此方式實現類似ELMo的概念。
接下來我們將對Transformer Decoder
中,由於平行運算方式所需使用的Mask(遮罩)
一事作詳細解說,此外考慮到該模型架構通常需要多層訓練,我們也討論了Internal Covariate Shift(內部協變量偏移)
的問題,並探討Layer Normalization
是如何有效解決這一問題。
Day 21針對該模型的程式實作方法進行介紹,我們透過文本摘要的任務來進行訓練,在這裡我們主要瞭解了在Pytorch中Transformer參數該如何使用,以及遮罩的使用方法。
在Day 22裡,我們學習了BPE(Byte Pair Encoder)
斷詞法的實現方式並理解其原理,在這一天中最重要的是我們理解為何NSP(Next Sentence Prediction)
與MLM(Mask Language Model)
這兩個預訓練任務可以更有效地提升模型的推理能力,同時從BERT
這個模型中我們體認到參考歷史模型的技術的重要性。
Day 23我們開始初步使用Hugging face這個平台的模型,而當天的主要內容是學習如何讓模型進行推理,從而作出QA形式的回答,這實我們也理解到了Hugging face平台模型的輸入特性和標記器的使用方式。
在Day 24的文章中,主要介紹了GPT系列如何透過自回歸(Autoregressive)
的模式達到優秀的效果,並說明了元學習(Meta Learning)
的核心概念以及實際運作的演算法。而在GPT-3的介紹中也詳細提及了In-Context Learning(上下文學習)
這項主要透過少量樣本(few-shot)
在內循環(Inner Loop)
執行訓練的策略,這種策略的優勢不僅能用於訓練過程,也能在後續的模型推理階段進行應用,以獲得更佳的成果。
在Day 25,我們介紹了一種名為LoRA(Low-Rank Adaptation)
的技巧,該技巧用於處理大型語言模型因無法適用單張GPU運算的問題,而LoRA透過轉換模型的資料型態並使用更小的矩陣來與配合動態凍結參數的方式,來增加模型的運算效率,在這個部分我利用GPT-J來示範如何對模型進行轉換,以及該如何進行這些模型的後續訓練。
Day 26則是介紹了ChatGPT這一個當今最強大的SOTA
模型以及其技術內容。在這裡我們比對了Prompt
與Instruction
的差異,並且探討了RLHF(Reinforcement Learning with Human Feedback)
這項技術的原理與概念,但由於ChatGPT的使用限制性,我們無法進行模型的微調,因此在Day 27中,我將教大家如何最大程度地設計Instruction
,並利用文本相似度分析的方法來找出最適合的Prompt
候選值。
最後在我們的Day 28中,我們談到了為何在LLaMA這一個與ChatGPT有著相似效能的模型中,為何要使用RMSNorm
、SwiGLU
以及Rotary Embeddings
這三項技術改零Transfromer架構,同時我們也討論了LLaMA實驗的結果以及其開源的重要特性。由於LLaMA 2的模型參數量最高已達到了70B
因此在Day 29的實作當中,我單獨為你介紹了另一種名為QLoRA
的實作方法,同時我還會教你如何微調LLaMA 2的聊天版本,以及如何利用RLHF來修正這些文本的生成結果。
這些就是目前自然語言處理中常用的技巧,雖然我在過程中省略了一些不太重要的技術細節,但對於目前的學習進度並無影響,因為我們主要學習的都是自然語言處理中的基礎技術,而我相信你看到這裡應該已經清楚後續的模型大多是這些基礎技術演化而成的。
而你現在擁有了這30天內所習得的基礎,這讓你在接觸新的技術時,理解起來會更加的流暢,從而減少陌生感,在此之後,你需要持續學習並累積處理文字的實務經驗,有了這些理論知識和經驗,我相信你在接手任何自然語言相關的任務時,都能輕鬆上手!
我不確定透過這種結合理論與實作的學習方式,是否能夠讓你掌握自然語言處理的技巧,但我必須承認在觀看並理解這篇文章是有一些難度在的,這主要是因為我撰寫這篇文章的動機,主要是我認為自然語言處理一直沒有一個清晰而徹底的學習流程。以我在學習的經驗我發現在程式碼的撰寫過程中,將理論概念與實際程式碼結合起來是一件相當困難的事情,所以我在解釋每一種技術或是概念之後,都會實際建構該模型的程式碼,並結合一個特定的自然語言處理任務,讓你能在學習模型建立的同時,也能實際感受如何根據任務需求去做適當的調整。
對於參加比賽的過程來說,雖然去年比賽結束後,我本來打算今年會提前準備,但因為9月開始變得非常忙碌所以還是沒做到這件事情,但好險經過了出一本書與去年的比賽經驗在程式碼編寫和文章撰寫方面變得更加迅速,而且在內容編排和文字流暢度方面,我認為也有非常大的提升。
在這個過程中,我翻閱了無數的期刊,搜尋了許多有趣的資料集,希望能通過這種像30天懶人包般的方式,讓你能迅速掌握過去幾十年來自然語言發展的脈絡。而這30天的程式我將會上傳到我的GitHub中,若你在學習的過程中有任何的問題或是程式上的問題也歡迎與我討論,那麼我們這次就到這邊,感謝大家的閱讀小弟我所寫的文章~