Sử dụng model pretrained

Nạp đúng model và chạy dự đoán đầu tiên

Chương 4 · Bài 4.1

2

Kho ảnh câu lạc bộ

Ít ảnh có nhãn, muốn xếp nhóm để tìm lại.

Có model đã được công bố. Ta cần gì ngoài tên model?

Cần thêm: cách xử lý ảnh đầu vào, bảng nhãn, đúng phiên bản.

Sai một thứ thì code vẫn chạy, nhưng kết quả sai.

3

Mục tiêu

  • Phân biệt kiến trúc, trọng số, bộ xử lý đầu vào và tập nhãn của một model.
  • Nạp model từ máy, chạy dự đoán theo batch và kiểm kết quả.
  • Ước lượng bộ nhớ cho trọng số.
  • Chuẩn bị file model để chạy khi không có Internet.
01

Một gói model gồm những gì

Một gói model gồm những gì5

Kiến trúc khác checkpoint

nn.Linear(2, 3) tạo các phép toán và trọng số ban đầu.

Pretrained cần trọng số đã học từ nhiệm vụ trước.

Processor quyết định input:

  • Ảnh: resize, RGB, chuẩn hóa.
  • Chữ: tokenizer, special token, padding.
  • Head: nhãn và thứ tự lớp.
Một gói model gồm những gì6

Vì sao trọng số cũ có ích?

  • Phân biệt hơn một triệu ảnh của 1000 lớp buộc mạng học cạnh, kết cấu, hình dạng.
  • Những đặc trưng ấy có trong mọi ảnh, kể cả ảnh câu lạc bộ.
  • Chỉ head gắn chặt với 1000 lớp cũ.
Một gói model gồm những gì7

Phần dùng lại, phần phải thay

Các tầng đầu học đặc trưng chung dùng lại được; chỉ head cuối gắn với 1000 lớp cũ.cạnhkết cấuhình dạngbộ phậnhead1000 lớp ImageNetdùng lại được cho ảnh câu lạc bộphải thaytầng nông → tầng sâu
Các tầng đầu học đặc trưng chung dùng lại được; chỉ head cuối gắn với 1000 lớp cũ.
Một gói model gồm những gì8

Hỏi nhanh

Có kiến trúc ResNet, và trọng số được khởi tạo ngẫu nhiên. Mô hình này đã là một model pretrained chưa?

Một gói model gồm những gì9

Shape trước khi chạy

Loại input Shape
Ảnh (B, C, H, W)
Token IDs (B, L)
Logits phân loại (B, K)

BB: batch · KK: lớp · LL: độ dài token.

Ảnh có CC kênh, chiều cao HH và chiều rộng WW.

ImageNet: chia 255, rồi chuẩn hóa mean/std từng kênh.

Một gói model gồm những gì10

Hỏi nhanh

Processor của checkpoint nhận pixel từ 0 đến 255, tự chia cho 255, rồi trừ mean và chia std. Code của đội lại đã chia cho 255 trước khi gọi processor. Chuyện gì xảy ra?

02

Kiểm bằng gói nhỏ

Kiểm bằng gói nhỏ12

Một gói nhỏ, đủ các bước

Trọng số đặt tay để kiểm được từng con số.

model.load_state_dict(
    loaded["state_dict"], strict=True)
model.eval()
print("shape W:", tuple(model.weight.shape))
Kết quảshape W: (3, 2)
  • strict=True: kiểm tên và shape.
  • map_location="cpu": mở trên CPU.
  • weights_only=True: chỉ mở tensor, số, chuỗi.
  • Gói còn có mean, scale và nhãn.
Kiểm bằng gói nhỏ13

Hỏi nhanh

Checkpoint được lưu từ một model bọc trong DataParallel, nên các khóa là module.weight và module.bias, trong khi model mới chờ weight và bias. Đội gọi load_state_dict(sd, strict=False). Kết quả là gì?

Kiểm bằng gói nhỏ14

Một mẫu qua gói nhỏ

x=(12,8)⟶z=x−(10,10)(2,2)=(1,−1)\mathbf{x}=(12,8)\quad\longrightarrow\quad\mathbf{z}=\frac{\mathbf{x}-(10,10)}{(2,2)}=(1,-1) ℓ=Wz+b=(2,−2,0.25)\boldsymbol{\ell}=W\mathbf{z}+\mathbf{b}=(2,-2,0.25)

Đây là logits của một mẫu. Lớp 0 thắng; argmax không cần softmax.

