🗺️ AI 學習與考證地圖
中級科目三程式實戰 · 深度學習與序列資料

三個數字各管一件事:
(32 筆, 24 步, 5 個特徵) 的讀法

LSTM 是吃「序列」的模型,輸入永遠是三維:(批次大小, 時間步數, 特徵數)——一次餵幾筆、每筆看幾個時刻、每個時刻量幾個值。本頁用 TensorFlow 實跑:答案 A 的 (32, 24, 5) 直接 predict 出 32 個預測;更把 B、C、D 三個錯 shape 真的餵進去——C、D 當場報錯,B 竟然不報錯,默默給你 24 個預測而不是 32 個。「沒報錯」不等於「餵對了」,這是本頁最重要的一課。

閱讀模式

00題目

以最近 24 個時間步、每步 5 個特徵建立 LSTM,並一次送入 32 筆序列。送入 model 的 X_batch 正確 shape 為何?

import numpy as np                                  # 拿出陣列工具,取小名 np
from tensorflow.keras import Sequential             # 「一層接一層」的模型容器
from tensorflow.keras.layers import Dense, Input, LSTM  # 三種積木層
X_batch = np.zeros((32, 24, 5), dtype=np.float32)   # 32 筆 × 24 步 × 5 特徵的資料
model = Sequential([                                  # 開始疊模型(中括號=清單)
    Input(shape=(24, 5)),                             # 宣告每一筆長什麼樣(沒有 32!)
    LSTM(16),                                         # 循序讀 24 步,吐 16 維摘要
    Dense(1)                                          # 摘要 → 1 個預測值
])                                                    # 疊完收工

先說:三個數字各管一件事,順序不能換

想像一家醫院的加護病房:32 位病人,每位手上有一份「最近 24 小時」的紀錄表,表上每小時量 5 個生命徵象(心跳、血壓、呼吸、血氧、體溫)。把這疊表格原封不動變成一個陣列,就是 X_batch:

最外層數「幾筆」(32 份病歷)→ 中層數「幾步」(24 個時刻)→ 最內層數「幾個值」(5 個徵象)。寫成 shape 就是 (32, 24, 5)——從外往內、由大到小地念。LSTM 拿到後,會替每一筆病歷沿著 24 個時刻依序讀,一步一步更新記憶,最後給出預測。

兩個先立好的事實: 讀法口訣:(幾筆, 幾步, 幾個特徵)=(batch, timesteps, features)——題目把三個數字都給你了,只考你「排進正確的位置」。 這箱資料總共 32 × 24 × 5 = 3,840 個數字——選項 D 的 120 是「一筆攤平」(24 × 5),不是一批。

先點開看:shape 三維怎麼讀時間步是什麼LSTM 是什麼?

不熟 AI 專有名詞?你需要先認識下列名詞

點擊後出現漸進式說明:白話說明 → 說清楚一點 → 常見錯誤與考點。

序列模型家族
LSTMRNN 家族SequentialDense(1)
三個軸
shape 三維怎麼讀批次 batch時間步 timestep特徵 features
模型的設定
Input 與 shape=(24, 5)LSTM(16) 的 16return_sequences參數 1,408 怎麼算
資料與陷阱
滑動視窗不報錯的錯Flatten 與 MLP 對照model.summary 讀法

不熟 Python?你需要先認識下列名詞

點擊後出現漸進式說明

把工具拿進來
importfrom模組 module
存東西、造陣列
= 指派變數與命名np.zeros(32, 24, 5) 元組dtype=float32
呼叫與排版
( ) 呼叫括號關鍵字引數[ ] 中括號清單為什麼可以換行寫行尾的逗號. 點運算子

01逐行拆解:第 1 行到第 9 行

九行,一行一行走完。右上角的「看位置」可以把這一行放回完整程式裡看。

第 1 行拿出陣列工具
import numpy as np   # 整箱搬進來,取小名 np

