Một số đề thi AI có phần lý thuyết: không cần code, chỉ cần lời giải viết ra kiểm được từng bước. Ví dụ: một bộ phát hiện bài nộp có lỗi “phát hiện được 90% bài lỗi”; vậy một bài bị cảnh báo có xác suất lỗi 90% không? Không nhất thiết, và phải dùng công thức Bayes để giải thích.
Bài này luyện các dạng bài lý thuyết về xác suất, đại số tuyến tính, tối ưu, kiến trúc mạng và đánh giá model; mỗi mục có ví dụ giải tay và một đoạn code ngắn để đối chiếu.
Một lời giải cần cho người đọc kiểm được
Trong CP, chứng minh thuật toán thường có invariant và độ phức tạp. Với AI, lời giải cũng cần một đường kiểm tra: đề cho gì, mô hình giả định gì, dùng định nghĩa nào và kết quả có ý nghĩa gì. Chẳng hạn “” chưa đủ; phải nói đây là hay .
Ta dùng quy trình bốn bước:
- Xác định đại lượng cần trả lời, không tính ngay số dễ có nhất.
- Viết ký hiệu cùng miền giá trị, shape hoặc đơn vị.
- Biến đổi công thức trước khi thế số, để người đọc nhận ra phép tính dùng định nghĩa nào.
- Kiểm bằng một trường hợp nhỏ hoặc code độc lập, rồi diễn giải kết quả.
Code là công cụ đối chiếu; dòng True không thay thế lời giải thích vì sao.
Hai chiều của việc kiểm không cân nhau. Một khẳng định “với mọi ” không được chứng minh bằng hữu hạn lần chạy, dù nhiều đến đâu. Ngược lại, một phản ví dụ nhỏ, chạy đúng, đủ để bác bỏ nó.
Hỏi nhanh
Đề yêu cầu chứng minh MSE không âm với mọi . Một bạn chạy 1000 bộ ngẫu nhiên và thấy loss luôn từ 0 trở lên. Phần này có giá trị gì?
Mỗi số hạng là một bình phương nên không âm, và trung bình các số không âm cũng không âm. Một dòng lập luận là xong. 1000 bộ, kể cả khi phủ đủ hai dấu, vẫn chỉ là hữu hạn trường hợp. Phần chạy vẫn có ích: nếu nó in ra một loss âm thì cài đặt có lỗi.
Xác suất: điều kiện nằm ở phía nào?
Giả sử một tập kiểm có đúng 1000 bài nộp: 20 bài có lỗi và 980 bài không lỗi. Detector cảnh báo 18 trong 20 bài lỗi, đồng thời cảnh báo nhầm 98 trong 980 bài sạch.
Chọn ngẫu nhiên đều một bài trong tập này. Gọi là biến cố “bài có lỗi”, là “bị cảnh báo”. Ta có , và . Bayes đảo chiều điều kiện:
Mẫu số dùng total probability:
Vậy , chỉ khoảng 15.5%. Khi lỗi hiếm, một tỉ lệ báo nhầm nhỏ trên nhóm sạch lớn vẫn sinh nhiều cảnh báo hơn nhóm lỗi. Không có mâu thuẫn với recall 90%; hai câu hỏi dùng hai tập làm mẫu số khác nhau. Recall và tỉ lệ báo nhầm là tính chất của detector; còn phụ thuộc tỉ lệ lỗi của nơi đem detector ra dùng.
Bộ phân loại Bayes chọn lớp có xác suất hậu nghiệm lớn nhất; không có đặc trưng nào thì chỉ còn tiền nghiệm, nên với hai lớp chiếm 2/3 và 1/3 ta đoán lớp đông.
import numpy as np
tp, fn, fp, tn = 18, 2, 98, 882
total = tp + fn + fp + tn
prior = (tp + fn) / total
sensitivity = tp / (tp + fn)
false_alarm_rate = fp / (fp + tn)
alarm_probability = sensitivity * prior + false_alarm_rate * (1 - prior)
posterior = sensitivity * prior / alarm_probability
print(f"P(lỗi)={prior:.4f}, P(cảnh báo)={alarm_probability:.4f}")
print(f"P(lỗi | cảnh báo)={posterior:.4f}")
assert np.isclose(posterior, tp / (tp + fp))
P(lỗi)=0.0200, P(cảnh báo)=0.1160
P(lỗi | cảnh báo)=0.1552
Muốn nhân hai xác suất cho hai thuộc tính, phải kiểm điều kiện độc lập tương ứng. Công thức luôn đúng là ; chỉ khi độc lập mới đổi thành . Một feature xuất hiện nhiều trong bài lỗi không tự động độc lập với feature khác, cũng không chứng minh quan hệ nhân quả.
Vài phép đếm cơ bản: xúc xắc cân đối ra mặt từ 5 trở lên có xác suất ; xác suất có điều kiện chỉ đếm trong nhóm điều kiện, nên lớp có 12 bạn nữ, 3 bạn nữ đeo kính cho .
Naive Bayes (bài 6.1) dùng đúng giả định độc lập khi đã biết lớp, nên chỉ ước lượng từng : đặc trưng nhị phân, hai lớp cần tham số. Nếu không có giả định này, ta phải đếm mọi tổ hợp, mà tổ hợp đủ từ khóa của một thư mới thường không có thư nào trong train. Cái giá: nhân đôi một cột thì bằng chứng ấy bị đếm hai lần và xác suất thành quá tự tin.
Hỏi nhanh
Gọi là bài có lỗi, là bài bị cảnh báo. Trong 20 bài đã biết là có lỗi, có 18 bài được cảnh báo. Tỉ lệ ước lượng xác suất nào?
Mẫu số là nhóm đã biết , nên nằm sau dấu điều kiện. Muốn thì mẫu số phải là mọi bài bị cảnh báo, gồm cả 98 cảnh báo nhầm. và lấy mẫu số là cả 1000 bài, ra và .
Hỏi nhanh
Giữ nguyên detector, bắt được 90% bài lỗi và báo nhầm 10% bài sạch. Đem dùng ở một lớp mà một nửa số bài có lỗi. Ở lớp này, một bài bị cảnh báo có lỗi với xác suất bao nhiêu?
, nên . là đáp án của tập chỉ có 2% bài lỗi: detector không đổi, nhưng precision đổi theo tỉ lệ lỗi. là . là , chưa chia cho .
Kỳ vọng và log-loss: trước khi biết đáp án
Một biến Bernoulli có thì , vì . Do , phương sai là . Với , hai số lần lượt là và . Kỳ vọng mô tả trung bình qua nhiều lần rút; một nhóm 50 bài cụ thể vẫn có thể có 0, 1 hay 3 bài lỗi.
Nếu model xuất xác suất của lớp 1 và nhãn thật là , binary cross-entropy là
Ta dùng logarithm tự nhiên nên loss có đơn vị nats. Khi , cho loss ; dự đoán tự tin sai cho khoảng . Accuracy không thấy mức tự tin này nếu hai xác suất vẫn ở cùng một phía threshold.
BCE chính là của xác suất mà model gán cho nhãn thật, tức negative log-likelihood của một mẫu Bernoulli. Vì tăng ngặt, tham số làm likelihood của cả tập lớn nhất cũng làm tổng log-loss nhỏ nhất: maximum likelihood và tối thiểu log-loss là cùng một bài toán.
Trước khi biết , kỳ vọng loss của dự đoán cố định là . Giá trị nhỏ nhất đạt tại khi ; thay vào cho entropy . Nói cách khác, biết tỉ lệ lớp thật thì xác suất phản ánh tỉ lệ đó là dự đoán tối ưu cho log-loss, chưa chắc là quyết định tối ưu cho mọi chi phí hành động.
def expected_log_loss(q, p):
return -q * np.log(p) - (1 - q) * np.log(1 - p)
q = 0.02
print(f"E[Y]={q:.4f}, Var(Y)={q * (1 - q):.4f}")
print(f"y=1: loss tại p=0.8 là {-np.log(0.8):.4f}; tại p=0.2 là {-np.log(0.2):.4f}")
print(f"E[loss] tại p=0.02: {expected_log_loss(q, 0.02):.4f}")
print(f"E[loss] tại p=0.50: {expected_log_loss(q, 0.50):.4f}")
assert expected_log_loss(q, q) < expected_log_loss(q, 0.5)
E[Y]=0.0200, Var(Y)=0.0196
y=1: loss tại p=0.8 là 0.2231; tại p=0.2 là 1.6094
E[loss] tại p=0.02: 0.0980
E[loss] tại p=0.50: 0.6931
Không lấy log(0) trong code tính tay; nó cho vô cùng. Với logits, thư viện có loss gộp sigmoid hoặc softmax để tính ổn định hơn. Một vector xác suất phải không âm và tổng bằng 1; một vector logits không có hai điều kiện này. Khi trình bày, cần nói model đang xuất đại lượng nào.
Hỏi nhanh
Trong tập train, 30% nhãn là 1. Model chỉ được xuất một xác suất cho mọi mẫu. Giá trị nào cho log-loss trung bình nhỏ nhất?
Log-loss trung bình là , nhỏ nhất tại , với giá trị , thấp hơn của . cho loss vô cùng ở mọi mẫu nhãn 1. Đoán theo đa số có ích cho accuracy, nhưng không có ích cho log-loss. là tỉ lệ của lớp 0, đặt nhầm vào chỗ xác suất của lớp 1.
Đại số tuyến tính: phép nhân mô tả việc gì?
Ta có hai mẫu, mỗi mẫu hai feature, xếp thành hàng của . Linear model với và cho
Hàng đầu có ; hàng sau có . Bias cộng vào mỗi mẫu. Shape của là (2, 2), của là (2,), của kết quả là (2,). Vector một chiều trong NumPy không tự thành cột hai chiều như cách vẽ trên giấy.
X = np.array([[1.0, 2.0], [3.0, 4.0]])
w_linear = np.array([2.0, -1.0])
b_linear = 1.0
prediction = X @ w_linear + b_linear
print("Shape:", X.shape, w_linear.shape, prediction.shape)
print("Dự đoán:", prediction)
assert np.allclose(prediction, [1.0, 3.0])
dependent = np.array([[1.0, 2.0], [2.0, 4.0]])
null_direction = np.array([2.0, -1.0])
print("Hướng không thay đổi dự đoán:", dependent @ null_direction)
print("Hạng ma trận:", np.linalg.matrix_rank(dependent))
Shape: (2, 2) (2,) (2,)
Dự đoán: [1. 3.]
Hướng không thay đổi dự đoán: [0. 0.]
Hạng ma trận: 1
Ma trận dependent có cột thứ hai gấp đôi cột thứ nhất, nên hạng bằng 1. Thêm vào trọng số không đổi dự đoán, vì tích với hướng ấy bằng 0. Bởi vậy một nghiệm hệ số chưa chắc duy nhất; muốn dùng nghịch đảo hay nói “nghiệm duy nhất”, phải kiểm điều kiện hạng. Đây là lý do ở bài 2.1 ta cần least squares và regularization khi feature phụ thuộc.
Tích vô hướng vừa dùng để dự đoán, vừa đo quan hệ hình học. Với hai vector khác 0, cosine similarity chia tích vô hướng cho tích độ dài. Nó không đổi khi nhân một vector với số dương; khoảng cách Euclidean thường đổi.
Vì vậy similarity và khoảng cách cần được chọn theo ý nghĩa của embedding, không chỉ theo công thức thuận tay. Vector 0 không có hướng nên cosine của nó không được định nghĩa bằng phép chia thông thường.
Hỏi nhanh
X có shape (5, 3), w có shape (3,), còn b là một số. X @ w + b có shape gì?
Mỗi hàng cho một tích vô hướng, nên có năm dự đoán, và số b được cộng vào từng phần tử. NumPy giữ kết quả là một chiều (5,), không tự thành cột (5, 1). (3,) là shape của w. (5, 3) là kết quả của X * w, phép nhân từng phần tử có broadcast.
Gradient: chia sai số về đúng tham số
Giờ dùng một mẫu phân loại: , nhãn , trọng số , bias . Logit , xác suất . Loss là .
Chain rule nói đạo hàm qua nhiều phép tính là tích các đạo hàm cục bộ. Với binary cross-entropy và sigmoid ghép đúng, các số hạng rút gọn thành
Vậy gradient của là , của là . Gradient descent với cho , . Logit mới bằng , xác suất tăng lên khoảng , loss giảm còn khoảng . Nhãn là 1 nên dấu thay đổi có nghĩa: model cần tăng xác suất lớp 1.
Ta gộp để kiểm cả ba thành phần bằng sai phân trung tâm. logaddexp(0, z) tính ổn định; loss từ logit là biểu thức đó trừ .
x = np.array([1.0, 2.0])
y = 1.0
theta = np.array([0.2, -0.1, 0.0])
def logistic_loss(parameters):
z = x @ parameters[:2] + parameters[2]
return float(np.logaddexp(0.0, z) - y * z)
def logistic_gradient(parameters):
z = x @ parameters[:2] + parameters[2]
p = 1.0 / (1.0 + np.exp(-z))
return np.append((p - y) * x, p - y)
gradient = logistic_gradient(theta)
h = 1e-5
numerical = np.zeros_like(theta)
for j in range(len(theta)):
shift = np.zeros_like(theta)
shift[j] = h
numerical[j] = (logistic_loss(theta + shift) - logistic_loss(theta - shift)) / (2 * h)
new_theta = theta - 0.1 * gradient
print("Gradient:", gradient)
print("Tham số mới:", new_theta)
print(f"Loss: {logistic_loss(theta):.4f} -> {logistic_loss(new_theta):.4f}")
print("Sai phân khớp:", np.allclose(gradient, numerical, atol=1e-8))
assert np.allclose(gradient, [-0.5, -1.0, -0.5])
assert logistic_loss(new_theta) < logistic_loss(theta)
Gradient: [-0.5 -1. -0.5]
Tham số mới: [0.25 0. 0.05]
Loss: 0.6931 -> 0.5544
Sai phân khớp: True
Gradient cho xấp xỉ bậc nhất khi nhỏ. Đạo hàm âm theo một tham số nghĩa là tăng tham số ấy một chút thì loss giảm, nên bước descent làm nó tăng.
Tình huống loss tăng ở đầu bài thường có một trong hai nguyên nhân: cộng gradient thay vì trừ, hoặc bước quá lớn, vượt khỏi vùng mà xấp xỉ tuyến tính còn dùng được.
Hỏi nhanh
Tại , đạo hàm . Tăng lên , giữ nguyên các tham số khác. Loss thay đổi xấp xỉ bao nhiêu?
. Đạo hàm âm nghĩa là tăng tham số thì loss giảm, chứ không tăng. 2 là quên nhân với độ dịch . Bước nhỏ thì thay đổi nhỏ, chứ không bằng 0. Chính vì bước nhỏ mà xấp xỉ bậc nhất mới đáng tin.
Gradient bằng 0 là điểm dừng, không tự chứng minh đó là cực tiểu toàn cục của một mạng phi tuyến. Với loss lồi, như MSE của linear regression hay log-loss của logistic regression, mọi điểm dừng đều là cực tiểu toàn cục; cần nói rõ lớp hàm đang xét.
Nếu thêm penalty thì gradient theo có thêm . Nếu đề dùng , số 2 biến mất. Trên một batch, loss lấy trung bình cũng làm gradient có hệ số . Viết rõ loss trước khi đạo hàm là cách tránh chép nhầm quy ước.
Hỏi nhanh
Gradient theo bias là , learning rate là , và bias ban đầu là . Sau một bước gradient descent, bias mới bằng bao nhiêu?
. là cộng gradient thay vì trừ, tức đi ngược hướng giảm loss. chỉ lấy mà quên giá trị cũ. là trừ gradient nhưng quên nhân learning rate. Descent không phải lúc nào cũng làm tham số nhỏ đi: gradient âm thì tham số tăng.
Kiến trúc mạng: đếm shape trước khi đếm tham số
Một câu lý thuyết về CNN thường chỉ cần phân biệt số mẫu, channel và không gian. Với convolution không dilation, input cao , kernel , padding , stride , chiều cao đầu ra là
Input (N, C, H, W) = (4, 3, 8, 8), hai output channel, , , cho . Shape output là (4, 2, 4, 4). Mỗi output channel dùng weight và một bias, tổng tham số.
Tổng quát, Conv2d có tham số, bỏ số 1 khi bias=False; cách đặt này thường gặp khi BatchNorm đứng ngay sau, vì BatchNorm đã có tham số dịch riêng. Batch size và số vị trí ảnh không nhân vào số tham số: các weight được dùng lại ở nhiều vị trí.
import torch
torch.manual_seed(0)
conv = torch.nn.Conv2d(3, 2, kernel_size=3, stride=2, padding=1)
images = torch.zeros(4, 3, 8, 8)
with torch.no_grad():
conv_output = conv(images)
parameter_count = sum(parameter.numel() for parameter in conv.parameters())
print("Output shape:", tuple(conv_output.shape))
print("Số tham số:", parameter_count)
assert tuple(conv_output.shape) == (4, 2, 4, 4)
assert parameter_count == 56
Output shape: (4, 2, 4, 4)
Số tham số: 56
Một forward trên tensor toàn 0 đủ để kiểm shape và số tham số; không cần train. Nếu đề có dilation , thay bằng effective size . Kernel vẫn có weight: nó không nhìn lân cận nhưng trộn các channel tại từng vị trí. Pooling thường không có weight học được; residual addition yêu cầu shape hai nhánh khớp hoặc có projection để đưa về cùng shape.
Hỏi nhanh
Input (8, 16, 32, 32) đi qua Conv2d(16, 32, kernel_size=3, padding=1), stride 1, có bias. Output có shape gì, và lớp có bao nhiêu tham số?
, và số channel ra là 32. Mỗi output channel có weight và 1 bias, tổng cộng . 4608 là quên bias. 30 là quên padding. Giữ 16 channel là nhầm số channel vào với số channel ra.
Attention: một hàng là một cách lấy trung bình
Với một head, có shape (Tq, dk), có shape (Tk, dk), có shape (Tk, dv). Ma trận score có shape (Tq, Tk). Softmax theo trục key tạo một phân phối cho mỗi query, rồi nhân để lấy tổng có trọng số:
Ta chọn , tức ma trận đơn vị 2 chiều, và hai value là , . Score của query đầu là . Softmax cho trọng số khoảng , nên output đầu là . Đây là vector giá trị pha trộn, không phải index của một token được chọn.
Q = np.eye(2)
K = np.eye(2)
values = np.array([[2.0, 0.0], [0.0, 4.0]])
def row_softmax(scores):
shifted = scores - scores.max(axis=1, keepdims=True)
exponentials = np.exp(shifted)
return exponentials / exponentials.sum(axis=1, keepdims=True)
scores = Q @ K.T / np.sqrt(Q.shape[1])
weights = row_softmax(scores)
attention_output = weights @ values
print("Trọng số:\n", weights.round(4))
print("Output:\n", attention_output.round(4))
assert np.allclose(weights.sum(axis=1), 1.0)
masked_scores = scores.copy()
masked_scores[0, 1] = -np.inf # query đầu không nhìn token tương lai
causal_weights = row_softmax(masked_scores)
print("Output đầu với causal mask:", (causal_weights @ values)[0])
assert np.allclose(causal_weights[0], [1.0, 0.0])
Trọng số:
[[0.6698 0.3302]
[0.3302 0.6698]]
Output:
[[1.3395 1.321 ]
[0.6605 2.679 ]]
Output đầu với causal mask: [2. 0.]
Đặt mask vào score trước softmax làm xác suất bị cấm bằng 0 rồi chuẩn hóa lại phần được phép. Đặt một weight về 0 sau softmax mà không chuẩn hóa lại làm tổng hàng nhỏ hơn 1. Nếu một query bị mask toàn bộ key, softmax không có phân phối hợp lệ; cần xử lý theo thiết kế của model, không mong phép tính tự hiểu padding.
Trong một layer thật, , , với shape (T, d_model), rồi các head được nối lại và đi qua một phép chiếu ra. Tham số nằm ở các ma trận chiếu, nên số tham số không phụ thuộc độ dài chuỗi ; ngược lại, ma trận score (T, T) tăng theo . Đếm tham số và đếm bộ nhớ là hai câu hỏi khác nhau.
Hỏi nhanh
Q có shape (3, 2), K có shape (5, 2), V có shape (5, 4). Output của một head có shape gì?
Score và weight có shape (3, 5), nhân với (5, 4) thì được (3, 4), tức một vector output cho mỗi query. (3, 5) mới chỉ là trọng số, chưa nhân với value. (5, 4) là shape của V. (2, 4) là lấy nhầm làm số hàng.
Hỏi nhanh
Query thứ hai chỉ được nhìn key 1 và key 2. Score cho ba key là , với log tự nhiên. Đặt score của key 3 thành trước khi softmax. Bộ trọng số thu được là gì?
Sau mask, các exponential là . Chuẩn hóa trên tổng 4 thì được . là softmax khi quên mask. là cắt xác suất sau softmax mà không chuẩn hóa lại, nên tổng chỉ còn . là argmax, không phải softmax.
Đánh giá: trở lại detector đầu bài
Bảng 1000 bài có , , , . Recall bằng , trả lời “bắt được bao nhiêu bài lỗi?”. Precision bằng , trả lời “cảnh báo đáng tin tới đâu?”. Hai số đúng là hai xác suất có điều kiện đã gặp ở đầu bài.
Accuracy bằng . Nhưng baseline luôn đoán sạch có accuracy và recall 0. Không thể từ một số 0.98 kết luận baseline giải quyết mục tiêu tìm lỗi tốt hơn; cũng không thể bỏ qua 98 cảnh báo nhầm vì recall cao. Metric cần phản ánh yêu cầu và chi phí kiểm thủ công của bài.
F1 dùng trung bình điều hòa của precision và recall, tương đương
Để đối chiếu với scikit-learn, ta dựng lại vector nhãn và vector dự đoán đúng theo bốn ô của bảng.
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
labels = np.array([1] * (tp + fn) + [0] * (fp + tn))
predicted = np.array([1] * tp + [0] * fn + [1] * fp + [0] * tn)
accuracy = (tp + tn) / total
precision = tp / (tp + fp)
recall = tp / (tp + fn)
f1 = 2 * tp / (2 * tp + fp + fn)
library = np.array([
accuracy_score(labels, predicted), precision_score(labels, predicted),
recall_score(labels, predicted), f1_score(labels, predicted),
])
assert np.allclose(library, [accuracy, precision, recall, f1])
print(f"Accuracy={accuracy:.4f}, precision={precision:.4f}, recall={recall:.4f}, F1={f1:.4f}")
print(f"Baseline sạch: accuracy={(fp + tn) / total:.4f}, recall=0.0000")
print("Tính tay khớp thư viện:", True)
Accuracy=0.9000, precision=0.1552, recall=0.9000, F1=0.2647
Baseline sạch: accuracy=0.9800, recall=0.0000
Tính tay khớp thư viện: True
Khi chấm model thật, chỉ dùng train để fit tham số; chọn threshold, kiến trúc và hyperparameter bằng validation phù hợp, rồi giữ test để đánh giá cuối.
Với nhiều bài của cùng một người hoặc cùng một nguồn, random split có thể lọt kiểu viết giữa train và validation; lúc ấy cần group split. Nếu mục tiêu dự đoán ở tương lai, cách chia theo thời gian có thể phù hợp hơn. Stratification giữ tỉ lệ lớp nhưng không tự chữa leakage theo nhóm.
Hỏi nhanh
Mỗi học sinh nộp nhiều bài, và bài của cùng một người có mặt ở cả train lẫn validation. Mục tiêu là dự đoán cho học sinh mới. Stratification theo nhãn có xử lý được rủi ro này không?
Stratification chỉ giữ tỉ lệ nhãn, không ngăn kiểu viết của một người xuất hiện ở cả hai phía. Validation khi đó đo khả năng nhận ra người cũ, nên lạc quan so với học sinh mới. Model nhỏ vẫn học được những dấu hiệu ấy. Chia theo thời gian hợp với mục tiêu dự đoán tương lai, nhưng vẫn có thể để một người ở cả hai phía.
Một điểm trên tập nhỏ có sai số lấy mẫu. Nếu 1000 kết quả đúng hay sai thật sự độc lập và cùng xác suất đúng 0.9, độ lệch chuẩn của accuracy mẫu là . Giả thiết độc lập là phần quan trọng: nếu nhiều mẫu đến từ cùng một người, chúng tương quan và độ bất định thật lớn hơn con số này.
Hai model nên được so trên cùng split và đọc loại lỗi của chúng, không chỉ xếp hạng một điểm duy nhất.
Hỏi nhanh
Với 1000 mẫu độc lập và accuracy thật là 0.9, độ lệch chuẩn của accuracy đo được khoảng . Nếu validation chỉ có 100 mẫu thì khoảng bao nhiêu?
. Giảm số mẫu đi 10 lần làm độ lệch chuẩn tăng lần, chứ không phải 10 lần. Trên 100 mẫu, hai model chênh nhau một hai điểm phần trăm thì chưa đủ để xếp hạng. là nhân 10. là chia 10. là quên rằng độ lệch chuẩn phụ thuộc số mẫu.
Khi đi thi
- Viết đại lượng cần tìm trước khi thế số, nhất là điều kiện nằm ở phía nào: hay .
- Đạo hàm từ loss viết đầy đủ, ghi rõ hệ số ; rồi kiểm dấu trên một mẫu.
- Bài kiến trúc thì tính shape từng lớp trước, rồi mới đếm tham số.
Tóm tắt
- Điều kiện xác suất quyết định mẫu số; Bayes, confusion matrix và precision có thể mô tả cùng một câu hỏi.
- Log-loss là negative log-likelihood; xác suất khớp tỉ lệ thật cho log-loss kỳ vọng nhỏ nhất.
- Đại số tuyến tính mô tả phép gộp feature, shape và tính duy nhất của nghiệm. Không nghịch đảo khi chưa kiểm điều kiện.
- Gradient đi qua từng phép tính; loss, dấu và phép lấy trung bình phải nhất quán với code.
- Convolution dùng lại tham số; attention chuẩn hóa theo key cho mỗi query. Shape giúp kiểm cả hai.
- Metric trả lời một mục tiêu cụ thể. Một điểm validation chỉ có ý nghĩa cùng cách chia, baseline và phạm vi dữ liệu.
Kiểm tra cuối bài
Câu 1
Trong 1000 bài nộp, có 200 bài dùng đệ quy, gọi là biến cố , 100 bài bị quá thời gian, gọi là biến cố , và 40 bài vừa dùng đệ quy vừa quá thời gian. và có độc lập không?
Độc lập nghĩa là . Ở đây , tức khoảng 20 bài nếu độc lập, nhưng thực tế có 40 bài. Nói cách khác, , gấp đôi . Một tỉ lệ nhỏ, hay “nhỏ hơn”, không nói gì về độc lập. Kiểm độc lập chỉ cần các xác suất, còn nhân quả là một câu hỏi khác. Sự phụ thuộc này cũng không chứng minh đệ quy gây ra quá thời gian.
Câu 2
Hàm có argmax duy nhất là , và có thể nhận giá trị âm, như một log-likelihood. Hàm nào không chắc có cùng argmax ?
Cộng một hằng số, nhân với một số dương, và lấy đều là biến đổi tăng ngặt, nên giữ thứ tự và giữ argmax. Cũng vì tăng ngặt mà cực đại likelihood tương đương với cực đại log-likelihood. Bình phương thì không tăng trên số âm. Với , argmax là , nhưng lại nhỏ nhất tại đó. Log-likelihood thường âm, nên bình phương nó là một lỗi có thật.
Phỏng theoCMU 10-601 · Exam 1 Practice · Q5.1
Câu 3
Hai model có cùng accuracy 95% trên một tập nhị phân. Model A luôn báo xác suất 0.999 cho lớp nó chọn, còn model B luôn báo 0.95. Log-loss trung bình, với log tự nhiên, của hai model là bao nhiêu?
A được . B được . Mỗi mẫu sai của A bị phạt . Cặp 0.001 và 0.05 là chỉ tính các mẫu đúng. Accuracy chỉ nhìn mẫu nằm phía nào của threshold, nên không phân biệt được hai model. Log-loss thưởng cho xác suất khớp với tần suất đúng, như kết luận của bài.
Câu 4
Linear regression với MSE, và ma trận dữ liệu có cột thứ hai gấp đôi cột thứ nhất. Kết luận nào đúng?
MSE là hàm bậc hai lồi theo , và phương trình luôn có nghiệm, vì là hình chiếu của lên không gian cột. Vì vậy cực tiểu toàn cục luôn tồn tại, và mọi cực tiểu địa phương đều là toàn cục. Nhưng hàm không lồi chặt: thêm vào không làm đổi , nên cả một đường thẳng nghiệm có cùng loss và cùng dự đoán. suy biến chỉ làm công thức nghịch đảo không dùng được, chứ không làm mất nghiệm. GD với bước đủ nhỏ hội tụ về một nghiệm trong số đó, tùy điểm khởi đầu.
Phỏng theoCMU 10-601 · Exam 2 Practice · Q1.2
Câu 5
Logistic regression trên ba điểm: nhãn 0, nhãn 1, nhãn 0. Model 1 là , còn model 2 có thêm bias . Đổi nhãn của thành 1, rồi chạy GD từ cùng khởi tạo, với cùng learning rate. Chuyện gì xảy ra?
Đóng góp của một mẫu vào gradient theo weight là , bằng 0 khi , dù nhãn là gì. Model 1 không có tham số nào khác, nên mọi bước GD giữ nguyên. Model 2 có . Đổi từ 0 sang 1 làm số hạng này giảm 1 ngay từ bước đầu, nên bias đi khác, rồi kéo theo cả weight. Không có bias, model 1 luôn cho tại gốc tọa độ, nên nó không thể học được nhãn của điểm ấy.
Phỏng theoCMU 10-601 · Exam 2 Practice · Q2.2
Câu 6
Logistic regression viết mục tiêu dạng tổng như scikit-learn: , trong đó bias w[0] không bị phạt. Code tối ưu , và đã có g = X.T @ (p - y) / m. Dòng nào cộng phần phạt vào cho đúng?
Chia cho thì phần phạt thành , với đạo hàm , chỉ từ phần tử 1 trở đi. Thiếu / m là phạt mạnh gấp lần so với mục tiêu đã chọn: code vẫn chạy, nhưng cho ra một model khác. Cộng vào cả g[0] là phạt luôn bias, kéo xác suất nền về 0.5 dù dữ liệu lệch lớp. Trong scikit-learn, tham số C đóng vai .
Phỏng theoNOAI 2026 Singapore · Chung kết · Câu 5
Câu 7
Đội dự đoán số khán giả , và chịu chi phí : thuê ghế với giá mỗi ghế, và mất cho mỗi người phải từ chối. Với , , , , và hiện tại , gradient là gì?
Vì , nhánh đang hoạt động, nên . Nhân với thì được . GD trừ gradient, nên tăng , vì thiếu ghế đắt hơn thừa ghế. là gradient khi , chỉ còn chi phí thuê. là quên số hạng . là sai dấu đạo hàm của theo .
Phỏng theoMIT 6.036 · Final, Spring 2022 · Q5(d)
Câu 8
Một bottleneck block của ResNet-50, trong layer3, có ba convolution không bias, mỗi cái theo sau bởi BatchNorm: từ 1024 xuống 256 channel, từ 256 sang 256, và từ 256 lên 1024. Ba convolution này có tổng cộng bao nhiêu tham số?
. Hai conv chiếm gần một nửa, dù kernel nhỏ nhất, vì chúng nối với 1024 channel. Chỉ đếm conv giữa thì được 589 824. Cộng thêm 1536 bias là quên bias=False. Tính hai conv như thì được 5 308 416.
Phỏng theoUSA-NA-AIO 2026 · Vòng 1 · Part 8.3
Câu 9
Một layer multi-head attention có , head, mỗi head có . Ba phép chiếu , , đi từ lên , phép chiếu ra đi từ về , tất cả đều không bias. Thêm relative positional encoding: mỗi head học một vector cho mỗi độ lệch , với chuỗi dài . Tổng số tham số là bao nhiêu?
Bốn ma trận chiếu có tham số. Độ lệch chạy từ đến , tức giá trị, nên phần vị trí có tham số, và tổng là . 13 504 là quên phép chiếu ra. 17 024 là chỉ đếm độ lệch. 16 688 là cho các head dùng chung . Chỉ có phần vị trí phụ thuộc , và không phần nào phụ thuộc batch.
Câu 10
Detector A có precision 0.5 và recall 0.5. Detector B có precision 0.9 và recall 0.1. Trung bình cộng hai chỉ số của cả hai đều bằng 0.5. F1 của mỗi detector bằng bao nhiêu?
F1 là trung bình điều hòa . A được . B được . Trung bình điều hòa bị kéo về phía số nhỏ hơn, nên một detector chỉ bắt được 10% bài lỗi thì precision cao cũng không cứu được. 0.50 cho B là trung bình cộng. 0.25 và 0.09 là tích , quên hệ số . 0.90 là lấy chỉ số lớn hơn.
Đọc thêm
- Deisenroth, Faisal, Ong — Mathematics for Machine Learning, chương 2, 5, 6 và 7. Đọc để nối đại số tuyến tính, đạo hàm nhiều biến, xác suất và tối ưu trong một hệ ký hiệu.
- Boyd, Vandenberghe — Introduction to Applied Linear Algebra. Dùng các ví dụ vector, hạng và least squares để luyện giải thích một phép nhân ma trận bằng lời.
- James và cộng sự — An Introduction to Statistical Learning with Applications in Python, chương 2, 4 và 5. Đọc lỗi tổng quát hóa, xác suất phân loại và validation để đặt phép tính metric vào đúng quy trình.
- Ma, Ng — CS229 Lecture Notes. Đọc các phần logistic regression và neural networks để đối chiếu chain rule với loss từ logits.
- Vaswani và cộng sự — Attention Is All You Need, mục 3.2. Đọc công thức scaled dot-product attention và lý do mask trước softmax.
- PyTorch — Conv2d và scikit-learn — Model evaluation. Dùng để kiểm quy ước shape, bias, positive class và averaging của thư viện.