Kiểm bằng gói nhỏ15

Ba phần của gói, ba bước

Một mẫu qua ba phần của gói: processor, trọng số, bảng nhãn.x = (12, 8)z = (1, −1)processorℓ = (2, −2, 0.25)state_dicthoat_dong_Alabels(x − mean) / scaleW z + bargmax = 0thiếu hay lệch một phần nào, chương trình vẫn chạy mà trả lời sai
Một mẫu qua ba phần của gói: processor, trọng số, bảng nhãn.
Kiểm bằng gói nhỏ16

Đọc logits

with torch.inference_mode():
    logits = model(process(raw))
    predicted = logits.argmax(dim=1)
print(logits.numpy().round(2))
Kết quả[[ 2.   -2.    0.25]
 [-2.    2.    0.25]
 [ 0.    0.    0.25]
 [ 4.   -4.    0.25]
 [-1.    1.    0.25]]

Hàng thứ ba chỉ còn bias: input ở đúng trung bình.

Kiểm bằng gói nhỏ17

Hỏi nhanh

logits có shape (5, 3). Muốn mỗi mẫu có một nhãn, ta dùng gì?

Kiểm bằng gói nhỏ18

Batch cuối không được mất

Năm mẫu chia batch 2, 2, 1; kết quả nối lại theo đúng thứ tự id.input101102103104105batch 1batch 2batch 3kết quả101102103104105batch 2, 2, 1 nối lại đúng thứ tự; giữ id theo từng hàng
Năm mẫu chia batch 2, 2, 1; kết quả nối lại theo đúng thứ tự id.
Kiểm bằng gói nhỏ19

Hai phép kiểm khác nhau

print("batch khop:",
      torch.allclose(batched, logits))
print("NumPy khop:",
      np.allclose(batched.numpy(), expected))
print("so mau:", len(batched))
Kết quảbatch khop: True
NumPy khop: True
so mau: 5

Phép so batch kiểm việc ghép hàng.

Phép so NumPy kiểm công thức bằng một đường tính độc lập.

ID phải đi cùng mỗi output.

Kiểm bằng gói nhỏ20

eval() và inference_mode() kiểm hai việc khác nhau

model.eval():

Dropout và BatchNorm chuyển cách hoạt động.

torch.inference_mode():

Không theo dõi gradient cho suy luận.

Nó không tự gọi eval().

Kiểm bằng gói nhỏ21

BatchNorm cần eval()

  • Train mode: chuẩn hóa bằng thống kê của batch, đầu ra của một ảnh phụ thuộc ảnh đi cùng.
  • Eval mode: dùng running statistics trong checkpoint, chia batch kiểu gì cũng như nhau.
Kiểm bằng gói nhỏ22

Hỏi nhanh

CNN pretrained có BatchNorm. Đội quên gọi eval(), nhưng có inference_mode(). Chạy cùng tập test với batch 32 rồi với batch 8, hai file nộp khác nhau ở vài dòng. Vì sao?

Kiểm bằng gói nhỏ23

Hỏi nhanh

Model đã gọi eval(), nhưng vòng dự đoán không bọc trong inference_mode() hay no_grad(). Tham số vẫn có requires_grad=True, còn input thì không. Câu nào đúng?

03

Bộ nhớ và model thật

Bộ nhớ và model thật25

Tính phần bộ nhớ trọng số

bytes=P×s\text{bytes}=P\times s

PP là số tham số; ss là byte mỗi tham số: FP32 dùng 4, FP16 dùng 2.

Một MiB bằng 2202^{20} byte.

Model 100 triệu tham số:

Precision Trọng số thô
FP32 381.47 MiB
FP16 190.73 MiB

Chưa tính input, activation, buffer, optimizer.

Bộ nhớ và model thật26

Input và activation theo B⋅H⋅WB\cdot H\cdot W

Batch 16 ảnh RGB 224×224224\times224, float32:

16⋅3⋅224⋅224⋅4 byte≈9.19 MiB16\cdot3\cdot224\cdot224\cdot4\ \text{byte}\approx9.19\ \text{MiB}

Gấp đôi cạnh ảnh tốn ngang gấp bốn batch.

Đo một batch nhỏ trên đúng thiết bị rồi tăng dần.

Bộ nhớ và model thật27

Trọng số và input