numpy 是 Python 的陣列工具箱,as np 幫它取慣用小名。本題用它做一件事:造出那箱 (32, 24, 5) 的資料——深度學習的資料容器幾乎都從 numpy 陣列出發。

相關名詞:import模組 module

第 2–3 行拿出模型容器與三種積木層
from tensorflow.keras import Sequential             # 模型容器:一層接一層
from tensorflow.keras.layers import Dense, Input, LSTM  # 三種積木層一次拿齊

Sequential 是「積木直直疊」的模型容器:資料從第一層流到最後一層。layers 抽屜裡拿三塊積木:Input(宣告入口的形狀)、LSTM(會沿時間讀的循環層)、Dense(全連接層,收尾用)。

一次 import 多件用逗號隔開——跟前幾頁 sklearn 的寫法一樣,只是這次的工具箱換成 TensorFlow 的 Keras。

相關名詞:SequentialLSTMDense(1)

第 4 行主角:造出 (32, 24, 5) 的資料箱
X_batch = np.zeros((32, 24, 5), dtype=np.float32)   # 全 0 的 32 筆 × 24 步 × 5 特徵

np.zeros(shape) 造出一箱全是 0 的陣列,shape 用元組 (32, 24, 5) 指定——這行就是答案 A 本人:最外層 32 筆序列、每筆 24 個時間步、每步 5 個特徵。dtype=np.float32 指定單精度浮點數——深度學習的慣用精度(省一半記憶體、GPU 友善)。

為什麼是全 0?考題只關心「形狀對不對」,內容是什麼無所謂——像搬家先確認紙箱尺寸,裡面先塞報紙也行。

相關名詞:np.zeros(32, 24, 5) 元組dtype=float32shape 三維怎麼讀

第 5 行開始疊模型
model = Sequential([   # 開始疊:中括號裡放「層的清單」(括號先不關)

呼叫 Sequential([...]),把成品貼上 model 的名牌。注意是小括號包中括號:小括號是呼叫、中括號是「層的清單」——清單的順序就是資料流動的順序。括號沒關,第 5 到 9 行是同一句話。

相關名詞:[ ] 中括號清單= 指派為什麼可以換行

第 6 行入口宣告:注意,沒有 32!
    Input(shape=(24, 5)),   # 每一筆長 (24, 5)——批次維不寫

Input(shape=(24, 5)) 宣告的是「每一筆」長什麼樣:24 步 × 5 特徵。批次大小 32 不寫進模型——batch 維永遠留白(summary 裡顯示 None),因為「一次餵幾筆」是餵資料的人臨時決定的:實跑同一個模型,餵 1 筆得 (1, 1)、餵 7 筆得 (7, 1)、餵 500 筆得 (500, 1),全都通。

考點雙生題:問「X_batch 的 shape」→ 答批次的 (32, 24, 5);問「Input 的 shape 參數」→ 答不含批次的 (24, 5)。兩題長得像,考的就是你知不知道 batch 維不進模型。

相關名詞:Input 與 shape=(24, 5)批次 batch

第 7 行LSTM(16):沿 24 步讀完,吐 16 維摘要
    LSTM(16),   # 循序讀 24 個時間步,最後吐一條 16 維摘要

LSTM 對每一筆序列從第 1 步讀到第 24 步,一路更新自己的記憶;16單元數(units)——記憶與輸出的維度。預設只回最後一步的輸出,所以 32 筆進去、出來是 (32, 16):每筆一條 16 維摘要(時間軸被讀掉了)。

本站實跑:這一層的參數量是 1,408 = 4 × (16×5 + 16×16 + 16)——四組閘門,每組都有「吃 5 個特徵的權重、吃自己 16 維記憶的權重、16 個偏置」。若改 return_sequences=True,24 步的輸出全保留,變 (32, 24, 16)——疊第二層 LSTM 時就要開這個。

相關名詞:LSTM(16) 的 16參數 1,408 怎麼算return_sequences

第 8–9 行Dense(1) 收尾,疊完收工
    Dense(1)   # 16 維摘要 → 1 個預測值
])              # 中括號、小括號依序關上,模型疊完

