Bài 15: Điện thoại nhận ra khuôn mặt bạn thế nào? Vector đặc trưng và khoảng cách

Bạn nhìn vào điện thoại và nó mở khóa trong chưa đầy một giây. Điện thoại không "nhìn" khuôn mặt như con người – nó biến khuôn mặt thành một dãy số, rồi đo khoảng cách giữa các dãy số đó.

Bài thứ mười lăm của chuyên mục "Thuật toán trong đời sống": nhận diện khuôn mặt và hình học của vector.
1. Khuôn mặt → dãy số
Năm 2015, ba nhà nghiên cứu của Google (Schroff, Kalenichenko, Philbin) công bố hệ thống FaceNet. Ý tưởng: dùng mạng nơ-ron biến mỗi ảnh khuôn mặt thành một vector 128 chiều (gọi là embedding hay vector đặc trưng), sao cho khoảng cách giữa hai vector phản ánh trực tiếp mức độ giống nhau của hai khuôn mặt.
- Hai ảnh của cùng một người → hai vector gần nhau.
- Ảnh của hai người khác nhau → hai vector xa nhau.
Theo bài báo, FaceNet đạt độ chính xác 99,63% trên bộ dữ liệu LFW (Labeled Faces in the Wild) và mỗi khuôn mặt chỉ cần 128 byte để lưu trữ.
2. Dạy máy bằng "bộ ba"
FaceNet được huấn luyện bằng các bộ ba ảnh: một ảnh gốc (anchor), một ảnh khác của cùng người (positive) và một ảnh của người khác (negative). Mục tiêu:
với α là một "khoảng đệm" bắt buộc giữa hai loại cặp ảnh.
Sau hàng triệu bộ ba, mạng nơ-ron học được cách đặt ảnh của cùng một người vào một "vùng" riêng trong không gian 128 chiều.
3. Đo khoảng cách giữa hai vector
Hai cách đo phổ biến:
- Khoảng cách Euclid: như đo bằng thước, nhưng trong không gian nhiều chiều: √((a₁−b₁)² + (a₂−b₂)² + …).
- Độ tương đồng cosin: đo góc giữa hai vector, bằng tích vô hướng chia cho tích độ dài. Giá trị càng gần 1 thì càng giống.
Trong FaceNet, các vector được chuẩn hóa về độ dài 1. Khi đó ‖u − v‖² = 2 − 2·cos(u, v), nên hai cách đo cho cùng một thứ tự "giống nhất".
4. Mô phỏng: ai đang đứng trước camera?
Ví dụ dưới đây rút gọn vector còn 4 chiều. Máy so khuôn mặt vừa chụp với từng người trong cơ sở dữ liệu, chọn người giống nhất – nhưng chỉ chấp nhận nếu độ giống vượt ngưỡng. Nếu không, đó là "người lạ".
So khớp khuôn mặt bằng độ tương đồng cosin
#include <bits/stdc++.h>
using namespace std;
double cosine(const vector<double>& a, const vector<double>& b){
double dot = 0, na = 0, nb = 0;
for(size_t i = 0; i < a.size(); i++){ dot += a[i]*b[i]; na += a[i]*a[i]; nb += b[i]*b[i]; }
return dot / (sqrt(na) * sqrt(nb));
}
int main(){
vector<pair<string, vector<double>>> db = {
{"An", {0.91, 0.12, 0.40, 0.05}},
{"Binh", {0.10, 0.88, 0.35, 0.30}},
{"Chi", {0.45, 0.40, 0.90, 0.10}}};
vector<double> camera = {0.87, 0.18, 0.43, 0.08};
const double NGUONG = 0.95;
string best; double bs = -1;
for(auto& [name, v] : db){
double s = cosine(v, camera);
printf("%-5s cosine = %.3f\n", name.c_str(), s);
if(s > bs){ bs = s; best = name; }
}
printf("Ket qua: %s (%.3f)\n", bs >= NGUONG ? best.c_str() : "Nguoi la", bs);
}import math
def cosine(a, b):
# độ tương đồng cosin giữa hai vector đặc trưng
dot = sum(x * y for x, y in zip(a, b))
na = math.sqrt(sum(x * x for x in a))
nb = math.sqrt(sum(y * y for y in b))
return dot / (na * nb)
# Vector đặc trưng (rút gọn còn 4 chiều để minh họa; thực tế 128–512 chiều)
db = {
"An": [0.91, 0.12, 0.40, 0.05],
"Binh": [0.10, 0.88, 0.35, 0.30],
"Chi": [0.45, 0.40, 0.90, 0.10],
}
camera = [0.87, 0.18, 0.43, 0.08] # khuôn mặt vừa chụp
NGUONG = 0.95
best = max(db, key=lambda name: cosine(db[name], camera))
for name, v in db.items():
print(f"{name:5s} cosine = {cosine(v, camera):.3f}")
s = cosine(db[best], camera)
print("Ket qua:", best if s >= NGUONG else "Nguoi la", f"({s:.3f})")Kết quả chạy:
An cosine = 0.997
Binh cosine = 0.425
Chi cosine = 0.797
Ket qua: An (0.997)Chọn ngưỡng là một bài toán đánh đổi: ngưỡng thấp thì dễ mở nhầm cho người khác; ngưỡng cao thì chủ máy đôi khi bị từ chối.
5. Còn Face ID trên iPhone?
Apple không công bố chi tiết thuật toán và không nói Face ID dùng FaceNet, nhưng nguyên lý tương tự:
- Theo thông cáo báo chí năm 2017 của Apple, Face ID chiếu hơn 30.000 điểm hồng ngoại vô hình để tạo bản đồ độ sâu khuôn mặt.
- Theo trang hỗ trợ của Apple, mạng nơ-ron chuyển bản đồ độ sâu và ảnh hồng ngoại thành một "biểu diễn toán học" rồi so với dữ liệu đã đăng ký. Dữ liệu này được mã hóa và bảo vệ trong Secure Enclave.
- Xác suất một người ngẫu nhiên mở được máy là dưới 1 phần 1.000.000 (với Touch ID vân tay là 1 phần 50.000). Apple lưu ý xác suất cao hơn với anh chị em sinh đôi và trẻ dưới 13 tuổi.
6. Bạn học được gì từ đây?
- Rất nhiều bài toán AI quy về tìm điểm gần nhất trong không gian nhiều chiều.
- Tích vô hướng, độ dài vector – kiến thức hình học lớp 10 – là nền tảng của học máy.
- Dữ liệu khuôn mặt là thông tin cá nhân nhạy cảm, cần được bảo vệ cẩn thận.
Bài tập luyện tập
- CSES – Minimum Euclidean Distance (tìm cặp điểm gần nhất)
- CSES – Point Location Test (làm quen tích có hướng)
- Sửa code để dùng khoảng cách Euclid thay cho cosin. Kết quả có thay đổi không?

Nguồn tham khảo
- Không biết học gì trước, học gì sau, học lan man nên kiến thức bị hổng.
- Bí bài không ai gỡ, ngồi cả buổi vẫn không ra rồi bỏ cuộc.
- Code chạy được nhưng không đủ điểm, không biết sai ở đâu, chậm ở đâu.
- Không có đề thi thử và người chấm, nên không biết mình đang ở mức nào.
- Dễ nản giữa chừng khi không có ai theo sát.
- Lộ trình 111 buổi video sắp sẵn từ dòng code đầu tiên đến đề HSG thật của các tỉnh.
- Thầy trực tiếp gỡ bí, chữa bài cho từng em qua nhóm Zalo riêng.
- Hệ thống chấm bài tự động 24/7 và thi thử HSG hằng tuần để biết chính xác mình đang ở đâu.
- Đóng học phí một lần, thầy kèm lâu dài: từ thi chuyên Tin đến HSG quốc gia và cả khi lên đại học.
Nhận xét
Đăng nhận xét