Pre-trained model là một mô hình được đào tạo bởi một người khác để giải quyết một vấn đề tương tự. Thay vì xây dựng một mô hình từ đầu để giải quyết một vấn đề tương tự, ta sử dụng mô hình được đào tạo về vấn đề khác làm điểm khởi đầu. Một mô hình được đào tạo trước có thể không chính xác 100%, nhưng nó giúp tiết kiệm thời gian và công sức.
2.4.2 FaceNet
FaceNet là một mạng lưới thần kinh sâu được sử dụng để trích xuất các tính năng từ hình ảnh của một người mặt. Nó được xuất bản vào năm 2015 bởi các nhà nghiên cứu của Google.
Hình 1. FaceNet lấy hình ảnh khuôn mặt làm đầu vào và xuất ra vector embedding
FaceNet lấy hình ảnh của mặt người làm đầu vào và xuất ra một vector 128 chiều, đại diện cho các tính năng quan trọng nhất của khuôn mặt. Trong học máy, vector này được gọi là nhúng (embeddings). Tại sao phải nhúng? Bởi vì tất cả các thông tin quan trọng từ một hình ảnh được nhúng vào vector này. Về cơ bản, FaceNet lấy một mặt người và nén nó thành một vector gồm 128 số. Khuôn mặt cần định danh cũng có nhúng tương tự.
Facenet chính là một dạng siam network có tác dụng biểu diễn các bức ảnh trong một không gian eucledean n chiều (thường là 128) sao cho khoảng cách giữa các vector embedding càng nhỏ, mức độ tương đồng giữa chúng càng lớn.
Hầu hết các thuật toán nhận diện khuôn mặt trước facenet đều tìm cách biểu diễn khuôn mặt bằng một vector nhúng (embedding) thông qua một layer bottle neck có tác dụng giảm chiều dữ liệu:
Tuy nhiên hạn chế của các thuật toán này đó là số lượng chiều embedding tương đối lớn (thường >= 1000) và ảnh hưởng tới tốc độ của thuật toán. Thường chúng ta phải áp dụng thêm thuật toán PCA để giảm chiều dữ liệu để giảm tốc độ tính toán.
Hàm loss function chỉ đo lường khoảng cách giữa 2 bức ảnh. Như vậy trong một đầu vào huấn luyện chỉ học được một trong hai khả năng là sự giống nhau nếu chúng cùng 1 class hoặc sự khác nhau nếu chúng khác class mà không học được cùng lúc sự giống nhau và khác nhau trên cùng một lượt huấn luyện.
Facenet đã giải quyết cả 2 vấn đề trên bằng các hiệu chỉnh nhỏ nhưng mang lại hiệu quả lớn:
Base network áp dụng một mạng convolutional neural network và giảm chiều dữ liệu xuống chỉ còn 128 chiều. Do đó quá trình suy diễn và dự báo nhanh hơn và đồng thời độ chính xác vẫn được đảm bảo.
Sử dụng loss function là hàm triplet loss có khả năng học được đồng thời sự giống nhau giữa 2 bức ảnh cùng nhóm và phân biệt các bức ảnh không cùng nhóm. Do đó hiệu quả hơn rất nhiều so với các phương pháp trước đây.
2.4.3 Thuật toán Triplet loss trong FaceNet:
Trong facenet, quá trình encoding của mạng convolutional neural network (CNN) đã giúp ta mã hóa bức ảnh về 128 chiều. Sau đó những vector này sẽ làm đầu vào cho hàm triplet loss đánh giá khoảng cách giữa các vector.
Hình 18. Triplet loss trên hai positive faces-mặt tích cực và một negative face- mặt tiêu cực
Mục tiêu của triplet loss là đảm bảo rằng:
Hai ví dụ có cùng nhãn có các phần nhúng của chúng gần nhau trong không gian nhúng.
Hai ví dụ với các nhãn khác nhau có các nhúng của chúng ở xa. Để áp dụng triple loss, chúng ta cần lấy ra 3 bức ảnh trong đó có một bức ảnh là anchor. Trong 3 ảnh thì ảnh anchor được cố định trước. Chúng ta sẽ lựa chọn 2 ảnh còn lại sao cho một ảnh là negative (của một người khác với anchor) và một ảnh là positive (cùng một người với anchor).
Hình 2. Triplet loss
Loss function:
Mục tiêu của hàm triplet loss là tối thiểu hóa khoảng cách giữa 2 ảnh khi chúng là negative và tối đa hóa khoảng cách khi chúng là positive. Như vậy chúng ta cần lựa chọn các bộ 3 ảnh sao cho:
Ảnh Anchor và Positive khác nhau nhất: cần lựa chọn để khoảng cách d(A,P) lớn. Điều này cũng tương tự như bạn lựa chọn một ảnh của mình hồi nhỏ so với hiện tại để thuật toán học khó hơn. Nhưng nếu nhận biết được thì nó sẽ thông minh hơn.
Ảnh Anchor và Negative giống nhau nhất: cần lựa chọn để khoảng cách d(A,N) d(A,N) nhỏ. Điều này tương tự như việc thuật toán phân biệt được ảnh của một người anh em giống bạn.
Triplet loss function luôn lấy 3 bức ảnh làm đầu vào và trong mọi trường hợp ta kì vọng:
d(A,P) < d(A,N) (1)
Để làm cho khoảng cách giữa vế trái và vế phải lớn hơn, chúng ta sẽ cộng thêm vào vế trái một hệ số α không âm rất nhỏ. Khi đó (1) trở thành:
Như vậy hàm loss function sẽ là:
Khi huấn luyện mô hình siam network với triplet loss ta luôn phải xác định trước cặp ảnh (A,P) thuộc về cùng một người. Ảnh N sẽ được lựa chọn ngẫu nhiên từ các bức ảnh thuộc các nhãn còn lại.
Như vậy khi áp dụng triplet loss vào các mô hình convolutional neural network chúng ta có thể tạo ra các biểu diễn vector tốt nhất cho mỗi một bức ảnh. Những biểu diễn vector này sẽ phân biệt tốt các ảnh Negative rất giống ảnh Positive. Và đồng thời các bức ảnh thuộc cùng một label sẽ trở nên gần nhau hơn trong không gian chiếu euclidean.
Hình 20. Triplet loss trước và sau khi đào tạo 2.5 Kỹ thuật căn chỉnh khuôn mặt (Face alignment)
Căn chỉnh khuôn mặt là nhiệm vụ xác định cấu trúc hình học của khuôn mặt trong hình ảnh kỹ thuật số và cố gắng có được sự căn chỉnh chính xác của khuôn mặt dựa trên sự biến dạng, tỷ lệ và xoay.
Có nhiều hình thức căn chỉnh khuôn mặt, một số phương pháp cố gắng áp đặt mô hình 3D (được xác định trước) sau đó áp dụng biến đổi cho hình ảnh đầu vào sao cho các mốc trên mặt đầu vào khớp với các mốc trên mô hình 3D.
Các phương pháp khác đơn giản hơn, chỉ dựa vào chính các mốc trên khuôn mặt (đặc biệt là vùng mắt) để thực hiện xoay, dịch chuyển và điều chỉnh tỷ lệ của khuôn mặt về cùng một kích thước.
Sau khi phát hiện các khuôn mặt có trên ảnh, các khuôn mặt có thể ở các trạng thái khác nhau, các góc độ khác nhau, có những khuôn mặt bị chéo và cũng có thể bị lệch do bước phát hiện chưa chính xác trong việc lấy ra khung hình chuẩn của mặt. Thì việc áp dụng căn chỉnh khuôn mặt ở đây là cần thiết, nó có thể hiểu như một hình thức của chuẩn hóa dữ liệu, giúp tiêu chuẩn hoá lại dữ liệu trước khi đưa vào mô hình dự đoán. Điều này giúp cải thiện độ chính xác của mô hình nhận diện khuôn mặt.
Hình 21. Căn chỉnh khuôn mặt 2.6 Ngôn ngữ Python
2.6.1 Giới thiệu sơ lược về ngôn ngữ Python
Python là một ngôn ngữ lập trình hướng đối tượng và rất thông dụng. Có
cấu trúc rõ ràng, rất thuận tiện cho người mới học lập trình và làm cho việc thử
nghiệm các tính năng của ngôn ngữ trở nên dễ dàng. Được tạo ra bởi Guido van Rossum tại Amsterdam vào năm 1990. Python hoàn toàn tạo kiểu động và dùng cơ chế cấp phát bộ nhớ tự động. Python được phát triển trong một dự án mã mở, do tổ chức phi lợi nhuận Python Software Foundation quản lý. Python là một
ngôn ngữ lập trình mạnh và dễ học. Python có tính hiệu quả rất cao với các cấu trúc dữ liệu và đơn giản nhưng lại rất hữu dụng với ngôn ngữ lập trình hướng đối tượng. Cú pháp Python gọn gàng và có tính năng gõ động, cùng với tính diễn dịch tự nhiên làm Python là một ngôn ngữ lý tưởng dành cho việc xây dựng và phát triển ứng dụng nhanh chóng trong nhiều lĩnh vực trên nhiều nền tảng khác nhau. [14]
2.6.2 Các đặc điểm của ngôn ngữ Python
Dễ học, dễ đọc: Python được thiết kế để trở thành một ngôn ngữ dễ học, mã nguồn dễ đọc, bố cục rõ ràng, dễ hiểu.
Từ khóa: Python tăng cường sử dụng từ khóa tiếng Anh, hạn chế các kí hiệu và cấu trúc, cú pháp so với các ngôn ngữ khác. Python là một ngôn ngữ phân biệt kiểu chữ hoa, chữ thường.
Khối lệnh: Trong các ngôn ngữ khác, khối lệnh thường được đánh dấu bằng cặp kí hiệu hoặc từ khóa. Ví dụ, trong C/C++, cặp ngoặc nhọn {} được dùng để bao bọc một khối lệnh. Ngược lại, Python có một cách rất đặc biệt để tạo khối lệnh, đó là thụt các câu lệnh trong khối vào sâu hơn (về bên phải) so với các câu lệnh của khối lệnh cha chứa nó. Ta có thể dùng dấu Tab để thụt các khối lệnh vào để dễ dàng viết lệnh hơn.
Khả năng mở rộng: Python có thể được mở rộng. Nếu ta biết sử dụng C, ta có thể dễ dàng viết và tích hợp vào Python nhiều hàm tùy theo nhu cầu. Các hàm này sẽ trở thành hàm xây dựng sẵn (built-in) của Python. Ta cũng có thể mở rộng chức năng của trình thông dịch, hoặc liên kết các chương trình Python với các thư viện chỉ ở dạng nhị phân (như các thư viện đồ họa do nhà sản xuất thiết bị cung cấp). Hơn thế nữa, ta cũng có thể liên kết trình thông dịch của Python với các ứng dụng viết từ C và sử dụng nó như là một mở rộng hoặc một ngôn ngữ dòng lệnh hỗ trợ cho ứng dụng đó.
Trình thông dịch: Python là một ngôn ngữ lập trình dạng thông dịch, vì vậy nên Python tiết kiệm được thời gian phát triển ứng dụng vì không cần phải thực hiện biên dịch và liên kết. Trình thông dịch có thể được sử dụng để chạy file script, hoặc cũng có thể được sử dụng theo cách tương tác. Ở chế độ tương tác,
trình thông dịch Python tương tự shell của các hệ điều hành họ Unix. Tại đó, ta có thể nhập vào từng biểu thức rồi gõ Enter, và kết quả thực thi sẽ được hiển thị ngay lập tức. Đặc điểm này rất hữu ích cho người mới học, giúp họ nghiên cứu tính năng của ngôn ngữ; hoặc để các lập trình viên chạy thử mã lệnh trong suốt quá trình phát triển phần mềm. Ngoài ra, cũng có thể tận dụng đặc điểm này để thực hiện các phép tính như với máy tính bỏ túi.
Lệnh và cấu trúc điều khiển: Mỗi câu lệnh trong Python nằm trên một dòng mã nguồn. Ta không cần phải kết thúc câu lệnh bằng bất kì kí tự gì. Như các ngôn ngữ khác, Python cũng có các cấu trúc điều khiển.
Chúng bao gồm:
Cấu trúc rẽ nhánh: Cấu trúc if (có thể sử dụng thêm elif hoặc else), dùng để thực thi có điều kiện một khối mã cụ thể.
Lệnh while: Thực thi lặp đi lặp lại các lệnh hoặc phần thân của vòng lặp miễn là điều kiện đã cho là true. Khi điều kiện là false, thì điều khiển sẽ thoát ra khỏi vòng lặp.
Vòng lặp for: Lặp qua từng phần tử của một dãy, mỗi phần tử sẽ được đưa vào biến cục bộ để sử dụng với khối mã trong vòng lặp.
Python cũng có từ khóa class dùng để khai báo lớp (sử dụng trong lập trình hướng đối tượng) và lệnh def dùng để định nghĩa hàm.
Hệ thống kiểu dữ liệu: Python sử dụng hệ thống kiểu duck typing, còn gọi là latent typing (tự động xác định kiểu). Có nghĩa là, Python không kiểm tra các ràng buộc về kiểu dữ liệu tại thời điểm dịch, mà là tại thời điểm thực thi. Khi thực thi, nếu một thao tác trên một đối tượng bị thất bại, thì có nghĩa là đối tượng đó không sử dụng một kiểu thích hợp. Python cũng là một ngôn ngữ định kiểu mạnh. Nó cấm mọi thao tác không hợp lệ. Ở Python, ta không cần phải khai báo biến. Biến được xem là đã khai báo nếu nó được gán một giá trị lần đầu tiên. Căn cứ vào mỗi lần gán, Python sẽ tự động xác định kiểu dữ liệu của biến.
Module: Python cho phép chia chương trình thành các module để có thể sử dụng lại trong các chương trình khác. Python cũng cung cấp sẵn một tập hợp các modules chuẩn mà lập trình viên có thể sử dụng lại trong chương trình của họ.
Các module này cung cấp nhiều chức năng hữu ích, như các hàm truy xuất tập tin, các lời gọi hệ thống, trợ giúp lập trình mạng.
Đa năng: Python là một ngôn ngữ lập trình đơn giản nhưng rất hiệu quả. - So với Unix shell, Python hỗ trợ các chương trình lớn hơn và cung cấp nhiều cấu trúc hơn.
- So với C, Python cung cấp nhiều cơ chế kiểm tra lỗi hơn. Nó cũng có sẵn nhiều kiểu dữ liệu cấp cao, ví dụ như các mảng (array) linh hoạt và từ điển (dictionary) mà ta sẽ phải mất nhiều thời gian nếu viết bằng C. Python là một ngôn ngữ lập trình cấp cao có thể đáp ứng phần lớn yêu cầu của lập trình viên:
Python thích hợp với các chương trình lớn hơn cả AWK và Perl.
Python được sử dụng để lập trình Web. Nó có thể được sử dụng như một ngôn ngữ kịch bản.
Python được tích hợp sẵn nhiều công cụ và có một thư viện chuẩn phong phú, Python cho phép người dùng dễ dàng tạo ra các dịch vụ Web, sử dụng các thành phần COM hay CORBA, hỗ trợ các loại định dạng dữ liệu Internet như email, HTML, XML và các ngôn ngữ đánh dấu khác. Python cũng được cung cấp các thư viện xử lý các giao thức Internet thông dụng như HTTP, FTP, …
Python có khả năng giao tiếp đến hầu hết các loại cơ sở dữ liệu, có khả năng xử lí văn bản, tài liệu hiệu quả, và có thể làm việc tốt với các công nghệ Web khác.
Python đặc biệt hiệu quả trong lập trình tính toán khoa học nhờ các công cụ Python Imaging Library, pyVTK, MayaVi 3D Visualization Toolkits, Numeric Python, ScientificPython, …
Python có thể được sử dụng để phát triển các ứng dụng desktop. Lập trình viên có thể dùng wxPython, PyQt, PyGtk để phát triển các ứng dụng giao diện đồ họa (GUI) chất lượng cao. Python còn hỗ trợ các nền tảng phát triển phần mềm khác như MFC, Carbon, Delphi, X11, Motif, Tk, Fox, FLTK, …
Python cũng có sẵn một unit testing framework để tạo ra các các bộ test (test suites).
Multiple paradigms (đa biến hóa): Python là một ngôn ngữ đa biến hóa (multiple paradigms). Có nghĩa là, thay vì ép buộc mọi người phải sử dụng duy nhất một phương pháp lập trình, Python lại cho phép sử dụng nhiều phương pháp lập trình khác nhau: hướng đối tượng, có cấu trúc, chức năng, hoặc chỉ hướng đến một khía cạnh. Python kiểu kiểu động và sử dụng bộ thu gom rác để quản lí bộ nhớ. Một đặc điểm quan trọng nữa của Python là giải pháp tên động, kết nối tên biến và tên phương thức lại với nhau trong suốt thực thi của chương trình.
2.6.3 Ứng dụng của Python
Python được ứng dụng trong nhiều lĩnh vực khác nhau:
- Xây dựng các tiện ích nhỏ để tự động hóa các công việc nào đó như: tự động tìm kiếm, phân loại tập tin theo tiêu chí riêng, tự động cập nhật các tập tin văn bản theo yêu cầu nào đó…
- Xây dựng ứng dụng web: Python cung cấp nhiều framework để ta có thể lựa chọn để phát triển ứng dụng web tùy theo mô hình của ứng dụng như: Django, Pyramid, Flask, …
- Lập trình các tính toán khoa học, số liệu nhờ các công cụ và lớp thư viện được xây dựng sẵn như: SciPy, IPython, …
- Lập trình ứng dụng desktop (wxWidgets), lập trình màn hình tương tác (Kivy), …
Bên cạnh đó, Python còn là ngôn ngữ lập trình được lựa chọn để giảng dạy về lập trình các khóa học nhập môn lập trình ở các trường Đại học lớn trên thế giới.
2.7 Một số thư viện quan trọng2.7.1 Opencv 2.7.1 Opencv
OpenCV (OpenSource Computer Vision) là một thư viện mã nguồn mở. OpenCV được phát hành theo giấy phép BSD, do đó nó hoàn toàn miễn phí cho cả học thuật và thương mại. Nó có các interface C++, C, Python, Java và hỗ trợ Windows, Linux, Mac OS, iOS và Android. OpenCV được thiết kế để tính toán hiệu quả và với sự tập trung nhiều vào các ứng dụng thời gian thực. Được viết bằng tối ưu hóa C/C++, thư viện có thể tận dụng lợi thế của xử lý đa lõi.