Dense(1) 把 16 維摘要加權成 1 個數字(例如「下一小時的用電量」)——參數 16 個權重+1 個偏置=17 個。整條旅程:(32, 24, 5) → LSTM(16) → (32, 16) → Dense(1) → (32, 1),實跑 model.predict(X_batch) 得到的正是 (32, 1):32 筆各一個預測。

整個模型的參數共 1,408 + 17 = 1,425 個——model.summary() 印出來的 Total params 就是這個數字。

相關名詞:Dense(1)model.summary 讀法

02軸拆解器:一層一層打開 (32, 24, 5)

三維陣列就是「箱子裡有盒子、盒子裡有格子」。點下面的三顆按鈕,看每個數字管到哪一層:

互動實驗室:軸拆解器點軸看層級;換批次大小看輸出
軸 0 · 3232 筆序列(32 份病歷)——實線外箱
軸 1 · 24每筆 24 個時間步(最近 24 小時)——虛線中盒
軸 2 · 5:每步 5 個特徵值 → [心跳, 血壓, 呼吸, 血氧, 體溫]
批次大小是自由的——同一個模型,這次要餵幾筆?(實跑)
順序不能自己換——而且錯序不一定會被抓到。同樣 3,840 個數字,reshape 成 (24, 32, 5) 是硬把格線重畫(實跑:原本第 3 筆第 10 步的值 31002,reshape 後跑到別人家變 131102)——資料全亂了但程式不報錯。真要交換軸,用的是 transpose(實跑:transpose(1, 0, 2) 後同一個值原封不動搬到新位置)。但本題根本不該換——照 (幾筆, 幾步, 幾個特徵) 的約定放好,才是唯一正解。

03四個選項全部真的餵進去:三種下場

考題只問哪個對;本站把四個 shape 全部實跑 model.predict(),下場分三種——其中最值得記的,是那個不報錯的錯

互動實驗室:四種 shape 的下場A 成功、C/D 當場炸、B 無聲地錯
三種下場總整理(本站實跑):A → 輸出 (32, 1),32 筆各一個預測。C → 當場 InvalidArgumentError:最後一軸的 24 個「特徵」撞上 [5, 64] 的權重矩陣(5 個特徵 × 4 個閘門 × 16 單元=64——錯誤訊息裡直接看得到模型的解剖構造)。D → 當場 ValueError:LSTM 要三維,(32, 120) 只有二維。B不報錯:時間步維是動態的,模型把 24 當「筆數」、32 當「步數」,默默回傳 (24, 1)——你要 32 個預測,它給 24 個,而且每一個都是用錯的切法算的。
「沒報錯」不等於「餵對了」。C 和 D 會逼你回頭改;B 這種錯會一路活到上線。防身術兩招: 餵之前 assert X_batch.shape == (32, 24, 5) 餵之後檢查輸出筆數等於你送進去的筆數。這也是為什麼考題愛考 shape——它是深度學習裡最常見、又最不會自己喊痛的 bug。

相關名詞:不報錯的錯批次 batch時間步 timestep

04滑動視窗工廠:那 24 步是從哪裡切出來的?

題目說「最近 24 個時間步」——實務上你手上是一條長長的感測紀錄(例如 100 個小時 × 5 個欄位),要自己切成一筆一筆的 24 步視窗:從第 1 小時開始框 24 小時、往右滑 1 步再框一次⋯⋯

互動實驗室:滑動視窗工廠原始序列多長,能切出幾筆?
原始序列長度 T 100 步
視窗長度 W
24
題目指定的「最近 24 步」
能切出的視窗數
77
T − W + 1
全部視窗疊起來
(77, 24, 5)
再從中抽 32 筆=一個批次
本站實跑:造一條 (100, 5) 的序列,用迴圈切 24 步視窗——得到 77 個視窗、疊成 (77, 24, 5)(77 = 100 − 24 + 1,驗算過)。訓練時每次從裡面抽一把(例如 32 筆)餵模型,這一把就叫一個 batch——(32, 24, 5) 的 32,就是這樣來的。站內「時間序列切分」頁講的訓練/測試切法,是同一條資料線的下一站。

