# 章節包:自然語言處理(NLP)W4(10/1)第 08 章「PyTorch:自動微分與訓練迴圈」 PyTorch 教學(助教,2024 錄影)影片 0:40:04–1:04:53,YouTube ID sg22677pUEs,逐字稿 C:\D槽\TAICA課程\自然語言處理\第四周1151001\W4_PyTorch教學_助教.逐字稿.txt。Notion 章節頁 https://app.notion.com/p/3ecfc631b030817fa3aceb0a27afd016(頁 ID 3ecfc631b030817fa3aceb0a27afd016),頁面標題「08 PyTorch:自動微分與訓練迴圈(0:40–1:04)」。 ## 1. 第一行(直接照抄,不要改) [自然語言處理](https://app.notion.com/p/3e6fc631b03081b4a9e8f91f3411f61f) › [W4(10/1)](https://app.notion.com/p/3ecfc631b03081b8aa2cf4a97467ed41) › 08|PyTorch 教學(助教,2024 錄影)影片 [0:40:04–1:04:53](https://www.youtube.com/watch?v=sg22677pUEs&t=2404s)|投影片 pytorch_tutorial_NTHU_NLP p.33–50|上一章 [07 PyTorch:用模組搭模型(0:25–0:40)](https://app.notion.com/p/3ecfc631b03081d0869df37240433e19)|下一章 [09 PyTorch:NLP 資料流與 BERT(1:04–1:26)](https://app.notion.com/p/3ecfc631b0308169a03bfc1e2049b467) ## 1b. 最後一行(直接照抄,放在 Self-check 後面,當全頁最後一行) 讀完了嗎?下一章:[09 PyTorch:NLP 資料流與 BERT(1:04–1:26)](https://app.notion.com/p/3ecfc631b0308169a03bfc1e2049b467)|回到週頁:[W4(10/1)](https://app.notion.com/p/3ecfc631b03081b8aa2cf4a97467ed41) ## 2. 各段標題(照順序;每段一個 ## 標題,直接照抄連結) - `## [0:40:04](https://www.youtube.com/watch?v=sg22677pUEs&t=2404s) 反向傳播:自動往回算梯度` 老師講什麼:訓練分兩步:往前算出預測和 loss,再用反向傳播(backpropagation)算梯度。loss.backward 會逐層往回用連鎖律算偏微分,把梯度存在每個參數的 grad 裡;中間計算結果不存。PyTorch 內部用有向無環圖(DAG)記錄計算關係。 - `## [0:41:22](https://www.youtube.com/watch?v=sg22677pUEs&t=2482s) 小例子:記下每一步怎麼算的` 老師講什麼:用 a、b 兩個參數經過 ReLU、矩陣乘法、加法得到輸出 e 的例子:往前算時,每個中間結果都記住自己是用哪種運算得到的(對應的 backward 函式),以及要等幾條路的梯度傳回來才能往回算(依賴數)。 - `## [0:44:42](https://www.youtube.com/watch?v=sg22677pUEs&t=2682s) 一步步把梯度傳回參數` 老師講什麼:依賴數歸零的節點才放進待執行佇列,算完就把下游節點的依賴數減一,像 BFS 一層層往回傳;有兩條路通到同一個節點時,兩條路的梯度相加。最後只有葉節點(參數 a、b)存下梯度。實際使用只要寫一行 loss.backward。 - `## [0:49:18](https://www.youtube.com/watch?v=sg22677pUEs&t=2958s) 不想算梯度的三種方法` 老師講什麼:把 requires_grad 設成 False(不追蹤這個 Tensor 的梯度)、用 no_grad 區塊包住的程式都不算梯度、detach 把某個中間結果從計算圖摘出來,變成和原本計算脫鉤的新 Tensor。 - `## [0:51:20](https://www.youtube.com/watch?v=sg22677pUEs&t=3080s) 訓練一個模型要準備什麼` 老師講什麼:五樣東西:資料集、模型(輸入和輸出的關係)、優化器、損失函數,以及訓練完用來驗證的測試集;測試集必須是訓練時沒看過的資料。 - `## [0:53:08](https://www.youtube.com/watch?v=sg22677pUEs&t=3188s) 常見的損失函數` 老師講什麼:損失函數把預測和標準答案的差距量化。分類用交叉熵(cross entropy),二元分類用 BCE;迴歸(預測一個數值)用 MSE;知識蒸餾(小模型學大模型)用 KL divergence 比較兩個機率分布;另外還有對比學習用的 contrastive loss,以及讓模型更有信心的 entropy 項。 - `## [0:56:59](https://www.youtube.com/watch?v=sg22677pUEs&t=3419s) 優化器與每輪清梯度` 老師講什麼:優化器選擇單純,沒特殊情況就用 Adam 或加了權重衰減的 AdamW。一步訓練:餵資料→算 loss→backward→optimizer 更新;每一輪都要先清掉上一輪的梯度,否則梯度會一直累加。 - `## [0:58:37](https://www.youtube.com/watch?v=sg22677pUEs&t=3517s) 線性迴歸範例` 老師講什麼:用一條直線 y = wx + b 去貼近一群散布的點:模型是一個輸入一個輸出的線性層,損失用 MSE,優化器用隨機梯度下降(SGD)並設學習率(步長);跑下來 loss 越來越小,並逐步印出清梯度、backward、step 時 w 和 b 的梯度與數值怎麼變。 ## 3. 老師強調/會考/不考的地方(原句已驗證;寫進筆記時 ASR 錯字要改正) - (0:58:08) [強調] 「那注意就是每一輪每一個step訓練每一輪梯度計算之後我們會需要把這個optimizer的前一輪算出來的梯度給清除掉」 → 每一步訓練都要先清掉上一輪的梯度,不然梯度會一直累加 ## 3b. 數學段候選(程式抓的,只是提示;寫「跳過提示」行用) 0:42:30–0:44:30 (120s, score 12) 偏微分 矩陣 然後這邊呢就是他這邊是矩陣這邊是矩陣乘法來算出通過矩陣乘法來算出這個D這個變量然後所以這邊也這邊D也儲存了一個矩陣乘法的backward function那每一個中間的變量都會有一個乘一個他是如何算出來的那麼這個計算方式對應的backward function 1 段候選(門檻 3.4 字/30 秒) ## 4. 這章摘要與重要度 (助教 PyTorch 教學影片,時間是那支影片的時間)PyTorch 在往前計算時會記下每一步怎麼算出來的,呼叫 backward 就能沿著這張計算圖自動往回算出每個參數的梯度;再配上損失函數和優化器,就組成完整的訓練迴圈,最後用線性迴歸跑一次給你看。(一般) ## 5. 整堂課的提醒(ASR 錯字、老師口誤、投影片缺公式等;只用跟這章有關的) - 這支只有約 1 小時 20 分(老師 1:18:56 下課),下半場改看助教預錄的 PyTorch 教學影片(約一個半小時),筆記在第 06–09 章,章名前面有「PyTorch:」,影片時間是那支影片自己的時間。 - PyTorch 教學是 2024 年錄的舊影片,片中提到的作業說法(例如建議用 teacher forcing、之後要用 Hugging Face)不代表今年,今年作業以今年公告為準。 - 課表寫的是「Text Classification, NB, NN」,但實際上還在講 W2_Word 投影片(p.17–47)的語言模型和詞向量;Naive Bayes 只在 0:55:59 拿來對比「統計」和「模型學習」。 - 開頭 0:00:27–0:02:24 有網路和回音問題,0:03:55–0:04:32 在調整直播畫面,內容沒有缺。 - 逐字稿有語音辨識重複行(0:27:41–0:29:20 幾乎每句重複兩次、0:39:37 一句重複四次),不影響理解。 - 全片沒有下課休息,一路講完(0:00:01–1:26:08)。 - 逐字稿 0:01:32–0:01:53 有語音辨識重複句與亂碼(同一句重複五次、CUDA 版本被辨識成 ientes/analytical sci-fi/evangelical sci-fi),內容只是「別直接 pip install,到官網選版本」。 - 0:35:46 老師說「這是新的嗎」,接著改用口述講 Google Bomb。p.31 的文字檔裡已經有「Google Bomb/Data Poisoning」,可能是 10/1 更新版才加的,直播畫面也許還是舊版。不確定。 - p.33–38 的 word2vec 細節,老師是用回顧的方式講的,沒有逐頁翻:p.34 共現矩陣、p.38 SGD 那頁沒有明確講到;0:47:21 的 A、B、C softmax 計算例子,對應的是 p.35 還是 p.36(只有圖),不確定。 - 老師好幾次把模型輸出的「機率」說成 perplexity(例如 0:45:48、0:48:31),應該是口誤,寫筆記時要寫成 probability,不要寫成困惑度。 - 老師 1:08:44 已經宣布下課,接著又講了約 5 分鐘 activation function(p.46–47),1:13:47 才真正收尾,所以第 05 章沒有在 1:08:44 切開。1:13:27 說的「這一段的敘述」應該是指 p.47 的 softmax、sigmoid、tanh、ReLU 表格,只用一句帶過。p.48(In text viewpoint)沒講,下週應該從 p.48 開始。 - 第 04 章長約 13.5 分鐘,比建議的 15 分鐘短一點;它講 contextual embedding,跟第 05 章的 NN 基礎主題不同,所以沒有合併。 - [PyTorch 影片,第 06–09 章] 投影片 p.7 寫模型是 y = ax²+b,助教口頭說成「y等於ax加b」(0:04:08);投影片寫「four data points」但只列三個點 (-1,1)、(1,2)、(2,3),助教口頭念的點也對不上(0:04:36 說 -1 對 1、-1 對 2、-2 對 3)。寫筆記以投影片的 y = ax²+b 和三個點為準。 - [PyTorch 影片,第 06–09 章] 逐字稿有大量語音辨識錯字,寫手要自己還原:T度=梯度、correct function=collate function、translation=truncation、badge size=batch size、relude/Renew=ReLU、MN backward=MmBackward、nodegrade=no_grad、width.backward=with torch.no_grad()、nonpy=NumPy、viewed=view、birth=BERT、復迴圈=for 迴圈、增刮號=中括號、高雄宇=高宏宇;0:23:00 的「3e」應是 stride (3, 1)、0:22:02 的「13」是 (1, 3)。 - [PyTorch 影片,第 06–09 章] 助教把 BERT 稱為「auto encoder」(1:21:5x 起),對應投影片 p.60–61 的「Transformer Auto-encoder」,指的是編碼器式 Transformer,不是一般說的自編碼器;寫筆記時要說清楚,避免混淆。 - [PyTorch 影片,第 06–09 章] 第 2 章只有約 14 分鐘,略低於 15 分鐘下限;因為「模組」是獨立概念,而第 3 章(自動微分+訓練迴圈)已約 25 分鐘,沒有再合併。若主 session 想更細,第 3 章可在 0:51:20 切成「自動微分」與「損失函數、優化器與線性迴歸」兩章(各約 11、13.5 分鐘)。 - [PyTorch 影片,第 06–09 章] 投影片檔放在 2026 資料夾,影片是 2024 年錄的;對照下來頁序與講解內容一致(p.62 是結尾的笑話頁,沒有內容),但不確定 2026 版投影片是否和 2024 錄影時的版本完全相同。 - [PyTorch 影片,第 06–09 章] emphasis 只放了助教明講作業相關或重複強調的地方;另外兩處助教有說「注意」或「建議」但跟作業無關,沒列進去:0:53:00「不要用訓練的資料來測試」、0:24:47「儘量用矩陣運算的方式來運算」(兩句都已過 quote_check)。 - [寫手注意,第 06–09 章] 這四章是助教的程式教學,但主理人不看程式碼、考試不考寫程式:預設看得到的內容寫「這個元件在做什麼、為什麼需要它」+生活比喻(例:optimizer 像導航決定下一步往哪走);程式碼最多一小段,放進「(進階,可跳過)」摺疊。Exam-ready 只放投影片上的英文概念句(例如 tensor、autograd、loss、optimizer 的說明),不放程式碼行;投影片沒有完整英文句時用短的英文定義並標 (my wording)。Self-check 問「為什麼/比較」,不問語法。助教不是老師,不標【老師強調】,要標就寫【助教強調】+時間。 ## 6. 投影片文字(這章範圍) **這幾頁的公式或內容只在圖裡(文字檔抓不到),寫 Exam-ready 與公式前先用 Read 看這幾張圖:** - pytorch_tutorial_NTHU_NLP p.34 → C:\D槽\TAICA課程\_work\notes-v2\nlp-w4\img\brief_pytorch_tutorial_NTHU_NLP_p034.png - pytorch_tutorial_NTHU_NLP p.35 → C:\D槽\TAICA課程\_work\notes-v2\nlp-w4\img\brief_pytorch_tutorial_NTHU_NLP_p035.png - pytorch_tutorial_NTHU_NLP p.36 → C:\D槽\TAICA課程\_work\notes-v2\nlp-w4\img\brief_pytorch_tutorial_NTHU_NLP_p036.png - pytorch_tutorial_NTHU_NLP p.37 → C:\D槽\TAICA課程\_work\notes-v2\nlp-w4\img\brief_pytorch_tutorial_NTHU_NLP_p037.png - pytorch_tutorial_NTHU_NLP p.38 → C:\D槽\TAICA課程\_work\notes-v2\nlp-w4\img\brief_pytorch_tutorial_NTHU_NLP_p038.png - pytorch_tutorial_NTHU_NLP p.39 → C:\D槽\TAICA課程\_work\notes-v2\nlp-w4\img\brief_pytorch_tutorial_NTHU_NLP_p039.png - pytorch_tutorial_NTHU_NLP p.40 → C:\D槽\TAICA課程\_work\notes-v2\nlp-w4\img\brief_pytorch_tutorial_NTHU_NLP_p040.png - pytorch_tutorial_NTHU_NLP p.42 → C:\D槽\TAICA課程\_work\notes-v2\nlp-w4\img\brief_pytorch_tutorial_NTHU_NLP_p042.png - pytorch_tutorial_NTHU_NLP p.46 → C:\D槽\TAICA課程\_work\notes-v2\nlp-w4\img\brief_pytorch_tutorial_NTHU_NLP_p046.png - pytorch_tutorial_NTHU_NLP p.48 → C:\D槽\TAICA課程\_work\notes-v2\nlp-w4\img\brief_pytorch_tutorial_NTHU_NLP_p048.png --- pytorch_tutorial_NTHU_NLP p.33 --- Training 33 forward backward Forward: Obtain output logits Backward: Back-propagation model.forward() loss.backward() --- pytorch_tutorial_NTHU_NLP p.34 --- Backward The backwardfunction in PyTorch is used to perform backpropagation. Gradient Calculation: PyTorch computes the gradient of the target tensor with respect to all the tensors that have requires_grad=True, using the chain rule of calculus. Gradient Storage: The computed gradients are stored in the .grad attribute of the tensors. Automatic Differentiation: PyTorch builds a computation graph dynamically during the forward pass, and when backward() is called, it traverses this graph in reverse order, applying the chain rule to calculate gradients step-by-step from the output back to the inputs. 34 --- pytorch_tutorial_NTHU_NLP p.35 --- A simple example a = torch.randn(1, requires_grad=True) b = torch.randn(1, requires_grad=True) c = torch.nn.functional.relu(b) d = a @ c e = c + d 35 Sample code (forward) : a b c d e relu mm add None None ReluBackward0 D=2 MmBackward0 D=1 AddBackward0 D=0 Record backward functions and dependency D and build a DAG. --- pytorch_tutorial_NTHU_NLP p.36 --- A simple example 36 Backward : a b c d e relu mm add None None Inverse Start from here ReluBackward0 D=2 MmBackward0 D=1 AddBackward0 D=0 0 AddBackward0 1 2 3 Leaf node (parameters) FunctionTask queue --- pytorch_tutorial_NTHU_NLP p.37 --- A simple example 37 Backward : a b c d e relu mm add None None Dependency = 0 ReluBackward0 D=1 ∂e/∂c MmBackward0 D=0 ∂e/∂d AddBackward0 D=0 0 MmBackward0 1 2 3 FunctionTask queue Pop AddBackward0 and execute. Push MmBackward0 --- pytorch_tutorial_NTHU_NLP p.38 --- A simple example 38 Backward : a b c d e relu mm add None None Dependency = 0 ReluBackward0 D=0 ∂e/∂c+(∂e/∂d)*(∂d/∂c) MmBackward0 D=0 ∂e/∂d AddBackward0 D=0 0 ReluBackward0 1 2 3 FunctionTask queue Pop MmBackward0 and execute. Push ReluBackward0 --- pytorch_tutorial_NTHU_NLP p.39 --- A simple example 39 Backward : a b c d e relu mm add None None ReluBackward0 D=0 MmBackward0 D=0 AddBackward0 D=0 0 1 2 3 FunctionTask queue Pop ReluBackward0 .grad = (∂e/∂d)*(∂d/∂a) .grad = (∂e/∂c)*(∂c/∂b)+(∂e/∂d)*(∂d/∂c)*(∂c/∂b) --- pytorch_tutorial_NTHU_NLP p.40 --- Run without gradient tensor.requires_grad = False oWhen you set the requires_grad attribute of a tensor to False, even if it participates in computations, gradients will not be tracked for it. with torch.no_grad(): oThis is a context manager that temporarily disables gradient tracking for all operations within its scope. tensor.detatch() oThe detach() method returns a new tensor that shares the same data as the original tensor but is detached from the computation graph. 40 Three ways to avoid gradient New view, Unchanged continuity --- pytorch_tutorial_NTHU_NLP p.41 --- Train a Model Step1: Prepare the dataset Step2: Construct the model Step3: Define Optimizer Step4: Define loss function Step5: Train the model Step6: Evaluate the model 41 1. clear gradients 2. Input data to the model 3. compute loss 4. compute gradients 5. optimize parameters 6. back to 1. --- pytorch_tutorial_NTHU_NLP p.42 --- Loss functions A loss function is a critical component that measures how well or poorly a model's predictions match the actual (true) values. In simple terms, it quantifies the "error" or "difference" between the predicted output and the true labels. The primary role of a loss function is to provide feedback to the model during the training process, helping the model improve its predictions over time. 42 --- pytorch_tutorial_NTHU_NLP p.43 --- Loss functions Loss functions Usage torch.nn.CrossEntropyLoss Classification tasks torch.nn.MSELoss Regression tasks torch.nn.KLDivLoss Knowledge Distillation torch.nn.BCELoss Binary classification tasks 43 Loss functions Usage Contrastive Loss Contrastive learning Entropy A special term in loss function to improve model's confidence Some loss functions in torch.nn Some other loss functions --- pytorch_tutorial_NTHU_NLP p.44 --- Optimizers 44 Optimizer Description torch.optim.SGD Stocastic gradient decend torch.optim.Adam Adam optimizer torch.optim.AdamW A variant of the Adam optimizer on weight decay formulation Some optimizers (most commonly used) in torch.nn --- pytorch_tutorial_NTHU_NLP p.45 --- Training 45 1. clear gradients 2. Input data to the model 3. compute loss 4. compute gradients 5. optimize parameters 6. back to 1. optimizer.zero_grad() output = model(**batch) loss = loss_fn(output, ground_truth) loss.backward() optimizer.step() --- pytorch_tutorial_NTHU_NLP p.46 --- An Example of Linear Regression Data distribution: Use a line to represent these data 46 --- pytorch_tutorial_NTHU_NLP p.47 --- An Example of Linear Regression initialize data tensor 47 model loss​ & optimizer load data 1. Input data to the model 2. compute loss 3. clear gradients 4. compute gradients 5. optimize parameters --- pytorch_tutorial_NTHU_NLP p.48 --- An Example of Linear Regression Outputs: 48 --- pytorch_tutorial_NTHU_NLP p.49 --- Check the parameters & gradients 49 step 1 step 2 --- pytorch_tutorial_NTHU_NLP p.50 --- Check the gradients 50 step 2 step 3 step 4 ## 7. 逐字稿(0:40:04 前後各多 1 分鐘,原始行) [00:39:04] 那這是訓練模式跟驗證模式的區別 [00:39:06] 一般來說訓練模式就是我們在訓練模型之前 [00:39:09] 我們會Model.Train [00:39:11] 把它 [00:39:12] 把這個模型以及下面所有的子模組都變成訓練模式 [00:39:16] 然後在驗證的時候 [00:39:18] 就在我們有 [00:39:18] Evaluate [00:39:19] 就是 [00:39:20] 驗證集驗證Dataset進來的時候 [00:39:23] 會 [00:39:24] 呼叫這個Model.EVAL的這個 [00:39:27] 函數 [00:39:28] 把它變成驗證的模式 [00:39:31] 然後這兩個模式 [00:39:32] 它都是用遞迴的方式 [00:39:34] 也就是我們呼叫一個模型的 [00:39:38] Train的時候 [00:39:39] 它會 [00:39:40] 尋找下面的每一個 [00:39:42] 尋找下面的各個模組 [00:39:45] 也子模組就是每一層 [00:39:46] 每一個torch.n.module [00:39:48] 然後就類別的東西 [00:39:49] 它都會去呼叫它的Train [00:39:52] 它也是這樣遞迴下去的 [00:39:54] 所以這也是印證了我們之前說的 [00:39:56] 要在模組裡面寫模組 [00:39:57] 不要在模組裡面寫Python基本性別 [00:40:01] 然後 [00:40:04] 我們介紹完了模型大概的建構 [00:40:06] 接下來我們就是要訓練這個模型 [00:40:09] 那訓練我們會有兩步吧 [00:40:10] 就首先 [00:40:11] 資料會 [00:40:12] 未進來獲得預測結果 [00:40:14] 預測結果會傳出loss [00:40:15] 我們最小化loss就會回傳T度 [00:40:19] 那這個T度 [00:40:20] 通過 [00:40:21] 一個叫 [00:40:21] 反向傳播的方式來計算 [00:40:23] 也就是 [00:40:24] 這邊的loss.backward [00:40:27] 這個backward它完成的具體功能 [00:40:31] 就是 [00:40:32] 逐層的往回 [00:40:34] 去計算偏微分 [00:40:35] 去計算T度 [00:40:38] 通過這個偏微分來計算T度以後 [00:40:41] 再把T度存在 [00:40:43] 各個參數的 [00:40:44] .grade這個變量裡面 [00:40:47] 注意是各個參數的grade這個變量 [00:40:50] 而不是中間計算結果的變量 [00:40:53] 的grade [00:40:54] 成員變量這裡面 [00:40:57] 它在計算的時候呢 [00:40:58] 會通過一個 [00:41:00] 有象 [00:41:01] 無環圖 [00:41:02] 就是 [00:41:03] DAG [00:41:05] 會構建這個DAG [00:41:07] 然後 [00:41:09] 用一種類似於BFS的方式 [00:41:11] 來 [00:41:12] 逐層的去 [00:41:13] 一層一層 [00:41:15] 往回 [00:41:15] 去回傳 [00:41:17] T度 [00:41:18] 去計算那個偏微分 [00:41:20] 那接下來 [00:41:22] 這邊有一個簡單的範例 [00:41:24] A跟B就是我們的參數 [00:41:26] 我們 [00:41:27] 傳進來兩個變量A跟B [00:41:30] 然後呢 [00:41:31] 這個A跟B [00:41:32] 會經過這樣的運算 [00:41:35] 就是B先經過relude [00:41:37] 然後A跟C再 [00:41:39] 矩陣乘法 [00:41:40] 然後 [00:41:41] C跟D再加一加 [00:41:43] 就會獲得我們的E [00:41:44] 這個E就是相當於我們模型的output [00:41:47] 假設這個E就是我們模型的output [00:41:50] 那 [00:41:51] 這邊 [00:41:51] 他在forward [00:41:53] 這個變 [00:41:54] 在跑這個forward過程當中 [00:41:56] 他會去記錄說 [00:41:58] 這個E他是如何從AB給算出來的 [00:42:02] 他會經歷這個C這個中間函數 [00:42:05] 跟D這個中間函數 [00:42:08] C這個中間的tensor跟D這個中間的tensor [00:42:12] 然後 [00:42:13] 然後說B是通過relude來算出這個C的 [00:42:16] 他這邊就會記錄 [00:42:18] C如果要返回去 [00:42:19] 就要算這個backward function [00:42:22] 那麼 [00:42:22] 他會經過這個relude backward [00:42:25] 來回來回到這個B這個地方 [00:42:30] 然後 [00:42:31] 這邊呢 [00:42:31] 就是他這邊是矩陣 [00:42:38] 這邊是矩陣乘法 [00:42:40] 來算出通過矩陣乘法來算出 [00:42:43] 這個D這個變量 [00:42:45] 然後 [00:42:46] 所以 [00:42:47] 這邊也 [00:42:48] 這邊D也儲存了一個矩陣乘法的backward function [00:42:52] 那每一個 [00:42:54] 中間的變量都會有一個乘一個 [00:42:57] 他是如何算出來的 [00:42:58] 那麼這個計算方式對應的backward function [00:43:02] 並且還有一個dependency [00:43:04] 就是他們的依賴 [00:43:06] 這個依賴表示的意思就是說 [00:43:08] 假如說這個D這個 [00:43:10] 我們要跑D [00:43:11] 往回 [00:43:12] 算A跟C的 [00:43:15] 這個偏微分的時候 [00:43:17] 我們需要先算出 [00:43:19] 就是E跟D [00:43:20] 從E到D的這個偏微分 [00:43:23] 為什麼因為 [00:43:24] 我們實際上是 [00:43:25] 我們實際上在backward [00:43:27] 往前傳遞的時候 [00:43:29] 我們是從這個E開始算 [00:43:32] 各個T度的 [00:43:33] 然後我們要優化的其實也是 [00:43:36] 就是把這個E的這個值 [00:43:38] 可能是最小化或者 [00:43:40] 怎樣 [00:43:41] 所以 [00:43:41] 我們其實要算假如說我們要算這個A的T度 [00:43:44] 我們是算 [00:43:45] E對A的偏微分 [00:43:47] 那E對A的偏微分要怎麼算呢就是 [00:43:49] 先算E對D的偏微分再D對A的偏微分 [00:43:54] 它是用一個這樣 [00:43:56] 就是 [00:43:57] 它是這樣子 [00:43:58] 通過中間的這樣一些變量給傳遞回去的 [00:44:02] 所以我們要算 [00:44:03] 我們這個D要算往前的偏微分的時候 [00:44:07] 我們要先算E跟D的偏微分 [00:44:09] E對D的偏微分再把D再傳回去 [00:44:12] 所以D就是depend [00:44:14] D就是依賴E [00:44:16] 回傳的這一步 [00:44:17] 所以它會依賴一個 [00:44:20] 就是E的這個偏微分 [00:44:22] 而C呢 [00:44:23] C [00:44:24] 它會依賴兩個 [00:44:26] 就是它有兩條路是E先走D再到C [00:44:29] 還有就是 [00:44:30] E就是直接到C [00:44:31] 所以它的 [00:44:32] 依賴就會是2 [00:44:34] 它有兩條路來算這個偏微分 [00:44:37] OK [00:44:38] 那我們 [00:44:40] 直接去跑它的 [00:44:42] 就是反向傳播 [00:44:43] 當我們呼叫backward的時候 [00:44:45] 它會就是 [00:44:46] PyTorch會構建這樣一個 [00:44:49] 反向的DAG [00:44:53] E [00:44:54] 通過E來跑backward的時候 [00:44:56] E的dependency是0 [00:44:58] 它這邊會有一個function task queue [00:45:01] 這個function task就是我們現在可以執行的backward function [00:45:06] 什麼叫現在可以執行呢 [00:45:07] 就是dependency [00:45:08] 它沒有 [00:45:09] 依賴於其他 [00:45:11] 沒有依賴於其他backward function要先完成 [00:45:15] 它自己才能做 [00:45:16] 那它就不能馬上 [00:45:18] 執行嘛 [00:45:19] 如果說別人要先做它自己才能做的話 [00:45:22] 那它不能馬上執行 [00:45:23] 它就不會被加到這個function task queue [00:45:26] 你看如果D是0它可以直接做了 [00:45:28] 那麼它就會被加到這個 [00:45:30] function task queue裡面 [00:45:32] 這個E它的D是0 [00:45:35] 它就會被加進來 [00:45:36] 並且 [00:45:37] 它會算著E到D的偏微分 [00:45:40] E到C的偏微分 [00:45:41] 這兩個偏微分的計算 [00:45:42] 其實就寫在這個 [00:45:44] add backward裡面 [00:45:47] 然後 [00:45:47] 這個add backward [00:45:49] 跑完以後 [00:45:51] 它這兩個變量 [00:45:53] 的D就會減1 [00:45:54] 然後 [00:45:58] 也就是在這兩個變量的位置 [00:46:02] 它會有算到這個 [00:46:03] E對D的偏微分跟E對C的偏微分 [00:46:07] 但注意這個算出來的偏微分並不會被存在這些中間變量的點gradient [00:46:14] 成員變量裡面 [00:46:15] 因為這個C跟D它是一個 [00:46:18] 中間tensor [00:46:20] 它並不是 [00:46:22] 它並不是一個 [00:46:24] 參數 [00:46:25] 它並不是像A跟B這樣的leaf node [00:46:27] 它只是一個 [00:46:28] 中間的 [00:46:29] 中間node而已 [00:46:30] 所以中間node它並不會去 [00:46:32] 存 [00:46:34] t度這個東西 [00:46:36] 然後 [00:46:37] E [00:46:38] 算出往回算出這個 [00:46:41] 對D跟C的偏微分以後 [00:46:43] 它們的dependency會各減1 [00:46:45] 因為畢竟E已經好了嘛 [00:46:47] 這時候我們會發現D的dependency變成了0 [00:46:53] 那這樣的話我們就可以算D了 [00:46:56] 因為只有0 [00:46:57] 接下來我們就會把D的這個 [00:46:59] MN backward [00:47:01] 就是它是通過 [00:47:02] 矩陣乘法來算出來的 [00:47:04] 把這個MN backward給丟給這個function task queue [00:47:08] 之後E的那個backward會 [00:47:11] 從這裡pop出來 [00:47:13] 然後再把MN backward給丟進去 [00:47:15] 在這個D在做反向傳播 [00:47:20] 然後 [00:47:22] D在算了以後 [00:47:24] 這邊 [00:47:26] 我們就會算 [00:47:27] 算出在C這個點 [00:47:29] 因為D它 [00:47:30] 一條線是指向A一條線是指向C [00:47:33] 這個A其實也會被算出來 [00:47:34] 然後接下來就是 [00:47:36] 它會算出C這個點它的 [00:47:38] 它的這個點它的偏微分是多少 [00:47:40] 那這個偏微分就是 [00:47:42] 首先就是一條路 [00:47:44] E到C這條路 [00:47:45] 前面這個是在第一步就算好的 [00:47:48] 第二步算出來是 [00:47:49] E通過D來算C [00:47:52] 就是 [00:47:53] 先對D做偏微分 [00:47:54] 再D再做對C做偏微分 [00:47:57] 是這樣一個動作 [00:47:59] 然後這個算好以後 [00:48:01] 那C的偏微分也完成了 [00:48:04] 那麼 [00:48:05] 這樣的話 [00:48:07] 我們就可以跑C的backward [00:48:10] 就是relude backward [00:48:12] 然後C再往前 [00:48:13] 再傳給B [00:48:15] 然後這下我們就可以算出來 [00:48:18] A的偏微分就是 [00:48:20] E [00:48:22] 傳到D再傳到A [00:48:24] 是這樣是這個運算的結果 [00:48:26] 那B的偏微分 [00:48:27] 就是E通過D [00:48:28] EDCB [00:48:30] 跟ECB [00:48:31] 這兩條路的偏微分 [00:48:33] 算出來的偏微分相加 [00:48:35] 然後也會存在B的 [00:48:38] gradient的這個變量裡面 [00:48:40] 然後這下來 [00:48:41] C的算完以後 [00:48:43] 把它的relude backward [00:48:45] 丟出去 [00:48:46] 這樣的話A跟B的 [00:48:49] 梯度就被算完了 [00:48:51] 那這就大概就是一個backward function它的底層實作的方法 [00:48:55] 那我們在 [00:48:56] 具體在 [00:48:57] 呼叫這個backward的時候其實我們就只要寫一行 [00:49:01] 就是loss [00:49:02] 就是我們算出來那個loss的tensor [00:49:04] 點backward [00:49:05] 這個過程其實就被完成了 [00:49:09] 所以大家其實這個過程它是 [00:49:11] 其實是 [00:49:12] Pytorch自己有 [00:49:14] 實作好的 [00:49:17] 那另外呢 [00:49:18] 另外這邊還有三種方法可以規避 [00:49:20] 梯度的計算 [00:49:23] 首先第一種是 [00:49:24] tensor.requires [00:49:26] grade [00:49:26] 就是 [00:49:27] 需不需要傳梯度呢 [00:49:29] 不需要 [00:49:31] 把它設定成false [00:49:33] 把它設定成false以後 [00:49:35] 它底層的代碼就會 [00:49:37] 看說它這個地方是不需要傳梯度的 [00:49:39] 那麼 [00:49:41] 它這個梯度就 [00:49:42] 就會 [00:49:43] 相當於是把這個 [00:49:45] 相當於是把這個node [00:49:47] 看作 [00:49:48] 一個 [00:49:49] 非leave node [00:49:50] 就看作相當於一箇中間結果的樣子 [00:49:53] 然後它這個 [00:49:54] 它這個 [00:49:55] 算出在這個這一步算出來 [00:49:56] 算出梯度就不會被保存下來 [00:49:58] 然後 [00:49:59] 還有一 [00:50:00] 還有一種是torch.nodegrade [00:50:01] 就是它這邊有一個context manager [00:50:04] 就是上下文管理器吧 [00:50:06] 我們可以叫做 [00:50:07] 在這個width.backward [00:50:09] 這個 [00:50:10] 管理器下的code [00:50:12] 也不會被算梯度 [00:50:15] 就是 [00:50:16] 也會當成中間的東西 [00:50:18] 不會被存下來梯度 [00:50:21] 第三個就是detach [00:50:23] detach跟前面兩個不一樣 [00:50:25] 它指的是在tensor [00:50:27] 比方說我們中間 [00:50:29] 中間我們比方說算出了某一個 [00:50:31] 中間產物 [00:50:32] detach就是說 [00:50:34] 讓這個中間產物跟原來的這個因為我們 [00:50:37] 算梯度的時候會有一個 [00:50:39] 有像 [00:50:41] 有像的 [00:50:42] dag嘛 [00:50:43] 就有一個graph [00:50:45] 那 [00:50:46] detach就是說這個 [00:50:47] tensor [00:50:48] 這一個 [00:50:49] 變量 [00:50:50] 它從graph當中 [00:50:51] 被摘出來 [00:50:53] 所以 [00:50:55] 它會創建一個新的tensor [00:50:57] 這個tensor它不會改變這個 [00:50:59] 底層的存儲 [00:51:01] 它會創建一個 [00:51:02] 新的view [00:51:03] 然後 [00:51:04] 它的連續性也不會改變 [00:51:06] 但是它 [00:51:07] 是已經從這個 [00:51:09] forward backward的這個系統當中脫離的這樣一個tensor [00:51:15] 然後我們介紹完了這個backward [00:51:18] forward backward就介紹完了 [00:51:20] 接下來就是我們要train一個模型了 [00:51:23] 模型 [00:51:23] 它會 [00:51:25] 它會吃data [00:51:27] data會算出預測結果 [00:51:29] 然後預測結果 [00:51:31] 再算出loss [00:51:32] loss再回傳梯度 [00:51:34] 那這樣一個 [00:51:35] 那模型 [00:51:36] 的訓練 [00:51:38] 參數更新大概就是這樣的一個過程 [00:51:40] 那 [00:51:41] 另外呢 [00:51:42] 在 [00:51:43] 這個主循在主循環的之外 [00:51:46] 我們還需要有比方說我們需要準備好dataset [00:51:50] 對吧 [00:51:50] 我們需要有data [00:51:52] data在之前我們的regression [00:51:54] 有那些 [00:51:56] 像是什麼線性迴歸啦或者是 [00:51:59] 之前那個二 [00:52:00] 之前那個多項式迴歸當中 [00:52:02] 就是一個 [00:52:03] 一些空間當中的點 [00:52:05] 那 [00:52:07] 第二個就是我們需要構建出我們的模型 [00:52:09] 模型就是input跟output之間 [00:52:12] 它是什麼樣的關係 [00:52:13] 它可能是線性關係也可能是卷積的關係 [00:52:15] 它也可能是rn的關係 [00:52:17] 等等等等 [00:52:19] 另外呢我們會需要構建出我們的optimizer [00:52:22] 就是我們需要定義 [00:52:23] 我們要用什麼樣的optimizer [00:52:25] 什麼樣的梯度下降工具 [00:52:28] 然後我們需要 [00:52:30] 對於這個特定的任務 [00:52:32] 我們要有什麼樣的loss function來衡量 [00:52:34] 模型的預測結果 [00:52:36] 跟我們希望它 [00:52:38] 就跟標準答案之間的距離 [00:52:41] 然後 [00:52:42] 我們還需要在模型訓練完以後去驗證這個模型 [00:52:46] 那實際上就是 [00:52:47] 把 [00:52:48] 測試級 [00:52:49] 我們會有一個專門獨立於訓練級以外的測試級 [00:52:52] 這個測試級 [00:52:54] 的資料一個個丟給模型看看模型能不能準確的預測 [00:52:58] 這些這些資料 [00:53:00] 注意它是模型訓練的時候沒有接觸過 [00:53:02] 不要用訓練的資料來測試 [00:53:07] 然後 [00:53:08] loss function [00:53:09] 那我們之前有講 [00:53:10] loss function的作用是什麼呢 [00:53:12] 它的作用就是 [00:53:13] 評價 [00:53:14] 模型的output [00:53:15] 跟標準答案之間的距離 [00:53:18] 它是一個量化的指標 [00:53:20] 就算 [00:53:22] 就算可能 [00:53:24] 比方說是分類任務它照樣也會有一個像這樣的量化指標 [00:53:28] 那這邊有很多我們在 [00:53:31] 在實際PyTorch訓練DL [00:53:34] 訓練深度學習模型當中經常會遇到的 [00:53:37] 經常會用到的一些loss function [00:53:39] 比方說cross entropy loss [00:53:40] 交叉上 [00:53:41] 就是我們所謂的 [00:53:43] 分類任務當中會需要的 [00:53:46] 需要的loss function [00:53:48] 那MSE就是我們 [00:53:50] 在 [00:53:51] 這一節助教課開頭所講的 [00:53:54] 就是標準答案減去 [00:53:56] 預測結果 [00:53:57] 在平方在平均 [00:53:59] 它是專門 [00:54:00] 它一般會用於 [00:54:02] 迴歸任務 [00:54:03] 也就是我們會有一個具體的數值 [00:54:05] 我們希望 [00:54:06] 這往往是一個像打分之類的 [00:54:09] 工作 [00:54:10] 我會希望模型的output是一個具體的數值 [00:54:13] 而 [00:54:15] 標準答案也是一個具體的數值 [00:54:17] 然後它的作用就是把兩個具體的數值 [00:54:20] 評價兩個具體數值之間的距離 [00:54:23] 第三個是KL [00:54:25] Divergence loss [00:54:27] 那這個往往被用於 [00:54:29] 資料的 [00:54:30] 知識蒸餾的這個方法 [00:54:32] 所謂知識蒸餾就是我們有一個 [00:54:34] Teacher模型 [00:54:35] 就是我們有一個模型當作老師 [00:54:37] 這個模型往往是更大更復雜的模型 [00:54:41] 然後我們會有個student模型 [00:54:42] 就是會有一個小模型來做 [00:54:45] 大模型的student [00:54:47] 我們希望在小模型當中去 [00:54:50] 用一個比較小的模型去編碼大模型的能力 [00:54:54] 所以我們會希望小模型的分佈 [00:54:56] 就它的output出來的分佈 [00:54:58] 跟大模型的越接近越好 [00:55:00] 所以KL divergence [00:55:02] 所評價的就是 [00:55:04] 兩個機率分佈之間的距離 [00:55:06] 然後 [00:55:07] BCE [00:55:08] BCE就是 [00:55:09] 所謂的 [00:55:10] Binary Cross Entropy [00:55:12] 那這個 [00:55:13] 它對於cross entropy之間的 [00:55:16] 不同點就是 [00:55:17] BCE [00:55:18] 它只能用於 [00:55:20] 它只能用於二元分類 [00:55:22] 兩個class的分類 [00:55:24] 它並不能使用在 [00:55:26] 很多class的分類 [00:55:29] 那麼另外 [00:55:30] 還有一些是有關於 [00:55:31] 我們其實 [00:55:33] 在未來的實作當中可能會經常遇到 [00:55:36] 但是PyTorch裡面並沒有實際寫出來的一些loss function [00:55:40] 比方說contrastive loss [00:55:42] 就是 [00:55:43] 它是適用於所謂的contrastive learning [00:55:45] 對比學習 [00:55:47] 就是在 [00:55:48] 就是我們output出來往往是一個 [00:55:51] 一個 [00:55:52] vector representation [00:55:54] 是一個具體的vector [00:55:56] 在高維的空間當中 [00:55:57] 我們希望vector去 [00:55:59] 靠近某一個 [00:56:00] 正樣本的 [00:56:02] 值 [00:56:03] 並且儘可能去遠離那些負樣本 [00:56:06] 那我們就會用到這個contrastive loss [00:56:08] 那下面這個entropy [00:56:10] entropy它往往可能不一定會是一個完整的 [00:56:13] loss function [00:56:14] 它往往 [00:56:15] 它有的時候在很多論文裡面 [00:56:17] 它會作為一個loss function [00:56:19] 裡面的一個 [00:56:21] 模組而存在 [00:56:23] 為的就是提升 [00:56:25] 模型預測結果的信心度 [00:56:27] 就是 [00:56:28] 當我們模型預測的 [00:56:30] 分數 [00:56:31] 大多數集中在某一個 [00:56:33] 某一個類別而不是分散在 [00:56:35] 平均分配的時候 [00:56:37] 也就是模型 [00:56:38] 它很自信 [00:56:40] 我的預測結果就是某一類 [00:56:43] 的時候 [00:56:44] 它的entropy的值就會小 [00:56:46] 也就是它的loss function [00:56:47] 它的這個loss值就會小 [00:56:50] 加這個也就是說希望模型能夠 [00:56:53] 儘可能的去 [00:56:55] 提高它的信心度 [00:56:57] 那這是我們常用的一些loss function [00:56:59] 接下來就是optimizer [00:57:01] 相對於loss function這種不同的任務我們會有不同的loss function [00:57:06] 那optimizer實際上就相對簡單 [00:57:08] 我們一般來說 [00:57:10] 我們一般來說會用到的 [00:57:12] 基本上就是這個adam [00:57:14] adamw就是加了weight decay的adam [00:57:19] 基本上沒有特別的情況我們都會 [00:57:22] 默認就是adam [00:57:23] 來作為我們的optimizer [00:57:26] 優化器來使用 [00:57:29] 那我們介紹了前面的各個深度學習的組件以後 [00:57:33] 接下來就是有關於 [00:57:35] 在training的過程當中 [00:57:37] 會有這樣一個最 [00:57:39] 一些基本的操作 [00:57:40] 就是首先 [00:57:42] 把資料為給模型算出模型的預測結果 [00:57:46] 模型的預測結果 [00:57:48] 在跟ground truth一起 [00:57:50] 這邊其實還有一個ground truth [00:57:52] 模型的預測結果跟ground truth一起算出loss值 [00:57:55] 然後loss在反向傳播 [00:57:59] 然後算出 [00:58:01] 就是 [00:58:02] 算出梯度 [00:58:04] 梯度再給optimizer [00:58:06] 來更新模型參數 [00:58:08] 那注意就是每一輪 [00:58:10] 每一個step訓練 [00:58:11] 每一輪梯度計算之後 [00:58:14] 我們會需要 [00:58:16] 把這個optimizer的 [00:58:18] 前一輪算出來的梯度 [00:58:20] 給清除掉 [00:58:21] 因為不然的話我們 [00:58:22] 在 [00:58:24] 我們不斷的去算梯度的過程當中這個梯度 [00:58:26] 他會不斷的累加累加累加 [00:58:29] 實際上可能對於我們 [00:58:31] 模型訓練的過程當中來說 [00:58:33] 是我們不願意看到的 [00:58:37] OK [00:58:37] 那這一個主循環的實作呢我們會有一個範例 [00:58:42] 這個範例是一個線性迴歸的範例 [00:58:45] 大家可能在作業的說明當中也有看到過 [00:58:48] 這線性迴歸就是在 [00:58:51] 這個二維空間當中有這樣一些點 [00:58:53] 這些點呢 [00:58:55] 我們希望用一條 [00:58:56] 用一個直線 [00:58:58] 去表示這個點 [00:58:59] 那這個點呢就是他 [00:59:00] 他們各自的分母他並不會是一個直線 [00:59:03] 就像在實際生活當中 [00:59:05] 現實中現實的任務往往是一個複雜非線性的 [00:59:09] 非線性的任務 [00:59:10] 那他往往每一筆data就每一個現實狀況他都會有自己的bias [00:59:15] 就像這些紅點一樣 [00:59:16] 他並不會完全的一條直線 [00:59:18] 來排列 [00:59:19] 那我們 [00:59:22] 往往對現實的 [00:59:23] data做建模的時候 [00:59:25] 會用一個比方說這邊我們希望用一個 [00:59:28] 直線 [00:59:29] 來對 [00:59:29] 這些現實的 [00:59:30] data來做建模 [00:59:32] 用直線來表示這些紅點 [00:59:36] 所以 [00:59:38] 所以 [00:59:40] 接下來就是 [00:59:41] 有關於 [00:59:42] 我們把這個 [00:59:44] 程式寫出來以後 [00:59:47] 首先就是有一些像這些 [00:59:49] input data跟output data的 [00:59:52] tensor [00:59:53] 那input data他會有x座標有y座標 [00:59:57] 然後 [00:59:58] 模型的定義 [01:00:00] 模型的定義 [01:00:01] 這邊因為是linear regression [01:00:03] 所以 [01:00:04] input size是1 [01:00:05] output size也是1 [01:00:08] 然後在input size跟output size都是1的時候 [01:00:11] 並且他 [01:00:12] 默認是有bias [01:00:14] nn.linear他的bias [01:00:16] 他裡面有個參數是bias [01:00:18] bias的默認值是true [01:00:19] 大家也可以把它變成false [01:00:23] 這個他的關係就是 [01:00:24] 這個他在他定義input跟output之間的關係 [01:00:27] 就是y等於wx加b [01:00:29] output等於w乘以input [01:00:30] input再加一個bias [01:00:33] 然後 [01:00:34] 那 [01:00:35] 那input就是我們的xtrain那output就是ytrain [01:00:40] 下面的criterion就是 [01:00:42] 因為我們是linear regression [01:00:45] 我們是一個迴歸任務 [01:00:46] 我們的 [01:00:48] output是一個數值 [01:00:51] 我們的ground truth是數值模型的預測也是數值 [01:00:53] 要讓數值更接近我們用的是 [01:00:56] mean square error loss [01:01:00] 這邊我們就定義 [01:01:01] 我們的loss function [01:01:03] 然後 [01:01:04] 再是optimizer,optimizer我們採用 [01:01:07] 一個比較基本的 [01:01:08] stochastic gradient descent [01:01:10] 就是一個t度下降的optimizer [01:01:13] 然後 [01:01:14] optimized的對象就是模型的 [01:01:18] 參數 [01:01:18] 然後他這邊會定義一個learning rate [01:01:21] learning rate就是 [01:01:23] 我們算出t度以後 [01:01:25] 我們的步長 [01:01:26] 我們所謂的步長就是我們 [01:01:29] 一般來說learning rate都會定義一個 [01:01:31] 在 [01:01:32] 1的 [01:01:33] 如果模型大的話可能是10的-5次方 [01:01:36] 如果模型比較小的話可能是-3甚至有可能是-2 [01:01:40] 次方 [01:01:41] 但一般來說是這樣一個數量級 [01:01:45] 然後接下來就是我們進入我們的模型訓練的主循環 [01:01:49] 就像我們一開始的範例給大家介紹的 [01:01:52] 把資料丟給模型算出這些資料的output [01:01:56] 就算出這些資料的預測結果 [01:01:58] 這些預測結果再跟ground truth [01:02:01] 來算出 [01:02:02] loss值 [01:02:05] 也就是 [01:02:05] 在這個資料集上 [01:02:07] 模型會 [01:02:08] 模型的效能評估 [01:02:10] 所謂的效能評估 [01:02:11] 量化的評估 [01:02:12] 就是這個loss值 [01:02:15] 預測結果跟output之間的 [01:02:18] 跟ground truth之間的距離 [01:02:20] 然後 [01:02:21] 最小化這個loss值 [01:02:23] 就會需要從 [01:02:25] 把前一輪的t度清空 [01:02:27] 然後再算出通過loss的backward [01:02:30] 算出新的t度 [01:02:31] 然後再根據這個t度 [01:02:34] 來 [01:02:35] 優化模型參數 [01:02:39] 然後 [01:02:40] 這樣一輪輪跑完以後 [01:02:42] 就會我們就會獲得這樣一條 [01:02:44] 大概就可以代表這個 [01:02:45] 紅點這個趨勢的這樣一條 [01:02:48] 直線 [01:02:52] 在這個過程當中訓練過程當中我們把 [01:02:55] 我們一步一步往前訓練我們就會發現這個loss值 [01:02:57] 就模型 [01:02:59] 算出來這個loss就越來越小越來越小 [01:03:04] 然後呢 [01:03:05] 我們再 [01:03:06] 進一步的去觀察它裡面的行為 [01:03:08] 那這個模型是y.wx加b [01:03:11] 它裡面就有兩個參數一個是w一個是b [01:03:13] 就是我們所謂的 [01:03:14] 第一個是weight [01:03:15] 第二個是bias [01:03:17] 那weight因為它是 [01:03:19] 因為它input跟output都是一維 [01:03:20] 不是一維是 [01:03:22] 只有一個數 [01:03:23] 所以它的weight [01:03:25] 它的weight就是 [01:03:26] 也是一個數 [01:03:27] 它的bias也是一個數 [01:03:29] 然後我們跑zero grade的時候 [01:03:32] 它的weight的 [01:03:34] t度就會是 [01:03:36] 空的 [01:03:37] 然後 [01:03:38] 它的bias也是空的 [01:03:39] 然後我們在 [01:03:41] loss點backward的時候我們再把它印出來會發現 [01:03:44] weight跟bias [01:03:45] 都有了一個新的值 [01:03:46] 這個值就是我們算出來的t度 [01:03:51] 然後我們在optimizer.step的時候 [01:03:55] 我們就會通過這個weight [01:03:57] 在乘上learning rate [01:03:59] 來更新我們的 [01:04:02] 模型的參數就是 [01:04:03] 我們的w跟b [01:04:05] 那這時候我們會發現 [01:04:07] 0.41 [01:04:08] 0.65被更新到了0.4065 [01:04:13] 也就是 [01:04:13] 這個weight在乘上learning rate [01:04:16] 這個learning rate [01:04:17] 它會是10的 [01:04:20] 可能是10的-3次方之類的大小 [01:04:24] 然後 [01:04:26] 然後 [01:04:27] optimizer.step更新完模型的權重 [01:04:30] 更新完模型的權重以後 [01:04:31] 模型裡面的參數以後 [01:04:33] 再optimizer.zero grade [01:04:35] 那這個gradient [01:04:36] 就是這個 [01:04:38] t度 [01:04:39] 它又會被清空 [01:04:41] 變成none [01:04:42] 回到none [01:04:43] 然後來準備下一次的更新 [01:04:45] 那這就是我們 [01:04:47] 這就是我們那個 [01:04:49] 一個最簡單的linear regression的範例 [01:04:53] 那麼在 [01:04:54] NLP [01:04:55] 接下來我們就會引入NLP [01:04:57] 自然語言處理的任務當中 [01:04:59] 模型的訓練的行為它大概是什麼 [01:05:02] 我們之前 [01:05:04] 所 [01:05:05] 給大家的範例其實都是一些非常簡單的模型 [01:05:07] 它裡面的參數其實就那麼一兩個 [01:05:10] 就像我們之前說的 [01:05:12] 第一個範例多項式 [01:05:14] 它的參數就是a跟b [01:05:16] 第二個linear regression它的參數就是w跟b [01:05:19] 那對於我們的自然語言處理來說 [01:05:21] 因為自然語言 [01:05:22] 它實際上是一個更加複雜的非線性系統 [01:05:26] 所以 [01:05:27] 它裡面的特徵 [01:05:29] 實際上會比這種最簡單的 [01:05:31] 就在 [01:05:32] 空間裡面的點這種特徵 [01:05:34] 要更要複雜的多 [01:05:37] 所以 [01:05:39] 我們在就是 [01:05:41] 我們在訓練這個自然語言處理的時候 [01:05:43] 我們的模型不管是模型還是資料 [01:05:46] 都會 [01:05:47] 遠遠遠遠高於之前的那些linear regression [01:05:51] 它可能會到它可能會到達的量級 ## 8. 寫作規則 (這是 `_筆記SOP.md` 第 3.1、4、5、6 節的濃縮版。兩者衝突時以 SOP 為準。) 讀者:碩士生,兩門課期末是英文考試。要只看筆記就能學會,講得比老師好懂。畫面要簡潔。 **概念優先(2026-09-26 主理人)**:主理人只想懂概念,不想補數學、不想看程式碼和座標圖。兩門課的考試也都是問答題、不考算式(AI W1 1:16:52;NLP W3 1:47:41、2:48:36)。所以: - 每段預設看得到的只有:白話摘要(2–4 句)+**一句生活比喻**(例:模擬退火像投資理財,年輕時敢冒險、越老越保守)+「考試可能怎麼問」一句。 - 數學推導、公式、手算、程式碼、座標圖,全部收進標題寫「(進階,可跳過)」的摺疊,例如「它到底怎麼運作?(進階,可跳過)」。每段最多一個進階摺疊,不要寫長篇計算。 - 演算法要能「用文字說出步驟」(考試可能要你描述),這一點放在預設看得到的地方,不用數字。 - **重心比例**:白話理論與概念模式(它在解決什麼問題、核心想法、跟別的方法差在哪、優缺點、生活比喻)占主要篇幅;數學與程式細節只用一兩句帶過,細節收進進階摺疊。 **圖文並茂(2026-09-26 主理人:不要只有文字)**: - 每章至少 2–3 個圖,放在**預設看得到**的地方,每個圖前後各用一兩句白話說明「這張圖在看什麼」。 - 流程、步驟、因果、比較 → 用 mermaid 流程圖(```mermaid,flowchart LR 或 TD;節點文字用中文、加雙引號;一張圖不超過 10 個節點)。 - 投影片上的示意圖、架構圖 → 用 [[IMG: …]] 放投影片圖。 - 仍守「每個 ## 段落最多一種視覺元素」。 ### 輸出兩個檔 1. `chNN.md`(Notion 寫法,不含頁面標題),結構固定: - 第一行:章節包第 1 節那行,原樣照抄。 - 第二行起(有數學段才寫):**跳過提示**,每段一行,讓主理人看影片時知道從哪跳到哪。用章節包第 3b 節的候選當提示,對照第 7 節逐字稿確認(只標老師連續講公式、推導、矩陣、微積分、機率計算、程式細節超過約 1 分鐘的段落;概念講解和比喻不算): `跳過提示:(1:31:02–1:35:40) 老師在推導梯度公式,聽不懂可以直接跳到 [1:35:40](YouTube 連結),接著講「步長 α 怎麼選」。` - `## 重點`:三點中文,每點一到兩句。 - `## Exam-ready`:3–10 行英文,**從章節包的投影片文字逐字抄**,每行 `- **Term**: "原句"(Ch3 p.14)`。老師有明確證據才在行尾加 `【老師強調】(h:mm:ss)`。 **每一行下面一定要有一行縮排的中文解釋**(主理人英文不好,看不懂的英文等於沒用): ``` - **Hill climbing**: "It keeps track of one current state and on each iteration moves to the neighboring state with highest value."(Ch4 p.5) - 中文:爬山法只記住「現在這一個狀態」,每一輪都移到分數最高的鄰居。白話:一直往比較高的地方走一步。 ``` 中文要先把句子意思講清楚,再補一句白話;最後用「英文(中文)」列出這句裡 1–3 個難字,例:sparse(稀疏)、distinct terms(不重複的字)。 **一行只放一句投影片原句**。同一頁有多句要考就拆成多行,每行各接一行中文;不要用分號串三句以上,不要把計算量 O(...) 塞進去。 - 章節包第 2 節的每一段:`## [h:mm:ss](連結) 標題`(照抄),下面 2–4 句白話摘要,其餘全部收進摺疊: ```
問句(例:用生活例子講,BFS 在做什麼?) 內容
``` 摺疊種類(需要才放):用生活例子講?/它到底怎麼運作?/要先懂什麼?(老師假設你會的數學或概念,短版教學)/老師原話是什麼?(「原話」(h:mm:ss),只放重要的,最多 5 句)。 - 「它到底怎麼運作?」要用一組小數字把這段的演算法**真的跑 1–3 步**(例:算出梯度、更新一次、比較兩個 α),不是只示範定義的加減乘除。全章盡量沿用同一組數字,讓前一段的答案能在下一段被驗證。 - 每段正文要回答讀者最可能卡住的一個「為什麼」。投影片公式方向跟題目相反、或投影片說「解不出來」時,用一兩句講出原因,自己補的標(我補充)。 - 投影片句子停在公式前(公式在圖裡)時:Exam-ready 在粗體詞條上補公式、引號內保持原句;正文寫出同一條式子。公式圖看章節包第 6 節列出的 PNG。 - `## Self-check`:2–4 題英文考題,答案收摺疊。**至少一題考老師強調的內容**;只出 explain/why/compare 這類問答題,**不出要代數字計算的題目**(考試不考算式);不出「老師和投影片哪裡不同」這類不會考的題目。每題格式: ```
Q1. English question?(中文:中文題目) **Answer**: English answer. 中文:把答案完整講一遍(不是只翻一句),讓看不懂英文的人也知道要怎麼答。
``` - **最後一行**:章節包第 1b 節那行(下一章連結),原樣照抄。讓讀完的人直接點下一章。 - 不要把章節包或這份規則裡的指示句寫進筆記(例如「寫筆記時照投影片寫」「已改正 ASR 錯字」)。 - 長度:全文不超過 16,000 字元(跟 check_note.py 同一個數字)。**不要為了壓字數反覆刪改**(實測一章最多花 12 輪在刪字);超過時只刪進階摺疊裡的第二組算例,比喻、比較表、圖說、「老師說不用背」的提醒都不刪。 - 預設看得到的正文不放計算量 O(...)、代號對照(例如 SMART 字母)、課本出處考據,一律移進進階摺疊。 2. `chNN.concepts.json`:JSON 陣列,4–12 個考試可能問的術語,每個物件: `name`(英文)、`zh`、`type`(概念/演算法/公式/人物事件/前置知識/行政)、`signal`("老師說會考"/"老師強調"/"核心(我判斷)"/"")、`evidence`(有 signal 前兩種時必填:原句+時間)、`definition_en`(投影片原句;沒有就註明 (textbook)/(lecture)/(my wording))、`plain`(一句中文)、`a4`(≤150 字元英文,可夾極短中文;期末拼貼用的小方塊)、`time`、`slides`、`prereq`(英文名陣列)。 ### 風格鐵律 - 不用 emoji 或裝飾符號(✓✗★⚠ 都不要;→ 可以)。不用 callout。不用 `$`。時間不要用 code 樣式。 - 每個 `##` 段落最多一種視覺元素:一張圖、或一個表格、或一個 mermaid。 - 摺疊標題是問句,前面不加符號。 - 圖片最多 3 張,只放文字取代不了的圖。放法:單獨一行 `[[IMG: | 中文圖說]]`,PNG 用 `slides_to_png.py <圖片資料夾> <頁> --dpi=110` 產生。 - 考試訊號只在老師明確說時標。老師只說「不用背」「不講」就寫「注意:……」。 - 老師口誤或跟投影片不同:照投影片寫,加「注意:老師口頭說的是……」。 - 引用老師的話時,ASR 錯字改成正確的字。 ### 沒有投影片時 不要憑記憶逐字重現課本段落或數值表。英文定義用自己的話寫、句尾標 (my wording);Exam-ready 每行標「(自擬,投影片待補)」。例子只用老師講的。 ### 寫完之後(只做一次) 跑檢查: `C:\Users\user\.cache\meeting-record\venv\Scripts\python.exe C:\Users\user\.claude\scripts\check_note.py --transcript <逐字稿> --slides <投影片 txt …> --start <起> --end <訖> --vid <影片 ID>` - STYLE/VISUAL/TIME/FORMAT:全部改掉。 - QUOTE:確認是不是你改正了 ASR 錯字(是就保留),不是就改成原文或拿掉引號。 - ENGLISH:確認是不是投影片斷行造成的(是就保留),不是就改成投影片原句。 **省額度守則**:章節包裡已經有你需要的全部資料。不要再去讀整份逐字稿、整份投影片、segments.json 或手冊。一次寫好整個檔(Write 一次),檢查後集中修改。