Gấp đôi batch và gấp đôi cạnh ảnh thì input gấp 8 lần.trọng số 100 triệu, FP32381.47 MiBtrọng số 100 triệu, FP16190.73 MiBinput 16 × 3 × 224²9.19 MiBinput 32 × 3 × 448²73.5 MiBchưa tính activation, gradient, optimizer và bộ nhớ dự trữ
Gấp đôi batch và gấp đôi cạnh ảnh thì input gấp 8 lần.
Bộ nhớ và model thật28

Hỏi nhanh

Một batch 16 ảnh RGB 224×224224\times 224 kiểu float32 chiếm 9.19 MiB. Đổi sang batch 32 và ảnh 448×448448\times 448 thì tensor input chiếm bao nhiêu?

Bộ nhớ và model thật29

Đọc model card trước

  • Học trên dữ liệu gì, input nào, nhãn nào, license nào.
  • Head ImageNet chỉ chọn trong 1000 lớp cũ.
  • Dùng lại các tầng dưới: 4.2 lấy đặc trưng, 4.3 học head mới.
Bộ nhớ và model thật30

Hỏi nhanh

Đội đưa ảnh câu lạc bộ vào một ResNet học trên ImageNet, còn nguyên head, rồi lấy argmax trên 1000 logits. Kết quả là gì?

Bộ nhớ và model thật31

Dùng model thật offline

Lượt có mạng:

  • Đọc model card và license.
  • Chốt revision commit.
  • Ghi hash các tệp.

Lượt offline:

  • Kiểm hash, rồi nạp model và processor từ máy (local_files_only=True).
  • Chạy dữ liệu nhỏ, kiểm shape và ID.

Rồi mới chấm validation.

Bộ nhớ và model thật32

Hỏi nhanh

Hai tuần sau, đội tải lại cùng model ID từ nhánh main, chạy năm ảnh kiểm ở chế độ eval, và thấy logits khác lần trước ngay từ chữ số đầu. Nên kiểm gì đầu tiên?

Bộ nhớ và model thật33

Hai lỗi processor trên ảnh thật

Đọc bằng cv2 thì đỏ và lam bị đảo; chia 255 hai lần thì ảnh gần như một màu.RGB đúngđọc bằng cv2 (BGR)chia 255 hai lầnmọi giá trị ≤ 1/255shape, dtype đều đúng: không có lỗi nào báo ra
Đọc bằng cv2 thì đỏ và lam bị đảo; chia 255 hai lần thì ảnh gần như một màu.
Bộ nhớ và model thật34

Ảnh thật qua processor và model

Ảnh mèo qua đúng tiền xử lý của ResNet-18: ba lớp mèo đứng đầu.
Bộ nhớ và model thật35

Khi đi thi

  • Đọc quy định về model, Internet, thư viện.
  • Đầu giờ: nạp offline, chạy một batch, nộp thử.
  • Processor giống hệt ở validation và test.
04

Luyện đề

Luyện đề37

Luyện đề 1

ResNet-50 nhận input (B, 3, 224, 224). Phần đầu, gồm conv stride 2 rồi max-pool stride 2, đưa ảnh về 56×5656\times 56. layer1 giữ 56×5656\times 56 và cho ra 256 kênh. Khối đầu của layer2 có conv 3×33\times 3 stride 2 trên 128 kênh, rồi conv 1×11\times 1 mở ra 512 kênh. Đầu ra của layer2 có shape gì?

Phỏng theoUSA-NA-AIO 2026 · Vòng 1 · Part 8.2

Luyện đề38

Luyện đề 2

Biểu thức nào đếm đúng số tham số học được của ResNet-50?

Phỏng theoUSA-NA-AIO 2026 · Vòng 1 · Part 8.1

Luyện đề39

Luyện đề 3

Trên Colab, đội lưu torch.save(model, "m.pt"), tức lưu cả đối tượng model. Máy chấm dùng PyTorch mới, và torch.load("m.pt") báo lỗi “Weights only load failed”. Lần sau nên lưu thế nào cho bền?

Phỏng theoNOAI 2026 Singapore · Vòng sơ loại · Câu 134

Luyện đề40

Chốt ý

Một model dùng được gồm kiến trúc, trọng số, processor và bảng nhãn; thiếu một thứ là kết quả sai mà không báo lỗi.

Chạy theo batch phải giữ ID; đo bộ nhớ trên thiết bị thật; model tải về phải nạp lại được khi không có mạng.

Luyện đề41

Sau giờ học

Làm 10 câu kiểm tra cuối bài trên trang bài học.

Chạy notebook: đổi batch size, kiểm thứ tự output không đổi.