相關名詞:滑動視窗批次 batch

05shape 的旅程:進了模型之後,三維去哪了?

(32, 24, 5) 只是起點。資料在模型裡每過一層,shape 就變一次——考題也愛考中途站:

互動實驗室:shape 旅程與參數點算切 return_sequences、換 units 看變化
LSTM 的 units(本題是 16)——參數量跟著平方長(實跑驗證)
本站實跑 model.summary():LSTM 層輸出 (None, 16)、Dense 層輸出 (None, 1)——那個 None 就是留白的批次維(第 6 行的伏筆)。Total params: 1,425(LSTM 1,408 + Dense 17)。參數公式 4 × (units×features + units² + units):units 8→448、16→1,408、32→4,864、64→17,920——全部與實跑相符,一個不差。

06(32, 120) 是誰的世界:Flatten 與 MLP 對照

選項 D 不是亂編的——24 × 5 = 120,它是「把一筆的時間表攤平成一排」的結果。攤平之後的世界屬於 MLP(多層感知機)

mlp = Sequential([Input(shape=(120,)), Dense(1)])   # MLP:一筆就是一排 120 個數字
mlp.predict(np.zeros((32, 120)))                     # (32, 120) 在這裡完全合法 → 輸出 (32, 1)

本站實跑:這個 MLP 吃 (32, 120) 完全沒問題;在 LSTM 模型前面加一層 Flatten(),也能把 (32, 24, 5) 攤成 120 維再接 Dense(該 Dense 的參數是 120 + 1 = 121,實跑相符)。所以 D 錯的點不是「120 算錯」,是「餵錯了對象」:本題的模型第一層是 LSTM——它沿著時間軸一步一步讀,攤平等於把 24 個時刻的先後順序拆掉,LSTM 就沒有「時間」可讀了。

一句話分家:MLP 吃 2 維 (batch, features);LSTM/RNN 吃 3 維 (batch, timesteps, features);CNN 吃 4 維影像 (batch, 高, 寬, 通道)。看到模型先看第一層,就知道該餵幾維。

相關名詞:Flatten 與 MLP 對照RNN 家族

07四個選項收工

A(32, 24, 5)正確

(幾筆, 幾步, 幾個特徵)=(batch, timesteps, features)——32 筆序列、每筆 24 個時間步、每步 5 個特徵,跟 Input(shape=(24, 5)) 的宣告嚴絲合縫(batch 維由餵的人決定)。實跑 model.predict(X_batch) 輸出 (32, 1):32 筆各一個預測。程式第 4 行 np.zeros((32, 24, 5)) 就是答案本人。

B(24, 32, 5)最陰:不報錯的錯

批次與時間步對調。實跑竟然不報錯——時間步維是動態的,模型把 24 當筆數、32 當步數,默默回傳 (24, 1):你要 32 個預測它給 24 個,每個都用錯的切法算。這種錯不會自己喊痛,得靠 assert X.shape == (32, 24, 5) 和「輸出筆數對不對」自己抓。

C(32, 5, 24)當場報錯

時間步與特徵對調——變成「5 個時間步、每步 24 個特徵」。實跑當場 InvalidArgumentErrorMatrix size-incompatible: In[0]: [32,24], In[1]: [5,64]——24 個「特徵」撞上為 5 個特徵打造的權重矩陣(5 × 64,64 = 4 閘門 × 16 單元)。特徵數是模型蓋好時就焊死的,對不上就炸。

D(32, 120)攤平了時間

24 × 5 = 120,把每筆的時間表攤成一排——那是 MLP 的吃法(實跑 Input(shape=(120,)) 的模型吃它完全合法)。但 LSTM 要三維:實跑當場 ValueError: Invalid input shape ... incompatible shape (32, 120)。攤平把 24 個時刻的先後順序拆掉,LSTM 就無時間可讀——選了 D,等於否定了用 LSTM 的理由。

