[自然語言處理](https://app.notion.com/p/3e6fc631b03081b4a9e8f91f3411f61f) › [W4(10/1)](https://app.notion.com/p/3ecfc631b03081b8aa2cf4a97467ed41) › 06|PyTorch 教學(助教,2024 錄影)影片 [0:00:01–0:25:47](https://www.youtube.com/watch?v=sg22677pUEs&t=1s)|投影片 pytorch_tutorial_NTHU_NLP p.1–23|上一章 [05 神經網路訓練基礎(1:03–1:19)](https://app.notion.com/p/3ecfc631b0308157b691e69c735de4b4)|下一章 [07 PyTorch:用模組搭模型(0:25–0:40)](https://app.notion.com/p/3ecfc631b03081d0869df37240433e19) 跳過提示:(0:15:46–0:19:30) 助教在逐一示範 Tensor 的加減乘、矩陣乘法、拼接、切塊、轉置的寫法,不寫程式可以直接跳到 [0:19:32](https://www.youtube.com/watch?v=sg22677pUEs&t=1172s),接著講「Tensor 在記憶體裡怎麼排」。 跳過的這段在做什麼(白話):助教把「整張表一次加減乘」「兩張表接起來或切開」「把表翻轉」的寫法各示範一次。真正要記的概念只有一個:兩張表用星號相乘是「同位置的格子相乘」,用 @ 才是線性代數的矩陣乘法;結果已經整理在下面「Tensor 的運算」那段的表格裡。 ## 重點 - 深度學習就是一個循環:模型吃資料做預測,跟標準答案比出誤差(loss),用梯度告訴 optimizer 參數該往哪調,調完再來一輪。 - 撐起這個循環的資料容器叫 Tensor(張量):像維度不受限的矩陣,能記住計算過程好算梯度,還能放到 GPU 上加速。 - Tensor 底層是一條連續的記憶體,上面蓋一層「視角」(view)決定怎麼排成矩陣;很多操作只換視角不搬資料,所以要用整批矩陣運算,不要一格一格用迴圈算。 ## Exam-ready - **Loss function, L = (Σi(yi−y'i)²)/n**: "We define the difference between predictions and ground truths as:"(pytorch_tutorial p.7) - 中文:我們把「預測值」和「標準答案」之間的差距定義成這條式子:每個點的差取平方,加總後除以點數。白話:平均起來猜錯多少。難字:predictions(預測值)、ground truths(標準答案)。 - **Gradient descent**: "In deep learning, we optimize the parameters a and b using gradient descent."(pytorch_tutorial p.8) - 中文:深度學習用梯度下降來調整參數 a 和 b。白話:沿著誤差變小最快的方向,一小步一小步改參數。難字:optimize(最佳化)、parameters(參數)。 - **Optimizer**: "The tool used to update a and b using gradient descent."(pytorch_tutorial p.8) - 中文:用梯度下降去更新 a 和 b 的那個工具,就叫 optimizer(優化器)。白話:拿到「坡度」之後,決定參數實際要改多少的人。難字:update(更新)。 - **Tensor**: "Tensors are very similar to arrays and matrices."(pytorch_tutorial p.10) - 中文:Tensor 跟陣列、矩陣非常像。白話:可以想成維度不限的矩陣。難字:arrays(陣列)、matrices(矩陣,matrix 的複數)。 - **Tensor on GPU**: "Tensors can run on GPUs or other hardware accelerators."(pytorch_tutorial p.10) - 中文:Tensor 可以放在 GPU 或其他硬體加速器上計算。白話:一般陣列只能用 CPU 慢慢算,Tensor 可以交給顯示卡一次算很多。難字:hardware accelerators(硬體加速器)。 - **tensor.data**: "Which means that a.data just creates a new view of tensor."(pytorch_tutorial p.15) - 中文:這代表 a.data 只是替這個 tensor 建了一個新的視角,沒有複製底層資料。白話:影印了座位表,學生還是同一批。難字:view(視角,怎麼解讀底層資料)。 - **Element-wise operation**: "The operation is applied equaly to every elements in the tensor except matrix multiplication(@)."(pytorch_tutorial p.16) - 中文:除了矩陣乘法(@)以外,運算都是對 tensor 裡每個元素各做一次。白話:A+1 就是每格都加 1;只有 @ 是真正的矩陣乘法。難字:equally(平均地、同樣地)、except(除了)。 - **Stride**: "Stride: defines the step (in RAM) size used to access the next token along a given dimension."(pytorch_tutorial p.19) - 中文:stride 是「沿某個維度走到下一個元素時,在記憶體裡要跳幾格」。白話:往下一列走要跳 3 格、往右走跳 1 格,這就是 stride (3, 1)。難字:access(存取)、dimension(維度)。 - **view()**: "The view function does not modify the tensor's data in memory or create a new tensor; it simply reshapes the existing tensor by changing how the data is interpreted."(pytorch_tutorial p.22) - 中文:view 不改記憶體裡的資料、也不建新的 tensor,只是改變「怎麼解讀這串資料」來換形狀。白話:同一排數字,換一種切法看。難字:modify(修改)、interpreted(被解讀)。 - **reshape()**: "For non-contiguous tensors, it will be a copy and the result is equivalent to contiguous+view."(pytorch_tutorial p.22) - 中文:遇到不連續的 tensor 時,reshape 會先複製一份,結果等於先 contiguous 再 view。白話:view 做不到時,reshape 會先幫你重排再換形狀。難字:non-contiguous(不連續)、equivalent(等同於)。 ## [0:00:01](https://www.youtube.com/watch?v=sg22677pUEs&t=1s) 環境建置 要在自己電腦跑深度學習,助教推薦用 Anaconda 或 Miniconda 建 Python 環境,再到 PyTorch 官網依作業系統和 CUDA(讓 GPU 能做通用計算的 NVIDIA 工具)版本選安裝指令。不建議直接 pip install,因為很難指定版本。PyTorch 已經內含 CUDA,不像 TensorFlow 要自己查版本對應再另外安裝,代價是安裝包比較大。要裝舊版或其他 CUDA 版本,官網有連結列出歷代版本的安裝指令,前提是電腦硬體要支援那個 CUDA 版本。
用生活例子講,為什麼要建「環境」? 環境像每個專案各自的工具箱。A 作業要舊版工具、B 作業要新版,放在同一個箱子會打架;各開一個箱子就互不干擾。conda 就是幫你開箱、換箱的管理員:Anaconda Prompt 左上角括號裡的 base 是你現在所在的箱子名稱。常用四個動作是建立(conda create -n 名稱 python=版本)、進入(conda activate 名稱)、離開(conda deactivate)、列出所有箱子(conda env list)。
## [0:03:31](https://www.youtube.com/watch?v=sg22677pUEs&t=211s) 深度學習在做什麼:梯度下降 助教用一個小模型 y = ax²+b 說明:a、b 是要學的參數,給三個資料點 (-1, 1)、(1, 2)、(2, 3) 當範例。隨便選一組 a、b,就會得到一組預測,跟標準答案的差距用均方誤差(MSE,差的平方取平均)變成一個數字 L。把每組 (a, b) 對應的 L 畫出來是一個碗形曲面,找碗底的方法就是梯度下降。 幾個前置名詞(我補充):參數就是模型裡可以轉的旋鈕(這裡是 a 和 b),訓練就是一直調旋鈕。梯度是「站在目前這組 a、b,每個旋鈕往大轉一點點,誤差會變大還是變小、變多快」,把這幾個變化量排在一起,就是一個指出方向的箭頭;偏微分就是「只轉一個旋鈕、其他不動」時誤差變化的快慢。(AI 第 3 週學過:[連續空間的梯度上升](https://app.notion.com/p/3e6fc631b030812a99d4eb793b437690),梯度指向分數上升最快的方向;這裡要讓誤差變小,所以往梯度的反方向走,叫梯度下降。) [[IMG: C:\D槽\TAICA課程\_work\notes-v2\nlp-w4\img\pytorch_tutorial_nthu_nlp_p008.png | 投影片 p.8:橫軸是參數 a、b,高度是誤差 L;碗底那一點就是最好的 a、b。下面三行定義了模型、損失函數、優化器]] 圖上重點:標題 Gradient decend 是「梯度下降」(投影片拼錯,正確是 descent)。左上文字:把不同 a、b 對應的誤差畫成一個曲面,就看得出誤差怎麼隨參數變化;深度學習用梯度下降來調整 a、b。橘色三行是定義:y = ax²+b 叫 model(模型),L 那條式子叫 Loss function(損失函數),「用梯度下降更新 a、b 的工具」叫 Optimizer(優化器)。右邊 3D 圖的三個軸是 a、b 和誤差 L。這張圖在講:訓練就是在這個碗形曲面上一路往下走,找到最低點。 圖上每一點代表「選這組 a、b 時錯得多嚴重」。為什麼要用梯度?因為參數組合無限多,不可能全試;梯度直接告訴你「站在這裡,往哪個方向走誤差降最快」。三個名詞:y = ax²+b 是**模型**,算差距的式子是**損失函數**(loss function),負責用梯度更新 a、b 的工具是**優化器**(optimizer)。考試可能怎麼問:解釋 model、loss function、optimizer 各自負責什麼。 注意:助教口頭說成「y 等於 ax 加 b」,念的三個點也和投影片不同;投影片寫「four data points」但只列了三個點。這裡以投影片的 y = ax²+b 和三個點為準。 下面摺疊在做什麼(白話):用投影片的三個點,真的把梯度下降走一步。先算現在錯多少,再算梯度看 a、b 該變大還是變小,然後往那個方向調一小步。結果誤差從約 1.67 降到約 0.35,代表走一步就更靠近碗底。
它到底怎麼運作?(進階,可跳過) 用投影片的數字跑一步。a=1、b=1 時,x = -1, 1, 2 的預測是 2, 2, 5,標準答案是 1, 2, 3。 - 誤差:(1−2)² + (2−2)² + (3−5)² = 1 + 0 + 4 = 5,除以 3,L ≈ 1.67。 - 梯度(我補充):對 a 偏微分 = (2/3)×Σ(預測−答案)×x² = (2/3)×(1×1 + 0×1 + 2×4) = 6;對 b 偏微分 = (2/3)×(1+0+2) = 2。兩個都是正的,代表 a、b 都該變小。 - 更新(我補充,步長取 0.1):a = 1 − 0.1×6 = 0.4,b = 1 − 0.1×2 = 0.8。 - 新預測 1.2, 1.2, 2.4,新誤差 (0.04 + 0.64 + 0.36)/3 ≈ 0.35。走一步,L 從 1.67 降到 0.35。
## [0:07:36](https://www.youtube.com/watch?v=sg22677pUEs&t=456s) 訓練主循環與 Tensor 的由來 把上一段串起來就是訓練的主循環(main loop):一批(batch)資料進模型,模型產生預測,預測和標準答案算出 loss,loss 算出梯度,optimizer 用梯度更新模型,再來一輪。 ```mermaid flowchart LR D["資料"] --> M["模型"] M --> P["預測結果"] P --> L["和標準答案算 loss"] L --> G["算出梯度"] G --> O["optimizer 更新參數"] O --> M ``` 這個循環要求資料容器同時做到三件事:能計算、能記住「算的過程」以便回頭算梯度、能搬到 GPU 上加速。一般的 Python list 或 NumPy 陣列做不到後兩件(我補充),所以有了 Tensor。可以把它想成維度自由的矩陣:平常線性代數多是二維,Tensor 可以是三維、四維甚至更高。TensorFlow 這個名字(張量流)也來自它。考試可能怎麼問:為什麼訓練需要 Tensor 這種特殊資料結構。 名詞補充(我補充):batch 是「一次餵給模型的一小疊資料」,不是一筆一筆餵,也不是全部一次餵。GPU 是顯示卡上的處理器,原本用來畫遊戲畫面,裡面有幾千個小計算單元能同時做簡單的乘法加法,剛好適合大量矩陣計算;CPU 則是少數幾個聰明但一次只做少數事的核心。陣列(array)是一排有編號的格子,矩陣是排成幾列幾行的數字表。NumPy 是 Python 最常用的數字計算工具,能存陣列和矩陣,但不會記錄計算過程,也只在 CPU 上算。(NLP 第 4 週第 05 章學過:model 負責猜、loss function 量差多遠、optimizer 決定怎麼改,見 [05 神經網路訓練基礎](https://app.notion.com/p/3ecfc631b0308157b691e69c735de4b4)。)
用生活例子講,Tensor 跟普通矩陣差在哪? 普通矩陣像一張只寫結果的計算紙。Tensor 像會自動記帳的計算紙:每一步怎麼算出來的都留著,最後要問「誤差是被哪個參數拖累的」,可以沿著帳本倒推回去(這就是算梯度);而且這本帳可以交給 GPU 這種「一百個人同時算」的團隊處理。
## [0:10:12](https://www.youtube.com/watch?v=sg22677pUEs&t=612s) 建立 Tensor 與它的屬性 Tensor 可以從 Python list、NumPy 陣列建立,也可以隨機產生(randn 是常態分布、rand 是均勻分布),或直接要全 0、全 1、對角矩陣。唯一限制是形狀要方方正正:不能第一列兩個數、第二列三個數。建立後可以查它的幾個屬性: | 屬性 | 問的是什麼 | 例子 | |---|---|---| | data | 內容本身(投影片寫回傳一份 copy,實際只複製 view,見下一段) | tensor([[1, 2], [3, 4]]) | | item() | 只有一個數時,取出那個數 | 1.1 | | shape | 幾乘幾 | torch.Size([2, 2]) | | dtype | 裡面是整數還是小數 | torch.int64 | | device | 放在 CPU 還是 GPU | cpu | | requires_grad | 要不要幫它算梯度 | False | | grad | 目前算出來的梯度 | tensor([...]) | 為什麼要有 device 和 requires_grad?因為這正是 Tensor 被發明的兩個理由:能上 GPU、能算梯度。模型的參數會開 requires_grad,輸入資料通常不用。
要先懂什麼?均勻分布、常態分布、對角矩陣、dtype 是什麼? - 均勻分布(rand):每個數字被抽到的機會一樣,像擲公正的骰子;rand 是在 0 到 1 之間平均亂抽。 - 常態分布(randn):像全班的身高,大部分擠在平均附近,離平均越遠越少見,畫出來是鐘形;randn 抽出的數大多在 0 附近,正負都有。 - 對角矩陣:只有左上到右下那條斜線上有數字(eye 放的是 1),其他格都是 0。 - dtype:數字的種類。int64 是整數(沒有小數點),float 是小數;要算梯度的參數必須是小數,因為每次只調一點點。 - grad(梯度):上一段那個「往哪走誤差降最快」的箭頭;requires_grad 打開,PyTorch 才會幫這個 tensor 記帳、算梯度。
## [0:13:04](https://www.youtube.com/watch?v=sg22677pUEs&t=784s) 底層資料和「視角」分開存 Tensor 其實分兩層:底層是一條一字排開的記憶體(storage),上面蓋一層 view,規定「這串數字要怎麼排成矩陣」。你的變數 a 指向的是 view。把 a.data 給 b,複製的只是 view,底層那條資料沒有複製。 名詞補充(我補充):記憶體(RAM)可以想成一長排編了號碼的置物格,電腦把數字一格一格放進去;「記憶體位置」就是格子號碼。程式裡的「變數」只是一張貼著的名牌,指向某個東西,不是東西本身。 [[IMG: C:\D槽\TAICA課程\_work\notes-v2\nlp-w4\img\pytorch_tutorial_nthu_nlp_p015.png | 投影片 p.15:變數 a、b 各有自己的 view(印出來的位置不同),但都指向同一條 storage 0 1 2 3,所以改 a 的值 b 也跟著變]] 圖上重點:標題 An interesting insight of tensor.data 是「tensor.data 的一個有趣發現」。左邊程式:建一個 2×2 的 a,令 b = a.data,印出兩者的記憶體位置(print the memory locations),再把 a 的一格改成 100;The output is(輸出結果)顯示兩個位置號碼不同,但 a、b 都變成 100。右邊的圖:Variable a、Variable b(變數 a、b)各指向一個 A view of tensor(tensor 的視角),copy 箭頭表示複製的只有視角,兩個視角最後都指向同一條 Storage(底層儲存)0 1 2 3。最下面一句:a.data 只是建了一個新的視角。這張圖在講:b 看起來是複製品,其實和 a 共用同一份資料。 圖裡左邊的程式把 a[0, 1] 改成 100,印出來 a 和 b 都變成 100。為什麼記憶體位置不同、值卻一起變?因為不同的是 view,相同的是底下那條 storage。考試可能怎麼問:為什麼改 a 之後 b 也跟著變。
用生活例子講,view 和 storage 是什麼關係? storage 是教室裡一排坐好的學生,view 是貼在門口的座位表。a.data 等於影印一張座位表給 b:兩張紙是不同的紙,但上面指的是同一批學生。你叫 a 表上的某個學生換衣服,從 b 表看過去也是換過的。
## [0:15:46](https://www.youtube.com/watch?v=sg22677pUEs&t=946s) Tensor 的運算 加減乘除、次方都是「對應位置各算各的」(element-wise);只有矩陣乘法另外用 @ 符號。此外還有幾個改形狀的操作。 | 操作 | 在做什麼 | 例子(A 是 2×2) | |---|---|---| | A + 1、A * 2 | 每一格都加 1、乘 2 | [[2, 3], [4, 5]] | | A * B | 對應位置相乘 | [[0, 2], [6, 12]] | | A @ B | 真正的矩陣乘法 | [[4, 7], [8, 15]] | | cat | 把兩個 tensor 接起來 | 沿維度 0 接成 4×2,沿維度 1 接成 2×4 | | split | 切成固定大小的塊,除不盡時最後一塊放餘數 | 5×6×7 每 2 切 → 2、2、1 | | unsqueeze/squeeze | 加一個大小為 1 的維度/拿掉它 | 2×2 → 2×2×1 → 2×2 | | transpose | 轉置,沿對角線翻 | [[1, 2], [3, 4]] → [[1, 3], [2, 4]] | 表裡 A = [[1, 2], [3, 4]]、B = [[0, 1], [2, 3]]。最容易搞混的是 * 和 @:* 是對應格相乘,@ 才是線性代數裡「列乘行再加總」的矩陣乘法。
要先懂什麼?矩陣乘法和「維度 0、維度 1」是什麼? - 矩陣乘法(@):結果的每一格 = 左邊那一列和右邊那一行「一對一相乘再加總」。例:A @ B 的左上角 = A 第一列 (1, 2) 配 B 第一行 (0, 2),1×0 + 2×2 = 4;右下角 = (3, 4) 配 (1, 3),3×1 + 4×3 = 15。 - 對應位置相乘(星號)只是同位置的格子相乘,左上角就是 1×0 = 0。 - 維度(dim):2×2 的表有兩個方向。維度 0 是「往下數第幾列」,維度 1 是「往右數第幾行」。沿維度 0 接就是上下疊(列變多,成 4×2),沿維度 1 接就是左右並排(行變多,成 2×4)。 - 轉置:把列變成行,第一列 (1, 2) 變成第一行。
## [0:19:32](https://www.youtube.com/watch?v=sg22677pUEs&t=1172s) 連續儲存、轉置與 reshape stride 告訴你「沿某個維度走一步,在底層記憶體要跳幾格」,用來判斷 Tensor 是不是照「第一列、第二列、第三列」的順序連續存放(contiguous)。轉置只換 view 不搬資料(PyTorch 很多操作都是這樣,只建新 view、不建新 tensor),所以轉置後變成不連續;呼叫 contiguous 會照新順序重新排一份,如果本來就連續則什麼都不做,直接回傳原本的 tensor。 [[IMG: C:\D槽\TAICA課程\_work\notes-v2\nlp-w4\img\pytorch_tutorial_nthu_nlp_p020.png | 投影片 p.20:3×3 矩陣原本 stride (3,1)、連續;transpose 後底層沒動,stride 變 (1,3)、不連續;contiguous 另建一條 0 3 6 1 4 7 2 5 8,stride 回到 (3,1)]] 圖上重點:標題 Matrix operations(矩陣運算),這頁講 contiguous(連續存放)。左邊 3×3 的表 stride = (3,1)、contiguous(連續);經過 transpose(轉置)變成中間的表,stride = (1,3)、non-contiguous(不連續),但下面那條記憶體還是 0 到 8 原順序,左表和中表共用它;再呼叫 contiguous,右邊 Create new(另建新的一條)0 3 6 1 4 7 2 5 8,stride 回到 (3,1)、又是連續。這張圖在講:轉置只換了解讀方式,要真正把資料重排,得呼叫 contiguous。 看中間那格:畫面上已經轉置了,底下那條記憶體還是 0 到 8 原順序,這就是「只換 view」。換形狀(例如 2×2 變 1×4 或 4×1)有兩個函式:view 只能用在連續的 Tensor 上;reshape 遇到連續的就等於 view,遇到不連續時會先 contiguous 再 view,所以 reshape 比較萬用。考試可能怎麼問:比較 view 和 reshape,為什麼轉置後 view 會出錯。 下面摺疊在做什麼(白話):用一條「格子號碼公式」算給你看:知道 stride,就能算出表上任一格在底層是第幾號格子。算完會發現轉置後資料一個都沒搬,只是換了一套跳格規則;這套跳法不是一格接一格,所以 view 沒辦法直接換形狀。
它到底怎麼運作?(進階,可跳過) A 是 0 到 8 排成 3×3,底層就是 0 1 2 3 4 5 6 7 8。第 [i][j] 個元素在底層的位置 = i×stride[0] + j×stride[1]。 - 原本 stride (3, 1):A[1][2] 在 1×3 + 2×1 = 5,值是 5。往下一列跳 3 格、往右跳 1 格。 - 轉置後 stride (1, 3):AT[0][1] 在 0×1 + 1×3 = 3,值是 3,正好是轉置後第一列的第二個數(0, 3, 6)。資料沒搬,只是換了跳法。 - 這時「往右走」要跳 3 格,不是一格接一格,所以叫不連續;view 沒辦法在這種跳法上換形狀,reshape 會先複製成 0 3 6 1 4 7 2 5 8 再換。
## [0:24:47](https://www.youtube.com/watch?v=sg22677pUEs&t=1487s) 用整批矩陣運算取代迴圈 助教建議做 Tensor 運算時盡量整批用矩陣運算,不要用迴圈一格一格算,因為 PyTorch 內部對矩陣運算有平行加速。投影片的例子是把 100×100 的隨機矩陣做 normalize(每個數減平均再除以標準差):兩層 for 迴圈要 0.127 秒,矩陣運算只要 0.000088 秒,差了一千多倍。所以對你寫作業的影響是:能寫成整個矩陣一起算的,就不要拆成迴圈。考試可能怎麼問:為什麼 PyTorch 偏好矩陣運算而不是迴圈。 名詞補充(我補充):迴圈(for 迴圈)是「同一個動作重複做,每次只處理一個」的寫法,兩層迴圈就是一列一列、每列再一格一格處理。平均是全部加起來除以個數;標準差是「這些數字離平均散得多開」,散越開標準差越大。normalize(標準化)做完,資料會變成平均 0、標準差 1,大小比較整齊,模型比較好學。平行加速就是很多計算單元同時各算一部分(上面講 GPU 那段)。
用生活例子講,為什麼整批算比較快? 迴圈像只開一個收銀台,一萬個客人排一條隊一個一個結帳;矩陣運算像同時開一百個收銀台一起結。PyTorch(尤其在 GPU 上)就是那一百個收銀台,但你得把客人一次交給它,它才能分工。
助教原話是什麼? 「儘量用矩陣運算的方式來運算,而不要用循序的方式來運算」(0:24:47)
## Self-check
Q1. Describe the main training loop in deep learning and the role of the model, loss function, and optimizer.(中文:描述深度學習的訓練主循環,以及模型、損失函數、優化器各自的角色。) **Answer**: Data is fed into the model to produce predictions. The loss function measures the difference between predictions and ground truths. Gradients of the loss are computed, and the optimizer uses them to update the model's parameters. This repeats until the loss is low. 中文:資料先進模型產生預測;損失函數把預測和標準答案的差距算成一個數字;接著算出 loss 對參數的梯度;optimizer 依梯度更新參數。這個循環一直重複,直到誤差夠小。模型負責「猜」、損失函數負責「打分數」、優化器負責「改」。
Q2. Why does PyTorch use a special data structure called Tensor instead of plain arrays?(中文:PyTorch 為什麼要用 Tensor,而不用一般陣列?) **Answer**: Training needs a structure that can compute results, record the computation steps so gradients can be back-propagated, and run on GPUs for acceleration. Tensors are like arrays and matrices with any number of dimensions, but they also support gradient tracking and GPU execution. 中文:訓練需要的資料容器要能做三件事:算出結果、記住計算過程以便倒推梯度、能放到 GPU 上加速。Tensor 跟陣列和矩陣很像、維度不限,但多了記錄梯度和上 GPU 的能力,一般陣列做不到。
Q3. Compare view() and reshape(). Why can view() fail after a transpose?(中文:比較 view 和 reshape。為什麼轉置之後 view 可能會失敗?) **Answer**: view() only changes how the existing data is interpreted and works only on contiguous tensors. Transpose creates a new view without moving data, so the tensor becomes non-contiguous and view() cannot be applied. reshape() works in both cases: for contiguous tensors it equals view, and for non-contiguous tensors it makes a copy, equivalent to contiguous + view. 中文:view 不搬資料,只改解讀方式,所以只能用在底層連續存放的 tensor。轉置只換視角、沒搬資料,tensor 就變成不連續,view 無法再換形狀。reshape 兩種都能處理:連續時等於 view;不連續時先複製一份連續的(等於 contiguous 加 view)再換形狀。
Q4. Why is matrix (vectorized) computation preferred over loops in PyTorch?(中文:為什麼在 PyTorch 裡要用矩陣運算取代迴圈?) **Answer**: All PyTorch computations are performed in a matrix operation mode with internal parallel acceleration. A loop forces elements to be processed one by one, while a matrix operation processes them together. In the slide's normalization example, the matrix version was more than a thousand times faster. 中文:PyTorch 內部把運算當成矩陣一起做,而且有平行加速;用迴圈等於強迫它一格一格算,加速完全用不上。投影片做 normalize 的例子裡,矩陣寫法比迴圈快了一千多倍。
讀完了嗎?下一章:[07 PyTorch:用模組搭模型(0:25–0:40)](https://app.notion.com/p/3ecfc631b03081d0869df37240433e19)|回到週頁:[W4(10/1)](https://app.notion.com/p/3ecfc631b03081b8aa2cf4a97467ed41)