回到題目:現在再作答一次

再看一次同一段程式。這次你知道三個數字各管哪一層了。

以最近 24 個時間步、每步 5 個特徵建立 LSTM,並一次送入 32 筆序列。送入 model 的 X_batch 正確 shape 為何?

X_batch = np.zeros((32, 24, 5), dtype=np.float32)   # (幾筆, 幾步, 幾個特徵)
model = Sequential([                                  # 疊模型
    Input(shape=(24, 5)),                             # 每一筆的形狀(batch 不寫)
    LSTM(16),                                         # (32,24,5) → (32,16)
    Dense(1)                                          # (32,16) → (32,1)
])                                                    # 收工

08自我檢測

八題,全部都是本題的延伸。答錯會直接告訴你錯在哪。

09重點整理

  1. 九行程式的分工:第 1–3 行拿工具、第 4 行造資料箱(答案本人)、第 5–9 行疊模型(Input 宣告入口 → LSTM 讀序列 → Dense 收尾)。小括號包中括號:呼叫裡放「層的清單」。
  2. 正確答案 A:(32, 24, 5)——讀法口訣 (幾筆, 幾步, 幾個特徵)=(batch, timesteps, features):32 筆序列、每筆 24 個時間步、每步 5 個特徵;共 3,840 個數字。實跑 predict 輸出 (32, 1)。
  3. Input(shape=(24, 5)) 不含批次維——batch 永遠留白(summary 顯示 None):同一個模型實跑餵 1/7/500 筆,輸出 (1,1)/(7,1)/(500,1) 全都通。「一次餵幾筆」是餵的人決定的。
  4. B (24, 32, 5) 是最陰的錯:不報錯——時間步維是動態的,模型把 24 當筆數、32 當步數,默默回傳 (24, 1)。防身術:assert X.shape == (32, 24, 5)+檢查輸出筆數。
  5. C (32, 5, 24) 當場炸:Matrix size-incompatible——24 個「特徵」撞上 [5, 64] 權重矩陣(5 特徵 × 4 閘門 × 16 單元)。特徵數是蓋模型時焊死的。
  6. D (32, 120) 當場炸:LSTM 要三維。120 = 24×5 是「攤平」——那是 MLP 的吃法(實跑 Input(shape=(120,)) 吃它合法);攤平拆掉時間順序,LSTM 就無時間可讀。
  7. LSTM(16) 的輸出:預設只回最後一步 → (32, 16);return_sequences=True 保留每一步 → (32, 24, 16)(疊第二層 LSTM 必開);後面接 Dense(1) 分別得 (32, 1) 與 (32, 24, 1)——全為實跑。
  8. 參數量公式:LSTM 參數 = 4 × (units×features + units² + units);本題 4×(80+256+16)=1,408,加 Dense(1) 的 17 共 1,425——與 model.summary() 實跑相符;units 8/32/64 → 448/4,864/17,920 也逐一驗證。
  9. 滑動視窗:長 T 的序列切 W=24 的視窗,能切 T − W + 1 筆——實跑 (100, 5) 切出 77 個視窗疊成 (77, 24, 5),再從中抽 32 筆=一個批次。
  10. reshape ≠ transpose:reshape 重畫格線(實跑:值 31002 跑到別人家變 131102,不報錯);transpose 才是換軸(同值原封搬家)。但正解是一開始就照約定擺。
  11. 維度分家口訣:MLP 吃 2 維 (batch, features)、RNN/LSTM 吃 3 維 (batch, timesteps, features)、CNN 影像吃 4 維 (batch, 高, 寬, 通道)。看第一層,定維度。
  12. 雙生考法:問 X_batch → 含 batch 的 (32, 24, 5);問 Input 的 shape 參數 → 不含 batch 的 (24, 5)。兩題都出過,別拿錯答案卡。
完整程式碼